Merge pull request #1387 from davvid/remote-dialog
[git-cola.git] / cola / widgets / filelist.py
blob803ad1d9ce5342c07f92270745ff5830df640606
1 from qtpy import QtWidgets
2 from qtpy.QtCore import Signal
3 from qtpy.QtCore import QSize
4 from qtpy.QtCore import Qt
6 from .. import cmds
7 from .. import hotkeys
8 from .. import qtutils
9 from ..i18n import N_
10 from .standard import TreeWidget
13 class FileWidget(TreeWidget):
14 files_selected = Signal(object)
15 difftool_selected = Signal(object)
16 histories_selected = Signal(object)
17 grab_file = Signal(object)
18 remark_toggled = Signal(object, object)
20 def __init__(self, context, parent, remarks=False):
21 TreeWidget.__init__(self, parent)
22 self.context = context
24 labels = [N_('Filename'), N_('Additions'), N_('Deletions')]
25 self.setHeaderLabels(labels)
27 self.show_history_action = qtutils.add_action(
28 self, N_('Show History'), self.show_history, hotkeys.HISTORY
31 self.launch_difftool_action = qtutils.add_action(
32 self, N_('Launch Diff Tool'), self.show_diff
35 self.launch_editor_action = qtutils.add_action(
36 self, N_('Launch Editor'), self.edit_paths, hotkeys.EDIT
39 self.grab_file_action = qtutils.add_action(
40 self, N_('Grab File...'), self._grab_file
43 if remarks:
44 self.toggle_remark_actions = tuple(
45 qtutils.add_action(
46 self,
48 lambda remark=r: self.toggle_remark(remark),
49 hotkeys.hotkey(Qt.CTRL | getattr(Qt, 'Key_' + r)),
51 for r in map(str, range(10))
53 else:
54 self.toggle_remark_actions = tuple()
56 self.itemSelectionChanged.connect(self.selection_changed)
58 def selection_changed(self):
59 items = self.selected_items()
60 self.files_selected.emit([i.path for i in items])
62 def commits_selected(self, commits):
63 if not commits:
64 self.clear()
65 return
67 git = self.context.git
68 paths = []
70 if len(commits) > 1:
71 # Get a list of changed files for a commit range.
72 start = commits[0].oid + '~'
73 end = commits[-1].oid
74 status, out, _ = git.diff(start, end, z=True, numstat=True, no_renames=True)
75 if status == 0:
76 paths = [f for f in out.rstrip('\0').split('\0') if f]
77 else:
78 # Get the list of changed files in a single commit.
79 commit = commits[0]
80 oid = commit.oid
81 status, out, _ = git.show(
82 oid, z=True, numstat=True, oneline=True, no_renames=True
84 if status == 0:
85 paths = [f for f in out.rstrip('\0').split('\0') if f]
86 if paths:
87 paths = paths[1:] # Skip over the summary on the first line.
89 self.list_files(paths)
91 def list_files(self, files_log):
92 self.clear()
93 if not files_log:
94 return
95 files = []
96 for filename in files_log:
97 item = FileTreeWidgetItem(filename)
98 files.append(item)
99 self.insertTopLevelItems(0, files)
101 def adjust_columns(self, size, old_size):
102 if size.isValid() and old_size.isValid():
103 width = self.columnWidth(0) + size.width() - old_size.width()
104 self.setColumnWidth(0, width)
105 else:
106 width = self.width()
107 two_thirds = (width * 2) // 3
108 one_sixth = width // 6
109 self.setColumnWidth(0, two_thirds)
110 self.setColumnWidth(1, one_sixth)
111 self.setColumnWidth(2, one_sixth)
113 def show(self):
114 self.adjust_columns(QSize(), QSize())
116 def resizeEvent(self, event):
117 self.adjust_columns(event.size(), event.oldSize())
119 def contextMenuEvent(self, event):
120 menu = qtutils.create_menu(N_('Actions'), self)
121 menu.addAction(self.grab_file_action)
122 menu.addAction(self.show_history_action)
123 menu.addAction(self.launch_difftool_action)
124 menu.addAction(self.launch_editor_action)
125 if self.toggle_remark_actions:
126 menu_toggle_remark = menu.addMenu(N_('Toggle remark of touching commits'))
127 tuple(map(menu_toggle_remark.addAction, self.toggle_remark_actions))
128 menu.exec_(self.mapToGlobal(event.pos()))
130 def show_diff(self):
131 self.difftool_selected.emit(self.selected_paths())
133 def _grab_file(self):
134 for path in self.selected_paths():
135 self.grab_file.emit(path)
137 def selected_paths(self):
138 return [i.path for i in self.selected_items()]
140 def edit_paths(self):
141 cmds.do(cmds.Edit, self.context, self.selected_paths())
143 def show_history(self):
144 items = self.selected_items()
145 paths = [i.path for i in items]
146 self.histories_selected.emit(paths)
148 def toggle_remark(self, remark):
149 items = self.selected_items()
150 paths = tuple(i.path for i in items)
151 self.remark_toggled.emit(remark, paths)
154 class FileTreeWidgetItem(QtWidgets.QTreeWidgetItem):
155 def __init__(self, file_log, parent=None):
156 QtWidgets.QTreeWidgetItem.__init__(self, parent)
157 texts = file_log.split('\t')
158 self.path = path = texts[2]
159 self.setText(0, path)
160 self.setText(1, texts[0])
161 self.setText(2, texts[1])