# # # add_file "res/forms/add_edit_attribute.ui" # content [82503020fbedbad0c1879c82e4203aaed9db637a] # # add_file "res/icons/blue_dot.png" # content [374a767d9c0e4543e105686b885ad71950941e1d] # # add_file "src/view/dialogs/AddEditAttribute.cpp" # content [1f9555c4103d227d66191031fea7b1e9d41462e7] # # add_file "src/view/dialogs/AddEditAttribute.h" # content [aea71c7ba22359058eaccfc8be8d112dd79bf231] # # patch "guitone.pro" # from [c11bc3fb57e03c3f13033bb24188b9eb6abd6924] # to [699626c565b3bcc3597192c0db6a9dbb8c68c365] # # patch "res/forms/main_window.ui" # from [600472d44fd5cd51100da93909a592d1815e3505] # to [62e7adc05de694719accc073130e06466fe8285a] # # patch "res/guitone.qrc" # from [9e442c897e6755d7320d762f2a9410ecef620221] # to [f79689930cf514724cb11d18e452cba44630c2b6] # # patch "res/i18n/guitone_de.ts" # from [f97a54ec58da7eec984b6fbaa85993e65ca85340] # to [2f3020049a9bd726f41f404406d2f5022441a531] # # patch "src/model/GetAttributes.cpp" # from [af7f17de332d7eef87a2bda5f565e094a4c1671a] # to [c1f8ccabf73da0b5f91634619197f0adbfeb31de] # # patch "src/model/GetAttributes.h" # from [b6e49201bf220ba5b56af673ae64f5d860c66df1] # to [f9f06f87a1177277bce55b69800a14df55fffbd3] # # patch "src/monotone/Monotone.cpp" # from [5464a4a21288891c7da8d95d84bccef25cb45beb] # to [6b962ee24fefc82e7a8fd109a9146791ce4d5bbb] # # patch "src/monotone/Monotone.h" # from [370ce5b4d643260e775d5c2c54cbd419c8a11885] # to [80301b24df106400ce43e27aabba89f46c8d43c3] # # patch "src/view/AttributesView.cpp" # from [79e6d4bc94d165c6023896d599cfb17e25101b4e] # to [f815426941c4a99796b7d9f05da890e614f14fa7] # # patch "src/view/AttributesView.h" # from [e61a81362d8675755fed6e28109c93b0b4363313] # to [80630071659d7628915dcd81f8adaa9f7b934638] # # patch "src/view/MainWindow.cpp" # from [79df09cea17cb3370404a769946f4b2f0c8de9c4] # to [b290e96f521b7c11d73ad9f8a5827ce8b00ff1c4] # # patch "src/view/MainWindow.h" # from [7b4ca503131853dfb98f4057c543a37cd63b3f16] # to [49a87144c3f5ef2d99f1ca0acc4acb11e21a402c] # # patch "src/vocab.h" # from [93fa57e57a96913ac73783a9abb2987bff6151e7] # to [e150d1f8366d29c1fb517be3cbddc54cadcf7092] # # set "res/icons/blue_dot.png" # attr "mtn:manual_merge" # value "true" # ============================================================ --- res/forms/add_edit_attribute.ui 82503020fbedbad0c1879c82e4203aaed9db637a +++ res/forms/add_edit_attribute.ui 82503020fbedbad0c1879c82e4203aaed9db637a @@ -0,0 +1,150 @@ + + AddEditAttributeDialog + + + + 0 + 0 + 422 + 136 + + + + Add / edit an attribute + + + :/icons/guitone.png + + + + 9 + + + 6 + + + + + 0 + + + 6 + + + + + 0 + + + 6 + + + + + 0 + + + 6 + + + + + Key + + + + + + + Value + + + + + + + + + 0 + + + 6 + + + + + true + + + + + + + + 3 + 0 + 0 + 0 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok + + + false + + + + + + + + + + + + + buttonBox + rejected() + AddEditAttributeDialog + reject() + + + 271 + 109 + + + 236 + 122 + + + + + buttonBox + accepted() + AddEditAttributeDialog + accept() + + + 353 + 107 + + + 379 + 127 + + + + + ============================================================ # res/icons/blue_dot.png is binary ============================================================ --- src/view/dialogs/AddEditAttribute.cpp 1f9555c4103d227d66191031fea7b1e9d41462e7 +++ src/view/dialogs/AddEditAttribute.cpp 1f9555c4103d227d66191031fea7b1e9d41462e7 @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2007 by Thomas Keller * + * address@hidden * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "AddEditAttribute.h" + +AddEditAttribute::AddEditAttribute( + QWidget * parent, const QString & key, const QString & value +) : Dialog(parent) +{ + setupUi(this); + Dialog::init(); + + // these are added here and not in designer to prevent their + // automatic localization through uic + attrKey->insertItem(0, "mtn:execute"); + attrKey->insertItem(1, "mtn:manual_merge"); + + int keyPos = attrKey->findText(key); + if (keyPos == -1) + { + attrKey->insertItem(0, key); + keyPos = 0; + } + + attrKey->setCurrentIndex(keyPos); + attrValue->setText(value); +} + +AddEditAttribute::~AddEditAttribute() {} + ============================================================ --- src/view/dialogs/AddEditAttribute.h aea71c7ba22359058eaccfc8be8d112dd79bf231 +++ src/view/dialogs/AddEditAttribute.h aea71c7ba22359058eaccfc8be8d112dd79bf231 @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2007 by Thomas Keller * + * address@hidden * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef ADDEDITATTRIBUTE_H +#define ADDEDITATTRIBUTE_H + +#include "ui_add_edit_attribute.h" +#include "Dialog.h" +#include "vocab.h" + +class AddEditAttribute : public Dialog, private Ui::AddEditAttributeDialog +{ + Q_OBJECT + +public: + AddEditAttribute(QWidget *, + const QString & key = QString(), const QString & value = QString()); + ~AddEditAttribute(); + QString getKey() const { return attrKey->currentText(); } + QString getValue() const { return attrValue->text(); } +}; + +#endif + ============================================================ --- guitone.pro c11bc3fb57e03c3f13033bb24188b9eb6abd6924 +++ guitone.pro 699626c565b3bcc3597192c0db6a9dbb8c68c365 @@ -37,6 +37,7 @@ HEADERS = src/view/MainWindow.h \ src/view/dialogs/CommitRevision.h \ src/view/dialogs/FileHistory.h \ src/view/dialogs/UnaccountedRenames.h \ + src/view/dialogs/AddEditAttribute.h \ src/monotone/Monotone.h \ src/monotone/MonotoneDelegate.h \ src/monotone/FileExporter.h \ @@ -98,6 +99,7 @@ SOURCES += src/view/MainWindow.cpp \ src/view/dialogs/CommitRevision.cpp \ src/view/dialogs/FileHistory.cpp \ src/view/dialogs/UnaccountedRenames.cpp \ + src/view/dialogs/AddEditAttribute.cpp \ src/monotone/Monotone.cpp \ src/monotone/MonotoneDelegate.cpp \ src/monotone/FileExporter.cpp \ @@ -152,7 +154,8 @@ FORMS += res/forms/select_revision.ui res/forms/commit_revision.ui \ res/forms/application_update.ui \ res/forms/file_history.ui \ - res/forms/unaccounted_renames.ui + res/forms/unaccounted_renames.ui \ + res/forms/add_edit_attribute.ui UI_DIR = tmp ============================================================ --- res/forms/main_window.ui 600472d44fd5cd51100da93909a592d1815e3505 +++ res/forms/main_window.ui 62e7adc05de694719accc073130e06466fe8285a @@ -26,7 +26,7 @@ - 1 + 0 @@ -61,7 +61,11 @@ QAbstractItemView::ExtendedSelection - + + + true + + ============================================================ --- res/guitone.qrc 9e442c897e6755d7320d762f2a9410ecef620221 +++ res/guitone.qrc f79689930cf514724cb11d18e452cba44630c2b6 @@ -6,6 +6,7 @@ icons/red_dot.png icons/yellow_dot.png icons/green_dot.png + icons/blue_dot.png icons/arrow_down.png overlays/added.png overlays/added_missing.png ============================================================ --- res/i18n/guitone_de.ts f97a54ec58da7eec984b6fbaa85993e65ca85340 +++ res/i18n/guitone_de.ts 2f3020049a9bd726f41f404406d2f5022441a531 @@ -1,13 +1,8 @@ About - - <small>Version %1.%2</small> - <small>Version %1.%2</small> - - <br/><br/>Authors: <a href="mailto:address@hidden">Thomas Keller</a>, <a href="mailto:address@hidden">Ingo Maindorfer</a> and <a href="mailto:address@hidden">Jean-Louis Fuchs</a>.<br/><br/>This program is free software; you can redistribute it and/or modify<br/>it under the terms of the GNU General Public License as published by<br/>the Free Software Foundation; either version 2 of the License, or<br/>(at your option) any later version.<br/><br/>Bugs? Suggestions? Help? <a href="http://guitone.thomaskeller.biz">guitone Homepage</a><br/><br/>Many thanks go to the friendly guys at <a href="irc://irc.freenode.net/qt">#qt</a> for their helpful<br/>comments during endless coding sessions - you guys rock! <br/><br/>Autoren: <a href="mailto:address@hidden">Thomas Keller</a>, <a href="mailto:address@hidden">Ingo Maindorfer</a> und <a href="mailto:address@hidden">Jean-Louis Fuchs</a><br/><br/>Dieses Programm ist freie Software. Sie können es unter den<br/>Bedingungen der GNU General Public License, wie von der<br/>Free Software Foundation veröffentlicht, weitergeben und/oder<br/>modifizieren, entweder gemäß Version 2 der Lizenz oder <br/>(nach Ihrer Option) jeder späteren Version.<br/><br/>Fehler? Vorschläge? Hilfe? <a href="http://guitone.thomaskeller.biz">guitone Webseite</a><br/><br/>Vielen Dank an die freundlichen Seelen auf <a href="irc://irc.freenode.net/qt">#qt</a> für die Hilfe während der<br/>unendlich langen Programmierstunden - Ihr Jungs s eid Spitze! @@ -32,6 +27,24 @@ + AddEditAttributeDialog + + + Add / edit an attribute + Hinzufügen / Editieren eines Attributes + + + + Key + Schlüssel + + + + Value + Wert + + + Ancestors @@ -58,42 +71,22 @@ - Attributes + AttributesView - - added - hinzugefügt + + add new attribute + Neues Attribut hinzufügen - - dropped - entfernt + + edit attribute + Attribut editieren - - changed - verändert + + drop attribute + Attribut löschen - - - unchanged - unverändert - - - - Key - Schlüssel - - - - Value - Wert - - - - State - Status - Branches @@ -373,16 +366,6 @@ Zeige Änderungen gegenüber Elternrevision - - Select all - Alle auswählen - - - - Invert Selection - Auswahl umkehren - - Changelog entry Changelog-Eintrag @@ -519,34 +502,6 @@ In jedem Fall sollte der derzeitige Arbe - DatabaseView - - - Database - Datenbank - - - - All Changesets - Alle Änderungen - - - - 50 More Changesets - 50 weitere Änderungen - - - - Done - Beenden - - - - ... - ... - - - FileDiff @@ -577,26 +532,6 @@ In jedem Fall sollte der derzeitige Arbe Unterschiede in der Datei "%1" - - Show Version - Zeige Version - - - - Left - links - - - - Right - rechts - - - - Both - beide - - Close Schließen @@ -635,11 +570,6 @@ In jedem Fall sollte der derzeitige Arbe FileExporter - - Exporting files... - Exportiere Dateien... - - Abort Abbrechen @@ -757,6 +687,44 @@ In jedem Fall sollte der derzeitige Arbe + GetAttributes + + + empty + leer + + + + added + hinzugefügt + + + + dropped + entfernt + + + + changed + verändert + + + + unchanged + unverändert + + + + Key + Schlüssel + + + + Value + Wert + + + GetContentChanged @@ -808,25 +776,12 @@ In jedem Fall sollte der derzeitige Arbe 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 - - Select your workspace... Wählen Sie Ihren Arbeitsbereich aus... - Inventory - - - [unknown branch] - [unbekannter Zweig] - - - InventoryItem @@ -902,101 +857,51 @@ In jedem Fall sollte der derzeitige Arbe 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 @@ -1017,11 +922,6 @@ In jedem Fall sollte der derzeitige Arbe 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 @@ -1087,61 +987,31 @@ In jedem Fall sollte der derzeitige Arbe Füge %1 Einträge hinzu - - Add multiple files - Fügt mehrere Einträge hinzu - - Remove %1 items Entferne %1 Einträge - - Remove multiple files - Entfernt mehrere Einträge - - Commit %1 items Pflege %1 Einträge ein - - Commit multiple files - Pflegt mehrere Einträge ein - - Ignore %1 items Ignoriere %1 Einträge - - Ignore multiple files - Ignoriert mehrere Einträge - - Unignore %1 items Ignoriere %1 Einträge nicht mehr - - Unignore multiple files - Ignoriere mehrere Einträge nicht mehr - - Revert %1 items Setze %1 Einträge zurück - - Revert multiple files - Setze mehrere Einträge zurück - - Add multiple items Füge mehrere Einträge hinzu @@ -1306,11 +1176,6 @@ In jedem Fall sollte der derzeitige Arbe Keine vorherigen Arbeitsbereiche verfügbar. - - Preferences.... - Einstellungen... - - Ctrl+P Strg+P @@ -1341,91 +1206,46 @@ In jedem Fall sollte der derzeitige Arbe 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 @@ -1436,11 +1256,6 @@ In jedem Fall sollte der derzeitige Arbe Strg+T - - Switch revision - Revision wechseln - - Ctrl+R Strg+R @@ -1486,26 +1301,6 @@ In jedem Fall sollte der derzeitige Arbe 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? - - Show ignored files Zeige ignorierte Dateien @@ -1596,17 +1391,6 @@ In jedem Fall sollte der derzeitige Arbe Alt+N - - Currently there is no workspace or database loaded. - -To open a workspace, go to File > Open workspace -or File > Open Database for a database respectively. - Derzeit ist weder ein Arbeitsbereich noch eine Datenbank geladen, - -Um einen Arbeitsbereich zu öffnen, gehen Sie auf Datei > Arbeitsbereich öffnen -oder respektive auf Datei > Datenbank öffnen. - - Window Fenster @@ -1672,11 +1456,6 @@ oder respektive auf Datei > Datenbank %1 - Arbeitsbereichmodus - guitone - - No workspace or database loaded - guitone - Kein Arbeitsbereich oder Datenbank geladen - guitone - - Unable to load workspace Konnte Arbeitsbereich nicht laden @@ -1814,17 +1593,6 @@ Die letzte Ausgabe war: Monotone - - 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 überprüfen Sie den Pfad zur ausführbaren Datei von monotone im Eigenschaften-Dialog und stellen Sie sicher, dass die Version der Datenbank, die Sie versucht haben zu laden, mit der Version von monotone übereinstimmt. - -monotone gab zurück: -%2 - - [process not created] [Prozess nicht erzeugt] @@ -1841,55 +1609,60 @@ monotone gab zurück: Preferences - - Low (fatal errors) - Niedrig (fatale Fehler) - - - - Medium (critical errors) - Mittel (kritische Fehler) - - - - High (warnings) - Hoch (Warnungen) - - - - All (debug messages) - Alle (Debugmeldungen) - - - + 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. - + Notice Hinweis - + You need to reload your current workspace or restart guitone to use the new monotone binary. Sie müssen Ihren derzeitigen Arbeitsbereich oder guitone neu laden, um die neue monotone-Binary zu nutzen. - + Choose the monotone executable Wählen Sie die ausführbare Datei von monotone - + Binaries (mtn mtn.exe) Binärdateien (mtn mtn.exe) + + + Very low (only fatal) + Sehr niedrig (nur fatale Fehler) + + + + Low (critical) + Niedrig (kritische Fehler) + + + + Medium (warnings) + Mittel (Warnungen) + + + + High (info messages) + Hoch (Informationen) + + + + Very high (debug messages) + Sehr hoch (Debug-Meldungen) + PreferencesDialog @@ -1987,21 +1760,6 @@ monotone gab zurück: Attr gelöscht - - %1 to %2 - %1 nach %2 - - - - '%1' from %2 - '%1' von %2 - - - - '%1' to '%2' for %3 - '%1' auf '%2' für %3 - - %1 to %2 @@ -2016,13 +1774,6 @@ monotone gab zurück: %2 - - '%1' to '%2' -for %3 - '%1' auf '%2' -für %3 - - '%1' to '%2' for @@ -2426,11 +2177,6 @@ für %3 - The selected revision has more than one branch cert attached - please select one: - Die ausgewählte Revision besitzt mehr als ein Zweigzertifikat - bitte wählen Sie eins: - - - The selected revision has more than one branch cert attached - please select one: Die ausgewählte Revision besitzt mehr als ein ============================================================ --- src/model/GetAttributes.cpp af7f17de332d7eef87a2bda5f565e094a4c1671a +++ src/model/GetAttributes.cpp c1f8ccabf73da0b5f91634619197f0adbfeb31de @@ -19,12 +19,11 @@ ***************************************************************************/ #include "GetAttributes.h" -#include "InventoryItem.h" #include "Monotone.h" #include "BasicIOParser.h" -#include #include +#include GetAttributes::GetAttributes(QObject *parent) : QAbstractItemModel(parent) @@ -40,34 +39,26 @@ GetAttributes::~GetAttributes() delete mtnDelegate; } -bool GetAttributes::readAttributes(const QModelIndex & index) +void GetAttributes::revert() { - // convert ProxyModel index to real Model index - QModelIndex sourceIndex = static_cast(index.model())->mapToSource(index); - // get the Model's item reference out there - InventoryItem *item = static_cast(sourceIndex.internalPointer()); + attributes->clear(); + path = QString(); + reset(); +} +bool GetAttributes::readAttributes(const QString & p) +{ // clear current attributes list attributes->clear(); // reset the view reset(); - if (item->isRootDirectory() || item->isCdUp()) - { - D("item is pseudo item (root or cdup)"); - return false; - } - - if (item->hasStatus(InventoryItem::Dropped) || !item->isTracked()) - { - D("item is not tracked or dropped"); - return false; - } - QStringList cmd; cmd.append("get_attributes"); - cmd.append(item->getPath()); + cmd.append(p); + path = p; + return mtnDelegate->triggerCommand(cmd); } @@ -161,13 +152,12 @@ QVariant GetAttributes::data(const QMode Attribute attr = attributes->at(row); - if (role == Qt::DisplayRole) { switch (col) { - case 1: return QVariant(attr.key); - case 2: return QVariant(attr.value); + case 1: return QVariant(attr.key.length() == 0 ? tr("empty") : attr.key); + case 2: return QVariant(attr.value.length() == 0 ? tr("empty") : attr.value); default: return QVariant(); } } @@ -190,11 +180,36 @@ QVariant GetAttributes::data(const QMode { case Attribute::Added: return QVariant(QIcon(":/icons/green_dot.png")); case Attribute::Dropped: return QVariant(QIcon(":/icons/red_dot.png")); - case Attribute::Changed: return QVariant(QIcon(":/icons/yellow_dot.png")); + case Attribute::Unchanged: return QVariant(QIcon(":/icons/yellow_dot.png")); + case Attribute::Changed: return QVariant(QIcon(":/icons/blue_dot.png")); default: return QVariant(); } } + if (role == Qt::FontRole) + { + QFont font; + font.setItalic(true); + + if (col == 1 && attr.key.length() == 0) + return QVariant(font); + + if (col == 2 && attr.value.length() == 0) + return QVariant(font); + + return QVariant(); + } + + if (role == Qt::UserRole) + { + switch (col) + { + case 1: return QVariant(attr.key); + case 2: return QVariant(attr.value); + default: return QVariant(); + } + } + return QVariant(); } ============================================================ --- src/model/GetAttributes.h b6e49201bf220ba5b56af673ae64f5d860c66df1 +++ src/model/GetAttributes.h f9f06f87a1177277bce55b69800a14df55fffbd3 @@ -39,7 +39,9 @@ public: public: GetAttributes(QObject*); virtual ~GetAttributes(); - + + inline QString currentPath() const { return path; } + // needed Qt Model methods QVariant data(const QModelIndex&, int) const; Qt::ItemFlags flags(const QModelIndex&) const; @@ -47,11 +49,12 @@ public: QModelIndex index(int, int, const QModelIndex&) const; QModelIndex parent(const QModelIndex&) const; int rowCount(const QModelIndex&) const; - int columnCount(const QModelIndex&) const; + int columnCount(const QModelIndex&) const; public slots: - bool readAttributes(const QModelIndex &); - + bool readAttributes(const QString &); + void revert(); + signals: void attributesRead(); @@ -59,6 +62,7 @@ private: void parseOutput(); AttributeList * attributes; MonotoneDelegate * mtnDelegate; + QString path; }; #endif ============================================================ --- src/monotone/Monotone.cpp 5464a4a21288891c7da8d95d84bccef25cb45beb +++ src/monotone/Monotone.cpp 6b962ee24fefc82e7a8fd109a9146791ce4d5bbb @@ -354,26 +354,27 @@ QString Monotone::getStderr() return stripMtnPrefix(output); } -bool Monotone::executeCommand(const QStringList & command, int & commandNumber) +bool Monotone::executeCommand(const QStringList & command, int & commandNumber, bool skipEmpty) { - return executeCommand(command, QStringList(), commandNumber); + return executeCommand(command, QStringList(), commandNumber, skipEmpty); } -bool Monotone::executeCommand(const ByteArrayList & command, int & commandNumber) +bool Monotone::executeCommand(const ByteArrayList & command, int & commandNumber, bool skipEmpty) { - return executeCommand(command, ByteArrayList(), commandNumber); + return executeCommand(command, ByteArrayList(), commandNumber, skipEmpty); } -bool Monotone::executeCommand(const QStringList & command, const QStringList & options, int & commandNumber) +bool Monotone::executeCommand(const QStringList & command, const QStringList & options, int & commandNumber, bool skipEmpty) { return executeCommand( stringToByteArrayList(command), stringToByteArrayList(options), - commandNumber + commandNumber, + skipEmpty ); } -bool Monotone::executeCommand(const ByteArrayList & command, const ByteArrayList & options, int & commandNumber) +bool Monotone::executeCommand(const ByteArrayList & command, const ByteArrayList & options, int & commandNumber, bool skipEmpty) { if (doAbortRequests || process->state() != QProcess::Running) { @@ -381,7 +382,7 @@ bool Monotone::executeCommand(const Byte return false; } - commandNumber = writeStdin(command, options); + commandNumber = writeStdin(command, options, skipEmpty); SignalWaiter waiter(this, SIGNAL(commandFinished(int))); do @@ -393,26 +394,27 @@ bool Monotone::executeCommand(const Byte return !doAbortRequests; } -bool Monotone::triggerCommand(const QStringList & command, int & commandNumber) +bool Monotone::triggerCommand(const QStringList & command, int & commandNumber, bool skipEmpty) { - return triggerCommand(command, QStringList(), commandNumber); + return triggerCommand(command, QStringList(), commandNumber, skipEmpty); } -bool Monotone::triggerCommand(const ByteArrayList & command, int & commandNumber) +bool Monotone::triggerCommand(const ByteArrayList & command, int & commandNumber, bool skipEmpty) { - return triggerCommand(command, ByteArrayList(), commandNumber); + return triggerCommand(command, ByteArrayList(), commandNumber, skipEmpty); } -bool Monotone::triggerCommand(const QStringList & command, const QStringList & options, int & commandNumber) +bool Monotone::triggerCommand(const QStringList & command, const QStringList & options, int & commandNumber, bool skipEmpty) { return triggerCommand( stringToByteArrayList(command), stringToByteArrayList(options), - commandNumber + commandNumber, + skipEmpty ); } -bool Monotone::triggerCommand(const ByteArrayList & command, const ByteArrayList & options, int & commandNumber) +bool Monotone::triggerCommand(const ByteArrayList & command, const ByteArrayList & options, int & commandNumber, bool skipEmpty) { if (doAbortRequests || process->state() != QProcess::Running) { @@ -420,11 +422,11 @@ bool Monotone::triggerCommand(const Byte return false; } - commandNumber = writeStdin(command, options); + commandNumber = writeStdin(command, options, skipEmpty); return true; } -int Monotone::writeStdin(const ByteArrayList & command, const ByteArrayList & options) +int Monotone::writeStdin(const ByteArrayList & command, const ByteArrayList & options, bool skipEmpty) { QByteArray commandLine; QTextStream streamCmdLine(&commandLine); @@ -438,7 +440,7 @@ int Monotone::writeStdin(const ByteArray for (int i=0, c=options.size(); i -AttributesView::AttributesView(QWidget* parent) -: TreeView(parent) +AttributesView::AttributesView(QWidget * parent) : TreeView(parent) { setRootIsDecorated(false); setItemsExpandable(false); QHeaderView * headerView = header(); headerView->setClickable(true); + headerView->setResizeMode(QHeaderView::ResizeToContents); connect( headerView, SIGNAL(sectionClicked(int)), this, SLOT(sectionClicked(int)) ); - popupMenu = new QMenu(this); - popupMenu->addAction( - tr("add new attribute"), this, SLOT(addAttribute()) + connect( + this, SIGNAL(contextMenuRequested(const QModelIndexList &, const QPoint &)), + this, SLOT(menuRequested(const QModelIndexList &, const QPoint &)) ); - popupMenu->addAction( - tr("edit selected attribute"), this, SLOT(editAttribute()) - ); - popupMenu->addAction( - tr("drop selected attribute"), this, SLOT(dropAttribute()) - ); } -AttributesView::~AttributesView() -{ - delete popupMenu; -} +AttributesView::~AttributesView() {} void AttributesView::sectionClicked(int logicalIndex) { + // do not popup the menu if we haven't focused a valid item + GetAttributes * attrModel = qobject_cast(model()); + if (attrModel->currentPath().isEmpty()) return; + if (logicalIndex != 0) return; QHeaderView * headerView = header(); @@ -77,21 +79,115 @@ void AttributesView::sectionClicked(int left = headerView->width() - headerView->sectionSize(logicalIndex); } - popupMenu->exec(mapToGlobal(QPoint(left, top))); + QMenu popupMenu(this); + popupMenu.addAction( + tr("add new attribute"), this, SLOT(addAttribute()) + ); + popupMenu.exec(mapToGlobal(QPoint(left, top))); } +void AttributesView::menuRequested(const QModelIndexList & indexes, const QPoint & pt) +{ + if (indexes.size() != 1) return; + + selectedIndex = indexes.at(0); + + QMenu popupMenu(this); + popupMenu.addAction( + tr("edit attribute"), this, SLOT(editAttribute()) + ); + popupMenu.addAction( + tr("drop attribute"), this, SLOT(dropAttribute()) + ); + + popupMenu.exec(pt); +} + void AttributesView::addAttribute() { - D("TODO"); + AddEditAttribute dlg(this); + + if (dlg.exec() == QDialog::Accepted) + { + GetAttributes * attrModel = qobject_cast(model()); + + QStringList cmd; + cmd << "set_attribute"; + cmd << attrModel->currentPath(); + cmd << dlg.getKey() << dlg.getValue(); + + Monotone * mtn = MTN(this); + int cmdNum = 0; + // do not skip empty parameters + mtn->executeCommand(cmd, cmdNum, false); + + if (mtn->getReturnCode(cmdNum) > 0) + { + C(QString("Couldn't set attribute")); + return; + } + + attrModel->readAttributes(attrModel->currentPath()); + } } void AttributesView::editAttribute() { - D("TODO"); + QModelIndex keyIdx = model()->index(selectedIndex.row(), 1, QModelIndex()); + QModelIndex valIdx = model()->index(selectedIndex.row(), 2, QModelIndex()); + + // UserRole is overloaded with the actual string value of the + // key / value pair + QString key = model()->data(keyIdx, Qt::UserRole).toString(); + QString val = model()->data(valIdx, Qt::UserRole).toString(); + + AddEditAttribute dlg(this, key, val); + + if (dlg.exec() == QDialog::Accepted) + { + GetAttributes * attrModel = qobject_cast(model()); + + QStringList cmd; + cmd << "set_attribute"; + cmd << attrModel->currentPath(); + cmd << dlg.getKey() << dlg.getValue(); + + Monotone * mtn = MTN(this); + int cmdNum = 0; + // do not skip empty parameters + mtn->executeCommand(cmd, cmdNum, false); + + if (mtn->getReturnCode(cmdNum) > 0) + { + C(QString("Couldn't set attribute")); + return; + } + + attrModel->readAttributes(attrModel->currentPath()); + } } void AttributesView::dropAttribute() { - D("TODO"); + GetAttributes * attrModel = qobject_cast(model()); + QModelIndex keyIdx = attrModel->index(selectedIndex.row(), 1, QModelIndex()); + + QStringList cmd; + cmd << "drop_attribute"; + cmd << attrModel->currentPath(); + cmd << model()->data(keyIdx, Qt::UserRole).toString(); // the key + + Monotone * mtn = MTN(this); + int cmdNum = 0; + // do not skip empty parameters + mtn->executeCommand(cmd, cmdNum, false); + + if (mtn->getReturnCode(cmdNum) > 0) + { + C(QString("Couldn't drop attribute")); + return; + } + + attrModel->readAttributes(attrModel->currentPath()); } ============================================================ --- src/view/AttributesView.h e61a81362d8675755fed6e28109c93b0b4363313 +++ src/view/AttributesView.h 80630071659d7628915dcd81f8adaa9f7b934638 @@ -34,12 +34,15 @@ private slots: private slots: void sectionClicked(int); + void menuRequested(const QModelIndexList &, const QPoint &); + void addAttribute(); void editAttribute(); void dropAttribute(); private: - QMenu * popupMenu; + QModelIndex selectedIndex; + QString path; }; #endif ============================================================ --- src/view/MainWindow.cpp 79df09cea17cb3370404a769946f4b2f0c8de9c4 +++ src/view/MainWindow.cpp b290e96f521b7c11d73ad9f8a5827ce8b00ff1c4 @@ -91,11 +91,11 @@ MainWindow::MainWindow() // query attributes on click connect( treeView, SIGNAL(clicked(const QModelIndex &)), - attrModel, SLOT(readAttributes(const QModelIndex &)) + this, SLOT(readAttributes(const QModelIndex &)) ); connect( listView, SIGNAL(clicked(const QModelIndex &)), - attrModel, SLOT(readAttributes(const QModelIndex &)) + this, SLOT(readAttributes(const QModelIndex &)) ); // filelist/tree synchronization @@ -678,3 +678,25 @@ void MainWindow::on_actionFind_unaccount dlg.execDocumentModal(); } +void MainWindow::readAttributes(const QModelIndex & index) +{ + QModelIndex sourceIndex = static_cast(index.model())->mapToSource(index); + InventoryItem * item = static_cast(sourceIndex.internalPointer()); + + if (item->isRootDirectory() || item->isCdUp()) + { + D("item is pseudo item (root or cdup)"); + attrModel->revert(); + return; + } + + if (item->hasStatus(InventoryItem::Dropped) || !item->isTracked()) + { + D("item is not tracked or dropped"); + attrModel->revert(); + return; + } + + attrModel->readAttributes(item->getPath()); +} + ============================================================ --- src/view/MainWindow.h 7b4ca503131853dfb98f4057c543a37cd63b3f16 +++ src/view/MainWindow.h 49a87144c3f5ef2d99f1ca0acc4acb11e21a402c @@ -82,6 +82,7 @@ private slots: void updateWindowList(); void activateOtherWindow(); void invalidWorkspaceFormat(const QString &); + void readAttributes(const QModelIndex &); private: void closeEvent(QCloseEvent *); ============================================================ --- src/vocab.h 93fa57e57a96913ac73783a9abb2987bff6151e7 +++ src/vocab.h e150d1f8366d29c1fb517be3cbddc54cadcf7092 @@ -5,6 +5,7 @@ // global macros and defines // +// if you use any of those two, you also have to include Guitone.h class Guitone; #define APP reinterpret_cast(qApp) #define MTN(arg) APP->getMonotoneInstance(arg)