B2016-130: Copy and paste replace steps causing missing and duplicate items in tree (problems with ‘NextItems’)

This commit is contained in:
Kathy Ruffing 2017-08-07 13:05:02 +00:00
parent e8ae40ef7f
commit 20a07c6a3e
12 changed files with 135 additions and 31 deletions

View File

@ -142,7 +142,7 @@ namespace VEPROMS.CSLA.Library
sb.Append(Counts<Membership>(Membership.CountNotDisposed, Membership.CountNotFinalized)); sb.Append(Counts<Membership>(Membership.CountNotDisposed, Membership.CountNotFinalized));
sb.Append(Counts<MembershipInfo>(MembershipInfo.CountNotDisposed, MembershipInfo.CountNotFinalized)); sb.Append(Counts<MembershipInfo>(MembershipInfo.CountNotDisposed, MembershipInfo.CountNotFinalized));
sb.Append(Counts<MembershipInfoList>(MembershipInfoList.CountNotDisposed, MembershipInfoList.CountNotFinalized)); sb.Append(Counts<MembershipInfoList>(MembershipInfoList.CountNotDisposed, MembershipInfoList.CountNotFinalized));
sb.Append(Counts<NextItems>(NextItems.CountNotDisposed, NextItems.CountNotFinalized)); //sb.Append(Counts<NextItems>(NextItems.CountNotDisposed, NextItems.CountNotFinalized));
sb.Append(Counts<Part>(Part.CountNotDisposed, Part.CountNotFinalized)); sb.Append(Counts<Part>(Part.CountNotDisposed, Part.CountNotFinalized));
sb.Append(Counts<PartAudit>(PartAudit.CountNotDisposed, PartAudit.CountNotFinalized)); sb.Append(Counts<PartAudit>(PartAudit.CountNotDisposed, PartAudit.CountNotFinalized));
sb.Append(Counts<PartAuditInfo>(PartAuditInfo.CountNotDisposed, PartAuditInfo.CountNotFinalized)); sb.Append(Counts<PartAuditInfo>(PartAuditInfo.CountNotDisposed, PartAuditInfo.CountNotFinalized));
@ -353,7 +353,7 @@ namespace VEPROMS.CSLA.Library
sb.Append(Counts<Membership>(Membership.CountCreated, Membership.CountNotDisposed, Membership.CountNotFinalized)); sb.Append(Counts<Membership>(Membership.CountCreated, Membership.CountNotDisposed, Membership.CountNotFinalized));
sb.Append(Counts<MembershipInfo>(MembershipInfo.CountCreated, MembershipInfo.CountNotDisposed, MembershipInfo.CountNotFinalized)); sb.Append(Counts<MembershipInfo>(MembershipInfo.CountCreated, MembershipInfo.CountNotDisposed, MembershipInfo.CountNotFinalized));
sb.Append(Counts<MembershipInfoList>(MembershipInfoList.CountCreated, MembershipInfoList.CountNotDisposed, MembershipInfoList.CountNotFinalized)); sb.Append(Counts<MembershipInfoList>(MembershipInfoList.CountCreated, MembershipInfoList.CountNotDisposed, MembershipInfoList.CountNotFinalized));
sb.Append(Counts<NextItems>(NextItems.CountCreated, NextItems.CountNotDisposed, NextItems.CountNotFinalized)); //sb.Append(Counts<NextItems>(NextItems.CountCreated, NextItems.CountNotDisposed, NextItems.CountNotFinalized));
sb.Append(Counts<Part>(Part.CountCreated, Part.CountNotDisposed, Part.CountNotFinalized)); sb.Append(Counts<Part>(Part.CountCreated, Part.CountNotDisposed, Part.CountNotFinalized));
sb.Append(Counts<PartAudit>(PartAudit.CountCreated, PartAudit.CountNotDisposed, PartAudit.CountNotFinalized)); sb.Append(Counts<PartAudit>(PartAudit.CountCreated, PartAudit.CountNotDisposed, PartAudit.CountNotFinalized));
sb.Append(Counts<PartAuditInfo>(PartAuditInfo.CountCreated, PartAuditInfo.CountNotDisposed, PartAuditInfo.CountNotFinalized)); sb.Append(Counts<PartAuditInfo>(PartAuditInfo.CountCreated, PartAuditInfo.CountNotDisposed, PartAuditInfo.CountNotFinalized));

View File

@ -254,9 +254,7 @@ namespace VEPROMS.CSLA.Library
{ {
using (Item fromitem = previousInfo == null ? null : previousInfo.Get()) using (Item fromitem = previousInfo == null ? null : previousInfo.Get())
{ {
ItemInfo nextInfo = null; // Check to see if the item is being inserted in the middle of some items. ItemInfo nextInfo = previousInfo.GetNext(); // Check to see if the item is being inserted in the middle of some items.
if (previousInfo != null && previousInfo.NextItems != null && previousInfo.NextItems.Count > 0)
nextInfo = previousInfo.NextItems[0];
using (Item itm = Item.MakeItem(fromitem, cont)) using (Item itm = Item.MakeItem(fromitem, cont))
{ {
newitemid = itm.ItemID; newitemid = itm.ItemID;
@ -1986,8 +1984,13 @@ namespace VEPROMS.CSLA.Library
get get
{ {
ItemInfo temp = this; ItemInfo temp = this;
while (temp.NextItems != null && temp.NextItems.Count > 0) temp = temp.NextItems[0]; ItemInfo last = this;
return temp; while (temp != null)
{
last = temp;
temp = temp.GetNext();
}
return last;
} }
} }
public ItemInfo LastChild(E_FromType partType) public ItemInfo LastChild(E_FromType partType)

View File

@ -2056,9 +2056,7 @@ namespace VEPROMS.CSLA.Library
get get
{ {
if (PrintAllAtOnce) return GetNextItem(); if (PrintAllAtOnce) return GetNextItem();
if (NextItemCount > 0 && NextItems != null && NextItems.Count > 0) return GetNext();
return NextItems[0];
return null;
} }
} }
private static void ResetOrdinal(int itemID) private static void ResetOrdinal(int itemID)
@ -2335,16 +2333,16 @@ namespace VEPROMS.CSLA.Library
newItemInfo.UpdateROText(); newItemInfo.UpdateROText();
newItemInfo.UpdatePastedStepTransitionText(); newItemInfo.UpdatePastedStepTransitionText();
// Add to tree // Add to tree
if (newItemInfo.NextItemCount > 0) if (newItemInfo.NextItem != null)
{ {
using (ItemInfo itm = ItemInfo.Get(newItemInfo.NextItem.ItemID)) using (ItemInfo itm = ItemInfo.GetNonCached(newItemInfo.NextItem.ItemID))
{ {
itm.OnNewSiblingBefore(new ItemInfoInsertEventArgs(newItemInfo, ItemInfo.EAddpingPart.Before)); itm.OnNewSiblingBefore(new ItemInfoInsertEventArgs(newItemInfo, ItemInfo.EAddpingPart.Before));
} }
} }
else if (newItemInfo.PreviousID != null) else if (newItemInfo.PreviousID != null)
{ {
using (ItemInfo itm2 = ItemInfo.Get((int)newItemInfo.PreviousID)) using (ItemInfo itm2 = ItemInfo.GetNonCached((int)newItemInfo.PreviousID))
{ {
itm2.OnNewSiblingAfter(new ItemInfoInsertEventArgs(newItemInfo, ItemInfo.EAddpingPart.After)); itm2.OnNewSiblingAfter(new ItemInfoInsertEventArgs(newItemInfo, ItemInfo.EAddpingPart.After));
} }

View File

@ -264,6 +264,76 @@ namespace VEPROMS.CSLA.Library
foreach (ItemInfo tmp in _CacheByPrimaryKey[_ItemID.ToString()]) foreach (ItemInfo tmp in _CacheByPrimaryKey[_ItemID.ToString()])
tmp._ItemDocVersionCount = -1; // This will cause the data to be requeried tmp._ItemDocVersionCount = -1; // This will cause the data to be requeried
} }
// B2016-130: GetNext was added so that NextItems was not used for finding the next item in a list of iteminfos using 'nextitems'.
// When using 'nextitems' internal list data structures for items were not maintained consistently with the database items during
// some occurrences of copy/paste/delete.
[Serializable()]
private class PreviousIDCriteria
{
public PreviousIDCriteria(int? previousID)
{
_PreviousID = previousID;
}
private int? _PreviousID;
public int? PreviousID
{
get { return _PreviousID; }
set { _PreviousID = value; }
}
}
public ItemInfo GetNext()
{
try
{
ItemInfo tmp = DataPortal.Fetch<ItemInfo>(new PreviousIDCriteria(ItemID));
if (tmp.ErrorMessage == "No Record Found")
{
tmp.Dispose(); // Clean-up ItemInfo
tmp = null;
}
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on ItemInfo.GetNext", ex);
}
}
private void DataPortal_Fetch(PreviousIDCriteria criteria)
{
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ItemInfo.DataPortal_FetchPreviousID", GetHashCode());
try
{
using (SqlConnection cn = Database.VEPROMS_SqlConnection)
{
ApplicationContext.LocalContext["cn"] = cn;
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "getNextItems";
cm.Parameters.AddWithValue("@PreviousID", criteria.PreviousID);
cm.CommandTimeout = Database.DefaultTimeout;
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
if (!dr.Read())
{
_ErrorMessage = "No Record Found";
return;
}
ReadData(dr);
}
}
// removing of item only needed for local data portal
if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client)
ApplicationContext.LocalContext.Remove("cn");
}
}
catch (Exception ex)
{
if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemInfo.DataPortal_FetchPreviousID", ex);
_ErrorMessage = ex.Message;
throw new DbCslaException("ItemInfo.DataPortal_Fetch", ex);
}
}
private int _NextItemCount = 0; private int _NextItemCount = 0;
/// <summary> /// <summary>
/// Count of NextItems for this Item /// Count of NextItems for this Item
@ -578,6 +648,25 @@ namespace VEPROMS.CSLA.Library
throw new DbCslaException("Error on ItemInfo.Get", ex); throw new DbCslaException("Error on ItemInfo.Get", ex);
} }
} }
// B2016-130: Just get an item from the database, but don't add it to the cache because it gets
// freed (only use this in a 'using' statement).
public static ItemInfo GetNonCached(int itemID)
{
try
{
ItemInfo tmp = DataPortal.Fetch<ItemInfo>(new PKCriteria(itemID));
if (tmp.ErrorMessage == "No Record Found")
{
tmp.Dispose(); // Clean-up ItemInfo
tmp = null;
}
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on ItemInfo.GetNonCached", ex);
}
}
#endregion #endregion
#region Data Access Portal #region Data Access Portal
internal ItemInfo(SafeDataReader dr) internal ItemInfo(SafeDataReader dr)

View File

@ -64,7 +64,17 @@ namespace VEPROMS.CSLA.Library
for (int i = 0; i < Count; i++) for (int i = 0; i < Count; i++)
{ {
if (base[i] == sender) if (base[i] == sender)
{
// Added insert to fix when item is replaced and a 'delete' is done, the item needs inserted. Note
// that when text is modified, i.e. 'Changed', this code is not executed. Fixed B2016-130.
RefreshingList = true;
IsReadOnly = false;
Items.Insert(i, (sender as ItemInfo).MyPrevious);
IsReadOnly = true;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, i)); this.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, i));
RefreshingList = false;
break;
}
} }
} }
private bool _Disposed = false; private bool _Disposed = false;

View File

@ -91,7 +91,7 @@ namespace Volian.Controls.Library
} }
else else
lstCBSteps.Items.Add(startitm, CheckState.Unchecked); lstCBSteps.Items.Add(startitm, CheckState.Unchecked);
startitm = (startitm.NextItem != null && startitm.NextItems.Count > 0 ? startitm.NextItems[0] : null); startitm = startitm.GetNext();
} }
} }
private void listBoxFoldouts_SelectedIndexChanged(object sender, EventArgs e) private void listBoxFoldouts_SelectedIndexChanged(object sender, EventArgs e)

View File

@ -520,7 +520,7 @@ namespace Volian.Controls.Library
// itm.UserID = Volian.Base.Library.VlnSettings.UserID; // itm.UserID = Volian.Base.Library.VlnSettings.UserID;
// itm.Save(); // itm.Save();
//} //}
startitm = (startitm.NextItem != null && startitm.NextItems.Count > 0 ? startitm.NextItems[0] : null); startitm = startitm.GetNext();
} }
msgBox = string.Format("All Step Types at this level were changed to {0}", listBoxStepTypes.Items[listBoxStepTypes.SelectedIndex]); msgBox = string.Format("All Step Types at this level were changed to {0}", listBoxStepTypes.Items[listBoxStepTypes.SelectedIndex]);
} }

View File

@ -513,7 +513,7 @@ namespace Volian.Controls.Library
tvTran.SelectedNode = tvTran.Nodes[active]; tvTran.SelectedNode = tvTran.Nodes[active];
setsel = true; setsel = true;
} }
startitm = (startitm.NextItem != null && startitm.NextItems.Count > 0 ? startitm.NextItems[0] : null); startitm = startitm.GetNext();
} }
if (!setsel) tvTran.SelectedNode = tvTran.Nodes[0]; if (!setsel) tvTran.SelectedNode = tvTran.Nodes[0];
tvTran.BeforeExpand += new TreeViewCancelEventHandler(tvTran_BeforeExpand); tvTran.BeforeExpand += new TreeViewCancelEventHandler(tvTran_BeforeExpand);
@ -544,7 +544,7 @@ namespace Volian.Controls.Library
if (secitm.ItemID == secstart) cbTranSects.SelectedIndex = active; if (secitm.ItemID == secstart) cbTranSects.SelectedIndex = active;
} }
if (secitm.Sections != null && secitm.Sections.Count > 0) cbTranSectsFillIn(secitm.Sections[0], secstart, false); if (secitm.Sections != null && secitm.Sections.Count > 0) cbTranSectsFillIn(secitm.Sections[0], secstart, false);
secitm = (secitm.NextItem != null && secitm.NextItems.Count > 0 ? secitm.NextItems[0] : null); secitm = secitm.GetNext();
} }
if (cbTranSects.SelectedIndex == -1) cbTranSects.SelectedIndex = 0; if (cbTranSects.SelectedIndex == -1) cbTranSects.SelectedIndex = 0;
cbTranSects.Refresh(); cbTranSects.Refresh();
@ -562,7 +562,7 @@ namespace Volian.Controls.Library
int active = cbTranProcs.Items.Add(prcitm); int active = cbTranProcs.Items.Add(prcitm);
if (_CurrentProcedure.ContentID == prcitm.MyContent.ContentID) _CurrentProcIndex = active; if (_CurrentProcedure.ContentID == prcitm.MyContent.ContentID) _CurrentProcIndex = active;
if (prcitm.MyContent.ContentID == selitm.MyContent.ContentID) cbTranProcs.SelectedIndex = active; if (prcitm.MyContent.ContentID == selitm.MyContent.ContentID) cbTranProcs.SelectedIndex = active;
prcitm = (prcitm.NextItem != null && prcitm.NextItems.Count > 0 ? prcitm.NextItems[0] : null); prcitm = prcitm.GetNext();
} }
} }
private void SetControlsEnabling() private void SetControlsEnabling()

View File

@ -3393,7 +3393,7 @@ namespace Volian.Controls.Library
} }
} }
// if on a caution or note check the step below me, which is really my activeparent (cautions/notes are above their respective parent) // if on a caution or note check the step below me, which is really my activeparent (cautions/notes are above their respective parent)
if ((itm.IsCaution || itm.IsNote) && (itm.NextItem == null || itm.NextItemCount == 0) && (itm.ActiveParent as ItemInfo).SupInfos != null && (itm.ActiveParent as ItemInfo).SupInfos.Count > 0) if ((itm.IsCaution || itm.IsNote) && itm.NextItem == null && (itm.ActiveParent as ItemInfo).SupInfos != null && (itm.ActiveParent as ItemInfo).SupInfos.Count > 0)
return GetEditItemFromItemID((itm.ActiveParent as ItemInfo).ItemID); return GetEditItemFromItemID((itm.ActiveParent as ItemInfo).ItemID);
// Finally check substeps: // Finally check substeps:

View File

@ -949,7 +949,8 @@ namespace Volian.Controls.Library
{ {
if (lookAtSub && ii.Sections != null) return TopPart(ii.Sections[0]); if (lookAtSub && ii.Sections != null) return TopPart(ii.Sections[0]);
if (lookAtSub && ii.Steps != null) return TopPart(ii.Steps[0]); if (lookAtSub && ii.Steps != null) return TopPart(ii.Steps[0]);
if (ii.IsSection && ii.NextItems != null && ii.NextItems.Count > 0) return TopPart(ii.NextItems[0]); ItemInfo nxt = ii.GetNext();
if (nxt != null) return TopPart(nxt);
} }
else else
{ {
@ -972,7 +973,8 @@ namespace Volian.Controls.Library
if (lookAtRNO && ii.RNOs != null && ii.RNOLevel >= ii.ColumnMode) return TopPart(ii.RNOs[0]); if (lookAtRNO && ii.RNOs != null && ii.RNOLevel >= ii.ColumnMode) return TopPart(ii.RNOs[0]);
// Nextsibling - go to top part of sibling // Nextsibling - go to top part of sibling
// TODO: RHM - NextItems was not null when it should have been after delete of a note below a caution // TODO: RHM - NextItems was not null when it should have been after delete of a note below a caution
if (ii.NextItems != null && ii.NextItems.Count > 0) return TopPart(ii.NextItems[0]); ItemInfo nxt = ii.GetNext();
if (nxt != null) return TopPart(nxt);
// If on caution, if parent has note - go to note // If on caution, if parent has note - go to note
if (ii.IsCautionPart && ii.MyParent.Notes != null) return ii.MyParent.Notes[0]; if (ii.IsCautionPart && ii.MyParent.Notes != null) return ii.MyParent.Notes[0];
// If on caution, if parent !has note or if on note go to parent // If on caution, if parent !has note or if on note go to parent
@ -1001,7 +1003,7 @@ namespace Volian.Controls.Library
ii = ii.LastSibling; ii = ii.LastSibling;
break; break;
case Keys.PageDown: case Keys.PageDown:
ii = ii.NextItems != null && ii.NextItems.Count > 0 ? ii.NextItems[0] : null; ii = ii.GetNext();
break; break;
case Keys.PageUp: case Keys.PageUp:
ii = ii.MyPrevious; ii = ii.MyPrevious;

View File

@ -375,7 +375,7 @@ namespace Volian.Print.Library
mySize += (2*SixLinesPerInch); mySize += (2*SixLinesPerInch);
// mySize is the size of this step and includes an extra blank line. For HLS, if this is the last step in section & there is room in footer to keep // mySize is the size of this step and includes an extra blank line. For HLS, if this is the last step in section & there is room in footer to keep
// step on the page, do so by eliminating the blank line before doing the test to see if it fits. // step on the page, do so by eliminating the blank line before doing the test to see if it fits.
if (MyItemInfo.IsHigh && mySize >= (2 * SixLinesPerInch) && MyItemInfo.MyDocStyle.Layout.FooterLength > 0 && (MyItemInfo.MyDocStyle.End.Message == null || MyItemInfo.MyDocStyle.End.Message == "") && MyItemInfo.NextItemCount == 0 && (MyItemInfo.Steps == null || MyItemInfo.Steps.Count == 0) && (MyItemInfo.RNOs == null || MyItemInfo.RNOs.Count == 0)) if (MyItemInfo.IsHigh && mySize >= (2 * SixLinesPerInch) && MyItemInfo.MyDocStyle.Layout.FooterLength > 0 && (MyItemInfo.MyDocStyle.End.Message == null || MyItemInfo.MyDocStyle.End.Message == "") && MyItemInfo.NextItem != null && (MyItemInfo.Steps == null || MyItemInfo.Steps.Count == 0) && (MyItemInfo.RNOs == null || MyItemInfo.RNOs.Count == 0))
mySize -= SixLinesPerInch; mySize -= SixLinesPerInch;
//// Account for extra lines in the end message (flag < 0) //// Account for extra lines in the end message (flag < 0)
float adjMsgY = 0; float adjMsgY = 0;

View File

@ -153,7 +153,7 @@ namespace Volian.Print.Library
{ {
if ((childItemInfo.IsCaution || childItemInfo.IsNote) && if ((childItemInfo.IsCaution || childItemInfo.IsNote) &&
childItemInfo.MyPrevious != null && childItemInfo.MyPrevious.MyContent.Type != childItemInfo.MyContent.Type && childItemInfo.MyPrevious != null && childItemInfo.MyPrevious.MyContent.Type != childItemInfo.MyContent.Type &&
childItemInfo.NextItemCount > 0 && childItemInfo.NextItem!= null && childItemInfo.MyContent.Type == childItemInfo.NextItem.MyContent.Type) childItemInfo.NextItem != null && childItemInfo.MyContent.Type == childItemInfo.NextItem.MyContent.Type)
childItemInfo.SetupTags(); // added for V.C. Summer Transition caution in EOP-15.0 step 5.4 childItemInfo.SetupTags(); // added for V.C. Summer Transition caution in EOP-15.0 step 5.4
if (lastHeader != null) if (lastHeader != null)
{ {
@ -372,7 +372,7 @@ namespace Volian.Print.Library
if (nxt != null && (nxt.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS) nxtIsBoxed = 0; if (nxt != null && (nxt.MyDocStyle.StructureStyle.Style & E_DocStructStyle.DoubleBoxHLS) == E_DocStructStyle.DoubleBoxHLS) nxtIsBoxed = 0;
yoff += (nxtIsBoxed * vlnPrintObject.SixLinesPerInch); yoff += (nxtIsBoxed * vlnPrintObject.SixLinesPerInch);
} }
if (childItemInfo.IsSequential && childItemInfo.NextItemCount > 0 && childItemInfo.MyParent.IsHigh && ((childItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.XBlankW1stLevSub) == E_DocStructStyle.XBlankW1stLevSub)) if (childItemInfo.IsSequential && childItemInfo.NextItem != null && childItemInfo.MyParent.IsHigh && ((childItemInfo.MyDocStyle.StructureStyle.Style & E_DocStructStyle.XBlankW1stLevSub) == E_DocStructStyle.XBlankW1stLevSub))
yoff += vlnPrintObject.SixLinesPerInch; yoff += vlnPrintObject.SixLinesPerInch;
boxHLS = false; boxHLS = false;
lastChild = childItemInfo; lastChild = childItemInfo;
@ -811,7 +811,7 @@ namespace Volian.Print.Library
{ {
// This section of code draws the lines around the substeps (the actual table part) // This section of code draws the lines around the substeps (the actual table part)
Paragraph horzLine = new Paragraph(ii.ActiveFormat.PlantFormat.FormatData.BoxList[0].BXHorz, iSymblFont); Paragraph horzLine = new Paragraph(ii.ActiveFormat.PlantFormat.FormatData.BoxList[0].BXHorz, iSymblFont);
bool bottomOfTable = (ii.NextItem == null || ii.NextItemCount == 0) || bool bottomOfTable = ii.NextItem == null ||
(MyPageHelper.ParaBreaks.Count > 0 && MyPageHelper.ParaBreaks[0].MyItemInfo.ItemID == ii.NextItem.ItemID); (MyPageHelper.ParaBreaks.Count > 0 && MyPageHelper.ParaBreaks[0].MyItemInfo.ItemID == ii.NextItem.ItemID);
// if bottom of table use different cross/beg/end chars than if in middle of table. // if bottom of table use different cross/beg/end chars than if in middle of table.
Paragraph leftLine = new Paragraph(bottomOfTable ? bx.BXLLC : bx.BXMLS, iSymblFont); Paragraph leftLine = new Paragraph(bottomOfTable ? bx.BXLLC : bx.BXMLS, iSymblFont);
@ -857,7 +857,7 @@ namespace Volian.Print.Library
// Now handle middle parts of the table. For whatever sub level we're at, draw the cross character // Now handle middle parts of the table. For whatever sub level we're at, draw the cross character
// and the horizontal. This is case where the component number may have multiple descriptions,positions, etc. associated // and the horizontal. This is case where the component number may have multiple descriptions,positions, etc. associated
// with it. // with it.
if (!ii.MyParent.IsHigh && ii.NextItem != null && ii.NextItemCount > 0) if (!ii.MyParent.IsHigh && ii.NextItem != null)
{ {
// draw horizontally from this sublevel to the end. // draw horizontally from this sublevel to the end.
int sublev = 0; int sublev = 0;
@ -2283,15 +2283,17 @@ namespace Volian.Print.Library
// Go to the parent, and find its next and check if it or any of its substeps or next steps or any of their substeps have supinfo, // Go to the parent, and find its next and check if it or any of its substeps or next steps or any of their substeps have supinfo,
// and if so, return the id. // and if so, return the id.
ItemInfo par = ii.MyParent; ItemInfo par = ii.MyParent;
if (!par.IsSection && par.NextItems != null && par.NextItems.Count > 0) ItemInfo parsnxt = par.GetNext();
if (!par.IsSection && parsnxt != null)
{ {
par = par.NextItem; par = parsnxt;
while (par != null && !par.IsSection) while (par != null && !par.IsSection)
{ {
id = GetIdThatHasSupInfoItemsSibNext(par, startid); id = GetIdThatHasSupInfoItemsSibNext(par, startid);
if (id != -1) return id; if (id != -1) return id;
par = par.MyParent; par = par.MyParent;
if (!par.IsSection && par.NextItems != null && par.NextItems.Count > 0) par = par.NextItem; ItemInfo sparsnxt = par.GetNext();
if (!par.IsSection && sparsnxt != null) par = sparsnxt;
else return -1; else return -1;
} }
} }
@ -2303,7 +2305,7 @@ namespace Volian.Print.Library
int id = -1; int id = -1;
while (ii != null) while (ii != null)
{ {
SectionInfo supInfoSect = ii.MyActiveSection as SectionInfo; SectionInfo supInfoSect = ii.ActiveSection as SectionInfo;
// if there is a pagebreak on this step section step, quit looking for supinfos. The // if there is a pagebreak on this step section step, quit looking for supinfos. The
// break has to occur here. // break has to occur here.
if (supInfoSect.StepSectPageBreaks.Contains(ii.ItemID)) return -1; if (supInfoSect.StepSectPageBreaks.Contains(ii.ItemID)) return -1;