aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/git/commitdata.cpp128
-rw-r--r--src/plugins/git/commitdata.h18
-rw-r--r--src/plugins/git/gitclient.cpp87
-rw-r--r--src/plugins/git/gitplugin.cpp2
-rw-r--r--src/plugins/git/gitsubmiteditor.cpp43
-rw-r--r--src/plugins/git/gitsubmiteditor.h7
-rw-r--r--src/plugins/perforce/perforceplugin.cpp16
-rw-r--r--src/plugins/perforce/perforcesubmiteditor.cpp65
-rw-r--r--src/plugins/perforce/perforcesubmiteditor.h6
-rw-r--r--src/plugins/subversion/subversionplugin.cpp42
-rw-r--r--src/plugins/subversion/subversionplugin.h1
-rw-r--r--src/plugins/subversion/subversionsubmiteditor.cpp16
-rw-r--r--src/plugins/subversion/subversionsubmiteditor.h9
-rw-r--r--src/plugins/vcsbase/submitfilemodel.cpp78
-rw-r--r--src/plugins/vcsbase/submitfilemodel.h62
-rw-r--r--src/plugins/vcsbase/vcsbase.pro45
-rw-r--r--src/plugins/vcsbase/vcsbasesubmiteditor.cpp22
-rw-r--r--src/plugins/vcsbase/vcsbasesubmiteditor.h14
18 files changed, 439 insertions, 222 deletions
diff --git a/src/plugins/git/commitdata.cpp b/src/plugins/git/commitdata.cpp
index 8b96fe23c97..ada478e3743 100644
--- a/src/plugins/git/commitdata.cpp
+++ b/src/plugins/git/commitdata.cpp
@@ -32,8 +32,12 @@
***************************************************************************/
#include "commitdata.h"
+#include <utils/qtcassert.h>
#include <QtCore/QDebug>
+#include <QtCore/QRegExp>
+
+const char *const kBranchIndicatorC = "# On branch";
namespace Git {
namespace Internal {
@@ -85,6 +89,130 @@ void CommitData::clear()
untrackedFiles.clear();
}
+// Split a state/file spec from git status output
+// '#<tab>modified:<blanks>git .pro'
+// into state and file ('modified', 'git .pro').
+CommitData::StateFilePair splitStateFileSpecification(const QString &line)
+{
+ QPair<QString, QString> rc;
+ const int statePos = 2;
+ const int colonIndex = line.indexOf(QLatin1Char(':'), statePos);
+ if (colonIndex == -1)
+ return rc;
+ rc.first = line.mid(statePos, colonIndex - statePos);
+ int filePos = colonIndex + 1;
+ const QChar blank = QLatin1Char(' ');
+ while (line.at(filePos) == blank)
+ filePos++;
+ if (filePos < line.size())
+ rc.second = line.mid(filePos, line.size() - filePos);
+ return rc;
+}
+
+// Convenience to add a state/file spec to a list
+static inline bool addStateFileSpecification(const QString &line, QList<CommitData::StateFilePair> *list)
+{
+ const CommitData::StateFilePair sf = splitStateFileSpecification(line);
+ if (sf.first.isEmpty() || sf.second.isEmpty())
+ return false;
+ list->push_back(sf);
+ return true;
+}
+
+/* Parse a git status file list:
+ * \code
+ # Changes to be committed:
+ #<tab>modified:<blanks>git.pro
+ # Changed but not updated:
+ #<tab>modified:<blanks>git.pro
+ # Untracked files:
+ #<tab>git.pro
+ \endcode
+*/
+
+bool CommitData::parseFilesFromStatus(const QString &output)
+{
+ enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles };
+
+ const QStringList lines = output.split(QLatin1Char('\n'));
+ const QString branchIndicator = QLatin1String(kBranchIndicatorC);
+ const QString commitIndicator = QLatin1String("# Changes to be committed:");
+ const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:");
+ const QString untrackedIndicator = QLatin1String("# Untracked files:");
+
+ State s = None;
+ // Match added/changed-not-updated files: "#<tab>modified: foo.cpp"
+ QRegExp filesPattern(QLatin1String("#\\t[^:]+:\\s+.+"));
+ QTC_ASSERT(filesPattern.isValid(), return false);
+
+ const QStringList::const_iterator cend = lines.constEnd();
+ for (QStringList::const_iterator it = lines.constBegin(); it != cend; ++it) {
+ const QString line = *it;
+ if (line.startsWith(branchIndicator)) {
+ panelInfo.branch = line.mid(branchIndicator.size() + 1);
+ } else {
+ if (line.startsWith(commitIndicator)) {
+ s = CommitFiles;
+ } else {
+ if (line.startsWith(notUpdatedIndicator)) {
+ s = NotUpdatedFiles;
+ } else {
+ if (line.startsWith(untrackedIndicator)) {
+ // Now match untracked: "#<tab>foo.cpp"
+ s = UntrackedFiles;
+ filesPattern = QRegExp(QLatin1String("#\\t.+"));
+ QTC_ASSERT(filesPattern.isValid(), return false);
+ } else {
+ if (filesPattern.exactMatch(line)) {
+ switch (s) {
+ case CommitFiles:
+ addStateFileSpecification(line, &stagedFiles);
+ break;
+ case NotUpdatedFiles:
+ addStateFileSpecification(line, &unstagedFiles);
+ break;
+ case UntrackedFiles:
+ untrackedFiles.push_back(line.mid(2).trimmed());
+ break;
+ case None:
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return !stagedFiles.empty() || !unstagedFiles.empty() || !untrackedFiles.empty();
+}
+
+// Convert a spec pair list to a list of file names, optionally
+// filter for a state
+static QStringList specToFileNames(const QList<CommitData::StateFilePair> &files,
+ const QString &stateFilter)
+{
+ typedef QList<CommitData::StateFilePair>::const_iterator ConstIterator;
+ if (files.empty())
+ return QStringList();
+ const bool emptyFilter = stateFilter.isEmpty();
+ QStringList rc;
+ const ConstIterator cend = files.constEnd();
+ for (ConstIterator it = files.constBegin(); it != cend; ++it)
+ if (emptyFilter || stateFilter == it->first)
+ rc.push_back(it->second);
+ return rc;
+}
+
+QStringList CommitData::stagedFileNames(const QString &stateFilter) const
+{
+ return specToFileNames(stagedFiles, stateFilter);
+}
+
+QStringList CommitData::unstagedFileNames(const QString &stateFilter) const
+{
+ return specToFileNames(unstagedFiles, stateFilter);
+}
+
QDebug operator<<(QDebug d, const CommitData &data)
{
d << data.panelInfo << data.panelData;
diff --git a/src/plugins/git/commitdata.h b/src/plugins/git/commitdata.h
index a1dc05ef425..6cb5ddb42b9 100644
--- a/src/plugins/git/commitdata.h
+++ b/src/plugins/git/commitdata.h
@@ -35,6 +35,7 @@
#define COMMITDATA_H
#include <QtCore/QStringList>
+#include <QtCore/QPair>
QT_BEGIN_NAMESPACE
class QDebug;
@@ -68,11 +69,24 @@ QDebug operator<<(QDebug d, const GitSubmitEditorPanelData &);
struct CommitData
{
+ // A pair of state string/file name ('modified', 'file.cpp').
+ typedef QPair<QString, QString> StateFilePair;
+
void clear();
+ // Parse the files and the branch of panelInfo
+ // from a git status output
+ bool parseFilesFromStatus(const QString &output);
+
+ // Convenience to retrieve the file names from
+ // the specification list. Optionally filter for a certain state
+ QStringList stagedFileNames(const QString &stateFilter = QString()) const;
+ QStringList unstagedFileNames(const QString &stateFilter = QString()) const;
+
GitSubmitEditorPanelInfo panelInfo;
GitSubmitEditorPanelData panelData;
- QStringList stagedFiles;
- QStringList unstagedFiles;
+
+ QList<StateFilePair> stagedFiles;
+ QList<StateFilePair> unstagedFiles;
QStringList untrackedFiles;
};
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 281a9572a21..d1ebda300b4 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -622,73 +622,6 @@ GitClient::StatusResult GitClient::gitStatus(const QString &workingDirectory,
return StatusChanged;
}
-/* Parse a git status file list:
- * \code
- # Changes to be committed:
- #<tab>modified:<blanks>git.pro
- # Changed but not updated:
- #<tab>modified:<blanks>git.pro
- # Untracked files:
- #<tab>git.pro
- \endcode
-*/
-static bool parseFiles(const QString &output, CommitData *d)
-{
- enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles };
-
- const QStringList lines = output.split(QLatin1Char('\n'));
- const QString branchIndicator = QLatin1String(kBranchIndicatorC);
- const QString commitIndicator = QLatin1String("# Changes to be committed:");
- const QString notUpdatedIndicator = QLatin1String("# Changed but not updated:");
- const QString untrackedIndicator = QLatin1String("# Untracked files:");
-
- State s = None;
- // Match added/changed-not-updated files: "#<tab>modified: foo.cpp"
- QRegExp filesPattern(QLatin1String("#\\t[^:]+:\\s+.+"));
- QTC_ASSERT(filesPattern.isValid(), return false);
-
- const QStringList::const_iterator cend = lines.constEnd();
- for (QStringList::const_iterator it = lines.constBegin(); it != cend; ++it) {
- const QString line = *it;
- if (line.startsWith(branchIndicator)) {
- d->panelInfo.branch = line.mid(branchIndicator.size() + 1);
- } else {
- if (line.startsWith(commitIndicator)) {
- s = CommitFiles;
- } else {
- if (line.startsWith(notUpdatedIndicator)) {
- s = NotUpdatedFiles;
- } else {
- if (line.startsWith(untrackedIndicator)) {
- // Now match untracked: "#<tab>foo.cpp"
- s = UntrackedFiles;
- filesPattern = QRegExp(QLatin1String("#\\t.+"));
- QTC_ASSERT(filesPattern.isValid(), return false);
- } else {
- if (filesPattern.exactMatch(line)) {
- const QString fileSpec = line.mid(2).trimmed();
- switch (s) {
- case CommitFiles:
- d->stagedFiles.push_back(trimFileSpecification(fileSpec));
- break;
- case NotUpdatedFiles:
- d->unstagedFiles.push_back(trimFileSpecification(fileSpec));
- break;
- case UntrackedFiles:
- d->untrackedFiles.push_back(fileSpec);
- break;
- case None:
- break;
- }
- }
- }
- }
- }
- }
- }
- return !d->stagedFiles.empty() || !d->unstagedFiles.empty() || !d->untrackedFiles.empty();
-}
-
// Filter out untracked files that are not part of the project
static void filterUntrackedFilesOfProject(const QString &repoDir, QStringList *l)
{
@@ -771,20 +704,12 @@ bool GitClient::getCommitData(const QString &workingDirectory,
// #
// # list of files...
- if (!parseFiles(output, d)) {
+ if (!d->parseFilesFromStatus(output)) {
*errorMessage = msgParseFilesFailed();
return false;
}
- // Filter out untracked files that are not part of the project and,
- // for symmetry, insert the prefix "untracked:" (as "added:" or ":modified"
- // for staged files).
+ // Filter out untracked files that are not part of the project
filterUntrackedFilesOfProject(repoDirectory, &d->untrackedFiles);
- if (!d->untrackedFiles.empty()) {
- const QString untrackedPrefix = QLatin1String("untracked: ");
- const QStringList::iterator pend = d->untrackedFiles.end();
- for (QStringList::iterator it = d->untrackedFiles.begin(); it != pend; ++it)
- it->insert(0, untrackedPrefix);
- }
d->panelData.author = readConfigValue(workingDirectory, QLatin1String("user.name"));
d->panelData.email = readConfigValue(workingDirectory, QLatin1String("user.email"));
@@ -881,7 +806,7 @@ GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirec
return RevertFailed;
}
CommitData data;
- if (!parseFiles(output, &data)) {
+ if (!data.parseFilesFromStatus(output)) {
*errorMessage = msgParseFilesFailed();
return RevertFailed;
}
@@ -896,9 +821,9 @@ GitClient::RevertResult GitClient::revertI(QStringList files, bool *ptrToIsDirec
}
// From the status output, determine all modified [un]staged files.
- const QString modifiedPattern = QLatin1String("modified: ");
- const QStringList allStagedFiles = GitSubmitEditor::statusListToFileList(data.stagedFiles.filter(modifiedPattern));
- const QStringList allUnstagedFiles = GitSubmitEditor::statusListToFileList(data.unstagedFiles.filter(modifiedPattern));
+ const QString modifiedState = QLatin1String("modified");
+ const QStringList allStagedFiles = data.stagedFileNames(modifiedState);
+ const QStringList allUnstagedFiles = data.unstagedFileNames(modifiedState);
// Unless a directory was passed, filter all modified files for the
// argument file list.
QStringList stagedFiles = allStagedFiles;
diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp
index fe2d93adbff..2ef08083393 100644
--- a/src/plugins/git/gitplugin.cpp
+++ b/src/plugins/git/gitplugin.cpp
@@ -602,7 +602,7 @@ void GitPlugin::startCommit()
// Store repository for diff and the original list of
// files to be able to unstage files the user unchecks
m_submitRepository = data.panelInfo.repository;
- m_submitOrigCommitFiles = GitSubmitEditor::statusListToFileList(data.stagedFiles);
+ m_submitOrigCommitFiles = data.stagedFileNames();
if (Git::Constants::debug)
qDebug() << Q_FUNC_INFO << data << commitTemplate;
diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp
index fe93a0c6ad1..d34a78240d2 100644
--- a/src/plugins/git/gitsubmiteditor.cpp
+++ b/src/plugins/git/gitsubmiteditor.cpp
@@ -36,6 +36,8 @@
#include "gitconstants.h"
#include "commitdata.h"
+#include <vcsbase/submitfilemodel.h>
+
#include <QtCore/QDebug>
namespace Git {
@@ -52,14 +54,14 @@ GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget()
return static_cast<GitSubmitEditorWidget *>(widget());
}
-QStringList GitSubmitEditor::statusListToFileList(const QStringList &rawList)
+static void addStateFileListToModel(const QList<CommitData::StateFilePair> &l,
+ VCSBase::SubmitFileModel *model,
+ bool checked)
{
- if (rawList.empty())
- return rawList;
- QStringList rc;
- foreach (const QString &rf, rawList)
- rc.push_back(fileFromStatusLine(rf));
- return rc;
+ typedef QList<CommitData::StateFilePair>::const_iterator ConstIterator;
+ const ConstIterator cend = l.constEnd();
+ for (ConstIterator it = l.constBegin(); it != cend; ++it)
+ model->addFile(it->second, it->first, checked);
}
void GitSubmitEditor::setCommitData(const CommitData &d)
@@ -67,10 +69,16 @@ void GitSubmitEditor::setCommitData(const CommitData &d)
submitEditorWidget()->setPanelData(d.panelData);
submitEditorWidget()->setPanelInfo(d.panelInfo);
- addFiles(d.stagedFiles, true, true);
- // Not Updated: Initially unchecked
- addFiles(d.unstagedFiles, false, true);
- addFiles(d.untrackedFiles, false, true);
+ VCSBase::SubmitFileModel *model = new VCSBase::SubmitFileModel(this);
+ addStateFileListToModel(d.stagedFiles, model, true);
+ addStateFileListToModel(d.unstagedFiles, model, false);
+ if (!d.untrackedFiles.empty()) {
+ const QString untrackedSpec = QLatin1String("untracked");
+ const QStringList::const_iterator cend = d.untrackedFiles.constEnd();
+ for (QStringList::const_iterator it = d.untrackedFiles.constBegin(); it != cend; ++it)
+ model->addFile(*it, untrackedSpec, false);
+ }
+ setFileModel(model);
}
GitSubmitEditorPanelData GitSubmitEditor::panelData() const
@@ -78,18 +86,5 @@ GitSubmitEditorPanelData GitSubmitEditor::panelData() const
return const_cast<GitSubmitEditor*>(this)->submitEditorWidget()->panelData();
}
-QString GitSubmitEditor::fileFromStatusLine(const QString &line)
-{
- QString rc = line;
- // "modified: mainwindow.cpp"
- const int index = rc.indexOf(QLatin1Char(':'));
- if (index != -1)
- rc.remove(0, index + 1);
- const QChar blank(' ');
- while (rc.startsWith(blank))
- rc.remove(0, 1);
- return rc;
-}
-
} // namespace Internal
} // namespace Git
diff --git a/src/plugins/git/gitsubmiteditor.h b/src/plugins/git/gitsubmiteditor.h
index 8199384d07f..a1a80ac22cf 100644
--- a/src/plugins/git/gitsubmiteditor.h
+++ b/src/plugins/git/gitsubmiteditor.h
@@ -54,13 +54,6 @@ public:
void setCommitData(const CommitData &);
GitSubmitEditorPanelData panelData() const;
- static QString fileFromStatusLine(const QString &line);
- static QStringList statusListToFileList(const QStringList &);
-
-protected:
- virtual QStringList vcsFileListToFileList(const QStringList &l) const
- { return statusListToFileList(l); }
-
private:
inline GitSubmitEditorWidget *submitEditorWidget();
};
diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp
index 0ad0224d1ca..aa4b0a4fa48 100644
--- a/src/plugins/perforce/perforceplugin.cpp
+++ b/src/plugins/perforce/perforceplugin.cpp
@@ -494,19 +494,19 @@ void PerforcePlugin::submit()
QTC_ASSERT(m_coreInstance, return);
if (!checkP4Command()) {
- showOutput(tr("No p4 executable specified!"));
+ showOutput(tr("No p4 executable specified!"), true);
return;
}
if (m_changeTmpFile) {
- showOutput(tr("Another submit is currently executed."));
+ showOutput(tr("Another submit is currently executed."), true);
m_perforceOutputWindow->popup(false);
return;
}
m_changeTmpFile = new QTemporaryFile(this);
if (!m_changeTmpFile->open()) {
- showOutput(tr("Cannot create temporary file."));
+ showOutput(tr("Cannot create temporary file."), true);
delete m_changeTmpFile;
m_changeTmpFile = 0;
return;
@@ -970,7 +970,7 @@ bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
QByteArray change = m_changeTmpFile->readAll();
m_changeTmpFile->close();
if (!checkP4Command()) {
- showOutput(tr("No p4 executable specified!"));
+ showOutput(tr("No p4 executable specified!"), true);
delete m_changeTmpFile;
m_changeTmpFile = 0;
return false;
@@ -981,8 +981,8 @@ bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
proc.start(m_settings.p4Command,
basicP4Args() << QLatin1String("submit") << QLatin1String("-i"));
- if (!proc.waitForStarted(3000)) {
- showOutput(tr("Cannot execute p4 submit."));
+ if (!proc.waitForStarted(p4Timeout)) {
+ showOutput(tr("Cannot execute p4 submit."), true);
QApplication::restoreOverrideCursor();
delete m_changeTmpFile;
m_changeTmpFile = 0;
@@ -992,7 +992,7 @@ bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
proc.closeWriteChannel();
if (!proc.waitForFinished()) {
- showOutput(tr("Cannot execute p4 submit."));
+ showOutput(tr("Cannot execute p4 submit."), true);
QApplication::restoreOverrideCursor();
delete m_changeTmpFile;
m_changeTmpFile = 0;
@@ -1000,7 +1000,7 @@ bool PerforcePlugin::editorAboutToClose(Core::IEditor *editor)
}
QString output = QString::fromUtf8(proc.readAll());
showOutput(output);
- if (output.contains("Out of date files must be resolved or reverted")) {
+ if (output.contains("Out of date files must be resolved or reverted"), true) {
QMessageBox::warning(editor->widget(), "Pending change", "Could not submit the change, because your workspace was out of date. Created a pending submit instead.");
}
QApplication::restoreOverrideCursor();
diff --git a/src/plugins/perforce/perforcesubmiteditor.cpp b/src/plugins/perforce/perforcesubmiteditor.cpp
index 6aa74f95fb2..826f2275718 100644
--- a/src/plugins/perforce/perforcesubmiteditor.cpp
+++ b/src/plugins/perforce/perforcesubmiteditor.cpp
@@ -36,6 +36,7 @@
#include "perforceplugin.h"
#include "perforceconstants.h"
+#include <vcsbase/submitfilemodel.h>
#include <utils/qtcassert.h>
#include <QtCore/QDebug>
@@ -43,10 +44,14 @@
namespace Perforce {
namespace Internal {
+enum { FileSpecRole = Qt::UserRole + 1 };
+
PerforceSubmitEditor::PerforceSubmitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, QWidget *parent) :
- VCSBaseSubmitEditor(parameters, new PerforceSubmitEditorWidget(parent))
+ VCSBaseSubmitEditor(parameters, new PerforceSubmitEditorWidget(parent)),
+ m_fileModel(new VCSBase::SubmitFileModel(this))
{
setDisplayName(tr("Perforce Submit"));
+ setFileModel(m_fileModel);
}
PerforceSubmitEditorWidget *PerforceSubmitEditor::submitEditorWidget()
@@ -54,14 +59,6 @@ PerforceSubmitEditorWidget *PerforceSubmitEditor::submitEditorWidget()
return static_cast<PerforceSubmitEditorWidget *>(widget());
}
-QStringList PerforceSubmitEditor::vcsFileListToFileList(const QStringList &rawList) const
-{
- QStringList rc;
- foreach (const QString &rf, rawList)
- rc.push_back(fileFromChangeLine(rf));
- return rc;
-}
-
QString PerforceSubmitEditor::fileContents() const
{
const_cast<PerforceSubmitEditor*>(this)->updateEntries();
@@ -121,25 +118,7 @@ bool PerforceSubmitEditor::parseText(QString text)
void PerforceSubmitEditor::restrictToProjectFiles(const QStringList &knownProjectFiles)
{
- QStringList allFiles = submitEditorWidget()->fileList();
- const int oldSize = allFiles.size();
- for (int i = oldSize - 1; i >= 0; i--)
- if (!knownProjectFiles.contains(fileFromChangeLine(allFiles.at(i))))
- allFiles.removeAt(i);
- if (allFiles.size() != oldSize)
- submitEditorWidget()->setFileList(allFiles);
- if (Perforce::Constants::debug)
- qDebug() << Q_FUNC_INFO << oldSize << "->" << allFiles.size();
-}
-
-QString PerforceSubmitEditor::fileFromChangeLine(const QString &line)
-{
- QString rc = line;
- // " foo.cpp#add"
- const int index = rc.lastIndexOf(QLatin1Char('#'));
- if (index != -1)
- rc.truncate(index);
- return rc.trimmed();
+ m_fileModel->filter(knownProjectFiles, fileNameColumn());
}
void PerforceSubmitEditor::updateFields()
@@ -161,12 +140,15 @@ void PerforceSubmitEditor::updateFields()
widget->setDescriptionText(lines.join(newLine));
lines = m_entries.value(QLatin1String("Files")).split(newLine);
- lines.replaceInStrings(leadingTabPattern, QString());
- QStringList fileList;
- foreach (const QString &line, lines)
- if (!line.isEmpty())
- fileList.push_back(line);
- widget->setFileList(fileList);
+ // split up "file#add" and store complete spec line as user data
+ foreach (const QString &specLine, lines) {
+ const QStringList list = specLine.split(QLatin1Char('#'));
+ if (list.size() == 2) {
+ const QString file = list.at(0).trimmed();
+ const QString state = list.at(1).trimmed();
+ m_fileModel->addFile(file, state).at(0)->setData(specLine, FileSpecRole);
+ }
+ }
}
void PerforceSubmitEditor::updateEntries()
@@ -181,13 +163,14 @@ void PerforceSubmitEditor::updateEntries()
lines.replaceInStrings(QRegExp(QLatin1String("^")), tab);
m_entries.insert(QLatin1String("Description"), newLine + lines.join(newLine) + QLatin1String("\n\n"));
QString files = newLine;
- // Files
- const QStringList fileList = submitEditorWidget()->fileList();
- const int count = fileList.size();
- for (int i = 0; i < count; i++) {
- files += tab;
- files += fileList.at(i);
- files += newLine;
+ // Re-build the file spec '<tab>file#add' from the user data
+ const int count = m_fileModel->rowCount();
+ for (int r = 0; r < count; r++) {
+ const QStandardItem *item = m_fileModel->item(r, 0);
+ if (item->checkState() == Qt::Checked) {
+ files += item->data(FileSpecRole).toString();
+ files += newLine;
+ }
}
files += newLine;
m_entries.insert(QLatin1String("Files"), files);
diff --git a/src/plugins/perforce/perforcesubmiteditor.h b/src/plugins/perforce/perforcesubmiteditor.h
index 0f44332a694..5dba0683158 100644
--- a/src/plugins/perforce/perforcesubmiteditor.h
+++ b/src/plugins/perforce/perforcesubmiteditor.h
@@ -39,6 +39,10 @@
#include <QtCore/QStringList>
#include <QtCore/QMap>
+namespace VCSBase {
+ class SubmitFileModel;
+}
+
namespace Perforce {
namespace Internal {
@@ -66,7 +70,6 @@ public:
static QString fileFromChangeLine(const QString &line);
protected:
- virtual QStringList vcsFileListToFileList(const QStringList &) const;
virtual QString fileContents() const;
virtual bool setFileContents(const QString &contents);
@@ -77,6 +80,7 @@ private:
void updateEntries();
QMap<QString, QString> m_entries;
+ VCSBase::SubmitFileModel *m_fileModel;
};
} // namespace Internal
diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp
index 5f5200aab34..36182eb94a0 100644
--- a/src/plugins/subversion/subversionplugin.cpp
+++ b/src/plugins/subversion/subversionplugin.cpp
@@ -139,6 +139,29 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property
return 0;
}
+// Parse "svn status" output for added/modified/deleted files
+// "M<7blanks>file"
+typedef QList<SubversionSubmitEditor::StatusFilePair> StatusList;
+
+StatusList parseStatusOutput(const QString &output)
+{
+ StatusList changeSet;
+ const QString newLine = QString(QLatin1Char('\n'));
+ const QStringList list = output.split(newLine, QString::SkipEmptyParts);
+ foreach (const QString &l, list) {
+ const QString line =l.trimmed();
+ if (line.size() > 8) {
+ const QChar state = line.at(0);
+ if (state == QLatin1Char('A') || state == QLatin1Char('D') || state == QLatin1Char('M')) {
+ const QString fileName = line.mid(7);
+ changeSet.push_back(SubversionSubmitEditor::StatusFilePair(QString(state), fileName));
+ }
+
+ }
+ }
+ return changeSet;
+}
+
// ------------- SubversionPlugin
Core::ICore *SubversionPlugin::m_coreInstance = 0;
SubversionPlugin *SubversionPlugin::m_subversionPluginInstance = 0;
@@ -694,7 +717,7 @@ void SubversionPlugin::startCommit(const QStringList &files)
if (response.error)
return;
// Get list of added/modified/deleted files
- const QStringList statusOutput = parseStatusOutput(response.stdOut);
+ const StatusList statusOutput = parseStatusOutput(response.stdOut);
if (statusOutput.empty()) {
showOutput(tr("There are no modified files."), true);
return;
@@ -717,22 +740,7 @@ void SubversionPlugin::startCommit(const QStringList &files)
m_changeTmpFile->seek(0);
// Create a submit editor and set file list
SubversionSubmitEditor *editor = openSubversionSubmitEditor(m_changeTmpFile->fileName());
- editor->setFileList(statusOutput);
-}
-
-// Parse "status" output for added/modified/deleted files
-QStringList SubversionPlugin::parseStatusOutput(const QString &output) const
-{
- QStringList changeSet;
- const QString newLine = QString(QLatin1Char('\n'));
- const QStringList list = output.split(newLine, QString::SkipEmptyParts);
- foreach (const QString &l, list) {
- QString line(l.trimmed());
- if (line.startsWith(QLatin1Char('A')) || line.startsWith(QLatin1Char('D'))
- || line.startsWith(QLatin1Char('M')))
- changeSet.append(line);
- }
- return changeSet;
+ editor->setStatusList(statusOutput);
}
bool SubversionPlugin::commit(const QString &messageFile,
diff --git a/src/plugins/subversion/subversionplugin.h b/src/plugins/subversion/subversionplugin.h
index 6c2c448241e..7909b3f2328 100644
--- a/src/plugins/subversion/subversionplugin.h
+++ b/src/plugins/subversion/subversionplugin.h
@@ -133,7 +133,6 @@ private:
SubversionResponse runSvn(const QStringList &arguments, int timeOut,
bool showStdOutInOutputWindow, QTextCodec *outputCodec = 0);
void showOutput(const QString &output, bool bringToForeground = true);
- QStringList parseStatusOutput(const QString &output) const;
void annotate(const QString &file);
void filelog(const QString &file);
bool managesDirectory(const QDir &directory) const;
diff --git a/src/plugins/subversion/subversionsubmiteditor.cpp b/src/plugins/subversion/subversionsubmiteditor.cpp
index b1e97e676e4..c65a2530dd7 100644
--- a/src/plugins/subversion/subversionsubmiteditor.cpp
+++ b/src/plugins/subversion/subversionsubmiteditor.cpp
@@ -35,6 +35,7 @@
#include "subversionsubmiteditor.h"
#include <utils/submiteditorwidget.h>
+#include <vcsbase/submitfilemodel.h>
using namespace Subversion::Internal;
@@ -45,6 +46,19 @@ SubversionSubmitEditor::SubversionSubmitEditor(const VCSBase::VCSBaseSubmitEdito
setDisplayName(tr("Subversion Submit"));
}
+void SubversionSubmitEditor::setStatusList(const QList<StatusFilePair> &statusOutput)
+{
+ typedef QList<StatusFilePair>::const_iterator ConstIterator;
+ VCSBase::SubmitFileModel *model = new VCSBase::SubmitFileModel(this);
+
+ const ConstIterator cend = statusOutput.constEnd();
+ for (ConstIterator it = statusOutput.constBegin(); it != cend; ++it)
+ model->addFile(it->second, it->first, true);
+ setFileModel(model);
+
+}
+
+/*
QStringList SubversionSubmitEditor::vcsFileListToFileList(const QStringList &rl) const
{
QStringList files;
@@ -59,3 +73,5 @@ QString SubversionSubmitEditor::fileFromStatusLine(const QString &statusLine)
enum { filePos = 7 };
return statusLine.mid(filePos, statusLine.size() - filePos);
}
+
+*/
diff --git a/src/plugins/subversion/subversionsubmiteditor.h b/src/plugins/subversion/subversionsubmiteditor.h
index c6bf0845ebc..6aae19c824e 100644
--- a/src/plugins/subversion/subversionsubmiteditor.h
+++ b/src/plugins/subversion/subversionsubmiteditor.h
@@ -34,6 +34,9 @@
#ifndef SUBVERSIONSUBMITEDITOR_H
#define SUBVERSIONSUBMITEDITOR_H
+#include <QtCore/QPair>
+#include <QtCore/QStringList>
+
#include <vcsbase/vcsbasesubmiteditor.h>
namespace Subversion {
@@ -48,8 +51,10 @@ public:
static QString fileFromStatusLine(const QString &statusLine);
-private:
- virtual QStringList vcsFileListToFileList(const QStringList &) const;
+ // A list of ( 'A','M','D') status indicators and file names.
+ typedef QPair<QString, QString> StatusFilePair;
+
+ void setStatusList(const QList<StatusFilePair> &statusOutput);
};
} // namespace Internal
diff --git a/src/plugins/vcsbase/submitfilemodel.cpp b/src/plugins/vcsbase/submitfilemodel.cpp
new file mode 100644
index 00000000000..f12eab38d14
--- /dev/null
+++ b/src/plugins/vcsbase/submitfilemodel.cpp
@@ -0,0 +1,78 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#include "submitfilemodel.h"
+#include "vcsbaseconstants.h"
+
+#include <QtGui/QStandardItem>
+#include <QtCore/QDebug>
+
+namespace VCSBase {
+
+SubmitFileModel::SubmitFileModel(QObject *parent) :
+ QStandardItemModel(0, 2, parent)
+{
+ // setColumnCount(2);
+ QStringList headerLabels;
+ headerLabels << tr("State") << tr("File");
+ setHorizontalHeaderLabels(headerLabels);
+}
+
+QList<QStandardItem *> SubmitFileModel::addFile(const QString &fileName, const QString &status, bool checked)
+{
+ if (VCSBase::Constants::Internal::debug)
+ qDebug() << Q_FUNC_INFO << fileName << status << checked;
+ QStandardItem *statusItem = new QStandardItem(status);
+ statusItem->setCheckable(true);
+ statusItem->setCheckState(checked ? Qt::Checked : Qt::Unchecked);
+ QStandardItem *fileItem = new QStandardItem(fileName);
+ QList<QStandardItem *> row;
+ row << statusItem << fileItem;
+ appendRow(row);
+ return row;
+}
+
+unsigned SubmitFileModel::filter(const QStringList &filter, int column)
+{
+ unsigned rc = 0;
+ for (int r = rowCount() - 1; r >= 0; r--)
+ if (const QStandardItem *i = item(r, column))
+ if (!filter.contains(i->text())) {
+ qDeleteAll(takeRow(r));
+ rc++;
+ }
+ if (VCSBase::Constants::Internal::debug)
+ qDebug() << Q_FUNC_INFO << " deleted " << rc << " items using " << filter << " , remaining " << rowCount();
+ return rc;
+}
+}
diff --git a/src/plugins/vcsbase/submitfilemodel.h b/src/plugins/vcsbase/submitfilemodel.h
new file mode 100644
index 00000000000..fef89df83be
--- /dev/null
+++ b/src/plugins/vcsbase/submitfilemodel.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information ([email protected])
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception
+** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+
+#ifndef SUBMITMODEL_H
+#define SUBMITMODEL_H
+
+#include "vcsbase_global.h"
+
+#include <QtGui/QStandardItemModel>
+
+namespace VCSBase {
+
+/* A 2-column (checkable, state, file name) model to be used to list the files-
+ * in the submit editor. Provides header items and a convience to add files. */
+
+class VCSBASE_EXPORT SubmitFileModel : public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ explicit SubmitFileModel(QObject *parent = 0);
+
+ // Convenience to add a file plus status text.
+ QList<QStandardItem *> addFile(const QString &fileName, const QString &status = QString(), bool checked = true);
+
+ // Filter for entries contained in the filter list. Returns the
+ // number of deleted entries.
+ unsigned filter(const QStringList &filter, int column);
+};
+
+}
+
+#endif // SUBMITMODEL_H
diff --git a/src/plugins/vcsbase/vcsbase.pro b/src/plugins/vcsbase/vcsbase.pro
index 329e27b0686..d34fe84e7c0 100644
--- a/src/plugins/vcsbase/vcsbase.pro
+++ b/src/plugins/vcsbase/vcsbase.pro
@@ -1,31 +1,28 @@
TEMPLATE = lib
TARGET = VCSBase
-
DEFINES += VCSBASE_LIBRARY
-
include(../../qworkbenchplugin.pri)
include(vcsbase_dependencies.pri)
-
HEADERS += vcsbase_global.h \
-vcsbaseconstants.h \
-vcsbaseplugin.h \
-baseannotationhighlighter.h \
-diffhighlighter.h \
-vcsbasetextdocument.h \
-vcsbaseeditor.h \
-vcsbasesubmiteditor.h \
-basevcseditorfactory.h \
-submiteditorfile.h \
-basevcssubmiteditorfactory.h
-
+ vcsbaseconstants.h \
+ vcsbaseplugin.h \
+ baseannotationhighlighter.h \
+ diffhighlighter.h \
+ vcsbasetextdocument.h \
+ vcsbaseeditor.h \
+ vcsbasesubmiteditor.h \
+ basevcseditorfactory.h \
+ submiteditorfile.h \
+ basevcssubmiteditorfactory.h \
+ submitfilemodel.h
SOURCES += vcsbaseplugin.cpp \
-baseannotationhighlighter.cpp \
-diffhighlighter.cpp \
-vcsbasetextdocument.cpp \
-vcsbaseeditor.cpp \
-vcsbasesubmiteditor.cpp \
-basevcseditorfactory.cpp \
-submiteditorfile.cpp \
-basevcssubmiteditorfactory.cpp
-
-RESOURCES=vcsbase.qrc
+ baseannotationhighlighter.cpp \
+ diffhighlighter.cpp \
+ vcsbasetextdocument.cpp \
+ vcsbaseeditor.cpp \
+ vcsbasesubmiteditor.cpp \
+ basevcseditorfactory.cpp \
+ submiteditorfile.cpp \
+ basevcssubmiteditorfactory.cpp \
+ submitfilemodel.cpp
+RESOURCES = vcsbase.qrc
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
index 9d668f16a76..d130c266459 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
@@ -129,6 +129,16 @@ VCSBaseSubmitEditor::~VCSBaseSubmitEditor()
delete m_d;
}
+int VCSBaseSubmitEditor::fileNameColumn() const
+{
+ return m_d->m_widget->fileNameColumn();
+}
+
+void VCSBaseSubmitEditor::setFileNameColumn(int c)
+{
+ m_d->m_widget->setFileNameColumn(c);
+}
+
void VCSBaseSubmitEditor::slotDescriptionChanged()
{
}
@@ -246,22 +256,22 @@ bool VCSBaseSubmitEditor::restoreState(const QByteArray &/*state*/)
QStringList VCSBaseSubmitEditor::checkedFiles() const
{
- return vcsFileListToFileList(m_d->m_widget->checkedFiles());
+ return m_d->m_widget->checkedFiles();
}
-void VCSBaseSubmitEditor::setFileList(const QStringList &l)
+void VCSBaseSubmitEditor::setFileModel(QAbstractItemModel *m)
{
- m_d->m_widget->setFileList(l);
+ m_d->m_widget->setFileModel(m);
}
-void VCSBaseSubmitEditor::addFiles(const QStringList& list, bool checked, bool userCheckable)
+QAbstractItemModel *VCSBaseSubmitEditor::fileModel() const
{
- m_d->m_widget->addFiles(list, checked, userCheckable);
+ return m_d->m_widget->fileModel();
}
void VCSBaseSubmitEditor::slotDiffSelectedVCSFiles(const QStringList &rawList)
{
- emit diffSelectedFiles(vcsFileListToFileList(rawList));
+ emit diffSelectedFiles(rawList);
}
bool VCSBaseSubmitEditor::save(const QString &fileName)
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.h b/src/plugins/vcsbase/vcsbasesubmiteditor.h
index 72553672411..91b10d488f9 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.h
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.h
@@ -42,6 +42,7 @@
QT_BEGIN_NAMESPACE
class QIcon;
+class QAbstractItemModel;
QT_END_NAMESPACE
namespace Core {
@@ -90,6 +91,7 @@ struct VCSBASE_EXPORT VCSBaseSubmitEditorParameters {
class VCSBASE_EXPORT VCSBaseSubmitEditor : public Core::IEditor
{
Q_OBJECT
+ Q_PROPERTY(int fileNameColumn READ fileNameColumn WRITE setFileNameColumn DESIGNABLE false)
public:
typedef QList<int> Context;
@@ -100,6 +102,9 @@ protected:
public:
virtual ~VCSBaseSubmitEditor();
+ int fileNameColumn() const;
+ void setFileNameColumn(int c);
+
// Core::IEditor
virtual bool createNew(const QString &contents);
virtual bool open(const QString &fileName);
@@ -119,8 +124,8 @@ public:
QStringList checkedFiles() const;
- void setFileList(const QStringList&);
- void addFiles(const QStringList&, bool checked = true, bool userCheckable = true);
+ void setFileModel(QAbstractItemModel *m);
+ QAbstractItemModel *fileModel() const;
// Utilities returning some predefined icons for actions
static QIcon diffIcon();
@@ -139,11 +144,6 @@ private slots:
void slotDescriptionChanged();
protected:
- /* Implemented this to extract the real file list from the status
- * output of the versioning system as displayed in the file list
- * for example "M foo.cpp" -> "foo.cpp". */
- virtual QStringList vcsFileListToFileList(const QStringList &) const = 0;
-
/* These hooks allow for modifying the contents that goes to
* the file. The default implementation uses the text
* of the description editor. */