using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using VEPROMS.CSLA.Library; using Volian.Controls.Library; using DevComponents.DotNetBar; using JR.Utils.GUI.Forms; using Volian.Base.Library; namespace Volian.Controls.Library { public delegate ItemInfo DisplayTabControlEditorSearchIncTransEvent(object sender, vlnTreeItemInfoEventArgs args); public delegate void DisplayTabControlEvent(object sender, EventArgs args); public delegate void DisplayTabControlStatusEvent(object sender, DisplayTabControlStatusEventArgs args); public partial class DisplayTabControlStatusEventArgs : EventArgs { private VolianStatusType _Type; public VolianStatusType Type { get { return _Type; } set { _Type = value; } } private int _Count; public int Count { get { return _Count; } set { _Count = value; } } private string _Text; public string Text { get { return _Text; } set { _Text = value; } } public DisplayTabControlStatusEventArgs() { _Type = VolianStatusType.Initialize; _Count = 0; _Text = "Default"; } public DisplayTabControlStatusEventArgs(VolianStatusType type, int count, string text) { _Type = type; _Count = count; _Text = text; } } public partial class DisplayTabControl : UserControl { #region Log4Net private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); #endregion private static bool _SyncronizeEnahnced = false; public static bool SyncronizeEnhanced { get { return DisplayTabControl._SyncronizeEnahnced; } set { DisplayTabControl._SyncronizeEnahnced = value; } } private static Dictionary _AllDTCs = new Dictionary(); private int _VersionID = 0; // zero tells us to PROMS just opened and no procedure was selected yet so use the main proms window // when the first procedure is opened, the VersionID is set and added to _AllDTCs public int VersionID { get { return _VersionID; } set { if ((int)value != 0) { if (!_AllDTCs.ContainsKey((int)value)) { _AllDTCs.Add((int)value, this); if (_VersionID == 0) _VersionID = value; else _MyLog.WarnFormat("VersionID tried to be Changed from {0} to {1}", _VersionID, value); } } else _VersionID = value; } } // This tells the display tab control whether or not the Separate Windows setting was set private bool _SeparateWindows = false; public bool SeparateWindows { get { return _SeparateWindows; } set { _SeparateWindows = value; } } // this gets called before displaying the PROMS Settings dialog (off of the V button) // return true if at least one procedure is one in more than one procedure set // Also cleanup the _AllDTCs dictionary by removing the VersionID's (procedure sets) that are not opened public bool MoreThanOneProcedureSetIsOpen { get { List verIdList = new List(); // list of procedure sets being used List rmvList = new List(); // list of procedure set no longer being used if (_AllDTCs.Count > 0 && _AllDTCs.Keys.Count > 0) { foreach (int k in _AllDTCs.Keys) { DisplayTabControl dtc = _AllDTCs[k]; if (_AllDTCs.Count > 1 && dtc._MyDisplayTabItems.Count == 0) { if (!rmvList.Contains(k)) rmvList.Add(k); } else { int numKeysVersionID = 0; foreach (string dtikey in dtc._MyDisplayTabItems.Keys) { DisplayTabItem dti = dtc._MyDisplayTabItems[dtikey]; if (dti.MyItemInfo.MyDocVersion.VersionID == k) { numKeysVersionID++; if (!verIdList.Contains(dti.MyItemInfo.MyDocVersion.VersionID)) verIdList.Add(dti.MyItemInfo.MyDocVersion.VersionID); } } if (numKeysVersionID == 0 && !rmvList.Contains(k)) rmvList.Add(k); } } } // remove the VersionID's that no not being used from the AllDTCs list if (rmvList.Count > 0) foreach (int i in rmvList) _AllDTCs.Remove(i); if (_AllDTCs.Count == 0) _VersionID = 0; return (verIdList.Count > 1); } } //public event ItemSelectedChangedEvent OpenEnhancedDocument; //public void OnOpenEnhancedDocument(ItemSelectedChangedEventArgs args) //{ // if (OpenEnhancedDocument != null) // OpenEnhancedDocument(this, args); //} public event ItemSelectedChangedEvent OpenInSeparateWindow; public void OnOpenInSeparateWindow(ItemSelectedChangedEventArgs args) { if (OpenInSeparateWindow != null) OpenInSeparateWindow(this, args); } // C2020-033: Provide way to expand/fill in Search/Incoming Transition panel public event DisplayTabControlEditorSearchIncTransEvent SearchIncTrans; public ItemInfo OnSearchIncTrans(object sender, vlnTreeItemInfoEventArgs args) { if (SearchIncTrans != null) return SearchIncTrans(sender, args); return args.MyItemInfo; } public event ItemSelectedChangedEvent RefreshEnhancedDocument; public void OnRefreshEnhancedDocument(ItemSelectedChangedEventArgs args) { if (RefreshEnhancedDocument != null) RefreshEnhancedDocument(this, args); } public event DisplayTabControlStatusEvent StatusChanged; public void ONStatusChanged(object Sender, DisplayTabControlStatusEventArgs args) { if (StatusChanged != null) StatusChanged(Sender, args); } public event DisplayTabControlEvent ToggleRibbonExpanded; public void OnToggleRibbonExpanded(object sender, EventArgs args) { if (ToggleRibbonExpanded != null) ToggleRibbonExpanded(sender, args); } public event DisplayTabControlEvent SelectedDisplayTabItemChanged; public void OnSelectedDisplayTabItemChanged(object sender, EventArgs args) { if (SelectedDisplayTabItemChanged != null) SelectedDisplayTabItemChanged(sender, args); } // C2015-022 added copystep event to commuicate with child windows public event ItemChangedEventHandler CopyStepSelected; public void OnCopyStepSelected(ItemChangedEventArgs args) { if (CopyStepSelected != null) CopyStepSelected(this, args); } #region Private Fields /// /// This is a lookup table for all of the DisplayTabItems that are currently open /// The key is: /// "Item - " + Procedure ItemID for step pages /// "Doc - " + DocumentID for Word Documents /// public Dictionary _MyDisplayTabItems; /// /// When a Tab is closed it is added to this list. /// When another Tab is opened, any Tabs in this list are closed /// private List _RemovedDisplayTabItems = null; /// /// This stores a UniqueID for Bars as they are opened. /// A bar is the docking location for the DisplayTabItems. /// private int _UniqueBarCount; /// /// ItemsChangeIds is used to store a procedure's itemid and its associated (input from dialog) /// Change Id. Any time a user enters a procedure for the first time in this program session, /// the user gets prompted to enter a change id. Any time a modification is made to the procedure /// this change id is used. The user can modify this change id from the step tab ribbon/change id /// tab (only if the format uses change ids is this tab visible). /// public Dictionary ItemsChangeIds = null; private ItemInfo _MyItemInfo = null; private EditItem _MyEditItem = null; public EditItem MyEditItem { get { return _MyEditItem; } set { _MyEditItem = value; } } private StepRTB _MyStepRTB = null; private bool _RibbonExpanded = true; public StepRTB MyStepRTB { get { return _MyStepRTB; } } public bool RibbonExpanded { get { return _RibbonExpanded; } set { _RibbonExpanded = value; foreach (DisplayTabItem tabItem in _MyDisplayTabItems.Values) if (tabItem.MyStepTabPanel != null) tabItem.MyStepTabPanel.MyStepTabRibbon.Expanded = _RibbonExpanded; } } private ItemInfo _MyCopyStep; public ItemInfo MyCopyStep { get { return _MyCopyStep; } set { _MyCopyStep = value; } } private string _ChgId; public string ChgId { get { return _ChgId; } set { _ChgId = value; } } public bool EditorialChange { get { if (_ChgId == null) return true; if (_ChgId == "") return true; if (_ChgId.ToUpper() == "EC") return true; return false; } } #endregion #region Events /// /// This event is raised when a the "Tab" of a DisplayItem is clicked with a mouse. /// So far this has just been used for demo purposes. It could be used to select a /// step and it's children for the purpose of copying. /// public event StepPanelEvent ItemClick; /// /// Checks to see if the ItemClick event is handled and launches it /// /// /// internal void OnItemClick(object sender, StepPanelEventArgs args) { if (ItemClick != null) ItemClick(sender, args); } /// /// This occurs when the user moves onto or off of a link within a RichTextBox /// or moves between RichTextBoxes or Pages. /// public event StepPanelLinkEvent LinkActiveChanged; /// /// Checks to see if the LinkActiveChanged event is handled and launches it /// /// /// internal void OnLinkActiveChanged(object sender, StepPanelLinkEventArgs args) { if (LinkActiveChanged != null) LinkActiveChanged(sender, args); else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Active Changed", MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// This occurs when a Transition is inserted /// public event StepPanelLinkEvent LinkInsertTran; /// /// Checks to see if the 'LinkInsertTran' event is handled and launches it /// /// /// internal void OnLinkInsertTran(object sender, StepPanelLinkEventArgs args) { if (LinkInsertTran != null) LinkInsertTran(sender, args); else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Insert Tran", MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// This occurs when an RO is inserted /// public event StepPanelLinkEvent LinkInsertRO; /// /// Checks to see if the 'LinkInsertRO' event is handled and launches it /// /// /// internal void OnLinkInsertRO(object sender, StepPanelLinkEventArgs args) { if (LinkInsertRO != null) LinkInsertRO(sender, args); else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Insert RO", MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// This occurs when a Transition is modified /// public event StepPanelLinkEvent LinkModifyTran; /// /// Checks to see if the 'LinkModifyTran' event is handled and launches it /// /// /// internal void OnLinkModifyTran(object sender, StepPanelLinkEventArgs args) { if (LinkModifyTran != null) LinkModifyTran(sender, args); else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Modify Tran", MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// This occurs when an RO is modified /// public event StepPanelLinkEvent LinkModifyRO; /// /// Checks to see if the 'LinkModifyRO' event is handled and launches it /// /// /// internal void OnLinkModifyRO(object sender, StepPanelLinkEventArgs args) { if (LinkModifyRO != null) LinkModifyRO(sender, args); else FlexibleMessageBox.Show(args.LinkInfoText, "Unhandled Link Modify RO", MessageBoxButtons.OK, MessageBoxIcon.Information); } /// /// Occurs when the user selects a different item or page /// public event ItemSelectedChangedEvent ItemSelectedChanged; /// /// Checks to see if the 'ItemSelectedChanged' event is handled and launches it /// /// /// internal void OnItemSelectedChanged(object sender, ItemSelectedChangedEventArgs args) { if (args != null) { _MyItemInfo = args.MyItemInfo; _MyEditItem = args.MyEditItem; if (_MyEditItem != null) { _MyStepRTB = _MyEditItem.MyStepRTB; if (_MyStepRTB != null) _MyStepRTB.Disposed += new EventHandler(_MyStepRTB_Disposed); } else _MyStepRTB = null; } else { _MyItemInfo = null; _MyEditItem = null; _MyStepRTB = null; } if (ItemSelectedChanged != null) ItemSelectedChanged(sender, args); } void _MyStepRTB_Disposed(object sender, EventArgs e) { _MyStepRTB = null; } public event StepPanelModeChangeEvent ModeChange; internal void OnModeChange(object sender, StepRTBModeChangeEventArgs args) { if (ModeChange != null) ModeChange(sender, args); else FlexibleMessageBox.Show("Cannot change mode"); } public event StepPanelTabDisplayEvent PanelTabDisplay; internal void OnPanelTabDisplay(object sender, StepPanelTabDisplayEventArgs args) { if (PanelTabDisplay != null) PanelTabDisplay(sender, args); else FlexibleMessageBox.Show("Cannot display information"); } public event StepPanelWordSectionCloseEvent WordSectionClose; internal void OnWordSectionClose(object sender, WordSectionEventArgs args) { if (WordSectionClose != null) WordSectionClose(sender, args); else FlexibleMessageBox.Show("Cannot close associated Word section"); } public event StepPanelWordSectionDeletedEvent WordSectionDeleted; internal void OnWordSectionDeleted(object sender, WordSectionEventArgs args) { if (WordSectionDeleted != null) WordSectionDeleted(sender, args); else FlexibleMessageBox.Show("Cannot delete associated Word section"); } public event StepPanelItemPastedEvent ItemPaste; internal void OnItemPaste(object sender, vlnTreeItemInfoPasteEventArgs args) { if (ItemPaste != null) ItemPaste(sender, args); else FlexibleMessageBox.Show("Cannot adjust panels for pasted item"); } #endregion #region Contructor & Setup public DisplayTabControl() { InitializeComponent(); SetUp(); } private void SetUp() { ItemsChangeIds = new Dictionary(); _RemovedDisplayTabItems = new List(); Dock = DockStyle.Fill; dotNetBarManager1.Style = DevComponents.DotNetBar.eDotNetBarStyle.Office2007; _MyDisplayTabItems = new Dictionary(); SetupBar(_MyBar); dotNetBarManager1.BarTearOff += new EventHandler(dotNetBarManager1_BarTearOff); this.Resize += new EventHandler(DisplayTabControl_Resize); } void DisplayTabControl_Resize(object sender, EventArgs e) { // If the currently selected Item is in a Step, then adjust the scroll as necessary to keep it visible if (_MyEditItem != null) _MyEditItem.ItemShow(); } private void SetupBar(Bar myBar) { if (myBar.DockTabControl != null) { myBar.DockTabControl.CloseButtonOnTabsVisible = true; myBar.DockTabControl.CloseButtonVisible = false; myBar.DockTabControl.CloseButtonPosition = DevComponents.DotNetBar.eTabCloseButtonPosition.Right; myBar.DockTabControl.Width = ClientRectangle.Width; } myBar.DockTabClosing += new DockTabClosingEventHandler(myBar_DockTabClosing); if (!myBar.Visible) myBar.Visible = true; myBar.RecalcLayout(); } #endregion #region Internal Event Handlers /// /// This is code recommended by DotNetBar /// /// /// void dotNetBarManager1_BarTearOff(object sender, EventArgs e) { Bar myBar = sender as Bar; myBar.Enter += new EventHandler(myBar_Enter); } /// /// This sets-up the bar after it is selected. /// /// /// void myBar_Enter(object sender, EventArgs e) { Bar myBar = sender as Bar; myBar.Enter -= new EventHandler(myBar_Enter); SetupBar(sender as Bar); } /// /// This handles the closing of a document page /// /// /// void myBar_DockTabClosing(object sender, DockTabClosingEventArgs e) { e.RemoveDockTab = true; _RemovedDisplayTabItems.Add((DisplayTabItem)e.DockContainerItem); if (_MyDisplayTabItems.ContainsKey(((DisplayTabItem)e.DockContainerItem).MyKey)) _MyDisplayTabItems.Remove(((DisplayTabItem)e.DockContainerItem).MyKey); // C2015-022 separate windows supporting logic DisplayTabItem dti = e.DockContainerItem as DisplayTabItem; if (dti != null && dti.MyStepTabPanel != null) dti.MyStepTabPanel.MyStepPanel.Dispose(); DisplayTabItem myTabItem = e.DockContainerItem as DisplayTabItem; if (myTabItem != null) { if (myTabItem.MyDSOTabPanel != null) { myTabItem.MyDSOTabPanel.CloseDSO(); } } MySessionInfo.CheckInItem(dti.OwnerID); if (((Bar)sender).Items == null) return; if (((Bar)sender).Items.Count == 1)// Remove bar if last item is closed... { Bar bar = sender as Bar; if (bar != null) { if (dotNetBarManager1.Bars.Contains(bar.Name)) dotNetBarManager1.Bars.Remove(bar); ActivateRemainingTab(); } // B2018-123 the last tab in the main window was closed. // remove the procedure version id from the _AllDTCs dictionary // reset VersionID to zero so that we know the main window is available _AllDTCs.Remove(VersionID); VersionID = 0; } else { if (!ShuttingDown) // B2022-026 RO Memory Reduction code - don't activate if shutting down PROMS ActivateRemainingTab((Bar)sender); } } #endregion #region Public Methods public void RefreshItem(ItemInfo myItemInfo) { ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item string key = "Item - " + proc.ItemID.ToString(); if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it { DisplayTabItem pg = _MyDisplayTabItems[key]; if (pg.MyStepTabPanel.MyStepPanel._LookupEditItems.ContainsKey(myItemInfo.ItemID)) OpenItem(myItemInfo, false); } } public DisplayTabItem OpenItem(ItemInfo myItemInfo2) { //B2017-251 Added Error Log message for Open Step or MSWord section include time to do open DateTime tStart = DateTime.Now; DisplayTabItem dti = OpenItem(myItemInfo2, true); _MyLog.InfoFormat("OpenItem {0} seconds {1} {2}", TimeSpan.FromTicks(DateTime.Now.Ticks - tStart.Ticks).TotalSeconds, myItemInfo2.ItemID, myItemInfo2.ShortPath); return dti; } /// /// Open a Step Item or a Word Item /// /// /// // C2023-016 Added doingFindReplace where if true Word section will not be opened - used only when doing Find/Replace // We are not opening and searching inside Word sections, instead we just stop on the section title in the procedure editor (if a match is found in the title) public DisplayTabItem OpenItem(ItemInfo myItemInfo2, bool setFocus, bool doingFindReplace=false) { ItemInfo myItemInfo = myItemInfo2; if (myItemInfo.MyDocVersion == null) // bug fix: B2016-108 disconnected data will not have a MyDocVersion { FlexibleMessageBox.Show(this, "Possible disconnected item", "Item Not Found"); return null; } string message = string.Empty; //if (!MySessionInfo.CanCheckOutItem(myItemInfo.MyDocVersion.VersionID, CheckOutType.DocVersion, ref message)) //{ // message = "The Working Draft is being processed.\n\n" + message; // MessageBox.Show(this, message, "Cannot Check Out Procedure", MessageBoxButtons.OK, MessageBoxIcon.Warning); //} if (myItemInfo.MyContent.MyEntry == null) //not a document { if (!MySessionInfo.CanCheckOutItem(myItemInfo.MyProcedure.ItemID, CheckOutType.Procedure, ref message)) { FlexibleMessageBox.Show(this, message, "Procedure Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning); return null; } } else { if (!MySessionInfo.CanCheckOutItem(myItemInfo.MyContent.MyEntry.DocID, CheckOutType.Document, ref message)) { FlexibleMessageBox.Show(this, message, "Document Already Checked Out", MessageBoxButtons.OK, MessageBoxIcon.Warning); return null; } } CleanUpClosedItems(); if (myItemInfo == null) return null; // if this is an auto table of contents section, don't edit it: if (myItemInfo.IsAutoTOCSection) { FlexibleMessageBox.Show("This is an automatically generated 'Table of Contents' section. It is not editable. It is generated during Print.", "Item not Editable", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return SelectedDisplayTabItem; } bool libDocAlreadyOpen = false; if (myItemInfo.MyContent.MyEntry != null) // Trying to open a Word document - see if it's a library document that is already opened. libDocAlreadyOpen = LibDocAlreadyOpen(myItemInfo); // C2015-022 modified if statement logic to support separate windows // if opening the first procedure in a set, and the main PROMS window has a procedure opened from a different set, // then create a new child window. All other procedures from that same set will open in this child window. // _AllDTCs is a dictionary of of all procedure sets opened along with their DisplayTabContol. The key to // the dictioan is the set's VersionID // B2018-048 needed to add a check to see if we are in Separate Windows // else we get stuck in a OpenItem loop when last DocVersion ID is not equal to the current DocVersion ID // happened when you open a procedure then close the procedure tab, do a text search in a different procedure set // then select one of search results. if (SeparateWindows && VersionID != 0) { if (!libDocAlreadyOpen) { if (!_AllDTCs.ContainsKey(myItemInfo.MyDocVersion.VersionID)) { OnOpenInSeparateWindow(new ItemSelectedChangedEventArgs(myItemInfo2)); // create a child (separate) PROMS window return _AllDTCs[myItemInfo.MyDocVersion.VersionID].OpenItem(myItemInfo); } } if (VersionID != myItemInfo.MyDocVersion.VersionID && _AllDTCs.ContainsKey(myItemInfo.MyDocVersion.VersionID)) { return _AllDTCs[myItemInfo.MyDocVersion.VersionID].OpenItem(myItemInfo); } } if (!libDocAlreadyOpen) VersionID = myItemInfo.MyDocVersion.VersionID; // add it to _AllDTCs _MyBar = GetParentBar(myItemInfo); // Get the docking bar associated with this item. // C2023-016 if a Word section and doing Find/Replace don't open Word section, position to section title in step editor instead if (myItemInfo.MyContent.MyEntry == null || doingFindReplace) // If it is not a Word document open in step editor { return OpenStepTabPage(myItemInfo, setFocus); } else // Otherwise open it in the Word editor { Document.ConvertWordSectionToDOCX(myItemInfo); // B2023-093 Convert a Word section to the DOCX Word format if needed before opening it for edit return OpenDSOTabPage(myItemInfo); } } public bool PasteRTBItem(ItemInfo myItemInfo, int copyStartID, ItemInfo.EAddpingPart pasteType, int type) { CleanUpClosedItems(); ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item string key = "Item - " + proc.ItemID.ToString(); if (_MyDisplayTabItems.ContainsKey(key) && pasteType != ItemInfo.EAddpingPart.Replace) // If procedure page open use it unless replace { DisplayTabItem pg = _MyDisplayTabItems[key]; if (pg.MyStepTabPanel.MyStepPanel._LookupEditItems.ContainsKey(myItemInfo.ItemID) && pg.MyStepTabPanel.MyStepPanel._LookupEditItems[myItemInfo.ItemID].Expanded) { EditItem edtitm = pg.MyStepTabPanel.MyStepPanel._LookupEditItems[myItemInfo.ItemID]; switch (pasteType) { case ItemInfo.EAddpingPart.Child: edtitm.PasteChild(copyStartID); break; case ItemInfo.EAddpingPart.Before: edtitm.PasteSiblingBefore(copyStartID); break; case ItemInfo.EAddpingPart.After: edtitm.PasteSiblingAfter(copyStartID); break; case ItemInfo.EAddpingPart.Replace: EditItem ei = edtitm.PasteReplace(copyStartID); if (ei == null) { CloseTabItem(_MyDisplayTabItems["Item - " + myItemInfo.ItemID.ToString()]); //Grab itemID and set to close open tab. return false; //B2017-179 PasteReplace will return null if was aborted } if (ei.MyItemInfo.ItemID != edtitm.MyItemInfo.ItemID) { edtitm.Dispose(); MyCopyStep = ei.MyItemInfo; } break; default: return false; } return true; } } else if (_MyDisplayTabItems.ContainsKey(key) && pasteType == ItemInfo.EAddpingPart.Replace) { CloseTabItem(_MyDisplayTabItems["Item - " + myItemInfo.ItemID.ToString()]); //Grab itemID and set to close open tab. return false; //B2017-179 PasteReplace will return null if was aborted } return false; } public bool DeleteRTBItem(ItemInfo myItemInfo) { CleanUpClosedItems(); //removeitem! ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item string key = "Item - " + proc.ItemID.ToString(); if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it { DisplayTabItem pg = _MyDisplayTabItems[key]; // if deleting a procedure, close the tab. if (proc.ItemID == myItemInfo.ItemID) { // do we need to close open doc tabs associated with this proc. CloseTabItem(pg); return false; } if (pg.MyStepTabPanel.MyStepPanel._LookupEditItems.ContainsKey(myItemInfo.ItemID)) { EditItem edtitm = pg.MyStepTabPanel.MyStepPanel._LookupEditItems[myItemInfo.ItemID]; edtitm.RemoveItem(); return true; } } return false; } public bool InsertRTBItem(ItemInfo myItemInfo, string text, E_InsertType insertType, E_FromType fromType, int type, bool updateSelection) { CleanUpClosedItems(); ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item string key = "Item - " + proc.ItemID.ToString(); if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it { DisplayTabItem pg = _MyDisplayTabItems[key]; if (pg.MyStepTabPanel.MyStepPanel._LookupEditItems.ContainsKey(myItemInfo.ItemID)) { EditItem edtitm = pg.MyStepTabPanel.MyStepPanel._LookupEditItems[myItemInfo.ItemID]; switch (insertType) { case E_InsertType.Before: edtitm.AddSiblingBefore(text, updateSelection); break; case E_InsertType.After: edtitm.AddSiblingAfter(text, updateSelection); break; case E_InsertType.Child: edtitm.AddChild(text, fromType, type, null); break; default: return false; ; } return true; } } return false; } private void CleanUpClosedItems() { while (_RemovedDisplayTabItems.Count > 0) // Clean-up any items that have been closed. { DisplayTabItem myTabItem = _RemovedDisplayTabItems[0]; _RemovedDisplayTabItems.RemoveAt(0); RemoveItem(myTabItem); } } public void CloseWordItem(ItemInfo myItemInfo) { CloseWordItem(myItemInfo, false); } public void CloseWordItem(ItemInfo myItemInfo, bool isBeingDeleted) { CleanUpClosedItems(); string key = "Doc - "; // there is no entry if it is an auto table of contents: if (myItemInfo.MyContent.MyEntry != null) key = key + myItemInfo.MyContent.MyEntry.MyDocument.DocID.ToString(); else key = key + "0"; DisplayTabItem myTabItem = null; if (_MyDisplayTabItems.ContainsKey(key)) // If page open, close it { myTabItem = _MyDisplayTabItems[key]; if (myTabItem.MyDSOTabPanel != null) { myTabItem.MyDSOTabPanel.IsBeingDeleted = isBeingDeleted; CloseTabItem(myTabItem); } } } public void CloseTabItem(DisplayTabItem myTabItem) { if (myTabItem.ContainerControl == null) return; Bar b = myTabItem.ContainerControl as Bar; if (b != null) { b.CloseDockTab(myTabItem); //b.Items.Remove(myTabItem); RemoveItem(myTabItem); } } /// /// Look for a tab and set it to active. /// private void ActivateRemainingTab() { foreach (Bar myBar in dotNetBarManager1.Bars) { if (myBar.DockSide == eDockSide.Document && myBar.Visible) { ActivateRemainingTab(myBar); return; } } // No Document Tabs Remaining - need to raise OnItemSelectedChanged OnItemSelectedChanged(this, null); } private DisplayTabItem FindRemainingTab(Bar myBar) { // C2023-004: Proms reverts to first tab rather than active tab/save last selected tab is and use to reset to it // B2023-078 Added the check for LastSelectedDisplayTabItem is in myBar. This fixes a crash issue where user has as split screen // each with procedure tabs and closes a procedure tab in the split screen that does not currently have focus. // that other screen has its own myBar list which does not contain the LastSelectedDisplayTabItem references. // In that case we want to run through the foreach loop to find a tab in the currently active split screen side if (LastSelectedDisplayTabItem != null && myBar.Items.Contains(LastSelectedDisplayTabItem) && !_RemovedDisplayTabItems.Contains(LastSelectedDisplayTabItem)) return LastSelectedDisplayTabItem; foreach (DisplayTabItem itm in myBar.Items) { if (!_RemovedDisplayTabItems.Contains(itm)) return itm; } return null; } private void ActivateRemainingTab(Bar myBar) { if (myBar.SelectedDockContainerItem != null) { if (_RemovedDisplayTabItems.Contains(myBar.SelectedDockContainerItem as DisplayTabItem)) myBar.SelectedDockContainerItem = FindRemainingTab(myBar); myBar.SelectedDockContainerItem.Selected = true; StepTabPanel pnl = myBar.SelectedDockContainerItem.Control as StepTabPanel; if (pnl != null) pnl.MyStepPanel.ItemShow(); } } #endregion #region Public Properties private AnnotationDetails _MyAnnotationDetails; public AnnotationDetails MyAnnotationDetails // B2019-029: added to find annotation details for saving w/o btnsave click { get { return _MyAnnotationDetails; } set { _MyAnnotationDetails = value; } } private SessionInfo _MySessionInfo; public SessionInfo MySessionInfo { get { return _MySessionInfo; } set { _MySessionInfo = value; } } public DevComponents.DotNetBar.Bar MyBar { get { return _MyBar; } } public Panel PnlCaret { get { return _PnlCaret; } } private static int trackerSC = 0; private bool _ShuttingDown = false; public bool ShuttingDown { get { return _ShuttingDown; } set { _ShuttingDown = value; } } public void ShowCaret() { if (_ShuttingDown) return; if (_MyStepRTB != null) { if (_MyEditItem.RTBLastFocus) { if (_MyStepRTB.MyItemInfo != null && _MyStepRTB.MyItemInfo.IsRtfRaw) return; trackerSC++; /*if (trackerSC>20) *///Console.WriteLine("ShowCaret: {0}", trackerSC); //Volian.Base.Library.vlnStackTrace.ShowStack("ShowCaret: EI: {0} StepRTB: {1}", _MyEditItem.MyItemInfo.ItemID, _MyStepRTB.MyItemInfo.ItemID); if (!_MyStepRTB.Visible) _MyStepRTB.Visible = true; if (_MyStepRTB.SelectionLength == 0) { Point pt = _MyStepRTB.GetPositionFromCharIndex(_MyStepRTB.SelectionStart); pt = _MyStepRTB.PointToScreen(pt); pt = this.PointToClient(pt); PnlCaret.Location = pt; PnlCaret.BackColor = _MyStepRTB.ForeColor; using (Graphics gr = this.CreateGraphics()) { SizeF sf = gr.MeasureString("Mg", _MyStepRTB.SelectionFont); sf.Width = 1; PnlCaret.Size = sf.ToSize(); } tmrCaret.Enabled = true; } else _MyStepRTB.HideSelection = false; // bug fix B215-147 we used to insert a highlight command - caused issues with IsDirty() where false dirtyness was reported } } } private static int trackerHC = 0; public void HideCaret() { if (_MyStepRTB != null && !_MyStepRTB.Disposing && !_MyStepRTB.Closed) { trackerHC++; /* if (trackerHC>20)*/ //Console.WriteLine("HideCaret {0}", trackerHC); //Volian.Base.Library.vlnStackTrace.ShowStack("HideCaret: StepRTB: {0}", _MyStepRTB.MyItemInfo.ItemID); HideTheCaret(); if (_MyStepRTB.SelectionLength > 0) _MyStepRTB.HideSelection = true; // bug fix B215-147 we used to insert a highlight command - caused issues with IsDirty() where false dirtyness was reported } } public void HideTheCaret() { tmrCaret.Enabled = false; PnlCaret.Visible = false; } // B2019-161 When tracking timing time this action private static VolianTimer _TimeActivity = new VolianTimer("DisplayTabControl.cs tmrCaret_Tick", 881); private void tmrCaret_Tick(object sender, EventArgs e) { _TimeActivity.Open(); PnlCaret.Visible = !PnlCaret.Visible; _TimeActivity.Close(); } #endregion #region Private Methods ///// ///// Gets and sets the SelectedDisplayTabItem (Active Tab) ///// //public DisplayTabItem SelectedDisplayTabItem1 //{ // get { return (DisplayTabItem)_MyBar.SelectedDockContainerItem; } // set // { // //Volian.Base.Library.vlnStackTrace.ShowStackLocal("SelectedDisplayTabItem"); // if (value != null) // { // value.Focus(); // value.Selected = true; // } // } //} public void SelectDisplayTabItem(DisplayTabItem myDisplayTabItem) { if (myDisplayTabItem != null) { if (!myDisplayTabItem.Selected) { myDisplayTabItem.Focus(); myDisplayTabItem.Selected = true; } } } // C2023-004: Proms reverts to first tab rather than active tab/save last selected tab is and use to reset to it private DisplayTabItem _lastSelectedDisplayTabItem; public DisplayTabItem LastSelectedDisplayTabItem { get { return _lastSelectedDisplayTabItem; } set { _lastSelectedDisplayTabItem = value; } } private DisplayTabItem _SelectedDisplayTabItem = null; public DisplayTabItem SelectedDisplayTabItem { get { return _SelectedDisplayTabItem; } set { if (DesignMode) return; // B2019-043 need to check if we are just saving changes to the user interface if (_SelectedDisplayTabItem != value) { if (_SelectedDisplayTabItem != null && _SelectedDisplayTabItem.MyDSOTabPanel != null) _SelectedDisplayTabItem.MyDSOTabPanel.InActive(); _lastSelectedDisplayTabItem = _SelectedDisplayTabItem; _SelectedDisplayTabItem = value; OnSelectedDisplayTabItemChanged(this, new EventArgs()); } } } /// /// This returns the parent bar (current docking location) for an item. /// It creates a bar if none exist /// /// /// private Bar GetParentBar(ItemInfo myItemInfo) { Bar myBar = null; foreach (Bar b in dotNetBarManager1.Bars) { if (b.DockSide == eDockSide.Document && b.Visible) { if (myBar == null) myBar = b;// Remember the first available bar if a specific bar cannot be found foreach (object itm in b.Items) { DisplayTabItem myTabItem = itm as DisplayTabItem; if (myTabItem != null && myTabItem.MyStepTabPanel != null && myItemInfo != null) if (myTabItem.MyStepTabPanel.MyProcedureItemInfo.ItemID == myItemInfo.MyProcedure.ItemID) return b; } } } if (myBar == null) { // If no documents bars found, create new one _UniqueBarCount++; myBar = BarUtilities.CreateDocumentBar(); myBar.DockTabClosing += new DockTabClosingEventHandler(myBar_DockTabClosing); myBar.Name = "barDocuments" + _UniqueBarCount.ToString(); fillDocDockSite.GetDocumentUIManager().Dock(myBar); SetupBar(myBar); } return myBar; } public StepTabPanel GetProcedureTabPanel(ItemInfo myItemInfo) { Bar myBar = null; foreach (Bar b in dotNetBarManager1.Bars) { if (b.DockSide == eDockSide.Document && b.Visible) { if (myBar == null) myBar = b;// Remember the first available bar if a specific bar cannot be found foreach (object itm in b.Items) { DisplayTabItem myTabItem = itm as DisplayTabItem; if (myTabItem != null && myTabItem.MyStepTabPanel != null && myTabItem.MyStepTabPanel.MyProcedureItemInfo != null) if (myTabItem.MyStepTabPanel.MyProcedureItemInfo.ItemID == myItemInfo.MyProcedure.ItemID) return myTabItem.MyStepTabPanel; } } } return null; } /// /// Save the current EditItem if it is in Edit mode /// /// ProcedureInfo public void SaveCurrentEditItem(ProcedureInfo pi) { DisplayTabItem dti = GetProcDisplayTabItem(pi); if (dti == null) return; EditItem ei = dti.MyStepTabPanel.SelectedEditItem; if (ei == null) return; ei.SaveCurrentAndContents(); } /// /// Save the current EditItem if it is in Edit mode /// public void SaveCurrentEditItem() { foreach (DisplayTabItem dti in _MyDisplayTabItems.Values) { StepTabPanel stp = dti.MyStepTabPanel; if (stp != null) { EditItem ei = stp.SelectedEditItem; if (ei != null) ei.SaveCurrentAndContents(); } } } public DisplayTabItem GetProcDisplayTabItem(ItemInfo myItemInfo) { ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item string key = "Item - " + proc.ItemID.ToString(); DisplayTabItem pg = null; if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it return _MyDisplayTabItems[key]; return null; } /// /// This opens a Step page based upon a ItemInfo. /// /// /// /// //public bool IsItemInfoProcedureOpen(ItemInfo ii) // if (ii == null) return false; //{ // ItemInfo proc = ii.MyProcedure; // Find procedure Item // if (dicEnhancedDocuments.ContainsKey(ii.MyProcedure.MyDocVersion)) // { // frmEnhanced frm = dicEnhancedDocuments[ii.MyProcedure.MyDocVersion]; // string key = "Item - " + proc.ItemID.ToString(); // if (frm.MyDisplayTabClntrol._MyDisplayTabItems.ContainsKey(key)) // return true; // } // // return true; // //return false; // return false; //} //public Dictionary dicEnhancedDocuments = new Dictionary(); private DisplayTabItem OpenStepTabPage(ItemInfo myItemInfo, bool setFocus) { ItemInfo proc = myItemInfo.MyProcedure; // Find procedure Item string key = "Item - " + proc.ItemID.ToString(); DisplayTabItem pg = null; if (_MyDisplayTabItems.ContainsKey(key)) // If procedure page open use it { pg = _MyDisplayTabItems[key]; if (setFocus) { pg.Selected = true; HandleChangeId(myItemInfo, pg); if (SelectedDisplayTabItem != pg) // If the selected page doesn't match SelectDisplayTabItem(pg); // Set the selected page } } else // If not already open, create a new Page { pg = new DisplayTabItem(this.components, this, proc, key); // Open a new Procedure Tab _MyDisplayTabItems.Add(key, pg); if (setFocus) { pg.Selected = true; HandleChangeId(myItemInfo, pg); SelectDisplayTabItem(pg); // If this is an enhanced document, check for refresh of text items: //if (myItemInfo.IsProcedure) //{ // make the myiteminfo into a procedureinfo (depending on where this is called from, just // casting it crashed: ProcedureInfo pi = ProcedureInfo.Get(myItemInfo.MyProcedure.ItemID); ItemInfoList iil = pi.FindEnhancedProcedureTextDifferences(); if (iil != null) { // C2019-045: See if this is a procedure & modifications are allowed, if that case, don't prompt: bool doMsg = true; if (iil.Count == 1 && iil[0].EnhAllowMod()) doMsg = false; if (doMsg && FlexibleMessageBox.Show(this, "Text differences were found between this enhanced procedure and its source procedure. Do you want to refresh the text in this procedure?", "Confirm Text Refresh", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes) { pi.EnhancedProcedureRefreshTextDifferences(iil); } } //} } pg.MyStepTabPanel.MyProcedureItemInfo = proc; // When more than one procedure is openned, the ribbon control cuts off the bottom of the buttons. // This happened to all the procedure tabs after the first one. // This is to kludge the logic into sizing the ribbon control properly. // This is done by toggling "pg.MyStepTabPanel.MyStepTabRibbon.Expanded" // Note that we are doing the NOT of its current setting. This takes care of when the // ribbon bar is minimized and a new procedure tab is created pg.MyStepTabPanel.MyStepTabRibbon.Expanded = !pg.MyStepTabPanel.MyStepTabRibbon.Expanded; pg.MyStepTabPanel.MyStepTabRibbon.Expanded = !pg.MyStepTabPanel.MyStepTabRibbon.Expanded; } Application.DoEvents(); pg.SelectedItemInfo = myItemInfo; // Select the item //StepConfig sc = new StepConfig(myItemInfo.MyContent.Config); //if (sc.Step_SourceToBackground != null || sc.Step_SourceToDeviation != null) // pg.MyStepTabPanel.MyStepTabRibbon.btnEnhancedDocSync.Visible = true; //else // pg.MyStepTabPanel.MyStepTabRibbon.btnEnhancedDocSync.Visible = false; return pg; } private bool _SyncEnhancedDocuments; public bool SyncEnhancedDocuments { get { return _SyncEnhancedDocuments; } set { _SyncEnhancedDocuments = value; } } public void HandleChangeId(ItemInfo myItemInfo, DisplayTabItem pg) { if (myItemInfo.ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ChangeIds) { if (ItemsChangeIds.ContainsKey(myItemInfo.MyProcedure.ItemID)) SetChangeId(ItemsChangeIds[myItemInfo.MyProcedure.ItemID], pg, myItemInfo); else PromptForChangeId(myItemInfo, pg); } } private void PromptForChangeId(ItemInfo myItemInfo, DisplayTabItem pg) { if (!Volian.Base.Library.VlnSettings.GetCommandFlag("NOCHGID")) { dlgChgId dlgCI = new dlgChgId(this); //, null); dlgCI.ShowDialog(this); } ItemsChangeIds.Add(myItemInfo.MyProcedure.ItemID, ChgId); SetChangeId(ChgId, pg, myItemInfo); } private void SetChangeId(string chgid, DisplayTabItem pg, ItemInfo ii) { //if (pg == null || pg.MyStepTabPanel == null) //{ // ChgId = null; // return; //} if (pg != null && pg.MyStepTabPanel != null) pg.MyStepTabPanel.MyStepTabRibbon.SetChangeId(chgid, ii); ChgId = chgid; } private bool LibDocAlreadyOpen(ItemInfo myItemInfo) { EntryInfo myEntry = myItemInfo.MyContent.MyEntry; string key = "Doc - " + myEntry.DocID; DisplayTabItem pg = null; return LibDocAlreadyOpen(myItemInfo, key, ref pg, false); } private bool LibDocAlreadyOpen(ItemInfo myItemInfo, string key, ref DisplayTabItem pg, bool displayMsg) { bool libDocAlreadyOpen = false; // C2015-022 part of separate windows logic, check all tabs in all windows to see if lib docs if (_AllDTCs != null && _AllDTCs.Count > 0) { foreach (int k in _AllDTCs.Keys) { DisplayTabControl dtc = _AllDTCs[k]; if (dtc._MyDisplayTabItems.ContainsKey(key)) { pg = dtc._MyDisplayTabItems[key]; if (pg.MyItemInfo.ItemID != myItemInfo.ItemID) { if (displayMsg) { string msg = string.Format("{0} is already open", myItemInfo.MyContent.MyEntry.MyDocument.LibTitle); FlexibleMessageBox.Show(msg, "Library Document is Already Open", MessageBoxButtons.OK); } libDocAlreadyOpen = true; break; } } } } return libDocAlreadyOpen; } /// /// This opens a Word page based upon an itemInfo. Since a word document may be a library /// document, the related DocID is used for the Word document. /// /// /// private DisplayTabItem OpenDSOTabPage(ItemInfo myItemInfo) { DisplayTabItem pg = null; EntryInfo myEntry = myItemInfo.MyContent.MyEntry; string key = "Doc - " + myEntry.DocID; bool libDocAlreadyOpen = LibDocAlreadyOpen(myItemInfo, key, ref pg, true); if (!libDocAlreadyOpen && pg == null) { if (DSOTabPanel.Count >= DSOTabPanel.MSWordLimit) // Limit the number of open document pages to 18 { FlexibleMessageBox.Show("Too many Word Documents Open. Please close one of the Documents before attempting to open another"); return null; } //if ((myItemInfo.MyContent.MyEntry.MyDocument.LibTitle ?? "") != "") // MessageBox.Show("WARNING: All edits made to this Library Document will be applied to all uses of the Document"); pg = new DisplayTabItem(this.components, this, myItemInfo, key); // Open a new document page // B2917-219 if MyEdWord is null that means we had trouble opening the word attachment and either a blank document was created or a previous version was recovered // so we now we want to open the now blank or recovered attachment if (pg.MyDSOTabPanel.MyEdWord == null) { pg = OpenDSOTabPage(myItemInfo); if (pg.MyDSOTabPanel.MyEdWord == null) return null; // even the blank or recovered attachment cannot be opened else return pg; } _MyDisplayTabItems.Add(key, pg); } SelectDisplayTabItem(pg); pg.MyDSOTabPanel.EnterPanel(); return pg; } public DisplayTabItem OpenDSOTabPage(DocumentInfo myDocumentInfo) { _MyBar = GetParentBar(null); // B2016-131 - allow open of a non-referenced library document CleanUpClosedItems(); DisplayTabItem pg = null; string key = "Doc - " + myDocumentInfo.DocID; if (_MyDisplayTabItems.ContainsKey(key)) // If document page open use it pg = _MyDisplayTabItems[key]; else { if (DSOTabPanel.Count > DSOTabPanel.MSWordLimit) //18) // Limit the number of open document pages to 18 { FlexibleMessageBox.Show("Too many Word Documents Open. Please close one of the Documents before attempting to open another"); return null; } pg = new DisplayTabItem(this.components, this, myDocumentInfo, key); // Open a new document page _MyDisplayTabItems.Add(key, pg); } SelectDisplayTabItem(pg); pg.MyDSOTabPanel.EnterPanel(); return pg; } /// /// Clean-up after a page is closed /// /// internal void RemoveItem(DisplayTabItem myDisplayTabItem) { if (_MyDisplayTabItems.ContainsKey(myDisplayTabItem.MyKey)) { try { _MyDisplayTabItems.Remove(myDisplayTabItem.MyKey); // Dispose of the procedure tab panel if (myDisplayTabItem.MyStepTabPanel != null) myDisplayTabItem.MyStepTabPanel.Dispose(); // Dispose of the MS Word Panel if (myDisplayTabItem.MyDSOTabPanel != null) myDisplayTabItem.MyDSOTabPanel.CloseDSO(); components.Remove(myDisplayTabItem); myDisplayTabItem.Dispose(); } catch { } } } #endregion } }