|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the queues extension interface. |
|
8 """ |
|
9 import os |
|
10 |
|
11 from PyQt4.QtCore import QObject, QProcess |
|
12 from PyQt4.QtGui import QDialog, QApplication, QInputDialog |
|
13 |
|
14 from E5Gui import E5MessageBox |
|
15 |
|
16 from ..HgDialog import HgDialog |
|
17 from ..HgDiffDialog import HgDiffDialog |
|
18 |
|
19 from .HgQueuesNewPatchDialog import HgQueuesNewPatchDialog |
|
20 from .HgQueuesListDialog import HgQueuesListDialog |
|
21 |
|
22 import Preferences |
|
23 |
|
24 |
|
25 class Queues(QObject): |
|
26 """ |
|
27 Class implementing the queues extension interface. |
|
28 """ |
|
29 APPLIED_LIST = 0 |
|
30 UNAPPLIED_LIST = 1 |
|
31 SERIES_LIST = 2 |
|
32 |
|
33 def __init__(self, vcs): |
|
34 """ |
|
35 Constructor |
|
36 """ |
|
37 QObject.__init__(self, vcs) |
|
38 |
|
39 self.vcs = vcs |
|
40 |
|
41 self.qdiffDialog = None |
|
42 |
|
43 def shutdown(self): |
|
44 """ |
|
45 Public method used to shutdown the queues interface. |
|
46 """ |
|
47 if self.qdiffDialog is not None: |
|
48 self.qdiffDialog.close() |
|
49 |
|
50 def hgQueueNewPatch(self, name): |
|
51 """ |
|
52 Public method to create a new named patch. |
|
53 |
|
54 @param name file/directory name (string) |
|
55 """ |
|
56 # find the root of the repo |
|
57 repodir = self.vcs.splitPath(name)[0] |
|
58 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
59 repodir = os.path.dirname(repodir) |
|
60 if repodir == os.sep: |
|
61 return |
|
62 |
|
63 dlg = HgQueuesNewPatchDialog() |
|
64 if dlg.exec_() == QDialog.Accepted: |
|
65 name, message, (userData, currentUser, userName), \ |
|
66 (dateData, currentDate, dateStr) = dlg.getData() |
|
67 |
|
68 args = [] |
|
69 args.append("qnew") |
|
70 if message != "": |
|
71 args.append("--message") |
|
72 args.append(message) |
|
73 if userData: |
|
74 if currentUser: |
|
75 args.append("--currentuser") |
|
76 else: |
|
77 args.append("--user") |
|
78 args.append(userName) |
|
79 if dateData: |
|
80 if currentDate: |
|
81 args.append("--currentdate") |
|
82 else: |
|
83 args.append("--date") |
|
84 args.append(dateStr) |
|
85 args.append(name) |
|
86 |
|
87 dia = HgDialog(self.trUtf8('New Patch')) |
|
88 res = dia.startProcess(args, repodir) |
|
89 if res: |
|
90 dia.exec_() |
|
91 self.vcs.checkVCSStatus() |
|
92 |
|
93 def hgQueueRefreshPatch(self, name): |
|
94 """ |
|
95 Public method to create a new named patch. |
|
96 |
|
97 @param name file/directory name (string) |
|
98 """ |
|
99 # find the root of the repo |
|
100 repodir = self.vcs.splitPath(name)[0] |
|
101 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
102 repodir = os.path.dirname(repodir) |
|
103 if repodir == os.sep: |
|
104 return |
|
105 |
|
106 args = [] |
|
107 args.append("qrefresh") |
|
108 |
|
109 dia = HgDialog(self.trUtf8('Update Current Patch')) |
|
110 res = dia.startProcess(args, repodir) |
|
111 if res: |
|
112 dia.exec_() |
|
113 self.vcs.checkVCSStatus() |
|
114 |
|
115 def hgQueueShowPatch(self, name): |
|
116 """ |
|
117 Public method to create a new named patch. |
|
118 |
|
119 @param name file/directory name (string) |
|
120 """ |
|
121 self.qdiffDialog = HgDiffDialog(self.vcs) |
|
122 self.qdiffDialog.show() |
|
123 QApplication.processEvents() |
|
124 self.qdiffDialog.start(name, qdiff=True) |
|
125 |
|
126 def hgQueuePushPopPatches(self, name, pop=False, all=False, named=False, force=False): |
|
127 """ |
|
128 Public method to push patches onto the stack or pop patches off the stack. |
|
129 |
|
130 @param name file/directory name (string) |
|
131 @keyparam pop flag indicating a pop action (boolean) |
|
132 @keyparam all flag indicating to push/pop all (boolean) |
|
133 @keyparam named flag indicating to push/pop until a named patch |
|
134 is at the top of the stack (boolean) |
|
135 @keyparam force flag indicating a forceful pop (boolean) |
|
136 """ |
|
137 # find the root of the repo |
|
138 repodir = self.vcs.splitPath(name)[0] |
|
139 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
140 repodir = os.path.dirname(repodir) |
|
141 if repodir == os.sep: |
|
142 return |
|
143 |
|
144 args = [] |
|
145 if pop: |
|
146 args.append("qpop") |
|
147 title = self.trUtf8("Pop Patches") |
|
148 listType = Queues.APPLIED_LIST |
|
149 else: |
|
150 args.append("qpush") |
|
151 title = self.trUtf8("Push Patches") |
|
152 listType = Queues.UNAPPLIED_LIST |
|
153 if force: |
|
154 args.append("--force") |
|
155 if all: |
|
156 args.append("--all") |
|
157 elif named: |
|
158 patchnames = self.__getUnAppliedPatches(repodir, listType) |
|
159 if patchnames: |
|
160 patch, ok = QInputDialog.getItem( |
|
161 None, |
|
162 self.trUtf8("Select Patch"), |
|
163 self.trUtf8("Select the target patch name:"), |
|
164 patchnames, |
|
165 0, False) |
|
166 if ok and patch: |
|
167 args.append(patch) |
|
168 else: |
|
169 return |
|
170 else: |
|
171 E5MessageBox.information(None, |
|
172 self.trUtf8("Select Patch"), |
|
173 self.trUtf8("""No patches to select from.""")) |
|
174 return |
|
175 |
|
176 dia = HgDialog(title) |
|
177 res = dia.startProcess(args, repodir) |
|
178 if res: |
|
179 dia.exec_() |
|
180 self.vcs.checkVCSStatus() |
|
181 |
|
182 def __getUnAppliedPatches(self, repodir, listType): |
|
183 """ |
|
184 Public method to get the list of applied or unapplied patches. |
|
185 |
|
186 @param repodir directory name of the repository (string) |
|
187 @param listType type of patcheslist to get |
|
188 (Queues.APPLIED_LIST, Queues.UNAPPLIED_LIST, Queues.SERIES_LIST) |
|
189 @return list of patches (list of string) |
|
190 """ |
|
191 patchesList = [] |
|
192 |
|
193 ioEncoding = Preferences.getSystem("IOEncoding") |
|
194 process = QProcess() |
|
195 args = [] |
|
196 if listType == Queues.APPLIED_LIST: |
|
197 args.append("qapplied") |
|
198 elif listType == Queues.UNAPPLIED_LIST: |
|
199 args.append("qunapplied") |
|
200 elif listType == Queues.SERIES_LIST: |
|
201 args.append("qseries") |
|
202 else: |
|
203 raise ValueError("Illegal value for listType.") |
|
204 |
|
205 process.setWorkingDirectory(repodir) |
|
206 process.start('hg', args) |
|
207 procStarted = process.waitForStarted() |
|
208 if procStarted: |
|
209 finished = process.waitForFinished(30000) |
|
210 if finished and process.exitCode() == 0: |
|
211 output = \ |
|
212 str(process.readAllStandardOutput(), ioEncoding, 'replace') |
|
213 for line in output.splitlines(): |
|
214 patchesList.append(line.strip()) |
|
215 |
|
216 return patchesList |
|
217 |
|
218 def hgQueueListPatches(self, name): |
|
219 """ |
|
220 Public method to create a new named patch. |
|
221 |
|
222 @param name file/directory name (string) |
|
223 """ |
|
224 self.queuesListDialog = HgQueuesListDialog(self.vcs) |
|
225 self.queuesListDialog.show() |
|
226 self.queuesListDialog.start(name) |
|
227 |
|
228 def hgQueueFinishAppliedPatches(self, name): |
|
229 """ |
|
230 Public method to create a new named patch. |
|
231 |
|
232 @param name file/directory name (string) |
|
233 """ |
|
234 # find the root of the repo |
|
235 repodir = self.vcs.splitPath(name)[0] |
|
236 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
237 repodir = os.path.dirname(repodir) |
|
238 if repodir == os.sep: |
|
239 return |
|
240 |
|
241 args = [] |
|
242 args.append("qfinish") |
|
243 args.append("--applied") |
|
244 |
|
245 dia = HgDialog(self.trUtf8('Finish Applied Patches')) |
|
246 res = dia.startProcess(args, repodir) |
|
247 if res: |
|
248 dia.exec_() |
|
249 self.vcs.checkVCSStatus() |