From 3509c25fc8964fbb964552caeeb57da6fef744c4 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Mon, 17 Oct 2022 23:23:05 +0800 Subject: [PATCH] - enhancement: delete a watch expression don't reload who watch var view - enhancement: auto save/restore debug panel's current tab - fix: correctly restore left(explorer) panel's current tab - enhancement: auto close non-modified new editor after file/project openned; - fix: project files openned by double click in bookmark/breakpoint panel may cause app crash when closed. - fix: When open a project that's already openned, shouldn't close it. - enhancement: When open a project, let user choose weither open it in new window or replace the already openned project --- NEWS.md | 6 + RedPandaIDE/RedPandaIDE.pro | 5 + RedPandaIDE/debugger.cpp | 28 +- RedPandaIDE/debugger.h | 3 +- RedPandaIDE/editorlist.cpp | 18 +- RedPandaIDE/editorlist.h | 3 - RedPandaIDE/main.cpp | 4 + RedPandaIDE/mainwindow.cpp | 212 +++-- RedPandaIDE/mainwindow.h | 7 +- RedPandaIDE/mainwindow.ui | 2 +- RedPandaIDE/settings.cpp | 120 +-- RedPandaIDE/settings.h | 28 +- RedPandaIDE/systemconsts.h | 3 +- RedPandaIDE/translations/RedPandaIDE_pt_BR.ts | 85 +- RedPandaIDE/translations/RedPandaIDE_zh_CN.ts | 893 ++++++++++-------- RedPandaIDE/translations/RedPandaIDE_zh_TW.ts | 107 +-- RedPandaIDE/visithistorymanager.cpp | 183 ++++ RedPandaIDE/visithistorymanager.h | 56 ++ RedPandaIDE/widgets/bookmarkmodel.cpp | 76 +- RedPandaIDE/widgets/bookmarkmodel.h | 1 - .../widgets/projectalreadyopendialog.cpp | 49 + .../widgets/projectalreadyopendialog.h | 43 + .../widgets/projectalreadyopendialog.ui | 96 ++ 23 files changed, 1260 insertions(+), 768 deletions(-) create mode 100644 RedPandaIDE/visithistorymanager.cpp create mode 100644 RedPandaIDE/visithistorymanager.h create mode 100644 RedPandaIDE/widgets/projectalreadyopendialog.cpp create mode 100644 RedPandaIDE/widgets/projectalreadyopendialog.h create mode 100644 RedPandaIDE/widgets/projectalreadyopendialog.ui diff --git a/NEWS.md b/NEWS.md index ebf05939..557597dd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -19,6 +19,12 @@ Red Panda C++ Version 1.5 - enhancement: project and non-project files use different breakpoint and watchvar view (auto switch when not debugging and editor switched) - enhancement: save project's breakpoint and watchvar in it's own debug file. - enhancement: delete a watch expression don't reload who watch var view + - enhancement: auto save/restore debug panel's current tab + - fix: correctly restore left(explorer) panel's current tab + - enhancement: auto close non-modified new editor after file/project openned; + - fix: project files openned by double click in bookmark/breakpoint panel may cause app crash when closed. + - fix: When open a project that's already openned, shouldn't close it. + - enhancement: When open a project, let user choose weither open it in new window or replace the already openned project Red Panda C++ Version 1.4 diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index b315ca0a..f4c336b5 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -136,6 +136,7 @@ SOURCES += \ vcs/gitresetdialog.cpp \ vcs/gituserconfigdialog.cpp \ vcs/gitutils.cpp \ + visithistorymanager.cpp \ widgets/aboutdialog.cpp \ widgets/bookmarkmodel.cpp \ widgets/choosethemedialog.cpp \ @@ -188,6 +189,7 @@ SOURCES += \ widgets/newtemplatedialog.cpp \ widgets/ojproblempropertywidget.cpp \ widgets/ojproblemsetmodel.cpp \ + widgets/projectalreadyopendialog.cpp \ widgets/qconsole.cpp \ widgets/qpatchedcombobox.cpp \ widgets/searchdialog.cpp \ @@ -266,6 +268,7 @@ HEADERS += \ vcs/gitresetdialog.h \ vcs/gituserconfigdialog.h \ vcs/gitutils.h \ + visithistorymanager.h \ widgets/aboutdialog.h \ widgets/bookmarkmodel.h \ widgets/choosethemedialog.h \ @@ -318,6 +321,7 @@ HEADERS += \ widgets/newtemplatedialog.h \ widgets/ojproblempropertywidget.h \ widgets/ojproblemsetmodel.h \ + widgets/projectalreadyopendialog.h \ widgets/qconsole.h \ widgets/qpatchedcombobox.h \ widgets/searchdialog.h \ @@ -383,6 +387,7 @@ FORMS += \ widgets/newprojectunitdialog.ui \ widgets/newtemplatedialog.ui \ widgets/ojproblempropertywidget.ui \ + widgets/projectalreadyopendialog.ui \ widgets/searchdialog.ui \ widgets/signalmessagedialog.ui diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index b45342e9..3f3f24bf 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -427,6 +427,7 @@ void Debugger::saveForProject(const QString &filename, const QString &projectFol void Debugger::loadForNonproject(const QString &filename) { bool forProject = false; + mLastLoadtime = 0; PDebugConfig pConfig = load(filename, forProject); if (pConfig->timestamp>0) { mBreakpointModel->setBreakpoints(pConfig->breakpoints,forProject); @@ -436,7 +437,8 @@ void Debugger::loadForNonproject(const QString &filename) void Debugger::loadForProject(const QString &filename, const QString &projectFolder) { - bool forProject = false; + bool forProject = true; + mProjectLastLoadtime = 0; PDebugConfig pConfig = load(filename, forProject); if (pConfig->timestamp>0) { QDir dir(projectFolder); @@ -463,8 +465,7 @@ void Debugger::addWatchVar(const QString &expression) var->hasMore = false; var->timestamp = QDateTime::currentMSecsSinceEpoch(); - mWatchModel->addWatchVar(var); - sendWatchCommand(var); + addWatchVar(var,isForProject()); } void Debugger::modifyWatchVarExpression(const QString &oldExpr, const QString &newExpr) @@ -692,7 +693,7 @@ void Debugger::save(const QString &filename, const QString& projectFolder) QString key = watchVar->expression; if (!watchVarCompareSet.contains(key)) { watchVarCompareSet.insert(key); - addWatchVar(key); + addWatchVar(watchVar,forProject); } } qint64 saveTimestamp = QDateTime::currentMSecsSinceEpoch();; @@ -761,6 +762,13 @@ PDebugConfig Debugger::load(const QString &filename, bool forProject) return pConfig; } +void Debugger::addWatchVar(const PWatchVar &watchVar, bool forProject) +{ + mWatchModel->addWatchVar(watchVar,forProject); + if (forProject == isForProject()) + sendWatchCommand(watchVar); +} + void Debugger::syncFinishedParsing() { bool spawnedcpuform = false; @@ -1927,7 +1935,7 @@ QList BreakpointModel::loadJson(const QJsonArray& jsonArray, qint64 if (ok && timestamp > criteriaTime) { PBreakpoint breakpoint = std::make_shared(); - breakpoint->filename = QFileInfo(obj["filename"].toString()).absoluteFilePath(); + breakpoint->filename = obj["filename"].toString(); breakpoint->line = obj["line"].toInt(); breakpoint->condition = obj["condition"].toString(); breakpoint->enabled = obj["enabled"].toBool(); @@ -2124,17 +2132,19 @@ int WatchModel::columnCount(const QModelIndex&) const return 3; } -void WatchModel::addWatchVar(PWatchVar watchVar) +void WatchModel::addWatchVar(PWatchVar watchVar, bool forProject) { - QList &vars=(mIsForProject?mProjectWatchVars:mWatchVars); + QList &vars=(forProject?mProjectWatchVars:mWatchVars); for (PWatchVar var:vars) { if (watchVar->expression == var->expression) { return; } } - beginInsertRows(QModelIndex(),vars.count(),vars.count()); + if (forProject==mIsForProject) + beginInsertRows(QModelIndex(),vars.count(),vars.count()); vars.append(watchVar); - endInsertRows(); + if (forProject==mIsForProject) + endInsertRows(); } void WatchModel::setWatchVars(const QList list, bool forProject) diff --git a/RedPandaIDE/debugger.h b/RedPandaIDE/debugger.h index 7be7344c..3d9acf1a 100644 --- a/RedPandaIDE/debugger.h +++ b/RedPandaIDE/debugger.h @@ -231,7 +231,7 @@ private: QJsonArray toJson(bool forProject); QList loadJson(const QJsonArray &jsonArray, qint64 criteriaTimestamp); const QList &watchVars() const; - void addWatchVar(PWatchVar watchVar); + void addWatchVar(PWatchVar watchVar, bool forProject); void setWatchVars(const QList list, bool forProject); private: @@ -371,6 +371,7 @@ private: void sendClearBreakpointCommand(PBreakpoint breakpoint); void save(const QString& filename, const QString& projectFolder); PDebugConfig load(const QString& filename, bool forProject); + void addWatchVar(const PWatchVar &watchVar, bool forProject); private slots: void syncFinishedParsing(); diff --git a/RedPandaIDE/editorlist.cpp b/RedPandaIDE/editorlist.cpp index e335c596..ad4d358e 100644 --- a/RedPandaIDE/editorlist.cpp +++ b/RedPandaIDE/editorlist.cpp @@ -23,6 +23,7 @@ #include "settings.h" #include "project.h" #include "systemconsts.h" +#include "visithistorymanager.h" #include EditorList::EditorList(QTabWidget* leftPageWidget, @@ -174,7 +175,7 @@ bool EditorList::closeEditor(Editor* editor, bool transferFocus, bool force) { PProjectUnit unit = pMainWindow->project()->findUnit(editor); pMainWindow->project()->closeUnit(unit); } else { - if (pSettings->history().addToOpenedFiles(editor->filename())) { + if (pMainWindow->visitHistoryManager()->addFile(editor->filename())) { pMainWindow->rebuildOpenedFileHisotryMenu(); } delete editor; @@ -358,20 +359,7 @@ Editor* EditorList::getOpenedEditorByFilename(QString filename) Editor *EditorList::getEditorByFilename(QString filename) { - if (filename.isEmpty()) - return nullptr; - //check if an editor is already openned - Editor* e=getOpenedEditorByFilename(filename); - if (e!=nullptr) - return e; - //Todo: check if is in the project - - //Create a new editor - QFileInfo fileInfo(filename); - QString fullname = fileInfo.absoluteFilePath(); - if (fileInfo.exists() && fileInfo.isFile()) - return newEditor(fullname,pSettings->editor().autoDetectFileEncoding()?ENCODING_AUTO_DETECT:pSettings->editor().defaultEncoding(),nullptr,false); - return nullptr; + return pMainWindow->openFile(filename,false); } bool EditorList::getContentFromOpenedEditor(const QString &filename, QStringList &buffer) diff --git a/RedPandaIDE/editorlist.h b/RedPandaIDE/editorlist.h index 336b1ffa..71bf4e3b 100644 --- a/RedPandaIDE/editorlist.h +++ b/RedPandaIDE/editorlist.h @@ -94,9 +94,6 @@ private: QSplitter *mSplitter; QWidget *mPanel; int mUpdateCount; - - - }; #endif // EDITORLIST_H diff --git a/RedPandaIDE/main.cpp b/RedPandaIDE/main.cpp index e2845931..2a1bb2cf 100644 --- a/RedPandaIDE/main.cpp +++ b/RedPandaIDE/main.cpp @@ -263,6 +263,10 @@ int main(int argc, char *argv[]) openInSingleInstance = envSetting.value("open_files_in_single_instance",false).toBool(); } else if (!settingFilename.isEmpty() && firstRun) openInSingleInstance = false; + if (app.arguments().contains("-ns")) { + openInSingleInstance = false; + } else if (app.arguments().contains("-s")) + openInSingleInstance = true; if (openInSingleInstance) { int openCount = 0; while (true) { diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index aa780e0c..48fb9123 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -48,6 +48,8 @@ #include "vcs/gituserconfigdialog.h" #include "widgets/infomessagebox.h" #include "widgets/newtemplatedialog.h" +#include "visithistorymanager.h" +#include "widgets/projectalreadyopendialog.h" #include #include @@ -149,6 +151,11 @@ MainWindow::MainWindow(QWidget *parent) mProjectProxyModel->setDynamicSortFilter(false); ui->EditorTabsRight->setVisible(false); + mVisitHistoryManager = std::make_shared( + includeTrailingPathDelimiter(pSettings->dirs().config()) + +DEV_HISTORY_FILE); + mVisitHistoryManager->load(); + //toolbar takes the owner mCompilerSet = new QComboBox(); mCompilerSet->setMinimumWidth(200); @@ -450,6 +457,14 @@ void MainWindow::updateEditorBookmarks() } } +void MainWindow::updateEditorBreakpoints() +{ + for (int i=0;ipageCount();i++) { + Editor * e=(*mEditorList)[i]; + e->resetBreakpoints(); + } +} + void MainWindow::updateEditorActions() { Editor* e = mEditorList->getEditor(); @@ -1046,14 +1061,15 @@ void MainWindow::rebuildOpenedFileHisotryMenu() { mMenuRecentFiles->clear(); mMenuRecentProjects->clear(); - if (pSettings->history().opennedFiles().size()==0) { + if (mVisitHistoryManager->files().count()==0) { mMenuRecentFiles->setEnabled(false); } else { mMenuRecentFiles->setEnabled(true); - for (const QString& filename: pSettings->history().opennedFiles()) { + foreach (const PVisitRecord& record, mVisitHistoryManager->files()) { + QString filename = record->filename; //menu takes the ownership QAction* action = new QAction(filename,mMenuRecentFiles); - connect(action, &QAction::triggered, [&filename,this](bool){ + connect(action, &QAction::triggered, [filename,this](bool){ openFile(filename); }); mMenuRecentFiles->addAction(action); @@ -1061,20 +1077,21 @@ void MainWindow::rebuildOpenedFileHisotryMenu() mMenuRecentFiles->addSeparator(); //menu takes the ownership QAction *action = new QAction(tr("Clear History"),mMenuRecentFiles); - connect(action, &QAction::triggered, [](bool){ - pSettings->history().clearOpennedFiles(); + connect(action, &QAction::triggered, [this](bool){ + mVisitHistoryManager->clearFiles(); }); mMenuRecentFiles->addAction(action); } - if (pSettings->history().opennedProjects().size()==0) { + if (mVisitHistoryManager->projects().count()==0) { mMenuRecentProjects->setEnabled(false); } else { mMenuRecentProjects->setEnabled(true); - for (const QString& filename: pSettings->history().opennedProjects()) { + foreach (const PVisitRecord& record, mVisitHistoryManager->projects()) { + QString filename = record->filename; //menu takes the ownership QAction* action = new QAction(filename,mMenuRecentProjects); - connect(action, &QAction::triggered, [&filename,this](bool){ + connect(action, &QAction::triggered, [filename,this](bool){ this->openProject(filename); }); mMenuRecentProjects->addAction(action); @@ -1082,8 +1099,8 @@ void MainWindow::rebuildOpenedFileHisotryMenu() mMenuRecentProjects->addSeparator(); //menu takes the ownership QAction *action = new QAction(tr("Clear History"),mMenuRecentProjects); - connect(action, &QAction::triggered, [](bool){ - pSettings->history().clearOpennedProjects(); + connect(action, &QAction::triggered, [this](bool){ + mVisitHistoryManager->clearProjects(); }); mMenuRecentProjects->addAction(action); } @@ -1216,17 +1233,24 @@ void MainWindow::openFiles(const QStringList &files) e->activate(); } -void MainWindow::openFile(const QString &filename, bool activate, QTabWidget* page) +Editor* MainWindow::openFile(const QString &filename, bool activate, QTabWidget* page) { Editor* editor = mEditorList->getOpenedEditorByFilename(filename); if (editor!=nullptr) { if (activate) { editor->activate(); } - return; + return editor; } try { - pSettings->history().removeFile(filename); + Editor* oldEditor=nullptr; + if (mEditorList->pageCount()==1) { + oldEditor = mEditorList->getEditor(0); + if (!oldEditor->isNew() || oldEditor->modified()) { + oldEditor = nullptr; + } + } + //mVisitHistoryManager->removeFile(filename); PProjectUnit unit; if (mProject) { unit = mProject->findUnit(filename); @@ -1243,10 +1267,14 @@ void MainWindow::openFile(const QString &filename, bool activate, QTabWidget* pa if (activate) { editor->activate(); } + if (mEditorList->pageCount()>1 && oldEditor) + mEditorList->closeEditor(oldEditor); // editor->activate(); + return editor; } catch (FileError e) { QMessageBox::critical(this,tr("Error"),e.reason()); } + return nullptr; } void MainWindow::openProject(const QString &filename, bool openFiles) @@ -1254,26 +1282,39 @@ void MainWindow::openProject(const QString &filename, bool openFiles) if (!fileExists(filename)) { return; } + Editor* oldEditor=nullptr; if (mProject) { - QString s; - if (mProject->name().isEmpty()) - s = mProject->filename(); - else - s = mProject->name(); - if (QMessageBox::question(this, - tr("Close project"), - tr("Are you sure you want to close %1?") - .arg(s), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::Yes) == QMessageBox::Yes) { + if (mProject->filename() == filename) + return; + ProjectAlreadyOpenDialog dlg; + if (dlg.exec()!=QDialog::Accepted) + return; + if (dlg.openType()==ProjectAlreadyOpenDialog::OpenType::ThisWindow) { closeProject(false); } else { + QProcess process; + process.setProgram(QApplication::instance()->applicationFilePath()); + process.setWorkingDirectory(QDir::currentPath()); + QStringList args; + args.append("-ns"); + args.append(filename); + process.setArguments(args); + process.startDetached(); return; } + + } else { + if (mEditorList->pageCount()==1) { + oldEditor = mEditorList->getEditor(0); + if (!oldEditor->isNew() || oldEditor->modified()) { + oldEditor = nullptr; + } + } } - ui->tabProject->setVisible(true); - ui->tabExplorer->setCurrentWidget(ui->tabProject); - stretchExplorerPanel(true); + //ui->tabProject->setVisible(true); + //stretchExplorerPanel(true); + if (openFiles) + ui->tabExplorer->setCurrentWidget(ui->tabProject); // { // LeftPageControl.ActivePage := LeftProjectSheet; // fLeftPageControlChanged := False; @@ -1287,7 +1328,7 @@ void MainWindow::openProject(const QString &filename, bool openFiles) ui->projectView->expand( mProjectProxyModel->mapFromSource( mProject->model()->rootIndex())); - pSettings->history().removeProject(filename); + //mVisitHistoryManager->removeProject(filename); // // if project manager isn't open then open it // if not devData.ShowLeftPages then @@ -1329,7 +1370,8 @@ void MainWindow::openProject(const QString &filename, bool openFiles) updateCompilerSet(); updateClassBrowserForEditor(e); mClassBrowserModel.endUpdate(); - + if (oldEditor) + mEditorList->closeEditor(oldEditor); //updateForEncodingInfo(); } @@ -2250,34 +2292,38 @@ void MainWindow::onBookmarkContextMenu(const QPoint &pos) void MainWindow::saveLastOpens() { QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_LASTOPENS_FILE; - if (fileExists(filename)) { - if (!QFile::remove(filename)) { - QMessageBox::critical(this, - tr("Save last open info error"), - tr("Can't remove old last open information file '%1'") - .arg(filename), - QMessageBox::Ok); - return; - } + QFile file(filename); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) { + QMessageBox::critical(this, + tr("Save last open info error"), + tr("Can't open last open information file '%1' for write!") + .arg(filename), + QMessageBox::Ok); + return; } - SimpleIni lastOpenIni; - lastOpenIni.SetLongValue("LastOpens","Count", mEditorList->pageCount()); + QJsonObject rootObj; if (mProject) { - lastOpenIni.SetValue("LastOpens","Project",mProject->filename().toLocal8Bit()); + rootObj["lastProject"]=mProject->filename(); } + QJsonArray filesArray; for (int i=0;ipageCount();i++) { Editor * editor = (*mEditorList)[i]; - QByteArray sectionName = QString("Editor_%1").arg(i).toLocal8Bit(); - lastOpenIni.SetValue(sectionName,"FileName", editor->filename().toLocal8Bit()); - lastOpenIni.SetBoolValue(sectionName, "OnLeft",editor->pageControl() != mEditorList->rightPageWidget()); - lastOpenIni.SetBoolValue(sectionName, "Focused",editor->hasFocus()); - lastOpenIni.SetLongValue(sectionName, "CursorCol", editor->caretX()); - lastOpenIni.SetLongValue(sectionName, "CursorRow", editor->caretY()); - lastOpenIni.SetLongValue(sectionName, "TopLine", editor->topLine()); - lastOpenIni.SetLongValue(sectionName, "LeftChar", editor->leftChar()); + QJsonObject fileObj; + fileObj["filename"] = editor->filename(); + fileObj["onLeft"] = (editor->pageControl() != mEditorList->rightPageWidget()); + fileObj["focused"] = editor->hasFocus(); + fileObj["caretX"] = editor->caretX(); + fileObj["caretY"] = editor->caretY(); + fileObj["topLine"] = editor->topLine(); + fileObj["leftChar"] = editor->leftChar(); + filesArray.append(fileObj); } - if (lastOpenIni.SaveFile(filename.toLocal8Bit())!=SI_Error::SI_OK) { + rootObj["files"]=filesArray; + QJsonDocument doc; + doc.setObject(rootObj); + QByteArray json = doc.toJson(); + if (file.write(doc.toJson())!=json.count()) { QMessageBox::critical(this, tr("Save last open info error"), tr("Can't save last open info file '%1'") @@ -2285,6 +2331,7 @@ void MainWindow::saveLastOpens() QMessageBox::Ok); return; } + file.close(); } void MainWindow::loadLastOpens() @@ -2292,8 +2339,8 @@ void MainWindow::loadLastOpens() QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_LASTOPENS_FILE; if (!fileExists(filename)) return; - SimpleIni lastOpenIni; - if (lastOpenIni.LoadFile(filename.toLocal8Bit())!=SI_Error::SI_OK) { + QFile file(filename); + if (!file.open(QFile::ReadOnly)) { QMessageBox::critical(this, tr("Load last open info error"), tr("Can't load last open info file '%1'") @@ -2301,19 +2348,31 @@ void MainWindow::loadLastOpens() QMessageBox::Ok); return; } - QString projectFilename = QString::fromLocal8Bit((lastOpenIni.GetValue("LastOpens", "Project",""))); - int count = lastOpenIni.GetLongValue("LastOpens","Count",0); - if (fileExists(projectFilename)) { + QJsonParseError error; + QJsonDocument doc=QJsonDocument::fromJson(file.readAll(),&error); + if (error.error != QJsonParseError::NoError) { + QMessageBox::critical(this, + tr("Load last open info error"), + tr("Can't load last open info file '%1'") + .arg(filename)+" :
" + +QString("%1").arg(error.errorString()), + QMessageBox::Ok); + return; + + } + QJsonObject rootObj = doc.object(); + QString projectFilename = rootObj["lastProject"].toString(); + if (!projectFilename.isEmpty()) { openProject(projectFilename, false); } + QJsonArray filesArray = rootObj["files"].toArray(); Editor * focusedEditor = nullptr; - for (int i=0;ileftPageWidget(); @@ -2338,24 +2397,26 @@ void MainWindow::loadLastOpens() if (!editor) continue; QSynedit::BufferCoord pos; - pos.ch = lastOpenIni.GetLongValue(sectionName,"CursorCol", 1); - pos.line = lastOpenIni.GetLongValue(sectionName,"CursorRow", 1); + pos.ch = fileObj["caretX"].toInt(1); + pos.line = fileObj["caretY"].toInt(1); editor->setCaretXY(pos); editor->setTopLine( - lastOpenIni.GetLongValue(sectionName,"TopLine", 1) + fileObj["topLine"].toInt(1) ); editor->setLeftChar( - lastOpenIni.GetLongValue(sectionName,"LeftChar", 1) + fileObj["leftChar"].toInt(1) ); - if (lastOpenIni.GetBoolValue(sectionName,"Focused",false)) + if (fileObj["focused"].toBool(false)) focusedEditor = editor; - pSettings->history().removeFile(editorFilename); + //mVisitHistoryManager->removeFile(editorFilename); } if (mProject && mEditorList->pageCount()==0) { mProject->doAutoOpen(); updateEditorBookmarks(); + updateEditorBreakpoints(); } - if (count>0) { + + if (mEditorList->pageCount()>0) { updateEditorActions(); //updateForEncodingInfo(); } @@ -4376,7 +4437,7 @@ void MainWindow::closeProject(bool refreshEditor) mClassBrowserModel.beginUpdate(); // Remember it - pSettings->history().addToOpenedProjects(mProject->filename()); + mVisitHistoryManager->addProject(mProject->filename()); mEditorList->beginUpdate(); mProject.reset(); @@ -4421,7 +4482,7 @@ void MainWindow::updateProjectView() //ui->projectView->expandAll(); stretchExplorerPanel(true); ui->tabProject->setVisible(true); - ui->tabExplorer->setCurrentWidget(ui->tabProject); + //ui->tabExplorer->setCurrentWidget(ui->tabProject); } else { // Clear project browser mProjectProxyModel->setSourceModel(nullptr); @@ -4576,6 +4637,7 @@ void MainWindow::closeEvent(QCloseEvent *event) { settings.setMainWindowGeometry(saveGeometry()); settings.setBottomPanelIndex(ui->tabMessages->currentIndex()); settings.setLeftPanelIndex(ui->tabExplorer->currentIndex()); + settings.setDebugPanelIndex(ui->debugViews->currentIndex()); settings.setShowStatusBar(ui->actionStatus_Bar->isChecked()); settings.setShowToolWindowBars(ui->actionTool_Window_Bars->isChecked()); @@ -4670,13 +4732,14 @@ void MainWindow::showEvent(QShowEvent *) const Settings::UI& settings = pSettings->ui(); ui->tabMessages->setCurrentIndex(settings.bottomPanelIndex()); ui->tabExplorer->setCurrentIndex(settings.leftPanelIndex()); + ui->debugViews->setCurrentIndex(settings.debugPanelIndex()); } void MainWindow::hideEvent(QHideEvent *) { - Settings::UI& settings = pSettings->ui(); - settings.setBottomPanelIndex(ui->tabMessages->currentIndex()); - settings.setLeftPanelIndex(ui->tabExplorer->currentIndex()); +// Settings::UI& settings = pSettings->ui(); +// settings.setBottomPanelIndex(ui->tabMessages->currentIndex()); +// settings.setLeftPanelIndex(ui->tabExplorer->currentIndex()); } bool MainWindow::event(QEvent *event) @@ -8288,6 +8351,11 @@ void MainWindow::on_actionNew_Template_triggered() } } +const std::shared_ptr &MainWindow::visitHistoryManager() const +{ + return mVisitHistoryManager; +} + bool MainWindow::isQuitting() const { return mQuitting; diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 0a2094bb..2fa18780 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -70,6 +70,7 @@ class Project; class ProjectModelNode; class ProjectUnit; class ColorSchemeItem; +class VisitHistoryManager; #define DPI_CHANGED_EVENT ((QEvent::Type)(QEvent::User+1)) @@ -112,6 +113,7 @@ public: void updateStatusbarMessage(const QString& s); void updateEditorSettings(); void updateEditorBookmarks(); + void updateEditorBreakpoints(); void updateEditorActions(); void updateProjectActions(); void updateCompileActions(); @@ -194,7 +196,7 @@ public: const PBookmarkModel &bookmarkModel() const; - void openFile(const QString& filename, bool activate=true, QTabWidget* page=nullptr); + Editor* openFile(const QString& filename, bool activate=true, QTabWidget* page=nullptr); void openProject(const QString& filename, bool openFiles = true); void changeOptions(const QString& widgetName=QString(), const QString& groupName=QString()); @@ -737,6 +739,8 @@ private: std::shared_ptr mHeaderCompletionPopup; std::shared_ptr mFunctionTip; + std::shared_ptr mVisitHistoryManager; + TodoModel mTodoModel; SearchResultModel mSearchResultModel; PBookmarkModel mBookmarkModel; @@ -855,6 +859,7 @@ public: bool event(QEvent *event) override; bool isClosingAll() const; bool isQuitting() const; + const std::shared_ptr &visitHistoryManager() const; }; extern MainWindow* pMainWindow; diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index 3401325d..702a410a 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -895,7 +895,7 @@ QTabWidget::South - 5 + 2 diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 818bdfb3..0d0b33a5 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -45,7 +45,6 @@ Settings::Settings(const QString &filename): mDebugger(this), mCodeCompletion(this), mCodeFormatter(this), - mHistory(this), mUI(this), mVCS(this) { @@ -106,7 +105,6 @@ void Settings::load() mEditor.load(); mExecutor.load(); mDebugger.load(); - mHistory.load(); mCodeCompletion.load(); mCodeFormatter.load(); mUI.load(); @@ -164,11 +162,6 @@ Settings::VCS &Settings::vcs() return mVCS; } -Settings::History& Settings::history() -{ - return mHistory; -} - Settings::Debugger& Settings::debugger() { return mDebugger; @@ -3671,106 +3664,6 @@ void Settings::Debugger::doLoad() mMemoryViewColumns = intValue("memory_view_columns",8); } -Settings::History::History(Settings *settings):_Base(settings, SETTING_HISTORY) -{ - -} - -const QStringList &Settings::History::opennedFiles() const -{ - return mOpenedFiles; -} - -const QStringList &Settings::History::opennedProjects() const -{ - return mOpenedProjects; -} - -void Settings::History::clearOpennedFiles() -{ - mOpenedFiles.clear(); -} - -void Settings::History::clearOpennedProjects() -{ - mOpenedProjects.clear(); -} - -bool Settings::History::addToOpenedFiles(const QString &filename) -{ - if (!QFile(filename).exists()) - return false; - int index = mOpenedFiles.indexOf(filename); - if (index>=0) { - mOpenedFiles.removeAt(index); - } - if (mOpenedFiles.size()>=15) { - mOpenedFiles.pop_back(); - } - mOpenedFiles.push_front(filename); - save(); - return true; - -} - -void Settings::History::removeFile(const QString &filename) -{ - int index = mOpenedFiles.indexOf(filename); - if (index>=0) { - mOpenedFiles.removeAt(index); - } - save(); - return; -} - -bool Settings::History::addToOpenedProjects(const QString &filename) -{ - if (!QFile(filename).exists()) - return false; - int index = mOpenedProjects.indexOf(filename); - if (index>=0) { - mOpenedProjects.removeAt(index); - } - if (mOpenedProjects.size()>=15) { - mOpenedProjects.pop_back(); - } - mOpenedProjects.push_front(filename); - save(); - return true; -} - -void Settings::History::removeProject(const QString &filename) -{ - int index = mOpenedProjects.indexOf(filename); - if (index>=0) { - mOpenedProjects.removeAt(index); - } - save(); - return; -} - -void Settings::History::doSave() -{ - saveValue("opened_files", mOpenedFiles); - saveValue("opened_projects", mOpenedProjects); -} - -static QStringList filterValidPathes(const QStringList& files) { - QStringList lst; - foreach (const QString& filePath, files) { - if (fileExists(filePath)) { - lst.append(QFileInfo(filePath).absoluteFilePath()); - } - } - return lst; -} - -void Settings::History::doLoad() -{ - mOpenedFiles = filterValidPathes(stringListValue("opened_files")); - mOpenedProjects = filterValidPathes(stringListValue("opened_projects")); -} - Settings::CodeCompletion::CodeCompletion(Settings *settings):_Base(settings, SETTING_CODE_COMPLETION) { @@ -4990,6 +4883,16 @@ void Settings::UI::setMessagesTabsSize(const QSize &newMessagesTabsSize) mMessagesTabsSize = newMessagesTabsSize; } +int Settings::UI::debugPanelIndex() const +{ + return mDebugPanelIndex; +} + +void Settings::UI::setDebugPanelIndex(int newDebugPanelIndex) +{ + mDebugPanelIndex = newDebugPanelIndex; +} + const QSize &Settings::UI::explorerTabsSize() const { return mExplorerTabsSize; @@ -5256,6 +5159,7 @@ void Settings::UI::doSave() saveValue("main_window_geometry",mMainWindowGeometry); saveValue("bottom_panel_index",mBottomPanelIndex); saveValue("left_panel_index",mLeftPanelIndex); + saveValue("debug_panel_index",mDebugPanelIndex); saveValue("class_browser_sort_alphabetically",mClassBrowserSortAlpha); saveValue("class_browser_sort_by_type",mClassBrowserSortType); saveValue("class_browser_show_inherited",mClassBrowserShowInherited); @@ -5305,6 +5209,8 @@ void Settings::UI::doLoad() mMainWindowGeometry = value("main_window_geometry",QByteArray()).toByteArray(); mBottomPanelIndex = intValue("bottom_panel_index",0); mLeftPanelIndex = intValue("left_panel_index",0); + mDebugPanelIndex = intValue("debug_panel_index",0); + mClassBrowserSortAlpha = boolValue("class_browser_sort_alphabetically",true); mClassBrowserSortType = boolValue("class_browser_sort_by_type",true); mClassBrowserShowInherited = boolValue("class_browser_show_inherited",true); diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index e71749dd..7f3388e8 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -817,28 +817,6 @@ public: void doLoad() override; }; - class History: public _Base { - public: - explicit History(Settings *settings); - - const QStringList& opennedFiles() const; - const QStringList& opennedProjects() const; - void clearOpennedFiles(); - void clearOpennedProjects(); - bool addToOpenedFiles(const QString& filename); - void removeFile(const QString& filename); - bool addToOpenedProjects(const QString& filename); - void removeProject(const QString& filename); - private: - QStringList mOpenedFiles; - QStringList mOpenedProjects; - - // _Base interface - protected: - void doSave() override; - void doLoad() override; - }; - class Executor: public _Base { public: explicit Executor(Settings * settings); @@ -1044,11 +1022,15 @@ public: const QSize &messagesTabsSize() const; void setMessagesTabsSize(const QSize &newMessagesTabsSize); + int debugPanelIndex() const; + void setDebugPanelIndex(int newDebugPanelIndex); + private: QByteArray mMainWindowState; QByteArray mMainWindowGeometry; int mBottomPanelIndex; int mLeftPanelIndex; + int mDebugPanelIndex; bool mClassBrowserSortAlpha; bool mClassBrowserSortType; bool mClassBrowserShowInherited; @@ -1412,7 +1394,6 @@ public: Environment& environment(); Executor& executor(); Debugger& debugger(); - History& history(); CodeCompletion &codeCompletion(); CodeFormatter &codeFormatter(); UI &ui(); @@ -1430,7 +1411,6 @@ private: Debugger mDebugger; CodeCompletion mCodeCompletion; CodeFormatter mCodeFormatter; - History mHistory; UI mUI; VCS mVCS; }; diff --git a/RedPandaIDE/systemconsts.h b/RedPandaIDE/systemconsts.h index 1f7e997b..66696a13 100644 --- a/RedPandaIDE/systemconsts.h +++ b/RedPandaIDE/systemconsts.h @@ -82,7 +82,7 @@ #define TEMPLATE_EXT "template" #define TEMPLATE_INFO_FILE "info.template" #define DEV_INTERNAL_OPEN "$__DEV_INTERNAL_OPEN" -#define DEV_LASTOPENS_FILE "lastopens.ini" +#define DEV_LASTOPENS_FILE "lastopens.json" #define DEV_SYMBOLUSAGE_FILE "symbolusage.json" #define DEV_CODESNIPPET_FILE "codesnippets.json" #define DEV_NEWFILETEMPLATES_FILE "newfiletemplate.txt" @@ -91,6 +91,7 @@ #define DEV_TOOLS_FILE "tools.json" #define DEV_BOOKMARK_FILE "bookmarks.json" #define DEV_DEBUGGER_FILE "debugger.json" +#define DEV_HISTORY_FILE "history.json" #ifdef Q_OS_WIN # define PATH_SENSITIVITY Qt::CaseInsensitive diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts index a13b039b..f94567d9 100644 --- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts +++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts @@ -156,19 +156,19 @@ Save file '%1' failed. - Falha ao salvar arquivo '%1'. + Falha ao salvar arquivo '%1'. Can't open file '%1' for write. - Impossível gravar arquivo '%1'. + Impossível gravar arquivo '%1'. Error in json file '%1':%2 : %3 - Erro no arquivo json '%1':%2 : %3 + Erro no arquivo json '%1':%2 : %3 Can't open file '%1' for read. - Impossível ler o arquivo '%1'. + Impossível ler o arquivo '%1'. @@ -703,10 +703,6 @@ Stop after the compilation proper stage - - Stop after the assembling stage - - Link and generate the executable @@ -715,10 +711,6 @@ Preprocessing output suffix - - Assembling output suffix - - Compiling output suffix @@ -810,11 +802,11 @@ Autosave breakpoints - Salvar breakpoints automaticamente + Salvar breakpoints automaticamente Autosave watches - Salvar automaticamente as observações + Salvar automaticamente as observações Show CPU Window when signal received @@ -852,6 +844,10 @@ Memory View Columns Colunas da memória + + Autosave breakpoints and watches + + Debugger @@ -915,6 +911,22 @@ Signal "%1" Received: Recebido sinal "%1": + + Save file '%1' failed. + + + + Can't open file '%1' for write. + + + + Error in json file '%1':%2 : %3 + Erro no arquivo json '%1':%2 : %3 + + + Can't open file '%1' for read. + + Editor @@ -3898,11 +3910,11 @@ Close project - Fechar projeto + Fechar projeto Are you sure you want to close %1? - Quer mesmo fechar %1? + Quer mesmo fechar %1? Confirm @@ -3998,7 +4010,7 @@ Can't remove old last open information file '%1' - Impossível remover o arquivo aberto com a última informação '%1' + Impossível remover o arquivo aberto com a última informação '%1' Can't save last open info file '%1' @@ -4660,6 +4672,10 @@ Please correct this before start debugging + + Can't open last open information file '%1' for write! + + NewClassDialog @@ -5004,6 +5020,33 @@ + + ProjectAlreadyOpenDialog + + Dialog + Diálogo + + + <html><head/><body><p>Projects can either be opened in a new window or replace the project in the existing window or be attached to the already opened projects. How would you like to open the project?</p></body></html> + + + + &This Window + + + + New &Window + + + + Cancel + + + + Open Project + + + ProjectCompileParamatersWidget @@ -6716,19 +6759,19 @@ Save file '%1' failed. - Falha ao gravar o arquivo '%1'. + Falha ao gravar o arquivo '%1'. Can't open file '%1' for write. - Impossível gravar no arquivo '%1'. + Impossível gravar no arquivo '%1'. Error in json file '%1':%2 : %3 - Erro no arquivo json '%1':%2 : %3 + Erro no arquivo json '%1':%2 : %3 Can't open file '%1' for read. - Impossível ler o arquivo '%1' + Impossível ler o arquivo '%1' Expression diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index ae81cc71..a2de02a4 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -188,17 +188,17 @@ p, li { white-space: pre-wrap; } BacktraceModel - + Function 函数 - + Filename 文件名 - + Line @@ -206,37 +206,37 @@ p, li { white-space: pre-wrap; } BookmarkModel - + Save file '%1' failed. 保存文件'%1'失败。 - + Can't open file '%1' for write. 无法写入文件'%1'. - + Error in json file '%1':%2 : %3 JSON文件'%1':%2中存在错误:%3 - + Can't open file '%1' for read. 无法读取文件'%1'. - + Description 描述 - + Line - + Filename 文件名 @@ -244,39 +244,35 @@ p, li { white-space: pre-wrap; } BreakpointModel - + Filename 文件名 - + Line - + Condition 条件 - Save file '%1' failed. - 保存文件'%1'失败。 + 保存文件'%1'失败。 - Can't open file '%1' for write. - 无法写入文件'%1'. + 无法写入文件'%1'. - Error in json file '%1':%2 : %3 - JSON文件'%1':%2中存在错误:%3 + JSON文件'%1':%2中存在错误:%3 - Can't open file '%1' for read. - 无法读取文件'%1'. + 无法读取文件'%1'. @@ -850,47 +846,45 @@ p, li { white-space: pre-wrap; } 输出 - + Compilation Stages 编译阶段 - + Stop after the preprocessing stage 在完成预处理后停止编译 - + Stop after the compilation proper stage 在完成编译仪式(compilation proper)后停止。 - Stop after the assembling stage - 在完成汇编后停止。 + 在完成汇编后停止。 - + Link and generate the executable 链接得到可执行文件。 - + Preprocessing output suffix 预处理输出后缀 - Assembling output suffix - 编译输出后缀 + 编译输出后缀 - + Compiling output suffix 编译仪式(Compilation proper)输出后缀 - + Executable suffix 可执行文件后缀 @@ -968,12 +962,12 @@ p, li { white-space: pre-wrap; } 选择性能分析器 - + Confirm 确认 - + Red Panda C++ will clear current compiler list and search for compilers in the following locations:<br /> '%1'<br /> '%2'<br />Are you really want to continue? Red Panda C++ will clear current compiler list and search for compilers in the following locations: '%1' @@ -982,50 +976,50 @@ Are you really want to continue? 小熊猫C++ 将会清除现有的编译器配置列表,然后在下列文件夹中搜索编译器:<br/> '%1'<br/> '%2'<br />你确定要继续吗? - + ANSI ANSI - + UTF-8 UTF-8 - + Red Panda C++ will clear current compiler list and search for compilers in the the PATH. <br />Are you really want to continue? 小熊猫C++ 将会清除现有的编译器配置列表,然后在PATH路径中搜索gcc编译器.<br />你确定要继续吗? - - + + Failed 失败 - - + + Can't find any compiler. 找不到编译器 - - + + Compiler Set Name 编译器配置名称 - + Name 名称 - + Compiler Set Folder 编译器所在文件夹 - + New name 新名称 @@ -1142,7 +1136,12 @@ Are you really want to continue? 内存视图列数 - + + Autosave breakpoints and watches + 自动保存断点和监视表达式 + + + Show CPU Window when signal received 程序收到信号停止时缺省打开CPU窗口 @@ -1156,41 +1155,39 @@ Are you really want to continue? 自动保存 - Autosave breakpoints - 自动保存断点 + 自动保存断点 - Autosave watches - 自动保存监视 + 自动保存监视 Disassembly Coding Style 反汇编代码样式 - + CPU Window CPU信息窗口 - + Disassembly Coding Style: 反汇编代码样式 - + Intel Intel - + AT&&T AT&&T - + Show disassembly code in blend mode 以混合模式显示反汇编代码 @@ -1198,17 +1195,17 @@ Are you really want to continue? Debugger - + No compiler set 无编译器设置 - + No compiler set is configured. 没有配置编译器设置。 - + Can't start debugging. 无法启动调试器 @@ -1221,66 +1218,86 @@ Are you really want to continue? 调试器路径"%1"中包含非ASCII字符(如,中文字符) - + This prevents it from executing. 这会导致调试器无法启动。 - + Debugger not exists 找不到调试器 - + Can''t find debugger in : "%1" 找不到调试器程序"%1" - + GDB Server path error gdb server路径错误 - + GDB Server's path "%1" contains non-ascii characters. gdb server的路径"%1"包含中文或者全角字符 - + GDB Server not exists 找不到gdb server - + Can''t find gdb server in : "%1" 无法在"%1"找到gdb server - + Execute to evaluate 执行以求值 + + + Save file '%1' failed. + 保存文件'%1'失败。 + + + + Can't open file '%1' for write. + 无法写入文件'%1'. + + + + Error in json file '%1':%2 : %3 + JSON文件'%1':%2中存在错误:%3 + + + + Can't open file '%1' for read. + 无法读取文件'%1'. + Not found in current context 不在当前语境中 - + Compile 编译 - + Source file is more recent than executable. 源文件比程序文件新。 - + Recompile? 重新编译? - + Signal "%1" Received: 收到信号"%1": @@ -3877,18 +3894,18 @@ Are you really want to continue? MainWindow - + Red Panda C++ 小熊猫C++ - - - - - + + + + + Issues 编译器 @@ -3962,7 +3979,7 @@ Are you really want to continue? - + Debug Console 调试主控台 @@ -4038,7 +4055,7 @@ Are you really want to continue? 工具栏2 - + New 新建 @@ -4096,8 +4113,8 @@ Are you really want to continue? - - + + Compile 编译 @@ -4175,9 +4192,9 @@ Are you really want to continue? - - - + + + Copy 复制 @@ -4188,7 +4205,7 @@ Are you really want to continue? - + Paste 粘贴 @@ -4199,8 +4216,8 @@ Are you really want to continue? - - + + Select All 选择全部 @@ -4326,7 +4343,7 @@ Are you really want to continue? - + New Problem Set 新建试题集 @@ -4345,14 +4362,14 @@ Are you really want to continue? - + Save Problem Set 保存试题集 - + Load Problem Set 载入试题集 @@ -4413,7 +4430,7 @@ Are you really want to continue? - + Run All Cases Run Current Case 运行所有案例 @@ -4706,7 +4723,7 @@ Are you really want to continue? - + Clear all breakpoints 删除所有断点 @@ -4871,7 +4888,7 @@ Are you really want to continue? 保存为模板... - + New File 新建文件 @@ -4912,7 +4929,7 @@ Are you really want to continue? - + Rename Symbol 重命名符号 @@ -4933,13 +4950,13 @@ Are you really want to continue? - + Export As RTF 导出为RTF - + Export As HTML 导出为HTML @@ -5208,42 +5225,42 @@ Are you really want to continue? 运行参数... - + File Encoding 文件编码 - + Recent Files 文件历史 - - - - - - + + + + + + Debugging 正在调试 - - - - - - + + + + + + Running 正在运行 - - - - - - + + + + + + Compiling 正在编译 @@ -5252,219 +5269,224 @@ Are you really want to continue? 行:%1 列:%2 已选择:%3 总行数:%4 总长度:%5 - + Line:%1 Col:%2 Selected:%3 Lines:%4 Length:%5 Line: %1 Col: %2 Selected: %3 Lines: %4 Length: %5 行: %1 列: %2 已选择 :%3 总行数: %4 总长度: %5 - + Read Only 只读 - + Insert 插入 - + Overwrite 覆写 - Close project - 关闭项目 + 关闭项目 - Are you sure you want to close %1? - 你确定要关闭'%1'吗? + 你确定要关闭'%1'吗? - - + + Confirm 确认 - - - + + + Source file is not compiled. 源文件尚未编译。 - - + + Compile now? 现在编译? - - + + Source file is more recent than executable. 源文件比可执行程序新。 - + Recompile now? 重新编译? - - + + + + Wrong Compiler Settings 错误的编译器设置 - - + + + + Compiler is set not to generate executable. 编译器被设置为不生成可执行文件。 - + + We need the executabe to run problem case. 我们需要可执行文件来运行试题案例。 - + No compiler set 无编译器设置 - + No compiler set is configured. 没有配置编译器设置。 - + Can't start debugging. 无法启动调试器 - - + + Enable debugging 启用调试参数 - - + + You have not enabled debugging info (-g3) and/or stripped it from the executable (-s) in Compiler Options.<BR /><BR />Do you want to correct this now? 当前编译设置中未启用调试选项(-g3),或启用了信息剥除选项(-s)<br /><br/>是否纠正这一问题? - + Project not built 项目尚未构建 - + Project hasn't been built. Build it now? 项目尚未构建。是否构建? - + Host applcation missing 宿主程序不存在 - + DLL project needs a host application to run. 动态链接库(DLL)需要一个宿主程序来运行。 - + But it's missing. 但它不存在。 - + Host application not exists 宿主程序不存在 - + Host application file '%1' doesn't exist. 宿主程序'%1'不存在。 - + + Please correct this before start debugging 请在调试前改正设置。 - + Recompile? 重新编译? - - + + Save last open info error 保存上次打开信息失败 - Can't remove old last open information file '%1' - 无法删除旧上次打开信息文件'%1' + 无法删除旧上次打开信息文件'%1' - + Can't save last open info file '%1' 无法保存上次打开信息文件'%1' - + + Load last open info error 载入上次打开信息失败 - + + Can't load last open info file '%1' 无法载入上次打开信息文件'%1' - + Open Source File 打开源代码文件 - - + + Batch Set Cases 批量设置案例 - + Show detail debug logs 显示详细调试器日志 - + Copy all 全部复制 - + Go to Line 跳转到行 - + Line - + Template Exists 模板已存在 - + Template %1 already exists. Do you want to overwrite? 模板%1已存在。是否覆盖? @@ -5472,25 +5494,25 @@ Are you really want to continue? - - - + + + Clear 清除 - + Export 导出 - + Insert Snippet 插入代码段 - - + + Problem Set %1 试题集%1 @@ -5511,68 +5533,68 @@ Are you really want to continue? 或者选择使用其他的网络端口。 - - + + Rebuild Project 重新构建项目 - - + + Project has been modified, do you want to rebuild it? 项目已经被修改过,是否需要重新构建? - + Auto Save Error 自动保存出错 - + Auto save "%1" to "%2" failed:%3 自动保存"%1"到"%2"失败:%3 - + Properties... 试题属性... - + Set Problem Set Name 设置试题集名称 - + Problem Set Name: 试题集名称: - + Remove 删除 - + Remove All Bookmarks 删除全部书签 - + Modify Description 修改描述 - - - + + + Bookmark Description 书签描述 - - - + + + Description: 描述: @@ -5581,179 +5603,184 @@ Are you really want to continue? 在调试主控台中显示调试器输出 - + Remove this search 清除这次搜索 - + Clear all searches 删除所有搜索 - + Breakpoint condition... 断点条件... - + Break point condition 断点条件 - + Enter the condition of the breakpoint: 输入当前断点的生效条件: - + Remove All Breakpoints Remove all breakpoints 删除所有断点 - + Remove Breakpoint 删除当前断点 - + Rename File 重命名文件 - - + + Add Folder 添加文件夹 - - + + New folder 新文件夹 - + Folder name: 文件夹: - + Rename Folder 重命名 - + + Can't open last open information file '%1' for write! + 无法写入配置文件'%1'。 + + + Run Current Case 运行当前案例 - + Remove Folder 删除文件夹 - + Switch to normal view 切换为普通视图 - + Switch to custom view 切换为自定义视图 - + Sort By Type 按类型排序 - + Sort alphabetically 按名称排序 - + Show inherited members 显示继承的成员 - + Goto declaration 跳转到声明处 - + Goto definition 跳转到定义处 - - + + New Folder 新建文件夹 - + Rename 重命名 - - - - + + + + Delete 删除 - + Open in Editor 在编辑器中打开 - + Open in External Program 使用外部程序打开 - + Open in Terminal 在终端中打开 - + Open in Windows Explorer 在Windows浏览器中打开 - + Character sets 字符集 - + Convert to %1 转换为%1编码 - + %1 files autosaved 已自动保存%1个文件 - + Set answer to... 设置答案源代码... - + select other file... 选择其他文件... - + Select Answer Source File 选择答案源代码文件 @@ -5763,7 +5790,7 @@ Are you really want to continue? C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + New Folder %1 新建文件夹%1 @@ -5776,68 +5803,67 @@ Are you really want to continue? 无标题%1 - + Do you really want to delete %1? 你真的要删除%1吗? - + Do you really want to delete %1 files? 你真的要删除%1个文件吗? - + Save project 保存项目 - + The project '%1' has modifications. 项目'%1'有改动。 - - + + Do you want to save it? 需要保存吗? - - + + File Changed 文件已发生变化 - + New Project File? 新建项目文件? - + Do you want to add the new file to the project? 您是否要将新建的文件加入项目? - - - - + + + Save Error 保存失败 - + Change Project Compiler Set 改变项目编译器配置集 - + Change the project's compiler set will lose all custom compiler set options. 改变项目的编译器配置集会导致所有的自定义编译器选项被重置。 - - + + Do you really want to do that? 你真的想要那么做吗? @@ -5846,119 +5872,119 @@ Are you really want to continue? 批量设置案例 - + Choose input files 选择输入数据文件 - + Input data files (*.in) 输入数据文件 (*.in) - + untitled%1 无标题%1 - + Modify Watch 修改监视表达式 - + Watch Expression 监视表达式 - + Do you really want to clear all breakpoints in this file? 您真的要清除该文件的所有断点吗? - + New project 新建项目 - + Close %1 and start new project? 关闭'%1'以打开新项目? - + Folder not exist 文件夹不存在 - + Folder '%1' doesn't exist. Create it now? 文件夹'%1'不存在。是否创建? - + Can't create folder 无法创建文件夹 - + Failed to create folder '%1'. 创建文件夹'%1'失败。 - + Save new project as - + Folder %1 is not empty. 文件夹%1不是空的。 - + Do you really want to delete it? 你真的要删除它吗? - + Change working folder 改变工作文件夹 - + File '%1' is not in the current working folder. File '%1' is not in the current working folder 文件'%1'不在当前工作文件夹中。 - + Do you want to change working folder to '%1'? 是否将工作文件夹改设为'%1'? - + Can't Commit 无法提交 - + Git needs user info to commit. Git需要用信息进行提交。 - + Choose Input Data File 选择输入数据文件 - - + + All files (*.*) 所有文件 (*.*) - + Choose Expected Output Data File Choose Expected Input Data File 选择期望输出文件 @@ -5970,59 +5996,59 @@ Are you really want to continue? - + Choose Working Folder 选择工作文件夹 - - + + Header Exists 头文件已存在 - - + + Header file "%1" already exists! 头文件"%1"已存在! - + Source Exists 源文件已存在! - + Source file "%1" already exists! 源文件"%1"已存在! - + Can't commit! 无法提交! - + The following files are in conflicting: 下列文件处于冲突状态,请解决后重新添加和提交: - + Commit Message 提交信息 - + Commit Message: 提交信息: - + Commit Failed 提交失败 - + Commit message shouldn't be empty! 提交信息不能为空! @@ -6031,256 +6057,255 @@ Are you really want to continue? 小熊猫Dev-C++项目文件 (*.dev) - + New project fail 新建项目失败 - + Can't assign project template 无法使用模板创建项目 - + Remove file 删除文件 - + Remove the file from disk? 同时从硬盘上删除文件? - - - + + + untitled 无标题 - + New Project File Name 新的项目文件名 - + File Name: 文件名: - + File Already Exists! 文件已存在! - + File '%1' already exists! 文件'%1'已经存在! - + Add to project 添加到项目 - + C/C++ Source Files (*.c *.cpp *.cc *.cxx) C/C++源代码文件 (*.c *.cpp *.cc *.cxx) - + This operation will remove all cases for the current problem. 本操作会删除此试题的所有案例。 - + Red Panda C++ project file (*.dev) 小熊猫C++项目文件(*.dev) - + Rename Error 重命名出错 - + Symbol '%1' is defined in system header. 符号'%1'在系统头文件中定义,无法修改。 - + New Name 新名称 - - + + Replace Error 替换出错 - + Can't open file '%1' for replace! 无法打开文件'%1'进行替换! - + Contents has changed since last search! 内容和上次查找时不一致。 - + Rich Text Format Files (*.rtf) RTF格式文件 (*.rtf) - + HTML Files (*.html) HTML文件 (*.html) - + The current problem set is not empty. 当前的试题集不是空的。 - + Problem %1 试题%1 - - + + Problem Set Files (*.pbs) 试题集文件 (*.pbs) - + Load Error 载入失败 - - + + Problem Case %1 试题案例%1 - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + Error 错误 - + Recent Projects 项目历史 - + Load Theme Error 载入主题失败 - - + + Clear History 清除历史 - - + + Version Control 版本控制 - + File '%1' was changed. 磁盘文件'%1'已被修改。 - + Reload its content from disk? 是否重新读取它的内容? - + File '%1' was removed. 磁盘文件'%1'已被删除。 - + Keep it open? 是否保持它在小熊猫C++中打开的编辑窗口? - + Open 打开 - + Compile Failed 编译失败 - + Run Failed 运行失败 - - - - + + + + Confirm Convertion 确认转换 - - - - + + + + The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue? 当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗? - + New Watch Expression 新监视表达式 - + Enter Watch Expression (it is recommended to use 'this->' for class members): 输入监视表达式 - + Parsing file %1 of %2: "%3" (%1/%2)正在解析文件"%3" - - + + Done parsing %1 files in %2 seconds 完成%1个文件的解析,用时%2秒 - + (%1 files per second) (每秒%1个文件) @@ -6738,6 +6763,38 @@ Are you really want to continue? 使用小熊猫C++编辑器开发 + + ProjectAlreadyOpenDialog + + Dialog + 对话框 + + + + Open Project + 打开项目 + + + + <html><head/><body><p>Projects can either be opened in a new window or replace the project in the existing window or be attached to the already opened projects. How would you like to open the project?</p></body></html> + <html><head/><body><p>可以在新窗口中打开项目,或者替换当前窗口中已打开的项目。 您希望如何打开项目?</p></body></html> + + + + &This Window + 本窗口(&T) + + + + New &Window + 新窗口(&W) + + + + Cancel + 取消 + + ProjectCompileParamatersWidget @@ -7426,7 +7483,7 @@ Are you really want to continue? QApplication - + Error 错误 @@ -7434,12 +7491,12 @@ Are you really want to continue? QObject - + Save 保存 - + Save changes to %1? 将修改保存到"%1"? @@ -7496,65 +7553,65 @@ Are you really want to continue? 无法写入配置文件夹"%1" - + Can't load autolink settings 无法载入自动链接设置 - - - - + + + + The following %1 directories don't exist: 下列%1文件夹不存在: - - + + binary 二进制 - + No %1 directories have been specified. 未指定%1文件夹 - + C include C包含 - - + + C++ include C++包含 - - - - + + + + Cannot find the %1 "%2" 无法找到%1程序"%2" - + C Compiler C编译器 - + C++ Compiler C++编译器 - + Maker 构建程序(Make) - + Debugger 调试器 @@ -7623,7 +7680,7 @@ Are you really want to continue? 生成调试信息(-g3) - + Would you like Red Panda C++ to search for compilers in PATH? 您同意小熊猫C++在PATH路径中寻找gcc编译器吗? @@ -7727,23 +7784,23 @@ Are you really want to continue? 只生成汇编代码(-S) - - + + Confirm 确认 - + The following problems were found during validation of compiler set "%1": 在验证编译器设置"%1"时遇到了下列问题: - + Leaving those directories will lead to problems during compilation. 在配置中保留这些文件夹可能会导致编译出错。 - + Would you like Red Panda C++ to remove them for you and add the default paths to the valid paths? 是否让小熊猫C++删除这些配置,并尝试重新建立配置? @@ -7752,13 +7809,13 @@ Are you really want to continue? 如果仍然保留这些设置,可能会导致编译错误。<br /><br />请选择“是”,除非您清楚的知道选择“否”的后果, - - + + Compiler set not configuared. 未配置编译器设置。 - + Would you like Red Panda C++ to search for compilers in the following locations: <BR />'%1'<BR />'%2'? 您需要小熊猫C++在下列位置搜索编译器吗:<br />%1<br />%2 @@ -8142,12 +8199,12 @@ Are you really want to continue? RegisterModel - + Register 寄存器 - + Value @@ -8575,14 +8632,14 @@ Are you really want to continue? 性能 - + Compiler Set 编译器配置集 - + Compiler @@ -8594,7 +8651,7 @@ Are you really want to continue? 自动链接 - + @@ -8670,15 +8727,15 @@ Are you really want to continue? 杂项 - - + + Program Runner 程序运行 - + Problem Set 试题集 @@ -9156,49 +9213,45 @@ Are you really want to continue? WatchModel - Save file '%1' failed. - 保存文件'%1'失败。 + 保存文件'%1'失败。 - Can't open file '%1' for write. - 无法写入文件'%1'. + 无法写入文件'%1'. - Error in json file '%1':%2 : %3 - JSON文件'%1':%2中存在错误:%3 + JSON文件'%1':%2中存在错误:%3 - - + + Execute to evaluate 执行以求值 - - + + Not Valid 在当前作用域中无效 - Can't open file '%1' for read. - 无法读取文件'%1'. + 无法读取文件'%1'. - + Expression 表达式 - + Type 类型 - + Value diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts index e6066c0a..aeea4d47 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts @@ -150,22 +150,6 @@ Condition - - Save file '%1' failed. - - - - Can't open file '%1' for write. - - - - Error in json file '%1':%2 : %3 - - - - Can't open file '%1' for read. - - CPUDialog @@ -628,10 +612,6 @@ Stop after the compilation proper stage - - Stop after the assembling stage - - Link and generate the executable @@ -640,10 +620,6 @@ Preprocessing output suffix - - Assembling output suffix - - Compiling output suffix @@ -733,14 +709,6 @@ Autosave - - Autosave breakpoints - - - - Autosave watches - - Show CPU Window when signal received @@ -777,6 +745,10 @@ Memory View Columns + + Autosave breakpoints and watches + + Debugger @@ -840,6 +812,22 @@ Signal "%1" Received: + + Save file '%1' failed. + + + + Can't open file '%1' for write. + + + + Error in json file '%1':%2 : %3 + + + + Can't open file '%1' for read. + + Editor @@ -3797,14 +3785,6 @@ Overwrite - - Close project - - - - Are you sure you want to close %1? - - Confirm @@ -3897,10 +3877,6 @@ Save last open info error - - Can't remove old last open information file '%1' - - Can't save last open info file '%1' @@ -4549,6 +4525,10 @@ Please correct this before start debugging + + Can't open last open information file '%1' for write! + + NewClassDialog @@ -4889,6 +4869,29 @@ + + ProjectAlreadyOpenDialog + + <html><head/><body><p>Projects can either be opened in a new window or replace the project in the existing window or be attached to the already opened projects. How would you like to open the project?</p></body></html> + + + + &This Window + + + + New &Window + + + + Cancel + + + + Open Project + + + ProjectCompileParamatersWidget @@ -6529,22 +6532,6 @@ Execute to evaluate - - Save file '%1' failed. - - - - Can't open file '%1' for write. - - - - Error in json file '%1':%2 : %3 - - - - Can't open file '%1' for read. - - Expression diff --git a/RedPandaIDE/visithistorymanager.cpp b/RedPandaIDE/visithistorymanager.cpp new file mode 100644 index 00000000..d8d3ce22 --- /dev/null +++ b/RedPandaIDE/visithistorymanager.cpp @@ -0,0 +1,183 @@ +#include "visithistorymanager.h" + +#include +#include +#include +#include +#include + +VisitHistoryManager::VisitHistoryManager(const QString& filename): + mLastLoadtime(0), + mSaveFilename(filename), + mMaxFileCount(15), + mMaxProjectCount(15) +{ + +} + +const QList &VisitHistoryManager::files() const +{ + return mFiles; +} + +const QList &VisitHistoryManager::projects() const +{ + return mProjects; +} + +void VisitHistoryManager::clearFiles() +{ + mFiles.clear(); +} + +void VisitHistoryManager::clearProjects() +{ + mProjects.clear(); +} + +static int indexOf(const QList &list, const QString& filename) { + for (int i=0;ifilename == filename) + return i; + } + return -1; +} + +bool VisitHistoryManager::addFile(const QString &filename) +{ + return doAdd(mFiles,filename,mMaxFileCount); +} + +void VisitHistoryManager::removeFile(const QString &filename) +{ + doRemove(mFiles,filename); +} + +bool VisitHistoryManager::addProject(const QString &filename) +{ + return doAdd(mProjects,filename,mMaxProjectCount); +} + +void VisitHistoryManager::removeProject(const QString &filename) +{ + return doRemove(mProjects,filename); +} + +void VisitHistoryManager::save() +{ + PVisitHistory pHistory = doLoad(mSaveFilename,mLastLoadtime); + mergeRead(mFiles,pHistory->files); + mergeRead(mProjects,pHistory->projects); + QJsonObject rootObj; + rootObj["files"] = toJson(mFiles); + rootObj["projects"] = toJson(mProjects); + rootObj["timestamp"] = QString("%1").arg(QDateTime::currentMSecsSinceEpoch()); + QFile file(mSaveFilename); + if (file.open(QFile::WriteOnly | QFile::Truncate)) { + QJsonDocument doc; + doc.setObject(rootObj); + file.write(doc.toJson()); + } +} + +void VisitHistoryManager::load() +{ + PVisitHistory pHistory = doLoad(mSaveFilename,0); + mFiles = pHistory->files; + mProjects = pHistory->projects; +} + +PVisitHistory VisitHistoryManager::doLoad(const QString &filename, qint64 criteriaTime) +{ + PVisitHistory pHistory=std::make_shared(); + pHistory->timestamp=0; + QFile file(filename); + if (!file.open(QFile::ReadOnly)) + return pHistory; + QJsonParseError error; + QJsonDocument doc=QJsonDocument::fromJson(file.readAll(),&error); + if (error.error!=QJsonParseError::NoError) + return pHistory; + bool ok; + QJsonObject rootObj = doc.object(); + pHistory->timestamp = rootObj["timestamp"].toString().toLongLong(&ok); + if (!ok || pHistory->timestamp < criteriaTime) + return pHistory; + pHistory->files = fromJson(rootObj["files"].toArray(),criteriaTime); + pHistory->projects = fromJson(rootObj["projects"].toArray(),criteriaTime); + mLastLoadtime = QDateTime::currentMSecsSinceEpoch(); + return pHistory; +} + +QList VisitHistoryManager::fromJson(const QJsonArray &array, qint64 criteriaTime) +{ + QList records; + for (int i=0;icriteriaTime) { + PVisitRecord record = std::make_shared(); + record->timestamp = timestamp; + record->filename = recordObj["filename"].toString(); + records.append(record); + } + } + return records; +} + +void VisitHistoryManager::mergeRead(QList &target, const QList &readed) +{ + QSet mergeCache; + foreach (const PVisitRecord& r, target) { + mergeCache.insert(r->filename); + } + for (int i=readed.count()-1;i>=0;i--) { + const PVisitRecord& r=readed[i]; + if (!mergeCache.contains(r->filename)) { + mergeCache.insert(r->filename); + target.push_front(r); + } + } +} + +QJsonArray VisitHistoryManager::toJson(const QList &list) +{ + QJsonArray array; + foreach(const PVisitRecord &record, list) { + QJsonObject recordObj; + recordObj["filename"]=record->filename; + recordObj["timestamp"]=QString("%1").arg(record->timestamp); + array.append(recordObj); + } + return array; +} + +bool VisitHistoryManager::doAdd(QList &list, const QString &filename, int maxCount) +{ + if (!QFile(filename).exists()) + return false; + int index = indexOf(list,filename); + if (index>=0) { + list.removeAt(index); + } + if (list.size()>=maxCount) { + list.pop_back(); + } + PVisitRecord record = std::make_shared(); + record->filename = filename; + record->timestamp = QDateTime::currentMSecsSinceEpoch(); + list.push_front(record); + save(); + return true; +} + +void VisitHistoryManager::doRemove(QList &list, const QString &filename) +{ + int index = indexOf(mFiles,filename); + if (index>=0) { + list.removeAt(index); + } + save(); +} + diff --git a/RedPandaIDE/visithistorymanager.h b/RedPandaIDE/visithistorymanager.h new file mode 100644 index 00000000..49d26acb --- /dev/null +++ b/RedPandaIDE/visithistorymanager.h @@ -0,0 +1,56 @@ +#ifndef VISITHISTORYMANAGER_H +#define VISITHISTORYMANAGER_H + +#include +#include +#include +#include + +struct VisitRecord { + QString filename; + qint64 timestamp; +}; + +using PVisitRecord = std::shared_ptr; + +struct VisitHistory{ + qint64 timestamp; + QList files; + QList projects; +}; + +using PVisitHistory = std::shared_ptr; + +class VisitHistoryManager +{ +public: + VisitHistoryManager(const QString& filename); + + const QList &files() const; + const QList &projects() const; + void clearFiles(); + void clearProjects(); + bool addFile(const QString& filename); + void removeFile(const QString& filename); + bool addProject(const QString& filename); + void removeProject(const QString& filename); + void save(); + void load(); +private: + PVisitHistory doLoad(const QString& filename, qint64 criteriaTime); + QList fromJson(const QJsonArray &array, qint64 criteriaTime); + void mergeRead(QList& target, const QList& readed); + QJsonArray toJson(const QList& list); + bool doAdd(QList &list, const QString& filename, int maxCount); + void doRemove(QList &list, const QString& filename); +private: + QList mFiles; + QList mProjects; + + qint64 mLastLoadtime; + QString mSaveFilename; + int mMaxFileCount; + int mMaxProjectCount; +}; + +#endif // VISITHISTORYMANAGER_H diff --git a/RedPandaIDE/widgets/bookmarkmodel.cpp b/RedPandaIDE/widgets/bookmarkmodel.cpp index 9ef03fc9..3f4086f8 100644 --- a/RedPandaIDE/widgets/bookmarkmodel.cpp +++ b/RedPandaIDE/widgets/bookmarkmodel.cpp @@ -210,44 +210,55 @@ void BookmarkModel::save(const QString &filename, const QString& projectFolder) } QList fileBookmarks=load(filename, t,&fileTimestamp); QFile file(filename); - int saveOrderCount=0; if (file.open(QFile::WriteOnly | QFile::Truncate)) { - QHash compareHash; + QHash compareHash; QList saveBookmarks; - foreach (const PBookmark& bookmark, bookmarks) { + for (int i=0; ifilename).arg(bookmark->line); - bookmark->saveOrder=saveOrderCount++; - compareHash.insert(key,bookmark); + compareHash.insert(key,i);; } + QDir dir(projectFolder); 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); + int idx = compareHash.value(key,-1); + if (idx<0) { + int count=forProject?mProjectBookmarks.count():mBookmarks.count(); + compareHash.insert(key,count); + if (forProject == mIsForProject) { + beginInsertRows(QModelIndex(),count,count); + } + 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; + bookmark->timestamp = pTemp->timestamp; + if (forProject == mIsForProject) + emit dataChanged(createIndex(idx,2),createIndex(idx,2)); + } } } - QList saveList; - foreach (const PBookmark& bookmark, compareHash) { - saveList.append(bookmark); - } - std::sort(saveList.begin(),saveList.end(), [](PBookmark b1,PBookmark b2) { - return b1->saveOrder - b2->saveOrder; - }); + qint64 saveTime = QDateTime::currentMSecsSinceEpoch();; if (forProject) { - mProjectBookmarks=saveList; - mLastLoadProjectBookmarksTimestamp = QDateTime::currentMSecsSinceEpoch(); + mLastLoadProjectBookmarksTimestamp = saveTime; } else { - mBookmarks=saveList; - mLastLoadBookmarksTimestamp = QDateTime::currentMSecsSinceEpoch(); + mLastLoadBookmarksTimestamp = saveTime; } + QJsonObject rootObj; + rootObj["timestamp"]=QString("%1").arg(saveTime); QJsonArray array; - foreach (const PBookmark& bookmark, saveList) { + const QList &list=forProject?mProjectBookmarks:mBookmarks; + foreach (const PBookmark& bookmark, list) { QJsonObject obj; obj["filename"]=bookmark->filename; obj["line"]=bookmark->line; @@ -255,8 +266,9 @@ void BookmarkModel::save(const QString &filename, const QString& projectFolder) obj["timestamp"]=QString("%1").arg(bookmark->timestamp); array.append(obj); } + rootObj["bookmarks"]=array; QJsonDocument doc; - doc.setArray(array); + doc.setObject(rootObj); if (file.write(doc.toJson())<0) { throw FileError(tr("Save file '%1' failed.") .arg(filename)); @@ -272,10 +284,6 @@ QList BookmarkModel::load(const QString& filename, qint64 criteriaTim //clear(forProject); QList 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 bookmarks; @@ -289,13 +297,17 @@ QList BookmarkModel::load(const QString& filename, qint64 criteriaTim .arg(error.offset) .arg(error.errorString())); } - QJsonArray array = doc.array(); - qint64 bookmarkTimestamp; + QJsonObject rootObj; bool ok; + qint64 timestamp = rootObj["timestamp"].toString().toLongLong(&ok); + if (!ok || timestamp<=criteriaTimestamp) + return bookmarks; + *pFileTimestamp=timestamp; + QJsonArray array = rootObj["bookmarks"].toArray(); for (int i=0;icriteriaTimestamp) { PBookmark bookmark = std::make_shared(); bookmark->filename = obj["filename"].toString(); diff --git a/RedPandaIDE/widgets/bookmarkmodel.h b/RedPandaIDE/widgets/bookmarkmodel.h index e0228c38..405e15c6 100644 --- a/RedPandaIDE/widgets/bookmarkmodel.h +++ b/RedPandaIDE/widgets/bookmarkmodel.h @@ -26,7 +26,6 @@ struct Bookmark { int line; QString description; qint64 timestamp; - int saveOrder; }; using PBookmark=std::shared_ptr; diff --git a/RedPandaIDE/widgets/projectalreadyopendialog.cpp b/RedPandaIDE/widgets/projectalreadyopendialog.cpp new file mode 100644 index 00000000..e0d4631c --- /dev/null +++ b/RedPandaIDE/widgets/projectalreadyopendialog.cpp @@ -0,0 +1,49 @@ +#include "projectalreadyopendialog.h" +#include "ui_projectalreadyopendialog.h" + +ProjectAlreadyOpenDialog::ProjectAlreadyOpenDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ProjectAlreadyOpenDialog) +{ + ui->setupUi(this); +} + +ProjectAlreadyOpenDialog::~ProjectAlreadyOpenDialog() +{ + delete ui; +} + +void ProjectAlreadyOpenDialog::on_btnCancel_clicked() +{ + reject(); +} + +ProjectAlreadyOpenDialog::OpenType ProjectAlreadyOpenDialog::openType() const +{ + return mOpenType; +} + +void ProjectAlreadyOpenDialog::setOpenType(OpenType newOpenType) +{ + mOpenType = newOpenType; +} + +void ProjectAlreadyOpenDialog::closeEvent(QCloseEvent */*event*/) +{ + reject(); +} + + +void ProjectAlreadyOpenDialog::on_btnThisWindow_clicked() +{ + mOpenType = OpenType::ThisWindow; + accept(); +} + + +void ProjectAlreadyOpenDialog::on_btnNewWindow_clicked() +{ + mOpenType = OpenType::NewWindow; + accept(); +} + diff --git a/RedPandaIDE/widgets/projectalreadyopendialog.h b/RedPandaIDE/widgets/projectalreadyopendialog.h new file mode 100644 index 00000000..6fc0d2b4 --- /dev/null +++ b/RedPandaIDE/widgets/projectalreadyopendialog.h @@ -0,0 +1,43 @@ +#ifndef PROJECTALREADOPENDIALOG_H +#define PROJECTALREADOPENDIALOG_H + +#include + +namespace Ui { +class ProjectAlreadyOpenDialog; +} + + + +class ProjectAlreadyOpenDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ProjectAlreadyOpenDialog(QWidget *parent = nullptr); + ~ProjectAlreadyOpenDialog(); + enum class OpenType { + ThisWindow, + NewWindow + }; + + OpenType openType() const; + void setOpenType(OpenType newOpenType); + +private slots: + void on_btnCancel_clicked(); + + void on_btnThisWindow_clicked(); + + void on_btnNewWindow_clicked(); + +private: + Ui::ProjectAlreadyOpenDialog *ui; + OpenType mOpenType; + + // QWidget interface +protected: + void closeEvent(QCloseEvent *event) override; +}; + +#endif // PROJECTALREADOPENDIALOG_H diff --git a/RedPandaIDE/widgets/projectalreadyopendialog.ui b/RedPandaIDE/widgets/projectalreadyopendialog.ui new file mode 100644 index 00000000..be4e3f73 --- /dev/null +++ b/RedPandaIDE/widgets/projectalreadyopendialog.ui @@ -0,0 +1,96 @@ + + + ProjectAlreadyOpenDialog + + + + 0 + 0 + 652 + 254 + + + + Open Project + + + + + + <html><head/><body><p>Projects can either be opened in a new window or replace the project in the existing window or be attached to the already opened projects. How would you like to open the project?</p></body></html> + + + true + + + 30 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &This Window + + + false + + + + + + + New &Window + + + true + + + + + + + Cancel + + + false + + + + + + + + + + +