#
#
# patch "guitone/res/forms/main_window.ui"
# from [ef1a9dfbacb7e4167ad4180dc8f41274599f975b]
# to [bc2f72a85b69de8d4a2cf8f4c56d476f100e094a]
#
# patch "guitone/res/i18n/guitone_de.ts"
# from [2cad7c417c61753edd7b571a949f7672c59589df]
# to [146ade18bbb098ffc1f73387026b9442f1c8adf2]
#
# patch "guitone/src/model/Inventory.cpp"
# from [a7ae242cbeae00663b494bf579ccc7b2c51826b0]
# to [e0bb4dac9fc8507d76b8cb89e04c6448d5a07599]
#
# patch "guitone/src/model/Inventory.h"
# from [0c72dcfb0e3865a6435d4d41a4d6b08fd7f14ece]
# to [63af6ccdd44203710c9c4bff07a1e0226ea885ab]
#
# patch "guitone/src/monotone/Monotone.cpp"
# from [4c3148a9a461e31c0611e7c6a1313a994050ce33]
# to [3f0a927058b89ae8347c9330ba9af9bf5db5900d]
#
# patch "guitone/src/monotone/Monotone.h"
# from [4096eea2ec6fcfb550252ca7e9f902708af64781]
# to [59e9f42d277f3c1df9410ed4472a801e484e1ae8]
#
# patch "guitone/src/util/Settings.cpp"
# from [f09f5c4e4725d265908c62c75790ac842df850a8]
# to [9955108213c99b2d16d3b1bd422435d4af93ae39]
#
# patch "guitone/src/util/Settings.h"
# from [81d4810800baf63a95af60eb5804783e36e9985e]
# to [09e0a8df4e7b1c5f77a929547ae69136c0a7bb6f]
#
# patch "guitone/src/view/InventoryView.cpp"
# from [082453d2f7dad1e28066e2d035acaeae8e5adfa4]
# to [201bb7a201028ee92c79fc9a7c0cb112b3c0f031]
#
# patch "guitone/src/view/MainWindow.cpp"
# from [75ef0a8f30ec67021ede4dc87daaa4c9f8b3d9e8]
# to [01df25829524918aa1cb6446fe60c58749706d97]
#
# patch "guitone/src/view/MainWindow.h"
# from [1aad25f68bbe311510475ef28c6650cc4dfff64f]
# to [d591f6f5f642c3fe6ee10da2d4adcd703b311f00]
#
# patch "guitone/src/view/dialogs/Preferences.cpp"
# from [379b849af2296a5953c11970c13e07b9b3fec0de]
# to [c3641052ddd621005322368074a6d56b9c0ec848]
#
============================================================
--- guitone/res/forms/main_window.ui ef1a9dfbacb7e4167ad4180dc8f41274599f975b
+++ guitone/res/forms/main_window.ui bc2f72a85b69de8d4a2cf8f4c56d476f100e094a
@@ -5,8 +5,8 @@
0
0
- 924
- 682
+ 926
+ 790
@@ -29,35 +29,79 @@
6
-
-
-
- Qt::Horizontal
-
-
-
-
- Qt::Vertical
+
+
+
+ 0
-
-
-
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+
+ Qt::Vertical
+
+
+
+
+
+
+
-
-
-
- <html><head><meta name="qrichtext" content="1" /><style type="text/css">
+
+
+
+ 0
+
+
+ 5
+
+
-
+
+
+ 0
+
+
+ 6
+
+
-
+
+
+ <html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal; text-decoration:none;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">guitone is in <span style=" font-weight:600;">database mode</span>. This means that only parts of the functionality are available. </p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You can switch back to the <span style=" font-weight:600;">workspace mode</span> at any time by loading a workspace.</p></body></html>
-
-
- Qt::RichText
-
-
- Qt::AlignCenter
-
+
+
+ Qt::RichText
+
+
+ Qt::AlignBottom|Qt::AlignHCenter
+
+
+
+ -
+
+
+ Loaded database: %1
+
+
+ Qt::AlignHCenter|Qt::AlignTop
+
+
+
+
+
+
@@ -69,24 +113,10 @@ p, li { white-space: pre-wrap; }
0
0
- 924
+ 926
22
-
-
+
+
+
@@ -310,6 +360,9 @@ p, li { white-space: pre-wrap; }
Open Database
+
+ Ctrl+Shift+O
+
============================================================
--- guitone/res/i18n/guitone_de.ts 2cad7c417c61753edd7b571a949f7672c59589df
+++ guitone/res/i18n/guitone_de.ts 146ade18bbb098ffc1f73387026b9442f1c8adf2
@@ -529,207 +529,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
@@ -744,57 +744,57 @@
Fehler
-
+
Critical Monotone Error
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
-
+
Unable to execute '%1' - maybe another command is still running?
Konnte '%1' nicht ausführen - eventuell läuft noch ein anderes Kommando?
-
+
Loading workspace...
Lade Arbeitsbereich...
-
+
Show ignored files
Zeige ignorierte Dateien
-
+
Collapse tree
Baum zuklappen
-
+
&%1 %2
&%1 %2
@@ -804,42 +804,94 @@
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.
-
+
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal; text-decoration:none;">
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">guitone is in <span style=" font-weight:600;">database mode</span>. This means that only parts of the functionality are available. </p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">You can switch back to the <span style=" font-weight:600;">workspace mode</span> at any time by loading a workspace.</p></body></html>
-
+ <html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">guitone befindet sich im <span style=" font-weight:600;">Datenbank-Modus</span>. Das bedeutet, dass nur Teile der Funktionalität verfügbar sind. </p><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Sie können zum <span style=" font-weight:600;">Arbeitsbereich-Modus</span> jederzeit zurückkehren, indem Sie einen Arbeitsbereich laden.</p></body></ht
ml>
-
+
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
+
Monotone
Monotone failed to start (Code %1). Please configure the path in the Preferences dialog.
- Monotone konnte nicht gestartet werden (Code %1). Bitte konfigurieren Sie den Pfad im Eintellungsdialog.
+ Monotone konnte nicht gestartet werden (Code %1). Bitte konfigurieren Sie den Pfad im Eintellungsdialog.
The connection to the monotone process was terminated (Code %1). Check your configuration and reload the current workspace afterwards.
- Die Verbindung zum monotone-Prozess wurde beendet (Code %1). Prüfen Sie Ihre Konfiguration und laden Sie ggf. den Arbeitsbereich danach neu.
+ Die Verbindung zum monotone-Prozess wurde beendet (Code %1). Prüfen Sie Ihre Konfiguration und laden Sie ggf. den Arbeitsbereich danach neu.
+
+
+ The monotone process exited unexpectedly (process error %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:
+%2
+ Der monotone-Prozess wurde unerwartet beendet (Prozess-Fehler %1). Bitte konfigurieren Sie den Pfad zur ausführbaren Datei von monotone im Einstellungsdialog neu oder überprüfen Sie, ob die Version der Datenbank, die Sie versucht haben zu laden, mit der Version von monotone übereinstimmt, die Sie benutzen.
+
+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:
+%2
+ Der monotone-Prozess wurde unerwartet beendet (Rückgabewert %1). Bitte konfigurieren Sie den Pfad zur ausführbaren Datei von monotone im Einstellungsdialog neu oder überprüfen Sie, ob die Version der Datenbank, die Sie versucht haben zu laden, mit der Version von monotone übereinstimmt, die Sie benutzen.
+
+monotone gab zurück:
+%2
+
Preferences
============================================================
--- guitone/src/model/Inventory.cpp a7ae242cbeae00663b494bf579ccc7b2c51826b0
+++ guitone/src/model/Inventory.cpp e0bb4dac9fc8507d76b8cb89e04c6448d5a07599
@@ -34,62 +34,26 @@ modelPresent(false)
iconProvider = new IconProvider();
regex = new QRegExp("^(R|D|[ ])(R|A|[ ])(M|P|U|I|[ ])\\s(\\d+)\\s(\\d+)\\s(.+)$");
- workspaceDir = new QDir();
regex->setMinimal(true);
}
Inventory::~Inventory()
{
- delete workspaceDir;
delete rootItem;
delete iconProvider;
delete regex;
- delete workspaceDir;
}
-bool Inventory::setWorkspaceDir(QString workspace)
-{
- QDir tempDir(workspace);
- if (!tempDir.exists())
- {
- qWarning("Cannot find directory %s", qPrintable(workspace));
- return false;
- }
-
- do
- {
- if (tempDir.cd("_MTN"))
- {
- tempDir.cdUp();
- workspaceDir->setPath(tempDir.path());
- return true;
- }
- }
- while (!tempDir.isRoot() && tempDir.cdUp());
-
- qWarning("Cannot find _MTN directory in or above %s", qPrintable(workspace));
- return false;
-}
-
-QString Inventory::getNormalizedWorkspaceDir()
-{
- return workspaceDir->path();
-}
-
bool Inventory::readInventory()
{
- // FIXME: this should probaby be moved out here...
- Monotone * mtn = Monotone::singleton();
- mtn->setup(workspaceDir);
-
- if (modelPresent)
+ if (modelPresent)
{
deleteModel();
}
QStringList cmd;
- cmd.append("inventory");
+ cmd << "inventory";
return AutomateCommand::triggerCommand(cmd);
}
@@ -150,7 +114,8 @@ 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);
- workspace->setLabel(workspaceDir->path());
+ Monotone * mtn = Monotone::singleton();
+ workspace->setLabel(mtn->getNormalizedWorkspacePath());
rootItem->appendChild(workspace);
workspace->setChildren(buildTreeRecursive(tempItems, NULL));
============================================================
--- guitone/src/model/Inventory.h 0c72dcfb0e3865a6435d4d41a4d6b08fd7f14ece
+++ guitone/src/model/Inventory.h 63af6ccdd44203710c9c4bff07a1e0226ea885ab
@@ -36,8 +36,6 @@ class Inventory : public AutomateCommand
public:
Inventory(QObject *parent);
~Inventory();
- bool setWorkspaceDir(QString workspace);
- QString getNormalizedWorkspaceDir();
bool readInventory();
// needed Qt Model methods
@@ -55,7 +53,6 @@ class Inventory : public AutomateCommand
QList buildTreeRecursive(QList &, InventoryItem*);
void deleteModel(void);
- QDir *workspaceDir;
InventoryItem *rootItem;
IconProvider *iconProvider;
QRegExp *regex;
============================================================
--- guitone/src/monotone/Monotone.cpp 4c3148a9a461e31c0611e7c6a1313a994050ce33
+++ guitone/src/monotone/Monotone.cpp 3f0a927058b89ae8347c9330ba9af9bf5db5900d
@@ -36,7 +36,7 @@
// triggerCommand() executeCommand()
// | |
// V V
-// newCommandSetup() newCommandSetup()
+// setupNewCommand() setupNewCommand()
// | |
// V V
// writeStdin() writeStdin()
@@ -61,7 +61,7 @@
//
// Since there is only one instance of the monotone process running at a time,
// pending commands need to be queued somehow in order to avoid confusion
-// (data are sent to the wrong caller, etc.) - this is done in newCommandSetup().
+// (data are sent to the wrong caller, etc.) - this is done in setupNewCommand().
// A QMutex hinders a second parallel request on entering the wait loop of a
// previous command.
//
@@ -84,6 +84,7 @@
#include
#include
#include
+#include
Monotone* Monotone::instance = 0;
@@ -107,23 +108,77 @@ Monotone::Monotone(QObject * parent) : Q
isCleanExit = false;
// inialize the process var
process = 0;
+ // path to the monotone binary
+ mtnBinaryPath = "";
+
+ workDir = "";
+ databaseFile = "";
}
-void Monotone::setup(QDir *workingDirectory)
+bool Monotone::normalizeWorkspacePath(QString & workspace) const
{
+ QDir tempDir(workspace);
+ if (!tempDir.exists())
+ {
+ qWarning("Cannot find directory %s", qPrintable(workspace));
+ return false;
+ }
+
+ do
+ {
+ if (tempDir.cd("_MTN"))
+ {
+ tempDir.cdUp();
+ workspace = tempDir.absolutePath();
+ return true;
+ }
+ }
+ while (!tempDir.isRoot() && tempDir.cdUp());
+
+ qWarning("Cannot find _MTN directory in or above %s", qPrintable(workspace));
+ return false;
+}
+
+bool Monotone::setMtnBinaryPath(const QString & path)
+{
+ if (checkProgramVersion(path) || checkInterfaceVersion(path))
+ {
+ mtnBinaryPath = path;
+ return true;
+ }
+ return false;
+}
+
+QString Monotone::getNormalizedWorkspacePath() const
+{
+ return workDir;
+}
+
+QString Monotone::getDatabaseFilePath() const
+{
+ return databaseFile;
+}
+
+void Monotone::setupNewProcess()
+{
+ Q_ASSERT(mtnBinaryPath.size() > 0);
+
+ // if a previous process is running, exit it cleanly
if (process)
{
isCleanExit = true;
isProcessingData = false;
+
// terminate any running process
process->terminate();
- qDebug("Calling waitForFinished");
+
// block until the process has really been finished
process->waitForFinished();
- delete process;
- qDebug("Process finished");
+
+ delete process;
}
-
+
+ isCleanExit = false;
process = new QProcess(this);
// monitor if the process is exited unexpectedly
@@ -138,22 +193,46 @@ void Monotone::setup(QDir *workingDirect
this, SLOT(startupError(QProcess::ProcessError))
);
-
- workDir = workingDirectory;
- process->setWorkingDirectory(workingDirectory->absolutePath());
-
+ if (mode == Workspace)
+ {
+ process->setWorkingDirectory(workDir);
+ }
+
QStringList args;
args << "automate";
args << "stdio";
args << QString("--automate-stdio-size=%1").arg(StdioBufferSize);
- // Start up monotone's executable 'mtn'
- // FIXME: make this wrapper independent from the Settings class
- QString mtn = Settings::getMtnExePath();
- qDebug("Starting mtn '%s' ...", qPrintable(mtn));
- process->start(mtn, args);
+ if (mode == Database)
+ {
+ args << "--db" << databaseFile;
+ }
+
+ qDebug("Executing %s %s", qPrintable(mtnBinaryPath), qPrintable(args.join(" ")));
+
+ process->start(mtnBinaryPath, args);
}
+bool Monotone::loadWorkspace(QString workspace)
+{
+ // try to find the _MTN directory in the given path and chdir to the root
+ if (!normalizeWorkspacePath(workspace)) return false;
+ workDir = workspace;
+ mode = Workspace;
+ setupNewProcess();
+ return true;
+}
+
+bool Monotone::loadDatabase(QString db)
+{
+ // FIXME: shall we check here for anything or do we just let monotone
+ // escalate later on if something goes wrong, e.g. file is not writable...?
+ databaseFile = db;
+ mode = Database;
+ setupNewProcess();
+ return true;
+}
+
Monotone::~Monotone()
{
isCleanExit = true;
@@ -168,22 +247,39 @@ Monotone* Monotone::singleton(QObject *
return instance;
}
-QString Monotone::getWorkspaceDir() const
-{
- return workDir->absolutePath();
-}
-
void Monotone::startupError(QProcess::ProcessError error)
{
if (isCleanExit) return;
- emit criticalError(tr("Monotone failed to start (Code %1). Please configure the path in the Preferences dialog.").arg(error));
+
+ // FIXME: we need a better error handling here afterwards, i.e. inform
+ // the GUI that nothing is available
+ QString msg(process->readAllStandardError());
+ emit criticalError(tr(
+ "The monotone process exited unexpectedly (process error %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.\n\n"
+ "monotone returned:\n%2"
+ ).arg(error).arg(stripMtnPrefix(msg))
+ );
}
-void Monotone::processTerminated(int code, QProcess::ExitStatus /* status */)
+void Monotone::processTerminated(int code, QProcess::ExitStatus status)
{
// this was a normal exit
if (code == 0 || isCleanExit) return;
- emit criticalError(tr("The connection to the monotone process was terminated (Code %1). Check your configuration and reload the current workspace afterwards.").arg(code));
+
+ // FIXME: we need a better error handling here afterwards, i.e. inform
+ // the GUI that nothing is available
+ QString msg(process->readAllStandardError());
+ emit criticalError(tr(
+ "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.\n\n"
+ "monotone returned:\n%2"
+ ).arg(code).arg(stripMtnPrefix(msg))
+ );
}
void Monotone::timedOut()
@@ -191,11 +287,11 @@ void Monotone::timedOut()
timeout = true;
}
-bool Monotone::newCommandSetup()
+bool Monotone::setupNewCommand()
{
if (process->state() != QProcess::Running && !process->waitForStarted(15000))
{
- qDebug("Monotone::newCommandSetup: Process is not running");
+ qDebug("Monotone::setupNewCommand: Process is not running");
return false;
}
@@ -210,7 +306,7 @@ bool Monotone::newCommandSetup()
if (timeout)
{
- qDebug("Monotone::newCommandSetup: Timed out waiting for other process");
+ qDebug("Monotone::setupNewCommand: Timed out waiting for other process");
mutex.unlock();
return false;
}
@@ -232,7 +328,7 @@ bool Monotone::executeCommand(const QStr
bool Monotone::executeCommand(const QStringList & command, const QStringList & options, int & retCode)
{
- if (!newCommandSetup())
+ if (!setupNewCommand())
{
return false;
}
@@ -265,7 +361,7 @@ bool Monotone::triggerCommand(const QStr
bool Monotone::triggerCommand(const QStringList & command, const QStringList & options)
{
- if (!newCommandSetup())
+ if (!setupNewCommand())
{
return false;
}
@@ -386,6 +482,14 @@ bool Monotone::readAndParseStdout(int &
{
Q_ASSERT(input.length() == 0);
retCode = list[2].toInt();
+
+ // if the command did not return successfully, try to strip
+ // prefixes from the error output
+ if (retCode > 0)
+ {
+ output = stripMtnPrefix(output);
+ }
+
// command successfully parsed
return true;
}
@@ -513,3 +617,26 @@ bool Monotone::checkInterfaceVersion(con
return curMajor > needMajor || curMajor == needMajor && curMinor >= needMinor;
}
+// strip mtn: warning: and alike from error strings coming from mtn
+// and unwrap them, if this fails we add the original string unwrapped
+QString Monotone::stripMtnPrefix(const QString & input)
+{
+ QString output;
+ QStringList list = input.split(QRegExp("\n"));
+
+ // FIXME: we should actually use basename(mtnBinaryPath) in case
+ // the binary is renamed, but I'm too lazy for this right now...
+ // and this would also require to make this method non-static
+ QRegExp rx = QRegExp("^mtn:[^:]+:[ ]*(.+)");
+ for (int i=0, j=list.size(); i
-#include
#include
class Monotone : public QObject
@@ -34,14 +33,18 @@ class Monotone : public QObject
static bool runCommand(const QString &, const QStringList &, QString &);
static bool checkProgramVersion(const QString &);
static bool checkInterfaceVersion(const QString &);
+ static QString stripMtnPrefix(const QString &);
static const QString RequiredProgramVersion;
static const QString RequiredInterfaceVersion;
static const int StdioBufferSize;
static const int TimeoutWaitForOtherCommand;
- void setup(QDir*);
- virtual ~Monotone();
- QString getWorkspaceDir() const;
+ bool loadWorkspace(QString);
+ bool loadDatabase(QString);
+ bool setMtnBinaryPath(const QString &);
+ virtual ~Monotone();
+ QString getNormalizedWorkspacePath() const;
+ QString getDatabaseFilePath() const;
bool triggerCommand(const QStringList &);
bool triggerCommand(const QStringList &, const QStringList &);
@@ -53,9 +56,13 @@ class Monotone : public QObject
void reset();
private:
+ enum Mode { Workspace, Database } mode;
+
Monotone(QObject *);
- bool newCommandSetup();
+ bool normalizeWorkspacePath(QString &) const;
+ bool setupNewCommand();
+ void setupNewProcess();
void writeStdin(const QStringList &, const QStringList &);
bool readAndParseStdout(int &);
@@ -68,7 +75,9 @@ class Monotone : public QObject
bool isCleanExit;
static Monotone* instance;
QProcess * process;
- QDir * workDir;
+ QString workDir;
+ QString databaseFile;
+ QString mtnBinaryPath;
private slots:
void readAndProcessCommand();
============================================================
--- guitone/src/util/Settings.cpp f09f5c4e4725d265908c62c75790ac842df850a8
+++ guitone/src/util/Settings.cpp 9955108213c99b2d16d3b1bd422435d4af93ae39
@@ -48,12 +48,12 @@ void Settings::setStartupSize(QSize size
settings->setValue("StartupSize", size);
}
-QString Settings::getMtnExePath()
+QString Settings::getMtnBinaryPath()
{
return singleton()->value("MtnExePath", "mtn").toString();
}
-void Settings::setMtnExePath(QString path)
+void Settings::setMtnBinaryPath(QString path)
{
Settings *settings = singleton();
settings->setValue("MtnExePath", path);
============================================================
--- guitone/src/util/Settings.h 81d4810800baf63a95af60eb5804783e36e9985e
+++ guitone/src/util/Settings.h 09e0a8df4e7b1c5f77a929547ae69136c0a7bb6f
@@ -35,8 +35,8 @@ public:
static void setItemList(const QString &, const QStringList &);
static void addItemToList(const QString&, const QString &, int);
static void removeItemFromList(const QString &, const QString &);
- static QString getMtnExePath();
- static void setMtnExePath(QString);
+ static QString getMtnBinaryPath();
+ static void setMtnBinaryPath(QString);
static void saveHeaderViewState(QHeaderView*, QString);
static void restoreHeaderViewState(QHeaderView*, QString);
static QByteArray getSplitterState(QString);
============================================================
--- guitone/src/view/InventoryView.cpp 082453d2f7dad1e28066e2d035acaeae8e5adfa4
+++ guitone/src/view/InventoryView.cpp 201bb7a201028ee92c79fc9a7c0cb112b3c0f031
@@ -326,7 +326,7 @@ void InventoryView::slotOpen(void)
InventoryItem * item = static_cast(index.internalPointer());
Monotone * mtn = Monotone::singleton();
- QFileInfo file(mtn->getWorkspaceDir() + "/" + item->getPath());
+ QFileInfo file(mtn->getNormalizedWorkspacePath() + "/" + item->getPath());
if (!file.exists())
{
============================================================
--- guitone/src/view/MainWindow.cpp 75ef0a8f30ec67021ede4dc87daaa4c9f8b3d9e8
+++ guitone/src/view/MainWindow.cpp 01df25829524918aa1cb6446fe60c58749706d97
@@ -52,17 +52,17 @@ bool MainWindow::init()
switchMode(mode);
+ Monotone * mtn = Monotone::singleton(this);
+
// catch critical errors from the Monotone class
connect(
- Monotone::singleton(this), SIGNAL(criticalError(const QString &)),
+ 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
- QString path = Settings::getMtnExePath();
- if (!Monotone::checkProgramVersion(path) &&
- !Monotone::checkInterfaceVersion(path))
+ if (!mtn->setMtnBinaryPath(Settings::getMtnBinaryPath()))
{
QMessageBox::critical(
this,
@@ -120,8 +120,9 @@ bool MainWindow::init()
treeView, SLOT(changeDirectory(const QModelIndex &))
);
- // load recent workspace list
+ // load recent workspace and database lists
updatePreviousWorkspacesMenu();
+ updatePreviousDatabasesMenu();
// set the data for some menu elements
actionAll_files->setData(QVariant(InventoryProxyModel::All));
@@ -166,6 +167,8 @@ void MainWindow::criticalMtnError(const
QMessageBox::critical(NULL, tr("Critical Monotone Error"),
msg, QMessageBox::Ok, 0, 0);
+
+ switchMode(None);
}
}
@@ -184,9 +187,9 @@ void MainWindow::loadWorkspace(QString f
void MainWindow::loadWorkspace(QString fn)
{
- qDebug("Last workspace %s", qPrintable(fn));
-
- if (!invModel->setWorkspaceDir(fn))
+ Monotone * mtn = Monotone::singleton();
+
+ if (!mtn->loadWorkspace(fn))
{
QMessageBox::information(
this,
@@ -215,7 +218,7 @@ void MainWindow::loadWorkspace(QString f
// add the workspace to the recent workspace list
// FIXME: the amount of recent workspaces should be made configurable
- Settings::addItemToList("RecentWorkspaceList", invModel->getNormalizedWorkspaceDir(), 5);
+ Settings::addItemToList("RecentWorkspaceList", mtn->getNormalizedWorkspacePath(), 5);
updatePreviousWorkspacesMenu();
statusBar()->showMessage(tr("Loading workspace..."), 2000 );
@@ -223,7 +226,37 @@ void MainWindow::on_actionOpen_Database_
void MainWindow::on_actionOpen_Database_triggered()
{
+ QString fn = QFileDialog::getOpenFileName(
+ this,
+ tr("Select your database..."),
+ QString(),
+ tr("monotone Databases (*.mtn *.db)")
+ );
+
+ if (fn.isEmpty())
+ {
+ statusBar()->showMessage(tr("Loading aborted"), 2000);
+ return;
+ }
+
+ loadDatabase(fn);
+}
+
+void MainWindow::loadDatabase(QString fn)
+{
+ Monotone * mtn = Monotone::singleton();
+ if (!mtn->loadDatabase(fn))
+ {
+ qDebug("Could not load database.");
+ // remove the workspace if it was recorded as recent workspace
+ Settings::removeItemFromList("RecentDatabaseList", fn);
+ return;
+ }
+
switchMode(Database);
+
+ Settings::addItemToList("RecentDatabaseList", fn, 5);
+ updatePreviousDatabasesMenu();
}
void MainWindow::switchMode(Mode m)
@@ -231,18 +264,33 @@ void MainWindow::switchMode(Mode m)
mode = m;
if (mode == Database)
{
- modeLabel->setVisible(true);
- mainSplitter->setVisible(false);
- menuView->setVisible(false);
- menuWorkspace->setVisible(false);
+ databaseModeWidget->setVisible(true);
+ workspaceModeWidget->setVisible(false);
+ 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()));
}
else
+ if (mode == Workspace)
{
- modeLabel->setVisible(false);
- mainSplitter->setVisible(true);
- menuView->setVisible(true);
- menuWorkspace->setVisible(true);
+ databaseModeWidget->setVisible(false);
+ workspaceModeWidget->setVisible(true);
+ menuView->menuAction()->setVisible(true);
+ menuWorkspace->menuAction()->setVisible(true);
+ menuDatabase->menuAction()->setVisible(true);
}
+ else
+ {
+ databaseModeWidget->setVisible(true);
+ workspaceModeWidget->setVisible(false);
+ menuView->menuAction()->setVisible(false);
+ menuWorkspace->menuAction()->setVisible(false);
+ menuDatabase->menuAction()->setVisible(false);
+ loadedDatabase->setText(tr("Loaded database: %1").arg(tr("No database loaded")));
+ }
+
emit modeChanged(mode);
}
@@ -299,6 +347,16 @@ void MainWindow::openRecentWorkspace()
}
}
+
+void MainWindow::openRecentDatabase()
+{
+ QAction *action = qobject_cast(sender());
+ if (action)
+ {
+ loadDatabase(action->data().toString());
+ }
+}
+
void MainWindow::updatePreviousWorkspacesMenu()
{
// clear previous actions
@@ -325,6 +383,32 @@ void MainWindow::updatePreviousWorkspace
}
}
+void MainWindow::updatePreviousDatabasesMenu()
+{
+ // clear previous actions
+ menuRecent_Databases->clear();
+
+ QStringList previousDb = Settings::getItemList("RecentDatabaseList");
+ int elemCount = previousDb.size();
+ if (elemCount == 0)
+ {
+ menuRecent_Databases->addAction(tr("No previous databases available."));
+ return;
+ }
+
+ QAction *act;
+ // add the new actions
+ for (int i = 0; i < elemCount; ++i)
+ {
+ act = menuRecent_Databases->addAction(
+ tr("&%1 %2").arg(i + 1).arg(previousDb[i]),
+ this,
+ SLOT(openRecentDatabase())
+ );
+ act->setData(previousDb[i]);
+ }
+}
+
void MainWindow::on_actionSwitch_revision_triggered()
{
// TODO: connect Inventory with the accept() signal here somehow
============================================================
--- guitone/src/view/MainWindow.h 1aad25f68bbe311510475ef28c6650cc4dfff64f
+++ guitone/src/view/MainWindow.h d591f6f5f642c3fe6ee10da2d4adcd703b311f00
@@ -36,7 +36,7 @@ public:
Q_OBJECT
public:
- enum Mode { Database, Workspace };
+ enum Mode { Database, Workspace, None };
MainWindow();
~MainWindow();
bool init();
@@ -57,12 +57,15 @@ private slots:
void on_actionAbout_guitone_triggered();
void openRecentWorkspace();
+ void openRecentDatabase();
void criticalMtnError(const QString &);
private:
void closeEvent(QCloseEvent *);
void loadWorkspace(QString);
+ void loadDatabase(QString);
void updatePreviousWorkspacesMenu();
+ void updatePreviousDatabasesMenu();
Inventory *invModel;
Attributes *attrModel;
============================================================
--- guitone/src/view/dialogs/Preferences.cpp 379b849af2296a5953c11970c13e07b9b3fec0de
+++ guitone/src/view/dialogs/Preferences.cpp c3641052ddd621005322368074a6d56b9c0ec848
@@ -30,7 +30,7 @@ Preferences::Preferences(QWidget* parent
: QDialog(parent)
{
setupUi(this);
- mtnExecutablePath->setText(Settings::getMtnExePath());
+ mtnExecutablePath->setText(Settings::getMtnBinaryPath());
connect(
selectMtnExecutable, SIGNAL(clicked()),
@@ -42,7 +42,7 @@ void Preferences::accept()
void Preferences::accept()
{
- QString oldPath = Settings::getMtnExePath();
+ QString oldPath = Settings::getMtnBinaryPath();
QString newPath = mtnExecutablePath->text();
// check if the new executable satisfies our version needs
@@ -77,7 +77,7 @@ void Preferences::accept()
QMessageBox::Ok
);
- Settings::setMtnExePath(newPath);
+ Settings::setMtnBinaryPath(newPath);
}
done(QDialog::Accepted);
}