// 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); }
/// <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); } } }