Plugins/VcsPlugins/vcsMercurial/HgServeDialog.py

changeset 305
5cf9e308f342
child 307
bdc899125e39
equal deleted inserted replaced
304:98429932e0c9 305:5cf9e308f342
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2010 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog for the Mercurial server.
8 """
9
10 import os
11
12 from PyQt4.QtCore import QProcess, Qt, QSize
13 from PyQt4.QtGui import QMainWindow, QAction, QToolBar, QPlainTextEdit, \
14 QMessageBox, QTextCursor, QBrush, QSpinBox, QComboBox
15
16 from E5Gui.E5Application import e5App
17
18 import UI.PixmapCache
19
20 import Preferences
21
22 class HgServeDialog(QMainWindow):
23 """
24 Class implementing a dialog for the Mercurial server.
25 """
26 def __init__(self, vcs, path, parent = None):
27 """
28 Constructor
29
30 @param vcs reference to the vcs object
31 @param path path of the repository to serve (string)
32 @param parent reference to the parent widget (QWidget)
33 """
34 QMainWindow.__init__(self, parent)
35
36 self.vcs = vcs
37 self.__repoPath = path
38
39 self.__styles = ["paper", "coal", "gitweb", "monoblue", "spartan", ]
40
41 self.__startAct = QAction(
42 UI.PixmapCache.getIcon(
43 os.path.join("VcsPlugins", "vcsMercurial", "icons", "startServer.png")),
44 self.trUtf8("Start Server"), self)
45 self.__startAct.triggered.connect(self.__startServer)
46 self.__stopAct = QAction(
47 UI.PixmapCache.getIcon(
48 os.path.join("VcsPlugins", "vcsMercurial", "icons", "stopServer.png")),
49 self.trUtf8("Stop Server"), self)
50 self.__stopAct.triggered.connect(self.__stopServer)
51 self.__browserAct = QAction(
52 UI.PixmapCache.getIcon("home.png"),
53 self.trUtf8("Start Browser"), self)
54 self.__browserAct.triggered.connect(self.__startBrowser)
55
56 self.__portSpin = QSpinBox(self)
57 self.__portSpin.setMinimum(2048)
58 self.__portSpin.setMaximum(65535)
59 self.__portSpin.setToolTip(self.trUtf8("Enter the server port"))
60 self.__portSpin.setValue(self.vcs.getPlugin().getPreferences("ServerPort"))
61
62 self.__styleCombo = QComboBox(self)
63 self.__styleCombo.addItems(self.__styles)
64 self.__styleCombo.setToolTip(self.trUtf8("Select the style to use"))
65 self.__styleCombo.setCurrentIndex(self.__styleCombo.findText(
66 self.vcs.getPlugin().getPreferences("ServerStyle")))
67
68 self.__serverToolbar = QToolBar(self.trUtf8("Server"), self)
69 self.__serverToolbar.addAction(self.__startAct)
70 self.__serverToolbar.addAction(self.__stopAct)
71 self.__serverToolbar.addSeparator()
72 self.__serverToolbar.addWidget(self.__portSpin)
73 self.__serverToolbar.addWidget(self.__styleCombo)
74
75 self.__browserToolbar = QToolBar(self.trUtf8("Browser"), self)
76 self.__browserToolbar.addAction(self.__browserAct)
77
78 self.addToolBar(Qt.TopToolBarArea, self.__serverToolbar)
79 self.addToolBar(Qt.TopToolBarArea, self.__browserToolbar)
80
81 self.__log = QPlainTextEdit(self)
82 self.setCentralWidget(self.__log)
83
84 # polish up the dialog
85 self.__startAct.setEnabled(True)
86 self.__stopAct.setEnabled(False)
87 self.__browserAct.setEnabled(False)
88 self.__portSpin.setEnabled(True)
89 self.__styleCombo.setEnabled(True)
90 self.resize(QSize(800, 600).expandedTo(self.minimumSizeHint()))
91
92 self.process = QProcess()
93 self.process.finished.connect(self.__procFinished)
94 self.process.readyReadStandardOutput.connect(self.__readStdout)
95 self.process.readyReadStandardError.connect(self.__readStderr)
96
97 self.cNormalFormat = self.__log.currentCharFormat()
98 self.cErrorFormat = self.__log.currentCharFormat()
99 self.cErrorFormat.setForeground(QBrush(Preferences.getUI("LogStdErrColour")))
100
101 def __startServer(self):
102 """
103 Private slot to start the Mercurial server.
104 """
105 port = self.__portSpin.value()
106 style = self.__styleCombo.currentText()
107
108 args = []
109 args.append("serve")
110 args.append("-v")
111 args.append("--port")
112 args.append(str(port))
113 args.append("--style")
114 args.append(style)
115
116 self.process.setWorkingDirectory(self.__repoPath)
117
118 self.process.start('hg', args)
119 procStarted = self.process.waitForStarted()
120 if procStarted:
121 self.__startAct.setEnabled(False)
122 self.__stopAct.setEnabled(True)
123 self.__browserAct.setEnabled(True)
124 self.__portSpin.setEnabled(False)
125 self.__styleCombo.setEnabled(False)
126 self.vcs.getPlugin().setPreferences("ServerPort", port)
127 self.vcs.getPlugin().setPreferences("ServerStyle", style)
128 else:
129 QMessageBox.critical(None,
130 self.trUtf8('Process Generation Error'),
131 self.trUtf8(
132 'The process {0} could not be started. '
133 'Ensure, that it is in the search path.'
134 ).format('hg'))
135
136 def __stopServer(self):
137 """
138 Private slot to stop the Mercurial server.
139 """
140 if self.process is not None and \
141 self.process.state() != QProcess.NotRunning:
142 self.process.terminate()
143 self.process.waitForFinished(5000)
144 if self.process.state() != QProcess.NotRunning:
145 self.process.kill()
146
147 self.__startAct.setEnabled(True)
148 self.__stopAct.setEnabled(False)
149 self.__browserAct.setEnabled(False)
150 self.__portSpin.setEnabled(True)
151 self.__styleCombo.setEnabled(True)
152
153 def __startBrowser(self):
154 """
155 Private slot to start a browser for the served repository.
156 """
157 ui = e5App().getObject("UserInterface")
158 ui.launchHelpViewer("http://localhost:{0}".format(self.__portSpin.value()))
159
160 def closeEvent(self, e):
161 """
162 Private slot implementing a close event handler.
163
164 @param e close event (QCloseEvent)
165 """
166 self.__stopServer()
167
168 def __procFinished(self, exitCode, exitStatus):
169 """
170 Private slot connected to the finished signal.
171
172 @param exitCode exit code of the process (integer)
173 @param exitStatus exit status of the process (QProcess.ExitStatus)
174 """
175 self.__stopServer()
176
177 def __readStdout(self):
178 """
179 Private slot to handle the readyReadStandardOutput signal.
180
181 It reads the output of the process and inserts it into the log.
182 """
183 if self.process is not None:
184 s = str(self.process.readAllStandardOutput(),
185 Preferences.getSystem("IOEncoding"),
186 'replace')
187 self.__appendText(s, False)
188
189 def __readStderr(self):
190 """
191 Private slot to handle the readyReadStandardError signal.
192
193 It reads the error output of the process and inserts it into the log.
194 """
195 if self.process is not None:
196 s = str(self.process.readAllStandardError(),
197 Preferences.getSystem("IOEncoding"),
198 'replace')
199 self.__appendText(s, True)
200
201 def __appendText(self, txt, error = False):
202 """
203 Public method to append text to the end.
204
205 @param txt text to insert (string)
206 @param error flag indicating to insert error text (boolean)
207 """
208 tc = self.__log.textCursor()
209 tc.movePosition(QTextCursor.End)
210 self.__log.setTextCursor(tc)
211 if error:
212 self.__log.setCurrentCharFormat(self.cErrorFormat)
213 else:
214 self.__log.setCurrentCharFormat(self.cNormalFormat)
215 self.__log.insertPlainText(txt)
216 self.__log.ensureCursorVisible()

eric ide

mercurial