Mercurial > hg > easyhg
diff src/mainwindow.cpp @ 422:2af4b5b0bf83
Merge from branch "ignore"
author | Chris Cannam <chris.cannam@eecs.qmul.ac.uk> |
---|---|
date | Wed, 22 Jun 2011 13:01:50 +0100 |
parents | 653e9694a694 |
children | 06e5c4f3dd7c |
line wrap: on
line diff
--- a/src/mainwindow.cpp Mon Jun 13 16:56:01 2011 +0100 +++ b/src/mainwindow.cpp Wed Jun 22 13:01:50 2011 +0100 @@ -48,6 +48,7 @@ #include "annotatedialog.h" #include "version.h" #include "workstatuswidget.h" +#include "hgignoredialog.h" MainWindow::MainWindow(QString myDirPath) : @@ -546,15 +547,11 @@ } } -void MainWindow::hgIgnore() +void MainWindow::initHgIgnore() { - QString hgIgnorePath; - QStringList params; - - hgIgnorePath = m_workFolderPath; - hgIgnorePath += "/.hgignore"; - if (!QDir(m_workFolderPath).exists()) return; + QString hgIgnorePath = m_workFolderPath + "/.hgignore"; + QFile f(hgIgnorePath); if (!f.exists()) { f.open(QFile::WriteOnly); @@ -563,14 +560,25 @@ delete ts; f.close(); } - +} + +void MainWindow::hgEditIgnore() +{ + if (!QDir(m_workFolderPath).exists()) return; + + initHgIgnore(); + + QString hgIgnorePath = m_workFolderPath + "/.hgignore"; + QStringList params; + params << hgIgnorePath; QString editor = getEditorBinaryName(); if (editor == "") { - DEBUG << "Failed to find a text editor" << endl; - //!!! visible error! + QMessageBox::critical + (this, tr("Edit .hgignore"), + tr("Failed to locate a system text editor program!")); return; } @@ -580,16 +588,161 @@ m_runner->requestAction(action); } +static QString regexEscape(QString filename) +{ + return filename + .replace(".", "\\.") + .replace("[", "\\[") + .replace("]", "\\]") + .replace("(", "\\(") + .replace(")", "\\)") + .replace("?", "\\?"); +} + void MainWindow::hgIgnoreFiles(QStringList files) { - //!!! not implemented yet - DEBUG << "MainWindow::hgIgnoreFiles: Not implemented" << endl; + if (!QDir(m_workFolderPath).exists() || files.empty()) return; + + // we should: + // + // * show the user the list of file names selected + // + // * offer a choice (depending on the files selected?) + // + // - ignore only these files + // + // - ignore files with these names, in any subdirectories? + // + // - ignore all files with this extension (if they have a common + // extension)? + // + // - ignore all files with these extensions (if they have any + // extensions?) + + DEBUG << "MainWindow::hgIgnoreFiles: File names are:" << endl; + foreach (QString file, files) DEBUG << file << endl; + + QSet<QString> suffixes; + foreach (QString file, files) { + QString s = QFileInfo(file).suffix(); + if (s != "") suffixes.insert(s); + } + + QString directory; + bool dirCount = 0; + foreach (QString file, files) { + QString d = QFileInfo(file).path(); + if (d != directory) { + ++dirCount; + directory = d; + } + } + if (dirCount != 1 || directory == ".") directory = ""; + + HgIgnoreDialog::IgnoreType itype = + HgIgnoreDialog::confirmIgnore + (this, files, QStringList::fromSet(suffixes), directory); + + DEBUG << "hgIgnoreFiles: Ignore type is " << itype << endl; + + if (itype == HgIgnoreDialog::IgnoreNothing) return; + + // Now, .hgignore can be switched from regex to glob syntax + // part-way through -- and glob is much simpler for us, so we + // should do that if it's in regex mode at the end of the file. + + initHgIgnore(); + + QString hgIgnorePath = m_workFolderPath + "/.hgignore"; + + // hgignore file should now exist (initHgIgnore should have + // created it if it didn't). Check for glob status first + + QFile f(hgIgnorePath); + if (!f.exists()) { + std::cerr << "MainWindow::ignoreFiles: Internal error: .hgignore file not found (even though we were supposed to have created it)" << std::endl; + return; + } + + f.open(QFile::ReadOnly); + bool glob = false; + while (!f.atEnd()) { + QByteArray ba = f.readLine(); + QString s = QString::fromLocal8Bit(ba).trimmed(); + if (s.startsWith("syntax:")) { + if (s.endsWith("glob")) { + glob = true; + } else { + glob = false; + } + } + } + f.close(); + + f.open(QFile::Append); + QTextStream out(&f); + + if (!glob) { + out << "syntax: glob" << endl; + } + + QString info = "<qt><h3>" + tr("Ignored files") + "</h3><p>"; + info += tr("The following lines have been added to the .hgignore file for this working copy:"); + info += "</p><code>"; + + QStringList args; + if (itype == HgIgnoreDialog::IgnoreAllFilesOfGivenSuffixes) { + args = QStringList::fromSet(suffixes); + } else if (itype == HgIgnoreDialog::IgnoreGivenFilesOnly) { + args = files; + } else if (itype == HgIgnoreDialog::IgnoreAllFilesOfGivenNames) { + QSet<QString> names; + foreach (QString f, files) { + names << QFileInfo(f).fileName(); + } + args = QStringList::fromSet(names); + } else if (itype == HgIgnoreDialog::IgnoreWholeDirectory) { + args << directory; + } + + bool first = true; + + foreach (QString a, args) { + QString line; + if (itype == HgIgnoreDialog::IgnoreAllFilesOfGivenSuffixes) { + line = "*." + a; + } else if (itype == HgIgnoreDialog::IgnoreGivenFilesOnly) { + // Doesn't seem to be possible to do this with a glob, + // because the glob is always unanchored and there is no + // equivalent of ^ to anchor it + line = "re:^" + regexEscape(a); + } else if (itype == HgIgnoreDialog::IgnoreAllFilesOfGivenNames) { + line = a; + } else if (itype == HgIgnoreDialog::IgnoreWholeDirectory) { + line = "re:^" + regexEscape(a) + "/"; + } + if (line != "") { + out << line << endl; + if (!first) info += "<br>"; + first = false; + info += xmlEncode(line); + } + } + + f.close(); + + info += "</code></qt>"; + + QMessageBox::information(this, tr("Ignored files"), + info); + + hgRefresh(); } void MainWindow::hgUnIgnoreFiles(QStringList files) { - //!!! not implemented yet - DEBUG << "MainWindow::hgUnIgnoreFiles: Not implemented" << endl; + // Not implemented: edit the .hgignore instead + hgEditIgnore(); } QString MainWindow::getDiffBinaryName() @@ -2339,7 +2492,7 @@ connect(m_hgUpdateAct, SIGNAL(triggered()), this, SLOT(hgUpdate())); connect(m_hgRevertAct, SIGNAL(triggered()), this, SLOT(hgRevert())); connect(m_hgMergeAct, SIGNAL(triggered()), this, SLOT(hgMerge())); - connect(m_hgIgnoreAct, SIGNAL(triggered()), this, SLOT(hgIgnore())); + connect(m_hgEditIgnoreAct, SIGNAL(triggered()), this, SLOT(hgEditIgnore())); connect(m_settingsAct, SIGNAL(triggered()), this, SLOT(settings())); connect(m_openAct, SIGNAL(triggered()), this, SLOT(open())); @@ -2493,7 +2646,7 @@ m_hgCommitAct->setEnabled(m_localRepoActionsEnabled); m_hgMergeAct->setEnabled(m_localRepoActionsEnabled); m_hgServeAct->setEnabled(m_localRepoActionsEnabled); - m_hgIgnoreAct->setEnabled(m_localRepoActionsEnabled); + m_hgEditIgnoreAct->setEnabled(m_localRepoActionsEnabled); DEBUG << "m_localRepoActionsEnabled = " << m_localRepoActionsEnabled << endl; DEBUG << "canCommit = " << m_hgTabs->canCommit() << endl; @@ -2710,8 +2863,8 @@ //Advanced actions - m_hgIgnoreAct = new QAction(tr("Edit .hgignore File"), this); - m_hgIgnoreAct->setStatusTip(tr("Edit the .hgignore file, containing the names of files that should be ignored by Mercurial")); + m_hgEditIgnoreAct = new QAction(tr("Edit .hgignore File"), this); + m_hgEditIgnoreAct->setStatusTip(tr("Edit the .hgignore file, containing the names of files that should be ignored by Mercurial")); m_hgServeAct = new QAction(tr("Serve via HTTP"), this); m_hgServeAct->setStatusTip(tr("Serve local repository via http for workgroup access")); @@ -2760,7 +2913,7 @@ remoteMenu->addAction(m_changeRemoteRepoAct); m_advancedMenu = menuBar()->addMenu(tr("&Advanced")); - m_advancedMenu->addAction(m_hgIgnoreAct); + m_advancedMenu->addAction(m_hgEditIgnoreAct); m_advancedMenu->addSeparator(); m_advancedMenu->addAction(m_hgServeAct);