33 @param parent parent widget (QWidget) |
35 @param parent parent widget (QWidget) |
34 """ |
36 """ |
35 QWidget.__init__(self, parent) |
37 QWidget.__init__(self, parent) |
36 self.setupUi(self) |
38 self.setupUi(self) |
37 |
39 |
38 self.__changelistColumn = 0 |
40 self.__toBeCommittedColumn = 0 |
39 self.__statusColumn = 1 |
41 self.__changelistColumn = 1 |
40 self.__propStatusColumn = 2 |
42 self.__statusColumn = 2 |
41 self.__lockedColumn = 3 |
43 self.__propStatusColumn = 3 |
42 self.__historyColumn = 4 |
44 self.__lockedColumn = 4 |
43 self.__switchedColumn = 5 |
45 self.__historyColumn = 5 |
44 self.__lockinfoColumn = 6 |
46 self.__switchedColumn = 6 |
45 self.__upToDateColumn = 7 |
47 self.__lockinfoColumn = 7 |
46 self.__pathColumn = 11 |
48 self.__upToDateColumn = 8 |
|
49 self.__pathColumn = 12 |
47 self.__lastColumn = self.statusList.columnCount() |
50 self.__lastColumn = self.statusList.columnCount() |
48 |
51 |
49 self.refreshButton = \ |
52 self.refreshButton = \ |
50 self.buttonBox.addButton(self.trUtf8("Refresh"), |
53 self.buttonBox.addButton(self.trUtf8("Refresh"), |
51 QDialogButtonBox.ActionRole) |
54 QDialogButtonBox.ActionRole) |
53 self.trUtf8("Press to refresh the status display")) |
56 self.trUtf8("Press to refresh the status display")) |
54 self.refreshButton.setEnabled(False) |
57 self.refreshButton.setEnabled(False) |
55 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) |
58 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) |
56 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
59 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
57 |
60 |
|
61 self.diff = None |
58 self.process = None |
62 self.process = None |
59 self.vcs = vcs |
63 self.vcs = vcs |
60 self.vcs.committed.connect(self.__committed) |
64 self.vcs.committed.connect(self.__committed) |
61 |
65 |
62 self.statusList.headerItem().setText(self.__lastColumn, "") |
66 self.statusList.headerItem().setText(self.__lastColumn, "") |
71 self.trUtf8("Commit changes to repository..."), self.__commit)) |
75 self.trUtf8("Commit changes to repository..."), self.__commit)) |
72 self.menu.addSeparator() |
76 self.menu.addSeparator() |
73 self.menuactions.append(self.menu.addAction( |
77 self.menuactions.append(self.menu.addAction( |
74 self.trUtf8("Add to repository"), self.__add)) |
78 self.trUtf8("Add to repository"), self.__add)) |
75 self.menuactions.append(self.menu.addAction( |
79 self.menuactions.append(self.menu.addAction( |
|
80 self.trUtf8("Show differences"), self.__diff)) |
|
81 self.menuactions.append(self.menu.addAction( |
76 self.trUtf8("Revert changes"), self.__revert)) |
82 self.trUtf8("Revert changes"), self.__revert)) |
|
83 self.menuactions.append(self.menu.addAction( |
|
84 self.trUtf8("Restore missing"), self.__restoreMissing)) |
77 if self.vcs.versionStr >= '1.5.0': |
85 if self.vcs.versionStr >= '1.5.0': |
78 self.menu.addSeparator() |
86 self.menu.addSeparator() |
79 self.menuactions.append(self.menu.addAction( |
87 self.menuactions.append(self.menu.addAction( |
80 self.trUtf8("Add to Changelist"), self.__addToChangelist)) |
88 self.trUtf8("Add to Changelist"), self.__addToChangelist)) |
81 self.menuactions.append(self.menu.addAction( |
89 self.menuactions.append(self.menu.addAction( |
106 |
114 |
107 self.modifiedIndicators = [ |
115 self.modifiedIndicators = [ |
108 self.trUtf8('added'), |
116 self.trUtf8('added'), |
109 self.trUtf8('deleted'), |
117 self.trUtf8('deleted'), |
110 self.trUtf8('modified'), |
118 self.trUtf8('modified'), |
|
119 ] |
|
120 |
|
121 self.missingIndicators = [ |
|
122 self.trUtf8('missing'), |
111 ] |
123 ] |
112 |
124 |
113 self.unversionedIndicators = [ |
125 self.unversionedIndicators = [ |
114 self.trUtf8('unversioned'), |
126 self.trUtf8('unversioned'), |
115 ] |
127 ] |
223 lockinfo == " " and \ |
235 lockinfo == " " and \ |
224 uptodate == " " and \ |
236 uptodate == " " and \ |
225 self.currentChangelist == "": |
237 self.currentChangelist == "": |
226 return |
238 return |
227 |
239 |
|
240 statusText = self.status[status] |
228 itm = QTreeWidgetItem(self.statusList, [ |
241 itm = QTreeWidgetItem(self.statusList, [ |
229 self.currentChangelist, |
242 self.currentChangelist, |
230 self.status[status], |
243 statusText, |
231 self.propStatus[propStatus], |
244 self.propStatus[propStatus], |
232 self.locked[locked], |
245 self.locked[locked], |
233 self.history[history], |
246 self.history[history], |
234 self.switched[switched], |
247 self.switched[switched], |
235 self.lockinfo[lockinfo], |
248 self.lockinfo[lockinfo], |
238 "{0:7}".format(str(change)), |
251 "{0:7}".format(str(change)), |
239 author, |
252 author, |
240 path, |
253 path, |
241 ]) |
254 ]) |
242 |
255 |
243 itm.setTextAlignment(0, Qt.AlignLeft) |
256 itm.setTextAlignment(1, Qt.AlignLeft) |
244 itm.setTextAlignment(1, Qt.AlignHCenter) |
|
245 itm.setTextAlignment(2, Qt.AlignHCenter) |
257 itm.setTextAlignment(2, Qt.AlignHCenter) |
246 itm.setTextAlignment(3, Qt.AlignHCenter) |
258 itm.setTextAlignment(3, Qt.AlignHCenter) |
247 itm.setTextAlignment(4, Qt.AlignHCenter) |
259 itm.setTextAlignment(4, Qt.AlignHCenter) |
248 itm.setTextAlignment(5, Qt.AlignHCenter) |
260 itm.setTextAlignment(5, Qt.AlignHCenter) |
249 itm.setTextAlignment(6, Qt.AlignHCenter) |
261 itm.setTextAlignment(6, Qt.AlignHCenter) |
250 itm.setTextAlignment(7, Qt.AlignHCenter) |
262 itm.setTextAlignment(7, Qt.AlignHCenter) |
251 itm.setTextAlignment(8, Qt.AlignRight) |
263 itm.setTextAlignment(8, Qt.AlignHCenter) |
252 itm.setTextAlignment(9, Qt.AlignRight) |
264 itm.setTextAlignment(9, Qt.AlignRight) |
253 itm.setTextAlignment(10, Qt.AlignLeft) |
265 itm.setTextAlignment(10, Qt.AlignRight) |
254 itm.setTextAlignment(11, Qt.AlignLeft) |
266 itm.setTextAlignment(11, Qt.AlignLeft) |
|
267 itm.setTextAlignment(12, Qt.AlignLeft) |
|
268 |
|
269 if status in "ADM" or propStatus in "M": |
|
270 itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) |
255 |
271 |
256 self.hidePropertyStatusColumn = self.hidePropertyStatusColumn and \ |
272 self.hidePropertyStatusColumn = self.hidePropertyStatusColumn and \ |
257 propStatus == " " |
273 propStatus == " " |
258 self.hideLockColumns = self.hideLockColumns and \ |
274 self.hideLockColumns = self.hideLockColumns and \ |
259 locked == " " and lockinfo == " " |
275 locked == " " and lockinfo == " " |
260 self.hideUpToDateColumn = self.hideUpToDateColumn and uptodate == " " |
276 self.hideUpToDateColumn = self.hideUpToDateColumn and uptodate == " " |
261 self.hideHistoryColumn = self.hideHistoryColumn and history == " " |
277 self.hideHistoryColumn = self.hideHistoryColumn and history == " " |
262 self.hideSwitchedColumn = self.hideSwitchedColumn and switched == " " |
278 self.hideSwitchedColumn = self.hideSwitchedColumn and switched == " " |
263 |
279 |
|
280 if statusText not in self.__statusFilters: |
|
281 self.__statusFilters.append(statusText) |
|
282 |
264 def closeEvent(self, e): |
283 def closeEvent(self, e): |
265 """ |
284 """ |
266 Private slot implementing a close event handler. |
285 Private slot implementing a close event handler. |
267 |
286 |
268 @param e close event (QCloseEvent) |
287 @param e close event (QCloseEvent) |
283 (string or list of strings) |
302 (string or list of strings) |
284 """ |
303 """ |
285 self.errorGroup.hide() |
304 self.errorGroup.hide() |
286 self.intercept = False |
305 self.intercept = False |
287 self.args = fn |
306 self.args = fn |
|
307 |
|
308 for act in self.menuactions: |
|
309 act.setEnabled(False) |
|
310 |
|
311 self.addButton.setEnabled(False) |
|
312 self.commitButton.setEnabled(False) |
|
313 self.diffButton.setEnabled(False) |
|
314 self.revertButton.setEnabled(False) |
|
315 self.restoreButton.setEnabled(False) |
|
316 |
|
317 self.statusFilterCombo.clear() |
|
318 self.__statusFilters = [] |
|
319 |
288 self.currentChangelist = "" |
320 self.currentChangelist = "" |
289 self.changelistFound = False |
321 self.changelistFound = False |
290 |
322 |
291 self.hidePropertyStatusColumn = True |
323 self.hidePropertyStatusColumn = True |
292 self.hideLockColumns = True |
324 self.hideLockColumns = True |
379 self.hideUpToDateColumn) |
415 self.hideUpToDateColumn) |
380 self.statusList.setColumnHidden(self.__historyColumn, |
416 self.statusList.setColumnHidden(self.__historyColumn, |
381 self.hideHistoryColumn) |
417 self.hideHistoryColumn) |
382 self.statusList.setColumnHidden(self.__switchedColumn, |
418 self.statusList.setColumnHidden(self.__switchedColumn, |
383 self.hideSwitchedColumn) |
419 self.hideSwitchedColumn) |
|
420 |
|
421 self.__updateButtons() |
|
422 self.__updateCommitButton() |
384 |
423 |
385 def on_buttonBox_clicked(self, button): |
424 def on_buttonBox_clicked(self, button): |
386 """ |
425 """ |
387 Private slot called by a button of the button box clicked. |
426 Private slot called by a button of the button box clicked. |
388 |
427 |
514 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
553 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) |
515 |
554 |
516 self.inputGroup.setEnabled(True) |
555 self.inputGroup.setEnabled(True) |
517 self.refreshButton.setEnabled(False) |
556 self.refreshButton.setEnabled(False) |
518 |
557 |
519 for act in self.menuactions: |
|
520 act.setEnabled(False) |
|
521 |
|
522 self.statusList.clear() |
558 self.statusList.clear() |
523 |
559 |
524 self.start(self.args) |
560 self.start(self.args) |
|
561 |
|
562 def __updateButtons(self): |
|
563 """ |
|
564 Private method to update the VCS buttons status. |
|
565 """ |
|
566 modified = len(self.__getModifiedItems()) |
|
567 unversioned = len(self.__getUnversionedItems()) |
|
568 missing = len(self.__getMissingItems()) |
|
569 |
|
570 self.addButton.setEnabled(unversioned) |
|
571 self.diffButton.setEnabled(modified) |
|
572 self.revertButton.setEnabled(modified) |
|
573 self.restoreButton.setEnabled(missing) |
|
574 |
|
575 def __updateCommitButton(self): |
|
576 """ |
|
577 Private method to update the Commit button status. |
|
578 """ |
|
579 commitable = len(self.__getCommitableItems()) |
|
580 self.commitButton.setEnabled(commitable) |
|
581 |
|
582 @pyqtSlot(str) |
|
583 def on_statusFilterCombo_activated(self, txt): |
|
584 """ |
|
585 Private slot to react to the selection of a status filter. |
|
586 |
|
587 @param txt selected status filter (string) |
|
588 """ |
|
589 if txt == "<{0}>".format(self.trUtf8("all")): |
|
590 for topIndex in range(self.statusList.topLevelItemCount()): |
|
591 topItem = self.statusList.topLevelItem(topIndex) |
|
592 topItem.setHidden(False) |
|
593 else: |
|
594 for topIndex in range(self.statusList.topLevelItemCount()): |
|
595 topItem = self.statusList.topLevelItem(topIndex) |
|
596 topItem.setHidden(topItem.text(self.__statusColumn) != txt) |
|
597 |
|
598 @pyqtSlot(QTreeWidgetItem, int) |
|
599 def on_statusList_itemChanged(self, item, column): |
|
600 """ |
|
601 Private slot to act upon item changes. |
|
602 |
|
603 @param item reference to the changed item (QTreeWidgetItem) |
|
604 @param column index of column that changed (integer) |
|
605 """ |
|
606 if column == self.__toBeCommittedColumn: |
|
607 self.__updateCommitButton() |
|
608 |
|
609 @pyqtSlot() |
|
610 def on_statusList_itemSelectionChanged(self): |
|
611 """ |
|
612 Private slot to act upon changes of selected items. |
|
613 """ |
|
614 self.__updateButtons() |
|
615 |
|
616 @pyqtSlot() |
|
617 def on_commitButton_clicked(self): |
|
618 """ |
|
619 Private slot to handle the press of the Commit button. |
|
620 """ |
|
621 self.__commit() |
|
622 |
|
623 @pyqtSlot() |
|
624 def on_addButton_clicked(self): |
|
625 """ |
|
626 Private slot to handle the press of the Add button. |
|
627 """ |
|
628 self.__add() |
|
629 |
|
630 @pyqtSlot() |
|
631 def on_diffButton_clicked(self): |
|
632 """ |
|
633 Private slot to handle the press of the Differences button. |
|
634 """ |
|
635 self.__diff() |
|
636 |
|
637 @pyqtSlot() |
|
638 def on_revertButton_clicked(self): |
|
639 """ |
|
640 Private slot to handle the press of the Revert button. |
|
641 """ |
|
642 self.__revert() |
|
643 |
|
644 @pyqtSlot() |
|
645 def on_restoreButton_clicked(self): |
|
646 """ |
|
647 Private slot to handle the press of the Restore button. |
|
648 """ |
|
649 self.__restoreMissing() |
525 |
650 |
526 ########################################################################### |
651 ########################################################################### |
527 ## Context menu handling methods |
652 ## Context menu handling methods |
528 ########################################################################### |
653 ########################################################################### |
529 |
654 |
538 def __commit(self): |
663 def __commit(self): |
539 """ |
664 """ |
540 Private slot to handle the Commit context menu entry. |
665 Private slot to handle the Commit context menu entry. |
541 """ |
666 """ |
542 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
667 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
543 for itm in self.__getModifiedItems()] |
668 for itm in self.__getCommitableItems()] |
544 if not names: |
669 if not names: |
545 E5MessageBox.information(self, |
670 E5MessageBox.information(self, |
546 self.trUtf8("Commit"), |
671 self.trUtf8("Commit"), |
547 self.trUtf8("""There are no uncommitted changes""" |
672 self.trUtf8("""There are no entries selected to be""" |
548 """ available/selected.""")) |
673 """ committed.""")) |
549 return |
674 return |
550 |
675 |
551 if Preferences.getVCS("AutoSaveFiles"): |
676 if Preferences.getVCS("AutoSaveFiles"): |
552 vm = e5App().getObject("ViewManager") |
677 vm = e5App().getObject("ViewManager") |
553 for name in names: |
678 for name in names: |
602 project = e5App().getObject("Project") |
727 project = e5App().getObject("Project") |
603 for name in names: |
728 for name in names: |
604 project.getModel().updateVCSStatus(name) |
729 project.getModel().updateVCSStatus(name) |
605 self.vcs.checkVCSStatus() |
730 self.vcs.checkVCSStatus() |
606 |
731 |
|
732 def __restoreMissing(self): |
|
733 """ |
|
734 Private slot to handle the Restore Missing context menu entry. |
|
735 """ |
|
736 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
|
737 for itm in self.__getMissingItems()] |
|
738 if not names: |
|
739 E5MessageBox.information(self, |
|
740 self.trUtf8("Revert"), |
|
741 self.trUtf8("""There are no missing entries""" |
|
742 """ available/selected.""")) |
|
743 return |
|
744 |
|
745 self.vcs.vcsRevert(names) |
|
746 self.on_refreshButton_clicked() |
|
747 self.vcs.checkVCSStatus() |
|
748 |
|
749 def __diff(self): |
|
750 """ |
|
751 Private slot to handle the Diff context menu entry. |
|
752 """ |
|
753 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
|
754 for itm in self.__getModifiedItems()] |
|
755 if not names: |
|
756 E5MessageBox.information(self, |
|
757 self.trUtf8("Differences"), |
|
758 self.trUtf8("""There are no uncommitted changes""" |
|
759 """ available/selected.""")) |
|
760 return |
|
761 |
|
762 if self.diff is None: |
|
763 self.diff = SvnDiffDialog(self.vcs) |
|
764 self.diff.show() |
|
765 QApplication.processEvents() |
|
766 self.diff.start(names) |
|
767 |
607 def __lock(self): |
768 def __lock(self): |
608 """ |
769 """ |
609 Private slot to handle the Lock context menu entry. |
770 Private slot to handle the Lock context menu entry. |
610 """ |
771 """ |
611 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
772 names = [os.path.join(self.dname, itm.text(self.__pathColumn)) |
704 ) |
865 ) |
705 return |
866 return |
706 self.vcs.svnRemoveFromChangelist(names) |
867 self.vcs.svnRemoveFromChangelist(names) |
707 self.on_refreshButton_clicked() |
868 self.on_refreshButton_clicked() |
708 |
869 |
|
870 def __getCommitableItems(self): |
|
871 """ |
|
872 Private method to retrieve all entries the user wants to commit. |
|
873 |
|
874 @return list of all items, the user has checked |
|
875 """ |
|
876 commitableItems = [] |
|
877 for index in range(self.statusList.topLevelItemCount()): |
|
878 itm = self.statusList.topLevelItem(index) |
|
879 if itm.checkState(self.__toBeCommittedColumn) == Qt.Checked: |
|
880 commitableItems.append(itm) |
|
881 return commitableItems |
|
882 |
709 def __getModifiedItems(self): |
883 def __getModifiedItems(self): |
710 """ |
884 """ |
711 Private method to retrieve all entries, that have a modified status. |
885 Private method to retrieve all entries, that have a modified status. |
712 |
886 |
713 @return list of all items with a modified status |
887 @return list of all items with a modified status |
730 for itm in self.statusList.selectedItems(): |
904 for itm in self.statusList.selectedItems(): |
731 if itm.text(self.__statusColumn) in self.unversionedIndicators: |
905 if itm.text(self.__statusColumn) in self.unversionedIndicators: |
732 unversionedItems.append(itm) |
906 unversionedItems.append(itm) |
733 return unversionedItems |
907 return unversionedItems |
734 |
908 |
|
909 def __getMissingItems(self): |
|
910 """ |
|
911 Private method to retrieve all entries, that have a missing status. |
|
912 |
|
913 @return list of all items with a missing status |
|
914 """ |
|
915 missingItems = [] |
|
916 for itm in self.statusList.selectedItems(): |
|
917 if itm.text(self.__statusColumn) in self.missingIndicators: |
|
918 missingItems.append(itm) |
|
919 return missingItems |
|
920 |
735 def __getLockActionItems(self, indicators): |
921 def __getLockActionItems(self, indicators): |
736 """ |
922 """ |
737 Private method to retrieve all emtries, that have a locked status. |
923 Private method to retrieve all emtries, that have a locked status. |
738 |
924 |
739 @return list of all items with a locked status |
925 @return list of all items with a locked status |