eric6/Plugins/VcsPlugins/vcsMercurial/HgServeDialog.py

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

eric ide

mercurial