Project/ProjectBrowserModel.py

changeset 945
8cd4d08fa9f6
parent 791
9ec2ac20e54e
child 1112
8a7d1b9d18db
equal deleted inserted replaced
944:1b59c4ba121e 945:8cd4d08fa9f6
19 import Preferences 19 import Preferences
20 import Utilities 20 import Utilities
21 21
22 import Utilities.ModuleParser 22 import Utilities.ModuleParser
23 23
24 ProjectBrowserItemSimpleDirectory = 100 24 ProjectBrowserItemSimpleDirectory = 100
25 ProjectBrowserItemDirectory = 101 25 ProjectBrowserItemDirectory = 101
26 ProjectBrowserItemFile = 102 26 ProjectBrowserItemFile = 102
27 27
28 ProjectBrowserNoType = 0 28 ProjectBrowserNoType = 0
29 ProjectBrowserSourceType = 1 29 ProjectBrowserSourceType = 1
30 ProjectBrowserFormType = 2 30 ProjectBrowserFormType = 2
31 ProjectBrowserInterfaceType = 3 31 ProjectBrowserInterfaceType = 3
32 ProjectBrowserTranslationType = 4 32 ProjectBrowserTranslationType = 4
33 ProjectBrowserOthersType = 5 33 ProjectBrowserOthersType = 5
34 ProjectBrowserResourceType = 6 34 ProjectBrowserResourceType = 6
35
35 36
36 class ProjectBrowserItemMixin(object): 37 class ProjectBrowserItemMixin(object):
37 """ 38 """
38 Class implementing common methods of project browser items. 39 Class implementing common methods of project browser items.
39 40
40 It is meant to be used as a mixin class. 41 It is meant to be used as a mixin class.
41 """ 42 """
42 def __init__(self, type_, bold = False): 43 def __init__(self, type_, bold=False):
43 """ 44 """
44 Constructor 45 Constructor
45 46
46 @param type_ type of file/directory in the project 47 @param type_ type of file/directory in the project
47 @param bold flag indicating a highlighted font 48 @param bold flag indicating a highlighted font
99 100
100 @param type_ type to add to the list 101 @param type_ type to add to the list
101 """ 102 """
102 self._projectTypes.append(type_) 103 self._projectTypes.append(type_)
103 104
105
104 class ProjectBrowserSimpleDirectoryItem(BrowserItem, ProjectBrowserItemMixin): 106 class ProjectBrowserSimpleDirectoryItem(BrowserItem, ProjectBrowserItemMixin):
105 """ 107 """
106 Class implementing the data structure for project browser simple directory items. 108 Class implementing the data structure for project browser simple directory items.
107 """ 109 """
108 def __init__(self, parent, projectType, text, path = ""): 110 def __init__(self, parent, projectType, text, path=""):
109 """ 111 """
110 Constructor 112 Constructor
111 113
112 @param parent parent item 114 @param parent parent item
113 @param projectType type of file/directory in the project 115 @param projectType type of file/directory in the project
126 self.symlink = True 128 self.symlink = True
127 self.icon = UI.PixmapCache.getSymlinkIcon("dirClosed.png") 129 self.icon = UI.PixmapCache.getSymlinkIcon("dirClosed.png")
128 else: 130 else:
129 self.icon = UI.PixmapCache.getIcon("dirClosed.png") 131 self.icon = UI.PixmapCache.getIcon("dirClosed.png")
130 132
131 def setName(self, dinfo, full = True): 133 def setName(self, dinfo, full=True):
132 """ 134 """
133 Public method to set the directory name. 135 Public method to set the directory name.
134 136
135 @param dinfo dinfo is the string for the directory (string) 137 @param dinfo dinfo is the string for the directory (string)
136 @param full flag indicating full pathname should be displayed (boolean) 138 @param full flag indicating full pathname should be displayed (boolean)
159 if Preferences.getUI("BrowsersListFoldersFirst"): 161 if Preferences.getUI("BrowsersListFoldersFirst"):
160 return order == Qt.AscendingOrder 162 return order == Qt.AscendingOrder
161 163
162 return BrowserItem.lessThan(self, other, column, order) 164 return BrowserItem.lessThan(self, other, column, order)
163 165
166
164 class ProjectBrowserDirectoryItem(BrowserDirectoryItem, ProjectBrowserItemMixin): 167 class ProjectBrowserDirectoryItem(BrowserDirectoryItem, ProjectBrowserItemMixin):
165 """ 168 """
166 Class implementing the data structure for project browser directory items. 169 Class implementing the data structure for project browser directory items.
167 """ 170 """
168 def __init__(self, parent, dinfo, projectType, full = True, bold = False): 171 def __init__(self, parent, dinfo, projectType, full=True, bold=False):
169 """ 172 """
170 Constructor 173 Constructor
171 174
172 @param parent parent item 175 @param parent parent item
173 @param dinfo dinfo is the string for the directory (string) 176 @param dinfo dinfo is the string for the directory (string)
178 BrowserDirectoryItem.__init__(self, parent, dinfo, full) 181 BrowserDirectoryItem.__init__(self, parent, dinfo, full)
179 ProjectBrowserItemMixin.__init__(self, projectType, bold) 182 ProjectBrowserItemMixin.__init__(self, projectType, bold)
180 183
181 self.type_ = ProjectBrowserItemDirectory 184 self.type_ = ProjectBrowserItemDirectory
182 185
186
183 class ProjectBrowserFileItem(BrowserFileItem, ProjectBrowserItemMixin): 187 class ProjectBrowserFileItem(BrowserFileItem, ProjectBrowserItemMixin):
184 """ 188 """
185 Class implementing the data structure for project browser file items. 189 Class implementing the data structure for project browser file items.
186 """ 190 """
187 def __init__(self, parent, finfo, projectType, full = True, bold = False, 191 def __init__(self, parent, finfo, projectType, full=True, bold=False,
188 sourceLanguage = ""): 192 sourceLanguage=""):
189 """ 193 """
190 Constructor 194 Constructor
191 195
192 @param parent parent item 196 @param parent parent item
193 @param finfo the string for the file (string) 197 @param finfo the string for the file (string)
199 BrowserFileItem.__init__(self, parent, finfo, full, sourceLanguage) 203 BrowserFileItem.__init__(self, parent, finfo, full, sourceLanguage)
200 ProjectBrowserItemMixin.__init__(self, projectType, bold) 204 ProjectBrowserItemMixin.__init__(self, projectType, bold)
201 205
202 self.type_ = ProjectBrowserItemFile 206 self.type_ = ProjectBrowserItemFile
203 207
208
204 class ProjectBrowserModel(BrowserModel): 209 class ProjectBrowserModel(BrowserModel):
205 """ 210 """
206 Class implementing the project browser model. 211 Class implementing the project browser model.
207 212
208 @signal vcsStateChanged(str) emitted after the VCS state has changed 213 @signal vcsStateChanged(str) emitted after the VCS state has changed
229 self.watcher.directoryChanged.connect(self.directoryChanged) 234 self.watcher.directoryChanged.connect(self.directoryChanged)
230 235
231 self.inRefresh = False 236 self.inRefresh = False
232 237
233 self.projectBrowserTypes = { 238 self.projectBrowserTypes = {
234 "SOURCES" : ProjectBrowserSourceType, 239 "SOURCES": ProjectBrowserSourceType,
235 "FORMS" : ProjectBrowserFormType, 240 "FORMS": ProjectBrowserFormType,
236 "RESOURCES" : ProjectBrowserResourceType, 241 "RESOURCES": ProjectBrowserResourceType,
237 "INTERFACES" : ProjectBrowserInterfaceType, 242 "INTERFACES": ProjectBrowserInterfaceType,
238 "TRANSLATIONS" : ProjectBrowserTranslationType, 243 "TRANSLATIONS": ProjectBrowserTranslationType,
239 "OTHERS" : ProjectBrowserOthersType, 244 "OTHERS": ProjectBrowserOthersType,
240 } 245 }
241 246
242 self.colorNames = { 247 self.colorNames = {
243 "A" : "VcsAdded", 248 "A": "VcsAdded",
244 "M" : "VcsModified", 249 "M": "VcsModified",
245 "O" : "VcsRemoved", 250 "O": "VcsRemoved",
246 "R" : "VcsReplaced", 251 "R": "VcsReplaced",
247 "U" : "VcsUpdate", 252 "U": "VcsUpdate",
248 "Z" : "VcsConflict", 253 "Z": "VcsConflict",
249 } 254 }
250 self.itemBackgroundColors = { 255 self.itemBackgroundColors = {
251 " " : QColor(), 256 " ": QColor(),
252 "A" : Preferences.getProjectBrowserColour(self.colorNames["A"]), 257 "A": Preferences.getProjectBrowserColour(self.colorNames["A"]),
253 "M" : Preferences.getProjectBrowserColour(self.colorNames["M"]), 258 "M": Preferences.getProjectBrowserColour(self.colorNames["M"]),
254 "O" : Preferences.getProjectBrowserColour(self.colorNames["O"]), 259 "O": Preferences.getProjectBrowserColour(self.colorNames["O"]),
255 "R" : Preferences.getProjectBrowserColour(self.colorNames["R"]), 260 "R": Preferences.getProjectBrowserColour(self.colorNames["R"]),
256 "U" : Preferences.getProjectBrowserColour(self.colorNames["U"]), 261 "U": Preferences.getProjectBrowserColour(self.colorNames["U"]),
257 "Z" : Preferences.getProjectBrowserColour(self.colorNames["Z"]), 262 "Z": Preferences.getProjectBrowserColour(self.colorNames["Z"]),
258 } 263 }
259 264
260 self.highLightColor = Preferences.getProjectBrowserColour("Highlighted") 265 self.highLightColor = Preferences.getProjectBrowserColour("Highlighted")
261 # needed by preferencesChanged() 266 # needed by preferencesChanged()
262 267
291 except KeyError: 296 except KeyError:
292 return None 297 return None
293 298
294 return BrowserModel.data(self, index, role) 299 return BrowserModel.data(self, index, role)
295 300
296 def populateItem(self, parentItem, repopulate = False): 301 def populateItem(self, parentItem, repopulate=False):
297 """ 302 """
298 Public method to populate an item's subtree. 303 Public method to populate an item's subtree.
299 304
300 @param parentItem reference to the item to be populated 305 @param parentItem reference to the item to be populated
301 @param repopulate flag indicating a repopulation (boolean) 306 @param repopulate flag indicating a repopulation (boolean)
307 elif parentItem.type() == ProjectBrowserItemFile: 312 elif parentItem.type() == ProjectBrowserItemFile:
308 self.populateFileItem(parentItem, repopulate) 313 self.populateFileItem(parentItem, repopulate)
309 else: 314 else:
310 BrowserModel.populateItem(self, parentItem, repopulate) 315 BrowserModel.populateItem(self, parentItem, repopulate)
311 316
312 def populateProjectDirectoryItem(self, parentItem, repopulate = False): 317 def populateProjectDirectoryItem(self, parentItem, repopulate=False):
313 """ 318 """
314 Public method to populate a directory item's subtree. 319 Public method to populate a directory item's subtree.
315 320
316 @param parentItem reference to the directory item to be populated 321 @param parentItem reference to the directory item to be populated
317 @param repopulate flag indicating a repopulation (boolean) 322 @param repopulate flag indicating a repopulation (boolean)
340 states = self.project.vcs.vcsAllRegisteredStates(states, dname) 345 states = self.project.vcs.vcsAllRegisteredStates(states, dname)
341 346
342 for f in entryInfoList: 347 for f in entryInfoList:
343 if f.isDir(): 348 if f.isDir():
344 node = ProjectBrowserDirectoryItem(parentItem, 349 node = ProjectBrowserDirectoryItem(parentItem,
345 Utilities.toNativeSeparators(f.absoluteFilePath()), 350 Utilities.toNativeSeparators(f.absoluteFilePath()),
346 parentItem.getProjectTypes()[0], False) 351 parentItem.getProjectTypes()[0], False)
347 else: 352 else:
348 node = ProjectBrowserFileItem(parentItem, 353 node = ProjectBrowserFileItem(parentItem,
349 Utilities.toNativeSeparators(f.absoluteFilePath()), 354 Utilities.toNativeSeparators(f.absoluteFilePath()),
350 parentItem.getProjectTypes()[0]) 355 parentItem.getProjectTypes()[0])
413 itm = ProjectBrowserDirectoryItem(parentItem, fname, 418 itm = ProjectBrowserDirectoryItem(parentItem, fname,
414 self.projectBrowserTypes[key], False, bold) 419 self.projectBrowserTypes[key], False, bold)
415 else: 420 else:
416 itm = ProjectBrowserFileItem(parentItem, fname, 421 itm = ProjectBrowserFileItem(parentItem, fname,
417 self.projectBrowserTypes[key], False, bold, 422 self.projectBrowserTypes[key], False, bold,
418 sourceLanguage = sourceLanguage) 423 sourceLanguage=sourceLanguage)
419 self._addItem(itm, parentItem) 424 self._addItem(itm, parentItem)
420 if self.project.vcs is not None: 425 if self.project.vcs is not None:
421 if states[os.path.normcase(fname)] == self.project.vcs.canBeCommitted: 426 if states[os.path.normcase(fname)] == self.project.vcs.canBeCommitted:
422 itm.addVcsStatus(self.project.vcs.vcsName()) 427 itm.addVcsStatus(self.project.vcs.vcsName())
423 else: 428 else:
425 else: 430 else:
426 itm.addVcsStatus("") 431 itm.addVcsStatus("")
427 self.inRefresh = False 432 self.inRefresh = False
428 self.reset() 433 self.reset()
429 434
430 def findParentItemByName(self, type_, name, dontSplit = False): 435 def findParentItemByName(self, type_, name, dontSplit=False):
431 """ 436 """
432 Public method to find an item given it's name. 437 Public method to find an item given it's name.
433 438
434 <b>Note</b>: This method creates all necessary parent items, if they 439 <b>Note</b>: This method creates all necessary parent items, if they
435 don't exist. 440 don't exist.
471 olditem = itm 476 olditem = itm
472 return (itm, pathlist[-1]) 477 return (itm, pathlist[-1])
473 else: 478 else:
474 return (self.rootItem, name) 479 return (self.rootItem, name)
475 480
476 def findChildItem(self, text, column, parentItem = None): 481 def findChildItem(self, text, column, parentItem=None):
477 """ 482 """
478 Public method to find a child item given some text. 483 Public method to find a child item given some text.
479 484
480 @param text text to search for (string) 485 @param text text to search for (string)
481 @param column column to search in (integer) 486 @param column column to search in (integer)
489 if itm.data(column) == text: 494 if itm.data(column) == text:
490 return itm 495 return itm
491 496
492 return None 497 return None
493 498
494 def addNewItem(self, typeString, name, additionalTypeStrings = []): 499 def addNewItem(self, typeString, name, additionalTypeStrings=[]):
495 """ 500 """
496 Public method to add a new item to the model. 501 Public method to add a new item to the model.
497 502
498 @param typeString string denoting the type of the new item (string) 503 @param typeString string denoting the type of the new item (string)
499 @param name name of the new item (string) 504 @param name name of the new item (string)
520 sourceLanguage = self.project.pdata["PROGLANGUAGE"][0] 525 sourceLanguage = self.project.pdata["PROGLANGUAGE"][0]
521 else: 526 else:
522 sourceLanguage = "" 527 sourceLanguage = ""
523 itm = ProjectBrowserFileItem(parentItem, fname, 528 itm = ProjectBrowserFileItem(parentItem, fname,
524 self.projectBrowserTypes[typeString], False, bold, 529 self.projectBrowserTypes[typeString], False, bold,
525 sourceLanguage = sourceLanguage) 530 sourceLanguage=sourceLanguage)
526 self.__addVCSStatus(itm, fname) 531 self.__addVCSStatus(itm, fname)
527 if additionalTypeStrings: 532 if additionalTypeStrings:
528 for additionalTypeString in additionalTypeStrings: 533 for additionalTypeString in additionalTypeStrings:
529 type_ = self.projectBrowserTypes[additionalTypeString] 534 type_ = self.projectBrowserTypes[additionalTypeString]
530 itm.addProjectType(type_) 535 itm.addProjectType(type_)
574 @param name name of the item (string) 579 @param name name of the item (string)
575 @return index of the item found (QModelIndex) 580 @return index of the item found (QModelIndex)
576 """ 581 """
577 itm = self.findItem(name) 582 itm = self.findItem(name)
578 if itm is None: 583 if itm is None:
579 index = QModelIndex() 584 index = QModelIndex()
580 else: 585 else:
581 index = self.createIndex(itm.row(), 0, itm) 586 index = self.createIndex(itm.row(), 0, itm)
582 return index 587 return index
583 588
584 def directoryChanged(self, path): 589 def directoryChanged(self, path):
585 """ 590 """
586 Public slot to handle the directoryChanged signal of the watcher. 591 Public slot to handle the directoryChanged signal of the watcher.
619 cnt = itm.childCount() 624 cnt = itm.childCount()
620 self.beginInsertRows(self.createIndex(itm.row(), 0, itm), 625 self.beginInsertRows(self.createIndex(itm.row(), 0, itm),
621 cnt, cnt) 626 cnt, cnt)
622 if f.isDir(): 627 if f.isDir():
623 node = ProjectBrowserDirectoryItem(itm, 628 node = ProjectBrowserDirectoryItem(itm,
624 Utilities.toNativeSeparators(f.absoluteFilePath()), 629 Utilities.toNativeSeparators(f.absoluteFilePath()),
625 itm.getProjectTypes()[0], 630 itm.getProjectTypes()[0],
626 False) 631 False)
627 else: 632 else:
628 node = ProjectBrowserFileItem(itm, 633 node = ProjectBrowserFileItem(itm,
629 Utilities.toNativeSeparators(f.absoluteFilePath()), 634 Utilities.toNativeSeparators(f.absoluteFilePath()),
630 itm.getProjectTypes()[0]) 635 itm.getProjectTypes()[0])
631 self._addItem(node, itm) 636 self._addItem(node, itm)
632 if self.project.vcs is not None: 637 if self.project.vcs is not None:
633 self.project.vcs.clearStatusCache() 638 self.project.vcs.clearStatusCache()
634 state = self.project.vcs.vcsRegisteredState(node.name()) 639 state = self.project.vcs.vcsRegisteredState(node.name())
671 else: 676 else:
672 item.addVcsStatus(self.trUtf8("local")) 677 item.addVcsStatus(self.trUtf8("local"))
673 else: 678 else:
674 item.addVcsStatus("") 679 item.addVcsStatus("")
675 680
676 def __updateVCSStatus(self, item, name, recursive = True): 681 def __updateVCSStatus(self, item, name, recursive=True):
677 """ 682 """
678 Private method used to update the vcs status of a node. 683 Private method used to update the vcs status of a node.
679 684
680 @param item item to work on 685 @param item item to work on
681 @param name filename belonging to this item (string) 686 @param name filename belonging to this item (string)
697 item.setVcsStatus("") 702 item.setVcsStatus("")
698 703
699 index = self.createIndex(item.row(), 0, item) 704 index = self.createIndex(item.row(), 0, item)
700 self.dataChanged.emit(index, index) 705 self.dataChanged.emit(index, index)
701 706
702 def updateVCSStatus(self, name, recursive = True): 707 def updateVCSStatus(self, name, recursive=True):
703 """ 708 """
704 Public method used to update the vcs status of a node. 709 Public method used to update the vcs status of a node.
705 710
706 @param name filename belonging to this item (string) 711 @param name filename belonging to this item (string)
707 @param recursive flag indicating a recursive update (boolean) 712 @param recursive flag indicating a recursive update (boolean)
762 767
763 def changeVCSStates(self, statesList): 768 def changeVCSStates(self, statesList):
764 """ 769 """
765 Public slot to record the (non normal) VCS states. 770 Public slot to record the (non normal) VCS states.
766 771
767 @param statesList list of VCS state entries (list of strings) giving the 772 @param statesList list of VCS state entries (list of strings) giving the
768 states in the first column and the path relative to the project 773 states in the first column and the path relative to the project
769 directory starting with the third column. The allowed status flags 774 directory starting with the third column. The allowed status flags
770 are: 775 are:
771 <ul> 776 <ul>
772 <li>"A" path was added but not yet comitted</li> 777 <li>"A" path was added but not yet comitted</li>
773 <li>"M" path has local changes</li> 778 <li>"M" path has local changes</li>
774 <li>"O" path was removed</li> 779 <li>"O" path was removed</li>
802 if itm: 807 if itm:
803 itemCache[name] = itm 808 itemCache[name] = itm
804 if itm: 809 if itm:
805 itm.setVcsState(state) 810 itm.setVcsState(state)
806 index1 = self.createIndex(itm.row(), 0, itm) 811 index1 = self.createIndex(itm.row(), 0, itm)
807 index2 = self.createIndex(itm.row(), 812 index2 = self.createIndex(itm.row(),
808 self.rootItem.columnCount(), itm) 813 self.rootItem.columnCount(), itm)
809 self.dataChanged.emit(index1, index2) 814 self.dataChanged.emit(index1, index2)
810 815
811 head, tail = os.path.split(name) 816 head, tail = os.path.split(name)
812 if head != lastHead: 817 if head != lastHead:
842 if state < id_.vcsState: 847 if state < id_.vcsState:
843 state = id_.vcsState 848 state = id_.vcsState
844 if state != itm.vcsState: 849 if state != itm.vcsState:
845 itm.setVcsState(state) 850 itm.setVcsState(state)
846 index1 = self.createIndex(itm.row(), 0, itm) 851 index1 = self.createIndex(itm.row(), 0, itm)
847 index2 = self.createIndex(itm.row(), 852 index2 = self.createIndex(itm.row(),
848 self.rootItem.columnCount(), itm) 853 self.rootItem.columnCount(), itm)
849 self.dataChanged.emit(index1, index2) 854 self.dataChanged.emit(index1, index2)
850 path, tail = os.path.split(path) 855 path, tail = os.path.split(path)
851 856
852 def preferencesChanged(self): 857 def preferencesChanged(self):

eric ide

mercurial