Plugins/VcsPlugins/vcsSubversion/SvnStatusDialog.py

branch
Py2 comp.
changeset 3484
645c12de6b0c
parent 3178
f25fc1364c88
parent 3190
a9a94491c4fd
child 3591
2f2a4a76dd22
equal deleted inserted replaced
3456:96232974dcdb 3484:645c12de6b0c
8 process. 8 process.
9 """ 9 """
10 10
11 from __future__ import unicode_literals 11 from __future__ import unicode_literals
12 try: 12 try:
13 str = unicode # __IGNORE_WARNING__ 13 str = unicode
14 except (NameError): 14 except NameError:
15 pass 15 pass
16 16
17 import os 17 import os
18 18
19 from PyQt4.QtCore import QTimer, QProcess, QRegExp, Qt, pyqtSlot 19 from PyQt4.QtCore import QTimer, QProcess, QRegExp, Qt, pyqtSlot
54 self.__upToDateColumn = 8 54 self.__upToDateColumn = 8
55 self.__pathColumn = 12 55 self.__pathColumn = 12
56 self.__lastColumn = self.statusList.columnCount() 56 self.__lastColumn = self.statusList.columnCount()
57 57
58 self.refreshButton = \ 58 self.refreshButton = \
59 self.buttonBox.addButton(self.trUtf8("Refresh"), 59 self.buttonBox.addButton(self.tr("Refresh"),
60 QDialogButtonBox.ActionRole) 60 QDialogButtonBox.ActionRole)
61 self.refreshButton.setToolTip( 61 self.refreshButton.setToolTip(
62 self.trUtf8("Press to refresh the status display")) 62 self.tr("Press to refresh the status display"))
63 self.refreshButton.setEnabled(False) 63 self.refreshButton.setEnabled(False)
64 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) 64 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
65 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) 65 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
66 66
67 self.diff = None 67 self.diff = None
76 self.statusList.header().hideSection(self.__changelistColumn) 76 self.statusList.header().hideSection(self.__changelistColumn)
77 77
78 self.menuactions = [] 78 self.menuactions = []
79 self.menu = QMenu() 79 self.menu = QMenu()
80 self.menuactions.append(self.menu.addAction( 80 self.menuactions.append(self.menu.addAction(
81 self.trUtf8("Commit changes to repository..."), self.__commit)) 81 self.tr("Commit changes to repository..."), self.__commit))
82 self.menuactions.append(self.menu.addAction( 82 self.menuactions.append(self.menu.addAction(
83 self.trUtf8("Select all for commit"), self.__commitSelectAll)) 83 self.tr("Select all for commit"), self.__commitSelectAll))
84 self.menuactions.append(self.menu.addAction( 84 self.menuactions.append(self.menu.addAction(
85 self.trUtf8("Deselect all from commit"), self.__commitDeselectAll)) 85 self.tr("Deselect all from commit"), self.__commitDeselectAll))
86 self.menu.addSeparator() 86 self.menu.addSeparator()
87 self.menuactions.append(self.menu.addAction( 87 self.menuactions.append(self.menu.addAction(
88 self.trUtf8("Add to repository"), self.__add)) 88 self.tr("Add to repository"), self.__add))
89 self.menuactions.append(self.menu.addAction( 89 self.menuactions.append(self.menu.addAction(
90 self.trUtf8("Show differences"), self.__diff)) 90 self.tr("Show differences"), self.__diff))
91 self.menuactions.append(self.menu.addAction( 91 self.menuactions.append(self.menu.addAction(
92 self.trUtf8("Show differences side-by-side"), self.__sbsDiff)) 92 self.tr("Show differences side-by-side"), self.__sbsDiff))
93 self.menuactions.append(self.menu.addAction( 93 self.menuactions.append(self.menu.addAction(
94 self.trUtf8("Revert changes"), self.__revert)) 94 self.tr("Revert changes"), self.__revert))
95 self.menuactions.append(self.menu.addAction( 95 self.menuactions.append(self.menu.addAction(
96 self.trUtf8("Restore missing"), self.__restoreMissing)) 96 self.tr("Restore missing"), self.__restoreMissing))
97 if self.vcs.version >= (1, 5, 0): 97 if self.vcs.version >= (1, 5, 0):
98 self.menu.addSeparator() 98 self.menu.addSeparator()
99 self.menuactions.append(self.menu.addAction( 99 self.menuactions.append(self.menu.addAction(
100 self.trUtf8("Add to Changelist"), self.__addToChangelist)) 100 self.tr("Add to Changelist"), self.__addToChangelist))
101 self.menuactions.append(self.menu.addAction( 101 self.menuactions.append(self.menu.addAction(
102 self.trUtf8("Remove from Changelist"), 102 self.tr("Remove from Changelist"),
103 self.__removeFromChangelist)) 103 self.__removeFromChangelist))
104 if self.vcs.version >= (1, 2, 0): 104 if self.vcs.version >= (1, 2, 0):
105 self.menu.addSeparator() 105 self.menu.addSeparator()
106 self.menuactions.append(self.menu.addAction( 106 self.menuactions.append(self.menu.addAction(
107 self.trUtf8("Lock"), self.__lock)) 107 self.tr("Lock"), self.__lock))
108 self.menuactions.append(self.menu.addAction( 108 self.menuactions.append(self.menu.addAction(
109 self.trUtf8("Unlock"), self.__unlock)) 109 self.tr("Unlock"), self.__unlock))
110 self.menuactions.append(self.menu.addAction( 110 self.menuactions.append(self.menu.addAction(
111 self.trUtf8("Break lock"), 111 self.tr("Break lock"),
112 self.__breakLock)) 112 self.__breakLock))
113 self.menuactions.append(self.menu.addAction( 113 self.menuactions.append(self.menu.addAction(
114 self.trUtf8("Steal lock"), 114 self.tr("Steal lock"),
115 self.__stealLock)) 115 self.__stealLock))
116 self.menu.addSeparator() 116 self.menu.addSeparator()
117 self.menuactions.append(self.menu.addAction( 117 self.menuactions.append(self.menu.addAction(
118 self.trUtf8("Adjust column sizes"), 118 self.tr("Adjust column sizes"),
119 self.__resizeColumns)) 119 self.__resizeColumns))
120 for act in self.menuactions: 120 for act in self.menuactions:
121 act.setEnabled(False) 121 act.setEnabled(False)
122 122
123 self.statusList.setContextMenuPolicy(Qt.CustomContextMenu) 123 self.statusList.setContextMenuPolicy(Qt.CustomContextMenu)
124 self.statusList.customContextMenuRequested.connect( 124 self.statusList.customContextMenuRequested.connect(
125 self.__showContextMenu) 125 self.__showContextMenu)
126 126
127 self.modifiedIndicators = [ 127 self.modifiedIndicators = [
128 self.trUtf8('added'), 128 self.tr('added'),
129 self.trUtf8('deleted'), 129 self.tr('deleted'),
130 self.trUtf8('modified'), 130 self.tr('modified'),
131 ] 131 ]
132 132
133 self.missingIndicators = [ 133 self.missingIndicators = [
134 self.trUtf8('missing'), 134 self.tr('missing'),
135 ] 135 ]
136 136
137 self.unversionedIndicators = [ 137 self.unversionedIndicators = [
138 self.trUtf8('unversioned'), 138 self.tr('unversioned'),
139 ] 139 ]
140 140
141 self.lockedIndicators = [ 141 self.lockedIndicators = [
142 self.trUtf8('locked'), 142 self.tr('locked'),
143 ] 143 ]
144 144
145 self.stealBreakLockIndicators = [ 145 self.stealBreakLockIndicators = [
146 self.trUtf8('other lock'), 146 self.tr('other lock'),
147 self.trUtf8('stolen lock'), 147 self.tr('stolen lock'),
148 self.trUtf8('broken lock'), 148 self.tr('broken lock'),
149 ] 149 ]
150 150
151 self.unlockedIndicators = [ 151 self.unlockedIndicators = [
152 self.trUtf8('not locked'), 152 self.tr('not locked'),
153 ] 153 ]
154 154
155 self.status = { 155 self.status = {
156 ' ': self.trUtf8('normal'), 156 ' ': self.tr('normal'),
157 'A': self.trUtf8('added'), 157 'A': self.tr('added'),
158 'D': self.trUtf8('deleted'), 158 'D': self.tr('deleted'),
159 'M': self.trUtf8('modified'), 159 'M': self.tr('modified'),
160 'R': self.trUtf8('replaced'), 160 'R': self.tr('replaced'),
161 'C': self.trUtf8('conflict'), 161 'C': self.tr('conflict'),
162 'X': self.trUtf8('external'), 162 'X': self.tr('external'),
163 'I': self.trUtf8('ignored'), 163 'I': self.tr('ignored'),
164 '?': self.trUtf8('unversioned'), 164 '?': self.tr('unversioned'),
165 '!': self.trUtf8('missing'), 165 '!': self.tr('missing'),
166 '~': self.trUtf8('type error'), 166 '~': self.tr('type error'),
167 } 167 }
168 self.propStatus = { 168 self.propStatus = {
169 ' ': self.trUtf8('normal'), 169 ' ': self.tr('normal'),
170 'M': self.trUtf8('modified'), 170 'M': self.tr('modified'),
171 'C': self.trUtf8('conflict'), 171 'C': self.tr('conflict'),
172 } 172 }
173 self.locked = { 173 self.locked = {
174 ' ': self.trUtf8('no'), 174 ' ': self.tr('no'),
175 'L': self.trUtf8('yes'), 175 'L': self.tr('yes'),
176 } 176 }
177 self.history = { 177 self.history = {
178 ' ': self.trUtf8('no'), 178 ' ': self.tr('no'),
179 '+': self.trUtf8('yes'), 179 '+': self.tr('yes'),
180 } 180 }
181 self.switched = { 181 self.switched = {
182 ' ': self.trUtf8('no'), 182 ' ': self.tr('no'),
183 'S': self.trUtf8('yes'), 183 'S': self.tr('yes'),
184 } 184 }
185 self.lockinfo = { 185 self.lockinfo = {
186 ' ': self.trUtf8('not locked'), 186 ' ': self.tr('not locked'),
187 'K': self.trUtf8('locked'), 187 'K': self.tr('locked'),
188 'O': self.trUtf8('other lock'), 188 'O': self.tr('other lock'),
189 'T': self.trUtf8('stolen lock'), 189 'T': self.tr('stolen lock'),
190 'B': self.trUtf8('broken lock'), 190 'B': self.tr('broken lock'),
191 } 191 }
192 self.uptodate = { 192 self.uptodate = {
193 ' ': self.trUtf8('yes'), 193 ' ': self.tr('yes'),
194 '*': self.trUtf8('no'), 194 '*': self.tr('no'),
195 } 195 }
196 196
197 self.rx_status = QRegExp( 197 self.rx_status = QRegExp(
198 '(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*') 198 '(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*')
199 # flags (8 or 9 anything), revision, changed rev, author, path 199 # flags (8 or 9 anything), revision, changed rev, author, path
387 self.dname, fname = self.vcs.splitPath(fn) 387 self.dname, fname = self.vcs.splitPath(fn)
388 args.append(fname) 388 args.append(fname)
389 389
390 self.process.setWorkingDirectory(self.dname) 390 self.process.setWorkingDirectory(self.dname)
391 391
392 self.setWindowTitle(self.trUtf8('Subversion Status')) 392 self.setWindowTitle(self.tr('Subversion Status'))
393 393
394 self.process.start('svn', args) 394 self.process.start('svn', args)
395 procStarted = self.process.waitForStarted(5000) 395 procStarted = self.process.waitForStarted(5000)
396 if not procStarted: 396 if not procStarted:
397 self.inputGroup.setEnabled(False) 397 self.inputGroup.setEnabled(False)
398 self.inputGroup.hide() 398 self.inputGroup.hide()
399 E5MessageBox.critical( 399 E5MessageBox.critical(
400 self, 400 self,
401 self.trUtf8('Process Generation Error'), 401 self.tr('Process Generation Error'),
402 self.trUtf8( 402 self.tr(
403 'The process {0} could not be started. ' 403 'The process {0} could not be started. '
404 'Ensure, that it is in the search path.' 404 'Ensure, that it is in the search path.'
405 ).format('svn')) 405 ).format('svn'))
406 else: 406 else:
407 self.inputGroup.setEnabled(True) 407 self.inputGroup.setEnabled(True)
427 self.inputGroup.setEnabled(False) 427 self.inputGroup.setEnabled(False)
428 self.inputGroup.hide() 428 self.inputGroup.hide()
429 self.refreshButton.setEnabled(True) 429 self.refreshButton.setEnabled(True)
430 430
431 self.__statusFilters.sort() 431 self.__statusFilters.sort()
432 self.__statusFilters.insert(0, "<{0}>".format(self.trUtf8("all"))) 432 self.__statusFilters.insert(0, "<{0}>".format(self.tr("all")))
433 self.statusFilterCombo.addItems(self.__statusFilters) 433 self.statusFilterCombo.addItems(self.__statusFilters)
434 434
435 for act in self.menuactions: 435 for act in self.menuactions:
436 act.setEnabled(True) 436 act.setEnabled(True)
437 437
623 """ 623 """
624 Private slot to react to the selection of a status filter. 624 Private slot to react to the selection of a status filter.
625 625
626 @param txt selected status filter (string) 626 @param txt selected status filter (string)
627 """ 627 """
628 if txt == "<{0}>".format(self.trUtf8("all")): 628 if txt == "<{0}>".format(self.tr("all")):
629 for topIndex in range(self.statusList.topLevelItemCount()): 629 for topIndex in range(self.statusList.topLevelItemCount()):
630 topItem = self.statusList.topLevelItem(topIndex) 630 topItem = self.statusList.topLevelItem(topIndex)
631 topItem.setHidden(False) 631 topItem.setHidden(False)
632 else: 632 else:
633 for topIndex in range(self.statusList.topLevelItemCount()): 633 for topIndex in range(self.statusList.topLevelItemCount()):
713 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 713 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
714 for itm in self.__getCommitableItems()] 714 for itm in self.__getCommitableItems()]
715 if not names: 715 if not names:
716 E5MessageBox.information( 716 E5MessageBox.information(
717 self, 717 self,
718 self.trUtf8("Commit"), 718 self.tr("Commit"),
719 self.trUtf8("""There are no entries selected to be""" 719 self.tr("""There are no entries selected to be"""
720 """ committed.""")) 720 """ committed."""))
721 return 721 return
722 722
723 if Preferences.getVCS("AutoSaveFiles"): 723 if Preferences.getVCS("AutoSaveFiles"):
724 vm = e5App().getObject("ViewManager") 724 vm = e5App().getObject("ViewManager")
725 for name in names: 725 for name in names:
753 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 753 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
754 for itm in self.__getUnversionedItems()] 754 for itm in self.__getUnversionedItems()]
755 if not names: 755 if not names:
756 E5MessageBox.information( 756 E5MessageBox.information(
757 self, 757 self,
758 self.trUtf8("Add"), 758 self.tr("Add"),
759 self.trUtf8("""There are no unversioned entries""" 759 self.tr("""There are no unversioned entries"""
760 """ available/selected.""")) 760 """ available/selected."""))
761 return 761 return
762 762
763 self.vcs.vcsAdd(names) 763 self.vcs.vcsAdd(names)
764 self.on_refreshButton_clicked() 764 self.on_refreshButton_clicked()
765 765
775 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 775 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
776 for itm in self.__getModifiedItems()] 776 for itm in self.__getModifiedItems()]
777 if not names: 777 if not names:
778 E5MessageBox.information( 778 E5MessageBox.information(
779 self, 779 self,
780 self.trUtf8("Revert"), 780 self.tr("Revert"),
781 self.trUtf8("""There are no uncommitted changes""" 781 self.tr("""There are no uncommitted changes"""
782 """ available/selected.""")) 782 """ available/selected."""))
783 return 783 return
784 784
785 self.vcs.vcsRevert(names) 785 self.vcs.vcsRevert(names)
786 self.raise_() 786 self.raise_()
787 self.activateWindow() 787 self.activateWindow()
799 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 799 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
800 for itm in self.__getMissingItems()] 800 for itm in self.__getMissingItems()]
801 if not names: 801 if not names:
802 E5MessageBox.information( 802 E5MessageBox.information(
803 self, 803 self,
804 self.trUtf8("Revert"), 804 self.tr("Revert"),
805 self.trUtf8("""There are no missing entries""" 805 self.tr("""There are no missing entries"""
806 """ available/selected.""")) 806 """ available/selected."""))
807 return 807 return
808 808
809 self.vcs.vcsRevert(names) 809 self.vcs.vcsRevert(names)
810 self.on_refreshButton_clicked() 810 self.on_refreshButton_clicked()
811 self.vcs.checkVCSStatus() 811 self.vcs.checkVCSStatus()
817 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 817 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
818 for itm in self.__getModifiedItems()] 818 for itm in self.__getModifiedItems()]
819 if not names: 819 if not names:
820 E5MessageBox.information( 820 E5MessageBox.information(
821 self, 821 self,
822 self.trUtf8("Differences"), 822 self.tr("Differences"),
823 self.trUtf8("""There are no uncommitted changes""" 823 self.tr("""There are no uncommitted changes"""
824 """ available/selected.""")) 824 """ available/selected."""))
825 return 825 return
826 826
827 if self.diff is None: 827 if self.diff is None:
828 from .SvnDiffDialog import SvnDiffDialog 828 from .SvnDiffDialog import SvnDiffDialog
829 self.diff = SvnDiffDialog(self.vcs) 829 self.diff = SvnDiffDialog(self.vcs)
838 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 838 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
839 for itm in self.__getModifiedItems()] 839 for itm in self.__getModifiedItems()]
840 if not names: 840 if not names:
841 E5MessageBox.information( 841 E5MessageBox.information(
842 self, 842 self,
843 self.trUtf8("Side-by-Side Diff"), 843 self.tr("Side-by-Side Diff"),
844 self.trUtf8("""There are no uncommitted changes""" 844 self.tr("""There are no uncommitted changes"""
845 """ available/selected.""")) 845 """ available/selected."""))
846 return 846 return
847 elif len(names) > 1: 847 elif len(names) > 1:
848 E5MessageBox.information( 848 E5MessageBox.information(
849 self, 849 self,
850 self.trUtf8("Side-by-Side Diff"), 850 self.tr("Side-by-Side Diff"),
851 self.trUtf8("""Only one file with uncommitted changes""" 851 self.tr("""Only one file with uncommitted changes"""
852 """ must be selected.""")) 852 """ must be selected."""))
853 return 853 return
854 854
855 self.vcs.svnSbsDiff(names[0]) 855 self.vcs.svnSbsDiff(names[0])
856 856
857 def __lock(self): 857 def __lock(self):
861 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 861 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
862 for itm in self.__getLockActionItems(self.unlockedIndicators)] 862 for itm in self.__getLockActionItems(self.unlockedIndicators)]
863 if not names: 863 if not names:
864 E5MessageBox.information( 864 E5MessageBox.information(
865 self, 865 self,
866 self.trUtf8("Lock"), 866 self.tr("Lock"),
867 self.trUtf8("""There are no unlocked files""" 867 self.tr("""There are no unlocked files"""
868 """ available/selected.""")) 868 """ available/selected."""))
869 return 869 return
870 870
871 self.vcs.svnLock(names, parent=self) 871 self.vcs.svnLock(names, parent=self)
872 self.on_refreshButton_clicked() 872 self.on_refreshButton_clicked()
873 873
878 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 878 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
879 for itm in self.__getLockActionItems(self.lockedIndicators)] 879 for itm in self.__getLockActionItems(self.lockedIndicators)]
880 if not names: 880 if not names:
881 E5MessageBox.information( 881 E5MessageBox.information(
882 self, 882 self,
883 self.trUtf8("Unlock"), 883 self.tr("Unlock"),
884 self.trUtf8("""There are no locked files""" 884 self.tr("""There are no locked files"""
885 """ available/selected.""")) 885 """ available/selected."""))
886 return 886 return
887 887
888 self.vcs.svnUnlock(names, parent=self) 888 self.vcs.svnUnlock(names, parent=self)
889 self.on_refreshButton_clicked() 889 self.on_refreshButton_clicked()
890 890
896 for itm in self.__getLockActionItems( 896 for itm in self.__getLockActionItems(
897 self.stealBreakLockIndicators)] 897 self.stealBreakLockIndicators)]
898 if not names: 898 if not names:
899 E5MessageBox.information( 899 E5MessageBox.information(
900 self, 900 self,
901 self.trUtf8("Break Lock"), 901 self.tr("Break Lock"),
902 self.trUtf8("""There are no locked files""" 902 self.tr("""There are no locked files"""
903 """ available/selected.""")) 903 """ available/selected."""))
904 return 904 return
905 905
906 self.vcs.svnUnlock(names, parent=self, breakIt=True) 906 self.vcs.svnUnlock(names, parent=self, breakIt=True)
907 self.on_refreshButton_clicked() 907 self.on_refreshButton_clicked()
908 908
914 for itm in self.__getLockActionItems( 914 for itm in self.__getLockActionItems(
915 self.stealBreakLockIndicators)] 915 self.stealBreakLockIndicators)]
916 if not names: 916 if not names:
917 E5MessageBox.information( 917 E5MessageBox.information(
918 self, 918 self,
919 self.trUtf8("Steal Lock"), 919 self.tr("Steal Lock"),
920 self.trUtf8("""There are no locked files""" 920 self.tr("""There are no locked files"""
921 """ available/selected.""")) 921 """ available/selected."""))
922 return 922 return
923 923
924 self.vcs.svnLock(names, parent=self, stealIt=True) 924 self.vcs.svnLock(names, parent=self, stealIt=True)
925 self.on_refreshButton_clicked() 925 self.on_refreshButton_clicked()
926 926
931 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 931 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
932 for itm in self.__getNonChangelistItems()] 932 for itm in self.__getNonChangelistItems()]
933 if not names: 933 if not names:
934 E5MessageBox.information( 934 E5MessageBox.information(
935 self, 935 self,
936 self.trUtf8("Remove from Changelist"), 936 self.tr("Remove from Changelist"),
937 self.trUtf8( 937 self.tr(
938 """There are no files available/selected not """ 938 """There are no files available/selected not """
939 """belonging to a changelist.""" 939 """belonging to a changelist."""
940 ) 940 )
941 ) 941 )
942 return 942 return
950 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) 950 names = [os.path.join(self.dname, itm.text(self.__pathColumn))
951 for itm in self.__getChangelistItems()] 951 for itm in self.__getChangelistItems()]
952 if not names: 952 if not names:
953 E5MessageBox.information( 953 E5MessageBox.information(
954 self, 954 self,
955 self.trUtf8("Remove from Changelist"), 955 self.tr("Remove from Changelist"),
956 self.trUtf8( 956 self.tr(
957 """There are no files available/selected belonging""" 957 """There are no files available/selected belonging"""
958 """ to a changelist.""" 958 """ to a changelist."""
959 ) 959 )
960 ) 960 )
961 return 961 return

eric ide

mercurial