146 |
149 |
147 self.__messageRole = Qt.UserRole |
150 self.__messageRole = Qt.UserRole |
148 self.__changesRole = Qt.UserRole + 1 |
151 self.__changesRole = Qt.UserRole + 1 |
149 self.__edgesRole = Qt.UserRole + 2 |
152 self.__edgesRole = Qt.UserRole + 2 |
150 self.__parentsRole = Qt.UserRole + 3 |
153 self.__parentsRole = Qt.UserRole + 3 |
|
154 self.__latestTagRole = Qt.UserRole + 4 |
151 |
155 |
152 if self.__hgClient: |
156 if self.__hgClient: |
153 self.process = None |
157 self.process = None |
154 else: |
158 else: |
155 self.process = QProcess() |
159 self.process = QProcess() |
698 if line.strip().endswith("(closed)"): |
702 if line.strip().endswith("(closed)"): |
699 parts = line.split() |
703 parts = line.split() |
700 self.__closedBranchesRevs.append( |
704 self.__closedBranchesRevs.append( |
701 parts[-2].split(":", 1)[0]) |
705 parts[-2].split(":", 1)[0]) |
702 |
706 |
|
707 def __getRevisionOfTag(self, tag): |
|
708 """ |
|
709 Private method to get the revision of a tag. |
|
710 |
|
711 @param tag tag name |
|
712 @type str |
|
713 @return tuple containing the revision and changeset ID |
|
714 @rtype tuple of (str, str) |
|
715 """ |
|
716 errMsg = "" |
|
717 |
|
718 args = self.vcs.initCommand("tags") |
|
719 |
|
720 output = "" |
|
721 if self.__hgClient: |
|
722 output, errMsg = self.__hgClient.runcommand(args) |
|
723 else: |
|
724 process = QProcess() |
|
725 process.setWorkingDirectory(self.repodir) |
|
726 process.start('hg', args) |
|
727 procStarted = process.waitForStarted(5000) |
|
728 if procStarted: |
|
729 finished = process.waitForFinished(30000) |
|
730 if finished and process.exitCode() == 0: |
|
731 output = str(process.readAllStandardOutput(), |
|
732 self.vcs.getEncoding(), 'replace') |
|
733 else: |
|
734 if not finished: |
|
735 errMsg = self.tr( |
|
736 "The hg process did not finish within 30s.") |
|
737 else: |
|
738 errMsg = self.tr("Could not start the hg executable.") |
|
739 |
|
740 if errMsg: |
|
741 E5MessageBox.critical( |
|
742 self, |
|
743 self.tr("Mercurial Error"), |
|
744 errMsg) |
|
745 |
|
746 res = ("", "") |
|
747 if output: |
|
748 for line in output.splitlines(): |
|
749 name, rev = line.strip().rsplit(None, 1) |
|
750 if name == tag: |
|
751 res = tuple(rev.split(":", 1)) |
|
752 break |
|
753 |
|
754 return res |
|
755 |
703 def __generateLogItem(self, author, date, message, revision, changedPaths, |
756 def __generateLogItem(self, author, date, message, revision, changedPaths, |
704 parents, branches, tags, phase, bookmarks=None): |
757 parents, branches, tags, phase, bookmarks, |
|
758 latestTag): |
705 """ |
759 """ |
706 Private method to generate a log tree entry. |
760 Private method to generate a log tree entry. |
707 |
761 |
708 @param author author info (string) |
762 @param author author info (string) |
709 @param date date info (string) |
763 @param date date info (string) |
714 @param parents list of parent revisions (list of integers) |
768 @param parents list of parent revisions (list of integers) |
715 @param branches list of branches (list of strings) |
769 @param branches list of branches (list of strings) |
716 @param tags list of tags (string) |
770 @param tags list of tags (string) |
717 @param phase phase of the entry (string) |
771 @param phase phase of the entry (string) |
718 @param bookmarks list of bookmarks (string) |
772 @param bookmarks list of bookmarks (string) |
|
773 @param latestTag the latest tag(s) reachable from the changeset |
|
774 (list of strings) |
719 @return reference to the generated item (QTreeWidgetItem) |
775 @return reference to the generated item (QTreeWidgetItem) |
720 """ |
776 """ |
721 logMessageColumnWidth = self.vcs.getPlugin().getPreferences( |
777 logMessageColumnWidth = self.vcs.getPlugin().getPreferences( |
722 "LogMessageColumnWidth") |
778 "LogMessageColumnWidth") |
723 msgtxt = "" |
779 msgtxt = "" |
763 column, color, edges = self.__generateEdges(int(rev), parents) |
819 column, color, edges = self.__generateEdges(int(rev), parents) |
764 |
820 |
765 itm.setData(0, self.__messageRole, message) |
821 itm.setData(0, self.__messageRole, message) |
766 itm.setData(0, self.__changesRole, changedPaths) |
822 itm.setData(0, self.__changesRole, changedPaths) |
767 itm.setData(0, self.__edgesRole, edges) |
823 itm.setData(0, self.__edgesRole, edges) |
|
824 itm.setData(0, self.__latestTagRole, latestTag) |
768 if parents == [-1]: |
825 if parents == [-1]: |
769 itm.setData(0, self.__parentsRole, []) |
826 itm.setData(0, self.__parentsRole, []) |
770 else: |
827 else: |
771 itm.setData(0, self.__parentsRole, parents) |
828 itm.setData(0, self.__parentsRole, parents) |
772 for parent in parents: |
829 for parent in parents: |
1092 log["tags"] = value.strip().split(", ") |
1149 log["tags"] = value.strip().split(", ") |
1093 elif key == "bookmarks": |
1150 elif key == "bookmarks": |
1094 log["bookmarks"] = value.strip().split(", ") |
1151 log["bookmarks"] = value.strip().split(", ") |
1095 elif key == "phase": |
1152 elif key == "phase": |
1096 log["phase"] = value.strip() |
1153 log["phase"] = value.strip() |
|
1154 elif key == "latesttag": |
|
1155 tag = value.strip() |
|
1156 if tag == "null": |
|
1157 log["latesttag"] = [] |
|
1158 elif ":" in tag: |
|
1159 log["latesttag"] = [ |
|
1160 t.strip() for t in tag.split(":") if t.strip()] |
|
1161 else: |
|
1162 log["latesttag"] = [tag] |
1097 else: |
1163 else: |
1098 if initialText: |
1164 if initialText: |
1099 continue |
1165 continue |
1100 if value.strip(): |
1166 if value.strip(): |
1101 log["message"].append(value.strip()) |
1167 log["message"].append(value.strip()) |
1103 if len(log) > 1: |
1169 if len(log) > 1: |
1104 self.__generateLogItem( |
1170 self.__generateLogItem( |
1105 log["author"], log["date"], |
1171 log["author"], log["date"], |
1106 log["message"], log["revision"], changedPaths, |
1172 log["message"], log["revision"], changedPaths, |
1107 log["parents"], log["branches"], log["tags"], |
1173 log["parents"], log["branches"], log["tags"], |
1108 log["phase"], log["bookmarks"]) |
1174 log["phase"], log["bookmarks"], log["latesttag"]) |
1109 dt = QDate.fromString(log["date"], Qt.ISODate) |
1175 dt = QDate.fromString(log["date"], Qt.ISODate) |
1110 if not self.__maxDate.isValid() and \ |
1176 if not self.__maxDate.isValid() and \ |
1111 not self.__minDate.isValid(): |
1177 not self.__minDate.isValid(): |
1112 self.__maxDate = dt |
1178 self.__maxDate = dt |
1113 self.__minDate = dt |
1179 self.__minDate = dt |
1362 if itm.text(self.BookmarksColumn): |
1428 if itm.text(self.BookmarksColumn): |
1363 bookmarksStr = self.__bookmarksTemplate.format( |
1429 bookmarksStr = self.__bookmarksTemplate.format( |
1364 itm.text(self.BookmarksColumn)) |
1430 itm.text(self.BookmarksColumn)) |
1365 else: |
1431 else: |
1366 bookmarksStr = "" |
1432 bookmarksStr = "" |
|
1433 |
|
1434 if itm.data(0, self.__latestTagRole): |
|
1435 latestTagLinks = [] |
|
1436 for tag in itm.data(0, self.__latestTagRole): |
|
1437 url = QUrl() |
|
1438 url.setScheme("rev") |
|
1439 url.setPath(self.__getRevisionOfTag(tag)[0]) |
|
1440 latestTagLinks.append('<a href="{0}">{1}</a>'.format( |
|
1441 url.toString(), tag)) |
|
1442 latestTagStr = self.__latestTagTemplate.format( |
|
1443 ", ".join(latestTagLinks)) |
|
1444 else: |
|
1445 latestTagStr = "" |
|
1446 |
1367 rev = int(itm.text(self.RevisionColumn).split(":", 1)[0]) |
1447 rev = int(itm.text(self.RevisionColumn).split(":", 1)[0]) |
1368 |
1448 |
1369 parentLinks = [] |
1449 parentLinks = [] |
1370 for parent in [str(x) for x in itm.data(0, self.__parentsRole)]: |
1450 for parent in [str(x) for x in itm.data(0, self.__parentsRole)]: |
1371 url = QUrl() |
1451 url = QUrl() |
1388 itm.text(self.AuthorColumn), |
1468 itm.text(self.AuthorColumn), |
1389 itm.text(self.BranchColumn).replace( |
1469 itm.text(self.BranchColumn).replace( |
1390 self.ClosedIndicator, ""), |
1470 self.ClosedIndicator, ""), |
1391 ", ".join(parentLinks), |
1471 ", ".join(parentLinks), |
1392 ", ".join(childLinks), |
1472 ", ".join(childLinks), |
1393 tagsStr + bookmarksStr, |
1473 tagsStr + latestTagStr + bookmarksStr, |
1394 )) |
1474 )) |
1395 |
1475 |
1396 for line in itm.data(0, self.__messageRole): |
1476 for line in itm.data(0, self.__messageRole): |
1397 self.messageEdit.append(line.strip()) |
1477 self.messageEdit.append(line.strip()) |
1398 |
1478 |
1432 @pyqtSlot() |
1512 @pyqtSlot() |
1433 def on_logTree_itemSelectionChanged(self): |
1513 def on_logTree_itemSelectionChanged(self): |
1434 """ |
1514 """ |
1435 Private slot called, when the selection has changed. |
1515 Private slot called, when the selection has changed. |
1436 """ |
1516 """ |
1437 if len(self.logTree.selectedItems()) == 1: |
|
1438 self.__updateGui(self.logTree.selectedItems()[0]) |
|
1439 |
|
1440 self.__updateDiffButtons() |
1517 self.__updateDiffButtons() |
1441 self.__updateToolMenuActions() |
1518 self.__updateToolMenuActions() |
1442 |
1519 |
1443 @pyqtSlot() |
1520 @pyqtSlot() |
1444 def on_upButton_clicked(self): |
1521 def on_upButton_clicked(self): |