2 |
2 |
3 # Copyright (c) 2003 - 2013 Detlev Offenbach <detlev@die-offenbachs.de> |
3 # Copyright (c) 2003 - 2013 Detlev Offenbach <detlev@die-offenbachs.de> |
4 # |
4 # |
5 |
5 |
6 """ |
6 """ |
7 Module implementing a dialog to show the output of the svn diff command process. |
7 Module implementing a dialog to show the output of the svn diff command |
|
8 process. |
8 """ |
9 """ |
9 |
10 |
10 import os |
11 import os |
11 |
12 |
12 import pysvn |
13 import pysvn |
13 |
14 |
14 from PyQt4.QtCore import QMutexLocker, QFileInfo, QDateTime, Qt, pyqtSlot |
15 from PyQt4.QtCore import QMutexLocker, QFileInfo, QDateTime, Qt, pyqtSlot |
15 from PyQt4.QtGui import QWidget, QColor, QCursor, QBrush, QApplication, QTextCursor, \ |
16 from PyQt4.QtGui import QWidget, QColor, QCursor, QBrush, QApplication, \ |
16 QDialogButtonBox |
17 QTextCursor, QDialogButtonBox |
17 |
18 |
18 from E5Gui.E5Application import e5App |
19 from E5Gui.E5Application import e5App |
19 from E5Gui import E5MessageBox, E5FileDialog |
20 from E5Gui import E5MessageBox, E5FileDialog |
20 |
21 |
21 from .SvnDialogMixin import SvnDialogMixin |
22 from .SvnDialogMixin import SvnDialogMixin |
66 self.client.callback_ssl_server_trust_prompt = \ |
67 self.client.callback_ssl_server_trust_prompt = \ |
67 self._clientSslServerTrustPromptCallback |
68 self._clientSslServerTrustPromptCallback |
68 |
69 |
69 def __getVersionArg(self, version): |
70 def __getVersionArg(self, version): |
70 """ |
71 """ |
71 Private method to get a pysvn revision object for the given version number. |
72 Private method to get a pysvn revision object for the given version |
|
73 number. |
72 |
74 |
73 @param version revision (integer or string) |
75 @param version revision (integer or string) |
74 @return revision object (pysvn.Revision) |
76 @return revision object (pysvn.Revision) |
75 """ |
77 """ |
76 if isinstance(version, int): |
78 if isinstance(version, int): |
113 def start(self, fn, versions=None, urls=None, summary=False, pegRev=None): |
115 def start(self, fn, versions=None, urls=None, summary=False, pegRev=None): |
114 """ |
116 """ |
115 Public slot to start the svn diff command. |
117 Public slot to start the svn diff command. |
116 |
118 |
117 @param fn filename to be diffed (string) |
119 @param fn filename to be diffed (string) |
118 @param versions list of versions to be diffed (list of up to 2 integer or None) |
120 @param versions list of versions to be diffed (list of up to 2 integer |
|
121 or None) |
119 @keyparam urls list of repository URLs (list of 2 strings) |
122 @keyparam urls list of repository URLs (list of 2 strings) |
120 @keyparam summary flag indicating a summarizing diff |
123 @keyparam summary flag indicating a summarizing diff |
121 (only valid for URL diffs) (boolean) |
124 (only valid for URL diffs) (boolean) |
122 @keyparam pegRev revision number the filename is valid (integer) |
125 @keyparam pegRev revision number the filename is valid (integer) |
123 """ |
126 """ |
195 try: |
198 try: |
196 dname = e5App().getObject('Project').getRelativePath(dname) |
199 dname = e5App().getObject('Project').getRelativePath(dname) |
197 if dname: |
200 if dname: |
198 dname += "/" |
201 dname += "/" |
199 for name in fnames: |
202 for name in fnames: |
200 self.__showError(self.trUtf8("Processing file '{0}'...\n").format(name)) |
203 self.__showError( |
|
204 self.trUtf8("Processing file '{0}'...\n").format(name)) |
201 if urls is not None: |
205 if urls is not None: |
202 url1 = "{0}/{1}{2}".format(urls[0], dname, name) |
206 url1 = "{0}/{1}{2}".format(urls[0], dname, name) |
203 url2 = "{0}/{1}{2}".format(urls[1], dname, name) |
207 url2 = "{0}/{1}{2}".format(urls[1], dname, name) |
204 if summary: |
208 if summary: |
205 diff_summary = self.client.diff_summarize( |
209 diff_summary = self.client.diff_summarize( |
207 url_or_path2=url2, revision2=rev2, |
211 url_or_path2=url2, revision2=rev2, |
208 recurse=recurse) |
212 recurse=recurse) |
209 diff_list = [] |
213 diff_list = [] |
210 for diff_sum in diff_summary: |
214 for diff_sum in diff_summary: |
211 diff_list.append("{0} {1}".format( |
215 diff_list.append("{0} {1}".format( |
212 self.__getDiffSummaryKind(diff_sum['summarize_kind']), |
216 self.__getDiffSummaryKind( |
|
217 diff_sum['summarize_kind']), |
213 diff_sum['path'])) |
218 diff_sum['path'])) |
214 diffText = os.linesep.join(diff_list) |
219 diffText = os.linesep.join(diff_list) |
215 else: |
220 else: |
216 diffText = self.client.diff(tmpdir, |
221 diffText = self.client.diff(tmpdir, |
217 url1, revision1=rev1, |
222 url1, revision1=rev1, |
218 url_or_path2=url2, revision2=rev2, |
223 url_or_path2=url2, revision2=rev2, |
219 recurse=recurse) |
224 recurse=recurse) |
220 else: |
225 else: |
221 if pegRev is not None: |
226 if pegRev is not None: |
222 diffText = self.client.diff_peg(tmpdir, name, |
227 diffText = self.client.diff_peg( |
|
228 tmpdir, name, |
223 peg_revision=self.__getVersionArg(pegRev), |
229 peg_revision=self.__getVersionArg(pegRev), |
224 revision_start=rev1, revision_end=rev2, recurse=recurse) |
230 revision_start=rev1, revision_end=rev2, |
|
231 recurse=recurse) |
225 else: |
232 else: |
226 diffText = self.client.diff(tmpdir, name, |
233 diffText = self.client.diff(tmpdir, name, |
227 revision1=rev1, revision2=rev2, recurse=recurse) |
234 revision1=rev1, revision2=rev2, recurse=recurse) |
228 counter = 0 |
235 counter = 0 |
229 for line in diffText.splitlines(): |
236 for line in diffText.splitlines(): |
257 """ |
264 """ |
258 Private method to append text to the end of the contents pane. |
265 Private method to append text to the end of the contents pane. |
259 |
266 |
260 @param line line of text to insert (string) |
267 @param line line of text to insert (string) |
261 """ |
268 """ |
262 if line.startswith('+') or line.startswith('>') or line.startswith('A '): |
269 if line.startswith('+') or line.startswith('>') or \ |
|
270 line.startswith('A '): |
263 format = self.cAddedFormat |
271 format = self.cAddedFormat |
264 elif line.startswith('-') or line.startswith('<') or line.startswith('D '): |
272 elif line.startswith('-') or line.startswith('<') or \ |
|
273 line.startswith('D '): |
265 format = self.cRemovedFormat |
274 format = self.cRemovedFormat |
266 elif line.startswith('@@'): |
275 elif line.startswith('@@'): |
267 format = self.cLineNoFormat |
276 format = self.cLineNoFormat |
268 else: |
277 else: |
269 format = self.cNormalFormat |
278 format = self.cNormalFormat |
295 if line.startswith('---'): |
304 if line.startswith('---'): |
296 self.__oldFileLine = self.paras |
305 self.__oldFileLine = self.paras |
297 self.__oldFile = self.__extractFileName(line) |
306 self.__oldFile = self.__extractFileName(line) |
298 else: |
307 else: |
299 self.__fileSeparators.append( |
308 self.__fileSeparators.append( |
300 (self.__oldFile, self.__extractFileName(line), self.__oldFileLine)) |
309 (self.__oldFile, self.__extractFileName(line), |
|
310 self.__oldFileLine)) |
301 |
311 |
302 def __finish(self): |
312 def __finish(self): |
303 """ |
313 """ |
304 Private slot called when the user pressed the button. |
314 Private slot called when the user pressed the button. |
305 """ |
315 """ |
316 |
326 |
317 self.filesCombo.addItem(self.trUtf8("<Start>"), 0) |
327 self.filesCombo.addItem(self.trUtf8("<Start>"), 0) |
318 self.filesCombo.addItem(self.trUtf8("<End>"), -1) |
328 self.filesCombo.addItem(self.trUtf8("<End>"), -1) |
319 for oldFile, newFile, pos in sorted(self.__fileSeparators): |
329 for oldFile, newFile, pos in sorted(self.__fileSeparators): |
320 if oldFile != newFile: |
330 if oldFile != newFile: |
321 self.filesCombo.addItem("{0}\n{1}".format(oldFile, newFile), pos) |
331 self.filesCombo.addItem( |
|
332 "{0}\n{1}".format(oldFile, newFile), pos) |
322 else: |
333 else: |
323 self.filesCombo.addItem(oldFile, pos) |
334 self.filesCombo.addItem(oldFile, pos) |
324 |
335 |
325 self._cancel() |
336 self._cancel() |
326 |
337 |
364 self.contents.ensureCursorVisible() |
375 self.contents.ensureCursorVisible() |
365 |
376 |
366 # step 2: move cursor to desired line |
377 # step 2: move cursor to desired line |
367 tc = self.contents.textCursor() |
378 tc = self.contents.textCursor() |
368 delta = tc.blockNumber() - para |
379 delta = tc.blockNumber() - para |
369 tc.movePosition(QTextCursor.PreviousBlock, QTextCursor.MoveAnchor, delta) |
380 tc.movePosition(QTextCursor.PreviousBlock, QTextCursor.MoveAnchor, |
|
381 delta) |
370 self.contents.setTextCursor(tc) |
382 self.contents.setTextCursor(tc) |
371 self.contents.ensureCursorVisible() |
383 self.contents.ensureCursorVisible() |
372 |
384 |
373 @pyqtSlot() |
385 @pyqtSlot() |
374 def on_saveButton_clicked(self): |
386 def on_saveButton_clicked(self): |