# # # patch "guitone/res/forms/main_window.ui" # from [34f23a7be62f106aa0ff21ed5cc936a6f0e62495] # to [9bba67503299628052d9503b88909fec0aa4d7ab] # # patch "guitone/res/i18n/guitone_de.ts" # from [83840573c9977cf20324c545c022e06d18ee8d97] # to [60fe3c5152a9fe7a0b82931f987a79c0263fdedd] # # patch "guitone/src/Guitone.cpp" # from [a48983b8fc37521f84ddf65367a198b9d516ede8] # to [b24e64854e45ef0832b72a299e1982c6af971fb2] # # patch "guitone/src/Guitone.h" # from [3d3bd25f8214e1781dbd3adbdaa23cee3ad10b4e] # to [b59a496010ede1bd51b8144c825fdd064e157a5e] # # patch "guitone/src/main.cpp" # from [7d3deba4170d9e0d60b58b8abdd19c253a7eae0c] # to [8ada0d2863004cf71e52119f283830d39e16b559] # # patch "guitone/src/model/ChangesetModel.cpp" # from [4d2f708a0de95674dec1b8782b8c09ba6b579496] # to [ec8370e95da1e93a5afa5c5c8989dc7d7c3e770a] # # patch "guitone/src/model/ContentDiff.cpp" # from [4cb868e9bf2d592db68a2988e25100cfb961a40e] # to [a9484b88510acf80d61fae0b0cf4d58889074dec] # # patch "guitone/src/model/GetFile.cpp" # from [847161c06efe93bed700432f94b5e358b8d62ebf] # to [0339733a560c651996c0901285d8fb671738e971] # # patch "guitone/src/model/Inventory.cpp" # from [27456152285ea14d09b7fe5efb57882a12d33e31] # to [58d0e21effeff5955284a02e3d08f5f64d750e1e] # # patch "guitone/src/model/MonotoneDelegate.cpp" # from [4ebb6a0e87914d4dbe4b3e68be5b206661c08e49] # to [caed1e6b526214e088d5fd7cfc18132b502cb395] # # patch "guitone/src/monotone/Monotone.cpp" # from [67695c80ab3235132e5ef09938b17ff9f9c41dc1] # to [8a6cdf66ffed1707f9cbd7edeac076d02fb611dd] # # patch "guitone/src/monotone/Monotone.h" # from [acbb4071e26433ba787703de88d9a8b67425eaa5] # to [8e3e6a9750e2ce4b0c5c42fa20d13a505eb43015] # # patch "guitone/src/view/InventoryView.cpp" # from [dc7b20564cdc3bd26e1dd4f498729f15198509f1] # to [692c80b1d24969ff915206b9c715e11c9f0eff52] # # patch "guitone/src/view/MainWindow.cpp" # from [aec19809367c4f89bb4dccf524f35dd8ed108c0f] # to [86d7eebe192976754605003e2a4ec2846a3e3ef4] # # patch "guitone/src/view/dialogs/Dialog.cpp" # from [dafd6a6a4cde4a53164b001665d0bf1fe3b6c007] # to [8d60a12cf4e2cd831b21f95508644908b908fd65] # # patch "guitone/src/view/dialogs/GenerateKeypair.cpp" # from [c28127273be56000aa5799437874a633c408b2a0] # to [0de4a596c8a54d9425853b89291c8084ccbecdad] # # patch "guitone/src/view/dialogs/RevisionManifest.cpp" # from [87c413184dee30b528d784b2f67d448d45f10ff7] # to [6618e4735bfb185c6b262ed646b0b0d83fa65e3c] # ============================================================ --- guitone/res/forms/main_window.ui 34f23a7be62f106aa0ff21ed5cc936a6f0e62495 +++ guitone/res/forms/main_window.ui 9bba67503299628052d9503b88909fec0aa4d7ab @@ -128,13 +128,6 @@ You can switch back to the workspace mod 22 - - - Help - - - - Database @@ -202,10 +195,25 @@ You can switch back to the workspace mod + + + Help + + + + + + + Window + + + + + @@ -438,19 +446,24 @@ You can switch back to the workspace mod Ctrl+W + + + Bring all to front + + - InventoryView - QTreeView -
../InventoryView.h
-
- Splitter QSplitter
../Splitter.h
+ InventoryView + QTreeView +
../InventoryView.h
+
+ AttributesView QTreeView
../AttributesView.h
============================================================ --- guitone/res/i18n/guitone_de.ts 83840573c9977cf20324c545c022e06d18ee8d97 +++ guitone/res/i18n/guitone_de.ts 60fe3c5152a9fe7a0b82931f987a79c0263fdedd @@ -7,6 +7,16 @@ Critical Monotone Error Kritischer monotone-Fehler + + + Error + Fehler + + + + The path to the monotone binary is either invalid or points to an older version of monotone. Guitone requires monotone version %1 or a monotone with interface version %2 or later. + Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt monotone Version %1 oder ein monotone mit einer Interface-Version %2 oder neuer. + About @@ -144,22 +154,22 @@ ChangesetModel - + Revision ID Revisions-ID - + Date Datum - + Author Autor - + Changelog @@ -334,17 +344,17 @@ Guitone - + Error Fehler - + The path to the monotone binary is either invalid or points to an older version of monotone. Guitone requires monotone version %1 or a monotone with interface version %2 or later. Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt monotone Version %1 oder ein monotone mit einer Interface-Version %2 oder neuer. - + Critical Monotone Error Kritischer monotone-Fehler @@ -410,102 +420,102 @@ InventoryView - + &Add &Hinzufügen - + Add to workspace Zum Arbeitsbereich hinzufügen - + &Remove En&tfernen - + Remove from workspace Vom Arbeitsbereich entfernen - + &Commit &Einpflegen - + Commit Einpflegen - + I&gnore Datei &ignorieren - + Ignore file Datei ignorieren - + &Unignore Datei nicht ign&orieren - + Unignore file Datei nicht mehr ignorieren - + R&evert &Zurücksetzen - + Revert uncommitted changes Nicht eingepflegte Änderungen verwerfen - + Rena&me Um&benennen - + Rename file Datei umbenennen - + D&iff U&nterschiede anzeigen - + Diff against base revision Unterschiede im Vergleich zur Basisrevision anzeigen - + &Go into &Wechseln zu - + Go into the directory Wechsle in das Verzeichnis - + &Open &Öffnen - + Open in default program In Standardprogramm öffnen @@ -525,12 +535,12 @@ Kann keine Dateien auf Ihrer Plattform öffnen - bitte kontaktieren Sie den Autor über dieses Problem. - + D&iff all Alle U&nterschiede anzeigen - + Show all differences Zeigt Unterschiede in allen Dateien @@ -619,207 +629,207 @@ MainWindow - + View Ansicht - + Help Hilfe - + Workspace Arbeitsbereich - + File Datei - + Recent Workspaces Vorherige Arbeitsbereiche - + Open Workspace Arbeitsbereich öffnen - + Ctrl+O Strg+O - + No previous workspaces available. Keine vorherigen Arbeitsbereiche verfügbar. - + Preferences.... Einstellungen... - + Ctrl+P Strg+P - + Quit Beenden - + Ctrl+Q Strg+Q - + Hide ignored files Ignorierte Dateien verstecken - + Ctrl+H Strg+H - + All files Alle Dateien - + A A - + All changed files Alle geänderten Dateien - + C G - + Patched files Inhaltlich geänderte Dateien - + P P - + Added files Hinzugefügte Dateien - + N H - + Removed files Entfernte Dateien - + D E - + Renamed files Umbenannte Dateien - + R U - + Missing files Fehlende Dateien - + M F - + Unknown files Unbekannte Dateien - + U K - + Ignored files Ignorierte Dateien - + I I - + Expand tree Baum aufklappen - + Ctrl+T Strg+T - + Switch revision Revision wechseln - + Ctrl+R Strg+R - + Key management Schlüsselverwaltung - + Ctrl+K Strg+K - + About Qt Über Qt - + About guitone Über guitone - + Show Zeige @@ -839,34 +849,34 @@ Kritischer monotone-Fehler - + Select your workspace... Wählen Sie Ihren Arbeitsbereich aus... - + Loading aborted Laden abgebrochen - + Invalid workspace Ungültiger Arbeitsbereich - + The chosen directory is no monotone workspace! Das gewählte Verzeichnis ist kein monotone-Arbeitsverzeichnis! - + Unable to execute command - Konnte Kommando nicht ausführen + Konnte Kommando nicht ausführen - + Unable to execute '%1' - maybe another command is still running? - Konnte '%1' nicht ausführen - eventuell läuft noch ein anderes Kommando? + Konnte '%1' nicht ausführen - eventuell läuft noch ein anderes Kommando? @@ -874,17 +884,17 @@ Lade Arbeitsbereich... - + Show ignored files Zeige ignorierte Dateien - + Collapse tree Baum zuklappen - + &%1 %2 &%1 %2 @@ -894,57 +904,57 @@ Der Pfad zur ausführbaren Datei von monotone ist entweder ungültig oder zeigt auf eine ältere Version von monotone. Guitone benötigt monotone Version %1 oder ein monotone mit einer Interface-Version %2 oder neuer. - + Recent Databases Vorherige Datenbanken - + Open Database Datenbank öffnen - + No previous databases available. Keine vorherigen geöffneten Datenbanken verfügbar. - + Database Datenbank - + Ctrl+Shift+O Strg+Shift+O - + Loaded database: %1 Geladene Datenbank: %1 - + Select your database... Wählen Sie eine Datenbank aus... - + monotone Databases (*.mtn *.db) monotone-Datenbanken (*.mtn *.db) - + No database loaded Keine Datenbank geladen - + Ctrl+B Strg+B - + Changeset browser Änderungen-Browser @@ -956,15 +966,25 @@ Sie können zum Arbeitsbereich-Modus jed Sie können zum Arbeitsbereich-Modus jederzeit zurückkehren, indem Sie einen Arbeitsbereich laden. - + Close Schließen - + Ctrl+W + + + Window + + + + + Bring all to front + + Manifest @@ -1016,7 +1036,7 @@ monotone gab zurück: %2 - + The monotone process exited unexpectedly (return code %1). Please reconfigure the path to the monotone binary in the Preferences dialog or check if the version of the database you try to load matches the monotone version you are using. monotone returned: @@ -1131,22 +1151,22 @@ monotone gab zurück: QShortcut - + Ctrl Strg - + Shift Umschalt - + Alt Alt - + Meta Meta ============================================================ --- guitone/src/Guitone.cpp a48983b8fc37521f84ddf65367a198b9d516ede8 +++ guitone/src/Guitone.cpp b24e64854e45ef0832b72a299e1982c6af971fb2 @@ -30,6 +30,7 @@ #include #include #include +#include void guitoneMsgHandler(QtMsgType type, const char *msg) { @@ -56,8 +57,6 @@ Guitone::Guitone(int argc, char** argv) setQuitOnLastWindowClosed(false); - gotError = false; - setOrganizationName("Thomas Keller"); setOrganizationDomain("thomaskeller.biz"); setApplicationName("guitone"); @@ -71,65 +70,48 @@ Guitone::Guitone(int argc, char** argv) { installTranslator(&translator); } - - Monotone * mtn = Monotone::singleton(this); - - // catch critical errors from the Monotone class - connect( - mtn, SIGNAL(criticalError(const QString &)), - this, SLOT(criticalMtnError(const QString &)) - ); - - // check the current monotone version and prompt the user - // to enter the correct path if there is a problem - if (!mtn->setMtnBinaryPath(Settings::getMtnBinaryPath())) + else { - QMessageBox::critical( - NULL, - tr("Error"), - tr("The path to the monotone binary is either invalid " - "or points to an older version of monotone. " - "Guitone requires monotone version %1 " - "or a monotone with interface version %2 or later.") - .arg(Monotone::RequiredProgramVersion) - .arg(Monotone::RequiredInterfaceVersion), - QMessageBox::Ok, 0, 0 - ); - - Preferences dialog(NULL); - if (dialog.exec() == QDialog::Rejected) - { - return; - } + qWarning("Guitone::Guitone: Couldn't load translation file " + "for %s - using default", qPrintable(locale)); } +} +bool Guitone::init() +{ MainWindow * mainWnd = addWindow(); + if (!addMonotoneInstance(mainWnd)) + { + qWarning("Guitone::init: couldn't initialize monotone"); + removeWindow(mainWnd); + return false; + } mainWnd->loadRecent(); mainWnd->show(); + return true; } -Guitone::~Guitone() {} +Guitone::~Guitone() +{ + Q_ASSERT(openWindows.size() == 0); + Q_ASSERT(monotoneInstances.size() == 0); +} void Guitone::criticalMtnError(const QString & msg) { - if (gotError == false) - { - gotError = true; - - // restore the normal cursor - restoreOverrideCursor(); - - QMessageBox::critical(NULL, tr("Critical Monotone Error"), - msg, QMessageBox::Ok, 0, 0); - - // TODO: we should disable all views now, or what? - } + // restore the normal cursor + restoreOverrideCursor(); + + QMessageBox::critical(NULL, tr("Critical Monotone Error"), + msg, QMessageBox::Ok, 0, 0); + + // TODO: shall we remove the errornous window? } void Guitone::loadWorkspace(const QString & path) { MainWindow * wnd = addWindow(); - if (!wnd->doLoadWorkspace(path)) + if (!addMonotoneInstance(wnd) || !wnd->doLoadWorkspace(path)) { removeWindow(wnd); return; @@ -140,7 +122,7 @@ void Guitone::loadDatabase(const QString void Guitone::loadDatabase(const QString & path) { MainWindow * wnd = addWindow(); - if (!wnd->doLoadDatabase(path)) + if (!addMonotoneInstance(wnd) || !wnd->doLoadDatabase(path)) { removeWindow(wnd); return; @@ -150,8 +132,12 @@ void Guitone::windowClosed(MainWindow * void Guitone::windowClosed(MainWindow * wnd) { + removeMonotoneInstance(wnd); removeWindow(wnd); - if (openWindows.size() == 0) quit(); + if (openWindows.size() == 0) + { + QTimer::singleShot(0, this, SLOT(quit())); + } } MainWindow * Guitone::addWindow() @@ -160,12 +146,46 @@ MainWindow * Guitone::addWindow() MainWindow * wnd = new MainWindow(); + // ensure somewhat that new windows do not overdraw current ones + // by adding a little x/y offset to the original position + if (openWindows.size() > 0) + { + MainWindow * lastWnd = openWindows.last(); + QDesktopWidget * desk = desktop(); + + if (desk->numScreens() > 1) + { + qWarning("Guitone::addWindow: No support for window cascading " + "on systems with more than one monitor yet."); + } + else + { + int cascade = 20; + QRect geom = desk->availableGeometry(); + int newX = lastWnd->x() + cascade; + int newY = lastWnd->y() + cascade; + + if (newX + wnd->width() > geom.right() || + newY + wnd->height() > geom.bottom()) + { + newX = geom.x(); + newY = geom.y(); + } + wnd->move(newX, newY); + } + } + connect( wnd, SIGNAL(quitApplication()), this, SLOT(quit()) ); connect( + wnd, SIGNAL(windowClosed(MainWindow *)), + this, SLOT(windowClosed(MainWindow *)) + ); + + connect( wnd, SIGNAL(loadWorkspace(const QString &)), this, SLOT(loadWorkspace(const QString &)) ); @@ -198,7 +218,7 @@ MainWindow * Guitone::addWindow() wnd, SLOT(doUpdatePreviousDatabasesMenu()) ); } - + openWindows.append(wnd); return wnd; @@ -218,6 +238,11 @@ void Guitone::removeWindow(MainWindow * ); disconnect( + wnd, SIGNAL(windowClosed(MainWindow *)), + this, SLOT(windowClosed(MainWindow *)) + ); + + disconnect( wnd, SIGNAL(loadWorkspace(const QString &)), this, SLOT(loadWorkspace(const QString &)) ); @@ -259,9 +284,86 @@ void Guitone::quit() Settings::sync(); // close all open windows - for (int i=0, j=openWindows.size(); isetMtnBinaryPath(Settings::getMtnBinaryPath())) break; + + QMessageBox::critical( + wnd, + tr("Error"), + tr("The path to the monotone binary is either invalid " + "or points to an older version of monotone. " + "Guitone requires monotone version %1 " + "or a monotone with interface version %2 or later.") + .arg(Monotone::RequiredProgramVersion) + .arg(Monotone::RequiredInterfaceVersion), + QMessageBox::Ok, 0, 0 + ); + + Preferences dialog(wnd); + + // if new settings have been entered, try to setup the wrapper + if (dialog.exec() == QDialog::Accepted) continue; + + // the user has rejected the dialog, i.e. made no new settings + return false; + } + + monotoneInstances.insert(wnd, mtn); + + return true; +} + +bool Guitone::removeMonotoneInstance(MainWindow * wnd) +{ + if (!monotoneInstances.contains(wnd)) return false; + + Monotone * mtn = monotoneInstances.value(wnd); + + disconnect( + mtn, SIGNAL(criticalError(const QString &)), + this, SLOT(criticalMtnError(const QString &)) + ); + + delete mtn; + monotoneInstances.remove(wnd); + + return true; +} + +Monotone * Guitone::monotoneInstance(QObject * obj) +{ + do + { + if (obj->inherits("MainWindow")) break; + obj = obj->parent(); + } while (obj); + + Q_ASSERT(obj); + + MainWindow * wnd = qobject_cast(obj); + Q_ASSERT(monotoneInstances.contains(wnd)); + return monotoneInstances.value(wnd); +} + ============================================================ --- guitone/src/Guitone.h 3d3bd25f8214e1781dbd3adbdaa23cee3ad10b4e +++ guitone/src/Guitone.h b59a496010ede1bd51b8144c825fdd064e157a5e @@ -21,10 +21,15 @@ #ifndef GUITONE_H #define GUITONE_H +#define APP reinterpret_cast(qApp) +#define MTN(arg) APP->monotoneInstance(arg) + #include "MainWindow.h" +#include "Monotone.h" #include #include +#include #include class Guitone : public QApplication @@ -33,8 +38,11 @@ public: public: Guitone(int, char**); - ~Guitone(); - + ~Guitone(); + bool init(); + + Monotone * monotoneInstance(QObject *); + private slots: void criticalMtnError(const QString &); void loadWorkspace(const QString &); @@ -45,9 +53,12 @@ private: private: MainWindow * addWindow(); void removeWindow(MainWindow *); + + bool addMonotoneInstance(MainWindow *); + bool removeMonotoneInstance(MainWindow *); - bool gotError; - QList openWindows; + QList openWindows; + QMap monotoneInstances; QMutex lock; }; ============================================================ --- guitone/src/main.cpp 7d3deba4170d9e0d60b58b8abdd19c253a7eae0c +++ guitone/src/main.cpp 8ada0d2863004cf71e52119f283830d39e16b559 @@ -22,7 +22,8 @@ int main(int argc, char** argv) int main(int argc, char** argv) { - Guitone app(argc,argv); + Guitone app(argc, argv); + if (!app.init()) return 1; return app.exec(); } ============================================================ --- guitone/src/model/ChangesetModel.cpp 4d2f708a0de95674dec1b8782b8c09ba6b579496 +++ guitone/src/model/ChangesetModel.cpp ec8370e95da1e93a5afa5c5c8989dc7d7c3e770a @@ -24,102 +24,103 @@ ChangesetModel::ChangesetModel(QObject * ChangesetModel::ChangesetModel(QObject *parent) : QAbstractItemModel(parent) { - currentBranch = ""; + currentBranch = ""; } ChangesetModel::~ChangesetModel() {} void ChangesetModel::receiveRevisions(bool all) { - int i = branchMap[currentBranch].certsRead; - int to = branchMap[currentBranch].revisions.count(); - int c = 0; - while(i < to && (c < revPerReceive || all)) - { - QString revision = branchMap[currentBranch].revisions[i]; - - if(changesetMap[revision] == NULL) - { - ChangesetCerts *certs = new ChangesetCerts(currentBranch, revision, i, this); - certs->readCerts(revision); - c++; - } - i++; - } + int i = branchMap[currentBranch].certsRead; + int to = branchMap[currentBranch].revisions.count(); + int c = 0; + while(i < to && (c < revPerReceive || all)) + { + QString revision = branchMap[currentBranch].revisions[i]; + + if(changesetMap[revision] == NULL) + { + ChangesetCerts *certs = new ChangesetCerts(currentBranch, revision, i, this); + certs->readCerts(revision); + c++; + } + i++; + } } void ChangesetModel::setBranch(QString branch) { - currentBranch = branch; - BranchInfo *branchInfo = &branchMap[currentBranch]; - if(branchInfo->revisions.count() == 0) - { - branchInfo->certsRead = 0; - GetBranchLog *glog = new GetBranchLog(branch, this); - } - else - reset(); + currentBranch = branch; + BranchInfo *branchInfo = &branchMap[currentBranch]; + if(branchInfo->revisions.count() == 0) + { + branchInfo->certsRead = 0; + GetBranchLog *glog = new GetBranchLog(branch, this); + Q_UNUSED(glog); + } + else + reset(); } void ChangesetModel::branchLogRead(GetBranchLog *glog) { - QString branch = glog->getBranch(); - branchMap[branch].revisions << glog->getRevisions(); - if(branch == currentBranch) - { - receiveRevisions(false); - } - delete glog; + QString branch = glog->getBranch(); + branchMap[branch].revisions << glog->getRevisions(); + if(branch == currentBranch) + { + receiveRevisions(false); + } + delete glog; } void ChangesetModel::changesetCertReady(ChangesetCerts *cert) { - QDateTime date; - QString author; - QString changelog; - QString key; - QString value; - int rows = cert->rowCount(QModelIndex()); - for(int i = 0; i < rows; i++) - { - key = cert->data(cert->index(i, 1, QModelIndex()), Qt::DisplayRole).toString(); - value = cert->data(cert->index(i, 2, QModelIndex()), Qt::DisplayRole).toString(); - if(key == "author") - { - author = value; - continue; - } - if(key == "changelog") - { - changelog = value; - continue; - } - if(key == "date") - { - date = QDateTime::fromString(value, "yyyy-MM-ddThh:mm:ss"); - continue; - } - } - Changeset *set = new Changeset(cert->getRevision(), date, author, changelog); - changesetMap[cert->getRevision()] = set; - int idx = cert->getIndex(); - branchMap[currentBranch].certsRead = idx; - beginInsertRows(QModelIndex(), idx, idx); - endInsertRows(); - delete cert; + QDateTime date; + QString author; + QString changelog; + QString key; + QString value; + int rows = cert->rowCount(QModelIndex()); + for(int i = 0; i < rows; i++) + { + key = cert->data(cert->index(i, 1, QModelIndex()), Qt::DisplayRole).toString(); + value = cert->data(cert->index(i, 2, QModelIndex()), Qt::DisplayRole).toString(); + if(key == "author") + { + author = value; + continue; + } + if(key == "changelog") + { + changelog = value; + continue; + } + if(key == "date") + { + date = QDateTime::fromString(value, "yyyy-MM-ddThh:mm:ss"); + continue; + } + } + Changeset *set = new Changeset(cert->getRevision(), date, author, changelog); + changesetMap[cert->getRevision()] = set; + int idx = cert->getIndex(); + branchMap[currentBranch].certsRead = idx; + beginInsertRows(QModelIndex(), idx, idx); + endInsertRows(); + delete cert; } int ChangesetModel::columnCount(const QModelIndex &parent) const { - return 4; + return 4; } QVariant ChangesetModel::data(const QModelIndex &index, int role) const { - if (!index.isValid()) - { - return QVariant(); - } + if (!index.isValid()) + { + return QVariant(); + } if (role == Qt::FontRole) { @@ -130,29 +131,29 @@ QVariant ChangesetModel::data(const QMod } if (role == Qt::DisplayRole) - { - BranchInfo branchInfo = branchMap[currentBranch]; + { + BranchInfo branchInfo = branchMap[currentBranch]; int row = index.row(); - if (branchInfo.revisions.count() > row) - { - int col = index.column(); - QString rev = branchInfo.revisions[row]; - if(changesetMap[rev] == NULL) return QVariant(); - switch(col) - { - case(0): - return QVariant(changesetMap[rev]->getDate()); - case(1): - return QVariant(changesetMap[rev]->getAuthor()); - case(2): - return QVariant(changesetMap[rev]->getChangelogFlat()); - case(3): - return QVariant(rev); - } - } + if (branchInfo.revisions.count() > row) + { + int col = index.column(); + QString rev = branchInfo.revisions[row]; + if(changesetMap[rev] == NULL) return QVariant(); + switch(col) + { + case(0): + return QVariant(changesetMap[rev]->getDate()); + case(1): + return QVariant(changesetMap[rev]->getAuthor()); + case(2): + return QVariant(changesetMap[rev]->getChangelogFlat()); + case(3): + return QVariant(rev); + } + } } - return QVariant(); + return QVariant(); } Qt::ItemFlags ChangesetModel::flags(const QModelIndex &index) const @@ -166,30 +167,30 @@ QVariant ChangesetModel::headerData(int QVariant ChangesetModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) - { - switch(section) - { - case(0): - return QVariant(tr("Date")); - case(1): - return QVariant(tr("Author")); - case(2): - return QVariant(tr("Changelog")); - case(3): - return QVariant(tr("Revision ID")); - } + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + switch(section) + { + case(0): + return QVariant(tr("Date")); + case(1): + return QVariant(tr("Author")); + case(2): + return QVariant(tr("Changelog")); + case(3): + return QVariant(tr("Revision ID")); + } } return QVariant(); } int ChangesetModel::rowCount(const QModelIndex& parent) const { - int i = branchMap[currentBranch].certsRead; - if (!parent.isValid()) - if(branchMap[currentBranch].revisions.count() != 0) - return i; - return 0; + int i = branchMap[currentBranch].certsRead; + if (!parent.isValid()) + if(branchMap[currentBranch].revisions.count() != 0) + return i; + return 0; } QModelIndex ChangesetModel::index(int row, int column, const QModelIndex& parent) const ============================================================ --- guitone/src/model/ContentDiff.cpp 4cb868e9bf2d592db68a2988e25100cfb961a40e +++ guitone/src/model/ContentDiff.cpp a9484b88510acf80d61fae0b0cf4d58889074dec @@ -19,7 +19,7 @@ ***************************************************************************/ #include "ContentDiff.h" -#include "Monotone.h" +#include "Guitone.h" #include #include @@ -56,7 +56,7 @@ bool ContentDiff::readDiff( // reset the view reset(); - Monotone *mtn = Monotone::singleton(); + Monotone * mtn = MTN(this); QStringList cmd; cmd << "content_diff" << fileName; ============================================================ --- guitone/src/model/GetFile.cpp 847161c06efe93bed700432f94b5e358b8d62ebf +++ guitone/src/model/GetFile.cpp 0339733a560c651996c0901285d8fb671738e971 @@ -19,7 +19,7 @@ ***************************************************************************/ #include "GetFile.h" -#include "Monotone.h" +#include "Guitone.h" #include #include @@ -35,7 +35,7 @@ bool GetFile::readFileByName(QString fil bool GetFile::readFileByName(QString fileName) { - Monotone * mtn = Monotone::singleton(); + Monotone * mtn = MTN(this); int commandNumber; QStringList cmd; ============================================================ --- guitone/src/model/Inventory.cpp 27456152285ea14d09b7fe5efb57882a12d33e31 +++ guitone/src/model/Inventory.cpp 58d0e21effeff5955284a02e3d08f5f64d750e1e @@ -20,7 +20,7 @@ #include "Inventory.h" #include "InventoryItem.h" -#include "Monotone.h" +#include "Guitone.h" #include "IconProvider.h" #include @@ -117,8 +117,7 @@ void Inventory::parseOutput() // FIXME: we shouldn't really add a workspace root item here, but // mtn automate inventory currently doesn't print the root workspace dir InventoryItem* workspace = new InventoryItem(rootItem, ".", 0, true, true); - Monotone * mtn = Monotone::singleton(); - workspace->setLabel(mtn->getNormalizedWorkspacePath()); + workspace->setLabel(MTN(this)->getNormalizedWorkspacePath()); rootItem->appendChild(workspace); workspace->setChildren(buildTreeRecursive(tempItems, NULL)); ============================================================ --- guitone/src/model/MonotoneDelegate.cpp 4ebb6a0e87914d4dbe4b3e68be5b206661c08e49 +++ guitone/src/model/MonotoneDelegate.cpp caed1e6b526214e088d5fd7cfc18132b502cb395 @@ -20,9 +20,8 @@ #include "MonotoneDelegate.h" #include "Monotone.h" +#include "Guitone.h" -#include - MonotoneDelegate::MonotoneDelegate(AutomateCommand * cmd) : cmdModel(cmd), commandNumber(-1) { @@ -37,21 +36,25 @@ bool MonotoneDelegate::triggerCommand(co bool MonotoneDelegate::triggerCommand(const QStringList & cmd, const QStringList & opts) { - Monotone * mtn = Monotone::singleton(); + QObject * obj = dynamic_cast(cmdModel); + Q_ASSERT(obj); + Monotone * mtn = MTN(obj); connect( mtn, SIGNAL(commandFinished()), this, SLOT(commandFinished()) ); - qApp->setOverrideCursor(Qt::WaitCursor); + APP->setOverrideCursor(Qt::WaitCursor); return mtn->triggerCommand(cmd, opts, commandNumber); } void MonotoneDelegate::commandFinished() { - Monotone * mtn = Monotone::singleton(); + QObject * obj = dynamic_cast(cmdModel); + Q_ASSERT(obj); + Monotone * mtn = MTN(obj); // check if this is the command which is interesting for us if (!mtn->isCommandFinished(commandNumber)) return; @@ -77,6 +80,6 @@ void MonotoneDelegate::commandFinished() } } - qApp->restoreOverrideCursor(); + APP->restoreOverrideCursor(); } ============================================================ --- guitone/src/monotone/Monotone.cpp 67695c80ab3235132e5ef09938b17ff9f9c41dc1 +++ guitone/src/monotone/Monotone.cpp 8a6cdf66ffed1707f9cbd7edeac076d02fb611dd @@ -82,8 +82,6 @@ #include #include -Monotone* Monotone::instance = 0; - // // this should be understood as either/or: // - if the program version is sufficient, everything is fine @@ -117,13 +115,6 @@ Monotone::~Monotone() shutdownCurrentProcess(); } -Monotone* Monotone::singleton(QObject * parent) -{ - // create a new instance if there is no instance - if (instance == 0) { instance = new Monotone(parent); } - return instance; -} - bool Monotone::normalizeWorkspacePath(QString & workspace) const { QDir tempDir(workspace); ============================================================ --- guitone/src/monotone/Monotone.h acbb4071e26433ba787703de88d9a8b67425eaa5 +++ guitone/src/monotone/Monotone.h 8e3e6a9750e2ce4b0c5c42fa20d13a505eb43015 @@ -31,7 +31,6 @@ class Monotone : public QObject Q_OBJECT public: - static Monotone* singleton(QObject * parent = 0); static bool runCommand(const QString &, const QStringList &, QString &); static bool checkProgramVersion(const QString &); static bool checkInterfaceVersion(const QString &); @@ -41,10 +40,12 @@ class Monotone : public QObject static const int StdioBufferSize; static const int WaitForMonotoneStart; + Monotone(QObject *); + virtual ~Monotone(); + bool loadWorkspace(QString); bool loadDatabase(QString); bool setMtnBinaryPath(const QString &); - virtual ~Monotone(); QString getNormalizedWorkspacePath() const; QString getDatabaseFilePath() const; @@ -62,8 +63,6 @@ class Monotone : public QObject private: enum Mode { Workspace, Database } mode; - Monotone(QObject *); - bool normalizeWorkspacePath(QString &) const; bool setupNewCommand(); void setupNewProcess(); @@ -75,7 +74,6 @@ class Monotone : public QObject QMap completedCommands; int commandCounter; bool isCleanExit; - static Monotone* instance; QProcess * process; QString workDir; QString databaseFile; ============================================================ --- guitone/src/view/InventoryView.cpp dc7b20564cdc3bd26e1dd4f498729f15198509f1 +++ guitone/src/view/InventoryView.cpp 692c80b1d24969ff915206b9c715e11c9f0eff52 @@ -25,6 +25,7 @@ #include "Monotone.h" #include "FileDiff.h" #include "RevisionDiff.h" +#include "Guitone.h" #include #include @@ -316,8 +317,7 @@ void InventoryView::slotOpen(void) InventoryItem * item = static_cast(index.internalPointer()); - Monotone * mtn = Monotone::singleton(); - QFileInfo file(mtn->getNormalizedWorkspacePath() + "/" + item->getPath()); + QFileInfo file(MTN(this)->getNormalizedWorkspacePath() + "/" + item->getPath()); if (!file.exists()) { ============================================================ --- guitone/src/view/MainWindow.cpp aec19809367c4f89bb4dccf524f35dd8ed108c0f +++ guitone/src/view/MainWindow.cpp 86d7eebe192976754605003e2a4ec2846a3e3ef4 @@ -33,6 +33,7 @@ #include "About.h" #include "Settings.h" #include "DatabaseView.h" +#include "Guitone.h" #include #include @@ -97,9 +98,19 @@ MainWindow::MainWindow() this, SIGNAL(quitApplication()) ); - // load recent workspace and database lists - updatePreviousWorkspacesMenu(); - updatePreviousDatabasesMenu(); + // update recent workspace and database lists on request + connect( + this, SIGNAL(updatePreviousWorkspacesMenu()), + this, SLOT(doUpdatePreviousWorkspacesMenu()) + ); + + connect( + this, SIGNAL(updatePreviousDatabasesMenu()), + this, SLOT(doUpdatePreviousDatabasesMenu()) + ); + + doUpdatePreviousWorkspacesMenu(); + doUpdatePreviousDatabasesMenu(); // set the data for some menu elements actionAll_files->setData(QVariant(InventoryProxyModel::All)); @@ -157,7 +168,7 @@ bool MainWindow::doLoadWorkspace(QString bool MainWindow::doLoadWorkspace(QString fn) { - Monotone * mtn = Monotone::singleton(); + Monotone * mtn = MTN(this); if (!mtn->loadWorkspace(fn)) { @@ -178,6 +189,17 @@ bool MainWindow::doLoadWorkspace(QString switchMode(Workspace); + if (!invModel->readInventory()) + { + QMessageBox::information( + this, + tr("Unable to execute command"), + tr("Unable to execute '%1' - maybe another command is still running?").arg("inventory"), + QMessageBox::Ok + ); + return false; + } + // add the workspace to the recent workspace list // FIXME: the amount of recent workspaces should be made configurable Settings::addItemToList("RecentWorkspaceList", mtn->getNormalizedWorkspacePath(), 5); @@ -215,10 +237,9 @@ bool MainWindow::doLoadDatabase(QString bool MainWindow::doLoadDatabase(QString fn) { - Monotone * mtn = Monotone::singleton(); // FIXME: currently a database is always loaded, but not checked // so this condition can actually never be false - if (!mtn->loadDatabase(fn)) + if (!MTN(this)->loadDatabase(fn)) { qDebug("Could not load database."); // remove the workspace if it was recorded as recent workspace @@ -248,8 +269,9 @@ void MainWindow::switchMode(Mode m) menuView->menuAction()->setVisible(false); menuWorkspace->menuAction()->setVisible(false); menuDatabase->menuAction()->setVisible(true); - Monotone * mtn = Monotone::singleton(); - loadedDatabase->setText(tr("Loaded database: %1").arg(mtn->getDatabaseFilePath())); + loadedDatabase->setText(tr("Loaded database: %1").arg( + MTN(this)->getDatabaseFilePath()) + ); } else if (mode == Workspace) ============================================================ --- guitone/src/view/dialogs/Dialog.cpp dafd6a6a4cde4a53164b001665d0bf1fe3b6c007 +++ guitone/src/view/dialogs/Dialog.cpp 8d60a12cf4e2cd831b21f95508644908b908fd65 @@ -22,6 +22,9 @@ #include "Settings.h" #include "SignalWaiter.h" +#include +#include + Dialog::Dialog(QWidget* parent) : QDialog(parent) { setAttribute(Qt::WA_MacMetalStyle); @@ -62,9 +65,19 @@ int Dialog::execDocumentModal() // http://doc.trolltech.com/qq/qq18-macfeatures.html int Dialog::execDocumentModal() { + // ensure that this is only called from top level windows + Q_ASSERT(parent()->inherits("QMainWindow")); + + // FIXME: for some unknown reason this does _not_ disable the menubar + // completly on OSX - is this a bug or are we doing something wrong? + qobject_cast(parent())->menuBar()->setEnabled(false); + show(); SignalWaiter waiter(this, SIGNAL(finished(int))); waiter.wait(); + + qobject_cast(parent())->menuBar()->setEnabled(true); + return result(); } ============================================================ --- guitone/src/view/dialogs/GenerateKeypair.cpp c28127273be56000aa5799437874a633c408b2a0 +++ guitone/src/view/dialogs/GenerateKeypair.cpp 0de4a596c8a54d9425853b89291c8084ccbecdad @@ -19,7 +19,7 @@ ***************************************************************************/ #include "GenerateKeypair.h" -#include "Monotone.h" +#include "Guitone.h" #include #include @@ -63,7 +63,7 @@ void GenerateKeypair::accept() QStringList cmd; cmd << "genkey" << lineKeyName->text() << lineKeyPasswd->text(); - Monotone * mtn = Monotone::singleton(); + Monotone * mtn = MTN(this); if (!mtn->executeCommand(cmd, commandNumber)) { ============================================================ --- guitone/src/view/dialogs/RevisionManifest.cpp 87c413184dee30b528d784b2f67d448d45f10ff7 +++ guitone/src/view/dialogs/RevisionManifest.cpp 6618e4735bfb185c6b262ed646b0b0d83fa65e3c @@ -19,7 +19,7 @@ ***************************************************************************/ #include "RevisionManifest.h" -#include "Monotone.h" +#include "Guitone.h" #include "Platform.h" #include @@ -102,7 +102,7 @@ void RevisionManifest::openFile(const QM // return silently if (entry->is_directory) return; - Monotone * mtn = Monotone::singleton(); + Monotone * mtn = MTN(this); int commandNumber; QStringList cmd;