RefactoringRope/HistoryDialog.py

branch
eric7
changeset 389
4f53795beff0
parent 374
958f34e97952
child 396
933b8fcd854f
equal deleted inserted replaced
388:cb044ec27c24 389:4f53795beff0
7 Module implementing the History dialog. 7 Module implementing the History dialog.
8 """ 8 """
9 9
10 from PyQt6.QtCore import pyqtSlot, Qt, QItemSelectionModel 10 from PyQt6.QtCore import pyqtSlot, Qt, QItemSelectionModel
11 from PyQt6.QtGui import QBrush, QTextCursor 11 from PyQt6.QtGui import QBrush, QTextCursor
12 from PyQt6.QtWidgets import ( 12 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QListWidgetItem, QAbstractButton
13 QDialog, QDialogButtonBox, QListWidgetItem, QAbstractButton
14 )
15 13
16 from EricWidgets.EricApplication import ericApp 14 from EricWidgets.EricApplication import ericApp
17 from EricWidgets import EricMessageBox 15 from EricWidgets import EricMessageBox
18 16
19 from .Ui_HistoryDialog import Ui_HistoryDialog 17 from .Ui_HistoryDialog import Ui_HistoryDialog
25 23
26 class HistoryDialog(QDialog, Ui_HistoryDialog): 24 class HistoryDialog(QDialog, Ui_HistoryDialog):
27 """ 25 """
28 Class implementing the History dialog. 26 Class implementing the History dialog.
29 """ 27 """
28
30 ChangeIDRole = Qt.ItemDataRole.UserRole 29 ChangeIDRole = Qt.ItemDataRole.UserRole
31 30
32 def __init__(self, refactoring, filename="", parent=None): 31 def __init__(self, refactoring, filename="", parent=None):
33 """ 32 """
34 Constructor 33 Constructor
35 34
36 @param refactoring reference to the main refactoring object 35 @param refactoring reference to the main refactoring object
37 @type RefactoringServer 36 @type RefactoringServer
38 @param filename name of the file to show the history for 37 @param filename name of the file to show the history for
39 @type str 38 @type str
40 @param parent reference to the parent widget 39 @param parent reference to the parent widget
41 @type QWidget 40 @type QWidget
42 """ 41 """
43 QDialog.__init__(self, parent) 42 QDialog.__init__(self, parent)
44 self.setupUi(self) 43 self.setupUi(self)
45 self.setWindowFlags(Qt.WindowType.Window) 44 self.setWindowFlags(Qt.WindowType.Window)
46 45
47 if Globals.isWindowsPlatform(): 46 if Globals.isWindowsPlatform():
48 self.previewEdit.setFontFamily("Lucida Console") 47 self.previewEdit.setFontFamily("Lucida Console")
49 else: 48 else:
50 self.previewEdit.setFontFamily("Monospace") 49 self.previewEdit.setFontFamily("Monospace")
51 50
52 self.formats = {} 51 self.formats = {}
53 self.formats[' '] = self.previewEdit.currentCharFormat() 52 self.formats[" "] = self.previewEdit.currentCharFormat()
54 53
55 charFormat = self.previewEdit.currentCharFormat() 54 charFormat = self.previewEdit.currentCharFormat()
56 charFormat.setBackground( 55 charFormat.setBackground(QBrush(Preferences.getDiffColour("AddedColor")))
57 QBrush(Preferences.getDiffColour("AddedColor"))) 56 self.formats["+"] = charFormat
58 self.formats['+'] = charFormat 57
59 58 charFormat = self.previewEdit.currentCharFormat()
60 charFormat = self.previewEdit.currentCharFormat() 59 charFormat.setBackground(QBrush(Preferences.getDiffColour("RemovedColor")))
61 charFormat.setBackground( 60 self.formats["-"] = charFormat
62 QBrush(Preferences.getDiffColour("RemovedColor"))) 61
63 self.formats['-'] = charFormat 62 charFormat = self.previewEdit.currentCharFormat()
64 63 charFormat.setBackground(QBrush(Preferences.getDiffColour("ReplacedColor")))
65 charFormat = self.previewEdit.currentCharFormat() 64 self.formats["@"] = charFormat
66 charFormat.setBackground( 65
67 QBrush(Preferences.getDiffColour("ReplacedColor"))) 66 charFormat = self.previewEdit.currentCharFormat()
68 self.formats['@'] = charFormat 67 charFormat.setBackground(QBrush(Preferences.getDiffColour("ContextColor")))
69 68 self.formats["?"] = charFormat
70 charFormat = self.previewEdit.currentCharFormat() 69
71 charFormat.setBackground( 70 charFormat = self.previewEdit.currentCharFormat()
72 QBrush(Preferences.getDiffColour("ContextColor"))) 71 charFormat.setBackground(QBrush(Preferences.getDiffColour("HeaderColor")))
73 self.formats['?'] = charFormat 72 self.formats["="] = charFormat
74 73
75 charFormat = self.previewEdit.currentCharFormat()
76 charFormat.setBackground(
77 QBrush(Preferences.getDiffColour("HeaderColor")))
78 self.formats['='] = charFormat
79
80 self.__refactoring = refactoring 74 self.__refactoring = refactoring
81 self.__filename = filename 75 self.__filename = filename
82 76
83 if not filename: 77 if not filename:
84 self.header.setText(self.tr("<b>Project History</b>")) 78 self.header.setText(self.tr("<b>Project History</b>"))
85 else: 79 else:
86 self.header.setText(self.tr("<b>File History: {0}</b>").format( 80 self.header.setText(self.tr("<b>File History: {0}</b>").format(filename))
87 filename)) 81
88
89 self.__undoButton = self.buttonBox.addButton( 82 self.__undoButton = self.buttonBox.addButton(
90 self.tr("&Undo"), QDialogButtonBox.ButtonRole.ActionRole) 83 self.tr("&Undo"), QDialogButtonBox.ButtonRole.ActionRole
84 )
91 self.__redoButton = self.buttonBox.addButton( 85 self.__redoButton = self.buttonBox.addButton(
92 self.tr("&Redo"), QDialogButtonBox.ButtonRole.ActionRole) 86 self.tr("&Redo"), QDialogButtonBox.ButtonRole.ActionRole
87 )
93 self.__refreshButton = self.buttonBox.addButton( 88 self.__refreshButton = self.buttonBox.addButton(
94 self.tr("Re&fresh"), QDialogButtonBox.ButtonRole.ActionRole) 89 self.tr("Re&fresh"), QDialogButtonBox.ButtonRole.ActionRole
90 )
95 self.__clearButton = self.buttonBox.addButton( 91 self.__clearButton = self.buttonBox.addButton(
96 self.tr("&Clear History"), QDialogButtonBox.ButtonRole.ActionRole) 92 self.tr("&Clear History"), QDialogButtonBox.ButtonRole.ActionRole
97 93 )
94
98 # populate the list 95 # populate the list
99 self.__refreshHistories() 96 self.__refreshHistories()
100 97
101 def __appendText(self, txt, charFormat): 98 def __appendText(self, txt, charFormat):
102 """ 99 """
103 Private method to append text to the end of the preview pane. 100 Private method to append text to the end of the preview pane.
104 101
105 @param txt text to insert 102 @param txt text to insert
106 @type str 103 @type str
107 @param charFormat text format to be used 104 @param charFormat text format to be used
108 @type QTextCharFormat 105 @type QTextCharFormat
109 """ 106 """
110 tc = self.previewEdit.textCursor() 107 tc = self.previewEdit.textCursor()
111 tc.movePosition(QTextCursor.MoveOperation.End) 108 tc.movePosition(QTextCursor.MoveOperation.End)
112 self.previewEdit.setTextCursor(tc) 109 self.previewEdit.setTextCursor(tc)
113 self.previewEdit.setCurrentCharFormat(charFormat) 110 self.previewEdit.setCurrentCharFormat(charFormat)
114 self.previewEdit.insertPlainText(txt) 111 self.previewEdit.insertPlainText(txt)
115 112
116 @pyqtSlot(QAbstractButton) 113 @pyqtSlot(QAbstractButton)
117 def on_buttonBox_clicked(self, button): 114 def on_buttonBox_clicked(self, button):
118 """ 115 """
119 Private slot handling the selection of a dialog button. 116 Private slot handling the selection of a dialog button.
120 117
121 @param button reference to the button clicked 118 @param button reference to the button clicked
122 @type QAbstractButton 119 @type QAbstractButton
123 """ 120 """
124 if button == QDialogButtonBox.StandardButton.Close: 121 if button == QDialogButtonBox.StandardButton.Close:
125 self.close() 122 self.close()
129 self.__redoChanges() 126 self.__redoChanges()
130 elif button == self.__refreshButton: 127 elif button == self.__refreshButton:
131 self.__refreshHistories() 128 self.__refreshHistories()
132 elif button == self.__clearButton: 129 elif button == self.__clearButton:
133 self.__clearHistory() 130 self.__clearHistory()
134 131
135 def __currentItemChanged(self, current): 132 def __currentItemChanged(self, current):
136 """ 133 """
137 Private method to request change data of an item. 134 Private method to request change data of an item.
138 135
139 @param current reference to the item to get change data for 136 @param current reference to the item to get change data for
140 @type QListWidgetItem 137 @type QListWidgetItem
141 """ 138 """
142 if current is None: 139 if current is None:
143 return 140 return
144 141
145 self.previewEdit.clear() 142 self.previewEdit.clear()
146 changeId = current.data(HistoryDialog.ChangeIDRole) 143 changeId = current.data(HistoryDialog.ChangeIDRole)
147 self.__refactoring.sendJson("History", { 144 self.__refactoring.sendJson(
148 "Subcommand": "GetChange", 145 "History",
149 "Id": changeId, 146 {
150 }) 147 "Subcommand": "GetChange",
151 148 "Id": changeId,
149 },
150 )
151
152 @pyqtSlot(QListWidgetItem, QListWidgetItem) 152 @pyqtSlot(QListWidgetItem, QListWidgetItem)
153 def on_redoChangesList_currentItemChanged(self, current, previous): 153 def on_redoChangesList_currentItemChanged(self, current, previous):
154 """ 154 """
155 Private slot handling a change of the current redo change. 155 Private slot handling a change of the current redo change.
156 156
157 @param current reference to the new current redo item 157 @param current reference to the new current redo item
158 @type QListWidgetItem 158 @type QListWidgetItem
159 @param previous reference to the previous current redo item 159 @param previous reference to the previous current redo item
160 @type QListWidgetItem 160 @type QListWidgetItem
161 """ 161 """
162 self.__redoButton.setEnabled(current is not None) 162 self.__redoButton.setEnabled(current is not None)
163 self.__currentItemChanged(current) 163 self.__currentItemChanged(current)
164 164
165 @pyqtSlot(QListWidgetItem) 165 @pyqtSlot(QListWidgetItem)
166 def on_redoChangesList_itemClicked(self, item): 166 def on_redoChangesList_itemClicked(self, item):
167 """ 167 """
168 Private slot handling a click on a redo entry. 168 Private slot handling a click on a redo entry.
169 169
170 @param item reference to the clicked item 170 @param item reference to the clicked item
171 @type QListWidgetItem 171 @type QListWidgetItem
172 """ 172 """
173 self.__currentItemChanged(item) 173 self.__currentItemChanged(item)
174 174
175 @pyqtSlot(QListWidgetItem, QListWidgetItem) 175 @pyqtSlot(QListWidgetItem, QListWidgetItem)
176 def on_undoChangesList_currentItemChanged(self, current, previous): 176 def on_undoChangesList_currentItemChanged(self, current, previous):
177 """ 177 """
178 Private slot handling a change of the current undo change. 178 Private slot handling a change of the current undo change.
179 179
180 @param current reference to the new current undo item 180 @param current reference to the new current undo item
181 @type QListWidgetItem 181 @type QListWidgetItem
182 @param previous reference to the previous current undo item 182 @param previous reference to the previous current undo item
183 @type QListWidgetItem 183 @type QListWidgetItem
184 """ 184 """
185 self.__undoButton.setEnabled(current is not None) 185 self.__undoButton.setEnabled(current is not None)
186 self.__currentItemChanged(current) 186 self.__currentItemChanged(current)
187 187
188 @pyqtSlot(QListWidgetItem) 188 @pyqtSlot(QListWidgetItem)
189 def on_undoChangesList_itemClicked(self, item): 189 def on_undoChangesList_itemClicked(self, item):
190 """ 190 """
191 Private slot handling a click on an undo entry. 191 Private slot handling a click on an undo entry.
192 192
193 @param item reference to the clicked item 193 @param item reference to the clicked item
194 @type QListWidgetItem 194 @type QListWidgetItem
195 """ 195 """
196 self.__currentItemChanged(item) 196 self.__currentItemChanged(item)
197 197
198 def __undoChanges(self): 198 def __undoChanges(self):
199 """ 199 """
200 Private method to undo the selected set of changes. 200 Private method to undo the selected set of changes.
201 """ 201 """
202 currentUndoItem = self.undoChangesList.currentItem() 202 currentUndoItem = self.undoChangesList.currentItem()
203 change = currentUndoItem.text() 203 change = currentUndoItem.text()
204 changeId = currentUndoItem.data(HistoryDialog.ChangeIDRole) 204 changeId = currentUndoItem.data(HistoryDialog.ChangeIDRole)
205 res = EricMessageBox.yesNo( 205 res = EricMessageBox.yesNo(
206 None, 206 None,
207 self.tr("Undo Refactorings"), 207 self.tr("Undo Refactorings"),
208 self.tr("""Shall all refactorings up to <b>{0}</b>""" 208 self.tr(
209 """ be undone?""") 209 """Shall all refactorings up to <b>{0}</b>""" """ be undone?"""
210 .format(Utilities.html_encode(change))) 210 ).format(Utilities.html_encode(change)),
211 )
211 if res: 212 if res:
212 if not self.__refactoring.confirmAllBuffersSaved(): 213 if not self.__refactoring.confirmAllBuffersSaved():
213 return 214 return
214 215
215 self.__refactoring.sendJson("History", { 216 self.__refactoring.sendJson(
216 "Subcommand": "Undo", 217 "History",
217 "Id": changeId, 218 {
218 }) 219 "Subcommand": "Undo",
219 220 "Id": changeId,
221 },
222 )
223
220 def __redoChanges(self): 224 def __redoChanges(self):
221 """ 225 """
222 Private method to redo the selected set of changes. 226 Private method to redo the selected set of changes.
223 """ 227 """
224 currentRedoItem = self.redoChangesList.currentItem() 228 currentRedoItem = self.redoChangesList.currentItem()
225 change = currentRedoItem.text() 229 change = currentRedoItem.text()
226 changeId = currentRedoItem.data(HistoryDialog.ChangeIDRole) 230 changeId = currentRedoItem.data(HistoryDialog.ChangeIDRole)
227 res = EricMessageBox.yesNo( 231 res = EricMessageBox.yesNo(
228 None, 232 None,
229 self.tr("Redo Refactorings"), 233 self.tr("Redo Refactorings"),
230 self.tr("""Shall all refactorings up to <b>{0}</b>""" 234 self.tr(
231 """ be redone?""") 235 """Shall all refactorings up to <b>{0}</b>""" """ be redone?"""
232 .format(Utilities.html_encode(change))) 236 ).format(Utilities.html_encode(change)),
237 )
233 if res: 238 if res:
234 if not self.__refactoring.confirmAllBuffersSaved(): 239 if not self.__refactoring.confirmAllBuffersSaved():
235 return 240 return
236 241
237 self.__refactoring.sendJson("History", { 242 self.__refactoring.sendJson(
238 "Subcommand": "Redo", 243 "History",
239 "Id": changeId, 244 {
240 }) 245 "Subcommand": "Redo",
241 246 "Id": changeId,
247 },
248 )
249
242 def __refreshHistories(self): 250 def __refreshHistories(self):
243 """ 251 """
244 Private method to refresh the undo and redo history lists. 252 Private method to refresh the undo and redo history lists.
245 """ 253 """
246 self.__undoButton.setEnabled(False) 254 self.__undoButton.setEnabled(False)
247 self.__redoButton.setEnabled(False) 255 self.__redoButton.setEnabled(False)
248 self.__refreshButton.setEnabled(False) 256 self.__refreshButton.setEnabled(False)
249 self.__clearButton.setEnabled(False) 257 self.__clearButton.setEnabled(False)
250 258
251 self.undoChangesList.clear() 259 self.undoChangesList.clear()
252 self.redoChangesList.clear() 260 self.redoChangesList.clear()
253 self.previewEdit.clear() 261 self.previewEdit.clear()
254 262
255 self.__refactoring.sendJson("History", { 263 self.__refactoring.sendJson(
256 "Subcommand": "Get", 264 "History", {"Subcommand": "Get", "Filename": self.__filename}
257 "Filename": self.__filename 265 )
258 }) 266
259
260 def __clearHistory(self): 267 def __clearHistory(self):
261 """ 268 """
262 Private method to clear the refactoring history. 269 Private method to clear the refactoring history.
263 """ 270 """
264 res = EricMessageBox.yesNo( 271 res = EricMessageBox.yesNo(
265 None, 272 None,
266 self.tr("Clear History"), 273 self.tr("Clear History"),
267 self.tr("Do you really want to clear the refactoring history?")) 274 self.tr("Do you really want to clear the refactoring history?"),
275 )
268 if res: 276 if res:
269 self.sendJson("History", { 277 self.sendJson(
270 "Subcommand": "Clear", 278 "History",
271 }) 279 {
272 280 "Subcommand": "Clear",
281 },
282 )
283
273 self.historyCleared() 284 self.historyCleared()
274 285
275 def historyCleared(self): 286 def historyCleared(self):
276 """ 287 """
277 Public method to indicate, that the refactoring history was cleared 288 Public method to indicate, that the refactoring history was cleared
278 through the menu. 289 through the menu.
279 """ 290 """
280 self.__refreshHistories() 291 self.__refreshHistories()
281 292
282 def processHistoryCommand(self, data): 293 def processHistoryCommand(self, data):
283 """ 294 """
284 Public method to process the data sent by the refactoring client. 295 Public method to process the data sent by the refactoring client.
285 296
286 @param data dictionary containing the history data 297 @param data dictionary containing the history data
287 @type dict 298 @type dict
288 """ 299 """
289 subcommand = data["Subcommand"] 300 subcommand = data["Subcommand"]
290 if subcommand == "Histories": 301 if subcommand == "Histories":
295 itm = QListWidgetItem(change, self.redoChangesList) 306 itm = QListWidgetItem(change, self.redoChangesList)
296 itm.setData(HistoryDialog.ChangeIDRole, changeId) 307 itm.setData(HistoryDialog.ChangeIDRole, changeId)
297 if self.undoChangesList.count() > 0: 308 if self.undoChangesList.count() > 0:
298 self.undoChangesList.setCurrentItem( 309 self.undoChangesList.setCurrentItem(
299 self.undoChangesList.item(0), 310 self.undoChangesList.item(0),
300 QItemSelectionModel.SelectionFlag.Select) 311 QItemSelectionModel.SelectionFlag.Select,
312 )
301 elif self.redoChangesList.count() > 0: 313 elif self.redoChangesList.count() > 0:
302 self.redoChangesList.setCurrentItem( 314 self.redoChangesList.setCurrentItem(
303 self.redoChangesList.item(0), 315 self.redoChangesList.item(0),
304 QItemSelectionModel.SelectionFlag.Select) 316 QItemSelectionModel.SelectionFlag.Select,
305 317 )
318
306 self.__refreshButton.setEnabled(True) 319 self.__refreshButton.setEnabled(True)
307 if ( 320 if self.undoChangesList.count() > 0 or self.redoChangesList.count() > 0:
308 self.undoChangesList.count() > 0 or
309 self.redoChangesList.count() > 0
310 ):
311 self.__clearButton.setEnabled(True) 321 self.__clearButton.setEnabled(True)
312 322
313 elif subcommand == "ChangeDescription": 323 elif subcommand == "ChangeDescription":
314 for line in data["Description"].splitlines(True): 324 for line in data["Description"].splitlines(True):
315 try: 325 try:
316 charFormat = self.formats[line[0]] 326 charFormat = self.formats[line[0]]
317 except (IndexError, KeyError): 327 except (IndexError, KeyError):
318 charFormat = self.formats[' '] 328 charFormat = self.formats[" "]
319 self.__appendText(line, charFormat) 329 self.__appendText(line, charFormat)
320 330
321 elif subcommand in ["Undo", "Redo"]: 331 elif subcommand in ["Undo", "Redo"]:
322 self.__refactoring.refreshEditors(data["ChangedFiles"]) 332 self.__refactoring.refreshEditors(data["ChangedFiles"])
323 p = ericApp().getObject("Project") 333 p = ericApp().getObject("Project")
324 if p.isDirty(): 334 if p.isDirty():
325 p.saveProject() 335 p.saveProject()
326 336
327 self.raise_() 337 self.raise_()
328 self.__refreshHistories() 338 self.__refreshHistories()
329 339
330 def closeEvent(self, evt): 340 def closeEvent(self, evt):
331 """ 341 """
332 Protected method handling close events. 342 Protected method handling close events.
333 343
334 @param evt reference to the close event object 344 @param evt reference to the close event object
335 @type QCloseEvent 345 @type QCloseEvent
336 """ 346 """
337 self.__refactoring.sendJson("History", { 347 self.__refactoring.sendJson(
338 "Subcommand": "ClearChanges", 348 "History",
339 }) 349 {
340 350 "Subcommand": "ClearChanges",
351 },
352 )
353
341 evt.accept() 354 evt.accept()

eric ide

mercurial