# HG changeset patch # User Chris Cannam # Date 1290429040 0 # Node ID aaeabc920ca80df16a75d80a272b6633493467d3 # Parent 07405f3a428b4221e30d001241b7c303b6ebe9d9 * Some work toward doing the Right Thing with each possible combination of existing/nonexisting directories in Open dialog diff -r 07405f3a428b -r aaeabc920ca8 common.cpp --- 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("<", "<") + .replace(">", ">") + .replace("\"", """) + .replace("'", "'"); + + return s; +} diff -r 07405f3a428b -r aaeabc920ca8 common.h --- 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 diff -r 07405f3a428b -r aaeabc920ca8 mainwindow.cpp --- 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("File chosen
The selected path (%1) is a file, not a folder as expected
").arg(xmlEncode(arg))); + return false; +} + +bool MainWindow::complainAboutUnknownFolder(QString arg) +{ + QMessageBox::critical + (this, tr("Folder does not exist"), + tr("Folder does not exist
The selected path (%1) does not exist, and nor does its parent
").arg(xmlEncode(arg))); + return false; +} + +bool MainWindow::askToOpenParentRepo(QString arg, QString parent) +{ + return (QMessageBox::question + (this, tr("Open containing repository?"), + tr("Open containing repository?
The selected path (%1) is located inside an existing repository (at %2).
Would you like to open that repository instead?
") + .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("Initialise repository?
The selected folder (%1) does not contain a Mercurial repository. Would you like to initialise a repository here?
") + .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("Initialise new repository?
The selected folder (%1) does not exist, but its parent does. Would you like to initialise a new empty repository in the selected folder?
") + .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() diff -r 07405f3a428b -r aaeabc920ca8 mainwindow.h --- 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 diff -r 07405f3a428b -r aaeabc920ca8 multichoicedialog.cpp --- 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