eric7/Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.py

branch
eric7
changeset 8312
800c432b34c8
parent 8218
7c09585bd960
child 8318
962bce857696
equal deleted inserted replaced
8311:4e8b98454baa 8312:800c432b34c8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2014 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to show a list of files which had or still have
8 conflicts.
9 """
10
11 from PyQt5.QtCore import pyqtSlot, Qt, QPoint
12 from PyQt5.QtWidgets import (
13 QAbstractButton, QDialogButtonBox, QHeaderView, QTreeWidgetItem,
14 QApplication, QWidget
15 )
16
17 from E5Gui.E5Application import e5App
18
19 from .Ui_HgConflictsListDialog import Ui_HgConflictsListDialog
20
21 import Utilities.MimeTypes
22
23
24 class HgConflictsListDialog(QWidget, Ui_HgConflictsListDialog):
25 """
26 Class implementing a dialog to show a list of files which had or still
27 have conflicts.
28 """
29 StatusRole = Qt.ItemDataRole.UserRole + 1
30 FilenameRole = Qt.ItemDataRole.UserRole + 2
31
32 def __init__(self, vcs, parent=None):
33 """
34 Constructor
35
36 @param vcs reference to the vcs object
37 @param parent parent widget (QWidget)
38 """
39 super().__init__(parent)
40 self.setupUi(self)
41
42 self.__position = QPoint()
43
44 self.buttonBox.button(
45 QDialogButtonBox.StandardButton.Close).setEnabled(False)
46 self.buttonBox.button(
47 QDialogButtonBox.StandardButton.Cancel).setDefault(True)
48
49 self.conflictsList.headerItem().setText(
50 self.conflictsList.columnCount(), "")
51 self.conflictsList.header().setSortIndicator(
52 0, Qt.SortOrder.AscendingOrder)
53
54 self.refreshButton = self.buttonBox.addButton(
55 self.tr("&Refresh"), QDialogButtonBox.ButtonRole.ActionRole)
56 self.refreshButton.setToolTip(
57 self.tr("Press to refresh the list of conflicts"))
58 self.refreshButton.setEnabled(False)
59
60 self.vcs = vcs
61 self.project = e5App().getObject("Project")
62
63 self.__hgClient = vcs.getClient()
64
65 def closeEvent(self, e):
66 """
67 Protected slot implementing a close event handler.
68
69 @param e close event (QCloseEvent)
70 """
71 if self.__hgClient.isExecuting():
72 self.__hgClient.cancel()
73
74 self.__position = self.pos()
75
76 e.accept()
77
78 def show(self):
79 """
80 Public slot to show the dialog.
81 """
82 if not self.__position.isNull():
83 self.move(self.__position)
84
85 super().show()
86
87 def start(self):
88 """
89 Public slot to start the tags command.
90 """
91 self.errorGroup.hide()
92 QApplication.processEvents()
93
94 self.intercept = False
95
96 self.activateWindow()
97 self.raise_()
98
99 self.conflictsList.clear()
100 self.__started = True
101 self.__getEntries()
102
103 def __getEntries(self):
104 """
105 Private method to get the conflict entries.
106 """
107 args = self.vcs.initCommand("resolve")
108 args.append('--list')
109
110 out, err = self.__hgClient.runcommand(args)
111 if err:
112 self.__showError(err)
113 if out:
114 for line in out.splitlines():
115 self.__processOutputLine(line)
116 if self.__hgClient.wasCanceled():
117 break
118 self.__finish()
119
120 def __finish(self):
121 """
122 Private slot called when the process finished or the user pressed
123 the button.
124 """
125 self.buttonBox.button(
126 QDialogButtonBox.StandardButton.Close).setEnabled(True)
127 self.buttonBox.button(
128 QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
129 self.buttonBox.button(
130 QDialogButtonBox.StandardButton.Close).setDefault(True)
131
132 self.refreshButton.setEnabled(True)
133
134 self.__resizeColumns()
135 self.__resort()
136 self.on_conflictsList_itemSelectionChanged()
137
138 @pyqtSlot(QAbstractButton)
139 def on_buttonBox_clicked(self, button):
140 """
141 Private slot called by a button of the button box clicked.
142
143 @param button button that was clicked (QAbstractButton)
144 """
145 if button == self.buttonBox.button(
146 QDialogButtonBox.StandardButton.Close
147 ):
148 self.close()
149 elif button == self.buttonBox.button(
150 QDialogButtonBox.StandardButton.Cancel
151 ):
152 self.__hgClient.cancel()
153 elif button == self.refreshButton:
154 self.on_refreshButton_clicked()
155
156 def __resort(self):
157 """
158 Private method to resort the tree.
159 """
160 self.conflictsList.sortItems(
161 self.conflictsList.sortColumn(),
162 self.conflictsList.header().sortIndicatorOrder())
163
164 def __resizeColumns(self):
165 """
166 Private method to resize the list columns.
167 """
168 self.conflictsList.header().resizeSections(
169 QHeaderView.ResizeMode.ResizeToContents)
170 self.conflictsList.header().setStretchLastSection(True)
171
172 def __generateItem(self, status, name):
173 """
174 Private method to generate a tag item in the tag list.
175
176 @param status status of the file (string)
177 @param name name of the file (string)
178 """
179 itm = QTreeWidgetItem(self.conflictsList)
180 if status == "U":
181 itm.setText(0, self.tr("Unresolved"))
182 elif status == "R":
183 itm.setText(0, self.tr("Resolved"))
184 else:
185 itm.setText(0, self.tr("Unknown Status"))
186 itm.setText(1, name)
187
188 itm.setData(0, self.StatusRole, status)
189 itm.setData(0, self.FilenameRole, self.project.getAbsolutePath(name))
190
191 def __processOutputLine(self, line):
192 """
193 Private method to process the lines of output.
194
195 @param line output line to be processed (string)
196 """
197 status, filename = line.strip().split(None, 1)
198 self.__generateItem(status, filename)
199
200 def __showError(self, out):
201 """
202 Private slot to show some error.
203
204 @param out error to be shown (string)
205 """
206 self.errorGroup.show()
207 self.errors.insertPlainText(out)
208 self.errors.ensureCursorVisible()
209
210 @pyqtSlot()
211 def on_refreshButton_clicked(self):
212 """
213 Private slot to refresh the log.
214 """
215 self.buttonBox.button(
216 QDialogButtonBox.StandardButton.Close).setEnabled(False)
217 self.buttonBox.button(
218 QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
219 self.buttonBox.button(
220 QDialogButtonBox.StandardButton.Cancel).setDefault(True)
221
222 self.refreshButton.setEnabled(False)
223 self.start()
224
225 @pyqtSlot(QTreeWidgetItem, int)
226 def on_conflictsList_itemDoubleClicked(self, item, column):
227 """
228 Private slot to open the double clicked entry.
229
230 @param item reference to the double clicked item (QTreeWidgetItem)
231 @param column column that was double clicked (integer)
232 """
233 self.on_editButton_clicked()
234
235 @pyqtSlot()
236 def on_conflictsList_itemSelectionChanged(self):
237 """
238 Private slot to handle a change of selected conflict entries.
239 """
240 selectedCount = len(self.conflictsList.selectedItems())
241 unresolved = resolved = 0
242 for itm in self.conflictsList.selectedItems():
243 status = itm.data(0, self.StatusRole)
244 if status == "U":
245 unresolved += 1
246 elif status == "R":
247 resolved += 1
248
249 self.resolvedButton.setEnabled(unresolved > 0)
250 self.unresolvedButton.setEnabled(resolved > 0)
251 self.reMergeButton.setEnabled(unresolved > 0)
252 self.editButton.setEnabled(
253 selectedCount == 1 and
254 Utilities.MimeTypes.isTextFile(
255 self.conflictsList.selectedItems()[0].data(
256 0, self.FilenameRole)))
257
258 @pyqtSlot()
259 def on_resolvedButton_clicked(self):
260 """
261 Private slot to mark the selected entries as resolved.
262 """
263 names = [
264 itm.data(0, self.FilenameRole)
265 for itm in self.conflictsList.selectedItems()
266 if itm.data(0, self.StatusRole) == "U"
267 ]
268 if names:
269 self.vcs.hgResolved(names)
270 self.on_refreshButton_clicked()
271
272 @pyqtSlot()
273 def on_unresolvedButton_clicked(self):
274 """
275 Private slot to mark the selected entries as unresolved.
276 """
277 names = [
278 itm.data(0, self.FilenameRole)
279 for itm in self.conflictsList.selectedItems()
280 if itm.data(0, self.StatusRole) == "R"
281 ]
282 if names:
283 self.vcs.hgResolved(names, unresolve=True)
284 self.on_refreshButton_clicked()
285
286 @pyqtSlot()
287 def on_reMergeButton_clicked(self):
288 """
289 Private slot to re-merge the selected entries.
290 """
291 names = [
292 itm.data(0, self.FilenameRole)
293 for itm in self.conflictsList.selectedItems()
294 if itm.data(0, self.StatusRole) == "U"
295 ]
296 if names:
297 self.vcs.hgReMerge(names)
298
299 @pyqtSlot()
300 def on_editButton_clicked(self):
301 """
302 Private slot to open the selected file in an editor.
303 """
304 itm = self.conflictsList.selectedItems()[0]
305 filename = itm.data(0, self.FilenameRole)
306 if Utilities.MimeTypes.isTextFile(filename):
307 e5App().getObject("ViewManager").getEditor(filename)

eric ide

mercurial