forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -1,13 +1,17 @@
|
|||||||
DEFINES += DIFFEDITOR_LIBRARY
|
DEFINES += DIFFEDITOR_LIBRARY
|
||||||
include(../../qtcreatorplugin.pri)
|
include(../../qtcreatorplugin.pri)
|
||||||
|
|
||||||
HEADERS += diffeditorplugin.h \
|
HEADERS += diffeditor_global.h \
|
||||||
diffeditorwidget.h \
|
|
||||||
diffeditorconstants.h \
|
diffeditorconstants.h \
|
||||||
diffeditor_global.h \
|
diffeditoreditable.h \
|
||||||
|
diffeditorfile.h \
|
||||||
|
diffeditorplugin.h \
|
||||||
|
diffeditorwidget.h \
|
||||||
differ.h
|
differ.h
|
||||||
|
|
||||||
SOURCES += diffeditorplugin.cpp \
|
SOURCES += diffeditoreditable.cpp \
|
||||||
|
diffeditorfile.cpp \
|
||||||
|
diffeditorplugin.cpp \
|
||||||
diffeditorwidget.cpp \
|
diffeditorwidget.cpp \
|
||||||
differ.cpp
|
differ.cpp
|
||||||
|
|
||||||
|
|||||||
@@ -13,14 +13,18 @@ QtcPlugin {
|
|||||||
Depends { name: "cpp" }
|
Depends { name: "cpp" }
|
||||||
|
|
||||||
files: [
|
files: [
|
||||||
|
"diffeditor_global.h",
|
||||||
|
"diffeditorconstants.h",
|
||||||
|
"diffeditoreditable.cpp",
|
||||||
|
"diffeditoreditable.h",
|
||||||
|
"diffeditorfile.cpp",
|
||||||
|
"diffeditorfile.h",
|
||||||
"diffeditorplugin.cpp",
|
"diffeditorplugin.cpp",
|
||||||
"diffeditorplugin.h",
|
"diffeditorplugin.h",
|
||||||
"differ.cpp",
|
|
||||||
"differ.h",
|
|
||||||
"diffeditorwidget.cpp",
|
"diffeditorwidget.cpp",
|
||||||
"diffeditorwidget.h",
|
"diffeditorwidget.h",
|
||||||
"diffeditorconstants.h",
|
"differ.cpp",
|
||||||
"diffeditor_global.h",
|
"differ.h",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
162
src/plugins/diffeditor/diffeditoreditable.cpp
Normal file
162
src/plugins/diffeditor/diffeditoreditable.cpp
Normal file
@@ -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
|
||||||
82
src/plugins/diffeditor/diffeditoreditable.h
Normal file
82
src/plugins/diffeditor/diffeditoreditable.h
Normal file
@@ -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
|
||||||
96
src/plugins/diffeditor/diffeditorfile.cpp
Normal file
96
src/plugins/diffeditor/diffeditorfile.cpp
Normal file
@@ -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
|
||||||
78
src/plugins/diffeditor/diffeditorfile.h
Normal file
78
src/plugins/diffeditor/diffeditorfile.h
Normal file
@@ -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
|
||||||
@@ -28,17 +28,14 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "diffeditorplugin.h"
|
#include "diffeditorplugin.h"
|
||||||
|
#include "diffeditoreditable.h"
|
||||||
#include "diffeditorwidget.h"
|
#include "diffeditorwidget.h"
|
||||||
#include "diffeditorconstants.h"
|
#include "diffeditorconstants.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QToolButton>
|
|
||||||
#include <QSpinBox>
|
|
||||||
#include <QStyle>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
|
#include <QtPlugin>
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
@@ -46,195 +43,14 @@
|
|||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
|
||||||
namespace DiffEditor {
|
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::DiffEditorFactory(DiffEditorPlugin *owner) :
|
namespace Internal {
|
||||||
m_mimeTypes(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE)),
|
|
||||||
m_owner(owner)
|
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());
|
const QString text2 = getFileContents(fileName2, editorWidget->codec());
|
||||||
|
|
||||||
DiffEditorWidget::DiffFilesContents dfc;
|
DiffEditorWidget::DiffFilesContents dfc;
|
||||||
dfc.leftFileName = fileName1;
|
dfc.leftFileInfo = fileName1;
|
||||||
dfc.leftText = text1;
|
dfc.leftText = text1;
|
||||||
dfc.rightFileName = fileName2;
|
dfc.rightFileInfo = fileName2;
|
||||||
dfc.rightText = text2;
|
dfc.rightText = text2;
|
||||||
QList<DiffEditorWidget::DiffFilesContents> list;
|
QList<DiffEditorWidget::DiffFilesContents> list;
|
||||||
list.append(dfc);
|
list.append(dfc);
|
||||||
|
|||||||
@@ -30,86 +30,22 @@
|
|||||||
#ifndef DIFFEDITORPLUGIN_H
|
#ifndef DIFFEDITORPLUGIN_H
|
||||||
#define DIFFEDITORPLUGIN_H
|
#define DIFFEDITORPLUGIN_H
|
||||||
|
|
||||||
|
#include "diffeditor_global.h"
|
||||||
|
|
||||||
#include <extensionsystem/iplugin.h>
|
#include <extensionsystem/iplugin.h>
|
||||||
#include <coreplugin/editormanager/ieditorfactory.h>
|
#include <coreplugin/editormanager/ieditorfactory.h>
|
||||||
#include <coreplugin/editormanager/ieditor.h>
|
|
||||||
#include <coreplugin/icontext.h>
|
#include <coreplugin/icontext.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
|
|
||||||
#include <QtPlugin>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QAction>
|
|
||||||
#include <QToolBar>
|
namespace Core { class IEditor; }
|
||||||
|
|
||||||
namespace DiffEditor {
|
namespace DiffEditor {
|
||||||
|
|
||||||
class DiffEditorWidget;
|
class DiffEditorWidget;
|
||||||
|
|
||||||
namespace Internal {
|
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
|
class DiffEditorPlugin : public ExtensionSystem::IPlugin
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,9 +35,7 @@
|
|||||||
#include <QTextBlock>
|
#include <QTextBlock>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QTime>
|
#include <QDir>
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include <texteditor/basetexteditor.h>
|
#include <texteditor/basetexteditor.h>
|
||||||
#include <texteditor/snippets/snippeteditor.h>
|
#include <texteditor/snippets/snippeteditor.h>
|
||||||
@@ -54,6 +52,46 @@ using namespace TextEditor;
|
|||||||
|
|
||||||
namespace DiffEditor {
|
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
|
class DiffViewEditorEditable : public BaseTextEditor
|
||||||
@@ -86,12 +124,15 @@ public:
|
|||||||
|
|
||||||
QMap<int, int> skippedLines() const { return m_skippedLines; }
|
QMap<int, int> skippedLines() const { return m_skippedLines; }
|
||||||
|
|
||||||
|
void setWorkingDirectory(const QString &workingDirectory) { m_workingDirectory = workingDirectory; }
|
||||||
void setLineNumber(int blockNumber, int lineNumber);
|
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 setSkippedLines(int blockNumber, int skippedLines) { m_skippedLines[blockNumber] = skippedLines; setSeparator(blockNumber, true); }
|
||||||
void setSeparator(int blockNumber, bool separator) { m_separators[blockNumber] = separator; }
|
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); }
|
bool isChunkLine(int blockNumber) const { return m_skippedLines.contains(blockNumber); }
|
||||||
|
void clearAll();
|
||||||
|
void clearAll(const QString &message);
|
||||||
void clearAllData();
|
void clearAllData();
|
||||||
QTextBlock firstVisibleBlock() const { return SnippetEditorWidget::firstVisibleBlock(); }
|
QTextBlock firstVisibleBlock() const { return SnippetEditorWidget::firstVisibleBlock(); }
|
||||||
|
|
||||||
@@ -116,10 +157,11 @@ private:
|
|||||||
void paintSeparator(QPainter &painter, const QString &text, const QTextBlock &block, int top);
|
void paintSeparator(QPainter &painter, const QString &text, const QTextBlock &block, int top);
|
||||||
void jumpToOriginalFile(const QTextCursor &cursor);
|
void jumpToOriginalFile(const QTextCursor &cursor);
|
||||||
|
|
||||||
|
QString m_workingDirectory;
|
||||||
QMap<int, int> m_lineNumbers;
|
QMap<int, int> m_lineNumbers;
|
||||||
int m_lineNumberDigits;
|
int m_lineNumberDigits;
|
||||||
// block number, fileName
|
// block number, fileInfo
|
||||||
QMap<int, QString> m_fileNames;
|
QMap<int, DiffEditorWidget::DiffFileInfo> m_fileInfo;
|
||||||
// block number, skipped lines
|
// block number, skipped lines
|
||||||
QMap<int, int> m_skippedLines;
|
QMap<int, int> m_skippedLines;
|
||||||
// block number, separator. Separator used as lines alignment and inside skipped lines
|
// 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());
|
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()
|
void DiffViewEditorWidget::clearAllData()
|
||||||
{
|
{
|
||||||
m_lineNumberDigits = 1;
|
m_lineNumberDigits = 1;
|
||||||
m_lineNumbers.clear();
|
m_lineNumbers.clear();
|
||||||
m_fileNames.clear();
|
m_fileInfo.clear();
|
||||||
m_skippedLines.clear();
|
m_skippedLines.clear();
|
||||||
m_separators.clear();
|
m_separators.clear();
|
||||||
}
|
}
|
||||||
@@ -253,7 +308,7 @@ void DiffViewEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
|
|||||||
|
|
||||||
void DiffViewEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
void DiffViewEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
||||||
{
|
{
|
||||||
if (m_fileNames.isEmpty())
|
if (m_fileInfo.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const int blockNumber = cursor.blockNumber();
|
const int blockNumber = cursor.blockNumber();
|
||||||
@@ -262,10 +317,11 @@ void DiffViewEditorWidget::jumpToOriginalFile(const QTextCursor &cursor)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const int lineNr = m_lineNumbers.value(blockNumber);
|
const int lineNr = m_lineNumbers.value(blockNumber);
|
||||||
QMap<int, QString>::const_iterator it = m_fileNames.upperBound(blockNumber);
|
QMap<int, DiffEditorWidget::DiffFileInfo>::const_iterator it = m_fileInfo.upperBound(blockNumber);
|
||||||
if (it != m_fileNames.constBegin())
|
if (it != m_fileInfo.constBegin())
|
||||||
--it;
|
--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);
|
Core::IEditor *ed = Core::EditorManager::openEditor(fileName, Core::Id(), Core::EditorManager::ModeSwitch);
|
||||||
if (TextEditor::ITextEditor *editor = qobject_cast<TextEditor::ITextEditor *>(ed))
|
if (TextEditor::ITextEditor *editor = qobject_cast<TextEditor::ITextEditor *>(ed))
|
||||||
@@ -300,9 +356,12 @@ void DiffViewEditorWidget::paintEvent(QPaintEvent *e)
|
|||||||
paintSeparator(painter, skippedRowsText, currentBlock, top);
|
paintSeparator(painter, skippedRowsText, currentBlock, top);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString fileName = m_fileNames.value(blockNumber);
|
const DiffEditorWidget::DiffFileInfo fileInfo = m_fileInfo.value(blockNumber);
|
||||||
if (!fileName.isEmpty()) {
|
if (!fileInfo.fileName.isEmpty()) {
|
||||||
paintSeparator(painter, fileName, currentBlock, top);
|
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)
|
DiffEditorWidget::DiffEditorWidget(QWidget *parent)
|
||||||
: QWidget(parent),
|
: QWidget(parent),
|
||||||
m_contextLinesNumber(1),
|
m_contextLinesNumber(3),
|
||||||
m_ignoreWhitespaces(true),
|
m_ignoreWhitespaces(true),
|
||||||
m_foldingBlocker(false)
|
m_foldingBlocker(false)
|
||||||
{
|
{
|
||||||
@@ -457,6 +516,8 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent)
|
|||||||
m_splitter->addWidget(m_rightEditor);
|
m_splitter->addWidget(m_rightEditor);
|
||||||
QVBoxLayout *l = new QVBoxLayout(this);
|
QVBoxLayout *l = new QVBoxLayout(this);
|
||||||
l->addWidget(m_splitter);
|
l->addWidget(m_splitter);
|
||||||
|
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
DiffEditorWidget::~DiffEditorWidget()
|
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;
|
Differ differ;
|
||||||
QList<DiffList> diffList;
|
QList<DiffList> diffList;
|
||||||
for (int i = 0; i < diffFileList.count(); i++) {
|
for (int i = 0; i < diffFileList.count(); i++) {
|
||||||
DiffFilesContents dfc = diffFileList.at(i);
|
DiffFilesContents dfc = diffFileList.at(i);
|
||||||
DiffList dl;
|
DiffList dl;
|
||||||
dl.leftFileName = dfc.leftFileName;
|
dl.leftFileInfo = dfc.leftFileInfo;
|
||||||
dl.rightFileName = dfc.rightFileName;
|
dl.rightFileInfo = dfc.rightFileInfo;
|
||||||
dl.diffList = differ.cleanupSemantics(differ.diff(dfc.leftText, dfc.rightText));
|
dl.diffList = differ.cleanupSemantics(differ.diff(dfc.leftText, dfc.rightText));
|
||||||
diffList.append(dl);
|
diffList.append(dl);
|
||||||
}
|
}
|
||||||
@@ -490,8 +565,8 @@ void DiffEditorWidget::setDiff(const QList<DiffList> &diffList)
|
|||||||
ChunkData chunkData = calculateOriginalData(dl.diffList);
|
ChunkData chunkData = calculateOriginalData(dl.diffList);
|
||||||
m_originalChunkData.append(chunkData);
|
m_originalChunkData.append(chunkData);
|
||||||
FileData fileData = calculateContextData(chunkData);
|
FileData fileData = calculateContextData(chunkData);
|
||||||
fileData.leftFileName = dl.leftFileName;
|
fileData.leftFileInfo = dl.leftFileInfo;
|
||||||
fileData.rightFileName = dl.rightFileName;
|
fileData.rightFileInfo = dl.rightFileInfo;
|
||||||
m_contextFileData.append(fileData);
|
m_contextFileData.append(fileData);
|
||||||
}
|
}
|
||||||
showDiff();
|
showDiff();
|
||||||
@@ -506,8 +581,8 @@ void DiffEditorWidget::setContextLinesNumber(int lines)
|
|||||||
for (int i = 0; i < m_diffList.count(); i++) {
|
for (int i = 0; i < m_diffList.count(); i++) {
|
||||||
const FileData oldFileData = m_contextFileData.at(i);
|
const FileData oldFileData = m_contextFileData.at(i);
|
||||||
FileData newFileData = calculateContextData(m_originalChunkData.at(i));
|
FileData newFileData = calculateContextData(m_originalChunkData.at(i));
|
||||||
newFileData.leftFileName = oldFileData.leftFileName;
|
newFileData.leftFileInfo = oldFileData.leftFileInfo;
|
||||||
newFileData.rightFileName = oldFileData.rightFileName;
|
newFileData.rightFileInfo = oldFileData.rightFileInfo;
|
||||||
m_contextFileData[i] = newFileData;
|
m_contextFileData[i] = newFileData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,8 +930,8 @@ FileData DiffEditorWidget::calculateContextData(const ChunkData &originalData) c
|
|||||||
RowData rowData = originalData.rows.at(i);
|
RowData rowData = originalData.rows.at(i);
|
||||||
chunkData.rows.append(rowData);
|
chunkData.rows.append(rowData);
|
||||||
|
|
||||||
leftCharCounter += rowData.leftLine.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 separator or for '\n', each line has one of it
|
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
while (leftChangedIt != originalData.changedLeftPositions.constEnd()) {
|
while (leftChangedIt != originalData.changedLeftPositions.constEnd()) {
|
||||||
@@ -889,8 +964,8 @@ FileData DiffEditorWidget::calculateContextData(const ChunkData &originalData) c
|
|||||||
RowData rowData = originalData.rows.at(i);
|
RowData rowData = originalData.rows.at(i);
|
||||||
chunkData.rows.append(rowData);
|
chunkData.rows.append(rowData);
|
||||||
|
|
||||||
leftCharCounter += rowData.leftLine.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 separator or for '\n', each line has one of it
|
rightCharCounter += rowData.rightLine.text.count() + 1; // +1 for '\n'
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
fileData.chunks.append(chunkData);
|
fileData.chunks.append(chunkData);
|
||||||
@@ -901,21 +976,12 @@ FileData DiffEditorWidget::calculateContextData(const ChunkData &originalData) c
|
|||||||
|
|
||||||
void DiffEditorWidget::showDiff()
|
void DiffEditorWidget::showDiff()
|
||||||
{
|
{
|
||||||
// QTime time;
|
|
||||||
// time.start();
|
|
||||||
|
|
||||||
// TODO: remember the line number of the line in the middle
|
// TODO: remember the line number of the line in the middle
|
||||||
const int verticalValue = m_leftEditor->verticalScrollBar()->value();
|
const int verticalValue = m_leftEditor->verticalScrollBar()->value();
|
||||||
const int leftHorizontalValue = m_leftEditor->horizontalScrollBar()->value();
|
const int leftHorizontalValue = m_leftEditor->horizontalScrollBar()->value();
|
||||||
const int rightHorizontalValue = m_rightEditor->horizontalScrollBar()->value();
|
const int rightHorizontalValue = m_rightEditor->horizontalScrollBar()->value();
|
||||||
|
|
||||||
m_leftEditor->setBlockSelection(false);
|
clear();
|
||||||
m_rightEditor->setBlockSelection(false);
|
|
||||||
m_leftEditor->clear();
|
|
||||||
m_rightEditor->clear();
|
|
||||||
m_leftEditor->clearAllData();
|
|
||||||
m_rightEditor->clearAllData();
|
|
||||||
// int ela1 = time.elapsed();
|
|
||||||
|
|
||||||
QString leftText, rightText;
|
QString leftText, rightText;
|
||||||
int blockNumber = 0;
|
int blockNumber = 0;
|
||||||
@@ -925,8 +991,8 @@ void DiffEditorWidget::showDiff()
|
|||||||
|
|
||||||
int leftLineNumber = 0;
|
int leftLineNumber = 0;
|
||||||
int rightLineNumber = 0;
|
int rightLineNumber = 0;
|
||||||
m_leftEditor->setFileName(blockNumber, contextFileData.leftFileName);
|
m_leftEditor->setFileInfo(blockNumber, contextFileData.leftFileInfo);
|
||||||
m_rightEditor->setFileName(blockNumber, contextFileData.rightFileName);
|
m_rightEditor->setFileInfo(blockNumber, contextFileData.rightFileInfo);
|
||||||
leftText += separator;
|
leftText += separator;
|
||||||
rightText += separator;
|
rightText += separator;
|
||||||
blockNumber++;
|
blockNumber++;
|
||||||
@@ -967,13 +1033,12 @@ void DiffEditorWidget::showDiff()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// int ela2 = time.elapsed();
|
|
||||||
|
if (leftText.isEmpty() && rightText.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
m_leftEditor->setPlainText(leftText);
|
m_leftEditor->setPlainText(leftText);
|
||||||
m_rightEditor->setPlainText(rightText);
|
m_rightEditor->setPlainText(rightText);
|
||||||
// int ela3 = time.elapsed();
|
|
||||||
|
|
||||||
// int ela4 = time.elapsed();
|
|
||||||
|
|
||||||
colorDiff(m_contextFileData);
|
colorDiff(m_contextFileData);
|
||||||
|
|
||||||
@@ -1029,14 +1094,10 @@ void DiffEditorWidget::showDiff()
|
|||||||
}
|
}
|
||||||
m_foldingBlocker = false;
|
m_foldingBlocker = false;
|
||||||
|
|
||||||
// int ela5 = time.elapsed();
|
|
||||||
|
|
||||||
m_leftEditor->verticalScrollBar()->setValue(verticalValue);
|
m_leftEditor->verticalScrollBar()->setValue(verticalValue);
|
||||||
m_rightEditor->verticalScrollBar()->setValue(verticalValue);
|
m_rightEditor->verticalScrollBar()->setValue(verticalValue);
|
||||||
m_leftEditor->horizontalScrollBar()->setValue(leftHorizontalValue);
|
m_leftEditor->horizontalScrollBar()->setValue(leftHorizontalValue);
|
||||||
m_rightEditor->horizontalScrollBar()->setValue(rightHorizontalValue);
|
m_rightEditor->horizontalScrollBar()->setValue(rightHorizontalValue);
|
||||||
// int ela6 = time.elapsed();
|
|
||||||
// qDebug() << ela1 << ela2 << ela3 << ela4 << ela5 << ela6;
|
|
||||||
m_leftEditor->updateFoldingHighlight(QPoint(-1, -1));
|
m_leftEditor->updateFoldingHighlight(QPoint(-1, -1));
|
||||||
m_rightEditor->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 leftPos = 0;
|
||||||
int rightPos = 0;
|
int rightPos = 0;
|
||||||
// startPos, endPos
|
|
||||||
QMap<int, int> leftLinePos;
|
QMap<int, int> leftLinePos;
|
||||||
QMap<int, int> rightLinePos;
|
QMap<int, int> rightLinePos;
|
||||||
QMap<int, int> leftCharPos;
|
QMap<int, int> leftCharPos;
|
||||||
@@ -1154,8 +1214,8 @@ void DiffEditorWidget::colorDiff(const QList<FileData> &fileDataList)
|
|||||||
for (int k = 0; k < chunkData.rows.count(); k++) {
|
for (int k = 0; k < chunkData.rows.count(); k++) {
|
||||||
RowData rowData = chunkData.rows.at(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
|
leftPos += rowData.leftLine.text.count() + 1; // +1 for '\n'
|
||||||
rightPos += rowData.rightLine.text.count() + 1; // +1 for separator or for '\n', each line has one of it
|
rightPos += rowData.rightLine.text.count() + 1; // +1 for '\n'
|
||||||
|
|
||||||
if (!rowData.equal) {
|
if (!rowData.equal) {
|
||||||
if (rowData.leftLine.textLineType == TextLineData::TextLine) {
|
if (rowData.leftLine.textLineType == TextLineData::TextLine) {
|
||||||
|
|||||||
@@ -52,59 +52,26 @@ QT_END_NAMESPACE
|
|||||||
namespace DiffEditor {
|
namespace DiffEditor {
|
||||||
|
|
||||||
class DiffViewEditorWidget;
|
class DiffViewEditorWidget;
|
||||||
|
struct TextLineData;
|
||||||
struct TextLineData {
|
struct ChunkData;
|
||||||
enum TextLineType {
|
struct FileData;
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DIFFEDITOR_EXPORT DiffEditorWidget : public QWidget
|
class DIFFEDITOR_EXPORT DiffEditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
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 {
|
struct DiffFilesContents {
|
||||||
QString leftFileName;
|
DiffFileInfo leftFileInfo;
|
||||||
QString leftText;
|
QString leftText;
|
||||||
QString rightFileName;
|
DiffFileInfo rightFileInfo;
|
||||||
QString rightText;
|
QString rightText;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,7 +79,8 @@ public:
|
|||||||
~DiffEditorWidget();
|
~DiffEditorWidget();
|
||||||
|
|
||||||
void clear();
|
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;
|
QTextCodec *codec() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -131,8 +99,8 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct DiffList {
|
struct DiffList {
|
||||||
QString leftFileName;
|
DiffFileInfo leftFileInfo;
|
||||||
QString rightFileName;
|
DiffFileInfo rightFileInfo;
|
||||||
QList<Diff> diffList;
|
QList<Diff> diffList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ QtcPlugin {
|
|||||||
Depends { name: "TextEditor" }
|
Depends { name: "TextEditor" }
|
||||||
Depends { name: "Find" }
|
Depends { name: "Find" }
|
||||||
Depends { name: "VcsBase" }
|
Depends { name: "VcsBase" }
|
||||||
|
Depends { name: "DiffEditor" }
|
||||||
Depends { name: "Locator" }
|
Depends { name: "Locator" }
|
||||||
|
|
||||||
files: [
|
files: [
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ QTC_PLUGIN_DEPENDS += \
|
|||||||
projectexplorer \
|
projectexplorer \
|
||||||
texteditor \
|
texteditor \
|
||||||
coreplugin \
|
coreplugin \
|
||||||
vcsbase
|
vcsbase \
|
||||||
|
diffeditor
|
||||||
|
|||||||
@@ -56,6 +56,10 @@
|
|||||||
#include <vcsbase/vcsbaseoutputwindow.h>
|
#include <vcsbase/vcsbaseoutputwindow.h>
|
||||||
#include <vcsbase/vcsbaseplugin.h>
|
#include <vcsbase/vcsbaseplugin.h>
|
||||||
|
|
||||||
|
#include <diffeditor/diffeditorwidget.h>
|
||||||
|
#include <diffeditor/diffeditoreditable.h>
|
||||||
|
#include <diffeditor/diffeditorconstants.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
@@ -75,6 +79,224 @@ static const char graphLogFormatC[] = "%h %d %an %s %ci";
|
|||||||
namespace Git {
|
namespace Git {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
class GitDiffHandler : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
GitDiffHandler(const QString &gitPath,
|
||||||
|
const QString &workingDirectory,
|
||||||
|
const QProcessEnvironment &environment,
|
||||||
|
DiffEditor::DiffEditorWidget *editor,
|
||||||
|
int timeout);
|
||||||
|
|
||||||
|
// index -> working tree
|
||||||
|
void diffFile(const QString &fileName);
|
||||||
|
// stagedFileNames - files in index, diff will compare the state in HEAD to the one in the index
|
||||||
|
// unstagedFileNames - diff will compare the state in the index to the one in the working tree
|
||||||
|
void diffFiles(const QStringList &stagedFileNames, const QStringList &unstagedFileNames);
|
||||||
|
// index -> working tree
|
||||||
|
void diffProjects(const QStringList &projectPaths);
|
||||||
|
// index -> working tree
|
||||||
|
void diffRepository();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void slotFileListReceived(const QByteArray &data);
|
||||||
|
void slotFileContentsReceived(const QByteArray &data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void collectFilesList(const QStringList &additionalArguments);
|
||||||
|
void collectFilesContents();
|
||||||
|
void feedEditor();
|
||||||
|
QString workingTreeContents(const QString &fileName) const;
|
||||||
|
|
||||||
|
const QString m_gitPath;
|
||||||
|
const QString m_workingDirectory;
|
||||||
|
const QProcessEnvironment m_processEnvironment;
|
||||||
|
QWeakPointer<DiffEditor::DiffEditorWidget> m_editor;
|
||||||
|
const int m_timeout;
|
||||||
|
const QString m_waitMessage;
|
||||||
|
|
||||||
|
enum RevisionType {
|
||||||
|
Head = 0x01,
|
||||||
|
Index = 0x02,
|
||||||
|
WorkingTree = 0x04
|
||||||
|
};
|
||||||
|
|
||||||
|
QStringList m_requestedHeadFileNames;
|
||||||
|
QStringList m_requestedIndexFileNames;
|
||||||
|
|
||||||
|
QStringList m_headFileNames;
|
||||||
|
QStringList m_indexFileNames;
|
||||||
|
|
||||||
|
QStringList m_headContents;
|
||||||
|
QStringList m_indexContents;
|
||||||
|
};
|
||||||
|
|
||||||
|
GitDiffHandler::GitDiffHandler(const QString &gitPath,
|
||||||
|
const QString &workingDirectory,
|
||||||
|
const QProcessEnvironment &environment,
|
||||||
|
DiffEditor::DiffEditorWidget *editor,
|
||||||
|
int timeout)
|
||||||
|
: m_gitPath(gitPath),
|
||||||
|
m_workingDirectory(workingDirectory),
|
||||||
|
m_processEnvironment(environment),
|
||||||
|
m_editor(editor),
|
||||||
|
m_timeout(timeout),
|
||||||
|
m_waitMessage(tr("Waiting for data..."))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::diffFile(const QString &fileName)
|
||||||
|
{
|
||||||
|
m_requestedIndexFileNames << fileName;
|
||||||
|
collectFilesList(QStringList() << QLatin1String("--") << m_requestedIndexFileNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::diffFiles(const QStringList &stagedFileNames, const QStringList &unstagedFileNames)
|
||||||
|
{
|
||||||
|
m_requestedHeadFileNames = stagedFileNames;
|
||||||
|
m_requestedHeadFileNames.removeDuplicates();
|
||||||
|
m_requestedIndexFileNames = unstagedFileNames;
|
||||||
|
m_requestedIndexFileNames.removeDuplicates();
|
||||||
|
|
||||||
|
m_headFileNames = m_requestedHeadFileNames;
|
||||||
|
m_indexFileNames = m_requestedIndexFileNames;
|
||||||
|
for (int i = 0; i < m_headFileNames.count(); i++) {
|
||||||
|
const QString headFileName = m_headFileNames.at(i);
|
||||||
|
if (!m_indexFileNames.contains(headFileName))
|
||||||
|
m_indexFileNames.append(headFileName);
|
||||||
|
}
|
||||||
|
collectFilesContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::diffProjects(const QStringList &projectPaths)
|
||||||
|
{
|
||||||
|
collectFilesList(QStringList() << QLatin1String("--") << projectPaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::diffRepository()
|
||||||
|
{
|
||||||
|
collectFilesList(QStringList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::collectFilesList(const QStringList &additionalArguments)
|
||||||
|
{
|
||||||
|
m_editor.data()->clear(m_waitMessage);
|
||||||
|
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
|
||||||
|
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotFileListReceived(QByteArray)));
|
||||||
|
QStringList arguments;
|
||||||
|
arguments << QLatin1String("diff") << QLatin1String("--name-only") << additionalArguments;
|
||||||
|
command->addJob(arguments, m_timeout);
|
||||||
|
command->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::slotFileListReceived(const QByteArray &data)
|
||||||
|
{
|
||||||
|
if (m_editor.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QString fileList = m_editor.data()->codec()->toUnicode(data);
|
||||||
|
m_requestedIndexFileNames = fileList.split(QLatin1Char('\n'), QString::SkipEmptyParts);
|
||||||
|
m_requestedIndexFileNames.removeDuplicates();
|
||||||
|
m_indexFileNames = m_requestedIndexFileNames;
|
||||||
|
|
||||||
|
collectFilesContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::collectFilesContents()
|
||||||
|
{
|
||||||
|
const int headFilesReceived = m_headContents.count();
|
||||||
|
const int indexFilesReceived = m_indexContents.count();
|
||||||
|
|
||||||
|
if (headFilesReceived < m_headFileNames.count()) {
|
||||||
|
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
|
||||||
|
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotFileContentsReceived(QByteArray)));
|
||||||
|
|
||||||
|
QStringList arguments;
|
||||||
|
arguments << QLatin1String("show") << QLatin1String("HEAD:./") + m_headFileNames.at(headFilesReceived);
|
||||||
|
command->addJob(arguments, m_timeout);
|
||||||
|
command->execute();
|
||||||
|
} else if (indexFilesReceived < m_indexFileNames.count()) {
|
||||||
|
VcsBase::Command *command = new VcsBase::Command(m_gitPath, m_workingDirectory, m_processEnvironment);
|
||||||
|
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(slotFileContentsReceived(QByteArray)));
|
||||||
|
|
||||||
|
QStringList arguments;
|
||||||
|
arguments << QLatin1String("show") << QLatin1String(":./") + m_indexFileNames.at(indexFilesReceived);
|
||||||
|
command->addJob(arguments, m_timeout);
|
||||||
|
command->execute();
|
||||||
|
} else {
|
||||||
|
feedEditor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::slotFileContentsReceived(const QByteArray &data)
|
||||||
|
{
|
||||||
|
if (m_editor.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const int headFilesReceived = m_headContents.count();
|
||||||
|
const int indexFilesReceived = m_indexContents.count();
|
||||||
|
const QString contents = m_editor.data()->codec()->toUnicode(data);
|
||||||
|
if (headFilesReceived < m_headFileNames.count())
|
||||||
|
m_headContents.append(contents);
|
||||||
|
else if (indexFilesReceived < m_indexFileNames.count())
|
||||||
|
m_indexContents.append(contents);
|
||||||
|
|
||||||
|
collectFilesContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GitDiffHandler::feedEditor()
|
||||||
|
{
|
||||||
|
QList<DiffEditor::DiffEditorWidget::DiffFilesContents> list;
|
||||||
|
|
||||||
|
for (int i = 0; i < m_requestedHeadFileNames.count(); i++) {
|
||||||
|
const QString fileName = m_requestedHeadFileNames.at(i);
|
||||||
|
const QString original = m_headContents.at(i);
|
||||||
|
const int idx = m_indexFileNames.indexOf(fileName);
|
||||||
|
if (idx >= 0) {
|
||||||
|
const QString modified = m_indexContents.at(idx);
|
||||||
|
if (original != modified) {
|
||||||
|
DiffEditor::DiffEditorWidget::DiffFilesContents dfc;
|
||||||
|
dfc.leftFileInfo = DiffEditor::DiffEditorWidget::DiffFileInfo(fileName, tr("Head"));
|
||||||
|
dfc.leftText = original;
|
||||||
|
dfc.rightFileInfo = DiffEditor::DiffEditorWidget::DiffFileInfo(fileName, tr("Index"));
|
||||||
|
dfc.rightText = modified;
|
||||||
|
list.append(dfc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < m_requestedIndexFileNames.count(); i++) {
|
||||||
|
const QString fileName = m_requestedIndexFileNames.at(i);
|
||||||
|
const QString original = m_indexContents.at(i);
|
||||||
|
const QString modified = workingTreeContents(fileName);
|
||||||
|
if (original != modified) {
|
||||||
|
DiffEditor::DiffEditorWidget::DiffFilesContents dfc;
|
||||||
|
dfc.leftFileInfo = DiffEditor::DiffEditorWidget::DiffFileInfo(fileName, tr("Index"));
|
||||||
|
dfc.leftText = original;
|
||||||
|
dfc.rightFileInfo = DiffEditor::DiffEditorWidget::DiffFileInfo(fileName, tr("Working tree"));
|
||||||
|
dfc.rightText = modified;
|
||||||
|
list.append(dfc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_editor.data()->setDiff(list, m_workingDirectory);
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString GitDiffHandler::workingTreeContents(const QString &fileName) const
|
||||||
|
{
|
||||||
|
QDir workingDir(m_workingDirectory);
|
||||||
|
QString absoluteFileName = workingDir.absoluteFilePath(fileName);
|
||||||
|
|
||||||
|
QFile file(absoluteFileName);
|
||||||
|
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
return m_editor.data()->codec()->toUnicode(file.readAll());
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class BaseGitDiffArgumentsWidget : public VcsBase::VcsBaseEditorParameterWidget
|
class BaseGitDiffArgumentsWidget : public VcsBase::VcsBaseEditorParameterWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -506,6 +728,22 @@ VcsBase::VcsBaseEditorWidget *GitClient::findExistingVCSEditor(const char *regis
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiffEditor::DiffEditorWidget *GitClient::findExistingDiffEditor(const char *registerDynamicProperty,
|
||||||
|
const QString &dynamicPropertyValue) const
|
||||||
|
{
|
||||||
|
DiffEditor::DiffEditorWidget *editorWidget = 0;
|
||||||
|
Core::IEditor *outputEditor = locateEditor(registerDynamicProperty, dynamicPropertyValue);
|
||||||
|
if (!outputEditor)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Exists already
|
||||||
|
Core::EditorManager::activateEditor(outputEditor, Core::EditorManager::ModeSwitch);
|
||||||
|
outputEditor->createNew(m_msgWait);
|
||||||
|
editorWidget = diffEditorWidget(outputEditor);
|
||||||
|
|
||||||
|
return editorWidget;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create an editor associated to VCS output of a source file/directory
|
/* 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
|
* (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
|
* existing instance and to reuse it (in case, say, 'git diff foo' is
|
||||||
@@ -549,94 +787,153 @@ VcsBase::VcsBaseEditorWidget *GitClient::createVcsEditor(const Core::Id &id,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiffEditor::DiffEditorWidget *GitClient::diffEditorWidget(const Core::IEditor *editor) const
|
||||||
|
{
|
||||||
|
if (const DiffEditor::DiffEditorEditable *de = qobject_cast<const DiffEditor::DiffEditorEditable *>(editor))
|
||||||
|
return de->editorWidget();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void GitClient::diff(const QString &workingDirectory,
|
void GitClient::diff(const QString &workingDirectory,
|
||||||
const QStringList &diffArgs,
|
const QStringList &diffArgs,
|
||||||
const QStringList &unstagedFileNames,
|
const QStringList &unstagedFileNames,
|
||||||
const QStringList &stagedFileNames)
|
const QStringList &stagedFileNames)
|
||||||
{
|
{
|
||||||
const QString binary = settings()->stringValue(GitSettings::binaryPathKey);
|
if (settings()->boolValue(GitSettings::useDiffEditorKey)) {
|
||||||
const Core::Id editorId = Git::Constants::GIT_DIFF_EDITOR_ID;
|
const Core::Id editorId = DiffEditor::Constants::DIFF_EDITOR_ID;
|
||||||
const QString title = tr("Git Diff");
|
QString title = tr("Git Diff");
|
||||||
|
|
||||||
VcsBase::VcsBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", workingDirectory);
|
DiffEditor::DiffEditorWidget *editorWidget = findExistingDiffEditor("originalFileName", workingDirectory);
|
||||||
if (!editor) {
|
|
||||||
GitCommitDiffArgumentsWidget *argWidget =
|
|
||||||
new GitCommitDiffArgumentsWidget(this, workingDirectory, diffArgs,
|
|
||||||
unstagedFileNames, stagedFileNames);
|
|
||||||
|
|
||||||
editor = createVcsEditor(editorId, title,
|
if (!editorWidget) {
|
||||||
workingDirectory, CodecSource, "originalFileName", workingDirectory, argWidget);
|
Core::IEditor *outputEditor = Core::EditorManager::openEditorWithContents(editorId, &title, m_msgWait);
|
||||||
connect(editor, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)), argWidget, SLOT(executeCommand()));
|
outputEditor->document()->setProperty("originalFileName", workingDirectory);
|
||||||
}
|
Core::EditorManager::activateEditor(outputEditor, Core::EditorManager::ModeSwitch); // should probably go outside this block
|
||||||
|
|
||||||
GitCommitDiffArgumentsWidget *argWidget = qobject_cast<GitCommitDiffArgumentsWidget *>(editor->configurationWidget());
|
editorWidget = diffEditorWidget(outputEditor);
|
||||||
QStringList userDiffArgs = argWidget->arguments();
|
}
|
||||||
editor->setDiffBaseDirectory(workingDirectory);
|
|
||||||
|
|
||||||
// Create a batch of 2 commands to be run after each other in case
|
int timeout = settings()->intValue(GitSettings::timeoutKey);
|
||||||
// we have a mixture of staged/unstaged files as is the case
|
GitDiffHandler *handler = new GitDiffHandler(gitBinaryPath(), workingDirectory, processEnvironment(), editorWidget, timeout);
|
||||||
// when using the submit dialog.
|
|
||||||
VcsBase::Command *command = createCommand(workingDirectory, editor);
|
|
||||||
// Directory diff?
|
|
||||||
|
|
||||||
QStringList cmdArgs;
|
if (unstagedFileNames.empty() && stagedFileNames.empty()) {
|
||||||
cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption);
|
// local repository diff
|
||||||
|
handler->diffRepository();
|
||||||
int timeout = settings()->intValue(GitSettings::timeoutKey);
|
} else {
|
||||||
|
if (!stagedFileNames.empty()) {
|
||||||
if (unstagedFileNames.empty() && stagedFileNames.empty()) {
|
// diff of selected files only with --cached option, used in commit editor
|
||||||
QStringList arguments(cmdArgs);
|
handler->diffFiles(stagedFileNames, unstagedFileNames);
|
||||||
arguments << userDiffArgs;
|
} else if (!unstagedFileNames.empty()) {
|
||||||
outputWindow()->appendCommand(workingDirectory, binary, arguments);
|
// current project diff
|
||||||
command->addJob(arguments, timeout);
|
handler->diffProjects(unstagedFileNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Files diff.
|
const QString binary = settings()->stringValue(GitSettings::binaryPathKey);
|
||||||
if (!unstagedFileNames.empty()) {
|
const Core::Id editorId = Git::Constants::GIT_DIFF_EDITOR_ID;
|
||||||
QStringList arguments(cmdArgs);
|
const QString title = tr("Git Diff");
|
||||||
arguments << userDiffArgs;
|
|
||||||
arguments << QLatin1String("--") << unstagedFileNames;
|
VcsBase::VcsBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", workingDirectory);
|
||||||
outputWindow()->appendCommand(workingDirectory, binary, arguments);
|
if (!editor) {
|
||||||
command->addJob(arguments, timeout);
|
GitCommitDiffArgumentsWidget *argWidget =
|
||||||
|
new GitCommitDiffArgumentsWidget(this, workingDirectory, diffArgs,
|
||||||
|
unstagedFileNames, stagedFileNames);
|
||||||
|
|
||||||
|
editor = createVcsEditor(editorId, title,
|
||||||
|
workingDirectory, CodecSource, "originalFileName", workingDirectory, argWidget);
|
||||||
|
connect(editor, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)), argWidget, SLOT(executeCommand()));
|
||||||
}
|
}
|
||||||
if (!stagedFileNames.empty()) {
|
|
||||||
QStringList arguments(cmdArgs);
|
GitCommitDiffArgumentsWidget *argWidget = qobject_cast<GitCommitDiffArgumentsWidget *>(editor->configurationWidget());
|
||||||
arguments << userDiffArgs;
|
QStringList userDiffArgs = argWidget->arguments();
|
||||||
arguments << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames;
|
editor->setDiffBaseDirectory(workingDirectory);
|
||||||
outputWindow()->appendCommand(workingDirectory, binary, arguments);
|
|
||||||
command->addJob(arguments, timeout);
|
// Create a batch of 2 commands to be run after each other in case
|
||||||
|
// we have a mixture of staged/unstaged files as is the case
|
||||||
|
// when using the submit dialog.
|
||||||
|
VcsBase::Command *command = createCommand(workingDirectory, editor);
|
||||||
|
// Directory diff?
|
||||||
|
|
||||||
|
QStringList cmdArgs;
|
||||||
|
cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption);
|
||||||
|
|
||||||
|
int timeout = settings()->intValue(GitSettings::timeoutKey);
|
||||||
|
|
||||||
|
if (unstagedFileNames.empty() && stagedFileNames.empty()) {
|
||||||
|
QStringList arguments(cmdArgs);
|
||||||
|
arguments << userDiffArgs;
|
||||||
|
outputWindow()->appendCommand(workingDirectory, binary, arguments);
|
||||||
|
command->addJob(arguments, timeout);
|
||||||
|
} else {
|
||||||
|
// Files diff.
|
||||||
|
if (!unstagedFileNames.empty()) {
|
||||||
|
QStringList arguments(cmdArgs);
|
||||||
|
arguments << userDiffArgs;
|
||||||
|
arguments << QLatin1String("--") << unstagedFileNames;
|
||||||
|
outputWindow()->appendCommand(workingDirectory, binary, arguments);
|
||||||
|
command->addJob(arguments, timeout);
|
||||||
|
}
|
||||||
|
if (!stagedFileNames.empty()) {
|
||||||
|
QStringList arguments(cmdArgs);
|
||||||
|
arguments << userDiffArgs;
|
||||||
|
arguments << QLatin1String("--cached") << diffArgs << QLatin1String("--") << stagedFileNames;
|
||||||
|
outputWindow()->appendCommand(workingDirectory, binary, arguments);
|
||||||
|
command->addJob(arguments, timeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
command->execute();
|
||||||
}
|
}
|
||||||
command->execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GitClient::diff(const QString &workingDirectory,
|
void GitClient::diff(const QString &workingDirectory,
|
||||||
const QStringList &diffArgs,
|
const QStringList &diffArgs,
|
||||||
const QString &fileName)
|
const QString &fileName)
|
||||||
{
|
{
|
||||||
const Core::Id editorId = Git::Constants::GIT_DIFF_EDITOR_ID;
|
if (settings()->boolValue(GitSettings::useDiffEditorKey)) {
|
||||||
const QString title = tr("Git Diff \"%1\"").arg(fileName);
|
const Core::Id editorId = DiffEditor::Constants::DIFF_EDITOR_ID;
|
||||||
const QString sourceFile = VcsBase::VcsBaseEditorWidget::getSource(workingDirectory, fileName);
|
QString title = tr("Git Diff \"%1\"").arg(fileName);
|
||||||
|
const QString sourceFile = VcsBase::VcsBaseEditorWidget::getSource(workingDirectory, fileName);
|
||||||
|
|
||||||
VcsBase::VcsBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", sourceFile);
|
DiffEditor::DiffEditorWidget *editorWidget = findExistingDiffEditor("originalFileName", sourceFile);
|
||||||
if (!editor) {
|
if (!editorWidget) {
|
||||||
GitFileDiffArgumentsWidget *argWidget =
|
Core::IEditor *outputEditor = Core::EditorManager::openEditorWithContents(editorId, &title, m_msgWait);
|
||||||
new GitFileDiffArgumentsWidget(this, workingDirectory, diffArgs, fileName);
|
outputEditor->document()->setProperty("originalFileName", sourceFile);
|
||||||
|
Core::EditorManager::activateEditor(outputEditor, Core::EditorManager::ModeSwitch);
|
||||||
|
|
||||||
editor = createVcsEditor(editorId, title, sourceFile, CodecSource, "originalFileName", sourceFile, argWidget);
|
editorWidget = diffEditorWidget(outputEditor);
|
||||||
connect(editor, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)), argWidget, SLOT(executeCommand()));
|
}
|
||||||
|
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
int timeout = settings()->intValue(GitSettings::timeoutKey);
|
||||||
|
GitDiffHandler *handler = new GitDiffHandler(gitBinaryPath(), workingDirectory, processEnvironment(), editorWidget, timeout);
|
||||||
|
handler->diffFile(fileName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const Core::Id editorId = Git::Constants::GIT_DIFF_EDITOR_ID;
|
||||||
|
const QString title = tr("Git Diff \"%1\"").arg(fileName);
|
||||||
|
const QString sourceFile = VcsBase::VcsBaseEditorWidget::getSource(workingDirectory, fileName);
|
||||||
|
|
||||||
|
VcsBase::VcsBaseEditorWidget *editor = findExistingVCSEditor("originalFileName", sourceFile);
|
||||||
|
if (!editor) {
|
||||||
|
GitFileDiffArgumentsWidget *argWidget =
|
||||||
|
new GitFileDiffArgumentsWidget(this, workingDirectory, diffArgs, fileName);
|
||||||
|
|
||||||
|
editor = createVcsEditor(editorId, title, sourceFile, CodecSource, "originalFileName", sourceFile, argWidget);
|
||||||
|
connect(editor, SIGNAL(diffChunkReverted(VcsBase::DiffChunk)), argWidget, SLOT(executeCommand()));
|
||||||
|
}
|
||||||
|
editor->setDiffBaseDirectory(workingDirectory);
|
||||||
|
|
||||||
|
GitFileDiffArgumentsWidget *argWidget = qobject_cast<GitFileDiffArgumentsWidget *>(editor->configurationWidget());
|
||||||
|
QStringList userDiffArgs = argWidget->arguments();
|
||||||
|
|
||||||
|
QStringList cmdArgs;
|
||||||
|
cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption)
|
||||||
|
<< userDiffArgs;
|
||||||
|
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
cmdArgs << QLatin1String("--") << fileName;
|
||||||
|
executeGit(workingDirectory, cmdArgs, editor);
|
||||||
}
|
}
|
||||||
editor->setDiffBaseDirectory(workingDirectory);
|
|
||||||
|
|
||||||
GitFileDiffArgumentsWidget *argWidget = qobject_cast<GitFileDiffArgumentsWidget *>(editor->configurationWidget());
|
|
||||||
QStringList userDiffArgs = argWidget->arguments();
|
|
||||||
|
|
||||||
QStringList cmdArgs;
|
|
||||||
cmdArgs << QLatin1String("diff") << QLatin1String(noColorOption)
|
|
||||||
<< userDiffArgs;
|
|
||||||
|
|
||||||
if (!fileName.isEmpty())
|
|
||||||
cmdArgs << QLatin1String("--") << fileName;
|
|
||||||
executeGit(workingDirectory, cmdArgs, editor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GitClient::diffBranch(const QString &workingDirectory,
|
void GitClient::diffBranch(const QString &workingDirectory,
|
||||||
|
|||||||
@@ -60,11 +60,16 @@ namespace Utils {
|
|||||||
struct SynchronousProcessResponse;
|
struct SynchronousProcessResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace DiffEditor {
|
||||||
|
class DiffEditorWidget;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Git {
|
namespace Git {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class GitPlugin;
|
class GitPlugin;
|
||||||
class GitOutputWindow;
|
class GitOutputWindow;
|
||||||
|
class GitDiffEditorWidget;
|
||||||
class CommitData;
|
class CommitData;
|
||||||
struct GitSubmitEditorPanelData;
|
struct GitSubmitEditorPanelData;
|
||||||
class Stash;
|
class Stash;
|
||||||
@@ -128,6 +133,8 @@ public:
|
|||||||
QString findRepositoryForDirectory(const QString &dir);
|
QString findRepositoryForDirectory(const QString &dir);
|
||||||
QString findGitDirForRepository(const QString &repositoryDir) const;
|
QString findGitDirForRepository(const QString &repositoryDir) const;
|
||||||
|
|
||||||
|
DiffEditor::DiffEditorWidget *diffEditorWidget(const Core::IEditor *editor) const;
|
||||||
|
|
||||||
void diff(const QString &workingDirectory, const QStringList &diffArgs, const QString &fileName);
|
void diff(const QString &workingDirectory, const QStringList &diffArgs, const QString &fileName);
|
||||||
void diff(const QString &workingDirectory, const QStringList &diffArgs,
|
void diff(const QString &workingDirectory, const QStringList &diffArgs,
|
||||||
const QStringList &unstagedFileNames, const QStringList &stagedFileNames= QStringList());
|
const QStringList &unstagedFileNames, const QStringList &stagedFileNames= QStringList());
|
||||||
@@ -319,6 +326,9 @@ private:
|
|||||||
QTextCodec *getSourceCodec(const QString &file) const;
|
QTextCodec *getSourceCodec(const QString &file) const;
|
||||||
VcsBase::VcsBaseEditorWidget *findExistingVCSEditor(const char *registerDynamicProperty,
|
VcsBase::VcsBaseEditorWidget *findExistingVCSEditor(const char *registerDynamicProperty,
|
||||||
const QString &dynamicPropertyValue) const;
|
const QString &dynamicPropertyValue) const;
|
||||||
|
DiffEditor::DiffEditorWidget *findExistingDiffEditor(const char *registerDynamicProperty,
|
||||||
|
const QString &dynamicPropertyValue) const;
|
||||||
|
|
||||||
enum CodecType { CodecSource, CodecLogOutput, CodecNone };
|
enum CodecType { CodecSource, CodecLogOutput, CodecNone };
|
||||||
VcsBase::VcsBaseEditorWidget *createVcsEditor(const Core::Id &kind,
|
VcsBase::VcsBaseEditorWidget *createVcsEditor(const Core::Id &kind,
|
||||||
QString title,
|
QString title,
|
||||||
|
|||||||
@@ -179,6 +179,8 @@ void GitEditor::setPlainTextDataFiltered(const QByteArray &a)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VcsBase::DiffOutput: {
|
case VcsBase::DiffOutput: {
|
||||||
|
if (array.isEmpty())
|
||||||
|
array = QByteArray("No difference to HEAD");
|
||||||
const QFileInfo fi(source());
|
const QFileInfo fi(source());
|
||||||
const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
|
const QString workingDirectory = fi.isDir() ? fi.absoluteFilePath() : fi.absolutePath();
|
||||||
QByteArray precedes, follows;
|
QByteArray precedes, follows;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
namespace Git {
|
namespace Git {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
const QLatin1String GitSettings::useDiffEditorKey("UseDiffEditor");
|
||||||
const QLatin1String GitSettings::pullRebaseKey("PullRebase");
|
const QLatin1String GitSettings::pullRebaseKey("PullRebase");
|
||||||
const QLatin1String GitSettings::showTagsKey("ShowTags");
|
const QLatin1String GitSettings::showTagsKey("ShowTags");
|
||||||
const QLatin1String GitSettings::omitAnnotationDateKey("OmitAnnotationDate");
|
const QLatin1String GitSettings::omitAnnotationDateKey("OmitAnnotationDate");
|
||||||
@@ -54,6 +55,7 @@ GitSettings::GitSettings()
|
|||||||
|
|
||||||
declareKey(binaryPathKey, QLatin1String("git"));
|
declareKey(binaryPathKey, QLatin1String("git"));
|
||||||
declareKey(timeoutKey, Utils::HostOsInfo::isWindowsHost() ? 60 : 30);
|
declareKey(timeoutKey, Utils::HostOsInfo::isWindowsHost() ? 60 : 30);
|
||||||
|
declareKey(useDiffEditorKey, true);
|
||||||
declareKey(pullRebaseKey, false);
|
declareKey(pullRebaseKey, false);
|
||||||
declareKey(showTagsKey, false);
|
declareKey(showTagsKey, false);
|
||||||
declareKey(omitAnnotationDateKey, false);
|
declareKey(omitAnnotationDateKey, false);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class GitSettings : public VcsBase::VcsBaseClientSettings
|
|||||||
public:
|
public:
|
||||||
GitSettings();
|
GitSettings();
|
||||||
|
|
||||||
|
static const QLatin1String useDiffEditorKey;
|
||||||
static const QLatin1String pullRebaseKey;
|
static const QLatin1String pullRebaseKey;
|
||||||
static const QLatin1String showTagsKey;
|
static const QLatin1String showTagsKey;
|
||||||
static const QLatin1String omitAnnotationDateKey;
|
static const QLatin1String omitAnnotationDateKey;
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ GitSettings SettingsPageWidget::settings() const
|
|||||||
rc.setValue(GitSettings::pathKey, m_ui.pathLineEdit->text());
|
rc.setValue(GitSettings::pathKey, m_ui.pathLineEdit->text());
|
||||||
rc.setValue(GitSettings::logCountKey, m_ui.logCountSpinBox->value());
|
rc.setValue(GitSettings::logCountKey, m_ui.logCountSpinBox->value());
|
||||||
rc.setValue(GitSettings::timeoutKey, m_ui.timeoutSpinBox->value());
|
rc.setValue(GitSettings::timeoutKey, m_ui.timeoutSpinBox->value());
|
||||||
|
rc.setValue(GitSettings::useDiffEditorKey, m_ui.useDiffEditorCheckBox->isChecked());
|
||||||
rc.setValue(GitSettings::pullRebaseKey, m_ui.pullRebaseCheckBox->isChecked());
|
rc.setValue(GitSettings::pullRebaseKey, m_ui.pullRebaseCheckBox->isChecked());
|
||||||
rc.setValue(GitSettings::showTagsKey, m_ui.showTagsCheckBox->isChecked());
|
rc.setValue(GitSettings::showTagsKey, m_ui.showTagsCheckBox->isChecked());
|
||||||
rc.setValue(GitSettings::promptOnSubmitKey, m_ui.promptToSubmitCheckBox->isChecked());
|
rc.setValue(GitSettings::promptOnSubmitKey, m_ui.promptToSubmitCheckBox->isChecked());
|
||||||
@@ -84,6 +85,7 @@ void SettingsPageWidget::setSettings(const GitSettings &s)
|
|||||||
m_ui.pathLineEdit->setText(s.stringValue(GitSettings::pathKey));
|
m_ui.pathLineEdit->setText(s.stringValue(GitSettings::pathKey));
|
||||||
m_ui.logCountSpinBox->setValue(s.intValue(GitSettings::logCountKey));
|
m_ui.logCountSpinBox->setValue(s.intValue(GitSettings::logCountKey));
|
||||||
m_ui.timeoutSpinBox->setValue(s.intValue(GitSettings::timeoutKey));
|
m_ui.timeoutSpinBox->setValue(s.intValue(GitSettings::timeoutKey));
|
||||||
|
m_ui.useDiffEditorCheckBox->setChecked(s.boolValue(GitSettings::useDiffEditorKey));
|
||||||
m_ui.pullRebaseCheckBox->setChecked(s.boolValue(GitSettings::pullRebaseKey));
|
m_ui.pullRebaseCheckBox->setChecked(s.boolValue(GitSettings::pullRebaseKey));
|
||||||
m_ui.showTagsCheckBox->setChecked(s.boolValue(GitSettings::showTagsKey));
|
m_ui.showTagsCheckBox->setChecked(s.boolValue(GitSettings::showTagsKey));
|
||||||
m_ui.promptToSubmitCheckBox->setChecked(s.boolValue(GitSettings::promptOnSubmitKey));
|
m_ui.promptToSubmitCheckBox->setChecked(s.boolValue(GitSettings::promptOnSubmitKey));
|
||||||
|
|||||||
@@ -137,6 +137,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QCheckBox" name="useDiffEditorCheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use Diff Editor</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -271,19 +271,13 @@ void Command::run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special hack: Always produce output for diff
|
if (ok && d->m_jobs.front().arguments.at(0) == QLatin1String("status"))
|
||||||
if (ok && stdOut.isEmpty() && d->m_jobs.front().arguments.at(0) == QLatin1String("diff")) {
|
removeColorCodes(&stdOut);
|
||||||
stdOut += "No difference to HEAD";
|
|
||||||
} else {
|
|
||||||
// @TODO: Remove, see below
|
|
||||||
if (ok && d->m_jobs.front().arguments.at(0) == QLatin1String("status"))
|
|
||||||
removeColorCodes(&stdOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
d->m_lastExecSuccess = ok;
|
d->m_lastExecSuccess = ok;
|
||||||
d->m_lastExecExitCode = exitCode;
|
d->m_lastExecExitCode = exitCode;
|
||||||
|
|
||||||
if (ok && !stdOut.isEmpty())
|
if (ok)
|
||||||
emit outputData(stdOut);
|
emit outputData(stdOut);
|
||||||
|
|
||||||
if (!error.isEmpty())
|
if (!error.isEmpty())
|
||||||
|
|||||||
Reference in New Issue
Block a user