From f84c2285680308cc7a7b48c86763c73dbd794371 Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@nokia.com> Date: Thu, 18 Nov 2010 16:58:30 +0100 Subject: [PATCH] Git: Add options to diff editor --- src/plugins/git/gitclient.cpp | 428 ++++++++++++++++++---- src/plugins/git/gitclient.h | 41 ++- src/plugins/git/giteditor.h | 2 +- src/plugins/git/gitplugin.cpp | 2 +- src/plugins/git/gitsettings.cpp | 16 +- src/plugins/git/gitsettings.h | 3 +- src/plugins/git/gitversioncontrol.cpp | 2 +- src/plugins/git/settingspage.cpp | 10 +- src/plugins/git/settingspage.ui | 23 +- src/plugins/texteditor/basetexteditor.cpp | 2 +- src/plugins/texteditor/basetexteditor.h | 2 +- src/plugins/vcsbase/vcsbaseeditor.cpp | 33 +- src/plugins/vcsbase/vcsbaseeditor.h | 4 + 13 files changed, 449 insertions(+), 119 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 3bf8ccdfac7..4ec8c407613 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -65,11 +65,233 @@ #include <QtGui/QMainWindow> // for msg box parent #include <QtGui/QMessageBox> -#include <QtGui/QPushButton> +#include <QtGui/QToolButton> static const char *const kGitDirectoryC = ".git"; static const char *const kBranchIndicatorC = "# On branch"; +namespace Git { +namespace Internal { + +BaseGitArgumentsWidget::BaseGitArgumentsWidget(GitSettings *settings, + Git::Internal::GitClient *client, + const QString &directory, + const QStringList &args) : + QWidget(0), + m_client(client), + m_workingDirectory(directory), + m_diffArgs(args), + m_settings(settings) +{ + Q_ASSERT(settings); + Q_ASSERT(client); +} + +} // namespace Internal +} // namespace Git + +namespace { + +class BaseGitDiffArgumentsWidget : public Git::Internal::BaseGitArgumentsWidget +{ +public: + BaseGitDiffArgumentsWidget(Git::Internal::GitSettings *settings, + Git::Internal::GitClient *client, + const QString &directory, + const QStringList &args) : + BaseGitArgumentsWidget(settings, client, directory, args), + m_patience(0), + m_ignoreSpaces(0) + { + QHBoxLayout * layout = new QHBoxLayout(this); + layout->setContentsMargins(3, 0, 3, 0); + + m_patience = new QToolButton; + m_patience->setText(tr("Patience")); + layout->addWidget(m_patience); + m_patience->setCheckable(true); + m_patience->setChecked(m_settings->diffPatience); + connect(m_patience, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged())); + + m_ignoreSpaces = new QToolButton; + m_ignoreSpaces->setText(tr("Ignore Whitespace")); + layout->addWidget(m_ignoreSpaces); + m_ignoreSpaces->setCheckable(true); + m_ignoreSpaces->setChecked(m_settings->ignoreSpaceChangesInDiff); + connect(m_ignoreSpaces, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged())); + } + + QStringList arguments() const + { + QStringList args = m_diffArgs; + + args.removeAll(QLatin1String("--patience")); + args.removeAll(QLatin1String("--ignore-space-change")); + + if (m_patience->isChecked()) + args.prepend(QLatin1String("--patience")); + if (m_ignoreSpaces->isChecked()) + args.prepend(QLatin1String("--ignore-space-change")); + + return args; + } + + void testForArgumentsChanged() { + m_settings->diffPatience = m_patience->isChecked(); + m_settings->ignoreSpaceChangesInDiff = m_ignoreSpaces->isChecked(); + + QStringList newArguments = arguments(); + + if (newArguments == m_diffArgs) + return; + + m_diffArgs = newArguments; + redoCommand(); + } + +private: + QToolButton *m_patience; + QToolButton *m_ignoreSpaces; +}; + +class GitCommitDiffArgumentsWidget : public BaseGitDiffArgumentsWidget +{ +public: + GitCommitDiffArgumentsWidget(Git::Internal::GitSettings *settings, + Git::Internal::GitClient *client, const QString &directory, + const QStringList &args, const QStringList &unstaged, + const QStringList &staged) : + BaseGitDiffArgumentsWidget(settings, client, directory, args), + m_unstagedFileNames(unstaged), + m_stagedFileNames(staged) + { } + + void redoCommand() + { + m_client->diff(m_workingDirectory, m_diffArgs, m_unstagedFileNames, m_stagedFileNames); + } + +private: + const QStringList m_unstagedFileNames; + const QStringList m_stagedFileNames; +}; + +class GitFileDiffArgumentsWidget : public BaseGitDiffArgumentsWidget +{ +public: + GitFileDiffArgumentsWidget(Git::Internal::GitSettings *settings, + Git::Internal::GitClient *client, const QString &directory, + const QStringList &args, const QString &file) : + BaseGitDiffArgumentsWidget(settings, client, directory, args), + m_fileName(file) + { } + + void redoCommand() + { + m_client->diff(m_workingDirectory, m_diffArgs, m_fileName); + } + +private: + const QString m_fileName; +}; + +class GitBranchDiffArgumentsWidget : public BaseGitDiffArgumentsWidget +{ +public: + GitBranchDiffArgumentsWidget(Git::Internal::GitSettings *settings, + Git::Internal::GitClient *client, const QString &directory, + const QStringList &args, const QString &branch) : + BaseGitDiffArgumentsWidget(settings, client, directory, args), + m_branchName(branch) + { } + + void redoCommand() + { + m_client->diffBranch(m_workingDirectory, m_diffArgs, m_branchName); + } + +private: + const QString m_branchName; +}; + +class GitBlameArgumentsWidget : public Git::Internal::BaseGitArgumentsWidget +{ +public: + GitBlameArgumentsWidget(Git::Internal::GitSettings *settings, + Git::Internal::GitClient *client, const QString &directory, + const QStringList &args, const QString &revision, + const QString &fileName) : + Git::Internal::BaseGitArgumentsWidget(settings, client, directory, args), + m_omitDate(0), + m_ignoreSpaces(0), + m_editor(0), + m_revision(revision), + m_fileName(fileName) + { + QHBoxLayout * layout = new QHBoxLayout(this); + layout->setContentsMargins(3, 0, 3, 0); + + m_omitDate = new QToolButton; + m_omitDate->setText(tr("Omit Date")); + layout->addWidget(m_omitDate); + m_omitDate->setCheckable(true); + m_omitDate->setChecked(m_settings->omitAnnotationDate); + m_omitDate->setMinimumHeight(16); + m_omitDate->setMaximumHeight(16); + connect(m_omitDate, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged())); + + m_ignoreSpaces = new QToolButton; + m_ignoreSpaces->setText(tr("Ignore Whitespace")); + layout->addWidget(m_ignoreSpaces); + m_ignoreSpaces->setCheckable(true); + m_ignoreSpaces->setChecked(m_settings->ignoreSpaceChangesInBlame); + m_ignoreSpaces->setMinimumHeight(16); + m_ignoreSpaces->setMaximumHeight(16); + connect(m_ignoreSpaces, SIGNAL(toggled(bool)), this, SLOT(testForArgumentsChanged())); + } + + void setEditor(VCSBase::VCSBaseEditor *editor) + { + Q_ASSERT(editor); + m_editor = editor; + } + + QStringList arguments() const + { + QStringList args = m_diffArgs; + + args.removeAll(QLatin1String("-w")); + + if (m_ignoreSpaces->isChecked()) + args.prepend(QLatin1String("-w")); + + return args; + } + + void testForArgumentsChanged() { + m_settings->omitAnnotationDate = m_omitDate->isChecked(); + m_settings->ignoreSpaceChangesInBlame = m_ignoreSpaces->isChecked(); + + m_diffArgs = arguments(); + redoCommand(); // always redo for omit date + } + + void redoCommand() + { + m_client->blame(m_workingDirectory, m_diffArgs, m_fileName, + m_revision, m_editor->lineNumberOfCurrentEditor()); + } + +private: + QToolButton *m_omitDate; + QToolButton *m_ignoreSpaces; + VCSBase::VCSBaseEditor *m_editor; + QString m_revision; + QString m_fileName; +}; + +} // namespace + inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property, const QString &entry) { foreach (Core::IEditor *ed, core->editorManager()->openedEditors()) @@ -147,41 +369,56 @@ QString GitClient::findRepositoryForDirectory(const QString &dir) return VCSBase::VCSBasePlugin::findRepositoryForDirectory(dir, checkFile); } +VCSBase::VCSBaseEditor *GitClient::findExistingVCSEditor(const char *registerDynamicProperty, + const QString &dynamicPropertyValue) const +{ + VCSBase::VCSBaseEditor *rc = 0; + Core::IEditor *outputEditor = locateEditor(m_core, registerDynamicProperty, dynamicPropertyValue); + if (!outputEditor) + return 0; + + // Exists already + outputEditor->createNew(m_msgWait); + rc = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor); + + return rc; +} + + /* Create an editor associated to VCS output of a source file/directory * (using the file's codec). Makes use of a dynamic property to find an * existing instance and to reuse it (in case, say, 'git diff foo' is * already open). */ -VCSBase::VCSBaseEditor - *GitClient::createVCSEditor(const QString &id, - QString title, - // Source file or directory - const QString &source, - bool setSourceCodec, - // Dynamic property and value to identify that editor - const char *registerDynamicProperty, - const QString &dynamicPropertyValue) const +VCSBase::VCSBaseEditor *GitClient::createVCSEditor(const QString &id, + QString title, + // Source file or directory + const QString &source, + bool setSourceCodec, + // Dynamic property and value to identify that editor + const char *registerDynamicProperty, + const QString &dynamicPropertyValue, + QWidget *configWidget) const { VCSBase::VCSBaseEditor *rc = 0; - Core::IEditor* outputEditor = locateEditor(m_core, registerDynamicProperty, dynamicPropertyValue); - if (outputEditor) { - // Exists already - outputEditor->createNew(m_msgWait); - rc = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor); - QTC_ASSERT(rc, return 0); - } else { - // Create new, set wait message, set up with source and codec - outputEditor = m_core->editorManager()->openEditorWithContents(id, &title, m_msgWait); - outputEditor->file()->setProperty(registerDynamicProperty, dynamicPropertyValue); - rc = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor); - connect(rc, SIGNAL(annotateRevisionRequested(QString,QString,int)), - this, SLOT(slotBlameRevisionRequested(QString,QString,int))); - QTC_ASSERT(rc, return 0); - rc->setSource(source); - if (setSourceCodec) - rc->setCodec(VCSBase::VCSBaseEditor::getCodec(source)); - } + Q_ASSERT(!findExistingVCSEditor(registerDynamicProperty, dynamicPropertyValue)); + + // Create new, set wait message, set up with source and codec + Core::IEditor *outputEditor = m_core->editorManager()->openEditorWithContents(id, &title, m_msgWait); + outputEditor->file()->setProperty(registerDynamicProperty, dynamicPropertyValue); + rc = VCSBase::VCSBaseEditor::getVcsBaseEditor(outputEditor); + connect(rc, SIGNAL(annotateRevisionRequested(QString,QString,int)), + this, SLOT(slotBlameRevisionRequested(QString,QString,int))); + QTC_ASSERT(rc, return 0); + rc->setSource(source); + if (setSourceCodec) + rc->setCodec(VCSBase::VCSBaseEditor::getCodec(source)); + m_core->editorManager()->activateEditor(outputEditor, Core::EditorManager::ModeSwitch); rc->setForceReadOnly(true); + + if (configWidget) + rc->setConfigurationWidget(configWidget); + return rc; } @@ -198,7 +435,17 @@ void GitClient::diff(const QString &workingDirectory, const QString editorId = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_ID); const QString title = tr("Git Diff"); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, workingDirectory, true, "originalFileName", workingDirectory); + QStringList userDiffArgs = diffArgs; + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("originalFileName", workingDirectory); + if (!editor) { + GitCommitDiffArgumentsWidget *argWidget = + new GitCommitDiffArgumentsWidget(&m_settings, this, workingDirectory, diffArgs, + unstagedFileNames, stagedFileNames); + userDiffArgs = argWidget->arguments(); + + editor = createVCSEditor(editorId, title, + workingDirectory, true, "originalFileName", workingDirectory, argWidget); + } editor->setDiffBaseDirectory(workingDirectory); // Create a batch of 2 commands to be run after each other in case @@ -206,27 +453,27 @@ void GitClient::diff(const QString &workingDirectory, // when using the submit dialog. GitCommand *command = createCommand(workingDirectory, editor); // Directory diff? - QStringList commonDiffArgs; - commonDiffArgs << QLatin1String("diff") << QLatin1String(noColorOption); - if (m_settings.diffPatience) - commonDiffArgs << QLatin1String("--patience"); - if (m_settings.ignoreSpaceChanges) - commonDiffArgs << QLatin1String("--ignore-space-change"); + + QStringList cmdArgs; + cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption); + if (unstagedFileNames.empty() && stagedFileNames.empty()) { - QStringList arguments(commonDiffArgs); - arguments << diffArgs; + QStringList arguments(cmdArgs); + arguments << userDiffArgs; outputWindow()->appendCommand(workingDirectory, binary, arguments); command->addJob(arguments, m_settings.timeoutSeconds); } else { // Files diff. if (!unstagedFileNames.empty()) { - QStringList arguments(commonDiffArgs); + QStringList arguments(cmdArgs); + arguments << userDiffArgs; arguments << QLatin1String("--") << unstagedFileNames; outputWindow()->appendCommand(workingDirectory, binary, arguments); command->addJob(arguments, m_settings.timeoutSeconds); } if (!stagedFileNames.empty()) { - QStringList arguments(commonDiffArgs); + QStringList arguments(cmdArgs); + arguments << userDiffArgs; arguments << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames; outputWindow()->appendCommand(workingDirectory, binary, arguments); command->addJob(arguments, m_settings.timeoutSeconds); @@ -239,18 +486,32 @@ 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") << QLatin1String(noColorOption) - << diffArgs; - if (!fileName.isEmpty()) - arguments << QLatin1String("--") << fileName; + // if (Git::Constants::debug) + qDebug() << "diff" << workingDirectory << fileName << diffArgs; + + const QString editorId = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_ID); const QString title = tr("Git Diff %1").arg(fileName); const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, fileName); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, sourceFile, true, "originalFileName", sourceFile); - executeGit(workingDirectory, arguments, editor); + + QStringList userDiffArgs = diffArgs; + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("originalFileName", sourceFile); + if (!editor) { + GitFileDiffArgumentsWidget *argWidget = + new GitFileDiffArgumentsWidget(&m_settings, this, workingDirectory, + diffArgs, fileName); + userDiffArgs = argWidget->arguments(); + + editor = createVCSEditor(editorId, title, sourceFile, true, "originalFileName", sourceFile, argWidget); + } + + QStringList cmdArgs; + cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption) + << userDiffArgs; + + if (!fileName.isEmpty()) + cmdArgs << QLatin1String("--") << fileName; + executeGit(workingDirectory, cmdArgs, editor); } void GitClient::diffBranch(const QString &workingDirectory, @@ -259,16 +520,27 @@ void GitClient::diffBranch(const QString &workingDirectory, { if (Git::Constants::debug) qDebug() << "diffBranch" << workingDirectory << branchName; - QStringList arguments; - arguments << QLatin1String("diff") << QLatin1String(noColorOption) - << diffArgs << branchName; const QString editorId = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_ID); const QString title = tr("Git Diff Branch %1").arg(branchName); const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, QStringList()); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, sourceFile, true, - "BranchName", branchName); - executeGit(workingDirectory, arguments, editor); + + QStringList userDiffArgs = diffArgs; + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("BranchName", branchName); + if (!editor) { + GitBranchDiffArgumentsWidget *argWidget = + new GitBranchDiffArgumentsWidget(&m_settings, this, workingDirectory, + diffArgs, branchName); + userDiffArgs = argWidget->arguments(); + + editor = createVCSEditor(editorId, title, sourceFile, true, "BranchName", branchName, argWidget); + } + + QStringList cmdArgs; + cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption) + << diffArgs << branchName; + + executeGit(workingDirectory, cmdArgs, editor); } void GitClient::status(const QString &workingDirectory) @@ -308,7 +580,9 @@ void GitClient::graphLog(const QString &workingDirectory, const QString & branch } const QString editorId = QLatin1String(Git::Constants::GIT_LOG_EDITOR_ID); const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, QStringList()); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, sourceFile, false, "logFileName", sourceFile); + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("logFileName", sourceFile); + if (!editor) + editor = createVCSEditor(editorId, title, sourceFile, false, "logFileName", sourceFile, 0); executeGit(workingDirectory, arguments, editor); } @@ -331,7 +605,9 @@ void GitClient::log(const QString &workingDirectory, const QStringList &fileName const QString title = tr("Git Log %1").arg(msgArg); const QString editorId = QLatin1String(Git::Constants::GIT_LOG_EDITOR_ID); const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, fileNames); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, sourceFile, false, "logFileName", sourceFile); + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("logFileName", sourceFile); + if (!editor) + editor = createVCSEditor(editorId, title, sourceFile, false, "logFileName", sourceFile, 0); editor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); executeGit(workingDirectory, arguments, editor); } @@ -365,7 +641,9 @@ void GitClient::show(const QString &source, const QString &id) const QString title = tr("Git Show %1").arg(id); const QString editorId = QLatin1String(Git::Constants::GIT_DIFF_EDITOR_ID); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, source, true, "show", id); + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("show", id); + if (!editor) + editor = createVCSEditor(editorId, title, source, true, "show", id, 0); const QFileInfo sourceFi(source); const QString workDir = sourceFi.isDir() ? sourceFi.absoluteFilePath() : sourceFi.absolutePath(); @@ -380,29 +658,41 @@ void GitClient::slotBlameRevisionRequested(const QString &source, QString change if (blankPos != -1) change.truncate(blankPos); const QFileInfo fi(source); - blame(fi.absolutePath(), fi.fileName(), change, lineNumber); + blame(fi.absolutePath(), QStringList(), fi.fileName(), change, lineNumber); } void GitClient::blame(const QString &workingDirectory, + const QStringList &args, const QString &fileName, const QString &revision /* = QString() */, int lineNumber /* = -1 */) { if (Git::Constants::debug) - qDebug() << "blame" << workingDirectory << fileName << lineNumber; - QStringList arguments(QLatin1String("blame")); - arguments << QLatin1String("--root"); - if (m_plugin->settings().ignoreSpaceChanges) - arguments << QLatin1String("-w"); - arguments << QLatin1String("--") << fileName; - if (!revision.isEmpty()) - arguments << revision; + qDebug() << "blame" << workingDirectory << fileName << lineNumber << args; + const QString editorId = QLatin1String(Git::Constants::GIT_BLAME_EDITOR_ID); const QString id = VCSBase::VCSBaseEditor::getTitleId(workingDirectory, QStringList(fileName), revision); const QString title = tr("Git Blame %1").arg(id); const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, fileName); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, sourceFile, true, "blameFileName", id); + QStringList userBlameArgs = args; + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("blameFileName", id); + if (!editor) { + GitBlameArgumentsWidget *argWidget = + new GitBlameArgumentsWidget(&m_settings, this, workingDirectory, userBlameArgs, + revision, fileName); + editor = createVCSEditor(editorId, title, sourceFile, true, "blameFileName", id, argWidget); + argWidget->setEditor(editor); + + userBlameArgs = argWidget->arguments(); + } + + QStringList arguments(QLatin1String("blame")); + arguments << QLatin1String("--root"); + arguments.append(userBlameArgs); + arguments << QLatin1String("--") << fileName; + if (!revision.isEmpty()) + arguments << revision; executeGit(workingDirectory, arguments, editor, false, GitCommand::NoReport, lineNumber); } @@ -1776,7 +2066,9 @@ void GitClient::subversionLog(const QString &workingDirectory) const QString title = tr("Git SVN Log"); const QString editorId = QLatin1String(Git::Constants::C_GIT_COMMAND_LOG_EDITOR); const QString sourceFile = VCSBase::VCSBaseEditor::getSource(workingDirectory, QStringList()); - VCSBase::VCSBaseEditor *editor = createVCSEditor(editorId, title, sourceFile, false, "svnLog", sourceFile); + VCSBase::VCSBaseEditor *editor = findExistingVCSEditor("svnLog", sourceFile); + if (!editor) + editor = createVCSEditor(editorId, title, sourceFile, false, "svnLog", sourceFile, 0); executeGit(workingDirectory, arguments, editor); } diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 2c8226d32f8..db8ba15f1f1 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -1,4 +1,4 @@ -/************************************************************************** + /************************************************************************** ** ** This file is part of Qt Creator ** @@ -37,8 +37,10 @@ #include <QtCore/QString> #include <QtCore/QStringList> +#include <QtGui/QWidget> QT_BEGIN_NAMESPACE +class QCheckBox; class QErrorMessage; class QSignalMapper; class QDebug; @@ -91,7 +93,7 @@ public: void graphLog(const QString &workingDirectory, const QString &branch); void log(const QString &workingDirectory, const QStringList &fileNames, bool enableAnnotationContextMenu = false); - void blame(const QString &workingDirectory, const QString &fileName, + void blame(const QString &workingDirectory, const QStringList &args, const QString &fileName, const QString &revision = QString(), int lineNumber = -1); void checkout(const QString &workingDirectory, const QString &file); void checkoutBranch(const QString &workingDirectory, const QString &branch); @@ -229,12 +231,15 @@ private slots: void slotBlameRevisionRequested(const QString &source, QString change, int lineNumber); private: + VCSBase::VCSBaseEditor *findExistingVCSEditor(const char *registerDynamicProperty, + const QString &dynamicPropertyValue) const; VCSBase::VCSBaseEditor *createVCSEditor(const QString &kind, - QString title, - const QString &source, - bool setSourceCodec, - const char *registerDynamicProperty, - const QString &dynamicPropertyValue) const; + QString title, + const QString &source, + bool setSourceCodec, + const char *registerDynamicProperty, + const QString &dynamicPropertyValue, + QWidget *configWidget) const; GitCommand *createCommand(const QString &workingDirectory, VCSBase::VCSBaseEditor* editor = 0, @@ -288,6 +293,28 @@ private: bool m_hasCachedGitVersion; }; +class BaseGitArgumentsWidget : public QWidget { + Q_OBJECT + +public: + BaseGitArgumentsWidget(GitSettings *settings, + GitClient *client, const QString &directory, + const QStringList &args); + + virtual QStringList arguments() const = 0; + virtual void redoCommand() = 0; + +protected slots: + virtual void testForArgumentsChanged() = 0; + +protected: + GitClient *m_client; + + const QString m_workingDirectory; + QStringList m_diffArgs; + GitSettings *m_settings; +}; + } // namespace Internal } // namespace Git diff --git a/src/plugins/git/giteditor.h b/src/plugins/git/giteditor.h index c82a501e545..7028a9c2806 100644 --- a/src/plugins/git/giteditor.h +++ b/src/plugins/git/giteditor.h @@ -47,7 +47,7 @@ class GitEditor : public VCSBase::VCSBaseEditor public: explicit GitEditor(const VCSBase::VCSBaseEditorParameters *type, - QWidget *parent); + QWidget *parent); public slots: void setPlainTextDataFiltered(const QByteArray &a); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 835592132be..25113a7a6de 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -596,7 +596,7 @@ void GitPlugin::blameFile() const VCSBase::VCSBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return) const int lineNumber = VCSBase::VCSBaseEditor::lineNumberOfCurrentEditor(state.currentFile()); - m_gitClient->blame(state.currentFileTopLevel(), state.relativeCurrentFile(), QString(), lineNumber); + m_gitClient->blame(state.currentFileTopLevel(), QStringList(), state.relativeCurrentFile(), QString(), lineNumber); } void GitPlugin::logProject() diff --git a/src/plugins/git/gitsettings.cpp b/src/plugins/git/gitsettings.cpp index 3cded7b2d87..56f77548e22 100644 --- a/src/plugins/git/gitsettings.cpp +++ b/src/plugins/git/gitsettings.cpp @@ -44,7 +44,8 @@ static const char timeoutKeyC[] = "TimeOut"; static const char pullRebaseKeyC[] = "PullRebase"; static const char promptToSubmitKeyC[] = "PromptForSubmit"; static const char omitAnnotationDateKeyC[] = "OmitAnnotationDate"; -static const char ignoreSpaceChangesC[] = "SpaceIgnorantBlame"; +static const char ignoreSpaceChangesBlameKeyC[] = "SpaceIgnorantBlame"; +static const char ignoreSpaceChangesDiffKeyC[] = "SpaceIgnorantDiff"; static const char diffPatienceKeyC[] = "DiffPatience"; static const char winSetHomeEnvironmentKeyC[] = "WinSetHomeEnvironment"; static const char gitkOptionsKeyC[] = "GitKOptions"; @@ -69,7 +70,8 @@ GitSettings::GitSettings() : pullRebase(bool(defaultPullRebase)), promptToSubmit(true), omitAnnotationDate(false), - ignoreSpaceChanges(true), + ignoreSpaceChangesInDiff(false), + ignoreSpaceChangesInBlame(true), diffPatience(true), winSetHomeEnvironment(false) { @@ -85,7 +87,8 @@ void GitSettings::fromSettings(QSettings *settings) pullRebase = settings->value(QLatin1String(pullRebaseKeyC), bool(defaultPullRebase)).toBool(); promptToSubmit = settings->value(QLatin1String(promptToSubmitKeyC), true).toBool(); omitAnnotationDate = settings->value(QLatin1String(omitAnnotationDateKeyC), false).toBool(); - ignoreSpaceChanges = settings->value(QLatin1String(ignoreSpaceChangesC), true).toBool(); + ignoreSpaceChangesInDiff = settings->value(QLatin1String(ignoreSpaceChangesDiffKeyC), true).toBool(); + ignoreSpaceChangesInBlame = settings->value(QLatin1String(ignoreSpaceChangesBlameKeyC), true).toBool(); diffPatience = settings->value(QLatin1String(diffPatienceKeyC), true).toBool(); winSetHomeEnvironment = settings->value(QLatin1String(winSetHomeEnvironmentKeyC), false).toBool(); gitkOptions = settings->value(QLatin1String(gitkOptionsKeyC)).toString(); @@ -102,7 +105,8 @@ void GitSettings::toSettings(QSettings *settings) const settings->setValue(QLatin1String(pullRebaseKeyC), pullRebase); settings->setValue(QLatin1String(promptToSubmitKeyC), promptToSubmit); settings->setValue(QLatin1String(omitAnnotationDateKeyC), omitAnnotationDate); - settings->setValue(QLatin1String(ignoreSpaceChangesC), ignoreSpaceChanges); + settings->setValue(QLatin1String(ignoreSpaceChangesDiffKeyC), ignoreSpaceChangesInDiff); + settings->setValue(QLatin1String(ignoreSpaceChangesBlameKeyC), ignoreSpaceChangesInBlame); settings->setValue(QLatin1String(diffPatienceKeyC), diffPatience); settings->setValue(QLatin1String(winSetHomeEnvironmentKeyC), winSetHomeEnvironment); settings->setValue(QLatin1String(gitkOptionsKeyC), gitkOptions); @@ -114,7 +118,9 @@ bool GitSettings::equals(const GitSettings &s) const return adoptPath == s.adoptPath && path == s.path && logCount == s.logCount && timeoutSeconds == s.timeoutSeconds && promptToSubmit == s.promptToSubmit && pullRebase == s.pullRebase - && omitAnnotationDate == s.omitAnnotationDate && ignoreSpaceChanges == s.ignoreSpaceChanges + && omitAnnotationDate == s.omitAnnotationDate + && ignoreSpaceChangesInBlame == s.ignoreSpaceChangesInBlame + && ignoreSpaceChangesInDiff == s.ignoreSpaceChangesInDiff && diffPatience == s.diffPatience && winSetHomeEnvironment == s.winSetHomeEnvironment && gitkOptions == s.gitkOptions; } diff --git a/src/plugins/git/gitsettings.h b/src/plugins/git/gitsettings.h index d7235230621..675162ed11d 100644 --- a/src/plugins/git/gitsettings.h +++ b/src/plugins/git/gitsettings.h @@ -59,7 +59,8 @@ struct GitSettings bool pullRebase; bool promptToSubmit; bool omitAnnotationDate; - bool ignoreSpaceChanges; + bool ignoreSpaceChangesInDiff; + bool ignoreSpaceChangesInBlame; bool diffPatience; bool winSetHomeEnvironment; QString gitkOptions; diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp index ad6cc63c2da..68926d42978 100644 --- a/src/plugins/git/gitversioncontrol.cpp +++ b/src/plugins/git/gitversioncontrol.cpp @@ -232,7 +232,7 @@ bool GitVersionControl::managesDirectory(const QString &directory, QString *topL bool GitVersionControl::vcsAnnotate(const QString &file, int line) { const QFileInfo fi(file); - gitClient()->blame(fi.absolutePath(), fi.fileName(), QString(), line); + gitClient()->blame(fi.absolutePath(), QStringList(), fi.fileName(), QString(), line); return true; } diff --git a/src/plugins/git/settingspage.cpp b/src/plugins/git/settingspage.cpp index 93c27315053..423cd920c70 100644 --- a/src/plugins/git/settingspage.cpp +++ b/src/plugins/git/settingspage.cpp @@ -73,9 +73,6 @@ GitSettings SettingsPageWidget::settings() const rc.timeoutSeconds = m_ui.timeoutSpinBox->value(); rc.pullRebase = m_ui.pullRebaseCheckBox->isChecked(); rc.promptToSubmit = m_ui.promptToSubmitCheckBox->isChecked(); - rc.omitAnnotationDate = m_ui.omitAnnotationDataCheckBox->isChecked(); - rc.ignoreSpaceChanges = m_ui.spaceIgnorantBlameCheckBox->isChecked(); - rc.diffPatience = m_ui.diffPatienceCheckBox->isChecked(); rc.winSetHomeEnvironment = m_ui.winHomeCheckBox->isChecked(); rc.gitkOptions = m_ui.gitkOptionsLineEdit->text().trimmed(); return rc; @@ -89,9 +86,6 @@ void SettingsPageWidget::setSettings(const GitSettings &s) m_ui.timeoutSpinBox->setValue(s.timeoutSeconds); m_ui.pullRebaseCheckBox->setChecked(s.pullRebase); m_ui.promptToSubmitCheckBox->setChecked(s.promptToSubmit); - m_ui.omitAnnotationDataCheckBox->setChecked(s.omitAnnotationDate); - m_ui.spaceIgnorantBlameCheckBox->setChecked(s.ignoreSpaceChanges); - m_ui.diffPatienceCheckBox->setChecked(s.diffPatience); m_ui.winHomeCheckBox->setChecked(s.winSetHomeEnvironment); m_ui.gitkOptionsLineEdit->setText(s.gitkOptions); } @@ -108,9 +102,7 @@ QString SettingsPageWidget::searchKeywords() const << ' ' << m_ui.timeoutLabel->text() << ' ' << m_ui.promptToSubmitCheckBox->text() << ' ' << m_ui.promptToSubmitCheckBox->text() - << ' ' << m_ui.omitAnnotationDataCheckBox->text() - << ' ' << m_ui.environmentGroupBox->title() - << ' ' << m_ui.spaceIgnorantBlameCheckBox->text(); + << ' ' << m_ui.environmentGroupBox->title(); rc.remove(QLatin1Char('&')); return rc; } diff --git a/src/plugins/git/settingspage.ui b/src/plugins/git/settingspage.ui index 386de3f01b1..6a7eefe8810 100644 --- a/src/plugins/git/settingspage.ui +++ b/src/plugins/git/settingspage.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>361</width> + <width>390</width> <height>444</height> </rect> </property> @@ -128,27 +128,6 @@ </property> </widget> </item> - <item row="5" column="0" colspan="2"> - <widget class="QCheckBox" name="omitAnnotationDataCheckBox"> - <property name="text"> - <string>Omit date from blame output</string> - </property> - </widget> - </item> - <item row="6" column="0" colspan="2"> - <widget class="QCheckBox" name="spaceIgnorantBlameCheckBox"> - <property name="text"> - <string>Ignore whitespace changes in blame and diff</string> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QCheckBox" name="diffPatienceCheckBox"> - <property name="text"> - <string>Use "patience diff" algorithm</string> - </property> - </widget> - </item> <item row="3" column="0" colspan="2"> <widget class="QCheckBox" name="pullRebaseCheckBox"> <property name="text"> diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index d9e2284d64f..e729431e76f 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -5927,7 +5927,7 @@ BaseTextEditorEditable::BaseTextEditorEditable(BaseTextEditor *editor) QWidget *w = new QWidget; l->setMargin(0); l->setContentsMargins(5, 0, 5, 0); - l->addStretch(0); + // l->addStretch(0); l->addWidget(m_cursorPositionLabel); w->setLayout(l); diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 9b19c2f0448..6f4dfc725c5 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -573,7 +573,7 @@ public: inline QByteArray saveState() const { return e->saveState(); } inline bool restoreState(const QByteArray &state) { return e->restoreState(state); } - QWidget *toolBar(); + virtual QWidget *toolBar(); // ITextEditor int find(const QString &string) const; diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index f65e221f634..c2939cd8576 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -131,7 +131,6 @@ VCSBaseDiffEditorEditable::VCSBaseDiffEditorEditable(VCSBaseEditor *e, const VCS m_diffFileBrowseComboBox(new QComboBox(m_toolBar)) { m_diffFileBrowseComboBox->setMinimumContentsLength(20); - m_diffFileBrowseComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); // Make the combo box prefer to expand QSizePolicy policy = m_diffFileBrowseComboBox->sizePolicy(); policy.setHorizontalPolicy(QSizePolicy::Expanding); @@ -163,6 +162,8 @@ struct VCSBaseEditorPrivate QString m_annotatePreviousRevisionTextFormat; QString m_copyRevisionTextFormat; bool m_fileLogAnnotateEnabled; + QToolBar *m_toolBar; + QWidget *m_configurationWidget; }; VCSBaseEditorPrivate::VCSBaseEditorPrivate(const VCSBaseEditorParameters *type) : @@ -170,7 +171,9 @@ VCSBaseEditorPrivate::VCSBaseEditorPrivate(const VCSBaseEditorParameters *type) m_cursorLine(-1), m_annotateRevisionTextFormat(VCSBaseEditor::tr("Annotate \"%1\"")), m_copyRevisionTextFormat(VCSBaseEditor::tr("Copy \"%1\"")), - m_fileLogAnnotateEnabled(false) + m_fileLogAnnotateEnabled(false), + m_toolBar(0), + m_configurationWidget(0) { } @@ -325,6 +328,8 @@ TextEditor::BaseTextEditorEditable *VCSBaseEditor::createEditableInterface() } else { editable = new VCSBaseEditorEditable(this, d->m_parameters); } + d->m_toolBar = qobject_cast<QToolBar *>(editable->toolBar()); + // Pass on signals. connect(this, SIGNAL(describeRequested(QString,QString)), editable, SIGNAL(describeRequested(QString,QString))); @@ -829,6 +834,30 @@ QString VCSBaseEditor::getTitleId(const QString &workingDirectory, return rc; } +bool VCSBaseEditor::setConfigurationWidget(QWidget *w) +{ + if (!d->m_toolBar || d->m_configurationWidget) + return false; + + d->m_configurationWidget = w; + if (contentType() == AnnotateOutput) { + QList<QAction *> actions = d->m_toolBar->actions(); + Q_ASSERT(actions.count() >= 1); + QWidget *spacer = new QWidget(d->m_toolBar); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + QAction *configAction = d->m_toolBar->insertWidget(actions.at(0), w); + d->m_toolBar->insertWidget(configAction, spacer); + } else { + d->m_toolBar->addWidget(w); + } + return true; +} + +QWidget *VCSBaseEditor::configurationWidget() const +{ + return d->m_configurationWidget; +} + // Find the complete file from a diff relative specification. QString VCSBaseEditor::findDiffFile(const QString &f, Core::IVersionControl *control /* = 0 */) const { diff --git a/src/plugins/vcsbase/vcsbaseeditor.h b/src/plugins/vcsbase/vcsbaseeditor.h index f03a83554b3..737c61fab75 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.h +++ b/src/plugins/vcsbase/vcsbaseeditor.h @@ -178,6 +178,10 @@ public: static QString getTitleId(const QString &workingDirectory, const QStringList &fileNames, const QString &revision = QString()); + + bool setConfigurationWidget(QWidget *w); + QWidget *configurationWidget() const; + signals: // These signals also exist in the opaque editable (IEditor) that is // handled by the editor manager for convenience. They are emitted -- GitLab