diff --git a/src/plugins/diffeditor/diffeditorwidget.cpp b/src/plugins/diffeditor/diffeditorwidget.cpp index 48c30433fbad721ddb5e4aaa1cc06a555cf8fe0f..1c80c97881623824e35e182d2844564e8a4c298d 100644 --- a/src/plugins/diffeditor/diffeditorwidget.cpp +++ b/src/plugins/diffeditor/diffeditorwidget.cpp @@ -139,7 +139,6 @@ public: QMap<int, int> skippedLines() const { return m_skippedLines; } QMap<int, DiffEditorWidget::DiffFileInfo> fileInfo() const { return m_fileInfo; } - void setWorkingDirectory(const QString &workingDirectory) { m_workingDirectory = workingDirectory; } void setLineNumber(int blockNumber, int lineNumber); 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); } @@ -157,6 +156,11 @@ public slots: void setDisplaySettings(const DisplaySettings &ds); void setFontSettings(const TextEditor::FontSettings &fs); +signals: + void jumpToOriginalFileRequested(int diffFileIndex, + int lineNumber, + int columnNumber); + protected: virtual int extraAreaWidth(int *markWidthPtr = 0) const { return BaseTextEditorWidget::extraAreaWidth(markWidthPtr); } BaseTextEditor *createEditor() { return new DiffViewEditorEditable(this); } @@ -180,7 +184,6 @@ private: const QTextBlock &block, int top); void jumpToOriginalFile(const QTextCursor &cursor); - QString m_workingDirectory; QMap<int, int> m_lineNumbers; int m_lineNumberDigits; // block number, fileInfo @@ -430,20 +433,13 @@ void DiffViewEditorWidget::jumpToOriginalFile(const QTextCursor &cursor) return; const int blockNumber = cursor.blockNumber(); - const int position = cursor.positionInBlock(); + const int columnNumber = cursor.positionInBlock(); if (!m_lineNumbers.contains(blockNumber)) return; - const int lineNr = m_lineNumbers.value(blockNumber); - QMap<int, DiffEditorWidget::DiffFileInfo>::const_iterator it = m_fileInfo.upperBound(blockNumber); - if (it != m_fileInfo.constBegin()) - --it; - const QDir dir(m_workingDirectory); - const QString fileName = dir.absoluteFilePath(it.value().fileName); + const int lineNumber = m_lineNumbers.value(blockNumber); - Core::IEditor *ed = Core::EditorManager::openEditor(fileName); - if (TextEditor::ITextEditor *editor = qobject_cast<TextEditor::ITextEditor *>(ed)) - editor->gotoLine(lineNr, position); + emit jumpToOriginalFileRequested(fileIndexForBlockNumber(blockNumber), lineNumber, columnNumber); } void DiffViewEditorWidget::paintEvent(QPaintEvent *e) @@ -609,6 +605,8 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent) m_leftEditor, SLOT(setDisplaySettings(TextEditor::DisplaySettings))); m_leftEditor->setDisplaySettings(settings->displaySettings()); m_leftEditor->setCodeStyle(settings->codeStyle()); + connect(m_leftEditor, SIGNAL(jumpToOriginalFileRequested(int,int,int)), + this, SLOT(slotLeftJumpToOriginalFileRequested(int,int,int))); m_rightEditor = new DiffViewEditorWidget(this); m_rightEditor->setReadOnly(true); @@ -616,6 +614,8 @@ DiffEditorWidget::DiffEditorWidget(QWidget *parent) m_rightEditor, SLOT(setDisplaySettings(TextEditor::DisplaySettings))); m_rightEditor->setDisplaySettings(settings->displaySettings()); m_rightEditor->setCodeStyle(settings->codeStyle()); + connect(m_rightEditor, SIGNAL(jumpToOriginalFileRequested(int,int,int)), + this, SLOT(slotRightJumpToOriginalFileRequested(int,int,int))); connect(settings, SIGNAL(fontSettingsChanged(TextEditor::FontSettings)), this, SLOT(setFontSettings(TextEditor::FontSettings))); @@ -680,8 +680,7 @@ void DiffEditorWidget::clear(const QString &message) void DiffEditorWidget::setDiff(const QList<DiffFilesContents> &diffFileList, const QString &workingDirectory) { - m_leftEditor->setWorkingDirectory(workingDirectory); - m_rightEditor->setWorkingDirectory(workingDirectory); + m_workingDirectory = workingDirectory; Differ differ; QList<DiffList> diffList; for (int i = 0; i < diffFileList.count(); i++) { @@ -1440,6 +1439,63 @@ void DiffEditorWidget::setFontSettings(const TextEditor::FontSettings &fontSetti colorDiff(m_contextFileData); } +void DiffEditorWidget::slotLeftJumpToOriginalFileRequested(int diffFileIndex, + int lineNumber, + int columnNumber) +{ + if (diffFileIndex < 0 || diffFileIndex >= m_contextFileData.count()) + return; + + const FileData fileData = m_contextFileData.at(diffFileIndex); + const QString leftFileName = fileData.leftFileInfo.fileName; + const QString rightFileName = fileData.rightFileInfo.fileName; + if (leftFileName == rightFileName) { + // The same file (e.g. in git diff), jump to the line number taken from the right editor. + // Warning: git show SHA^ vs SHA or git diff HEAD vs Index + // (when Working tree has changed in meantime) will not work properly. + int leftLineNumber = 0; + int rightLineNumber = 0; + + for (int i = 0; i < fileData.chunks.count(); i++) { + const ChunkData chunkData = fileData.chunks.at(i); + for (int j = 0; j < chunkData.rows.count(); j++) { + const RowData rowData = chunkData.rows.at(j); + if (rowData.leftLine.textLineType == TextLineData::TextLine) + leftLineNumber++; + if (rowData.rightLine.textLineType == TextLineData::TextLine) + rightLineNumber++; + if (leftLineNumber == lineNumber) { + int colNr = rowData.equal ? columnNumber : 0; + jumpToOriginalFile(leftFileName, rightLineNumber, colNr); + return; + } + } + } + } else { + // different file (e.g. in Tools | Diff...) + jumpToOriginalFile(leftFileName, lineNumber, columnNumber); + } +} + +void DiffEditorWidget::slotRightJumpToOriginalFileRequested(int diffFileIndex, + int lineNumber, int columnNumber) +{ + if (diffFileIndex < 0 || diffFileIndex >= m_contextFileData.count()) + return; + + const FileData fileData = m_contextFileData.at(diffFileIndex); + const QString fileName = fileData.rightFileInfo.fileName; + jumpToOriginalFile(fileName, lineNumber, columnNumber); +} + +void DiffEditorWidget::jumpToOriginalFile(const QString &fileName, + int lineNumber, int columnNumber) +{ + const QDir dir(m_workingDirectory); + const QString absoluteFileName = dir.absoluteFilePath(fileName); + Core::EditorManager::openEditorAt(absoluteFileName, lineNumber, columnNumber); +} + void DiffEditorWidget::leftVSliderChanged() { m_rightEditor->verticalScrollBar()->setValue(m_leftEditor->verticalScrollBar()->value()); diff --git a/src/plugins/diffeditor/diffeditorwidget.h b/src/plugins/diffeditor/diffeditorwidget.h index 5bb4e1cb7f3880d1d2a75d72bffa6809e3897ef2..3b82a4ccba5d2fc8cf758fe04c4612f68a14dd20 100644 --- a/src/plugins/diffeditor/diffeditorwidget.h +++ b/src/plugins/diffeditor/diffeditorwidget.h @@ -103,6 +103,8 @@ protected: private slots: void setFontSettings(const TextEditor::FontSettings &fontSettings); + void slotLeftJumpToOriginalFileRequested(int diffFileIndex, int lineNumber, int columnNumber); + void slotRightJumpToOriginalFileRequested(int diffFileIndex, int lineNumber, int columnNumber); void leftVSliderChanged(); void rightVSliderChanged(); void leftHSliderChanged(); @@ -135,6 +137,7 @@ private: FileData calculateContextData(const ChunkData &originalData) const; void showDiff(); void synchronizeFoldings(DiffViewEditorWidget *source, DiffViewEditorWidget *destination); + void jumpToOriginalFile(const QString &fileName, int lineNumber, int columnNumber); DiffViewEditorWidget *m_leftEditor; DiffViewEditorWidget *m_rightEditor; @@ -143,6 +146,7 @@ private: QList<DiffList> m_diffList; // list of original outputs from differ QList<ChunkData> m_originalChunkData; // one big chunk for every file, ignoreWhitespaces taken into account QList<FileData> m_contextFileData; // ultimate data to be shown, contextLinesNumber taken into account + QString m_workingDirectory; int m_contextLinesNumber; bool m_ignoreWhitespaces; bool m_syncScrollBars;