34 |
34 |
35 class MultiProject(QObject): |
35 class MultiProject(QObject): |
36 """ |
36 """ |
37 Class implementing the project management functionality. |
37 Class implementing the project management functionality. |
38 |
38 |
39 @signal dirty(int) emitted when the dirty state changes |
39 @signal dirty(bool) emitted when the dirty state changes |
40 @signal newMultiProject() emitted after a new multi project was generated |
40 @signal newMultiProject() emitted after a new multi project was generated |
41 @signal multiProjectOpened() emitted after a multi project file was read |
41 @signal multiProjectOpened() emitted after a multi project file was read |
42 @signal multiProjectClosed() emitted after a multi project was closed |
42 @signal multiProjectClosed() emitted after a multi project was closed |
43 @signal multiProjectPropertiesChanged() emitted after the multi project |
43 @signal multiProjectPropertiesChanged() emitted after the multi project |
44 properties were changed |
44 properties were changed |
50 has been added |
50 has been added |
51 @signal projectRemoved(project data dict) emitted after a project entry |
51 @signal projectRemoved(project data dict) emitted after a project entry |
52 has been removed |
52 has been removed |
53 @signal projectOpened(filename) emitted after the project has been opened |
53 @signal projectOpened(filename) emitted after the project has been opened |
54 """ |
54 """ |
|
55 dirty = pyqtSignal(bool) |
|
56 newMultiProject = pyqtSignal() |
|
57 multiProjectOpened = pyqtSignal() |
|
58 multiProjectClosed = pyqtSignal() |
|
59 multiProjectPropertiesChanged = pyqtSignal() |
|
60 showMenu = pyqtSignal(str, QMenu) |
|
61 projectDataChanged = pyqtSignal(dict) |
|
62 projectAdded = pyqtSignal(dict) |
|
63 projectRemoved = pyqtSignal(dict) |
55 projectOpened = pyqtSignal(str) |
64 projectOpened = pyqtSignal(str) |
56 |
65 |
57 def __init__(self, project, parent = None, filename = None): |
66 def __init__(self, project, parent = None, filename = None): |
58 """ |
67 """ |
59 Constructor |
68 Constructor |
395 # step 2: check, if master should be changed |
404 # step 2: check, if master should be changed |
396 if isMaster: |
405 if isMaster: |
397 for project in self.projects: |
406 for project in self.projects: |
398 if project['master']: |
407 if project['master']: |
399 project['master'] = False |
408 project['master'] = False |
400 self.emit(SIGNAL("projectDataChanged"), project) |
409 self.projectDataChanged.emit(project) |
401 self.setDirty(True) |
410 self.setDirty(True) |
402 break |
411 break |
403 |
412 |
404 # step 3: add the project entry |
413 # step 3: add the project entry |
405 project = { |
414 project = { |
407 'file' : filename, |
416 'file' : filename, |
408 'master' : isMaster, |
417 'master' : isMaster, |
409 'description' : description, |
418 'description' : description, |
410 } |
419 } |
411 self.projects.append(project) |
420 self.projects.append(project) |
412 self.emit(SIGNAL("projectAdded"), project) |
421 self.projectAdded.emit(project) |
413 self.setDirty(True) |
422 self.setDirty(True) |
414 |
423 |
415 def changeProjectProperties(self, pro): |
424 def changeProjectProperties(self, pro): |
416 """ |
425 """ |
417 Public method to change the data of a project entry. |
426 Public method to change the data of a project entry. |
422 if pro['master']: |
431 if pro['master']: |
423 for project in self.projects: |
432 for project in self.projects: |
424 if project['master']: |
433 if project['master']: |
425 if project['file'] != pro['file']: |
434 if project['file'] != pro['file']: |
426 project['master'] = False |
435 project['master'] = False |
427 self.emit(SIGNAL("projectDataChanged"), project) |
436 self.projectDataChanged.emit(project) |
428 self.setDirty(True) |
437 self.setDirty(True) |
429 break |
438 break |
430 |
439 |
431 # step 2: change the entry |
440 # step 2: change the entry |
432 for project in self.projects: |
441 for project in self.projects: |
433 if project['file'] == pro['file']: |
442 if project['file'] == pro['file']: |
434 # project filename is not changeable via interface |
443 # project filename is not changeable via interface |
435 project['name'] = pro['name'] |
444 project['name'] = pro['name'] |
436 project['master'] = pro['master'] |
445 project['master'] = pro['master'] |
437 project['description'] = pro['description'] |
446 project['description'] = pro['description'] |
438 self.emit(SIGNAL("projectDataChanged"), project) |
447 self.projectDataChanged.emit(project) |
439 self.setDirty(True) |
448 self.setDirty(True) |
440 |
449 |
441 def getProjects(self): |
450 def getProjects(self): |
442 """ |
451 """ |
443 Public method to get all project entries. |
452 Public method to get all project entries. |
466 @param fn filename of the project to be removed from the multi project (string) |
475 @param fn filename of the project to be removed from the multi project (string) |
467 """ |
476 """ |
468 for project in self.projects: |
477 for project in self.projects: |
469 if project['file'] == fn: |
478 if project['file'] == fn: |
470 self.projects.remove(project) |
479 self.projects.remove(project) |
471 self.emit(SIGNAL("projectRemoved"), project) |
480 self.projectRemoved.emit(project) |
472 self.setDirty(True) |
481 self.setDirty(True) |
473 break |
482 break |
474 |
483 |
475 def newMultiProject(self): |
484 def __newMultiProject(self): |
476 """ |
485 """ |
477 Public slot to build a new multi project. |
486 Private slot to build a new multi project. |
478 |
487 |
479 This method displays the new multi project dialog and initializes |
488 This method displays the new multi project dialog and initializes |
480 the multi project object with the data entered. |
489 the multi project object with the data entered. |
481 """ |
490 """ |
482 if not self.checkDirty(): |
491 if not self.checkDirty(): |
490 self.setDirty(True) |
499 self.setDirty(True) |
491 self.closeAct.setEnabled(True) |
500 self.closeAct.setEnabled(True) |
492 self.saveasAct.setEnabled(True) |
501 self.saveasAct.setEnabled(True) |
493 self.addProjectAct.setEnabled(True) |
502 self.addProjectAct.setEnabled(True) |
494 self.propsAct.setEnabled(True) |
503 self.propsAct.setEnabled(True) |
495 self.emit(SIGNAL('newMultiProject')) |
504 self.newMultiProject.emit() |
496 |
505 |
497 def __showProperties(self): |
506 def __showProperties(self): |
498 """ |
507 """ |
499 Private slot to display the properties dialog. |
508 Private slot to display the properties dialog. |
500 """ |
509 """ |
501 dlg = PropertiesDialog(self, False) |
510 dlg = PropertiesDialog(self, False) |
502 if dlg.exec_() == QDialog.Accepted: |
511 if dlg.exec_() == QDialog.Accepted: |
503 dlg.storeData() |
512 dlg.storeData() |
504 self.setDirty(True) |
513 self.setDirty(True) |
505 self.emit(SIGNAL('multiProjectPropertiesChanged')) |
514 self.multiProjectPropertiesChanged.emit() |
506 |
515 |
507 def openMultiProject(self, fn = None, openMaster = True): |
516 def openMultiProject(self, fn = None, openMaster = True): |
508 """ |
517 """ |
509 Public slot to open a multi project. |
518 Public slot to open a multi project. |
510 |
519 |
539 self.closeAct.setEnabled(True) |
548 self.closeAct.setEnabled(True) |
540 self.saveasAct.setEnabled(True) |
549 self.saveasAct.setEnabled(True) |
541 self.addProjectAct.setEnabled(True) |
550 self.addProjectAct.setEnabled(True) |
542 self.propsAct.setEnabled(True) |
551 self.propsAct.setEnabled(True) |
543 |
552 |
544 self.emit(SIGNAL('multiProjectOpened')) |
553 self.multiProjectOpened.emit() |
545 |
554 |
546 if openMaster and Preferences.getMultiProject("OpenMasterAutomatically"): |
555 if openMaster and Preferences.getMultiProject("OpenMasterAutomatically"): |
547 self.__openMasterProject(False) |
556 self.__openMasterProject(False) |
548 else: |
557 else: |
549 QApplication.restoreOverrideCursor() |
558 QApplication.restoreOverrideCursor() |
601 return False |
610 return False |
602 |
611 |
603 self.name = QFileInfo(fn).baseName() |
612 self.name = QFileInfo(fn).baseName() |
604 self.__writeMultiProject(fn) |
613 self.__writeMultiProject(fn) |
605 |
614 |
606 self.emit(SIGNAL('multiProjectClosed')) |
615 self.multiProjectClosed.emit() |
607 self.emit(SIGNAL('multiProjectOpened')) |
616 self.multiProjectOpened.emit() |
608 return True |
617 return True |
609 else: |
618 else: |
610 return False |
619 return False |
611 |
620 |
612 def checkDirty(self): |
621 def checkDirty(self): |
663 self.saveasAct.setEnabled(False) |
672 self.saveasAct.setEnabled(False) |
664 self.saveAct.setEnabled(False) |
673 self.saveAct.setEnabled(False) |
665 self.addProjectAct.setEnabled(False) |
674 self.addProjectAct.setEnabled(False) |
666 self.propsAct.setEnabled(False) |
675 self.propsAct.setEnabled(False) |
667 |
676 |
668 self.emit(SIGNAL('multiProjectClosed')) |
677 self.multiProjectClosed.emit() |
669 |
678 |
670 return True |
679 return True |
671 |
680 |
672 def initActions(self): |
681 def initActions(self): |
673 """ |
682 """ |
685 act.setWhatsThis(self.trUtf8( |
694 act.setWhatsThis(self.trUtf8( |
686 """<b>New...</b>""" |
695 """<b>New...</b>""" |
687 """<p>This opens a dialog for entering the info for a""" |
696 """<p>This opens a dialog for entering the info for a""" |
688 """ new multiproject.</p>""" |
697 """ new multiproject.</p>""" |
689 )) |
698 )) |
690 act.triggered[()].connect(self.newMultiProject) |
699 act.triggered[()].connect(self.__newMultiProject) |
691 self.actions.append(act) |
700 self.actions.append(act) |
692 |
701 |
693 act = E5Action(self.trUtf8('Open multiproject'), |
702 act = E5Action(self.trUtf8('Open multiproject'), |
694 UI.PixmapCache.getIcon("multiProjectOpen.png"), |
703 UI.PixmapCache.getIcon("multiProjectOpen.png"), |
695 self.trUtf8('&Open...'), 0, 0, |
704 self.trUtf8('&Open...'), 0, 0, |
781 "Recent" : self.recentMenu, |
790 "Recent" : self.recentMenu, |
782 } |
791 } |
783 |
792 |
784 # connect the aboutToShow signals |
793 # connect the aboutToShow signals |
785 self.recentMenu.aboutToShow.connect(self.__showContextMenuRecent) |
794 self.recentMenu.aboutToShow.connect(self.__showContextMenuRecent) |
786 self.connect(self.recentMenu, SIGNAL('triggered(QAction *)'), |
795 self.recentMenu.triggered.connect(self.__openRecent) |
787 self.__openRecent) |
|
788 menu.aboutToShow.connect(self.__showMenu) |
796 menu.aboutToShow.connect(self.__showMenu) |
789 |
797 |
790 # build the main menu |
798 # build the main menu |
791 menu.setTearOffEnabled(True) |
799 menu.setTearOffEnabled(True) |
792 menu.addActions(self.actGrp1.actions()) |
800 menu.addActions(self.actGrp1.actions()) |
832 """ |
840 """ |
833 Private method to set up the multi project menu. |
841 Private method to set up the multi project menu. |
834 """ |
842 """ |
835 self.menuRecentAct.setEnabled(len(self.recent) > 0) |
843 self.menuRecentAct.setEnabled(len(self.recent) > 0) |
836 |
844 |
837 self.emit(SIGNAL("showMenu"), "Main", self.__menus["Main"]) |
845 self.showMenu.emit("Main", self.__menus["Main"]) |
838 |
846 |
839 def __syncRecent(self): |
847 def __syncRecent(self): |
840 """ |
848 """ |
841 Private method to synchronize the list of recently opened multi projects |
849 Private method to synchronize the list of recently opened multi projects |
842 with the central store. |
850 with the central store. |