eric6/Project/ProjectBrowserModel.py

branch
maintenance
changeset 8273
698ae46f40a4
parent 8176
31965986ecd1
parent 8259
2bbec88047dd
equal deleted inserted replaced
8190:fb0ef164f536 8273:698ae46f40a4
7 Module implementing the browser model. 7 Module implementing the browser model.
8 """ 8 """
9 9
10 import os 10 import os
11 import re 11 import re
12 import contextlib
12 13
13 from PyQt5.QtCore import QDir, QModelIndex, pyqtSignal, QFileSystemWatcher, Qt 14 from PyQt5.QtCore import QDir, QModelIndex, pyqtSignal, QFileSystemWatcher, Qt
14 from PyQt5.QtGui import QColor 15 from PyQt5.QtGui import QColor
15 16
16 from UI.BrowserModel import ( 17 from UI.BrowserModel import (
35 ProjectBrowserOthersType = 5 36 ProjectBrowserOthersType = 5
36 ProjectBrowserResourceType = 6 37 ProjectBrowserResourceType = 6
37 ProjectBrowserProtocolsType = 7 38 ProjectBrowserProtocolsType = 7
38 39
39 40
40 class ProjectBrowserItemMixin(object): 41 class ProjectBrowserItemMixin:
41 """ 42 """
42 Class implementing common methods of project browser items. 43 Class implementing common methods of project browser items.
43 44
44 It is meant to be used as a mixin class. 45 It is meant to be used as a mixin class.
45 """ 46 """
167 @param other reference to item to compare against (BrowserItem) 168 @param other reference to item to compare against (BrowserItem)
168 @param column column number to use for the comparison (integer) 169 @param column column number to use for the comparison (integer)
169 @param order sort order (Qt.SortOrder) (for special sorting) 170 @param order sort order (Qt.SortOrder) (for special sorting)
170 @return true, if this item is less than other (boolean) 171 @return true, if this item is less than other (boolean)
171 """ 172 """
172 if issubclass(other.__class__, BrowserFileItem): 173 if (
173 if Preferences.getUI("BrowsersListFoldersFirst"): 174 issubclass(other.__class__, BrowserFileItem) and
174 return order == Qt.SortOrder.AscendingOrder 175 Preferences.getUI("BrowsersListFoldersFirst")
176 ):
177 return order == Qt.SortOrder.AscendingOrder
175 178
176 return BrowserItem.lessThan(self, other, column, order) 179 return BrowserItem.lessThan(self, other, column, order)
177 180
178 181
179 class ProjectBrowserDirectoryItem(BrowserDirectoryItem, 182 class ProjectBrowserDirectoryItem(BrowserDirectoryItem,
231 """ 234 """
232 Constructor 235 Constructor
233 236
234 @param parent reference to parent object (Project.Project) 237 @param parent reference to parent object (Project.Project)
235 """ 238 """
236 super(ProjectBrowserModel, self).__init__(parent, nopopulate=True) 239 super().__init__(parent, nopopulate=True)
237 240
238 rootData = self.tr("Name") 241 rootData = self.tr("Name")
239 self.rootItem = BrowserItem(None, rootData) 242 self.rootItem = BrowserItem(None, rootData)
240 self.rootItem.itemData.append(self.tr("VCS Status")) 243 self.rootItem.itemData.append(self.tr("VCS Status"))
241 244
340 """ 343 """
341 self._addWatchedItem(parentItem) 344 self._addWatchedItem(parentItem)
342 345
343 qdir = QDir(parentItem.dirName()) 346 qdir = QDir(parentItem.dirName())
344 347
345 if Preferences.getProject("BrowsersListHiddenFiles"): 348 fileFilter = (
346 fileFilter = QDir.Filters( 349 QDir.Filters(
347 QDir.Filter.AllEntries | 350 QDir.Filter.AllEntries |
348 QDir.Filter.Hidden | 351 QDir.Filter.Hidden |
349 QDir.Filter.NoDotAndDotDot 352 QDir.Filter.NoDotAndDotDot
350 ) 353 )
351 else: 354 if Preferences.getProject("BrowsersListHiddenFiles") else
352 fileFilter = QDir.Filters( 355 QDir.Filters(QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot)
353 QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot) 356 )
354 entryInfoList = qdir.entryInfoList(fileFilter) 357 entryInfoList = qdir.entryInfoList(fileFilter)
355 358
356 if len(entryInfoList) > 0: 359 if len(entryInfoList) > 0:
357 if repopulate: 360 if repopulate:
358 self.beginInsertRows(self.createIndex( 361 self.beginInsertRows(self.createIndex(
366 dname = parentItem.dirName() 369 dname = parentItem.dirName()
367 self.project.vcs.clearStatusCache() 370 self.project.vcs.clearStatusCache()
368 states = self.project.vcs.vcsAllRegisteredStates(states, dname) 371 states = self.project.vcs.vcsAllRegisteredStates(states, dname)
369 372
370 for f in entryInfoList: 373 for f in entryInfoList:
371 if f.isDir(): 374 node = (
372 node = ProjectBrowserDirectoryItem( 375 ProjectBrowserDirectoryItem(
373 parentItem, 376 parentItem,
374 Utilities.toNativeSeparators(f.absoluteFilePath()), 377 Utilities.toNativeSeparators(f.absoluteFilePath()),
375 parentItem.getProjectTypes()[0], False) 378 parentItem.getProjectTypes()[0], False)
376 else: 379 if f.isDir() else
377 node = ProjectBrowserFileItem( 380 ProjectBrowserFileItem(
378 parentItem, 381 parentItem,
379 Utilities.toNativeSeparators(f.absoluteFilePath()), 382 Utilities.toNativeSeparators(f.absoluteFilePath()),
380 parentItem.getProjectTypes()[0]) 383 parentItem.getProjectTypes()[0])
384 )
381 if self.project.vcs is not None: 385 if self.project.vcs is not None:
382 fname = f.absoluteFilePath() 386 fname = f.absoluteFilePath()
383 if ( 387 if (
384 states[os.path.normcase(fname)] == 388 states[os.path.normcase(fname)] ==
385 self.project.vcs.canBeCommitted 389 self.project.vcs.canBeCommitted
434 438
435 self.inRefresh = True 439 self.inRefresh = True
436 for key in keys: 440 for key in keys:
437 # Show the entry in bold in the others browser to make it more 441 # Show the entry in bold in the others browser to make it more
438 # distinguishable 442 # distinguishable
439 if key == "OTHERS": 443 bold = key == "OTHERS"
440 bold = True 444 sourceLanguage = (
441 else: 445 self.project.getProjectLanguage() if key == "SOURCES" else ""
442 bold = False 446 )
443
444 if key == "SOURCES":
445 sourceLanguage = self.project.getProjectLanguage()
446 else:
447 sourceLanguage = ""
448 447
449 for fn in self.project.pdata[key]: 448 for fn in self.project.pdata[key]:
450 fname = os.path.join(self.project.ppath, fn) 449 fname = os.path.join(self.project.ppath, fn)
451 parentItem, dt = self.findParentItemByName( 450 parentItem, dt = self.findParentItemByName(
452 self.projectBrowserTypes[key], fn) 451 self.projectBrowserTypes[key], fn)
453 if os.path.isdir(fname): 452 itm = (
454 itm = ProjectBrowserDirectoryItem( 453 ProjectBrowserDirectoryItem(
455 parentItem, fname, self.projectBrowserTypes[key], 454 parentItem, fname, self.projectBrowserTypes[key],
456 False, bold) 455 False, bold)
457 else: 456 if os.path.isdir(fname) else
458 itm = ProjectBrowserFileItem( 457 ProjectBrowserFileItem(
459 parentItem, fname, self.projectBrowserTypes[key], 458 parentItem, fname, self.projectBrowserTypes[key],
460 False, bold, sourceLanguage=sourceLanguage) 459 False, bold, sourceLanguage=sourceLanguage)
460 )
461 self._addItem(itm, parentItem) 461 self._addItem(itm, parentItem)
462 if self.project.vcs is not None: 462 if self.project.vcs is not None:
463 if ( 463 if (
464 states[os.path.normcase(fname)] == 464 states[os.path.normcase(fname)] ==
465 self.project.vcs.canBeCommitted 465 self.project.vcs.canBeCommitted
547 @param name name of the new item (string) 547 @param name name of the new item (string)
548 @param additionalTypeStrings names of additional types (list of string) 548 @param additionalTypeStrings names of additional types (list of string)
549 """ 549 """
550 # Show the entry in bold in the others browser to make it more 550 # Show the entry in bold in the others browser to make it more
551 # distinguishable 551 # distinguishable
552 if typeString == "OTHERS": 552 bold = typeString == "OTHERS"
553 bold = True
554 else:
555 bold = False
556 553
557 fname = os.path.join(self.project.ppath, name) 554 fname = os.path.join(self.project.ppath, name)
558 parentItem, dt = self.findParentItemByName( 555 parentItem, dt = self.findParentItemByName(
559 self.projectBrowserTypes[typeString], name) 556 self.projectBrowserTypes[typeString], name)
560 if parentItem == self.rootItem: 557 parentIndex = (
561 parentIndex = QModelIndex() 558 QModelIndex()
562 else: 559 if parentItem == self.rootItem else
563 parentIndex = self.createIndex(parentItem.row(), 0, parentItem) 560 self.createIndex(parentItem.row(), 0, parentItem)
561 )
564 if os.path.isdir(fname): 562 if os.path.isdir(fname):
565 itm = ProjectBrowserDirectoryItem( 563 itm = ProjectBrowserDirectoryItem(
566 parentItem, fname, self.projectBrowserTypes[typeString], 564 parentItem, fname, self.projectBrowserTypes[typeString],
567 False, bold) 565 False, bold)
568 else: 566 else:
623 621
624 @param name name of the item (string) 622 @param name name of the item (string)
625 @return index of the item found (QModelIndex) 623 @return index of the item found (QModelIndex)
626 """ 624 """
627 itm = self.findItem(name) 625 itm = self.findItem(name)
628 if itm is None: 626 index = self.createIndex(itm.row(), 0, itm) if itm else QModelIndex()
629 index = QModelIndex()
630 else:
631 index = self.createIndex(itm.row(), 0, itm)
632 return index 627 return index
633 628
634 def itemIndexByNameAndLine(self, name, lineno): 629 def itemIndexByNameAndLine(self, name, lineno):
635 """ 630 """
636 Public method to find an item's index given its name. 631 Public method to find an item's index given its name.
652 if itm.isLazyPopulated() and autoPopulate: 647 if itm.isLazyPopulated() and autoPopulate:
653 self.populateItem(itm) 648 self.populateItem(itm)
654 else: 649 else:
655 break 650 break
656 for child in itm.children(): 651 for child in itm.children():
657 try: 652 with contextlib.suppress(AttributeError):
658 start, end = child.boundaries() 653 start, end = child.boundaries()
659 if end == -1: 654 if end == -1:
660 end = 1000000 # assume end of file 655 end = 1000000 # assume end of file
661 if start <= lineno <= end: 656 if start <= lineno <= end:
662 itm = child 657 itm = child
663 break 658 break
664 except AttributeError:
665 pass
666 else: 659 else:
667 itm = None 660 itm = None
668 if itm: 661 if itm:
669 olditem = itm 662 olditem = itm
670 index = self.createIndex(olditem.row(), 0, olditem) 663 index = self.createIndex(olditem.row(), 0, olditem)
694 687
695 if path not in self.watchedItems: 688 if path not in self.watchedItems:
696 # just ignore the situation we don't have a reference to the item 689 # just ignore the situation we don't have a reference to the item
697 return 690 return
698 691
699 if Preferences.getProject("BrowsersListHiddenFiles"): 692 fileFilter = (
700 fileFilter = QDir.Filters( 693 QDir.Filters(
701 QDir.Filter.AllEntries | 694 QDir.Filter.AllEntries |
702 QDir.Filter.Hidden | 695 QDir.Filter.Hidden |
703 QDir.Filter.NoDotAndDotDot 696 QDir.Filter.NoDotAndDotDot
704 ) 697 )
705 else: 698 if Preferences.getProject("BrowsersListHiddenFiles") else
706 fileFilter = QDir.Filters( 699 QDir.Filters(QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot)
707 QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot) 700 )
708 701
709 for itm in self.watchedItems[path]: 702 for itm in self.watchedItems[path]:
710 oldCnt = itm.childCount() 703 oldCnt = itm.childCount()
711 704
712 qdir = QDir(itm.dirName()) 705 qdir = QDir(itm.dirName())
727 continue 720 continue
728 721
729 cnt = itm.childCount() 722 cnt = itm.childCount()
730 self.beginInsertRows( 723 self.beginInsertRows(
731 self.createIndex(itm.row(), 0, itm), cnt, cnt) 724 self.createIndex(itm.row(), 0, itm), cnt, cnt)
732 if f.isDir(): 725 node = (
733 node = ProjectBrowserDirectoryItem( 726 ProjectBrowserDirectoryItem(
734 itm, 727 itm,
735 Utilities.toNativeSeparators(f.absoluteFilePath()), 728 Utilities.toNativeSeparators(f.absoluteFilePath()),
736 itm.getProjectTypes()[0], 729 itm.getProjectTypes()[0],
737 False) 730 False)
738 else: 731 if f.isDir() else
739 node = ProjectBrowserFileItem( 732 ProjectBrowserFileItem(
740 itm, 733 itm,
741 Utilities.toNativeSeparators(f.absoluteFilePath()), 734 Utilities.toNativeSeparators(f.absoluteFilePath()),
742 itm.getProjectTypes()[0]) 735 itm.getProjectTypes()[0])
736 )
743 self._addItem(node, itm) 737 self._addItem(node, itm)
744 if self.project.vcs is not None: 738 if self.project.vcs is not None:
745 self.project.vcs.clearStatusCache() 739 self.project.vcs.clearStatusCache()
746 state = self.project.vcs.vcsRegisteredState(node.name()) 740 state = self.project.vcs.vcsRegisteredState(node.name())
747 if state == self.project.vcs.canBeCommitted: 741 if state == self.project.vcs.canBeCommitted:
829 823
830 @param name file or directory name of the item (string). 824 @param name file or directory name of the item (string).
831 """ 825 """
832 fname = os.path.basename(name) 826 fname = os.path.basename(name)
833 parentItem = self.findParentItemByName(0, name)[0] 827 parentItem = self.findParentItemByName(0, name)[0]
834 if parentItem == self.rootItem: 828 parentIndex = (
835 parentIndex = QModelIndex() 829 QModelIndex()
836 else: 830 if parentItem == self.rootItem else
837 parentIndex = self.createIndex(parentItem.row(), 0, parentItem) 831 self.createIndex(parentItem.row(), 0, parentItem)
832 )
838 childItem = self.findChildItem(fname, 0, parentItem) 833 childItem = self.findChildItem(fname, 0, parentItem)
839 if childItem is not None: 834 if childItem is not None:
840 self.beginRemoveRows(parentIndex, childItem.row(), childItem.row()) 835 self.beginRemoveRows(parentIndex, childItem.row(), childItem.row())
841 parentItem.removeChild(childItem) 836 parentItem.removeChild(childItem)
842 self.endRemoveRows() 837 self.endRemoveRows()

eric ide

mercurial