Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py

changeset 4059
15b78ac687fb
parent 4021
195a471c327b
child 4060
6dc9821fc9c8
equal deleted inserted replaced
4058:99ec13e695f9 4059:15b78ac687fb
84 self.tr("&Refresh"), QDialogButtonBox.ActionRole) 84 self.tr("&Refresh"), QDialogButtonBox.ActionRole)
85 self.refreshButton.setToolTip( 85 self.refreshButton.setToolTip(
86 self.tr("Press to refresh the list of changesets")) 86 self.tr("Press to refresh the list of changesets"))
87 self.refreshButton.setEnabled(False) 87 self.refreshButton.setEnabled(False)
88 88
89 self.findPrevButton.setIcon(UI.PixmapCache.getIcon("1leftarrow.png"))
90 self.findNextButton.setIcon(UI.PixmapCache.getIcon("1rightarrow.png"))
91 self.__findBackwards = False
92
93 self.modeComboBox.addItem(self.tr("Find"), "find")
94 self.modeComboBox.addItem(self.tr("Filter"), "filter")
95
96 self.fieldCombo.addItem(self.tr("Revision"), "revision")
97 self.fieldCombo.addItem(self.tr("Author"), "author")
98 self.fieldCombo.addItem(self.tr("Message"), "message")
99
89 self.vcs = vcs 100 self.vcs = vcs
90 if mode in ("log", "incoming", "outgoing"): 101 if mode in ("log", "incoming", "outgoing"):
91 self.commandMode = mode 102 self.commandMode = mode
92 self.initialCommandMode = mode 103 self.initialCommandMode = mode
93 else: 104 else:
99 "<table>" 110 "<table>"
100 "<tr><td><b>Revision</b></td><td>{0}</td></tr>" 111 "<tr><td><b>Revision</b></td><td>{0}</td></tr>"
101 "<tr><td><b>Date</b></td><td>{1}</td></tr>" 112 "<tr><td><b>Date</b></td><td>{1}</td></tr>"
102 "<tr><td><b>Author</b></td><td>{2}</td></tr>" 113 "<tr><td><b>Author</b></td><td>{2}</td></tr>"
103 "<tr><td><b>Branch</b></td><td>{3}</td></tr>" 114 "<tr><td><b>Branch</b></td><td>{3}</td></tr>"
104 "<tr><td><b>Tags</b></td><td>{4}</td></tr>" 115 "<tr><td><b>Parents</b></td><td>{4}</td></tr>"
105 "<tr><td><b>Bookmarks</b></td><td>{5}</td></tr>" 116 "{5}"
106 "<tr><td><b>Parents</b></td><td>{6}</td></tr>"
107 "</table>" 117 "</table>"
118 )
119 self.__tagsTemplate = self.tr(
120 "<tr><td><b>Tags</b></td><td>{0}</td></tr>"
121 )
122 self.__bookmarksTemplate = self.tr(
123 "<tr><td><b>Bookmarks</b></td><td>{0}</td></tr>"
108 ) 124 )
109 125
110 self.__bundle = "" 126 self.__bundle = ""
111 self.__filename = "" 127 self.__filename = ""
112 self.__isFile = False 128 self.__isFile = False
251 Private method to reset the user interface. 267 Private method to reset the user interface.
252 """ 268 """
253 self.branchCombo.clear() 269 self.branchCombo.clear()
254 self.fromDate.setDate(QDate.currentDate()) 270 self.fromDate.setDate(QDate.currentDate())
255 self.toDate.setDate(QDate.currentDate()) 271 self.toDate.setDate(QDate.currentDate())
256 self.fieldCombo.setCurrentIndex(self.fieldCombo.findText( 272 self.fieldCombo.setCurrentIndex(self.fieldCombo.findData("message"))
257 self.tr("Message")))
258 self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences( 273 self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences(
259 "LogLimit")) 274 "LogLimit"))
260 self.stopCheckBox.setChecked(self.vcs.getPlugin().getPreferences( 275 self.stopCheckBox.setChecked(self.vcs.getPlugin().getPreferences(
261 "StopLogOnCopy")) 276 "StopLogOnCopy"))
262 277
1049 [self.__allBranchesFilter] + sorted(self.__branchColors.keys())) 1064 [self.__allBranchesFilter] + sorted(self.__branchColors.keys()))
1050 self.branchCombo.setCurrentIndex( 1065 self.branchCombo.setCurrentIndex(
1051 self.branchCombo.findText(branchFilter)) 1066 self.branchCombo.findText(branchFilter))
1052 1067
1053 self.__filterLogsEnabled = True 1068 self.__filterLogsEnabled = True
1054 self.__filterLogs() 1069 if self.__actionMode() == "filter":
1055 1070 self.__filterLogs()
1056 self.__updateDiffButtons() 1071 self.__updateDiffButtons()
1057 self.__updateToolMenuActions() 1072 self.__updateToolMenuActions()
1058 1073
1059 # restore current item 1074 # restore current item
1060 if self.__currentRevision: 1075 if self.__currentRevision:
1225 self.detailsEdit.clear() 1240 self.detailsEdit.clear()
1226 self.messageEdit.clear() 1241 self.messageEdit.clear()
1227 self.filesTree.clear() 1242 self.filesTree.clear()
1228 1243
1229 if itm is not None: 1244 if itm is not None:
1245 if itm.text(self.TagsColumn):
1246 tagsStr = self.__tagsTemplate.format(itm.text(self.TagsColumn))
1247 else:
1248 tagsStr = ""
1249 if itm.text(self.BookmarksColumn):
1250 bookmarksStr = self.__bookmarksTemplate.format(
1251 itm.text(self.BookmarksColumn))
1252 else:
1253 bookmarksStr = ""
1230 self.detailsEdit.setHtml(self.__detailsTemplate.format( 1254 self.detailsEdit.setHtml(self.__detailsTemplate.format(
1231 itm.text(self.RevisionColumn), 1255 itm.text(self.RevisionColumn),
1232 itm.text(self.DateColumn), 1256 itm.text(self.DateColumn),
1233 itm.text(self.AuthorColumn), 1257 itm.text(self.AuthorColumn),
1234 itm.text(self.BranchColumn).replace( 1258 itm.text(self.BranchColumn).replace(
1235 self.ClosedIndicator, ""), 1259 self.ClosedIndicator, ""),
1236 itm.text(self.TagsColumn),
1237 itm.text(self.BookmarksColumn),
1238 ", ".join( 1260 ", ".join(
1239 [str(x) for x in itm.data(0, self.__parentsRole)] 1261 [str(x) for x in itm.data(0, self.__parentsRole)]
1240 ), 1262 ),
1263 tagsStr + bookmarksStr,
1241 )) 1264 ))
1242 1265
1243 for line in itm.data(0, self.__messageRole): 1266 for line in itm.data(0, self.__messageRole):
1244 self.messageEdit.append(line.strip()) 1267 self.messageEdit.append(line.strip())
1245 1268
1341 """ 1364 """
1342 Private slot called, when the from date changes. 1365 Private slot called, when the from date changes.
1343 1366
1344 @param date new date (QDate) 1367 @param date new date (QDate)
1345 """ 1368 """
1346 self.__filterLogs() 1369 if self.__actionMode() == "filter":
1370 self.__filterLogs()
1347 1371
1348 @pyqtSlot(QDate) 1372 @pyqtSlot(QDate)
1349 def on_toDate_dateChanged(self, date): 1373 def on_toDate_dateChanged(self, date):
1350 """ 1374 """
1351 Private slot called, when the from date changes. 1375 Private slot called, when the from date changes.
1352 1376
1353 @param date new date (QDate) 1377 @param date new date (QDate)
1354 """ 1378 """
1355 self.__filterLogs() 1379 if self.__actionMode() == "filter":
1380 self.__filterLogs()
1356 1381
1357 @pyqtSlot(str) 1382 @pyqtSlot(str)
1358 def on_branchCombo_activated(self, txt): 1383 def on_branchCombo_activated(self, txt):
1359 """ 1384 """
1360 Private slot called, when a new branch is selected. 1385 Private slot called, when a new branch is selected.
1361 1386
1362 @param txt text of the selected branch (string) 1387 @param txt text of the selected branch (string)
1363 """ 1388 """
1364 self.__filterLogs() 1389 if self.__actionMode() == "filter":
1390 self.__filterLogs()
1365 1391
1366 @pyqtSlot(str) 1392 @pyqtSlot(str)
1367 def on_fieldCombo_activated(self, txt): 1393 def on_fieldCombo_activated(self, txt):
1368 """ 1394 """
1369 Private slot called, when a new filter field is selected. 1395 Private slot called, when a new filter field is selected.
1370 1396
1371 @param txt text of the selected field (string) 1397 @param txt text of the selected field (string)
1372 """ 1398 """
1373 self.__filterLogs() 1399 if self.__actionMode() == "filter":
1400 self.__filterLogs()
1374 1401
1375 @pyqtSlot(str) 1402 @pyqtSlot(str)
1376 def on_rxEdit_textChanged(self, txt): 1403 def on_rxEdit_textChanged(self, txt):
1377 """ 1404 """
1378 Private slot called, when a filter expression is entered. 1405 Private slot called, when a filter expression is entered.
1379 1406
1380 @param txt filter expression (string) 1407 @param txt filter expression (string)
1381 """ 1408 """
1382 self.__filterLogs() 1409 if self.__actionMode() == "filter":
1410 self.__filterLogs()
1411 elif self.__actionMode() == "find":
1412 self.__findItem(self.__findBackwards, interactive=True)
1413
1414 @pyqtSlot()
1415 def on_rxEdit_returnPressed(self):
1416 """
1417 Private slot handling a press of the Return key in the rxEdit input.
1418 """
1419 if self.__actionMode() == "find":
1420 self.__findItem(self.__findBackwards, interactive=True)
1383 1421
1384 def __filterLogs(self): 1422 def __filterLogs(self):
1385 """ 1423 """
1386 Private method to filter the log entries. 1424 Private method to filter the log entries.
1387 """ 1425 """
1388 if self.__filterLogsEnabled: 1426 if self.__filterLogsEnabled:
1389 from_ = self.fromDate.date().toString("yyyy-MM-dd") 1427 from_ = self.fromDate.date().toString("yyyy-MM-dd")
1390 to_ = self.toDate.date().addDays(1).toString("yyyy-MM-dd") 1428 to_ = self.toDate.date().addDays(1).toString("yyyy-MM-dd")
1391 branch = self.branchCombo.currentText() 1429 branch = self.branchCombo.currentText()
1392 closedBranch = branch + '--' 1430 closedBranch = branch + '--'
1393 1431 fieldIndex, searchRx = self.__prepareFieldSearch()
1394 txt = self.fieldCombo.currentText() 1432
1395 if txt == self.tr("Author"): 1433 ## txt = self.fieldCombo.currentText()
1396 fieldIndex = self.AuthorColumn 1434 ## if txt == self.tr("Author"):
1397 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) 1435 ## fieldIndex = self.AuthorColumn
1398 elif txt == self.tr("Revision"): 1436 ## searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
1399 fieldIndex = self.RevisionColumn 1437 ## elif txt == self.tr("Revision"):
1400 txt = self.rxEdit.text() 1438 ## fieldIndex = self.RevisionColumn
1401 if txt.startswith("^"): 1439 ## txt = self.rxEdit.text()
1402 searchRx = QRegExp("^\s*{0}".format(txt[1:]), 1440 ## if txt.startswith("^"):
1403 Qt.CaseInsensitive) 1441 ## searchRx = QRegExp("^\s*{0}".format(txt[1:]),
1404 else: 1442 ## Qt.CaseInsensitive)
1405 searchRx = QRegExp(txt, Qt.CaseInsensitive) 1443 ## else:
1406 else: 1444 ## searchRx = QRegExp(txt, Qt.CaseInsensitive)
1407 fieldIndex = self.MessageColumn 1445 ## else:
1408 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive) 1446 ## fieldIndex = self.MessageColumn
1409 1447 ## searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
1448 ##
1449 visibleItemCount = self.logTree.topLevelItemCount()
1410 currentItem = self.logTree.currentItem() 1450 currentItem = self.logTree.currentItem()
1411 for topIndex in range(self.logTree.topLevelItemCount()): 1451 for topIndex in range(self.logTree.topLevelItemCount()):
1412 topItem = self.logTree.topLevelItem(topIndex) 1452 topItem = self.logTree.topLevelItem(topIndex)
1453 if fieldIndex == self.MessageColumn:
1454 # Find based on complete message text
1455 txt = "\n".join(topItem.data(0, self.__messageRole))
1456 else:
1457 txt = topItem.text(fieldIndex)
1413 if topItem.text(self.DateColumn) <= to_ and \ 1458 if topItem.text(self.DateColumn) <= to_ and \
1414 topItem.text(self.DateColumn) >= from_ and \ 1459 topItem.text(self.DateColumn) >= from_ and \
1415 (branch == self.__allBranchesFilter or 1460 (branch == self.__allBranchesFilter or
1416 topItem.text(self.BranchColumn) in 1461 topItem.text(self.BranchColumn) in
1417 [branch, closedBranch]) and \ 1462 [branch, closedBranch]) and \
1418 searchRx.indexIn(topItem.text(fieldIndex)) > -1: 1463 searchRx.indexIn(txt) > -1:
1419 topItem.setHidden(False) 1464 topItem.setHidden(False)
1420 if topItem is currentItem: 1465 if topItem is currentItem:
1421 self.on_logTree_currentItemChanged(topItem, None) 1466 self.on_logTree_currentItemChanged(topItem, None)
1422 else: 1467 else:
1423 topItem.setHidden(True) 1468 topItem.setHidden(True)
1424 if topItem is currentItem: 1469 if topItem is currentItem:
1425 self.messageEdit.clear() 1470 self.messageEdit.clear()
1426 self.filesTree.clear() 1471 self.filesTree.clear()
1472 visibleItemCount -= 1
1473 self.logTree.header().setSectionHidden(
1474 self.IconColumn,
1475 visibleItemCount != self.logTree.topLevelItemCount())
1476
1477 def __prepareFieldSearch(self):
1478 """
1479 Private slot to prepare the filed search data.
1480
1481 @return tuple of field index and search expression (integer, string)
1482 """
1483 txt = self.fieldCombo.itemData(self.fieldCombo.currentIndex())
1484 if txt == "author":
1485 fieldIndex = self.AuthorColumn
1486 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
1487 elif txt == "revision":
1488 fieldIndex = self.RevisionColumn
1489 txt = self.rxEdit.text()
1490 if txt.startswith("^"):
1491 searchRx = QRegExp("^\s*{0}".format(txt[1:]),
1492 Qt.CaseInsensitive)
1493 else:
1494 searchRx = QRegExp(txt, Qt.CaseInsensitive)
1495 else:
1496 fieldIndex = self.MessageColumn
1497 searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
1498
1499 return fieldIndex, searchRx
1427 1500
1428 @pyqtSlot(bool) 1501 @pyqtSlot(bool)
1429 def on_stopCheckBox_clicked(self, checked): 1502 def on_stopCheckBox_clicked(self, checked):
1430 """ 1503 """
1431 Private slot called, when the stop on copy/move checkbox is clicked. 1504 Private slot called, when the stop on copy/move checkbox is clicked.
1621 revs.append(rev) 1694 revs.append(rev)
1622 1695
1623 if revs: 1696 if revs:
1624 self.vcs.getExtensionObject("largefiles").hgLfPull( 1697 self.vcs.getExtensionObject("largefiles").hgLfPull(
1625 self.repodir, revisions=revs) 1698 self.repodir, revisions=revs)
1699
1700 def __actionMode(self):
1701 """
1702 Private method to get the selected action mode.
1703
1704 @return selected action mode (string, one of filter or find)
1705 """
1706 return self.modeComboBox.itemData(
1707 self.modeComboBox.currentIndex())
1708
1709 @pyqtSlot(int)
1710 def on_modeComboBox_currentIndexChanged(self, index):
1711 """
1712 Private slot to react on mode changes.
1713 """
1714 mode = self.modeComboBox.itemData(index)
1715 findMode = mode == "find"
1716 filterMode = mode == "filter"
1717
1718 self.fromDate.setEnabled(filterMode)
1719 self.toDate.setEnabled(filterMode)
1720 self.branchCombo.setEnabled(filterMode)
1721 self.findPrevButton.setVisible(findMode)
1722 self.findNextButton.setVisible(findMode)
1723
1724 if findMode:
1725 for topIndex in range(self.logTree.topLevelItemCount()):
1726 self.logTree.topLevelItem(topIndex).setHidden(False)
1727 self.logTree.header().setSectionHidden(self.IconColumn, False)
1728 elif filterMode:
1729 self.__filterLogs()
1730
1731 @pyqtSlot()
1732 def on_findPrevButton_clicked(self):
1733 """
1734 Private slot to find the previous item matching the entered criteria.
1735 """
1736 self.__findItem(True)
1737
1738 @pyqtSlot()
1739 def on_findNextButton_clicked(self):
1740 """
1741 Private slot to find the next item matching the entered criteria.
1742 """
1743 self.__findItem(False)
1744
1745 def __findItem(self, backwards=False, interactive=False):
1746 """
1747 Private slot to find an item matching the entered criteria.
1748
1749 @param backwards flag indicating to search backwards (boolean)
1750 @param interactive flag indicating an interactive search (boolean)
1751 """
1752 self.__findBackwards = backwards
1753
1754 fieldIndex, searchRx = self.__prepareFieldSearch()
1755 currentIndex = self.logTree.indexOfTopLevelItem(
1756 self.logTree.currentItem())
1757 if backwards:
1758 if interactive:
1759 indexes = range(currentIndex, -1, -1)
1760 else:
1761 indexes = range(currentIndex - 1, -1, -1)
1762 else:
1763 if interactive:
1764 indexes = range(currentIndex, self.logTree.topLevelItemCount())
1765 else:
1766 indexes = range(currentIndex + 1,
1767 self.logTree.topLevelItemCount())
1768
1769 for index in indexes:
1770 topItem = self.logTree.topLevelItem(index)
1771 if fieldIndex == self.MessageColumn:
1772 # Find based on complete message text
1773 txt = "\n".join(topItem.data(0, self.__messageRole))
1774 else:
1775 txt = topItem.text(fieldIndex)
1776 if searchRx.indexIn(txt) > -1:
1777 self.logTree.setCurrentItem(self.logTree.topLevelItem(index))
1778 break
1779 else:
1780 E5MessageBox.information(
1781 self,
1782 self.tr("Find Commit"),
1783 self.tr("""'{0}' was not found.""").format(self.rxEdit.text()))

eric ide

mercurial