changeset 79:aaeabc920ca8

* Some work toward doing the Right Thing with each possible combination of existing/nonexisting directories in Open dialog
author Chris Cannam
date Mon, 22 Nov 2010 12:30:40 +0000
parents 07405f3a428b
children 32fa40c3d174
files common.cpp common.h mainwindow.cpp mainwindow.h multichoicedialog.cpp
diffstat 5 files changed, 215 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/common.cpp	Mon Nov 22 10:03:15 2010 +0000
+++ b/common.cpp	Mon Nov 22 12:30:40 2010 +0000
@@ -177,3 +177,55 @@
     }
 #endif
 }
+
+FolderStatus getFolderStatus(QString path)
+{
+    QFileInfo fi(path);
+    if (fi.exists()) {
+        QDir dir(path);
+        if (!dir.exists()) { // returns false for files
+            return FolderIsFile;
+        }
+        if (QDir(dir.filePath(".hg")).exists()) {
+            return FolderHasRepo;
+        }
+        return FolderExists;
+    } else {
+        QDir parent = fi.dir();
+        if (parent.exists()) {
+            return FolderParentExists;
+        }
+        return FolderUnknown;
+    }
+}
+
+QString getContainingRepoFolder(QString path)
+{
+    if (getFolderStatus(path) == FolderHasRepo) return "";
+
+    QFileInfo me(path);
+    QFileInfo parent(me.dir().absolutePath());
+
+    while (me != parent) {
+        QString parentPath = parent.filePath();
+        if (getFolderStatus(parentPath) == FolderHasRepo) {
+            return parentPath;
+        }
+        me = parent;
+        parent = me.dir().absolutePath();
+    }
+
+    return "";
+}
+
+QString xmlEncode(QString s)
+{
+    s
+	.replace("&", "&")
+	.replace("<", "&lt;")
+	.replace(">", "&gt;")
+	.replace("\"", "&quot;")
+	.replace("'", "&apos;");
+
+    return s;
+}
--- a/common.h	Mon Nov 22 10:03:15 2010 +0000
+++ b/common.h	Mon Nov 22 12:30:40 2010 +0000
@@ -50,6 +50,34 @@
 
 extern void loseControllingTerminal();
 
+/**
+ * Status used in testing whether a folder argument (received from the
+ * user) is valid for particular uses.
+ */
+enum FolderStatus {
+    FolderUnknown,      /// Neither the folder nor its parent exists
+    FolderParentExists, /// The folder is absent, but its parent exists
+    FolderExists,       /// The folder exists and has no .hg repo in it
+    FolderHasRepo,      /// The folder exists and has an .hg repo in it
+    FolderIsFile        /// The "folder" is actually a file
+};
+
+FolderStatus getFolderStatus(QString path);
+
+/**
+ * If the given path is somewhere within an existing repository,
+ * return the path of the root directory of the repository (i.e. the
+ * one with .hg in it).
+ *
+ * If the given path is _not_ in a repository, or the given path _is_
+ * the root directory of a repository, return QString().  Use
+ * getFolderStatus to distinguish between these cases.
+ */
+QString getContainingRepoFolder(QString path);
+
+QString xmlEncode(QString);
+    
+
 #endif 	//COMMON_H
 
 
--- a/mainwindow.cpp	Mon Nov 22 10:03:15 2010 +0000
+++ b/mainwindow.cpp	Mon Nov 22 12:30:40 2010 +0000
@@ -736,27 +736,131 @@
 
         QString choice = d->getCurrentChoice();
         QString arg = d->getArgument().trimmed();
+
+        bool result = false;
     
         if (choice == "local") {
-            DEBUG << "open " << arg << endl;
-            workFolderPath = arg;
-            remoteRepoPath = "";
+            result = openLocal(arg);
         } else if (choice == "remote") {
-            DEBUG << "clone " << arg << " to " << d->getAdditionalArgument().trimmed() << endl;
-            //!!! check that work folder does not exist, append to it if it does
+            result = openRemote(arg, d->getAdditionalArgument().trimmed());
         } else if (choice == "init") {
-            DEBUG << "init " << arg << endl;
-            //!!!
+            result = openInit(arg);
         }
-        
-        hgExp->clearLists();
-        enableDisableActions();
-        hgPaths();
+
+        if (result) {
+            hgExp->clearLists();
+            enableDisableActions();
+            hgPaths();
+        }
     }
 
     delete d;
 }
 
+bool MainWindow::complainAboutFilePath(QString arg)
+{    
+    QMessageBox::critical
+        (this, tr("File chosen"),
+         tr("<qt><b>File chosen<b><br>The selected path (%1) is a file, not a folder as expected</qt>").arg(xmlEncode(arg)));
+    return false;
+}
+
+bool MainWindow::complainAboutUnknownFolder(QString arg)
+{    
+    QMessageBox::critical
+        (this, tr("Folder does not exist"),
+         tr("<qt><b>Folder does not exist<b><br>The selected path (%1) does not exist, and nor does its parent</qt>").arg(xmlEncode(arg)));
+    return false;
+}
+
+bool MainWindow::askToOpenParentRepo(QString arg, QString parent)
+{
+    return (QMessageBox::question
+            (this, tr("Open containing repository?"),
+             tr("<qt><b>Open containing repository?</b><br>The selected path (%1) is located inside an existing repository (at %2).<br>Would you like to open that repository instead?</qt>")
+             .arg(xmlEncode(arg)).arg(xmlEncode(parent)),
+             QMessageBox::Ok | QMessageBox::Cancel,
+             QMessageBox::Ok)
+            == QMessageBox::Ok);
+}
+
+bool MainWindow::askToInitExisting(QString arg)
+{
+    return (QMessageBox::question
+            (this, tr("Initialise repository?"),
+             tr("<qt><b>Initialise repository?</b><br>The selected folder (%1) does not contain a Mercurial repository.  Would you like to initialise a repository here?</qt>")
+             .arg(xmlEncode(arg)),
+             QMessageBox::Ok | QMessageBox::Cancel,
+             QMessageBox::Ok)
+            == QMessageBox::Ok);
+}
+
+bool MainWindow::askToInitNew(QString arg)
+{
+    return (QMessageBox::question
+            (this, tr("Initialise new repository?"),
+             tr("<qt><b>Initialise new repository?</b><br>The selected folder (%1) does not exist, but its parent does.  Would you like to initialise a new empty repository in the selected folder?</qt>")
+             .arg(xmlEncode(arg)),
+             QMessageBox::Ok | QMessageBox::Cancel,
+             QMessageBox::Ok)
+            == QMessageBox::Ok);
+}
+
+bool MainWindow::openLocal(QString local)
+{
+    DEBUG << "open " << local << endl;
+
+    FolderStatus status = getFolderStatus(local);
+    QString containing = getContainingRepoFolder(local);
+
+    switch (status) {
+
+    case FolderHasRepo:
+        // fine
+        break;
+
+    case FolderExists:
+        if (containing != "") {
+            if (!askToOpenParentRepo(local, containing)) return false;
+        } else {
+            if (!askToInitExisting(local)) return false;
+            return openInit(local);
+        }
+        break;
+
+    case FolderParentExists:
+        if (containing != "") {
+            if (!askToOpenParentRepo(local, containing)) return false;
+        } else {
+            if (!askToInitNew(local)) return false;
+            return openInit(local);
+        }
+        break;
+
+    case FolderUnknown:
+        return complainAboutUnknownFolder(local);
+        
+    case FolderIsFile:
+        return complainAboutFilePath(local);
+    }
+
+    workFolderPath = local;
+    remoteRepoPath = "";
+    return true;
+}    
+
+bool MainWindow::openRemote(QString remote, QString local)
+{
+    DEBUG << "clone " << remote << " to " << local << endl;
+    //!!! check that work folder does not exist, append to it if it does
+    return true;
+}
+
+bool MainWindow::openInit(QString arg)
+{
+    return true;
+}
+
 void MainWindow::settings()
 {
 /*!!!
@@ -996,7 +1100,7 @@
     runningAction = ACT_NONE;
     runner -> hideProgBar();
 
-    //!!! N.B hg incoming returns failure even if successful, if there were no changes
+    //!!! N.B hg incoming returns 1 even if successful, if there were no changes
 }
 
 void MainWindow::commandCompleted()
--- a/mainwindow.h	Mon Nov 22 10:03:15 2010 +0000
+++ b/mainwindow.h	Mon Nov 22 12:30:40 2010 +0000
@@ -141,6 +141,16 @@
 
     QString getUserInfo() const;
 
+    bool openLocal(QString);
+    bool openRemote(QString, QString);
+    bool openInit(QString);
+
+    bool complainAboutFilePath(QString);
+    bool complainAboutUnknownFolder(QString);
+    bool askToInitExisting(QString);
+    bool askToInitNew(QString);
+    bool askToOpenParentRepo(QString, QString);
+
     bool firstStart;
 
     //Actions enabled flags
--- a/multichoicedialog.cpp	Mon Nov 22 10:03:15 2010 +0000
+++ b/multichoicedialog.cpp	Mon Nov 22 12:30:40 2010 +0000
@@ -202,6 +202,7 @@
 void
 MultiChoiceDialog::urlChanged(const QString &s)
 {
+/* This doesn't work well
     if (m_argTypes[m_currentChoice] != UrlToDirectoryArg) {
         return;
     }
@@ -214,11 +215,18 @@
         return;
     }
     QString urlDirName = url;
-    urlDirName.replace(QRegExp("^.*//.*/"), "");
+    urlDirName.replace(QRegExp("^.*\\//.*\\/"), "");
     if (urlDirName == "" || urlDirName == url) {
         return;
     }
     m_fileCombo->lineEdit()->setText(dirPath.filePath(urlDirName));
+*/
+    if (m_argTypes[m_currentChoice] == UrlToDirectoryArg) {
+        m_okButton->setEnabled(getArgument() != "" &&
+                               getAdditionalArgument() != "");
+    } else {
+        m_okButton->setEnabled(getArgument() != "");
+    }
 }
 
 void