1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-13 05:44:11 +02:00
Beef/IDE/src/BookmarkManager.bf

435 lines
10 KiB
Beef
Raw Normal View History

2019-08-23 11:56:54 -07:00
using System;
using System.Collections;
2019-08-23 11:56:54 -07:00
using System.Text;
using System.Threading.Tasks;
using IDE.ui;
using System.Diagnostics;
namespace IDE
{
public class TrackedTextElement
{
public int mRefCount = 1;
public bool mIsDead;
public String mFileName ~ delete _;
public int32 mLineNum;
public int32 mColumn;
public bool mSnapToLineStart = true;
public int32 mMoveIdx; // Increments when we manually move an element (ie: a history location updating because the user types near the previous history location)
public virtual void Move(int wantLineNum, int wantColumn)
{
mLineNum = (int32)wantLineNum;
mColumn = (int32)wantColumn;
}
public virtual void Kill()
{
mIsDead = true;
Deref();
}
public void AddRef()
{
mRefCount++;
}
public void Deref()
{
if (--mRefCount == 0)
delete this;
}
public ~this()
{
Debug.Assert(mRefCount == 0);
}
}
public class Bookmark : TrackedTextElement
2022-06-08 20:11:39 +02:00
{
public String mTitle ~ delete _;
2019-08-23 11:56:54 -07:00
public String mNotes ~ delete _;
2022-06-08 20:11:39 +02:00
public bool mIsDisabled;
2022-06-09 12:25:48 +02:00
public BookmarkFolder mFolder;
2019-08-23 11:56:54 -07:00
}
2022-06-09 12:25:48 +02:00
public class BookmarkFolder
{
/// The title of the bookmark-folder that will be visible in the bookmark-panel
public String mTitle ~ delete _;
public List<Bookmark> mBookmarkList = new List<Bookmark>() ~
{
2019-08-23 11:56:54 -07:00
for (var bookmark in mBookmarkList)
bookmark.Kill();
2022-06-09 12:25:48 +02:00
gApp.mDebugger.mBreakpointsChangedDelegate();
2019-08-23 11:56:54 -07:00
delete _;
2022-06-09 12:25:48 +02:00
};
/// Gets or Sets whether every bookmark in this folder is disabled or not.
public bool IsDisabled
{
get
{
for (var bookmark in mBookmarkList)
if (!bookmark.mIsDisabled)
return false;
return true;
}
set
{
for (var bookmark in mBookmarkList)
bookmark.mIsDisabled = value;
gApp.mBookmarksPanel.mBookmarksDirty = true;
}
}
/// Adds the given bookmark to this folder. If needed, removes it from its old folder.
public void AddBookmark(Bookmark bookmark)
{
if (bookmark.mFolder != null)
{
bookmark.mFolder.mBookmarkList.Remove(bookmark);
}
mBookmarkList.Add(bookmark);
bookmark.mFolder = this;
//gApp.mBookmarksPanel.mBookmarksDirty = true;
}
}
public class BookmarkManager
{
public BookmarkFolder mRootFolder = new .();
public List<BookmarkFolder> mBookmarkFolders = new .() {mRootFolder} ~ DeleteContainerAndItems!(_);
private int mBookmarkCount;
/// Index of the folder that was navigated to last
public int32 mFolderIdx;
/// Index of the bookmark (inside of its folder) that was navigated to last
2019-08-23 11:56:54 -07:00
public int32 mBookmarkIdx;
2022-06-08 20:11:39 +02:00
2022-06-09 12:25:48 +02:00
/// Number of bookmarks created, used to generate the names.
2022-06-08 20:11:39 +02:00
private int32 _createdBookmarks;
2022-06-09 12:25:48 +02:00
/// Number of folders created, used to generate the names.
private int32 _createdFolders;
/// Gets or sets whether all bookmarks are disabled or not.
2022-06-08 20:11:39 +02:00
public bool AllBookmarksDisabled
{
get
{
2022-06-09 12:25:48 +02:00
for (var folder in mBookmarkFolders)
2022-06-08 20:11:39 +02:00
{
2022-06-09 12:25:48 +02:00
if (!folder.IsDisabled)
2022-06-08 20:11:39 +02:00
return false;
}
return true;
}
2022-06-09 12:25:48 +02:00
set
{
for (var folder in mBookmarkFolders)
{
folder.IsDisabled = value;
}
gApp.mBookmarksPanel.mBookmarksDirty = true;
}
}
/**
* Creates a new bookmark folder
* @param title The title of the bookmark
* @returns the newly created BookmarkFolder
*/
public BookmarkFolder CreateFolder(String title = null)
{
mBookmarkIdx = -1;
BookmarkFolder folder = new .();
if (title == null)
folder.mTitle = new $"Folder {_createdFolders++}";
else
folder.mTitle = new String(title);
mBookmarkFolders.Add(folder);
gApp.mBookmarksPanel.mBookmarksDirty = true;
return folder;
2022-06-08 20:11:39 +02:00
}
2022-06-09 12:25:48 +02:00
/// Deletes the given bookmark folder and all bookmarks inside it.
public void DeleteFolder(BookmarkFolder folder)
2022-06-08 20:11:39 +02:00
{
2022-06-09 12:25:48 +02:00
int folderIdx = mBookmarkFolders.IndexOf(folder);
mBookmarkFolders.Remove(folder);
delete folder;
// Select the previous folder
if (mFolderIdx == folderIdx)
folderIdx--;
if (mFolderIdx >= mBookmarkFolders.Count)
mFolderIdx = (int32)mBookmarkFolders.Count - 1;
// Select last bookmark inside the newly selected folder
if (mBookmarkIdx >= mBookmarkFolders[mFolderIdx].mBookmarkList.Count)
mBookmarkIdx = (int32)mBookmarkFolders[mFolderIdx].mBookmarkList.Count - 1;
gApp.mBookmarksPanel.mBookmarksDirty = true;
}
public Bookmark CreateBookmark(String fileName, int wantLineNum, int wantColumn, bool isDisabled = false, String title = null, BookmarkFolder folder = null)
{
var folder;
folder = folder ?? mRootFolder;
mFolderIdx = (int32)mBookmarkFolders.IndexOf(folder);
mBookmarkIdx = (int32)folder.mBookmarkList.Count;
2019-08-23 11:56:54 -07:00
Bookmark bookmark = new Bookmark();
bookmark.mFileName = new String(fileName);
bookmark.mLineNum = (int32)wantLineNum;
bookmark.mColumn = (int32)wantColumn;
2022-06-08 20:11:39 +02:00
if (title == null)
bookmark.mTitle = new $"Bookmark {_createdBookmarks++}";
else
bookmark.mTitle = new String(title);
bookmark.mIsDisabled = isDisabled;
2022-06-09 12:25:48 +02:00
folder.AddBookmark(bookmark);
2019-08-23 11:56:54 -07:00
gApp.mDebugger.mBreakpointsChangedDelegate();
2022-06-08 20:11:39 +02:00
gApp.mBookmarksPanel.mBookmarksDirty = true;
2022-06-09 12:25:48 +02:00
mBookmarkCount++;
2019-08-23 11:56:54 -07:00
return bookmark;
}
2022-06-09 12:25:48 +02:00
/** Moves the bookmark to the specified folder.
* @param bookmark The bookmark to move.
* @param folder The folder to which the bookmark will be moved.
* @param insertBefore If null the bookmark will be added at the end of the folder. Otherwise it will be inserted before the specified bookmark.
*/
public void MoveBookmarkToFolder(Bookmark bookmark, BookmarkFolder folder, Bookmark insertBefore = null)
{
if (bookmark.mFolder != null)
{
bookmark.mFolder.mBookmarkList.Remove(bookmark);
}
if (insertBefore == null)
folder.mBookmarkList.Add(bookmark);
else
{
Debug.Assert(folder == insertBefore.mFolder, "Insert before must be in folder.");
int index = folder.mBookmarkList.IndexOf(insertBefore);
folder.mBookmarkList.Insert(index, bookmark);
}
bookmark.mFolder = folder;
FixupIndices();
gApp.mBookmarksPanel.mBookmarksDirty = true;
}
enum Placement
{
Before,
After
}
public void MoveFolder(BookmarkFolder folder, Placement place = .After, BookmarkFolder target = null)
{
if (folder == target)
return;
if (mBookmarkFolders.Contains(folder))
mBookmarkFolders.Remove(folder);
if (target == null)
{
mBookmarkFolders.Add(folder);
}
else
{
int index = mBookmarkFolders.IndexOf(target);
if (place == .After)
index++;
mBookmarkFolders.Insert(index, folder);
}
FixupIndices();
gApp.mBookmarksPanel.mBookmarksDirty = true;
}
/// Make sure that the bookmark and folder indices are valid.
private void FixupIndices()
{
if (mBookmarkIdx <= 0 || mBookmarkIdx >= mBookmarkFolders[mFolderIdx].mBookmarkList.Count)
{
mBookmarkIdx = 0;
// Don't have an empty folder selected
if (mBookmarkFolders[mFolderIdx].mBookmarkList.Count == 0)
mFolderIdx = 0;
}
}
2019-08-23 11:56:54 -07:00
public void DeleteBookmark(Bookmark bookmark)
{
2022-06-09 12:25:48 +02:00
BookmarkFolder folder = bookmark.mFolder;
folder.mBookmarkList.Remove(bookmark);
FixupIndices();
gApp.mDebugger.mBreakpointsChangedDelegate();
2019-08-23 11:56:54 -07:00
bookmark.Kill();
2022-06-08 20:11:39 +02:00
gApp.mBookmarksPanel.mBookmarksDirty = true;
2022-06-09 12:25:48 +02:00
mBookmarkCount--;
2019-08-23 11:56:54 -07:00
}
public void Clear()
{
2022-06-09 12:25:48 +02:00
for (var folder in mBookmarkFolders)
{
for (var bookmark in folder.mBookmarkList)
bookmark.Kill();
folder.mBookmarkList.Clear();
}
ClearAndDeleteItems!(mBookmarkFolders);
mRootFolder = new BookmarkFolder();
mBookmarkFolders.Add(mRootFolder);
mFolderIdx = 0;
2019-08-23 11:56:54 -07:00
mBookmarkIdx = 0;
gApp.mDebugger.mBreakpointsChangedDelegate();
2022-06-08 20:11:39 +02:00
gApp.mBookmarksPanel.mBookmarksDirty = true;
2019-08-23 11:56:54 -07:00
}
2022-06-09 12:25:48 +02:00
public void PrevBookmark(bool currentFolderOnly = false)
2019-08-23 11:56:54 -07:00
{
2022-06-09 12:25:48 +02:00
if (mBookmarkCount == 0)
return;
2019-08-23 11:56:54 -07:00
2022-06-09 12:25:48 +02:00
int32 currentFolderIdx = mFolderIdx;
int32 currentBookmarkIdx = mBookmarkIdx;
2022-06-08 20:11:39 +02:00
2022-06-09 12:25:48 +02:00
Bookmark nextBookmark = null;
2022-06-08 20:11:39 +02:00
repeat
{
2022-06-09 12:25:48 +02:00
mBookmarkIdx++;
if (mBookmarkIdx >= mBookmarkFolders[mFolderIdx].mBookmarkList.Count)
{
if (!currentFolderOnly)
{
mFolderIdx++;
if (mFolderIdx >= mBookmarkFolders.Count)
{
// wrap to first folder
mFolderIdx = 0;
}
}
// Select first bookmark in current folder (or -1 if there is no bookmark)
mBookmarkIdx = mBookmarkFolders[mFolderIdx].mBookmarkList.IsEmpty ? -1 : 0;
}
if (mBookmarkIdx >= 0)
nextBookmark = mBookmarkFolders[mFolderIdx].mBookmarkList[mBookmarkIdx];
else
nextBookmark = null;
2022-06-08 20:11:39 +02:00
}
// skip disabled bookmarks, stop when we reach starting point
2022-06-09 12:25:48 +02:00
while ((nextBookmark == null || nextBookmark.mIsDisabled) && ((currentFolderIdx != mFolderIdx) || (currentBookmarkIdx != mBookmarkIdx) && mBookmarkIdx != -1));
2019-08-23 11:56:54 -07:00
2022-06-09 12:25:48 +02:00
// If nextBookmark is disabled no bookmark is enabled.
if (nextBookmark != null && !nextBookmark.mIsDisabled)
GotoBookmark(nextBookmark);
2019-08-23 11:56:54 -07:00
}
2022-06-09 12:25:48 +02:00
public void NextBookmark(bool currentFolderOnly = false)
2019-08-23 11:56:54 -07:00
{
2022-06-09 12:25:48 +02:00
if (mBookmarkCount == 0)
return;
2019-08-23 11:56:54 -07:00
2022-06-09 12:25:48 +02:00
int32 currentFolderIdx = mFolderIdx;
int32 currentBookmarkIdx = mBookmarkIdx;
2022-06-08 20:11:39 +02:00
2022-06-09 12:25:48 +02:00
Bookmark nextBookmark = null;
2019-08-23 11:56:54 -07:00
2022-06-08 20:11:39 +02:00
repeat
{
mBookmarkIdx--;
2022-06-09 12:25:48 +02:00
2022-06-08 20:11:39 +02:00
if (mBookmarkIdx < 0)
2022-06-09 12:25:48 +02:00
{
if (!currentFolderOnly)
{
mFolderIdx--;
if (mFolderIdx < 0)
{
// wrap to last folder
mFolderIdx = (int32)mBookmarkFolders.Count - 1;
}
}
// Select last bookmark in current folder
mBookmarkIdx = (int32)mBookmarkFolders[mFolderIdx].mBookmarkList.Count - 1;
}
2022-06-08 20:11:39 +02:00
2022-06-09 12:25:48 +02:00
if (mBookmarkIdx >= 0)
nextBookmark = mBookmarkFolders[mFolderIdx].mBookmarkList[mBookmarkIdx];
else
nextBookmark = null;
2022-06-08 20:11:39 +02:00
}
// skip disabled bookmarks, stop when we reach starting point
2022-06-09 12:25:48 +02:00
while ((nextBookmark == null || nextBookmark.mIsDisabled) && ((currentFolderIdx != mFolderIdx) || (currentBookmarkIdx != mBookmarkIdx) && mBookmarkIdx != -1));
2022-06-08 20:11:39 +02:00
2022-06-09 12:25:48 +02:00
// If nextBookmark is disabled no bookmark is enabled.
if (nextBookmark != null && !nextBookmark.mIsDisabled)
GotoBookmark(nextBookmark);
2019-08-23 11:56:54 -07:00
}
2022-06-08 20:11:39 +02:00
public void GotoBookmark(Bookmark bookmark)
{
2022-06-09 12:25:48 +02:00
mFolderIdx = (int32)mBookmarkFolders.IndexOf(bookmark.mFolder);
mBookmarkIdx = (int32)bookmark.mFolder.mBookmarkList.IndexOf(bookmark);
2022-06-08 20:11:39 +02:00
gApp.ShowSourceFileLocation(bookmark.mFileName, -1, -1, bookmark.mLineNum, bookmark.mColumn, LocatorType.Smart);
}
2019-08-23 11:56:54 -07:00
}
}