Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py

changeset 4059
15b78ac687fb
parent 4021
195a471c327b
child 4060
6dc9821fc9c8
--- a/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py	Sun Jan 18 16:09:07 2015 +0100
+++ b/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.py	Sun Jan 18 17:28:53 2015 +0100
@@ -86,6 +86,17 @@
             self.tr("Press to refresh the list of changesets"))
         self.refreshButton.setEnabled(False)
         
+        self.findPrevButton.setIcon(UI.PixmapCache.getIcon("1leftarrow.png"))
+        self.findNextButton.setIcon(UI.PixmapCache.getIcon("1rightarrow.png"))
+        self.__findBackwards = False
+        
+        self.modeComboBox.addItem(self.tr("Find"), "find")
+        self.modeComboBox.addItem(self.tr("Filter"), "filter")
+        
+        self.fieldCombo.addItem(self.tr("Revision"), "revision")
+        self.fieldCombo.addItem(self.tr("Author"), "author")
+        self.fieldCombo.addItem(self.tr("Message"), "message")
+        
         self.vcs = vcs
         if mode in ("log", "incoming", "outgoing"):
             self.commandMode = mode
@@ -101,11 +112,16 @@
             "<tr><td><b>Date</b></td><td>{1}</td></tr>"
             "<tr><td><b>Author</b></td><td>{2}</td></tr>"
             "<tr><td><b>Branch</b></td><td>{3}</td></tr>"
-            "<tr><td><b>Tags</b></td><td>{4}</td></tr>"
-            "<tr><td><b>Bookmarks</b></td><td>{5}</td></tr>"
-            "<tr><td><b>Parents</b></td><td>{6}</td></tr>"
+            "<tr><td><b>Parents</b></td><td>{4}</td></tr>"
+            "{5}"
             "</table>"
         )
+        self.__tagsTemplate = self.tr(
+            "<tr><td><b>Tags</b></td><td>{0}</td></tr>"
+        )
+        self.__bookmarksTemplate = self.tr(
+            "<tr><td><b>Bookmarks</b></td><td>{0}</td></tr>"
+        )
         
         self.__bundle = ""
         self.__filename = ""
@@ -253,8 +269,7 @@
         self.branchCombo.clear()
         self.fromDate.setDate(QDate.currentDate())
         self.toDate.setDate(QDate.currentDate())
-        self.fieldCombo.setCurrentIndex(self.fieldCombo.findText(
-            self.tr("Message")))
+        self.fieldCombo.setCurrentIndex(self.fieldCombo.findData("message"))
         self.limitSpinBox.setValue(self.vcs.getPlugin().getPreferences(
             "LogLimit"))
         self.stopCheckBox.setChecked(self.vcs.getPlugin().getPreferences(
@@ -1051,8 +1066,8 @@
             self.branchCombo.findText(branchFilter))
         
         self.__filterLogsEnabled = True
-        self.__filterLogs()
-        
+        if self.__actionMode() == "filter":
+            self.__filterLogs()        
         self.__updateDiffButtons()
         self.__updateToolMenuActions()
         
@@ -1227,17 +1242,25 @@
         self.filesTree.clear()
         
         if itm is not None:
+            if itm.text(self.TagsColumn):
+                tagsStr = self.__tagsTemplate.format(itm.text(self.TagsColumn))
+            else:
+                tagsStr = ""
+            if itm.text(self.BookmarksColumn):
+                bookmarksStr = self.__bookmarksTemplate.format(
+                    itm.text(self.BookmarksColumn))
+            else:
+                bookmarksStr = ""
             self.detailsEdit.setHtml(self.__detailsTemplate.format(
                 itm.text(self.RevisionColumn),
                 itm.text(self.DateColumn),
                 itm.text(self.AuthorColumn),
                 itm.text(self.BranchColumn).replace(
                     self.ClosedIndicator, ""),
-                itm.text(self.TagsColumn),
-                itm.text(self.BookmarksColumn),
                 ", ".join(
                     [str(x) for x in itm.data(0, self.__parentsRole)]
                 ),
+                tagsStr + bookmarksStr,
             ))
             
             for line in itm.data(0, self.__messageRole):
@@ -1343,7 +1366,8 @@
         
         @param date new date (QDate)
         """
-        self.__filterLogs()
+        if self.__actionMode() == "filter":
+            self.__filterLogs()
     
     @pyqtSlot(QDate)
     def on_toDate_dateChanged(self, date):
@@ -1352,7 +1376,8 @@
         
         @param date new date (QDate)
         """
-        self.__filterLogs()
+        if self.__actionMode() == "filter":
+            self.__filterLogs()
     
     @pyqtSlot(str)
     def on_branchCombo_activated(self, txt):
@@ -1361,7 +1386,8 @@
         
         @param txt text of the selected branch (string)
         """
-        self.__filterLogs()
+        if self.__actionMode() == "filter":
+            self.__filterLogs()
     
     @pyqtSlot(str)
     def on_fieldCombo_activated(self, txt):
@@ -1370,7 +1396,8 @@
         
         @param txt text of the selected field (string)
         """
-        self.__filterLogs()
+        if self.__actionMode() == "filter":
+            self.__filterLogs()
     
     @pyqtSlot(str)
     def on_rxEdit_textChanged(self, txt):
@@ -1379,7 +1406,18 @@
         
         @param txt filter expression (string)
         """
-        self.__filterLogs()
+        if self.__actionMode() == "filter":
+            self.__filterLogs()
+        elif self.__actionMode() == "find":
+            self.__findItem(self.__findBackwards, interactive=True)
+    
+    @pyqtSlot()
+    def on_rxEdit_returnPressed(self):
+        """
+        Private slot handling a press of the Return key in the rxEdit input.
+        """
+        if self.__actionMode() == "find":
+            self.__findItem(self.__findBackwards, interactive=True)
     
     def __filterLogs(self):
         """
@@ -1390,32 +1428,39 @@
             to_ = self.toDate.date().addDays(1).toString("yyyy-MM-dd")
             branch = self.branchCombo.currentText()
             closedBranch = branch + '--'
+            fieldIndex, searchRx = self.__prepareFieldSearch()
             
-            txt = self.fieldCombo.currentText()
-            if txt == self.tr("Author"):
-                fieldIndex = self.AuthorColumn
-                searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
-            elif txt == self.tr("Revision"):
-                fieldIndex = self.RevisionColumn
-                txt = self.rxEdit.text()
-                if txt.startswith("^"):
-                    searchRx = QRegExp("^\s*{0}".format(txt[1:]),
-                                       Qt.CaseInsensitive)
-                else:
-                    searchRx = QRegExp(txt, Qt.CaseInsensitive)
-            else:
-                fieldIndex = self.MessageColumn
-                searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
-            
+##            txt = self.fieldCombo.currentText()
+##            if txt == self.tr("Author"):
+##                fieldIndex = self.AuthorColumn
+##                searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
+##            elif txt == self.tr("Revision"):
+##                fieldIndex = self.RevisionColumn
+##                txt = self.rxEdit.text()
+##                if txt.startswith("^"):
+##                    searchRx = QRegExp("^\s*{0}".format(txt[1:]),
+##                                       Qt.CaseInsensitive)
+##                else:
+##                    searchRx = QRegExp(txt, Qt.CaseInsensitive)
+##            else:
+##                fieldIndex = self.MessageColumn
+##                searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
+##            
+            visibleItemCount = self.logTree.topLevelItemCount()
             currentItem = self.logTree.currentItem()
             for topIndex in range(self.logTree.topLevelItemCount()):
                 topItem = self.logTree.topLevelItem(topIndex)
+                if fieldIndex == self.MessageColumn:
+                    # Find based on complete message text
+                    txt = "\n".join(topItem.data(0, self.__messageRole))
+                else:
+                    txt = topItem.text(fieldIndex)
                 if topItem.text(self.DateColumn) <= to_ and \
                    topItem.text(self.DateColumn) >= from_ and \
                    (branch == self.__allBranchesFilter or
                     topItem.text(self.BranchColumn) in
                         [branch, closedBranch]) and \
-                   searchRx.indexIn(topItem.text(fieldIndex)) > -1:
+                   searchRx.indexIn(txt) > -1:
                     topItem.setHidden(False)
                     if topItem is currentItem:
                         self.on_logTree_currentItemChanged(topItem, None)
@@ -1424,6 +1469,34 @@
                     if topItem is currentItem:
                         self.messageEdit.clear()
                         self.filesTree.clear()
+                    visibleItemCount -= 1
+            self.logTree.header().setSectionHidden(
+                self.IconColumn,
+                visibleItemCount != self.logTree.topLevelItemCount())
+    
+    def __prepareFieldSearch(self):
+        """
+        Private slot to prepare the filed search data.
+        
+        @return tuple of field index and search expression (integer, string)
+        """
+        txt = self.fieldCombo.itemData(self.fieldCombo.currentIndex())
+        if txt == "author":
+            fieldIndex = self.AuthorColumn
+            searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
+        elif txt == "revision":
+            fieldIndex = self.RevisionColumn
+            txt = self.rxEdit.text()
+            if txt.startswith("^"):
+                searchRx = QRegExp("^\s*{0}".format(txt[1:]),
+                                   Qt.CaseInsensitive)
+            else:
+                searchRx = QRegExp(txt, Qt.CaseInsensitive)
+        else:
+            fieldIndex = self.MessageColumn
+            searchRx = QRegExp(self.rxEdit.text(), Qt.CaseInsensitive)
+        
+        return fieldIndex, searchRx
     
     @pyqtSlot(bool)
     def on_stopCheckBox_clicked(self, checked):
@@ -1623,3 +1696,88 @@
         if revs:
             self.vcs.getExtensionObject("largefiles").hgLfPull(
                 self.repodir, revisions=revs)
+    
+    def __actionMode(self):
+        """
+        Private method to get the selected action mode.
+        
+        @return selected action mode (string, one of filter or find)
+        """
+        return self.modeComboBox.itemData(
+            self.modeComboBox.currentIndex())
+    
+    @pyqtSlot(int)
+    def on_modeComboBox_currentIndexChanged(self, index):
+        """
+        Private slot to react on mode changes.
+        """
+        mode = self.modeComboBox.itemData(index)
+        findMode = mode == "find"
+        filterMode = mode == "filter"
+        
+        self.fromDate.setEnabled(filterMode)
+        self.toDate.setEnabled(filterMode)
+        self.branchCombo.setEnabled(filterMode)
+        self.findPrevButton.setVisible(findMode)
+        self.findNextButton.setVisible(findMode)
+        
+        if findMode:
+            for topIndex in range(self.logTree.topLevelItemCount()):
+                self.logTree.topLevelItem(topIndex).setHidden(False)
+            self.logTree.header().setSectionHidden(self.IconColumn, False)
+        elif filterMode:
+            self.__filterLogs()
+    
+    @pyqtSlot()
+    def on_findPrevButton_clicked(self):
+        """
+        Private slot to find the previous item matching the entered criteria.
+        """
+        self.__findItem(True)
+    
+    @pyqtSlot()
+    def on_findNextButton_clicked(self):
+        """
+        Private slot to find the next item matching the entered criteria.
+        """
+        self.__findItem(False)
+    
+    def __findItem(self, backwards=False, interactive=False):
+        """
+        Private slot to find an item matching the entered criteria.
+        
+        @param backwards flag indicating to search backwards (boolean)
+        @param interactive flag indicating an interactive search (boolean)
+        """
+        self.__findBackwards = backwards
+        
+        fieldIndex, searchRx = self.__prepareFieldSearch()
+        currentIndex = self.logTree.indexOfTopLevelItem(
+            self.logTree.currentItem())
+        if backwards:
+            if interactive:
+                indexes = range(currentIndex, -1, -1)
+            else:
+                indexes = range(currentIndex - 1, -1, -1)
+        else:
+            if interactive:
+                indexes = range(currentIndex, self.logTree.topLevelItemCount())
+            else:
+                indexes = range(currentIndex + 1,
+                                self.logTree.topLevelItemCount())
+        
+        for index in indexes:
+            topItem = self.logTree.topLevelItem(index)
+            if fieldIndex == self.MessageColumn:
+                # Find based on complete message text
+                txt = "\n".join(topItem.data(0, self.__messageRole))
+            else:
+                txt = topItem.text(fieldIndex)
+            if searchRx.indexIn(txt) > -1:
+                self.logTree.setCurrentItem(self.logTree.topLevelItem(index))
+                break
+        else:
+            E5MessageBox.information(
+                self,
+                self.tr("Find Commit"),
+                self.tr("""'{0}' was not found.""").format(self.rxEdit.text()))

eric ide

mercurial