diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 7b3162786ff08087b13baf023255bf6f612dce1c..69da0fb1f0e3dc05575b5500f5a8e0f440cc9e58 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -673,6 +673,17 @@ VcsBaseEditorWidget *GitClient::findExistingVCSEditor(const char *registerDynami return rc; } +QTextCodec *GitClient::codecFor(GitClient::CodecType codecType, const QString &source) const +{ + if (codecType == CodecSource) { + return QFileInfo(source).isFile() ? VcsBaseEditor::getCodec(source) + : encoding(source, "gui.encoding"); + } + if (codecType == CodecLogOutput) + return encoding(source, "i18n.logOutputEncoding"); + return 0; +} + void GitClient::slotChunkActionsRequested(QMenu *menu, bool isValid) { menu->addSeparator(); @@ -746,37 +757,6 @@ void GitClient::stage(const QString &patch, bool revert) } } -/* 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). */ -VcsBaseEditorWidget *GitClient::createVcsEditor(Id id, QString title, - const QString &source, // Source file or directory - CodecType codecType, - const char *registerDynamicProperty, // Dynamic property and value to identify that editor - const QString &dynamicPropertyValue) const -{ - VcsBaseEditorWidget *rc = 0; - QTC_CHECK(!findExistingVCSEditor(registerDynamicProperty, dynamicPropertyValue)); - - // Create new, set wait message, set up with source and codec - IEditor *outputEditor = EditorManager::openEditorWithContents(id, &title); - outputEditor->document()->setProperty(registerDynamicProperty, dynamicPropertyValue); - rc = VcsBaseEditor::getVcsBaseEditor(outputEditor); - connect(rc, &VcsBaseEditorWidget::annotateRevisionRequested, - this, &GitClient::slotBlameRevisionRequested); - QTC_ASSERT(rc, return 0); - rc->setSource(source); - if (codecType == CodecSource) - rc->setCodec(getSourceCodec(source)); - else if (codecType == CodecLogOutput) - rc->setCodec(encoding(source, "i18n.logOutputEncoding")); - - rc->setForceReadOnly(true); - - return rc; -} - void GitClient::requestReload(const QString &documentId, const QString &source, const QString &title, std::function<DiffEditorController *(IDocument *)> factory) const @@ -889,7 +869,8 @@ void GitClient::log(const QString &workingDirectory, const QString &fileName, auto *argWidget = new GitLogArgumentsWidget(settings()); connect(argWidget, &VcsBaseEditorParameterWidget::commandExecutionRequested, [=]() { this->log(workingDirectory, fileName, enableAnnotationContextMenu, args); }); - editor = createVcsEditor(editorId, title, sourceFile, CodecLogOutput, "logTitle", msgArg); + editor = createVcsEditor(editorId, title, sourceFile, codecFor(CodecLogOutput), + "logTitle", msgArg); editor->setConfigurationWidget(argWidget); } editor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); @@ -921,7 +902,7 @@ void GitClient::reflog(const QString &workingDirectory) const Id editorId = Git::Constants::GIT_LOG_EDITOR_ID; VcsBaseEditorWidget *editor = findExistingVCSEditor("reflogRepository", workingDirectory); if (!editor) { - editor = createVcsEditor(editorId, title, workingDirectory, CodecLogOutput, + editor = createVcsEditor(editorId, title, workingDirectory, codecFor(CodecLogOutput), "reflogRepository", workingDirectory); } editor->setWorkingDirectory(workingDirectory); @@ -974,21 +955,16 @@ void GitClient::show(const QString &source, const QString &id, const QString &na }); } -void GitClient::slotBlameRevisionRequested(const QString &workingDirectory, const QString &file, - QString change, int lineNumber) +void GitClient::annotateRevisionRequested(const QString &workingDirectory, const QString &file, + const QString &change, int lineNumber) { + QString sha1 = change; // This might be invoked with a verbose revision description // "SHA1 author subject" from the annotation context menu. Strip the rest. - const int blankPos = change.indexOf(QLatin1Char(' ')); + const int blankPos = sha1.indexOf(QLatin1Char(' ')); if (blankPos != -1) - change.truncate(blankPos); - blame(workingDirectory, QStringList(), file, change, lineNumber); -} - -QTextCodec *GitClient::getSourceCodec(const QString &file) const -{ - return QFileInfo(file).isFile() ? VcsBaseEditor::getCodec(file) - : encoding(file, "gui.encoding"); + sha1.truncate(blankPos); + blame(workingDirectory, QStringList(), file, sha1, lineNumber); } void GitClient::blame(const QString &workingDirectory, @@ -1011,7 +987,8 @@ void GitClient::blame(const QString &workingDirectory, const int line = VcsBaseEditor::lineNumberOfCurrentEditor(); blame(workingDirectory, args, fileName, revision, line); } ); - editor = createVcsEditor(editorId, title, sourceFile, CodecSource, "blameFileName", id); + editor = createVcsEditor(editorId, title, sourceFile, codecFor(CodecSource, sourceFile), + "blameFileName", id); editor->setConfigurationWidget(argWidget); } @@ -1564,7 +1541,7 @@ void GitClient::branchesForCommit(const QString &revision) auto controller = qobject_cast<DiffEditorController *>(sender()); QString workingDirectory = controller->baseDirectory(); auto command = new VcsCommand(vcsBinary(), workingDirectory, processEnvironment()); - command->setCodec(getSourceCodec(currentDocumentPath())); + command->setCodec(codecFor(CodecSource, currentDocumentPath())); command->setCookie(workingDirectory); connect(command, &VcsCommand::output, controller, @@ -3022,7 +2999,8 @@ void GitClient::subversionLog(const QString &workingDirectory) const QString sourceFile = VcsBaseEditor::getSource(workingDirectory, QStringList()); VcsBaseEditorWidget *editor = findExistingVCSEditor("svnLog", sourceFile); if (!editor) - editor = createVcsEditor(editorId, title, sourceFile, CodecNone, "svnLog", sourceFile); + editor = createVcsEditor(editorId, title, sourceFile, codecFor(CodecNone), + "svnLog", sourceFile); editor->setWorkingDirectory(workingDirectory); executeGit(workingDirectory, arguments, editor); } diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index efc2127f0611d34ea3bf8afbb36db37e3e05f4b8..8a2bb35bf91b2aaad2103a2aa22b000ccec7d55d 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -349,8 +349,6 @@ public slots: const QString &name = QString()); private slots: - void slotBlameRevisionRequested(const QString &workingDirectory, const QString &file, - QString change, int lineNumber); void finishSubmoduleUpdate(); void fetchFinished(const QVariant &cookie); void slotChunkActionsRequested(QMenu *menu, bool isValid); @@ -359,19 +357,15 @@ private slots: void branchesForCommit(const QString &revision); private: + void annotateRevisionRequested(const QString &workingDirectory, const QString &file, + const QString &change, int lineNumber) override; + void stage(const QString &patch, bool revert); - QTextCodec *getSourceCodec(const QString &file) const; VcsBase::VcsBaseEditorWidget *findExistingVCSEditor(const char *registerDynamicProperty, const QString &dynamicPropertyValue) const; enum CodecType { CodecSource, CodecLogOutput, CodecNone }; - - VcsBase::VcsBaseEditorWidget *createVcsEditor(Core::Id kind, - QString title, - const QString &source, - CodecType codecType, - const char *registerDynamicProperty, - const QString &dynamicPropertyValue) const; + QTextCodec *codecFor(CodecType codecType, const QString &source = QString()) const; void requestReload(const QString &documentId, const QString &source, const QString &title, std::function<DiffEditor::DiffEditorController *(Core::IDocument *)> factory) const; diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index a736d8f622c55cb7d46141806bcb5abcc4bebdd3..7ca29f347f64a12dd33b0b742451928810639f0c 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -282,7 +282,8 @@ void MercurialClient::incoming(const QString &repositoryRoot, const QString &rep const QString title = tr("Hg incoming %1").arg(id); VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot, - true, "incoming", id); + VcsBaseEditor::getCodec(repositoryRoot), + "incoming", id); VcsCommand *cmd = createCommand(repository, editor); enqueueJob(cmd, args); } @@ -295,7 +296,8 @@ void MercurialClient::outgoing(const QString &repositoryRoot) const QString title = tr("Hg outgoing %1"). arg(QDir::toNativeSeparators(repositoryRoot)); - VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot, true, + VcsBaseEditorWidget *editor = createVcsEditor(Constants::DIFFLOG_ID, title, repositoryRoot, + VcsBaseEditor::getCodec(repositoryRoot), "outgoing", repositoryRoot); VcsCommand *cmd = createCommand(repositoryRoot, editor); diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 6ac445db0ccda5500ff36fb659bd1ecaec13a264..2412355b3034f1be01bf0d40872a1b9a1b1ab43c 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -180,6 +180,36 @@ int VcsBaseClientImpl::vcsTimeout() const return settings().intValue(VcsBaseClientSettings::timeoutKey); } +VcsBaseEditorWidget *VcsBaseClientImpl::createVcsEditor(Core::Id kind, QString title, + const QString &source, QTextCodec *codec, + const char *registerDynamicProperty, + const QString &dynamicPropertyValue) const +{ + VcsBaseEditorWidget *baseEditor = 0; + Core::IEditor *outputEditor = locateEditor(registerDynamicProperty, dynamicPropertyValue); + const QString progressMsg = tr("Working..."); + if (outputEditor) { + // Exists already + outputEditor->document()->setContents(progressMsg.toUtf8()); + baseEditor = VcsBaseEditor::getVcsBaseEditor(outputEditor); + QTC_ASSERT(baseEditor, return 0); + Core::EditorManager::activateEditor(outputEditor); + } else { + outputEditor = Core::EditorManager::openEditorWithContents(kind, &title, progressMsg.toUtf8()); + outputEditor->document()->setProperty(registerDynamicProperty, dynamicPropertyValue); + baseEditor = VcsBaseEditor::getVcsBaseEditor(outputEditor); + connect(baseEditor, &VcsBaseEditorWidget::annotateRevisionRequested, + this, &VcsBaseClientImpl::annotateRevisionRequested); + QTC_ASSERT(baseEditor, return 0); + baseEditor->setSource(source); + if (codec) + baseEditor->setCodec(codec); + } + + baseEditor->setForceReadOnly(true); + return baseEditor; +} + void VcsBaseClientImpl::saveSettings() { settings().writeSettings(Core::ICore::settings()); @@ -386,7 +416,8 @@ void VcsBaseClient::annotate(const QString &workingDir, const QString &file, const QString title = vcsEditorTitle(vcsCmdString, id); const QString source = VcsBaseEditor::getSource(workingDir, file); - VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, true, + VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, + VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); VcsCommand *cmd = createCommand(workingDir, editor); @@ -402,7 +433,8 @@ void VcsBaseClient::diff(const QString &workingDir, const QStringList &files, const QString id = VcsBaseEditor::getTitleId(workingDir, files); const QString title = vcsEditorTitle(vcsCmdString, id); const QString source = VcsBaseEditor::getSource(workingDir, files); - VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, true, + VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, + VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); editor->setWorkingDirectory(workingDir); @@ -434,7 +466,8 @@ void VcsBaseClient::log(const QString &workingDir, const QStringList &files, const QString id = VcsBaseEditor::getTitleId(workingDir, files); const QString title = vcsEditorTitle(vcsCmdString, id); const QString source = VcsBaseEditor::getSource(workingDir, files); - VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, true, + VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, + VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); editor->setFileLogAnnotateEnabled(enableAnnotationContextMenu); @@ -555,7 +588,8 @@ void VcsBaseClient::view(const QString &source, const QString &id, const Core::Id kind = vcsEditorKind(DiffCommand); const QString title = vcsEditorTitle(vcsCommandString(LogCommand), id); - VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, true, "view", id); + VcsBaseEditorWidget *editor = createVcsEditor(kind, title, source, + VcsBaseEditor::getCodec(source), "view", id); const QFileInfo fi(source); const QString workingDirPath = fi.isFile() ? fi.absolutePath() : source; @@ -601,36 +635,6 @@ QString VcsBaseClient::vcsEditorTitle(const QString &vcsCmd, const QString &sour Utils::FileName::fromString(sourceId).fileName(); } -VcsBaseEditorWidget *VcsBaseClient::createVcsEditor(Core::Id kind, QString title, - const QString &source, bool setSourceCodec, - const char *registerDynamicProperty, - const QString &dynamicPropertyValue) const -{ - VcsBaseEditorWidget *baseEditor = 0; - Core::IEditor *outputEditor = locateEditor(registerDynamicProperty, dynamicPropertyValue); - const QString progressMsg = tr("Working..."); - if (outputEditor) { - // Exists already - outputEditor->document()->setContents(progressMsg.toUtf8()); - baseEditor = VcsBaseEditor::getVcsBaseEditor(outputEditor); - QTC_ASSERT(baseEditor, return 0); - Core::EditorManager::activateEditor(outputEditor); - } else { - outputEditor = Core::EditorManager::openEditorWithContents(kind, &title, progressMsg.toUtf8()); - outputEditor->document()->setProperty(registerDynamicProperty, dynamicPropertyValue); - baseEditor = VcsBaseEditor::getVcsBaseEditor(outputEditor); - connect(baseEditor, &VcsBaseEditorWidget::annotateRevisionRequested, - this, &VcsBaseClient::annotateRevision); - QTC_ASSERT(baseEditor, return 0); - baseEditor->setSource(source); - if (setSourceCodec) - baseEditor->setCodec(VcsBaseEditor::getCodec(source)); - } - - baseEditor->setForceReadOnly(true); - return baseEditor; -} - void VcsBaseClient::statusParser(const QString &text) { QList<VcsBaseClient::StatusItem> lineInfoList; @@ -646,8 +650,9 @@ void VcsBaseClient::statusParser(const QString &text) emit parsedStatus(lineInfoList); } -void VcsBaseClient::annotateRevision(const QString &workingDirectory, const QString &file, - const QString& change, int lineNumber) +void VcsBaseClient::annotateRevisionRequested(const QString &workingDirectory, + const QString &file, const QString &change, + int line) { QString changeCopy = change; // This might be invoked with a verbose revision description @@ -655,7 +660,7 @@ void VcsBaseClient::annotateRevision(const QString &workingDirectory, const QSt const int blankPos = changeCopy.indexOf(QLatin1Char(' ')); if (blankPos != -1) changeCopy.truncate(blankPos); - annotate(workingDirectory, file, changeCopy, lineNumber); + annotate(workingDirectory, file, changeCopy, line); } } // namespace VcsBase diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index d176e926768f51cc738d30fdb6b3feeec7d8e219..e9de7fa20176b754184cd034f6d6809c5c629ec1 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -81,6 +81,11 @@ public: VcsWindowOutputBind }; + VcsBaseEditorWidget *createVcsEditor(Core::Id kind, QString title, + const QString &source, QTextCodec *codec, + const char *registerDynamicProperty, + const QString &dynamicPropertyValue) const; + VcsCommand *createCommand(const QString &workingDirectory, VcsBaseEditorWidget *editor = 0, JobOutputBindMode mode = NoOutputBind) const; @@ -92,6 +97,8 @@ public: protected: void resetCachedVcsInfo(const QString &workingDir); + virtual void annotateRevisionRequested(const QString &workingDirectory, const QString &file, + const QString &change, int line) = 0; private: void saveSettings(); @@ -172,6 +179,9 @@ public slots: const QStringList &extraOptions = QStringList()); protected: + void annotateRevisionRequested(const QString &workingDirectory, const QString &file, + const QString &change, int line); + enum VcsCommandTag { CreateRepositoryCommand, @@ -212,14 +222,9 @@ protected: const QStringList &args, unsigned flags = 0, QTextCodec *outputCodec = 0) const; - VcsBaseEditorWidget *createVcsEditor(Core::Id kind, QString title, - const QString &source, bool setSourceCodec, - const char *registerDynamicProperty, - const QString &dynamicPropertyValue) const; private: void statusParser(const QString&); - void annotateRevision(const QString&, const QString&, const QString&, int); friend class VcsBaseClientPrivate; VcsBaseClientPrivate *d;