From be0c9ad4f5cba28bde6587bcc7835d07f04680f4 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Sun, 23 Oct 2022 00:39:24 +0800 Subject: [PATCH] - fix: save/load bookmark doesn't work --- NEWS.md | 1 + RedPandaIDE/debugger.cpp | 16 ++++ RedPandaIDE/debugger.h | 2 + RedPandaIDE/mainwindow.cpp | 3 + RedPandaIDE/todoparser.cpp | 13 +++- RedPandaIDE/todoparser.h | 1 + RedPandaIDE/widgets/bookmarkmodel.cpp | 40 +++++----- libs/qsynedit/qsynedit/TextBuffer.cpp | 8 +- libs/redpanda_qt_utils/qt_utils/utils.cpp | 90 ++++++++++++++--------- 9 files changed, 110 insertions(+), 64 deletions(-) diff --git a/NEWS.md b/NEWS.md index 3c72a454..4751a081 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ Red Panda C++ Version 2.0 - redesign the project parser, more efficient and correct - enhancement: todo parser for project + - fix: save/load bookmark doesn't work Red Panda C++ Version 1.5 diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index e14fb10c..6b9d88a6 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -310,6 +310,12 @@ void Debugger::setIsForProject(bool newIsForProject) } } +void Debugger::clearForProject() +{ + mBreakpointModel->clear(true); + mWatchModel->clear(true); +} + void Debugger::addBreakpoint(int line, const Editor* editor) { addBreakpoint(line,editor->filename(), editor->inProject()); @@ -2197,6 +2203,16 @@ void WatchModel::clear() endResetModel(); } +void WatchModel::clear(bool forProject) +{ + if (mIsForProject == forProject) + beginResetModel(); + QList &vars=(forProject?mProjectWatchVars:mWatchVars); + vars.clear(); + if (mIsForProject == forProject) + endResetModel(); +} + const QList &WatchModel::watchVars() const { return watchVars(mIsForProject); diff --git a/RedPandaIDE/debugger.h b/RedPandaIDE/debugger.h index 3d9acf1a..cd709d9d 100644 --- a/RedPandaIDE/debugger.h +++ b/RedPandaIDE/debugger.h @@ -196,6 +196,7 @@ public: void removeWatchVar(const QString& expression); void removeWatchVar(const QModelIndex& index); void clear(); + void clear(bool forProject); PWatchVar findWatchVar(const QModelIndex& index); PWatchVar findWatchVar(const QString& expr); void resetAllVarInfos(); @@ -307,6 +308,7 @@ public: bool isForProject() const; void setIsForProject(bool newIsForProject); + void clearForProject(); //breakpoints void addBreakpoint(int line, const Editor* editor); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 051982c3..6243bb4e 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -4474,8 +4474,11 @@ void MainWindow::closeProject(bool refreshEditor) mClassBrowserModel.endUpdate(); if (!mQuitting) { + mBookmarkModel->clear(true); mBookmarkModel->setIsForProject(false); + mDebugger->clearForProject(); mDebugger->setIsForProject(false); + mTodoModel.clear(true); mTodoModel.setIsForProject(false); // Clear error browser clearIssues(); diff --git a/RedPandaIDE/todoparser.cpp b/RedPandaIDE/todoparser.cpp index ba7eea79..c616c03b 100644 --- a/RedPandaIDE/todoparser.cpp +++ b/RedPandaIDE/todoparser.cpp @@ -131,11 +131,10 @@ void TodoThread::doParseFile(const QString &filename, QSynedit::PHighlighter hig attr = highlighter->getTokenAttribute(); if (attr == commentAttr) { QString token = highlighter->getToken(); - qDebug()<=0) { emit todoFound( - mFilename, + filename, i+1, pos+highlighter->getTokenPos(), lines[i].trimmed() @@ -196,6 +195,16 @@ void TodoModel::clear() endResetModel(); } +void TodoModel::clear(bool forProject) +{ + if (mIsForProject == forProject) + beginResetModel(); + QList &items=getItems(forProject); + items.clear(); + if (mIsForProject == forProject) + endResetModel(); +} + PTodoItem TodoModel::getItem(const QModelIndex &index) { if (!index.isValid()) diff --git a/RedPandaIDE/todoparser.h b/RedPandaIDE/todoparser.h index 59576613..bf8980a7 100644 --- a/RedPandaIDE/todoparser.h +++ b/RedPandaIDE/todoparser.h @@ -41,6 +41,7 @@ public: int ch, const QString& line); void removeTodosForFile(const QString& filename); void clear(); + void clear(bool forProject); PTodoItem getItem(const QModelIndex& index); private: QList &getItems(bool forProject); diff --git a/RedPandaIDE/widgets/bookmarkmodel.cpp b/RedPandaIDE/widgets/bookmarkmodel.cpp index 927aa14e..313ec63b 100644 --- a/RedPandaIDE/widgets/bookmarkmodel.cpp +++ b/RedPandaIDE/widgets/bookmarkmodel.cpp @@ -194,37 +194,31 @@ void BookmarkModel::save(const QString &filename, const QString& projectFolder) { bool forProject = !projectFolder.isEmpty(); qint64 t,fileTimestamp; - QList bookmarks; + QHash compareHash; + QList &list=forProject?mProjectBookmarks:mBookmarks; if (forProject) { t=mLastLoadProjectBookmarksTimestamp; - foreach (const PBookmark& bookmark, mProjectBookmarks) { - PBookmark newBookmark=std::make_shared(); - 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; + } + for (int i=0;ifilename):bookmark->filename; + QString key = QString("%1-%2").arg(filename).arg(bookmark->line); + compareHash.insert(key,i); } QList fileBookmarks=load(filename, t,&fileTimestamp); QFile file(filename); if (file.open(QFile::WriteOnly | QFile::Truncate)) { - QHash compareHash; + QList saveBookmarks; - for (int i=0; ifilename).arg(bookmark->line); - compareHash.insert(key,i);; - } + QDir dir(projectFolder); foreach (const PBookmark& bookmark, fileBookmarks) { QString key = QString("%1-%2").arg(bookmark->filename).arg(bookmark->line); int idx = compareHash.value(key,-1); if (idx<0) { - int count=forProject?mProjectBookmarks.count():mBookmarks.count(); + int count=list.count(); compareHash.insert(key,count); if (forProject == mIsForProject) { beginInsertRows(QModelIndex(),count,count); @@ -232,12 +226,11 @@ void BookmarkModel::save(const QString &filename, const QString& projectFolder) if (forProject) { bookmark->filename = dir.absoluteFilePath(bookmark->filename); } - QList &list=forProject?mProjectBookmarks:mBookmarks; + list.append(bookmark); if (forProject == mIsForProject) endInsertRows(); } else { - const QList &list=forProject?mProjectBookmarks:mBookmarks; PBookmark pTemp = list[idx]; if (pTemp->timestamp<=bookmark->timestamp) { bookmark->description = pTemp->timestamp; @@ -258,10 +251,10 @@ void BookmarkModel::save(const QString &filename, const QString& projectFolder) QJsonObject rootObj; rootObj["timestamp"]=QString("%1").arg(saveTime); QJsonArray array; - const QList &list=forProject?mProjectBookmarks:mBookmarks; foreach (const PBookmark& bookmark, list) { QJsonObject obj; - obj["filename"]=bookmark->filename; + QString filename = forProject?extractRelativePath(projectFolder, bookmark->filename):bookmark->filename; + obj["filename"]=filename; obj["line"]=bookmark->line; obj["description"]=bookmark->description; obj["timestamp"]=QString("%1").arg(bookmark->timestamp); @@ -298,7 +291,7 @@ QList BookmarkModel::load(const QString& filename, qint64 criteriaTim .arg(error.offset) .arg(error.errorString())); } - QJsonObject rootObj; + QJsonObject rootObj=doc.object(); bool ok; qint64 timestamp = rootObj["timestamp"].toString().toLongLong(&ok); if (!ok || timestamp<=criteriaTimestamp) @@ -309,6 +302,7 @@ QList BookmarkModel::load(const QString& filename, qint64 criteriaTim QJsonValue value = array[i]; QJsonObject obj=value.toObject(); qint64 bookmarkTimestamp = obj["timestamp"].toString().toULongLong(&ok); + qDebug()<criteriaTimestamp) { PBookmark bookmark = std::make_shared(); bookmark->filename = obj["filename"].toString(); @@ -338,7 +332,9 @@ void BookmarkModel::loadProjectBookmarks(const QString &filename, const QString& mLastLoadProjectBookmarksTimestamp = QDateTime::currentMSecsSinceEpoch(); mProjectBookmarks = load(filename,0,&t); QDir folder(projectFolder); + qDebug()<<"load books"<filename; bookmark->filename=folder.absoluteFilePath(bookmark->filename); } if (mIsForProject) diff --git a/libs/qsynedit/qsynedit/TextBuffer.cpp b/libs/qsynedit/qsynedit/TextBuffer.cpp index a496faf3..7ae67cec 100644 --- a/libs/qsynedit/qsynedit/TextBuffer.cpp +++ b/libs/qsynedit/qsynedit/TextBuffer.cpp @@ -595,12 +595,12 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding, realEncoding = ENCODING_ASCII; return; } - realEncoding = pCharsetInfoManager->getDefaultSystemEncoding(); + realEncoding = pCharsetInfoManager->getDefaultSystemEncoding(); + if (tryLoadFileByEncoding(realEncoding,file)) { + return; + } QList charsets = pCharsetInfoManager->findCharsetByLocale(pCharsetInfoManager->localeName()); if (!charsets.isEmpty()) { - if (tryLoadFileByEncoding(realEncoding,file)) { - return; - } QSet encodingSet; for (int i=0;i #include #endif +#include "charsetinfo.h" BaseError::BaseError(const QString &reason): mReason(reason) @@ -301,51 +302,68 @@ void readFileToLines(const QString &fileName, QTextCodec *codec, LineProcessFunc } } +static QStringList tryLoadFileByEncoding(QByteArray encodingName, QFile& file, bool* isOk) { + QStringList result; + *isOk=false; + QTextCodec* codec = QTextCodec::codecForName(encodingName); + if (!codec) + return result; + file.reset(); + QTextCodec::ConverterState state; + while (true) { + if (file.atEnd()){ + break; + } + QByteArray line = file.readLine(); + if (line.endsWith("\r\n")) { + line.remove(line.length()-2,2); + } else if (line.endsWith("\r")) { + line.remove(line.length()-1,1); + } else if (line.endsWith("\n")){ + line.remove(line.length()-1,1); + } + QString newLine = codec->toUnicode(line.constData(),line.length(),&state); + if (state.invalidChars>0) { + return QStringList(); + } + result.append(newLine); + } + *isOk=true; + return result; +} + QStringList readFileToLines(const QString &fileName) { QFile file(fileName); if (file.size()<=0) return QStringList(); - QTextCodec* codec = QTextCodec::codecForLocale(); QStringList result; - QTextCodec::ConverterState state; - bool ok = true; if (file.open(QFile::ReadOnly)) { - while (!file.atEnd()) { - QByteArray array = file.readLine(); - QString s = codec->toUnicode(array,array.length(),&state); - if (state.invalidChars>0) { - ok=false; - break; - } - if (s.endsWith("\r\n")) { - s.remove(s.length()-2,2); - } else if (s.endsWith("\r")) { - s.remove(s.length()-1,1); - } else if (s.endsWith("\n")){ - s.remove(s.length()-1,1); - } - result.append(s); + bool ok; + result = tryLoadFileByEncoding("UTF-8",file,&ok); + if (ok) { + return result; } - if (!ok) { - file.seek(0); - result.clear(); - codec = QTextCodec::codecForName("UTF-8"); - while (!file.atEnd()) { - QByteArray array = file.readLine(); - QString s = codec->toUnicode(array,array.length(),&state); - if (state.invalidChars>0) { - result.clear(); - break; + + QByteArray realEncoding = pCharsetInfoManager->getDefaultSystemEncoding(); + result = tryLoadFileByEncoding(realEncoding,file,&ok); + if (ok) { + return result; + } + QList charsets = pCharsetInfoManager->findCharsetByLocale(pCharsetInfoManager->localeName()); + if (!charsets.isEmpty()) { + QSet encodingSet; + for (int i=0;iname); + } + encodingSet.remove(realEncoding); + foreach (const QByteArray& encodingName,encodingSet) { + if (encodingName == ENCODING_UTF8) + continue; + result = tryLoadFileByEncoding("UTF-8",file,&ok); + if (ok) { + return result; } - if (s.endsWith("\r\n")) { - s.remove(s.length()-2,2); - } else if (s.endsWith("\r")) { - s.remove(s.length()-1,1); - } else if (s.endsWith("\n")){ - s.remove(s.length()-1,1); - } - result.append(s); } } }