using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Data.SqlClient; using System.Text.RegularExpressions; using Csla; using Csla.Data; using System.Windows.Forms; using JR.Utils.GUI.Forms; namespace VEPROMS.CSLA.Library { public delegate void ItemInfoInsertEvent(object sender, ItemInfoInsertEventArgs args); public class ItemInfoInsertEventArgs { private ItemInfo _ItemInserted; public ItemInfo ItemInserted { get { return _ItemInserted; } set { _ItemInserted = value; } } private ItemInfo.EAddpingPart _AddingPart; public ItemInfo.EAddpingPart AddingPart { get { return _AddingPart; } set { _AddingPart = value; } } public ItemInfoInsertEventArgs(ItemInfo itemInserted,ItemInfo.EAddpingPart addingPart) { _ItemInserted = itemInserted; _AddingPart = addingPart; } } public partial class ItemInfo { public ItemInfo HandleSqlExceptionOnDelete(Exception ex) { if (ex.Message.Contains("has External Transitions and has no next step")) { using (TransitionInfoList exTrans = TransitionInfoList.GetExternalTransitionsToChildren(ItemID)) { DialogResult ans = FlexibleMessageBox.Show("Transitions exist to this step and cannot be adjusted automatically." + "\r\n\r\nDo you want to be placed on the " + (exTrans.Count > 1 ? "first " : "") + "substep with the problem Transition?" + "\r\n\r\nSubsteps with Problem Transitions" + exTrans.Summarize(), "Cannot Delete This Step", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ans == DialogResult.Yes) { return exTrans[0].MyContent.ContentItems[0]; } } } else if (ex.Message.Contains("has External Transitions to Procedure")) { using (TransitionInfoList exTrans = TransitionInfoList.GetExternalTransitionsToChildren(ItemID)) { DialogResult ans = FlexibleMessageBox.Show("Transitions exist to this procedure and cannot be adjusted automatically." + "\r\n\r\nDo you want to be placed on the " + (exTrans.Count > 1 ? "first " : "") + "substep with the problem Transition?" + "\r\n\r\nSubsteps with Problem Transitions" + exTrans.Summarize(), "Cannot Delete This Procedure", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ans == DialogResult.Yes) { return exTrans[0].MyContent.ContentItems[0]; } } } else if (ex.Message.Contains("has External Transitions to it's children")) { using (TransitionInfoList exTrans = TransitionInfoList.GetExternalTransitionsToChildren(ItemID)) { DialogResult ans = FlexibleMessageBox.Show("Transitions exist to substeps of this step and cannot be adjusted automatically." + "\r\n\r\nDo you want to be placed on the " + (exTrans.Count > 1 ? "first " : "") + "substep with the problem Transition?" + "\r\n\r\nSubsteps with Problem Transitions:" + exTrans.Summarize(), "Cannot Delete This Step", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (ans == DialogResult.Yes) { return exTrans[0].MyContent.ContentItems[0]; } } } else MessageBox.Show(ex.Message, "SQL Exception", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return null; } #region Old Insert //public ItemInfo InsertSiblingBeforeOld(string text) //{ // return InsertSiblingBefore(text, null); //} //public ItemInfo InsertSiblingBeforeOld(string text, string number) //{ // ItemInfo prevItemInfo = MyPrevious; // ItemInfo newItemInfo = null; // PartInfoList partInfoList = null; // if (MyParent != null && MyParent.MyContent != null) // { // MyParent.MyContent.RefreshContentParts(); // partInfoList = MyParent.MyContent.ContentParts; // } // using (Item prevItem = prevItemInfo == null ? null : prevItemInfo.Get()) // Get the previous Item // { // using (Item newItem = Item.MakeItem(prevItem, Content.MakeContent(number, text, MyContent.Type, null, null))) // Create the new Item // { // using (Item thisItem = Get()) // Get the next item in the list // { // thisItem.MyPrevious = newItem; // Point to the new item // thisItem.Save(); // Save Changes // if (prevItem == null) // { // PartInfo partInfo = partInfoList.Find(this); // using (Part part = partInfo.Get()) // { // part.MyItem = newItem; // part.Save(); // } // } // } // // ToDo: Need change PartInfo in PartInfoList // newItemInfo = ItemInfo.Get(newItem.ItemID); // newItemInfo.ResetOrdinal(); // } // } // return newItemInfo; //} //public ItemInfo InsertSiblingAfterOld(string text) //{ // return InsertSiblingAfter(text, null); //} //public ItemInfo InsertSiblingAfterOld(string text, string number) //{ // return InsertSiblingAfter(text, number, MyContent.Type); //} //public ItemInfo InsertSiblingAfterOld(string text, string number, int? type) //{ // ItemInfo nextItemInfo = NextItem; // ItemInfo newItemInfo = null; // using (Item thisItem = Get()) // Get the Current Item // { // using (Item newItem = Item.MakeItem(thisItem, Content.MakeContent(number, text, type, null, null))) // Create the new Item // { // if (nextItemInfo != null) // Simple case, adding to end of list: // using (Item nextItem = nextItemInfo.Get()) // Get the next item in the list // { // nextItem.MyPrevious = newItem; // Point to the new item // nextItem.Save(); // Save Changes // } // // ToDo: Need change PartInfo in PartInfoList // newItemInfo = ItemInfo.Get(newItem.ItemID); // newItemInfo.ResetOrdinal(); // } // } // return newItemInfo; //} //public ItemInfo InsertChildOld(E_FromType fromType, int type, string text) //{ // return InsertChild(fromType, type, text, null); //} //public ItemInfo InsertChildOld(E_FromType fromType, int type, string text, string number) //{ // ItemInfo newItemInfo = null; // using (Item thisItem = Get()) // Get the Current Item // { // using (Item newItem = Item.MakeItem(null, Content.MakeContent(number, text, type, null, null))) // Create the new Item // { // PartInfo partInfo = MyContent.ContentParts == null ? null : MyContent.ContentParts.Find(fromType); // if (partInfo != null) // { // //this could be equivalent to adding a sibling with a specific type // using (Part part = partInfo.Get()) // { // part.MyItem.MyPrevious = newItem; // part.MyItem.Save(); // part.MyItem = newItem; // part.Save(); // } // } // else // { // // This means that a part needs to be added to point to the new item // //using (Part part = Part.MakePart(thisItem.MyContent, )) // //{ ;} // thisItem.MyContent.ContentParts.Add((int)fromType, newItem); // thisItem.Save(); // } // newItemInfo = ItemInfo.Get(newItem.ItemID); // } // } // ResetParts(); // return newItemInfo; //} #endregion #region Events public event ItemInfoEvent BeforeDelete; public void OnBeforeDelete() { OnBeforeDelete(ItemID); if (MyContent.ContentPartCount > 0) { foreach (PartInfo pi in MyContent.ContentParts) { foreach (ItemInfo ii in pi.MyItems) { ii.OnBeforeDelete(); } } } //if (ItemPartCount > 0) //{ // foreach (PartInfo pi in ItemParts) // { // foreach (ItemInfo ii in pi.MyItems) // { // ii.OnBeforeDelete(); // } // } //} } private void OnBeforeDelete(int ItemID) { if (_CacheByPrimaryKey.ContainsKey(ItemID.ToString())) { List itmlst = _CacheByPrimaryKey[ItemID.ToString()]; foreach (ItemInfo itm in itmlst) if (itm.BeforeDelete != null) { itm.BeforeDelete(itm); } } } public static event ItemInfoEvent ItemDeleted; public event ItemInfoEvent Deleted; internal void OnDeleted(object sender) { if (Deleted != null) Deleted(sender); if (ItemDeleted != null) ItemDeleted(sender); if (MyParent != null) { MyParent.OnChildrenDeleted(sender); MyParent.MyContent.RefreshContentParts(); } } //internal void OnDeleted(object sender, Volian.Base.Library.VlnTimer tmr) //{ //tmr.ActiveProcess = "Deleted"; //if (Deleted != null) Deleted(sender); //tmr.ActiveProcess = "ItemDeleted"; //if (ItemDeleted != null) ItemDeleted(sender); //if (MyParent != null) //{ //tmr.ActiveProcess = "OnChildrenDeleted"; //MyParent.OnChildrenDeleted(sender); //tmr.ActiveProcess = "RefreshContentParts"; //MyParent.MyContent.RefreshContentParts(); //} //} public event ItemInfoEvent ChildrenDeleted; internal void OnChildrenDeleted(object sender) { if (_CacheByPrimaryKey.ContainsKey(ItemID.ToString())) { List itmlst = _CacheByPrimaryKey[ItemID.ToString()]; foreach (ItemInfo itm in itmlst) if (itm.ChildrenDeleted != null) { itm.ChildrenDeleted(itm); } } } public event ItemInfoInsertEvent NewSiblingAfter; internal void OnNewSiblingAfter(object sender, ItemInfoInsertEventArgs args) { if (NewSiblingAfter != null) NewSiblingAfter(sender,args); if (MyParent != null) MyParent.MyContent.RefreshContentParts(); } internal void OnNewSiblingAfter(ItemInfoInsertEventArgs args) { string key = ItemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) { ItemInfo[] items = _CacheByPrimaryKey[key].ToArray(); foreach (ItemInfo item in items) { item.OnNewSiblingAfter(item,args); } } } public event ItemInfoInsertEvent NewSiblingBefore; internal void OnNewSiblingBefore(object sender, ItemInfoInsertEventArgs args) { if (NewSiblingBefore != null) NewSiblingBefore(sender,args); if (MyParent != null) MyParent.MyContent.RefreshContentParts(); } internal void OnNewSiblingBefore(ItemInfoInsertEventArgs args) { string key = ItemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) { ItemInfo[] items = _CacheByPrimaryKey[key].ToArray(); foreach (ItemInfo item in items) { item.OnNewSiblingBefore(item,args); } } } public event ItemInfoInsertEvent NewChild; internal void OnNewChild(object sender, ItemInfoInsertEventArgs args) { if (NewChild != null) NewChild(sender, args); MyContent.RefreshContentParts(); } internal void OnNewChild(ItemInfoInsertEventArgs args) { string key = ItemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) { ItemInfo[] items = _CacheByPrimaryKey[key].ToArray(); foreach (ItemInfo item in items) { item.OnNewChild(item, args); } } } #endregion #region Insert Before public ItemInfo InsertSiblingBefore(string text) { return InsertSiblingBefore(text, null); } public ItemInfo InsertSiblingBefore(string text, string number) { return InsertSiblingBefore(text, number, null); } public ItemInfo InsertSiblingBefore(string text, string number,int? type) { ItemInfo tmp = null; if (!IsSection && (FormatStepData.UseSmartTemplate || (MyHLS!=null && MyHLS.FormatStepData.UseSmartTemplate) || FormatStepData.UseOldTemplate)) tmp = InsertSmartTemplateSteps(text, number, tmp, EAddpingPart.Before, (int)MyContent.Type); if (tmp == null) tmp = NewItemInfoFetch(ItemID, EAddpingPart.Before, number, text, type, null, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); // this item is updated in SQL so we have to manually force the iteminfo updates // Refresh ItemInfo to update Previous using (Item item = Get()) ItemInfo.Refresh(item); // Update all of the content records that have transitions that point to the Siblings or Sibling Children of the new item tmp.UpdateTransitionText(); tmp.UpdateROText(); OnNewSiblingBefore(new ItemInfoInsertEventArgs(tmp, EAddpingPart.Before)); ((ItemInfo)ActiveParent).MyContent.RefreshContentParts(); return tmp; } private ItemInfo InsertSmartTemplateSubStep(string text, string number, ItemInfo tmp, EAddpingPart adPart, int type, E_FromType fromTypeTop) { int newItemID = 0; int topType = GetSmartTemplateTopLevelIndxOfThisType(type); if (topType == -1) return null; int tpIndx = GetSmartTemplateIndex(topType, type); if (tpIndx != -1) { ItemInfo siblingSmart = null; ItemInfo firstSmart = null; int level = ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level; string tmptext = ActiveFormat.PlantFormat.FormatData.NewTemplateFormat ? text : ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].text; int prevlevel = level; while (level > 0) { if (firstSmart == null) { firstSmart = NewItemInfoFetch(ItemID, adPart, number, tmptext, type, (int ?)fromTypeTop, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); //firstSmart = NewItemInfoFetch(ItemID, adPart, number, tmptext, type, null, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); siblingSmart = firstSmart; newItemID = firstSmart.ItemID; } else { E_FromType fromType = E_FromType.Step; EAddpingPart addPart = EAddpingPart.Child; // level > previous, add a child. if (level == prevlevel) addPart = EAddpingPart.After; if (level < prevlevel) { if (ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type == 39) { fromType = E_FromType.RNO; addPart = EAddpingPart.Child; } else { addPart = EAddpingPart.After; } newItemID = siblingSmart.ItemID; } tmptext = /*ActiveFormat.PlantFormat.FormatData.NewTemplateFormat ? " ": */ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].text; tmp = NewItemInfoFetch(newItemID, addPart, null, tmptext, ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type + 20001, (int?)fromType, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); newItemID = tmp.ItemID; if (level < prevlevel) siblingSmart = tmp; } tpIndx++; prevlevel = level; level = tpIndx < ActiveFormat.PlantFormat.FormatData.Templates.Count ? ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level : -1; } tmp = firstSmart; } return tmp; } private ItemInfo InsertSmartTemplateSteps(string text, string number, ItemInfo tmp, EAddpingPart adPart, int type) { int newItemID = 0; int topType = GetSmartTemplateTopLevelIndx(); if (topType == -1) return null; int tpIndx = GetSmartTemplateIndex(topType, (int)MyContent.Type); if (tpIndx != -1) { ItemInfo siblingSmart = null; // keep track of sibling ItemInfo firstSmart = null; // hls or top template step ItemInfo parentSmart = null; // keep track of parent as creating children int level = ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level; string tmptext = ActiveFormat.PlantFormat.FormatData.NewTemplateFormat ? text : ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].text; int prevlevel = level; while (level > 0) { if (firstSmart == null) { firstSmart = NewItemInfoFetch(ItemID, adPart, number, tmptext, type, null, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); siblingSmart = parentSmart = firstSmart; newItemID = firstSmart.ItemID; } else { E_FromType fromType = E_FromType.Step; EAddpingPart addPart = EAddpingPart.Child; // level > previous, add a child. if (level == prevlevel) addPart = EAddpingPart.After; // level = previous, add a sibling if (level < prevlevel) // level < previous, go up to previous level's id { if (ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type == 39) { fromType = E_FromType.RNO; addPart = EAddpingPart.Child; newItemID = firstSmart.ItemID; } else { addPart = EAddpingPart.After; newItemID = parentSmart.ItemID; } } tmptext = ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].text; tmp = NewItemInfoFetch(newItemID, addPart, null, tmptext, ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type + 20001, (int?)fromType, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); newItemID = tmp.ItemID; if (level < prevlevel) siblingSmart = parentSmart; else if (level > prevlevel) parentSmart = siblingSmart; if (level == prevlevel) siblingSmart = tmp; } tpIndx++; prevlevel = level; level = tpIndx < ActiveFormat.PlantFormat.FormatData.Templates.Count ? ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level : -1; } tmp = firstSmart; } return tmp; } #endregion #region PasteChangeId public static void PasteSetChangeId(ItemInfo ii, string chgid) { if (!ii.ActiveFormat.PlantFormat.FormatData.ProcData.ChangeBarData.ChangeIds) return; if (ii.IsProcedure) { return; // copy over change bars & change ids as they exist. } else if (ii.IsSection) { // don't save change id for section. DON'T return though because code below sets // change ids for steps within section. } else if (ii.IsStep) { StepConfig sc = ii.MyConfig as StepConfig; if (chgid != null && sc.Step_ChangeID != chgid) { sc.Step_ChangeID = chgid; using (Item itm = ii.Get()) { itm.MyContent.Config = sc.ToString(); itm.MyContent.DTS = DateTime.Now; itm.MyContent.UserID = Volian.Base.Library.VlnSettings.UserID; itm.Save(); } } } // handle all of the children if (ii.Cautions != null) foreach (ItemInfo chldc in ii.Cautions) PasteSetChangeId(chldc, chgid); if (ii.Notes != null) foreach (ItemInfo chldn in ii.Notes) PasteSetChangeId(chldn, chgid); if (ii.RNOs != null) foreach (ItemInfo chldr in ii.RNOs) PasteSetChangeId(chldr, chgid); if (ii.Tables != null) foreach (ItemInfo chldt in ii.Tables) PasteSetChangeId(chldt, chgid); if (ii.Sections != null) foreach (ItemInfo chldsc in ii.Sections) PasteSetChangeId(chldsc, chgid); if (ii.Steps != null) foreach (ItemInfo chlds in ii.Steps) PasteSetChangeId(chlds, chgid); } #endregion #region Paste public ItemInfo PasteChild(int copyStartID, string chgid) { // To determine 'type' of pasted item, if it's a step (type >=20000), use the originating // item, i.e. item inserting after. If it's a section or procedure, use the copied item's type. ItemInfo cpItem = ItemInfo.Get(copyStartID); int? type = MyContent.Type >= 20000 ? MyContent.Type : cpItem.MyContent.Type; int? fromtype = MyContent.Type >= 20000 ? MyContent.Type : ((int?)(IsProcedure ? E_FromType.Section : (cpItem.IsSection ? E_FromType.Section : E_FromType.Step))); try { ItemInfo tmp = CopyPasteItemInfoFetch(copyStartID, this.ItemID, type, fromtype, EAddpingPart.Child); using (Item item = Get()) ItemInfo.Refresh(item); if (tmp.NextItem != null) using (Item item = tmp.NextItem.Get()) ItemInfo.Refresh(item); RefreshNextItems(); tmp.UpdateTransitionText(); tmp.UpdatePastedStepTransitionText(); PasteSetChangeId(tmp, chgid); OnNewChild(new ItemInfoInsertEventArgs(tmp, EAddpingPart.Child)); return tmp; } catch (Exception ex) { if (!HandleSqlExceptionOnCopy(ex)) System.Windows.Forms.MessageBox.Show("Details were written to the Error Log.", "Paste Failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return this; } } public ItemInfo PasteSiblingBefore(int copyStartID, string chgid) { // To determine 'type' of pasted item, if it's a step (type >=20000), use the originating // item, i.e. item inserting after. If it's a section or procedure, use the copied item's type. ItemInfo cpItem = ItemInfo.Get(copyStartID); int? type = MyContent.Type >= 20000 ? MyContent.Type : cpItem.MyContent.Type; try { ItemInfo tmp = CopyPasteItemInfoFetch(copyStartID, this.ItemID, type, type, EAddpingPart.Before); using (Item item = Get()) ItemInfo.Refresh(item); tmp.UpdateTransitionText(); tmp.UpdateROText(); tmp.UpdatePastedStepTransitionText(); PasteSetChangeId(tmp, chgid); OnNewSiblingBefore(new ItemInfoInsertEventArgs(tmp, EAddpingPart.Before)); return tmp; } catch (Exception ex) { if (!HandleSqlExceptionOnCopy(ex)) System.Windows.Forms.MessageBox.Show("Details were written to the Error Log.","Paste Failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return this; } } public ItemInfo PasteSiblingAfter(int copyStartID, string chgid) { // To determine 'type' of pasted item, if it's a step (type >=20000), use the originating // item, i.e. item inserting after. If it's a section or procedure, use the copied item's type. ItemInfo cpItem = ItemInfo.Get(copyStartID); int? type = MyContent.Type >= 20000 ? MyContent.Type : cpItem.MyContent.Type; try { ItemInfo tmp = CopyPasteItemInfoFetch(copyStartID, this.ItemID, type, type, EAddpingPart.After); using (Item item = Get()) ItemInfo.Refresh(item); if (tmp.NextItem != null) using (Item item = tmp.NextItem.Get()) ItemInfo.Refresh(item); RefreshNextItems(); // if inserting after a caution or note, refreshes tabs. This will adjust bullets // of any previous cautions or notes. if (tmp.IsCaution || tmp.IsNote) ResetOrdinal(); tmp.UpdateTransitionText(); tmp.UpdateROText(); tmp.UpdatePastedStepTransitionText(); PasteSetChangeId(tmp, chgid); OnNewSiblingAfter(new ItemInfoInsertEventArgs(tmp, EAddpingPart.After)); return tmp; } catch (Exception ex) { if(!HandleSqlExceptionOnCopy(ex)) System.Windows.Forms.MessageBox.Show("Details were written to the Error Log.", "Paste Failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return this; } } private bool HandleSqlExceptionOnCopy(Exception ex) { if (ex.Message.Contains("Collection was modified;")) { _MyLog.WarnFormat(ex.Message); return true; } if (ex.Message.Contains("This step has been deleted")) { System.Windows.Forms.MessageBox.Show("The step being pasted has been deleted!", "Cannot Paste Deleted Step" , System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Hand); return true; } if(ex.Message.Contains("This current step has been deleted in another session")) { System.Windows.Forms.MessageBox.Show("The highlighted step has been deleted by another user!", "Cannot Paste Step" , System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Hand); return true; } return false; } private ItemInfo CopyPasteItemInfoFetch(int copyStartID, int itemID, int? type, int? fromType, EAddpingPart addType) { ItemInfo tmp=null; if (addType == EAddpingPart.Child) // has to add in child relationship - uses 'fromtype' { // adding children. Type is based on 'fromType' switch ((E_FromType)fromType) { case E_FromType.Procedure: tmp = DataPortal.Fetch(new PastingPartCriteria(copyStartID, itemID, addType, type, fromType, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); break; case E_FromType.Section: tmp = DataPortal.Fetch(new PastingPartCriteria(copyStartID, itemID, addType, type, fromType, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); break; default: tmp = DataPortal.Fetch(new PastingPartCriteria(copyStartID, itemID, addType, type, fromType, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); break; } } else { if (GetType() == typeof(ProcedureInfo) || MyContent.Type < 10000) tmp = DataPortal.Fetch(new PastingPartCriteria(copyStartID, itemID, addType, type, fromType, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); else if (GetType() == typeof(SectionInfo) || (MyContent.Type < 20000)) tmp = DataPortal.Fetch(new PastingPartCriteria(copyStartID, itemID, addType, type, fromType, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); else tmp = DataPortal.Fetch(new PastingPartCriteria(copyStartID, itemID, addType, type, fromType, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); } AddToCache(tmp); return tmp; } #endregion #region Insert After public ItemInfo InsertSiblingAfter(string text) { return InsertSiblingAfter(text, null); } public ItemInfo InsertSiblingAfter(string text, string number) { return InsertSiblingAfter(text, number, MyContent.Type); } public ItemInfo InsertSiblingAfter(string text, string number, int? type) { ItemInfo tmp = null; if (!IsSection && (FormatStepData.UseSmartTemplate || (MyHLS != null && MyHLS.FormatStepData.UseSmartTemplate) || FormatStepData.UseOldTemplate)) tmp = InsertSmartTemplateSteps(text, number, tmp, EAddpingPart.After, (int)MyContent.Type); if (tmp == null) tmp = NewItemInfoFetch(ItemID, EAddpingPart.After, number, text, type, null, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); // if next exists, it is updated in SQL so we have to manually force the iteminfo updates // Refresh ItemInfo to update PreviousID field if (tmp.NextItem != null) using (Item item = tmp.NextItem.Get()) ItemInfo.Refresh(item); RefreshNextItems(); // if inserting after a caution or note, refreshes tabs. This will adjust bullets // of any previous cautions or notes. if (tmp.IsCaution || tmp.IsNote) ResetOrdinal(); // Update all of the content records that have transitions that point to the Siblings or Sibling Children of the new item tmp.UpdateTransitionText(); tmp.UpdateROText(); OnNewSiblingAfter(new ItemInfoInsertEventArgs(tmp, EAddpingPart.After)); return tmp; } private ItemInfo NewItemInfoFetch(int itemID, EAddpingPart addType, string number, string text, int? type, int? fromType, int? formatID, string config, DateTime dts, string userID) { ItemInfo tmp; if (addType == EAddpingPart.Child) { // adding children. Type is based on 'fromType' switch ((E_FromType)fromType) { case E_FromType.Procedure: tmp = DataPortal.Fetch(new AddingPartCriteria(itemID, addType, number, text, type, fromType, formatID, config, dts, userID)); break; case E_FromType.Section: tmp = DataPortal.Fetch(new AddingPartCriteria(itemID, addType, number, text, type, fromType, formatID, config, dts, userID)); break; default: tmp = DataPortal.Fetch(new AddingPartCriteria(itemID, addType, number, text, type, fromType, formatID, config, dts, userID)); break; } } else { if (GetType() == typeof(ProcedureInfo)) tmp = DataPortal.Fetch(new AddingPartCriteria(itemID, addType, number, text, type, fromType, formatID, config, dts, userID)); else if (GetType() == typeof(SectionInfo)) tmp = DataPortal.Fetch(new AddingPartCriteria(itemID, addType, number, text, type, fromType, formatID, config, dts, userID)); else tmp = DataPortal.Fetch(new AddingPartCriteria(itemID, addType, number, text, type, fromType, formatID, config, dts, userID)); } AddToCache(tmp); return tmp; } public void UpdateTransitionText() { // Update Ordinals from here down for Steps //if (!IsStep) return; ResetOrdinal(); // This returns a list of all of the transitions that may have been affected using(TransitionInfoList trans = TransitionInfoList.GetAffected(this.ItemID)) { #region B2012-071 fix JCB foreach (TransitionInfo tran in trans) { using (Transition trn = tran.Get()) TransitionInfo.Refresh(trn); Content oldContent = null; using (Content content = tran.MyContent.Get()) { if (oldContent != null && content.ContentID != oldContent.ContentID) { if (oldContent.IsDirty) { oldContent.DTS = DateTime.Now; #region B2012-079 fix JCB oldContent.UserID = Volian.Base.Library.VlnSettings.UserID + " - Renumber"; #endregion B2012-079 fix JCB oldContent.Save(); } else // Update ContentInfo objects to reflect the change in the transition ContentInfo.Refresh(oldContent); oldContent = content; } if (oldContent == null) oldContent = content; //check to see if noneditable bool forceConvertToText = false; if (tran.MyItemToID.ActiveSection != null) { SectionConfig sc = tran.MyItemToID.ActiveSection.MyConfig as SectionConfig; //SectionConfig sc = new SectionConfig(tran.MyItemToID.ActiveSection.MyConfig.ToString()); forceConvertToText = (sc.SubSection_Edit == "N"); } if (!forceConvertToText) //check to see if external with internal format { if (tran.MyContent.ContentItems[0].MyProcedure.ItemID != tran.MyItemToID.MyProcedure.ItemID) if (!tran.MyContent.ContentItems[0].ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[tran.TranType].TransMenu.Contains("Proc")) forceConvertToText = true; } oldContent.FixTransitionText(tran, forceConvertToText); //if (content.IsDirty) //{ // content.DTS = DateTime.Now; // content.Save(); //} if (oldContent != null) { if (oldContent.IsDirty) { oldContent.DTS = DateTime.Now; #region B2012-079 fix JCB oldContent.UserID = Volian.Base.Library.VlnSettings.UserID + " - Renumber"; #endregion B2012-079 fix JCB oldContent.Save(); } else // Update ContentInfo objects to reflect the change in the transition ContentInfo.Refresh(oldContent); } } } #endregion B2012-071 fix JCB } } public void UpdatePastedStepTransitionText() { // Get a list of all of the transitions included in this step & its children. // Their transition text may have been affected, i.e. depending on the format, etc using (TransitionInfoList trans = TransitionInfoList.GetPastedAffected(this.ItemID)) { foreach (TransitionInfo tran in trans) { using (Content content = tran.MyContent.Get()) { //check to see if noneditable bool forceConvertToText = false; if (tran.MyItemToID.ActiveSection != null) { SectionConfig sc = tran.MyItemToID.ActiveSection.MyConfig as SectionConfig; //SectionConfig sc = new SectionConfig(tran.MyItemToID.ActiveSection.MyConfig.ToString()); forceConvertToText = (sc.SubSection_Edit == "N"); } if (!forceConvertToText) //check to see if external with internal format { if (tran.MyContent.ContentItems[0].MyProcedure.ItemID != tran.MyItemToID.MyProcedure.ItemID) if (!tran.MyContent.ContentItems[0].ActiveFormat.PlantFormat.FormatData.TransData.TransTypeList[tran.TranType].TransMenu.Contains("Proc")) forceConvertToText = true; } if (!forceConvertToText) { if (tran.MyContent.ContentItems[0].MyDocVersion.VersionID != tran.MyItemToID.MyDocVersion.VersionID) forceConvertToText = true; } content.FixTransitionText(tran, forceConvertToText); if (content.IsDirty) content.Save(); else // Update ContentInfo objects to reflect the change in the transition ContentInfo.Refresh(content); } } } } #endregion #region Insert Child public ItemInfo InsertChild(E_FromType fromType, int type, string text) { return InsertChild(fromType, type, text, null); } public ItemInfo InsertChild(E_FromType fromType, int type, string text, string number) { ItemInfo tmp = null; tmp = InsertSmartTemplateSubStep(text, number, tmp, EAddpingPart.Child, type, fromType); //tmp = InsertSmartTemplateSubStep(text, number, tmp, EAddpingPart.After, type); if (tmp == null) tmp = NewItemInfoFetch(ItemID, EAddpingPart.Child, number, text, type, (int?)fromType, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); // if next exists, it is updated in SQL so we have to manually force the iteminfo updates // Refresh ItemInfo to update PreviousID field if (tmp.NextItem != null) using (Item item = tmp.NextItem.Get()) ItemInfo.Refresh(item); // Update all of the content records that have transitions that point to the Siblings or Sibling Children of the new item tmp.UpdateTransitionText(); tmp.UpdateROText(); MyContent.RefreshContentParts(); OnNewChild(new ItemInfoInsertEventArgs(tmp, EAddpingPart.Child)); return tmp; } #endregion #region Enhanced Document Support public ItemInfo DoAddEnhancedSteps(int enhType, int enhItemID, EAddpingPart addpart) { // get the item object in the enhanced document so that inserting of the new enhanced item and // its children can be done: ItemInfo existingEnhancedItemInfo = ItemInfo.Get(enhItemID); ItemInfo newEnhancedItemInfo = existingEnhancedItemInfo.InsertEnhancedSteps(MyContent.Text, null, addpart, MyContent.Type, enhType, ItemID); if (newEnhancedItemInfo == null) return null; StepConfig sc = new StepConfig(MyContent.Config); sc.AddEnhancedDocument(enhType, newEnhancedItemInfo.ItemID); SaveConfig(sc.ToString()); return newEnhancedItemInfo; } public ItemInfo InsertEnhancedSteps(string text, string number, EAddpingPart addType, int? type, int eDocType, int newSourceID) { ItemInfo tmp = null; if (addType == EAddpingPart.Child) { E_FromType fromType = E_FromType.Caution; if (this.IsSection) fromType = E_FromType.Step; else if (ActiveFormat.PlantFormat.FormatData.StepDataList[(int)type - 20000].Type.ToUpper() == "NOTE") fromType = E_FromType.Note; tmp = InsertEnhancedSmartTemplateSubStep(text, number, this, addType, (int)type, fromType, newSourceID); } else tmp = InsertEnhancedSmartTemplateSteps(text, number, this, addType, 20002, newSourceID); if (tmp == null) return null; // if next exists, it is updated in SQL so we have to manually force the iteminfo updates // Refresh ItemInfo to update PreviousID field if (tmp.NextItem != null) using (Item item = tmp.NextItem.Get()) ItemInfo.Refresh(item); RefreshNextItems(); // if inserting after a caution or note, refreshes tabs. This will adjust bullets // of any previous cautions or notes. if (tmp.IsCaution || tmp.IsNote) ResetOrdinal(); tmp.UpdateTransitionText(); // even though enhanced does not have transitions, this is needed to refresh tabs // Note that non-enhanced update transition and ro text at this point. But since // transitions and ro's are converted to text, this is not needed. if (addType == EAddpingPart.Child) OnNewChild(new ItemInfoInsertEventArgs(tmp, EAddpingPart.Child)); else if (addType == EAddpingPart.After) { OnNewSiblingAfter(new ItemInfoInsertEventArgs(tmp, EAddpingPart.After)); } else if (addType == EAddpingPart.Before) OnNewSiblingBefore(new ItemInfoInsertEventArgs(tmp, EAddpingPart.Before)); return tmp; } private ItemInfo InsertEnhancedSmartTemplateSubStep(string text, string number, ItemInfo tmp, EAddpingPart addType, int type, E_FromType fromTypeTop, int newSourceID) { int newItemID = 0; int topType = GetSmartTemplateTopLevelIndxOfThisType(type); if (topType == -1) return null; int tpIndx = GetSmartTemplateIndex(topType, type); if (tpIndx != -1) { ItemInfo siblingSmart = null; ItemInfo firstSmart = null; int level = ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level; string tmptext = ActiveFormat.PlantFormat.FormatData.NewTemplateFormat ? text : ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].text; int prevlevel = level; while (level > 0) { if (firstSmart == null) { StepConfig sc = new StepConfig(""); sc.AddEnhancedDocument(0, newSourceID); firstSmart = NewItemInfoFetch(ItemID, addType, number, tmptext, type, (int?)fromTypeTop, null, sc.ToString(), DateTime.Now, Volian.Base.Library.VlnSettings.UserID); siblingSmart = firstSmart; newItemID = firstSmart.ItemID; } else { E_FromType fromType = E_FromType.Step; EAddpingPart addPart = EAddpingPart.Child; // level > previous, add a child. if (level == prevlevel) addPart = EAddpingPart.After; if (level < prevlevel) { if (ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type == 39) { fromType = E_FromType.RNO; addPart = EAddpingPart.Child; } else { addPart = EAddpingPart.After; } newItemID = siblingSmart.ItemID; } tmptext = /*ActiveFormat.PlantFormat.FormatData.NewTemplateFormat ? " ": */ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].text; tmp = NewItemInfoFetch(newItemID, addPart, null, tmptext, ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type + 20001, (int?)fromType, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); newItemID = tmp.ItemID; if (level < prevlevel) siblingSmart = tmp; } tpIndx++; prevlevel = level; level = tpIndx < ActiveFormat.PlantFormat.FormatData.Templates.Count ? ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level : -1; } tmp = firstSmart; } return tmp; } private ItemInfo InsertEnhancedSmartTemplateSteps(string text, string number, ItemInfo tmp, EAddpingPart eAddpingPart, int type, int newSourceID) { int newItemID = 0; int topType = GetSmartTemplateTopLevelIndx(); if (topType == -1) return null; int tpIndx = GetSmartTemplateIndex(topType, (int)MyContent.Type); if (tpIndx != -1) { ItemInfo siblingSmart = null; // keep track of sibling ItemInfo firstSmart = null; // hls or top template step ItemInfo parentSmart = null; // keep track of parent as creating children int level = ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level; string tmptext = text; int prevlevel = level; while (level > 0) { if (firstSmart == null) { // set stepconfig for this new enhanced item: StepConfig sc = new StepConfig(""); sc.AddEnhancedDocument(0, newSourceID); firstSmart = NewItemInfoFetch(ItemID, eAddpingPart, number, tmptext, type, null, null, sc.ToString(), DateTime.Now, Volian.Base.Library.VlnSettings.UserID); siblingSmart = parentSmart = firstSmart; newItemID = firstSmart.ItemID; } else { E_FromType fromType = E_FromType.Step; EAddpingPart addPart = EAddpingPart.Child; // level > previous, add a child. if (level == prevlevel) addPart = EAddpingPart.After; // level = previous, add a sibling if (level < prevlevel) // level < previous, go up to previous level's id { if (ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type == 39) { fromType = E_FromType.RNO; addPart = EAddpingPart.Child; newItemID = firstSmart.ItemID; } else { addPart = EAddpingPart.After; newItemID = parentSmart.ItemID; } } tmptext = ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].text; tmp = NewItemInfoFetch(newItemID, addPart, null, tmptext, ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].type + 20001, (int?)fromType, null, null, DateTime.Now, Volian.Base.Library.VlnSettings.UserID); newItemID = tmp.ItemID; if (level < prevlevel) siblingSmart = parentSmart; else if (level > prevlevel) parentSmart = siblingSmart; if (level == prevlevel) siblingSmart = tmp; } tpIndx++; prevlevel = level; level = tpIndx < ActiveFormat.PlantFormat.FormatData.Templates.Count ? ActiveFormat.PlantFormat.FormatData.Templates[tpIndx].level : -1; } tmp = firstSmart; } return tmp; } public ItemInfo EnhancedPasteItem(int copyStartID, ItemInfo pasteFromItem, EAddpingPart addType, string chgid) { EnhancedDocuments pasteFromItemsEnhancedDocuments = pasteFromItem.GetMyEnhancedDocuments(); if (pasteFromItemsEnhancedDocuments == null || pasteFromItemsEnhancedDocuments.Count == 0) return null; ItemInfo newItemInfo = this; ItemInfo newEnhancedItemInfo = null; // need to save the original item ids in the copied item so that they can be // changed to the new enhanced ids in 'config'. The oldid/newid pairs will // be stored in a dictionary & the update will be made after the loop. Dictionary oldToNewEnhancedIds = new Dictionary(); // tmpCopyStartSourceItem is the item that was copied in source. ItemInfo tmpCopyStartSourceItem = ItemInfo.Get(copyStartID); if (tmpCopyStartSourceItem.IsStep) { // if the copied step is not a 'source', then this really needs to be more of an insert for the enhanced steps. StepConfig stepFromCfg = tmpCopyStartSourceItem.MyConfig as StepConfig; if (stepFromCfg.MyEnhancedDocuments == null || stepFromCfg.MyEnhancedDocuments.Count == 0) { // Insert the enhanced steps. Loop through all enhanced document types, insert from // the paste item's linked step. ItemInfo newEnh = null; foreach (EnhancedDocument edSource in pasteFromItem.GetMyEnhancedDocuments()) { // create a new enhanced step and link it to this new source step. // the new source step's item is used to know what type & what to link to. // The ed.Type & ed.itemid show what type of enhanced document (use to create new // config Type). ItemInfo exEnh = ItemInfo.Get(edSource.ItemID); newEnh = exEnh.InsertEnhancedSteps(tmpCopyStartSourceItem.MyContent.Text, null, addType, MyContent.Type, edSource.Type, this.ItemID); if (newEnh == null) return null; StepConfig sc = new StepConfig(MyContent.Config); sc.AddEnhancedDocument(edSource.Type, newEnh.ItemID); SaveConfig(sc.ToString()); } return newEnh; } } // loop through all enhanced document types, pasting in the copied item(s). // Note that the copy/paste finds the enhanced items that relate to source, // i.e. copied item & paste from, and uses those to do the copy/paste. // sc is the config (passed in) for the item that we are pasting around. foreach (EnhancedDocument edSource in pasteFromItem.GetMyEnhancedDocuments()) { if (edSource.Type != 0) { ItemInfo tmpPasteItemFrom = ItemInfo.Get(edSource.ItemID); // here is problem // get the 'enhanced' item to copy. To do this, get the enhanced link // from source's config that matches this 'type'. Use that Id to get the enhanced // Item that is to be copied: int tmpCopyEnhancedID = 0; foreach (EnhancedDocument edCopy in tmpCopyStartSourceItem.GetMyEnhancedDocuments()) { if (edSource.Type == edCopy.Type) { tmpCopyEnhancedID = edCopy.ItemID; break; } } if (tmpCopyEnhancedID == 0) break; // no connected copied item. if (addType == EAddpingPart.Before) newEnhancedItemInfo = tmpPasteItemFrom.PasteSiblingBefore(tmpCopyEnhancedID, chgid); else if (addType == EAddpingPart.After) newEnhancedItemInfo = tmpPasteItemFrom.PasteSiblingAfter(tmpCopyEnhancedID, chgid); else if (addType == EAddpingPart.Child) newEnhancedItemInfo = tmpPasteItemFrom.PasteChild(tmpCopyEnhancedID, chgid); else if (addType == EAddpingPart.Replace) // what about user interface for enhanced pasted steps? { ItemInfo enhReplaceItem = ItemInfo.Get(edSource.ItemID); newEnhancedItemInfo = Item.PasteReplace(enhReplaceItem, tmpCopyEnhancedID, chgid); } // update the config data for the new enhanced item (procedure, section or step) to point back to the correct source string cfgEnhStr = null; if (newEnhancedItemInfo.IsStep) { StepConfig scnewenh = newEnhancedItemInfo.MyConfig as StepConfig; if (scnewenh == null) break; //error here, i.e. should have a related enhanced step scnewenh.MyEnhancedDocuments[0].ItemID = newItemInfo.ItemID; scnewenh.SaveEnhancedDocuments(); cfgEnhStr = scnewenh.ToString(); } else if (newEnhancedItemInfo.IsSection) { SectionConfig secnewenh = newEnhancedItemInfo.MyConfig as SectionConfig; if (secnewenh == null) break; //error here, i.e. should have a related enhanced step secnewenh.MyEnhancedDocuments[0].ItemID = newItemInfo.ItemID; secnewenh.SaveEnhancedDocuments(); cfgEnhStr = secnewenh.ToString(); } else if (newEnhancedItemInfo.IsProcedure) { ProcedureConfig pnewenh = newEnhancedItemInfo.MyConfig as ProcedureConfig; if (pnewenh == null) break; //error here, i.e. should have a related enhanced step pnewenh.MyEnhancedDocuments[0].ItemID = newItemInfo.ItemID; pnewenh.SaveEnhancedDocuments(); cfgEnhStr = pnewenh.ToString(); } if (cfgEnhStr != null) newEnhancedItemInfo.SaveConfig(cfgEnhStr); // save the new enhanced step ids to set in the new source's config (to relate steps) foreach (EnhancedDocument edNew in newItemInfo.GetMyEnhancedDocuments()) { if (edNew.ItemID == tmpCopyEnhancedID) oldToNewEnhancedIds.Add(edNew.ItemID, newEnhancedItemInfo.ItemID); } } } // update the config to point to new enhanced document steps for the new source item if (oldToNewEnhancedIds.Count > 0) { // save the updated config info on the newly pasted source: step, section or procedure: string cfgNewSrc = null; if (newItemInfo.IsStep) { StepConfig scnewpst1 = newItemInfo.MyConfig as StepConfig; foreach (EnhancedDocument edOrig in scnewpst1.MyEnhancedDocuments) edOrig.ItemID = oldToNewEnhancedIds[edOrig.ItemID]; scnewpst1.SaveEnhancedDocuments(); cfgNewSrc = scnewpst1.ToString(); } else if (newItemInfo.IsSection) { SectionConfig secnewpst1 = newItemInfo.MyConfig as SectionConfig; foreach (EnhancedDocument edOrig in secnewpst1.MyEnhancedDocuments) edOrig.ItemID = oldToNewEnhancedIds[edOrig.ItemID]; secnewpst1.SaveEnhancedDocuments(); cfgNewSrc = secnewpst1.ToString(); } else if (newItemInfo.IsProcedure) { ProcedureConfig pnewpst1 = newItemInfo.MyConfig as ProcedureConfig; foreach (EnhancedDocument edOrig in pnewpst1.MyEnhancedDocuments) edOrig.ItemID = oldToNewEnhancedIds[edOrig.ItemID]; pnewpst1.SaveEnhancedDocuments(); cfgNewSrc = pnewpst1.ToString(); } if (cfgNewSrc != null) newItemInfo.SaveConfig(cfgNewSrc); } // if this is a HLS, then need to adjust links between any associated notes/cautions too: if (newItemInfo.IsStep) { StepConfig scForNC = newItemInfo.MyConfig as StepConfig; foreach (EnhancedDocument ed in scForNC.MyEnhancedDocuments) EnhancedSetNoteCautionLinks(newItemInfo, ed.Type); } return newEnhancedItemInfo; } #region HandleEnhancedNoteCautionConfigLinks private static void EnhancedSetNoteCautionLinks(ItemInfo newItemInfo, int enhType) { // For this enhanced document type, adjust all of the ids to link between source & enhanced if there are // notes & cautions. Notes first. There may be some source notes that aren't linked and some enhanced // that are not linked, so account for this. // get the high level enhanced step, this will be used for both note & caution code: ItemInfo enhHls = null; foreach (EnhancedDocument enh in newItemInfo.GetMyEnhancedDocuments()) { if (enh.Type == enhType) { enhHls = ItemInfo.Get(enh.ItemID); break; } } if (newItemInfo.IsHigh && enhHls != null && newItemInfo.Notes != null && newItemInfo.Notes.Count > 0) { int srcIndxNt = 0; int enhIndxNt = 0; // for each note association between the source & enhanced document, update // the config items to link them. ItemInfo srcNtItem = newItemInfo.Notes[srcIndxNt]; while (srcNtItem != null) { StepConfig scSourceNote = newItemInfo.Notes[srcIndxNt].MyConfig as StepConfig; if (scSourceNote.MyEnhancedDocuments.Count > 0) { // Loop through for each enhanced document related to the pasted source HLS foreach (EnhancedDocument enh in srcNtItem.GetMyEnhancedDocuments()) { if (enh.Type == enhType) { // Find hls in enhanced in order to get its notes to set their config to // point back to the new source's note itemid. There may be enhanced items that // don't connect back, so find one that does based on Enhance HLS note list & // the notes' links back to source. ItemInfo enhNtItem = null; while (enhNtItem == null && enhIndxNt < enhHls.Notes.Count) { ItemInfo enhTstNote = enhHls.Notes[enhIndxNt]; StepConfig enhTstNoteCfg = enhTstNote.MyConfig as StepConfig; if (enhTstNoteCfg.MyEnhancedDocuments.Count > 0) { foreach (EnhancedDocument enhNt in enhTstNote.GetMyEnhancedDocuments()) { if (enhNt.Type == 0) // found it: { enhNtItem = enhTstNote; break; } } } if (enhNtItem == null) enhIndxNt++; } if (enhNtItem != null) { StepConfig scNewEnhancedNote = enhNtItem.MyConfig as StepConfig; scNewEnhancedNote.MyEnhancedDocuments[0].ItemID = newItemInfo.Notes[srcIndxNt].ItemID; scNewEnhancedNote.SaveEnhancedDocuments(); enhNtItem.SaveConfig(scNewEnhancedNote.ToString()); foreach (EnhancedDocument noteEnh in scSourceNote.MyEnhancedDocuments) { if (noteEnh.Type == enhType) { noteEnh.ItemID = enhHls.Notes[enhIndxNt].ItemID; scSourceNote.SaveEnhancedDocuments(); newItemInfo.Notes[srcIndxNt].SaveConfig(scSourceNote.ToString()); break; } } enhIndxNt++; } } } } srcIndxNt++; srcNtItem = srcIndxNt>=newItemInfo.Notes.Count?null:newItemInfo.Notes[srcIndxNt]; } } // now do any cautions. if (newItemInfo.IsHigh && newItemInfo.Cautions != null && newItemInfo.Cautions.Count > 0) { int srcIndxCt = 0; int enhIndxCt = 0; // for each caution association between the source & enhanced document, update // the config items to link them. ItemInfo srcCtItem = newItemInfo.Cautions[srcIndxCt]; while (srcCtItem != null) { StepConfig scSourceCaution = newItemInfo.Cautions[srcIndxCt].MyConfig as StepConfig; if (scSourceCaution.MyEnhancedDocuments.Count > 0) { // Loop through for each enhanced document related to the pasted source HLS foreach (EnhancedDocument enh in srcCtItem.GetMyEnhancedDocuments()) { if (enh.Type == enhType) { // Find hls in enhanced in order to get its notes to set their config to // point back to the new source's note itemid. ItemInfo enhCtItem = null; while (enhCtItem == null && enhIndxCt < enhHls.Cautions.Count) { ItemInfo enhTstCaut = enhHls.Cautions[enhIndxCt]; StepConfig enhTstCautCfg = enhTstCaut.MyConfig as StepConfig; if (enhTstCautCfg.MyEnhancedDocuments.Count > 0) { foreach (EnhancedDocument enhCt in enhTstCaut.GetMyEnhancedDocuments()) { if (enhCt.Type == 0) { enhCtItem = enhTstCaut; break; } } } if (enhCtItem == null) enhIndxCt++; } if (enhCtItem != null) { StepConfig scNewEnhancedCaution = enhCtItem.MyConfig as StepConfig; scNewEnhancedCaution.MyEnhancedDocuments[0].ItemID = newItemInfo.Cautions[srcIndxCt].ItemID; scNewEnhancedCaution.SaveEnhancedDocuments(); enhCtItem.SaveConfig(scNewEnhancedCaution.ToString()); foreach (EnhancedDocument cautionEnh in scSourceCaution.MyEnhancedDocuments) { if (cautionEnh.Type == enh.Type) { cautionEnh.ItemID = enhHls.Cautions[enhIndxCt].ItemID; scSourceCaution.SaveEnhancedDocuments(); newItemInfo.Cautions[srcIndxCt].SaveConfig(scSourceCaution.ToString()); break; } } enhIndxCt++; } } } } srcIndxCt++; srcCtItem = srcIndxCt >= newItemInfo.Cautions.Count ? null : newItemInfo.Cautions[srcIndxCt]; } } } #endregion #region HandleEnhancedStepConfigLinks private void EnhancedSetStepLinks(ItemInfo newSourceSectionInfo, int enhType) { //for the input source section, link all HLS to enhanced HLS (and any associated cautions/notes). Note that // this assumes that all source steps are linked, but there may be 'deleted' steps in enhanced that may not be linked back. ItemInfo newEnhSectionInfo = null; ItemInfo enhStep = null; // in enhanced document, find first step that has links (there may be enhanced steps that don't have links) SectionConfig newSectCfg = newSourceSectionInfo.MyConfig as SectionConfig; foreach (EnhancedDocument ed in newSectCfg.MyEnhancedDocuments) { if (ed.Type == enhType) { newEnhSectionInfo = ItemInfo.Get(ed.ItemID); StepConfig cfg = newEnhSectionInfo.Steps[0].MyConfig as StepConfig; if (cfg.MyEnhancedDocuments.Count > 0) enhStep = newEnhSectionInfo.Steps[0]; else enhStep = GetNextEnhancedStep(newEnhSectionInfo.Steps[0]); break; } } if (enhStep == null) return; // now adjust all of the ids to link between source & enhanced for this section's steps. // The enhType represents which enhanced document we are working with, for example, backgrounds or deviations. for (int iStp = 0; iStp < newSourceSectionInfo.Steps.Count; iStp++) { StepConfig scSourceStep = newSourceSectionInfo.Steps[iStp].MyConfig as StepConfig; if (scSourceStep.MyEnhancedDocuments.Count > 0) { // Loop through for each enhanced document related to the pasted source HLS foreach (EnhancedDocument enh in scSourceStep.MyEnhancedDocuments) { if (enh.Type == enhType) { // Find hls in enhanced in order to set the config to point back to the new source's itemid. ItemInfo enhHls = enhStep; StepConfig scNewEnhancedStep = enhHls.MyConfig as StepConfig; scNewEnhancedStep.MyEnhancedDocuments[0].ItemID = newSourceSectionInfo.Steps[iStp].ItemID; scNewEnhancedStep.SaveEnhancedDocuments(); enhHls.SaveConfig(scNewEnhancedStep.ToString()); // set the source to go to this enh. enh.ItemID = enhHls.ItemID; scSourceStep.SaveEnhancedDocuments(); newSourceSectionInfo.Steps[iStp].SaveConfig(scSourceStep.ToString()); EnhancedSetNoteCautionLinks(newSourceSectionInfo.Steps[iStp], enhType); } } } enhStep = GetNextEnhancedStep(enhStep); } } private ItemInfo GetNextEnhancedStep(ItemInfo itemInfo) { if (itemInfo==null) return null; ItemInfo curStep = itemInfo.NextItem; while (curStep != null) { StepConfig cfg = curStep.MyConfig as StepConfig; if (cfg.MyEnhancedDocuments.Count > 0) return curStep; curStep = curStep.NextItem; } return null; } private ItemInfo GetNextEnhancedSection(ItemInfo itemInfo) { if (itemInfo == null) return null; ItemInfo curSect = itemInfo.NextItem; while (curSect != null) { SectionConfig cfg = curSect.MyConfig as SectionConfig; if (cfg.MyEnhancedDocuments.Count > 0) return curSect; curSect = curSect.NextItem; } return null; } #endregion public ItemInfo PasteEnhancedItems(int copyStartID, ItemInfo pasteFromItem, EAddpingPart addType, string chgid) { ItemInfo retItem = null; if (IsProcedure) // newly Pasted Item is a procedure. { // the following pastes each type of enhanced procedure, including its sections/steps EnhancedPasteItem(copyStartID, pasteFromItem, addType, chgid); // for each enhanced type for this procedure, adjust the config data for its sections/steps: ProcedureConfig sourceProcConfig = this.MyConfig as ProcedureConfig; foreach (EnhancedDocument enhProc in sourceProcConfig.MyEnhancedDocuments) { if (enhProc.Type != 0) { ItemInfo pastedEnhancedProc = ItemInfo.Get(enhProc.ItemID); // get the first enhanced section, there may be non-linked sections before first linked section: SectionConfig firstEnhSectionConfig = pastedEnhancedProc.Sections == null ? null : pastedEnhancedProc.Sections[0].MyConfig as SectionConfig; ItemInfo pastedEnhancedCurrentSection = null; if (firstEnhSectionConfig.MyEnhancedDocuments.Count > 0) pastedEnhancedCurrentSection = pastedEnhancedProc.Sections[0]; else pastedEnhancedCurrentSection = GetNextEnhancedSection(pastedEnhancedProc.Sections[0]); // newly pasted procedure has sections/steps, need to adjust 'MyEnhancedDocuments' config items to point to correct if (Sections != null) { foreach (ItemInfo sourceSect in Sections) { SectionConfig srcCfg = sourceSect.MyConfig as SectionConfig; if (srcCfg != null && (srcCfg.Section_LnkEnh=="Y" || srcCfg.Section_LnkEnh=="T") && srcCfg.MyEnhancedDocuments != null && srcCfg.MyEnhancedDocuments.Count > 0) { // use pastedEnhancedCurrentSection to link to: foreach (EnhancedDocument ed in srcCfg.MyEnhancedDocuments) { if (ed.Type == enhProc.Type) { ed.ItemID = pastedEnhancedCurrentSection.ItemID; srcCfg.SaveEnhancedDocuments(); sourceSect.SaveConfig(srcCfg.ToString()); break; } } SectionConfig enhSectCfg = pastedEnhancedCurrentSection.MyConfig as SectionConfig; enhSectCfg.MyEnhancedDocuments[0].ItemID = sourceSect.ItemID; enhSectCfg.SaveEnhancedDocuments(); pastedEnhancedCurrentSection.SaveConfig(enhSectCfg.ToString()); if (srcCfg.Section_LnkEnh == "Y") EnhancedSetStepLinks(sourceSect, enhProc.Type); //if steps, do them for this type pastedEnhancedCurrentSection = GetNextEnhancedSection(pastedEnhancedCurrentSection); } } } } } retItem = null; } else if (IsSection) { ItemInfo pastedSect = EnhancedPasteItem(copyStartID, pasteFromItem, addType, chgid); SectionConfig sourceSectConfig = this.MyConfig as SectionConfig; foreach (EnhancedDocument enhSect in sourceSectConfig.MyEnhancedDocuments) if (enhSect.Type != 0) EnhancedSetStepLinks(this, enhSect.Type); retItem = pastedSect; } else if (pasteFromItem.IsStep || (pasteFromItem.IsSection && addType == EAddpingPart.Child)) { ItemInfo pastedStep = EnhancedPasteItem(copyStartID, pasteFromItem, addType, chgid); retItem = pastedStep; } return retItem; } private void SaveConfig(string cfg) { using (Content c1 = Content.Get(ContentID)) { c1.Config = cfg; c1.Save(); } RefreshConfig(); } #endregion #region DataPortal private void DataPortal_Fetch(PastingPartCriteria criteria) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ItemInfo.DataPortal_Fetch", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { Csla.ApplicationContext.LocalContext["cn"] = cn; using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.Parameters.AddWithValue("@StartItemID", criteria.StartItemID); cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); //ABC After Before Child cm.Parameters.AddWithValue("@Type", criteria.Type); //ABC cm.Parameters.AddWithValue("@DTS", criteria.DTS); //ABC cm.Parameters.AddWithValue("@UserID", criteria.UserID); //ABC SqlParameter param_ContentID = new SqlParameter("@NewItemID", SqlDbType.Int); param_ContentID.Direction = ParameterDirection.Output; cm.Parameters.Add(param_ContentID); switch (criteria.AddType) { case EAddpingPart.Child: cm.CommandText = "PasteItemChild"; cm.Parameters.AddWithValue("@FromType", criteria.FromType); //--C break; case EAddpingPart.Before: cm.CommandText = "PasteItemSiblingBefore"; break; case EAddpingPart.After: cm.CommandText = "PasteItemSiblingAfter"; break; case EAddpingPart.Replace: cm.CommandText = "PasteItemReplace"; break; } cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { //newItemID = (int)cm.Parameters["@newContentID"].Value; if (!dr.Read()) { _ErrorMessage = "No Record Found"; return; } ReadData(dr); } } // removing of item only needed for local data portal if (Csla.ApplicationContext.ExecutionLocation == Csla.ApplicationContext.ExecutionLocations.Client) Csla.ApplicationContext.LocalContext.Remove("cn"); } } catch (Exception ex) { if (!ex.Message.Contains("This step has been deleted") && !ex.Message.Contains("This current step has been deleted in another session")) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemInfo.DataPortal_Fetch", ex); } _ErrorMessage = ex.Message; throw new DbCslaException("ItemInfo.DataPortal_Fetch", ex); } } private void DataPortal_Fetch(AddingPartCriteria criteria) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ItemInfo.DataPortal_Fetch", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { Csla.ApplicationContext.LocalContext["cn"] = cn; using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); //ABC After Before Child cm.Parameters.AddWithValue("@Number", criteria.Number); //ABC cm.Parameters.AddWithValue("@Text", criteria.Text); //ABC cm.Parameters.AddWithValue("@FormatID", criteria.FormatID); //ABC cm.Parameters.AddWithValue("@Config", criteria.Config); //ABC cm.Parameters.AddWithValue("@Type", criteria.Type); //ABC cm.Parameters.AddWithValue("@DTS", criteria.DTS); //ABC cm.Parameters.AddWithValue("@UserID", criteria.UserID); //ABC SqlParameter param_ContentID = new SqlParameter("@newItemID", SqlDbType.Int); param_ContentID.Direction = ParameterDirection.Output; cm.Parameters.Add(param_ContentID); switch (criteria.AddType) { case EAddpingPart.Child: cm.CommandText = "addItemChild"; cm.Parameters.AddWithValue("@FromType", criteria.FromType); //--C break; case EAddpingPart.Before: cm.CommandText = "addItemSiblingBefore"; break; case EAddpingPart.After: cm.CommandText = "addItemSiblingAfter"; break; } cm.CommandTimeout = Database.DefaultTimeout; using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader())) { //newItemID = (int)cm.Parameters["@newContentID"].Value; if (!dr.Read()) { _ErrorMessage = "No Record Found"; return; } ReadData(dr); } } // removing of item only needed for local data portal if (Csla.ApplicationContext.ExecutionLocation == Csla.ApplicationContext.ExecutionLocations.Client) Csla.ApplicationContext.LocalContext.Remove("cn"); } } catch (Exception ex) { if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemInfo.DataPortal_Fetch", ex); _ErrorMessage = ex.Message; throw new DbCslaException("ItemInfo.DataPortal_Fetch", ex); } } #endregion #region PastingPartCriteria [Serializable()] public class PastingPartCriteria { #region Properties private int _StartItemID; public int StartItemID { get { return _StartItemID; } set { _StartItemID = value; } } //private int _CopyEndID; //public int CopyEndID //{ // get { return _CopyEndID; } // set { _CopyEndID = value; } //} private int _ItemID; // paste relative to this itemid public int ItemID { get { return _ItemID; } set { _ItemID = value; } } private EAddpingPart _AddType; public EAddpingPart AddType { get { return _AddType; } set { _AddType = value; } } private int? _FromType = null; public int? FromType { get { return _FromType; } set { _FromType = value; } } private int? _Type = null; public int? Type { get { return _Type; } set { _Type = value; } } private DateTime _DTS; public DateTime DTS { get { return _DTS; } set { _DTS = value; } } private string _UserID; public string UserID { get { return _UserID; } set { _UserID = value; } } #endregion #region Constructor public PastingPartCriteria(int startItemid, int itemID, EAddpingPart addType, int? type, int? fromType, DateTime dts, string userID) { _StartItemID = startItemid; _ItemID = itemID; _AddType = addType; _Type = type; _FromType = fromType; _DTS = dts; _UserID = userID; } #endregion } #endregion [Serializable()] protected class AddingPartCriteria { #region Properties private int _ItemID; public int ItemID { get { return _ItemID; } set { _ItemID = value; } } private EAddpingPart _AddType; public EAddpingPart AddType { get { return _AddType; } set { _AddType = value; } } private string _Number=null; public string Number { get { return _Number; } set { _Number = value; } } private string _Text=null; public string Text { get { return _Text; } set { _Text = value; } } private int? _FromType = null; public int? FromType { get { return _FromType; } set { _FromType = value; } } private int? _Type=null; public int? Type { get { return _Type; } set { _Type = value; } } private int? _FormatID=null; public int? FormatID { get { return _FormatID; } set { _FormatID = value; } } private string _Config=null; public string Config { get { return _Config; } set { _Config = value; } } private DateTime _DTS; public DateTime DTS { get { return _DTS; } set { _DTS = value; } } private string _UserID; public string UserID { get { return _UserID; } set { _UserID = value; } } #endregion #region Constructor public AddingPartCriteria(int itemID, EAddpingPart addType, string number, string text, int? type, int? fromType, int? formatID, string config, DateTime dts, string userID) { _ItemID = itemID; _AddType = addType; _Number = number; _Text = text; _Type = type; _FromType = fromType; _FormatID = formatID; _Config = config; _DTS = dts; _UserID = userID; } #endregion } public enum EAddpingPart { Child=0, Before=1, After=2, Replace=3 } public ItemInfo NextItem { get { if (PrintAllAtOnce) return GetNextItem(); if (NextItemCount > 0 && NextItems != null && NextItems.Count > 0) return NextItems[0]; return null; } } private static void ResetOrdinal(int itemID) { ConvertListToDictionary(); string key = itemID.ToString(); while (key != null && _CacheByPrimaryKey.ContainsKey(key)) { ItemInfo[] items = _CacheByPrimaryKey[key].ToArray(); key = null; foreach (ItemInfo item in items) { item._Ordinal = null; item._TagsSetup = false; //item.MyContent.ShowChange(); // Replaced with OnOrdinalChange below if (key == null && item.NextItem != null) key = item.NextItem.ItemID.ToString(); } ItemInfo.OnOrdinalChange(items[0].ItemID); // After _Ordinal reset trigger event } } public void ResetOrdinal() { ResetOrdinal(ItemID); } public static void DeleteItemInfoAndChildren(int itemID) { //Volian.Base.Library.VlnTimer _MyTimer = new Volian.Base.Library.VlnTimer(); //_MyTimer.ActiveProcess = "ConvertListToDictionary"; ConvertListToDictionary(); string key = itemID.ToString(); if(_CacheByPrimaryKey.ContainsKey(key)) { ItemInfo [] items = _CacheByPrimaryKey[key].ToArray(); ItemInfo parent = items[0].ActiveParent as ItemInfo; //_MyTimer.ActiveProcess = "ResetParts"; if (parent != null) ItemInfo.ResetParts(parent.ItemID); //Console.WriteLine("\r\n\r\n'Deleting Item {0}'\r\n{0}'Type ','ParentID','ParentUnique','ItemID','Unique'",itemID); foreach (ItemInfo item in items) { //_MyTimer.ActiveProcess = "IsDeleted"; item.IsDeleted = true; //_MyTimer.ActiveProcess = string.Format("OnDeleted {0}", items.Length); item.OnDeleted(item); //item.OnDeleted(item, _MyTimer); //_MyTimer.ActiveProcess = "DeleteItemInfoAndChildren"; item.DeleteItemInfoAndChildren(" "); } //Console.WriteLine("\r\n'Item Deleted'"); } //_MyTimer.ShowElapsedTimes("DeleteItemInfoAndChildren"); } private void DeleteItemInfoAndChildren(string depth) { if (MyContent.LocalContentParts != null) { foreach (PartInfo part in MyContent.LocalContentParts) { if (part._MyItems != null) { int whereami = 1; try { List items = new List(); foreach (ItemInfo item in part._MyItems) { items.Add(item); } foreach (ItemInfo item in items) { string key = item.ItemID.ToString(); if (_CacheByPrimaryKey.ContainsKey(key)) { ItemInfo[] itemz = _CacheByPrimaryKey[key].ToArray(); foreach (ItemInfo itm in itemz) { //Console.WriteLine("'{0}cache ',{1},{2},{3},{4}", depth + depth, this.ItemID, this._MyItemInfoUnique, itm.ItemID, itm._MyItemInfoUnique); //whereami = 2; itm.OnDeleted(itm); //whereami = 4; itm.DeleteItemInfoAndChildren(depth + " "); //whereami = 3; } } else { //Console.WriteLine("'{0}noncache',{1},{2},{3},{4}", depth + depth, this.ItemID, this._MyItemInfoUnique, item.ItemID, item._MyItemInfoUnique); //whereami = 5; item.OnDeleted(item); //whereami = 7; item.DeleteItemInfoAndChildren(depth + " "); //whereami = 6; } } } catch (Exception ex) { Console.WriteLine("where = {0}, type = {1}, msg = {2}", whereami, ex.GetType().Name, ex.Message); } } } } Dispose(); } public static void RefreshPrevious(int? itemID, int? previousID) { if (itemID == null) return; string key = itemID.ToString(); ConvertListToDictionary(); if (_CacheByPrimaryKey.ContainsKey(key)) foreach (ItemInfo tmpInfo in _CacheByPrimaryKey[key]) tmpInfo.RefreshPrevious(previousID); } private void RefreshPrevious(int? previousID) { if (_PreviousID != previousID) { if (MyPrevious != null) MyPrevious.RefreshNextItems(); // Update List for old value _PreviousID = previousID; // Update the value } _MyPrevious = null; // Reset list so that the next line gets a new list if (MyPrevious != null) MyPrevious.RefreshNextItems(); // Update List for new value } internal static ItemInfo CopyPasteReplaceItemInfoFetch(int copyStartID, ItemInfo itemInfo) // int itemID, int? type, int? fromType) { ItemInfo tmp = null; if (itemInfo.GetType() == typeof(ProcedureInfo) || itemInfo.MyContent.Type < 10000) tmp = DataPortal.Fetch(new ItemInfo.PastingPartCriteria(copyStartID, itemInfo.ItemID, ItemInfo.EAddpingPart.Replace, itemInfo.MyContent.Type, itemInfo.MyContent.Type, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); else if (itemInfo.GetType() == typeof(SectionInfo) || itemInfo.MyContent.Type < 20000) tmp = DataPortal.Fetch(new ItemInfo.PastingPartCriteria(copyStartID, itemInfo.ItemID, ItemInfo.EAddpingPart.Replace, itemInfo.MyContent.Type, itemInfo.MyContent.Type, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); else tmp = DataPortal.Fetch(new ItemInfo.PastingPartCriteria(copyStartID, itemInfo.ItemID, ItemInfo.EAddpingPart.Replace, itemInfo.MyContent.Type, itemInfo.MyContent.Type, DateTime.Now, Volian.Base.Library.VlnSettings.UserID)); AddToCache(tmp); return tmp; } } public partial class Item { #region DeleteItemAndChildren public static void DeleteItemAndChildren(ItemInfo item) { //Volian.Base.Library.VlnTimer _MyTimer = new Volian.Base.Library.VlnTimer(); if (!CanDeleteObject()) throw new System.Security.SecurityException("User not authorized to remove a Item"); try { ItemInfo nextItem = item.NextItem; ItemInfo prevItem = item.MyPrevious; DocVersionInfo docVersion = item.ItemDocVersionCount == 1 ? item.ItemDocVersions[0] : null; item.OnBeforeDelete(); //_MyTimer.ActiveProcess = "DataPortal.Delete"; DataPortal.Delete(new DeleteCriteria(item.ItemID, Volian.Base.Library.VlnSettings.UserID)); if (nextItem != null) // Adjust PreviousID for NextItem { if (docVersion != null) using (DocVersion dv = docVersion.Get()) DocVersionInfo.Refresh(dv); //_MyTimer.ActiveProcess = "RefreshPrevious"; ItemInfo.RefreshPrevious(nextItem.ItemID, item.PreviousID); // The order of the next two methods was required to fix a null reference // when getting myparent. This bug was found when deleting a node from the // tree when the RTBItem was not open (i.e. in the step editor window). //_MyTimer.ActiveProcess = "RefreshItemParts"; nextItem.RefreshItemParts(); //nextItem.ResetOrdinal(); - UpdateTransitionText calls ResetOrdinal //_MyTimer.ActiveProcess = "UpdateTransitionText"; if(prevItem != null) prevItem.UpdateTransitionText(); else nextItem.UpdateTransitionText(); } else if (prevItem != null) { //_MyTimer.ActiveProcess = "RefreshNextItems"; prevItem.RefreshNextItems(); //_MyTimer.ActiveProcess = "ResetOrdinal"; if (prevItem.IsCaution || prevItem.IsNote) prevItem.ResetOrdinal(); //_MyTimer.ActiveProcess = "UpdateTransitionText"; prevItem.UpdateTransitionText(); } //_MyTimer.ActiveProcess = "DeleteItemInfoAndChildren"; ItemInfo.DeleteItemInfoAndChildren(item.ItemID); // Dispose ItemInfo and Children } catch (Exception ex) { System.Data.SqlClient.SqlException exSQL = SqlException(ex); if (exSQL != null && exSQL.Message.Contains("###Cannot Delete Item###")) throw exSQL; Console.WriteLine("ItemInsertExt: Stacktrace = {0}", ex.StackTrace); throw new DbCslaException("Error on Item.DeleteItemAndChildren", ex); } //_MyTimer.ShowElapsedTimes("DeleteItemAndChildren"); } private static System.Data.SqlClient.SqlException SqlException(Exception ex) { Type sqlExType = typeof(System.Data.SqlClient.SqlException); while (ex != null) { if (ex.GetType() == sqlExType) return ex as System.Data.SqlClient.SqlException; ex = ex.InnerException; } return null; } [Serializable()] protected class DeleteCriteria { private int _ItemID; public int ItemID { get { return _ItemID; } } private string _UserID; public string UserID { get { return _UserID; } set { _UserID = value; } } public DeleteCriteria(int itemID,String userID) { _ItemID = itemID; _UserID = userID; } } [Transactional(TransactionalTypes.TransactionScope)] private void DataPortal_Delete(DeleteCriteria criteria) { if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] Item.DataPortal_Delete", GetHashCode()); try { using (SqlConnection cn = Database.VEPROMS_SqlConnection) { using (SqlCommand cm = cn.CreateCommand()) { cm.CommandType = CommandType.StoredProcedure; cm.CommandText = "DeleteItemAndChildren"; cm.Parameters.AddWithValue("@ItemID", criteria.ItemID); cm.Parameters.AddWithValue("@UserID", criteria.UserID); cm.ExecuteNonQuery(); } } } catch (Exception ex) { if (_MyLog.IsErrorEnabled && !ex.Message.Contains("###Cannot Delete Item###")) _MyLog.Error("Item.DataPortal_Delete", ex); _ErrorMessage = ex.Message; throw new DbCslaException("Item.DataPortal_Delete", ex); } } #endregion #region PasteReplace public static ItemInfo PasteReplace(ItemInfo itemInfo, int copyStartID, string chgid) { if (!CanDeleteObject()) throw new System.Security.SecurityException("User not authorized to remove a Item"); try { ItemInfo newItemInfo = ItemInfo.CopyPasteReplaceItemInfoFetch(copyStartID, itemInfo); //itemInfo.ItemID, itemInfo.MyContent.Type, itemInfo.MyContent.Type); // Delete business objects, including remove from tree ItemInfo.DeleteItemInfoAndChildren(itemInfo.ItemID); // Dispose ItemInfo and Children using (Item item = Get(newItemInfo.ItemID)) ItemInfo.Refresh(item); ItemInfo.PasteSetChangeId(newItemInfo, chgid); if (newItemInfo.NextItem != null) using (Item item = newItemInfo.NextItem.Get()) ItemInfo.Refresh(item); newItemInfo.RefreshNextItems(); // if inserting after a caution or note, refreshes tabs. This will adjust bullets // of any previous cautions or notes. if (newItemInfo.IsCaution || newItemInfo.IsNote) newItemInfo.ResetOrdinal(); newItemInfo.UpdateTransitionText(); newItemInfo.UpdateROText(); newItemInfo.UpdatePastedStepTransitionText(); // Add to tree if (newItemInfo.NextItemCount > 0) { using (ItemInfo itm = ItemInfo.Get(newItemInfo.NextItem.ItemID)) { itm.OnNewSiblingBefore(new ItemInfoInsertEventArgs(newItemInfo, ItemInfo.EAddpingPart.Before)); } } else if (newItemInfo.PreviousID != null) { using (ItemInfo itm2 = ItemInfo.Get((int)newItemInfo.PreviousID)) { itm2.OnNewSiblingAfter(new ItemInfoInsertEventArgs(newItemInfo, ItemInfo.EAddpingPart.After)); } } else { newItemInfo.MyParent.OnNewChild(new ItemInfoInsertEventArgs(newItemInfo, ItemInfo.EAddpingPart.Child)); } return newItemInfo; } catch (Exception ex) { ItemInfo iii = itemInfo.HandleSqlExceptionOnDelete(ex); if (iii != null) return iii; if (!HandleSqlExceptionOnCopy(ex)) { if (ex.Message.Contains("has External Transitions and has no next step") || ex.Message.Contains("has External Transitions to Procedure") || ex.Message.Contains("has External Transitions to it's children") || ex.Message.Contains("This step has been deleted") ) throw ex; System.Windows.Forms.MessageBox.Show("Details were written to the Error Log.", "Paste Replace Failed", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return itemInfo; } else return itemInfo; } } #endregion private static bool HandleSqlExceptionOnCopy(Exception ex) { if (ex.Message.Contains("This step has been deleted")) { System.Windows.Forms.MessageBox.Show("The step being pasted has been deleted!", "Cannot Paste Deleted Step" , System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Hand); return true; } if (ex.Message.Contains("This current step has been deleted in another session")) { System.Windows.Forms.MessageBox.Show("The highlighted step has been deleted by another user!", "Cannot Paste Step" , System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Hand); return true; } return false; } } }