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