diff options
author | jkobus <jaroslaw.kobus@digia.com> | 2013-05-07 14:02:08 +0200 |
---|---|---|
committer | Tobias Hunger <tobias.hunger@digia.com> | 2013-05-15 16:24:38 +0200 |
commit | 97a86c50dc00551818e9fcef37908ef7ebfb242b (patch) | |
tree | c6b064ca42e9f3a98987337730eaf8f678df082d /src/plugins/diffeditor | |
parent | 60b1aaeae482ac8f9b74aa74d4a2053e47ee81be (diff) | |
download | qt-creator-97a86c50dc00551818e9fcef37908ef7ebfb242b.tar.gz |
Basic integration of diff editor inside git plugin
Change-Id: I7675fc1d994020f94f42f6bd7b4f75aa29e6edf6
Reviewed-by: David Schulz <david.schulz@digia.com>
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
Diffstat (limited to 'src/plugins/diffeditor')
-rw-r--r-- | src/plugins/diffeditor/diffeditor.pro | 12 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditor.qbs | 12 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditoreditable.cpp | 162 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditoreditable.h | 82 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditorfile.cpp | 96 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditorfile.h | 78 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditorplugin.cpp | 202 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditorplugin.h | 74 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditorwidget.cpp | 160 | ||||
-rw-r--r-- | src/plugins/diffeditor/diffeditorwidget.h | 66 |
10 files changed, 575 insertions, 369 deletions
diff --git a/src/plugins/diffeditor/diffeditor.pro b/src/plugins/diffeditor/diffeditor.pro index 9e36bdbf77..2d6b13fc23 100644 --- a/src/plugins/diffeditor/diffeditor.pro +++ b/src/plugins/diffeditor/diffeditor.pro @@ -1,13 +1,17 @@ DEFINES += DIFFEDITOR_LIBRARY include(../../qtcreatorplugin.pri) -HEADERS += diffeditorplugin.h \ - diffeditorwidget.h \ +HEADERS += diffeditor_global.h \ diffeditorconstants.h \ - diffeditor_global.h \ + diffeditoreditable.h \ + diffeditorfile.h \ + diffeditorplugin.h \ + diffeditorwidget.h \ differ.h -SOURCES += diffeditorplugin.cpp \ +SOURCES += diffeditoreditable.cpp \ + diffeditorfile.cpp \ + diffeditorplugin.cpp \ diffeditorwidget.cpp \ differ.cpp diff --git a/src/plugins/diffeditor/diffeditor.qbs b/src/plugins/diffeditor/diffeditor.qbs index 568321d149..6d472cbc75 100644 --- a/src/plugins/diffeditor/diffeditor.qbs +++ b/src/plugins/diffeditor/diffeditor.qbs @@ -13,14 +13,18 @@ QtcPlugin { Depends { name: "cpp" } files: [ + "diffeditor_global.h", + "diffeditorconstants.h", + "diffeditoreditable.cpp", + "diffeditoreditable.h", + "diffeditorfile.cpp", + "diffeditorfile.h", "diffeditorplugin.cpp", "diffeditorplugin.h", - "differ.cpp", - "differ.h", "diffeditorwidget.cpp", "diffeditorwidget.h", - "diffeditorconstants.h", - "diffeditor_global.h", + "differ.cpp", + "differ.h", ] } diff --git a/src/plugins/diffeditor/diffeditoreditable.cpp b/src/plugins/diffeditor/diffeditoreditable.cpp new file mode 100644 index 0000000000..9f2c9e1a8a --- /dev/null +++ b/src/plugins/diffeditor/diffeditoreditable.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 "diffeditoreditable.h" +#include "diffeditorfile.h" +#include "diffeditorwidget.h" +#include "diffeditorconstants.h" + +#include <coreplugin/icore.h> +#include <QCoreApplication> +#include <QToolButton> +#include <QSpinBox> +#include <QStyle> +#include <QLabel> + +namespace DiffEditor { + +///////////////////////////////// DiffEditorEditable ////////////////////////////////// + +DiffEditorEditable::DiffEditorEditable(DiffEditorWidget *editorWidget) + : IEditor(0), + m_file(new Internal::DiffEditorFile(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE), this)), + m_editorWidget(editorWidget), + m_toolWidget(0) +{ + setWidget(editorWidget); +} + +DiffEditorEditable::~DiffEditorEditable() +{ + delete m_toolWidget; + if (m_widget) + delete m_widget; +} + +bool DiffEditorEditable::createNew(const QString &contents) +{ + Q_UNUSED(contents) + return true; +} + +bool DiffEditorEditable::open(QString *errorString, const QString &fileName, const QString &realFileName) +{ + Q_UNUSED(errorString) + Q_UNUSED(fileName) + Q_UNUSED(realFileName) + return true; +} + +Core::IDocument *DiffEditorEditable::document() +{ + return m_file; +} + +QString DiffEditorEditable::displayName() const +{ + if (m_displayName.isEmpty()) + m_displayName = QCoreApplication::translate("DiffEditor", Constants::DIFF_EDITOR_DISPLAY_NAME); + return m_displayName; +} + +void DiffEditorEditable::setDisplayName(const QString &title) +{ + m_displayName = title; + emit changed(); +} + +bool DiffEditorEditable::duplicateSupported() const +{ + return false; +} + +Core::IEditor *DiffEditorEditable::duplicate(QWidget *parent) +{ + Q_UNUSED(parent) + return 0; +} + +Core::Id DiffEditorEditable::id() const +{ + return Constants::DIFF_EDITOR_ID; +} + +static QToolBar *createToolBar(const QWidget *someWidget) +{ + // Create + QToolBar *toolBar = new QToolBar; + toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + const int size = someWidget->style()->pixelMetric(QStyle::PM_SmallIconSize); + toolBar->setIconSize(QSize(size, size)); + toolBar->addSeparator(); + + return toolBar; +} + +QWidget *DiffEditorEditable::toolBar() +{ + if (m_toolWidget) + return m_toolWidget; + + // Create + m_toolWidget = createToolBar(m_editorWidget); + + QToolButton *whitespaceButton = new QToolButton(m_toolWidget); + whitespaceButton->setText(tr("Ignore Whitespaces")); + whitespaceButton->setCheckable(true); + whitespaceButton->setChecked(true); + connect(whitespaceButton, SIGNAL(clicked(bool)), + m_editorWidget, SLOT(setIgnoreWhitespaces(bool))); + m_toolWidget->addWidget(whitespaceButton); + + QLabel *contextLabel = new QLabel(tr("Context Lines:"), m_toolWidget); + m_toolWidget->addWidget(contextLabel); + + QSpinBox *contextSpinBox = new QSpinBox(m_toolWidget); + contextSpinBox->setRange(-1, 100); + contextSpinBox->setValue(3); + connect(contextSpinBox, SIGNAL(valueChanged(int)), + m_editorWidget, SLOT(setContextLinesNumber(int))); + m_toolWidget->addWidget(contextSpinBox); + + return m_toolWidget; +} + +QByteArray DiffEditorEditable::saveState() const +{ + return QByteArray(); +} + +bool DiffEditorEditable::restoreState(const QByteArray &state) +{ + Q_UNUSED(state) + return true; +} + +} // namespace DiffEditor diff --git a/src/plugins/diffeditor/diffeditoreditable.h b/src/plugins/diffeditor/diffeditoreditable.h new file mode 100644 index 0000000000..8047fce312 --- /dev/null +++ b/src/plugins/diffeditor/diffeditoreditable.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 DIFFEDITOREDITABLE_H +#define DIFFEDITOREDITABLE_H + +#include "diffeditor_global.h" + +#include <coreplugin/editormanager/ieditor.h> +#include <coreplugin/idocument.h> + +#include <QToolBar> + +namespace DiffEditor { + +class DiffEditorWidget; + +namespace Internal { +class DiffEditorFile; +} + +class DIFFEDITOR_EXPORT DiffEditorEditable : public Core::IEditor +{ + Q_OBJECT +public: + explicit DiffEditorEditable(DiffEditorWidget *editorWidget); + virtual ~DiffEditorEditable(); + +public: + // Core::IEditor + bool createNew(const QString &contents); + bool open(QString *errorString, const QString &fileName, const QString &realFileName); + Core::IDocument *document(); + QString displayName() const; + void setDisplayName(const QString &title); + bool duplicateSupported() const; + Core::IEditor *duplicate(QWidget *parent); + Core::Id id() const; + bool isTemporary() const { return true; } + DiffEditorWidget *editorWidget() const { return m_editorWidget; } + + QWidget *toolBar(); + + QByteArray saveState() const; + bool restoreState(const QByteArray &state); + +private: + Internal::DiffEditorFile *m_file; + DiffEditorWidget *m_editorWidget; + QToolBar *m_toolWidget; + mutable QString m_displayName; +}; + +} // namespace DiffEditor + +#endif // DIFFEDITOREDITABLE_H diff --git a/src/plugins/diffeditor/diffeditorfile.cpp b/src/plugins/diffeditor/diffeditorfile.cpp new file mode 100644 index 0000000000..ede0392bd2 --- /dev/null +++ b/src/plugins/diffeditor/diffeditorfile.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 "diffeditorfile.h" + +namespace DiffEditor { +namespace Internal { + +///////////////////////////////// DiffFile ////////////////////////////////// + +DiffEditorFile::DiffEditorFile(const QString &mimeType, QObject *parent) : + Core::IDocument(parent), + m_mimeType(mimeType), + m_modified(false) +{ +} + +void DiffEditorFile::rename(const QString &newName) +{ + Q_UNUSED(newName); + return; +} + +void DiffEditorFile::setFileName(const QString &name) +{ + if (m_fileName == name) + return; + m_fileName = name; + emit changed(); +} + +void DiffEditorFile::setModified(bool modified) +{ + if (m_modified == modified) + return; + m_modified = modified; + emit changed(); +} + +bool DiffEditorFile::save(QString *errorString, const QString &fileName, bool autoSave) +{ + emit saveMe(errorString, fileName, autoSave); + if (!errorString->isEmpty()) + return false; + emit changed(); + return true; +} + +QString DiffEditorFile::mimeType() const +{ + return m_mimeType; +} + +Core::IDocument::ReloadBehavior DiffEditorFile::reloadBehavior(ChangeTrigger state, ChangeType type) const +{ + Q_UNUSED(state) + Q_UNUSED(type) + return BehaviorSilent; +} + +bool DiffEditorFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) +{ + Q_UNUSED(errorString) + Q_UNUSED(flag) + Q_UNUSED(type) + return true; +} + +} // namespace Internal +} // namespace DiffEditor diff --git a/src/plugins/diffeditor/diffeditorfile.h b/src/plugins/diffeditor/diffeditorfile.h new file mode 100644 index 0000000000..4a45fb4aa5 --- /dev/null +++ b/src/plugins/diffeditor/diffeditorfile.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2013 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 DIFFEDITORFILE_H +#define DIFFEDITORFILE_H + +#include "diffeditor_global.h" + +#include <coreplugin/idocument.h> + +namespace DiffEditor { + +class DiffEditorWidget; +class DiffEditorFile; + +namespace Internal { + +class DiffEditorFile : public Core::IDocument +{ + Q_OBJECT +public: + explicit DiffEditorFile(const QString &mimeType, + QObject *parent = 0); + + QString fileName() const { return m_fileName; } + QString defaultPath() const { return QString(); } + QString suggestedFileName() const { return QString(); } + + bool isModified() const { return m_modified; } + QString mimeType() const; + bool isSaveAsAllowed() const { return false; } + bool save(QString *errorString, const QString &fileName, bool autoSave); + ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const; + bool reload(QString *errorString, ReloadFlag flag, ChangeType type); + void rename(const QString &newName); + + void setFileName(const QString &name); + void setModified(bool modified = true); + +signals: + void saveMe(QString *errorString, const QString &fileName, bool autoSave); + +private: + const QString m_mimeType; + bool m_modified; + QString m_fileName; +}; + +} // namespace Internal +} // namespace DiffEditor + +#endif // DIFFEDITOREDITABLE_H diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 30fa36ca83..a4a1429539 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -28,17 +28,14 @@ ****************************************************************************/ #include "diffeditorplugin.h" +#include "diffeditoreditable.h" #include "diffeditorwidget.h" #include "diffeditorconstants.h" -#include <coreplugin/icore.h> #include <QCoreApplication> -#include <QToolButton> -#include <QSpinBox> -#include <QStyle> -#include <QLabel> #include <QFileDialog> #include <QTextCodec> +#include <QtPlugin> #include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actionmanager.h> @@ -46,195 +43,14 @@ #include <coreplugin/editormanager/editormanager.h> namespace DiffEditor { -namespace Internal { - -///////////////////////////////// DiffEditor ////////////////////////////////// - -DiffEditorEditable::DiffEditorEditable(DiffEditorWidget *editorWidget) - : - IEditor(0), - m_file(new DiffFile(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE), this)), - m_editorWidget(editorWidget), - m_toolWidget(0) -{ - setWidget(editorWidget); -} - -DiffEditorEditable::~DiffEditorEditable() -{ - delete m_toolWidget; - if (m_widget) - delete m_widget; -} - -bool DiffEditorEditable::createNew(const QString &contents) -{ - Q_UNUSED(contents) -// setFileContents(contents); - return true; -} - -bool DiffEditorEditable::open(QString *errorString, const QString &fileName, const QString &realFileName) -{ - Q_UNUSED(errorString) - Q_UNUSED(fileName) - Q_UNUSED(realFileName) - const QString text = QLatin1String("Open"); - if (!createNew(text)) - return false; - - return true; -} - -Core::IDocument *DiffEditorEditable::document() -{ - return m_file; -} - -QString DiffEditorEditable::displayName() const -{ - if (m_displayName.isEmpty()) - m_displayName = QCoreApplication::translate("DiffEditor", Constants::DIFF_EDITOR_DISPLAY_NAME); - return m_displayName; -} - -void DiffEditorEditable::setDisplayName(const QString &title) -{ - m_displayName = title; - emit changed(); -} - -bool DiffEditorEditable::duplicateSupported() const -{ - return false; -} - -Core::IEditor *DiffEditorEditable::duplicate(QWidget * /*parent*/) -{ - return 0; -} - -Core::Id DiffEditorEditable::id() const -{ - return Constants::DIFF_EDITOR_ID; -} - -static QToolBar *createToolBar(const QWidget *someWidget) -{ - // Create - QToolBar *toolBar = new QToolBar; - toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - const int size = someWidget->style()->pixelMetric(QStyle::PM_SmallIconSize); - toolBar->setIconSize(QSize(size, size)); - toolBar->addSeparator(); - - return toolBar; -} - -QWidget *DiffEditorEditable::toolBar() -{ - if (m_toolWidget) - return m_toolWidget; - - // Create - m_toolWidget = createToolBar(m_editorWidget); - - QToolButton *whitespaceButton = new QToolButton(m_toolWidget); - whitespaceButton->setText(tr("Ignore Whitespaces")); - whitespaceButton->setCheckable(true); - whitespaceButton->setChecked(true); - connect(whitespaceButton, SIGNAL(clicked(bool)), - m_editorWidget, SLOT(setIgnoreWhitespaces(bool))); - m_toolWidget->addWidget(whitespaceButton); - - QLabel *contextLabel = new QLabel(tr("Context Lines:"), m_toolWidget); - m_toolWidget->addWidget(contextLabel); - - QSpinBox *contextSpinBox = new QSpinBox(m_toolWidget); - contextSpinBox->setRange(-1, 100); - contextSpinBox->setValue(1); - connect(contextSpinBox, SIGNAL(valueChanged(int)), - m_editorWidget, SLOT(setContextLinesNumber(int))); - m_toolWidget->addWidget(contextSpinBox); - - return m_toolWidget; -} - -QByteArray DiffEditorEditable::saveState() const -{ - return QByteArray(); -} - -bool DiffEditorEditable::restoreState(const QByteArray &/*state*/) -{ - return true; -} - -///////////////////////////////// DiffFile ////////////////////////////////// - -DiffFile::DiffFile(const QString &mimeType, QObject *parent) : - Core::IDocument(parent), - m_mimeType(mimeType), - m_modified(false) -{ -} - -void DiffFile::rename(const QString &newName) -{ - Q_UNUSED(newName); - return; -} - -void DiffFile::setFileName(const QString &name) -{ - if (m_fileName == name) - return; - m_fileName = name; - emit changed(); -} - -void DiffFile::setModified(bool modified) -{ - if (m_modified == modified) - return; - m_modified = modified; - emit changed(); -} - -bool DiffFile::save(QString *errorString, const QString &fileName, bool autoSave) -{ - emit saveMe(errorString, fileName, autoSave); - if (!errorString->isEmpty()) - return false; - emit changed(); - return true; -} - -QString DiffFile::mimeType() const -{ - return m_mimeType; -} - -Core::IDocument::ReloadBehavior DiffFile::reloadBehavior(ChangeTrigger state, ChangeType type) const -{ - Q_UNUSED(state) - Q_UNUSED(type) - return BehaviorSilent; -} - -bool DiffFile::reload(QString *errorString, ReloadFlag flag, ChangeType type) -{ - Q_UNUSED(errorString) - Q_UNUSED(flag) - Q_UNUSED(type) - return true; -} ///////////////////////////////// DiffEditorFactory ////////////////////////////////// -DiffEditorFactory::DiffEditorFactory(DiffEditorPlugin *owner) : - m_mimeTypes(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE)), - m_owner(owner) +namespace Internal { + +DiffEditorFactory::DiffEditorFactory(DiffEditorPlugin *owner) + : m_mimeTypes(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE)), + m_owner(owner) { } @@ -329,9 +145,9 @@ void DiffEditorPlugin::diff() const QString text2 = getFileContents(fileName2, editorWidget->codec()); DiffEditorWidget::DiffFilesContents dfc; - dfc.leftFileName = fileName1; + dfc.leftFileInfo = fileName1; dfc.leftText = text1; - dfc.rightFileName = fileName2; + dfc.rightFileInfo = fileName2; dfc.rightText = text2; QList<DiffEditorWidget::DiffFilesContents> list; list.append(dfc); diff --git a/src/plugins/diffeditor/diffeditorplugin.h b/src/plugins/diffeditor/diffeditorplugin.h index cc0de258fd..39b6e4bf51 100644 --- a/src/plugins/diffeditor/diffeditorplugin.h +++ b/src/plugins/diffeditor/diffeditorplugin.h @@ -30,86 +30,22 @@ #ifndef DIFFEDITORPLUGIN_H #define DIFFEDITORPLUGIN_H +#include "diffeditor_global.h" + #include <extensionsystem/iplugin.h> #include <coreplugin/editormanager/ieditorfactory.h> -#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/icontext.h> #include <coreplugin/idocument.h> -#include <QtPlugin> -#include <QPointer> #include <QStringList> -#include <QAction> -#include <QToolBar> + +namespace Core { class IEditor; } namespace DiffEditor { + class DiffEditorWidget; namespace Internal { -class DiffFile; - -class DiffEditorEditable : public Core::IEditor -{ - Q_OBJECT -public: - explicit DiffEditorEditable(DiffEditorWidget *editorWidget); - virtual ~DiffEditorEditable(); - -public: - // Core::IEditor - bool createNew(const QString &contents); - bool open(QString *errorString, const QString &fileName, const QString &realFileName); - Core::IDocument *document(); - QString displayName() const; - void setDisplayName(const QString &title); - bool duplicateSupported() const; - Core::IEditor *duplicate(QWidget *parent); - Core::Id id() const; - bool isTemporary() const { return true; } - DiffEditorWidget *editorWidget() const { return m_editorWidget; } - - QWidget *toolBar(); - - QByteArray saveState() const; - bool restoreState(const QByteArray &state); - -private: - DiffFile *m_file; - DiffEditorWidget *m_editorWidget; - QToolBar *m_toolWidget; - mutable QString m_displayName; -}; - -class DiffFile : public Core::IDocument -{ - Q_OBJECT -public: - explicit DiffFile(const QString &mimeType, - QObject *parent = 0); - - QString fileName() const { return m_fileName; } - QString defaultPath() const { return QString(); } - QString suggestedFileName() const { return QString(); } - - bool isModified() const { return m_modified; } - QString mimeType() const; - bool isSaveAsAllowed() const { return false; } - bool save(QString *errorString, const QString &fileName, bool autoSave); - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const; - bool reload(QString *errorString, ReloadFlag flag, ChangeType type); - void rename(const QString &newName); - - void setFileName(const QString &name); - void setModified(bool modified = true); - -signals: - void saveMe(QString *errorString, const QString &fileName, bool autoSave); - -private: - const QString m_mimeType; - bool m_modified; - QString m_fileName; -}; class DiffEditorPlugin : public ExtensionSystem::IPlugin { diff --git a/src/plugins/diffeditor/diffeditorwidget.cpp b/src/plugins/diffeditor/diffeditorwidget.cpp index bf6630d6c9..fd8a43e958 100644 --- a/src/plugins/diffeditor/diffeditorwidget.cpp +++ b/src/plugins/diffeditor/diffeditorwidget.cpp @@ -35,9 +35,7 @@ #include <QTextBlock> #include <QScrollBar> #include <QPainter> -#include <QTime> - -#include <QDebug> +#include <QDir> #include <texteditor/basetexteditor.h> #include <texteditor/snippets/snippeteditor.h> @@ -54,6 +52,46 @@ using namespace TextEditor; namespace DiffEditor { +struct TextLineData { + enum TextLineType { + TextLine, + Separator, + Invalid + }; + TextLineData() : textLineType(Invalid) {} + TextLineData(const QString &txt) : textLineType(TextLine), text(txt) {} + TextLineData(TextLineType t) : textLineType(t) {} + TextLineType textLineType; + QString text; +}; + +struct RowData { + RowData() : equal(true) {} + RowData(const TextLineData &l) + : leftLine(l), rightLine(l), equal(true) {} + RowData(const TextLineData &l, const TextLineData &r, bool e = false) + : leftLine(l), rightLine(r), equal(e) {} + TextLineData leftLine; + TextLineData rightLine; + bool equal; // true if left and right lines are equal, taking whitespaces into account (or both invalid) +}; + +struct ChunkData { + ChunkData() : contextChunk(false) {} + QList<RowData> rows; + bool contextChunk; + QMap<int, int> changedLeftPositions; // counting from the beginning of the chunk + QMap<int, int> changedRightPositions; // counting from the beginning of the chunk +}; + +struct FileData { + FileData() {} + FileData(const ChunkData &chunkData) { chunks.append(chunkData); } + QList<ChunkData> chunks; + DiffEditorWidget::DiffFileInfo leftFileInfo; + DiffEditorWidget::DiffFileInfo rightFileInfo; +}; + ////////////////////// class DiffViewEditorEditable : public BaseTextEditor @@ -86,12 +124,15 @@ public: QMap<int, int> skippedLines() const { return m_skippedLines; } + void setWorkingDirectory(const QString &workingDirectory) { m_workingDirectory = workingDirectory; } void setLineNumber(int blockNumber, int lineNumber); - void setFileName(int blockNumber, const QString &fileName) { m_fileNames[blockNumber] = fileName; setSeparator(blockNumber, true); } + void setFileInfo(int blockNumber, const DiffEditorWidget::DiffFileInfo &fileInfo) { m_fileInfo[blockNumber] = fileInfo; setSeparator(blockNumber, true); } void setSkippedLines(int blockNumber, int skippedLines) { m_skippedLines[blockNumber] = skippedLines; setSeparator(blockNumber, true); } void setSeparator(int blockNumber, bool separator) { m_separators[blockNumber] = separator; } - bool isFileLine(int blockNumber) const { return m_fileNames.contains(blockNumber); } + bool isFileLine(int blockNumber) const { return m_fileInfo.contains(blockNumber); } bool isChunkLine(int blockNumber) const { return m_skippedLines.contains(blockNumber); } + void clearAll(); + void clearAll(const QString &message); void clearAllData(); QTextBlock firstVisibleBlock() const { return SnippetEditorWidget::firstVisibleBlock(); } @@ -116,10 +157,11 @@ private: void paintSeparator(QPainter &painter, const QString &text, const QTextBlock &block, int top); void jumpToOriginalFile(const QTextCursor &cursor); + QString m_workingDirectory; QMap<int, int> m_lineNumbers; int m_lineNumberDigits; - // block number, fileName - QMap<int, QString> m_fileNames; + // block number, fileInfo + QMap<int, DiffEditorWidget::DiffFileInfo> m_fileInfo; // block number, skipped lines QMap<int, int> m_skippedLines; // block number, separator. Separator used as lines alignment and inside skipped lines @@ -200,11 +242,24 @@ void DiffViewEditorWidget::setLineNumber(int blockNumber, int lineNumber) m_lineNumberDigits = qMax(m_lineNumberDigits, lineNumberString.count()); } +void DiffViewEditorWidget::clearAll() +{ + clearAll(tr("No difference")); +} + +void DiffViewEditorWidget::clearAll(const QString &message) +{ + setBlockSelection(false); + clear(); + clearAllData(); + setPlainText(message); +} + void DiffViewEditorWidget::clearAllData() { m_lineNumberDigits = 1; m_lineNumbers.clear(); - m_fileNames.clear(); + m_fileInfo.clear(); m_skippedLines.clear(); m_separators.clear(); } @@ -253,7 +308,7 @@ void DiffViewEditorWidget::mouseDoubleClickEvent(QMouseEvent *e) void DiffViewEditorWidget::jumpToOriginalFile(const QTextCursor &cursor) { - if (m_fileNames.isEmpty()) + if (m_fileInfo.isEmpty()) return; const int blockNumber = cursor.blockNumber(); @@ -262,10 +317,11 @@ void DiffViewEditorWidget::jumpToOriginalFile(const QTextCursor &cursor) return; const int lineNr = m_lineNumbers.value(blockNumber); - QMap<int, QString>::const_iterator it = m_fileNames.upperBound(blockNumber); - if (it != m_fileNames.constBegin()) + QMap<int, DiffEditorWidget::DiffFileInfo>::const_iterator it = m_fileInfo.upperBound(blockNumber); + if (it != m_fileInfo.constBegin()) --it; - const QString fileName = it.value(); + const QDir dir(m_workingDirectory); + const QString fileName = dir.absoluteFilePath(it.value().fileName); Core::IEditor *ed = Core::EditorManager::openEditor(fileName, Core::Id(), Core::EditorManager::ModeSwitch); if (TextEditor::ITextEditor *editor = qobject_cast<TextEditor::ITextEditor *>(ed)) @@ -300,9 +356,12 @@ void DiffViewEditorWidget::paintEvent(QPaintEvent *e) paintSeparator(painter, skippedRowsText, currentBlock, top); } - const QString fileName = m_fileNames.value(blockNumber); - if (!fileName.isEmpty()) { - paintSeparator(painter, fileName, currentBlock, top); + const DiffEditorWidget::DiffFileInfo fileInfo = m_fileInfo.value(blockNumber); + if (!fileInfo.fileName.isEmpty()) { + const QString fileNameText = fileInfo.typeInfo.isEmpty() + ? fileInfo.fileName + : tr("[%1] %2").arg(fileInfo.typeInfo).arg(fileInfo.fileName); + paintSeparator(painter, fileNameText, currentBlock, top); } } } @@ -416,7 +475,7 @@ void DiffViewEditorWidget::drawCollapsedBlockPopup(QPainter &painter, DiffEditorWidget::DiffEditorWidget(QWidget *parent) : QWidget(parent), - m_contextLinesNumber(1), + m_contextLinesNumber(3), m_ignoreWhitespaces(true), m_foldingBlocker(false) { @@ -457,6 +516,8 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent) m_splitter->addWidget(m_rightEditor); QVBoxLayout *l = new QVBoxLayout(this); l->addWidget(m_splitter); + + clear(); } DiffEditorWidget::~DiffEditorWidget() @@ -464,15 +525,29 @@ DiffEditorWidget::~DiffEditorWidget() } -void DiffEditorWidget::setDiff(const QList<DiffFilesContents> &diffFileList) +void DiffEditorWidget::clear() +{ + m_leftEditor->clearAll(); + m_rightEditor->clearAll(); +} + +void DiffEditorWidget::clear(const QString &message) +{ + m_leftEditor->clearAll(message); + m_rightEditor->clearAll(message); +} + +void DiffEditorWidget::setDiff(const QList<DiffFilesContents> &diffFileList, const QString &workingDirectory) { + m_leftEditor->setWorkingDirectory(workingDirectory); + m_rightEditor->setWorkingDirectory(workingDirectory); Differ differ; QList<DiffList> diffList; for (int i = 0; i < diffFileList.count(); i++) { DiffFilesContents dfc = diffFileList.at(i); DiffList dl; - dl.leftFileName = dfc.leftFileName; - dl.rightFileName = dfc.rightFileName; + dl.leftFileInfo = dfc.leftFileInfo; + dl.rightFileInfo = dfc.rightFileInfo; dl.diffList = differ.cleanupSemantics(differ.diff(dfc.leftText, dfc.rightText)); diffList.append(dl); } @@ -490,8 +565,8 @@ void DiffEditorWidget::setDiff(const QList<DiffList> &diffList) ChunkData chunkData = calculateOriginalData(dl.diffList); m_originalChunkData.append(chunkData); FileData fileData = calculateContextData(chunkData); - fileData.leftFileName = dl.leftFileName; - fileData.rightFileName = dl.rightFileName; + fileData.leftFileInfo = dl.leftFileInfo; + fileData.rightFileInfo = dl.rightFileInfo; m_contextFileData.append(fileData); } showDiff(); @@ -506,8 +581,8 @@ void DiffEditorWidget::setContextLinesNumber(int lines) for (int i = 0; i < m_diffList.count(); i++) { const FileData oldFileData = m_contextFileData.at(i); FileData newFileData = calculateContextData(m_originalChunkData.at(i)); - newFileData.leftFileName = oldFileData.leftFileName; - newFileData.rightFileName = oldFileData.rightFileName; + newFileData.leftFileInfo = oldFileData.leftFileInfo; + newFileData.rightFileInfo = oldFileData.rightFileInfo; m_contextFileData[i] = newFileData; } @@ -855,8 +930,8 @@ FileData DiffEditorWidget::calculateContextData(const ChunkData &originalData) c RowData rowData = originalData.rows.at(i); chunkData.rows.append(rowData); - leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for separator or for '\n', each line has one of it - rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for separator or for '\n', each line has one of it + leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n' + rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n' i++; } while (leftChangedIt != originalData.changedLeftPositions.constEnd()) { @@ -889,8 +964,8 @@ FileData DiffEditorWidget::calculateContextData(const ChunkData &originalData) c RowData rowData = originalData.rows.at(i); chunkData.rows.append(rowData); - leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for separator or for '\n', each line has one of it - rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for separator or for '\n', each line has one of it + leftCharCounter += rowData.leftLine.text.count() + 1; // +1 for '\n' + rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n' i++; } fileData.chunks.append(chunkData); @@ -901,21 +976,12 @@ FileData DiffEditorWidget::calculateContextData(const ChunkData &originalData) c void DiffEditorWidget::showDiff() { -// QTime time; -// time.start(); - // TODO: remember the line number of the line in the middle const int verticalValue = m_leftEditor->verticalScrollBar()->value(); const int leftHorizontalValue = m_leftEditor->horizontalScrollBar()->value(); const int rightHorizontalValue = m_rightEditor->horizontalScrollBar()->value(); - m_leftEditor->setBlockSelection(false); - m_rightEditor->setBlockSelection(false); - m_leftEditor->clear(); - m_rightEditor->clear(); - m_leftEditor->clearAllData(); - m_rightEditor->clearAllData(); -// int ela1 = time.elapsed(); + clear(); QString leftText, rightText; int blockNumber = 0; @@ -925,8 +991,8 @@ void DiffEditorWidget::showDiff() int leftLineNumber = 0; int rightLineNumber = 0; - m_leftEditor->setFileName(blockNumber, contextFileData.leftFileName); - m_rightEditor->setFileName(blockNumber, contextFileData.rightFileName); + m_leftEditor->setFileInfo(blockNumber, contextFileData.leftFileInfo); + m_rightEditor->setFileInfo(blockNumber, contextFileData.rightFileInfo); leftText += separator; rightText += separator; blockNumber++; @@ -967,13 +1033,12 @@ void DiffEditorWidget::showDiff() } } } -// int ela2 = time.elapsed(); + + if (leftText.isEmpty() && rightText.isEmpty()) + return; m_leftEditor->setPlainText(leftText); m_rightEditor->setPlainText(rightText); -// int ela3 = time.elapsed(); - -// int ela4 = time.elapsed(); colorDiff(m_contextFileData); @@ -1029,14 +1094,10 @@ void DiffEditorWidget::showDiff() } m_foldingBlocker = false; -// int ela5 = time.elapsed(); - m_leftEditor->verticalScrollBar()->setValue(verticalValue); m_rightEditor->verticalScrollBar()->setValue(verticalValue); m_leftEditor->horizontalScrollBar()->setValue(leftHorizontalValue); m_rightEditor->horizontalScrollBar()->setValue(rightHorizontalValue); -// int ela6 = time.elapsed(); -// qDebug() << ela1 << ela2 << ela3 << ela4 << ela5 << ela6; m_leftEditor->updateFoldingHighlight(QPoint(-1, -1)); m_rightEditor->updateFoldingHighlight(QPoint(-1, -1)); } @@ -1099,7 +1160,6 @@ void DiffEditorWidget::colorDiff(const QList<FileData> &fileDataList) int leftPos = 0; int rightPos = 0; - // startPos, endPos QMap<int, int> leftLinePos; QMap<int, int> rightLinePos; QMap<int, int> leftCharPos; @@ -1154,8 +1214,8 @@ void DiffEditorWidget::colorDiff(const QList<FileData> &fileDataList) for (int k = 0; k < chunkData.rows.count(); k++) { RowData rowData = chunkData.rows.at(k); - leftPos += rowData.leftLine.text.count() + 1; // +1 for separator or for '\n', each line has one of it - rightPos += rowData.rightLine.text.count() + 1; // +1 for separator or for '\n', each line has one of it + leftPos += rowData.leftLine.text.count() + 1; // +1 for '\n' + rightPos += rowData.rightLine.text.count() + 1; // +1 for '\n' if (!rowData.equal) { if (rowData.leftLine.textLineType == TextLineData::TextLine) { diff --git a/src/plugins/diffeditor/diffeditorwidget.h b/src/plugins/diffeditor/diffeditorwidget.h index 17b5107485..b4e7fe83b4 100644 --- a/src/plugins/diffeditor/diffeditorwidget.h +++ b/src/plugins/diffeditor/diffeditorwidget.h @@ -52,59 +52,26 @@ QT_END_NAMESPACE namespace DiffEditor { class DiffViewEditorWidget; - -struct TextLineData { - enum TextLineType { - TextLine, - Separator, - Invalid - }; - TextLineData() : textLineType(Invalid) {} - TextLineData(const QString &txt) : textLineType(TextLine), text(txt) {} - TextLineData(TextLineType t) : textLineType(t) {} - TextLineType textLineType; - QString text; -}; - -struct RowData { - RowData() : equal(true) {} - RowData(const TextLineData &l) - : leftLine(l), rightLine(l), equal(true) {} - RowData(const TextLineData &l, const TextLineData &r, bool e = false) - : leftLine(l), rightLine(r), equal(e) {} - TextLineData leftLine; - TextLineData rightLine; - bool equal; // true if left and right lines are equal, taking whitespaces into account (or both invalid) -}; - -struct ChunkData { - ChunkData() : contextChunk(false) {} - QList<RowData> rows; - bool contextChunk; - QMap<int, int> changedLeftPositions; // counting from the beginning of the chunk - QMap<int, int> changedRightPositions; // counting from the beginning of the chunk -}; - -struct FileData { - FileData() {} - FileData(const ChunkData &chunkData) { chunks.append(chunkData); } - QList<ChunkData> chunks; - QString leftFileName; - QString rightFileName; -}; - -struct DiffData { - QList<FileData> files; -}; +struct TextLineData; +struct ChunkData; +struct FileData; class DIFFEDITOR_EXPORT DiffEditorWidget : public QWidget { Q_OBJECT public: + struct DiffFileInfo { + DiffFileInfo() {} + DiffFileInfo(const QString &file) : fileName(file) {} + DiffFileInfo(const QString &file, const QString &type) : fileName(file), typeInfo(type) {} + QString fileName; + QString typeInfo; + }; + struct DiffFilesContents { - QString leftFileName; + DiffFileInfo leftFileInfo; QString leftText; - QString rightFileName; + DiffFileInfo rightFileInfo; QString rightText; }; @@ -112,7 +79,8 @@ public: ~DiffEditorWidget(); void clear(); - void setDiff(const QList<DiffFilesContents> &diffFileList); + void clear(const QString &message); + void setDiff(const QList<DiffFilesContents> &diffFileList, const QString &workingDirectory = QString()); QTextCodec *codec() const; public slots: @@ -131,8 +99,8 @@ private slots: private: struct DiffList { - QString leftFileName; - QString rightFileName; + DiffFileInfo leftFileInfo; + DiffFileInfo rightFileInfo; QList<Diff> diffList; }; |