Plugins/VcsPlugins/vcsPySvn/subversion.py

changeset 945
8cd4d08fa9f6
parent 791
9ec2ac20e54e
child 1083
dc680a0ce221
equal deleted inserted replaced
944:1b59c4ba121e 945:8cd4d08fa9f6
7 Module implementing the version control systems interface to Subversion. 7 Module implementing the version control systems interface to Subversion.
8 """ 8 """
9 9
10 import os 10 import os
11 import shutil 11 import shutil
12 import urllib.request, urllib.parse, urllib.error 12 import urllib.request
13 import urllib.parse
14 import urllib.error
13 import time 15 import time
14 16
15 from PyQt4.QtCore import * 17 from PyQt4.QtCore import *
16 from PyQt4.QtGui import * 18 from PyQt4.QtGui import *
17 19
51 53
52 from Plugins.VcsPlugins.vcsSubversion.SvnDialog import SvnDialog as SvnProcessDialog 54 from Plugins.VcsPlugins.vcsSubversion.SvnDialog import SvnDialog as SvnProcessDialog
53 55
54 import Utilities 56 import Utilities
55 57
58
56 class Subversion(VersionControl): 59 class Subversion(VersionControl):
57 """ 60 """
58 Class implementing the version control systems interface to Subversion. 61 Class implementing the version control systems interface to Subversion.
59 62
60 @signal committed() emitted after the commit action has completed 63 @signal committed() emitted after the commit action has completed
61 """ 64 """
62 committed = pyqtSignal() 65 committed = pyqtSignal()
63 66
64 def __init__(self, plugin, parent = None, name = None): 67 def __init__(self, plugin, parent=None, name=None):
65 """ 68 """
66 Constructor 69 Constructor
67 70
68 @param plugin reference to the plugin object 71 @param plugin reference to the plugin object
69 @param parent parent widget (QWidget) 72 @param parent parent widget (QWidget)
70 @param name name of this object (string) 73 @param name name of this object (string)
71 """ 74 """
72 VersionControl.__init__(self, parent, name) 75 VersionControl.__init__(self, parent, name)
73 self.defaultOptions = { 76 self.defaultOptions = {
74 'global' : [''], 77 'global': [''],
75 'commit' : [''], 78 'commit': [''],
76 'checkout' : [''], 79 'checkout': [''],
77 'update' : [''], 80 'update': [''],
78 'add' : [''], 81 'add': [''],
79 'remove' : [''], 82 'remove': [''],
80 'diff' : [''], 83 'diff': [''],
81 'log' : [''], 84 'log': [''],
82 'history' : [''], 85 'history': [''],
83 'status' : [''], 86 'status': [''],
84 'tag' : [''], 87 'tag': [''],
85 'export' : [''] 88 'export': ['']
86 } 89 }
87 self.interestingDataKeys = [ 90 self.interestingDataKeys = [
88 "standardLayout", 91 "standardLayout",
89 ] 92 ]
90 93
99 self.mergeList = [[], [], []] 102 self.mergeList = [[], [], []]
100 self.showedTags = False 103 self.showedTags = False
101 self.showedBranches = False 104 self.showedBranches = False
102 105
103 self.tagTypeList = [ 106 self.tagTypeList = [
104 'tags', 107 'tags',
105 'branches' 108 'branches'
106 ] 109 ]
107 110
108 self.commandHistory = [] 111 self.commandHistory = []
109 self.wdHistory = [] 112 self.wdHistory = []
187 @return flag indicating the existance (boolean) and an error message (string) 190 @return flag indicating the existance (boolean) and an error message (string)
188 """ 191 """
189 self.versionStr = ".".join([str(v) for v in pysvn.svn_version[:-1]]) 192 self.versionStr = ".".join([str(v) for v in pysvn.svn_version[:-1]])
190 return True, "" 193 return True, ""
191 194
192 def vcsInit(self, vcsDir, noDialog = False): 195 def vcsInit(self, vcsDir, noDialog=False):
193 """ 196 """
194 Public method used to initialize the subversion repository. 197 Public method used to initialize the subversion repository.
195 198
196 The subversion repository has to be initialized from outside eric5 199 The subversion repository has to be initialized from outside eric5
197 because the respective command always works locally. Therefore we 200 because the respective command always works locally. Therefore we
251 project.setDirty(True) 254 project.setDirty(True)
252 project.saveProject() 255 project.saveProject()
253 project.closeProject() 256 project.closeProject()
254 return 257 return
255 shutil.rmtree(tmpProjectDir, True) 258 shutil.rmtree(tmpProjectDir, True)
256 project.closeProject(noSave = True) 259 project.closeProject(noSave=True)
257 project.openProject(pfn) 260 project.openProject(pfn)
258 261
259 def vcsImport(self, vcsDataDict, projectDir, noDialog = False): 262 def vcsImport(self, vcsDataDict, projectDir, noDialog=False):
260 """ 263 """
261 Public method used to import the project into the Subversion repository. 264 Public method used to import the project into the Subversion repository.
262 265
263 @param vcsDataDict dictionary of data required for the import 266 @param vcsDataDict dictionary of data required for the import
264 @param projectDir project directory (string) 267 @param projectDir project directory (string)
290 shutil.copytree(projectDir, os.path.join(tmpDir, project, 'trunk')) 293 shutil.copytree(projectDir, os.path.join(tmpDir, project, 'trunk'))
291 else: 294 else:
292 shutil.copytree(projectDir, os.path.join(tmpDir, project)) 295 shutil.copytree(projectDir, os.path.join(tmpDir, project))
293 except OSError as e: 296 except OSError as e:
294 if os.path.isdir(tmpDir): 297 if os.path.isdir(tmpDir):
295 shutil.rmtree(tmpDir, True) 298 shutil.rmtree(tmpDir, True)
296 return False, False 299 return False, False
297 300
298 locker = QMutexLocker(self.vcsExecutionMutex) 301 locker = QMutexLocker(self.vcsExecutionMutex)
299 cwd = os.getcwd() 302 cwd = os.getcwd()
300 os.chdir(os.path.join(tmpDir, project)) 303 os.chdir(os.path.join(tmpDir, project))
304 client = self.getClient() 307 client = self.getClient()
305 if not noDialog: 308 if not noDialog:
306 dlg = \ 309 dlg = \
307 SvnDialog(self.trUtf8('Importing project into Subversion repository'), 310 SvnDialog(self.trUtf8('Importing project into Subversion repository'),
308 "import{0} --message {1} .".format( 311 "import{0} --message {1} .".format(
309 (not recurse) and " --non-recursive" or "", 312 (not recurse) and " --non-recursive" or "",
310 msg), 313 msg),
311 client) 314 client)
312 QApplication.processEvents() 315 QApplication.processEvents()
313 try: 316 try:
314 rev = client.import_(".", url, msg, recurse, ignore = True) 317 rev = client.import_(".", url, msg, recurse, ignore=True)
315 status = True 318 status = True
316 except pysvn.ClientError as e: 319 except pysvn.ClientError as e:
317 status = False 320 status = False
318 rev = None 321 rev = None
319 if not noDialog: 322 if not noDialog:
327 os.chdir(cwd) 330 os.chdir(cwd)
328 331
329 shutil.rmtree(tmpDir, True) 332 shutil.rmtree(tmpDir, True)
330 return status, False 333 return status, False
331 334
332 def vcsCheckout(self, vcsDataDict, projectDir, noDialog = False): 335 def vcsCheckout(self, vcsDataDict, projectDir, noDialog=False):
333 """ 336 """
334 Public method used to check the project out of the Subversion repository. 337 Public method used to check the project out of the Subversion repository.
335 338
336 @param vcsDataDict dictionary of data required for the checkout 339 @param vcsDataDict dictionary of data required for the checkout
337 @param projectDir project directory to create (string) 340 @param projectDir project directory to create (string)
375 client = self.getClient() 378 client = self.getClient()
376 if not noDialog: 379 if not noDialog:
377 dlg = \ 380 dlg = \
378 SvnDialog(self.trUtf8('Checking project out of Subversion repository'), 381 SvnDialog(self.trUtf8('Checking project out of Subversion repository'),
379 "checkout{0} {1} {2}".format( 382 "checkout{0} {1} {2}".format(
380 (not recurse) and " --non-recursive" or "", 383 (not recurse) and " --non-recursive" or "",
381 url, projectDir), 384 url, projectDir),
382 client) 385 client)
383 QApplication.processEvents() 386 QApplication.processEvents()
384 locker = QMutexLocker(self.vcsExecutionMutex) 387 locker = QMutexLocker(self.vcsExecutionMutex)
385 try: 388 try:
442 url, projectDir), 445 url, projectDir),
443 client) 446 client)
444 QApplication.processEvents() 447 QApplication.processEvents()
445 locker = QMutexLocker(self.vcsExecutionMutex) 448 locker = QMutexLocker(self.vcsExecutionMutex)
446 try: 449 try:
447 client.export(url, projectDir, force = True, recurse = recurse) 450 client.export(url, projectDir, force=True, recurse=recurse)
448 status = True 451 status = True
449 except pysvn.ClientError as e: 452 except pysvn.ClientError as e:
450 status = False 453 status = False
451 dlg.showError(e.args[0]) 454 dlg.showError(e.args[0])
452 locker.unlock() 455 locker.unlock()
453 dlg.finish() 456 dlg.finish()
454 dlg.exec_() 457 dlg.exec_()
455 return status 458 return status
456 459
457 def vcsCommit(self, name, message, noDialog = False): 460 def vcsCommit(self, name, message, noDialog=False):
458 """ 461 """
459 Public method used to make the change of a file/directory permanent in the 462 Public method used to make the change of a file/directory permanent in the
460 Subversion repository. 463 Subversion repository.
461 464
462 @param name file/directory name to be committed (string or list of strings) 465 @param name file/directory name to be committed (string or list of strings)
522 dlg = \ 525 dlg = \
523 SvnDialog(self.trUtf8('Commiting changes to Subversion repository'), 526 SvnDialog(self.trUtf8('Commiting changes to Subversion repository'),
524 "commit{0}{1}{2}{3} --message {4} {5}".format( 527 "commit{0}{1}{2}{3} --message {4} {5}".format(
525 (not recurse) and " --non-recursive" or "", 528 (not recurse) and " --non-recursive" or "",
526 keeplocks and " --keep-locks" or "", 529 keeplocks and " --keep-locks" or "",
527 keepChangelists and " --keep-changelists" or "", 530 keepChangelists and " --keep-changelists" or "",
528 changelists and \ 531 changelists and \
529 " --changelist ".join([""] + changelists) or "", 532 " --changelist ".join([""] + changelists) or "",
530 msg, " ".join(fnames)), 533 msg, " ".join(fnames)),
531 client) 534 client)
532 QApplication.processEvents() 535 QApplication.processEvents()
533 try: 536 try:
534 if changelists: 537 if changelists:
535 rev = client.checkin(fnames, msg, 538 rev = client.checkin(fnames, msg,
536 recurse = recurse, keep_locks = keeplocks, 539 recurse=recurse, keep_locks=keeplocks,
537 keep_changelist = keepChangelists, 540 keep_changelist=keepChangelists,
538 changelists = changelists) 541 changelists=changelists)
539 else: 542 else:
540 rev = client.checkin(fnames, msg, 543 rev = client.checkin(fnames, msg,
541 recurse = recurse, keep_locks = keeplocks) 544 recurse=recurse, keep_locks=keeplocks)
542 except pysvn.ClientError as e: 545 except pysvn.ClientError as e:
543 rev = None 546 rev = None
544 if not noDialog: 547 if not noDialog:
545 dlg.showError(e.args[0]) 548 dlg.showError(e.args[0])
546 locker.unlock() 549 locker.unlock()
551 dlg.exec_() 554 dlg.exec_()
552 os.chdir(cwd) 555 os.chdir(cwd)
553 self.committed.emit() 556 self.committed.emit()
554 self.checkVCSStatus() 557 self.checkVCSStatus()
555 558
556 def vcsUpdate(self, name, noDialog = False): 559 def vcsUpdate(self, name, noDialog=False):
557 """ 560 """
558 Public method used to update a file/directory with the Subversion repository. 561 Public method used to update a file/directory with the Subversion repository.
559 562
560 @param name file/directory name to be updated (string or list of strings) 563 @param name file/directory name to be updated (string or list of strings)
561 @param noDialog flag indicating quiet operations (boolean) 564 @param noDialog flag indicating quiet operations (boolean)
595 res = False 598 res = False
596 os.chdir(cwd) 599 os.chdir(cwd)
597 self.checkVCSStatus() 600 self.checkVCSStatus()
598 return res 601 return res
599 602
600 def vcsAdd(self, name, isDir = False, noDialog = False): 603 def vcsAdd(self, name, isDir=False, noDialog=False):
601 """ 604 """
602 Public method used to add a file/directory to the Subversion repository. 605 Public method used to add a file/directory to the Subversion repository.
603 606
604 @param name file/directory name to be added (string) 607 @param name file/directory name to be added (string)
605 @param isDir flag indicating name is a directory (boolean) 608 @param isDir flag indicating name is a directory (boolean)
657 noignore and " --no-ignore" or "", 660 noignore and " --no-ignore" or "",
658 " ".join(names)), 661 " ".join(names)),
659 client) 662 client)
660 QApplication.processEvents() 663 QApplication.processEvents()
661 try: 664 try:
662 client.add(names, recurse = recurse, force = force, ignore = not noignore) 665 client.add(names, recurse=recurse, force=force, ignore=not noignore)
663 except pysvn.ClientError as e: 666 except pysvn.ClientError as e:
664 if not noDialog: 667 if not noDialog:
665 dlg.showError(e.args[0]) 668 dlg.showError(e.args[0])
666 locker.unlock() 669 locker.unlock()
667 if not noDialog: 670 if not noDialog:
668 dlg.finish() 671 dlg.finish()
669 dlg.exec_() 672 dlg.exec_()
670 os.chdir(cwd) 673 os.chdir(cwd)
671 674
672 def vcsAddBinary(self, name, isDir = False): 675 def vcsAddBinary(self, name, isDir=False):
673 """ 676 """
674 Public method used to add a file/directory in binary mode to the 677 Public method used to add a file/directory in binary mode to the
675 Subversion repository. 678 Subversion repository.
676 679
677 @param name file/directory name to be added (string) 680 @param name file/directory name to be added (string)
689 if isinstance(path, list): 692 if isinstance(path, list):
690 dname, fnames = self.splitPathList(path) 693 dname, fnames = self.splitPathList(path)
691 for n in path: 694 for n in path:
692 d = os.path.split(n)[0] 695 d = os.path.split(n)[0]
693 while not os.path.exists(os.path.join(d, self.adminDir)): 696 while not os.path.exists(os.path.join(d, self.adminDir)):
694 # add directories recursively, 697 # add directories recursively,
695 # if they aren't in the repository already 698 # if they aren't in the repository already
696 if d in tree: 699 if d in tree:
697 break 700 break
698 tree.append(d) 701 tree.append(d)
699 d = os.path.split(d)[0] 702 d = os.path.split(d)[0]
730 ignore and " --ignore" or "", 733 ignore and " --ignore" or "",
731 " ".join(names)), 734 " ".join(names)),
732 client) 735 client)
733 QApplication.processEvents() 736 QApplication.processEvents()
734 try: 737 try:
735 client.add(names, recurse = recurse, force = force, ignore = ignore) 738 client.add(names, recurse=recurse, force=force, ignore=ignore)
736 except pysvn.ClientError as e: 739 except pysvn.ClientError as e:
737 dlg.showError(e.args[0]) 740 dlg.showError(e.args[0])
738 locker.unlock() 741 locker.unlock()
739 dlg.finish() 742 dlg.finish()
740 dlg.exec_() 743 dlg.exec_()
741 os.chdir(cwd) 744 os.chdir(cwd)
742 745
743 def vcsRemove(self, name, project = False, noDialog = False): 746 def vcsRemove(self, name, project=False, noDialog=False):
744 """ 747 """
745 Public method used to remove a file/directory from the Subversion repository. 748 Public method used to remove a file/directory from the Subversion repository.
746 749
747 The default operation is to remove the local copy as well. 750 The default operation is to remove the local copy as well.
748 751
765 " ".join(name)), 768 " ".join(name)),
766 client) 769 client)
767 QApplication.processEvents() 770 QApplication.processEvents()
768 locker = QMutexLocker(self.vcsExecutionMutex) 771 locker = QMutexLocker(self.vcsExecutionMutex)
769 try: 772 try:
770 client.remove(name, force = force) 773 client.remove(name, force=force)
771 res = True 774 res = True
772 except pysvn.ClientError as e: 775 except pysvn.ClientError as e:
773 res = False 776 res = False
774 if not noDialog: 777 if not noDialog:
775 dlg.showError(e.args[0]) 778 dlg.showError(e.args[0])
778 dlg.finish() 781 dlg.finish()
779 dlg.exec_() 782 dlg.exec_()
780 783
781 return res 784 return res
782 785
783 def vcsMove(self, name, project, target = None, noDialog = False): 786 def vcsMove(self, name, project, target=None, noDialog=False):
784 """ 787 """
785 Public method used to move a file/directory. 788 Public method used to move a file/directory.
786 789
787 @param name file/directory name to be moved (string) 790 @param name file/directory name to be moved (string)
788 @param project reference to the project object 791 @param project reference to the project object
822 dlg = \ 825 dlg = \
823 SvnDialog( 826 SvnDialog(
824 self.trUtf8('Moving {0}').format(name), 827 self.trUtf8('Moving {0}').format(name),
825 "move{0}{1} {2} {3}".format( 828 "move{0}{1} {2} {3}".format(
826 force and " --force" or "", 829 force and " --force" or "",
827 log and (" --message {0}".format(log)) or "", 830 log and (" --message {0}".format(log)) or "",
828 name, target), 831 name, target),
829 client, log = log) 832 client, log=log)
830 QApplication.processEvents() 833 QApplication.processEvents()
831 locker = QMutexLocker(self.vcsExecutionMutex) 834 locker = QMutexLocker(self.vcsExecutionMutex)
832 try: 835 try:
833 client.move(name, target, force = force) 836 client.move(name, target, force=force)
834 res = True 837 res = True
835 except pysvn.ClientError as e: 838 except pysvn.ClientError as e:
836 res = False 839 res = False
837 if not noDialog: 840 if not noDialog:
838 dlg.showError(e.args[0]) 841 dlg.showError(e.args[0])
853 project.removeFile(name) 856 project.removeFile(name)
854 return res 857 return res
855 858
856 def vcsLog(self, name): 859 def vcsLog(self, name):
857 """ 860 """
858 Public method used to view the log of a file/directory from the 861 Public method used to view the log of a file/directory from the
859 Subversion repository. 862 Subversion repository.
860 863
861 @param name file/directory name to show the log of (string) 864 @param name file/directory name to show the log of (string)
862 """ 865 """
863 self.log = SvnLogDialog(self) 866 self.log = SvnLogDialog(self)
865 QApplication.processEvents() 868 QApplication.processEvents()
866 self.log.start(name) 869 self.log.start(name)
867 870
868 def vcsDiff(self, name): 871 def vcsDiff(self, name):
869 """ 872 """
870 Public method used to view the difference of a file/directory to the 873 Public method used to view the difference of a file/directory to the
871 Subversion repository. 874 Subversion repository.
872 875
873 If name is a directory and is the project directory, all project files 876 If name is a directory and is the project directory, all project files
874 are saved first. If name is a file (or list of files), which is/are being edited 877 are saved first. If name is a file (or list of files), which is/are being edited
875 and has unsaved modification, they can be saved or the operation may be aborted. 878 and has unsaved modification, they can be saved or the operation may be aborted.
876 879
877 @param name file/directory name to be diffed (string) 880 @param name file/directory name to be diffed (string)
878 """ 881 """
879 if isinstance(name, list): 882 if isinstance(name, list):
881 else: 884 else:
882 names = [name] 885 names = [name]
883 for nam in names: 886 for nam in names:
884 if os.path.isfile(nam): 887 if os.path.isfile(nam):
885 editor = e5App().getObject("ViewManager").getOpenEditor(nam) 888 editor = e5App().getObject("ViewManager").getOpenEditor(nam)
886 if editor and not editor.checkDirty() : 889 if editor and not editor.checkDirty():
887 return 890 return
888 else: 891 else:
889 project = e5App().getObject("Project") 892 project = e5App().getObject("Project")
890 if nam == project.ppath and not project.saveAllScripts(): 893 if nam == project.ppath and not project.saveAllScripts():
891 return 894 return
894 QApplication.processEvents() 897 QApplication.processEvents()
895 self.diff.start(name) 898 self.diff.start(name)
896 899
897 def vcsStatus(self, name): 900 def vcsStatus(self, name):
898 """ 901 """
899 Public method used to view the status of files/directories in the 902 Public method used to view the status of files/directories in the
900 Subversion repository. 903 Subversion repository.
901 904
902 @param name file/directory name(s) to show the status of 905 @param name file/directory name(s) to show the status of
903 (string or list of strings) 906 (string or list of strings)
904 """ 907 """
907 QApplication.processEvents() 910 QApplication.processEvents()
908 self.status.start(name) 911 self.status.start(name)
909 912
910 def vcsTag(self, name): 913 def vcsTag(self, name):
911 """ 914 """
912 Public method used to set the tag of a file/directory in the 915 Public method used to set the tag of a file/directory in the
913 Subversion repository. 916 Subversion repository.
914 917
915 @param name file/directory name to be tagged (string) 918 @param name file/directory name to be tagged (string)
916 """ 919 """
917 dname, fname = self.splitPath(name) 920 dname, fname = self.splitPath(name)
964 log = 'Created tag <{0}>'.format(self.tagName) 967 log = 'Created tag <{0}>'.format(self.tagName)
965 dlg = \ 968 dlg = \
966 SvnDialog( 969 SvnDialog(
967 self.trUtf8('Tagging {0} in the Subversion repository').format(name), 970 self.trUtf8('Tagging {0} in the Subversion repository').format(name),
968 "copy --message {0} {1} {2}".format(log, reposURL, url), 971 "copy --message {0} {1} {2}".format(log, reposURL, url),
969 client, log = log) 972 client, log=log)
970 QApplication.processEvents() 973 QApplication.processEvents()
971 locker = QMutexLocker(self.vcsExecutionMutex) 974 locker = QMutexLocker(self.vcsExecutionMutex)
972 try: 975 try:
973 rev = client.copy(reposURL, url) 976 rev = client.copy(reposURL, url)
974 except pysvn.ClientError as e: 977 except pysvn.ClientError as e:
978 log = 'Deleted tag <{0}>'.format(self.tagName) 981 log = 'Deleted tag <{0}>'.format(self.tagName)
979 dlg = \ 982 dlg = \
980 SvnDialog( 983 SvnDialog(
981 self.trUtf8('Tagging {0} in the Subversion repository').format(name), 984 self.trUtf8('Tagging {0} in the Subversion repository').format(name),
982 "remove --message {0} {1}".format(log, url), 985 "remove --message {0} {1}".format(log, url),
983 client, log = log) 986 client, log=log)
984 QApplication.processEvents() 987 QApplication.processEvents()
985 locker = QMutexLocker(self.vcsExecutionMutex) 988 locker = QMutexLocker(self.vcsExecutionMutex)
986 try: 989 try:
987 rev = client.remove(url) 990 rev = client.remove(url)
988 except pysvn.ClientError as e: 991 except pysvn.ClientError as e:
1098 @param name file/directory name to be merged (string) 1101 @param name file/directory name to be merged (string)
1099 """ 1102 """
1100 dname, fname = self.splitPath(name) 1103 dname, fname = self.splitPath(name)
1101 1104
1102 opts = self.options['global'] 1105 opts = self.options['global']
1103 dlg = SvnMergeDialog(self.mergeList[0], self.mergeList[1], self.mergeList[2], 1106 dlg = SvnMergeDialog(self.mergeList[0], self.mergeList[1], self.mergeList[2],
1104 "--force" in opts) 1107 "--force" in opts)
1105 if dlg.exec_() == QDialog.Accepted: 1108 if dlg.exec_() == QDialog.Accepted:
1106 urlrev1, urlrev2, target, force = dlg.getParameters() 1109 urlrev1, urlrev2, target, force = dlg.getParameters()
1107 else: 1110 else:
1108 return 1111 return
1179 SvnDialog( 1182 SvnDialog(
1180 self.trUtf8('Merging {0}').format(name), 1183 self.trUtf8('Merging {0}').format(name),
1181 "merge{0}{1} {2} {3} {4}".format( 1184 "merge{0}{1} {2} {3} {4}".format(
1182 (not recurse) and " --non-recursive" or "", 1185 (not recurse) and " --non-recursive" or "",
1183 force and " --force" or "", 1186 force and " --force" or "",
1184 "{0}{1}".format(url1, rev1 and ("@"+rev1) or ""), 1187 "{0}{1}".format(url1, rev1 and ("@" + rev1) or ""),
1185 "{0}{1}".format(url2, rev2 and ("@"+rev2) or ""), 1188 "{0}{1}".format(url2, rev2 and ("@" + rev2) or ""),
1186 fname), 1189 fname),
1187 client) 1190 client)
1188 QApplication.processEvents() 1191 QApplication.processEvents()
1189 try: 1192 try:
1190 client.merge(url1, revision1, url2, revision2, fname, 1193 client.merge(url1, revision1, url2, revision2, fname,
1191 recurse = recurse, force = force) 1194 recurse=recurse, force=force)
1192 except pysvn.ClientError as e: 1195 except pysvn.ClientError as e:
1193 dlg.showError(e.args[0]) 1196 dlg.showError(e.args[0])
1194 locker.unlock() 1197 locker.unlock()
1195 dlg.finish() 1198 dlg.finish()
1196 dlg.exec_() 1199 dlg.exec_()
1210 return self.canBeCommitted 1213 return self.canBeCommitted
1211 else: 1214 else:
1212 return self.canBeAdded 1215 return self.canBeAdded
1213 1216
1214 name = os.path.normcase(name) 1217 name = os.path.normcase(name)
1215 states = { name : 0 } 1218 states = {name: 0}
1216 states = self.vcsAllRegisteredStates(states, dname, False) 1219 states = self.vcsAllRegisteredStates(states, dname, False)
1217 if states[name] == self.canBeCommitted: 1220 if states[name] == self.canBeCommitted:
1218 return self.canBeCommitted 1221 return self.canBeCommitted
1219 else: 1222 else:
1220 return self.canBeAdded 1223 return self.canBeAdded
1221 1224
1222 def vcsAllRegisteredStates(self, names, dname, shortcut = True): 1225 def vcsAllRegisteredStates(self, names, dname, shortcut=True):
1223 """ 1226 """
1224 Public method used to get the registered states of a number of files in the vcs. 1227 Public method used to get the registered states of a number of files in the vcs.
1225 1228
1226 <b>Note:</b> If a shortcut is to be taken, the code will only check, if the named 1229 <b>Note:</b> If a shortcut is to be taken, the code will only check, if the named
1227 directory has been scanned already. If so, it is assumed, that the states for 1230 directory has been scanned already. If so, it is assumed, that the states for
1228 all files has been populated by the previous run. 1231 all files has been populated by the previous run.
1229 1232
1230 @param names dictionary with all filenames to be checked as keys 1233 @param names dictionary with all filenames to be checked as keys
1231 @param dname directory to check in (string) 1234 @param dname directory to check in (string)
1232 @param shortcut flag indicating a shortcut should be taken (boolean) 1235 @param shortcut flag indicating a shortcut should be taken (boolean)
1233 @return the received dictionary completed with a combination of 1236 @return the received dictionary completed with a combination of
1234 canBeCommited and canBeAdded or None in order to signal an error 1237 canBeCommited and canBeAdded or None in order to signal an error
1235 """ 1238 """
1236 if not os.path.isdir(os.path.join(dname, self.adminDir)): 1239 if not os.path.isdir(os.path.join(dname, self.adminDir)):
1237 # not under version control -> do nothing 1240 # not under version control -> do nothing
1238 return names 1241 return names
1256 client.callback_ssl_server_trust_prompt = \ 1259 client.callback_ssl_server_trust_prompt = \
1257 mixin._clientSslServerTrustPromptCallback 1260 mixin._clientSslServerTrustPromptCallback
1258 1261
1259 try: 1262 try:
1260 locker = QMutexLocker(self.vcsExecutionMutex) 1263 locker = QMutexLocker(self.vcsExecutionMutex)
1261 allFiles = client.status(dname, recurse = True, get_all = True, 1264 allFiles = client.status(dname, recurse=True, get_all=True,
1262 ignore = True, update = False) 1265 ignore=True, update=False)
1263 locker.unlock() 1266 locker.unlock()
1264 for file in allFiles: 1267 for file in allFiles:
1265 name = os.path.normcase(file.path) 1268 name = os.path.normcase(file.path)
1266 if file.is_versioned: 1269 if file.is_versioned:
1267 if name in names: 1270 if name in names:
1335 dia = SvnProcessDialog(self.trUtf8('Subversion command')) 1338 dia = SvnProcessDialog(self.trUtf8('Subversion command'))
1336 res = dia.startProcess(args, wd) 1339 res = dia.startProcess(args, wd)
1337 if res: 1340 if res:
1338 dia.exec_() 1341 dia.exec_()
1339 1342
1340 def vcsOptionsDialog(self, project, archive, editable = False, parent = None): 1343 def vcsOptionsDialog(self, project, archive, editable=False, parent=None):
1341 """ 1344 """
1342 Public method to get a dialog to enter repository info. 1345 Public method to get a dialog to enter repository info.
1343 1346
1344 @param project reference to the project object 1347 @param project reference to the project object
1345 @param archive name of the project in the repository (string) 1348 @param archive name of the project in the repository (string)
1346 @param editable flag indicating that the project name is editable (boolean) 1349 @param editable flag indicating that the project name is editable (boolean)
1347 @param parent parent widget (QWidget) 1350 @param parent parent widget (QWidget)
1348 """ 1351 """
1349 return SvnOptionsDialog(self, project, parent) 1352 return SvnOptionsDialog(self, project, parent)
1350 1353
1351 def vcsNewProjectOptionsDialog(self, parent = None): 1354 def vcsNewProjectOptionsDialog(self, parent=None):
1352 """ 1355 """
1353 Public method to get a dialog to enter repository info for getting a new project. 1356 Public method to get a dialog to enter repository info for getting a new project.
1354 1357
1355 @param parent parent widget (QWidget) 1358 @param parent parent widget (QWidget)
1356 """ 1359 """
1368 except pysvn.ClientError as e: 1371 except pysvn.ClientError as e:
1369 return e.args[0] 1372 return e.args[0]
1370 1373
1371 if hasattr(pysvn, 'svn_api_version'): 1374 if hasattr(pysvn, 'svn_api_version'):
1372 apiVersion = "{0} {1}".format( 1375 apiVersion = "{0} {1}".format(
1373 ".".join([str(v) for v in pysvn.svn_api_version[:3]]), 1376 ".".join([str(v) for v in pysvn.svn_api_version[:3]]),
1374 pysvn.svn_api_version[3]) 1377 pysvn.svn_api_version[3])
1375 else: 1378 else:
1376 apiVersion = QApplication.translate('subversion', "unknown") 1379 apiVersion = QApplication.translate('subversion', "unknown")
1377 return QApplication.translate('subversion', 1380 return QApplication.translate('subversion',
1378 """<h3>Repository information</h3>""" 1381 """<h3>Repository information</h3>"""
1386 """<tr><td><b>Committed date</b></td><td>{6}</td></tr>""" 1389 """<tr><td><b>Committed date</b></td><td>{6}</td></tr>"""
1387 """<tr><td><b>Comitted time</b></td><td>{7}</td></tr>""" 1390 """<tr><td><b>Comitted time</b></td><td>{7}</td></tr>"""
1388 """<tr><td><b>Last author</b></td><td>{8}</td></tr>""" 1391 """<tr><td><b>Last author</b></td><td>{8}</td></tr>"""
1389 """</table>""" 1392 """</table>"""
1390 )\ 1393 )\
1391 .format(".".join([str(v) for v in pysvn.version]), 1394 .format(".".join([str(v) for v in pysvn.version]),
1392 ".".join([str(v) for v in pysvn.svn_version[:3]]), 1395 ".".join([str(v) for v in pysvn.svn_version[:3]]),
1393 apiVersion, 1396 apiVersion,
1394 entry.url, 1397 entry.url,
1395 entry.revision.number, 1398 entry.revision.number,
1396 entry.commit_revision.number, 1399 entry.commit_revision.number,
1397 time.strftime("%Y-%m-%d", time.localtime(entry.commit_time)), 1400 time.strftime("%Y-%m-%d", time.localtime(entry.commit_time)),
1398 time.strftime("%H:%M:%S %Z", time.localtime(entry.commit_time)), 1401 time.strftime("%H:%M:%S %Z", time.localtime(entry.commit_time)),
1399 entry.commit_author 1402 entry.commit_author
1400 ) 1403 )
1401 1404
1402 ############################################################################ 1405 ############################################################################
1403 ## Public Subversion specific methods are below. 1406 ## Public Subversion specific methods are below.
1439 recurse = "--non-recursive" not in opts 1442 recurse = "--non-recursive" not in opts
1440 client = self.getClient() 1443 client = self.getClient()
1441 dlg = \ 1444 dlg = \
1442 SvnDialog(self.trUtf8('Resolving conficts'), 1445 SvnDialog(self.trUtf8('Resolving conficts'),
1443 "resolved{0} {1}".format( 1446 "resolved{0} {1}".format(
1444 (not recurse) and " --non-recursive" or "", 1447 (not recurse) and " --non-recursive" or "",
1445 " ".join(fnames)), 1448 " ".join(fnames)),
1446 client) 1449 client)
1447 QApplication.processEvents() 1450 QApplication.processEvents()
1448 try: 1451 try:
1449 for name in fnames: 1452 for name in fnames:
1450 client.resolved(name, recurse = recurse) 1453 client.resolved(name, recurse=recurse)
1451 except pysvn.ClientError as e: 1454 except pysvn.ClientError as e:
1452 dlg.showError(e.args[0]) 1455 dlg.showError(e.args[0])
1453 locker.unlock() 1456 locker.unlock()
1454 dlg.finish() 1457 dlg.finish()
1455 dlg.exec_() 1458 dlg.exec_()
1479 target = target 1482 target = target
1480 dlg = \ 1483 dlg = \
1481 SvnDialog( 1484 SvnDialog(
1482 self.trUtf8('Copying {0}').format(name), 1485 self.trUtf8('Copying {0}').format(name),
1483 "copy{0} {1} {2}".format( 1486 "copy{0} {1} {2}".format(
1484 log and (" --message {0}".format(log)) or "", 1487 log and (" --message {0}".format(log)) or "",
1485 name, target), 1488 name, target),
1486 client, log = log) 1489 client, log=log)
1487 QApplication.processEvents() 1490 QApplication.processEvents()
1488 locker = QMutexLocker(self.vcsExecutionMutex) 1491 locker = QMutexLocker(self.vcsExecutionMutex)
1489 try: 1492 try:
1490 client.copy(name, target) 1493 client.copy(name, target)
1491 res = True 1494 res = True
1502 project.copyDirectory(name, target) 1505 project.copyDirectory(name, target)
1503 else: 1506 else:
1504 project.appendFile(target) 1507 project.appendFile(target)
1505 return res 1508 return res
1506 1509
1507 def svnListProps(self, name, recursive = False): 1510 def svnListProps(self, name, recursive=False):
1508 """ 1511 """
1509 Public method used to list the properties of a file/directory. 1512 Public method used to list the properties of a file/directory.
1510 1513
1511 @param name file/directory name (string or list of strings) 1514 @param name file/directory name (string or list of strings)
1512 @param recursive flag indicating a recursive list is requested 1515 @param recursive flag indicating a recursive list is requested
1514 self.propList = SvnPropListDialog(self) 1517 self.propList = SvnPropListDialog(self)
1515 self.propList.show() 1518 self.propList.show()
1516 QApplication.processEvents() 1519 QApplication.processEvents()
1517 self.propList.start(name, recursive) 1520 self.propList.start(name, recursive)
1518 1521
1519 def svnSetProp(self, name, recursive = False): 1522 def svnSetProp(self, name, recursive=False):
1520 """ 1523 """
1521 Public method used to add a property to a file/directory. 1524 Public method used to add a property to a file/directory.
1522 1525
1523 @param name file/directory name (string or list of strings) 1526 @param name file/directory name (string or list of strings)
1524 @param recursive flag indicating a recursive set is requested 1527 @param recursive flag indicating a recursive set is requested
1554 " ".join(fnames)), 1557 " ".join(fnames)),
1555 client) 1558 client)
1556 QApplication.processEvents() 1559 QApplication.processEvents()
1557 try: 1560 try:
1558 for name in fnames: 1561 for name in fnames:
1559 client.propset(propName, propValue, name, 1562 client.propset(propName, propValue, name,
1560 recurse = recurse, skip_checks = skipchecks) 1563 recurse=recurse, skip_checks=skipchecks)
1561 except pysvn.ClientError as e: 1564 except pysvn.ClientError as e:
1562 dlg.showError(e.args[0]) 1565 dlg.showError(e.args[0])
1563 locker.unlock() 1566 locker.unlock()
1564 dlg.showMessage(self.trUtf8("Property set.")) 1567 dlg.showMessage(self.trUtf8("Property set."))
1565 dlg.finish() 1568 dlg.finish()
1566 dlg.exec_() 1569 dlg.exec_()
1567 os.chdir(cwd) 1570 os.chdir(cwd)
1568 1571
1569 def svnDelProp(self, name, recursive = False): 1572 def svnDelProp(self, name, recursive=False):
1570 """ 1573 """
1571 Public method used to delete a property of a file/directory. 1574 Public method used to delete a property of a file/directory.
1572 1575
1573 @param name file/directory name (string or list of strings) 1576 @param name file/directory name (string or list of strings)
1574 @param recursive flag indicating a recursive list is requested 1577 @param recursive flag indicating a recursive list is requested
1604 propName, " ".join(fnames)), 1607 propName, " ".join(fnames)),
1605 client) 1608 client)
1606 QApplication.processEvents() 1609 QApplication.processEvents()
1607 try: 1610 try:
1608 for name in fnames: 1611 for name in fnames:
1609 client.propdel(propName, name, 1612 client.propdel(propName, name,
1610 recurse = recurse, skip_checks = skipchecks) 1613 recurse=recurse, skip_checks=skipchecks)
1611 except pysvn.ClientError as e: 1614 except pysvn.ClientError as e:
1612 dlg.showError(e.args[0]) 1615 dlg.showError(e.args[0])
1613 locker.unlock() 1616 locker.unlock()
1614 dlg.showMessage(self.trUtf8("Property deleted.")) 1617 dlg.showMessage(self.trUtf8("Property deleted."))
1615 dlg.finish() 1618 dlg.finish()
1616 dlg.exec_() 1619 dlg.exec_()
1617 os.chdir(cwd) 1620 os.chdir(cwd)
1618 1621
1619 def svnListTagBranch(self, path, tags = True): 1622 def svnListTagBranch(self, path, tags=True):
1620 """ 1623 """
1621 Public method used to list the available tags or branches. 1624 Public method used to list the available tags or branches.
1622 1625
1623 @param path directory name of the project (string) 1626 @param path directory name of the project (string)
1624 @param tags flag indicating listing of branches or tags 1627 @param tags flag indicating listing of branches or tags
1651 QApplication.processEvents() 1654 QApplication.processEvents()
1652 self.blame.start(name) 1655 self.blame.start(name)
1653 1656
1654 def svnExtendedDiff(self, name): 1657 def svnExtendedDiff(self, name):
1655 """ 1658 """
1656 Public method used to view the difference of a file/directory to the 1659 Public method used to view the difference of a file/directory to the
1657 Subversion repository. 1660 Subversion repository.
1658 1661
1659 If name is a directory and is the project directory, all project files 1662 If name is a directory and is the project directory, all project files
1660 are saved first. If name is a file (or list of files), which is/are being edited 1663 are saved first. If name is a file (or list of files), which is/are being edited
1661 and has unsaved modification, they can be saved or the operation may be aborted. 1664 and has unsaved modification, they can be saved or the operation may be aborted.
1662 1665
1663 This method gives the chance to enter the revisions to be compared. 1666 This method gives the chance to enter the revisions to be compared.
1664 1667
1665 @param name file/directory name to be diffed (string) 1668 @param name file/directory name to be diffed (string)
1669 else: 1672 else:
1670 names = [name] 1673 names = [name]
1671 for nam in names: 1674 for nam in names:
1672 if os.path.isfile(nam): 1675 if os.path.isfile(nam):
1673 editor = e5App().getObject("ViewManager").getOpenEditor(nam) 1676 editor = e5App().getObject("ViewManager").getOpenEditor(nam)
1674 if editor and not editor.checkDirty() : 1677 if editor and not editor.checkDirty():
1675 return 1678 return
1676 else: 1679 else:
1677 project = e5App().getObject("Project") 1680 project = e5App().getObject("Project")
1678 if nam == project.ppath and not project.saveAllScripts(): 1681 if nam == project.ppath and not project.saveAllScripts():
1679 return 1682 return
1689 """ 1692 """
1690 Public method used to view the difference of a file/directory of two 1693 Public method used to view the difference of a file/directory of two
1691 repository URLs. 1694 repository URLs.
1692 1695
1693 If name is a directory and is the project directory, all project files 1696 If name is a directory and is the project directory, all project files
1694 are saved first. If name is a file (or list of files), which is/are being edited 1697 are saved first. If name is a file (or list of files), which is/are being edited
1695 and has unsaved modification, they can be saved or the operation may be aborted. 1698 and has unsaved modification, they can be saved or the operation may be aborted.
1696 1699
1697 This method gives the chance to enter the revisions to be compared. 1700 This method gives the chance to enter the revisions to be compared.
1698 1701
1699 @param name file/directory name to be diffed (string) 1702 @param name file/directory name to be diffed (string)
1703 else: 1706 else:
1704 names = [name] 1707 names = [name]
1705 for nam in names: 1708 for nam in names:
1706 if os.path.isfile(nam): 1709 if os.path.isfile(nam):
1707 editor = e5App().getObject("ViewManager").getOpenEditor(nam) 1710 editor = e5App().getObject("ViewManager").getOpenEditor(nam)
1708 if editor and not editor.checkDirty() : 1711 if editor and not editor.checkDirty():
1709 return 1712 return
1710 else: 1713 else:
1711 project = e5App().getObject("Project") 1714 project = e5App().getObject("Project")
1712 if nam == project.ppath and not project.saveAllScripts(): 1715 if nam == project.ppath and not project.saveAllScripts():
1713 return 1716 return
1718 if dlg.exec_() == QDialog.Accepted: 1721 if dlg.exec_() == QDialog.Accepted:
1719 urls, summary = dlg.getURLs() 1722 urls, summary = dlg.getURLs()
1720 self.diff = SvnDiffDialog(self) 1723 self.diff = SvnDiffDialog(self)
1721 self.diff.show() 1724 self.diff.show()
1722 QApplication.processEvents() 1725 QApplication.processEvents()
1723 self.diff.start(name, urls = urls, summary = summary) 1726 self.diff.start(name, urls=urls, summary=summary)
1724 1727
1725 def svnLogLimited(self, name): 1728 def svnLogLimited(self, name):
1726 """ 1729 """
1727 Public method used to view the (limited) log of a file/directory from the 1730 Public method used to view the (limited) log of a file/directory from the
1728 Subversion repository. 1731 Subversion repository.
1729 1732
1730 @param name file/directory name to show the log of (string) 1733 @param name file/directory name to show the log of (string)
1731 """ 1734 """
1732 noEntries, ok = QInputDialog.getInteger( 1735 noEntries, ok = QInputDialog.getInteger(
1740 QApplication.processEvents() 1743 QApplication.processEvents()
1741 self.log.start(name, noEntries) 1744 self.log.start(name, noEntries)
1742 1745
1743 def svnLogBrowser(self, path): 1746 def svnLogBrowser(self, path):
1744 """ 1747 """
1745 Public method used to browse the log of a file/directory from the 1748 Public method used to browse the log of a file/directory from the
1746 Subversion repository. 1749 Subversion repository.
1747 1750
1748 @param path file/directory name to show the log of (string) 1751 @param path file/directory name to show the log of (string)
1749 """ 1752 """
1750 self.logBrowser = SvnLogBrowserDialog(self) 1753 self.logBrowser = SvnLogBrowserDialog(self)
1784 self.trUtf8('Locking in the Subversion repository'), 1787 self.trUtf8('Locking in the Subversion repository'),
1785 "lock{0}{1} {2}".format( 1788 "lock{0}{1} {2}".format(
1786 stealIt and " --force" or "", 1789 stealIt and " --force" or "",
1787 comment and (" --message {0}".format(comment)) or "", 1790 comment and (" --message {0}".format(comment)) or "",
1788 " ".join(fnames)), 1791 " ".join(fnames)),
1789 client, parent = parent) 1792 client, parent=parent)
1790 QApplication.processEvents() 1793 QApplication.processEvents()
1791 try: 1794 try:
1792 client.lock(fnames, comment, force = stealIt) 1795 client.lock(fnames, comment, force=stealIt)
1793 except pysvn.ClientError as e: 1796 except pysvn.ClientError as e:
1794 dlg.showError(e.args[0]) 1797 dlg.showError(e.args[0])
1795 except AttributeError as e: 1798 except AttributeError as e:
1796 dlg.showError(str(e)) 1799 dlg.showError(str(e))
1797 locker.unlock() 1800 locker.unlock()
1821 SvnDialog( 1824 SvnDialog(
1822 self.trUtf8('Unlocking in the Subversion repository'), 1825 self.trUtf8('Unlocking in the Subversion repository'),
1823 "unlock{0} {1}".format( 1826 "unlock{0} {1}".format(
1824 breakIt and " --force" or "", 1827 breakIt and " --force" or "",
1825 " ".join(fnames)), 1828 " ".join(fnames)),
1826 client, parent = parent) 1829 client, parent=parent)
1827 QApplication.processEvents() 1830 QApplication.processEvents()
1828 try: 1831 try:
1829 client.unlock(fnames, force = breakIt) 1832 client.unlock(fnames, force=breakIt)
1830 except pysvn.ClientError as e: 1833 except pysvn.ClientError as e:
1831 dlg.showError(e.args[0]) 1834 dlg.showError(e.args[0])
1832 except AttributeError as e: 1835 except AttributeError as e:
1833 dlg.showError(str(e)) 1836 dlg.showError(str(e))
1834 locker.unlock() 1837 locker.unlock()
1868 locker = QMutexLocker(self.vcsExecutionMutex) 1871 locker = QMutexLocker(self.vcsExecutionMutex)
1869 try: 1872 try:
1870 if inside: 1873 if inside:
1871 client.switch(projectPath, newUrl) 1874 client.switch(projectPath, newUrl)
1872 else: 1875 else:
1873 client.relocate(currUrl, newUrl, projectPath, recurse = True) 1876 client.relocate(currUrl, newUrl, projectPath, recurse=True)
1874 except pysvn.ClientError as e: 1877 except pysvn.ClientError as e:
1875 dlg.showError(e.args[0]) 1878 dlg.showError(e.args[0])
1876 locker.unlock() 1879 locker.unlock()
1877 dlg.finish() 1880 dlg.finish()
1878 dlg.exec_() 1881 dlg.exec_()
1879 1882
1880 def svnRepoBrowser(self, projectPath = None): 1883 def svnRepoBrowser(self, projectPath=None):
1881 """ 1884 """
1882 Public method to open the repository browser. 1885 Public method to open the repository browser.
1883 1886
1884 @param projectPath path name of the project (string) 1887 @param projectPath path name of the project (string)
1885 """ 1888 """
1954 client) 1957 client)
1955 QApplication.processEvents() 1958 QApplication.processEvents()
1956 locker = QMutexLocker(self.vcsExecutionMutex) 1959 locker = QMutexLocker(self.vcsExecutionMutex)
1957 try: 1960 try:
1958 for name in names: 1961 for name in names:
1959 client.add_to_changelist(name, clname, depth = pysvn.depth.infinity) 1962 client.add_to_changelist(name, clname, depth=pysvn.depth.infinity)
1960 except pysvn.ClientError as e: 1963 except pysvn.ClientError as e:
1961 dlg.showError(e.args[0]) 1964 dlg.showError(e.args[0])
1962 locker.unlock() 1965 locker.unlock()
1963 dlg.finish() 1966 dlg.finish()
1964 dlg.exec_() 1967 dlg.exec_()
1977 url = self.svnNormalizeURL(url) 1980 url = self.svnNormalizeURL(url)
1978 url = url.split(':', 2) 1981 url = url.split(':', 2)
1979 if len(url) == 3: 1982 if len(url) == 3:
1980 scheme = url[0] 1983 scheme = url[0]
1981 host = url[1] 1984 host = url[1]
1982 port, path = url[2].split("/",1) 1985 port, path = url[2].split("/", 1)
1983 return "{0}:{1}:{2}/{3}".format(scheme, host, port, urllib.parse.quote(path)) 1986 return "{0}:{1}:{2}/{3}".format(scheme, host, port, urllib.parse.quote(path))
1984 else: 1987 else:
1985 scheme = url[0] 1988 scheme = url[0]
1986 if scheme == "file": 1989 if scheme == "file":
1987 return "{0}:{1}".format(scheme, urllib.parse.quote(url[1])) 1990 return "{0}:{1}".format(scheme, urllib.parse.quote(url[1]))
2008 2011
2009 ############################################################################ 2012 ############################################################################
2010 ## Methods to get the helper objects are below. 2013 ## Methods to get the helper objects are below.
2011 ############################################################################ 2014 ############################################################################
2012 2015
2013 def vcsGetProjectBrowserHelper(self, browser, project, isTranslationsBrowser = False): 2016 def vcsGetProjectBrowserHelper(self, browser, project, isTranslationsBrowser=False):
2014 """ 2017 """
2015 Public method to instanciate a helper object for the different project browsers. 2018 Public method to instanciate a helper object for the different project browsers.
2016 2019
2017 @param browser reference to the project browser object 2020 @param browser reference to the project browser object
2018 @param project reference to the project object 2021 @param project reference to the project object

eric ide

mercurial