28 """ |
31 """ |
29 APPLIED_LIST = 0 |
32 APPLIED_LIST = 0 |
30 UNAPPLIED_LIST = 1 |
33 UNAPPLIED_LIST = 1 |
31 SERIES_LIST = 2 |
34 SERIES_LIST = 2 |
32 |
35 |
|
36 POP = 0 |
|
37 PUSH = 1 |
|
38 GOTO = 2 |
|
39 |
33 def __init__(self, vcs): |
40 def __init__(self, vcs): |
34 """ |
41 """ |
35 Constructor |
42 Constructor |
36 """ |
43 """ |
37 QObject.__init__(self, vcs) |
44 QObject.__init__(self, vcs) |
38 |
45 |
39 self.vcs = vcs |
46 self.vcs = vcs |
40 |
47 |
41 self.qdiffDialog = None |
48 self.qdiffDialog = None |
|
49 self.qheaderDialog = None |
42 |
50 |
43 def shutdown(self): |
51 def shutdown(self): |
44 """ |
52 """ |
45 Public method used to shutdown the queues interface. |
53 Public method used to shutdown the queues interface. |
46 """ |
54 """ |
47 if self.qdiffDialog is not None: |
55 if self.qdiffDialog is not None: |
48 self.qdiffDialog.close() |
56 self.qdiffDialog.close() |
|
57 if self.qheaderDialog is not None: |
|
58 self.qheaderDialog.close() |
|
59 |
|
60 def __getPatchesList(self, repodir, listType, withSummary=False): |
|
61 """ |
|
62 Public method to get a list of patches of a given type. |
|
63 |
|
64 @param repodir directory name of the repository (string) |
|
65 @param listType type of patches list to get |
|
66 (Queues.APPLIED_LIST, Queues.UNAPPLIED_LIST, Queues.SERIES_LIST) |
|
67 @param withSummary flag indicating to get a summary as well (boolean) |
|
68 @return list of patches (list of string) |
|
69 """ |
|
70 patchesList = [] |
|
71 |
|
72 ioEncoding = Preferences.getSystem("IOEncoding") |
|
73 process = QProcess() |
|
74 args = [] |
|
75 if listType == Queues.APPLIED_LIST: |
|
76 args.append("qapplied") |
|
77 elif listType == Queues.UNAPPLIED_LIST: |
|
78 args.append("qunapplied") |
|
79 elif listType == Queues.SERIES_LIST: |
|
80 args.append("qseries") |
|
81 else: |
|
82 raise ValueError("illegal value for listType") |
|
83 if withSummary: |
|
84 args.append("--summary") |
|
85 |
|
86 process.setWorkingDirectory(repodir) |
|
87 process.start('hg', args) |
|
88 procStarted = process.waitForStarted() |
|
89 if procStarted: |
|
90 finished = process.waitForFinished(30000) |
|
91 if finished and process.exitCode() == 0: |
|
92 output = \ |
|
93 str(process.readAllStandardOutput(), ioEncoding, 'replace') |
|
94 for line in output.splitlines(): |
|
95 if withSummary: |
|
96 l = line.strip().split(": ") |
|
97 if len(l) == 1: |
|
98 patch, summary = l[0][:-1], "" |
|
99 else: |
|
100 patch, summary = l[0], l[1] |
|
101 patchesList.append("{0}@@{1}".format(patch, summary)) |
|
102 else: |
|
103 patchesList.append(line.strip()) |
|
104 |
|
105 return patchesList |
|
106 |
|
107 def __getCurrentPatch(self, repodir): |
|
108 """ |
|
109 Public method to get the name of the current patch. |
|
110 |
|
111 @param repodir directory name of the repository (string) |
|
112 @return name of the current patch (string) |
|
113 """ |
|
114 currentPatch = "" |
|
115 |
|
116 ioEncoding = Preferences.getSystem("IOEncoding") |
|
117 process = QProcess() |
|
118 args = [] |
|
119 args.append("qtop") |
|
120 |
|
121 process.setWorkingDirectory(repodir) |
|
122 process.start('hg', args) |
|
123 procStarted = process.waitForStarted() |
|
124 if procStarted: |
|
125 finished = process.waitForFinished(30000) |
|
126 if finished and process.exitCode() == 0: |
|
127 currentPatch = str( |
|
128 process.readAllStandardOutput(), |
|
129 ioEncoding, 'replace').strip() |
|
130 |
|
131 return currentPatch |
|
132 |
|
133 def __getCommitMessage(self, repodir): |
|
134 """ |
|
135 Public method to get the commit message of the current patch. |
|
136 |
|
137 @param repodir directory name of the repository (string) |
|
138 @return name of the current patch (string) |
|
139 """ |
|
140 message = "" |
|
141 |
|
142 ioEncoding = Preferences.getSystem("IOEncoding") |
|
143 process = QProcess() |
|
144 args = [] |
|
145 args.append("qheader") |
|
146 |
|
147 process.setWorkingDirectory(repodir) |
|
148 process.start('hg', args) |
|
149 procStarted = process.waitForStarted() |
|
150 if procStarted: |
|
151 finished = process.waitForFinished(30000) |
|
152 if finished and process.exitCode() == 0: |
|
153 message = str( |
|
154 process.readAllStandardOutput(), |
|
155 ioEncoding, 'replace') |
|
156 |
|
157 return message |
49 |
158 |
50 def hgQueueNewPatch(self, name): |
159 def hgQueueNewPatch(self, name): |
51 """ |
160 """ |
52 Public method to create a new named patch. |
161 Public method to create a new named patch. |
53 |
162 |
58 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
167 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
59 repodir = os.path.dirname(repodir) |
168 repodir = os.path.dirname(repodir) |
60 if repodir == os.sep: |
169 if repodir == os.sep: |
61 return |
170 return |
62 |
171 |
63 dlg = HgQueuesNewPatchDialog() |
172 dlg = HgQueuesNewPatchDialog(HgQueuesNewPatchDialog.NEW_MODE) |
64 if dlg.exec_() == QDialog.Accepted: |
173 if dlg.exec_() == QDialog.Accepted: |
65 name, message, (userData, currentUser, userName), \ |
174 name, message, (userData, currentUser, userName), \ |
66 (dateData, currentDate, dateStr) = dlg.getData() |
175 (dateData, currentDate, dateStr) = dlg.getData() |
67 |
176 |
68 args = [] |
177 args = [] |
88 res = dia.startProcess(args, repodir) |
197 res = dia.startProcess(args, repodir) |
89 if res: |
198 if res: |
90 dia.exec_() |
199 dia.exec_() |
91 self.vcs.checkVCSStatus() |
200 self.vcs.checkVCSStatus() |
92 |
201 |
93 def hgQueueRefreshPatch(self, name): |
202 def hgQueueRefreshPatch(self, name, editMessage=False): |
94 """ |
203 """ |
95 Public method to create a new named patch. |
204 Public method to refresh the current patch. |
96 |
205 |
97 @param name file/directory name (string) |
206 @param name file/directory name (string) |
|
207 @param editMessage flag indicating to edit the current |
|
208 commit message (boolean) |
98 """ |
209 """ |
99 # find the root of the repo |
210 # find the root of the repo |
100 repodir = self.vcs.splitPath(name)[0] |
211 repodir = self.vcs.splitPath(name)[0] |
101 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
212 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
102 repodir = os.path.dirname(repodir) |
213 repodir = os.path.dirname(repodir) |
103 if repodir == os.sep: |
214 if repodir == os.sep: |
104 return |
215 return |
105 |
216 |
106 args = [] |
217 args = [] |
107 args.append("qrefresh") |
218 args.append("qrefresh") |
|
219 |
|
220 if editMessage: |
|
221 currentMessage = self.__getCommitMessage(repodir) |
|
222 dlg = HgQueuesNewPatchDialog(HgQueuesNewPatchDialog.REFRESH_MODE, |
|
223 currentMessage) |
|
224 if dlg.exec_() == QDialog.Accepted: |
|
225 name, message, (userData, currentUser, userName), \ |
|
226 (dateData, currentDate, dateStr) = dlg.getData() |
|
227 if message != "" and message != currentMessage: |
|
228 args.append("--message") |
|
229 args.append(message) |
|
230 if userData: |
|
231 if currentUser: |
|
232 args.append("--currentuser") |
|
233 else: |
|
234 args.append("--user") |
|
235 args.append(userName) |
|
236 if dateData: |
|
237 if currentDate: |
|
238 args.append("--currentdate") |
|
239 else: |
|
240 args.append("--date") |
|
241 args.append(dateStr) |
|
242 else: |
|
243 return |
108 |
244 |
109 dia = HgDialog(self.trUtf8('Update Current Patch')) |
245 dia = HgDialog(self.trUtf8('Update Current Patch')) |
110 res = dia.startProcess(args, repodir) |
246 res = dia.startProcess(args, repodir) |
111 if res: |
247 if res: |
112 dia.exec_() |
248 dia.exec_() |
113 self.vcs.checkVCSStatus() |
249 self.vcs.checkVCSStatus() |
114 |
250 |
115 def hgQueueShowPatch(self, name): |
251 def hgQueueShowPatch(self, name): |
116 """ |
252 """ |
117 Public method to create a new named patch. |
253 Public method to show the contents of the current patch. |
118 |
254 |
119 @param name file/directory name (string) |
255 @param name file/directory name (string) |
120 """ |
256 """ |
121 self.qdiffDialog = HgDiffDialog(self.vcs) |
257 self.qdiffDialog = HgDiffDialog(self.vcs) |
122 self.qdiffDialog.show() |
258 self.qdiffDialog.show() |
123 QApplication.processEvents() |
259 QApplication.processEvents() |
124 self.qdiffDialog.start(name, qdiff=True) |
260 self.qdiffDialog.start(name, qdiff=True) |
125 |
261 |
126 def hgQueuePushPopPatches(self, name, pop=False, all=False, named=False, force=False): |
262 def hgQueueShowHeader(self, name): |
|
263 """ |
|
264 Public method to show the commit message of the current patch. |
|
265 |
|
266 @param name file/directory name (string) |
|
267 """ |
|
268 self.qheaderDialog = HgQueuesHeaderDialog(self.vcs) |
|
269 self.qheaderDialog.show() |
|
270 QApplication.processEvents() |
|
271 self.qheaderDialog.start(name) |
|
272 |
|
273 def hgQueuePushPopPatches(self, name, operation, all=False, named=False, force=False): |
127 """ |
274 """ |
128 Public method to push patches onto the stack or pop patches off the stack. |
275 Public method to push patches onto the stack or pop patches off the stack. |
129 |
276 |
130 @param name file/directory name (string) |
277 @param name file/directory name (string) |
131 @keyparam pop flag indicating a pop action (boolean) |
278 @param operation operation type to be performed (Queues.POP, |
|
279 Queues.PUSH, Queues.GOTO) |
132 @keyparam all flag indicating to push/pop all (boolean) |
280 @keyparam all flag indicating to push/pop all (boolean) |
133 @keyparam named flag indicating to push/pop until a named patch |
281 @keyparam named flag indicating to push/pop until a named patch |
134 is at the top of the stack (boolean) |
282 is at the top of the stack (boolean) |
135 @keyparam force flag indicating a forceful pop (boolean) |
283 @keyparam force flag indicating a forceful pop (boolean) |
136 """ |
284 """ |
140 repodir = os.path.dirname(repodir) |
288 repodir = os.path.dirname(repodir) |
141 if repodir == os.sep: |
289 if repodir == os.sep: |
142 return |
290 return |
143 |
291 |
144 args = [] |
292 args = [] |
145 if pop: |
293 if operation == Queues.POP: |
146 args.append("qpop") |
294 args.append("qpop") |
147 title = self.trUtf8("Pop Patches") |
295 title = self.trUtf8("Pop Patches") |
148 listType = Queues.APPLIED_LIST |
296 listType = Queues.APPLIED_LIST |
149 else: |
297 elif operation == Queues.PUSH: |
150 args.append("qpush") |
298 args.append("qpush") |
151 title = self.trUtf8("Push Patches") |
299 title = self.trUtf8("Push Patches") |
152 listType = Queues.UNAPPLIED_LIST |
300 listType = Queues.UNAPPLIED_LIST |
|
301 elif operation == Queues.GOTO: |
|
302 args.append("qgoto") |
|
303 title = self.trUtf8("Go to Patch") |
|
304 listType = Queues.SERIES_LIST |
|
305 else: |
|
306 raise ValueError("illegal value for operation") |
153 if force: |
307 if force: |
154 args.append("--force") |
308 args.append("--force") |
155 if all: |
309 if all and operation in (Queues.POP, Queues.PUSH): |
156 args.append("--all") |
310 args.append("--all") |
157 elif named: |
311 elif named or operation == Queues.GOTO: |
158 patchnames = self.__getUnAppliedPatches(repodir, listType) |
312 patchnames = self.__getPatchesList(repodir, listType) |
159 if patchnames: |
313 if patchnames: |
160 patch, ok = QInputDialog.getItem( |
314 patch, ok = QInputDialog.getItem( |
161 None, |
315 None, |
162 self.trUtf8("Select Patch"), |
316 self.trUtf8("Select Patch"), |
163 self.trUtf8("Select the target patch name:"), |
317 self.trUtf8("Select the target patch name:"), |
177 res = dia.startProcess(args, repodir) |
331 res = dia.startProcess(args, repodir) |
178 if res: |
332 if res: |
179 dia.exec_() |
333 dia.exec_() |
180 self.vcs.checkVCSStatus() |
334 self.vcs.checkVCSStatus() |
181 |
335 |
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): |
336 def hgQueueListPatches(self, name): |
219 """ |
337 """ |
220 Public method to create a new named patch. |
338 Public method to show a list of all patches. |
221 |
339 |
222 @param name file/directory name (string) |
340 @param name file/directory name (string) |
223 """ |
341 """ |
224 self.queuesListDialog = HgQueuesListDialog(self.vcs) |
342 self.queuesListDialog = HgQueuesListDialog(self.vcs) |
225 self.queuesListDialog.show() |
343 self.queuesListDialog.show() |
226 self.queuesListDialog.start(name) |
344 self.queuesListDialog.start(name) |
227 |
345 |
228 def hgQueueFinishAppliedPatches(self, name): |
346 def hgQueueFinishAppliedPatches(self, name): |
229 """ |
347 """ |
230 Public method to create a new named patch. |
348 Public method to finish all applied patches. |
231 |
349 |
232 @param name file/directory name (string) |
350 @param name file/directory name (string) |
233 """ |
351 """ |
234 # find the root of the repo |
352 # find the root of the repo |
235 repodir = self.vcs.splitPath(name)[0] |
353 repodir = self.vcs.splitPath(name)[0] |
245 dia = HgDialog(self.trUtf8('Finish Applied Patches')) |
363 dia = HgDialog(self.trUtf8('Finish Applied Patches')) |
246 res = dia.startProcess(args, repodir) |
364 res = dia.startProcess(args, repodir) |
247 if res: |
365 if res: |
248 dia.exec_() |
366 dia.exec_() |
249 self.vcs.checkVCSStatus() |
367 self.vcs.checkVCSStatus() |
|
368 |
|
369 def hgQueueRenamePatch(self, name): |
|
370 """ |
|
371 Public method to rename the current or a selected patch. |
|
372 |
|
373 @param name file/directory name (string) |
|
374 """ |
|
375 # find the root of the repo |
|
376 repodir = self.vcs.splitPath(name)[0] |
|
377 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
378 repodir = os.path.dirname(repodir) |
|
379 if repodir == os.sep: |
|
380 return |
|
381 |
|
382 args = [] |
|
383 args.append("qrename") |
|
384 patchnames = sorted(self.__getPatchesList(repodir, Queues.SERIES_LIST)) |
|
385 if patchnames: |
|
386 currentPatch = self.__getCurrentPatch(repodir) |
|
387 if currentPatch: |
|
388 dlg = HgQueuesRenamePatchDialog(currentPatch, patchnames) |
|
389 if dlg.exec_() == QDialog.Accepted: |
|
390 newName, selectedPatch = dlg.getData() |
|
391 if selectedPatch: |
|
392 args.append(selectedPatch) |
|
393 args.append(newName) |
|
394 |
|
395 dia = HgDialog(self.trUtf8("Rename Patch")) |
|
396 res = dia.startProcess(args, repodir) |
|
397 if res: |
|
398 dia.exec_() |
|
399 |
|
400 def hgQueueDeletePatch(self, name): |
|
401 """ |
|
402 Public method to delete a selected unapplied patch. |
|
403 |
|
404 @param name file/directory name (string) |
|
405 """ |
|
406 # find the root of the repo |
|
407 repodir = self.vcs.splitPath(name)[0] |
|
408 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
409 repodir = os.path.dirname(repodir) |
|
410 if repodir == os.sep: |
|
411 return |
|
412 |
|
413 args = [] |
|
414 args.append("qdelete") |
|
415 patchnames = sorted(self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST)) |
|
416 if patchnames: |
|
417 patch, ok = QInputDialog.getItem( |
|
418 None, |
|
419 self.trUtf8("Select Patch"), |
|
420 self.trUtf8("Select the patch to be deleted:"), |
|
421 patchnames, |
|
422 0, False) |
|
423 if ok and patch: |
|
424 args.append(patch) |
|
425 |
|
426 dia = HgDialog(self.trUtf8("Delete Patch")) |
|
427 res = dia.startProcess(args, repodir) |
|
428 if res: |
|
429 dia.exec_() |
|
430 else: |
|
431 E5MessageBox.information(None, |
|
432 self.trUtf8("Select Patch"), |
|
433 self.trUtf8("""No patches to select from.""")) |
|
434 |
|
435 def hgQueueFoldUnappliedPatches(self, name): |
|
436 """ |
|
437 Public method to fold patches into the current patch. |
|
438 |
|
439 @param name file/directory name (string) |
|
440 """ |
|
441 # find the root of the repo |
|
442 repodir = self.vcs.splitPath(name)[0] |
|
443 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)): |
|
444 repodir = os.path.dirname(repodir) |
|
445 if repodir == os.sep: |
|
446 return |
|
447 |
|
448 args = [] |
|
449 args.append("qfold") |
|
450 patchnames = sorted( |
|
451 self.__getPatchesList(repodir, Queues.UNAPPLIED_LIST, withSummary=True)) |
|
452 if patchnames: |
|
453 dlg = HgQueuesFoldDialog(patchnames) |
|
454 if dlg.exec_() == QDialog.Accepted: |
|
455 message, patchesList = dlg.getData() |
|
456 if message: |
|
457 args.append("--message") |
|
458 args.append(message) |
|
459 if patchesList: |
|
460 args.extend(patchesList) |
|
461 |
|
462 dia = HgDialog(self.trUtf8("Fold Patches")) |
|
463 res = dia.startProcess(args, repodir) |
|
464 if res: |
|
465 dia.exec_() |
|
466 else: |
|
467 E5MessageBox.information(None, |
|
468 self.trUtf8("Fold Patches"), |
|
469 self.trUtf8("""No patches selected.""")) |
|
470 else: |
|
471 E5MessageBox.information(None, |
|
472 self.trUtf8("Fold Patches"), |
|
473 self.trUtf8("""No patches available to be folded.""")) |