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): |