Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Utilities
Kate
Commits
60d3b464
Commit
60d3b464
authored
Sep 03, 2022
by
Waqar Ahmed
Browse files
Add Stage/Unstage/Discard to DiffWidget
parent
77097dee
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
addons/git-blame/kategitblameplugin.cpp
View file @
60d3b464
...
...
@@ -6,6 +6,7 @@
#include
"kategitblameplugin.h"
#include
"commitfilesview.h"
#include
"diffparams.h"
#include
<gitprocess.h>
...
...
@@ -587,7 +588,9 @@ void KateGitBlamePluginView::hideToolView()
void
KateGitBlamePluginView
::
showDiffForFile
(
const
QByteArray
&
diffContents
,
const
QString
&
file
)
{
auto
mw
=
m_mainWindow
->
window
();
QMetaObject
::
invokeMethod
(
mw
,
"showDiff"
,
Q_ARG
(
QByteArray
,
diffContents
),
Q_ARG
(
QString
,
file
),
Q_ARG
(
QString
,
{}));
DiffParams
d
;
d
.
tabTitle
=
file
;
QMetaObject
::
invokeMethod
(
mw
,
"showDiff"
,
Q_ARG
(
QByteArray
,
diffContents
),
Q_ARG
(
DiffParams
,
d
));
}
#include
"kategitblameplugin.moc"
addons/project/gitwidget.cpp
View file @
60d3b464
...
...
@@ -9,6 +9,7 @@
#include
"branchdeletedialog.h"
#include
"branchesdialog.h"
#include
"comparebranchesview.h"
#include
"diffparams.h"
#include
"git/gitdiff.h"
#include
"gitcommitdialog.h"
#include
"gitstatusmodel.h"
...
...
@@ -642,7 +643,14 @@ void GitWidget::showDiff(const QString &file, bool staged, bool showInKate)
}
else
{
if
(
showInKate
)
{
auto
mw
=
mainWindow
()
->
window
();
QMetaObject
::
invokeMethod
(
mw
,
"showDiff"
,
Q_ARG
(
QByteArray
,
git
->
readAllStandardOutput
()),
Q_ARG
(
QString
,
file
),
Q_ARG
(
QString
,
{}));
DiffParams
d
;
d
.
srcFile
=
file
;
d
.
workingDir
=
m_activeGitDirPath
;
d
.
arguments
=
git
->
arguments
();
d
.
flags
.
setFlag
(
DiffParams
::
Flag
::
ShowStage
,
!
staged
);
d
.
flags
.
setFlag
(
DiffParams
::
Flag
::
ShowUnstage
,
staged
);
d
.
flags
.
setFlag
(
DiffParams
::
Flag
::
ShowDiscard
,
!
staged
);
QMetaObject
::
invokeMethod
(
mw
,
"showDiff"
,
Q_ARG
(
QByteArray
,
git
->
readAllStandardOutput
()),
Q_ARG
(
DiffParams
,
d
));
return
;
}
auto
addContextMenuActions
=
[
this
,
file
,
staged
](
KTextEditor
::
View
*
v
)
{
...
...
addons/project/kateprojectview.cpp
View file @
60d3b464
...
...
@@ -7,6 +7,7 @@
#include
"kateprojectview.h"
#include
"branchcheckoutdialog.h"
#include
"diffparams.h"
#include
"filehistorywidget.h"
#include
"git/gitutils.h"
#include
"gitwidget.h"
...
...
@@ -158,8 +159,9 @@ void KateProjectView::showFileGitHistory(const QString &file)
connect
(
fhs
,
&
FileHistoryWidget
::
backClicked
,
this
,
&
KateProjectView
::
setTreeViewAsCurrent
);
connect
(
fhs
,
&
FileHistoryWidget
::
commitClicked
,
this
,
[
this
,
file
](
const
QByteArray
&
diff
,
const
QString
&
commit
)
{
auto
mw
=
m_pluginView
->
mainWindow
()
->
window
();
const
QString
name
=
QStringLiteral
(
"%1[%2]"
).
arg
(
file
,
commit
);
QMetaObject
::
invokeMethod
(
mw
,
"showDiff"
,
Q_ARG
(
QByteArray
,
diff
),
Q_ARG
(
QString
,
name
),
Q_ARG
(
QString
,
{}));
DiffParams
d
;
d
.
tabTitle
=
QStringLiteral
(
"%1[%2]"
).
arg
(
file
,
commit
);
QMetaObject
::
invokeMethod
(
mw
,
"showDiff"
,
Q_ARG
(
QByteArray
,
diff
),
Q_ARG
(
DiffParams
,
d
));
});
connect
(
fhs
,
&
FileHistoryWidget
::
errorMessage
,
m_pluginView
,
[
this
](
const
QString
&
s
,
bool
warn
)
{
QVariantMap
genericMessage
;
...
...
apps/lib/CMakeLists.txt
View file @
60d3b464
...
...
@@ -22,6 +22,7 @@ target_include_directories(
${
CMAKE_CURRENT_SOURCE_DIR
}
${
CMAKE_CURRENT_SOURCE_DIR
}
/session
${
CMAKE_CURRENT_SOURCE_DIR
}
/quickopen
${
CMAKE_CURRENT_SOURCE_DIR
}
/diff
${
CMAKE_CURRENT_BINARY_DIR
}
# kateprivate_export.h
)
...
...
@@ -111,9 +112,10 @@ target_sources(
data/kateprivate.qrc
hostprocess.cpp
diffwidget.cpp
diffeditor.cpp
difflinenumarea.cpp
diff/diffwidget.cpp
diff/diffeditor.cpp
diff/difflinenumarea.cpp
diff/gitdiff.cpp
)
if
(
BUILD_TESTING
)
...
...
apps/lib/diffeditor.cpp
→
apps/lib/
diff/
diffeditor.cpp
View file @
60d3b464
#include
"diffeditor.h"
#include
"difflinenumarea.h"
#include
"diffwidget.h"
#include
"ktexteditor_utils.h"
#include
<QMenu>
...
...
@@ -9,9 +10,11 @@
#include
<KLocalizedString>
DiffEditor
::
DiffEditor
(
QWidget
*
parent
)
DiffEditor
::
DiffEditor
(
DiffParams
::
Flags
f
,
QWidget
*
parent
)
:
QPlainTextEdit
(
parent
)
,
m_lineNumArea
(
new
LineNumArea
(
this
))
,
m_diffWidget
(
static_cast
<
DiffWidget
*>
(
parent
))
,
m_flags
(
f
)
{
setFrameStyle
(
QFrame
::
NoFrame
);
...
...
@@ -65,27 +68,109 @@ void DiffEditor::resizeEvent(QResizeEvent *event)
updateLineNumAreaGeometry
();
}
KTextEditor
::
Range
DiffEditor
::
selectionRange
()
const
{
const
auto
cursor
=
textCursor
();
if
(
!
cursor
.
hasSelection
())
return
KTextEditor
::
Range
::
invalid
();
QTextCursor
start
=
cursor
;
start
.
setPosition
(
qMin
(
cursor
.
selectionStart
(),
cursor
.
selectionEnd
()));
QTextCursor
end
=
cursor
;
end
.
setPosition
(
qMax
(
cursor
.
selectionStart
(),
cursor
.
selectionEnd
()));
const
int
startLine
=
start
.
blockNumber
();
const
int
endLine
=
end
.
blockNumber
();
const
int
startColumn
=
start
.
selectionStart
()
-
start
.
block
().
position
();
const
int
endColumn
=
end
.
selectionEnd
()
-
end
.
block
().
position
();
return
{
startLine
,
startColumn
,
endLine
,
endColumn
};
}
void
DiffEditor
::
contextMenuEvent
(
QContextMenuEvent
*
e
)
{
// Follow KTextEditor behaviour
if
(
!
textCursor
().
hasSelection
())
{
setTextCursor
(
cursorForPosition
(
e
->
pos
()));
}
auto
menu
=
createStandardContextMenu
();
QAction
*
before
=
nullptr
;
if
(
!
menu
->
actions
().
isEmpty
())
before
=
menu
->
actions
().
constFirst
();
auto
a
=
new
QAction
(
i18n
(
"Change Style"
));
auto
styleMenu
=
new
QMenu
(
this
);
styleMenu
->
addAction
(
i18n
(
"Side By Side"
),
this
,
[
this
]
{
Q_EMIT
switchStyle
(
SideBySide
);
});
styleMenu
->
addAction
(
i18n
(
"Unified"
),
this
,
[
this
]
{
Q_EMIT
switchStyle
(
Unified
);
});
styleMenu
->
addAction
(
i18n
(
"Raw"
),
this
,
[
this
]
{
Q_EMIT
switchStyle
(
Raw
);
});
a
->
setMenu
(
styleMenu
);
menu
->
insertAction
(
before
,
a
);
menu
->
exec
(
mapToGlobal
(
e
->
pos
()));
{
auto
a
=
new
QAction
(
i18n
(
"Change Style"
));
auto
styleMenu
=
new
QMenu
(
this
);
styleMenu
->
addAction
(
i18n
(
"Side By Side"
),
this
,
[
this
]
{
Q_EMIT
switchStyle
(
SideBySide
);
});
styleMenu
->
addAction
(
i18n
(
"Unified"
),
this
,
[
this
]
{
Q_EMIT
switchStyle
(
Unified
);
});
styleMenu
->
addAction
(
i18n
(
"Raw"
),
this
,
[
this
]
{
Q_EMIT
switchStyle
(
Raw
);
});
a
->
setMenu
(
styleMenu
);
menu
->
insertAction
(
before
,
a
);
}
addStageUnstageDiscardActions
(
menu
);
menu
->
exec
(
viewport
()
->
mapToGlobal
(
e
->
pos
()));
}
void
DiffEditor
::
addStageUnstageDiscardActions
(
QMenu
*
menu
)
{
const
auto
selection
=
selectionRange
();
const
int
lineCount
=
!
selection
.
isValid
()
?
1
:
selection
.
numberOfLines
()
+
1
;
int
startLine
=
textCursor
().
blockNumber
();
int
endLine
=
startLine
;
if
(
selection
.
isValid
())
{
startLine
=
selection
.
start
().
line
();
endLine
=
selection
.
end
().
line
();
}
QAction
*
before
=
nullptr
;
if
(
!
menu
->
actions
().
isEmpty
())
before
=
menu
->
actions
().
constFirst
();
if
(
m_flags
.
testFlag
(
DiffParams
::
Flag
::
ShowStage
))
{
auto
a
=
new
QAction
(
i18np
(
"Stage Line"
,
"Stage Lines"
,
lineCount
));
connect
(
a
,
&
QAction
::
triggered
,
this
,
[
=
]
{
Q_EMIT
actionTriggered
(
this
,
startLine
,
endLine
,
(
int
)
Line
,
DiffParams
::
Flag
::
ShowStage
);
});
menu
->
insertAction
(
before
,
a
);
a
=
new
QAction
(
i18n
(
"Stage Hunk"
));
connect
(
a
,
&
QAction
::
triggered
,
this
,
[
=
]
{
Q_EMIT
actionTriggered
(
this
,
startLine
,
endLine
,
(
int
)
Hunk
,
DiffParams
::
Flag
::
ShowStage
);
});
menu
->
insertAction
(
before
,
a
);
}
if
(
m_flags
.
testFlag
(
DiffParams
::
Flag
::
ShowDiscard
))
{
auto
a
=
new
QAction
(
i18np
(
"Discard Line"
,
"Discard Lines"
,
lineCount
));
connect
(
a
,
&
QAction
::
triggered
,
this
,
[
=
]
{
Q_EMIT
actionTriggered
(
this
,
startLine
,
endLine
,
(
int
)
Line
,
DiffParams
::
Flag
::
ShowDiscard
);
});
menu
->
insertAction
(
before
,
a
);
a
=
new
QAction
(
i18n
(
"Discard Hunk"
));
connect
(
a
,
&
QAction
::
triggered
,
this
,
[
=
]
{
Q_EMIT
actionTriggered
(
this
,
startLine
,
endLine
,
(
int
)
Hunk
,
DiffParams
::
Flag
::
ShowDiscard
);
});
menu
->
insertAction
(
before
,
a
);
}
if
(
m_flags
.
testFlag
(
DiffParams
::
Flag
::
ShowUnstage
))
{
auto
a
=
new
QAction
(
i18np
(
"Unstage Line"
,
"Unstage Lines"
,
lineCount
));
connect
(
a
,
&
QAction
::
triggered
,
this
,
[
=
]
{
Q_EMIT
actionTriggered
(
this
,
startLine
,
endLine
,
(
int
)
Line
,
DiffParams
::
Flag
::
ShowUnstage
);
});
menu
->
insertAction
(
before
,
a
);
a
=
new
QAction
(
i18n
(
"Unstage Hunk"
));
connect
(
a
,
&
QAction
::
triggered
,
this
,
[
=
]
{
Q_EMIT
actionTriggered
(
this
,
startLine
,
endLine
,
(
int
)
Hunk
,
DiffParams
::
Flag
::
ShowUnstage
);
});
menu
->
insertAction
(
before
,
a
);
}
}
void
DiffEditor
::
updateLineNumberArea
(
const
QRect
&
rect
,
int
dy
)
...
...
@@ -220,3 +305,20 @@ void DiffEditor::setLineNumberData(QVector<int> data, int maxLineNum)
m_lineNumArea
->
setMaxLineNum
(
maxLineNum
);
updateLineNumberAreaWidth
(
0
);
}
DiffEditor
::
State
DiffEditor
::
saveState
()
const
{
return
{
verticalScrollBar
()
->
value
(),
textCursor
().
position
()};
}
void
DiffEditor
::
restoreState
(
State
s
)
{
if
(
document
()
&&
document
()
->
isEmpty
())
{
return
;
}
verticalScrollBar
()
->
setValue
(
qMax
(
0
,
s
.
scrollValue
));
auto
cursor
=
textCursor
();
cursor
.
setPosition
(
qMin
(
cursor
.
document
()
->
characterCount
(),
s
.
cursorPosition
));
setTextCursor
(
cursor
);
}
apps/lib/diffeditor.h
→
apps/lib/
diff/
diffeditor.h
View file @
60d3b464
#ifndef KATE_DIFF_EDITOR
#define KATE_DIFF_EDITOR
#include
"diffparams.h"
#include
<KTextEditor/Range>
#include
<QPlainTextEdit>
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
...
...
@@ -28,7 +30,15 @@ class DiffEditor : public QPlainTextEdit
friend
class
LineNumArea
;
public:
DiffEditor
(
QWidget
*
parent
=
nullptr
);
enum
{
Line
=
0
,
Hunk
=
1
};
DiffEditor
(
DiffParams
::
Flags
,
QWidget
*
parent
=
nullptr
);
struct
State
{
int
scrollValue
;
int
cursorPosition
;
};
State
saveState
()
const
;
void
restoreState
(
State
);
void
clearData
()
{
...
...
@@ -43,6 +53,8 @@ public:
void
setLineNumberData
(
QVector
<
int
>
data
,
int
maxLineNum
);
KTextEditor
::
Range
selectionRange
()
const
;
protected:
void
resizeEvent
(
QResizeEvent
*
event
)
override
;
void
paintEvent
(
QPaintEvent
*
e
)
override
;
...
...
@@ -55,6 +67,7 @@ private:
void
updateLineNumberAreaWidth
(
int
);
void
updateDiffColors
(
bool
darkMode
);
void
onContextMenuRequest
();
void
addStageUnstageDiscardActions
(
QMenu
*
menu
);
QVector
<
LineHighlight
>
m_data
;
QColor
red1
;
...
...
@@ -62,9 +75,12 @@ private:
QColor
green1
;
QColor
green2
;
class
LineNumArea
*
const
m_lineNumArea
;
class
DiffWidget
*
const
m_diffWidget
;
DiffParams
::
Flags
m_flags
;
Q_SIGNALS:
void
switchStyle
(
int
);
void
actionTriggered
(
DiffEditor
*
e
,
int
startLine
,
int
endLine
,
int
actionType
,
DiffParams
::
Flag
);
};
#endif
apps/lib/difflinenumarea.cpp
→
apps/lib/
diff/
difflinenumarea.cpp
View file @
60d3b464
File moved
apps/lib/difflinenumarea.h
→
apps/lib/
diff/
difflinenumarea.h
View file @
60d3b464
File moved
apps/lib/diff/diffparams.h
0 → 100644
View file @
60d3b464
#ifndef KATE_DIFF_PARAMS
#define KATE_DIFF_PARAMS
#include
<QMetaType>
#include
<QStringList>
struct
DiffParams
{
enum
Flag
{
ShowStage
=
1
,
ShowUnstage
=
2
,
ShowDiscard
=
4
};
Q_DECLARE_FLAGS
(
Flags
,
Flag
)
Q_FLAGS
(
Flags
)
/**
* The tab title that will get shown in Kate.
* If not specified, srcFile/destFile will be
* used instead
*/
QString
tabTitle
;
/** Source File **/
QString
srcFile
;
/** Destination file **/
QString
destFile
;
/** Working dir i.e., to which
* src/dest files belong and where
* the command was run. This should
* normally be your repo base path
*/
QString
workingDir
;
/**
* The arguments that were passed to git
* when this diff was generated
*/
QStringList
arguments
;
/**
* These flags are used internally for e.g.,
* for the context menu actions
*/
Flags
flags
;
void
clear
()
{
tabTitle
=
srcFile
=
destFile
=
workingDir
=
QString
();
arguments
.
clear
();
flags
=
{};
}
};
Q_DECLARE_METATYPE
(
DiffParams
)
#endif
apps/lib/diffwidget.cpp
→
apps/lib/
diff/
diffwidget.cpp
View file @
60d3b464
...
...
@@ -3,9 +3,9 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include
"diffwidget.h"
#include
"ktexteditor_utils.h"
#include
"gitdiff.h"
#include
"gitprocess.h"
#include
"ktexteditor_utils.h"
#include
<QApplication>
#include
<QHBoxLayout>
...
...
@@ -15,6 +15,7 @@
#include
<QRegularExpression>
#include
<QScrollBar>
#include
<QSyntaxHighlighter>
#include
<QTemporaryFile>
#include
<KConfigGroup>
#include
<KSharedConfig>
...
...
@@ -23,23 +24,11 @@
#include
<KSyntaxHighlighting/Repository>
#include
<KSyntaxHighlighting/SyntaxHighlighter>
std
::
pair
<
uint
,
uint
>
parseRange
(
const
QString
&
range
)
{
int
commaPos
=
range
.
indexOf
(
QLatin1Char
(
','
));
if
(
commaPos
>
-
1
)
{
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
return
{
range
.
midRef
(
0
,
commaPos
).
toInt
(),
range
.
midRef
(
commaPos
+
1
).
toInt
()};
#else
return
{
QStringView
(
range
).
sliced
(
0
,
commaPos
).
toInt
(),
QStringView
(
range
).
sliced
(
commaPos
+
1
).
toInt
()};
#endif
}
return
{
range
.
toInt
(),
1
};
}
DiffWidget
::
DiffWidget
(
QWidget
*
parent
)
DiffWidget
::
DiffWidget
(
DiffParams
p
,
QWidget
*
parent
)
:
QWidget
(
parent
)
,
m_left
(
new
DiffEditor
(
this
))
,
m_right
(
new
DiffEditor
(
this
))
,
m_left
(
new
DiffEditor
(
p
.
flags
,
this
))
,
m_right
(
new
DiffEditor
(
p
.
flags
,
this
))
,
m_params
(
p
)
{
auto
layout
=
new
QHBoxLayout
(
this
);
layout
->
addWidget
(
m_left
);
...
...
@@ -61,6 +50,7 @@ DiffWidget::DiffWidget(QWidget *parent)
for
(
auto
*
e
:
{
m_left
,
m_right
})
{
connect
(
e
,
&
DiffEditor
::
switchStyle
,
this
,
&
DiffWidget
::
handleStyleChange
);
connect
(
e
,
&
DiffEditor
::
actionTriggered
,
this
,
&
DiffWidget
::
handleStageUnstage
);
}
KSharedConfig
::
Ptr
config
=
KSharedConfig
::
openConfig
();
...
...
@@ -75,7 +65,9 @@ void DiffWidget::handleStyleChange(int newStyle)
}
m_style
=
(
DiffStyle
)
newStyle
;
const
auto
diff
=
m_rawDiff
;
const
auto
params
=
m_params
;
clearData
();
m_params
=
params
;
if
(
m_style
==
SideBySide
)
{
m_left
->
setVisible
(
true
);
...
...
@@ -95,11 +87,151 @@ void DiffWidget::handleStyleChange(int newStyle)
}
}
void
DiffWidget
::
handleStageUnstage
(
DiffEditor
*
e
,
int
startLine
,
int
endLine
,
int
actionType
,
DiffParams
::
Flag
f
)
{
if
(
m_style
==
SideBySide
)
{
handleStageUnstage_sideBySide
(
e
,
startLine
,
endLine
,
actionType
,
f
);
}
else
if
(
m_style
==
Unified
)
{
handleStageUnstage_unified
(
startLine
,
endLine
,
actionType
,
f
);
}
else
if
(
m_style
==
Raw
)
{
handleStageUnstage_raw
(
startLine
,
endLine
,
actionType
,
f
);
}
}
void
DiffWidget
::
handleStageUnstage_unified
(
int
startLine
,
int
endLine
,
int
actionType
,
DiffParams
::
Flag
f
)
{
handleStageUnstage_sideBySide
(
m_left
,
startLine
,
endLine
,
actionType
,
f
);
}
void
DiffWidget
::
handleStageUnstage_sideBySide
(
DiffEditor
*
e
,
int
startLine
,
int
endLine
,
int
actionType
,
DiffParams
::
Flag
flags
)
{
bool
added
=
e
==
m_right
;
int
diffLine
=
-
1
;
if
(
actionType
==
DiffEditor
::
Line
)
{
for
(
auto
vToD
:
std
::
as_const
(
m_lineToRawDiffLine
))
{
if
(
vToD
.
line
==
startLine
&&
vToD
.
added
==
added
)
{
diffLine
=
vToD
.
diffLine
;
break
;
}
}
}
else
if
(
actionType
==
DiffEditor
::
Hunk
)
{
// find the first hunk smaller than/equal this line
for
(
auto
it
=
m_lineToDiffHunkLine
.
crbegin
();
it
!=
m_lineToDiffHunkLine
.
crend
();
++
it
)
{
if
(
it
->
line
<=
startLine
)
{
diffLine
=
it
->
diffLine
;
break
;
}
}
}
if
(
diffLine
==
-
1
)
{
// Nothing found somehow
return
;
}
doStageUnStage
(
diffLine
,
diffLine
+
(
endLine
-
startLine
),
actionType
,
flags
);
}
void
DiffWidget
::
handleStageUnstage_raw
(
int
startLine
,
int
endLine
,
int
actionType
,
DiffParams
::
Flag
flags
)
{
doStageUnStage
(
startLine
,
endLine
+
(
endLine
-
startLine
),
actionType
,
flags
);
}
void
DiffWidget
::
doStageUnStage
(
int
startLine
,
int
endLine
,
int
actionType
,
DiffParams
::
Flag
flags
)
{
VcsDiff
d
;
const
auto
stageOrDiscard
=
flags
==
DiffParams
::
Flag
::
ShowDiscard
||
flags
==
DiffParams
::
Flag
::
ShowUnstage
;
const
auto
dir
=
stageOrDiscard
?
VcsDiff
::
Reverse
:
VcsDiff
::
Forward
;
d
.
setDiff
(
QString
::
fromUtf8
(
m_rawDiff
));
const
auto
x
=
actionType
==
DiffEditor
::
Line
?
d
.
subDiff
(
startLine
,
startLine
+
(
endLine
-
startLine
),
dir
)
:
d
.
subDiffHunk
(
startLine
,
dir
);
if
(
flags
&
DiffParams
::
Flag
::
ShowStage
)
{
applyDiff
(
x
.
diff
(),
ApplyFlags
::
None
);
}
else
if
(
flags
&
DiffParams
::
ShowUnstage
)
{
applyDiff
(
x
.
diff
(),
ApplyFlags
::
Staged
);
}
else
if
(
flags
&
DiffParams
::
ShowDiscard
)
{
applyDiff
(
x
.
diff
(),
ApplyFlags
::
Discard
);
}
}
void
DiffWidget
::
applyDiff
(
const
QString
&
diff
,
ApplyFlags
flags
)
{
// const QString diff = getDiff(v, flags & Hunk, flags & (Staged | Discard));
if
(
diff
.
isEmpty
())
{
return
;
}
QTemporaryFile
*
file
=
new
QTemporaryFile
(
this
);
if
(
!
file
->
open
())
{
// sendMessage(i18n("Failed to stage selection"), true);
return
;
}
file
->
write
(
diff
.
toUtf8
());
file
->
close
();
Q_ASSERT
(
!
m_params
.
workingDir
.
isEmpty
());
QProcess
*
git
=
new
QProcess
(
this
);
QStringList
args
;
if
(
flags
&
Discard
)
{
args
=
QStringList
{
QStringLiteral
(
"apply"
),
file
->
fileName
()};
}
else
{
args
=
QStringList
{
QStringLiteral
(
"apply"
),
QStringLiteral
(
"--index"
),
QStringLiteral
(
"--cached"
),
file
->
fileName
()};
}
setupGitProcess
(
*
git
,
m_params
.
workingDir
,
args
);
connect
(
git
,
&
QProcess
::
finished
,
this
,
[
=
](
int
exitCode
,
QProcess
::
ExitStatus
es
)
{
if
(
es
!=
QProcess
::
NormalExit
||
exitCode
!=
0
)
{
onError
(
git
->
readAllStandardError
(),
git
->
exitCode
());
}
else
{
runGitDiff
();
}
delete
file
;
git
->
deleteLater
();
});
startHostProcess
(
*
git
,
QProcess
::
ReadOnly
);
}
void
DiffWidget
::
runGitDiff
()
{
const
QStringList
arguments
=
m_params
.
arguments
;
const
QString
workingDir
=
m_params
.
workingDir
;
if
(
workingDir
.
isEmpty
()
||
arguments
.
isEmpty
())
{
return
;
}
auto
leftState
=
m_left
->
saveState
();
auto
rightState
=
m_right
->
saveState
();
QProcess
*
git
=
new
QProcess
(
this
);
setupGitProcess
(
*
git
,
workingDir
,
arguments
);
connect
(
git
,
&
QProcess
::
finished
,
this
,
[
=
](
int
exitCode
,
QProcess
::
ExitStatus
es
)
{
const
auto
params
=
m_params
;
clearData
();
m_params
=
params
;
m_left
->
setUpdatesEnabled
(
false
);
m_right
->
setUpdatesEnabled
(
false
);
if
(
es
!=
QProcess
::
NormalExit
||
exitCode
!=
0
)
{
onError
(
git
->
readAllStandardError
(),
git
->
exitCode
());
}
else
{
openDiff
(
git
->
readAllStandardOutput
());
m_left
->
restoreState
(
leftState
);
m_right
->
restoreState
(
rightState
);
}
m_left
->
setUpdatesEnabled
(
true
);
m_right
->
setUpdatesEnabled
(
true
);
git
->
deleteLater
();
});
startHostProcess
(
*
git
,
QProcess
::
ReadOnly
);
}
void
DiffWidget
::
clearData
()
{
m_left
->
clearData
();
m_right
->
clearData
();
m_rawDiff
.
clear
();
m_lineToRawDiffLine
.
clear
();
m_lineToDiffHunkLine
.
clear
();
m_params
.
clear
();
}
void
DiffWidget
::
diffDocs
(
KTextEditor
::
Document
*
l
,
KTextEditor
::
Document
*
r
)
...
...
@@ -277,6 +409,11 @@ void DiffWidget::parseAndShowDiff(const QByteArray &raw)
QString
srcFile
;
QString
tgtFile
;
// viewLine => rawDiffLine
QVector
<
ViewLineToDiffLine
>
lineToRawDiffLine
;
// for Folding/stage/unstage hunk
QVector
<
ViewLineToDiffLine
>
linesWithHunkHeading
;
int
maxLineNoFound
=
0
;
int
lineA
=
0
;
int
lineB
=
0
;
...
...
@@ -308,6 +445,7 @@ void DiffWidget::parseAndShowDiff(const QByteArray &raw)
lineNumsB
.
append
(
-
1
);
left
.
append
(
headingLeft
);
right
.
append
(
headingRight
);
linesWithHunkHeading
.
append
({
lineA
,
i
,
/*unused*/
false
});
lineA
++
;
lineB
++
;
...
...
@@ -345,6 +483,7 @@ void DiffWidget::parseAndShowDiff(const QByteArray &raw)
h
.
changes
.
push_back
({
0
,
l
.
size
()});
rightHlts
.
push_back
(
h
);
lineNumsB
.
append
(
tgtLine
++
);
lineToRawDiffLine
.
append
({
lineB
,
j
,
true
});
right
.
append
(
l
);
hunkChangedLinesB
.
emplace_back
(
l
,
lineB
,
h
.
added
);
...
...
@@ -363,6 +502,7 @@ void DiffWidget::parseAndShowDiff(const QByteArray &raw)
lineNumsA
.
append
(
srcLine
++
);
left
.
append
(
l
);
hunkChangedLinesA
.
emplace_back
(
l
,
lineA
,
h
.
added
);
lineToRawDiffLine
.
append
({
lineA
,
j
,
false
});