10 |
10 |
11 import os |
11 import os |
12 import re |
12 import re |
13 import collections |
13 import collections |
14 |
14 |
15 from PyQt5.QtCore import pyqtSlot, Qt, QDate, QProcess, QTimer, QRegExp, \ |
15 from PyQt5.QtCore import ( |
16 QSize, QPoint, QFileInfo |
16 pyqtSlot, Qt, QDate, QProcess, QTimer, QRegExp, QSize, QPoint, QFileInfo |
17 from PyQt5.QtGui import QCursor, QColor, QPixmap, QPainter, QPen, QBrush, \ |
17 ) |
18 QIcon, QTextCursor |
18 from PyQt5.QtGui import ( |
19 from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QHeaderView, \ |
19 QCursor, QColor, QPixmap, QPainter, QPen, QBrush, QIcon, QTextCursor |
20 QTreeWidgetItem, QApplication, QLineEdit, QMenu, QInputDialog |
20 ) |
|
21 from PyQt5.QtWidgets import ( |
|
22 QWidget, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QApplication, |
|
23 QLineEdit, QMenu, QInputDialog |
|
24 ) |
21 |
25 |
22 from E5Gui.E5Application import e5App |
26 from E5Gui.E5Application import e5App |
23 from E5Gui import E5MessageBox, E5FileDialog |
27 from E5Gui import E5MessageBox, E5FileDialog |
24 |
28 |
25 from .Ui_HgLogBrowserDialog import Ui_HgLogBrowserDialog |
29 from .Ui_HgLogBrowserDialog import Ui_HgLogBrowserDialog |
428 """ |
432 """ |
429 if self.__hgClient: |
433 if self.__hgClient: |
430 if self.__hgClient.isExecuting(): |
434 if self.__hgClient.isExecuting(): |
431 self.__hgClient.cancel() |
435 self.__hgClient.cancel() |
432 else: |
436 else: |
433 if self.process is not None and \ |
437 if ( |
434 self.process.state() != QProcess.NotRunning: |
438 self.process is not None and |
|
439 self.process.state() != QProcess.NotRunning |
|
440 ): |
435 self.process.terminate() |
441 self.process.terminate() |
436 QTimer.singleShot(2000, self.process.kill) |
442 QTimer.singleShot(2000, self.process.kill) |
437 self.process.waitForFinished(3000) |
443 self.process.waitForFinished(3000) |
438 |
444 |
439 self.vcs.getPlugin().setPreferences( |
445 self.vcs.getPlugin().setPreferences( |
735 args = self.vcs.initCommand("parents") |
741 args = self.vcs.initCommand("parents") |
736 if self.commandMode == "incoming": |
742 if self.commandMode == "incoming": |
737 if self.__bundle: |
743 if self.__bundle: |
738 args.append("--repository") |
744 args.append("--repository") |
739 args.append(self.__bundle) |
745 args.append(self.__bundle) |
740 elif self.vcs.bundleFile and \ |
746 elif ( |
741 os.path.exists(self.vcs.bundleFile): |
747 self.vcs.bundleFile and |
|
748 os.path.exists(self.vcs.bundleFile) |
|
749 ): |
742 args.append("--repository") |
750 args.append("--repository") |
743 args.append(self.vcs.bundleFile) |
751 args.append(self.vcs.bundleFile) |
744 args.append("--template") |
752 args.append("--template") |
745 args.append("{rev}\n") |
753 args.append("{rev}\n") |
746 args.append("-r") |
754 args.append("-r") |
1042 for parent in parents: |
1050 for parent in parents: |
1043 self.__childrenInfo[parent].append(int(rev)) |
1051 self.__childrenInfo[parent].append(int(rev)) |
1044 itm.setData(0, self.__incomingRole, self.commandMode == "incoming") |
1052 itm.setData(0, self.__incomingRole, self.commandMode == "incoming") |
1045 |
1053 |
1046 if self.logTree.topLevelItemCount() > 1: |
1054 if self.logTree.topLevelItemCount() > 1: |
1047 topedges = \ |
1055 topedges = self.logTree.topLevelItem( |
1048 self.logTree.topLevelItem( |
1056 self.logTree.indexOfTopLevelItem(itm) - 1 |
1049 self.logTree.indexOfTopLevelItem(itm) - 1)\ |
1057 ).data(0, self.__edgesRole) |
1050 .data(0, self.__edgesRole) |
|
1051 else: |
1058 else: |
1052 topedges = None |
1059 topedges = None |
1053 |
1060 |
1054 icon = self.__generateIcon(column, color, edges, topedges, |
1061 icon = self.__generateIcon(column, color, edges, topedges, |
1055 QColor(self.__branchColor(branches[0])), |
1062 QColor(self.__branchColor(branches[0])), |
1099 if self.vcs.hasSubrepositories(): |
1106 if self.vcs.hasSubrepositories(): |
1100 args.append("--subrepos") |
1107 args.append("--subrepos") |
1101 if startRev is not None: |
1108 if startRev is not None: |
1102 args.append('--rev') |
1109 args.append('--rev') |
1103 args.append('{0}:0'.format(startRev)) |
1110 args.append('{0}:0'.format(startRev)) |
1104 if not self.projectMode and \ |
1111 if ( |
1105 not self.fname == "." and \ |
1112 not self.projectMode and |
1106 not self.stopCheckBox.isChecked(): |
1113 not self.fname == "." and |
|
1114 not self.stopCheckBox.isChecked() |
|
1115 ): |
1107 args.append('--follow') |
1116 args.append('--follow') |
1108 if self.commandMode == "log": |
1117 if self.commandMode == "log": |
1109 args.append('--copies') |
1118 args.append('--copies') |
1110 args.append('--template') |
1119 args.append('--template') |
1111 args.append(os.path.join(os.path.dirname(__file__), |
1120 args.append(os.path.join(os.path.dirname(__file__), |
1135 if preargs: |
1144 if preargs: |
1136 out, err = self.__hgClient.runcommand(preargs) |
1145 out, err = self.__hgClient.runcommand(preargs) |
1137 else: |
1146 else: |
1138 err = "" |
1147 err = "" |
1139 if err: |
1148 if err: |
1140 if self.commandMode == "incoming" and \ |
1149 if ( |
1141 self.initialCommandMode == "full_log": |
1150 self.commandMode == "incoming" and |
|
1151 self.initialCommandMode == "full_log" |
|
1152 ): |
1142 # ignore the error |
1153 # ignore the error |
1143 self.commandMode = "log" |
1154 self.commandMode = "log" |
1144 else: |
1155 else: |
1145 self.__showError(err) |
1156 self.__showError(err) |
1146 elif self.commandMode != "incoming" or \ |
1157 elif ( |
|
1158 self.commandMode != "incoming" or |
1147 (self.vcs.bundleFile and |
1159 (self.vcs.bundleFile and |
1148 os.path.exists(self.vcs.bundleFile)) or \ |
1160 os.path.exists(self.vcs.bundleFile)) or |
1149 self.__bundle: |
1161 self.__bundle |
|
1162 ): |
1150 out, err = self.__hgClient.runcommand(args) |
1163 out, err = self.__hgClient.runcommand(args) |
1151 self.buf = out.splitlines(True) |
1164 self.buf = out.splitlines(True) |
1152 if err: |
1165 if err: |
1153 self.__showError(err) |
1166 self.__showError(err) |
1154 self.__processBuffer() |
1167 self.__processBuffer() |
1155 elif self.commandMode == "incoming" and \ |
1168 elif ( |
1156 self.initialCommandMode == "full_log": |
1169 self.commandMode == "incoming" and |
|
1170 self.initialCommandMode == "full_log" |
|
1171 ): |
1157 # no incoming changesets, just switch to log mode |
1172 # no incoming changesets, just switch to log mode |
1158 self.commandMode = "log" |
1173 self.commandMode = "log" |
1159 self.__finish() |
1174 self.__finish() |
1160 else: |
1175 else: |
1161 self.process.kill() |
1176 self.process.kill() |
1168 process.start('hg', args) |
1183 process.start('hg', args) |
1169 procStarted = process.waitForStarted(5000) |
1184 procStarted = process.waitForStarted(5000) |
1170 if procStarted: |
1185 if procStarted: |
1171 process.waitForFinished(30000) |
1186 process.waitForFinished(30000) |
1172 |
1187 |
1173 if self.commandMode != "incoming" or \ |
1188 if ( |
|
1189 self.commandMode != "incoming" or |
1174 (self.vcs.bundleFile and |
1190 (self.vcs.bundleFile and |
1175 os.path.exists(self.vcs.bundleFile)) or \ |
1191 os.path.exists(self.vcs.bundleFile)) or |
1176 self.__bundle: |
1192 self.__bundle |
|
1193 ): |
1177 self.process.start('hg', args) |
1194 self.process.start('hg', args) |
1178 procStarted = self.process.waitForStarted(5000) |
1195 procStarted = self.process.waitForStarted(5000) |
1179 if not procStarted: |
1196 if not procStarted: |
1180 self.inputGroup.setEnabled(False) |
1197 self.inputGroup.setEnabled(False) |
1181 self.inputGroup.hide() |
1198 self.inputGroup.hide() |
1253 def __finish(self): |
1270 def __finish(self): |
1254 """ |
1271 """ |
1255 Private slot called when the process finished or the user pressed |
1272 Private slot called when the process finished or the user pressed |
1256 the button. |
1273 the button. |
1257 """ |
1274 """ |
1258 if self.process is not None and \ |
1275 if ( |
1259 self.process.state() != QProcess.NotRunning: |
1276 self.process is not None and |
|
1277 self.process.state() != QProcess.NotRunning |
|
1278 ): |
1260 self.process.terminate() |
1279 self.process.terminate() |
1261 QTimer.singleShot(2000, self.process.kill) |
1280 QTimer.singleShot(2000, self.process.kill) |
1262 self.process.waitForFinished(3000) |
1281 self.process.waitForFinished(3000) |
1263 |
1282 |
1264 QApplication.restoreOverrideCursor() |
1283 QApplication.restoreOverrideCursor() |
1307 initialText = False |
1326 initialText = False |
1308 log["revision"] = value.strip() |
1327 log["revision"] = value.strip() |
1309 elif key == "user": |
1328 elif key == "user": |
1310 log["author"] = value.strip() |
1329 log["author"] = value.strip() |
1311 elif key == "parents": |
1330 elif key == "parents": |
1312 log["parents"] = \ |
1331 log["parents"] = [ |
1313 [int(x.split(":", 1)[0]) |
1332 int(x.split(":", 1)[0]) |
1314 for x in value.strip().split()] |
1333 for x in value.strip().split() |
|
1334 ] |
1315 elif key == "date": |
1335 elif key == "date": |
1316 log["date"] = " ".join(value.strip().split()[:2]) |
1336 log["date"] = " ".join(value.strip().split()[:2]) |
1317 elif key == "description": |
1337 elif key == "description": |
1318 log["message"].append(value.strip()) |
1338 log["message"].append(value.strip()) |
1319 elif key == "file_adds": |
1339 elif key == "file_adds": |
1384 log["author"], log["date"], |
1404 log["author"], log["date"], |
1385 log["message"], log["revision"], changedPaths, |
1405 log["message"], log["revision"], changedPaths, |
1386 log["parents"], log["branches"], log["tags"], |
1406 log["parents"], log["branches"], log["tags"], |
1387 log["phase"], log["bookmarks"], log["latesttag"]) |
1407 log["phase"], log["bookmarks"], log["latesttag"]) |
1388 dt = QDate.fromString(log["date"], Qt.ISODate) |
1408 dt = QDate.fromString(log["date"], Qt.ISODate) |
1389 if not self.__maxDate.isValid() and \ |
1409 if ( |
1390 not self.__minDate.isValid(): |
1410 not self.__maxDate.isValid() and |
|
1411 not self.__minDate.isValid() |
|
1412 ): |
1391 self.__maxDate = dt |
1413 self.__maxDate = dt |
1392 self.__minDate = dt |
1414 self.__minDate = dt |
1393 else: |
1415 else: |
1394 if self.__maxDate < dt: |
1416 if self.__maxDate < dt: |
1395 self.__maxDate = dt |
1417 self.__maxDate = dt |
1538 self.sbsSelectLabel.clear() |
1560 self.sbsSelectLabel.clear() |
1539 if self.__isFile: |
1561 if self.__isFile: |
1540 selectedItems = self.logTree.selectedItems() |
1562 selectedItems = self.logTree.selectedItems() |
1541 if len(selectedItems) == 1: |
1563 if len(selectedItems) == 1: |
1542 currentItem = selectedItems[0] |
1564 currentItem = selectedItems[0] |
1543 rev2 = currentItem.text(self.RevisionColumn).split(":", 1)[0]\ |
1565 rev2 = ( |
|
1566 currentItem.text(self.RevisionColumn).split(":", 1)[0] |
1544 .strip() |
1567 .strip() |
|
1568 ) |
1545 parents = currentItem.data(0, self.__parentsRole) |
1569 parents = currentItem.data(0, self.__parentsRole) |
1546 if parents: |
1570 if parents: |
1547 parentLinks = [] |
1571 parentLinks = [] |
1548 for index in range(len(parents)): |
1572 for index in range(len(parents)): |
1549 parentLinks.append( |
1573 parentLinks.append( |
1585 secret += 1 |
1609 secret += 1 |
1586 else: |
1610 else: |
1587 public += 1 |
1611 public += 1 |
1588 |
1612 |
1589 # step 2: set the status of the phase action |
1613 # step 2: set the status of the phase action |
1590 if public == 0 and \ |
1614 if ( |
1591 ((secret > 0 and draft == 0) or |
1615 public == 0 and |
1592 (secret == 0 and draft > 0)): |
1616 ((secret > 0 and draft == 0) or |
|
1617 (secret == 0 and draft > 0)) |
|
1618 ): |
1593 self.__phaseAct.setEnabled(True) |
1619 self.__phaseAct.setEnabled(True) |
1594 else: |
1620 else: |
1595 self.__phaseAct.setEnabled(False) |
1621 self.__phaseAct.setEnabled(False) |
1596 |
1622 |
1597 # do the graft action |
1623 # do the graft action |
1766 self.__diffUpdatesFiles = True |
1792 self.__diffUpdatesFiles = True |
1767 index1 = self.logTree.indexOfTopLevelItem(selectedItems[0]) |
1793 index1 = self.logTree.indexOfTopLevelItem(selectedItems[0]) |
1768 index2 = self.logTree.indexOfTopLevelItem(selectedItems[1]) |
1794 index2 = self.logTree.indexOfTopLevelItem(selectedItems[1]) |
1769 if index1 > index2: |
1795 if index1 > index2: |
1770 # Swap the entries |
1796 # Swap the entries |
1771 selectedItems[0], selectedItems[1] = \ |
1797 selectedItems[0], selectedItems[1] = ( |
1772 selectedItems[1], selectedItems[0] |
1798 selectedItems[1], selectedItems[0] |
|
1799 ) |
1773 html = "{0}<hr/>{1}".format( |
1800 html = "{0}<hr/>{1}".format( |
1774 self.__generateDetailsTableText(selectedItems[0]), |
1801 self.__generateDetailsTableText(selectedItems[0]), |
1775 self.__generateDetailsTableText(selectedItems[1]), |
1802 self.__generateDetailsTableText(selectedItems[1]), |
1776 ) |
1803 ) |
1777 self.detailsEdit.setHtml(html) |
1804 self.detailsEdit.setHtml(html) |
2026 else: |
2053 else: |
2027 # Find based on complete message text |
2054 # Find based on complete message text |
2028 txt = "\n".join(topItem.data(0, self.__messageRole)) |
2055 txt = "\n".join(topItem.data(0, self.__messageRole)) |
2029 else: |
2056 else: |
2030 txt = topItem.text(fieldIndex) |
2057 txt = topItem.text(fieldIndex) |
2031 if topItem.text(self.DateColumn) <= to_ and \ |
2058 if ( |
2032 topItem.text(self.DateColumn) >= from_ and \ |
2059 topItem.text(self.DateColumn) <= to_ and |
2033 (branch == self.__allBranchesFilter or |
2060 topItem.text(self.DateColumn) >= from_ and |
2034 topItem.text(self.BranchColumn) in |
2061 (branch == self.__allBranchesFilter or |
2035 [branch, closedBranch]) and \ |
2062 topItem.text(self.BranchColumn) in |
2036 searchRx.indexIn(txt) > -1: |
2063 [branch, closedBranch]) and |
|
2064 searchRx.indexIn(txt) > -1 |
|
2065 ): |
2037 topItem.setHidden(False) |
2066 topItem.setHidden(False) |
2038 if topItem is currentItem: |
2067 if topItem is currentItem: |
2039 self.on_logTree_currentItemChanged(topItem, None) |
2068 self.on_logTree_currentItemChanged(topItem, None) |
2040 else: |
2069 else: |
2041 topItem.setHidden(True) |
2070 topItem.setHidden(True) |
2315 Private slot to bookmark the selected revision. |
2344 Private slot to bookmark the selected revision. |
2316 """ |
2345 """ |
2317 if len([itm for itm in self.logTree.selectedItems() |
2346 if len([itm for itm in self.logTree.selectedItems() |
2318 if not itm.data(0, self.__incomingRole)]) == 1: |
2347 if not itm.data(0, self.__incomingRole)]) == 1: |
2319 itm = self.logTree.selectedItems()[0] |
2348 itm = self.logTree.selectedItems()[0] |
2320 rev, changeset = \ |
2349 rev, changeset = ( |
2321 itm.text(self.RevisionColumn).strip().split(":", 1) |
2350 itm.text(self.RevisionColumn).strip().split(":", 1) |
|
2351 ) |
2322 bookmark, ok = QInputDialog.getText( |
2352 bookmark, ok = QInputDialog.getText( |
2323 self, |
2353 self, |
2324 self.tr("Define Bookmark"), |
2354 self.tr("Define Bookmark"), |
2325 self.tr('Enter bookmark name for changeset "{0}":').format( |
2355 self.tr('Enter bookmark name for changeset "{0}":').format( |
2326 changeset), |
2356 changeset), |
2337 Private slot to move a bookmark to the selected revision. |
2367 Private slot to move a bookmark to the selected revision. |
2338 """ |
2368 """ |
2339 if len([itm for itm in self.logTree.selectedItems() |
2369 if len([itm for itm in self.logTree.selectedItems() |
2340 if not itm.data(0, self.__incomingRole)]) == 1: |
2370 if not itm.data(0, self.__incomingRole)]) == 1: |
2341 itm = self.logTree.selectedItems()[0] |
2371 itm = self.logTree.selectedItems()[0] |
2342 rev, changeset = \ |
2372 rev, changeset = ( |
2343 itm.text(self.RevisionColumn).strip().split(":", 1) |
2373 itm.text(self.RevisionColumn).strip().split(":", 1) |
|
2374 ) |
2344 bookmarksList = self.vcs.hgGetBookmarksList(self.repodir) |
2375 bookmarksList = self.vcs.hgGetBookmarksList(self.repodir) |
2345 bookmark, ok = QInputDialog.getItem( |
2376 bookmark, ok = QInputDialog.getItem( |
2346 self, |
2377 self, |
2347 self.tr("Move Bookmark"), |
2378 self.tr("Move Bookmark"), |
2348 self.tr('Select the bookmark to be moved to changeset' |
2379 self.tr('Select the bookmark to be moved to changeset' |