/// <summary> /// Removes specified model from composition. /// </summary> /// <param name="model">Model to be removed.</param> /// <remarks>The <c>Dispose</c> method is called on the model.</remarks> public void RemoveModel(UIModel model) { // first remove all links from/to this model UIConnection[] copyOfLinks = (UIConnection[])_connections.ToArray(typeof(UIConnection)); foreach (UIConnection uiLink in copyOfLinks) { if (uiLink.AcceptingModel == model || uiLink.ProvidingModel == model) { RemoveConnection(uiLink); } } try { // We call Finish() after computation finished, // Dispose() when removing models model.LinkableComponent.Dispose(); } catch { // we don't care about just disposed model, so do nothing... } _shouldBeSaved = true; _models.Remove(model); // remove model itself }
/// <summary> /// Adds new model to this composition. /// </summary> /// <param name="omiFilename">Relative or absolute path to OMI file describing the model.</param> /// <param name="directory">Directory <c>omiFilename</c> is relative to, or <c>null</c> if <c>omiFilename</c> is absolute or relative to current directory.</param> /// <returns>Returns newly added model.</returns> /// <remarks>See <see cref="Utils.GetFileInfo">Utils.GetFileInfo</see> for more info about how /// specified file is searched.</remarks> public UIModel AddModel(string directory, string omiFilename) { UIModel newUiModel; if (omiFilename == TriggerModelID) { newUiModel = UIModel.NewTrigger(); } else { newUiModel = new UIModel(); newUiModel.ReadOMIFile(directory, omiFilename); } // check whether ModelID is unique and also calculate newUiModel's positon foreach (UIModel uiModel in _models) { if (newUiModel.ModelID == uiModel.ModelID) { throw (new Exception("Composition already contains model with ModelID \"" + newUiModel.ModelID + "\" ")); } if (newUiModel.Rect.X == uiModel.Rect.X && newUiModel.Rect.Y == uiModel.Rect.Y) { newUiModel.Rect.X = newUiModel.Rect.X + newUiModel.Rect.Width / 2; newUiModel.Rect.Y = newUiModel.Rect.Y + newUiModel.Rect.Height / 2; } } _models.Add(newUiModel); _shouldBeSaved = true; return(newUiModel); }
/// <summary> /// Creates a new instance of trigger model. /// </summary> /// <returns>Returns trigger model.</returns> /// <remarks>See <see cref="Trigger">Trigger</see> for more detail.</remarks> public static UIModel NewTrigger() { UIModel trigger = new UIModel(); trigger.LinkableComponent = new Trigger(); trigger.OmiFilename = CompositionManager.TriggerModelID; trigger._modelID = CompositionManager.TriggerModelID; return(trigger); }
/// <summary> /// Creates a new instance of <see cref="UIConnection">UIConnection</see> class. /// </summary> /// <param name="providingModel">Model providing data.</param> /// <param name="acceptingModel">Model accepting data.</param> public UIConnection(UIModel providingModel, UIModel acceptingModel) { _providingModel = providingModel; _acceptingModel = acceptingModel; _links = new ArrayList(); _trianglePoints = new Point[3]; linePen = new Pen(Color.Blue, 2); linePenDisabled = new Pen(Color.LightGray, 2); }
/// <summary> /// Creates a new instance of <see cref="UIConnection">UIConnection</see> class. /// </summary> /// <param name="providingModel">Model providing data.</param> /// <param name="acceptingModel">Model accepting data.</param> public UIConnection(UIModel providingModel, UIModel acceptingModel) { _providingModel = providingModel; _acceptingModel = acceptingModel; _links = new ArrayList(); _trianglePoints = new Point[3]; linePen = new Pen(Color.Blue, 2); linePenDisabled = new Pen(Color.LightGray, 2); }
private void StopAddingConnection() { _isAddingConnection = false; compositionBox.Cursor = Cursors.Default; _sourceModel = null; }
private void compositionBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { StopMovingModel(); compositionBox.Invalidate(); bool actionFoundOut = false; // Left mouse button if( e.Button == MouseButtons.Left ) { // if adding a connection if( _isAddingConnection ) { UIModel model = GetModel( e.X, e.Y ); // if some model selected if( model!=null ) { // if source model selected if( _sourceModel == null ) { _sourceModel = model; compositionBox.Cursor = _targetCursor; } else { // target model selected => add connection to composition if( _sourceModel != model ) _composition.AddConnection( _sourceModel, model ); StopAddingConnection(); } } else { // no model selected StopAddingConnection(); } actionFoundOut = true; } // move model ? if( !actionFoundOut ) { UIModel model = GetModel( e.X, e.Y ); if( model != null ) { _prevMouse.X = e.X; _prevMouse.Y = e.Y; _isMovingModel = true; model.IsMoving = true; actionFoundOut = true; } } // or show link dialog ? if( !actionFoundOut ) { UIConnection connection = GetConnection(e.X,e.Y); if( connection!=null ) ShowLinkDialog( connection ); } } else if( e.Button == MouseButtons.Right ) { // right button => show context menu // stop other actions StopAddingConnection(); StopMovingModel(); // get model under cursor _contextSelectedObject = GetModel(e.X,e.Y); if( _contextSelectedObject == null ) _contextSelectedObject = GetConnection(e.X,e.Y); contextMenu.Show( compositionBox, new Point(e.X,e.Y) ); } }
/// <summary> /// Creates a new instance of trigger model. /// </summary> /// <returns>Returns trigger model.</returns> /// <remarks>See <see cref="Trigger">Trigger</see> for more detail.</remarks> public static UIModel NewTrigger() { UIModel trigger = new UIModel(); trigger.LinkableComponent = new Trigger(); trigger.OmiFilename = CompositionManager.TriggerModelID; trigger._modelID = CompositionManager.TriggerModelID; return( trigger ); }
/// <summary> /// Creates new connection between two models in composition. /// </summary> /// <param name="providingModel">Source model</param> /// <param name="acceptingModel">Target model</param> /// <remarks>Connection between two models is just abstraction which can hold links between models. /// The direction of connection and its links is same. There can be only one connection between two models.</remarks> public void AddConnection(UIModel providingModel, UIModel acceptingModel) { if (providingModel == acceptingModel) throw (new Exception("Cannot connect model with itself.")); // Check whether both models exist bool providingFound = false, acceptingFound = false; foreach (UIModel model in _models) { if (model == providingModel) providingFound = true; if (model == acceptingModel) acceptingFound = true; } if (!providingFound || !acceptingFound) throw (new Exception("Cannot find providing or accepting.")); // check whether this link isn't already here (if yes, do nothing) foreach (UIConnection link in _connections) if (link.ProvidingModel == providingModel && link.AcceptingModel == acceptingModel) return; // if providing model is trigger, do nothing if (providingModel.ModelID == TriggerModelID) return; // if accepting model is trigger, remove all other trigger connections if (acceptingModel.ModelID == TriggerModelID) { ArrayList connectionsToRemove = new ArrayList(); foreach (UIConnection uiLink in _connections) { if (uiLink.AcceptingModel.ModelID == TriggerModelID || uiLink.ProvidingModel.ModelID == TriggerModelID) connectionsToRemove.Add(uiLink); } foreach (UIConnection uiLink in connectionsToRemove) RemoveConnection(uiLink); } _connections.Add(new UIConnection(providingModel, acceptingModel)); _shouldBeSaved = true; }
/// <summary> /// Removes specified model from composition. /// </summary> /// <param name="model">Model to be removed.</param> /// <remarks>The <c>Dispose</c> method is called on the model.</remarks> public void RemoveModel(UIModel model) { // first remove all links from/to this model UIConnection[] copyOfLinks = (UIConnection[])_connections.ToArray(typeof(UIConnection)); foreach (UIConnection uiLink in copyOfLinks) if (uiLink.AcceptingModel == model || uiLink.ProvidingModel == model) RemoveConnection(uiLink); try { // We call Finish() after computation finished, // Dispose() when removing models model.LinkableComponent.Dispose(); } catch { // we don't care about just disposed model, so do nothing... } _shouldBeSaved = true; _models.Remove(model); // remove model itself }
/// <summary> /// Adds new model to this composition. /// </summary> /// <param name="omiFilename">Relative or absolute path to OMI file describing the model.</param> /// <param name="directory">Directory <c>omiFilename</c> is relative to, or <c>null</c> if <c>omiFilename</c> is absolute or relative to current directory.</param> /// <returns>Returns newly added model.</returns> /// <remarks>See <see cref="Utils.GetFileInfo">Utils.GetFileInfo</see> for more info about how /// specified file is searched.</remarks> public UIModel AddModel(string directory, string omiFilename) { UIModel newUiModel; if (omiFilename == TriggerModelID) { newUiModel = UIModel.NewTrigger(); } else { newUiModel = new UIModel(); newUiModel.ReadOMIFile(directory, omiFilename); } // check whether ModelID is unique and also calculate newUiModel's positon foreach (UIModel uiModel in _models) { if (newUiModel.ModelID == uiModel.ModelID) throw (new Exception("Composition already contains model with ModelID \"" + newUiModel.ModelID + "\" ")); if (newUiModel.Rect.X == uiModel.Rect.X && newUiModel.Rect.Y == uiModel.Rect.Y) { newUiModel.Rect.X = newUiModel.Rect.X + newUiModel.Rect.Width / 2; newUiModel.Rect.Y = newUiModel.Rect.Y + newUiModel.Rect.Height / 2; } } _models.Add(newUiModel); _shouldBeSaved = true; return (newUiModel); }
/// <summary> /// Loads composition from XML document. /// </summary> /// <param name="omiRelativeDirectory">Directory the OMI files are relative to.</param> /// <param name="xmlDocument">XML document</param> private void LoadFromXmlDocument(string omiRelativeDirectory, XmlDocument xmlDocument) { // once you choose to load new file, all previously opened models are closed Release(); CultureInfo currentCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = new CultureInfo(""); XmlElement xmlRoot = (XmlElement)xmlDocument.ChildNodes[0]; XmlElement xmlModels = (XmlElement)xmlRoot.ChildNodes[0]; XmlElement xmlLinks = (XmlElement)xmlRoot.ChildNodes[1]; // run properties aren't mandatory XmlElement xmlRunProperties = null; if (xmlRoot.ChildNodes.Count > 2) { xmlRunProperties = (XmlElement)xmlRoot.ChildNodes[2]; } // check if (xmlRoot.GetAttribute("version") != "1.0") { throw (new FormatException("Version of file not supported. Currently supported only version '1.0'")); } if (xmlModels.Name != "models" || xmlLinks.Name != "links") { throw (new FormatException("Unknown file format ('models' or 'links' tag not present where expected).")); } if (xmlRunProperties != null) { if (xmlRunProperties.Name != "runproperties") { throw (new FormatException("Unknown file format ('runproperties' tag not present where expected).")); } } // read UIModels foreach (XmlElement xmlUiModel in xmlModels.ChildNodes) { try { UIModel uiModel = AddModel(omiRelativeDirectory, xmlUiModel.GetAttribute("omi")); uiModel.Rect.X = Int32.Parse(xmlUiModel.GetAttribute("rect_x")); uiModel.Rect.Y = Int32.Parse(xmlUiModel.GetAttribute("rect_y")); uiModel.Rect.Width = Int32.Parse(xmlUiModel.GetAttribute("rect_width")); uiModel.Rect.Height = Int32.Parse(xmlUiModel.GetAttribute("rect_height")); } catch (Exception e) { throw (new Exception( "Model cannot be added to composition due to exception.\n" + "OMI filename: " + xmlUiModel.GetAttribute("omi") + "\n" + "Exception: " + e.ToString())); } } // read UILinks foreach (XmlElement xmlUiLink in xmlLinks.ChildNodes) { // find models corresponding to this UIConnection UIModel providingModel = null, acceptingModel = null; foreach (UIModel uiModel in _models) { if (uiModel.ModelID == xmlUiLink.GetAttribute("model_providing")) { providingModel = uiModel; break; } } foreach (UIModel uiModel in _models) { if (uiModel.ModelID == xmlUiLink.GetAttribute("model_accepting")) { acceptingModel = uiModel; break; } } if (providingModel == null || acceptingModel == null) { throw (new Exception( "One model (or both) corresponding to this link cannot be found...\n" + "Providing model: " + xmlUiLink.GetAttribute("model_providing") + "\n" + "Accepting model: " + xmlUiLink.GetAttribute("model_accepting"))); } // construct UIConnection UIConnection uiLink = new UIConnection(providingModel, acceptingModel); // read OpenMI Links foreach (XmlElement xmlLink in xmlUiLink.ChildNodes) { // find corresponding exchange items IOutputExchangeItem outputExchangeItem = null; IInputExchangeItem inputExchangeItem = null; int count = providingModel.LinkableComponent.OutputExchangeItemCount; string sourceElementSetID = xmlLink.GetAttribute("source_elementset"); string sourceQuantityID = xmlLink.GetAttribute("source_quantity"); for (int i = 0; i < count; i++) { if (sourceElementSetID == providingModel.LinkableComponent.GetOutputExchangeItem(i).ElementSet.ID && sourceQuantityID == providingModel.LinkableComponent.GetOutputExchangeItem(i).Quantity.ID) { outputExchangeItem = providingModel.LinkableComponent.GetOutputExchangeItem(i); break; } } for (int i = 0; i < acceptingModel.LinkableComponent.InputExchangeItemCount; i++) { if (xmlLink.GetAttribute("target_elementset") == acceptingModel.LinkableComponent.GetInputExchangeItem(i).ElementSet.ID && xmlLink.GetAttribute("target_quantity") == acceptingModel.LinkableComponent.GetInputExchangeItem(i).Quantity.ID) { inputExchangeItem = acceptingModel.LinkableComponent.GetInputExchangeItem(i); break; } } if (outputExchangeItem == null || inputExchangeItem == null) { throw (new Exception( "Cannot find exchange item\n" + "Providing model: " + providingModel.ModelID + "\n" + "Accepting model: " + acceptingModel.ModelID + "\n" + "Source ElementSet: " + xmlLink.GetAttribute("source_elementset") + "\n" + "Source Quantity: " + xmlLink.GetAttribute("source_quantity") + "\n" + "Target ElementSet: " + xmlLink.GetAttribute("target_elementset") + "\n" + "Target Quantity: " + xmlLink.GetAttribute("target_quantity"))); } // read selected DataOperation's IDs, find their equivalents // in outputExchangeItem, and add these to link ArrayList dataOperationsToAdd = new ArrayList(); foreach (XmlElement xmlDataOperation in xmlLink.ChildNodes) { for (int i = 0; i < outputExchangeItem.DataOperationCount; i++) { IDataOperation dataOperation = outputExchangeItem.GetDataOperation(i); if (dataOperation.ID == xmlDataOperation.GetAttribute("id")) { // set data operation's arguments if any foreach (XmlElement xmlArgument in xmlDataOperation.ChildNodes) { string argumentKey = xmlArgument.GetAttribute("key"); for (int j = 0; j < dataOperation.ArgumentCount; j++) { IArgument argument = dataOperation.GetArgument(j); if (argument.Key == argumentKey && !argument.ReadOnly) { argument.Value = xmlArgument.GetAttribute("value"); } } } dataOperationsToAdd.Add(dataOperation); break; } } } // now construct the Link... Link link = new Link( providingModel.LinkableComponent, outputExchangeItem.ElementSet, outputExchangeItem.Quantity, acceptingModel.LinkableComponent, inputExchangeItem.ElementSet, inputExchangeItem.Quantity, "No description available.", xmlLink.GetAttribute("id"), dataOperationsToAdd); // ...add the link to the list uiLink.Links.Add(link); // and add it to both LinkableComponents uiLink.AcceptingModel.LinkableComponent.AddLink(link); uiLink.ProvidingModel.LinkableComponent.AddLink(link); } // add new UIConnection to list of connections _connections.Add(uiLink); } // read run properties (if present) if (xmlRunProperties != null) { string str = xmlRunProperties.GetAttribute("listenedeventtypes"); if (str.Length != (int)EventType.NUM_OF_EVENT_TYPES) { throw (new FormatException("Invalid number of event types in 'runproperties' tag, expected " + EventType.NUM_OF_EVENT_TYPES + ", but only " + str.Length + " found.")); } for (int i = 0; i < (int)EventType.NUM_OF_EVENT_TYPES; i++) { switch (str[i]) { case '1': _listenedEventTypes[i] = true; break; case '0': _listenedEventTypes[i] = false; break; default: throw (new FormatException("Unknown format of 'listenedeventtypes' attribute in 'runproperties' tag.")); } } _triggerInvokeTime = DateTime.Parse(xmlRunProperties.GetAttribute("triggerinvoke")); _logFileName = xmlRunProperties.GetAttribute("logfilename"); if (_logFileName != null) { _logFileName = _logFileName.Trim(); if (_logFileName == "") { _logFileName = null; // if not set, logfile isn't used } } str = xmlRunProperties.GetAttribute("showeventsinlistbox"); if (str == null || str == "" || str == "1") { _showEventsInListbox = true; // if not set, value is true } else { _showEventsInListbox = false; } str = xmlRunProperties.GetAttribute("runinsamethread"); if (str == "1") { _runInSameThread = true; } } Thread.CurrentThread.CurrentCulture = currentCulture; }
/// <summary> /// Creates new connection between two models in composition. /// </summary> /// <param name="providingModel">Source model</param> /// <param name="acceptingModel">Target model</param> /// <remarks>Connection between two models is just abstraction which can hold links between models. /// The direction of connection and its links is same. There can be only one connection between two models.</remarks> public void AddConnection(UIModel providingModel, UIModel acceptingModel) { if (providingModel == acceptingModel) { throw (new Exception("Cannot connect model with itself.")); } // Check whether both models exist bool providingFound = false, acceptingFound = false; foreach (UIModel model in _models) { if (model == providingModel) { providingFound = true; } if (model == acceptingModel) { acceptingFound = true; } } if (!providingFound || !acceptingFound) { throw (new Exception("Cannot find providing or accepting.")); } // check whether this link isn't already here (if yes, do nothing) foreach (UIConnection link in _connections) { if (link.ProvidingModel == providingModel && link.AcceptingModel == acceptingModel) { return; } } // if providing model is trigger, do nothing if (providingModel.ModelID == TriggerModelID) { return; } // if accepting model is trigger, remove all other trigger connections if (acceptingModel.ModelID == TriggerModelID) { ArrayList connectionsToRemove = new ArrayList(); foreach (UIConnection uiLink in _connections) { if (uiLink.AcceptingModel.ModelID == TriggerModelID || uiLink.ProvidingModel.ModelID == TriggerModelID) { connectionsToRemove.Add(uiLink); } } foreach (UIConnection uiLink in connectionsToRemove) { RemoveConnection(uiLink); } } _connections.Add(new UIConnection(providingModel, acceptingModel)); _shouldBeSaved = true; }