442 from datetime import datetime |
442 from datetime import datetime |
443 # import necessary stuff from PLCOpenEditor |
443 # import necessary stuff from PLCOpenEditor |
444 from PLCControler import PLCControler |
444 from PLCControler import PLCControler |
445 from PLCOpenEditor import PLCOpenEditor, ProjectDialog |
445 from PLCOpenEditor import PLCOpenEditor, ProjectDialog |
446 from TextViewer import TextViewer |
446 from TextViewer import TextViewer |
447 from plcopen.structures import IEC_KEYWORDS |
447 from plcopen.structures import IEC_KEYWORDS, AddPluginBlockList, ClearPluginTypes, PluginTypes |
448 import re |
448 import re |
449 |
449 |
450 class PluginsRoot(PlugTemplate): |
450 class PluginsRoot(PlugTemplate, PLCControler): |
451 """ |
451 """ |
452 This class define Root object of the plugin tree. |
452 This class define Root object of the plugin tree. |
453 It is responsible of : |
453 It is responsible of : |
454 - Managing project directory |
454 - Managing project directory |
455 - Building project |
455 - Building project |
515 </xsd:element> |
515 </xsd:element> |
516 </xsd:schema> |
516 </xsd:schema> |
517 """ |
517 """ |
518 |
518 |
519 def __init__(self, frame): |
519 def __init__(self, frame): |
520 |
520 PLCControler.__init__(self) |
|
521 |
521 self.MandatoryParams = None |
522 self.MandatoryParams = None |
522 self.AppFrame = frame |
523 self.AppFrame = frame |
523 |
524 |
524 """ |
525 """ |
525 This method are not called here... but in NewProject and OpenProject |
526 This method are not called here... but in NewProject and OpenProject |
532 # Keep track of the plugin type name |
533 # Keep track of the plugin type name |
533 self.PlugType = "Beremiz" |
534 self.PlugType = "Beremiz" |
534 |
535 |
535 # After __init__ root plugin is not valid |
536 # After __init__ root plugin is not valid |
536 self.ProjectPath = None |
537 self.ProjectPath = None |
537 self.PLCManager = None |
|
538 self.PLCEditor = None |
538 self.PLCEditor = None |
539 |
539 |
540 def HasProjectOpened(self): |
540 def HasProjectOpened(self): |
541 """ |
541 """ |
542 Return if a project is actually opened |
542 Return if a project is actually opened |
575 dialog.Destroy() |
575 dialog.Destroy() |
576 else: |
576 else: |
577 dialog.Destroy() |
577 dialog.Destroy() |
578 return "Project not created" |
578 return "Project not created" |
579 |
579 |
580 # Create Controler for PLCOpen program |
580 # Create PLCOpen program |
581 self.PLCManager = PLCControler() |
581 self.CreateNewProject(values.pop("projectName")) |
582 self.PLCManager.CreateNewProject(values.pop("projectName")) |
582 self.SetProjectProperties(properties = values) |
583 self.PLCManager.SetProjectProperties(properties = values) |
|
584 # Change XSD into class members |
583 # Change XSD into class members |
585 self._AddParamsMembers() |
584 self._AddParamsMembers() |
586 self.PluggedChilds = {} |
585 self.PluggedChilds = {} |
587 # Keep track of the root plugin (i.e. project path) |
586 # Keep track of the root plugin (i.e. project path) |
588 self.ProjectPath = ProjectPath |
587 self.ProjectPath = ProjectPath |
|
588 self.RefreshPluginsBlockLists() |
589 return None |
589 return None |
590 |
590 |
591 def LoadProject(self, ProjectPath, logger): |
591 def LoadProject(self, ProjectPath, logger): |
592 """ |
592 """ |
593 Load a project contained in a folder |
593 Load a project contained in a folder |
595 """ |
595 """ |
596 # Verify that project contains a PLCOpen program |
596 # Verify that project contains a PLCOpen program |
597 plc_file = os.path.join(ProjectPath, "plc.xml") |
597 plc_file = os.path.join(ProjectPath, "plc.xml") |
598 if not os.path.isfile(plc_file): |
598 if not os.path.isfile(plc_file): |
599 return "Folder choosen doesn't contain a program. It's not a valid project!" |
599 return "Folder choosen doesn't contain a program. It's not a valid project!" |
600 # Create Controler for PLCOpen program |
|
601 self.PLCManager = PLCControler() |
|
602 # Load PLCOpen file |
600 # Load PLCOpen file |
603 result = self.PLCManager.OpenXMLFile(plc_file) |
601 result = self.OpenXMLFile(plc_file) |
604 if result: |
602 if result: |
605 return result |
603 return result |
606 # Change XSD into class members |
604 # Change XSD into class members |
607 self._AddParamsMembers() |
605 self._AddParamsMembers() |
608 self.PluggedChilds = {} |
606 self.PluggedChilds = {} |
614 result = self.LoadXMLParams() |
612 result = self.LoadXMLParams() |
615 if result: |
613 if result: |
616 return result |
614 return result |
617 #Load and init all the childs |
615 #Load and init all the childs |
618 self.LoadChilds(logger) |
616 self.LoadChilds(logger) |
|
617 self.RefreshPluginsBlockLists() |
619 return None |
618 return None |
620 |
619 |
621 def SaveProject(self): |
620 def SaveProject(self): |
622 if not self.PLCManager.SaveXMLFile(): |
621 if not self.SaveXMLFile(): |
623 self.PLCManager.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml')) |
622 self.SaveXMLFile(os.path.join(self.ProjectPath, 'plc.xml')) |
624 if self.PLCEditor: |
623 if self.PLCEditor: |
625 self.PLCEditor.RefreshTitle() |
624 self.PLCEditor.RefreshTitle() |
626 self.PlugRequestSave() |
625 self.PlugRequestSave() |
|
626 |
|
627 # Update PLCOpenEditor Plugin Block types from loaded plugins |
|
628 def RefreshPluginsBlockLists(self): |
|
629 ClearPluginTypes() |
|
630 AddPluginBlockList(self.BlockTypesFactory()) |
|
631 for child in self.IterChilds(): |
|
632 AddPluginBlockList(child.BlockTypesFactory()) |
627 |
633 |
628 def PlugPath(self, PlugName=None): |
634 def PlugPath(self, PlugName=None): |
629 return self.ProjectPath |
635 return self.ProjectPath |
630 |
636 |
631 def PluginXmlFilePath(self, PlugName=None): |
637 def PluginXmlFilePath(self, PlugName=None): |
653 Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2CC |
659 Generate SoftPLC ST/IL/SFC code out of PLCOpenEditor controller, and compile it with IEC2CC |
654 @param buildpath: path where files should be created |
660 @param buildpath: path where files should be created |
655 @param logger: the log pseudo file |
661 @param logger: the log pseudo file |
656 """ |
662 """ |
657 |
663 |
|
664 # Update PLCOpenEditor Plugin Block types before generate ST code |
|
665 self.RefreshPluginsBlockLists() |
|
666 |
658 logger.write("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n") |
667 logger.write("Generating SoftPLC IEC-61131 ST/IL/SFC code...\n") |
659 buildpath = self._getBuildPath() |
668 buildpath = self._getBuildPath() |
660 # define name for IEC code file |
669 # define name for IEC code file |
661 plc_file = self._getIECcodepath() |
670 plc_file = self._getIECcodepath() |
662 # ask PLCOpenEditor controller to write ST/IL/SFC code file |
671 # ask PLCOpenEditor controller to write ST/IL/SFC code file |
663 result = self.PLCManager.GenerateProgram(plc_file) |
672 result = self.GenerateProgram(plc_file) |
664 if not result: |
673 if not result: |
665 # Failed ! |
674 # Failed ! |
666 logger.write_error("Error : ST/IL/SFC code generator returned %d\n"%result) |
675 logger.write_error("Error : ST/IL/SFC code generator returned %d\n"%result) |
667 return False |
676 return False |
668 logger.write("Compiling ST Program in to C Program...\n") |
677 logger.write("Compiling ST Program in to C Program...\n") |
761 |
770 |
762 new_dialog.Show() |
771 new_dialog.Show() |
763 |
772 |
764 def _EditPLC(self, logger): |
773 def _EditPLC(self, logger): |
765 if not self.PLCEditor: |
774 if not self.PLCEditor: |
|
775 self.RefreshPluginsBlockLists() |
766 def _onclose(): |
776 def _onclose(): |
767 self.PLCEditor = None |
777 self.PLCEditor = None |
768 def _onsave(): |
778 def _onsave(): |
769 self.SaveProject() |
779 self.SaveProject() |
770 self.PLCEditor = PLCOpenEditor(self.AppFrame, self.PLCManager) |
780 self.PLCEditor = PLCOpenEditor(self.AppFrame, self) |
771 self.PLCEditor.RefreshProjectTree() |
781 self.PLCEditor.RefreshProjectTree() |
772 self.PLCEditor.RefreshFileMenu() |
782 self.PLCEditor.RefreshFileMenu() |
773 self.PLCEditor.RefreshEditMenu() |
783 self.PLCEditor.RefreshEditMenu() |
774 self.PLCEditor.RefreshToolBar() |
784 self.PLCEditor.RefreshToolBar() |
775 self.PLCEditor._onclose = _onclose |
785 self.PLCEditor._onclose = _onclose |