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() |