- 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
This commit is contained in:
Roy Qu 2022-10-17 23:23:05 +08:00
parent 984d10eaf1
commit 3509c25fc8
23 changed files with 1260 additions and 768 deletions

View File

@ -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: 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: 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: 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 Red Panda C++ Version 1.4

View File

@ -136,6 +136,7 @@ SOURCES += \
vcs/gitresetdialog.cpp \ vcs/gitresetdialog.cpp \
vcs/gituserconfigdialog.cpp \ vcs/gituserconfigdialog.cpp \
vcs/gitutils.cpp \ vcs/gitutils.cpp \
visithistorymanager.cpp \
widgets/aboutdialog.cpp \ widgets/aboutdialog.cpp \
widgets/bookmarkmodel.cpp \ widgets/bookmarkmodel.cpp \
widgets/choosethemedialog.cpp \ widgets/choosethemedialog.cpp \
@ -188,6 +189,7 @@ SOURCES += \
widgets/newtemplatedialog.cpp \ widgets/newtemplatedialog.cpp \
widgets/ojproblempropertywidget.cpp \ widgets/ojproblempropertywidget.cpp \
widgets/ojproblemsetmodel.cpp \ widgets/ojproblemsetmodel.cpp \
widgets/projectalreadyopendialog.cpp \
widgets/qconsole.cpp \ widgets/qconsole.cpp \
widgets/qpatchedcombobox.cpp \ widgets/qpatchedcombobox.cpp \
widgets/searchdialog.cpp \ widgets/searchdialog.cpp \
@ -266,6 +268,7 @@ HEADERS += \
vcs/gitresetdialog.h \ vcs/gitresetdialog.h \
vcs/gituserconfigdialog.h \ vcs/gituserconfigdialog.h \
vcs/gitutils.h \ vcs/gitutils.h \
visithistorymanager.h \
widgets/aboutdialog.h \ widgets/aboutdialog.h \
widgets/bookmarkmodel.h \ widgets/bookmarkmodel.h \
widgets/choosethemedialog.h \ widgets/choosethemedialog.h \
@ -318,6 +321,7 @@ HEADERS += \
widgets/newtemplatedialog.h \ widgets/newtemplatedialog.h \
widgets/ojproblempropertywidget.h \ widgets/ojproblempropertywidget.h \
widgets/ojproblemsetmodel.h \ widgets/ojproblemsetmodel.h \
widgets/projectalreadyopendialog.h \
widgets/qconsole.h \ widgets/qconsole.h \
widgets/qpatchedcombobox.h \ widgets/qpatchedcombobox.h \
widgets/searchdialog.h \ widgets/searchdialog.h \
@ -383,6 +387,7 @@ FORMS += \
widgets/newprojectunitdialog.ui \ widgets/newprojectunitdialog.ui \
widgets/newtemplatedialog.ui \ widgets/newtemplatedialog.ui \
widgets/ojproblempropertywidget.ui \ widgets/ojproblempropertywidget.ui \
widgets/projectalreadyopendialog.ui \
widgets/searchdialog.ui \ widgets/searchdialog.ui \
widgets/signalmessagedialog.ui widgets/signalmessagedialog.ui

View File

@ -427,6 +427,7 @@ void Debugger::saveForProject(const QString &filename, const QString &projectFol
void Debugger::loadForNonproject(const QString &filename) void Debugger::loadForNonproject(const QString &filename)
{ {
bool forProject = false; bool forProject = false;
mLastLoadtime = 0;
PDebugConfig pConfig = load(filename, forProject); PDebugConfig pConfig = load(filename, forProject);
if (pConfig->timestamp>0) { if (pConfig->timestamp>0) {
mBreakpointModel->setBreakpoints(pConfig->breakpoints,forProject); mBreakpointModel->setBreakpoints(pConfig->breakpoints,forProject);
@ -436,7 +437,8 @@ void Debugger::loadForNonproject(const QString &filename)
void Debugger::loadForProject(const QString &filename, const QString &projectFolder) void Debugger::loadForProject(const QString &filename, const QString &projectFolder)
{ {
bool forProject = false; bool forProject = true;
mProjectLastLoadtime = 0;
PDebugConfig pConfig = load(filename, forProject); PDebugConfig pConfig = load(filename, forProject);
if (pConfig->timestamp>0) { if (pConfig->timestamp>0) {
QDir dir(projectFolder); QDir dir(projectFolder);
@ -463,8 +465,7 @@ void Debugger::addWatchVar(const QString &expression)
var->hasMore = false; var->hasMore = false;
var->timestamp = QDateTime::currentMSecsSinceEpoch(); var->timestamp = QDateTime::currentMSecsSinceEpoch();
mWatchModel->addWatchVar(var); addWatchVar(var,isForProject());
sendWatchCommand(var);
} }
void Debugger::modifyWatchVarExpression(const QString &oldExpr, const QString &newExpr) 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; QString key = watchVar->expression;
if (!watchVarCompareSet.contains(key)) { if (!watchVarCompareSet.contains(key)) {
watchVarCompareSet.insert(key); watchVarCompareSet.insert(key);
addWatchVar(key); addWatchVar(watchVar,forProject);
} }
} }
qint64 saveTimestamp = QDateTime::currentMSecsSinceEpoch();; qint64 saveTimestamp = QDateTime::currentMSecsSinceEpoch();;
@ -761,6 +762,13 @@ PDebugConfig Debugger::load(const QString &filename, bool forProject)
return pConfig; return pConfig;
} }
void Debugger::addWatchVar(const PWatchVar &watchVar, bool forProject)
{
mWatchModel->addWatchVar(watchVar,forProject);
if (forProject == isForProject())
sendWatchCommand(watchVar);
}
void Debugger::syncFinishedParsing() void Debugger::syncFinishedParsing()
{ {
bool spawnedcpuform = false; bool spawnedcpuform = false;
@ -1927,7 +1935,7 @@ QList<PBreakpoint> BreakpointModel::loadJson(const QJsonArray& jsonArray, qint64
if (ok && timestamp > criteriaTime) { if (ok && timestamp > criteriaTime) {
PBreakpoint breakpoint = std::make_shared<Breakpoint>(); PBreakpoint breakpoint = std::make_shared<Breakpoint>();
breakpoint->filename = QFileInfo(obj["filename"].toString()).absoluteFilePath(); breakpoint->filename = obj["filename"].toString();
breakpoint->line = obj["line"].toInt(); breakpoint->line = obj["line"].toInt();
breakpoint->condition = obj["condition"].toString(); breakpoint->condition = obj["condition"].toString();
breakpoint->enabled = obj["enabled"].toBool(); breakpoint->enabled = obj["enabled"].toBool();
@ -2124,17 +2132,19 @@ int WatchModel::columnCount(const QModelIndex&) const
return 3; return 3;
} }
void WatchModel::addWatchVar(PWatchVar watchVar) void WatchModel::addWatchVar(PWatchVar watchVar, bool forProject)
{ {
QList<PWatchVar> &vars=(mIsForProject?mProjectWatchVars:mWatchVars); QList<PWatchVar> &vars=(forProject?mProjectWatchVars:mWatchVars);
for (PWatchVar var:vars) { for (PWatchVar var:vars) {
if (watchVar->expression == var->expression) { if (watchVar->expression == var->expression) {
return; return;
} }
} }
beginInsertRows(QModelIndex(),vars.count(),vars.count()); if (forProject==mIsForProject)
beginInsertRows(QModelIndex(),vars.count(),vars.count());
vars.append(watchVar); vars.append(watchVar);
endInsertRows(); if (forProject==mIsForProject)
endInsertRows();
} }
void WatchModel::setWatchVars(const QList<PWatchVar> list, bool forProject) void WatchModel::setWatchVars(const QList<PWatchVar> list, bool forProject)

View File

@ -231,7 +231,7 @@ private:
QJsonArray toJson(bool forProject); QJsonArray toJson(bool forProject);
QList<PWatchVar> loadJson(const QJsonArray &jsonArray, qint64 criteriaTimestamp); QList<PWatchVar> loadJson(const QJsonArray &jsonArray, qint64 criteriaTimestamp);
const QList<PWatchVar> &watchVars() const; const QList<PWatchVar> &watchVars() const;
void addWatchVar(PWatchVar watchVar); void addWatchVar(PWatchVar watchVar, bool forProject);
void setWatchVars(const QList<PWatchVar> list, bool forProject); void setWatchVars(const QList<PWatchVar> list, bool forProject);
private: private:
@ -371,6 +371,7 @@ private:
void sendClearBreakpointCommand(PBreakpoint breakpoint); void sendClearBreakpointCommand(PBreakpoint breakpoint);
void save(const QString& filename, const QString& projectFolder); void save(const QString& filename, const QString& projectFolder);
PDebugConfig load(const QString& filename, bool forProject); PDebugConfig load(const QString& filename, bool forProject);
void addWatchVar(const PWatchVar &watchVar, bool forProject);
private slots: private slots:
void syncFinishedParsing(); void syncFinishedParsing();

View File

@ -23,6 +23,7 @@
#include "settings.h" #include "settings.h"
#include "project.h" #include "project.h"
#include "systemconsts.h" #include "systemconsts.h"
#include "visithistorymanager.h"
#include <QApplication> #include <QApplication>
EditorList::EditorList(QTabWidget* leftPageWidget, EditorList::EditorList(QTabWidget* leftPageWidget,
@ -174,7 +175,7 @@ bool EditorList::closeEditor(Editor* editor, bool transferFocus, bool force) {
PProjectUnit unit = pMainWindow->project()->findUnit(editor); PProjectUnit unit = pMainWindow->project()->findUnit(editor);
pMainWindow->project()->closeUnit(unit); pMainWindow->project()->closeUnit(unit);
} else { } else {
if (pSettings->history().addToOpenedFiles(editor->filename())) { if (pMainWindow->visitHistoryManager()->addFile(editor->filename())) {
pMainWindow->rebuildOpenedFileHisotryMenu(); pMainWindow->rebuildOpenedFileHisotryMenu();
} }
delete editor; delete editor;
@ -358,20 +359,7 @@ Editor* EditorList::getOpenedEditorByFilename(QString filename)
Editor *EditorList::getEditorByFilename(QString filename) Editor *EditorList::getEditorByFilename(QString filename)
{ {
if (filename.isEmpty()) return pMainWindow->openFile(filename,false);
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;
} }
bool EditorList::getContentFromOpenedEditor(const QString &filename, QStringList &buffer) bool EditorList::getContentFromOpenedEditor(const QString &filename, QStringList &buffer)

View File

@ -94,9 +94,6 @@ private:
QSplitter *mSplitter; QSplitter *mSplitter;
QWidget *mPanel; QWidget *mPanel;
int mUpdateCount; int mUpdateCount;
}; };
#endif // EDITORLIST_H #endif // EDITORLIST_H

View File

@ -263,6 +263,10 @@ int main(int argc, char *argv[])
openInSingleInstance = envSetting.value("open_files_in_single_instance",false).toBool(); openInSingleInstance = envSetting.value("open_files_in_single_instance",false).toBool();
} else if (!settingFilename.isEmpty() && firstRun) } else if (!settingFilename.isEmpty() && firstRun)
openInSingleInstance = false; openInSingleInstance = false;
if (app.arguments().contains("-ns")) {
openInSingleInstance = false;
} else if (app.arguments().contains("-s"))
openInSingleInstance = true;
if (openInSingleInstance) { if (openInSingleInstance) {
int openCount = 0; int openCount = 0;
while (true) { while (true) {

View File

@ -48,6 +48,8 @@
#include "vcs/gituserconfigdialog.h" #include "vcs/gituserconfigdialog.h"
#include "widgets/infomessagebox.h" #include "widgets/infomessagebox.h"
#include "widgets/newtemplatedialog.h" #include "widgets/newtemplatedialog.h"
#include "visithistorymanager.h"
#include "widgets/projectalreadyopendialog.h"
#include <QCloseEvent> #include <QCloseEvent>
#include <QComboBox> #include <QComboBox>
@ -149,6 +151,11 @@ MainWindow::MainWindow(QWidget *parent)
mProjectProxyModel->setDynamicSortFilter(false); mProjectProxyModel->setDynamicSortFilter(false);
ui->EditorTabsRight->setVisible(false); ui->EditorTabsRight->setVisible(false);
mVisitHistoryManager = std::make_shared<VisitHistoryManager>(
includeTrailingPathDelimiter(pSettings->dirs().config())
+DEV_HISTORY_FILE);
mVisitHistoryManager->load();
//toolbar takes the owner //toolbar takes the owner
mCompilerSet = new QComboBox(); mCompilerSet = new QComboBox();
mCompilerSet->setMinimumWidth(200); mCompilerSet->setMinimumWidth(200);
@ -450,6 +457,14 @@ void MainWindow::updateEditorBookmarks()
} }
} }
void MainWindow::updateEditorBreakpoints()
{
for (int i=0;i<mEditorList->pageCount();i++) {
Editor * e=(*mEditorList)[i];
e->resetBreakpoints();
}
}
void MainWindow::updateEditorActions() void MainWindow::updateEditorActions()
{ {
Editor* e = mEditorList->getEditor(); Editor* e = mEditorList->getEditor();
@ -1046,14 +1061,15 @@ void MainWindow::rebuildOpenedFileHisotryMenu()
{ {
mMenuRecentFiles->clear(); mMenuRecentFiles->clear();
mMenuRecentProjects->clear(); mMenuRecentProjects->clear();
if (pSettings->history().opennedFiles().size()==0) { if (mVisitHistoryManager->files().count()==0) {
mMenuRecentFiles->setEnabled(false); mMenuRecentFiles->setEnabled(false);
} else { } else {
mMenuRecentFiles->setEnabled(true); mMenuRecentFiles->setEnabled(true);
for (const QString& filename: pSettings->history().opennedFiles()) { foreach (const PVisitRecord& record, mVisitHistoryManager->files()) {
QString filename = record->filename;
//menu takes the ownership //menu takes the ownership
QAction* action = new QAction(filename,mMenuRecentFiles); QAction* action = new QAction(filename,mMenuRecentFiles);
connect(action, &QAction::triggered, [&filename,this](bool){ connect(action, &QAction::triggered, [filename,this](bool){
openFile(filename); openFile(filename);
}); });
mMenuRecentFiles->addAction(action); mMenuRecentFiles->addAction(action);
@ -1061,20 +1077,21 @@ void MainWindow::rebuildOpenedFileHisotryMenu()
mMenuRecentFiles->addSeparator(); mMenuRecentFiles->addSeparator();
//menu takes the ownership //menu takes the ownership
QAction *action = new QAction(tr("Clear History"),mMenuRecentFiles); QAction *action = new QAction(tr("Clear History"),mMenuRecentFiles);
connect(action, &QAction::triggered, [](bool){ connect(action, &QAction::triggered, [this](bool){
pSettings->history().clearOpennedFiles(); mVisitHistoryManager->clearFiles();
}); });
mMenuRecentFiles->addAction(action); mMenuRecentFiles->addAction(action);
} }
if (pSettings->history().opennedProjects().size()==0) { if (mVisitHistoryManager->projects().count()==0) {
mMenuRecentProjects->setEnabled(false); mMenuRecentProjects->setEnabled(false);
} else { } else {
mMenuRecentProjects->setEnabled(true); mMenuRecentProjects->setEnabled(true);
for (const QString& filename: pSettings->history().opennedProjects()) { foreach (const PVisitRecord& record, mVisitHistoryManager->projects()) {
QString filename = record->filename;
//menu takes the ownership //menu takes the ownership
QAction* action = new QAction(filename,mMenuRecentProjects); QAction* action = new QAction(filename,mMenuRecentProjects);
connect(action, &QAction::triggered, [&filename,this](bool){ connect(action, &QAction::triggered, [filename,this](bool){
this->openProject(filename); this->openProject(filename);
}); });
mMenuRecentProjects->addAction(action); mMenuRecentProjects->addAction(action);
@ -1082,8 +1099,8 @@ void MainWindow::rebuildOpenedFileHisotryMenu()
mMenuRecentProjects->addSeparator(); mMenuRecentProjects->addSeparator();
//menu takes the ownership //menu takes the ownership
QAction *action = new QAction(tr("Clear History"),mMenuRecentProjects); QAction *action = new QAction(tr("Clear History"),mMenuRecentProjects);
connect(action, &QAction::triggered, [](bool){ connect(action, &QAction::triggered, [this](bool){
pSettings->history().clearOpennedProjects(); mVisitHistoryManager->clearProjects();
}); });
mMenuRecentProjects->addAction(action); mMenuRecentProjects->addAction(action);
} }
@ -1216,17 +1233,24 @@ void MainWindow::openFiles(const QStringList &files)
e->activate(); 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); Editor* editor = mEditorList->getOpenedEditorByFilename(filename);
if (editor!=nullptr) { if (editor!=nullptr) {
if (activate) { if (activate) {
editor->activate(); editor->activate();
} }
return; return editor;
} }
try { 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; PProjectUnit unit;
if (mProject) { if (mProject) {
unit = mProject->findUnit(filename); unit = mProject->findUnit(filename);
@ -1243,10 +1267,14 @@ void MainWindow::openFile(const QString &filename, bool activate, QTabWidget* pa
if (activate) { if (activate) {
editor->activate(); editor->activate();
} }
if (mEditorList->pageCount()>1 && oldEditor)
mEditorList->closeEditor(oldEditor);
// editor->activate(); // editor->activate();
return editor;
} catch (FileError e) { } catch (FileError e) {
QMessageBox::critical(this,tr("Error"),e.reason()); QMessageBox::critical(this,tr("Error"),e.reason());
} }
return nullptr;
} }
void MainWindow::openProject(const QString &filename, bool openFiles) void MainWindow::openProject(const QString &filename, bool openFiles)
@ -1254,26 +1282,39 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
if (!fileExists(filename)) { if (!fileExists(filename)) {
return; return;
} }
Editor* oldEditor=nullptr;
if (mProject) { if (mProject) {
QString s; if (mProject->filename() == filename)
if (mProject->name().isEmpty()) return;
s = mProject->filename(); ProjectAlreadyOpenDialog dlg;
else if (dlg.exec()!=QDialog::Accepted)
s = mProject->name(); return;
if (QMessageBox::question(this, if (dlg.openType()==ProjectAlreadyOpenDialog::OpenType::ThisWindow) {
tr("Close project"),
tr("Are you sure you want to close %1?")
.arg(s),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes) == QMessageBox::Yes) {
closeProject(false); closeProject(false);
} else { } 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; return;
} }
} else {
if (mEditorList->pageCount()==1) {
oldEditor = mEditorList->getEditor(0);
if (!oldEditor->isNew() || oldEditor->modified()) {
oldEditor = nullptr;
}
}
} }
ui->tabProject->setVisible(true); //ui->tabProject->setVisible(true);
ui->tabExplorer->setCurrentWidget(ui->tabProject); //stretchExplorerPanel(true);
stretchExplorerPanel(true); if (openFiles)
ui->tabExplorer->setCurrentWidget(ui->tabProject);
// { // {
// LeftPageControl.ActivePage := LeftProjectSheet; // LeftPageControl.ActivePage := LeftProjectSheet;
// fLeftPageControlChanged := False; // fLeftPageControlChanged := False;
@ -1287,7 +1328,7 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
ui->projectView->expand( ui->projectView->expand(
mProjectProxyModel->mapFromSource( mProjectProxyModel->mapFromSource(
mProject->model()->rootIndex())); mProject->model()->rootIndex()));
pSettings->history().removeProject(filename); //mVisitHistoryManager->removeProject(filename);
// // if project manager isn't open then open it // // if project manager isn't open then open it
// if not devData.ShowLeftPages then // if not devData.ShowLeftPages then
@ -1329,7 +1370,8 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
updateCompilerSet(); updateCompilerSet();
updateClassBrowserForEditor(e); updateClassBrowserForEditor(e);
mClassBrowserModel.endUpdate(); mClassBrowserModel.endUpdate();
if (oldEditor)
mEditorList->closeEditor(oldEditor);
//updateForEncodingInfo(); //updateForEncodingInfo();
} }
@ -2250,34 +2292,38 @@ void MainWindow::onBookmarkContextMenu(const QPoint &pos)
void MainWindow::saveLastOpens() void MainWindow::saveLastOpens()
{ {
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_LASTOPENS_FILE; QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_LASTOPENS_FILE;
if (fileExists(filename)) { QFile file(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;
}
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; QJsonObject rootObj;
lastOpenIni.SetLongValue("LastOpens","Count", mEditorList->pageCount());
if (mProject) { if (mProject) {
lastOpenIni.SetValue("LastOpens","Project",mProject->filename().toLocal8Bit()); rootObj["lastProject"]=mProject->filename();
} }
QJsonArray filesArray;
for (int i=0;i<mEditorList->pageCount();i++) { for (int i=0;i<mEditorList->pageCount();i++) {
Editor * editor = (*mEditorList)[i]; Editor * editor = (*mEditorList)[i];
QByteArray sectionName = QString("Editor_%1").arg(i).toLocal8Bit(); QJsonObject fileObj;
lastOpenIni.SetValue(sectionName,"FileName", editor->filename().toLocal8Bit()); fileObj["filename"] = editor->filename();
lastOpenIni.SetBoolValue(sectionName, "OnLeft",editor->pageControl() != mEditorList->rightPageWidget()); fileObj["onLeft"] = (editor->pageControl() != mEditorList->rightPageWidget());
lastOpenIni.SetBoolValue(sectionName, "Focused",editor->hasFocus()); fileObj["focused"] = editor->hasFocus();
lastOpenIni.SetLongValue(sectionName, "CursorCol", editor->caretX()); fileObj["caretX"] = editor->caretX();
lastOpenIni.SetLongValue(sectionName, "CursorRow", editor->caretY()); fileObj["caretY"] = editor->caretY();
lastOpenIni.SetLongValue(sectionName, "TopLine", editor->topLine()); fileObj["topLine"] = editor->topLine();
lastOpenIni.SetLongValue(sectionName, "LeftChar", editor->leftChar()); 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, QMessageBox::critical(this,
tr("Save last open info error"), tr("Save last open info error"),
tr("Can't save last open info file '%1'") tr("Can't save last open info file '%1'")
@ -2285,6 +2331,7 @@ void MainWindow::saveLastOpens()
QMessageBox::Ok); QMessageBox::Ok);
return; return;
} }
file.close();
} }
void MainWindow::loadLastOpens() void MainWindow::loadLastOpens()
@ -2292,8 +2339,8 @@ void MainWindow::loadLastOpens()
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_LASTOPENS_FILE; QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_LASTOPENS_FILE;
if (!fileExists(filename)) if (!fileExists(filename))
return; return;
SimpleIni lastOpenIni; QFile file(filename);
if (lastOpenIni.LoadFile(filename.toLocal8Bit())!=SI_Error::SI_OK) { if (!file.open(QFile::ReadOnly)) {
QMessageBox::critical(this, QMessageBox::critical(this,
tr("Load last open info error"), tr("Load last open info error"),
tr("Can't load last open info file '%1'") tr("Can't load last open info file '%1'")
@ -2301,19 +2348,31 @@ void MainWindow::loadLastOpens()
QMessageBox::Ok); QMessageBox::Ok);
return; return;
} }
QString projectFilename = QString::fromLocal8Bit((lastOpenIni.GetValue("LastOpens", "Project",""))); QJsonParseError error;
int count = lastOpenIni.GetLongValue("LastOpens","Count",0); QJsonDocument doc=QJsonDocument::fromJson(file.readAll(),&error);
if (fileExists(projectFilename)) { 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)+" : <BR/>"
+QString("%1").arg(error.errorString()),
QMessageBox::Ok);
return;
}
QJsonObject rootObj = doc.object();
QString projectFilename = rootObj["lastProject"].toString();
if (!projectFilename.isEmpty()) {
openProject(projectFilename, false); openProject(projectFilename, false);
} }
QJsonArray filesArray = rootObj["files"].toArray();
Editor * focusedEditor = nullptr; Editor * focusedEditor = nullptr;
for (int i=0;i<count;i++) { for (int i=0;i<filesArray.count();i++) {
QByteArray sectionName = QString("Editor_%1").arg(i).toLocal8Bit(); QJsonObject fileObj = filesArray[i].toObject();
QString editorFilename = QString::fromLocal8Bit(lastOpenIni.GetValue(sectionName,"FileName","")); QString editorFilename = fileObj["filename"].toString("");
if (!fileExists(editorFilename)) if (!fileExists(editorFilename))
continue; continue;
editorFilename = QFileInfo(editorFilename).absoluteFilePath(); bool onLeft = fileObj["onLeft"].toBool();
bool onLeft = lastOpenIni.GetBoolValue(sectionName,"OnLeft",true);
QTabWidget* page; QTabWidget* page;
if (onLeft) if (onLeft)
page = mEditorList->leftPageWidget(); page = mEditorList->leftPageWidget();
@ -2338,24 +2397,26 @@ void MainWindow::loadLastOpens()
if (!editor) if (!editor)
continue; continue;
QSynedit::BufferCoord pos; QSynedit::BufferCoord pos;
pos.ch = lastOpenIni.GetLongValue(sectionName,"CursorCol", 1); pos.ch = fileObj["caretX"].toInt(1);
pos.line = lastOpenIni.GetLongValue(sectionName,"CursorRow", 1); pos.line = fileObj["caretY"].toInt(1);
editor->setCaretXY(pos); editor->setCaretXY(pos);
editor->setTopLine( editor->setTopLine(
lastOpenIni.GetLongValue(sectionName,"TopLine", 1) fileObj["topLine"].toInt(1)
); );
editor->setLeftChar( editor->setLeftChar(
lastOpenIni.GetLongValue(sectionName,"LeftChar", 1) fileObj["leftChar"].toInt(1)
); );
if (lastOpenIni.GetBoolValue(sectionName,"Focused",false)) if (fileObj["focused"].toBool(false))
focusedEditor = editor; focusedEditor = editor;
pSettings->history().removeFile(editorFilename); //mVisitHistoryManager->removeFile(editorFilename);
} }
if (mProject && mEditorList->pageCount()==0) { if (mProject && mEditorList->pageCount()==0) {
mProject->doAutoOpen(); mProject->doAutoOpen();
updateEditorBookmarks(); updateEditorBookmarks();
updateEditorBreakpoints();
} }
if (count>0) {
if (mEditorList->pageCount()>0) {
updateEditorActions(); updateEditorActions();
//updateForEncodingInfo(); //updateForEncodingInfo();
} }
@ -4376,7 +4437,7 @@ void MainWindow::closeProject(bool refreshEditor)
mClassBrowserModel.beginUpdate(); mClassBrowserModel.beginUpdate();
// Remember it // Remember it
pSettings->history().addToOpenedProjects(mProject->filename()); mVisitHistoryManager->addProject(mProject->filename());
mEditorList->beginUpdate(); mEditorList->beginUpdate();
mProject.reset(); mProject.reset();
@ -4421,7 +4482,7 @@ void MainWindow::updateProjectView()
//ui->projectView->expandAll(); //ui->projectView->expandAll();
stretchExplorerPanel(true); stretchExplorerPanel(true);
ui->tabProject->setVisible(true); ui->tabProject->setVisible(true);
ui->tabExplorer->setCurrentWidget(ui->tabProject); //ui->tabExplorer->setCurrentWidget(ui->tabProject);
} else { } else {
// Clear project browser // Clear project browser
mProjectProxyModel->setSourceModel(nullptr); mProjectProxyModel->setSourceModel(nullptr);
@ -4576,6 +4637,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
settings.setMainWindowGeometry(saveGeometry()); settings.setMainWindowGeometry(saveGeometry());
settings.setBottomPanelIndex(ui->tabMessages->currentIndex()); settings.setBottomPanelIndex(ui->tabMessages->currentIndex());
settings.setLeftPanelIndex(ui->tabExplorer->currentIndex()); settings.setLeftPanelIndex(ui->tabExplorer->currentIndex());
settings.setDebugPanelIndex(ui->debugViews->currentIndex());
settings.setShowStatusBar(ui->actionStatus_Bar->isChecked()); settings.setShowStatusBar(ui->actionStatus_Bar->isChecked());
settings.setShowToolWindowBars(ui->actionTool_Window_Bars->isChecked()); settings.setShowToolWindowBars(ui->actionTool_Window_Bars->isChecked());
@ -4670,13 +4732,14 @@ void MainWindow::showEvent(QShowEvent *)
const Settings::UI& settings = pSettings->ui(); const Settings::UI& settings = pSettings->ui();
ui->tabMessages->setCurrentIndex(settings.bottomPanelIndex()); ui->tabMessages->setCurrentIndex(settings.bottomPanelIndex());
ui->tabExplorer->setCurrentIndex(settings.leftPanelIndex()); ui->tabExplorer->setCurrentIndex(settings.leftPanelIndex());
ui->debugViews->setCurrentIndex(settings.debugPanelIndex());
} }
void MainWindow::hideEvent(QHideEvent *) void MainWindow::hideEvent(QHideEvent *)
{ {
Settings::UI& settings = pSettings->ui(); // Settings::UI& settings = pSettings->ui();
settings.setBottomPanelIndex(ui->tabMessages->currentIndex()); // settings.setBottomPanelIndex(ui->tabMessages->currentIndex());
settings.setLeftPanelIndex(ui->tabExplorer->currentIndex()); // settings.setLeftPanelIndex(ui->tabExplorer->currentIndex());
} }
bool MainWindow::event(QEvent *event) bool MainWindow::event(QEvent *event)
@ -8288,6 +8351,11 @@ void MainWindow::on_actionNew_Template_triggered()
} }
} }
const std::shared_ptr<VisitHistoryManager> &MainWindow::visitHistoryManager() const
{
return mVisitHistoryManager;
}
bool MainWindow::isQuitting() const bool MainWindow::isQuitting() const
{ {
return mQuitting; return mQuitting;

View File

@ -70,6 +70,7 @@ class Project;
class ProjectModelNode; class ProjectModelNode;
class ProjectUnit; class ProjectUnit;
class ColorSchemeItem; class ColorSchemeItem;
class VisitHistoryManager;
#define DPI_CHANGED_EVENT ((QEvent::Type)(QEvent::User+1)) #define DPI_CHANGED_EVENT ((QEvent::Type)(QEvent::User+1))
@ -112,6 +113,7 @@ public:
void updateStatusbarMessage(const QString& s); void updateStatusbarMessage(const QString& s);
void updateEditorSettings(); void updateEditorSettings();
void updateEditorBookmarks(); void updateEditorBookmarks();
void updateEditorBreakpoints();
void updateEditorActions(); void updateEditorActions();
void updateProjectActions(); void updateProjectActions();
void updateCompileActions(); void updateCompileActions();
@ -194,7 +196,7 @@ public:
const PBookmarkModel &bookmarkModel() const; 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 openProject(const QString& filename, bool openFiles = true);
void changeOptions(const QString& widgetName=QString(), const QString& groupName=QString()); void changeOptions(const QString& widgetName=QString(), const QString& groupName=QString());
@ -737,6 +739,8 @@ private:
std::shared_ptr<HeaderCompletionPopup> mHeaderCompletionPopup; std::shared_ptr<HeaderCompletionPopup> mHeaderCompletionPopup;
std::shared_ptr<FunctionTooltipWidget> mFunctionTip; std::shared_ptr<FunctionTooltipWidget> mFunctionTip;
std::shared_ptr<VisitHistoryManager> mVisitHistoryManager;
TodoModel mTodoModel; TodoModel mTodoModel;
SearchResultModel mSearchResultModel; SearchResultModel mSearchResultModel;
PBookmarkModel mBookmarkModel; PBookmarkModel mBookmarkModel;
@ -855,6 +859,7 @@ public:
bool event(QEvent *event) override; bool event(QEvent *event) override;
bool isClosingAll() const; bool isClosingAll() const;
bool isQuitting() const; bool isQuitting() const;
const std::shared_ptr<VisitHistoryManager> &visitHistoryManager() const;
}; };
extern MainWindow* pMainWindow; extern MainWindow* pMainWindow;

View File

@ -895,7 +895,7 @@
<enum>QTabWidget::South</enum> <enum>QTabWidget::South</enum>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>5</number> <number>2</number>
</property> </property>
<property name="iconSize"> <property name="iconSize">
<size> <size>

View File

@ -45,7 +45,6 @@ Settings::Settings(const QString &filename):
mDebugger(this), mDebugger(this),
mCodeCompletion(this), mCodeCompletion(this),
mCodeFormatter(this), mCodeFormatter(this),
mHistory(this),
mUI(this), mUI(this),
mVCS(this) mVCS(this)
{ {
@ -106,7 +105,6 @@ void Settings::load()
mEditor.load(); mEditor.load();
mExecutor.load(); mExecutor.load();
mDebugger.load(); mDebugger.load();
mHistory.load();
mCodeCompletion.load(); mCodeCompletion.load();
mCodeFormatter.load(); mCodeFormatter.load();
mUI.load(); mUI.load();
@ -164,11 +162,6 @@ Settings::VCS &Settings::vcs()
return mVCS; return mVCS;
} }
Settings::History& Settings::history()
{
return mHistory;
}
Settings::Debugger& Settings::debugger() Settings::Debugger& Settings::debugger()
{ {
return mDebugger; return mDebugger;
@ -3671,106 +3664,6 @@ void Settings::Debugger::doLoad()
mMemoryViewColumns = intValue("memory_view_columns",8); 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) Settings::CodeCompletion::CodeCompletion(Settings *settings):_Base(settings, SETTING_CODE_COMPLETION)
{ {
@ -4990,6 +4883,16 @@ void Settings::UI::setMessagesTabsSize(const QSize &newMessagesTabsSize)
mMessagesTabsSize = newMessagesTabsSize; mMessagesTabsSize = newMessagesTabsSize;
} }
int Settings::UI::debugPanelIndex() const
{
return mDebugPanelIndex;
}
void Settings::UI::setDebugPanelIndex(int newDebugPanelIndex)
{
mDebugPanelIndex = newDebugPanelIndex;
}
const QSize &Settings::UI::explorerTabsSize() const const QSize &Settings::UI::explorerTabsSize() const
{ {
return mExplorerTabsSize; return mExplorerTabsSize;
@ -5256,6 +5159,7 @@ void Settings::UI::doSave()
saveValue("main_window_geometry",mMainWindowGeometry); saveValue("main_window_geometry",mMainWindowGeometry);
saveValue("bottom_panel_index",mBottomPanelIndex); saveValue("bottom_panel_index",mBottomPanelIndex);
saveValue("left_panel_index",mLeftPanelIndex); saveValue("left_panel_index",mLeftPanelIndex);
saveValue("debug_panel_index",mDebugPanelIndex);
saveValue("class_browser_sort_alphabetically",mClassBrowserSortAlpha); saveValue("class_browser_sort_alphabetically",mClassBrowserSortAlpha);
saveValue("class_browser_sort_by_type",mClassBrowserSortType); saveValue("class_browser_sort_by_type",mClassBrowserSortType);
saveValue("class_browser_show_inherited",mClassBrowserShowInherited); saveValue("class_browser_show_inherited",mClassBrowserShowInherited);
@ -5305,6 +5209,8 @@ void Settings::UI::doLoad()
mMainWindowGeometry = value("main_window_geometry",QByteArray()).toByteArray(); mMainWindowGeometry = value("main_window_geometry",QByteArray()).toByteArray();
mBottomPanelIndex = intValue("bottom_panel_index",0); mBottomPanelIndex = intValue("bottom_panel_index",0);
mLeftPanelIndex = intValue("left_panel_index",0); mLeftPanelIndex = intValue("left_panel_index",0);
mDebugPanelIndex = intValue("debug_panel_index",0);
mClassBrowserSortAlpha = boolValue("class_browser_sort_alphabetically",true); mClassBrowserSortAlpha = boolValue("class_browser_sort_alphabetically",true);
mClassBrowserSortType = boolValue("class_browser_sort_by_type",true); mClassBrowserSortType = boolValue("class_browser_sort_by_type",true);
mClassBrowserShowInherited = boolValue("class_browser_show_inherited",true); mClassBrowserShowInherited = boolValue("class_browser_show_inherited",true);

View File

@ -817,28 +817,6 @@ public:
void doLoad() override; 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 { class Executor: public _Base {
public: public:
explicit Executor(Settings * settings); explicit Executor(Settings * settings);
@ -1044,11 +1022,15 @@ public:
const QSize &messagesTabsSize() const; const QSize &messagesTabsSize() const;
void setMessagesTabsSize(const QSize &newMessagesTabsSize); void setMessagesTabsSize(const QSize &newMessagesTabsSize);
int debugPanelIndex() const;
void setDebugPanelIndex(int newDebugPanelIndex);
private: private:
QByteArray mMainWindowState; QByteArray mMainWindowState;
QByteArray mMainWindowGeometry; QByteArray mMainWindowGeometry;
int mBottomPanelIndex; int mBottomPanelIndex;
int mLeftPanelIndex; int mLeftPanelIndex;
int mDebugPanelIndex;
bool mClassBrowserSortAlpha; bool mClassBrowserSortAlpha;
bool mClassBrowserSortType; bool mClassBrowserSortType;
bool mClassBrowserShowInherited; bool mClassBrowserShowInherited;
@ -1412,7 +1394,6 @@ public:
Environment& environment(); Environment& environment();
Executor& executor(); Executor& executor();
Debugger& debugger(); Debugger& debugger();
History& history();
CodeCompletion &codeCompletion(); CodeCompletion &codeCompletion();
CodeFormatter &codeFormatter(); CodeFormatter &codeFormatter();
UI &ui(); UI &ui();
@ -1430,7 +1411,6 @@ private:
Debugger mDebugger; Debugger mDebugger;
CodeCompletion mCodeCompletion; CodeCompletion mCodeCompletion;
CodeFormatter mCodeFormatter; CodeFormatter mCodeFormatter;
History mHistory;
UI mUI; UI mUI;
VCS mVCS; VCS mVCS;
}; };

View File

@ -82,7 +82,7 @@
#define TEMPLATE_EXT "template" #define TEMPLATE_EXT "template"
#define TEMPLATE_INFO_FILE "info.template" #define TEMPLATE_INFO_FILE "info.template"
#define DEV_INTERNAL_OPEN "$__DEV_INTERNAL_OPEN" #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_SYMBOLUSAGE_FILE "symbolusage.json"
#define DEV_CODESNIPPET_FILE "codesnippets.json" #define DEV_CODESNIPPET_FILE "codesnippets.json"
#define DEV_NEWFILETEMPLATES_FILE "newfiletemplate.txt" #define DEV_NEWFILETEMPLATES_FILE "newfiletemplate.txt"
@ -91,6 +91,7 @@
#define DEV_TOOLS_FILE "tools.json" #define DEV_TOOLS_FILE "tools.json"
#define DEV_BOOKMARK_FILE "bookmarks.json" #define DEV_BOOKMARK_FILE "bookmarks.json"
#define DEV_DEBUGGER_FILE "debugger.json" #define DEV_DEBUGGER_FILE "debugger.json"
#define DEV_HISTORY_FILE "history.json"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
# define PATH_SENSITIVITY Qt::CaseInsensitive # define PATH_SENSITIVITY Qt::CaseInsensitive

View File

@ -156,19 +156,19 @@
</message> </message>
<message> <message>
<source>Save file &apos;%1&apos; failed.</source> <source>Save file &apos;%1&apos; failed.</source>
<translation>Falha ao salvar arquivo &apos;%1&apos;.</translation> <translation type="vanished">Falha ao salvar arquivo &apos;%1&apos;.</translation>
</message> </message>
<message> <message>
<source>Can&apos;t open file &apos;%1&apos; for write.</source> <source>Can&apos;t open file &apos;%1&apos; for write.</source>
<translation>Impossível gravar arquivo &apos;%1&apos;.</translation> <translation type="vanished">Impossível gravar arquivo &apos;%1&apos;.</translation>
</message> </message>
<message> <message>
<source>Error in json file &apos;%1&apos;:%2 : %3</source> <source>Error in json file &apos;%1&apos;:%2 : %3</source>
<translation>Erro no arquivo json &apos;%1&apos;:%2 : %3</translation> <translation type="vanished">Erro no arquivo json &apos;%1&apos;:%2 : %3</translation>
</message> </message>
<message> <message>
<source>Can&apos;t open file &apos;%1&apos; for read.</source> <source>Can&apos;t open file &apos;%1&apos; for read.</source>
<translation>Impossível ler o arquivo &apos;%1&apos;.</translation> <translation type="vanished">Impossível ler o arquivo &apos;%1&apos;.</translation>
</message> </message>
</context> </context>
<context> <context>
@ -703,10 +703,6 @@
<source>Stop after the compilation proper stage</source> <source>Stop after the compilation proper stage</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Stop after the assembling stage</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Link and generate the executable </source> <source>Link and generate the executable </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -715,10 +711,6 @@
<source>Preprocessing output suffix</source> <source>Preprocessing output suffix</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Assembling output suffix</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Compiling output suffix</source> <source>Compiling output suffix</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -810,11 +802,11 @@
</message> </message>
<message> <message>
<source>Autosave breakpoints</source> <source>Autosave breakpoints</source>
<translation>Salvar breakpoints automaticamente</translation> <translation type="vanished">Salvar breakpoints automaticamente</translation>
</message> </message>
<message> <message>
<source>Autosave watches</source> <source>Autosave watches</source>
<translation>Salvar automaticamente as observações</translation> <translation type="vanished">Salvar automaticamente as observações</translation>
</message> </message>
<message> <message>
<source>Show CPU Window when signal received</source> <source>Show CPU Window when signal received</source>
@ -852,6 +844,10 @@
<source>Memory View Columns</source> <source>Memory View Columns</source>
<translation>Colunas da memória</translation> <translation>Colunas da memória</translation>
</message> </message>
<message>
<source>Autosave breakpoints and watches</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Debugger</name> <name>Debugger</name>
@ -915,6 +911,22 @@
<source>Signal &quot;%1&quot; Received: </source> <source>Signal &quot;%1&quot; Received: </source>
<translation>Recebido sinal &quot;%1&quot;: </translation> <translation>Recebido sinal &quot;%1&quot;: </translation>
</message> </message>
<message>
<source>Save file &apos;%1&apos; failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for write.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error in json file &apos;%1&apos;:%2 : %3</source>
<translation type="unfinished">Erro no arquivo json &apos;%1&apos;:%2 : %3</translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for read.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Editor</name> <name>Editor</name>
@ -3898,11 +3910,11 @@
</message> </message>
<message> <message>
<source>Close project</source> <source>Close project</source>
<translation>Fechar projeto</translation> <translation type="vanished">Fechar projeto</translation>
</message> </message>
<message> <message>
<source>Are you sure you want to close %1?</source> <source>Are you sure you want to close %1?</source>
<translation>Quer mesmo fechar %1?</translation> <translation type="vanished">Quer mesmo fechar %1?</translation>
</message> </message>
<message> <message>
<source>Confirm</source> <source>Confirm</source>
@ -3998,7 +4010,7 @@
</message> </message>
<message> <message>
<source>Can&apos;t remove old last open information file &apos;%1&apos;</source> <source>Can&apos;t remove old last open information file &apos;%1&apos;</source>
<translation>Impossível remover o arquivo aberto com a última informação &apos;%1&apos; </translation> <translation type="vanished">Impossível remover o arquivo aberto com a última informação &apos;%1&apos; </translation>
</message> </message>
<message> <message>
<source>Can&apos;t save last open info file &apos;%1&apos;</source> <source>Can&apos;t save last open info file &apos;%1&apos;</source>
@ -4660,6 +4672,10 @@
<source>Please correct this before start debugging</source> <source>Please correct this before start debugging</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Can&apos;t open last open information file &apos;%1&apos; for write!</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>NewClassDialog</name> <name>NewClassDialog</name>
@ -5004,6 +5020,33 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>ProjectAlreadyOpenDialog</name>
<message>
<source>Dialog</source>
<translation type="obsolete">Diálogo</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;This Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New &amp;Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open Project</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>ProjectCompileParamatersWidget</name> <name>ProjectCompileParamatersWidget</name>
<message> <message>
@ -6716,19 +6759,19 @@
</message> </message>
<message> <message>
<source>Save file &apos;%1&apos; failed.</source> <source>Save file &apos;%1&apos; failed.</source>
<translation>Falha ao gravar o arquivo &apos;%1&apos;.</translation> <translation type="vanished">Falha ao gravar o arquivo &apos;%1&apos;.</translation>
</message> </message>
<message> <message>
<source>Can&apos;t open file &apos;%1&apos; for write.</source> <source>Can&apos;t open file &apos;%1&apos; for write.</source>
<translation>Impossível gravar no arquivo &apos;%1&apos;.</translation> <translation type="vanished">Impossível gravar no arquivo &apos;%1&apos;.</translation>
</message> </message>
<message> <message>
<source>Error in json file &apos;%1&apos;:%2 : %3</source> <source>Error in json file &apos;%1&apos;:%2 : %3</source>
<translation>Erro no arquivo json &apos;%1&apos;:%2 : %3</translation> <translation type="vanished">Erro no arquivo json &apos;%1&apos;:%2 : %3</translation>
</message> </message>
<message> <message>
<source>Can&apos;t open file &apos;%1&apos; for read.</source> <source>Can&apos;t open file &apos;%1&apos; for read.</source>
<translation>Impossível ler o arquivo &apos;%1&apos;</translation> <translation type="vanished">Impossível ler o arquivo &apos;%1&apos;</translation>
</message> </message>
<message> <message>
<source>Expression</source> <source>Expression</source>

File diff suppressed because it is too large Load Diff

View File

@ -150,22 +150,6 @@
<source>Condition</source> <source>Condition</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Save file &apos;%1&apos; failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for write.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error in json file &apos;%1&apos;:%2 : %3</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for read.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>CPUDialog</name> <name>CPUDialog</name>
@ -628,10 +612,6 @@
<source>Stop after the compilation proper stage</source> <source>Stop after the compilation proper stage</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Stop after the assembling stage</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Link and generate the executable </source> <source>Link and generate the executable </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -640,10 +620,6 @@
<source>Preprocessing output suffix</source> <source>Preprocessing output suffix</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Assembling output suffix</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Compiling output suffix</source> <source>Compiling output suffix</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -733,14 +709,6 @@
<source>Autosave</source> <source>Autosave</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Autosave breakpoints</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Autosave watches</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Show CPU Window when signal received</source> <source>Show CPU Window when signal received</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -777,6 +745,10 @@
<source>Memory View Columns</source> <source>Memory View Columns</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Autosave breakpoints and watches</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Debugger</name> <name>Debugger</name>
@ -840,6 +812,22 @@
<source>Signal &quot;%1&quot; Received: </source> <source>Signal &quot;%1&quot; Received: </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Save file &apos;%1&apos; failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for write.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error in json file &apos;%1&apos;:%2 : %3</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for read.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Editor</name> <name>Editor</name>
@ -3797,14 +3785,6 @@
<source>Overwrite</source> <source>Overwrite</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Close project</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure you want to close %1?</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Confirm</source> <source>Confirm</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -3897,10 +3877,6 @@
<source>Save last open info error</source> <source>Save last open info error</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Can&apos;t remove old last open information file &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Can&apos;t save last open info file &apos;%1&apos;</source> <source>Can&apos;t save last open info file &apos;%1&apos;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -4549,6 +4525,10 @@
<source>Please correct this before start debugging</source> <source>Please correct this before start debugging</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Can&apos;t open last open information file &apos;%1&apos; for write!</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>NewClassDialog</name> <name>NewClassDialog</name>
@ -4889,6 +4869,29 @@
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context>
<name>ProjectAlreadyOpenDialog</name>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&amp;This Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>New &amp;Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Cancel</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open Project</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>ProjectCompileParamatersWidget</name> <name>ProjectCompileParamatersWidget</name>
<message> <message>
@ -6529,22 +6532,6 @@
<source>Execute to evaluate</source> <source>Execute to evaluate</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Save file &apos;%1&apos; failed.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for write.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Error in json file &apos;%1&apos;:%2 : %3</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Can&apos;t open file &apos;%1&apos; for read.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Expression</source> <source>Expression</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>

View File

@ -0,0 +1,183 @@
#include "visithistorymanager.h"
#include <QDateTime>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QSet>
VisitHistoryManager::VisitHistoryManager(const QString& filename):
mLastLoadtime(0),
mSaveFilename(filename),
mMaxFileCount(15),
mMaxProjectCount(15)
{
}
const QList<PVisitRecord> &VisitHistoryManager::files() const
{
return mFiles;
}
const QList<PVisitRecord> &VisitHistoryManager::projects() const
{
return mProjects;
}
void VisitHistoryManager::clearFiles()
{
mFiles.clear();
}
void VisitHistoryManager::clearProjects()
{
mProjects.clear();
}
static int indexOf(const QList<PVisitRecord> &list, const QString& filename) {
for (int i=0;i<list.count();i++) {
if (list[i]->filename == 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<VisitHistory>();
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<PVisitRecord> VisitHistoryManager::fromJson(const QJsonArray &array, qint64 criteriaTime)
{
QList<PVisitRecord> records;
for (int i=0;i<array.count();i++) {
QJsonObject recordObj = array[i].toObject();
bool ok;
qint64 timestamp = recordObj["timestamp"].toString().toLongLong(&ok);
if (ok && timestamp>criteriaTime) {
PVisitRecord record = std::make_shared<VisitRecord>();
record->timestamp = timestamp;
record->filename = recordObj["filename"].toString();
records.append(record);
}
}
return records;
}
void VisitHistoryManager::mergeRead(QList<PVisitRecord> &target, const QList<PVisitRecord> &readed)
{
QSet<QString> 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<PVisitRecord> &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<PVisitRecord> &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<VisitRecord>();
record->filename = filename;
record->timestamp = QDateTime::currentMSecsSinceEpoch();
list.push_front(record);
save();
return true;
}
void VisitHistoryManager::doRemove(QList<PVisitRecord> &list, const QString &filename)
{
int index = indexOf(mFiles,filename);
if (index>=0) {
list.removeAt(index);
}
save();
}

View File

@ -0,0 +1,56 @@
#ifndef VISITHISTORYMANAGER_H
#define VISITHISTORYMANAGER_H
#include <QJsonArray>
#include <QList>
#include <QString>
#include <memory>
struct VisitRecord {
QString filename;
qint64 timestamp;
};
using PVisitRecord = std::shared_ptr<VisitRecord>;
struct VisitHistory{
qint64 timestamp;
QList<PVisitRecord> files;
QList<PVisitRecord> projects;
};
using PVisitHistory = std::shared_ptr<VisitHistory>;
class VisitHistoryManager
{
public:
VisitHistoryManager(const QString& filename);
const QList<PVisitRecord> &files() const;
const QList<PVisitRecord> &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<PVisitRecord> fromJson(const QJsonArray &array, qint64 criteriaTime);
void mergeRead(QList<PVisitRecord>& target, const QList<PVisitRecord>& readed);
QJsonArray toJson(const QList<PVisitRecord>& list);
bool doAdd(QList<PVisitRecord> &list, const QString& filename, int maxCount);
void doRemove(QList<PVisitRecord> &list, const QString& filename);
private:
QList<PVisitRecord> mFiles;
QList<PVisitRecord> mProjects;
qint64 mLastLoadtime;
QString mSaveFilename;
int mMaxFileCount;
int mMaxProjectCount;
};
#endif // VISITHISTORYMANAGER_H

View File

@ -210,44 +210,55 @@ void BookmarkModel::save(const QString &filename, const QString& projectFolder)
} }
QList<PBookmark> fileBookmarks=load(filename, t,&fileTimestamp); QList<PBookmark> fileBookmarks=load(filename, t,&fileTimestamp);
QFile file(filename); QFile file(filename);
int saveOrderCount=0;
if (file.open(QFile::WriteOnly | QFile::Truncate)) { if (file.open(QFile::WriteOnly | QFile::Truncate)) {
QHash<QString,PBookmark> compareHash; QHash<QString,int> compareHash;
QList<PBookmark> saveBookmarks; QList<PBookmark> saveBookmarks;
foreach (const PBookmark& bookmark, bookmarks) { for (int i=0; i<bookmarks.count(); i++) {
PBookmark& bookmark=bookmarks[i];
QString key = QString("%1-%2").arg(bookmark->filename).arg(bookmark->line); QString key = QString("%1-%2").arg(bookmark->filename).arg(bookmark->line);
bookmark->saveOrder=saveOrderCount++; compareHash.insert(key,i);;
compareHash.insert(key,bookmark);
} }
QDir dir(projectFolder);
foreach (const PBookmark& bookmark, fileBookmarks) { foreach (const PBookmark& bookmark, fileBookmarks) {
QString key = QString("%1-%2").arg(bookmark->filename).arg(bookmark->line); QString key = QString("%1-%2").arg(bookmark->filename).arg(bookmark->line);
bookmark->saveOrder=saveOrderCount++; int idx = compareHash.value(key,-1);
if (!compareHash.contains(key)) if (idx<0) {
compareHash.insert(key,bookmark); int count=forProject?mProjectBookmarks.count():mBookmarks.count();
else { compareHash.insert(key,count);
PBookmark pTemp=compareHash.value(key); if (forProject == mIsForProject) {
if (pTemp->timestamp<=bookmark->timestamp) beginInsertRows(QModelIndex(),count,count);
compareHash.insert(key,bookmark); }
if (forProject) {
bookmark->filename = dir.absoluteFilePath(bookmark->filename);
}
QList<PBookmark> &list=forProject?mProjectBookmarks:mBookmarks;
list.append(bookmark);
if (forProject == mIsForProject)
endInsertRows();
} else {
const QList<PBookmark> &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<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;
});
qint64 saveTime = QDateTime::currentMSecsSinceEpoch();;
if (forProject) { if (forProject) {
mProjectBookmarks=saveList; mLastLoadProjectBookmarksTimestamp = saveTime;
mLastLoadProjectBookmarksTimestamp = QDateTime::currentMSecsSinceEpoch();
} else { } else {
mBookmarks=saveList; mLastLoadBookmarksTimestamp = saveTime;
mLastLoadBookmarksTimestamp = QDateTime::currentMSecsSinceEpoch();
} }
QJsonObject rootObj;
rootObj["timestamp"]=QString("%1").arg(saveTime);
QJsonArray array; QJsonArray array;
foreach (const PBookmark& bookmark, saveList) { const QList<PBookmark> &list=forProject?mProjectBookmarks:mBookmarks;
foreach (const PBookmark& bookmark, list) {
QJsonObject obj; QJsonObject obj;
obj["filename"]=bookmark->filename; obj["filename"]=bookmark->filename;
obj["line"]=bookmark->line; obj["line"]=bookmark->line;
@ -255,8 +266,9 @@ void BookmarkModel::save(const QString &filename, const QString& projectFolder)
obj["timestamp"]=QString("%1").arg(bookmark->timestamp); obj["timestamp"]=QString("%1").arg(bookmark->timestamp);
array.append(obj); array.append(obj);
} }
rootObj["bookmarks"]=array;
QJsonDocument doc; QJsonDocument doc;
doc.setArray(array); doc.setObject(rootObj);
if (file.write(doc.toJson())<0) { if (file.write(doc.toJson())<0) {
throw FileError(tr("Save file '%1' failed.") throw FileError(tr("Save file '%1' failed.")
.arg(filename)); .arg(filename));
@ -272,10 +284,6 @@ QList<PBookmark> BookmarkModel::load(const QString& filename, qint64 criteriaTim
//clear(forProject); //clear(forProject);
QList<PBookmark> bookmarks; QList<PBookmark> bookmarks;
QFileInfo fileInfo(filename); QFileInfo fileInfo(filename);
qint64 timestamp=fileInfo.fileTime(QFile::FileModificationTime).toMSecsSinceEpoch();
*pFileTimestamp=timestamp;
if (timestamp<=criteriaTimestamp)
return bookmarks;
QFile file(filename); QFile file(filename);
if (!file.exists()) if (!file.exists())
return bookmarks; return bookmarks;
@ -289,13 +297,17 @@ QList<PBookmark> BookmarkModel::load(const QString& filename, qint64 criteriaTim
.arg(error.offset) .arg(error.offset)
.arg(error.errorString())); .arg(error.errorString()));
} }
QJsonArray array = doc.array(); QJsonObject rootObj;
qint64 bookmarkTimestamp;
bool ok; 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;i<array.count();i++) { for (int i=0;i<array.count();i++) {
QJsonValue value = array[i]; QJsonValue value = array[i];
QJsonObject obj=value.toObject(); QJsonObject obj=value.toObject();
bookmarkTimestamp = obj["timestamp"].toString().toULongLong(&ok); qint64 bookmarkTimestamp = obj["timestamp"].toString().toULongLong(&ok);
if (ok && bookmarkTimestamp>criteriaTimestamp) { if (ok && bookmarkTimestamp>criteriaTimestamp) {
PBookmark bookmark = std::make_shared<Bookmark>(); PBookmark bookmark = std::make_shared<Bookmark>();
bookmark->filename = obj["filename"].toString(); bookmark->filename = obj["filename"].toString();

View File

@ -26,7 +26,6 @@ struct Bookmark {
int line; int line;
QString description; QString description;
qint64 timestamp; qint64 timestamp;
int saveOrder;
}; };
using PBookmark=std::shared_ptr<Bookmark>; using PBookmark=std::shared_ptr<Bookmark>;

View File

@ -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();
}

View File

@ -0,0 +1,43 @@
#ifndef PROJECTALREADOPENDIALOG_H
#define PROJECTALREADOPENDIALOG_H
#include <QDialog>
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

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ProjectAlreadyOpenDialog</class>
<widget class="QDialog" name="ProjectAlreadyOpenDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>652</width>
<height>254</height>
</rect>
</property>
<property name="windowTitle">
<string>Open Project</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;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?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>30</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnThisWindow">
<property name="text">
<string>&amp;This Window</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnNewWindow">
<property name="text">
<string>New &amp;Window</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnCancel">
<property name="text">
<string>Cancel</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>