src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py
--- a/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/Plugins/VcsPlugins/vcsSubversion/SvnRepoBrowserDialog.py	Wed Jul 13 14:55:47 2022 +0200
@@ -12,7 +12,11 @@
 
 from PyQt6.QtCore import pyqtSlot, Qt, QTimer, QProcess
 from PyQt6.QtWidgets import (
-    QHeaderView, QLineEdit, QDialog, QDialogButtonBox, QTreeWidgetItem
+    QHeaderView,
+    QLineEdit,
+    QDialog,
+    QDialogButtonBox,
+    QTreeWidgetItem,
 )
 
 from EricWidgets import EricMessageBox
@@ -30,10 +34,11 @@
     """
     Class implementing the subversion repository browser dialog.
     """
+
     def __init__(self, vcs, mode="browse", parent=None):
         """
         Constructor
-        
+
         @param vcs reference to the vcs object
         @param mode mode of the dialog (string, "browse" or "select")
         @param parent parent widget (QWidget)
@@ -41,78 +46,76 @@
         super().__init__(parent)
         self.setupUi(self)
         self.setWindowFlags(Qt.WindowType.Window)
-        
+
         self.repoTree.headerItem().setText(self.repoTree.columnCount(), "")
         self.repoTree.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
-        
+
         self.vcs = vcs
         self.mode = mode
-        
+
         self.__process = EricOverrideCursorProcess()
         self.__process.finished.connect(self.__procFinished)
         self.__process.readyReadStandardOutput.connect(self.__readStdout)
         self.__process.readyReadStandardError.connect(self.__readStderr)
-        
+
         if self.mode == "select":
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Ok).setEnabled(False)
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
             self.buttonBox.button(QDialogButtonBox.StandardButton.Close).hide()
         else:
             self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).hide()
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Cancel).hide()
-        
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).hide()
+
         self.__dirIcon = UI.PixmapCache.getIcon("dirClosed")
         self.__fileIcon = UI.PixmapCache.getIcon("fileMisc")
-        
+
         self.__urlRole = Qt.ItemDataRole.UserRole
         self.__ignoreExpand = False
         self.intercept = False
-        
+
         self.__rx_dir = re.compile(
             r"""\s*([0-9]+)\s+(\w+)\s+"""
-            r"""((?:\w+\s+\d+|[0-9.]+\s+\w+)\s+[0-9:]+)\s+(.+)\s*""")
+            r"""((?:\w+\s+\d+|[0-9.]+\s+\w+)\s+[0-9:]+)\s+(.+)\s*"""
+        )
         self.__rx_file = re.compile(
             r"""\s*([0-9]+)\s+(\w+)\s+([0-9]+)\s"""
-            r"""((?:\w+\s+\d+|[0-9.]+\s+\w+)\s+[0-9:]+)\s+(.+)\s*""")
-    
+            r"""((?:\w+\s+\d+|[0-9.]+\s+\w+)\s+[0-9:]+)\s+(.+)\s*"""
+        )
+
     def closeEvent(self, e):
         """
         Protected slot implementing a close event handler.
-        
+
         @param e close event (QCloseEvent)
         """
         if (
-            self.__process is not None and
-            self.__process.state() != QProcess.ProcessState.NotRunning
+            self.__process is not None
+            and self.__process.state() != QProcess.ProcessState.NotRunning
         ):
             self.__process.terminate()
             QTimer.singleShot(2000, self.__process.kill)
             self.__process.waitForFinished(3000)
-        
+
         e.accept()
-        
+
     def __resort(self):
         """
         Private method to resort the tree.
         """
         self.repoTree.sortItems(
-            self.repoTree.sortColumn(),
-            self.repoTree.header().sortIndicatorOrder())
-    
+            self.repoTree.sortColumn(), self.repoTree.header().sortIndicatorOrder()
+        )
+
     def __resizeColumns(self):
         """
         Private method to resize the tree columns.
         """
-        self.repoTree.header().resizeSections(
-            QHeaderView.ResizeMode.ResizeToContents)
+        self.repoTree.header().resizeSections(QHeaderView.ResizeMode.ResizeToContents)
         self.repoTree.header().setStretchLastSection(True)
-    
-    def __generateItem(self, repopath, revision, author, size, date,
-                       nodekind, url):
+
+    def __generateItem(self, repopath, revision, author, size, date, nodekind, url):
         """
         Private method to generate a tree item in the repository tree.
-        
+
         @param repopath path of the item (string)
         @param revision revision info (string)
         @param author author info (string)
@@ -124,133 +127,131 @@
         """
         rev = "" if revision == "" else int(revision)
         sz = "" if size == "" else int(size)
-        
+
         itm = QTreeWidgetItem(self.parentItem)
         itm.setData(0, Qt.ItemDataRole.DisplayRole, repopath)
         itm.setData(1, Qt.ItemDataRole.DisplayRole, rev)
         itm.setData(2, Qt.ItemDataRole.DisplayRole, author)
         itm.setData(3, Qt.ItemDataRole.DisplayRole, sz)
         itm.setData(4, Qt.ItemDataRole.DisplayRole, date)
-        
+
         if nodekind == "dir":
             itm.setIcon(0, self.__dirIcon)
             itm.setChildIndicatorPolicy(
-                QTreeWidgetItem.ChildIndicatorPolicy.ShowIndicator)
+                QTreeWidgetItem.ChildIndicatorPolicy.ShowIndicator
+            )
         elif nodekind == "file":
             itm.setIcon(0, self.__fileIcon)
-        
+
         itm.setData(0, self.__urlRole, url)
-        
+
         itm.setTextAlignment(0, Qt.AlignmentFlag.AlignLeft)
         itm.setTextAlignment(1, Qt.AlignmentFlag.AlignRight)
         itm.setTextAlignment(2, Qt.AlignmentFlag.AlignLeft)
         itm.setTextAlignment(3, Qt.AlignmentFlag.AlignRight)
         itm.setTextAlignment(4, Qt.AlignmentFlag.AlignLeft)
-        
+
         return itm
-    
+
     def __repoRoot(self, url):
         """
         Private method to get the repository root using the svn info command.
-        
+
         @param url the repository URL to browser (string)
         @return repository root (string)
         """
         ioEncoding = Preferences.getSystem("IOEncoding")
         repoRoot = None
-        
+
         process = QProcess()
-        
+
         args = []
-        args.append('info')
-        self.vcs.addArguments(args, self.vcs.options['global'])
-        args.append('--xml')
+        args.append("info")
+        self.vcs.addArguments(args, self.vcs.options["global"])
+        args.append("--xml")
         args.append(url)
-        
-        process.start('svn', args)
+
+        process.start("svn", args)
         procStarted = process.waitForStarted(5000)
         if procStarted:
             finished = process.waitForFinished(30000)
             if finished:
                 if process.exitCode() == 0:
-                    output = str(process.readAllStandardOutput(), ioEncoding,
-                                 'replace')
+                    output = str(process.readAllStandardOutput(), ioEncoding, "replace")
                     for line in output.splitlines():
                         line = line.strip()
-                        if line.startswith('<root>'):
-                            repoRoot = (
-                                line.replace('<root>', '')
-                                .replace('</root>', '')
-                            )
+                        if line.startswith("<root>"):
+                            repoRoot = line.replace("<root>", "").replace("</root>", "")
                             break
                 else:
-                    error = str(process.readAllStandardError(),
-                                Preferences.getSystem("IOEncoding"),
-                                'replace')
+                    error = str(
+                        process.readAllStandardError(),
+                        Preferences.getSystem("IOEncoding"),
+                        "replace",
+                    )
                     self.errors.insertPlainText(error)
                     self.errors.ensureCursorVisible()
         else:
             EricMessageBox.critical(
                 self,
-                self.tr('Process Generation Error'),
+                self.tr("Process Generation Error"),
                 self.tr(
-                    'The process {0} could not be started. '
-                    'Ensure, that it is in the search path.'
-                ).format('svn'))
+                    "The process {0} could not be started. "
+                    "Ensure, that it is in the search path."
+                ).format("svn"),
+            )
         return repoRoot
-    
+
     def __listRepo(self, url, parent=None):
         """
         Private method to perform the svn list command.
-        
+
         @param url the repository URL to browse (string)
         @param parent reference to the item, the data should be appended to
             (QTreeWidget or QTreeWidgetItem)
         """
         self.errorGroup.hide()
-        
+
         self.repoUrl = url
-        
+
         if parent is None:
             self.parentItem = self.repoTree
         else:
             self.parentItem = parent
-        
+
         if self.parentItem == self.repoTree:
             repoRoot = self.__repoRoot(url)
             if repoRoot is None:
                 self.__finish()
                 return
             self.__ignoreExpand = True
-            itm = self.__generateItem(
-                repoRoot, "", "", "", "", "dir", repoRoot)
+            itm = self.__generateItem(repoRoot, "", "", "", "", "dir", repoRoot)
             itm.setExpanded(True)
             self.parentItem = itm
             urlPart = repoRoot
             for element in url.replace(repoRoot, "").split("/"):
                 if element:
                     urlPart = "{0}/{1}".format(urlPart, element)
-                    itm = self.__generateItem(
-                        element, "", "", "", "", "dir", urlPart)
+                    itm = self.__generateItem(element, "", "", "", "", "dir", urlPart)
                     itm.setExpanded(True)
                     self.parentItem = itm
             itm.setExpanded(False)
             self.__ignoreExpand = False
             self.__finish()
             return
-        
+
         self.intercept = False
-        
+
         self.__process.kill()
-        
+
         args = []
-        args.append('list')
-        self.vcs.addArguments(args, self.vcs.options['global'])
-        if '--verbose' not in self.vcs.options['global']:
-            args.append('--verbose')
+        args.append("list")
+        self.vcs.addArguments(args, self.vcs.options["global"])
+        if "--verbose" not in self.vcs.options["global"]:
+            args.append("--verbose")
         args.append(url)
-        
-        self.__process.start('svn', args)
+
+        self.__process.start("svn", args)
         procStarted = self.__process.waitForStarted(5000)
         if not procStarted:
             self.__finish()
@@ -258,45 +259,46 @@
             self.inputGroup.hide()
             EricMessageBox.critical(
                 self,
-                self.tr('Process Generation Error'),
+                self.tr("Process Generation Error"),
                 self.tr(
-                    'The process {0} could not be started. '
-                    'Ensure, that it is in the search path.'
-                ).format('svn'))
+                    "The process {0} could not be started. "
+                    "Ensure, that it is in the search path."
+                ).format("svn"),
+            )
         else:
             self.inputGroup.setEnabled(True)
             self.inputGroup.show()
-    
+
     def __normalizeUrl(self, url):
         """
         Private method to normalite the url.
-        
+
         @param url the url to normalize (string)
         @return normalized URL (string)
         """
         if url.endswith("/"):
             return url[:-1]
         return url
-    
+
     def start(self, url):
         """
         Public slot to start the svn info command.
-        
+
         @param url the repository URL to browser (string)
         """
         self.repoTree.clear()
-        
+
         self.url = ""
-        
+
         url = self.__normalizeUrl(url)
         if self.urlCombo.findText(url) == -1:
             self.urlCombo.addItem(url)
-    
+
     @pyqtSlot(int)
     def on_urlCombo_currentIndexChanged(self, index):
         """
         Private slot called, when a new repository URL is entered or selected.
-        
+
         @param index index of the current item
         @type int
         """
@@ -306,50 +308,49 @@
             self.url = url
             self.repoTree.clear()
             self.__listRepo(url)
-    
+
     @pyqtSlot(QTreeWidgetItem)
     def on_repoTree_itemExpanded(self, item):
         """
         Private slot called when an item is expanded.
-        
+
         @param item reference to the item to be expanded (QTreeWidgetItem)
         """
         if not self.__ignoreExpand:
             url = item.data(0, self.__urlRole)
             self.__listRepo(url, item)
-    
+
     @pyqtSlot(QTreeWidgetItem)
     def on_repoTree_itemCollapsed(self, item):
         """
         Private slot called when an item is collapsed.
-        
+
         @param item reference to the item to be collapsed (QTreeWidgetItem)
         """
         for child in item.takeChildren():
             del child
-    
+
     @pyqtSlot()
     def on_repoTree_itemSelectionChanged(self):
         """
         Private slot called when the selection changes.
         """
         if self.mode == "select":
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Ok).setEnabled(True)
-    
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(True)
+
     def accept(self):
         """
         Public slot called when the dialog is accepted.
         """
         if self.focusWidget() == self.urlCombo:
             return
-        
+
         super().accept()
-    
+
     def getSelectedUrl(self):
         """
         Public method to retrieve the selected repository URL.
-        
+
         @return the selected repository URL (string)
         """
         items = self.repoTree.selectedItems()
@@ -357,54 +358,52 @@
             return items[0].data(0, self.__urlRole)
         else:
             return ""
-    
+
     def __finish(self):
         """
         Private slot called when the process finished or the user pressed the
         button.
         """
         if (
-            self.__process is not None and
-            self.__process.state() != QProcess.ProcessState.NotRunning
+            self.__process is not None
+            and self.__process.state() != QProcess.ProcessState.NotRunning
         ):
             self.__process.terminate()
             QTimer.singleShot(2000, self.__process.kill)
             self.__process.waitForFinished(3000)
-        
+
         self.inputGroup.setEnabled(False)
         self.inputGroup.hide()
-        
+
         self.__resizeColumns()
         self.__resort()
-    
+
     def __procFinished(self, exitCode, exitStatus):
         """
         Private slot connected to the finished signal.
-        
+
         @param exitCode exit code of the process (integer)
         @param exitStatus exit status of the process (QProcess.ExitStatus)
         """
         self.__finish()
-    
+
     def __readStdout(self):
         """
         Private slot to handle the readyReadStandardOutput signal.
-        
+
         It reads the output of the process, formats it and inserts it into
         the contents pane.
         """
         if self.__process is not None:
-            self.__process.setReadChannel(
-                QProcess.ProcessChannel.StandardOutput)
-            
+            self.__process.setReadChannel(QProcess.ProcessChannel.StandardOutput)
+
             while self.__process.canReadLine():
-                s = str(self.__process.readLine(),
-                        Preferences.getSystem("IOEncoding"),
-                        'replace')
-                match = (
-                    self.__rx_dir.fullmatch(s) or
-                    self.__rx_file.fullmatch(s)
+                s = str(
+                    self.__process.readLine(),
+                    Preferences.getSystem("IOEncoding"),
+                    "replace",
                 )
+                match = self.__rx_dir.fullmatch(s) or self.__rx_file.fullmatch(s)
                 if match is None:
                     continue
                 elif match.re is self.__rx_dir:
@@ -425,37 +424,38 @@
                     date = match.group(4)
                     name = match.group(5).strip()
                     nodekind = "file"
-                
+
                 url = "{0}/{1}".format(self.repoUrl, name)
-                self.__generateItem(
-                    name, revision, author, size, date, nodekind, url)
-   
+                self.__generateItem(name, revision, author, size, date, nodekind, url)
+
     def __readStderr(self):
         """
         Private slot to handle the readyReadStandardError signal.
-        
+
         It reads the error output of the process and inserts it into the
         error pane.
         """
         if self.__process is not None:
-            s = str(self.__process.readAllStandardError(),
-                    Preferences.getSystem("IOEncoding"),
-                    'replace')
+            s = str(
+                self.__process.readAllStandardError(),
+                Preferences.getSystem("IOEncoding"),
+                "replace",
+            )
             self.errors.insertPlainText(s)
             self.errors.ensureCursorVisible()
             self.errorGroup.show()
-    
+
     def on_passwordCheckBox_toggled(self, isOn):
         """
         Private slot to handle the password checkbox toggled.
-        
+
         @param isOn flag indicating the status of the check box (boolean)
         """
         if isOn:
             self.input.setEchoMode(QLineEdit.EchoMode.Password)
         else:
             self.input.setEchoMode(QLineEdit.EchoMode.Normal)
-    
+
     @pyqtSlot()
     def on_sendButton_clicked(self):
         """
@@ -463,30 +463,30 @@
         """
         inputTxt = self.input.text()
         inputTxt += os.linesep
-        
+
         if self.passwordCheckBox.isChecked():
             self.errors.insertPlainText(os.linesep)
             self.errors.ensureCursorVisible()
         else:
             self.errors.insertPlainText(inputTxt)
             self.errors.ensureCursorVisible()
-        
+
         self.__process.write(strToQByteArray(inputTxt))
-        
+
         self.passwordCheckBox.setChecked(False)
         self.input.clear()
-    
+
     def on_input_returnPressed(self):
         """
         Private slot to handle the press of the return key in the input field.
         """
         self.intercept = True
         self.on_sendButton_clicked()
-    
+
     def keyPressEvent(self, evt):
         """
         Protected slot to handle a key press event.
-        
+
         @param evt the key press event (QKeyEvent)
         """
         if self.intercept:

eric ide

mercurial