21 from .SvnDiffDialog import SvnDiffDialog |
21 from .SvnDiffDialog import SvnDiffDialog |
22 |
22 |
23 from .Ui_SvnLogBrowserDialog import Ui_SvnLogBrowserDialog |
23 from .Ui_SvnLogBrowserDialog import Ui_SvnLogBrowserDialog |
24 |
24 |
25 import UI.PixmapCache |
25 import UI.PixmapCache |
|
26 |
26 |
27 |
27 class SvnLogBrowserDialog(QDialog, SvnDialogMixin, Ui_SvnLogBrowserDialog): |
28 class SvnLogBrowserDialog(QDialog, SvnDialogMixin, Ui_SvnLogBrowserDialog): |
28 """ |
29 """ |
29 Class implementing a dialog to browse the log history. |
30 Class implementing a dialog to browse the log history. |
30 """ |
31 """ |
31 def __init__(self, vcs, parent = None): |
32 def __init__(self, vcs, parent=None): |
32 """ |
33 """ |
33 Constructor |
34 Constructor |
34 |
35 |
35 @param vcs reference to the vcs object |
36 @param vcs reference to the vcs object |
36 @param parent parent widget (QWidget) |
37 @param parent parent widget (QWidget) |
62 |
63 |
63 self.__messageRole = Qt.UserRole |
64 self.__messageRole = Qt.UserRole |
64 self.__changesRole = Qt.UserRole + 1 |
65 self.__changesRole = Qt.UserRole + 1 |
65 |
66 |
66 self.flags = { |
67 self.flags = { |
67 'A' : self.trUtf8('Added'), |
68 'A': self.trUtf8('Added'), |
68 'D' : self.trUtf8('Deleted'), |
69 'D': self.trUtf8('Deleted'), |
69 'M' : self.trUtf8('Modified') |
70 'M': self.trUtf8('Modified') |
70 } |
71 } |
71 |
72 |
72 self.diff = None |
73 self.diff = None |
73 self.__lastRev = 0 |
74 self.__lastRev = 0 |
74 |
75 |
102 |
103 |
103 def __resortLog(self): |
104 def __resortLog(self): |
104 """ |
105 """ |
105 Private method to resort the log tree. |
106 Private method to resort the log tree. |
106 """ |
107 """ |
107 self.logTree.sortItems(self.logTree.sortColumn(), |
108 self.logTree.sortItems(self.logTree.sortColumn(), |
108 self.logTree.header().sortIndicatorOrder()) |
109 self.logTree.header().sortIndicatorOrder()) |
109 |
110 |
110 def __resizeColumnsFiles(self): |
111 def __resizeColumnsFiles(self): |
111 """ |
112 """ |
112 Private method to resize the changed files tree columns. |
113 Private method to resize the changed files tree columns. |
117 def __resortFiles(self): |
118 def __resortFiles(self): |
118 """ |
119 """ |
119 Private method to resort the changed files tree. |
120 Private method to resort the changed files tree. |
120 """ |
121 """ |
121 sortColumn = self.filesTree.sortColumn() |
122 sortColumn = self.filesTree.sortColumn() |
122 self.filesTree.sortItems(1, |
123 self.filesTree.sortItems(1, |
123 self.filesTree.header().sortIndicatorOrder()) |
124 self.filesTree.header().sortIndicatorOrder()) |
124 self.filesTree.sortItems(sortColumn, |
125 self.filesTree.sortItems(sortColumn, |
125 self.filesTree.header().sortIndicatorOrder()) |
126 self.filesTree.header().sortIndicatorOrder()) |
126 |
127 |
127 def __generateLogItem(self, author, date, message, revision, changedPaths): |
128 def __generateLogItem(self, author, date, message, revision, changedPaths): |
128 """ |
129 """ |
129 Private method to generate a log tree entry. |
130 Private method to generate a log tree entry. |
131 @param author author info (string) |
132 @param author author info (string) |
132 @param date date info (integer) |
133 @param date date info (integer) |
133 @param message text of the log message (string) |
134 @param message text of the log message (string) |
134 @param revision revision info (string or pysvn.opt_revision_kind) |
135 @param revision revision info (string or pysvn.opt_revision_kind) |
135 @param changedPaths list of pysvn dictionary like objects containing |
136 @param changedPaths list of pysvn dictionary like objects containing |
136 info about the changed files/directories |
137 info about the changed files/directories |
137 @return reference to the generated item (QTreeWidgetItem) |
138 @return reference to the generated item (QTreeWidgetItem) |
138 """ |
139 """ |
139 if revision == "": |
140 if revision == "": |
140 rev = "" |
141 rev = "" |
141 self.__lastRev = 0 |
142 self.__lastRev = 0 |
145 if date == "": |
146 if date == "": |
146 dt = "" |
147 dt = "" |
147 else: |
148 else: |
148 dt = formatTime(date) |
149 dt = formatTime(date) |
149 |
150 |
150 itm = QTreeWidgetItem(self.logTree, |
151 itm = QTreeWidgetItem(self.logTree, |
151 [rev, author, dt," ".join(message.splitlines())] |
152 [rev, author, dt, " ".join(message.splitlines())] |
152 ) |
153 ) |
153 |
154 |
154 changes = [] |
155 changes = [] |
155 for changedPath in changedPaths: |
156 for changedPath in changedPaths: |
156 if changedPath["copyfrom_path"] is None: |
157 if changedPath["copyfrom_path"] is None: |
160 if changedPath["copyfrom_revision"] is None: |
161 if changedPath["copyfrom_revision"] is None: |
161 copyRev = "" |
162 copyRev = "" |
162 else: |
163 else: |
163 copyRev = "{0:7d}".format(changedPath["copyfrom_revision"].number) |
164 copyRev = "{0:7d}".format(changedPath["copyfrom_revision"].number) |
164 change = { |
165 change = { |
165 "action" : changedPath["action"], |
166 "action": changedPath["action"], |
166 "path" : changedPath["path"], |
167 "path": changedPath["path"], |
167 "copyfrom_path" : copyPath, |
168 "copyfrom_path": copyPath, |
168 "copyfrom_revision" : copyRev, |
169 "copyfrom_revision": copyRev, |
169 } |
170 } |
170 changes.append(change) |
171 changes.append(change) |
171 itm.setData(0, self.__messageRole, message) |
172 itm.setData(0, self.__messageRole, message) |
172 itm.setData(0, self.__changesRole, changes) |
173 itm.setData(0, self.__changesRole, changes) |
173 |
174 |
187 @param path path of the file in the repository (string) |
188 @param path path of the file in the repository (string) |
188 @param copyFrom path the file was copied from (None, string) |
189 @param copyFrom path the file was copied from (None, string) |
189 @param copyRev revision the file was copied from (None, string) |
190 @param copyRev revision the file was copied from (None, string) |
190 @return reference to the generated item (QTreeWidgetItem) |
191 @return reference to the generated item (QTreeWidgetItem) |
191 """ |
192 """ |
192 itm = QTreeWidgetItem(self.filesTree, |
193 itm = QTreeWidgetItem(self.filesTree, |
193 [self.flags[action], path, copyFrom, copyRev] |
194 [self.flags[action], path, copyFrom, copyRev] |
194 ) |
195 ) |
195 |
196 |
196 itm.setTextAlignment(3, Qt.AlignRight) |
197 itm.setTextAlignment(3, Qt.AlignRight) |
197 |
198 |
198 return itm |
199 return itm |
199 |
200 |
200 def __getLogEntries(self, startRev = None): |
201 def __getLogEntries(self, startRev=None): |
201 """ |
202 """ |
202 Private method to retrieve log entries from the repository. |
203 Private method to retrieve log entries from the repository. |
203 |
204 |
204 @param startRev revision number to start from (integer, string) |
205 @param startRev revision number to start from (integer, string) |
205 """ |
206 """ |
230 if fetched == 0: |
231 if fetched == 0: |
231 revstart = start |
232 revstart = start |
232 else: |
233 else: |
233 revstart = pysvn.Revision( |
234 revstart = pysvn.Revision( |
234 pysvn.opt_revision_kind.number, nextRev) |
235 pysvn.opt_revision_kind.number, nextRev) |
235 allLogs = self.client.log(self.fname, |
236 allLogs = self.client.log(self.fname, |
236 revision_start = revstart, |
237 revision_start=revstart, |
237 discover_changed_paths = True, |
238 discover_changed_paths=True, |
238 limit = flimit + 1, |
239 limit=flimit + 1, |
239 strict_node_history = self.stopCheckBox.isChecked()) |
240 strict_node_history=self.stopCheckBox.isChecked()) |
240 if len(allLogs) <= flimit or self._clientCancelCallback(): |
241 if len(allLogs) <= flimit or self._clientCancelCallback(): |
241 logs.extend(allLogs) |
242 logs.extend(allLogs) |
242 break |
243 break |
243 else: |
244 else: |
244 logs.extend(allLogs[:-1]) |
245 logs.extend(allLogs[:-1]) |
245 nextRev = allLogs[-1]["revision"].number |
246 nextRev = allLogs[-1]["revision"].number |
246 fetched += fetchLimit |
247 fetched += fetchLimit |
247 locker.unlock() |
248 locker.unlock() |
248 |
249 |
249 for log in logs: |
250 for log in logs: |
250 self.__generateLogItem(log["author"], log["date"], |
251 self.__generateLogItem(log["author"], log["date"], |
251 log["message"], log["revision"], log['changed_paths']) |
252 log["message"], log["revision"], log['changed_paths']) |
252 dt = dateFromTime_t(log["date"]) |
253 dt = dateFromTime_t(log["date"]) |
253 if not self.__maxDate.isValid() and not self.__minDate.isValid(): |
254 if not self.__maxDate.isValid() and not self.__minDate.isValid(): |
254 self.__maxDate = dt |
255 self.__maxDate = dt |
255 self.__minDate = dt |
256 self.__minDate = dt |
317 """ |
318 """ |
318 if self.diff is None: |
319 if self.diff is None: |
319 self.diff = SvnDiffDialog(self.vcs) |
320 self.diff = SvnDiffDialog(self.vcs) |
320 self.diff.show() |
321 self.diff.show() |
321 QApplication.processEvents() |
322 QApplication.processEvents() |
322 self.diff.start(self.filename, [rev1, rev2], pegRev = peg_rev) |
323 self.diff.start(self.filename, [rev1, rev2], pegRev=peg_rev) |
323 |
324 |
324 def on_buttonBox_clicked(self, button): |
325 def on_buttonBox_clicked(self, button): |
325 """ |
326 """ |
326 Private slot called by a button of the button box clicked. |
327 Private slot called by a button of the button box clicked. |
327 |
328 |
345 |
346 |
346 self.filesTree.clear() |
347 self.filesTree.clear() |
347 changes = current.data(0, self.__changesRole) |
348 changes = current.data(0, self.__changesRole) |
348 if len(changes) > 0: |
349 if len(changes) > 0: |
349 for change in changes: |
350 for change in changes: |
350 self.__generateFileItem(change["action"], change["path"], |
351 self.__generateFileItem(change["action"], change["path"], |
351 change["copyfrom_path"], change["copyfrom_revision"]) |
352 change["copyfrom_path"], change["copyfrom_revision"]) |
352 self.__resizeColumnsFiles() |
353 self.__resizeColumnsFiles() |
353 self.__resortFiles() |
354 self.__resortFiles() |
354 |
355 |
355 self.diffPreviousButton.setEnabled( |
356 self.diffPreviousButton.setEnabled( |
508 @pyqtSlot(bool) |
509 @pyqtSlot(bool) |
509 def on_stopCheckBox_clicked(self, checked): |
510 def on_stopCheckBox_clicked(self, checked): |
510 """ |
511 """ |
511 Private slot called, when the stop on copy/move checkbox is clicked |
512 Private slot called, when the stop on copy/move checkbox is clicked |
512 """ |
513 """ |
513 self.vcs.getPlugin().setPreferences("StopLogOnCopy", |
514 self.vcs.getPlugin().setPreferences("StopLogOnCopy", |
514 int(self.stopCheckBox.isChecked())) |
515 int(self.stopCheckBox.isChecked())) |
515 self.nextButton.setEnabled(True) |
516 self.nextButton.setEnabled(True) |
516 self.limitSpinBox.setEnabled(True) |
517 self.limitSpinBox.setEnabled(True) |