- enhancement: save project's bookmark in it's own bookmark file

- enhancement: project and non-project files use different bookmark view (auto switch when switch editors)
  - enhancement: auto merge when save bookmarks.
This commit is contained in:
Roy Qu 2022-10-11 21:51:33 +08:00
parent f67628863f
commit 975d90c8f1
9 changed files with 440 additions and 141 deletions

View File

@ -9,7 +9,9 @@ Red Panda C++ Version 1.5
- change: don't show syntax check messages in the tools output panel (to reduce longtime memory usage)
- fix: minor memory leaks when set itemmodels
- fix: thread for parsing doesn't correctly released when parsing finished ( so and the parser)
- enhancement: save project's bookmark in it's own bookmark file
- enhancement: project and non-project files use different bookmark view (auto switch when switch editors)
- enhancement: auto merge when save bookmarks.
Red Panda C++ Version 1.4

View File

@ -1292,6 +1292,7 @@ void Editor::showEvent(QShowEvent */*event*/)
reparse();
}
pMainWindow->bookmarkModel()->setIsForProject(inProject());
// if (pSettings->codeCompletion().clearWhenEditorHidden()
// && !inProject()) {
// reparse();
@ -1696,7 +1697,7 @@ void Editor::onLinesDeleted(int first, int count)
{
pMainWindow->caretList().linesDeleted(this,first,count);
pMainWindow->debugger()->breakpointModel()->onFileDeleteLines(mFilename,first,count);
pMainWindow->bookmarkModel()->onFileDeleteLines(mFilename,first,count);
pMainWindow->bookmarkModel()->onFileDeleteLines(mFilename,first,count, inProject());
resetBreakpoints();
resetBookmarks();
if (!pSettings->editor().syntaxCheckWhenLineChanged()) {
@ -1708,7 +1709,7 @@ void Editor::onLinesInserted(int first, int count)
{
pMainWindow->caretList().linesInserted(this,first,count);
pMainWindow->debugger()->breakpointModel()->onFileInsertLines(mFilename,first,count);
pMainWindow->bookmarkModel()->onFileInsertLines(mFilename,first,count);
pMainWindow->bookmarkModel()->onFileInsertLines(mFilename,first,count, inProject());
resetBreakpoints();
resetBookmarks();
if (!pSettings->editor().syntaxCheckWhenLineChanged()) {
@ -1747,7 +1748,7 @@ bool Editor::shouldOpenInReadonly()
void Editor::resetBookmarks()
{
mBookmarkLines=pMainWindow->bookmarkModel()->bookmarksInFile(mFilename);
mBookmarkLines=pMainWindow->bookmarkModel()->bookmarksInFile(mFilename,inProject());
invalidate();
}
@ -4407,17 +4408,15 @@ bool Editor::hasBreakpoint(int line)
return mBreakpointLines.contains(line);
}
void Editor::addBookmark(int line, const QString& description)
void Editor::addBookmark(int line)
{
mBookmarkLines.insert(line);
pMainWindow->bookmarkModel()->addBookmark(mFilename,line,description);
invalidateGutterLine(line);
}
void Editor::removeBookmark(int line)
{
mBookmarkLines.remove(line);
pMainWindow->bookmarkModel()->removeBookmark(mFilename,line);
invalidateGutterLine(line);
}
@ -4429,7 +4428,6 @@ bool Editor::hasBookmark(int line)
void Editor::clearBookmarks()
{
mBookmarkLines.clear();
pMainWindow->bookmarkModel()->removeBookmarks(mFilename);
invalidateGutter();
}

View File

@ -187,7 +187,7 @@ public:
void toggleBreakpoint(int line);
void clearBreakpoints();
bool hasBreakpoint(int line);
void addBookmark(int line,const QString& description);
void addBookmark(int line);
void removeBookmark(int line);
bool hasBookmark(int line);
void clearBookmarks();
@ -224,6 +224,7 @@ public:
QString getWordForCompletionSearch(const QSynedit::BufferCoord& pos,bool permitTilde);
QStringList getExpressionAtPosition(
const QSynedit::BufferCoord& pos);
void resetBookmarks();
const PCppParser &parser();
@ -242,7 +243,6 @@ private slots:
private:
bool isBraceChar(QChar ch);
bool shouldOpenInReadonly();
void resetBookmarks();
QChar getCurrentChar();
bool handleSymbolCompletion(QChar key);
bool handleParentheseCompletion();

View File

@ -281,7 +281,7 @@ MainWindow::MainWindow(QWidget *parent)
}
mBookmarkModel = std::make_shared<BookmarkModel>();
try {
mBookmarkModel->load(includeTrailingPathDelimiter(pSettings->dirs().config())
mBookmarkModel->loadBookmarks(includeTrailingPathDelimiter(pSettings->dirs().config())
+DEV_BOOKMARK_FILE);
} catch (FileError &e) {
QMessageBox::warning(nullptr,
@ -407,6 +407,7 @@ MainWindow::MainWindow(QWidget *parent)
updateShortcuts();
updateTools();
updateEditorSettings();
//updateEditorBookmarks();
}
MainWindow::~MainWindow()
@ -449,6 +450,14 @@ void MainWindow::updateEditorSettings()
mEditorList->applySettings();
}
void MainWindow::updateEditorBookmarks()
{
for (int i=0;i<mEditorList->pageCount();i++) {
Editor * e=(*mEditorList)[i];
e->resetBookmarks();
}
}
void MainWindow::updateEditorActions()
{
Editor* e = mEditorList->getEditor();
@ -1281,10 +1290,6 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
// Only update class browser once
mClassBrowserModel.beginUpdate();
{
auto action = finally([this]{
mClassBrowserModel.endUpdate();
});
mProject = Project::load(filename,mEditorList,&mFileSystemWatcher);
updateProjectView();
ui->projectView->expand(
@ -1292,15 +1297,21 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
mProject->model()->rootIndex()));
pSettings->history().removeProject(filename);
// // if project manager isn't open then open it
// if not devData.ShowLeftPages then
// actProjectManager.Execute;
// // if project manager isn't open then open it
// if not devData.ShowLeftPages then
// actProjectManager.Execute;
//checkForDllProfiling();
//parse the project
// UpdateClassBrowsing;
scanActiveProject(true);
mBookmarkModel->setIsForProject(true);
mBookmarkModel->loadProjectBookmarks(
changeFileExt(mProject->filename(), PROJECT_BOOKMARKS_EXT),
mProject->directory());
if (openFiles) {
PProjectUnit unit = mProject->doAutoOpen();
setProjectViewCurrentUnit(unit);
@ -1310,6 +1321,8 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
foreach (PProjectUnit unit, mProject->unitList()) {
Editor* e = mEditorList->getOpenedEditorByFilename(unit->fileName());
mProject->associateEditorToUnit(e,unit);
if (e)
e->resetBookmarks();
}
Editor * e = mEditorList->getEditor();
@ -1319,7 +1332,8 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
updateAppTitle();
updateCompilerSet();
updateClassBrowserForEditor(e);
}
mClassBrowserModel.endUpdate();
//updateForEncodingInfo();
}
@ -2294,8 +2308,10 @@ void MainWindow::loadLastOpens()
focusedEditor = editor;
pSettings->history().removeFile(editorFilename);
}
if (mProject && mEditorList->pageCount()==0)
if (mProject && mEditorList->pageCount()==0) {
mProject->doAutoOpen();
updateEditorBookmarks();
}
if (count>0) {
updateEditorActions();
//updateForEncodingInfo();
@ -3759,20 +3775,20 @@ void MainWindow::onBookmarkRemove()
PBookmark bookmark = mBookmarkModel->bookmark(index.row());
if (bookmark) {
Editor * editor = mEditorList->getOpenedEditorByFilename(bookmark->filename);
if (editor) {
if (editor && editor->inProject() == mBookmarkModel->isForProject()) {
editor->removeBookmark(bookmark->line);
} else {
mBookmarkModel->removeBookmarkAt(index.row());
}
mBookmarkModel->removeBookmarkAt(index.row());
}
}
}
void MainWindow::onBookmarkRemoveAll()
{
mBookmarkModel->clear();
mBookmarkModel->clear(mBookmarkModel->isForProject());
for (int i=0;i<mEditorList->pageCount();i++) {
Editor * editor = (*mEditorList)[i];
if (editor->inProject() == mBookmarkModel->isForProject())
editor->clearBookmarks();
}
}
@ -4305,19 +4321,15 @@ void MainWindow::closeProject(bool refreshEditor)
} else
mProject->saveLayout(); // always save layout, but not when SaveAll has been called
mBookmarkModel->saveProjectBookmarks(
changeFileExt(mProject->filename(), PROJECT_BOOKMARKS_EXT),
mProject->directory());
mClassBrowserModel.beginUpdate();
{
auto action2 = finally([this]{
mClassBrowserModel.endUpdate();
});
// Remember it
pSettings->history().addToOpenedProjects(mProject->filename());
mEditorList->beginUpdate();
{
auto action3 = finally([this]{
mEditorList->endUpdate();
});
mProject.reset();
if (!mQuitting && refreshEditor) {
@ -4329,9 +4341,11 @@ void MainWindow::closeProject(bool refreshEditor)
mClassBrowserModel.setParser(nullptr);
mClassBrowserModel.setCurrentFile("");
}
}
}
mEditorList->endUpdate();
mClassBrowserModel.endUpdate();
if (!mQuitting) {
mBookmarkModel->setIsForProject(false);
// Clear error browser
clearIssues();
updateProjectView();
@ -4540,7 +4554,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
pSettings->environment().setDefaultOpenFolder(QDir::currentPath());
pSettings->environment().save();
try {
mBookmarkModel->save(includeTrailingPathDelimiter(pSettings->dirs().config())
mBookmarkModel->saveBookmarks(includeTrailingPathDelimiter(pSettings->dirs().config())
+DEV_BOOKMARK_FILE);
} catch (FileError& e) {
QMessageBox::warning(nullptr,
@ -4672,8 +4686,8 @@ void MainWindow::on_actionSave_triggered()
if (editor != NULL) {
try {
editor->save();
if (editor->inProject() && (mProject))
mProject->saveAll();
// if (editor->inProject() && (mProject))
// mProject->saveAll();
} catch(FileError e) {
QMessageBox::critical(editor,tr("Error"),e.reason());
}
@ -6942,7 +6956,8 @@ void MainWindow::on_actionAdd_bookmark_triggered()
tr("Description:"),QLineEdit::Normal,
editor->document()->getString(line-1).trimmed());
desc = desc.trimmed();
editor->addBookmark(line,desc);
editor->addBookmark(line);
mBookmarkModel->addBookmark(editor->filename(),line,desc,editor->inProject());
}
}
@ -6953,6 +6968,7 @@ void MainWindow::on_actionRemove_Bookmark_triggered()
int line;
if (editor && editor->pointToLine(mEditorContextMenuPos,line)) {
editor->removeBookmark(line);
mBookmarkModel->removeBookmark(editor->filename(),line,editor->inProject());
}
}

View File

@ -110,6 +110,7 @@ public:
void updateForStatusbarModeInfo(bool clear=false);
void updateStatusbarMessage(const QString& s);
void updateEditorSettings();
void updateEditorBookmarks();
void updateEditorActions();
void updateProjectActions();
void updateCompileActions();

View File

@ -895,7 +895,7 @@
<enum>QTabWidget::South</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>5</number>
</property>
<property name="iconSize">
<size>
@ -1512,6 +1512,9 @@
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>

View File

@ -70,6 +70,7 @@
#endif
#define DEV_PROJECT_EXT "dev"
#define PROJECT_BOOKMARKS_EXT "bookmarks"
#define RC_EXT "rc"
#define RES_EXT "res"
#define H_EXT "h"

View File

@ -17,6 +17,7 @@
#include "bookmarkmodel.h"
#include "../systemconsts.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QJsonArray>
@ -26,15 +27,21 @@
#include <QSet>
#include "../utils.h"
BookmarkModel::BookmarkModel(QObject* parent):QAbstractTableModel(parent)
BookmarkModel::BookmarkModel(QObject* parent):QAbstractTableModel(parent),
mIsForProject(false)
{
}
QSet<int> BookmarkModel::bookmarksInFile(const QString &filename)
QSet<int> BookmarkModel::bookmarksInFile(const QString &filename, bool forProject)
{
QSet<int> lines;
foreach (const PBookmark& bookmark, mBookmarks) {
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
foreach (const PBookmark& bookmark, bookmarks) {
if (bookmark->filename.compare(filename, PATH_SENSITIVITY) == 0) {
lines.insert(bookmark->line);
}
@ -42,27 +49,48 @@ QSet<int> BookmarkModel::bookmarksInFile(const QString &filename)
return lines;
}
void BookmarkModel::addBookmark(const QString &filename, int line, const QString &description)
void BookmarkModel::addBookmark(const QString &filename, int line, const QString &description, bool forProject)
{
Q_ASSERT(!isBookmarkExists(filename,line));
Q_ASSERT(!isBookmarkExists(filename,line,forProject));
PBookmark bookmark = std::make_shared<Bookmark>();
bookmark->filename = filename;
bookmark->line = line;
bookmark->description = description;
bookmark->timestamp = QDateTime::currentMSecsSinceEpoch();
if (forProject) {
if (forProject==mIsForProject)
beginInsertRows(QModelIndex(),mProjectBookmarks.count(),mProjectBookmarks.count());
mProjectBookmarks.append(bookmark);
} else {
if (forProject==mIsForProject)
beginInsertRows(QModelIndex(),mBookmarks.count(),mBookmarks.count());
mBookmarks.append(bookmark);
}
if (forProject==mIsForProject)
endInsertRows();
}
PBookmark BookmarkModel::bookmark(int i, bool forProject)
{
if (forProject)
return mProjectBookmarks[i];
else
return mBookmarks[i];
}
PBookmark BookmarkModel::bookmark(int i)
{
return mBookmarks[i];
return bookmark(i,isForProject());
}
PBookmark BookmarkModel::bookmark(const QString &filename, int line)
PBookmark BookmarkModel::bookmark(const QString &filename, int line, bool forProject)
{
for (int i=0;i<mBookmarks.count();i++) {
PBookmark bookmark = mBookmarks[i];
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
foreach (PBookmark bookmark, bookmarks) {
if (bookmark->filename.compare(filename, PATH_SENSITIVITY) == 0
&& bookmark->line == line) {
return bookmark;
@ -71,40 +99,65 @@ PBookmark BookmarkModel::bookmark(const QString &filename, int line)
return PBookmark();
}
bool BookmarkModel::removeBookmark(const QString &filename, int line)
PBookmark BookmarkModel::bookmark(const QString &filename, int line)
{
for (int i=0;i<mBookmarks.count();i++) {
PBookmark bookmark = mBookmarks[i];
return bookmark(filename,line,isForProject());
}
bool BookmarkModel::removeBookmark(const QString &filename, int line, bool forProject)
{
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
for (int i=0;i<bookmarks.count();i++) {
PBookmark bookmark = bookmarks[i];
if (bookmark->filename.compare(filename, PATH_SENSITIVITY) == 0
&& bookmark->line == line) {
removeBookmarkAt(i);
removeBookmarkAt(i, forProject);
return true;
}
}
return false;
}
void BookmarkModel::removeBookmarks(const QString &filename)
void BookmarkModel::removeBookmarks(const QString &filename, bool forProject)
{
for (int i=mBookmarks.count()-1;i>=0;i--) {
PBookmark bookmark = mBookmarks[i];
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
for (int i=bookmarks.count()-1;i>=0;i--) {
PBookmark bookmark = bookmarks[i];
if (bookmark->filename.compare(filename, PATH_SENSITIVITY) == 0) {
removeBookmarkAt(i);
removeBookmarkAt(i, forProject);
}
}
}
void BookmarkModel::clear()
void BookmarkModel::clear(bool forProject)
{
if (forProject==mIsForProject)
beginResetModel();
if (forProject)
mProjectBookmarks.clear();
else
mBookmarks.clear();
if (forProject==mIsForProject)
endResetModel();
}
bool BookmarkModel::updateDescription(const QString &filename, int line, const QString &description)
bool BookmarkModel::updateDescription(const QString &filename, int line, const QString &description, bool forProject)
{
for (int i=0;i<mBookmarks.count();i++) {
PBookmark bookmark = mBookmarks[i];
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
for (int i=0;i<bookmarks.count();i++) {
PBookmark bookmark = bookmarks[i];
if (bookmark->filename.compare(filename, PATH_SENSITIVITY) == 0
&& bookmark->line == line) {
bookmark->description = description;
@ -115,16 +168,90 @@ bool BookmarkModel::updateDescription(const QString &filename, int line, const Q
return false;
}
void BookmarkModel::save(const QString &filename)
bool BookmarkModel::updateDescription(const QString &filename, int line, const QString &description)
{
return updateDescription(filename,line,description,mIsForProject);
}
void BookmarkModel::saveBookmarks(const QString &filename)
{
save(filename,QString());
}
void BookmarkModel::loadBookmarks(const QString &filename)
{
if (!mIsForProject)
beginResetModel();
mBookmarks = load(filename,0,&mLastLoadBookmarksTimestamp);
if (!mIsForProject)
endResetModel();
}
void BookmarkModel::save(const QString &filename, const QString& projectFolder)
{
bool forProject = !projectFolder.isEmpty();
qint64 t,fileTimestamp;
QList<PBookmark> bookmarks;
if (forProject) {
t=mLastLoadProjectBookmarksTimestamp;
foreach (const PBookmark& bookmark, mProjectBookmarks) {
PBookmark newBookmark=std::make_shared<Bookmark>();
newBookmark->description = bookmark->description;
newBookmark->filename = extractRelativePath(projectFolder, bookmark->filename);
newBookmark->line = bookmark->line;
newBookmark->timestamp = bookmark->timestamp;
bookmarks.append(newBookmark);
}
} else {
t=mLastLoadBookmarksTimestamp;
bookmarks = mBookmarks;
}
QList<PBookmark> fileBookmarks=load(filename, t,&fileTimestamp);
QFile file(filename);
int saveOrderCount=0;
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
QHash<QString,PBookmark> compareHash;
QList<PBookmark> saveBookmarks;
foreach (const PBookmark& bookmark, bookmarks) {
QString key = QString("%1-%2").arg(bookmark->filename).arg(bookmark->line);
bookmark->saveOrder=saveOrderCount++;
compareHash.insert(key,bookmark);
}
foreach (const PBookmark& bookmark, fileBookmarks) {
QString key = QString("%1-%2").arg(bookmark->filename).arg(bookmark->line);
bookmark->saveOrder=saveOrderCount++;
if (!compareHash.contains(key))
compareHash.insert(key,bookmark);
else {
PBookmark pTemp=compareHash.value(key);
if (pTemp->timestamp<=bookmark->timestamp)
compareHash.insert(key,bookmark);
}
compareHash.insert(key,bookmark);
}
QList<PBookmark> saveList;
foreach (const PBookmark& bookmark, compareHash) {
saveList.append(bookmark);
}
std::sort(saveList.begin(),saveList.end(), [](PBookmark b1,PBookmark b2) {
return b1->saveOrder - b2->saveOrder;
});
if (forProject) {
mProjectBookmarks=saveList;
mLastLoadProjectBookmarksTimestamp = QDateTime::currentMSecsSinceEpoch();
} else {
mBookmarks=saveList;
mLastLoadBookmarksTimestamp = QDateTime::currentMSecsSinceEpoch();
}
QJsonArray array;
foreach (const PBookmark& bookmark, mBookmarks) {
foreach (const PBookmark& bookmark, saveList) {
QJsonObject obj;
obj["filename"]=bookmark->filename;
obj["line"]=bookmark->line;
obj["description"]=bookmark->description;
obj["timestamp"]=QString("%1").arg(bookmark->timestamp);
array.append(obj);
}
QJsonDocument doc;
@ -139,12 +266,18 @@ void BookmarkModel::save(const QString &filename)
}
}
void BookmarkModel::load(const QString& filename)
QList<PBookmark> BookmarkModel::load(const QString& filename, qint64 criteriaTimestamp, qint64* pFileTimestamp)
{
clear();
//clear(forProject);
QList<PBookmark> bookmarks;
QFileInfo fileInfo(filename);
qint64 timestamp=fileInfo.fileTime(QFile::FileModificationTime).toMSecsSinceEpoch();
*pFileTimestamp=timestamp;
if (timestamp<=criteriaTimestamp)
return bookmarks;
QFile file(filename);
if (!file.exists())
return;
return bookmarks;
if (file.open(QFile::ReadOnly)) {
QByteArray content = file.readAll();
QJsonParseError error;
@ -156,58 +289,111 @@ void BookmarkModel::load(const QString& filename)
.arg(error.errorString()));
}
QJsonArray array = doc.array();
qint64 bookmarkTimestamp;
bool ok;
for (int i=0;i<array.count();i++) {
QJsonValue value = array[i];
QJsonObject obj=value.toObject();
addBookmark( QFileInfo(obj["filename"].toString()).absoluteFilePath(),
obj["line"].toInt(),
obj["description"].toString());
bookmarkTimestamp = obj["timestamp"].toString().toULongLong(&ok);
if (ok && bookmarkTimestamp>criteriaTimestamp) {
PBookmark bookmark = std::make_shared<Bookmark>();
bookmark->filename = obj["filename"].toString();
bookmark->line = obj["line"].toInt();
bookmark->description = obj["description"].toString();
bookmark->timestamp=obj["timestamp"].toString().toULongLong();
bookmarks.append(bookmark);
}
}
} else {
throw FileError(tr("Can't open file '%1' for read.")
.arg(filename));
}
return bookmarks;
}
void BookmarkModel::onFileDeleteLines(const QString &filename, int startLine, int count)
void BookmarkModel::saveProjectBookmarks(const QString &filename, const QString& projectFolder)
{
for (int i = mBookmarks.count()-1;i>=0;i--){
PBookmark bookmark = mBookmarks[i];
save(filename,projectFolder);
}
void BookmarkModel::loadProjectBookmarks(const QString &filename, const QString& projectFolder)
{
if (mIsForProject)
beginResetModel();
mProjectBookmarks = load(filename,0,&mLastLoadProjectBookmarksTimestamp);
QDir folder(projectFolder);
foreach (PBookmark bookmark, mProjectBookmarks) {
bookmark->filename=folder.absoluteFilePath(bookmark->filename);
}
if (mIsForProject)
endResetModel();
}
void BookmarkModel::onFileDeleteLines(const QString &filename, int startLine, int count, bool forProject)
{
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
for (int i = bookmarks.count()-1;i>=0;i--){
PBookmark bookmark = bookmarks[i];
if (bookmark->filename == filename
&& bookmark->line>=startLine) {
if (bookmark->line >= startLine+count) {
bookmark->line -= count;
if (forProject == mIsForProject)
emit dataChanged(createIndex(i,0),createIndex(i,2));
} else {
removeBookmarkAt(i);
removeBookmarkAt(i,forProject);
}
}
}
}
void BookmarkModel::onFileInsertLines(const QString &filename, int startLine, int count)
void BookmarkModel::onFileInsertLines(const QString &filename, int startLine, int count, bool forProject)
{
for (int i = mBookmarks.count()-1;i>=0;i--){
PBookmark bookmark = mBookmarks[i];
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
for (int i = bookmarks.count()-1;i>=0;i--){
PBookmark bookmark = bookmarks[i];
if (bookmark->filename == filename
&& bookmark->line>=startLine) {
bookmark->line+=count;
if (forProject == mIsForProject)
emit dataChanged(createIndex(i,0),createIndex(i,2));
}
}
}
void BookmarkModel::removeBookmarkAt(int i, bool forProject)
{
if (forProject == mIsForProject)
beginRemoveRows(QModelIndex(), i,i);
if (forProject)
mProjectBookmarks.removeAt(i);
else
mBookmarks.removeAt(i);
if (forProject == mIsForProject)
endRemoveRows();
}
void BookmarkModel::removeBookmarkAt(int i)
{
beginRemoveRows(QModelIndex(), i,i);
mBookmarks.removeAt(i);
endRemoveRows();
return removeBookmarkAt(i,isForProject());
}
bool BookmarkModel::isBookmarkExists(const QString &filename, int line)
bool BookmarkModel::isBookmarkExists(const QString &filename, int line, bool forProject)
{
foreach (const PBookmark& bookmark, mBookmarks) {
QList<PBookmark> bookmarks;
if (forProject)
bookmarks = mProjectBookmarks;
else
bookmarks = mBookmarks;
foreach (const PBookmark& bookmark, bookmarks) {
if (bookmark->filename.compare(filename, PATH_SENSITIVITY) == 0
&& bookmark->line == line) {
return true;
@ -216,8 +402,76 @@ bool BookmarkModel::isBookmarkExists(const QString &filename, int line)
return false;
}
bool BookmarkModel::isForProject() const
{
return mIsForProject;
}
void BookmarkModel::setIsForProject(bool newIsForProject)
{
if (newIsForProject!=mIsForProject) {
mIsForProject = newIsForProject;
beginResetModel();
endResetModel();
}
}
void BookmarkModel::sort(int column, Qt::SortOrder order)
{
switch(column) {
case 0:
if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b1->description,b2->description);
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b2->description,b1->description);
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
}
break;
case 1:
if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b1->filename,b2->filename);
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else {
auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b2->filename,b1->filename);
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
}
break;
case 2:
if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) {
return b1->line-b2->line;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else {
auto sorter=[](PBookmark b1,PBookmark b2) {
return b2->line-b1->line;
};
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
}
break;
}
}
int BookmarkModel::rowCount(const QModelIndex &) const
{
if (mIsForProject)
return mProjectBookmarks.count();
else
return mBookmarks.count();
}
@ -226,7 +480,11 @@ QVariant BookmarkModel::data(const QModelIndex &index, int role) const
if (!index.isValid())
return QVariant();
int row = index.row();
PBookmark bookmark = mBookmarks[row];
PBookmark bookmark;
if (mIsForProject)
bookmark = mProjectBookmarks[row];
else
bookmark = mBookmarks[row];
if (role == Qt::DisplayRole) {
switch(index.column()) {
case 0:

View File

@ -25,6 +25,8 @@ struct Bookmark {
QString filename;
int line;
QString description;
qint64 timestamp;
int saveOrder;
};
using PBookmark=std::shared_ptr<Bookmark>;
@ -34,25 +36,37 @@ class BookmarkModel : public QAbstractTableModel
Q_OBJECT
public:
BookmarkModel(QObject* parent=nullptr);
QSet<int> bookmarksInFile(const QString& filename);
void addBookmark(const QString&filename, int line, const QString& description);
QSet<int> bookmarksInFile(const QString& filename, bool forProject);
void addBookmark(const QString&filename, int line, const QString& description, bool forProject);
PBookmark bookmark(int i, bool forProject);
PBookmark bookmark(int i);
PBookmark bookmark(const QString&filename, int line, bool forProject);
PBookmark bookmark(const QString&filename, int line);
bool removeBookmark(const QString&filename, int line);
void removeBookmarks(const QString& filename);
void clear();
bool removeBookmark(const QString&filename, int line, bool forProject);
void removeBookmarks(const QString& filename, bool forProject);
void clear(bool forProject);
bool updateDescription(const QString&filename, int line, const QString& description, bool forProject);
bool updateDescription(const QString&filename, int line, const QString& description);
void save(const QString& filename);
void load(const QString& filename);
void saveBookmarks(const QString& filename);
void loadBookmarks(const QString& filename);
void saveProjectBookmarks(const QString& filename, const QString& projectFolder);
void loadProjectBookmarks(const QString& filename, const QString& projectFolder);
void removeBookmarkAt(int i, bool forProject);
void removeBookmarkAt(int i);
public slots:
void onFileDeleteLines(const QString& filename, int startLine, int count);
void onFileInsertLines(const QString& filename, int startLine, int count);
void onFileDeleteLines(const QString& filename, int startLine, int count, bool forProject);
void onFileInsertLines(const QString& filename, int startLine, int count, bool forProject);
private:
bool isBookmarkExists(const QString&filename, int line);
bool isBookmarkExists(const QString&filename, int line, bool forProject);
void save(const QString& filename, const QString& projectFolder);
QList<PBookmark> load(const QString& filename, qint64 criteriaTimestamp, qint64* pFileTimestamp);
private:
QList<PBookmark> mBookmarks;
QList<PBookmark> mProjectBookmarks;
qint64 mLastLoadBookmarksTimestamp;
qint64 mLastLoadProjectBookmarksTimestamp;
bool mIsForProject;
// QAbstractItemModel interface
public:
@ -63,6 +77,12 @@ public:
// QAbstractItemModel interface
public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
bool isForProject() const;
void setIsForProject(bool newIsForProject);
// QAbstractItemModel interface
public:
void sort(int column, Qt::SortOrder order) override;
};
using PBookmarkModel = std::shared_ptr<BookmarkModel>;