From da55996088b6274e0e8719e5feb0888869d3d477 Mon Sep 17 00:00:00 2001 From: Rich Date: Tue, 29 Jul 2014 02:32:44 +0000 Subject: [PATCH] Added code to allow user with Writer permission to force check-in a procedure that they have checked-out Added code to export individual procedure and to import individual procedure as a copy or overwrite in same procedure set or as a new procedure in a different procedure set Added code to handle events for exporting and importing procedures to same or different procedure sets within the same database Added code to allow user with both RO Editor and Writer permisssions to user RO Editor and edit procedure. Added menu items to export a procedure or import procedure and initiate their corresponding events. --- .../dlgCheckedOutProcedure.cs | 2 +- .../VEPROMS User Interface/dlgExportImport.cs | 317 +++++++++++++----- PROMS/VEPROMS User Interface/frmVEPROMS.cs | 49 ++- .../Volian.Controls.Library/DisplayTabItem.cs | 6 +- PROMS/Volian.Controls.Library/vlnTreeView.cs | 14 +- 5 files changed, 301 insertions(+), 87 deletions(-) diff --git a/PROMS/VEPROMS User Interface/dlgCheckedOutProcedure.cs b/PROMS/VEPROMS User Interface/dlgCheckedOutProcedure.cs index e99627b9..ac4d54b9 100644 --- a/PROMS/VEPROMS User Interface/dlgCheckedOutProcedure.cs +++ b/PROMS/VEPROMS User Interface/dlgCheckedOutProcedure.cs @@ -62,7 +62,7 @@ namespace VEPROMS sb.AppendLine(string.Format("in a VEPROMS session on computer {0} that was started on {1}", MySessionInfo.MachineName, MySessionInfo.DTSDtart.ToString("MM/dd/yyyy @ HH:mm:ss"))); lblInfo.Text = sb.ToString(); if(MyProcedureInfo != null) - btnForce.Visible = MyUserInfo.IsAdministrator() || MyUserInfo.IsSetAdministrator(MyProcedureInfo.MyDocVersion); + btnForce.Visible = MyUserInfo.IsAdministrator() || MyUserInfo.IsSetAdministrator(MyProcedureInfo.MyDocVersion) || (MyUserInfo.IsWriter(MyProcedureInfo.MyDocVersion) && MyOwnerInfo.OwnerItemID == MyProcedureInfo.ItemID); else btnForce.Visible = MyUserInfo.IsAdministrator() || MyUserInfo.IsSetAdministrator(MySectionInfo.MyProcedure.MyDocVersion); } diff --git a/PROMS/VEPROMS User Interface/dlgExportImport.cs b/PROMS/VEPROMS User Interface/dlgExportImport.cs index 8ea37bf5..c11fa727 100644 --- a/PROMS/VEPROMS User Interface/dlgExportImport.cs +++ b/PROMS/VEPROMS User Interface/dlgExportImport.cs @@ -24,9 +24,15 @@ namespace VEPROMS { get { return _MyNewFolder; } } + private ProcedureInfo _MyNewProcedure; + public ProcedureInfo MyNewProcedure + { + get { return _MyNewProcedure; } + } private string PEIPath; private string _MyMode; private FolderInfo MyFolder = null; + private DocVersionInfo MyDocVersion = null; private ProcedureInfo MyProcedure = null; private XmlAttribute AddAttribute(XmlDocument xd, string name, string value) { @@ -41,6 +47,13 @@ namespace VEPROMS InitializeComponent(); this.Text = mode + " Dialog for " + folderInfo.Name; } + public dlgExportImport(string mode, DocVersionInfo docVersionInfo) + { + _MyMode = mode; + MyDocVersion = docVersionInfo; + InitializeComponent(); + this.Text = mode + " Dialog for " + docVersionInfo.Name + " of " + docVersionInfo.MyFolder.Name; + } public dlgExportImport(string mode, ProcedureInfo procedureInfo) { _MyMode = mode; @@ -55,7 +68,7 @@ namespace VEPROMS Directory.CreateDirectory(PEIPath); if (_MyMode == "Import") { - if (MyFolder.ChildFolderCount == 0) + if (MyFolder != null && MyFolder.ChildFolderCount == 0) { Directory.Delete(PEIPath, true); Directory.CreateDirectory(PEIPath); @@ -79,7 +92,9 @@ namespace VEPROMS { if (MyFolder != null) { - sfd.FileName = string.Format("{0}.expx", MyFolder.Name); + //Database.SelectedDatabase + //sfd.FileName = string.Format("{0}.expx", MyFolder.Name); + sfd.FileName = string.Format("{0}-{1}.expx",Database.SelectedDatabase, MyFolder.Name); if (sfd.ShowDialog(this) == DialogResult.OK) { if (sfd.FileName != string.Empty) @@ -94,7 +109,7 @@ namespace VEPROMS } else if (MyProcedure != null) { - txtExport.Text = string.Format(@"{0}\{1}.xml", PEIPath, MyProcedure.DisplayNumber); + txtExport.Text = string.Format(@"{0}\{1}.pxml", PEIPath, MyProcedure.DisplayNumber); } } private void txtExport_TextChanged(object sender, EventArgs e) @@ -131,6 +146,7 @@ namespace VEPROMS MyStart = DateTime.Now; btnDoExport.Enabled = false; lblExportStatus.Text = "Performing Export"; + pbExportProcedure.Maximum = 1; XmlDocument xd = new XmlDocument(); ExportItem(xd, MyProcedure, "procedure"); xd.Save(txtExport.Text); @@ -155,22 +171,153 @@ namespace VEPROMS ExportFolder(MyFolder, "folder"); MyWriter.Close(); } - private void btnDoImport_Click(object sender, EventArgs e) - { + private void btnDoImport_Click(object sender, EventArgs e) + { btnImport.Enabled = false; - this.Cursor = Cursors.WaitCursor; - MyStart = DateTime.Now; - btnDoImport.Enabled = false; - lblImportStatus.Text = "Performing Import"; - //LoadImportDataReader(); - TurnChangeManagerOff.Execute(); - LoadImportDataDocument(); - TurnChangeManagerOn.Execute(); + this.Cursor = Cursors.WaitCursor; + MyStart = DateTime.Now; + btnDoImport.Enabled = false; + lblImportStatus.Text = "Performing Import"; + //LoadImportDataReader(); + if (MyFolder != null) + { + TurnChangeManagerOff.Execute(); + LoadImportDataDocument(); + TurnChangeManagerOn.Execute(); + } + if (MyDocVersion != null) + { + TurnChangeManagerOff.Execute(); + XmlDocument xd = new XmlDocument(); + xd.Load(txtImport.Text); + bool isImported = false; + pbImportProcedure.Maximum = 1; + foreach (ProcedureInfo pi in MyDocVersion.Procedures) + { + if (pi.ItemID == int.Parse(xd.SelectSingleNode("procedure/@itemid").InnerText) || pi.MyContent.Number == xd.SelectSingleNode("procedure/content/@number").InnerText) + { + DialogResult dr = MessageBox.Show(this, "The procedure you are importing already exists in this procedure set. Do you want to overwrite the existing procedure?", "Overwrite Existing Procedure", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop); + if (dr == DialogResult.Yes) + { + ImportProcedureOverwrite(xd, pi); + isImported = true; + break; + } + if (dr == DialogResult.No) + { + dr = MessageBox.Show(this, "The procedure you are importing already exists in this procedure set. Do you want to create a copy of the existing procedure?", "Create Copy Of Existing Procedure", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Stop); + if (dr == DialogResult.Yes) + { + ImportProcedureCopy(xd); + isImported = true; + break; + } + } + } + } + if (!isImported) + { + ImportProcedureNew(xd); + } + TurnChangeManagerOn.Execute(); + } TimeSpan elapsed = DateTime.Now.Subtract(MyStart); - lblImportStatus.Text = "Import Completed in " + elapsed.ToString(); - this.Cursor = Cursors.Default; + lblImportStatus.Text = "Import Completed in " + elapsed.ToString(); + this.Cursor = Cursors.Default; btnCloseImport.Enabled = true; - } + } + private void ImportProcedureNew(XmlDocument xd) + { + //add imported procedure + oldFormat = new Dictionary(); + newFormat = new Dictionary(); + FormatInfoList fil = FormatInfoList.Get(); + foreach (FormatInfo fi in fil) + { + oldFormat.Add(fi.FormatID, fi.Name); + newFormat.Add(fi.Name, fi.FormatID); + } + Old2NewItem = new Dictionary(); + Old2NewContent = new Dictionary(); + Old2NewLibDoc = new Dictionary(); + PendingTransitions = new XmlDocument(); + XmlElement xe = PendingTransitions.CreateElement("transitions"); + PendingTransitions.AppendChild(xe); + string fn = PEIPath + @"\transitions.xml"; + PendingTransitions.Save(fn); + ProcedureInfo lastProcedure = null; + foreach (ProcedureInfo pi in MyDocVersion.Procedures) + lastProcedure = pi; + _MyNewProcedure = AddProcedure(xd.DocumentElement, MyDocVersion, lastProcedure); + //update transitions + AddTransitions(PendingTransitions); + File.Delete(fn); + } + private void ImportProcedureCopy(XmlDocument xd) + { + oldFormat = new Dictionary(); + newFormat = new Dictionary(); + FormatInfoList fil = FormatInfoList.Get(); + foreach (FormatInfo fi in fil) + { + oldFormat.Add(fi.FormatID, fi.Name); + newFormat.Add(fi.Name, fi.FormatID); + } + Old2NewItem = new Dictionary(); + Old2NewContent = new Dictionary(); + Old2NewLibDoc = new Dictionary(); + PendingTransitions = new XmlDocument(); + XmlElement xe = PendingTransitions.CreateElement("transitions"); + PendingTransitions.AppendChild(xe); + string fn = PEIPath + @"\transitions.xml"; + PendingTransitions.Save(fn); + ProcedureInfo lastProcedure = null; + //determine count of existing procedures with same number + string number = xd.SelectSingleNode("procedure/content/@number").InnerText; + int count = 0; + foreach (ProcedureInfo pi in MyDocVersion.Procedures) + { + lastProcedure = pi; + if (pi.MyContent.Number.EndsWith(number)) + count++; + } + xd.SelectSingleNode("procedure/content/@number").InnerText = string.Format("Copy({0}) of {1}", count.ToString(), number); + //add imported procedure and copy count + _MyNewProcedure = AddProcedure(xd.DocumentElement, MyDocVersion, lastProcedure); + //update transitions + AddTransitions(PendingTransitions); + File.Delete(fn); + } + private void ImportProcedureOverwrite(XmlDocument xd, ProcedureInfo pi) + { + oldFormat = new Dictionary(); + newFormat = new Dictionary(); + FormatInfoList fil = FormatInfoList.Get(); + foreach (FormatInfo fi in fil) + { + oldFormat.Add(fi.FormatID, fi.Name); + newFormat.Add(fi.Name, fi.FormatID); + } + Old2NewItem = new Dictionary(); + Old2NewContent = new Dictionary(); + Old2NewLibDoc = new Dictionary(); + PendingTransitions = new XmlDocument(); + XmlElement xe = PendingTransitions.CreateElement("transitions"); + PendingTransitions.AppendChild(xe); + string fn = PEIPath + @"\transitions.xml"; + PendingTransitions.Save(fn); + ProcedureInfo lastProcedure = null; + //delete old procedure + foreach (ProcedureInfo lp in MyDocVersion.Procedures) + lastProcedure = lp; + //delete opi + Item.DeleteItemAndChildren(pi); + //add imported procedure + _MyNewProcedure = AddProcedure(xd.DocumentElement, MyDocVersion, lastProcedure); + //update transitions + AddTransitions(PendingTransitions); + File.Delete(fn); + } private void LoadImportDataDocument() { ZipEntry ze = MyExpxZipFile[0]; @@ -486,8 +633,8 @@ namespace VEPROMS if(nd.InnerText == "") xd.DocumentElement.AppendChild(xd.ImportNode(nd, true)); } - xd.Save(fn); } + xd.Save(fn); ze = MyImpxZipFile["transitions.xml"]; MyImpxZipFile.RemoveEntry(ze); MyImpxZipFile.Save(); @@ -581,6 +728,7 @@ namespace VEPROMS //if (!Old2NewItem.ContainsKey(oldid)) Old2NewItem.Add(oldid, newid); } + File.Delete(fn); ze = MyImpxZipFile["contents.xml"]; ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); fn = PEIPath + @"\contents.xml"; @@ -594,6 +742,7 @@ namespace VEPROMS //if (!Old2NewContent.ContainsKey(oldid)) Old2NewContent.Add(oldid, newid); } + File.Delete(fn); ze = MyImpxZipFile["libdocs.xml"]; ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); fn = PEIPath + @"\libdocs.xml"; @@ -607,10 +756,12 @@ namespace VEPROMS //if (!Old2NewContent.ContainsKey(oldid)) Old2NewLibDoc.Add(oldid, newid); } + File.Delete(fn); ze = MyImpxZipFile["transitions.xml"]; ze.Extract(PEIPath, ExtractExistingFileAction.OverwriteSilently); fn = PEIPath + @"\transitions.xml"; PendingTransitions.Load(fn); + File.Delete(fn); } private void AddStoredItemContentIDs(XmlDocument xd) { @@ -736,67 +887,78 @@ namespace VEPROMS } private void btnImport_Click(object sender, EventArgs e) { - if (ofd.ShowDialog(this) == DialogResult.OK) - { - if (ofd.FileName != string.Empty) - { - Old2NewItem = new Dictionary(); - Old2NewContent = new Dictionary(); - Old2NewLibDoc = new Dictionary(); - PendingTransitions = new XmlDocument(); - FileInfo fi = new FileInfo(ofd.FileName); - string dn = fi.Directory.Name; - txtImport.Text = ofd.FileName; - ReadOptions ro = new ReadOptions(); - ro.Encoding = Encoding.UTF8; - MyExpxZipFile = ZipFile.Read(txtImport.Text, ro); - string fn = string.Format(@"{0}\{1}.impx", PEIPath, dn); - if (File.Exists(fn)) + if (MyFolder != null) + { + if (ofd.ShowDialog(this) == DialogResult.OK) + { + if (ofd.FileName != string.Empty) { - MyImpxZipFile = ZipFile.Read(fn, ro); - ReadTransitionAndItemContentIDs(); + Old2NewItem = new Dictionary(); + Old2NewContent = new Dictionary(); + Old2NewLibDoc = new Dictionary(); + PendingTransitions = new XmlDocument(); + FileInfo fi = new FileInfo(ofd.FileName); + string dn = fi.Name.Substring(0, fi.Name.IndexOf("-")); + txtImport.Text = ofd.FileName; + ReadOptions ro = new ReadOptions(); + ro.Encoding = Encoding.UTF8; + MyExpxZipFile = ZipFile.Read(txtImport.Text, ro); + string fn = string.Format(@"{0}\{1}.impx", PEIPath, dn); + if (File.Exists(fn)) + { + MyImpxZipFile = ZipFile.Read(fn, ro); + ReadTransitionAndItemContentIDs(); + } + else + { + MyImpxZipFile = new ZipFile(fn, Encoding.UTF8); + //transitions + XmlElement xe = PendingTransitions.CreateElement("transitions"); + PendingTransitions.AppendChild(xe); + fn = PEIPath + @"\transitions.xml"; + PendingTransitions.Save(fn); + MyImpxZipFile.AddFile(fn, ""); + MyImpxZipFile.Save(); + File.Delete(fn); + //itemids + XmlDocument xd = new XmlDocument(); + xe = xd.CreateElement("items"); + xd.AppendChild(xe); + fn = PEIPath + @"\items.xml"; + xd.Save(fn); + MyImpxZipFile.AddFile(fn, ""); + MyImpxZipFile.Save(); + File.Delete(fn); + //contentids + xd = new XmlDocument(); + xe = xd.CreateElement("contents"); + xd.AppendChild(xe); + fn = PEIPath + @"\contents.xml"; + xd.Save(fn); + MyImpxZipFile.AddFile(fn, ""); + MyImpxZipFile.Save(); + File.Delete(fn); + //libdocids + xd = new XmlDocument(); + xe = xd.CreateElement("libdocs"); + xd.AppendChild(xe); + fn = PEIPath + @"\libdocs.xml"; + xd.Save(fn); + MyImpxZipFile.AddFile(fn, ""); + MyImpxZipFile.Save(); + File.Delete(fn); + } } - else - { - MyImpxZipFile = new ZipFile(fn, Encoding.UTF8); - //transitions - XmlElement xe = PendingTransitions.CreateElement("transitions"); - PendingTransitions.AppendChild(xe); - fn = PEIPath + @"\transitions.xml"; - PendingTransitions.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - //File.Delete(fn); - //itemids - XmlDocument xd = new XmlDocument(); - xe = xd.CreateElement("items"); - xd.AppendChild(xe); - fn = PEIPath + @"\items.xml"; - xd.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - //contentids - xd = new XmlDocument(); - xe = xd.CreateElement("contents"); - xd.AppendChild(xe); - fn = PEIPath + @"\contents.xml"; - xd.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - //libdocids - xd = new XmlDocument(); - xe = xd.CreateElement("libdocs"); - xd.AppendChild(xe); - fn = PEIPath + @"\libdocs.xml"; - xd.Save(fn); - MyImpxZipFile.AddFile(fn, ""); - MyImpxZipFile.Save(); - File.Delete(fn); - } - } - } + } + } + if (MyDocVersion != null) + { + ofd.Filter = "PROMS Procedure Export Files|*.pxml"; + if (ofd.ShowDialog(this) == DialogResult.OK) + { + txtImport.Text = ofd.FileName; + } + } } private void txtImport_TextChanged(object sender, EventArgs e) { @@ -1179,7 +1341,8 @@ namespace VEPROMS pbExportSection.Maximum = pbExportSection.Value; pbExportStep.Value = 0; pbExportStep.Maximum = pbExportStep.Value; - pbExportSection.Maximum = ii.Sections.Count; + if(ii.Sections != null) + pbExportSection.Maximum = ii.Sections.Count; } if (ii.IsSection && ii.ActiveParent.IsProcedure) { diff --git a/PROMS/VEPROMS User Interface/frmVEPROMS.cs b/PROMS/VEPROMS User Interface/frmVEPROMS.cs index 9d963bc6..8867b4e3 100644 --- a/PROMS/VEPROMS User Interface/frmVEPROMS.cs +++ b/PROMS/VEPROMS User Interface/frmVEPROMS.cs @@ -283,7 +283,17 @@ namespace VEPROMS void tv_ExportImportProcedureSets(object sender, vlnTreeEventArgs args) { - FolderInfo fi = (args.Node as VETreeNode).VEObject as FolderInfo; + FolderInfo fi = null; + DocVersionInfo dvi = null; + ProcedureInfo pi = null; + if ((args.Node as VETreeNode).VEObject is FolderInfo) + fi = (args.Node as VETreeNode).VEObject as FolderInfo; + if ((args.Node as VETreeNode).VEObject is DocVersionInfo) + dvi = (args.Node as VETreeNode).VEObject as DocVersionInfo; + if ((args.Node as VETreeNode).VEObject is ProcedureInfo) + pi = (args.Node as VETreeNode).VEObject as ProcedureInfo; + if (fi != null) + { string msg = string.Empty; bool ok = MySessionInfo.CanCheckOutItem(fi.FolderID, CheckOutType.Folder, ref msg); if (!ok) @@ -302,10 +312,43 @@ namespace VEPROMS if (args.Index == 1 && dlg.MyNewFolder != null) tv.AddNewNode(dlg.MyNewFolder); } - + } + if (dvi != null) + { + string msg = string.Empty; + bool ok = MySessionInfo.CanCheckOutItem(dvi.VersionID, CheckOutType.DocVersion, ref msg); + if (!ok) + { + MessageBox.Show(this, msg, "Import Procedure Unavailable"); + } + else + { + int ownerid = MySessionInfo.CheckOutItem(dvi.VersionID, CheckOutType.DocVersion); + dlgExportImport dlg = new dlgExportImport("Import", dvi); + dlg.ShowDialog(this); + MySessionInfo.CheckInItem(ownerid); + tv.AddNewNode(dlg.MyNewProcedure); + } + } + if (pi != null) + { + string msg = string.Empty; + bool ok = MySessionInfo.CanCheckOutItem(pi.ItemID, CheckOutType.Procedure, ref msg); + if (!ok) + { + MessageBox.Show(this, msg, "Export Procedure Unavailable"); + } + else + { + int ownerid = MySessionInfo.CheckOutItem(pi.ItemID, CheckOutType.Procedure); + dlgExportImport dlg = new dlgExportImport("Export", pi); + dlg.ShowDialog(this); + MySessionInfo.CheckInItem(ownerid); + } + } } - private void MakeDatabaseChanges() + private void MakeDatabaseChanges() { // September 2012: Decided to store roimages as zipped. Any previous data may not have them zipped. // Check the top folders config to see, and if needed, zip them: diff --git a/PROMS/Volian.Controls.Library/DisplayTabItem.cs b/PROMS/Volian.Controls.Library/DisplayTabItem.cs index 850a2229..6df2576b 100644 --- a/PROMS/Volian.Controls.Library/DisplayTabItem.cs +++ b/PROMS/Volian.Controls.Library/DisplayTabItem.cs @@ -132,10 +132,10 @@ namespace Volian.Controls.Library _MyStepTabPanel.MyStepTabRibbon.SetupSetAdminMode(); MyUserRole = Volian.Base.Library.VlnSettings.UserID + " - Set Administrator"; } - else if (ui.IsROEditor(myItem.MyDocVersion)) + else if (ui.IsROEditor(myItem.MyDocVersion) && !ui.IsWriter(myItem.MyDocVersion)) { - if (_MyStepTabPanel != null) - _MyStepTabPanel.MyStepTabRibbon.SetupROEditorMode(); + if (_MyStepTabPanel != null) + _MyStepTabPanel.MyStepTabRibbon.SetupROEditorMode(); MyUserRole = Volian.Base.Library.VlnSettings.UserID + " - RO Editor"; } else if (ui.IsWriter(myItem.MyDocVersion)) diff --git a/PROMS/Volian.Controls.Library/vlnTreeView.cs b/PROMS/Volian.Controls.Library/vlnTreeView.cs index 585c0009..a597a112 100644 --- a/PROMS/Volian.Controls.Library/vlnTreeView.cs +++ b/PROMS/Volian.Controls.Library/vlnTreeView.cs @@ -541,7 +541,11 @@ namespace Volian.Controls.Library else if (tn.VEObject as DocVersionInfo != null) // DocVersions can only contain procs { DocVersionInfo dvi = tn.VEObject as DocVersionInfo; - if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi) || ui.IsWriter(dvi)) + if (ui.IsAdministrator()) + { + cm.MenuItems.Add("Import Procedure", mi_Click); + } + if (ui.IsAdministrator() || ui.IsSetAdministrator(dvi) || ui.IsWriter(dvi)) { OwnerInfoList.Reset(); oil = OwnerInfoList.GetByVersionID(dvi.VersionID); @@ -628,6 +632,10 @@ namespace Volian.Controls.Library { ProcedureInfo pri = tn.VEObject as ProcedureInfo; oi = OwnerInfo.GetByItemID(pri.ItemID, CheckOutType.Procedure); + if (ui.IsAdministrator()) + { + cm.MenuItems.Add("Export Procedure", mi_Click); + } if (ui.IsAdministrator() || ui.IsSetAdministrator(pri.MyDocVersion) || ui.IsWriter(pri.MyDocVersion)) { if (oi != null && oi.SessionID != MySessionInfo.SessionID) @@ -1122,12 +1130,12 @@ namespace Volian.Controls.Library MenuItem mi = sender as MenuItem; if (mi == null) return; - if (mi.Text == "Export Procedure Set") + if (mi.Text == "Export Procedure Set" || mi.Text == "Export Procedure") { OnExportImportProcedureSets(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 0)); return; } - if (mi.Text == "Import Procedure Set") + if (mi.Text == "Import Procedure Set" || mi.Text == "Import Procedure") { OnExportImportProcedureSets(this, new vlnTreeEventArgs(SelectedNode as VETreeNode, null, 1)); return;