#
#
# patch "guitone/res/forms/commit_revision.ui"
# from [258d991be703a11e4ef344c8fc8f71d7a7bba0c9]
# to [c91ce1af1162eac46c2c489763cd6738da0f9a1e]
#
# patch "guitone/src/model/GetRevision.cpp"
# from [9ced226a036d9bf560f8b2bc7c2bd90d3d916b40]
# to [f6421a3436ec2f167ed088d707584c9339115902]
#
# patch "guitone/src/model/GetRevision.h"
# from [9cb280cfdc594b15059acce545e9c0a90a8de9d4]
# to [6d277716bb8d73b698e0106d281a1cf626cf01bb]
#
# patch "guitone/src/view/dialogs/CommitRevision.cpp"
# from [7e11a18bb2cfcfd540aeb08139768b216fa21874]
# to [b9af9c76a9a56da8ec92fa06fe3a10b2a495046c]
#
# patch "guitone/src/view/dialogs/CommitRevision.h"
# from [e8c3e1b8d4b3012c7c49c4128a4d9de6ffccd518]
# to [9dfc94422ee757d0387ad5c82421dc3584bad2bc]
#
============================================================
--- guitone/res/forms/commit_revision.ui 258d991be703a11e4ef344c8fc8f71d7a7bba0c9
+++ guitone/res/forms/commit_revision.ui c91ce1af1162eac46c2c489763cd6738da0f9a1e
@@ -52,6 +52,12 @@
QAbstractItemView::ExtendedSelection
+
+ false
+
+
+ false
+
-
@@ -376,21 +382,5 @@
-
- previousChangelogEntryList
- currentIndexChanged(QString)
- changelogEntry
- setPlainText(QString)
-
-
- 308
- 376
-
-
- 293
- 322
-
-
-
============================================================
--- guitone/src/model/GetRevision.cpp 9ced226a036d9bf560f8b2bc7c2bd90d3d916b40
+++ guitone/src/model/GetRevision.cpp f6421a3436ec2f167ed088d707584c9339115902
@@ -21,12 +21,13 @@
#include "GetRevision.h"
#include "InventoryItem.h"
#include "Monotone.h"
-#include "BasicIOParser.h"
-#include
+#include
+#include
+#include
GetRevision::GetRevision(QObject *parent)
- : QStandardItemModel(parent)
+ : QAbstractItemModel(parent)
{
mtnDelegate = new MonotoneDelegate(this);
}
@@ -38,7 +39,8 @@ bool GetRevision::readRevision(const QSt
bool GetRevision::readRevision(const QString & rev)
{
- clear();
+ oldRevision = QString();
+ changelist.clear();
QStringList cmd;
cmd << "get_revision";
@@ -56,17 +58,12 @@ void GetRevision::parseOutput()
Q_ASSERT(parser.parse());
StanzaList list = parser.getStanzas();
- setHorizontalHeaderLabels(QStringList() << tr("Changes"));
- QMap changemap;
-
for (int i=0, size = list.size(); i < size; ++i)
{
Stanza stanza = list.at(i);
+ Change change;
+ bool found_change = false;
- QString type;
- QString data;
- QString data2;
-
for (int j=0, size2 = stanza.size(); j < size2; j++)
{
StanzaEntry entry = stanza.at(j);
@@ -84,149 +81,197 @@ void GetRevision::parseOutput()
break;
}
- // we're only interested in real changeset entries
- if (j == 0 && (entry.sym == "new_manifest" || entry.sym == "old_revision"))
- break;
+ // the calculated manifest is useless if we select parts of the rev
+ if (j == 0 && entry.sym == "new_manifest") break;
- if (entry.sym == "delete")
+ if (entry.sym == "old_revision")
{
Q_ASSERT(entry.vals.size() == 1);
- type = "delete";
- data = entry.vals.at(0);
+ oldRevision = entry.vals.at(0);
break;
}
- if (entry.sym == "rename")
+ found_change = true;
+
+ if (entry.sym == "delete")
{
Q_ASSERT(entry.vals.size() == 1);
- type = "rename";
- data = entry.vals.at(0);
- continue;
+ change.type = Delete;
+ change.stanza = stanza;
+ break;
}
- if (entry.sym == "to" && type == "rename")
+ if (entry.sym == "rename")
{
Q_ASSERT(entry.vals.size() == 1);
- data = tr("%1 to %2").arg(data).arg(entry.vals.at(0));
+ change.type = Rename;
+ change.stanza = stanza;
break;
}
if (entry.sym == "add_dir")
{
Q_ASSERT(entry.vals.size() == 1);
- type = "add_dir";
- data = entry.vals.at(0);
+ change.type = AddDir;
+ change.stanza = stanza;
break;
}
if (entry.sym == "add_file")
{
Q_ASSERT(entry.vals.size() == 1);
- type ="add_file";
- data = entry.vals.at(0);
- // we're not interested in the FILEID here
+ change.type = AddFile;
+ change.stanza = stanza;
break;
}
if (entry.sym == "patch")
{
Q_ASSERT(entry.vals.size() == 1);
- type = "patch";
- data = entry.vals.at(0);
- // we're not interested in the old/new FILEID here
+ change.type = Patch;
+ change.stanza = stanza;
break;
}
if (entry.sym == "clear")
{
Q_ASSERT(entry.vals.size() == 1);
- type = "clear";
- data = entry.vals.at(0);
- continue;
- }
-
- if (entry.sym == "attr" && type == "clear")
- {
- Q_ASSERT(entry.vals.size() == 1);
- data = tr("'%1' from %2").arg(entry.vals.at(0)).arg(data);
+ change.type = AttrClear;
+ change.stanza = stanza;
break;
}
if (entry.sym == "set")
{
Q_ASSERT(entry.vals.size() == 1);
- type = "set";
- data = entry.vals.at(0);
- continue;
- }
-
- if (entry.sym == "attr" && type == "set")
- {
- Q_ASSERT(entry.vals.size() == 1);
- data2 = entry.vals.at(0);
- continue;
- }
-
- if (entry.sym == "value" && type == "set")
- {
- Q_ASSERT(entry.vals.size() == 1);
- data = tr("'%1' to '%2' for %3").arg(entry.vals.at(0)).arg(data2).arg(data);
+ change.type = AttrSet;
+ change.stanza = stanza;
break;
}
+ found_change = false;
+
qWarning("GetRevision::parseOutput(): Unknown symbol %s.", qPrintable(entry.sym));
}
// check if we really processed an item entry
- if (type.size() == 0) continue;
+ if (!found_change) continue;
- if (!changemap.contains(type))
- {
- changemap.insert(type, QStringList());
- }
-
- changemap[type].append(data);
+ changelist.append(change);
}
- QStandardItem * parent = invisibleRootItem();
+ // reset the view
+ reset();
- // FIXME: we should create QStandardItems right from the start and
- // store references to the original Stanza's as data part
- // to make it possible to commit partial changes
- foreach (QString key, changemap.keys())
+ // signal that we've finished (whoever listens to that)
+ emit revisionRead();
+}
+
+QString GetRevision::getRevisionFromSelection(const QModelIndexList & indexes)
+{
+ QString dat;
+ QTextStream stream(&dat);
+
+ stream << "format_version \"1\"\n\n";
+ stream << "old_revision [" << oldRevision << "]\n\n";
+ stream << "new_manifest [" << QString().fill('0', 40) << "]\n\n";
+
+ foreach (QModelIndex index, indexes)
{
- QString label;
- if (key == "delete")
- label = tr("deleted entries");
- else if (key == "renamed")
- label = tr("renamed entries");
- else if (key == "add_dir")
- label = tr("added directories");
- else if (key == "add_file")
- label = tr("added files");
- else if (key == "patch")
- label = tr("patched files");
- else if (key == "clear")
- label = tr("removed attributes");
- else if (key == "set")
- label = tr("added attributes");
- else
- Q_ASSERT(false);
-
- QStandardItem * type = new QStandardItem(label);
- parent->appendRow(type);
-
- foreach (QString data, changemap.value(key))
+ Change * change = static_cast(index.internalPointer());
+ stream << change->getStanzaData() << "\n\n";
+ }
+
+ return dat;
+}
+
+int GetRevision::columnCount(const QModelIndex &parent) const
+{
+ return 2;
+}
+
+QVariant GetRevision::data(const QModelIndex & index, int role) const
+{
+ if (!index.isValid())
+ {
+ return QVariant();
+ }
+
+ int row = index.row();
+ if (row >= changelist.size()) return QVariant();
+
+ Change change(changelist.at(row));
+
+ if (role == Qt::DisplayRole)
+ {
+ switch (index.column())
{
- QStandardItem * entry = new QStandardItem(data);
- type->appendRow(entry);
+ case 0: return QVariant(change.getTypeString());
+ case 1: return QVariant(change.getDisplayData());
+ default: Q_ASSERT(false);
}
}
+ else
+ if (role == Qt::BackgroundRole)
+ {
+ if (index.column() == 0)
+ {
+ return QVariant(QBrush(change.getTypeColor()));
+ }
+ return QVariant();
+ }
+ else
+ if (role == Qt::FontRole && index.column() == 0)
+ {
+ QFont font;
+ font.setPointSize(8);
+ return QVariant(font);
+ }
+ else
+ if (role == Qt::TextAlignmentRole && index.column() == 0)
+ {
+ return QVariant(Qt::AlignCenter);
+ }
+ return QVariant();
+}
+
+Qt::ItemFlags GetRevision::flags(const QModelIndex &index) const
+{
+ return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+}
+
+QVariant GetRevision::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role == Qt::DisplayRole)
+ {
+ switch (section)
+ {
+ case 0: return QVariant(tr("Type"));
+ case 1: return QVariant(tr("Change"));
+ }
+ }
+
+ return QVariant();
+}
+
+int GetRevision::rowCount(const QModelIndex & parent) const
+{
+ return changelist.size();
+}
+
+QModelIndex GetRevision::index(int row, int column, const QModelIndex & parent) const
+{
+ if (!hasIndex(row, column, parent))
+ {
+ return QModelIndex();
+ }
- // reset the view
- reset();
-
- // signal that we've finished (whoever listens to that)
- emit revisionRead();
+ Change * change = new Change(changelist.at(row));
+ return createIndex(row, column, change);
}
+QModelIndex GetRevision::parent(const QModelIndex& index) const
+{
+ return QModelIndex();
+}
+
============================================================
--- guitone/src/model/GetRevision.h 9cb280cfdc594b15059acce545e9c0a90a8de9d4
+++ guitone/src/model/GetRevision.h 6d277716bb8d73b698e0106d281a1cf626cf01bb
@@ -23,16 +23,137 @@
#include "AutomateCommand.h"
#include "MonotoneDelegate.h"
+#include "BasicIOParser.h"
-#include
+#include
+enum ChangeType { Delete, Rename, AddDir, AddFile, Patch, AttrSet, AttrClear };
-class GetRevision : public QStandardItemModel, public AutomateCommand
+struct Change {
+ ChangeType type;
+ Stanza stanza;
+
+ inline QString getTypeString()
+ {
+ switch (type)
+ {
+ case Delete: return QObject::tr("Delete");
+ case Rename: return QObject::tr("Rename");
+ case AddDir: return QObject::tr("Dir add");
+ case AddFile: return QObject::tr("File add");
+ case Patch: return QObject::tr("Patch");
+ case AttrSet: return QObject::tr("Attr set");
+ case AttrClear: return QObject::tr("Attr clear");
+ }
+ return QString();
+ }
+
+ inline Qt::GlobalColor getTypeColor()
+ {
+ switch (type)
+ {
+ case Delete: return Qt::red;
+ case Rename: return Qt::gray;
+ case AddDir: return Qt::darkGreen;
+ case AddFile: return Qt::green;
+ case Patch: return Qt::yellow;
+ case AttrSet: return Qt::cyan;
+ case AttrClear: return Qt::magenta;
+ }
+ return Qt::transparent;
+ }
+
+ inline QString escape(const QString & in)
+ {
+ QString out(in);
+ out.replace("\\", "\\\\");
+ out.replace("\"", "\\\"");
+ return out;
+ }
+
+ inline QString getStanzaData()
+ {
+ switch (type)
+ {
+ case AddDir:
+ return QString("add_dir \"%1\"")
+ .arg(escape(stanza.at(0).vals.at(0)));
+ case AddFile:
+ return QString("add_file \"%1\"\ncontent [%2]")
+ .arg(escape(stanza.at(0).vals.at(0)))
+ .arg(stanza.at(1).vals.at(0));
+ case Delete:
+ return QString("delete \"%1\"")
+ .arg(escape(stanza.at(0).vals.at(0)));
+ case Patch:
+ return QString("patch \"%1\"\nfrom [%2]\nto [%3]")
+ .arg(escape(stanza.at(0).vals.at(0)))
+ .arg(stanza.at(1).vals.at(0))
+ .arg(stanza.at(2).vals.at(0));
+ case Rename:
+ return QString("rename \"%1\"\nto \"%2\"")
+ .arg(escape(stanza.at(0).vals.at(0)))
+ .arg(escape(stanza.at(1).vals.at(0)));
+ case AttrClear:
+ return QObject::tr("clear \"%1\"\nattr \"%2\"")
+ .arg(escape(stanza.at(0).vals.at(0)))
+ .arg(escape(stanza.at(1).vals.at(0)));
+ case AttrSet:
+ return QObject::tr("set \"%1\"\nattr \"%2\"\nvalue \"%3\"")
+ .arg(stanza.at(0).vals.at(0))
+ .arg(stanza.at(1).vals.at(0))
+ .arg(stanza.at(2).vals.at(0));
+ }
+ return QString();
+ }
+
+ inline QString getDisplayData()
+ {
+ switch (type)
+ {
+ case AddDir:
+ case AddFile:
+ case Patch:
+ case Delete:
+ return stanza.at(0).vals.at(0);
+ case Rename:
+ return QObject::tr("%1 to %2")
+ .arg(stanza.at(0).vals.at(0))
+ .arg(stanza.at(1).vals.at(0));
+ case AttrClear:
+ return QObject::tr("'%1' from %2")
+ .arg(stanza.at(1).vals.at(0))
+ .arg(stanza.at(0).vals.at(0));
+ case AttrSet:
+ return QObject::tr("'%1' to '%2' for %3")
+ .arg(stanza.at(1).vals.at(0))
+ .arg(stanza.at(2).vals.at(0))
+ .arg(stanza.at(0).vals.at(0));
+ }
+ return QString();
+ }
+};
+
+typedef QList ChangeList;
+
+
+class GetRevision : public QAbstractItemModel, public AutomateCommand
{
Q_OBJECT
public:
- GetRevision(QObject*);
+ GetRevision(QObject *);
virtual ~GetRevision();
+
+ QString getRevisionFromSelection(const QModelIndexList &);
+
+ // needed Qt Model methods
+ QVariant data(const QModelIndex &, int) const;
+ Qt::ItemFlags flags(const QModelIndex &) const;
+ QVariant headerData(int, Qt::Orientation, int) const;
+ QModelIndex index(int, int, const QModelIndex &) const;
+ QModelIndex parent(const QModelIndex &) const;
+ int rowCount(const QModelIndex &) const;
+ int columnCount(const QModelIndex &) const;
public slots:
bool readRevision(const QString &);
@@ -42,7 +163,10 @@ private:
private:
void parseOutput();
+
MonotoneDelegate * mtnDelegate;
+ ChangeList changelist;
+ QString oldRevision;
};
#endif
============================================================
--- guitone/src/view/dialogs/CommitRevision.cpp 7e11a18bb2cfcfd540aeb08139768b216fa21874
+++ guitone/src/view/dialogs/CommitRevision.cpp b9af9c76a9a56da8ec92fa06fe3a10b2a495046c
@@ -21,9 +21,11 @@
#include "CommitRevision.h"
#include "Monotone.h"
#include "Settings.h"
+#include "Guitone.h"
#include
#include
+#include
CommitRevision::CommitRevision(QWidget* parent) : Dialog(parent)
{
@@ -33,11 +35,20 @@ CommitRevision::CommitRevision(QWidget*
// OSX sheet-alike dialog
setWindowFlags(Qt::Sheet);
- previousChangelogEntryList->addItems(Settings::getItemList("ChangelogEntries"));
+ QStringList entries = Settings::getItemList("ChangelogEntries");
+ QRegExp re("\\s+");
+ for (int i=0, j=entries.size(); iinsertItem(i, shortened, QVariant(entry));
+ }
+
revModel = new GetRevision(this);
changeView->setModel(revModel);
- changeView->header()->hide();
revModel->readRevision(QString());
connect(
@@ -49,6 +60,14 @@ CommitRevision::CommitRevision(QWidget*
invertSelection, SIGNAL(clicked()),
this, SLOT(invertChangesetSelection())
);
+
+ connect(
+ previousChangelogEntryList, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(setChangelogEntryFromList(int))
+ );
+
+ // initialize the text view with the most recent entry
+ setChangelogEntryFromList(0);
}
CommitRevision::~CommitRevision()
@@ -56,10 +75,22 @@ CommitRevision::~CommitRevision()
delete revModel;
}
+void CommitRevision::setChangelogEntryFromList(int index)
+{
+ changelogEntry->setPlainText(
+ previousChangelogEntryList->itemData(index).toString()
+ );
+}
+
void CommitRevision::accept()
{
+ QString newRev = revModel->getRevisionFromSelection(
+ changeView->selectionModel()->selectedRows(1)
+ );
+
+ D(QString("CommitRevision::accept: new revision to commit:\n%1").arg(newRev));
+
Settings::addItemToList("ChangelogEntries", changelogEntry->toPlainText(), 10);
- qDebug("CommitRevision::accept: TODO: commit revision");
done(0);
}
@@ -68,34 +99,20 @@ void CommitRevision::invertChangesetSele
QItemSelectionModel * selectionModel = changeView->selectionModel();
QModelIndex parent;
-
QModelIndex topLeft = revModel->index(0, 0, parent);
QModelIndex bottomRight = revModel->index(
revModel->rowCount(parent)-1,
revModel->columnCount(parent)-1,
parent
);
-
QItemSelection selection(topLeft, bottomRight);
- // FIXME: this does not work in trees with more than two levels
- foreach(QModelIndex parent, selection.indexes())
- {
- topLeft = revModel->index(0, 0, parent);
- bottomRight = revModel->index(
- revModel->rowCount(parent)-1,
- revModel->columnCount(parent)-1,
- parent
- );
- selection.merge(QItemSelection(topLeft, bottomRight), QItemSelectionModel::Select);
- }
-
selectionModel->select(selection, QItemSelectionModel::Toggle);
}
void CommitRevision::checkForChanges()
{
- if (revModel->rowCount() == 0)
+ if (revModel->rowCount(QModelIndex()) == 0)
{
QMessageBox::information(
this,
============================================================
--- guitone/src/view/dialogs/CommitRevision.h e8c3e1b8d4b3012c7c49c4128a4d9de6ffccd518
+++ guitone/src/view/dialogs/CommitRevision.h 9dfc94422ee757d0387ad5c82421dc3584bad2bc
@@ -38,6 +38,7 @@ private slots:
private slots:
void invertChangesetSelection();
+ void setChangelogEntryFromList(int);
void checkForChanges();
void accept();
};