changeset 108:8ae3b44c0073

* Enable/disable update and merge actions depending on whether default update and merge will actually do anything
author Chris Cannam
date Thu, 25 Nov 2010 21:08:17 +0000
parents fdca34c989c0
children 1721c580c10e
files changeset.cpp changeset.h hgtabwidget.cpp logparser.cpp mainwindow.cpp mainwindow.h
diffstat 6 files changed, 84 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/changeset.cpp	Thu Nov 25 20:18:10 2010 +0000
+++ b/changeset.cpp	Thu Nov 25 21:08:17 2010 +0000
@@ -28,6 +28,8 @@
             setParents(parents);
         } else if (key == "timestamp") {
             setTimestamp(e.value(key).split(" ")[0].toULongLong());
+        } else if (key == "changeset") {
+            setId(e.value(key));
         } else {
             setProperty(key.toLocal8Bit().data(), e.value(key));
         }
--- a/changeset.h	Thu Nov 25 20:18:10 2010 +0000
+++ b/changeset.h	Thu Nov 25 21:08:17 2010 +0000
@@ -26,6 +26,10 @@
 
 #include "logparser.h"
 
+class Changeset;
+
+typedef QList<Changeset *> Changesets;  //!!! should be QList<QSharedPointer<Changeset> >
+
 class Changeset : public QObject
 {
     Q_OBJECT
@@ -69,6 +73,23 @@
         return datetime().split(' ')[0];
     }
 
+    bool isOnBranch(QString branch) {
+        QString b = m_branch;
+        if (branch == "") branch = "default";
+        if (b == "") b = "default";
+        if (branch == b) return true;
+        return false;
+    }
+
+    static Changesets parseChangesets(QString logText) {
+        Changesets csets;
+        LogList log = LogParser(logText).parse();
+        foreach (LogEntry e, log) {
+            csets.push_back(new Changeset(e));
+        }
+        return csets;
+    }
+
 signals:
     void idChanged(QString id);
     void authorChanged(QString author);
@@ -107,6 +128,5 @@
     QString m_comment;
 };
 
-typedef QList<Changeset *> Changesets;
 
 #endif // CHANGESET_H
--- a/hgtabwidget.cpp	Thu Nov 25 20:18:10 2010 +0000
+++ b/hgtabwidget.cpp	Thu Nov 25 21:08:17 2010 +0000
@@ -150,16 +150,12 @@
     if (oldScene) delete oldScene;
     ChangesetItem *tipItem = g.getItemFor(csets[0]);
     if (tipItem) tipItem->ensureVisible();
+    //!!! track lifecycle of those Changesets
 }
 
 Changesets HgTabWidget::parseChangeSets(QString changeSetsStr)
 {
-    Changesets csets;
-    LogList log = LogParser(changeSetsStr).parse();
-    foreach (LogEntry e, log) {
-        Changeset *cs = new Changeset(e);
-        csets.push_back(cs);
-    }
+    Changesets csets = Changeset::parseChangesets(changeSetsStr);
     for (int i = 0; i+1 < csets.size(); ++i) {
         Changeset *cs = csets[i];
         if (cs->parents().empty()) {
--- a/logparser.cpp	Thu Nov 25 20:18:10 2010 +0000
+++ b/logparser.cpp	Thu Nov 25 21:08:17 2010 +0000
@@ -36,7 +36,7 @@
 LogList LogParser::parse()
 {
     LogList results;
-    QRegExp re(QString("^(\\w+)\\s*%1\\s+(.*)$").arg(m_sep));
+    QRegExp re(QString("^(\\w+)\\s*%1\\s+([^\\s].*)$").arg(m_sep));
     QStringList entries = split();
     foreach (QString entry, entries) {
         LogEntry dictionary;
--- a/mainwindow.cpp	Thu Nov 25 20:18:10 2010 +0000
+++ b/mainwindow.cpp	Thu Nov 25 21:08:17 2010 +0000
@@ -362,7 +362,7 @@
                 params << "commit" << "--message" << comment << "--user" << getUserInfo();
             }
 
-            runner -> startHgCommand(workFolderPath, params, true);
+            runner -> startHgCommand(workFolderPath, params, false);
             runningAction = ACT_COMMIT;
         }
     }
@@ -1122,14 +1122,15 @@
             //Clumsy...
             if ((EXITOK(exitCode)) || ((exitCode == 1) && (runningAction == ACT_INCOMING)))
             {
+                QString output = runner->getOutput();
+
                 //Successful running.
                 switch(runningAction)
                 {
                     case ACT_PATHS:
                     {
-                        QString sout = runner->getOutput();
-                        DEBUG << "stdout is " << sout << endl;
-                        LogParser lp(sout, "=");
+                        DEBUG << "stdout is " << output << endl;
+                        LogParser lp(output, "=");
                         LogList ll = lp.parse();
                         DEBUG << ll.size() << " results" << endl;
                         if (!ll.empty()) {
@@ -1144,12 +1145,12 @@
                     }
 
                     case ACT_BRANCH:
-                        currentBranch = runner->getOutput().trimmed();
+                        currentBranch = output.trimmed();
                         hgTabs->setBranch(currentBranch);
                         break;
 
                     case ACT_STAT:
-                        hgTabs -> updateWorkFolderFileList(runner -> getOutput());
+                        hgTabs -> updateWorkFolderFileList(output);
                         updateFileSystemWatcher();
                         break;
 
@@ -1157,17 +1158,17 @@
                     case ACT_ANNOTATE:
                     case ACT_RESOLVE_LIST:
                     case ACT_RESOLVE_MARK:
-                        presentLongStdoutToUser(runner -> getOutput());
+                        presentLongStdoutToUser(output);
                         shouldHgStat = true;
                         break;
 
                     case ACT_PULL:
-                        QMessageBox::information(this, "Pull", runner -> getOutput());
+                        QMessageBox::information(this, "Pull", output);
                         shouldHgStat = true;
                         break;
 
                     case ACT_PUSH:
-                        QMessageBox::information(this, "Push", runner -> getOutput());
+                        QMessageBox::information(this, "Push", output);
                         shouldHgStat = true;
                         break;
 
@@ -1182,32 +1183,23 @@
                         MultiChoiceDialog::addRecentArgument("local", workFolderPath);
                         MultiChoiceDialog::addRecentArgument("remote", remoteRepoPath);
                         MultiChoiceDialog::addRecentArgument("remote", workFolderPath, true);
-                        QMessageBox::information(this, "Clone", runner -> getOutput());
+                        QMessageBox::information(this, "Clone", output);
                         enableDisableActions();
                         shouldHgStat = true;
                         break;
 
                     case ACT_LOG:
-                        hgTabs -> updateLocalRepoHgLogList(runner -> getOutput());
+                        hgTabs -> updateLocalRepoHgLogList(output);
                         break;
 
                     case ACT_PARENTS:
-                        {
-                        //!!!    hgTabs -> updateLocalRepoParentsList(runner -> getOutput());
-                        }
+                        foreach (Changeset *cs, currentParents) delete cs;
+                        currentParents = Changeset::parseChangesets(output);
                         break;
 
                     case ACT_HEADS:
-                        {
-                            foreach (Changeset *cs, currentHeads) delete cs;
-                            currentHeads.clear();
-                            QString output = runner -> getOutput();
-                            DEBUG << "heads output is: " << output << endl;
-                            LogList log = LogParser(output).parse();
-                            foreach (LogEntry e, log) {
-                                currentHeads.push_back(new Changeset(e));
-                            }
-                        }
+                        foreach (Changeset *cs, currentHeads) delete cs;
+                        currentHeads = Changeset::parseChangesets(output);
                         break;
 
                     case ACT_REMOVE:
@@ -1224,12 +1216,12 @@
                         break;
 
                     case ACT_UPDATE:
-                        QMessageBox::information(this, tr("Update"), runner -> getOutput());
+                        QMessageBox::information(this, tr("Update"), output);
                         shouldHgStat = true;
                         break;
 
                     case ACT_MERGE:
-                        QMessageBox::information(this, tr("Merge"), runner -> getOutput());
+                        QMessageBox::information(this, tr("Merge"), output);
                         shouldHgStat = true;
                         justMerged = true;
                         break;
@@ -1418,6 +1410,45 @@
     hgRevertAct->setEnabled(localRepoActionsEnabled && hgTabs->canCommit());
     hgFolderDiffAct->setEnabled(localRepoActionsEnabled && hgTabs->canDoDiff());
 
+    // A default merge makes sense if:
+    //  * there is only one parent (if there are two, we have an uncommitted merge) and
+    //  * there are exactly two heads that have the same branch as the current branch and
+    //  * our parent is one of those heads
+    //
+    // A default update makes sense if:
+    //  * there is only one parent and
+    //  * the parent is not one of the current heads
+    //!!! test this
+    bool canMerge = false;
+    bool canUpdate = false;
+    if (currentParents.size() == 1) {
+        Changeset *parent = currentParents[0];
+        int currentBranchHeads = 0;
+        bool parentIsHead = false;
+        foreach (Changeset *head, currentHeads) {
+            DEBUG << "head branch " << head->branch() << ", current branch " << currentBranch << endl;
+            if (head->isOnBranch(currentBranch)) {
+                ++currentBranchHeads;
+                if (parent->id() == head->id()) {
+                    parentIsHead = true;
+                }
+            }
+        }
+        if (currentBranchHeads == 2 && parentIsHead) {
+            canMerge = true;
+        }
+        if (!parentIsHead) {
+            canUpdate = true;
+            DEBUG << "parent id = " << parent->id() << endl;
+            DEBUG << " head ids "<<endl;
+            foreach (Changeset *h, currentHeads) {
+                DEBUG << "head id = " << h->id() << endl;
+            }
+        }
+    }
+    hgMergeAct->setEnabled(localRepoActionsEnabled && canMerge);
+    hgUpdateAct->setEnabled(localRepoActionsEnabled && canUpdate);
+
 /*!!!
     int added, modified, removed, notTracked, selected, selectedAdded, selectedModified, selectedRemoved, selectedNotTracked;
 
--- a/mainwindow.h	Thu Nov 25 20:18:10 2010 +0000
+++ b/mainwindow.h	Thu Nov 25 21:08:17 2010 +0000
@@ -80,6 +80,7 @@
     QString workFolderPath;
     QString currentBranch;
     Changesets currentHeads;
+    Changesets currentParents;
 
 protected:
     void closeEvent(QCloseEvent *event);