From 5620a956274dd0cdb3728c72238fa9d85d5da93a Mon Sep 17 00:00:00 2001 From: kostas Date: Mon, 8 Aug 2011 14:44:31 +0000 Subject: [PATCH] Dialog refactoring Extended the settings dialog Reorganized the workspace management code Fixed issue where the previous current directory was in effect even in new workspaces Improved the log responsiveness on long fossil operations FossilOrigin-Name: 945c841fba73be1355611554499e68a878b95359 --- MainWindow.cpp | 245 ++++++++++++++++++++++++++++++++++----------- MainWindow.h | 1 + MainWindow.ui | 3 +- RepoDialog.ui | 99 ++++++++++++++---- SettingsDialog.cpp | 76 +++++++++----- SettingsDialog.h | 6 +- SettingsDialog.ui | 99 ++++++++++++++---- manifest | 24 ++--- manifest.uuid | 2 +- 9 files changed, 421 insertions(+), 134 deletions(-) diff --git a/MainWindow.cpp b/MainWindow.cpp index c9be693..9639a56 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -23,6 +23,7 @@ QString EOL_MARK("\n"); #endif +//----------------------------------------------------------------------------- enum { COLUMN_STATUS, @@ -32,11 +33,13 @@ enum COLUMN_MODIFIED }; +//----------------------------------------------------------------------------- static QString QuotePath(const QString &path) { return path; } +//----------------------------------------------------------------------------- static QStringList QuotePaths(const QStringList &paths) { QStringList res; @@ -45,8 +48,80 @@ static QStringList QuotePaths(const QStringList &paths) return res; } +//----------------------------------------------------------------------------- +typedef QMap QStringMap; +static QStringMap MakeKeyValue(QStringList lines) +{ + QStringMap res; + foreach(QString l, lines) + { + l = l.trimmed(); + int index = l.indexOf(' '); + QString key; + QString value; + if(index!=-1) + { + key = l.left(index).trimmed(); + value = l.mid(index).trimmed(); + } + else + key = l; + + res.insert(key, value); + } + return res; +} + +/////////////////////////////////////////////////////////////////////////////// +enum DialogAnswer +{ + ANSWER_YES, + ANSWER_NO, + ANSWER_YESALL +}; + +static DialogAnswer DialogQuery(QWidget *parent, const QString &title, const QString &query, bool yesToAllButton=false) +{ + QMessageBox::StandardButtons buttons = QMessageBox::Yes|QMessageBox::No; + if(yesToAllButton) + buttons |= QMessageBox::YesToAll; + + QMessageBox mb(QMessageBox::Question, title, query, buttons, parent, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::Sheet ); + mb.setDefaultButton(QMessageBox::No); + mb.setWindowModality(Qt::WindowModal); + mb.setModal(true); + mb.exec(); + int res = mb.standardButton(mb.clickedButton()); + if(res==QDialogButtonBox::Yes) + return ANSWER_YES; + else if(res==QDialogButtonBox::YesToAll) + return ANSWER_YESALL; + return ANSWER_NO; +} + +//----------------------------------------------------------------------------- +static bool DialogQueryText(QWidget *parent, const QString &title, const QString &query, QString &text, bool isPassword=false) +{ + QInputDialog dlg(parent, Qt::Sheet); + dlg.setWindowTitle(title); + dlg.setInputMode(QInputDialog::TextInput); + dlg.setWindowModality(Qt::WindowModal); + dlg.setModal(true); + dlg.setLabelText(query); + dlg.setTextValue(text); + if(isPassword) + dlg.setTextEchoMode(QLineEdit::Password); + + if(dlg.exec() == QDialog::Rejected) + return false; + + text = dlg.textValue(); + return true; +} + +/////////////////////////////////////////////////////////////////////////////// MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) @@ -109,11 +184,47 @@ MainWindow::~MainWindow() saveSettings(); delete ui; } +//----------------------------------------------------------------------------- const QString &MainWindow::getCurrentWorkspace() { return currentWorkspace; } +//----------------------------------------------------------------------------- +void MainWindow::setCurrentWorkspace(const QString &workspace) +{ + if(workspace.isEmpty()) + { + currentWorkspace.clear(); + return; + } + + QString new_workspace = QDir(workspace).absolutePath(); + + currentWorkspace = new_workspace; + addWorkspace(new_workspace); + + if(!QDir::setCurrent(new_workspace)) + QMessageBox::critical(this, tr("Error"), tr("Could not change current diectory"), QMessageBox::Ok ); +} + +//------------------------------------------------------------------------------ +void MainWindow::addWorkspace(const QString &dir) +{ + if(dir.isEmpty()) + return; + + QDir d(dir); + QString new_workspace = d.absolutePath(); + + // Do not add the workspace if it exists already + if(workspaceHistory.indexOf(new_workspace)!=-1) + return; + + workspaceHistory.append(new_workspace); + rebuildRecent(); +} + //------------------------------------------------------------------------------ void MainWindow::on_actionRefresh_triggered() { @@ -123,20 +234,20 @@ void MainWindow::on_actionRefresh_triggered() //------------------------------------------------------------------------------ bool MainWindow::openWorkspace(const QString &dir) { - addWorkspace(dir); - currentWorkspace = dir; + setCurrentWorkspace(dir); on_actionClearLog_triggered(); stopUI(); - bool ok = refresh(); - if(ok) + // If this repository is not valid, remove it from the history + if(!refresh()) { - QDir::setCurrent(dir); + setCurrentWorkspace(""); + workspaceHistory.removeAll(dir); rebuildRecent(); + return false; } - - return ok; + return true; } //------------------------------------------------------------------------------ @@ -170,8 +281,12 @@ void MainWindow::rebuildRecent() void MainWindow::onOpenRecent() { QAction *action = qobject_cast(sender()); - if (action) - openWorkspace(action->data().toString()); + if(!action) + return; + + QString workspace = action->data().toString(); + + openWorkspace(workspace); } //------------------------------------------------------------------------------ @@ -348,7 +463,7 @@ void MainWindow::scanWorkspace() // Status Column const char *tag = "?"; // Default Tag const char *tooltip = "Unknown"; - const char *icon = ":icons/icons/Button Blank Gray-01.png"; // Default icon + const char *status_icon= ":icons/icons/Button Blank Gray-01.png"; // Default icon for(size_t t=0; tsetToolTip(tooltip); itemModel.setItem(i, COLUMN_STATUS, status); @@ -513,6 +628,8 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int process.waitForReadyRead(500); buffer += process.readAll(); + QCoreApplication::processEvents(); + if(buffer.isEmpty()) continue; @@ -557,20 +674,13 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int if(have_query && have_yna_query) { QString query = ParseFossilQuery(last_line); - - QMessageBox mb(QMessageBox::Question, "Fossil", query, QMessageBox::Yes|QMessageBox::No|QMessageBox::YesToAll, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::Sheet ); - mb.setDefaultButton(QMessageBox::No); - mb.setWindowModality(Qt::WindowModal); - mb.setModal(true); - mb.exec(); - int res = mb.standardButton(mb.clickedButton()); - - if(res==QDialogButtonBox::Yes) + DialogAnswer res = DialogQuery(this, "Fossil", query, true); + if(res==ANSWER_YES) { process.write(ans_yes.toAscii()); log("Y\n"); } - else if(res==QDialogButtonBox::YesToAll) + else if(res==ANSWER_YESALL) { process.write(ans_always.toAscii()); log("A\n"); @@ -585,15 +695,9 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int else if(have_query && have_yn_query) { QString query = ParseFossilQuery(last_line); + DialogAnswer res = DialogQuery(this, "Fossil", query, false); - QMessageBox mb(QMessageBox::Question, "Fossil", query, QMessageBox::Yes|QMessageBox::No|QMessageBox::YesToAll, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::Sheet ); - mb.setDefaultButton(QMessageBox::No); - mb.setWindowModality(Qt::WindowModal); - mb.setModal(true); - mb.exec(); - int res = mb.standardButton(mb.clickedButton()); - - if(res==QMessageBox::Yes) + if(res==ANSWER_YES) { process.write(ans_yes.toAscii()); log("Y\n"); @@ -622,18 +726,6 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int return true; } -//------------------------------------------------------------------------------ -void MainWindow::addWorkspace(const QString &dir) -{ - QDir d(dir); - QString new_workspace = QDir(dir).absolutePath(); - - // Do not add the workspace if it exists already - if(workspaceHistory.indexOf(new_workspace)!=-1) - return; - - workspaceHistory.append(new_workspace); -} //------------------------------------------------------------------------------ QString MainWindow::getFossilPath() @@ -670,7 +762,7 @@ void MainWindow::loadSettings() addWorkspace(wk); if(qsettings.contains("Active") && qsettings.value("Active").toBool()) - currentWorkspace = wk; + setCurrentWorkspace(wk); } qsettings.endArray(); @@ -706,7 +798,7 @@ void MainWindow::saveSettings() { qsettings.setArrayIndex(i); qsettings.setValue("Path", workspaceHistory[i]); - if(currentWorkspace == workspaceHistory[i]) + if(getCurrentWorkspace() == workspaceHistory[i]) qsettings.setValue("Active", true); } qsettings.endArray(); @@ -1034,10 +1126,19 @@ void MainWindow::on_actionNew_triggered() } stopUI(); + on_actionClearLog_triggered(); + QFileInfo path_info(path); Q_ASSERT(path_info.dir().exists()); QString wkdir = path_info.absoluteDir().absolutePath(); - addWorkspace(wkdir); + + setCurrentWorkspace(wkdir); + if(!QDir::setCurrent(wkdir)) + { + QMessageBox::critical(this, tr("Error"), tr("Could not change current diectory"), QMessageBox::Ok ); + return; + } + repositoryFile = path_info.absoluteFilePath(); // Create repo @@ -1059,6 +1160,7 @@ void MainWindow::on_actionNew_triggered() //------------------------------------------------------------------------------ void MainWindow::on_actionClone_triggered() { + // FIXME: Implement this stopUI(); } @@ -1149,7 +1251,45 @@ void MainWindow::on_actionUpdate_triggered() //------------------------------------------------------------------------------ void MainWindow::on_actionSettings_triggered() { - SettingsDialog::run(this, settings); + // Also retrieve the fossil global settings + QStringList out; + if(!runFossil(QStringList() << "settings", &out, true)) + return; + + QStringMap kv = MakeKeyValue(out); + struct { const char *command; QString *value; } maps[] = + { + { "gdiff-command", &settings.gDiffCommand }, + { "gmerge-command", &settings.gMergeCommand } + }; + + for(size_t m=0; misEmpty()) + runFossil(QStringList() << "unset" << maps[m].command << "-global"); + else + runFossil(QStringList() << "settings" << maps[m].command << *maps[m].value << "-global"); + } + } + } //------------------------------------------------------------------------------ @@ -1161,19 +1301,9 @@ void MainWindow::on_actionSyncSettings_triggered() if(runFossil(QStringList() << "remote-url", &out, true) && out.length()==1) current = out[0].trimmed(); - QInputDialog dlg(this, Qt::Sheet); - dlg.setWindowTitle(tr("Remote URL")); - dlg.setInputMode(QInputDialog::TextInput); - dlg.setWindowModality(Qt::WindowModal); - dlg.setModal(true); - dlg.setLabelText(tr("Enter new remote URL:")); - dlg.setTextValue(current); - - if(dlg.exec() == QDialog::Rejected) + if(!DialogQueryText(this, tr("Remote URL"), tr("Enter new remote URL:"), current)) return; - current = dlg.textValue(); - QUrl url(current); if(!url.isValid()) { @@ -1184,3 +1314,4 @@ void MainWindow::on_actionSyncSettings_triggered() // Run as silent to avoid displaying credentials in the log runFossil(QStringList() << "remote-url" << QuotePath(url.toString()), 0, true); } + diff --git a/MainWindow.h b/MainWindow.h index 7e9e9d0..f0ab4cf 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -106,6 +106,7 @@ private: void loadSettings(); void saveSettings(); const QString &getCurrentWorkspace(); + void setCurrentWorkspace(const QString &workspace); void log(const QString &text); void setStatus(const QString &text); bool uiRunning() const { return fossilUI.state() == QProcess::Running; } diff --git a/MainWindow.ui b/MainWindow.ui index 61c2568..fdad44b 100644 --- a/MainWindow.ui +++ b/MainWindow.ui @@ -97,6 +97,7 @@ + @@ -448,7 +449,7 @@ - Synchronization Settings... + Workspace Settings... Set remote synchronization settings diff --git a/RepoDialog.ui b/RepoDialog.ui index 57413cb..4be1825 100644 --- a/RepoDialog.ui +++ b/RepoDialog.ui @@ -6,35 +6,32 @@ 0 0 - 400 - 300 + 436 + 166 Dialog - + - 30 - 240 - 341 - 32 + 9 + 9 + 66 + 17 - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + Push URL - + - 150 - 60 - 241 + 129 + 9 + 144 25 @@ -42,14 +39,76 @@ - 30 - 70 - 181 + 9 + 40 + 99 17 - Repository Name + Graphical Diff + + + + + + 129 + 40 + 144 + 25 + + + + + + + 9 + 71 + 114 + 17 + + + + Graphical Merge + + + + + + 129 + 71 + 144 + 25 + + + + + + + 129 + 102 + 90 + 22 + + + + Autosync + + + + + + 9 + 130 + 176 + 27 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok diff --git a/SettingsDialog.cpp b/SettingsDialog.cpp index d4b3d1e..d2cec00 100644 --- a/SettingsDialog.cpp +++ b/SettingsDialog.cpp @@ -2,48 +2,78 @@ #include "ui_SettingsDialog.h" #include +static QString SelectExe(QWidget *parent, const QString &description) +{ +#ifdef Q_WS_WIN + QString filter("Applications (*.exe)"); +#else + QString filter("Applications (*)"); +#endif + QString path = QFileDialog::getOpenFileName( + parent, + "Select "+description, + QString(), + filter, + &filter); + + if(!QFile::exists(path)) + return QString(); + +return path; +} + +/////////////////////////////////////////////////////////////////////////////// SettingsDialog::SettingsDialog(QWidget *parent, Settings &_settings) : QDialog(parent, Qt::Sheet), ui(new Ui::SettingsDialog), settings(&_settings) { ui->setupUi(this); - ui->lineEdit->setText(settings->fossilPath); + ui->lineFossilPath->setText(settings->fossilPath); + ui->lineGDiffCommand->setText(settings->gDiffCommand); + ui->lineGMergeCommand->setText(settings->gMergeCommand); } +//----------------------------------------------------------------------------- SettingsDialog::~SettingsDialog() { delete ui; } -void SettingsDialog::on_btnSelectFossil_clicked() -{ -#ifdef Q_WS_WIN - QString filter(tr("Fossil Executables (*.exe)")); -#else - QString filter(tr("Fossil Executables (*)")); -#endif - QString path = QFileDialog::getOpenFileName( - this, - tr("Select Fossil Executable"), - QString(), - filter, - &filter); - - if(QFile::exists(path)) - { - ui->lineEdit->setText(path) ; - } -} - - +//----------------------------------------------------------------------------- bool SettingsDialog::run(QWidget *parent, Settings &settings) { SettingsDialog dlg(parent, settings); return dlg.exec() == QDialog::Accepted; } +//----------------------------------------------------------------------------- void SettingsDialog::on_buttonBox_accepted() { - settings->fossilPath = ui->lineEdit->text(); + settings->fossilPath = ui->lineFossilPath->text(); + settings->gDiffCommand = ui->lineGDiffCommand->text(); + settings->gMergeCommand = ui->lineGMergeCommand->text(); +} +//----------------------------------------------------------------------------- +void SettingsDialog::on_btnSelectFossil_clicked() +{ + QString path = SelectExe(this, tr("Fossil executable")); + if(!path.isEmpty()) + ui->lineFossilPath->setText(path); +} + +//----------------------------------------------------------------------------- +void SettingsDialog::on_btnSelectFossilGDiff_clicked() +{ + QString path = SelectExe(this, tr("Graphical Diff application")); + if(!path.isEmpty()) + ui->lineGDiffCommand->setText(path); +} + +//----------------------------------------------------------------------------- +void SettingsDialog::on_btnSelectGMerge_clicked() +{ + QString path = SelectExe(this, tr("Graphical Merge application")); + if(!path.isEmpty()) + ui->lineGMergeCommand->setText(path); } diff --git a/SettingsDialog.h b/SettingsDialog.h index 3dcd0b6..b017344 100644 --- a/SettingsDialog.h +++ b/SettingsDialog.h @@ -10,7 +10,8 @@ namespace Ui { struct Settings { QString fossilPath; - + QString gDiffCommand; + QString gMergeCommand; }; @@ -27,8 +28,9 @@ public: private slots: void on_btnSelectFossil_clicked(); - void on_buttonBox_accepted(); + void on_btnSelectFossilGDiff_clicked(); + void on_btnSelectGMerge_clicked(); private: Ui::SettingsDialog *ui; diff --git a/SettingsDialog.ui b/SettingsDialog.ui index 5541a04..970cec7 100644 --- a/SettingsDialog.ui +++ b/SettingsDialog.ui @@ -9,8 +9,8 @@ 0 0 - 400 - 100 + 520 + 150 @@ -19,25 +19,30 @@ true - - - + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Fossil Path + + + + + - - - Fossil Path - - - - - - - true - - + + + + 0 + 0 + + ... @@ -45,7 +50,41 @@ - + + + + Graphical Diff + + + + + + + Graphical Merge + + + + + + + + + + + + + 0 + 0 + + + + ... + + + + + + Qt::Horizontal @@ -55,7 +94,31 @@ + + + + + + + + + + 0 + 0 + + + + ... + + + + + + buttonBox + label_2 + label_3 + label diff --git a/manifest b/manifest index 915db4d..982f4d3 100644 --- a/manifest +++ b/manifest @@ -1,20 +1,20 @@ -C Improved\sOSX\sGUI\n"About"\sdialog\snow\sdisplays\sthe\sfossil\sversion -D 2011-08-07T08:15:07.685 +C Dialog\srefactoring\nExtended\sthe\ssettings\sdialog\nReorganized\sthe\sworkspace\smanagement\scode\nFixed\sissue\swhere\sthe\sprevious\scurrent\sdirectory\swas\sin\seffect\seven\sin\snew\sworkspaces\nImproved\sthe\slog\sresponsiveness\son\slong\sfossil\soperations\n +D 2011-08-08T14:44:31.214 F CommitDialog.cpp a1fcdc94933f4e1a144224c7c70f1e067d3ee31e F CommitDialog.h 0550b1b652924ae54b6f6c9274cad2d4c491808a F CommitDialog.ui 5067623f6af6f5a42c87df903278e383e945e154 F FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8 F FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce F FileActionDialog.ui c63644428579741aeb5fa052e237ba799ced9ad7 -F MainWindow.cpp 80d52a1f0b9b099dde95a5be7e89f8aff869c190 -F MainWindow.h f458f469ab1b680268000553ffb917374dd3e67b -F MainWindow.ui 67ab0e7b52f0023c02406c851cdf4c267e12cedd +F MainWindow.cpp c6f682988e59727d5235fbb821e34746724b1220 +F MainWindow.h 104f575b6fffe43880849c9ce8c8b986292e4d6c +F MainWindow.ui 2f08596fe34f5496af90f6d355d4de857e77ad8a F RepoDialog.cpp 8f20e1511526973555c774350ec413dcecf51c9e F RepoDialog.h a958c5f98f1e6882bf41dbdd2e4df3cb89700802 -F RepoDialog.ui 8fe9b7f7528332ca9a45e919cf116aaf144a3286 -F SettingsDialog.cpp 4e4cd109baed184bf0d1bb506e98aebf81ca43f0 -F SettingsDialog.h 0da162b0bf9656f5ca5e6977ef669c24a44659e5 -F SettingsDialog.ui 998b2bf7cf84df8247493c0f948b4193808494cd +F RepoDialog.ui be7b18199c04a3003f3c7534a616cd7441b7bb0c +F SettingsDialog.cpp 7fdf56e25e1b9ff12369a63f8a35ecb101d51d3c +F SettingsDialog.h 9b02af204d7cf90c2fb92de50fb634fb36f179dc +F SettingsDialog.ui 9114ca5b9d8644cd0e910954c04f0425f89a960d F fuel.pro 295944fd817518c7c2412c5e52ce5ecad11dd8f8 F fuel.rc 8e9ac966f283102c11a77cd7f936cdc09e09bd79 F icons/Address\sBook-01.png ef2cec80ea5a559b72e8be4a344a1869fe69cbd8 @@ -173,7 +173,7 @@ F icons/fuel.icns 81e535004b62db801a02f3e15d0a33afc9d4070b F icons/fuel.ico eb529ab3332a17b9302ef3e851db5b9ebce2a038 F main.cpp 360c3ec843cd72dcaf735b7fb6f51f5639830959 F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53 -P dbb036dbd2c7e2a34fae27e2a39bddf2168ab83d -R d953e0a12899c0c5f8173cdd242461fe +P 81e1f4c7ec00176abd9d467add266f84b0e63059 +R ea0388f9e4683051a59d562c7fbdaf7c U kostas -Z f2b518bc85eac6f6d5652326d3dcd962 +Z 1ba1cb23226ee30525026ffe7669a4da diff --git a/manifest.uuid b/manifest.uuid index 040991b..7bef897 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81e1f4c7ec00176abd9d467add266f84b0e63059 \ No newline at end of file +945c841fba73be1355611554499e68a878b95359 \ No newline at end of file