src/eric7/EricWidgets/EricSideBar.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9298
8863f3e970a2
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
18 18
19 class EricSideBarSide(enum.Enum): 19 class EricSideBarSide(enum.Enum):
20 """ 20 """
21 Class defining the sidebar sides. 21 Class defining the sidebar sides.
22 """ 22 """
23
23 NORTH = 0 24 NORTH = 0
24 EAST = 1 25 EAST = 1
25 SOUTH = 2 26 SOUTH = 2
26 WEST = 3 27 WEST = 3
27 28
29 class EricSideBar(QWidget): 30 class EricSideBar(QWidget):
30 """ 31 """
31 Class implementing a sidebar with a widget area, that is hidden or shown, 32 Class implementing a sidebar with a widget area, that is hidden or shown,
32 if the current tab is clicked again. 33 if the current tab is clicked again.
33 """ 34 """
35
34 Version = 4 36 Version = 4
35 37
36 def __init__(self, orientation=None, 38 def __init__(
37 iconBarSize=EricIconBar.DefaultBarSize, parent=None): 39 self, orientation=None, iconBarSize=EricIconBar.DefaultBarSize, parent=None
40 ):
38 """ 41 """
39 Constructor 42 Constructor
40 43
41 @param orientation orientation of the sidebar widget 44 @param orientation orientation of the sidebar widget
42 @type EricSideBarSide 45 @type EricSideBarSide
43 @param iconBarSize size category for the bar (one of 'xs', 'sm', 'md', 46 @param iconBarSize size category for the bar (one of 'xs', 'sm', 'md',
44 'lg', 'xl', 'xxl') 47 'lg', 'xl', 'xxl')
45 @type str 48 @type str
46 @param parent parent widget 49 @param parent parent widget
47 @type QWidget 50 @type QWidget
48 """ 51 """
49 super().__init__(parent) 52 super().__init__(parent)
50 53
51 # initial layout is done for NORTH 54 # initial layout is done for NORTH
52 self.__iconBar = EricIconBar(orientation=Qt.Orientation.Horizontal, 55 self.__iconBar = EricIconBar(
53 barSize=iconBarSize) 56 orientation=Qt.Orientation.Horizontal, barSize=iconBarSize
54 57 )
58
55 self.__stackedWidget = QStackedWidget(self) 59 self.__stackedWidget = QStackedWidget(self)
56 self.__stackedWidget.setContentsMargins(0, 0, 0, 0) 60 self.__stackedWidget.setContentsMargins(0, 0, 0, 0)
57 61
58 self.layout = QBoxLayout(QBoxLayout.Direction.TopToBottom) 62 self.layout = QBoxLayout(QBoxLayout.Direction.TopToBottom)
59 self.layout.setContentsMargins(0, 0, 0, 0) 63 self.layout.setContentsMargins(0, 0, 0, 0)
60 self.layout.setSpacing(3) 64 self.layout.setSpacing(3)
61 self.layout.addWidget(self.__iconBar) 65 self.layout.addWidget(self.__iconBar)
62 self.layout.addWidget(self.__stackedWidget) 66 self.layout.addWidget(self.__stackedWidget)
63 self.setLayout(self.layout) 67 self.setLayout(self.layout)
64 68
65 self.__minimized = False 69 self.__minimized = False
66 self.__minSize = 0 70 self.__minSize = 0
67 self.__maxSize = 0 71 self.__maxSize = 0
68 self.__bigSize = QSize() 72 self.__bigSize = QSize()
69 73
70 self.__hasFocus = False 74 self.__hasFocus = False
71 # flag storing if this widget or any child has the focus 75 # flag storing if this widget or any child has the focus
72 self.__autoHide = False 76 self.__autoHide = False
73 77
74 self.__orientation = EricSideBarSide.NORTH 78 self.__orientation = EricSideBarSide.NORTH
75 if orientation is None: 79 if orientation is None:
76 orientation = EricSideBarSide.NORTH 80 orientation = EricSideBarSide.NORTH
77 self.setOrientation(orientation) 81 self.setOrientation(orientation)
78 82
79 self.__iconBar.currentChanged.connect( 83 self.__iconBar.currentChanged.connect(self.__stackedWidget.setCurrentIndex)
80 self.__stackedWidget.setCurrentIndex) 84 self.__iconBar.currentChanged.connect(self.__currentIconChanged)
81 self.__iconBar.currentChanged.connect( 85 self.__iconBar.currentClicked.connect(self.__currentIconClicked)
82 self.__currentIconChanged) 86
83 self.__iconBar.currentClicked.connect(
84 self.__currentIconClicked)
85
86 def __shrinkIt(self): 87 def __shrinkIt(self):
87 """ 88 """
88 Private method to shrink the sidebar. 89 Private method to shrink the sidebar.
89 """ 90 """
90 self.__minimized = True 91 self.__minimized = True
91 self.__bigSize = self.size() 92 self.__bigSize = self.size()
92 if self.__orientation in ( 93 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
93 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
94 ):
95 self.__minSize = self.minimumSizeHint().height() 94 self.__minSize = self.minimumSizeHint().height()
96 self.__maxSize = self.maximumHeight() 95 self.__maxSize = self.maximumHeight()
97 else: 96 else:
98 self.__minSize = self.minimumSizeHint().width() 97 self.__minSize = self.minimumSizeHint().width()
99 self.__maxSize = self.maximumWidth() 98 self.__maxSize = self.maximumWidth()
100 99
101 self.__stackedWidget.hide() 100 self.__stackedWidget.hide()
102 101
103 if self.__orientation in ( 102 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
104 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
105 ):
106 self.setFixedHeight(self.__iconBar.minimumSizeHint().height()) 103 self.setFixedHeight(self.__iconBar.minimumSizeHint().height())
107 else: 104 else:
108 self.setFixedWidth(self.__iconBar.minimumSizeHint().width()) 105 self.setFixedWidth(self.__iconBar.minimumSizeHint().width())
109 106
110 def __expandIt(self): 107 def __expandIt(self):
111 """ 108 """
112 Private method to expand the sidebar. 109 Private method to expand the sidebar.
113 """ 110 """
114 self.__minimized = False 111 self.__minimized = False
115 self.__stackedWidget.show() 112 self.__stackedWidget.show()
116 self.resize(self.__bigSize) 113 self.resize(self.__bigSize)
117 if self.__orientation in ( 114 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
118 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
119 ):
120 minSize = max(self.__minSize, self.minimumSizeHint().height()) 115 minSize = max(self.__minSize, self.minimumSizeHint().height())
121 self.setMinimumHeight(minSize) 116 self.setMinimumHeight(minSize)
122 self.setMaximumHeight(self.__maxSize) 117 self.setMaximumHeight(self.__maxSize)
123 else: 118 else:
124 minSize = max(self.__minSize, self.minimumSizeHint().width()) 119 minSize = max(self.__minSize, self.minimumSizeHint().width())
125 self.setMinimumWidth(minSize) 120 self.setMinimumWidth(minSize)
126 self.setMaximumWidth(self.__maxSize) 121 self.setMaximumWidth(self.__maxSize)
127 122
128 def isMinimized(self): 123 def isMinimized(self):
129 """ 124 """
130 Public method to check the minimized state. 125 Public method to check the minimized state.
131 126
132 @return flag indicating the minimized state (boolean) 127 @return flag indicating the minimized state (boolean)
133 """ 128 """
134 return self.__minimized 129 return self.__minimized
135 130
136 @pyqtSlot(int) 131 @pyqtSlot(int)
137 def __currentIconChanged(self, index): 132 def __currentIconChanged(self, index):
138 """ 133 """
139 Private slot to handle a change of the current icon. 134 Private slot to handle a change of the current icon.
140 135
141 @param index index of the current icon 136 @param index index of the current icon
142 @type int 137 @type int
143 """ 138 """
144 if self.isMinimized(): 139 if self.isMinimized():
145 self.__expandIt() 140 self.__expandIt()
146 141
147 @pyqtSlot(int) 142 @pyqtSlot(int)
148 def __currentIconClicked(self, index): 143 def __currentIconClicked(self, index):
149 """ 144 """
150 Private slot to handle a click of the current icon. 145 Private slot to handle a click of the current icon.
151 146
152 @param index index of the clicked icon 147 @param index index of the clicked icon
153 @type int 148 @type int
154 """ 149 """
155 if self.isMinimized(): 150 if self.isMinimized():
156 self.__expandIt() 151 self.__expandIt()
157 else: 152 else:
158 self.__shrinkIt() 153 self.__shrinkIt()
159 154
160 def addTab(self, widget, icon, label=None): 155 def addTab(self, widget, icon, label=None):
161 """ 156 """
162 Public method to add a tab to the sidebar. 157 Public method to add a tab to the sidebar.
163 158
164 @param widget reference to the widget to add 159 @param widget reference to the widget to add
165 @type QWidget 160 @type QWidget
166 @param icon reference to the icon of the widget 161 @param icon reference to the icon of the widget
167 @type QIcon 162 @type QIcon
168 @param label the label text of the widget 163 @param label the label text of the widget
169 @type str 164 @type str
170 """ 165 """
171 self.__iconBar.addIcon(icon, label) 166 self.__iconBar.addIcon(icon, label)
172 self.__stackedWidget.addWidget(widget) 167 self.__stackedWidget.addWidget(widget)
173 if self.__orientation in ( 168 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
174 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
175 ):
176 self.__minSize = self.minimumSizeHint().height() 169 self.__minSize = self.minimumSizeHint().height()
177 else: 170 else:
178 self.__minSize = self.minimumSizeHint().width() 171 self.__minSize = self.minimumSizeHint().width()
179 172
180 def insertTab(self, index, widget, icon, label=None): 173 def insertTab(self, index, widget, icon, label=None):
181 """ 174 """
182 Public method to insert a tab into the sidebar. 175 Public method to insert a tab into the sidebar.
183 176
184 @param index the index to insert the tab at 177 @param index the index to insert the tab at
185 @type int 178 @type int
186 @param widget reference to the widget to insert 179 @param widget reference to the widget to insert
187 @type QWidget 180 @type QWidget
188 @param icon reference to the icon of the widget 181 @param icon reference to the icon of the widget
189 @type QIcon 182 @type QIcon
190 @param label the label text of the widget 183 @param label the label text of the widget
191 @type str 184 @type str
192 """ 185 """
193 self.__iconBar.insertIcon(index, icon, label) 186 self.__iconBar.insertIcon(index, icon, label)
194 187
195 self.__stackedWidget.insertWidget(index, widget) 188 self.__stackedWidget.insertWidget(index, widget)
196 if self.__orientation in ( 189 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
197 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
198 ):
199 self.__minSize = self.minimumSizeHint().height() 190 self.__minSize = self.minimumSizeHint().height()
200 else: 191 else:
201 self.__minSize = self.minimumSizeHint().width() 192 self.__minSize = self.minimumSizeHint().width()
202 193
203 def removeTab(self, index): 194 def removeTab(self, index):
204 """ 195 """
205 Public method to remove a tab. 196 Public method to remove a tab.
206 197
207 @param index the index of the tab to remove 198 @param index the index of the tab to remove
208 @type int 199 @type int
209 """ 200 """
210 self.__stackedWidget.removeWidget(self.__stackedWidget.widget(index)) 201 self.__stackedWidget.removeWidget(self.__stackedWidget.widget(index))
211 self.__iconBar.removeIcon(index) 202 self.__iconBar.removeIcon(index)
212 if self.__orientation in ( 203 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
213 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
214 ):
215 self.__minSize = self.minimumSizeHint().height() 204 self.__minSize = self.minimumSizeHint().height()
216 else: 205 else:
217 self.__minSize = self.minimumSizeHint().width() 206 self.__minSize = self.minimumSizeHint().width()
218 207
219 def clear(self): 208 def clear(self):
220 """ 209 """
221 Public method to remove all tabs. 210 Public method to remove all tabs.
222 """ 211 """
223 while self.count() > 0: 212 while self.count() > 0:
224 self.removeTab(0) 213 self.removeTab(0)
225 214
226 def prevTab(self): 215 def prevTab(self):
227 """ 216 """
228 Public slot used to show the previous tab. 217 Public slot used to show the previous tab.
229 """ 218 """
230 ind = self.currentIndex() - 1 219 ind = self.currentIndex() - 1
231 if ind == -1: 220 if ind == -1:
232 ind = self.count() - 1 221 ind = self.count() - 1
233 222
234 self.setCurrentIndex(ind) 223 self.setCurrentIndex(ind)
235 self.currentWidget().setFocus() 224 self.currentWidget().setFocus()
236 225
237 def nextTab(self): 226 def nextTab(self):
238 """ 227 """
239 Public slot used to show the next tab. 228 Public slot used to show the next tab.
240 """ 229 """
241 ind = self.currentIndex() + 1 230 ind = self.currentIndex() + 1
242 if ind == self.count(): 231 if ind == self.count():
243 ind = 0 232 ind = 0
244 233
245 self.setCurrentIndex(ind) 234 self.setCurrentIndex(ind)
246 self.currentWidget().setFocus() 235 self.currentWidget().setFocus()
247 236
248 def count(self): 237 def count(self):
249 """ 238 """
250 Public method to get the number of tabs. 239 Public method to get the number of tabs.
251 240
252 @return number of tabs in the sidebar (integer) 241 @return number of tabs in the sidebar (integer)
253 """ 242 """
254 return self.__iconBar.count() 243 return self.__iconBar.count()
255 244
256 def currentIndex(self): 245 def currentIndex(self):
257 """ 246 """
258 Public method to get the index of the current tab. 247 Public method to get the index of the current tab.
259 248
260 @return index of the current tab (integer) 249 @return index of the current tab (integer)
261 """ 250 """
262 return self.__stackedWidget.currentIndex() 251 return self.__stackedWidget.currentIndex()
263 252
264 def setCurrentIndex(self, index): 253 def setCurrentIndex(self, index):
265 """ 254 """
266 Public slot to set the current index. 255 Public slot to set the current index.
267 256
268 @param index the index to set as the current index (integer) 257 @param index the index to set as the current index (integer)
269 """ 258 """
270 self.__iconBar.setCurrentIndex(index) 259 self.__iconBar.setCurrentIndex(index)
271 self.__stackedWidget.setCurrentIndex(index) 260 self.__stackedWidget.setCurrentIndex(index)
272 if self.isMinimized(): 261 if self.isMinimized():
273 self.__expandIt() 262 self.__expandIt()
274 263
275 def currentWidget(self): 264 def currentWidget(self):
276 """ 265 """
277 Public method to get a reference to the current widget. 266 Public method to get a reference to the current widget.
278 267
279 @return reference to the current widget (QWidget) 268 @return reference to the current widget (QWidget)
280 """ 269 """
281 return self.__stackedWidget.currentWidget() 270 return self.__stackedWidget.currentWidget()
282 271
283 def setCurrentWidget(self, widget): 272 def setCurrentWidget(self, widget):
284 """ 273 """
285 Public slot to set the current widget. 274 Public slot to set the current widget.
286 275
287 @param widget reference to the widget to become the current widget 276 @param widget reference to the widget to become the current widget
288 (QWidget) 277 (QWidget)
289 """ 278 """
290 self.__stackedWidget.setCurrentWidget(widget) 279 self.__stackedWidget.setCurrentWidget(widget)
291 self.__iconBar.setCurrentIndex(self.__stackedWidget.currentIndex()) 280 self.__iconBar.setCurrentIndex(self.__stackedWidget.currentIndex())
292 if self.isMinimized(): 281 if self.isMinimized():
293 self.__expandIt() 282 self.__expandIt()
294 283
295 def indexOf(self, widget): 284 def indexOf(self, widget):
296 """ 285 """
297 Public method to get the index of the given widget. 286 Public method to get the index of the given widget.
298 287
299 @param widget reference to the widget to get the index of (QWidget) 288 @param widget reference to the widget to get the index of (QWidget)
300 @return index of the given widget (integer) 289 @return index of the given widget (integer)
301 """ 290 """
302 return self.__stackedWidget.indexOf(widget) 291 return self.__stackedWidget.indexOf(widget)
303 292
304 def orientation(self): 293 def orientation(self):
305 """ 294 """
306 Public method to get the orientation of the sidebar. 295 Public method to get the orientation of the sidebar.
307 296
308 @return orientation of the sidebar 297 @return orientation of the sidebar
309 @rtype EricSideBarSide 298 @rtype EricSideBarSide
310 """ 299 """
311 return self.__orientation 300 return self.__orientation
312 301
313 def setOrientation(self, orient): 302 def setOrientation(self, orient):
314 """ 303 """
315 Public method to set the orientation of the sidebar. 304 Public method to set the orientation of the sidebar.
316 305
317 @param orient orientation of the sidebar 306 @param orient orientation of the sidebar
328 self.layout.setDirection(QBoxLayout.Direction.BottomToTop) 317 self.layout.setDirection(QBoxLayout.Direction.BottomToTop)
329 elif orient == EricSideBarSide.WEST: 318 elif orient == EricSideBarSide.WEST:
330 self.__iconBar.setOrientation(Qt.Orientation.Vertical) 319 self.__iconBar.setOrientation(Qt.Orientation.Vertical)
331 self.layout.setDirection(QBoxLayout.Direction.LeftToRight) 320 self.layout.setDirection(QBoxLayout.Direction.LeftToRight)
332 self.__orientation = orient 321 self.__orientation = orient
333 322
334 def widget(self, index): 323 def widget(self, index):
335 """ 324 """
336 Public method to get a reference to the widget associated with a tab. 325 Public method to get a reference to the widget associated with a tab.
337 326
338 @param index index of the tab (integer) 327 @param index index of the tab (integer)
339 @return reference to the widget (QWidget) 328 @return reference to the widget (QWidget)
340 """ 329 """
341 return self.__stackedWidget.widget(index) 330 return self.__stackedWidget.widget(index)
342 331
343 def setIconBarColor(self, color): 332 def setIconBarColor(self, color):
344 """ 333 """
345 Public method to set the icon bar color. 334 Public method to set the icon bar color.
346 335
347 @param color icon bar color 336 @param color icon bar color
348 @type QColor 337 @type QColor
349 """ 338 """
350 self.__iconBar.setColor(color) 339 self.__iconBar.setColor(color)
351 340
352 def iconBarColor(self): 341 def iconBarColor(self):
353 """ 342 """
354 Public method to get the icon bar color. 343 Public method to get the icon bar color.
355 344
356 @return icon bar color 345 @return icon bar color
357 @rtype QColor 346 @rtype QColor
358 """ 347 """
359 return self.__iconBar.color() 348 return self.__iconBar.color()
360 349
361 def setIconBarSize(self, barSize): 350 def setIconBarSize(self, barSize):
362 """ 351 """
363 Public method to set the icon bar size. 352 Public method to set the icon bar size.
364 353
365 @param barSize size category for the bar (one of 'xs', 'sm', 'md', 354 @param barSize size category for the bar (one of 'xs', 'sm', 'md',
366 'lg', 'xl', 'xxl') 355 'lg', 'xl', 'xxl')
367 @type str 356 @type str
368 """ 357 """
369 self.__iconBar.setBarSize(barSize) 358 self.__iconBar.setBarSize(barSize)
370 if self.isMinimized(): 359 if self.isMinimized():
371 self.__shrinkIt() 360 self.__shrinkIt()
372 else: 361 else:
373 self.__expandIt() 362 self.__expandIt()
374 363
375 def barSize(self): 364 def barSize(self):
376 """ 365 """
377 Public method to get the icon bar size. 366 Public method to get the icon bar size.
378 367
379 @return barSize size category for the bar (one of 'xs', 'sm', 'md', 368 @return barSize size category for the bar (one of 'xs', 'sm', 'md',
380 'lg', 'xl', 'xxl') 369 'lg', 'xl', 'xxl')
381 @rtype str 370 @rtype str
382 """ 371 """
383 return self.__iconBar.barSize() 372 return self.__iconBar.barSize()
384 373
385 def saveState(self): 374 def saveState(self):
386 """ 375 """
387 Public method to save the state of the sidebar. 376 Public method to save the state of the sidebar.
388 377
389 @return saved state as a byte array (QByteArray) 378 @return saved state as a byte array (QByteArray)
390 """ 379 """
391 self.__bigSize = self.size() 380 self.__bigSize = self.size()
392 if self.__orientation in ( 381 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
393 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
394 ):
395 self.__minSize = self.minimumSizeHint().height() 382 self.__minSize = self.minimumSizeHint().height()
396 self.__maxSize = self.maximumHeight() 383 self.__maxSize = self.maximumHeight()
397 else: 384 else:
398 self.__minSize = self.minimumSizeHint().width() 385 self.__minSize = self.minimumSizeHint().width()
399 self.__maxSize = self.maximumWidth() 386 self.__maxSize = self.maximumWidth()
400 387
401 dataDict = { 388 dataDict = {
402 "version": self.Version, 389 "version": self.Version,
403 "minimized": self.__minimized, 390 "minimized": self.__minimized,
404 "big_size": [self.__bigSize.width(), self.__bigSize.height()], 391 "big_size": [self.__bigSize.width(), self.__bigSize.height()],
405 "min_size": self.__minSize, 392 "min_size": self.__minSize,
406 "max_size": self.__maxSize, 393 "max_size": self.__maxSize,
407 } 394 }
408 data = json.dumps(dataDict) 395 data = json.dumps(dataDict)
409 396
410 return data 397 return data
411 398
412 def restoreState(self, state): 399 def restoreState(self, state):
413 """ 400 """
414 Public method to restore the state of the sidebar. 401 Public method to restore the state of the sidebar.
415 402
416 @param state byte array containing the saved state (QByteArray) 403 @param state byte array containing the saved state (QByteArray)
417 @return flag indicating success (boolean) 404 @return flag indicating success (boolean)
418 """ 405 """
419 if not isinstance(state, str) or state == "": 406 if not isinstance(state, str) or state == "":
420 return False 407 return False
421 408
422 try: 409 try:
423 stateDict = json.loads(state) 410 stateDict = json.loads(state)
424 except json.JSONDecodeError: 411 except json.JSONDecodeError:
425 return False 412 return False
426 413
427 if not stateDict: 414 if not stateDict:
428 return False 415 return False
429 416
430 if self.__orientation in ( 417 if self.__orientation in (EricSideBarSide.NORTH, EricSideBarSide.SOUTH):
431 EricSideBarSide.NORTH, EricSideBarSide.SOUTH
432 ):
433 minSize = self.layout.minimumSize().height() 418 minSize = self.layout.minimumSize().height()
434 maxSize = self.maximumHeight() 419 maxSize = self.maximumHeight()
435 else: 420 else:
436 minSize = self.layout.minimumSize().width() 421 minSize = self.layout.minimumSize().width()
437 maxSize = self.maximumWidth() 422 maxSize = self.maximumWidth()
438 423
439 if stateDict["version"] in (2, 3, 4): 424 if stateDict["version"] in (2, 3, 4):
440 if stateDict["minimized"] and not self.__minimized: 425 if stateDict["minimized"] and not self.__minimized:
441 self.__shrinkIt() 426 self.__shrinkIt()
442 427
443 self.__bigSize = QSize(*stateDict["big_size"]) 428 self.__bigSize = QSize(*stateDict["big_size"])
444 self.__minSize = max(stateDict["min_size"], minSize) 429 self.__minSize = max(stateDict["min_size"], minSize)
445 self.__maxSize = max(stateDict["max_size"], maxSize) 430 self.__maxSize = max(stateDict["max_size"], maxSize)
446 431
447 if not stateDict["minimized"]: 432 if not stateDict["minimized"]:
448 self.__expandIt() 433 self.__expandIt()
449 434
450 return True 435 return True
451 436
452 return False 437 return False

eric ide

mercurial