/// <summary> /// Load circuit templates stored in an external file</summary> /// <param name="uri">Document URI, or null to present file open dialog to user</param> /// <returns>Returns the file path used to load the external templates. /// An empty string indicates no templates were loaded</returns> protected override ImportedContent LoadExternalTemplateLibrary(Uri uri) { string filePath = string.Empty; if (uri == null) { var dlg = new OpenFileDialog(); dlg.Filter = "Script Template File (*.vscript)|*.vscript".Localize(); dlg.CheckFileExists = true; if (dlg.ShowDialog() == DialogResult.OK) { uri = new Uri(dlg.FileName, UriKind.RelativeOrAbsolute); filePath = dlg.FileName; } } else { filePath = uri.LocalPath; } if (File.Exists(filePath)) { if (TemplatingContext.ValidateNewFolderUri(uri)) { // read existing document using standard XML reader using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { var reader = new ScriptReader(m_nodeDefinitionManager.NodeTypeManager); var root = reader.Read(stream, uri); var toFolder = CreateTemplateFolder(); reader.ImportTemplates(toFolder.DomNode, root, uri); return(new ImportedContent(toFolder.DomNode, uri)); } } } return(new ImportedContent(null, null)); }
/// <summary> /// Promotes objects to template library. /// Items can be promoted when the active context is CircuitEditingContext and all the items are selected modules.</summary> /// <param name="items">Items to promote</param> public override void PromoteToTemplateLibrary(IEnumerable <object> items) { var itemsArray = items.ToArray(); // cache the external connections var externalConnectionsDict = new Dictionary <Element, List <Wire> >(); var circuitEditingContext = ContextRegistry.GetActiveContext <TongScriptEditingContext>(); var graphContainer = circuitEditingContext.CircuitContainer; foreach (var item in itemsArray) { var modules = new HashSet <Element>(); var internalConnections = new List <Wire>(); var externalConnections = new List <Wire>(); CircuitUtil.GetSubGraph(graphContainer, new[] { item }, modules, internalConnections, externalConnections, externalConnections); externalConnectionsDict.Add(item.Cast <Element>(), externalConnections); } // check source guid for templates to be replaced var templatingItems = new List <object>(); var replacingItems = new List <object>(); foreach (var item in itemsArray) { if (item.Is <ScriptNode>()) { var module = item.Cast <ScriptNode>(); if (module.SourceGuid != Guid.Empty) { var existingTemplate = TemplatingContext.SearchForTemplateByGuid(TemplatingContext.RootFolder, module.SourceGuid); if (existingTemplate != null) { string message = string.Format( "Overwrite the existing \"{0}\" Template with \"{1}\", or Add new one?\n".Localize(), existingTemplate.Name, module.TitleText); var dialog = new ConfirmationDialog("Overwrite / Add".Localize(), message); dialog.YesButtonText = "Overwrite".Localize(); dialog.NoButtonText = "Add".Localize(); dialog.Size = new System.Drawing.Size(300, 100); DialogResult result = dialog.ShowDialog(); if (result == DialogResult.Yes) { TemplatingContext.ReplaceTemplateModel(existingTemplate, module.Cast <DomNode>()); replacingItems.Add(item); } else if (result == DialogResult.No) { templatingItems.Add(item); } //otherwise the item is skipped } } else { templatingItems.Add(item); } } } // pack objects in IDataObject format var dataObject = new DataObject(); dataObject.SetData(typeof(object[]), templatingItems.ToArray()); // Insert() expects IDataObject TemplatingContext.Insert(dataObject); // replace the original items with the template instances foreach (var originalItem in templatingItems.Concat(replacingItems)) { var template = TemplatingContext.LastPromoted(originalItem); var instance = TemplatingContext.CreateReference(template); var originalModule = originalItem.Cast <Element>(); var replacedModule = instance.Cast <Element>(); replacedModule.Bounds = originalModule.Bounds; replacedModule.Position = originalModule.Position; // reroute external connections from original modules to replaced template instances. var externalConnections = externalConnectionsDict[originalModule]; foreach (var connection in externalConnections) { if (connection.InputElement.DomNode == originalModule.DomNode) { // input pin, i.e. pin on element that receives connection as input var pinName = connection.InputPin.Name; connection.InputPin = replacedModule.ElementType.GetInputPin(pinName); connection.InputElement = replacedModule; connection.InputPinTarget = null; // reset } else if (connection.OutputElement.DomNode == originalModule.DomNode) //output pin, i.e., pin on element that receives connection as output { connection.OutputPin = replacedModule.ElementType.GetOutputPin(connection.OutputPin.Name); connection.OutputElement = replacedModule; connection.OutputPinTarget = null; } else { Debug.Assert(false); } } circuitEditingContext.CircuitContainer.Elements.Remove(originalItem.Cast <Element>()); circuitEditingContext.CircuitContainer.Elements.Add(replacedModule); } }