// Gets a stateId but... if the shape doesn't have one, it will return // an automatically generated one internal string GetStateId() { string stateId = Common.GetCellString(shape, ShapeProperties.StateId); if (stateId.Length == 0) { stateId = BuildStateIdForStorage(StatePrefixAndNumberManager.GetCurrentStateIdPrefix(), StatePrefixAndNumberManager.GetNextAvailableNumber(), String.Empty); } return(stateId); }
virtual internal void SetStateId(string stateId) { // remove the old prefix+number from the list StatePrefixAndNumberManager.Remove(this); Common.SetCellString(shape, ShapeProperties.Play.StateId, stateId); shape.Text = StateIdForDisplay(stateId); // add the new prefix+number to the list StatePrefixAndNumberManager.Add(this, shape); }
public override void OnBeforeShapeDelete() { StatePrefixAndNumberManager.Remove(this); // check to see if any max handlers use this - if so change to hang up List <Shadow> shadowList = PathMaker.LookupAllShadows(); foreach (Shadow s in shadowList) { if (s.RemoveGotosThatDontUseConnectors(shape.get_UniqueID((short)VisUniqueIDArgs.visGetOrMakeGUID))) { Common.ErrorMessage("Shape was being used as a goto in " + s.GetGotoName() + " - changing to Hang up"); } } }
public override void OnShapeExitTextEdit() { base.OnShapeExitTextEdit(); string prefix, number, name, errorMessage; string newName = StateIdForDisplay(shape.Text); DisectStateIdIntoParts(newName, out prefix, out number, out name); // always use uppercase prefixes prefix = prefix.ToUpper(); // They can enter anything in the shape text - here we make sure it's a good stateid // and, if not, we make it one. if (!ValidateStateIdTextBoxStrings(prefix, number, name, out errorMessage)) { if (GetStateId().Length > 0) { string oldPrefix, oldNumber, oldName; DisectStateIdIntoParts(GetStateId(), out oldPrefix, out oldNumber, out oldName); newName = oldPrefix.ToUpper() + oldNumber + Strings.StateIdWordDisplayDelimiter + newName; } else { newName = StatePrefixAndNumberManager.GetCurrentStateIdPrefix() + StatePrefixAndNumberManager.GetNextAvailableNumber() + Strings.StateIdWordDisplayDelimiter + newName; } } else { // make sure we pick up the uppercase prefix newName = prefix + number + Strings.StateIdWordDisplayDelimiter + name; } string oldStateId = GetStateId(); string newStateId = StateIdForStorage(newName); SetStateId(newStateId); StartShadow shadowStart = PathMaker.LookupStartShadow(); if (shadowStart != null && !oldStateId.Equals(newStateId)) { string promptIdFormat = shadowStart.GetDefaultSetting(Strings.DefaultSettingsPromptIDFormat); if (promptIdFormat.Equals(Strings.PromptIdFormatFull) || promptIdFormat.Equals(Strings.PromptIdFormatPartial)) { RedoPromptIds(0, promptIdFormat); } } }
// Validates the individual components used by dialog boxes to represent a stateId public bool ValidateStateIdTextBoxStrings(string prefix, string number, string name, out string errorMessage) { string oldPrefix, oldNumber, oldName; DisectStateIdIntoParts(GetStateId(), out oldPrefix, out oldNumber, out oldName); if (prefix.Length != StatePrefixAndNumberManager.PrefixLength) { errorMessage = "Enter a valid 2-letter uppercase state prefix"; return(false); } else { if (!Regex.Match(prefix, AllowedPrefixRegEx).Success) { errorMessage = "Prefix must be 2 uppercase alpha characters"; return(false); } } if (number.Length != StatePrefixAndNumberManager.NumberLength) { errorMessage = "Enter a valid 4 digit state number"; return(false); } else { if (!Regex.Match(number, AllowedNumberRegEx).Success) { errorMessage = "Number must consist of 4 numberical characters"; return(false); } } if (StatePrefixAndNumberManager.ContainsPrefixAndNumber(prefix + number) && (!((prefix == oldPrefix) && (number == oldNumber)))) { errorMessage = "State prefix and number are already assigned to another state"; return(false); } else { errorMessage = String.Empty; return(true); } }
void OnShapeAdd(Shape shape) { ShapeTypes type = Common.GetShapeType(shape); bool is1D = shape.OneD != 0; // Tricky - when pasting, Visio gives out new uids to the shapes if there are duplicates // in this document. So, we are going to stash the original ones - unless we are pasting. // If we are pasting, the paste end will fix the ones that were added. if (!visioControl.Document.Application.get_IsInScope((int)VisUICmds.visCmdUFEditPaste) && !visioControl.Document.Application.get_IsInScope((int)VisUICmds.visCmdUFEditDuplicate)) { string uid = shape.get_UniqueID((short)VisUniqueIDArgs.visGetOrMakeGUID); string cached = Common.GetCellString(shape, Strings.CutCopyPasteTempCellName); // when undoing a delete page, you can't write this yet so this check will ignore it if (!uid.Equals(cached)) { Common.SetCellString(shape, Strings.CutCopyPasteTempCellName, uid); } } else if (Common.GetShapeType(shape) == ShapeTypes.OffPageRef) { Common.ErrorMessage("Pasted off-page reference needs to be connected. Double click on it to repair."); // Because these can be cut and pasted from a single document, clearing these fields // allows us to avoid having more than one off page connector pointing to a single other one // which causes issues with tracking things in the shadows. This way here, double clicking // on the connector will ask which page to connect it to. Common.SetCellString(shape, ShapeProperties.OffPageConnectorDestinationPageID, ""); Common.SetCellString(shape, ShapeProperties.OffPageConnectorDestinationShapeID, ""); } if (type == ShapeTypes.None && is1D) { // rogue connector - need to make it conform Common.SetCellString(shape, ShapeProperties.ShapeType, ((int)ShapeTypes.Connector).ToString()); shape.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLine, (short)VisCellIndices.visLineEndArrow).FormulaU = "13"; shape.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLine, (short)VisCellIndices.visLineRounding).FormulaU = "0.25 in"; shape.get_CellsSRC((short)VisSectionIndices.visSectionObject, (short)VisRowIndices.visRowLock, (short)VisCellIndices.visLockTextEdit).FormulaU = "1"; // just in case Common.FixConnectorTextControl(shape); // make every row in the shape data section invisible short row = (short)VisRowIndices.visRowFirst; while (shape.get_CellsSRCExists((short)VisSectionIndices.visSectionProp, row, (short)VisCellIndices.visCustPropsInvis, (short)VisExistsFlags.visExistsAnywhere) != 0) { shape.get_CellsSRC((short)VisSectionIndices.visSectionProp, row++, (short)VisCellIndices.visCustPropsInvis).FormulaU = "TRUE"; } } // when a shape is copied and pasted, it will be an exact copy of the previous shape // we need fix the duplicate name issue before we do anything else string oldPastedStateName = String.Empty; if (visioControl.Document.Application.get_IsInScope((int)VisUICmds.visCmdUFEditPaste) || visioControl.Document.Application.get_IsInScope((int)VisUICmds.visCmdUFEditDuplicate)) { string stateId = Common.GetCellString(shape, ShapeProperties.StateId); if (stateId.Length > 0) { if (!StatePrefixAndNumberManager.IsStateIdOkayForUse(stateId)) { oldPastedStateName = stateId; // NEVER, NEVER do this without going through the shadow except here, before the shadow is made Common.SetCellString(shape, ShapeProperties.StateId, String.Empty); } } } Shadow shadow = Common.MakeShapeShadow(shape); if (shadow != null) { // if we have a pasted name that conflicted, this will reuse the name portion // but get us a new prefix and number and then renumber any prompts if (oldPastedStateName.Length > 0) { string prefix, number, name; StateShadow.DisectStateIdIntoParts(oldPastedStateName, out prefix, out number, out name); shape.Text = StateShadow.StateIdForDisplay(name).Trim(); // this just pretends we just typed the name portion into the shape itself shadow.OnShapeExitTextEdit(); // and now let's renumber any prompts if we're not using the "number" option List <Shadow> shadowList = LookupShadowsByShapeType(ShapeTypes.Start); if (shadowList.Count > 0) { StartShadow startShadow = shadowList[0] as StartShadow; string promptIdFormat = startShadow.GetDefaultSetting(Strings.DefaultSettingsPromptIDFormat); if (promptIdFormat.Equals(Strings.PromptIdFormatFull) || promptIdFormat.Equals(Strings.PromptIdFormatPartial)) { StateShadow stateShadow = shadow as StateShadow; if (stateShadow != null) { stateShadow.RedoPromptIds(0, promptIdFormat); } } } } shadowShapeMap.Add(shape.get_UniqueID((short)VisUniqueIDArgs.visGetOrMakeGUID), shadow); shadow.OnShapeAdd(); if (shadow.GetShapeType() == ShapeTypes.DocTitle || shadow.GetShapeType() == ShapeTypes.ChangeLog || shadow.GetShapeType() == ShapeTypes.AppDesc || shadow.GetShapeType() == ShapeTypes.PrefixList || shadow.GetShapeType() == ShapeTypes.Start) { if (LookupShadowsByShapeType(shadow.GetShapeType()).Count > 1) { Common.ErrorMessage("Cannot have two Start, Change Log, or Document Title, App Description or Prefix List shapes"); Common.ForcedSetShapeText(shape, Strings.ToBeDeletedLabel); } } } else { Common.ErrorMessage("Invalid non-PathMaker shape added"); try { Common.ForcedSetShapeText(shape, Strings.ToBeDeletedLabel); } catch { // it may be a shape with two subshapes (play/interaction) so try this too try { Common.ForcedSetShapeText(shape.Shapes[0], Strings.ToBeDeletedLabel); } catch { // copying from non-PathMaker visios can cause this to fail depending on shape sheets, locks, etc. // We did our best - we can ignore these } } } }
private void OnSrcDocumentChange() { int pathMakerVersion = Common.GetDocumentSchemaVersion(visioControl.Document); bool repaired = false; StatePrefixAndNumberManager.Initialize(); if (pathMakerVersion < Common.GetResourceInt(Strings.PathMakerSchemaVersionRes)) { if (!Repair.UpgradeDocumentToCurrentSchemaVersion(visioControl.Document)) { visioControl.Src = System.Windows.Forms.Application.StartupPath + @"\\" + Strings.VisioTemplateFile; } else { repaired = true; } } if (pathMakerVersion > Common.GetResourceInt(Strings.PathMakerSchemaVersionRes)) { Common.ErrorMessage("This file was created using a newer schema than this version of\n" + "PathMaker supports. Upgrade to a newer version to edit this file."); visioControl.Src = System.Windows.Forms.Application.StartupPath + @"\\" + Strings.VisioTemplateFile; repaired = false; } try { // For some reason our template will cause an exception if you add a new // page to it before you have put a shape on it. My guess is something to // do with it being a vst but it only happens in the activeX control, not // standard visio. Either way, this little trick of putting a connector on and // deleting it seems to solve the problem. One other note, the shape you drop // matters. A comment shape didn't work... Page page = visioControl.Document.Application.ActivePage; Document stencil = visioControl.Document.Application.Documents[Strings.StencilFileName]; if (page != null) { Shape shape = page.Drop(stencil.Masters["Dynamic connector"], 1, 1); shape.Delete(); } } catch { // fails if the window isn't up yet - can be ignored } // when starting from the template, the doc title and change log cut copy paste temp // data isn't set - so let's set it here foreach (Page page in visioControl.Document.Pages) { foreach (Shape shape in page.Shapes) { string uid = shape.get_UniqueID((short)VisUniqueIDArgs.visGetOrMakeGUID); Common.SetCellString(shape, Strings.CutCopyPasteTempCellName, uid); } } // if we didn't do a repair, make it so the hack above doesn't mean we have to save if (!repaired) { visioControl.Document.Saved = true; } // set up our gotoPageComboBox on the toolbar gotoPageComboBox.Items.Clear(); gotoPageComboBox.DropDownStyle = ComboBoxStyle.DropDownList; foreach (Page p in visioControl.Document.Pages) { gotoPageComboBox.Items.Add(p.Name); } if (visioControl.Document.Application.ActivePage != null) { string pageName = visioControl.Document.Application.ActivePage.Name; int index = visioControl.Document.Pages[pageName].Index; gotoPageComboBox.SelectedIndex = index - 1; } StencilCleanup(); // set titlebar string filename = System.IO.Path.GetFileName(visioControl.Src); if (filename.Contains(Strings.VisioTemplateFileSuffix)) { Text = Common.StripExtensionFileName(Strings.DefaultFileName) + Strings.TitleBarSuffix; } else { Text = Common.StripExtensionFileName(filename) + Strings.TitleBarSuffix; } // we rebuild this every time we get a new document BuildShadowShapeMap(); // and add the event handlers which are associated with the document (as opposed to the application) SetupDocumentEventHandlersAndRemoveAccelerators(); //JDK added this to update older formats for date stamps to version stamps Common.RedoAllHiddenPromptMarkers(); }
public StateShadow(Shape shape) : base(shape) { StatePrefixAndNumberManager.Add(this, shape); }