39 SvnDialogMixin.__init__(self) |
41 SvnDialogMixin.__init__(self) |
40 |
42 |
41 self.__changelistColumn = 0 |
43 self.__changelistColumn = 0 |
42 self.__statusColumn = 1 |
44 self.__statusColumn = 1 |
43 self.__propStatusColumn = 2 |
45 self.__propStatusColumn = 2 |
|
46 self.__lockedColumn = 3 |
|
47 self.__historyColumn = 4 |
|
48 self.__switchedColumn = 5 |
44 self.__lockinfoColumn = 6 |
49 self.__lockinfoColumn = 6 |
|
50 self.__upToDateColumn = 7 |
45 self.__pathColumn = 11 |
51 self.__pathColumn = 11 |
46 self.__lastColumn = self.statusList.columnCount() |
52 self.__lastColumn = self.statusList.columnCount() |
47 |
53 |
48 self.refreshButton = \ |
54 self.refreshButton = \ |
49 self.buttonBox.addButton(self.trUtf8("Refresh"), QDialogButtonBox.ActionRole) |
55 self.buttonBox.addButton(self.trUtf8("Refresh"), |
50 self.refreshButton.setToolTip(self.trUtf8("Press to refresh the status display")) |
56 QDialogButtonBox.ActionRole) |
|
57 self.refreshButton.setToolTip( |
|
58 self.trUtf8("Press to refresh the status display")) |
51 self.refreshButton.setEnabled(False) |
59 self.refreshButton.setEnabled(False) |
52 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) |
60 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) |
53 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
61 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
54 |
62 |
55 self.vcs = vcs |
63 self.vcs = vcs |
56 self.vcs.committed.connect(self.__committed) |
64 self.vcs.committed.connect(self.__committed) |
57 |
65 |
58 self.statusList.headerItem().setText(self.__lastColumn, "") |
66 self.statusList.headerItem().setText(self.__lastColumn, "") |
59 self.statusList.header().setSortIndicator(self.__pathColumn, Qt.AscendingOrder) |
67 self.statusList.header().setSortIndicator(self.__pathColumn, |
|
68 Qt.AscendingOrder) |
60 if pysvn.svn_version < (1, 5, 0) or pysvn.version < (1, 6, 0): |
69 if pysvn.svn_version < (1, 5, 0) or pysvn.version < (1, 6, 0): |
61 self.statusList.header().hideSection(self.__changelistColumn) |
70 self.statusList.header().hideSection(self.__changelistColumn) |
62 |
71 |
63 self.menuactions = [] |
72 self.menuactions = [] |
64 self.menu = QMenu() |
73 self.menu = QMenu() |
72 if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0): |
81 if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0): |
73 self.menu.addSeparator() |
82 self.menu.addSeparator() |
74 self.menuactions.append(self.menu.addAction( |
83 self.menuactions.append(self.menu.addAction( |
75 self.trUtf8("Add to Changelist"), self.__addToChangelist)) |
84 self.trUtf8("Add to Changelist"), self.__addToChangelist)) |
76 self.menuactions.append(self.menu.addAction( |
85 self.menuactions.append(self.menu.addAction( |
77 self.trUtf8("Remove from Changelist"), self.__removeFromChangelist)) |
86 self.trUtf8("Remove from Changelist"), |
|
87 self.__removeFromChangelist)) |
78 if self.vcs.versionStr >= '1.2.0': |
88 if self.vcs.versionStr >= '1.2.0': |
79 self.menu.addSeparator() |
89 self.menu.addSeparator() |
80 self.menuactions.append(self.menu.addAction(self.trUtf8("Lock"), |
90 self.menuactions.append(self.menu.addAction(self.trUtf8("Lock"), |
81 self.__lock)) |
91 self.__lock)) |
82 self.menuactions.append(self.menu.addAction(self.trUtf8("Unlock"), |
92 self.menuactions.append(self.menu.addAction(self.trUtf8("Unlock"), |
83 self.__unlock)) |
93 self.__unlock)) |
84 self.menuactions.append(self.menu.addAction(self.trUtf8("Break lock"), |
94 self.menuactions.append(self.menu.addAction( |
|
95 self.trUtf8("Break lock"), |
85 self.__breakLock)) |
96 self.__breakLock)) |
86 self.menuactions.append(self.menu.addAction(self.trUtf8("Steal lock"), |
97 self.menuactions.append(self.menu.addAction( |
|
98 self.trUtf8("Steal lock"), |
87 self.__stealLock)) |
99 self.__stealLock)) |
88 self.menu.addSeparator() |
100 self.menu.addSeparator() |
89 self.menuactions.append(self.menu.addAction(self.trUtf8("Adjust column sizes"), |
101 self.menuactions.append(self.menu.addAction( |
|
102 self.trUtf8("Adjust column sizes"), |
90 self.__resizeColumns)) |
103 self.__resizeColumns)) |
91 for act in self.menuactions: |
104 for act in self.menuactions: |
92 act.setEnabled(False) |
105 act.setEnabled(False) |
93 |
106 |
94 self.statusList.setContextMenuPolicy(Qt.CustomContextMenu) |
107 self.statusList.setContextMenuPolicy(Qt.CustomContextMenu) |
95 self.statusList.customContextMenuRequested.connect(self.__showContextMenu) |
108 self.statusList.customContextMenuRequested.connect( |
|
109 self.__showContextMenu) |
96 |
110 |
97 self.modifiedIndicators = [ |
111 self.modifiedIndicators = [ |
98 self.trUtf8(svnStatusMap[pysvn.wc_status_kind.added]), |
112 self.trUtf8(svnStatusMap[pysvn.wc_status_kind.added]), |
99 self.trUtf8(svnStatusMap[pysvn.wc_status_kind.deleted]), |
113 self.trUtf8(svnStatusMap[pysvn.wc_status_kind.deleted]), |
100 self.trUtf8(svnStatusMap[pysvn.wc_status_kind.modified]) |
114 self.trUtf8(svnStatusMap[pysvn.wc_status_kind.modified]) |
153 Private method to resize the list columns. |
167 Private method to resize the list columns. |
154 """ |
168 """ |
155 self.statusList.header().resizeSections(QHeaderView.ResizeToContents) |
169 self.statusList.header().resizeSections(QHeaderView.ResizeToContents) |
156 self.statusList.header().setStretchLastSection(True) |
170 self.statusList.header().setStretchLastSection(True) |
157 |
171 |
158 def __generateItem(self, changelist, status, propStatus, locked, history, switched, |
172 def __generateItem(self, changelist, status, propStatus, locked, history, |
159 lockinfo, uptodate, revision, change, author, path): |
173 switched, lockinfo, uptodate, revision, change, author, |
|
174 path): |
160 """ |
175 """ |
161 Private method to generate a status item in the status list. |
176 Private method to generate a status item in the status list. |
162 |
177 |
163 @param changelist name of the changelist (string) |
178 @param changelist name of the changelist (string) |
164 @param status text status (pysvn.wc_status_kind) |
179 @param status text status (pysvn.wc_status_kind) |
228 opts = self.vcs.options['global'] + self.vcs.options['status'] |
243 opts = self.vcs.options['global'] + self.vcs.options['status'] |
229 verbose = "--verbose" in opts |
244 verbose = "--verbose" in opts |
230 recurse = "--non-recursive" not in opts |
245 recurse = "--non-recursive" not in opts |
231 update = "--show-updates" in opts |
246 update = "--show-updates" in opts |
232 |
247 |
|
248 hidePropertyStatusColumn = True |
|
249 hideLockColumns = True |
|
250 hideUpToDateColumn = True |
|
251 hideHistoryColumn = True |
|
252 hideSwitchedColumn = True |
|
253 |
233 locker = QMutexLocker(self.vcs.vcsExecutionMutex) |
254 locker = QMutexLocker(self.vcs.vcsExecutionMutex) |
234 cwd = os.getcwd() |
255 cwd = os.getcwd() |
235 os.chdir(self.dname) |
256 os.chdir(self.dname) |
236 try: |
257 try: |
237 for name in fnames: |
258 for name in fnames: |
240 if hasattr(self.client, 'get_changelist'): |
261 if hasattr(self.client, 'get_changelist'): |
241 if recurse: |
262 if recurse: |
242 depth = pysvn.depth.infinity |
263 depth = pysvn.depth.infinity |
243 else: |
264 else: |
244 depth = pysvn.depth.immediate |
265 depth = pysvn.depth.immediate |
245 changelists = self.client.get_changelist(name, depth = depth) |
266 changelists = self.client.get_changelist(name, depth=depth) |
246 for entry in changelists: |
267 for entry in changelists: |
247 changelistsDict[entry[0]] = entry[1] |
268 changelistsDict[entry[0]] = entry[1] |
248 self.statusList.setColumnHidden(self.__changelistColumn, |
269 self.statusList.setColumnHidden(self.__changelistColumn, |
249 len(changelistsDict) == 0) |
270 len(changelistsDict) == 0) |
250 |
271 |
251 # step 2: determine status of files |
272 # step 2: determine status of files |
252 allFiles = self.client.status(name, recurse = recurse, get_all = verbose, |
273 allFiles = self.client.status(name, recurse = recurse, |
253 ignore = True, update = update) |
274 get_all=verbose, ignore=True, |
|
275 update = update) |
254 counter = 0 |
276 counter = 0 |
255 for file in allFiles: |
277 for file in allFiles: |
256 uptodate = True |
278 uptodate = True |
257 if file.repos_text_status != pysvn.wc_status_kind.none: |
279 if file.repos_text_status != pysvn.wc_status_kind.none: |
258 uptodate = uptodate and file.repos_text_status == file.text_status |
280 uptodate = uptodate and \ |
|
281 file.repos_text_status == file.text_status |
259 if file.repos_prop_status != pysvn.wc_status_kind.none: |
282 if file.repos_prop_status != pysvn.wc_status_kind.none: |
260 uptodate = uptodate and file.repos_prop_status == file.prop_status |
283 uptodate = uptodate and \ |
|
284 file.repos_prop_status == file.prop_status |
261 |
285 |
262 lockState = " " |
286 lockState = " " |
263 if file.entry is not None and \ |
287 if file.entry is not None and \ |
264 hasattr(file.entry, 'lock_token') and \ |
288 hasattr(file.entry, 'lock_token') and \ |
265 file.entry.lock_token is not None: |
289 file.entry.lock_token is not None: |
267 if hasattr(file, 'repos_lock') and update: |
291 if hasattr(file, 'repos_lock') and update: |
268 if lockState == "L" and file.repos_lock is None: |
292 if lockState == "L" and file.repos_lock is None: |
269 lockState = "B" |
293 lockState = "B" |
270 elif lockState == " " and file.repos_lock is not None: |
294 elif lockState == " " and file.repos_lock is not None: |
271 lockState = "O" |
295 lockState = "O" |
272 elif lockState == "L" and file.repos_lock is not None and \ |
296 elif lockState == "L" and \ |
|
297 file.repos_lock is not None and \ |
273 file.entry.lock_token != file.repos_lock["token"]: |
298 file.entry.lock_token != file.repos_lock["token"]: |
274 lockState = "S" |
299 lockState = "S" |
275 |
300 |
276 if file.path in changelistsDict: |
301 if file.path in changelistsDict: |
277 changelist = changelistsDict[file.path] |
302 changelist = changelistsDict[file.path] |
278 else: |
303 else: |
279 changelist = "" |
304 changelist = "" |
|
305 |
|
306 hidePropertyStatusColumn = hidePropertyStatusColumn and \ |
|
307 file.prop_status in [ |
|
308 pysvn.wc_status_kind.none, |
|
309 pysvn.wc_status_kind.normal |
|
310 ] |
|
311 hideLockColumns = hideLockColumns and \ |
|
312 not file.is_locked and lockState == " " |
|
313 hideUpToDateColumn = hideUpToDateColumn and uptodate |
|
314 hideHistoryColumn = hideHistoryColumn and \ |
|
315 not file.is_copied |
|
316 hideSwitchedColumn = hideSwitchedColumn and \ |
|
317 not file.is_switched |
280 |
318 |
281 self.__generateItem( |
319 self.__generateItem( |
282 changelist, |
320 changelist, |
283 file.text_status, |
321 file.text_status, |
284 file.prop_status, |
322 file.prop_status, |
300 break |
338 break |
301 if self._clientCancelCallback(): |
339 if self._clientCancelCallback(): |
302 break |
340 break |
303 except pysvn.ClientError as e: |
341 except pysvn.ClientError as e: |
304 self.__showError(e.args[0]+'\n') |
342 self.__showError(e.args[0]+'\n') |
|
343 |
|
344 self.statusList.setColumnHidden(self.__propStatusColumn, |
|
345 hidePropertyStatusColumn) |
|
346 self.statusList.setColumnHidden(self.__lockedColumn, |
|
347 hideLockColumns) |
|
348 self.statusList.setColumnHidden(self.__lockinfoColumn, |
|
349 hideLockColumns) |
|
350 self.statusList.setColumnHidden(self.__upToDateColumn, |
|
351 hideUpToDateColumn) |
|
352 self.statusList.setColumnHidden(self.__historyColumn, |
|
353 hideHistoryColumn) |
|
354 self.statusList.setColumnHidden(self.__switchedColumn, |
|
355 hideSwitchedColumn) |
|
356 |
305 locker.unlock() |
357 locker.unlock() |
306 self.__finish() |
358 self.__finish() |
307 os.chdir(cwd) |
359 os.chdir(cwd) |
308 |
360 |
309 def __finish(self): |
361 def __finish(self): |
310 """ |
362 """ |
311 Private slot called when the process finished or the user pressed the button. |
363 Private slot called when the process finished or the user pressed |
|
364 the button. |
312 """ |
365 """ |
313 QApplication.restoreOverrideCursor() |
366 QApplication.restoreOverrideCursor() |
314 |
367 |
315 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) |
368 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) |
316 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) |
369 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) |
367 """ |
420 """ |
368 self.errorGroup.show() |
421 self.errorGroup.show() |
369 self.errors.insertPlainText(msg) |
422 self.errors.insertPlainText(msg) |
370 self.errors.ensureCursorVisible() |
423 self.errors.ensureCursorVisible() |
371 |
424 |
372 ############################################################################ |
425 ########################################################################### |
373 ## Context menu handling methods |
426 ## Context menu handling methods |
374 ############################################################################ |
427 ########################################################################### |
375 |
428 |
376 def __showContextMenu(self, coord): |
429 def __showContextMenu(self, coord): |
377 """ |
430 """ |
378 Protected slot to show the context menu of the status list. |
431 Protected slot to show the context menu of the status list. |
379 |
432 |
388 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
441 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
389 for itm in self.__getModifiedItems()] |
442 for itm in self.__getModifiedItems()] |
390 if not names: |
443 if not names: |
391 E5MessageBox.information(self, |
444 E5MessageBox.information(self, |
392 self.trUtf8("Commit"), |
445 self.trUtf8("Commit"), |
393 self.trUtf8("""There are no uncommitted changes available/selected.""")) |
446 self.trUtf8("""There are no uncommitted changes""" |
|
447 """ available/selected.""")) |
394 return |
448 return |
395 |
449 |
396 if Preferences.getVCS("AutoSaveFiles"): |
450 if Preferences.getVCS("AutoSaveFiles"): |
397 vm = e5App().getObject("ViewManager") |
451 vm = e5App().getObject("ViewManager") |
398 for name in names: |
452 for name in names: |
414 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
468 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
415 for itm in self.__getUnversionedItems()] |
469 for itm in self.__getUnversionedItems()] |
416 if not names: |
470 if not names: |
417 E5MessageBox.information(self, |
471 E5MessageBox.information(self, |
418 self.trUtf8("Add"), |
472 self.trUtf8("Add"), |
419 self.trUtf8("""There are no unversioned entries available/selected.""")) |
473 self.trUtf8("""There are no unversioned entries""" |
|
474 """ available/selected.""")) |
420 return |
475 return |
421 |
476 |
422 self.vcs.vcsAdd(names) |
477 self.vcs.vcsAdd(names) |
423 self.on_refreshButton_clicked() |
478 self.on_refreshButton_clicked() |
424 |
479 |
434 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
489 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
435 for itm in self.__getModifiedItems()] |
490 for itm in self.__getModifiedItems()] |
436 if not names: |
491 if not names: |
437 E5MessageBox.information(self, |
492 E5MessageBox.information(self, |
438 self.trUtf8("Revert"), |
493 self.trUtf8("Revert"), |
439 self.trUtf8("""There are no uncommitted changes available/selected.""")) |
494 self.trUtf8("""There are no uncommitted changes""" |
|
495 """ available/selected.""")) |
440 return |
496 return |
441 |
497 |
442 self.vcs.vcsRevert(names) |
498 self.vcs.vcsRevert(names) |
443 self.on_refreshButton_clicked() |
499 self.on_refreshButton_clicked() |
444 |
500 |
454 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
510 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
455 for itm in self.__getLockActionItems(self.unlockedIndicators)] |
511 for itm in self.__getLockActionItems(self.unlockedIndicators)] |
456 if not names: |
512 if not names: |
457 E5MessageBox.information(self, |
513 E5MessageBox.information(self, |
458 self.trUtf8("Lock"), |
514 self.trUtf8("Lock"), |
459 self.trUtf8("""There are no unlocked files available/selected.""")) |
515 self.trUtf8("""There are no unlocked files""" |
|
516 """ available/selected.""")) |
460 return |
517 return |
461 |
518 |
462 self.vcs.svnLock(names, parent = self) |
519 self.vcs.svnLock(names, parent = self) |
463 self.on_refreshButton_clicked() |
520 self.on_refreshButton_clicked() |
464 |
521 |
469 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
526 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
470 for itm in self.__getLockActionItems(self.lockedIndicators)] |
527 for itm in self.__getLockActionItems(self.lockedIndicators)] |
471 if not names: |
528 if not names: |
472 E5MessageBox.information(self, |
529 E5MessageBox.information(self, |
473 self.trUtf8("Unlock"), |
530 self.trUtf8("Unlock"), |
474 self.trUtf8("""There are no locked files available/selected.""")) |
531 self.trUtf8("""There are no locked files""" |
|
532 """ available/selected.""")) |
475 return |
533 return |
476 |
534 |
477 self.vcs.svnUnlock(names, parent = self) |
535 self.vcs.svnUnlock(names, parent = self) |
478 self.on_refreshButton_clicked() |
536 self.on_refreshButton_clicked() |
479 |
537 |
480 def __breakLock(self): |
538 def __breakLock(self): |
481 """ |
539 """ |
482 Private slot to handle the Break Lock context menu entry. |
540 Private slot to handle the Break Lock context menu entry. |
483 """ |
541 """ |
484 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
542 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
485 for itm in self.__getLockActionItems(self.stealBreakLockIndicators)] |
543 for itm in self.__getLockActionItems( |
|
544 self.stealBreakLockIndicators)] |
486 if not names: |
545 if not names: |
487 E5MessageBox.information(self, |
546 E5MessageBox.information(self, |
488 self.trUtf8("Break Lock"), |
547 self.trUtf8("Break Lock"), |
489 self.trUtf8("""There are no locked files available/selected.""")) |
548 self.trUtf8("""There are no locked files""" |
|
549 """ available/selected.""")) |
490 return |
550 return |
491 |
551 |
492 self.vcs.svnUnlock(names, parent = self, breakIt = True) |
552 self.vcs.svnUnlock(names, parent = self, breakIt = True) |
493 self.on_refreshButton_clicked() |
553 self.on_refreshButton_clicked() |
494 |
554 |
495 def __stealLock(self): |
555 def __stealLock(self): |
496 """ |
556 """ |
497 Private slot to handle the Break Lock context menu entry. |
557 Private slot to handle the Break Lock context menu entry. |
498 """ |
558 """ |
499 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \ |
559 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
500 for itm in self.__getLockActionItems(self.stealBreakLockIndicators)] |
560 for itm in self.__getLockActionItems( |
|
561 self.stealBreakLockIndicators)] |
501 if not names: |
562 if not names: |
502 E5MessageBox.information(self, |
563 E5MessageBox.information(self, |
503 self.trUtf8("Steal Lock"), |
564 self.trUtf8("Steal Lock"), |
504 self.trUtf8("""There are no locked files available/selected.""")) |
565 self.trUtf8("""There are no locked files""" |
|
566 """ available/selected.""")) |
505 return |
567 return |
506 |
568 |
507 self.vcs.svnLock(names, parent=self, stealIt=True) |
569 self.vcs.svnLock(names, parent=self, stealIt=True) |
508 self.on_refreshButton_clicked() |
570 self.on_refreshButton_clicked() |
509 |
571 |
533 for itm in self.__getChangelistItems()] |
595 for itm in self.__getChangelistItems()] |
534 if not names: |
596 if not names: |
535 E5MessageBox.information(self, |
597 E5MessageBox.information(self, |
536 self.trUtf8("Remove from Changelist"), |
598 self.trUtf8("Remove from Changelist"), |
537 self.trUtf8( |
599 self.trUtf8( |
538 """There are no files available/selected belonging to a changelist.""" |
600 """There are no files available/selected belonging""" |
|
601 """ to a changelist.""" |
539 ) |
602 ) |
540 ) |
603 ) |
541 return |
604 return |
542 self.vcs.svnRemoveFromChangelist(names) |
605 self.vcs.svnRemoveFromChangelist(names) |
543 self.on_refreshButton_clicked() |
606 self.on_refreshButton_clicked() |