Пример #1
0
 public Block(PlcBlock plcBlock)
 {
     _block  = plcBlock;
     _parent = (PlcBlockGroup)_block.Parent;
     Name    = plcBlock.Name;
     SetChangeableState();
 }
Пример #2
0
        private void menuSofwareAdd_Click(object sender, EventArgs e)
        {
            PlcSoftware   soft  = (PlcSoftware)treeView1.SelectedNode.Tag;
            PlcBlockGroup group = soft.BlockGroup;

            string       name = string.Empty;
            DialogResult dlg  = Input.InputBox("Enter new group name", "New group", ref name);

            if (dlg == DialogResult.OK)
            {
                if (name != string.Empty)
                {
                    if (!groups.GroupExists(name, group))
                    {
                        try
                        {
                            group.Groups.Create(name);
                            IterateThroughDevices(project);
                        }
                        catch (Exception ex)
                        {
                            MessageError(ex.Message, "Exception");
                        }
                    }
                    else
                    {
                        MessageError(name + " exist already", "Name exist already");
                    }
                }
            }
        }
Пример #3
0
        private void menuGroupDelete_Click(object sender, EventArgs e)
        {
            // delete group
            PlcBlockGroup group = (PlcBlockGroup)treeView1.SelectedNode.Tag;

            if (group.Blocks.Count > 0)
            {
                MessageOK("The group " + group.Name + " has sub blocks!\nDelete this blocks first", "Delete group");
                return;
            }

            if (group.Groups.Count > 0)
            {
                MessageOK("The group " + group.Name + " has sub groups!\nDelete this groups first", "Delete group");
                return;
            }

            if (MessageYesNo("Do you really want to delete the group " + group.Name + "?", "Delete block") == DialogResult.Yes)
            {
                // not implemented yet, there is no method to delete a group?

                // code from Tia Example is using invoke
                var selectedProjectObject = treeView1.SelectedNode.Tag;
                try
                {
                    var engineeringObject = selectedProjectObject as IEngineeringObject;
                    engineeringObject?.Invoke("Delete", new Dictionary <Type, object>());
                }
                catch (EngineeringException)
                {
                }
                IterateThroughDevices(project);
            }
        }
Пример #4
0
        private void btnAddPath_Click(object sender, EventArgs e)
        {
            if (software != null)
            {
                string[]      lst   = txtPath.Text.Split('\\');
                PlcBlockGroup group = software.BlockGroup;

                foreach (string p in lst)
                {
                    string name = p.Trim();
                    if (!groups.GroupExists(name, group))
                    {
                        try
                        {
                            // create new group
                            group.Groups.Create(name);
                        }
                        catch (Exception ex)
                        {
                            MessageError(ex.Message, "Exception");
                            break;
                        }
                    }
                    else
                    {
                        // grop exist already
                    }

                    // into next group
                    group = group.Groups.Find(name);
                }

                IterateThroughDevices(project);
            }
        }
Пример #5
0
 private void WriteGroupList(PlcBlockGroup plcGroup)
 {
     WriteDebug($"WriteGroupList/1 for {plcGroup?.Name}");
     foreach (PlcBlockGroup grp in plcGroup?.Groups)
     {
         WriteObject(grp);
     }
 }
 public CreatePresetRecallBlockTask(TiaPortal portal, IList <PresetTag> tags, PlcBlockGroup blockGroup, string blockName, string value_type_name, string enable_type_name)
 {
     this.portal         = portal;
     this.tags           = tags;
     this.resultGroup    = blockGroup;
     this.valueTypeName  = value_type_name;
     this.enableTypeName = enable_type_name;
     this.blockName      = blockName;
     Description         = "Create recall SCL block " + blockName;
 }
Пример #7
0
        public PresetGenerate(TiaPortal portal, IEngineeringCompositionOrObject top, List <HmiTarget> hmiTargets, string culture)
        {
            InitializeComponent();
            tiaPortal    = portal;
            FormClosing += FormClosingEventHandler;
            presetListView.AutoGenerateColumns = false;
            presetList = new PresetTagList
            {
                Culture = culture
            };
            presetListView.DataSource = presetList;

            writeButton.Enabled  = false;
            exportButton.Enabled = false;
            parser            = new TagParser(portal);
            parser.HandleTag += HandleTag;
            parser.ParseDone += ParseDone;
            parser.ParseAsync(top, log);

            IEngineeringCompositionOrObject node = top;

            while (node.Parent is PlcBlockGroup)
            {
                node = node.Parent;
            }
            PlcBlockGroup top_group = (PlcBlockGroup)node;

            resultGroup = top_group.Groups.Find("Preset");
            if (resultGroup == null)
            {
                resultGroup = top_group.Groups.Create("Preset");
            }
            while (node != null && !(node is PlcSoftware))
            {
                node = node.Parent;
            }
            if (node == null)
            {
                throw new Exception("No PlcSoftware node found");
            }
            plcSoftware = (PlcSoftware)node;
            typeGroup   = plcSoftware.TypeGroup.Groups.Find("Preset");
            if (typeGroup == null)
            {
                typeGroup = plcSoftware.TypeGroup.Groups.Create("Preset");
            }
            this.hmiTargets = hmiTargets;

            Project             proj  = tiaPortal.Projects[0];
            LanguageAssociation langs = proj.LanguageSettings.ActiveLanguages;

            cultureComboBox.Items.Clear();
            cultureComboBox.Items.AddRange(langs.Select(l => l.Culture.Name).ToArray());
            cultureComboBox.SelectedItem = culture;
        }
Пример #8
0
        private static void HandleBlockFolder(NodeHandler handler, PlcBlockGroup folder)
        {
            NodeHandler child_handler = handler.Enter(folder, folder.Name);

            if (child_handler != null)
            {
                iterDataBlock(child_handler, folder.Blocks);
                iterBlockFolder(child_handler, folder.Groups);
            }
            handler.Exit(folder);
        }
Пример #9
0
 public List <string> GetAllBlocksNames(PlcBlockGroup SearchGroup, List <string> result)
 {
     foreach (PlcBlock block in SearchGroup.Blocks)
     {
         result.Add(block.Name);
     }
     foreach (PlcBlockGroup group in SearchGroup.Groups)
     {
         result = GetAllBlocksNames(group, result);
     }
     return(result);
 }
Пример #10
0
        public bool GroupExists(string Name, PlcBlockGroup Group)
        {
            foreach (PlcBlockGroup g in Group.Groups)
            {
                if (g.Name.ToLower() == Name.ToLower())
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #11
0
 public List <PlcBlock> GetAllBlocks(PlcBlockGroup SearchGroup, List <PlcBlock> result)
 {
     foreach (PlcBlock block in SearchGroup.Blocks)
     {
         result.Add(block);
     }
     foreach (PlcBlockGroup group in SearchGroup.Groups)
     {
         result = GetAllBlocks(group, result);
     }
     return(result);
 }
Пример #12
0
 private void AddBlocks(PlcBlockGroup group)
 {
     foreach (PlcBlock block in group.Blocks)
     {
         worker.ReportProgress(50, new NodeData(NodeDest.From, block.Name, block));
     }
     foreach (PlcBlockGroup child in group.Groups)
     {
         worker.ReportProgress(50, new NodeEnter(NodeDest.From, child.Name, true));
         AddBlocks(child);
         worker.ReportProgress(50, new NodeExit(NodeDest.From));
     }
 }
Пример #13
0
 protected void BlockGroupIter(PlcBlockGroup group, string function, string HMI_group)
 {
     foreach (PlcBlock block in group.Blocks)
     {
         Console.WriteLine("Block " + block.Name);
         if (block.ProgrammingLanguage == ProgrammingLanguage.DB)
         {
             if (block.HeaderFamily == "HMI" || block.HeaderFamily == "Settings")
             {
                 find_db_worker.ReportProgress(50, new HMItagInfo(block, hmi.TagFolder, function));
             }
         }
     }
 }
 /// <summary>
 /// Adds all PlcBlocks with the defined ProgrammingLanguage to collection
 /// </summary>
 /// <param name="folder">The folder.</param>
 /// <param name="language">The language.</param>
 /// <param name="collection">The collection.</param>
 private static void RecursiveFindBlocksByLanguage(PlcBlockGroup folder, ProgrammingLanguage language, ref Collection <PlcBlock> collection)
 {
     foreach (var block in folder.Blocks)
     {
         if (block.ProgrammingLanguage == language)
         {
             collection.Add(block);
         }
     }
     foreach (var subFolder in folder.Groups)
     {
         RecursiveFindBlocksByLanguage(subFolder, language, ref collection);
     }
 }
Пример #15
0
        private PlcBlock findPlcBlock(PathComponent path, PlcBlockGroup blocks)
        {
            while (path.Parent != null)
            {
                path = path.Parent;
            }
            if (!(path is MemberComponent))
            {
                return(null);
            }
            string name = ((MemberComponent)path).Name;

            Console.WriteLine("Name " + name);
            return(findPlcBlockName(name, blocks));
        }
Пример #16
0
        private void menuGroupAdd_Click(object sender, EventArgs e)
        {
            PlcBlockGroup group = (PlcBlockGroup)treeView1.SelectedNode.Tag;

            string       name = string.Empty;
            DialogResult dlg  = Input.InputBox("Enter new group name", "New group", ref name);

            if (dlg == DialogResult.OK)
            {
                if (name != string.Empty)
                {
                    group.Groups.Create(name);
                    IterateThroughDevices(project);
                }
            }
        }
Пример #17
0
        private PlcBlock findPlcBlockName(string name, PlcBlockGroup blocks)
        {
            PlcBlock block = blocks.Blocks.Find(name);

            if (block == null)
            {
                foreach (PlcBlockGroup group in blocks.Groups)
                {
                    block = findPlcBlockName(name, group);
                    if (block != null)
                    {
                        break;
                    }
                }
            }
            return(block);
        }
Пример #18
0
 private static void ExportSystemBlocks(PlcSoftware plcsoftware)
 {
     try
     {
         PlcBlockGroup sbSystemGroup = plcsoftware.BlockGroup;
         foreach (PlcBlockGroup group in sbSystemGroup.Groups)
         {
             foreach (PlcBlock block in group.Blocks)
             {
                 block.Export(new FileInfo(string.Format(@"C:\test\" + block.Name + ".xml")), ExportOptions.WithDefaults);
             }
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Chyba: " + ex);
     }
 }
Пример #19
0
        //Import blocks
        private static void ImportBlocks(PlcSoftware plcSoftware, string path)
        {
            try
            {
                // PlcBlockGroup blockGroup = plcSoftware.BlockGroup;
                // IList<PlcBlock> blocks = blockGroup.Blocks.Import(new FileInfo(path), ImportOptions.Override);
                PlcBlockGroup blockGroup = plcSoftware.BlockGroup;
                string[]      files      = Directory.GetFiles(path, "*", SearchOption.AllDirectories);

                foreach (var block in files)
                {
                    IList <PlcBlock> blocks = blockGroup.Blocks.Import(new FileInfo(block), ImportOptions.Override);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Chyba: " + ex.Message);
            }
        }
Пример #20
0
 private void WriteGroupList(string path, PlcBlockGroup plcGroup)
 {
     WriteDebug($"WriteGroupList/2 for {plcGroup?.Name}");
     if (filter != null)
     {
         var npath = path + pathDelimeter;
         foreach (PlcBlockGroup grp in plcGroup?.Groups)
         {
             var opath = npath + grp.Name;
             WriteDebug($"[WriteGroupList] matching the {opath} with {includePattern} and with {excludePattern}");
             if (filter.IsMatch(opath))
             {
                 WriteObject(grp);
             }
         }
     }
     else
     {
         WriteGroupList(plcGroup);
     }
 }
Пример #21
0
        private PlcBlockGroup GetUserGroup(string path, PlcBlockUserGroupComposition root)
        {
            PlcBlockUserGroupComposition ugc = root;
            PlcBlockGroup grp = null;

            char[]   sep     = { pathDelimeter };
            string[] ugnames = path.Split(sep, StringSplitOptions.RemoveEmptyEntries);
            WriteDebug($"[GetUserGroup] path is {path}");
            if (ugnames.Length > 0)
            {
                WriteDebug($"[GetUserGroup] root group is {ugnames[0]}");
                foreach (String gn in ugnames)
                {
                    if (ugc != null)
                    {
                        WriteDebug($"[GetUserGroup] the group {gn} is finding");
                        grp = ugc.Find(gn);
                        if (grp != null)
                        {
                            ugc = grp.Groups;
                            WriteDebug($"[GetUserGroup] the group {gn} is found");
                        }
                        else
                        {
                            WriteDebug($"[GetUserGroup] the group {gn} is not found");
                            break;
                        }
                    }
                    else
                    {
                        grp = null;
                        break;
                    }
                }
                return(grp);
            }
            return(null);
        }
Пример #22
0
        static public void ImportPlcBlockXML(XmlDocument doc, PlcBlockGroup group)
        {
            FileInfo path = TempFile.File("import_block_", "xml");

            try {
                XmlWriter writer = XmlWriter.Create(path.ToString());
                doc.Save(writer);
                writer.Close();

                group.Blocks.Import(path, ImportOptions.Override);
            }
            finally
            {
                try
                {
                    path.Delete();
                }
                catch (IOException e)
                {
                    Console.WriteLine("Failed to delete temporary file: " + e.Message);
                }
            }
        }
Пример #23
0
 protected override void DoWork()
 {
     lock (portal)
     {
         try
         {
             Stack <string>     group_names = new Stack <string>();
             IEngineeringObject obj         = fromBlock.Parent;
             while (obj is PlcBlockUserGroup)
             {
                 group_names.Push(((PlcBlockGroup)obj).Name);
                 obj = obj.Parent;
             }
             PlcBlockGroup group = toPlc.BlockGroup;
             foreach (string group_name in group_names)
             {
                 PlcBlockUserGroup child = group.Groups.Find(group_name);
                 if (child != null)
                 {
                     group = child;
                 }
                 else
                 {
                     group = group.Groups.Create(group_name);
                 }
             }
             FileInfo file = TempFile.File("export_block_", "xml");
             fromBlock.Export(file, ExportOptions.None);
             group.Blocks.Import(file, overwrite ? ImportOptions.Override : ImportOptions.None);
         } catch (Exception ex)
         {
             LogMessage(MessageLog.Severity.Error, "Failed to copy from " + fromBlock.Name + " to " + toPlc.Name + ":\n" + ex.Message);
             return;
         }
     }
 }
Пример #24
0
 internal void LoadSubProgramBlocksFoldersViaOpennessDlls(TIAOpennessProgramFolder parent, PlcBlockGroup plcBlockGroup)
 {
     foreach (var e in plcBlockGroup.Groups)
     {
         var fld = new TIAOpennessProgramFolder(this, parent.ControllerFolder, e.Blocks)
         {
             //TiaPortalItem = e,
             Name   = e.Name,
             Parent = parent,
         };
         parent.SubItems.Add(fld);
         LoadSubProgramBlocksFoldersViaOpennessDlls(fld, e);
     }
 }
Пример #25
0
 private void ImportBlocks(PlcSoftware plcSoftware, string path)
 {
     //string path = _OFD_Import.FileName;
     PlcBlockGroup    blockGroup = plcSoftware.BlockGroup;
     IList <PlcBlock> blocks     = blockGroup.Blocks.Import(new FileInfo(path), ImportOptions.Override);
 }
Пример #26
0
 public void HandleBlockFolder(PlcBlockGroup folder)
 {
     IterDataBlock(folder.Blocks);
     IterBlockFolder(folder.Groups);
 }
Пример #27
0
        private void blocksToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (software == null)
            {
                return;
            }

            DialogResult res;

            if (treeView1.SelectedNode != null)
            {
                var sel = treeView1.SelectedNode.Tag;
                if (sel is PlcBlockGroup)
                {
                    try
                    {
                        string importPath = (string)Properties.Settings.Default["PathImportBlock"];
                        if (importPath == string.Empty)
                        {
                            importPath = Application.StartupPath + "\\Import";
                        }

                        using (OpenFileDialog openFileDialog = new OpenFileDialog())
                        {
                            openFileDialog.Filter           = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
                            openFileDialog.FilterIndex      = 1;
                            openFileDialog.InitialDirectory = importPath;

                            if (openFileDialog.ShowDialog() == DialogResult.OK)
                            {
                                Properties.Settings.Default["PathImportBlock"] = openFileDialog.FileName;
                                Properties.Settings.Default.Save();

                                PlcBlockGroup group = (PlcBlockGroup)sel;
                                cImportBlock  f     = new cImportBlock(openFileDialog.FileName);
                                if (f.BlockName != string.Empty)
                                {
                                    // check if the data type exists
                                    if (!groups.NameExists(f.BlockName, software))
                                    {
                                        // import the file
                                        group.Blocks.Import(f.XmlFileInfo, ImportOptions.None);
                                        IterateThroughDevices(project);
                                    }
                                    else
                                    {
                                        // overwrite? yes = overwrite / no = new name / cancel = just cancel
                                        res = MessageBox.Show("Data block " + f.BlockName + " exists already. Overwrite(Yes) or Rename(No) ?",
                                                              "Overwrite / Rename",
                                                              MessageBoxButtons.YesNoCancel,
                                                              MessageBoxIcon.Question);

                                        if (res == DialogResult.Yes)
                                        {
                                            // overwrite plc block
                                            group.Blocks.Import(f.XmlFileInfo, ImportOptions.Override);
                                            IterateThroughDevices(project);
                                        }
                                        else if (res == DialogResult.No)
                                        {
                                            // with a different name we need to save a copy
                                            res = DialogResult.OK;
                                            string newName = f.BlockName;

                                            while (groups.NameExists(newName, software) && res == DialogResult.OK)
                                            {
                                                res = Input.InputBox("New block name", "Enter a new block name", ref newName);
                                            }
                                            // we don't cancel, so import with new name
                                            if (res == DialogResult.OK)
                                            {
                                                f.BlockName = newName;
                                                f.SaveXml(Application.StartupPath + "\\Temp\\temp.xml");

                                                group.Blocks.Import(f.XmlFileInfo, ImportOptions.None);
                                                IterateThroughDevices(project);
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    MessageOK("The file " + Path.GetFileName(openFileDialog.FileName) + " is not PLC block",
                                              "Not a PLC block file");
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageError(ex.Message,
                                     "Exception");
                    }
                }
                else
                {
                    MessageOK("Not a group selected!",
                              "Not a group");
                }
            }
            else
            {
                MessageOK("Nothing selected!",
                          "Select a group");
            }
        }
Пример #28
0
        private void exportButton_Click(object sender, EventArgs e)
        {
            if (savePresetList.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    ConstantLookup constants = new ConstantLookup();
                    constants.Populate(tiaPortal, plcSoftware);

                    Dictionary <string, List <PresetTag> > tag_groups = tagGroups(presetList);

                    PlcBlockGroup plc_preset_group = plcSoftware.BlockGroup.Groups.Find("Preset");
                    if (plc_preset_group == null)
                    {
                        MessageBox.Show("No group named Preset found for PLC " + plcSoftware.Name);
                        return;
                    }
                    Dictionary <string, PresetGroup> preset_groups = new Dictionary <string, PresetGroup>();


                    foreach (string group_name in tag_groups.Keys)
                    {
                        PresetGroup group          = new PresetGroup();
                        string      preset_db_name = "sDB_Preset_" + group_name;
                        PlcBlock    preset_db      = plc_preset_group.Blocks.Find(preset_db_name);
                        if (preset_db == null)
                        {
                            MessageBox.Show("No block named " + preset_db_name + " found for PLC " + plcSoftware.Name);
                            return;
                        }
                        XmlDocument doc;
                        try
                        {
                            doc = TIAutils.ExportPlcBlockXML(preset_db);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Failed to export block " + preset_db_name + ": " + ex.Message);
                            return;
                        }

                        if (doc.DocumentElement.SelectSingleNode("/Document/SW.Blocks.GlobalDB//if:Section[@Name='Static']", XMLUtil.nameSpaces) is XmlElement static_elem)
                        {
                            group.preset_names  = PresetValueParser.GetPresetNames(static_elem, constants);
                            group.preset_colors = PresetValueParser.GetPresetColors(static_elem, constants);
                            group.presets       = new List <PresetDocument.PresetInfo>();
                            var tags = tag_groups[group_name];
                            foreach (var tag in tags)
                            {
                                var values  = PresetValueParser.GetPresetValue(static_elem, tag.tagPath, constants);
                                var enabled = PresetValueParser.GetPresetEnabled(static_elem, tag.tagPath, constants);
                                Console.WriteLine(tag.tagPath + ":" + (string.Join(",", values)));
                                group.presets.Add(new PresetDocument.PresetInfo()
                                {
                                    tag = tag, values = values, enabled = enabled
                                });
                            }

                            preset_groups[group_name] = group;
                        }
                        else
                        {
                            MessageBox.Show("No static section found for " + preset_db_name);
                            return;
                        }
                    }



                    PresetDocument.Save(savePresetList.FileName, preset_groups, cultureComboBox.SelectedItem.ToString());
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Failed to export preset list: " + ex.Message);
                }
            }
        }
Пример #29
0
        void UpdatePresetValues(
            PlcSoftware plcSoftware,
            Dictionary <string, PresetGroup> preset_groups)
        {
            ConstantLookup constants = new ConstantLookup();

            constants.Populate(tiaPortal, plcSoftware);



            PlcBlockGroup preset_group = plcSoftware.BlockGroup.Groups.Find("Preset");

            if (preset_group == null)
            {
                MessageBox.Show("No group named Preset found for PLC " + plcSoftware.Name);
                return;
            }

            foreach (string group_name in preset_groups.Keys)
            {
                string   preset_db_name = "sDB_Preset_" + group_name;
                PlcBlock preset_db      = preset_group.Blocks.Find(preset_db_name);
                if (preset_db == null)
                {
                    MessageBox.Show("No block named " + preset_db_name + " found for PLC " + plcSoftware.Name);
                    return;
                }
                XmlDocument doc;
                try
                {
                    doc = TIAutils.ExportPlcBlockXML(preset_db);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Failed to export block " + preset_db_name + ": " + ex.Message);
                    return;
                }

                if (doc.DocumentElement.SelectSingleNode("/Document/SW.Blocks.GlobalDB//if:Section[@Name='Static']", XMLUtil.nameSpaces) is XmlElement static_elem)
                {
                    var infos = preset_groups[group_name].presets;
                    foreach (PresetInfo info in infos)
                    {
                        PresetValueParser.SetPresetValue(static_elem, info.tag.tagPath, constants, info.values);
                        PresetValueParser.SetPresetEnabled(static_elem, info.tag.tagPath, constants, info.enabled);
                    }
                    PresetValueParser.SetPresetNames(static_elem, constants, preset_groups[group_name].preset_names);
                    PresetValueParser.SetPresetColors(static_elem, constants, preset_groups[group_name].preset_colors);
                }
                else
                {
                    MessageBox.Show("No static section found for " + preset_db_name);
                    return;
                }
                try
                {
                    var group = (Siemens.Engineering.SW.Blocks.PlcBlockGroup)preset_db.Parent;
                    var name  = group.Name;
                    TIAutils.ImportPlcBlockXML(doc, group);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Failed to import block " + preset_db_name + ": " + ex.Message);
                    return;
                }
            }
        }
Пример #30
0
        public void AddPlcBlocks(PlcBlockGroup plcGroup, TreeNode node)
        {
            // first add all plc blocks
            foreach (PlcBlock plcBlock in plcGroup.Blocks)
            {
                TreeNode n = null;

                if (plcBlock is OB)
                {
                    n     = new TreeNode(plcBlock.Name + " [OB" + plcBlock.Number.ToString() + "]");
                    n.Tag = plcBlock;
                    //n.ToolTipText = "Version " + plcBlock.HeaderVersion.ToString();
                    n.ImageIndex = 2;

                    OB ob = (OB)plcBlock;
                    if (ob.SecondaryType.Contains("Safe"))
                    {
                        n.BackColor  = Color.Yellow;
                        n.ImageIndex = 7;
                    }
                }
                else if (plcBlock is FB)
                {
                    n            = new TreeNode(plcBlock.Name + " [FB" + plcBlock.Number.ToString() + "]");
                    n.Tag        = plcBlock;
                    n.ImageIndex = 3;

                    FB fb = (FB)plcBlock;
                    if ((fb.ProgrammingLanguage == ProgrammingLanguage.F_LAD) ||
                        (fb.ProgrammingLanguage == ProgrammingLanguage.F_FBD))
                    {
                        n.BackColor  = Color.Yellow;
                        n.ImageIndex = 8;
                    }
                }
                else if (plcBlock is FC)
                {
                    n            = new TreeNode(plcBlock.Name + " [FC" + plcBlock.Number.ToString() + "]");
                    n.Tag        = plcBlock;
                    n.ImageIndex = 4;
                }
                else if (plcBlock is InstanceDB)
                {
                    n            = new TreeNode(plcBlock.Name + " [DB" + plcBlock.Number.ToString() + "]");
                    n.Tag        = plcBlock;
                    n.ImageIndex = 5;

                    InstanceDB db = (InstanceDB)plcBlock;
                    n.Name = db.Name + "[DB" + db.Number.ToString() + "]";
                    if (db.ProgrammingLanguage == ProgrammingLanguage.F_DB)
                    {
                        n.BackColor  = Color.Yellow;
                        n.ImageIndex = 6;
                    }
                }
                else if (plcBlock is GlobalDB)
                {
                    n            = new TreeNode(plcBlock.Name + " [DB" + plcBlock.Number.ToString() + "]");
                    n.Tag        = plcBlock;
                    n.ImageIndex = 5;

                    GlobalDB db = (GlobalDB)plcBlock;
                    n.Name = db.Name + "[FB" + db.Number.ToString() + "]";
                    if (db.ProgrammingLanguage == ProgrammingLanguage.F_DB)
                    {
                        n.BackColor  = Color.Yellow;
                        n.ImageIndex = 6;
                    }
                }

                n.SelectedImageIndex = n.ImageIndex;
                node.Nodes.Add(n);
            }

            // then add groups and search recursive
            foreach (PlcBlockGroup group in plcGroup.Groups)
            {
                TreeNode n = new TreeNode(group.Name);
                n.Tag                = group;
                n.ImageIndex         = 1;
                n.SelectedImageIndex = 1;

                AddPlcBlocks(group, n);
                node.Nodes.Add(n);
            }
        }