diff options
author | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2009-01-13 10:06:06 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2009-01-13 10:06:06 +0100 |
commit | 4741a7282d87dbbfb2e2e4e1493e73c22c38f6ad (patch) | |
tree | 0bc885764c78da2ffccdf725ea694979b87d246b /src/plugins | |
parent | 278ff780407c6b14644d6e09b81c563316beca85 (diff) | |
download | qt-creator-4741a7282d87dbbfb2e2e4e1493e73c22c38f6ad.tar.gz |
Fixes: Make git diff work for staged files, do not launch submit if file list empty, make file model read only, add conveniences
Details: Add a type data field to the git file model
Diffstat (limited to 'src/plugins')
-rw-r--r-- | src/plugins/git/commitdata.cpp | 7 | ||||
-rw-r--r-- | src/plugins/git/commitdata.h | 2 | ||||
-rw-r--r-- | src/plugins/git/gitclient.cpp | 16 | ||||
-rw-r--r-- | src/plugins/git/gitclient.h | 4 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.cpp | 26 | ||||
-rw-r--r-- | src/plugins/git/gitplugin.h | 3 | ||||
-rw-r--r-- | src/plugins/git/gitsubmiteditor.cpp | 63 | ||||
-rw-r--r-- | src/plugins/git/gitsubmiteditor.h | 13 | ||||
-rw-r--r-- | src/plugins/vcsbase/submitfilemodel.cpp | 29 | ||||
-rw-r--r-- | src/plugins/vcsbase/submitfilemodel.h | 9 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbasesubmiteditor.cpp | 11 | ||||
-rw-r--r-- | src/plugins/vcsbase/vcsbasesubmiteditor.h | 5 |
12 files changed, 156 insertions, 32 deletions
diff --git a/src/plugins/git/commitdata.cpp b/src/plugins/git/commitdata.cpp index ada478e374..65962ef557 100644 --- a/src/plugins/git/commitdata.cpp +++ b/src/plugins/git/commitdata.cpp @@ -130,6 +130,11 @@ static inline bool addStateFileSpecification(const QString &line, QList<CommitDa \endcode */ +bool CommitData::filesEmpty() const +{ + return stagedFiles.empty() && unstagedFiles.empty() && untrackedFiles.empty(); +} + bool CommitData::parseFilesFromStatus(const QString &output) { enum State { None, CommitFiles, NotUpdatedFiles, UntrackedFiles }; @@ -183,7 +188,7 @@ bool CommitData::parseFilesFromStatus(const QString &output) } } } - return !stagedFiles.empty() || !unstagedFiles.empty() || !untrackedFiles.empty(); + return true; } // Convert a spec pair list to a list of file names, optionally diff --git a/src/plugins/git/commitdata.h b/src/plugins/git/commitdata.h index 6cb5ddb42b..ca9779c69e 100644 --- a/src/plugins/git/commitdata.h +++ b/src/plugins/git/commitdata.h @@ -77,6 +77,8 @@ struct CommitData // from a git status output bool parseFilesFromStatus(const QString &output); + bool filesEmpty() const; + // Convenience to retrieve the file names from // the specification list. Optionally filter for a certain state QStringList stagedFileNames(const QString &stateFilter = QString()) const; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index d1ebda300b..5ae6d0b7da 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -184,12 +184,14 @@ VCSBase::VCSBaseEditor return rc; } -void GitClient::diff(const QString &workingDirectory, const QStringList &fileNames) +void GitClient::diff(const QString &workingDirectory, + const QStringList &diffArgs, + const QStringList &fileNames) { if (Git::Constants::debug) qDebug() << "diff" << workingDirectory << fileNames; QStringList arguments; - arguments << QLatin1String("diff") << QLatin1String("--") << fileNames; + arguments << QLatin1String("diff") << diffArgs << QLatin1String("--") << fileNames; const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND); const QString title = tr("Git Diff"); @@ -199,14 +201,16 @@ void GitClient::diff(const QString &workingDirectory, const QStringList &fileNam } -void GitClient::diff(const QString &workingDirectory, const QString &fileName) +void GitClient::diff(const QString &workingDirectory, + const QStringList &diffArgs, + const QString &fileName) { if (Git::Constants::debug) qDebug() << "diff" << workingDirectory << fileName; QStringList arguments; arguments << QLatin1String("diff"); if (!fileName.isEmpty()) - arguments << QLatin1String("--") << fileName; + arguments << diffArgs << QLatin1String("--") << fileName; const QString kind = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_KIND); const QString title = tr("Git Diff %1").arg(fileName); @@ -710,6 +714,10 @@ bool GitClient::getCommitData(const QString &workingDirectory, } // Filter out untracked files that are not part of the project filterUntrackedFilesOfProject(repoDirectory, &d->untrackedFiles); + if (d->filesEmpty()) { + *errorMessage = msgNoChangedFiles(); + return false; + } d->panelData.author = readConfigValue(workingDirectory, QLatin1String("user.name")); d->panelData.email = readConfigValue(workingDirectory, QLatin1String("user.email")); diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index f09daa00ab..43a0957d91 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -78,8 +78,8 @@ public: static QString findRepositoryForFile(const QString &fileName); static QString findRepositoryForDirectory(const QString &dir); - void diff(const QString &workingDirectory, const QString &fileName); - void diff(const QString &workingDirectory, const QStringList &fileNames); + void diff(const QString &workingDirectory, const QStringList &diffArgs, const QString &fileName); + void diff(const QString &workingDirectory, const QStringList &diffArgs, const QStringList &fileNames); void status(const QString &workingDirectory); void log(const QString &workingDirectory, const QString &fileName); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 2ef0808339..50214c7c35 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -450,19 +450,24 @@ void GitPlugin::extensionsInitialized() m_projectExplorer = ExtensionSystem::PluginManager::instance()->getObject<ProjectExplorer::ProjectExplorerPlugin>(); } -void GitPlugin::submitEditorDiff(const QStringList &files) +void GitPlugin::submitEditorDiffStaged(const QStringList &files) { - if (files.empty()) - return; - m_gitClient->diff(m_submitRepository, files); + if (!files.empty()) + m_gitClient->diff(m_submitRepository, QStringList(QLatin1String("--cached")), files); +} + +void GitPlugin::submitEditorDiffUnstaged(const QStringList &files) +{ + if (!files.empty()) + m_gitClient->diff(m_submitRepository, QStringList(), files); } void GitPlugin::diffCurrentFile() { - QFileInfo fileInfo = currentFile(); - QString fileName = fileInfo.fileName(); - QString workingDirectory = fileInfo.absolutePath(); - m_gitClient->diff(workingDirectory, fileName); + const QFileInfo fileInfo = currentFile(); + const QString fileName = fileInfo.fileName(); + const QString workingDirectory = fileInfo.absolutePath(); + m_gitClient->diff(workingDirectory, QStringList(), fileName); } void GitPlugin::diffCurrentProject() @@ -470,7 +475,7 @@ void GitPlugin::diffCurrentProject() QString workingDirectory = getWorkingDirectory(); if (workingDirectory.isEmpty()) return; - m_gitClient->diff(workingDirectory, QString()); + m_gitClient->diff(workingDirectory, QStringList(), QString()); } QFileInfo GitPlugin::currentFile() const @@ -640,7 +645,8 @@ Core::IEditor *GitPlugin::openSubmitEditor(const QString &fileName, const Commit m_undoAction->setEnabled(false); m_redoAction->setEnabled(false); submitEditor->setCommitData(cd); - connect(submitEditor, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(submitEditorDiff(QStringList))); + connect(submitEditor, SIGNAL(diffStaged(QStringList)), this, SLOT(submitEditorDiffStaged(QStringList))); + connect(submitEditor, SIGNAL(diffUnstaged(QStringList)), this, SLOT(submitEditorDiffUnstaged(QStringList))); return editor; } diff --git a/src/plugins/git/gitplugin.h b/src/plugins/git/gitplugin.h index 39287e1939..9fdde403d6 100644 --- a/src/plugins/git/gitplugin.h +++ b/src/plugins/git/gitplugin.h @@ -108,7 +108,8 @@ public slots: private slots: void diffCurrentFile(); void diffCurrentProject(); - void submitEditorDiff(const QStringList &); + void submitEditorDiffUnstaged(const QStringList &); + void submitEditorDiffStaged(const QStringList &); void submitCurrentLog(); void statusFile(); void statusProject(); diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp index d34a78240d..fbdc4e5132 100644 --- a/src/plugins/git/gitsubmiteditor.cpp +++ b/src/plugins/git/gitsubmiteditor.cpp @@ -43,10 +43,22 @@ namespace Git { namespace Internal { +enum { FileTypeRole = Qt::UserRole + 1 }; +enum FileType { StagedFile , UnstagedFile, UntrackedFile }; + +/* The problem with git is that no diff can be obtained to for a random + * multiselection of staged/unstaged files; it requires the --cached + * option for staged files. So, we set the file list to + * single selection and sort the files manual according to a type + * flag we add to the model. */ + GitSubmitEditor::GitSubmitEditor(const VCSBase::VCSBaseSubmitEditorParameters *parameters, QWidget *parent) : - VCSBaseSubmitEditor(parameters, new GitSubmitEditorWidget(parent)) + VCSBaseSubmitEditor(parameters, new GitSubmitEditorWidget(parent)), + m_model(0) { setDisplayName(tr("Git Commit")); + setFileListSelectionMode(QAbstractItemView::SingleSelection); + connect(this, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(slotDiffSelected(QStringList))); } GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget() @@ -54,14 +66,20 @@ GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget() return static_cast<GitSubmitEditorWidget *>(widget()); } -static void addStateFileListToModel(const QList<CommitData::StateFilePair> &l, - VCSBase::SubmitFileModel *model, - bool checked) +// Utility to add a list of state/file pairs to the model +// setting a file type. +static void addStateFileListToModel(const QList<CommitData::StateFilePair> &l, + bool checked, FileType ft, + VCSBase::SubmitFileModel *model) { + 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); + if (!l.empty()) { + const ConstIterator cend = l.constEnd(); + const QVariant fileTypeData(ft); + for (ConstIterator it = l.constBegin(); it != cend; ++it) + model->addFile(it->second, it->first, checked).front()->setData(fileTypeData, FileTypeRole); + } } void GitSubmitEditor::setCommitData(const CommitData &d) @@ -69,16 +87,37 @@ void GitSubmitEditor::setCommitData(const CommitData &d) submitEditorWidget()->setPanelData(d.panelData); submitEditorWidget()->setPanelInfo(d.panelInfo); - VCSBase::SubmitFileModel *model = new VCSBase::SubmitFileModel(this); - addStateFileListToModel(d.stagedFiles, model, true); - addStateFileListToModel(d.unstagedFiles, model, false); + m_model = new VCSBase::SubmitFileModel(this); + addStateFileListToModel(d.stagedFiles, true, StagedFile, m_model); + addStateFileListToModel(d.unstagedFiles, false, UnstagedFile, m_model); if (!d.untrackedFiles.empty()) { const QString untrackedSpec = QLatin1String("untracked"); + const QVariant fileTypeData(UntrackedFile); const QStringList::const_iterator cend = d.untrackedFiles.constEnd(); for (QStringList::const_iterator it = d.untrackedFiles.constBegin(); it != cend; ++it) - model->addFile(*it, untrackedSpec, false); + m_model->addFile(*it, untrackedSpec, false).front()->setData(fileTypeData, FileTypeRole); + } + setFileModel(m_model); +} + +void GitSubmitEditor::slotDiffSelected(const QStringList &files) +{ + QList<QStandardItem *> fileRow = m_model->findRow(files.front(), fileNameColumn()); + if (fileRow.empty()) + return; + const FileType ft = static_cast<FileType>(fileRow.front()->data(FileTypeRole).toInt()); + switch (ft) { + case StagedFile: + emit diffStaged(files); + break; + case UnstagedFile: + emit diffUnstaged(files); + break; + case UntrackedFile: + break; } - setFileModel(model); + + } GitSubmitEditorPanelData GitSubmitEditor::panelData() const diff --git a/src/plugins/git/gitsubmiteditor.h b/src/plugins/git/gitsubmiteditor.h index a1a80ac22c..78b99682d0 100644 --- a/src/plugins/git/gitsubmiteditor.h +++ b/src/plugins/git/gitsubmiteditor.h @@ -38,6 +38,10 @@ #include <QtCore/QStringList> +namespace VCSBase { + class SubmitFileModel; +} + namespace Git { namespace Internal { @@ -54,8 +58,17 @@ public: void setCommitData(const CommitData &); GitSubmitEditorPanelData panelData() const; +signals: + void diffStaged(const QStringList &); + void diffUnstaged(const QStringList &); + +private slots: + void slotDiffSelected(const QStringList &); + private: inline GitSubmitEditorWidget *submitEditorWidget(); + + VCSBase::SubmitFileModel *m_model; }; } // namespace Internal diff --git a/src/plugins/vcsbase/submitfilemodel.cpp b/src/plugins/vcsbase/submitfilemodel.cpp index f12eab38d1..e38c1f4e38 100644 --- a/src/plugins/vcsbase/submitfilemodel.cpp +++ b/src/plugins/vcsbase/submitfilemodel.cpp @@ -48,20 +48,47 @@ SubmitFileModel::SubmitFileModel(QObject *parent) : setHorizontalHeaderLabels(headerLabels); } -QList<QStandardItem *> SubmitFileModel::addFile(const QString &fileName, const QString &status, bool checked) +QList<QStandardItem *> SubmitFileModel::createFileRow(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); + statusItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled); QStandardItem *fileItem = new QStandardItem(fileName); + fileItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled); QList<QStandardItem *> row; row << statusItem << fileItem; + return row; +} + +QList<QStandardItem *> SubmitFileModel::addFile(const QString &fileName, const QString &status, bool checked) +{ + const QList<QStandardItem *> row = createFileRow(fileName, status, checked); appendRow(row); return row; } +QList<QStandardItem *> SubmitFileModel::rowAt(int row) const +{ + const int colCount = columnCount(); + QList<QStandardItem *> rc; + for (int c = 0; c < colCount; c++) + rc.push_back(item(row, c)); + return rc; +} + +QList<QStandardItem *> SubmitFileModel::findRow(const QString &text, int column) const +{ + // Single item + const QList<QStandardItem *> items = findItems(text, Qt::MatchExactly, column); + if (items.empty()) + return items; + // Compile row + return rowAt(items.front()->row()); + } + unsigned SubmitFileModel::filter(const QStringList &filter, int column) { unsigned rc = 0; diff --git a/src/plugins/vcsbase/submitfilemodel.h b/src/plugins/vcsbase/submitfilemodel.h index fef89df83b..e6a0cd76f2 100644 --- a/src/plugins/vcsbase/submitfilemodel.h +++ b/src/plugins/vcsbase/submitfilemodel.h @@ -49,9 +49,16 @@ class VCSBASE_EXPORT SubmitFileModel : public QStandardItemModel public: explicit SubmitFileModel(QObject *parent = 0); - // Convenience to add a file plus status text. + // Convenience to create and add rows containing a file plus status text. + static QList<QStandardItem *> createFileRow(const QString &fileName, const QString &status = QString(), bool checked = true); QList<QStandardItem *> addFile(const QString &fileName, const QString &status = QString(), bool checked = true); + // Find convenience that returns the whole row (as opposed to QStandardItemModel::find). + QList<QStandardItem *> findRow(const QString &text, int column = 0) const; + + // Convenience to obtain a row + QList<QStandardItem *> rowAt(int row) const; + // Filter for entries contained in the filter list. Returns the // number of deleted entries. unsigned filter(const QStringList &filter, int column); diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp index d130c26645..25fbce7634 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp @@ -139,6 +139,17 @@ void VCSBaseSubmitEditor::setFileNameColumn(int c) m_d->m_widget->setFileNameColumn(c); } +QAbstractItemView::SelectionMode VCSBaseSubmitEditor::fileListSelectionMode() const +{ + return m_d->m_widget->fileListSelectionMode(); +} + +void VCSBaseSubmitEditor::setFileListSelectionMode(QAbstractItemView::SelectionMode sm) +{ + m_d->m_widget->setFileListSelectionMode(sm); +} + + void VCSBaseSubmitEditor::slotDescriptionChanged() { } diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.h b/src/plugins/vcsbase/vcsbasesubmiteditor.h index 91b10d488f..d3e9166b35 100644 --- a/src/plugins/vcsbase/vcsbasesubmiteditor.h +++ b/src/plugins/vcsbase/vcsbasesubmiteditor.h @@ -39,6 +39,7 @@ #include <coreplugin/editormanager/ieditor.h> #include <QtCore/QList> +#include <QtGui/QAbstractItemView> QT_BEGIN_NAMESPACE class QIcon; @@ -92,6 +93,7 @@ class VCSBASE_EXPORT VCSBaseSubmitEditor : public Core::IEditor { Q_OBJECT Q_PROPERTY(int fileNameColumn READ fileNameColumn WRITE setFileNameColumn DESIGNABLE false) + Q_PROPERTY(QAbstractItemView::SelectionMode fileListSelectionMode READ fileListSelectionMode WRITE setFileListSelectionMode DESIGNABLE true) public: typedef QList<int> Context; @@ -105,6 +107,9 @@ public: int fileNameColumn() const; void setFileNameColumn(int c); + QAbstractItemView::SelectionMode fileListSelectionMode() const; + void setFileListSelectionMode(QAbstractItemView::SelectionMode sm); + // Core::IEditor virtual bool createNew(const QString &contents); virtual bool open(const QString &fileName); |