Plugins/VcsPlugins/vcsMercurial/BookmarksExtension/HgBookmarksListDialog.py

changeset 1011
0b118aefae5b
child 1131
7781e396c903
equal deleted inserted replaced
1010:06393b5f5330 1011:0b118aefae5b
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2011 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to show a list of bookmarks.
8 """
9
10 import os
11
12 from PyQt4.QtCore import pyqtSlot, QProcess, Qt, QTimer
13 from PyQt4.QtGui import QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem, \
14 QLineEdit
15
16 from E5Gui import E5MessageBox
17
18 from .Ui_HgBookmarksListDialog import Ui_HgBookmarksListDialog
19
20 import Preferences
21
22
23 class HgBookmarksListDialog(QDialog, Ui_HgBookmarksListDialog):
24 """
25 Class implementing a dialog to show a list of bookmarks.
26 """
27 def __init__(self, vcs, parent=None):
28 """
29 Constructor
30
31 @param vcs reference to the vcs object
32 @param parent parent widget (QWidget)
33 """
34 QDialog.__init__(self, parent)
35 self.setupUi(self)
36
37 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
38 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
39
40 self.process = QProcess()
41 self.vcs = vcs
42 self.__bookmarksList = None
43
44 self.bookmarksList.headerItem().setText(self.bookmarksList.columnCount(), "")
45 self.bookmarksList.header().setSortIndicator(3, Qt.AscendingOrder)
46
47 self.process.finished.connect(self.__procFinished)
48 self.process.readyReadStandardOutput.connect(self.__readStdout)
49 self.process.readyReadStandardError.connect(self.__readStderr)
50
51 def closeEvent(self, e):
52 """
53 Private slot implementing a close event handler.
54
55 @param e close event (QCloseEvent)
56 """
57 if self.process is not None and \
58 self.process.state() != QProcess.NotRunning:
59 self.process.terminate()
60 QTimer.singleShot(2000, self.process.kill)
61 self.process.waitForFinished(3000)
62
63 e.accept()
64
65 def start(self, path, bookmarksList):
66 """
67 Public slot to start the bookmarks command.
68
69 @param path name of directory to be listed (string)
70 @param bookmarksList reference to string list receiving the bookmarks
71 (list of strings)
72 """
73 self.errorGroup.hide()
74
75 self.intercept = False
76 self.activateWindow()
77
78 self.__bookmarksList = bookmarksList
79 dname, fname = self.vcs.splitPath(path)
80
81 # find the root of the repo
82 repodir = dname
83 while not os.path.isdir(os.path.join(repodir, self.vcs.adminDir)):
84 repodir = os.path.dirname(repodir)
85 if repodir == os.sep:
86 return
87
88 args = []
89 args.append('bookmarks')
90
91 self.process.kill()
92 self.process.setWorkingDirectory(repodir)
93
94 self.process.start('hg', args)
95 procStarted = self.process.waitForStarted()
96 if not procStarted:
97 self.inputGroup.setEnabled(False)
98 self.inputGroup.hide()
99 E5MessageBox.critical(self,
100 self.trUtf8('Process Generation Error'),
101 self.trUtf8(
102 'The process {0} could not be started. '
103 'Ensure, that it is in the search path.'
104 ).format('hg'))
105 else:
106 self.inputGroup.setEnabled(True)
107 self.inputGroup.show()
108
109 def __finish(self):
110 """
111 Private slot called when the process finished or the user pressed the button.
112 """
113 if self.process is not None and \
114 self.process.state() != QProcess.NotRunning:
115 self.process.terminate()
116 QTimer.singleShot(2000, self.process.kill)
117 self.process.waitForFinished(3000)
118
119 self.inputGroup.setEnabled(False)
120 self.inputGroup.hide()
121
122 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
123 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
124 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
125 self.buttonBox.button(QDialogButtonBox.Close).setFocus(Qt.OtherFocusReason)
126
127 self.process = None
128
129 if self.bookmarksList.topLevelItemCount() == 0:
130 # no bookmarks defined
131 self.__generateItem(self.trUtf8("no bookmarks defined"), "", "", "")
132 self.bookmarksList.doItemsLayout()
133 self.__resizeColumns()
134 self.__resort()
135
136 def on_buttonBox_clicked(self, button):
137 """
138 Private slot called by a button of the button box clicked.
139
140 @param button button that was clicked (QAbstractButton)
141 """
142 if button == self.buttonBox.button(QDialogButtonBox.Close):
143 self.close()
144 elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
145 self.__finish()
146
147 def __procFinished(self, exitCode, exitStatus):
148 """
149 Private slot connected to the finished signal.
150
151 @param exitCode exit code of the process (integer)
152 @param exitStatus exit status of the process (QProcess.ExitStatus)
153 """
154 self.__finish()
155
156 def __resort(self):
157 """
158 Private method to resort the tree.
159 """
160 self.bookmarksList.sortItems(self.bookmarksList.sortColumn(),
161 self.bookmarksList.header().sortIndicatorOrder())
162
163 def __resizeColumns(self):
164 """
165 Private method to resize the list columns.
166 """
167 self.bookmarksList.header().resizeSections(QHeaderView.ResizeToContents)
168 self.bookmarksList.header().setStretchLastSection(True)
169
170 def __generateItem(self, revision, changeset, status, name):
171 """
172 Private method to generate a bookmark item in the bookmarks list.
173
174 @param revision revision of the bookmark (string)
175 @param changeset changeset of the bookmark (string)
176 @param status of the bookmark (string)
177 @param name name of the bookmark (string)
178 """
179 itm = QTreeWidgetItem(self.bookmarksList, [
180 "{0:>7}".format(revision),
181 changeset,
182 status,
183 name])
184 itm.setTextAlignment(0, Qt.AlignRight)
185 itm.setTextAlignment(1, Qt.AlignRight)
186 itm.setTextAlignment(2, Qt.AlignHCenter)
187
188 def __readStdout(self):
189 """
190 Private slot to handle the readyReadStdout signal.
191
192 It reads the output of the process, formats it and inserts it into
193 the contents pane.
194 """
195 self.process.setReadChannel(QProcess.StandardOutput)
196
197 while self.process.canReadLine():
198 s = str(self.process.readLine(),
199 Preferences.getSystem("IOEncoding"),
200 'replace').strip()
201 l = s.split()
202 if l[-1][0] in "1234567890":
203 # last element is a rev:changeset
204 rev, changeset = l[-1].split(":", 1)
205 del l[-1]
206 if l[0] == "*":
207 status = "current"
208 del l[0]
209 else:
210 status = ""
211 name = " ".join(l)
212 self.__generateItem(rev, changeset, status, name)
213 if self.__bookmarksList is not None:
214 self.__bookmarksList.append(name)
215
216 def __readStderr(self):
217 """
218 Private slot to handle the readyReadStderr signal.
219
220 It reads the error output of the process and inserts it into the
221 error pane.
222 """
223 if self.process is not None:
224 self.errorGroup.show()
225 s = str(self.process.readAllStandardError(),
226 Preferences.getSystem("IOEncoding"),
227 'replace')
228 self.errors.insertPlainText(s)
229 self.errors.ensureCursorVisible()
230
231 def on_passwordCheckBox_toggled(self, isOn):
232 """
233 Private slot to handle the password checkbox toggled.
234
235 @param isOn flag indicating the status of the check box (boolean)
236 """
237 if isOn:
238 self.input.setEchoMode(QLineEdit.Password)
239 else:
240 self.input.setEchoMode(QLineEdit.Normal)
241
242 @pyqtSlot()
243 def on_sendButton_clicked(self):
244 """
245 Private slot to send the input to the subversion process.
246 """
247 input = self.input.text()
248 input += os.linesep
249
250 if self.passwordCheckBox.isChecked():
251 self.errors.insertPlainText(os.linesep)
252 self.errors.ensureCursorVisible()
253 else:
254 self.errors.insertPlainText(input)
255 self.errors.ensureCursorVisible()
256
257 self.process.write(input)
258
259 self.passwordCheckBox.setChecked(False)
260 self.input.clear()
261
262 def on_input_returnPressed(self):
263 """
264 Private slot to handle the press of the return key in the input field.
265 """
266 self.intercept = True
267 self.on_sendButton_clicked()
268
269 def keyPressEvent(self, evt):
270 """
271 Protected slot to handle a key press event.
272
273 @param evt the key press event (QKeyEvent)
274 """
275 if self.intercept:
276 self.intercept = False
277 evt.accept()
278 return
279 QDialog.keyPressEvent(self, evt)

eric ide

mercurial