Add file list combobox to diff editor

Change-Id: I2a40207ed3c4a5c07ba544d681aed6649a0b1a11
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
jkobus
2013-05-23 13:36:27 +02:00
committed by Jarek Kobus
parent 13504eec18
commit 2ddb726dd5
8 changed files with 227 additions and 85 deletions

View File

@@ -39,6 +39,9 @@
#include <QStyle>
#include <QLabel>
#include <QHBoxLayout>
#include <QToolBar>
#include <QComboBox>
#include <QFileInfo>
namespace DiffEditor {
@@ -48,9 +51,12 @@ DiffEditorEditable::DiffEditorEditable(DiffEditorWidget *editorWidget)
: IEditor(0),
m_file(new Internal::DiffEditorFile(QLatin1String(Constants::DIFF_EDITOR_MIMETYPE), this)),
m_editorWidget(editorWidget),
m_toolWidget(0)
m_toolWidget(0),
m_entriesComboBox(0)
{
setWidget(editorWidget);
connect(m_editorWidget, SIGNAL(navigatedToDiffFile(int)),
this, SLOT(activateEntry(int)));
}
DiffEditorEditable::~DiffEditorEditable()
@@ -115,7 +121,6 @@ static QToolBar *createToolBar(const QWidget *someWidget)
toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
const int size = someWidget->style()->pixelMetric(QStyle::PM_SmallIconSize);
toolBar->setIconSize(QSize(size, size));
toolBar->addSeparator();
return toolBar;
}
@@ -128,12 +133,15 @@ QWidget *DiffEditorEditable::toolBar()
// Create
m_toolWidget = createToolBar(m_editorWidget);
QWidget *spacerWidget = new QWidget();
QLayout *spacerLayout = new QHBoxLayout();
spacerLayout->setMargin(0);
spacerLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
spacerWidget->setLayout(spacerLayout);
m_toolWidget->addWidget(spacerWidget);
m_entriesComboBox = new QComboBox;
m_entriesComboBox->setMinimumContentsLength(20);
// Make the combo box prefer to expand
QSizePolicy policy = m_entriesComboBox->sizePolicy();
policy.setHorizontalPolicy(QSizePolicy::Expanding);
m_entriesComboBox->setSizePolicy(policy);
connect(m_entriesComboBox, SIGNAL(activated(int)),
this, SLOT(entryActivated(int)));
m_toolWidget->addWidget(m_entriesComboBox);
QToolButton *whitespaceButton = new QToolButton(m_toolWidget);
whitespaceButton->setText(tr("Ignore Whitespace"));
@@ -156,6 +164,78 @@ QWidget *DiffEditorEditable::toolBar()
return m_toolWidget;
}
void DiffEditorEditable::setDiff(const QList<DiffEditorWidget::DiffFilesContents> &diffFileList,
const QString &workingDirectory)
{
m_entriesComboBox->clear();
const int count = diffFileList.count();
for (int i = 0; i < count; i++) {
const DiffEditorWidget::DiffFileInfo leftEntry = diffFileList.at(i).leftFileInfo;
const DiffEditorWidget::DiffFileInfo rightEntry = diffFileList.at(i).rightFileInfo;
const QString leftShortFileName = QFileInfo(leftEntry.fileName).fileName();
const QString rightShortFileName = QFileInfo(rightEntry.fileName).fileName();
QString itemText;
QString itemToolTip;
if (leftEntry.fileName == rightEntry.fileName) {
itemText = leftShortFileName;
if (leftEntry.typeInfo.isEmpty() && rightEntry.typeInfo.isEmpty()) {
itemToolTip = leftEntry.fileName;
} else {
itemToolTip = tr("[%1] vs. [%2] %3")
.arg(leftEntry.typeInfo, rightEntry.typeInfo, leftEntry.fileName);
}
} else {
if (leftShortFileName == rightShortFileName) {
itemText = leftShortFileName;
} else {
itemText = tr("%1 vs. %2")
.arg(leftShortFileName, rightShortFileName);
}
if (leftEntry.typeInfo.isEmpty() && rightEntry.typeInfo.isEmpty()) {
itemToolTip = tr("%1 vs. %2")
.arg(leftEntry.fileName, rightEntry.fileName);
} else {
itemToolTip = tr("[%1] %2 vs. [%3] %4")
.arg(leftEntry.typeInfo, leftEntry.fileName, rightEntry.typeInfo, rightEntry.fileName);
}
}
m_entriesComboBox->addItem(itemText);
m_entriesComboBox->setItemData(m_entriesComboBox->count() - 1, itemToolTip, Qt::ToolTipRole);
}
updateEntryToolTip();
m_editorWidget->setDiff(diffFileList, workingDirectory);
}
void DiffEditorEditable::clear(const QString &message)
{
m_entriesComboBox->clear();
updateEntryToolTip();
m_editorWidget->clear(message);
}
void DiffEditorEditable::updateEntryToolTip()
{
const QString &toolTip = m_entriesComboBox->itemData(
m_entriesComboBox->currentIndex(), Qt::ToolTipRole).toString();
m_entriesComboBox->setToolTip(toolTip);
}
void DiffEditorEditable::entryActivated(int index)
{
updateEntryToolTip();
m_editorWidget->navigateToDiffFile(index);
}
void DiffEditorEditable::activateEntry(int index)
{
m_entriesComboBox->blockSignals(true);
m_entriesComboBox->setCurrentIndex(index);
m_entriesComboBox->blockSignals(false);
updateEntryToolTip();
}
QByteArray DiffEditorEditable::saveState() const
{
return QByteArray();

View File

@@ -31,16 +31,18 @@
#define DIFFEDITOREDITABLE_H
#include "diffeditor_global.h"
#include "diffeditorwidget.h"
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <QToolBar>
QT_BEGIN_NAMESPACE
class QToolBar;
class QComboBox;
QT_END_NAMESPACE
namespace DiffEditor {
class DiffEditorWidget;
namespace Internal {
class DiffEditorFile;
}
@@ -53,6 +55,10 @@ public:
virtual ~DiffEditorEditable();
public:
void setDiff(const QList<DiffEditorWidget::DiffFilesContents> &diffFileList,
const QString &workingDirectory = QString());
void clear(const QString &message);
// Core::IEditor
bool createNew(const QString &contents);
bool open(QString *errorString, const QString &fileName, const QString &realFileName);
@@ -69,11 +75,19 @@ public:
QByteArray saveState() const;
bool restoreState(const QByteArray &state);
public slots:
void activateEntry(int index);
private slots:
void entryActivated(int index);
private:
void updateEntryToolTip();
Internal::DiffEditorFile *m_file;
DiffEditorWidget *m_editorWidget;
QToolBar *m_toolWidget;
QComboBox *m_entriesComboBox;
mutable QString m_displayName;
};

View File

@@ -136,31 +136,28 @@ void DiffEditorPlugin::diff()
const Core::Id editorId = Constants::DIFF_EDITOR_ID;
//: Editor title
QString title = tr("Diff \"%1\", \"%2\"").arg(fileName1).arg(fileName2);
Core::IEditor *outputEditor = Core::EditorManager::openEditorWithContents(editorId, &title, QString());
Core::EditorManager::activateEditor(outputEditor, Core::EditorManager::ModeSwitch);
DiffEditorEditable *editorEditable = qobject_cast<DiffEditorEditable *>
(Core::EditorManager::openEditorWithContents(editorId, &title, QString()));
DiffEditorWidget *editorWidget = getDiffEditorWidget(outputEditor);
if (editorWidget) {
const QString text1 = getFileContents(fileName1, editorWidget->codec());
const QString text2 = getFileContents(fileName2, editorWidget->codec());
if (!editorEditable)
return;
DiffEditorWidget::DiffFilesContents dfc;
dfc.leftFileInfo = fileName1;
dfc.leftText = text1;
dfc.rightFileInfo = fileName2;
dfc.rightText = text2;
QList<DiffEditorWidget::DiffFilesContents> list;
list.append(dfc);
Core::EditorManager::activateEditor(editorEditable, Core::EditorManager::ModeSwitch);
editorWidget->setDiff(list);
}
}
DiffEditorWidget *editorWidget = editorEditable->editorWidget();
DiffEditorWidget *DiffEditorPlugin::getDiffEditorWidget(const Core::IEditor *editor) const
{
if (const DiffEditorEditable *de = qobject_cast<const DiffEditorEditable *>(editor))
return de->editorWidget();
return 0;
const QString text1 = getFileContents(fileName1, editorWidget->codec());
const QString text2 = getFileContents(fileName2, editorWidget->codec());
DiffEditorWidget::DiffFilesContents dfc;
dfc.leftFileInfo = fileName1;
dfc.leftText = text1;
dfc.rightFileInfo = fileName2;
dfc.rightText = text2;
QList<DiffEditorWidget::DiffFilesContents> list;
list.append(dfc);
editorEditable->setDiff(list);
}
QString DiffEditorPlugin::getFileContents(const QString &fileName, QTextCodec *codec) const

View File

@@ -66,7 +66,6 @@ private slots:
void diff();
private:
DiffEditorWidget *getDiffEditorWidget(const Core::IEditor *editor) const;
QString getFileContents(const QString &fileName, QTextCodec *codec) const;
};

View File

@@ -131,6 +131,8 @@ public:
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_fileInfo.contains(blockNumber); }
int blockNumberForFileIndex(int fileIndex) const;
int fileIndexForBlockNumber(int blockNumber) const;
bool isChunkLine(int blockNumber) const { return m_skippedLines.contains(blockNumber); }
void clearAll();
void clearAll(const QString &message);
@@ -243,6 +245,36 @@ void DiffViewEditorWidget::setLineNumber(int blockNumber, int lineNumber)
m_lineNumberDigits = qMax(m_lineNumberDigits, lineNumberString.count());
}
int DiffViewEditorWidget::blockNumberForFileIndex(int fileIndex) const
{
if (fileIndex < 0 || fileIndex >= m_fileInfo.count())
return -1;
QMap<int, DiffEditorWidget::DiffFileInfo>::const_iterator it
= m_fileInfo.constBegin();
for (int i = 0; i < fileIndex; i++)
++it;
return it.key();
}
int DiffViewEditorWidget::fileIndexForBlockNumber(int blockNumber) const
{
QMap<int, DiffEditorWidget::DiffFileInfo>::const_iterator it
= m_fileInfo.constBegin();
QMap<int, DiffEditorWidget::DiffFileInfo>::const_iterator itEnd
= m_fileInfo.constEnd();
int i = -1;
while (it != itEnd) {
if (it.key() > blockNumber)
break;
++it;
++i;
}
return i;
}
void DiffViewEditorWidget::clearAll()
{
clearAll(tr("No difference"));
@@ -512,16 +544,14 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent)
this, SLOT(leftVSliderChanged()));
connect(m_leftEditor->verticalScrollBar(), SIGNAL(actionTriggered(int)),
this, SLOT(leftVSliderChanged()));
connect(m_leftEditor, SIGNAL(cursorPositionChanged()),
this, SLOT(leftVSliderChanged()));
connect(m_leftEditor->horizontalScrollBar(), SIGNAL(valueChanged(int)),
this, SLOT(leftHSliderChanged()));
connect(m_leftEditor->horizontalScrollBar(), SIGNAL(actionTriggered(int)),
this, SLOT(leftHSliderChanged()));
connect(m_leftEditor, SIGNAL(cursorPositionChanged()),
this, SLOT(leftHSliderChanged()));
connect(m_leftEditor, SIGNAL(cursorPositionChanged()),
this, SLOT(leftCursorPositionChanged()));
connect(m_leftEditor->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)),
this, SLOT(leftDocumentSizeChanged()));
@@ -529,16 +559,14 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent)
this, SLOT(rightVSliderChanged()));
connect(m_rightEditor->verticalScrollBar(), SIGNAL(actionTriggered(int)),
this, SLOT(rightVSliderChanged()));
connect(m_rightEditor, SIGNAL(cursorPositionChanged()),
this, SLOT(rightVSliderChanged()));
connect(m_rightEditor->horizontalScrollBar(), SIGNAL(valueChanged(int)),
this, SLOT(rightHSliderChanged()));
connect(m_rightEditor->horizontalScrollBar(), SIGNAL(actionTriggered(int)),
this, SLOT(rightHSliderChanged()));
connect(m_rightEditor, SIGNAL(cursorPositionChanged()),
this, SLOT(rightHSliderChanged()));
connect(m_rightEditor, SIGNAL(cursorPositionChanged()),
this, SLOT(rightCursorPositionChanged()));
connect(m_rightEditor->document()->documentLayout(), SIGNAL(documentSizeChanged(QSizeF)),
this, SLOT(rightDocumentSizeChanged()));
@@ -630,6 +658,24 @@ void DiffEditorWidget::setIgnoreWhitespaces(bool ignore)
setDiff(m_diffList);
}
void DiffEditorWidget::navigateToDiffFile(int diffFileIndex)
{
const int blockNumber = m_leftEditor->blockNumberForFileIndex(diffFileIndex);
QTextBlock leftBlock = m_leftEditor->document()->findBlockByNumber(blockNumber);
QTextCursor leftCursor = m_leftEditor->textCursor();
leftCursor.setPosition(leftBlock.position());
m_leftEditor->setTextCursor(leftCursor);
QTextBlock rightBlock = m_rightEditor->document()->findBlockByNumber(blockNumber);
QTextCursor rightCursor = m_rightEditor->textCursor();
rightCursor.setPosition(rightBlock.position());
m_rightEditor->setTextCursor(rightCursor);
m_leftEditor->centerCursor();
m_rightEditor->centerCursor();
}
QTextCodec *DiffEditorWidget::codec() const
{
return const_cast<QTextCodec *>(m_leftEditor->codec());
@@ -1329,6 +1375,20 @@ void DiffEditorWidget::rightHSliderChanged()
m_leftEditor->horizontalScrollBar()->setValue(m_rightEditor->horizontalScrollBar()->value());
}
void DiffEditorWidget::leftCursorPositionChanged()
{
leftVSliderChanged();
leftHSliderChanged();
emit navigatedToDiffFile(m_leftEditor->fileIndexForBlockNumber(m_leftEditor->textCursor().blockNumber()));
}
void DiffEditorWidget::rightCursorPositionChanged()
{
rightVSliderChanged();
rightHSliderChanged();
emit navigatedToDiffFile(m_rightEditor->fileIndexForBlockNumber(m_rightEditor->textCursor().blockNumber()));
}
void DiffEditorWidget::leftDocumentSizeChanged()
{
synchronizeFoldings(m_leftEditor, m_rightEditor);

View File

@@ -86,6 +86,10 @@ public:
public slots:
void setContextLinesNumber(int lines);
void setIgnoreWhitespaces(bool ignore);
void navigateToDiffFile(int diffFileIndex);
signals:
void navigatedToDiffFile(int diffFileIndex);
protected:
TextEditor::SnippetEditorWidget *leftEditor() const;
@@ -96,6 +100,8 @@ private slots:
void rightVSliderChanged();
void leftHSliderChanged();
void rightHSliderChanged();
void leftCursorPositionChanged();
void rightCursorPositionChanged();
void leftDocumentSizeChanged();
void rightDocumentSizeChanged();
void toggleScrollBarSynchronization(bool on);