Commit 9774f117 authored by Jaroslaw Kobus's avatar Jaroslaw Kobus
Browse files

Support diff a file from project explorer against the current file



Task-number: QTCREATORBUG-9432
Change-Id: Ie370bbffdb67dac520f392a73c1358f887157806
Reviewed-by: default avatarAndré Hartmann <aha_1980@gmx.de>
Reviewed-by: Orgad Shaneh's avatarOrgad Shaneh <orgads@gmail.com>
Reviewed-by: Tobias Hunger's avatarTobias Hunger <tobias.hunger@qt.io>
parent ecacea18
......@@ -37,6 +37,7 @@ class CORE_EXPORT DiffService
public:
virtual ~DiffService() {}
virtual void diffFiles(const QString &leftFileName, const QString &rightFileName) = 0;
virtual void diffModifiedFiles(const QStringList &fileNames) = 0;
};
......
......@@ -426,6 +426,22 @@ DiffEditorServiceImpl::DiffEditorServiceImpl(QObject *parent) :
{
}
void DiffEditorServiceImpl::diffFiles(const QString &leftFileName, const QString &rightFileName)
{
const QString documentId = Constants::DIFF_EDITOR_PLUGIN
+ QLatin1String(".DiffFiles.") + leftFileName + QLatin1Char('.') + rightFileName;
const QString title = tr("Diff Files");
auto const document = qobject_cast<DiffEditorDocument *>(
DiffEditorController::findOrCreateDocument(documentId, title));
if (!document)
return;
if (!DiffEditorController::controller(document))
new DiffExternalFilesController(document, leftFileName, rightFileName);
EditorManager::activateEditorForDocument(document);
document->reload();
}
void DiffEditorServiceImpl::diffModifiedFiles(const QStringList &fileNames)
{
const QString documentId = Constants::DIFF_EDITOR_PLUGIN
......
......@@ -44,6 +44,7 @@ class DiffEditorServiceImpl : public QObject, public Core::DiffService
public:
explicit DiffEditorServiceImpl(QObject *parent = nullptr);
void diffFiles(const QString &leftFileName, const QString &rightFileName) override;
void diffModifiedFiles(const QStringList &fileNames) override;
};
......
......@@ -115,7 +115,10 @@
#include <coreplugin/iversioncontrol.h>
#include <coreplugin/fileutils.h>
#include <coreplugin/removefiledialog.h>
#include <coreplugin/diffservice.h>
#include <texteditor/findinfiles.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditorconstants.h>
#include <ssh/sshconnection.h>
#include <utils/algorithm.h>
......@@ -211,6 +214,7 @@ const char REMOVEFILE[] = "ProjectExplorer.RemoveFile";
const char DUPLICATEFILE[] = "ProjectExplorer.DuplicateFile";
const char DELETEFILE[] = "ProjectExplorer.DeleteFile";
const char RENAMEFILE[] = "ProjectExplorer.RenameFile";
const char DIFFFILE[] = "ProjectExplorer.DiffFile";
const char SETSTARTUP[] = "ProjectExplorer.SetStartup";
const char PROJECTTREE_COLLAPSE_ALL[] = "ProjectExplorer.CollapseAll";
......@@ -255,6 +259,17 @@ static Kit *currentKit()
return target ? target->kit() : nullptr;
}
static bool isTextFile(const QString &fileName)
{
return Utils::mimeTypeForFile(fileName).inherits(
TextEditor::Constants::C_TEXTEDITOR_MIMETYPE_TEXT);
}
static bool isDiffServiceAvailable()
{
return ExtensionSystem::PluginManager::getObject<DiffService>();
}
class ProjectExplorerPluginPrivate : public QObject
{
Q_DECLARE_TR_FUNCTIONS(ProjectExplorer::ProjectExplorerPlugin)
......@@ -303,6 +318,7 @@ public:
void duplicateFile();
void deleteFile();
void handleRenameFile();
void handleDiffFile();
void handleSetStartupProject();
void setStartupProject(ProjectExplorer::Project *project);
......@@ -375,6 +391,7 @@ public:
QAction *m_removeProjectAction;
QAction *m_deleteFileAction;
QAction *m_renameFileAction;
QAction *m_diffFileAction;
QAction *m_openFileAction;
QAction *m_projectTreeCollapseAllAction;
QAction *m_searchOnFileSystem;
......@@ -1063,6 +1080,12 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
cmd = ActionManager::registerAction(dd->m_renameFileAction, Constants::RENAMEFILE,
projecTreeContext);
mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
// diff file action
dd->m_diffFileAction = new QAction(tr("Diff Against Current File"), this);
cmd = ActionManager::registerAction(dd->m_diffFileAction, Constants::DIFFFILE, projecTreeContext);
mfileContextMenu->addAction(cmd, Constants::G_FILE_OTHER);
// Not yet used by anyone, so hide for now
// mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
// msubProject->addAction(cmd, Constants::G_FOLDER_FILES);
......@@ -1302,6 +1325,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
dd, &ProjectExplorerPluginPrivate::deleteFile);
connect(dd->m_renameFileAction, &QAction::triggered,
dd, &ProjectExplorerPluginPrivate::handleRenameFile);
connect(dd->m_diffFileAction, &QAction::triggered,
dd, &ProjectExplorerPluginPrivate::handleDiffFile);
connect(dd->m_setStartupProjectAction, &QAction::triggered,
dd, &ProjectExplorerPluginPrivate::handleSetStartupProject);
connect(dd->m_projectTreeCollapseAllAction, &QAction::triggered,
......@@ -2889,6 +2914,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
m_duplicateFileAction->setEnabled(false);
m_deleteFileAction->setEnabled(false);
m_renameFileAction->setEnabled(false);
m_diffFileAction->setEnabled(false);
m_addExistingFilesAction->setVisible(true);
m_addExistingDirectoryAction->setVisible(true);
......@@ -2899,6 +2925,7 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
m_duplicateFileAction->setVisible(false);
m_deleteFileAction->setVisible(true);
m_runActionContextMenu->setVisible(false);
m_diffFileAction->setVisible(isDiffServiceAvailable());
m_openTerminalHere->setVisible(true);
m_showInGraphicalShell->setVisible(true);
......@@ -2966,6 +2993,10 @@ void ProjectExplorerPluginPrivate::updateContextMenuActions()
m_removeFileAction->setVisible(!enableDelete || enableRemove);
m_renameFileAction->setEnabled(actions.contains(Rename));
const bool currentNodeIsTextFile = isTextFile(
ProjectTree::currentNode()->filePath().toString());
m_diffFileAction->setEnabled(isDiffServiceAvailable()
&& currentNodeIsTextFile && TextEditor::TextDocument::currentTextDocument());
m_duplicateFileAction->setVisible(actions.contains(DuplicateFile));
m_duplicateFileAction->setEnabled(actions.contains(DuplicateFile));
......@@ -3249,6 +3280,39 @@ void ProjectExplorerPluginPrivate::handleRenameFile()
}
}
void ProjectExplorerPluginPrivate::handleDiffFile()
{
// current editor's file
auto textDocument = TextEditor::TextDocument::currentTextDocument();
if (!textDocument)
return;
const QString leftFileName = textDocument->filePath().toString();
if (leftFileName.isEmpty())
return;
// current item's file
Node *currentNode = ProjectTree::currentNode();
QTC_ASSERT(currentNode && currentNode->nodeType() == NodeType::File, return);
FileNode *fileNode = currentNode->asFileNode();
if (!fileNode)
return;
const QString rightFileName = currentNode->filePath().toString();
if (rightFileName.isEmpty())
return;
if (!isTextFile(rightFileName))
return;
if (auto diffService = ExtensionSystem::PluginManager::getObject<DiffService>())
diffService->diffFiles(leftFileName, rightFileName);
}
void ProjectExplorerPlugin::renameFile(Node *node, const QString &newFilePath)
{
const QString oldFilePath = node->filePath().toFileInfo().absoluteFilePath();
......
......@@ -291,6 +291,11 @@ QMap<QString, QTextCodec *> TextDocument::openedTextDocumentEncodings()
return workingCopy;
}
TextDocument *TextDocument::currentTextDocument()
{
return qobject_cast<TextDocument *>(EditorManager::currentDocument());
}
QString TextDocument::plainText() const
{
return document()->toPlainText();
......
......@@ -65,6 +65,7 @@ public:
static QMap<QString, QString> openedTextDocumentContents();
static QMap<QString, QTextCodec *> openedTextDocumentEncodings();
static TextDocument *currentTextDocument();
virtual QString plainText() const;
virtual QString textAt(int pos, int length) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment