1 from __future__
import division
, absolute_import
, unicode_literals
3 from qtpy
import QtWidgets
4 from qtpy
.QtCore
import Qt
13 from .widgets
import completion
14 from .widgets
import defs
15 from .widgets
import filetree
18 def diff_commits(parent
, a
, b
):
19 """Show a dialog for diffing two commits"""
20 dlg
= FileDiffDialog(parent
, a
=a
, b
=b
)
23 return dlg
.exec_() == QtWidgets
.QDialog
.Accepted
26 def diff_expression(parent
, expr
,
30 """Show a diff dialog for diff expressions"""
31 dlg
= FileDiffDialog(parent
,
34 focus_tree
=focus_tree
)
39 return dlg
.exec_() == QtWidgets
.QDialog
.Accepted
42 class FileDiffDialog(QtWidgets
.QDialog
):
44 def __init__(self
, parent
, a
=None, b
=None, expr
=None, title
=None,
45 hide_expr
=False, focus_tree
=False):
46 """Show files with differences and launch difftool"""
48 QtWidgets
.QDialog
.__init
__(self
, parent
)
55 title
= N_('git-cola diff')
57 self
.setWindowTitle(title
)
58 self
.setWindowModality(Qt
.WindowModal
)
60 self
.expr
= completion
.GitRefLineEdit(parent
=self
)
62 self
.expr
.setText(expr
)
64 if expr
is None or hide_expr
:
67 self
.tree
= filetree
.FileTree(parent
=self
)
69 self
.diff_button
= qtutils
.create_button(text
=N_('Compare'),
72 self
.diff_button
.setShortcut(hotkeys
.DIFF
)
74 self
.diff_all_button
= qtutils
.create_button(text
=N_('Compare All'),
76 self
.edit_button
= qtutils
.edit_button()
77 self
.edit_button
.setShortcut(hotkeys
.EDIT
)
79 self
.close_button
= qtutils
.close_button()
81 self
.button_layout
= qtutils
.hbox(defs
.no_margin
, defs
.spacing
,
88 self
.main_layout
= qtutils
.vbox(defs
.margin
, defs
.spacing
,
91 self
.setLayout(self
.main_layout
)
93 self
.tree
.itemSelectionChanged
.connect(self
.tree_selection_changed
)
94 self
.tree
.itemDoubleClicked
.connect(self
.tree_double_clicked
)
95 self
.tree
.up
.connect(self
.focus_input
)
97 self
.expr
.textChanged
.connect(self
.text_changed
)
99 self
.expr
.activated
.connect(self
.focus_tree
)
100 self
.expr
.down
.connect(self
.focus_tree
)
101 self
.expr
.enter
.connect(self
.focus_tree
)
103 qtutils
.connect_button(self
.diff_button
, self
.diff
)
104 qtutils
.connect_button(self
.diff_all_button
,
105 lambda: self
.diff(dir_diff
=True))
106 qtutils
.connect_button(self
.edit_button
, self
.edit
)
107 qtutils
.connect_button(self
.close_button
, self
.close
)
109 qtutils
.add_action(self
, 'Focus Input', self
.focus_input
, hotkeys
.FOCUS
)
110 qtutils
.add_action(self
, 'Diff All', lambda: self
.diff(dir_diff
=True),
111 hotkeys
.CTRL_ENTER
, hotkeys
.CTRL_RETURN
)
112 qtutils
.add_close_action(self
)
114 self
.resize(720, 420)
120 def focus_tree(self
):
121 """Focus the files tree"""
124 def focus_input(self
):
125 """Focus the expression input"""
128 def text_changed(self
, txt
):
133 """Redo the diff when the expression changes"""
134 if self
.diff_expr
is not None:
135 self
.diff_arg
= utils
.shell_split(self
.diff_expr
)
137 self
.diff_arg
= [self
.a
]
139 self
.diff_arg
= [self
.a
, self
.b
]
140 self
.refresh_filenames()
142 def refresh_filenames(self
):
143 if self
.a
and self
.b
is None:
144 filenames
= gitcmds
.diff_index_filenames(self
.a
)
146 filenames
= gitcmds
.diff(self
.diff_arg
)
147 self
.tree
.set_filenames(filenames
, select
=True)
149 def tree_selection_changed(self
):
150 has_selection
= self
.tree
.has_selection()
151 self
.diff_button
.setEnabled(has_selection
)
152 self
.diff_all_button
.setEnabled(has_selection
)
154 def tree_double_clicked(self
, item
, column
):
155 path
= self
.tree
.filename_from_item(item
)
156 left
, right
= self
._left
_right
_args
()
157 cmds
.difftool_launch(left
=left
, right
=right
, paths
=[path
])
159 def diff(self
, dir_diff
=False):
160 paths
= self
.tree
.selected_filenames()
161 left
, right
= self
._left
_right
_args
()
162 cmds
.difftool_launch(left
=left
, right
=right
, paths
=paths
,
165 def _left_right_args(self
):
167 left
= self
.diff_arg
[0]
170 if len(self
.diff_arg
) > 1:
171 right
= self
.diff_arg
[1]
177 paths
= self
.tree
.selected_filenames()
178 cmds
.do(cmds
.Edit
, paths
)