UI/BrowserModel.py

changeset 0
de9c2efb9d02
child 7
c679fb30c8f3
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2006 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the browser model.
8 """
9
10 import sys
11 import os
12
13 from PyQt4.QtCore import *
14 from PyQt4.QtGui import *
15
16 import Utilities.ClassBrowsers
17 import Utilities.ClassBrowsers.ClbrBaseClasses
18
19 import UI.PixmapCache
20 import Preferences
21 import Utilities
22
23 BrowserItemRoot = 0
24 BrowserItemDirectory = 1
25 BrowserItemSysPath = 2
26 BrowserItemFile = 3
27 BrowserItemClass = 4
28 BrowserItemMethod = 5
29 BrowserItemAttributes = 6
30 BrowserItemAttribute = 7
31 BrowserItemCoding = 8
32
33 class BrowserModel(QAbstractItemModel):
34 """
35 Class implementing the browser model.
36 """
37 def __init__(self, parent = None):
38 """
39 Constructor
40
41 @param parent reference to parent object (QObject)
42 """
43 QAbstractItemModel.__init__(self, parent)
44
45 rootData = QVariant(QApplication.translate("BrowserModel", "Name"))
46 self.rootItem = BrowserItem(None, rootData)
47
48 self.progDir = None
49
50 self.__populateModel()
51
52 def columnCount(self, parent=QModelIndex()):
53 """
54 Public method to get the number of columns.
55
56 @param parent index of parent item (QModelIndex)
57 @return number of columns (integer)
58 """
59 if parent.isValid():
60 item = parent.internalPointer()
61 else:
62 item = self.rootItem
63
64 return item.columnCount() + 1
65
66 def data(self, index, role):
67 """
68 Public method to get data of an item.
69
70 @param index index of the data to retrieve (QModelIndex)
71 @param role role of data (Qt.ItemDataRole)
72 @return requested data (QVariant)
73 """
74 if not index.isValid():
75 return QVariant()
76
77 if role == Qt.DisplayRole:
78 item = index.internalPointer()
79 if index.column() < item.columnCount():
80 return QVariant(item.data(index.column()))
81 elif index.column() == item.columnCount() and \
82 index.column() < self.columnCount(self.parent(index)):
83 # This is for the case where an item under a multi-column parent
84 # doesn't have a value for all the columns
85 return QVariant("")
86 elif role == Qt.DecorationRole:
87 if index.column() == 0:
88 return QVariant(index.internalPointer().getIcon())
89
90 return QVariant()
91
92 def flags(self, index):
93 """
94 Public method to get the item flags.
95
96 @param index index of the data to retrieve (QModelIndex)
97 @return requested flags (Qt.ItemFlags)
98 """
99 if not index.isValid():
100 return Qt.ItemIsEnabled
101
102 return Qt.ItemIsEnabled | Qt.ItemIsSelectable
103
104 def headerData(self, section, orientation, role = Qt.DisplayRole):
105 """
106 Public method to get the header data.
107
108 @param section number of section to get data for (integer)
109 @param orientation header orientation (Qt.Orientation)
110 @param role role of data (Qt.ItemDataRole)
111 @return requested header data (QVariant)
112 """
113 if orientation == Qt.Horizontal and role == Qt.DisplayRole:
114 if section >= self.rootItem.columnCount():
115 return QVariant("")
116 else:
117 return self.rootItem.data(section)
118
119 return QVariant()
120
121 def index(self, row, column, parent = QModelIndex()):
122 """
123 Public method to create an index.
124
125 @param row row number of the new index (integer)
126 @param column column number of the new index (integer)
127 @param parent index of parent item (QModelIndex)
128 @return index object (QModelIndex)
129 """
130 # The model/view framework considers negative values out-of-bounds,
131 # however in python they work when indexing into lists. So make sure
132 # we return an invalid index for out-of-bounds row/col
133 if row < 0 or column < 0 or \
134 row >= self.rowCount(parent) or column >= self.columnCount(parent):
135 return QModelIndex()
136
137 if not parent.isValid():
138 parentItem = self.rootItem
139 else:
140 parentItem = parent.internalPointer()
141
142 try:
143 if not parentItem.isPopulated():
144 self.populateItem(parentItem)
145 childItem = parentItem.child(row)
146 except IndexError:
147 childItem = None
148 if childItem:
149 return self.createIndex(row, column, childItem)
150 else:
151 return QModelIndex()
152
153 def parent(self, index):
154 """
155 Public method to get the index of the parent object.
156
157 @param index index of the item (QModelIndex)
158 @return index of parent item (QModelIndex)
159 """
160 if not index.isValid():
161 return QModelIndex()
162
163 childItem = index.internalPointer()
164 parentItem = childItem.parent()
165
166 if parentItem == self.rootItem:
167 return QModelIndex()
168
169 return self.createIndex(parentItem.row(), 0, parentItem)
170
171 def rowCount(self, parent = QModelIndex()):
172 """
173 Public method to get the number of rows.
174
175 @param parent index of parent item (QModelIndex)
176 @return number of rows (integer)
177 """
178 # Only the first column should have children
179 if parent.column() > 0:
180 return 0
181
182 if not parent.isValid():
183 parentItem = self.rootItem
184 else:
185 parentItem = parent.internalPointer()
186 if not parentItem.isPopulated(): # lazy population
187 self.populateItem(parentItem)
188
189 return parentItem.childCount()
190
191 def hasChildren(self, parent = QModelIndex()):
192 """
193 Public method to check for the presence of child items.
194
195 We always return True for normal items in order to do lazy
196 population of the tree.
197
198 @param parent index of parent item (QModelIndex)
199 @return flag indicating the presence of child items (boolean)
200 """
201 # Only the first column should have children
202 if parent.column() > 0:
203 return 0
204
205 if not parent.isValid():
206 return self.rootItem.childCount() > 0
207
208 if parent.internalPointer().isLazyPopulated():
209 return True
210 else:
211 return parent.internalPointer().childCount() > 0
212
213 def clear(self):
214 """
215 Public method to clear the model.
216 """
217 self.rootItem.removeChildren()
218 self.reset()
219
220 def item(self, index):
221 """
222 Public method to get a reference to an item.
223
224 @param index index of the data to retrieve (QModelIndex)
225 @return requested item reference (BrowserItem)
226 """
227 if not index.isValid():
228 return None
229
230 return index.internalPointer()
231
232 def __populateModel(self):
233 """
234 Private method to populate the browser model.
235 """
236 self._addItem(BrowserSysPathItem(self.rootItem), self.rootItem)
237
238 self.toplevelDirs = []
239 tdp = Preferences.Prefs.settings.value('BrowserModel/ToplevelDirs').toStringList()
240 if tdp:
241 self.toplevelDirs = tdp
242 else:
243 self.toplevelDirs.append(Utilities.toNativeSeparators(QDir.homePath()))
244 for d in QDir.drives():
245 self.toplevelDirs.append(Utilities.toNativeSeparators(\
246 d.absoluteFilePath()))
247
248 for d in self.toplevelDirs:
249 self._addItem(BrowserDirectoryItem(self.rootItem, d), self.rootItem)
250
251 def programChange(self, dirname):
252 """
253 Public method to change the entry for the directory of file being debugged.
254
255 @param dirname name of the directory containg the file (string)
256 """
257 if self.progDir:
258 if dirname == self.progDir.dirName():
259 return
260
261 # remove old entry
262 self.beginRemoveRows(QModelIndex(), self.progDir.row(), self.progDir.row())
263 self.rootItem.removeChild(self.progDir)
264 self.endRemoveRows()
265 self.progDir = None
266
267 itm = BrowserDirectoryItem(self.rootItem, dirname)
268 self.addItem(itm)
269 self.progDir = itm
270
271 def addTopLevelDir(self, dirname):
272 """
273 Public method to add a new toplevel directory.
274
275 @param dirname name of the new toplevel directory (string)
276 """
277 if dirname not in self.toplevelDirs:
278 itm = BrowserDirectoryItem(self.rootItem, dirname)
279 self.addItem(itm)
280 self.toplevelDirs.append(itm.dirName())
281
282 def removeToplevelDir(self, index):
283 """
284 Public method to remove a toplevel directory.
285
286 @param index index of the toplevel directory to be removed (QModelIndex)
287 """
288 if not index.isValid():
289 return
290
291 item = index.internalPointer()
292 self.beginRemoveRows(index.parent(), index.row(), index.row())
293 self.rootItem.removeChild(item)
294 self.endRemoveRows()
295
296 self.toplevelDirs.remove(item.dirName())
297
298 def saveToplevelDirs(self):
299 """
300 Public slot to save the toplevel directories.
301 """
302 Preferences.Prefs.settings.setValue('BrowserModel/ToplevelDirs',
303 QVariant(self.toplevelDirs))
304
305 def _addItem(self, itm, parentItem):
306 """
307 Protected slot to add an item.
308
309 @param itm reference to item to add (BrowserItem)
310 @param parentItem reference to item to add to (BrowserItem)
311 """
312 parentItem.appendChild(itm)
313
314 def addItem(self, itm, parent = QModelIndex()):
315 """
316 Puplic slot to add an item.
317
318 @param itm item to add (BrowserItem)
319 @param parent index of parent item (QModelIndex)
320 """
321 if not parent.isValid():
322 parentItem = self.rootItem
323 else:
324 parentItem = parent.internalPointer()
325
326 cnt = parentItem.childCount()
327 self.beginInsertRows(parent, cnt, cnt)
328 self._addItem(itm, parentItem)
329 self.endInsertRows()
330
331 def populateItem(self, parentItem, repopulate = False):
332 """
333 Public method to populate an item's subtree.
334
335 @param parentItem reference to the item to be populated
336 @param repopulate flag indicating a repopulation (boolean)
337 """
338 if parentItem.type() == BrowserItemDirectory:
339 self.populateDirectoryItem(parentItem, repopulate)
340 elif parentItem.type() == BrowserItemSysPath:
341 self.populateSysPathItem(parentItem, repopulate)
342 elif parentItem.type() == BrowserItemFile:
343 self.populateFileItem(parentItem, repopulate)
344 elif parentItem.type() == BrowserItemClass:
345 self.populateClassItem(parentItem, repopulate)
346 elif parentItem.type() == BrowserItemMethod:
347 self.populateMethodItem(parentItem, repopulate)
348 elif parentItem.type() == BrowserItemAttributes:
349 self.populateClassAttributesItem(parentItem, repopulate)
350
351 def populateDirectoryItem(self, parentItem, repopulate = False):
352 """
353 Public method to populate a directory item's subtree.
354
355 @param parentItem reference to the directory item to be populated
356 @param repopulate flag indicating a repopulation (boolean)
357 """
358 qdir = QDir(parentItem.dirName())
359
360 entryInfoList = \
361 qdir.entryInfoList(QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot))
362 if len(entryInfoList) > 0:
363 if repopulate:
364 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem),
365 0, len(entryInfoList) - 1)
366 for f in entryInfoList:
367 if f.isDir():
368 node = BrowserDirectoryItem(parentItem,
369 Utilities.toNativeSeparators(f.absoluteFilePath()),
370 False)
371 else:
372 node = BrowserFileItem(parentItem,
373 Utilities.toNativeSeparators(f.absoluteFilePath()))
374 self._addItem(node, parentItem)
375 if repopulate:
376 self.endInsertRows()
377
378 def populateSysPathItem(self, parentItem, repopulate = False):
379 """
380 Public method to populate a sys.path item's subtree.
381
382 @param parentItem reference to the sys.path item to be populated
383 @param repopulate flag indicating a repopulation (boolean)
384 """
385 if len(sys.path) > 0:
386 if repopulate:
387 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem),
388 0, len(sys.path) - 1)
389 for p in sys.path:
390 if p == '':
391 p = os.getcwd()
392
393 node = BrowserDirectoryItem(parentItem, p)
394 self._addItem(node, parentItem)
395 if repopulate:
396 self.endInsertRows()
397
398 def populateFileItem(self, parentItem, repopulate = False):
399 """
400 Public method to populate a file item's subtree.
401
402 @param parentItem reference to the file item to be populated
403 @param repopulate flag indicating a repopulation (boolean)
404 """
405 moduleName = parentItem.moduleName()
406 fileName = parentItem.fileName()
407 try:
408 dict = Utilities.ClassBrowsers.readmodule(\
409 moduleName, [parentItem.dirName()],
410 parentItem.isPythonFile() or parentItem.isPython3File())
411 except ImportError:
412 return
413
414 keys = dict.keys()
415 if len(keys) > 0:
416 if repopulate:
417 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem),
418 0, len(keys) - 1)
419 for key in keys:
420 if key.startswith("@@"):
421 # special treatment done later
422 continue
423 cl = dict[key]
424 try:
425 if cl.module == moduleName:
426 node = BrowserClassItem(parentItem, cl, fileName)
427 self._addItem(node, parentItem)
428 except AttributeError:
429 pass
430 if "@@Coding@@" in keys:
431 node = BrowserCodingItem(parentItem,
432 QApplication.translate("BrowserModel", "Coding: {0}")\
433 .format(dict["@@Coding@@"].coding))
434 self._addItem(node, parentItem)
435 if "@@Globals@@" in keys:
436 node = BrowserClassAttributesItem(parentItem,
437 dict["@@Globals@@"].globals,
438 QApplication.translate("BrowserModel", "Globals"))
439 self._addItem(node, parentItem)
440 if repopulate:
441 self.endInsertRows()
442
443 def populateClassItem(self, parentItem, repopulate = False):
444 """
445 Public method to populate a class item's subtree.
446
447 @param parentItem reference to the class item to be populated
448 @param repopulate flag indicating a repopulation (boolean)
449 """
450 cl = parentItem.classObject()
451 file_ = parentItem.fileName()
452
453 if cl is None:
454 return
455
456 # build sorted list of names
457 keys = []
458 for name in cl.classes.keys():
459 keys.append((name, 'c'))
460 for name in cl.methods.keys():
461 keys.append((name, 'm'))
462
463 if len(keys) > 0:
464 if repopulate:
465 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem),
466 0, len(keys) - 1)
467 for key, kind in keys:
468 if kind == 'c':
469 node = BrowserClassItem(parentItem, cl.classes[key], file_)
470 elif kind == 'm':
471 node = BrowserMethodItem(parentItem, cl.methods[key], file_)
472 self._addItem(node, parentItem)
473 if repopulate:
474 self.endInsertRows()
475
476 if len(cl.attributes):
477 node = BrowserClassAttributesItem(\
478 parentItem, cl.attributes,
479 QApplication.translate("BrowserModel", "Attributes"))
480 if repopulate:
481 self.addItem(node,
482 self.createIndex(parentItem.row(), 0, parentItem))
483 else:
484 self._addItem(node, parentItem)
485
486 if len(cl.globals):
487 node = BrowserClassAttributesItem(\
488 parentItem, cl.globals,
489 QApplication.translate("BrowserModel", "Attributes (global)"))
490 if repopulate:
491 self.addItem(node,
492 self.createIndex(parentItem.row(), 0, parentItem))
493 else:
494 self._addItem(node, parentItem)
495
496 def populateMethodItem(self, parentItem, repopulate = False):
497 """
498 Public method to populate a method item's subtree.
499
500 @param parentItem reference to the method item to be populated
501 @param repopulate flag indicating a repopulation (boolean)
502 """
503 fn = parentItem.functionObject()
504 file_ = parentItem.fileName()
505
506 if fn is None:
507 return
508
509 # build sorted list of names
510 keys = []
511 for name in fn.classes.keys():
512 keys.append((name, 'c'))
513 for name in fn.methods.keys():
514 keys.append((name, 'm'))
515
516 if len(keys) > 0:
517 if repopulate:
518 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem),
519 0, len(keys) - 1)
520 for key, kind in keys:
521 if kind == 'c':
522 node = BrowserClassItem(parentItem, fn.classes[key], file_)
523 elif kind == 'm':
524 node = BrowserMethodItem(parentItem, fn.methods[key], file_)
525 self._addItem(node, parentItem)
526 if repopulate:
527 self.endInsertRows()
528
529 def populateClassAttributesItem(self, parentItem, repopulate = False):
530 """
531 Public method to populate a class attributes item's subtree.
532
533 @param parentItem reference to the class attributes item to be populated
534 @param repopulate flag indicating a repopulation (boolean)
535 """
536 attributes = parentItem.attributes()
537 if not attributes:
538 return
539
540 keys = attributes.keys()
541 if len(keys) > 0:
542 if repopulate:
543 self.beginInsertRows(self.createIndex(parentItem.row(), 0, parentItem),
544 0, len(keys) - 1)
545 for key in keys:
546 node = BrowserClassAttributeItem(parentItem, attributes[key])
547 self._addItem(node, parentItem)
548 if repopulate:
549 self.endInsertRows()
550
551 class BrowserItem(object):
552 """
553 Class implementing the data structure for browser items.
554 """
555 def __init__(self, parent, data):
556 """
557 Constructor.
558
559 @param parent reference to the parent item
560 @param data single data of the item
561 """
562 self.childItems = []
563
564 self.parentItem = parent
565 self.itemData = [data]
566 self.type_ = BrowserItemRoot
567 self.icon = UI.PixmapCache.getIcon("empty.png")
568 self._populated = True
569 self._lazyPopulation = False
570
571 def appendChild(self, child):
572 """
573 Public method to add a child to this item.
574
575 @param child reference to the child item to add (BrowserItem)
576 """
577 self.childItems.append(child)
578 self._populated = True
579
580 def removeChild(self, child):
581 """
582 Public method to remove a child.
583
584 @param child reference to the child to remove (BrowserItem)
585 """
586 self.childItems.remove(child)
587
588 def removeChildren(self):
589 """
590 Public method to remove all children.
591 """
592 self.childItems = []
593
594 def child(self, row):
595 """
596 Public method to get a child id.
597
598 @param row number of child to get the id of (integer)
599 @param return reference to the child item (BrowserItem)
600 """
601 return self.childItems[row]
602
603 def children(self):
604 """
605 Public method to get the ids of all child items.
606
607 @return references to all child items (list of BrowserItem)
608 """
609 return self.childItems[:]
610
611 def childCount(self):
612 """
613 Public method to get the number of available child items.
614
615 @return number of child items (integer)
616 """
617 return len(self.childItems)
618
619 def columnCount(self):
620 """
621 Public method to get the number of available data items.
622
623 @return number of data items (integer)
624 """
625 return len(self.itemData)
626
627 def data(self, column):
628 """
629 Public method to get a specific data item.
630
631 @param column number of the requested data item (integer)
632 @param return the stored data item
633 """
634 try:
635 return self.itemData[column]
636 except IndexError:
637 return ""
638
639 def parent(self):
640 """
641 Public method to get the reference to the parent item.
642
643 @return reference to the parent item
644 """
645 return self.parentItem
646
647 def row(self):
648 """
649 Public method to get the row number of this item.
650
651 @return row number (integer)
652 """
653 return self.parentItem.childItems.index(self)
654
655 def type(self):
656 """
657 Public method to get the item type.
658
659 @return type of the item
660 """
661 return self.type_
662
663 def isPublic(self):
664 """
665 Public method returning the public visibility status.
666
667 @return flag indicating public visibility (boolean)
668 """
669 return True
670
671 def getIcon(self):
672 """
673 Public method to get the items icon.
674
675 @return the icon (QIcon)
676 """
677 return self.icon
678
679 def isPopulated(self):
680 """
681 Public method to chek, if this item is populated.
682
683 @return population status (boolean)
684 """
685 return self._populated
686
687 def isLazyPopulated(self):
688 """
689 Public method to check, if this item should be populated lazyly.
690
691 @return lazy population flag (boolean)
692 """
693 return self._lazyPopulation
694
695 def lessThan(self, other, column, order):
696 """
697 Public method to check, if the item is less than the other one.
698
699 @param other reference to item to compare against (BrowserItem)
700 @param column column number to use for the comparison (integer)
701 @param order sort order (Qt.SortOrder) (for special sorting)
702 @return true, if this item is less than other (boolean)
703 """
704 try:
705 return self.itemData[column] < other.itemData[column]
706 except IndexError:
707 return False
708
709 class BrowserDirectoryItem(BrowserItem):
710 """
711 Class implementing the data structure for browser directory items.
712 """
713 def __init__(self, parent, dinfo, full = True):
714 """
715 Constructor
716
717 @param parent parent item
718 @param dinfo dinfo is the string for the directory (string)
719 @param full flag indicating full pathname should be displayed (boolean)
720 """
721 self._dirName = os.path.abspath(dinfo)
722
723 if full:
724 dn = self._dirName
725 else:
726 dn = os.path.basename(self._dirName)
727
728 BrowserItem.__init__(self, parent, dn)
729
730 self.type_ = BrowserItemDirectory
731 self.icon = UI.PixmapCache.getIcon("dirClosed.png")
732 self._populated = False
733 self._lazyPopulation = True
734
735 def setName(self, dinfo, full = True):
736 """
737 Public method to set the directory name.
738
739 @param dinfo dinfo is the string for the directory (string)
740 @param full flag indicating full pathname should be displayed (boolean)
741 """
742 self._dirName = os.path.abspath(dinfo)
743
744 if full:
745 dn = self._dirName
746 else:
747 dn = os.path.basename(self._dirName)
748 self.itemData[0] = dn
749
750 def dirName(self):
751 """
752 Public method returning the directory name.
753
754 @return directory name (string)
755 """
756 return self._dirName
757
758 def lessThan(self, other, column, order):
759 """
760 Public method to check, if the item is less than the other one.
761
762 @param other reference to item to compare against (BrowserItem)
763 @param column column number to use for the comparison (integer)
764 @param order sort order (Qt.SortOrder) (for special sorting)
765 @return true, if this item is less than other (boolean)
766 """
767 if issubclass(other.__class__, BrowserFileItem):
768 if Preferences.getUI("BrowsersListFoldersFirst"):
769 return order == Qt.AscendingOrder
770
771 return BrowserItem.lessThan(self, other, column, order)
772
773 class BrowserSysPathItem(BrowserItem):
774 """
775 Class implementing the data structure for browser sys.path items.
776 """
777 def __init__(self, parent):
778 """
779 Constructor
780
781 @param parent parent item
782 """
783 BrowserItem.__init__(self, parent, "sys.path")
784
785 self.type_ = BrowserItemSysPath
786 self.icon = UI.PixmapCache.getIcon("filePython.png")
787 self._populated = False
788 self._lazyPopulation = True
789
790 class BrowserFileItem(BrowserItem):
791 """
792 Class implementing the data structure for browser file items.
793 """
794 def __init__(self, parent, finfo, full = True, sourceLanguage = ""):
795 """
796 Constructor
797
798 @param parent parent item
799 @param finfo the string for the file (string)
800 @param full flag indicating full pathname should be displayed (boolean)
801 @param sourceLanguage source code language of the project (string)
802 """
803 BrowserItem.__init__(self, parent, os.path.basename(finfo))
804
805 self.type_ = BrowserItemFile
806 self.fileext = os.path.splitext(finfo)[1].lower()
807 self._filename = os.path.abspath(finfo)
808 self._dirName = os.path.dirname(finfo)
809 self.sourceLanguage = sourceLanguage
810
811 self._moduleName = ''
812
813 if self.isPythonFile():
814 if self.fileext == '.py':
815 self.icon = UI.PixmapCache.getIcon("filePython.png")
816 else:
817 self.icon = UI.PixmapCache.getIcon("filePython2.png")
818 self._populated = False
819 self._lazyPopulation = True
820 self._moduleName = os.path.basename(finfo)
821 elif self.isPython3File():
822 self.icon = UI.PixmapCache.getIcon("filePython.png")
823 self._populated = False
824 self._lazyPopulation = True
825 self._moduleName = os.path.basename(finfo)
826 elif self.isRubyFile():
827 self.icon = UI.PixmapCache.getIcon("fileRuby.png")
828 self._populated = False
829 self._lazyPopulation = True
830 self._moduleName = os.path.basename(finfo)
831 elif self.isDesignerFile():
832 self.icon = UI.PixmapCache.getIcon("fileDesigner.png")
833 elif self.isLinguistFile():
834 if self.fileext == '.ts':
835 self.icon = UI.PixmapCache.getIcon("fileLinguist.png")
836 else:
837 self.icon = UI.PixmapCache.getIcon("fileLinguist2.png")
838 elif self.isResourcesFile():
839 self.icon = UI.PixmapCache.getIcon("fileResource.png")
840 elif self.isProjectFile():
841 self.icon = UI.PixmapCache.getIcon("fileProject.png")
842 elif self.isMultiProjectFile():
843 self.icon = UI.PixmapCache.getIcon("fileMultiProject.png")
844 elif self.isIdlFile():
845 self.icon = UI.PixmapCache.getIcon("fileIDL.png")
846 self._populated = False
847 self._lazyPopulation = True
848 self._moduleName = os.path.basename(finfo)
849 elif self.isPixmapFile():
850 self.icon = UI.PixmapCache.getIcon("filePixmap.png")
851 elif self.isSvgFile():
852 self.icon = UI.PixmapCache.getIcon("fileSvg.png")
853 elif self.isDFile():
854 self.icon = UI.PixmapCache.getIcon("fileD.png")
855 else:
856 self.icon = UI.PixmapCache.getIcon("fileMisc.png")
857
858 def setName(self, finfo, full = True):
859 """
860 Public method to set the directory name.
861
862 @param finfo the string for the file (string)
863 @param full flag indicating full pathname should be displayed (boolean)
864 """
865 self._filename = os.path.abspath(finfo)
866 self.itemData[0] = os.path.basename(finfo)
867 if self.isPythonFile() or self.isPython3File() or \
868 self.isRubyFile() or self.isIdlFile():
869 self._dirName = os.path.dirname(finfo)
870 self._moduleName = os.path.basename(finfo)
871
872 def fileName(self):
873 """
874 Public method returning the filename.
875
876 @return filename (string)
877 """
878 return self._filename
879
880 def fileExt(self):
881 """
882 Public method returning the file extension.
883
884 @return file extension (string)
885 """
886 return self.fileext
887
888 def dirName(self):
889 """
890 Public method returning the directory name.
891
892 @return directory name (string)
893 """
894 return self._dirName
895
896 def moduleName(self):
897 """
898 Public method returning the module name.
899
900 @return module name (string)
901 """
902 return self._moduleName
903
904 def isPythonFile(self):
905 """
906 Public method to check, if this file is a Python script.
907
908 @return flag indicating a Python file (boolean)
909 """
910 return self.fileext in Preferences.getPython("PythonExtensions") or \
911 (self.fileext == "" and self.sourceLanguage == "Python")
912
913 def isPython3File(self):
914 """
915 Public method to check, if this file is a Python3 script.
916
917 @return flag indicating a Python file (boolean)
918 """
919 return self.fileext in Preferences.getPython("Python3Extensions") or \
920 (self.fileext == "" and self.sourceLanguage == "Python3")
921
922 def isRubyFile(self):
923 """
924 Public method to check, if this file is a Ruby script.
925
926 @return flag indicating a Ruby file (boolean)
927 """
928 return self.fileext == '.rb' or \
929 (self.fileext == "" and self.sourceLanguage == "Ruby")
930
931 def isDesignerFile(self):
932 """
933 Public method to check, if this file is a Qt-Designer file.
934
935 @return flag indicating a Qt-Designer file (boolean)
936 """
937 return self.fileext == '.ui'
938
939 def isLinguistFile(self):
940 """
941 Public method to check, if this file is a Qt-Linguist file.
942
943 @return flag indicating a Qt-Linguist file (boolean)
944 """
945 return self.fileext in ['.ts', '.qm']
946
947 def isResourcesFile(self):
948 """
949 Public method to check, if this file is a Qt-Resources file.
950
951 @return flag indicating a Qt-Resources file (boolean)
952 """
953 return self.fileext == '.qrc'
954
955 def isProjectFile(self):
956 """
957 Public method to check, if this file is an eric4 project file.
958
959 @return flag indicating an eric4 project file (boolean)
960 """
961 return self.fileext in ['.e3p', '.e3pz', '.e4p', '.e4pz']
962
963 def isMultiProjectFile(self):
964 """
965 Public method to check, if this file is an eric4 multi project file.
966
967 @return flag indicating an eric4 project file (boolean)
968 """
969 return self.fileext in ['.e4m', '.e4mz']
970
971 def isIdlFile(self):
972 """
973 Public method to check, if this file is a CORBA IDL file.
974
975 @return flag indicating a CORBA IDL file (boolean)
976 """
977 return self.fileext == '.idl'
978
979 def isPixmapFile(self):
980 """
981 Public method to check, if this file is a pixmap file.
982
983 @return flag indicating a pixmap file (boolean)
984 """
985 return self.fileext[1:] in QImageReader.supportedImageFormats()
986
987 def isSvgFile(self):
988 """
989 Public method to check, if this file is a SVG file.
990
991 @return flag indicating a SVG file (boolean)
992 """
993 return self.fileext == '.svg'
994
995 def isDFile(self):
996 """
997 Public method to check, if this file is a D file.
998
999 @return flag indicating a D file (boolean)
1000 """
1001 return self.fileext in ['.d', '.di'] or \
1002 (self.fileext == "" and self.sourceLanguage == "D")
1003
1004 def lessThan(self, other, column, order):
1005 """
1006 Public method to check, if the item is less than the other one.
1007
1008 @param other reference to item to compare against (BrowserItem)
1009 @param column column number to use for the comparison (integer)
1010 @param order sort order (Qt.SortOrder) (for special sorting)
1011 @return true, if this item is less than other (boolean)
1012 """
1013 if not issubclass(other.__class__, BrowserFileItem):
1014 if Preferences.getUI("BrowsersListFoldersFirst"):
1015 return order == Qt.DescendingOrder
1016
1017 if issubclass(other.__class__, BrowserFileItem):
1018 sinit = os.path.basename(self._filename).startswith('__init__.py')
1019 oinit = os.path.basename(other.fileName()).startswith('__init__.py')
1020 if sinit and not oinit:
1021 return order == Qt.AscendingOrder
1022 if not sinit and oinit:
1023 return order == Qt.DescendingOrder
1024
1025 return BrowserItem.lessThan(self, other, column, order)
1026
1027 class BrowserClassItem(BrowserItem):
1028 """
1029 Class implementing the data structure for browser class items.
1030 """
1031 def __init__(self, parent, cl, filename):
1032 """
1033 Constructor
1034
1035 @param parent parent item
1036 @param cl Class object to be shown
1037 @param filename filename of the file defining this class
1038 """
1039 name = cl.name
1040 if hasattr(cl, 'super') and cl.super:
1041 supers = []
1042 for sup in cl.super:
1043 try:
1044 sname = sup.name
1045 if sup.module != cl.module:
1046 sname = "%s.%s" % (sup.module, sname)
1047 except AttributeError:
1048 sname = sup
1049 supers.append(sname)
1050 name = name + "(%s)" % ", ".join(supers)
1051
1052 BrowserItem.__init__(self, parent, name)
1053
1054 self.type_ = BrowserItemClass
1055 self.name = name
1056 self._classObject = cl
1057 self._filename = filename
1058
1059 self.isfunction = isinstance(self._classObject,
1060 Utilities.ClassBrowsers.ClbrBaseClasses.Function)
1061 self.ismodule = isinstance(self._classObject,
1062 Utilities.ClassBrowsers.ClbrBaseClasses.Module)
1063 if self.isfunction:
1064 if cl.isPrivate():
1065 self.icon = UI.PixmapCache.getIcon("method_private.png")
1066 elif cl.isProtected():
1067 self.icon = UI.PixmapCache.getIcon("method_protected.png")
1068 else:
1069 self.icon = UI.PixmapCache.getIcon("method.png")
1070 self.itemData[0] = "%s(%s)" % (name, ", ".join(self._classObject.parameters))
1071 # if no defaults are wanted
1072 # ... % (name, ", ".join([e.split('=')[0].strip() \
1073 # for e in self._classObject.parameters]))
1074 elif self.ismodule:
1075 self.icon = UI.PixmapCache.getIcon("module.png")
1076 else:
1077 if cl.isPrivate():
1078 self.icon = UI.PixmapCache.getIcon("class_private.png")
1079 elif cl.isProtected():
1080 self.icon = UI.PixmapCache.getIcon("class_protected.png")
1081 else:
1082 self.icon = UI.PixmapCache.getIcon("class.png")
1083 if self._classObject and \
1084 (self._classObject.methods or \
1085 self._classObject.classes or \
1086 self._classObject.attributes):
1087 self._populated = False
1088 self._lazyPopulation = True
1089
1090 def fileName(self):
1091 """
1092 Public method returning the filename.
1093
1094 @return filename (string)
1095 """
1096 return self._filename
1097
1098 def classObject(self):
1099 """
1100 Public method returning the class object.
1101
1102 @return reference to the class object
1103 """
1104 return self._classObject
1105
1106 def lineno(self):
1107 """
1108 Public method returning the line number defining this object.
1109
1110 return line number defining the object (integer)
1111 """
1112 return self._classObject.lineno
1113
1114 def lessThan(self, other, column, order):
1115 """
1116 Public method to check, if the item is less than the other one.
1117
1118 @param other reference to item to compare against (BrowserItem)
1119 @param column column number to use for the comparison (integer)
1120 @param order sort order (Qt.SortOrder) (for special sorting)
1121 @return true, if this item is less than other (boolean)
1122 """
1123 if issubclass(other.__class__, BrowserCodingItem) or \
1124 issubclass(other.__class__, BrowserClassAttributesItem):
1125 return order == Qt.DescendingOrder
1126
1127 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0:
1128 if order == Qt.AscendingOrder:
1129 return self.lineno() < other.lineno()
1130 else:
1131 return self.lineno() > other.lineno()
1132
1133 return BrowserItem.lessThan(self, other, column, order)
1134
1135 def isPublic(self):
1136 """
1137 Public method returning the public visibility status.
1138
1139 @return flag indicating public visibility (boolean)
1140 """
1141 return self._classObject.isPublic()
1142
1143 class BrowserMethodItem(BrowserItem):
1144 """
1145 Class implementing the data structure for browser method items.
1146 """
1147 def __init__(self, parent, fn, filename):
1148 """
1149 Constructor
1150
1151 @param parent parent item
1152 @param fn Function object to be shown
1153 @param filename filename of the file defining this class (string)
1154 """
1155 name = fn.name
1156 BrowserItem.__init__(self, parent, name)
1157
1158 self.type_ = BrowserItemMethod
1159 self.name = name
1160 self._functionObject = fn
1161 self._filename = filename
1162 if self._functionObject.isPrivate():
1163 self.icon = UI.PixmapCache.getIcon("method_private.png")
1164 elif self._functionObject.isProtected():
1165 self.icon = UI.PixmapCache.getIcon("method_protected.png")
1166 else:
1167 self.icon = UI.PixmapCache.getIcon("method.png")
1168 self.itemData[0] = "%s(%s)" % \
1169 (name, ", ".join(self._functionObject.parameters))
1170 # if no defaults are wanted
1171 # ... % (name, ", ".join(\
1172 # [e.split('=')[0].strip() for e in self._functionObject.parameters]))
1173 if self._functionObject and \
1174 (self._functionObject.methods or self._functionObject.classes):
1175 self._populated = False
1176 self._lazyPopulation = True
1177
1178 def fileName(self):
1179 """
1180 Public method returning the filename.
1181
1182 @return filename (string)
1183 """
1184 return self._filename
1185
1186 def functionObject(self):
1187 """
1188 Public method returning the function object.
1189
1190 @return reference to the function object
1191 """
1192 return self._functionObject
1193
1194 def lineno(self):
1195 """
1196 Public method returning the line number defining this object.
1197
1198 return line number defining the object (integer)
1199 """
1200 return self._functionObject.lineno
1201
1202 def lessThan(self, other, column, order):
1203 """
1204 Public method to check, if the item is less than the other one.
1205
1206 @param other reference to item to compare against (BrowserItem)
1207 @param column column number to use for the comparison (integer)
1208 @param order sort order (Qt.SortOrder) (for special sorting)
1209 @return true, if this item is less than other (boolean)
1210 """
1211 if issubclass(other.__class__, BrowserMethodItem):
1212 if self.name.startswith('__init__'):
1213 return order == Qt.AscendingOrder
1214 if other.name.startswith('__init__'):
1215 return order == Qt.DescendingOrder
1216 elif issubclass(other.__class__, BrowserClassAttributesItem):
1217 return order == Qt.DescendingOrder
1218
1219 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0:
1220 if order == Qt.AscendingOrder:
1221 return self.lineno() < other.lineno()
1222 else:
1223 return self.lineno() > other.lineno()
1224
1225 return BrowserItem.lessThan(self, other, column, order)
1226
1227 def isPublic(self):
1228 """
1229 Public method returning the public visibility status.
1230
1231 @return flag indicating public visibility (boolean)
1232 """
1233 return self._functionObject.isPublic()
1234
1235 class BrowserClassAttributesItem(BrowserItem):
1236 """
1237 Class implementing the data structure for browser class attributes items.
1238 """
1239 def __init__(self, parent, attributes, text):
1240 """
1241 Constructor
1242
1243 @param parent parent item
1244 @param attributes list of attributes
1245 @param text text to be shown by this item (string)
1246 """
1247 BrowserItem.__init__(self, parent, text)
1248
1249 self.type_ = BrowserItemAttributes
1250 self._attributes = attributes.copy()
1251 self._populated = False
1252 self._lazyPopulation = True
1253 self.icon = UI.PixmapCache.getIcon("attributes.png")
1254
1255 def attributes(self):
1256 """
1257 Public method returning the attribute list.
1258
1259 @return reference to the list of attributes
1260 """
1261 return self._attributes
1262
1263 def lessThan(self, other, column, order):
1264 """
1265 Public method to check, if the item is less than the other one.
1266
1267 @param other reference to item to compare against (BrowserItem)
1268 @param column column number to use for the comparison (integer)
1269 @param order sort order (Qt.SortOrder) (for special sorting)
1270 @return true, if this item is less than other (boolean)
1271 """
1272 if issubclass(other.__class__, BrowserCodingItem):
1273 return order == Qt.DescendingOrder
1274 elif issubclass(other.__class__, BrowserClassItem) or \
1275 issubclass(other.__class__, BrowserMethodItem):
1276 return order == Qt.AscendingOrder
1277
1278 return BrowserItem.lessThan(self, other, column, order)
1279
1280 class BrowserClassAttributeItem(BrowserItem):
1281 """
1282 Class implementing the data structure for browser class attribute items.
1283 """
1284 def __init__(self, parent, attribute):
1285 """
1286 Constructor
1287
1288 @param parent parent item
1289 @param attribute reference to the attribute object
1290 """
1291 BrowserItem.__init__(self, parent, attribute.name)
1292
1293 self.type_ = BrowserItemAttribute
1294 self._attributeObject = attribute
1295 self.__public = attribute.isPublic()
1296 if attribute.isPrivate():
1297 self.icon = UI.PixmapCache.getIcon("attribute_private.png")
1298 elif attribute.isProtected():
1299 self.icon = UI.PixmapCache.getIcon("attribute_protected.png")
1300 else:
1301 self.icon = UI.PixmapCache.getIcon("attribute.png")
1302
1303 def isPublic(self):
1304 """
1305 Public method returning the public visibility status.
1306
1307 @return flag indicating public visibility (boolean)
1308 """
1309 return self.__public
1310
1311 def attributeObject(self):
1312 """
1313 Public method returning the class object.
1314
1315 @return reference to the class object
1316 """
1317 return self._attributeObject
1318
1319 def fileName(self):
1320 """
1321 Public method returning the filename.
1322
1323 @return filename (string)
1324 """
1325 return self._attributeObject.file
1326
1327 def lineno(self):
1328 """
1329 Public method returning the line number defining this object.
1330
1331 return line number defining the object (integer)
1332 """
1333 return self._attributeObject.lineno
1334
1335 def lessThan(self, other, column, order):
1336 """
1337 Public method to check, if the item is less than the other one.
1338
1339 @param other reference to item to compare against (BrowserItem)
1340 @param column column number to use for the comparison (integer)
1341 @param order sort order (Qt.SortOrder) (for special sorting)
1342 @return true, if this item is less than other (boolean)
1343 """
1344 if Preferences.getUI("BrowsersListContentsByOccurrence") and column == 0:
1345 if order == Qt.AscendingOrder:
1346 return self.lineno() < other.lineno()
1347 else:
1348 return self.lineno() > other.lineno()
1349
1350 return BrowserItem.lessThan(self, other, column, order)
1351
1352 class BrowserCodingItem(BrowserItem):
1353 """
1354 Class implementing the data structure for browser coding items.
1355 """
1356 def __init__(self, parent, text):
1357 """
1358 Constructor
1359
1360 @param parent parent item
1361 @param text text to be shown by this item (string)
1362 """
1363 BrowserItem.__init__(self, parent, text)
1364
1365 self.type_ = BrowserItemCoding
1366 self.icon = UI.PixmapCache.getIcon("textencoding.png")
1367
1368 def lessThan(self, other, column, order):
1369 """
1370 Public method to check, if the item is less than the other one.
1371
1372 @param other reference to item to compare against (BrowserItem)
1373 @param column column number to use for the comparison (integer)
1374 @param order sort order (Qt.SortOrder) (for special sorting)
1375 @return true, if this item is less than other (boolean)
1376 """
1377 if issubclass(other.__class__, BrowserClassItem) or \
1378 issubclass(other.__class__, BrowserClassAttributesItem):
1379 return order == Qt.AscendingOrder
1380
1381 return BrowserItem.lessThan(self, other, column, order)

eric ide

mercurial