UI/BrowserModel.py

changeset 3012
d177226027e2
parent 2965
d133c7edd88a
child 3030
4a0a82ddd9d2
child 3057
10516539f238
equal deleted inserted replaced
3011:18292228c724 3012:d177226027e2
9 9
10 import sys 10 import sys
11 import os 11 import os
12 import fnmatch 12 import fnmatch
13 13
14 from PyQt4.QtCore import QDir, QModelIndex, QAbstractItemModel, QFileSystemWatcher, Qt 14 from PyQt4.QtCore import QDir, QModelIndex, QAbstractItemModel, \
15 QFileSystemWatcher, Qt
15 from PyQt4.QtGui import QImageReader, QApplication, QFont 16 from PyQt4.QtGui import QImageReader, QApplication, QFont
16 17
17 import UI.PixmapCache 18 import UI.PixmapCache
18 import Preferences 19 import Preferences
19 import Utilities 20 import Utilities
36 def __init__(self, parent=None, nopopulate=False): 37 def __init__(self, parent=None, nopopulate=False):
37 """ 38 """
38 Constructor 39 Constructor
39 40
40 @param parent reference to parent object (QObject) 41 @param parent reference to parent object (QObject)
41 @keyparam nopopulate flag indicating to not populate the model (boolean) 42 @keyparam nopopulate flag indicating to not populate the model
43 (boolean)
42 """ 44 """
43 super().__init__(parent) 45 super().__init__(parent)
44 46
45 self.progDir = None 47 self.progDir = None
46 self.watchedItems = {} 48 self.watchedItems = {}
82 item = index.internalPointer() 84 item = index.internalPointer()
83 if index.column() < item.columnCount(): 85 if index.column() < item.columnCount():
84 return item.data(index.column()) 86 return item.data(index.column())
85 elif index.column() == item.columnCount() and \ 87 elif index.column() == item.columnCount() and \
86 index.column() < self.columnCount(self.parent(index)): 88 index.column() < self.columnCount(self.parent(index)):
87 # This is for the case where an item under a multi-column parent 89 # This is for the case where an item under a multi-column
88 # doesn't have a value for all the columns 90 # parent doesn't have a value for all the columns
89 return "" 91 return ""
90 elif role == Qt.DecorationRole: 92 elif role == Qt.DecorationRole:
91 if index.column() == 0: 93 if index.column() == 0:
92 return index.internalPointer().getIcon() 94 return index.internalPointer().getIcon()
93 elif role == Qt.FontRole: 95 elif role == Qt.FontRole:
282 if path not in self.watchedItems: 284 if path not in self.watchedItems:
283 # just ignore the situation we don't have a reference to the item 285 # just ignore the situation we don't have a reference to the item
284 return 286 return
285 287
286 if Preferences.getUI("BrowsersListHiddenFiles"): 288 if Preferences.getUI("BrowsersListHiddenFiles"):
287 filter = QDir.Filters(QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot) 289 filter = QDir.Filters(
290 QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot)
288 else: 291 else:
289 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot) 292 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)
290 293
291 for itm in self.watchedItems[path]: 294 for itm in self.watchedItems[path]:
292 oldCnt = itm.childCount() 295 oldCnt = itm.childCount()
350 self.toplevelDirs = [] 353 self.toplevelDirs = []
351 tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs') 354 tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs')
352 if tdp: 355 if tdp:
353 self.toplevelDirs = tdp 356 self.toplevelDirs = tdp
354 else: 357 else:
355 self.toplevelDirs.append(Utilities.toNativeSeparators(QDir.homePath())) 358 self.toplevelDirs.append(
359 Utilities.toNativeSeparators(QDir.homePath()))
356 for d in QDir.drives(): 360 for d in QDir.drives():
357 self.toplevelDirs.append(Utilities.toNativeSeparators( 361 self.toplevelDirs.append(Utilities.toNativeSeparators(
358 d.absoluteFilePath())) 362 d.absoluteFilePath()))
359 363
360 for d in self.toplevelDirs: 364 for d in self.toplevelDirs:
361 itm = BrowserDirectoryItem(self.rootItem, d) 365 itm = BrowserDirectoryItem(self.rootItem, d)
362 self._addItem(itm, self.rootItem) 366 self._addItem(itm, self.rootItem)
363 367
364 def programChange(self, dirname): 368 def programChange(self, dirname):
365 """ 369 """
366 Public method to change the entry for the directory of file being debugged. 370 Public method to change the entry for the directory of file being
371 debugged.
367 372
368 @param dirname name of the directory containing the file (string) 373 @param dirname name of the directory containing the file (string)
369 """ 374 """
370 if self.progDir: 375 if self.progDir:
371 if dirname == self.progDir.dirName(): 376 if dirname == self.progDir.dirName():
372 return 377 return
373 378
374 # remove old entry 379 # remove old entry
375 self._removeWatchedItem(self.progDir) 380 self._removeWatchedItem(self.progDir)
376 self.beginRemoveRows(QModelIndex(), self.progDir.row(), self.progDir.row()) 381 self.beginRemoveRows(
382 QModelIndex(), self.progDir.row(), self.progDir.row())
377 self.rootItem.removeChild(self.progDir) 383 self.rootItem.removeChild(self.progDir)
378 self.endRemoveRows() 384 self.endRemoveRows()
379 self.progDir = None 385 self.progDir = None
380 386
381 itm = BrowserDirectoryItem(self.rootItem, dirname) 387 itm = BrowserDirectoryItem(self.rootItem, dirname)
395 401
396 def removeToplevelDir(self, index): 402 def removeToplevelDir(self, index):
397 """ 403 """
398 Public method to remove a toplevel directory. 404 Public method to remove a toplevel directory.
399 405
400 @param index index of the toplevel directory to be removed (QModelIndex) 406 @param index index of the toplevel directory to be removed
407 (QModelIndex)
401 """ 408 """
402 if not index.isValid(): 409 if not index.isValid():
403 return 410 return
404 411
405 item = index.internalPointer() 412 item = index.internalPointer()
473 self._addWatchedItem(parentItem) 480 self._addWatchedItem(parentItem)
474 481
475 qdir = QDir(parentItem.dirName()) 482 qdir = QDir(parentItem.dirName())
476 483
477 if Preferences.getUI("BrowsersListHiddenFiles"): 484 if Preferences.getUI("BrowsersListHiddenFiles"):
478 filter = QDir.Filters(QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot) 485 filter = QDir.Filters(
486 QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot)
479 else: 487 else:
480 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot) 488 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)
481 entryInfoList = qdir.entryInfoList(filter) 489 entryInfoList = qdir.entryInfoList(filter)
482 if len(entryInfoList) > 0: 490 if len(entryInfoList) > 0:
483 if repopulate: 491 if repopulate:
484 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 492 self.beginInsertRows(
493 self.createIndex(parentItem.row(), 0, parentItem),
485 0, len(entryInfoList) - 1) 494 0, len(entryInfoList) - 1)
486 for f in entryInfoList: 495 for f in entryInfoList:
487 if f.isDir(): 496 if f.isDir():
488 node = BrowserDirectoryItem(parentItem, 497 node = BrowserDirectoryItem(parentItem,
489 Utilities.toNativeSeparators(f.absoluteFilePath()), 498 Utilities.toNativeSeparators(f.absoluteFilePath()),
490 False) 499 False)
491 else: 500 else:
492 fileFilters = Preferences.getUI("BrowsersFileFilters").split(";") 501 fileFilters = \
502 Preferences.getUI("BrowsersFileFilters").split(";")
493 if fileFilters: 503 if fileFilters:
494 fn = f.fileName() 504 fn = f.fileName()
495 if any([fnmatch.fnmatch(fn, ff.strip()) 505 if any([fnmatch.fnmatch(fn, ff.strip())
496 for ff in fileFilters]): 506 for ff in fileFilters]):
497 continue 507 continue
508 @param parentItem reference to the sys.path item to be populated 518 @param parentItem reference to the sys.path item to be populated
509 @param repopulate flag indicating a repopulation (boolean) 519 @param repopulate flag indicating a repopulation (boolean)
510 """ 520 """
511 if len(sys.path) > 0: 521 if len(sys.path) > 0:
512 if repopulate: 522 if repopulate:
513 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 523 self.beginInsertRows(
524 self.createIndex(parentItem.row(), 0, parentItem),
514 0, len(sys.path) - 1) 525 0, len(sys.path) - 1)
515 for p in sys.path: 526 for p in sys.path:
516 if p == '': 527 if p == '':
517 p = os.getcwd() 528 p = os.getcwd()
518 529
539 return 550 return
540 551
541 keys = list(dict.keys()) 552 keys = list(dict.keys())
542 if len(keys) > 0: 553 if len(keys) > 0:
543 if repopulate: 554 if repopulate:
544 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 555 self.beginInsertRows(
556 self.createIndex(parentItem.row(), 0, parentItem),
545 0, len(keys) - 1) 557 0, len(keys) - 1)
546 for key in keys: 558 for key in keys:
547 if key.startswith("@@"): 559 if key.startswith("@@"):
548 # special treatment done later 560 # special treatment done later
549 continue 561 continue
587 for name in list(cl.methods.keys()): 599 for name in list(cl.methods.keys()):
588 keys.append((name, 'm')) 600 keys.append((name, 'm'))
589 601
590 if len(keys) > 0: 602 if len(keys) > 0:
591 if repopulate: 603 if repopulate:
592 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 604 self.beginInsertRows(
605 self.createIndex(parentItem.row(), 0, parentItem),
593 0, len(keys) - 1) 606 0, len(keys) - 1)
594 for key, kind in keys: 607 for key, kind in keys:
595 if kind == 'c': 608 if kind == 'c':
596 node = BrowserClassItem(parentItem, cl.classes[key], file_) 609 node = BrowserClassItem(parentItem, cl.classes[key], file_)
597 elif kind == 'm': 610 elif kind == 'm':
598 node = BrowserMethodItem(parentItem, cl.methods[key], file_) 611 node = BrowserMethodItem(parentItem, cl.methods[key],
612 file_)
599 self._addItem(node, parentItem) 613 self._addItem(node, parentItem)
600 if repopulate: 614 if repopulate:
601 self.endInsertRows() 615 self.endInsertRows()
602 616
603 if len(cl.attributes): 617 if len(cl.attributes):
641 for name in list(fn.methods.keys()): 655 for name in list(fn.methods.keys()):
642 keys.append((name, 'm')) 656 keys.append((name, 'm'))
643 657
644 if len(keys) > 0: 658 if len(keys) > 0:
645 if repopulate: 659 if repopulate:
646 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 660 self.beginInsertRows(
661 self.createIndex(parentItem.row(), 0, parentItem),
647 0, len(keys) - 1) 662 0, len(keys) - 1)
648 for key, kind in keys: 663 for key, kind in keys:
649 if kind == 'c': 664 if kind == 'c':
650 node = BrowserClassItem(parentItem, fn.classes[key], file_) 665 node = BrowserClassItem(parentItem, fn.classes[key], file_)
651 elif kind == 'm': 666 elif kind == 'm':
652 node = BrowserMethodItem(parentItem, fn.methods[key], file_) 667 node = BrowserMethodItem(parentItem, fn.methods[key],
668 file_)
653 self._addItem(node, parentItem) 669 self._addItem(node, parentItem)
654 if repopulate: 670 if repopulate:
655 self.endInsertRows() 671 self.endInsertRows()
656 672
657 def populateClassAttributesItem(self, parentItem, repopulate=False): 673 def populateClassAttributesItem(self, parentItem, repopulate=False):
658 """ 674 """
659 Public method to populate a class attributes item's subtree. 675 Public method to populate a class attributes item's subtree.
660 676
661 @param parentItem reference to the class attributes item to be populated 677 @param parentItem reference to the class attributes item to be
678 populated
662 @param repopulate flag indicating a repopulation (boolean) 679 @param repopulate flag indicating a repopulation (boolean)
663 """ 680 """
664 classAttributes = parentItem.isClassAttributes() 681 classAttributes = parentItem.isClassAttributes()
665 attributes = parentItem.attributes() 682 attributes = parentItem.attributes()
666 if not attributes: 683 if not attributes:
667 return 684 return
668 685
669 keys = list(attributes.keys()) 686 keys = list(attributes.keys())
670 if len(keys) > 0: 687 if len(keys) > 0:
671 if repopulate: 688 if repopulate:
672 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 689 self.beginInsertRows(
690 self.createIndex(parentItem.row(), 0, parentItem),
673 0, len(keys) - 1) 691 0, len(keys) - 1)
674 for key in keys: 692 for key in keys:
675 node = BrowserClassAttributeItem(parentItem, attributes[key], 693 node = BrowserClassAttributeItem(parentItem, attributes[key],
676 classAttributes) 694 classAttributes)
677 self._addItem(node, parentItem) 695 self._addItem(node, parentItem)
1081 Public method to check, if this file is a Python script. 1099 Public method to check, if this file is a Python script.
1082 1100
1083 @return flag indicating a Python file (boolean) 1101 @return flag indicating a Python file (boolean)
1084 """ 1102 """
1085 return self.fileext in Preferences.getPython("PythonExtensions") or \ 1103 return self.fileext in Preferences.getPython("PythonExtensions") or \
1086 (self.fileext == "" and self.sourceLanguage in ["Python", "Python2"]) 1104 (self.fileext == "" and self.sourceLanguage in ["Python",
1105 "Python2"])
1087 1106
1088 def isPython3File(self): 1107 def isPython3File(self):
1089 """ 1108 """
1090 Public method to check, if this file is a Python3 script. 1109 Public method to check, if this file is a Python3 script.
1091 1110
1197 if Preferences.getUI("BrowsersListFoldersFirst"): 1216 if Preferences.getUI("BrowsersListFoldersFirst"):
1198 return order == Qt.DescendingOrder 1217 return order == Qt.DescendingOrder
1199 1218
1200 if issubclass(other.__class__, BrowserFileItem): 1219 if issubclass(other.__class__, BrowserFileItem):
1201 sinit = os.path.basename(self._filename).startswith('__init__.py') 1220 sinit = os.path.basename(self._filename).startswith('__init__.py')
1202 oinit = os.path.basename(other.fileName()).startswith('__init__.py') 1221 oinit = \
1222 os.path.basename(other.fileName()).startswith('__init__.py')
1203 if sinit and not oinit: 1223 if sinit and not oinit:
1204 return order == Qt.AscendingOrder 1224 return order == Qt.AscendingOrder
1205 if not sinit and oinit: 1225 if not sinit and oinit:
1206 return order == Qt.DescendingOrder 1226 return order == Qt.DescendingOrder
1207 1227
1239 self.name = name 1259 self.name = name
1240 self._classObject = cl 1260 self._classObject = cl
1241 self._filename = filename 1261 self._filename = filename
1242 1262
1243 import Utilities.ClassBrowsers.ClbrBaseClasses 1263 import Utilities.ClassBrowsers.ClbrBaseClasses
1244 self.isfunction = isinstance(self._classObject, 1264 self.isfunction = isinstance(
1245 Utilities.ClassBrowsers.ClbrBaseClasses.Function) 1265 self._classObject,
1246 self.ismodule = isinstance(self._classObject, 1266 Utilities.ClassBrowsers.ClbrBaseClasses.Function)
1247 Utilities.ClassBrowsers.ClbrBaseClasses.Module) 1267 self.ismodule = isinstance(
1268 self._classObject,
1269 Utilities.ClassBrowsers.ClbrBaseClasses.Module)
1248 if self.isfunction: 1270 if self.isfunction:
1249 if cl.isPrivate(): 1271 if cl.isPrivate():
1250 self.icon = UI.PixmapCache.getIcon("method_private.png") 1272 self.icon = UI.PixmapCache.getIcon("method_private.png")
1251 elif cl.isProtected(): 1273 elif cl.isProtected():
1252 self.icon = UI.PixmapCache.getIcon("method_protected.png") 1274 self.icon = UI.PixmapCache.getIcon("method_protected.png")
1253 else: 1275 else:
1254 self.icon = UI.PixmapCache.getIcon("method.png") 1276 self.icon = UI.PixmapCache.getIcon("method.png")
1255 self.itemData[0] = "{0}({1})".format( 1277 self.itemData[0] = "{0}({1})".format(
1256 name, ", ".join(self._classObject.parameters)) 1278 name, ", ".join(self._classObject.parameters))
1257 # if no defaults are wanted 1279 # if no defaults are wanted
1258 # ....format(name, ", ".join([e.split('=')[0].strip() \ 1280 # ....format(name,
1259 # for e in self._classObject.parameters])) 1281 # ", ".join([e.split('=')[0].strip() \
1282 # for e in self._classObject.parameters]))
1260 elif self.ismodule: 1283 elif self.ismodule:
1261 self.icon = UI.PixmapCache.getIcon("module.png") 1284 self.icon = UI.PixmapCache.getIcon("module.png")
1262 else: 1285 else:
1263 if cl.isPrivate(): 1286 if cl.isPrivate():
1264 self.icon = UI.PixmapCache.getIcon("class_private.png") 1287 self.icon = UI.PixmapCache.getIcon("class_private.png")
1316 """ 1339 """
1317 if issubclass(other.__class__, BrowserCodingItem) or \ 1340 if issubclass(other.__class__, BrowserCodingItem) or \
1318 issubclass(other.__class__, BrowserClassAttributesItem): 1341 issubclass(other.__class__, BrowserClassAttributesItem):
1319 return order == Qt.DescendingOrder 1342 return order == Qt.DescendingOrder
1320 1343
1321 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0: 1344 if Preferences.getUI("BrowsersListContentsByOccurrence") and \
1345 column == 0:
1322 if order == Qt.AscendingOrder: 1346 if order == Qt.AscendingOrder:
1323 return self.lineno() < other.lineno() 1347 return self.lineno() < other.lineno()
1324 else: 1348 else:
1325 return self.lineno() > other.lineno() 1349 return self.lineno() > other.lineno()
1326 1350
1368 else: 1392 else:
1369 self.icon = UI.PixmapCache.getIcon("method.png") 1393 self.icon = UI.PixmapCache.getIcon("method.png")
1370 self.itemData[0] = "{0}({1})".format( 1394 self.itemData[0] = "{0}({1})".format(
1371 name, ", ".join(self._functionObject.parameters)) 1395 name, ", ".join(self._functionObject.parameters))
1372 # if no defaults are wanted 1396 # if no defaults are wanted
1373 # ....format(name, ", ".join( 1397 # ....format(name,
1374 # [e.split('=')[0].strip() for e in self._functionObject.parameters])) 1398 # ", ".join([e.split('=')[0].strip()
1399 # for e in self._functionObject.parameters]))
1375 if self._functionObject and \ 1400 if self._functionObject and \
1376 (self._functionObject.methods or self._functionObject.classes): 1401 (self._functionObject.methods or self._functionObject.classes):
1377 self._populated = False 1402 self._populated = False
1378 self._lazyPopulation = True 1403 self._lazyPopulation = True
1379 1404
1424 if other.name.startswith('__init__'): 1449 if other.name.startswith('__init__'):
1425 return order == Qt.DescendingOrder 1450 return order == Qt.DescendingOrder
1426 elif issubclass(other.__class__, BrowserClassAttributesItem): 1451 elif issubclass(other.__class__, BrowserClassAttributesItem):
1427 return order == Qt.DescendingOrder 1452 return order == Qt.DescendingOrder
1428 1453
1429 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0: 1454 if Preferences.getUI("BrowsersListContentsByOccurrence") and \
1455 column == 0:
1430 if order == Qt.AscendingOrder: 1456 if order == Qt.AscendingOrder:
1431 return self.lineno() < other.lineno() 1457 return self.lineno() < other.lineno()
1432 else: 1458 else:
1433 return self.lineno() > other.lineno() 1459 return self.lineno() > other.lineno()
1434 1460
1575 @param other reference to item to compare against (BrowserItem) 1601 @param other reference to item to compare against (BrowserItem)
1576 @param column column number to use for the comparison (integer) 1602 @param column column number to use for the comparison (integer)
1577 @param order sort order (Qt.SortOrder) (for special sorting) 1603 @param order sort order (Qt.SortOrder) (for special sorting)
1578 @return true, if this item is less than other (boolean) 1604 @return true, if this item is less than other (boolean)
1579 """ 1605 """
1580 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0: 1606 if Preferences.getUI("BrowsersListContentsByOccurrence") and \
1607 column == 0:
1581 if order == Qt.AscendingOrder: 1608 if order == Qt.AscendingOrder:
1582 return self.lineno() < other.lineno() 1609 return self.lineno() < other.lineno()
1583 else: 1610 else:
1584 return self.lineno() > other.lineno() 1611 return self.lineno() > other.lineno()
1585 1612

eric ide

mercurial