Plugins/VcsPlugins/vcsMercurial/HgServeDialog.py

changeset 305
5cf9e308f342
child 307
bdc899125e39
diff -r 98429932e0c9 -r 5cf9e308f342 Plugins/VcsPlugins/vcsMercurial/HgServeDialog.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/VcsPlugins/vcsMercurial/HgServeDialog.py	Sat May 29 17:52:59 2010 +0200
@@ -0,0 +1,216 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2010 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog for the Mercurial server.
+"""
+
+import os
+
+from PyQt4.QtCore import QProcess, Qt, QSize
+from PyQt4.QtGui import QMainWindow, QAction, QToolBar, QPlainTextEdit, \
+    QMessageBox, QTextCursor, QBrush, QSpinBox, QComboBox
+
+from E5Gui.E5Application import e5App
+
+import UI.PixmapCache
+
+import Preferences
+
+class HgServeDialog(QMainWindow):
+    """
+    Class implementing a dialog for the Mercurial server.
+    """
+    def __init__(self, vcs, path, parent = None):
+        """
+        Constructor
+        
+        @param vcs reference to the vcs object
+        @param path path of the repository to serve (string)
+        @param parent reference to the parent widget (QWidget)
+        """
+        QMainWindow.__init__(self, parent)
+        
+        self.vcs = vcs
+        self.__repoPath = path
+        
+        self.__styles = ["paper", "coal", "gitweb", "monoblue", "spartan", ]
+        
+        self.__startAct = QAction(
+            UI.PixmapCache.getIcon(
+                os.path.join("VcsPlugins", "vcsMercurial", "icons", "startServer.png")), 
+            self.trUtf8("Start Server"), self) 
+        self.__startAct.triggered.connect(self.__startServer)
+        self.__stopAct = QAction(
+            UI.PixmapCache.getIcon(
+                os.path.join("VcsPlugins", "vcsMercurial", "icons", "stopServer.png")), 
+            self.trUtf8("Stop Server"), self) 
+        self.__stopAct.triggered.connect(self.__stopServer)
+        self.__browserAct = QAction(
+            UI.PixmapCache.getIcon("home.png"), 
+            self.trUtf8("Start Browser"), self) 
+        self.__browserAct.triggered.connect(self.__startBrowser)
+        
+        self.__portSpin = QSpinBox(self)
+        self.__portSpin.setMinimum(2048)
+        self.__portSpin.setMaximum(65535)
+        self.__portSpin.setToolTip(self.trUtf8("Enter the server port"))
+        self.__portSpin.setValue(self.vcs.getPlugin().getPreferences("ServerPort"))
+        
+        self.__styleCombo = QComboBox(self)
+        self.__styleCombo.addItems(self.__styles)
+        self.__styleCombo.setToolTip(self.trUtf8("Select the style to use"))
+        self.__styleCombo.setCurrentIndex(self.__styleCombo.findText(
+            self.vcs.getPlugin().getPreferences("ServerStyle")))
+        
+        self.__serverToolbar = QToolBar(self.trUtf8("Server"), self)
+        self.__serverToolbar.addAction(self.__startAct)
+        self.__serverToolbar.addAction(self.__stopAct)
+        self.__serverToolbar.addSeparator()
+        self.__serverToolbar.addWidget(self.__portSpin)
+        self.__serverToolbar.addWidget(self.__styleCombo)
+        
+        self.__browserToolbar = QToolBar(self.trUtf8("Browser"), self)
+        self.__browserToolbar.addAction(self.__browserAct)
+        
+        self.addToolBar(Qt.TopToolBarArea, self.__serverToolbar)
+        self.addToolBar(Qt.TopToolBarArea, self.__browserToolbar)
+        
+        self.__log = QPlainTextEdit(self)
+        self.setCentralWidget(self.__log)
+        
+        # polish up the dialog
+        self.__startAct.setEnabled(True)
+        self.__stopAct.setEnabled(False)
+        self.__browserAct.setEnabled(False)
+        self.__portSpin.setEnabled(True)
+        self.__styleCombo.setEnabled(True)
+        self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint()))
+        
+        self.process = QProcess()
+        self.process.finished.connect(self.__procFinished)
+        self.process.readyReadStandardOutput.connect(self.__readStdout)
+        self.process.readyReadStandardError.connect(self.__readStderr)
+        
+        self.cNormalFormat = self.__log.currentCharFormat()
+        self.cErrorFormat = self.__log.currentCharFormat()
+        self.cErrorFormat.setForeground(QBrush(Preferences.getUI("LogStdErrColour")))
+    
+    def __startServer(self):
+        """
+        Private slot to start the Mercurial server.
+        """
+        port = self.__portSpin.value()
+        style = self.__styleCombo.currentText()
+        
+        args = []
+        args.append("serve")
+        args.append("-v")
+        args.append("--port")
+        args.append(str(port))
+        args.append("--style")
+        args.append(style)
+        
+        self.process.setWorkingDirectory(self.__repoPath)
+        
+        self.process.start('hg', args)
+        procStarted = self.process.waitForStarted()
+        if procStarted:
+            self.__startAct.setEnabled(False)
+            self.__stopAct.setEnabled(True)
+            self.__browserAct.setEnabled(True)
+            self.__portSpin.setEnabled(False)
+            self.__styleCombo.setEnabled(False)
+            self.vcs.getPlugin().setPreferences("ServerPort", port)
+            self.vcs.getPlugin().setPreferences("ServerStyle", style)
+        else:
+            QMessageBox.critical(None,
+                self.trUtf8('Process Generation Error'),
+                self.trUtf8(
+                    'The process {0} could not be started. '
+                    'Ensure, that it is in the search path.'
+                ).format('hg'))
+    
+    def __stopServer(self):
+        """
+        Private slot to stop the Mercurial server.
+        """
+        if self.process is not None and \
+           self.process.state() != QProcess.NotRunning:
+            self.process.terminate()
+            self.process.waitForFinished(5000)
+            if self.process.state() != QProcess.NotRunning:
+                self.process.kill()
+        
+        self.__startAct.setEnabled(True)
+        self.__stopAct.setEnabled(False)
+        self.__browserAct.setEnabled(False)
+        self.__portSpin.setEnabled(True)
+        self.__styleCombo.setEnabled(True)
+    
+    def __startBrowser(self):
+        """
+        Private slot to start a browser for the served repository.
+        """
+        ui = e5App().getObject("UserInterface")
+        ui.launchHelpViewer("http://localhost:{0}".format(self.__portSpin.value()))
+    
+    def closeEvent(self, e):
+        """
+        Private slot implementing a close event handler.
+        
+        @param e close event (QCloseEvent)
+        """
+        self.__stopServer()
+    
+    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.__stopServer()
+    
+    def __readStdout(self):
+        """
+        Private slot to handle the readyReadStandardOutput signal. 
+        
+        It reads the output of the process and inserts it into the log.
+        """
+        if self.process is not None:
+            s = str(self.process.readAllStandardOutput(), 
+                     Preferences.getSystem("IOEncoding"), 
+                     'replace')
+            self.__appendText(s, False)
+    
+    def __readStderr(self):
+        """
+        Private slot to handle the readyReadStandardError signal.
+        
+        It reads the error output of the process and inserts it into the log.
+        """
+        if self.process is not None:
+            s = str(self.process.readAllStandardError(), 
+                     Preferences.getSystem("IOEncoding"), 
+                     'replace')
+            self.__appendText(s, True)
+    
+    def __appendText(self, txt, error = False):
+        """
+        Public method to append text to the end.
+        
+        @param txt text to insert (string)
+        @param error flag indicating to insert error text (boolean)
+        """
+        tc = self.__log.textCursor()
+        tc.movePosition(QTextCursor.End)
+        self.__log.setTextCursor(tc)
+        if error:
+            self.__log.setCurrentCharFormat(self.cErrorFormat)
+        else:
+            self.__log.setCurrentCharFormat(self.cNormalFormat)
+        self.__log.insertPlainText(txt)
+        self.__log.ensureCursorVisible()

eric ide

mercurial