Inheritance: Microsoft.Windows.Controls.Ribbon.RibbonSplitMenuItem
        // The above mentioned solution for Dev10 bug# 908460 needed another supporting change.
        // The base class for RibbonApplicationMenu viz. MenuBase woudn't wait for the
        // CloseSubmenuTimer to elapse but instead forcibly closed the first Popup as soon as
        // the second one was about to show. And this happened when the IsSubmenuOpen property
        // on the first Popup was being turned off. So in order to counter this behavior, we
        // now coerce the IsSubenuOpen property for top level RibbonApplicationMenuItems and
        // RibbonApplicationSplitMenuItems whenever the timer is running and the current
        // selection has moved to another MenuItem with a submenu.

        private static object CoerceIsSubmenuOpen(DependencyObject d, object baseValue)
        {
            RibbonApplicationSplitMenuItem menuItem = (RibbonApplicationSplitMenuItem)d;

            if (menuItem.Level == RibbonApplicationMenuItemLevel.Top)
            {
                return(RibbonHelper.CoerceIsSubmenuOpenForTopLevelItem(menuItem, menuItem.ParentItemsControl, (bool)baseValue));
            }

            return(baseValue);
        }
Example #2
0
        /// <summary>
        /// Save the selected group to a file, so that it can be reused
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveGroupButton_Click(object sender, RoutedEventArgs e)
        {
            groupComponent groupToSave = null;
            foreach (componentType mc in selectedComponentList) {
                if (mc.ComponentType == ACS2.componentTypeDataTypes.group) {
                    groupToSave = groupsList[mc.id];
                    break;
                }
            }
            if (groupToSave != null) {
                storageDialog = new StorageDialog();

                string[] filesInGroupsFolder;
                if (ini.IniReadValue("Options", "useAppDataFolder").Equals("true")) {
                    filesInGroupsFolder = Directory.GetFiles(Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + "\\AsTeRICS\\ACS\\groups\\", "*.agr");
                } else {
                    filesInGroupsFolder = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "\\groups\\", "*.agr");
                }
                foreach (string s in filesInGroupsFolder) {
                    storageDialog.filenameListbox.Items.Add(s.Substring(s.LastIndexOf('\\') + 1));
                }
                storageDialog.filenameListbox.SelectionChanged += filenameListbox_SelectionChanged;
                storageDialog.Title = Properties.Resources.GroupStoreDialogTitle;
                storageDialog.listLabel.Content = Properties.Resources.GroupStoreDialogListLabel;
                storageDialog.filenameTextbox.Text = "NewGroup.agr";

                storageDialog.modelNameLabel.Content = Properties.Resources.GroupStoreDialogGroupName;

                storageDialog.Owner = this;
                storageDialog.ShowDialog();

                if (storageDialog.filenameTextbox.Text != null && storageDialog.filenameTextbox.Text != "") {
                    try {
                        model groupModelToSave;
                        if (groupToSave != null) {
                            ClearSelectedChannelList();
                            ClearSelectedEventChannelList();
                            ClearSelectedComponentList();

                            foreach (componentType componentInGroup in groupToSave.AddedComponentList) {
                                AddSelectedComponent(deploymentComponentList[componentInGroup.id]);
                            }

                            // make a submodel, containing all grouging relevant data

                            groupModelToSave = new model();
                            groupModelToSave.modelName = groupToSave.GroupID;
                            // insert all selected components to the model
                            LinkedList<componentType> t = new LinkedList<componentType>();
                            for (int i = 0; i < selectedComponentList.Count; i++) {
                                componentType ct = selectedComponentList.ElementAt(i);
                                t.AddLast(ct);
                            }
                            groupModelToSave.components = t.ToArray();
                            // adding a group element to save the aliases
                            groupModelToSave.groups = new group[1];
                            foreach (group groupToAdd in deploymentModel.groups) {
                                if (groupToAdd.id == groupToSave.ID) {
                                    groupModelToSave.groups[0] = groupToAdd;
                                    break;
                                }
                            }

                            //get all selected channels where the source and target components
                            //are also selected
                            LinkedList<channel> copyChannels = new LinkedList<channel>();
                            foreach (channel c in groupToSave.AddedChannelsList) {
                                bool sourceFound, targetFound;
                                sourceFound = targetFound = false;
                                foreach (componentType mc in groupModelToSave.components) {
                                    if (mc.id == c.source.component.id)
                                        sourceFound = true;
                                    if (mc.id == c.target.component.id)
                                        targetFound = true;
                                    if (sourceFound && targetFound)
                                        break;
                                }
                                if (sourceFound && targetFound)
                                    copyChannels.AddLast(c);
                            }

                            // Adding dummy channels to make the input and output ports of the group visible

                            componentType groupComponent = deploymentComponentList[groupToSave.ID];
                            int index = 0;
                            foreach (object o in groupComponent.ports) {
                                channel c = new channel();
                                c.id = "bindingveigl." + index;
                                if (o is inputPortType) {
                                    c.source.component.id = pasteDummyName;
                                    c.source.port.id = "out";
                                    c.target.component.id = ((inputPortType)o).refs.componentID;
                                    c.target.port.id = ((inputPortType)o).refs.portID;
                                } else {
                                    c.source.component.id = ((outputPortType)o).refs.componentID;
                                    c.source.port.id = ((outputPortType)o).refs.portID;
                                    c.target.component.id = pasteDummyName;
                                    c.target.port.id = "in";
                                }
                                copyChannels.AddLast(c);
                                index++;
                            }

                            groupModelToSave.channels = new channel[copyChannels.Count];
                            for (int i = 0; i < copyChannels.Count; i++)
                                groupModelToSave.channels[i] = copyChannels.ElementAt(i);

                            // get all selected Eventchannels

                            index = 0;
                            LinkedList<eventChannel> copyEventChannels = new LinkedList<eventChannel>();
                            LinkedList<EventListenerPort> foundEdgeListenerEvents = new LinkedList<EventListenerPort>();
                            LinkedList<EventTriggerPort> foundEdgeTriggerEvents = new LinkedList<EventTriggerPort>();
                            foreach (eventChannel ec in eventChannelList) {
                                // search for each event channel on the edge of the group element
                                if (!selectedComponentList.Contains(deploymentComponentList[ec.targets.target.component.id]) && selectedComponentList.Contains(deploymentComponentList[ec.sources.source.component.id])) {
                                    eventChannel newEc = new eventChannel();
                                    newEc.id = "eventbindingveigl." + index;
                                    newEc.sources.source.component.id = ec.sources.source.component.id;
                                    newEc.sources.source.eventPort.id = ec.sources.source.eventPort.id;
                                    newEc.targets.target.component.id = pasteDummyName;
                                    newEc.targets.target.eventPort.id = "eventlistener";
                                    index++;
                                    copyEventChannels.AddLast(newEc);
                                    // search for each event channel on the edge of the group element
                                } else if (selectedComponentList.Contains(deploymentComponentList[ec.targets.target.component.id]) && !selectedComponentList.Contains(deploymentComponentList[ec.sources.source.component.id])) {
                                    eventChannel newEc = new eventChannel();
                                    newEc.id = "eventbindingveigl." + index;
                                    newEc.sources.source.component.id = pasteDummyName;
                                    newEc.sources.source.eventPort.id = "eventtrigger";
                                    newEc.targets.target.component.id = ec.targets.target.component.id;
                                    newEc.targets.target.eventPort.id = ec.targets.target.eventPort.id;
                                    index++;
                                    copyEventChannels.AddLast(newEc);
                                } else if ((selectedComponentList.Contains(deploymentComponentList[ec.targets.target.component.id]) && selectedComponentList.Contains(deploymentComponentList[ec.sources.source.component.id]))) {
                                    copyEventChannels.AddFirst(ec);
                                }
                            }

                            // Adding dummy eventchannels to make the input and output ports of the group visible
                            foreach (EventListenerPort elp in groupComponent. EventListenerList) {
                                eventChannel newEc = new eventChannel();
                                foreach (componentType mc in groupModelToSave.components) {
                                    if (elp.EventListenerId.StartsWith(mc.id)) {
                                        newEc.targets.target.component.id = mc.id;
                                        newEc.targets.target.eventPort.id = ((EventListenerPort)mc.EventListenerList[0]).EventListenerId;
                                        newEc.id = "eventbindingveigl." + index;
                                        newEc.sources.source.component.id = pasteDummyName;
                                        newEc.sources.source.eventPort.id = "eventtrigger";

                                        index++;
                                        copyEventChannels.AddLast(newEc);
                                        break;
                                    }
                                }

                            }
                            foreach (EventTriggerPort etp in groupComponent.EventTriggerList) {
                                eventChannel newEc = new eventChannel();
                                foreach (componentType mc in groupModelToSave.components) {
                                    if (etp.EventTriggerId.StartsWith(mc.id)) {
                                        newEc.id = "eventbindingveigl." + index;
                                        newEc.sources.source.component.id = mc.id;
                                        newEc.sources.source.eventPort.id = ((EventTriggerPort)mc.EventTriggerList[0]).EventTriggerId;
                                        newEc.targets.target.component.id = pasteDummyName;
                                        newEc.targets.target.eventPort.id = "eventlistener";
                                        index++;
                                        copyEventChannels.AddLast(newEc);
                                        break;
                                    }
                                }
                            }

                            if (copyEventChannels.Count == 0) {
                                groupModelToSave.eventChannels = null;
                            } else {
                                groupModelToSave.eventChannels = copyEventChannels.ToArray();
                            }
                            groupModelToSave = CopyModel(groupModelToSave);

                            // write group stream
                            XmlSerializer x = new XmlSerializer(groupModelToSave.GetType());
                            string filename;
                            if (ini.IniReadValue("Options", "useAppDataFolder").Equals("true")) {
                                filename = Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + "\\AsTeRICS\\ACS\\groups\\" + storageDialog.filenameTextbox.Text;
                            } else {
                                filename = AppDomain.CurrentDomain.BaseDirectory + "\\groups\\" + storageDialog.filenameTextbox.Text;
                            }
                            if (!filename.EndsWith(".agr")) {
                                filename += ".agr";
                            }
                            FileStream str = new FileStream(filename, FileMode.Create);
                            x.Serialize(str, groupModelToSave);
                            str.Close();

                            // add new group to list of groups
                            bool alreadyInMenu = false;
                            foreach (RibbonApplicationSplitMenuItem i in groupDropDown.Items) {
                                if (((string)i.CommandParameter) == filename) {
                                    alreadyInMenu = true;
                                    break;
                                }
                            }
                            if (!alreadyInMenu) {
                                RibbonApplicationSplitMenuItem i = new RibbonApplicationSplitMenuItem();
                                string header = filename.Substring(filename.LastIndexOf('\\') + 1);
                                i.Header = header.Substring(0, header.LastIndexOf('.'));
                                i.Click += AddGroupFromRibbonMenu;
                                i.CommandParameter = filename;
                                groupDropDown.Items.Add(i);

                            }

                        }
                    } catch (Exception ex) {
                        MessageBox.Show(Properties.Resources.StoreModelOnAREError, Properties.Resources.GroupStoreErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error);
                        traceSource.TraceEvent(TraceEventType.Error, 3, ex.Message);
                    }
                }
            } else {
                MessageBox.Show(Properties.Resources.GroupStoreNoGroupSelected, Properties.Resources.GroupStoreErrorHeader, MessageBoxButton.OK, MessageBoxImage.Information);
            }
        }
        /// <summary>
        /// Load the bundle-model (all available components) to the ribbon menu
        /// </summary>
        private void LoadBundle(String pathToBundleFile)
        {
            // check, if model is valid against the deployment_model schema
            String xmlError;
            string fName;
            try {
                if (pathToBundleFile == null) {
                    if (File.Exists(ini.IniReadValue("model", "bundle_model_startup"))) {
                        fName = ini.IniReadValue("model", "bundle_model_startup");
                    } else if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + ini.IniReadValue("model", "bundle_model"))) {
                        fName = AppDomain.CurrentDomain.BaseDirectory + ini.IniReadValue("model", "bundle_model");
                    } else {
                        fName = ini.IniReadValue("model", "bundle_model");
                    }
                } else {
                    fName = pathToBundleFile;
                }
                activeBundle = System.IO.Path.GetFileNameWithoutExtension(fName);
                if (activeBundle == "bundle")
                    activeBundle = "default";

                XmlValidation xv = new XmlValidation();
                //xmlError = xv.validateXml(fName, ini.IniReadValue("model", "bundle_schema"));
                if (File.Exists(ini.IniReadValue("model", "bundle_schema"))) {
                    xmlError = xv.validateXml(fName, ini.IniReadValue("model", "bundle_schema"));
                } else {
                    xmlError = xv.validateXml(fName, AppDomain.CurrentDomain.BaseDirectory + ini.IniReadValue("model", "bundle_schema"));
                }
            } catch (Exception ex) {
                MessageBox.Show(Properties.Resources.ReadBundleErrorText, Properties.Resources.ReadBundleErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error); // called twice to be shown once. Some kind of initialisation problem
                traceSource.TraceEvent(TraceEventType.Error, 3, ex.Message);
                xmlError = "Error opening bundle file";
                fName = "";
            }

            // if valid, xml-file will be written
            if (xmlError.Equals("")) {
                try {
                    XmlSerializer ser = new XmlSerializer(typeof(Asterics.ACS2.componentTypes));
                    //string fName;
                    //if (File.Exists(ini.IniReadValue("model", "bundle_model"))) {
                    //    fName = ini.IniReadValue("model", "bundle_model");
                    //}
                    //else {
                    //    fName = AppDomain.CurrentDomain.BaseDirectory + ini.IniReadValue("model", "bundle_model");
                    //}
                    StreamReader sr = new StreamReader(fName);
                    Asterics.ACS2.componentTypes allComponents = (Asterics.ACS2.componentTypes)ser.Deserialize(sr);
                    sr.Close();
                    foreach (object o in allComponents.componentType) {
                        if (o is Asterics.ACS2.componentTypesComponentType) {
                            Asterics.ACS2.componentTypesComponentType comp = (Asterics.ACS2.componentTypesComponentType)o;
                            comp.InitGraphPorts(comp.id);
                            componentList.Add(comp.id, comp);
                        }
                    }
                    foreach (Asterics.ACS2.componentTypesComponentType component in componentList.Values) {
                        // making each element in the plugin selection focusable
                        component.ComponentCanvas.Focusable = true;
                    }

                    // setting the ribbon 'components', adding the components to the
                    // four categories
                    actuatorDropDown.Items.Clear();
                    processorDropDown.Items.Clear();
                    sensorDropDown.Items.Clear();
                    specialDropDown.Items.Clear();
                    groupDropDown.Items.Clear();
                    Dictionary<string, RibbonSplitMenuItem> actuatorSubmenus = new Dictionary<string, RibbonSplitMenuItem>();
                    Dictionary<string, RibbonSplitMenuItem> processorSubmenus = new Dictionary<string, RibbonSplitMenuItem>();
                    Dictionary<string, RibbonSplitMenuItem> sensorSubmenus = new Dictionary<string, RibbonSplitMenuItem>();
                    Dictionary<string, RibbonSplitMenuItem> specialSubmenus = new Dictionary<string, RibbonSplitMenuItem>();
                    foreach (RibbonSplitMenuItem rsmi in actuatorSubmenus.Values) {
                        if (rsmi != null)
                            rsmi.Items.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending));
                    }
                    foreach (Asterics.ACS2.componentTypesComponentType component in componentList.Values) {
                        RibbonApplicationSplitMenuItem i = new RibbonApplicationSplitMenuItem();
                        string header = component.id;
                        header = TrimComponentName(header);
                        i.Header = header;
                        i.Click += AddComponentFromRibbonMenu;
                        i.CommandParameter = component.id;
                        RibbonSplitMenuItem rmi = new RibbonSplitMenuItem();
                        rmi.StaysOpenOnClick = true;
                        rmi.Height = 37;
                        rmi.Header = component.type.subtype;

                        switch (component.type.Value) {
                            case Asterics.ACS2.componentTypeDataTypes.actuator:
                                if (component.type.subtype == null || component.type.subtype.Equals(""))
                                    actuatorDropDown.Items.Add(i);
                                else {
                                    if (actuatorSubmenus.ContainsKey(component.type.subtype) == false) {
                                        rmi.Items.Add(i);
                                        actuatorDropDown.Items.Add(rmi);
                                        actuatorSubmenus.Add(component.type.subtype, rmi);
                                    }
                                    else {
                                        rmi = actuatorSubmenus[component.type.subtype];
                                        rmi.Items.Add(i);
                                    }
                                }
                                break;
                            case Asterics.ACS2.componentTypeDataTypes.processor:
                                if (component.type.subtype == null || component.type.subtype.Equals(""))
                                    processorDropDown.Items.Add(i);
                                else {
                                    if (processorSubmenus.ContainsKey(component.type.subtype) == false) {
                                        rmi.Items.Add(i);
                                        processorDropDown.Items.Add(rmi);
                                        processorSubmenus.Add(component.type.subtype, rmi);
                                    }
                                    else {
                                        rmi = processorSubmenus[component.type.subtype];
                                        rmi.Items.Add(i);
                                    }
                                }
                                break;
                            case Asterics.ACS2.componentTypeDataTypes.sensor:
                                if (component.type.subtype == null || component.type.subtype.Equals(""))
                                    sensorDropDown.Items.Add(i);
                                else {
                                    if (sensorSubmenus.ContainsKey(component.type.subtype) == false) {
                                        rmi.Items.Add(i);
                                        sensorDropDown.Items.Add(rmi);
                                        sensorSubmenus.Add(component.type.subtype, rmi);
                                    }
                                    else {
                                        rmi = sensorSubmenus[component.type.subtype];
                                        rmi.Items.Add(i);
                                    }
                                }
                                break;
                            case Asterics.ACS2.componentTypeDataTypes.special:
                                if (component.type.subtype == null || component.type.subtype.Equals(""))
                                    specialDropDown.Items.Add(i);
                                else {
                                    if (specialSubmenus.ContainsKey(component.type.subtype) == false) {
                                        rmi.Items.Add(i);
                                        specialDropDown.Items.Add(rmi);
                                        specialSubmenus.Add(component.type.subtype, rmi);
                                    }
                                    else {
                                        rmi = specialSubmenus[component.type.subtype];
                                        rmi.Items.Add(i);
                                    }
                                }
                                break;
                        }
                    }
                    // Sorting the lists alphabetically
                    sensorDropDown.Items.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending));
                    actuatorDropDown.Items.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending));
                    processorDropDown.Items.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending));
                    specialDropDown.Items.SortDescriptions.Add(new SortDescription("Header", ListSortDirection.Ascending));
                    // sort Submenus
                    sortComponentSubmenu(actuatorSubmenus.Values.ToArray());
                    sortComponentSubmenu(sensorSubmenus.Values.ToArray());
                    sortComponentSubmenu(processorSubmenus.Values.ToArray());
                    sortComponentSubmenu(specialSubmenus.Values.ToArray());
                    //move others at the end of the submenus
                    moveOthersMenuItemBack(sensorDropDown);
                    moveOthersMenuItemBack(processorDropDown);
                    moveOthersMenuItemBack(actuatorDropDown);
                    moveOthersMenuItemBack(specialDropDown);
                    if (pathToBundleFile != null) {
                        MessageBox.Show(Properties.Resources.ReadBundleText, Properties.Resources.ReadBundleHeader, MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                } catch (Exception e) {
                    actuatorDropDown.Items.Clear();
                    processorDropDown.Items.Clear();
                    sensorDropDown.Items.Clear();
                    specialDropDown.Items.Clear();
                    groupDropDown.Items.Clear();
                    componentList.Clear();
                    if (pathToBundleFile == null) {
                        MessageBox.Show(Properties.Resources.ReadBundleErrorText, Properties.Resources.ReadBundleErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error);
                        MessageBox.Show(Properties.Resources.ReadBundleErrorText, Properties.Resources.ReadBundleErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error); // called twice to be shown once. Some kind of initialisation problem
                        traceSource.TraceEvent(TraceEventType.Error, 3, e.Message);
                        //Application.Current.Shutdown();
                        //Environment.Exit(0);
                    } else {
                        MessageBox.Show(Properties.Resources.ReadDownloadedBundleErrorText, Properties.Resources.ReadBundleErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error);
                        componentList.Clear();
                        LoadBundle(null);
                    }
                }

                // loading the presaved groups
                string errorStr = "unknown";
                try {
                    string[] filesInGroupsFolder = null;
                    if (ini.IniReadValue("Options", "useAppDataFolder").Equals("true")) {
                        if (Directory.Exists(Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData)+"\\AsTeRICS\\ACS\\groups\\")) {
                            filesInGroupsFolder = Directory.GetFiles(Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData)+"\\AsTeRICS\\ACS\\groups\\", "*.agr");
                        }
                    } else {
                        if (Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + "\\groups\\")) {
                            filesInGroupsFolder = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + "\\groups\\", "*.agr");
                        }
                    }
                    if (filesInGroupsFolder != null) {
                        foreach (string filename in filesInGroupsFolder) {
                            errorStr = filename;
                            RibbonApplicationSplitMenuItem i = new RibbonApplicationSplitMenuItem();
                            string header = filename.Substring(filename.LastIndexOf('\\') + 1);
                            i.Header = header.Substring(0, header.LastIndexOf('.'));
                            i.Click += AddGroupFromRibbonMenu;
                            i.CommandParameter = filename;
                            groupDropDown.Items.Add(i);
                        }
                    }
                } catch (Exception e) {
                    MessageBox.Show(Properties.Resources.GroupingErrorReadingGroupFormat(errorStr), Properties.Resources.GroupingErrorReadingGroupHeader, MessageBoxButton.OK, MessageBoxImage.Error);
                    traceSource.TraceEvent(TraceEventType.Error, 3, e.Message);
                }

            } else {
                actuatorDropDown.Items.Clear();
                processorDropDown.Items.Clear();
                sensorDropDown.Items.Clear();
                specialDropDown.Items.Clear();
                groupDropDown.Items.Clear();
                componentList.Clear();
                if (pathToBundleFile == null) {
                    MessageBox.Show(Properties.Resources.ReadBundleErrorText, Properties.Resources.ReadBundleErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error);
                    MessageBox.Show(Properties.Resources.ReadBundleErrorText, Properties.Resources.ReadBundleErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error); // called twice to be shown once. Some kind of initialisation problem
                    traceSource.TraceEvent(TraceEventType.Error, 3, xmlError);
                    //Application.Current.Shutdown();
                    //Environment.Exit(0);
                } else {
                    MessageBox.Show(Properties.Resources.ReadDownloadedBundleErrorText, Properties.Resources.ReadBundleErrorHeader, MessageBoxButton.OK, MessageBoxImage.Error);
                    componentList.Clear();
                    LoadBundle(null);
                }

            }
        }