eric6/VCS/StatusMonitorThread.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7165
375c077ef7e2
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2006 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the VCS status monitor thread base class.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtCore import QThread, QMutex, QWaitCondition, pyqtSignal, \
13 QCoreApplication
14
15
16 class VcsStatusMonitorThread(QThread):
17 """
18 Class implementing the VCS status monitor thread base class.
19
20 @signal vcsStatusMonitorData(list of str) emitted to update the VCS status
21 @signal vcsStatusMonitorStatus(str, str) emitted to signal the status of
22 the monitoring thread (ok, nok, op) and a status message
23 @signal vcsStatusMonitorInfo(str) emitted to signal some info of the
24 monitoring thread
25 """
26 vcsStatusMonitorData = pyqtSignal(list)
27 vcsStatusMonitorStatus = pyqtSignal(str, str)
28 vcsStatusMonitorInfo = pyqtSignal(str)
29
30 def __init__(self, interval, project, vcs, parent=None):
31 """
32 Constructor
33
34 @param interval new interval in seconds (integer)
35 @param project reference to the project object (Project)
36 @param vcs reference to the version control object
37 @param parent reference to the parent object (QObject)
38 """
39 super(VcsStatusMonitorThread, self).__init__(parent)
40 self.setObjectName("VcsStatusMonitorThread")
41
42 self.setTerminationEnabled(True)
43
44 self.projectDir = project.getProjectPath()
45 self.project = project
46 self.vcs = vcs
47
48 self.interval = interval
49 self.autoUpdate = False
50
51 self.statusList = []
52 self.reportedStates = {}
53 self.shouldUpdate = False
54
55 self.monitorMutex = QMutex()
56 self.monitorCondition = QWaitCondition()
57 self.__stopIt = False
58
59 def run(self):
60 """
61 Public method implementing the tasks action.
62 """
63 while not self.__stopIt:
64 # perform the checking task
65 self.statusList = []
66 self.vcsStatusMonitorStatus.emit(
67 "wait", QCoreApplication.translate(
68 "VcsStatusMonitorThread", "Waiting for lock"))
69 try:
70 locked = self.vcs.vcsExecutionMutex.tryLock(5000)
71 except TypeError:
72 locked = self.vcs.vcsExecutionMutex.tryLock()
73 if locked:
74 try:
75 self.vcsStatusMonitorStatus.emit(
76 "op", QCoreApplication.translate(
77 "VcsStatusMonitorThread",
78 "Checking repository status"))
79 res, statusMsg = self._performMonitor()
80 infoMsg = self._getInfo()
81 finally:
82 self.vcs.vcsExecutionMutex.unlock()
83 if res:
84 status = "ok"
85 else:
86 status = "nok"
87 self.vcsStatusMonitorStatus.emit(
88 "send", QCoreApplication.translate(
89 "VcsStatusMonitorThread", "Sending data"))
90 self.vcsStatusMonitorData.emit(self.statusList)
91 self.vcsStatusMonitorStatus.emit(status, statusMsg)
92 self.vcsStatusMonitorInfo.emit(infoMsg)
93 else:
94 self.vcsStatusMonitorStatus.emit(
95 "timeout", QCoreApplication.translate(
96 "VcsStatusMonitorThread",
97 "Timed out waiting for lock"))
98 self.vcsStatusMonitorInfo.emit("")
99
100 if self.autoUpdate and self.shouldUpdate:
101 self.vcs.vcsUpdate(self.projectDir, True)
102 continue # check again
103 self.shouldUpdate = False
104
105 # wait until interval has expired checking for a stop condition
106 self.monitorMutex.lock()
107 if not self.__stopIt:
108 self.monitorCondition.wait(
109 self.monitorMutex, self.interval * 1000)
110 self.monitorMutex.unlock()
111
112 self._shutdown()
113 self.exit()
114
115 def setInterval(self, interval):
116 """
117 Public method to change the monitor interval.
118
119 @param interval new interval in seconds (integer)
120 """
121 locked = self.monitorMutex.tryLock()
122 self.interval = interval
123 self.monitorCondition.wakeAll()
124 if locked:
125 self.monitorMutex.unlock()
126
127 def getInterval(self):
128 """
129 Public method to get the monitor interval.
130
131 @return interval in seconds (integer)
132 """
133 return self.interval
134
135 def setAutoUpdate(self, auto):
136 """
137 Public method to enable the auto update function.
138
139 @param auto status of the auto update function (boolean)
140 """
141 self.autoUpdate = auto
142
143 def getAutoUpdate(self):
144 """
145 Public method to retrieve the status of the auto update function.
146
147 @return status of the auto update function (boolean)
148 """
149 return self.autoUpdate
150
151 def checkStatus(self):
152 """
153 Public method to wake up the status monitor thread.
154 """
155 locked = self.monitorMutex.tryLock()
156 self.monitorCondition.wakeAll()
157 if locked:
158 self.monitorMutex.unlock()
159
160 def stop(self):
161 """
162 Public method to stop the monitor thread.
163 """
164 locked = self.monitorMutex.tryLock()
165 self.__stopIt = True
166 self.monitorCondition.wakeAll()
167 if locked:
168 self.monitorMutex.unlock()
169
170 def clearCachedState(self, name):
171 """
172 Public method to clear the cached VCS state of a file/directory.
173
174 @param name name of the entry to be cleared (string)
175 """
176 key = self.project.getRelativePath(name)
177 try:
178 del self.reportedStates[key]
179 except KeyError:
180 pass
181
182 def _performMonitor(self):
183 """
184 Protected method implementing the real monitoring action.
185
186 This method must be overridden and populate the statusList member
187 variable with a list of strings giving the status in the first column
188 and the path relative to the project directory starting with the
189 third column. The allowed status flags are:
190 <ul>
191 <li>"A" path was added but not yet comitted</li>
192 <li>"M" path has local changes</li>
193 <li>"O" path was removed</li>
194 <li>"R" path was deleted and then re-added</li>
195 <li>"U" path needs an update</li>
196 <li>"Z" path contains a conflict</li>
197 <li>" " path is back at normal</li>
198 </ul>
199
200 @ireturn tuple of flag indicating successful operation (boolean) and
201 a status message in case of non successful operation (string)
202 @exception RuntimeError to indicate that this method must be
203 implemented by a subclass
204 """
205 raise RuntimeError('Not implemented')
206
207 def _getInfo(self):
208 """
209 Protected method implementing the real info action.
210
211 This method should be overridden and create a short info message to be
212 shown in the main window status bar right next to the status indicator.
213
214 @return short info message
215 @rtype str
216 """
217 return ""
218
219 def _shutdown(self):
220 """
221 Protected method performing shutdown actions.
222
223 The default implementation does nothing.
224 """
225 pass

eric ide

mercurial