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