Commit 73cf43f3 authored by jkobus's avatar jkobus Committed by Jarek Kobus

Add DiffEditorManager, refactoring.

GitDiffSwitcher operates now on IDocument.
GitDiffHandler operates now on DiffEditorController.
"source" property now attached to editor's document (VcsBasePlugin).

Change-Id: Ie2570a597b8b992ac1dc33b9179eca459c8a751a
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
Reviewed-by: default avatarJarek Kobus <jaroslaw.kobus@digia.com>
parent 84e8a79c
......@@ -118,7 +118,7 @@ void DescriptionEditorWidget::setDisplaySettings(const DisplaySettings &ds)
DiffEditor::DiffEditor()
: IEditor(0)
, m_document(new Internal::DiffEditorDocument(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE)))
, m_document(new DiffEditorDocument(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE)))
, m_descriptionWidget(0)
, m_diffWidget(0)
, m_diffEditorController(0)
......@@ -163,9 +163,13 @@ void DiffEditor::ctor()
m_descriptionWidget->setCodeStyle(TextEditorSettings::codeStyle());
m_descriptionWidget->baseTextDocument()->setFontSettings(TextEditorSettings::fontSettings());
m_diffEditorController = m_document->diffEditorController();
m_diffEditorController = m_document->controller();
m_diffWidget->setDiffEditorController(m_diffEditorController);
connect(m_diffEditorController, SIGNAL(cleared(QString)),
this, SLOT(slotCleared(QString)));
connect(m_diffEditorController, SIGNAL(diffContentsChanged(QList<DiffEditorController::DiffFilesContents>,QString)),
this, SLOT(slotDiffContentsChanged(QList<DiffEditorController::DiffFilesContents>,QString)));
connect(m_diffEditorController, SIGNAL(currentDiffFileIndexChanged(int)),
this, SLOT(activateEntry(int)));
connect(m_diffEditorController, SIGNAL(descriptionChanged(QString)),
......@@ -209,11 +213,6 @@ Core::Id DiffEditor::id() const
return Constants::DIFF_EDITOR_ID;
}
QTextCodec *DiffEditor::codec() const
{
return m_diffWidget->codec();
}
static QToolBar *createToolBar(const QWidget *someWidget)
{
// Create
......@@ -275,24 +274,50 @@ QWidget *DiffEditor::toolBar()
m_toggleDescriptionAction = m_toolBar->addWidget(toggleDescription);
slotDescriptionVisibilityChanged();
if (m_diffEditorController) {
connect(whitespaceButton, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setIgnoreWhitespaces(bool)));
connect(contextSpinBox, SIGNAL(valueChanged(int)),
m_diffEditorController, SLOT(setContextLinesNumber(int)));
connect(toggleSync, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setHorizontalScrollBarSynchronization(bool)));
connect(toggleDescription, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setDescriptionVisible(bool)));
// TODO: synchronize in opposite direction too
}
connect(whitespaceButton, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setIgnoreWhitespaces(bool)));
connect(contextSpinBox, SIGNAL(valueChanged(int)),
m_diffEditorController, SLOT(setContextLinesNumber(int)));
connect(toggleSync, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setHorizontalScrollBarSynchronization(bool)));
connect(toggleDescription, SIGNAL(clicked(bool)),
m_diffEditorController, SLOT(setDescriptionVisible(bool)));
// TODO: synchronize in opposite direction too
return m_toolBar;
}
void DiffEditor::setDiff(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory)
DiffEditorController * DiffEditor::controller() const
{
return m_diffEditorController;
}
void DiffEditor::updateEntryToolTip()
{
const QString &toolTip = m_entriesComboBox->itemData(
m_entriesComboBox->currentIndex(), Qt::ToolTipRole).toString();
m_entriesComboBox->setToolTip(toolTip);
}
void DiffEditor::entryActivated(int index)
{
updateEntryToolTip();
m_diffEditorController->setCurrentDiffFileIndex(index);
}
void DiffEditor::slotCleared(const QString &message)
{
Q_UNUSED(message)
m_entriesComboBox->clear();
updateEntryToolTip();
}
void DiffEditor::slotDiffContentsChanged(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory)
{
Q_UNUSED(workingDirectory)
m_entriesComboBox->clear();
const int count = diffFileList.count();
for (int i = 0; i < count; i++) {
......@@ -331,42 +356,6 @@ void DiffEditor::setDiff(const QList<DiffEditorController::DiffFilesContents> &d
m_entriesComboBox->setItemData(m_entriesComboBox->count() - 1, itemToolTip, Qt::ToolTipRole);
}
updateEntryToolTip();
if (m_diffEditorController)
m_diffEditorController->setDiffContents(diffFileList, workingDirectory);
}
void DiffEditor::setDescription(const QString &description)
{
if (m_diffEditorController)
m_diffEditorController->setDescription(description);
}
void DiffEditor::setDescriptionEnabled(bool on)
{
if (m_diffEditorController)
m_diffEditorController->setDescriptionEnabled(on);
}
void DiffEditor::clear(const QString &message)
{
m_entriesComboBox->clear();
updateEntryToolTip();
if (m_diffEditorController)
m_diffEditorController->clear(message);
}
void DiffEditor::updateEntryToolTip()
{
const QString &toolTip = m_entriesComboBox->itemData(
m_entriesComboBox->currentIndex(), Qt::ToolTipRole).toString();
m_entriesComboBox->setToolTip(toolTip);
}
void DiffEditor::entryActivated(int index)
{
updateEntryToolTip();
if (m_diffEditorController)
m_diffEditorController->setCurrentDiffFileIndex(index);
}
void DiffEditor::activateEntry(int index)
......@@ -384,9 +373,6 @@ void DiffEditor::slotDescriptionChanged(const QString &description)
void DiffEditor::slotDescriptionVisibilityChanged()
{
if (!m_diffEditorController)
return;
const bool visible = m_diffEditorController->isDescriptionVisible();
const bool enabled = m_diffEditorController->isDescriptionEnabled();
......
......@@ -45,9 +45,9 @@ QT_END_NAMESPACE
namespace TextEditor { class BaseTextEditorWidget; }
namespace DiffEditor {
class SideBySideDiffEditorWidget;
namespace Internal { class DiffEditorDocument; }
class DiffEditorDocument;
class SideBySideDiffEditorWidget;
class DIFFEDITOR_EXPORT DiffEditor : public Core::IEditor
{
......@@ -58,11 +58,7 @@ public:
virtual ~DiffEditor();
public:
void setDiff(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory = QString());
void setDescription(const QString &description);
void setDescriptionEnabled(bool on);
void clear(const QString &message);
DiffEditorController *controller() const;
// Core::IEditor
bool duplicateSupported() const { return false; }
......@@ -71,7 +67,6 @@ public:
bool open(QString *errorString, const QString &fileName, const QString &realFileName);
Core::IDocument *document();
Core::Id id() const;
QTextCodec *codec() const;
QWidget *toolBar();
......@@ -79,6 +74,9 @@ public slots:
void activateEntry(int index);
private slots:
void slotCleared(const QString &message);
void slotDiffContentsChanged(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory);
void entryActivated(int index);
void slotDescriptionChanged(const QString &description);
void slotDescriptionVisibilityChanged();
......@@ -87,7 +85,7 @@ private:
void ctor();
void updateEntryToolTip();
QSharedPointer<Internal::DiffEditorDocument> m_document;
QSharedPointer<DiffEditorDocument> m_document;
TextEditor::BaseTextEditorWidget *m_descriptionWidget;
SideBySideDiffEditorWidget *m_diffWidget;
DiffEditorController *m_diffEditorController;
......
......@@ -7,6 +7,7 @@ HEADERS += diffeditor_global.h \
diffeditorcontroller.h \
diffeditordocument.h \
diffeditorfactory.h \
diffeditormanager.h \
diffeditorplugin.h \
differ.h \
sidebysidediffeditorwidget.h
......@@ -15,6 +16,7 @@ SOURCES += diffeditor.cpp \
diffeditorcontroller.cpp \
diffeditordocument.cpp \
diffeditorfactory.cpp \
diffeditormanager.cpp \
diffeditorplugin.cpp \
differ.cpp \
sidebysidediffeditorwidget.cpp
......
......@@ -23,6 +23,8 @@ QtcPlugin {
"diffeditordocument.h",
"diffeditorfactory.cpp",
"diffeditorfactory.h",
"diffeditormanager.cpp",
"diffeditormanager.h",
"diffeditorplugin.cpp",
"diffeditorplugin.h",
"differ.cpp",
......
......@@ -110,7 +110,8 @@ void DiffEditorController::clear(const QString &message)
emit cleared(message);
}
void DiffEditorController::setDiffContents(const QList<DiffFilesContents> &diffFileList, const QString &workingDirectory)
void DiffEditorController::setDiffContents(const QList<DiffFilesContents> &diffFileList,
const QString &workingDirectory)
{
m_diffFileList = diffFileList;
m_workingDirectory = workingDirectory;
......@@ -188,8 +189,3 @@ void DiffEditorController::setCurrentDiffFileIndex(int diffFileIndex)
}
} // namespace DiffEditor
//QTextCodec *DiffEditorWidget::codec() const
//{
//}
......@@ -60,8 +60,6 @@ public:
DiffEditorController(QObject *parent = 0);
~DiffEditorController();
// QTextCodec *codec() const;
QString clearMessage() const;
QList<DiffFilesContents> diffContents() const;
......@@ -78,7 +76,8 @@ public:
public slots:
void clear();
void clear(const QString &message);
void setDiffContents(const QList<DiffEditorController::DiffFilesContents> &diffFileList, const QString &workingDirectory = QString());
void setDiffContents(const QList<DiffEditorController::DiffFilesContents> &diffFileList,
const QString &workingDirectory = QString());
void setDescription(const QString &description);
void setDescriptionEnabled(bool on);
......@@ -90,7 +89,7 @@ public slots:
signals:
// This sets the current diff file index to -1
void cleared(const QString message);
void cleared(const QString &message);
// This sets the current diff file index to 0 (unless diffFileList is empty)
void diffContentsChanged(const QList<DiffEditorController::DiffFilesContents> &diffFileList, const QString &workingDirectory);
void descriptionChanged(const QString &description);
......
......@@ -34,9 +34,6 @@
#include <QCoreApplication>
namespace DiffEditor {
namespace Internal {
///////////////////////////////// DiffFile //////////////////////////////////
DiffEditorDocument::DiffEditorDocument(const QString &mimeType) :
Core::IDocument(),
......@@ -51,7 +48,7 @@ DiffEditorDocument::~DiffEditorDocument()
{
}
DiffEditorController *DiffEditorDocument::diffEditorController() const
DiffEditorController *DiffEditorDocument::controller() const
{
return m_diffEditorController;
}
......@@ -90,5 +87,4 @@ bool DiffEditorDocument::reload(QString *errorString, ReloadFlag flag, ChangeTyp
return false;
}
} // namespace Internal
} // namespace DiffEditor
......@@ -38,16 +38,14 @@ namespace DiffEditor {
class DiffEditorController;
namespace Internal {
class DiffEditorDocument : public Core::IDocument
class DIFFEDITOR_EXPORT DiffEditorDocument : public Core::IDocument
{
Q_OBJECT
public:
explicit DiffEditorDocument(const QString &mimeType);
virtual ~DiffEditorDocument();
DiffEditorController *diffEditorController() const;
DiffEditorController *controller() const;
bool setContents(const QByteArray &contents);
QString defaultPath() const { return QString(); }
......@@ -65,7 +63,6 @@ private:
DiffEditorController *m_diffEditorController;
};
} // namespace Internal
} // namespace DiffEditor
#endif // DIFFEDITORDOCUMENT_H
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "diffeditormanager.h"
#include "diffeditor.h"
#include "diffeditorconstants.h"
#include "diffeditordocument.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/id.h>
#include <utils/qtcassert.h>
namespace DiffEditor {
static DiffEditorManager *m_instance = 0;
DiffEditorManager::DiffEditorManager(QObject *parent)
: QObject(parent)
{
QTC_ASSERT(!m_instance, return);
m_instance = this;
Core::EditorManager *editorManager = Core::EditorManager::instance();
connect(editorManager, SIGNAL(editorsClosed(QList<Core::IEditor*>)),
this, SLOT(slotEditorsClosed(QList<Core::IEditor*>)));
}
DiffEditorManager::~DiffEditorManager()
{
m_instance = 0;
}
DiffEditorManager *DiffEditorManager::instance()
{
return m_instance;
}
void DiffEditorManager::slotEditorsClosed(const QList<Core::IEditor *> &editors)
{
QMap<Core::IDocument *, int> editorsForDocument;
for (int i = 0; i < editors.count(); i++) {
DiffEditor *diffEditor = qobject_cast<DiffEditor *>(editors.at(i));
if (diffEditor) {
Core::IDocument *document = diffEditor->document();
editorsForDocument[document]++;
}
}
Core::DocumentModel *documentModel = Core::EditorManager::documentModel();
QMapIterator<Core::IDocument *, int> it(editorsForDocument);
while (it.hasNext()) {
it.next();
if (documentModel->editorsForDocument(it.key()).count() == 0) { // no other editors use that document
DiffEditorDocument *document
= qobject_cast<DiffEditorDocument *>(it.key());
if (document) {
const QString documentId = documentToId.value(document);
documentToId.remove(document);
idToDocument.remove(documentId);
}
}
}
}
DiffEditorDocument *DiffEditorManager::find(const QString &documentId)
{
return instance()->idToDocument.value(documentId);
}
DiffEditorDocument *DiffEditorManager::findOrCreate(const QString &documentId, const QString &displayName)
{
DiffEditorDocument *document = find(documentId);
if (document)
return document;
const QString msgWait = tr("Waiting for data...");
DiffEditor *diffEditor = qobject_cast<DiffEditor *>(
Core::EditorManager::openEditorWithContents(Constants::DIFF_EDITOR_ID,
0, msgWait.toUtf8()));
QTC_ASSERT(diffEditor, return 0);
document = qobject_cast<DiffEditorDocument *>(diffEditor->document());
QTC_ASSERT(diffEditor, return 0);
document->setDisplayName(displayName);
instance()->idToDocument.insert(documentId, document);
instance()->documentToId.insert(document, documentId);
return document;
}
} // namespace DiffEditor
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef DIFFEDITORMANAGER_H
#define DIFFEDITORMANAGER_H
#include "diffeditor_global.h"
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <QMap>
namespace DiffEditor {
class DiffEditorDocument;
class DIFFEDITOR_EXPORT DiffEditorManager : public QObject
{
Q_OBJECT
public:
explicit DiffEditorManager(QObject *parent);
virtual ~DiffEditorManager();
static DiffEditorManager *instance();
static DiffEditorDocument *find(const QString &documentId);
static DiffEditorDocument *findOrCreate(const QString &documentId, const QString &displayName);
private slots:
void slotEditorsClosed(const QList<Core::IEditor *> &editors);
private:
QMap<QString, DiffEditorDocument *> idToDocument;
QMap<DiffEditorDocument *, QString> documentToId;
};
} // namespace DiffEditor
#endif // DIFFEDITORMANAGER_H
......@@ -31,7 +31,7 @@
#include "diffeditor.h"
#include "diffeditorconstants.h"
#include "diffeditorfactory.h"
#include "sidebysidediffeditorwidget.h"
#include "diffeditormanager.h"
#include <QFileDialog>
#include <QTextCodec>
......@@ -74,6 +74,8 @@ bool DiffEditorPlugin::initialize(const QStringList &arguments, QString *errorMe
addAutoReleasedObject(new DiffEditorFactory(this));
new DiffEditorManager(this);
return true;
}
......@@ -107,10 +109,8 @@ void DiffEditorPlugin::diff()
Core::EditorManager::activateEditor(editor);
QTextCodec *codec = editor->codec();
const QString text1 = getFileContents(fileName1, codec);
const QString text2 = getFileContents(fileName2, codec);
const QString text1 = getFileContents(fileName1);
const QString text2 = getFileContents(fileName2);
DiffEditorController::DiffFilesContents dfc;
dfc.leftFileInfo = fileName1;
......@@ -120,14 +120,14 @@ void DiffEditorPlugin::diff()
QList<DiffEditorController::DiffFilesContents> list;
list.append(dfc);
editor->setDiff(list);
editor->controller()->setDiffContents(list);
}
QString DiffEditorPlugin::getFileContents(const QString &fileName, QTextCodec *codec) const
QString DiffEditorPlugin::getFileContents(const QString &fileName) const
{
QFile file(fileName);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
return codec->toUnicode(file.readAll());
return Core::EditorManager::defaultTextCodec()->toUnicode(file.readAll());
return QString();
}
......@@ -136,6 +136,8 @@ QString DiffEditorPlugin::getFileContents(const QString &fileName, QTextCodec *c
#ifdef WITH_TESTS
#include "sidebysidediffeditorwidget.h"
void DiffEditor::Internal::DiffEditorPlugin::testAssemblyRows()
{
SideBySideDiffEditorWidget::testAssemblyRows();
......
......@@ -58,7 +58,7 @@ private slots:
#endif // WITH_TESTS
private:
QString getFileContents(const QString &fileName, QTextCodec *codec) const;
QString getFileContents(const QString &fileName) const;
};
......
......@@ -405,11 +405,6 @@ public:
SideDiffEditorWidget(QWidget *parent = 0);
// TODO: remove me, codec should be taken from somewhere else
QTextCodec *codec() const {
return const_cast<QTextCodec *>(baseTextDocument()->codec());
}
// block number, file info
QMap<int, DiffEditorController::DiffFileInfo> fileInfo() const { return m_fileInfo; }
......@@ -1175,11 +1170,6 @@ void SideBySideDiffEditorWidget::setCurrentDiffFileIndex(int diffFileIndex)
m_rightEditor->centerCursor();
}
QTextCodec *SideBySideDiffEditorWidget::codec() const
{
return const_cast<QTextCodec *>(m_leftEditor->codec());
}
FileData SideBySideDiffEditorWidget::calculateContextData(const ChunkData &originalData) const
{
const int contextLinesNumber = m_controller ? m_controller->contextLinesNumber() : 3;
......
......@@ -36,15 +36,10 @@
#include <QTextEdit>
namespace TextEditor {
class BaseTextEditorWidget;
class FontSettings;
}
namespace TextEditor { class FontSettings; }
QT_BEGIN_NAMESPACE
class QPlainTextEdit;
class QSplitter;
class QSyntaxHighlighter;
class QTextCharFormat;
QT_END_NAMESPACE
......@@ -53,7 +48,6 @@ QT_END_NAMESPACE
namespace DiffEditor {
class SideDiffEditorWidget;
class TextLineData;
class ChunkData;
class FileData;
......@@ -67,8 +61,6 @@ public:
void setDiffEditorController(DiffEditorController *controller);
DiffEditorController *diffEditorController() const;
QTextCodec *codec() const;
#ifdef WITH_TESTS
static void testAssemblyRows();