#
#
# patch "i18n/guitone_de.qm"
# from [92e44318cdd9c80c79fc023376d8f3ea3c0ca9e9]
# to [2fd1174515f976c44c21eeaede95500ef2387237]
#
# patch "i18n/guitone_de.ts"
# from [fb312dd3b4574049e13837d110b310e569271557]
# to [1aaaadfcb3efe96c55074583710159c1727c8832]
#
# patch "src/Properties.cpp"
# from [0c0831ffb9b173f3241286a72d34e4aa1cab46e5]
# to [f860c5e50b3b293d2694378ceada921be3a38bff]
#
# patch "src/Properties.h"
# from [cee36b1fe0f3991a17365a3e2545b4098d95c723]
# to [4d87d01a0081b68d48ffe76ae53616587a765ba0]
#
# patch "src/model/Monotone.cpp"
# from [83753eba69edcd9a471999590ca9685b6cb0f06f]
# to [bf0826043e54b20fe041910b5448ae9f4850fc14]
#
# patch "src/model/Monotone.h"
# from [3306459c13c76bf2bb5ddfb6c30ba16607f4b5fe]
# to [45e871cfc575a52e9f4f1a75a26057837bbeac8d]
#
# patch "src/model/Workspace.cpp"
# from [11e182493b340a11ebe3729fe5f1bb1a93d7e210]
# to [687f1015e073c3cbb3114bebe220f6fda4dc7855]
#
# patch "src/model/Workspace.h"
# from [5bd5433c0ba3e9b54d352e8685a636f9a40eaef8]
# to [6a7552214cb613775845cb358ea2e93ef9dd0b53]
#
# patch "src/view/Guitone.cpp"
# from [22d38d0766c14d9a0927dc23c941aea3de1b1c1d]
# to [c1f1a06ade3dbdabd5131f815b85f4e0946e198f]
#
# patch "src/view/Guitone.h"
# from [df4f6efd4141467224a52cd0d97bb92a2e4652c9]
# to [240ec4685a00a13789e9667ff6d5c83ed282ae26]
#
# patch "src/view/WorkspaceView.cpp"
# from [1d9d8dd6173a212bc4f584458ca031e3d8dc4bc9]
# to [fa1baaf882b961e59dac7bb709b5074e4793bee3]
#
============================================================
# i18n/guitone_de.qm is binary
============================================================
--- i18n/guitone_de.ts fb312dd3b4574049e13837d110b310e569271557
+++ i18n/guitone_de.ts 1aaaadfcb3efe96c55074583710159c1727c8832
@@ -19,7 +19,7 @@
- Bereit
+ Bereit
@@ -65,7 +65,7 @@
- &Importiere Arbeitsbereich
+ &Importiere Arbeitsbereich
@@ -88,6 +88,22 @@
Ignorierte Dateien a&nzeigen
+
+
+ &Vorherige Arbeitsbereiche
+
+
+
+ Arbeitsbereich &öffnen
+
+
+
+ &%1 %2
+
+
+
+ Keine vorherigen Arbeitsbereiche verfügbar.
+
Monotone
============================================================
--- src/Properties.cpp 0c0831ffb9b173f3241286a72d34e4aa1cab46e5
+++ src/Properties.cpp f860c5e50b3b293d2694378ceada921be3a38bff
@@ -20,46 +20,90 @@
#include "Properties.h"
-Properties::Properties()
+Properties* Properties::props = 0;
+
+Properties* Properties::singleton()
{
- settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "GUITONE", "GUITONE");
+ if (!props)
+ {
+ props = new Properties();
+ }
+ return props;
}
+Properties::Properties()
+ : QSettings(QSettings::IniFormat, QSettings::UserScope, "GUITONE", "GUITONE")
+{}
-Properties::~Properties()
-{
- delete settings;
-}
+Properties::~Properties() {}
-QSize Properties::getStartupSize(void) const
+QSize Properties::getStartupSize(void)
{
- return settings->value("StartupSize", QSize(300, 200)).toSize();
+ return singleton()->value("StartupSize", QSize(640, 480)).toSize();
}
void Properties::setStartupSize(QSize size)
{
- settings->setValue("StartupSize", size);
- settings->sync();
+ props = singleton();
+ props->setValue("StartupSize", size);
+ props->sync();
}
-QSize Properties::getFileListSize(void) const
+QSize Properties::getFileListSize(void)
{
- return settings->value("FileListSize", QSize(100, 100)).toSize();
+ return singleton()->value("FileListSize", QSize(100, 100)).toSize();
}
void Properties::setFileListSize(QSize size)
{
- settings->setValue("FileListSize", size);
- settings->sync();
+ props = singleton();
+ props->setValue("FileListSize", size);
+ props->sync();
}
-QSize Properties::getTreeViewSize(void) const
+QSize Properties::getTreeViewSize(void)
{
- return settings->value("TreeViewSize", QSize(100, 100)).toSize();
+ return singleton()->value("TreeViewSize", QSize(100, 100)).toSize();
}
void Properties::setTreeViewSize(QSize size)
{
- settings->setValue("TreeViewSize", size);
- settings->sync();
+ props = singleton();
+ props->setValue("TreeViewSize", size);
+ props->sync();
}
+
+QStringList Properties::getPreviousWorkspaces()
+{
+ return singleton()->value("RecentWorkspaceList").toStringList();
+}
+
+void Properties::setPreviousWorkspaces(QStringList list)
+{
+ props = singleton();
+ props->setValue("RecentWorkspaceList", list);
+ props->sync();
+}
+
+void Properties::addPreviousWorkspace(QString workspace)
+{
+ QStringList list = getPreviousWorkspaces();
+ // do not do anything if we've already recorded this workspace
+ if (list.contains(workspace)) return;
+
+ if (list.size() > MaxPreviousWorkspaces)
+ {
+ list.removeLast();
+ }
+ list.prepend(workspace);
+ setPreviousWorkspaces(list);
+}
+
+void Properties::removePreviousWorkspace(QString workspace)
+{
+ QStringList list = getPreviousWorkspaces();
+ int pos = list.indexOf(workspace);
+ if (pos == -1) return;
+ list.removeAt(pos);
+ setPreviousWorkspaces(list);
+}
============================================================
--- src/Properties.h cee36b1fe0f3991a17365a3e2545b4098d95c723
+++ src/Properties.h 4d87d01a0081b68d48ffe76ae53616587a765ba0
@@ -27,22 +27,29 @@
class QSettings;
class QSize;
-class Properties
+class Properties : public QSettings
{
public:
- Properties(void);
- ~Properties(void);
- QSize getStartupSize(void) const;
- void setStartupSize(QSize size);
- QSize getFileListSize(void) const;
- void setFileListSize(QSize size);
- QSize getTreeViewSize(void) const;
- void setTreeViewSize(QSize size);
+ static QSize getStartupSize(void);
+ static void setStartupSize(QSize size);
+ static QSize getFileListSize(void);
+ static void setFileListSize(QSize size);
+ static QSize getTreeViewSize(void);
+ static void setTreeViewSize(QSize size);
+ static QStringList getPreviousWorkspaces();
+ static void setPreviousWorkspaces(QStringList);
+ static void addPreviousWorkspace(QString);
+ static void removePreviousWorkspace(QString);
-
+ // FIXME: we may want to make this configurable later on
+ enum { MaxPreviousWorkspaces = 8 };
private:
QSettings *settings;
+ Properties();
+ ~Properties(void);
+ static Properties* singleton();
+ static Properties* props;
};
============================================================
--- src/model/Monotone.cpp 83753eba69edcd9a471999590ca9685b6cb0f06f
+++ src/model/Monotone.cpp bf0826043e54b20fe041910b5448ae9f4850fc14
@@ -52,7 +52,7 @@
process, SIGNAL(readyReadStandardOutput()),
this, SLOT(parseLineFromStdout())
);
-
+
// monitor if the process is exited unexpectedly
connect(
process, SIGNAL(finished(int, QProcess::ExitStatus)),
@@ -175,6 +175,10 @@
for (QStringList::Iterator it = inputList.begin(); it != inputList.end(); ++it )
{
lineFromStdIn = *it;
+ // FIXME: skip empty lines, they pop up otherwise, but
+ // I have no idea where these should come from
+ if (lineFromStdIn.size() == 0) continue;
+
if (regex.indexIn(lineFromStdIn) == -1)
{
qWarning("Monotone::parseLineFromStdout: Can't parse data %s", qPrintable(lineFromStdIn));
@@ -182,6 +186,12 @@
}
QStringList list = regex.capturedTexts();
+ // valid output, append it
+ if (list[5].size() > 0)
+ {
+ output->append(list[5]);
+ }
+
// last output? then this contains just the status,
// and no additional information
if (list[3].compare("l") == 0)
@@ -189,9 +199,7 @@
isProcessingData = false;
emit commandFinished(list[2].toInt());
break;
- }
- // valid output, append it
- output->append(list[5]);
+ }
}
}
============================================================
--- src/model/Monotone.h 3306459c13c76bf2bb5ddfb6c30ba16607f4b5fe
+++ src/model/Monotone.h 45e871cfc575a52e9f4f1a75a26057837bbeac8d
@@ -49,12 +49,11 @@
bool isProcessingData;
bool isCleanExit;
static Monotone* instance;
-
QProcess * process;
private slots:
void parseLineFromStdout();
- void processTerminated(int, QProcess::ExitStatus);
+ void processTerminated(int, QProcess::ExitStatus);
void startupError(QProcess::ProcessError);
signals:
============================================================
--- src/model/Workspace.cpp 11e182493b340a11ebe3729fe5f1bb1a93d7e210
+++ src/model/Workspace.cpp 687f1015e073c3cbb3114bebe220f6fda4dc7855
@@ -71,6 +71,11 @@
return false;
}
+QString Workspace::getNormalizedWorkspaceDir()
+{
+ return workspaceDir->path();
+}
+
bool Workspace::readInventory()
{
if(modelPresent)
@@ -97,25 +102,27 @@
void Workspace::createModel(int returnCode)
{
- if(modelPresent)
+ if (modelPresent)
{
qWarning("Workspace::createModel: A model is already created!");
return;
}
QStringList *output = monotone->getOutput();
- // TODO: Better error reporting!
+ // FIXME: we should throw the monotone interface errors further
+ // to the user or at least log them somewhere...
if ((returnCode > 0) && (!output->isEmpty()))
{
QString error = output->front();
- qWarning("A error occured: %s", qPrintable(error));
+
+ qWarning("Workspace::parseInventory: A monotone error occured: %s", qPrintable(error));
// restore the normal cursor
qApp->restoreOverrideCursor();
return;
}
else if (returnCode > 0)
{
- qWarning("Workspace::parseInventory: A error occured with empty output list");
+ qWarning("Workspace::parseInventory: A monotone error occured (no further information available)");
// restore the normal cursor
qApp->restoreOverrideCursor();
return;
@@ -131,28 +138,27 @@
int to_id(0);
QString path("");
bool isDirectory(false);
- bool isOk(false);
for (QStringList::Iterator it = output->begin(); it != output->end(); ++it)
{
- parseOutputLine(*it, status, from_id, to_id, path, isDirectory, isOk);
-
- if (isOk)
+ if (!parseInventoryLine(*it, status, from_id, to_id, path, isDirectory))
{
- // this item is given a parent explicitely later on
- item = new WorkspaceItem(NULL, path, status, isDirectory);
+ continue;
+ }
+
+ // this item is given a parent explicitely later on
+ item = new WorkspaceItem(NULL, path, status, isDirectory);
- if (from_id > 0)
- {
- renameMap[-from_id] = item;
- }
- if (to_id > 0)
- {
- renameMap[to_id] = item;
- }
+ if (from_id > 0)
+ {
+ renameMap[-from_id] = item;
+ }
+ if (to_id > 0)
+ {
+ renameMap[to_id] = item;
+ }
- tempItems.push_back(item);
- }
+ tempItems.push_back(item);
}
int id = 0;
@@ -339,21 +345,19 @@
return parentItem->childCount();
}
-void Workspace::parseOutputLine(const QString &inputString,
- int &status,
- int &from_id,
- int &to_id,
- QString &path,
- bool &isDirectory,
- bool &ok)
+bool Workspace::parseInventoryLine(
+ const QString &inputString,
+ int &status,
+ int &from_id,
+ int &to_id,
+ QString &path,
+ bool &isDirectory)
{
if (regex->indexIn(inputString) == -1)
{
qWarning("Couldn't parse inventory line %s", qPrintable(inputString));
- ok = false;
- return;
+ return false;
}
- ok = true;
QStringList list = regex->capturedTexts();
status = 0;
@@ -363,69 +367,71 @@
{
status |= WorkspaceItem::RenamedFrom;
} else
- if (list[1].compare("D") == 0)
- {
- status |= WorkspaceItem::Dropped;
- }
- else
- {
- if (list[1].compare(" ") != 0)
- {
- qWarning("Unknown status first tripel %s", qPrintable(list[1]));
- }
- }
+ if (list[1].compare("D") == 0)
+ {
+ status |= WorkspaceItem::Dropped;
+ }
+ else
+ if (list[1].compare(" ") != 0)
+ {
+ qWarning("Unknown status first tripel %s", qPrintable(list[1]));
+ return false;
+ }
- // the second match
- if (list[2].compare("R") == 0)
- {
- status |= WorkspaceItem::RenamedTo;
- } else
- if (list[2].compare("A") == 0)
- {
- status |= WorkspaceItem::Added;
- }
- else
- {
- if (list[2].compare(" ") != 0)
- {
- qWarning("Unknown status second tripel %s", qPrintable(list[2]));
- }
- }
- // the third match
- if (list[3].compare("M") == 0)
- {
- status |= WorkspaceItem::Missing;
- } else
- if (list[3].compare("P") == 0)
- {
- status |= WorkspaceItem::Patched;
- } else
- if (list[3].compare("U") == 0)
- {
- status |= WorkspaceItem::Unknown;
- } else
- if (list[3].compare("I") == 0)
- {
- status |= WorkspaceItem::Ignored;
- } else
- {
- // if nothing is outputted, the file is unchanged
- status |= WorkspaceItem::Unchanged;
- }
+ // the second match
+ if (list[2].compare("R") == 0)
+ {
+ status |= WorkspaceItem::RenamedTo;
+ } else
+ if (list[2].compare("A") == 0)
+ {
+ status |= WorkspaceItem::Added;
+ }
+ else
+ if (list[2].compare(" ") != 0)
+ {
+ qWarning("Unknown status second tripel %s", qPrintable(list[2]));
+ return false;
+ }
- // now determine if the file has been renamed
- from_id = list[4].toInt();
- to_id = list[5].toInt();
+ // the third match
+ if (list[3].compare("M") == 0)
+ {
+ status |= WorkspaceItem::Missing;
+ } else
+ if (list[3].compare("P") == 0)
+ {
+ status |= WorkspaceItem::Patched;
+ } else
+ if (list[3].compare("U") == 0)
+ {
+ status |= WorkspaceItem::Unknown;
+ } else
+ if (list[3].compare("I") == 0)
+ {
+ status |= WorkspaceItem::Ignored;
+ } else
+ {
+ // if nothing is outputted, the file is unchanged
+ status |= WorkspaceItem::Unchanged;
+ }
- // remove trailing slash
- path = list[6].trimmed();
- isDirectory = false;
- if (path.endsWith('/'))
- {
- isDirectory = true;
- path = path.left(path.length() - 1);
- }
+ // now determine if the file has been renamed
+ from_id = list[4].toInt();
+ to_id = list[5].toInt();
+
+ // remove trailing slash
+ path = list[6].trimmed();
+ isDirectory = false;
+ if (path.endsWith('/'))
+ {
+ isDirectory = true;
+ path = path.left(path.length() - 1);
+ }
+
+ // parsing was successful
+ return true;
}
void Workspace::deleteModel(void)
============================================================
--- src/model/Workspace.h 5bd5433c0ba3e9b54d352e8685a636f9a40eaef8
+++ src/model/Workspace.h 6a7552214cb613775845cb358ea2e93ef9dd0b53
@@ -36,6 +36,7 @@
Workspace(QObject *parent);
~Workspace();
bool setWorkspaceDir(QString workspace);
+ QString getNormalizedWorkspaceDir();
bool readInventory();
// needed Qt Model methods
@@ -48,7 +49,7 @@
int columnCount(const QModelIndex&) const;
private:
- void parseOutputLine(const QString &, int &, int &, int &, QString &, bool &, bool &);
+ bool parseInventoryLine(const QString &, int &, int &, int &, QString &, bool &);
QList buildTreeRecursive(QList &, WorkspaceItem*);
void deleteModel(void);
============================================================
--- src/view/Guitone.cpp 22d38d0766c14d9a0927dc23c941aea3de1b1c1d
+++ src/view/Guitone.cpp c1f1a06ade3dbdabd5131f815b85f4e0946e198f
@@ -34,21 +34,30 @@
// create Workspace model
myWorkspace = new Workspace(this);
- // connect Monotone:
- connect(Monotone::singleton(this), SIGNAL(criticalError(const QString &)),
- this, SLOT(criticalMtnError(const QString &)));
+ // connect to Monotone to catch critical errors
+ connect(
+ Monotone::singleton(this), SIGNAL(criticalError(const QString &)),
+ this, SLOT(criticalMtnError(const QString &))
+ );
//
// Menubar
//
menu = menuBar()->addMenu(tr("&File"));
menu->addAction(
- tr("&Import Working Directory..."),
+ tr("&Open Workspace"),
this,
SLOT(chooseWorkspace()),
- Qt::CTRL + Qt::Key_I
+ Qt::CTRL + Qt::Key_O
);
+
+ //
+ // load recent workspace list
+ //
+ wsSubMenu = menu->addMenu(tr("&Recent Workspaces"));
+ updatePreviousWorkspacesMenu();
+
QAction *act = menu->addAction("");
act->setSeparator(true);
@@ -107,10 +116,14 @@
setCentralWidget(mainSplitter);
- Properties properties;
- resize(properties.getStartupSize());
+ resize(Properties::getStartupSize());
- statusBar()->showMessage(tr("Ready"), 2000);
+ // load the most recent previous workspace, if there is any
+ QStringList list = Properties::getPreviousWorkspaces();
+ if (list.size() > 0)
+ {
+ loadWorkspace(list[0]);
+ }
}
@@ -162,7 +175,14 @@
statusBar()->showMessage(tr("Loading aborted"), 2000);
return;
}
+
+ loadWorkspace(fn);
+}
+void Guitone::loadWorkspace(QString fn)
+{
+ qDebug("Last workspace %s", qPrintable(fn));
+
if (!myWorkspace->setWorkspaceDir(fn))
{
QMessageBox::information(
@@ -170,7 +190,10 @@
tr("Invalid workspace"),
tr("The chosen directory is no monotone workspace!"),
QMessageBox::Ok
- );
+ );
+ // remove the workspace if it was recorded as recent workspace
+ Properties::removePreviousWorkspace(fn);
+ updatePreviousWorkspacesMenu();
return;
}
@@ -185,15 +208,17 @@
return;
}
+ // add the workspace to the recent workspace list
+ Properties::addPreviousWorkspace(myWorkspace->getNormalizedWorkspaceDir());
+ updatePreviousWorkspacesMenu();
+
statusBar()->showMessage(tr("Loading workspace..."), 2000 );
}
void Guitone::closeEvent(QCloseEvent *event)
{
- // Do some cleanup before colseing down the application
- Properties properties;
-
- properties.setStartupSize(size());
+ // Do some cleanup before closing down the application
+ Properties::setStartupSize(size());
event->accept();
}
@@ -207,3 +232,38 @@
hide ? tr("&Hide ignored files") : tr("&Show ignored files")
);
}
+
+void Guitone::openRecentWorkspace()
+{
+ QAction *action = qobject_cast(sender());
+ if (action)
+ {
+ loadWorkspace(action->data().toString());
+ }
+}
+
+void Guitone::updatePreviousWorkspacesMenu()
+{
+ // clear previous actions
+ wsSubMenu->clear();
+
+ QStringList previousWs = Properties::getPreviousWorkspaces();
+ int elemCount = previousWs.size();
+ if (elemCount == 0)
+ {
+ wsSubMenu->addAction(tr("No previous workspaces available."));
+ return;
+ }
+
+ QAction *act;
+ // add the new actions
+ for (int i = 0; i < elemCount; ++i)
+ {
+ act = wsSubMenu->addAction(
+ tr("&%1 %2").arg(i + 1).arg(previousWs[i]),
+ this,
+ SLOT(openRecentWorkspace())
+ );
+ act->setData(previousWs[i]);
+ }
+}
============================================================
--- src/view/Guitone.h df4f6efd4141467224a52cd0d97bb92a2e4652c9
+++ src/view/Guitone.h 240ec4685a00a13789e9667ff6d5c83ed282ae26
@@ -42,7 +42,8 @@
~Guitone();
private slots:
void chooseWorkspace();
- void criticalMtnError(const QString &);
+ void openRecentWorkspace();
+ void criticalMtnError(const QString &);
//void doFindAndSelectItem( WorkspaceItem* );
void slotMapFolderTreeToFileList( const QModelIndex &proxyIndex );
void slotMapFileListToFolderTree( const QModelIndex &proxyIndex );
@@ -50,8 +51,11 @@
private:
void closeEvent(QCloseEvent *event);
-
+ void loadWorkspace(QString);
+ void updatePreviousWorkspacesMenu();
+
QMenu *menu;
+ QMenu *wsSubMenu;
QAction *actShowHideIgnored;
QToolBar *toolBar;
Workspace *myWorkspace;
============================================================
--- src/view/WorkspaceView.cpp 1d9d8dd6173a212bc4f584458ca031e3d8dc4bc9
+++ src/view/WorkspaceView.cpp fa1baaf882b961e59dac7bb709b5074e4793bee3
@@ -24,18 +24,16 @@
WorkspaceView::WorkspaceView(QWidget* parent, Type type_)
: QTreeView(parent), type(type_)
{
- Properties properties;
-
if(type == FileList)
{
setRootIsDecorated(false);
setItemsExpandable(false);
- resize(properties.getFileListSize());
+ resize(Properties::getFileListSize());
}
else
{
setRootIsDecorated(true);
- resize(properties.getTreeViewSize());
+ resize(Properties::getTreeViewSize());
}
setSelectionMode(QAbstractItemView::ExtendedSelection);
@@ -241,14 +239,13 @@
void WorkspaceView::slotSaveState(void)
{
- Properties properties;
- if(type == FileList)
+ if (type == FileList)
{
- properties.setFileListSize(size());
+ Properties::setFileListSize(size());
}
else
{
- properties.setTreeViewSize(size());
+ Properties::setTreeViewSize(size());
}
}