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
16 from .widgets
import standard
19 def diff_commits(context
, parent
, a
, b
):
20 """Show a dialog for diffing two commits"""
21 dlg
= Difftool(context
, parent
, a
=a
, b
=b
)
24 return dlg
.exec_() == QtWidgets
.QDialog
.Accepted
27 def diff_expression(context
, parent
, expr
,
28 create_widget
=False, hide_expr
=False, focus_tree
=False):
29 """Show a diff dialog for diff expressions"""
30 dlg
= Difftool(context
, parent
,
31 expr
=expr
, hide_expr
=hide_expr
,
32 focus_tree
=focus_tree
)
37 return dlg
.exec_() == QtWidgets
.QDialog
.Accepted
40 class Difftool(standard
.Dialog
):
42 def __init__(self
, context
, parent
, a
=None, b
=None, expr
=None, title
=None,
43 hide_expr
=False, focus_tree
=False):
44 """Show files with differences and launch difftool"""
46 standard
.Dialog
.__init
__(self
, parent
=parent
)
48 self
.context
= context
54 title
= N_('git-cola diff')
56 self
.setWindowTitle(title
)
57 self
.setWindowModality(Qt
.WindowModal
)
59 self
.expr
= completion
.GitRefLineEdit(context
, parent
=self
)
61 self
.expr
.setText(expr
)
63 if expr
is None or hide_expr
:
66 self
.tree
= filetree
.FileTree(parent
=self
)
68 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
.init_state(None, self
.resize_widget
, parent
)
120 def resize_widget(self
, parent
):
121 """Set the initial size of the widget"""
122 width
, height
= qtutils
.default_size(parent
, 720, 420)
123 self
.resize(width
, height
)
125 def focus_tree(self
):
126 """Focus the files tree"""
129 def focus_input(self
):
130 """Focus the expression input"""
133 def text_changed(self
, txt
):
138 """Redo the diff when the expression changes"""
139 if self
.diff_expr
is not None:
140 self
.diff_arg
= utils
.shell_split(self
.diff_expr
)
142 self
.diff_arg
= [self
.a
]
144 self
.diff_arg
= [self
.a
, self
.b
]
145 self
.refresh_filenames()
147 def refresh_filenames(self
):
148 context
= self
.context
149 if self
.a
and self
.b
is None:
150 filenames
= gitcmds
.diff_index_filenames(context
, self
.a
)
152 filenames
= gitcmds
.diff(context
, self
.diff_arg
)
153 self
.tree
.set_filenames(filenames
, select
=True)
155 def tree_selection_changed(self
):
156 has_selection
= self
.tree
.has_selection()
157 self
.diff_button
.setEnabled(has_selection
)
158 self
.diff_all_button
.setEnabled(has_selection
)
160 def tree_double_clicked(self
, item
, _column
):
161 path
= self
.tree
.filename_from_item(item
)
162 left
, right
= self
._left
_right
_args
()
163 cmds
.difftool_launch(
164 self
.context
, left
=left
, right
=right
, paths
=[path
])
166 def diff(self
, dir_diff
=False):
167 paths
= self
.tree
.selected_filenames()
168 left
, right
= self
._left
_right
_args
()
169 cmds
.difftool_launch(self
.context
, left
=left
, right
=right
, paths
=paths
,
172 def _left_right_args(self
):
174 left
= self
.diff_arg
[0]
177 if len(self
.diff_arg
) > 1:
178 right
= self
.diff_arg
[1]
184 paths
= self
.tree
.selected_filenames()
185 cmds
.do(cmds
.Edit
, self
.context
, paths
)