UI/BrowserModel.py

branch
Py2 comp.
changeset 3057
10516539f238
parent 2847
1843ef6e2656
parent 3012
d177226027e2
child 3058
0a02c433f52d
equal deleted inserted replaced
3056:9986ec0e559a 3057:10516539f238
11 11
12 import sys 12 import sys
13 import os 13 import os
14 import fnmatch 14 import fnmatch
15 15
16 from PyQt4.QtCore import QDir, QModelIndex, QAbstractItemModel, QFileSystemWatcher, Qt 16 from PyQt4.QtCore import QDir, QModelIndex, QAbstractItemModel, \
17 QFileSystemWatcher, Qt
17 from PyQt4.QtGui import QImageReader, QApplication, QFont 18 from PyQt4.QtGui import QImageReader, QApplication, QFont
18 19
19 import UI.PixmapCache 20 import UI.PixmapCache
20 import Preferences 21 import Preferences
21 import Utilities 22 import Utilities
38 def __init__(self, parent=None, nopopulate=False): 39 def __init__(self, parent=None, nopopulate=False):
39 """ 40 """
40 Constructor 41 Constructor
41 42
42 @param parent reference to parent object (QObject) 43 @param parent reference to parent object (QObject)
43 @keyparam nopopulate flag indicating to not populate the model (boolean) 44 @keyparam nopopulate flag indicating to not populate the model
45 (boolean)
44 """ 46 """
45 super(BrowserModel, self).__init__(parent) 47 super(BrowserModel, self).__init__(parent)
46 48
47 self.progDir = None 49 self.progDir = None
48 self.watchedItems = {} 50 self.watchedItems = {}
84 item = index.internalPointer() 86 item = index.internalPointer()
85 if index.column() < item.columnCount(): 87 if index.column() < item.columnCount():
86 return item.data(index.column()) 88 return item.data(index.column())
87 elif index.column() == item.columnCount() and \ 89 elif index.column() == item.columnCount() and \
88 index.column() < self.columnCount(self.parent(index)): 90 index.column() < self.columnCount(self.parent(index)):
89 # This is for the case where an item under a multi-column parent 91 # This is for the case where an item under a multi-column
90 # doesn't have a value for all the columns 92 # parent doesn't have a value for all the columns
91 return "" 93 return ""
92 elif role == Qt.DecorationRole: 94 elif role == Qt.DecorationRole:
93 if index.column() == 0: 95 if index.column() == 0:
94 return index.internalPointer().getIcon() 96 return index.internalPointer().getIcon()
95 elif role == Qt.FontRole: 97 elif role == Qt.FontRole:
284 if path not in self.watchedItems: 286 if path not in self.watchedItems:
285 # just ignore the situation we don't have a reference to the item 287 # just ignore the situation we don't have a reference to the item
286 return 288 return
287 289
288 if Preferences.getUI("BrowsersListHiddenFiles"): 290 if Preferences.getUI("BrowsersListHiddenFiles"):
289 filter = QDir.Filters(QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot) 291 filter = QDir.Filters(
292 QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot)
290 else: 293 else:
291 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot) 294 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)
292 295
293 for itm in self.watchedItems[path]: 296 for itm in self.watchedItems[path]:
294 oldCnt = itm.childCount() 297 oldCnt = itm.childCount()
352 self.toplevelDirs = [] 355 self.toplevelDirs = []
353 tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs') 356 tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs')
354 if tdp: 357 if tdp:
355 self.toplevelDirs = tdp 358 self.toplevelDirs = tdp
356 else: 359 else:
357 self.toplevelDirs.append(Utilities.toNativeSeparators(QDir.homePath())) 360 self.toplevelDirs.append(
361 Utilities.toNativeSeparators(QDir.homePath()))
358 for d in QDir.drives(): 362 for d in QDir.drives():
359 self.toplevelDirs.append(Utilities.toNativeSeparators( 363 self.toplevelDirs.append(Utilities.toNativeSeparators(
360 d.absoluteFilePath())) 364 d.absoluteFilePath()))
361 365
362 for d in self.toplevelDirs: 366 for d in self.toplevelDirs:
363 itm = BrowserDirectoryItem(self.rootItem, d) 367 itm = BrowserDirectoryItem(self.rootItem, d)
364 self._addItem(itm, self.rootItem) 368 self._addItem(itm, self.rootItem)
365 369
366 def programChange(self, dirname): 370 def programChange(self, dirname):
367 """ 371 """
368 Public method to change the entry for the directory of file being debugged. 372 Public method to change the entry for the directory of file being
373 debugged.
369 374
370 @param dirname name of the directory containing the file (string) 375 @param dirname name of the directory containing the file (string)
371 """ 376 """
372 if self.progDir: 377 if self.progDir:
373 if dirname == self.progDir.dirName(): 378 if dirname == self.progDir.dirName():
374 return 379 return
375 380
376 # remove old entry 381 # remove old entry
377 self._removeWatchedItem(self.progDir) 382 self._removeWatchedItem(self.progDir)
378 self.beginRemoveRows(QModelIndex(), self.progDir.row(), self.progDir.row()) 383 self.beginRemoveRows(
384 QModelIndex(), self.progDir.row(), self.progDir.row())
379 self.rootItem.removeChild(self.progDir) 385 self.rootItem.removeChild(self.progDir)
380 self.endRemoveRows() 386 self.endRemoveRows()
381 self.progDir = None 387 self.progDir = None
382 388
383 itm = BrowserDirectoryItem(self.rootItem, dirname) 389 itm = BrowserDirectoryItem(self.rootItem, dirname)
397 403
398 def removeToplevelDir(self, index): 404 def removeToplevelDir(self, index):
399 """ 405 """
400 Public method to remove a toplevel directory. 406 Public method to remove a toplevel directory.
401 407
402 @param index index of the toplevel directory to be removed (QModelIndex) 408 @param index index of the toplevel directory to be removed
409 (QModelIndex)
403 """ 410 """
404 if not index.isValid(): 411 if not index.isValid():
405 return 412 return
406 413
407 item = index.internalPointer() 414 item = index.internalPointer()
475 self._addWatchedItem(parentItem) 482 self._addWatchedItem(parentItem)
476 483
477 qdir = QDir(parentItem.dirName()) 484 qdir = QDir(parentItem.dirName())
478 485
479 if Preferences.getUI("BrowsersListHiddenFiles"): 486 if Preferences.getUI("BrowsersListHiddenFiles"):
480 filter = QDir.Filters(QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot) 487 filter = QDir.Filters(
488 QDir.AllEntries | QDir.Hidden | QDir.NoDotAndDotDot)
481 else: 489 else:
482 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot) 490 filter = QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)
483 entryInfoList = qdir.entryInfoList(filter) 491 entryInfoList = qdir.entryInfoList(filter)
484 if len(entryInfoList) > 0: 492 if len(entryInfoList) > 0:
485 if repopulate: 493 if repopulate:
486 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 494 self.beginInsertRows(
495 self.createIndex(parentItem.row(), 0, parentItem),
487 0, len(entryInfoList) - 1) 496 0, len(entryInfoList) - 1)
488 for f in entryInfoList: 497 for f in entryInfoList:
489 if f.isDir(): 498 if f.isDir():
490 node = BrowserDirectoryItem(parentItem, 499 node = BrowserDirectoryItem(parentItem,
491 Utilities.toNativeSeparators(f.absoluteFilePath()), 500 Utilities.toNativeSeparators(f.absoluteFilePath()),
492 False) 501 False)
493 else: 502 else:
494 fileFilters = Preferences.getUI("BrowsersFileFilters").split(";") 503 fileFilters = \
504 Preferences.getUI("BrowsersFileFilters").split(";")
495 if fileFilters: 505 if fileFilters:
496 fn = f.fileName() 506 fn = f.fileName()
497 if any([fnmatch.fnmatch(fn, ff.strip()) 507 if any([fnmatch.fnmatch(fn, ff.strip())
498 for ff in fileFilters]): 508 for ff in fileFilters]):
499 continue 509 continue
510 @param parentItem reference to the sys.path item to be populated 520 @param parentItem reference to the sys.path item to be populated
511 @param repopulate flag indicating a repopulation (boolean) 521 @param repopulate flag indicating a repopulation (boolean)
512 """ 522 """
513 if len(sys.path) > 0: 523 if len(sys.path) > 0:
514 if repopulate: 524 if repopulate:
515 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 525 self.beginInsertRows(
526 self.createIndex(parentItem.row(), 0, parentItem),
516 0, len(sys.path) - 1) 527 0, len(sys.path) - 1)
517 for p in sys.path: 528 for p in sys.path:
518 if p == '': 529 if p == '':
519 p = os.getcwd() 530 p = os.getcwd()
520 531
541 return 552 return
542 553
543 keys = list(dict.keys()) 554 keys = list(dict.keys())
544 if len(keys) > 0: 555 if len(keys) > 0:
545 if repopulate: 556 if repopulate:
546 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 557 self.beginInsertRows(
558 self.createIndex(parentItem.row(), 0, parentItem),
547 0, len(keys) - 1) 559 0, len(keys) - 1)
548 for key in keys: 560 for key in keys:
549 if key.startswith("@@"): 561 if key.startswith("@@"):
550 # special treatment done later 562 # special treatment done later
551 continue 563 continue
589 for name in list(cl.methods.keys()): 601 for name in list(cl.methods.keys()):
590 keys.append((name, 'm')) 602 keys.append((name, 'm'))
591 603
592 if len(keys) > 0: 604 if len(keys) > 0:
593 if repopulate: 605 if repopulate:
594 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 606 self.beginInsertRows(
607 self.createIndex(parentItem.row(), 0, parentItem),
595 0, len(keys) - 1) 608 0, len(keys) - 1)
596 for key, kind in keys: 609 for key, kind in keys:
597 if kind == 'c': 610 if kind == 'c':
598 node = BrowserClassItem(parentItem, cl.classes[key], file_) 611 node = BrowserClassItem(parentItem, cl.classes[key], file_)
599 elif kind == 'm': 612 elif kind == 'm':
600 node = BrowserMethodItem(parentItem, cl.methods[key], file_) 613 node = BrowserMethodItem(parentItem, cl.methods[key],
614 file_)
601 self._addItem(node, parentItem) 615 self._addItem(node, parentItem)
602 if repopulate: 616 if repopulate:
603 self.endInsertRows() 617 self.endInsertRows()
604 618
605 if len(cl.attributes): 619 if len(cl.attributes):
643 for name in list(fn.methods.keys()): 657 for name in list(fn.methods.keys()):
644 keys.append((name, 'm')) 658 keys.append((name, 'm'))
645 659
646 if len(keys) > 0: 660 if len(keys) > 0:
647 if repopulate: 661 if repopulate:
648 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 662 self.beginInsertRows(
663 self.createIndex(parentItem.row(), 0, parentItem),
649 0, len(keys) - 1) 664 0, len(keys) - 1)
650 for key, kind in keys: 665 for key, kind in keys:
651 if kind == 'c': 666 if kind == 'c':
652 node = BrowserClassItem(parentItem, fn.classes[key], file_) 667 node = BrowserClassItem(parentItem, fn.classes[key], file_)
653 elif kind == 'm': 668 elif kind == 'm':
654 node = BrowserMethodItem(parentItem, fn.methods[key], file_) 669 node = BrowserMethodItem(parentItem, fn.methods[key],
670 file_)
655 self._addItem(node, parentItem) 671 self._addItem(node, parentItem)
656 if repopulate: 672 if repopulate:
657 self.endInsertRows() 673 self.endInsertRows()
658 674
659 def populateClassAttributesItem(self, parentItem, repopulate=False): 675 def populateClassAttributesItem(self, parentItem, repopulate=False):
660 """ 676 """
661 Public method to populate a class attributes item's subtree. 677 Public method to populate a class attributes item's subtree.
662 678
663 @param parentItem reference to the class attributes item to be populated 679 @param parentItem reference to the class attributes item to be
680 populated
664 @param repopulate flag indicating a repopulation (boolean) 681 @param repopulate flag indicating a repopulation (boolean)
665 """ 682 """
666 classAttributes = parentItem.isClassAttributes() 683 classAttributes = parentItem.isClassAttributes()
667 attributes = parentItem.attributes() 684 attributes = parentItem.attributes()
668 if not attributes: 685 if not attributes:
669 return 686 return
670 687
671 keys = list(attributes.keys()) 688 keys = list(attributes.keys())
672 if len(keys) > 0: 689 if len(keys) > 0:
673 if repopulate: 690 if repopulate:
674 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem), 691 self.beginInsertRows(
692 self.createIndex(parentItem.row(), 0, parentItem),
675 0, len(keys) - 1) 693 0, len(keys) - 1)
676 for key in keys: 694 for key in keys:
677 node = BrowserClassAttributeItem(parentItem, attributes[key], 695 node = BrowserClassAttributeItem(parentItem, attributes[key],
678 classAttributes) 696 classAttributes)
679 self._addItem(node, parentItem) 697 self._addItem(node, parentItem)
728 def child(self, row): 746 def child(self, row):
729 """ 747 """
730 Public method to get a child id. 748 Public method to get a child id.
731 749
732 @param row number of child to get the id of (integer) 750 @param row number of child to get the id of (integer)
733 @param return reference to the child item (BrowserItem) 751 @return reference to the child item (BrowserItem)
734 """ 752 """
735 return self.childItems[row] 753 return self.childItems[row]
736 754
737 def children(self): 755 def children(self):
738 """ 756 """
761 def data(self, column): 779 def data(self, column):
762 """ 780 """
763 Public method to get a specific data item. 781 Public method to get a specific data item.
764 782
765 @param column number of the requested data item (integer) 783 @param column number of the requested data item (integer)
766 @param return the stored data item 784 @return stored data item
767 """ 785 """
768 try: 786 try:
769 return self.itemData[column] 787 return self.itemData[column]
770 except IndexError: 788 except IndexError:
771 return "" 789 return ""
1083 Public method to check, if this file is a Python script. 1101 Public method to check, if this file is a Python script.
1084 1102
1085 @return flag indicating a Python file (boolean) 1103 @return flag indicating a Python file (boolean)
1086 """ 1104 """
1087 return self.fileext in Preferences.getPython("PythonExtensions") or \ 1105 return self.fileext in Preferences.getPython("PythonExtensions") or \
1088 (self.fileext == "" and self.sourceLanguage in ["Python", "Python2"]) 1106 (self.fileext == "" and self.sourceLanguage in ["Python",
1107 "Python2"])
1089 1108
1090 def isPython3File(self): 1109 def isPython3File(self):
1091 """ 1110 """
1092 Public method to check, if this file is a Python3 script. 1111 Public method to check, if this file is a Python3 script.
1093 1112
1199 if Preferences.getUI("BrowsersListFoldersFirst"): 1218 if Preferences.getUI("BrowsersListFoldersFirst"):
1200 return order == Qt.DescendingOrder 1219 return order == Qt.DescendingOrder
1201 1220
1202 if issubclass(other.__class__, BrowserFileItem): 1221 if issubclass(other.__class__, BrowserFileItem):
1203 sinit = os.path.basename(self._filename).startswith('__init__.py') 1222 sinit = os.path.basename(self._filename).startswith('__init__.py')
1204 oinit = os.path.basename(other.fileName()).startswith('__init__.py') 1223 oinit = \
1224 os.path.basename(other.fileName()).startswith('__init__.py')
1205 if sinit and not oinit: 1225 if sinit and not oinit:
1206 return order == Qt.AscendingOrder 1226 return order == Qt.AscendingOrder
1207 if not sinit and oinit: 1227 if not sinit and oinit:
1208 return order == Qt.DescendingOrder 1228 return order == Qt.DescendingOrder
1209 1229
1241 self.name = name 1261 self.name = name
1242 self._classObject = cl 1262 self._classObject = cl
1243 self._filename = filename 1263 self._filename = filename
1244 1264
1245 import Utilities.ClassBrowsers.ClbrBaseClasses 1265 import Utilities.ClassBrowsers.ClbrBaseClasses
1246 self.isfunction = isinstance(self._classObject, 1266 self.isfunction = isinstance(
1247 Utilities.ClassBrowsers.ClbrBaseClasses.Function) 1267 self._classObject,
1248 self.ismodule = isinstance(self._classObject, 1268 Utilities.ClassBrowsers.ClbrBaseClasses.Function)
1249 Utilities.ClassBrowsers.ClbrBaseClasses.Module) 1269 self.ismodule = isinstance(
1270 self._classObject,
1271 Utilities.ClassBrowsers.ClbrBaseClasses.Module)
1250 if self.isfunction: 1272 if self.isfunction:
1251 if cl.isPrivate(): 1273 if cl.isPrivate():
1252 self.icon = UI.PixmapCache.getIcon("method_private.png") 1274 self.icon = UI.PixmapCache.getIcon("method_private.png")
1253 elif cl.isProtected(): 1275 elif cl.isProtected():
1254 self.icon = UI.PixmapCache.getIcon("method_protected.png") 1276 self.icon = UI.PixmapCache.getIcon("method_protected.png")
1255 else: 1277 else:
1256 self.icon = UI.PixmapCache.getIcon("method.png") 1278 self.icon = UI.PixmapCache.getIcon("method.png")
1257 self.itemData[0] = "{0}({1})".format( 1279 self.itemData[0] = "{0}({1})".format(
1258 name, ", ".join(self._classObject.parameters)) 1280 name, ", ".join(self._classObject.parameters))
1259 # if no defaults are wanted 1281 # if no defaults are wanted
1260 # ....format(name, ", ".join([e.split('=')[0].strip() \ 1282 # ....format(name,
1261 # for e in self._classObject.parameters])) 1283 # ", ".join([e.split('=')[0].strip() \
1284 # for e in self._classObject.parameters]))
1262 elif self.ismodule: 1285 elif self.ismodule:
1263 self.icon = UI.PixmapCache.getIcon("module.png") 1286 self.icon = UI.PixmapCache.getIcon("module.png")
1264 else: 1287 else:
1265 if cl.isPrivate(): 1288 if cl.isPrivate():
1266 self.icon = UI.PixmapCache.getIcon("class_private.png") 1289 self.icon = UI.PixmapCache.getIcon("class_private.png")
1293 1316
1294 def lineno(self): 1317 def lineno(self):
1295 """ 1318 """
1296 Public method returning the line number defining this object. 1319 Public method returning the line number defining this object.
1297 1320
1298 return line number defining the object (integer) 1321 @return line number defining the object (integer)
1299 """ 1322 """
1300 return self._classObject.lineno 1323 return self._classObject.lineno
1301 1324
1302 def boundaries(self): 1325 def boundaries(self):
1303 """ 1326 """
1318 """ 1341 """
1319 if issubclass(other.__class__, BrowserCodingItem) or \ 1342 if issubclass(other.__class__, BrowserCodingItem) or \
1320 issubclass(other.__class__, BrowserClassAttributesItem): 1343 issubclass(other.__class__, BrowserClassAttributesItem):
1321 return order == Qt.DescendingOrder 1344 return order == Qt.DescendingOrder
1322 1345
1323 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0: 1346 if Preferences.getUI("BrowsersListContentsByOccurrence") and \
1347 column == 0:
1324 if order == Qt.AscendingOrder: 1348 if order == Qt.AscendingOrder:
1325 return self.lineno() < other.lineno() 1349 return self.lineno() < other.lineno()
1326 else: 1350 else:
1327 return self.lineno() > other.lineno() 1351 return self.lineno() > other.lineno()
1328 1352
1370 else: 1394 else:
1371 self.icon = UI.PixmapCache.getIcon("method.png") 1395 self.icon = UI.PixmapCache.getIcon("method.png")
1372 self.itemData[0] = "{0}({1})".format( 1396 self.itemData[0] = "{0}({1})".format(
1373 name, ", ".join(self._functionObject.parameters)) 1397 name, ", ".join(self._functionObject.parameters))
1374 # if no defaults are wanted 1398 # if no defaults are wanted
1375 # ....format(name, ", ".join( 1399 # ....format(name,
1376 # [e.split('=')[0].strip() for e in self._functionObject.parameters])) 1400 # ", ".join([e.split('=')[0].strip()
1401 # for e in self._functionObject.parameters]))
1377 if self._functionObject and \ 1402 if self._functionObject and \
1378 (self._functionObject.methods or self._functionObject.classes): 1403 (self._functionObject.methods or self._functionObject.classes):
1379 self._populated = False 1404 self._populated = False
1380 self._lazyPopulation = True 1405 self._lazyPopulation = True
1381 1406
1426 if other.name.startswith('__init__'): 1451 if other.name.startswith('__init__'):
1427 return order == Qt.DescendingOrder 1452 return order == Qt.DescendingOrder
1428 elif issubclass(other.__class__, BrowserClassAttributesItem): 1453 elif issubclass(other.__class__, BrowserClassAttributesItem):
1429 return order == Qt.DescendingOrder 1454 return order == Qt.DescendingOrder
1430 1455
1431 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0: 1456 if Preferences.getUI("BrowsersListContentsByOccurrence") and \
1457 column == 0:
1432 if order == Qt.AscendingOrder: 1458 if order == Qt.AscendingOrder:
1433 return self.lineno() < other.lineno() 1459 return self.lineno() < other.lineno()
1434 else: 1460 else:
1435 return self.lineno() > other.lineno() 1461 return self.lineno() > other.lineno()
1436 1462
1556 1582
1557 def lineno(self): 1583 def lineno(self):
1558 """ 1584 """
1559 Public method returning the line number defining this object. 1585 Public method returning the line number defining this object.
1560 1586
1561 return line number defining the object (integer) 1587 @return line number defining the object (integer)
1562 """ 1588 """
1563 return self._attributeObject.lineno 1589 return self._attributeObject.lineno
1564 1590
1565 def linenos(self): 1591 def linenos(self):
1566 """ 1592 """
1567 Public method returning the line numbers this object is assigned to. 1593 Public method returning the line numbers this object is assigned to.
1568 1594
1569 return line number the object is assigned to (list of integers) 1595 @return line number the object is assigned to (list of integers)
1570 """ 1596 """
1571 return self._attributeObject.linenos[:] 1597 return self._attributeObject.linenos[:]
1572 1598
1573 def lessThan(self, other, column, order): 1599 def lessThan(self, other, column, order):
1574 """ 1600 """
1577 @param other reference to item to compare against (BrowserItem) 1603 @param other reference to item to compare against (BrowserItem)
1578 @param column column number to use for the comparison (integer) 1604 @param column column number to use for the comparison (integer)
1579 @param order sort order (Qt.SortOrder) (for special sorting) 1605 @param order sort order (Qt.SortOrder) (for special sorting)
1580 @return true, if this item is less than other (boolean) 1606 @return true, if this item is less than other (boolean)
1581 """ 1607 """
1582 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0: 1608 if Preferences.getUI("BrowsersListContentsByOccurrence") and \
1609 column == 0:
1583 if order == Qt.AscendingOrder: 1610 if order == Qt.AscendingOrder:
1584 return self.lineno() < other.lineno() 1611 return self.lineno() < other.lineno()
1585 else: 1612 else:
1586 return self.lineno() > other.lineno() 1613 return self.lineno() > other.lineno()
1587 1614

eric ide

mercurial