89 self.pfile = "" # name of the multi project file |
89 self.pfile = "" # name of the multi project file |
90 self.ppath = "" # name of the multi project directory |
90 self.ppath = "" # name of the multi project directory |
91 self.description = "" # description of the multi project |
91 self.description = "" # description of the multi project |
92 self.name = "" |
92 self.name = "" |
93 self.opened = False |
93 self.opened = False |
94 self.projects = [] |
94 self.__projects = {} |
95 # list of project info; each info entry is a dictionary |
95 # dict of project info keyed by 'uid'; each info entry is a dictionary |
96 # 'name' : name of the project |
96 # 'name' : name of the project |
97 # 'file' : project file name |
97 # 'file' : project file name |
98 # 'master' : flag indicating the master |
98 # 'master' : flag indicating the master |
99 # project |
99 # project |
100 # 'description' : description of the project |
100 # 'description' : description of the project |
184 The project files are checked for existance in the |
184 The project files are checked for existance in the |
185 filesystem. Non existant projects are removed from the list and the |
185 filesystem. Non existant projects are removed from the list and the |
186 dirty state of the multi project is changed accordingly. |
186 dirty state of the multi project is changed accordingly. |
187 """ |
187 """ |
188 removelist = [] |
188 removelist = [] |
189 for project in self.projects: |
189 for key, project in self.__projects.items(): |
190 if not os.path.exists(project['file']): |
190 if not os.path.exists(project['file']): |
191 removelist.append(project) |
191 removelist.append(key) |
192 |
192 |
193 if removelist: |
193 if removelist: |
194 for project in removelist: |
194 for key in removelist: |
195 self.projects.remove(project) |
195 del self.__projects[key] |
196 self.setDirty(True) |
196 self.setDirty(True) |
197 |
197 |
198 def __extractCategories(self): |
198 def __extractCategories(self): |
199 """ |
199 """ |
200 Private slot to extract the categories used in the project definitions. |
200 Private slot to extract the categories used in the project definitions. |
201 """ |
201 """ |
202 for project in self.projects: |
202 for project in self.__projects.values(): |
203 if project['category'] and \ |
203 if project['category'] and \ |
204 project['category'] not in self.categories: |
204 project['category'] not in self.categories: |
205 self.categories.append(project['category']) |
205 self.categories.append(project['category']) |
206 |
206 |
207 def getCategories(self): |
207 def getCategories(self): |
291 # insert filename into list of recently opened projects |
291 # insert filename into list of recently opened projects |
292 self.__syncRecent() |
292 self.__syncRecent() |
293 |
293 |
294 return res |
294 return res |
295 |
295 |
|
296 def addProject(self, project): |
|
297 """ |
|
298 Public method to add a project to the multi-project. |
|
299 |
|
300 @param project dictionary containing the project data to be added |
|
301 @type dict |
|
302 """ |
|
303 self.__projects[project['uid']] = project |
|
304 |
296 @pyqtSlot() |
305 @pyqtSlot() |
297 def addProject(self, startdir=None): |
306 def addNewProject(self, startdir=None): |
298 """ |
307 """ |
299 Public slot used to add files to the project. |
308 Public slot used to add a new project to the multi-project. |
300 |
309 |
301 @param startdir start directory for the selection dialog (string) |
310 @param startdir start directory for the selection dialog (string) |
302 """ |
311 """ |
303 from .AddProjectDialog import AddProjectDialog |
312 from .AddProjectDialog import AddProjectDialog |
304 if not startdir: |
313 if not startdir: |
310 if dlg.exec_() == QDialog.Accepted: |
319 if dlg.exec_() == QDialog.Accepted: |
311 name, filename, isMaster, description, category, uid = \ |
320 name, filename, isMaster, description, category, uid = \ |
312 dlg.getData() |
321 dlg.getData() |
313 |
322 |
314 # step 1: check, if project was already added |
323 # step 1: check, if project was already added |
315 for project in self.projects: |
324 for project in self.__projects.values(): |
316 if project['file'] == filename: |
325 if project['file'] == filename: |
317 return |
326 return |
318 |
327 |
319 # step 2: check, if master should be changed |
328 # step 2: check, if master should be changed |
320 if isMaster: |
329 if isMaster: |
321 for project in self.projects: |
330 for project in self.__projects.values(): |
322 if project['master']: |
331 if project['master']: |
323 project['master'] = False |
332 project['master'] = False |
324 self.projectDataChanged.emit(project) |
333 self.projectDataChanged.emit(project) |
325 self.setDirty(True) |
334 self.setDirty(True) |
326 break |
335 break |
346 |
355 |
347 @param pro dictionary with the project data (string) |
356 @param pro dictionary with the project data (string) |
348 """ |
357 """ |
349 # step 1: check, if master should be changed |
358 # step 1: check, if master should be changed |
350 if pro['master']: |
359 if pro['master']: |
351 for project in self.projects: |
360 for project in self.__projects.values(): |
352 if project['master']: |
361 if project['master']: |
353 if project['uid'] != pro['uid']: |
362 if project['uid'] != pro['uid']: |
354 project['master'] = False |
363 project['master'] = False |
355 self.projectDataChanged.emit(project) |
364 self.projectDataChanged.emit(project) |
356 self.setDirty(True) |
365 self.setDirty(True) |
357 break |
366 break |
358 |
367 |
359 # step 2: change the entry |
368 # step 2: change the entry |
360 for project in self.projects: |
369 project = self.__projects[pro['uid']] |
361 if project['uid'] == pro['uid']: |
370 # project UID is not changeable via interface |
362 # project UID is not changeable via interface |
371 project['file'] = pro['file'] |
363 project['file'] = pro['file'] |
372 project['name'] = pro['name'] |
364 project['name'] = pro['name'] |
373 project['master'] = pro['master'] |
365 project['master'] = pro['master'] |
374 project['description'] = pro['description'] |
366 project['description'] = pro['description'] |
375 project['category'] = pro['category'] |
367 project['category'] = pro['category'] |
376 if project['category'] not in self.categories: |
368 if project['category'] not in self.categories: |
377 self.categories.append(project['category']) |
369 self.categories.append(project['category']) |
378 self.projectDataChanged.emit(project) |
370 self.projectDataChanged.emit(project) |
379 self.setDirty(True) |
371 self.setDirty(True) |
|
372 |
380 |
373 def getProjects(self): |
381 def getProjects(self): |
374 """ |
382 """ |
375 Public method to get all project entries. |
383 Public method to get all project entries. |
376 |
384 |
377 @return list of all project entries (list of dictionaries) |
385 @return list of all project entries (list of dictionaries) |
378 """ |
386 """ |
379 return self.projects |
387 return self.__projects.values() |
380 |
388 |
381 def getProject(self, fn): |
389 def getProject(self, uid): |
382 """ |
390 """ |
383 Public method to get a reference to a project entry. |
391 Public method to get a reference to a project entry. |
384 |
392 |
385 @param fn filename of the project (string) |
393 @param uid UID of the project to get |
|
394 @type str |
386 @return dictionary containing the project data |
395 @return dictionary containing the project data |
387 """ |
396 @rtype dict |
388 for project in self.projects: |
397 """ |
389 if project['file'] == fn: |
398 if uid in self.__projects: |
390 return project |
399 return self.__projects[uid] |
391 |
400 else: |
392 return None |
401 return None |
393 |
402 |
394 def removeProject(self, fn): |
403 def removeProject(self, uid): |
395 """ |
404 """ |
396 Public slot to remove a project from the multi project. |
405 Public slot to remove a project from the multi project. |
397 |
406 |
398 @param fn filename of the project to be removed from the multi |
407 @param uid UID of the project to be removed from the multi |
399 project (string) |
408 project |
400 """ |
409 @type str |
401 for project in self.projects: |
410 """ |
402 if project['file'] == fn: |
411 if uid in self.__projects: |
403 self.projects.remove(project) |
412 project = self.__projects[uid] |
404 self.projectRemoved.emit(project) |
413 del self.__projects[uid] |
405 self.setDirty(True) |
414 self.projectRemoved.emit(project) |
406 break |
415 self.setDirty(True) |
407 |
416 |
408 def __newMultiProject(self): |
417 def __newMultiProject(self): |
409 """ |
418 """ |
410 Private slot to build a new multi project. |
419 Private slot to build a new multi project. |
411 |
420 |
688 self.addProjectAct.setWhatsThis(self.tr( |
697 self.addProjectAct.setWhatsThis(self.tr( |
689 """<b>Add project...</b>""" |
698 """<b>Add project...</b>""" |
690 """<p>This opens a dialog for adding a project""" |
699 """<p>This opens a dialog for adding a project""" |
691 """ to the current multiproject.</p>""" |
700 """ to the current multiproject.</p>""" |
692 )) |
701 )) |
693 self.addProjectAct.triggered.connect(self.addProject) |
702 self.addProjectAct.triggered.connect(self.addNewProject) |
694 self.actions.append(self.addProjectAct) |
703 self.actions.append(self.addProjectAct) |
695 |
704 |
696 self.propsAct = E5Action( |
705 self.propsAct = E5Action( |
697 self.tr('Multiproject properties'), |
706 self.tr('Multiproject properties'), |
698 UI.PixmapCache.getIcon("multiProjectProps.png"), |
707 UI.PixmapCache.getIcon("multiProjectProps.png"), |
895 Private slot to open the master project. |
904 Private slot to open the master project. |
896 |
905 |
897 @param reopen flag indicating, that the master project should be |
906 @param reopen flag indicating, that the master project should be |
898 reopened, if it has been opened already (boolean) |
907 reopened, if it has been opened already (boolean) |
899 """ |
908 """ |
900 for project in self.projects: |
909 for project in self.__projects.values(): |
901 if project['master']: |
910 if project['master']: |
902 if reopen or \ |
911 if reopen or \ |
903 not self.projectObject.isOpen() or \ |
912 not self.projectObject.isOpen() or \ |
904 self.projectObject.getProjectFile() != project['file']: |
913 self.projectObject.getProjectFile() != project['file']: |
905 self.openProject(project['file']) |
914 self.openProject(project['file']) |