diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 7bec91dce36..43601b187ce 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -3174,6 +3174,11 @@ void GitClient::handleMergeConflicts(const QString &workingDir, const QString &c } } +void GitClient::addFuture(const QFuture &future) +{ + m_synchronizer.addFuture(future); +} + // Subversion: git svn void GitClient::synchronousSubversionFetch(const QString &workingDirectory) { diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 1b20d75e2a7..1972852cb88 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -35,6 +35,7 @@ #include +#include #include #include #include @@ -329,6 +330,7 @@ public: void endStashScope(const QString &workingDirectory); bool isValidRevision(const QString &revision) const; void handleMergeConflicts(const QString &workingDir, const QString &commit, const QStringList &files, const QString &abortCommand); + void addFuture(const QFuture &future); static QString msgNoChangedFiles(); static QString msgNoCommits(bool includeRemote); @@ -433,6 +435,7 @@ private: int m_contextDiffFileIndex; int m_contextChunkIndex; QPointer m_contextDocument; + QFutureSynchronizer m_synchronizer; // for commit updates }; } // namespace Internal diff --git a/src/plugins/git/gitsubmiteditor.cpp b/src/plugins/git/gitsubmiteditor.cpp index e35e298e88a..d7844723b39 100644 --- a/src/plugins/git/gitsubmiteditor.cpp +++ b/src/plugins/git/gitsubmiteditor.cpp @@ -34,6 +34,7 @@ #include "gitsubmiteditorwidget.h" #include +#include #include #include #include @@ -41,6 +42,9 @@ #include #include #include +#include + +static const char TASK_UPDATE_COMMIT[] = "Git.UpdateCommit"; namespace Git { namespace Internal { @@ -80,6 +84,38 @@ private: } }; +class CommitDataFetcher : public QObject +{ + Q_OBJECT + +public: + CommitDataFetcher(CommitType commitType, const QString &workingDirectory) : + m_commitData(commitType), + m_workingDirectory(workingDirectory) + { + } + + void start() + { + GitClient *client = GitPlugin::instance()->gitClient(); + QString commitTemplate; + bool success = client->getCommitData(m_workingDirectory, &commitTemplate, + m_commitData, &m_errorMessage); + emit finished(success); + } + + const CommitData &commitData() const { return m_commitData; } + const QString &errorMessage() const { return m_errorMessage; } + +signals: + void finished(bool result); + +private: + CommitData m_commitData; + QString m_workingDirectory; + QString m_errorMessage; +}; + /* 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 sort apart the diff file lists @@ -90,12 +126,18 @@ GitSubmitEditor::GitSubmitEditor(const VcsBase::VcsBaseSubmitEditorParameters *p m_model(0), m_commitEncoding(0), m_commitType(SimpleCommit), - m_firstUpdate(true) + m_firstUpdate(true), + m_commitDataFetcher(0) { connect(this, SIGNAL(diffSelectedFiles(QList)), this, SLOT(slotDiffSelected(QList))); connect(submitEditorWidget(), SIGNAL(show(QString)), this, SLOT(showCommit(QString))); } +GitSubmitEditor::~GitSubmitEditor() +{ + resetCommitDataFetcher(); +} + GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget() { return static_cast(widget()); @@ -106,6 +148,14 @@ const GitSubmitEditorWidget *GitSubmitEditor::submitEditorWidget() const return static_cast(widget()); } +void GitSubmitEditor::resetCommitDataFetcher() +{ + if (!m_commitDataFetcher) + return; + disconnect(m_commitDataFetcher, SIGNAL(finished(bool)), this, SLOT(commitDataRetrieved(bool))); + connect(m_commitDataFetcher, SIGNAL(finished(bool)), m_commitDataFetcher, SLOT(deleteLater())); +} + void GitSubmitEditor::setCommitData(const CommitData &d) { m_commitEncoding = d.commitEncoding; @@ -181,19 +231,32 @@ void GitSubmitEditor::updateFileModel() } if (m_workingDirectory.isEmpty()) return; - GitClient *client = GitPlugin::instance()->gitClient(); - QString errorMessage, commitTemplate; - CommitData data(m_commitType); - if (client->getCommitData(m_workingDirectory, &commitTemplate, data, &errorMessage)) { - setCommitData(data); + submitEditorWidget()->setUpdateInProgress(true); + resetCommitDataFetcher(); + m_commitDataFetcher = new CommitDataFetcher(m_commitType, m_workingDirectory); + connect(m_commitDataFetcher, SIGNAL(finished(bool)), this, SLOT(commitDataRetrieved(bool))); + QFuture future = QtConcurrent::run(m_commitDataFetcher, &CommitDataFetcher::start); + Core::ProgressManager::addTask(future, tr("Refreshing Commit Data"), TASK_UPDATE_COMMIT); + + GitPlugin::instance()->gitClient()->addFuture(future); +} + +void GitSubmitEditor::commitDataRetrieved(bool success) +{ + GitSubmitEditorWidget *w = submitEditorWidget(); + w->setUpdateInProgress(false); + if (success) { + setCommitData(m_commitDataFetcher->commitData()); submitEditorWidget()->refreshLog(m_workingDirectory); - widget()->setEnabled(true); + w->setEnabled(true); } else { // Nothing to commit left! - VcsBase::VcsBaseOutputWindow::instance()->appendError(errorMessage); + VcsBase::VcsBaseOutputWindow::instance()->appendError(m_commitDataFetcher->errorMessage()); m_model->clear(); - widget()->setEnabled(false); + w->setEnabled(false); } + m_commitDataFetcher->deleteLater(); + m_commitDataFetcher = 0; } GitSubmitEditorPanelData GitSubmitEditor::panelData() const @@ -222,3 +285,5 @@ QByteArray GitSubmitEditor::fileContents() const } // namespace Internal } // namespace Git + +#include "gitsubmiteditor.moc" diff --git a/src/plugins/git/gitsubmiteditor.h b/src/plugins/git/gitsubmiteditor.h index ed5b3924d74..57c1d4f20f0 100644 --- a/src/plugins/git/gitsubmiteditor.h +++ b/src/plugins/git/gitsubmiteditor.h @@ -43,6 +43,7 @@ namespace Internal { class GitSubmitEditorWidget; class CommitData; +class CommitDataFetcher; struct GitSubmitEditorPanelData; class GitSubmitEditor : public VcsBase::VcsBaseSubmitEditor @@ -50,6 +51,7 @@ class GitSubmitEditor : public VcsBase::VcsBaseSubmitEditor Q_OBJECT public: explicit GitSubmitEditor(const VcsBase::VcsBaseSubmitEditorParameters *parameters, QWidget *parent); + ~GitSubmitEditor(); void setCommitData(const CommitData &); GitSubmitEditorPanelData panelData() const; @@ -68,10 +70,12 @@ protected: private slots: void slotDiffSelected(const QList &rows); void showCommit(const QString &commit); + void commitDataRetrieved(bool success); private: inline GitSubmitEditorWidget *submitEditorWidget(); inline const GitSubmitEditorWidget *submitEditorWidget() const; + void resetCommitDataFetcher(); VcsBase::SubmitFileModel *m_model; QTextCodec *m_commitEncoding; @@ -79,6 +83,7 @@ private: QString m_amendSHA1; QString m_workingDirectory; bool m_firstUpdate; + CommitDataFetcher *m_commitDataFetcher; }; } // namespace Internal diff --git a/src/plugins/vcsbase/submiteditorwidget.cpp b/src/plugins/vcsbase/submiteditorwidget.cpp index 10d6a93ce99..7f070a978e3 100644 --- a/src/plugins/vcsbase/submiteditorwidget.cpp +++ b/src/plugins/vcsbase/submiteditorwidget.cpp @@ -156,6 +156,7 @@ struct SubmitEditorWidgetPrivate bool m_commitEnabled; bool m_ignoreChange; bool m_descriptionMandatory; + bool m_updateInProgress; QActionPushButton *m_submitButton; }; @@ -170,6 +171,7 @@ SubmitEditorWidgetPrivate::SubmitEditorWidgetPrivate() : m_commitEnabled(false), m_ignoreChange(false), m_descriptionMandatory(true), + m_updateInProgress(false), m_submitButton(0) { } @@ -567,12 +569,20 @@ void SubmitEditorWidget::descriptionTextChanged() bool SubmitEditorWidget::canSubmit() const { + if (d->m_updateInProgress) + return false; if (isDescriptionMandatory() && cleanupDescription(descriptionText()).trimmed().isEmpty()) return false; const unsigned checkedCount = checkedFilesCount(); return d->m_emptyFileListEnabled || checkedCount > 0; } +void SubmitEditorWidget::setUpdateInProgress(bool value) +{ + d->m_updateInProgress = value; + updateSubmitAction(); +} + QString SubmitEditorWidget::commitName() const { return tr("&Commit"); diff --git a/src/plugins/vcsbase/submiteditorwidget.h b/src/plugins/vcsbase/submiteditorwidget.h index 3293e56d00e..6d841977356 100644 --- a/src/plugins/vcsbase/submiteditorwidget.h +++ b/src/plugins/vcsbase/submiteditorwidget.h @@ -104,6 +104,7 @@ public: QList submitFieldWidgets() const; virtual bool canSubmit() const; + void setUpdateInProgress(bool value); signals: void diffSelected(const QList &); @@ -126,6 +127,8 @@ protected: protected slots: void descriptionTextChanged(); + +public slots: void updateSubmitAction(); private slots: