src/eric7/VCS/StatusMonitorThread.py

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

eric ide

mercurial