diff --git a/PROMS/Volian.Controls.Library/StepItem.cs b/PROMS/Volian.Controls.Library/StepItem.cs index 7422a711..c63fe754 100644 --- a/PROMS/Volian.Controls.Library/StepItem.cs +++ b/PROMS/Volian.Controls.Library/StepItem.cs @@ -109,8 +109,15 @@ namespace Volian.Controls.Library if ((value.ItemID % 25) == 0) ChangeBar = true; #endif + value.MyContent.Changed += new ContentInfoEvent(MyContent_Changed); } } + void MyContent_Changed(object sender) + { + // Update the text to reflect the content change + MyStepRTB.MyItemInfo=MyStepRTB.MyItemInfo; // Reset Text + // TODO: Need code to update tabs. + } /// /// Used to connect the RichTextBox with the menus and toolbars /// diff --git a/PROMS/Volian.Controls.Library/StepItem.designer.cs b/PROMS/Volian.Controls.Library/StepItem.designer.cs index f621dc5b..6f0f9aa3 100644 --- a/PROMS/Volian.Controls.Library/StepItem.designer.cs +++ b/PROMS/Volian.Controls.Library/StepItem.designer.cs @@ -17,6 +17,7 @@ namespace Volian.Controls.Library components.Dispose(); } base.Dispose(disposing); + MyItemInfo.MyContent.Changed -= new VEPROMS.CSLA.Library.ContentInfoEvent(MyContent_Changed); } #region Component Designer generated code diff --git a/PROMS/Volian.Controls.Library/StepPanel.cs b/PROMS/Volian.Controls.Library/StepPanel.cs index 2755cea7..9e9edacd 100644 --- a/PROMS/Volian.Controls.Library/StepPanel.cs +++ b/PROMS/Volian.Controls.Library/StepPanel.cs @@ -236,7 +236,8 @@ namespace Volian.Controls.Library if (_LookupStepItems.ContainsKey(id)) // Expanding Parent should have added it to _LookupStepItems { StepItem itm = _LookupStepItems[id]; - if (itm.Visible == false) + ItemInfo ii = myItemInfo.ActiveParent as ItemInfo; + if (itm.Visible == false && ii != null) ExpandAsNeeded((ItemInfo)myItemInfo.ActiveParent); itm.AutoExpand(); // Expand it if it should expand } @@ -269,6 +270,15 @@ namespace Volian.Controls.Library //// TIMING: DisplayItem.TimeIt("pMyItem End"); } } + public void Reset() + { + ItemInfo parent = SelectedItemInfo.ActiveParent as ItemInfo; + if (parent != null) ItemInfo.ResetParts(parent.ItemID); // Force data to reload + // The following line actually reloads the procedure item + MyProcedureItemInfo = MyProcedureItemInfo; // see get/set above. - Load Procedure and Sections + // The following line expands the items needed to display SelectedItemInfo + ExpandAsNeeded(SelectedItemInfo); + } /// /// Get or Set currently selected RichTextBox (StepRTB) /// @@ -303,6 +313,8 @@ namespace Volian.Controls.Library _SelectedItemInfo = value; int id = value.ItemID; ExpandAsNeeded(value); + // reset the entire step panel if the item isn't found. + if (!_LookupStepItems.ContainsKey(id)) Reset(); StepItem itm = _LookupStepItems[id]; itm.ItemSelect(); OnItemSelectedChanged(this, new ItemSelectedChangedEventArgs(itm)); @@ -333,7 +345,7 @@ namespace Volian.Controls.Library OnItemSelectedChanged(this, new ItemSelectedChangedEventArgs(SelectedStepItem)); } } - public void MouseWheel(MouseEventArgs e) + public new void MouseWheel(MouseEventArgs e) { base.OnMouseWheel(e); } diff --git a/PROMS/Volian.Controls.Library/StepRTB.cs b/PROMS/Volian.Controls.Library/StepRTB.cs index b55ce63d..b735512a 100644 --- a/PROMS/Volian.Controls.Library/StepRTB.cs +++ b/PROMS/Volian.Controls.Library/StepRTB.cs @@ -72,7 +72,7 @@ namespace Volian.Controls.Library DisplayText vlntxt = new DisplayText(_MyItemInfo, EpMode, VwMode); _origDisplayText = vlntxt; Font = _origDisplayText.TextFont.WindowsFont; - + Text = ""; // Initialize text before add text AddRtfText(vlntxt); //AddRtfStyles(); ReadOnly = !(EpMode == E_EditPrintMode.Edit && VwMode == E_ViewMode.Edit); diff --git a/PROMS/Volian.Controls.Library/vlnTreeView.cs b/PROMS/Volian.Controls.Library/vlnTreeView.cs index 28b881c7..b7e22a77 100644 --- a/PROMS/Volian.Controls.Library/vlnTreeView.cs +++ b/PROMS/Volian.Controls.Library/vlnTreeView.cs @@ -4,17 +4,21 @@ using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; +using System.Text.RegularExpressions; using System.Windows.Forms; using System.Runtime.InteropServices; // For DragHelper using System.Reflection; +using Csla; +using Csla.Validation; using VEPROMS.CSLA.Library; namespace Volian.Controls.Library { + #region DelegatesAndEventArgs public delegate void vlnTreeViewEvent(object sender, vlnTreeEventArgs args); public delegate bool vlnTreeViewBoolEvent(object sender, vlnTreeEventArgs args); public delegate TreeNode vlnTreeViewTreeNodeEvent(object sender, vlnTreeEventArgs args); - //public delegate void vlnTreeViewDDEvent(object sender, System.Windows.Forms.DragEventArgs args); + public delegate DialogResult vlnTreeViewPropertyEvent(object sender, vlnTreePropertyEventArgs args); public partial class vlnTreeEventArgs { #region Business Methods @@ -51,15 +55,83 @@ namespace Volian.Controls.Library } #endregion } + public partial class vlnTreePropertyEventArgs : EventArgs + { + private string _Title; + public string Title + { + get { return _Title; } + set { _Title = value; } + } + private object _ConfigObject; + public object ConfigObject + { + get { return _ConfigObject; } + set { _ConfigObject = value; } + } + private FolderConfig _FolderConfig; + public FolderConfig FolderConfig + { + get { return _FolderConfig; } + set { _ConfigObject = _FolderConfig = value; } + } + private DocVersionConfig _DocVersionConfig; + public DocVersionConfig DocVersionConfig + { + get { return _DocVersionConfig; } + set { _ConfigObject = _DocVersionConfig = value; } + } + private ProcedureConfig _ProcedureConfig; + public ProcedureConfig ProcedureConfig + { + get { return _ProcedureConfig; } + set { _ConfigObject = _ProcedureConfig = value; } + } + private SectionConfig _SectionConfig; + public SectionConfig SectionConfig + { + get { return _SectionConfig; } + set { _ConfigObject = _SectionConfig = value; } + } + private vlnTreePropertyEventArgs() { ;} + public vlnTreePropertyEventArgs(string title, FolderConfig folderConfig) + { + _Title = title; + FolderConfig = folderConfig; + } + public vlnTreePropertyEventArgs(string title, DocVersionConfig docVersionConfig) + { + _Title = title; + DocVersionConfig = docVersionConfig; + } + public vlnTreePropertyEventArgs(string title, ProcedureConfig procedureConfig) + { + _Title = title; + ProcedureConfig = procedureConfig; + } + public vlnTreePropertyEventArgs(string title, SectionConfig sectionConfig) + { + _Title = title; + DocStyleListConverter.MySection = sectionConfig.MySection; + SectionConfig = sectionConfig; + } + } + #endregion public partial class vlnTreeView : TreeView { + #region Local Vars private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + FolderInfo _LastFolderInfo = null; + ProcedureInfo _LastProcedureInfo = null; + DocVersionInfo _LastDocVersionInfo = null; + SectionInfo _LastSectionInfo = null; + VETreeNode _LastTreeNode = null; + StepInfo _LastStepInfo = null; + ItemInfo _LastItemInfo = null; + bool CanPaste = false; + #endregion #region Events - public event vlnTreeViewEvent NodeDragDrop; - private void OnNodeDragDrop(object sender, vlnTreeEventArgs args) - { - if (NodeDragDrop != null) NodeDragDrop(sender, args); - } public event vlnTreeViewEvent NodeMove; private void OnNodeMove(object sender, vlnTreeEventArgs args) { @@ -70,23 +142,16 @@ namespace Volian.Controls.Library { if (NodeCopy != null) NodeCopy(sender, args); } - public event vlnTreeViewBoolEvent NodeDelete; - private bool OnNodeDelete(object sender, vlnTreeEventArgs args) + public event vlnTreeViewPropertyEvent NodeOpenProperty; + private DialogResult OnNodeOpenProperty(object sender, vlnTreePropertyEventArgs args) { - bool result = true; - if (NodeDelete != null) result = NodeDelete(sender, args); - return result; + if (NodeOpenProperty != null) return NodeOpenProperty(sender, args); + return DialogResult.Cancel; } - public event vlnTreeViewTreeNodeEvent NodeNew; - private TreeNode OnNodeNew(object sender, vlnTreeEventArgs args) + public event vlnTreeViewEvent NodeSelect; + private void OnNodeSelect(object sender, vlnTreeEventArgs args) { - if (NodeNew != null) return NodeNew(sender, args); - else return new TreeNode("New Item"); - } - public event vlnTreeViewEvent NodeProperties; - private void OnNodeProperties(object sender, vlnTreeEventArgs args) - { - if (NodeProperties != null) NodeProperties(sender, args); + if (NodeSelect != null) NodeSelect(sender, args); } public event vlnTreeViewEvent NodeSelectionChange; private void OnNodeSelectionChange(object sender, vlnTreeEventArgs args) @@ -94,9 +159,6 @@ namespace Volian.Controls.Library if (NodeSelectionChange != null) NodeSelectionChange(sender, args); } #endregion - #region Business Methods - ImageList _dragImageList = new ImageList(); - #endregion #region Constructors public vlnTreeView() { @@ -109,30 +171,104 @@ namespace Volian.Controls.Library this.DragLeave += new EventHandler(tv_DragLeave); this.DragOver += new DragEventHandler(tv_DragOver); this.MouseDown += new MouseEventHandler(tv_MouseDown); + this.KeyPress += new KeyPressEventHandler(tv_KeyPress); base.AfterSelect += new TreeViewEventHandler(tv_AfterSelect); } + #endregion + #region MenuSupport private void tv_AfterSelect(object sender, TreeViewEventArgs e) { OnNodeSelectionChange(sender, new vlnTreeEventArgs(e.Node)); } + // use to determine which menu items have been selected for those tree nodes + // that allow more than one type of operation associated with their selection. + public enum MenuSelections : int + { + None = 0, Folder = 1, DocVersion = 2, Procedure = 3, ProcedureBefore = 4, ProcedureAfter = 5, Section = 6, SectionBefore = 7, SectionAfter = 8, Step = 9, StepBefore = 10, StepAfter = 11 + } void tv_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { - TreeNode tn = this.GetNodeAt(new Point(e.X, e.Y)); + VETreeNode tn = this.GetNodeAt(new Point(e.X, e.Y)) as VETreeNode; if (tn != null) { - this.SelectedNode = tn; + this.SelectedNode = tn as TreeNode; Application.DoEvents(); // Display Menu ToolStripMenuItem mi = new ToolStripMenuItem(); ContextMenu cm = new ContextMenu(); - cm.MenuItems.Add("New...",new EventHandler(mi_Click)); - cm.MenuItems.Add("Cut", new EventHandler(mi_Click)); - cm.MenuItems.Add("Copy", new EventHandler(mi_Click)); - cm.MenuItems.Add("Paste", new EventHandler(mi_Click)); - cm.MenuItems.Add("Delete", new EventHandler(mi_Click)); + + #region Menu_New + if (tn.VEObject as FolderInfo != null) + { + // For Folders, if no children, can add either docversion or folder. If children are + // folders then can only add another folder, and if children are docversions can only + // add docversion. + FolderInfo fi = tn.VEObject as FolderInfo; + if (fi.FolderDocVersionCount == 0) cm.MenuItems.Add("New Folder", new EventHandler(mi_Click)); + if (fi.ChildFolderCount == 0) cm.MenuItems.Add("New Document Version", new EventHandler(mi_Click)); + } + else if (tn.VEObject as DocVersionInfo != null) // DocVersions can only contain procs + cm.MenuItems.Add("New Procedure", new EventHandler(mi_Click)); + else if (tn.VEObject as ProcedureInfo != null) // Procs can only contain sections + { + cm.MenuItems.Add("New Procedure Before", new EventHandler(mi_Click)); + cm.MenuItems.Add("New Procedure After", new EventHandler(mi_Click)); + cm.MenuItems.Add("New Section", new EventHandler(mi_Click)); + } + else if (tn.VEObject as SectionInfo != null) + { + // A step Section can contain other steps or can contain subsections (either step section + // or word doc section). Also note that there can be a mix. + // A word doc section can contain another subsection (either step section or word doc section), + // but cannot contain steps. + SectionInfo si = tn.VEObject as SectionInfo; + // Do not need step versus Word doc options, user enters this in property page during + // insert process. + cm.MenuItems.Add("New Section Before", new EventHandler(mi_Click)); + cm.MenuItems.Add("New Section After", new EventHandler(mi_Click)); + cm.MenuItems.Add("New Subsection", new EventHandler(mi_Click)); + if (si.IsStepSection) cm.MenuItems.Add("New Step", new EventHandler(mi_Click)); + } + else if (tn.VEObject as StepInfo != null) + { + cm.MenuItems.Add("New Step Before", new EventHandler(mi_Click)); + cm.MenuItems.Add("New Step After", new EventHandler(mi_Click)); + } + #endregion + #region Menu_Open + if (!tn.IsExpanded && tn.VEObject as SectionInfo != null) + { + SectionInfo si = tn.VEObject as SectionInfo; + if (si.IsStepSection) cm.MenuItems.Add("Open", new EventHandler(mi_Click)); + } + else if (!tn.IsExpanded && tn.VEObject as StepInfo != null) + { + StepInfo stpi = tn.VEObject as StepInfo; + if (stpi.HasChildren) cm.MenuItems.Add("Open", new EventHandler(mi_Click)); + } + else if (!tn.IsExpanded) + cm.MenuItems.Add("Open", new EventHandler(mi_Click)); + #endregion + #region Menu_CutCopy + // For initial release, cut/copy are not available for folders or docversions + if (tn.VEObject as FolderInfo != null && tn.VEObject as DocVersionInfo != null) + { + cm.MenuItems.Add("Cut (not supported yet)", new EventHandler(mi_Click)); + cm.MenuItems.Add("Copy (not supported yet)", new EventHandler(mi_Click)); + } + #endregion + #region MenuPaste + if (CanPaste)cm.MenuItems.Add("Paste (not supported yet)", new EventHandler(mi_Click)); + #endregion + #region Menu_Delete + // Add delete to the menu unless at the very 'top' node. + if (tn.Parent!=null) cm.MenuItems.Add("Delete", new EventHandler(mi_Click)); + #endregion + #region Menu_Properties cm.MenuItems.Add("Properties...", new EventHandler(mi_Click)); + #endregion cm.Show(this, new Point(e.X, e.Y)); } } @@ -141,20 +277,45 @@ namespace Volian.Controls.Library void mi_Click(object sender, EventArgs e) { MenuItem mi = (MenuItem)sender; + SelectedNode.Expand(); switch (mi.Text) { - case "New..."://Add a new child node at the current location - // Should Give the option to the controling code to Add a New Node - SelectedNode.Expand(); - TreeNode tn = OnNodeNew(this, new vlnTreeEventArgs(SelectedNode)); - if (tn != null) - { - SelectedNode.Nodes.Add(tn); - if (LabelEdit) - tn.BeginEdit(); - else - SelectedNode = tn; - } + case "Open": + OpenNode(); + break; + case "New Folder"://Add a new child node at the current location + tv_NodeNew(MenuSelections.Folder); + break; + case "New Document Version": + tv_NodeNew(MenuSelections.DocVersion); + break; + case "New Procedure": + tv_NodeNew(MenuSelections.Procedure); + break; + case "New Procedure Before": + tv_NodeNew(MenuSelections.ProcedureBefore); + break; + case "New Procedure After": + tv_NodeNew(MenuSelections.ProcedureAfter); + break; + case "New Section": + case "New Subsection": + tv_NodeNew(MenuSelections.Section); + break; + case "New Section Before": + tv_NodeNew(MenuSelections.SectionBefore); + break; + case "New Section After": + tv_NodeNew(MenuSelections.SectionAfter); + break; + case "New Step Before": + tv_NodeNew(MenuSelections.StepBefore); + break; + case "New Step After": + tv_NodeNew(MenuSelections.StepAfter); + break; + case "New Step": + tv_NodeNew(MenuSelections.Step); break; case "Cut"://Cut the selected node // Cut to Clipboard @@ -167,11 +328,17 @@ namespace Volian.Controls.Library // if it is from a cut then when the paste is done it should be set to a copy break; case "Delete"://Delete the selected node - if(OnNodeDelete(this, new vlnTreeEventArgs(SelectedNode))) + if (tv_NodeDelete()) + { + TreeNode myParent = SelectedNode.Parent; SelectedNode.Remove(); + SelectedNode = myParent; + OnNodeSelect(this, new vlnTreeEventArgs(SelectedNode)); + } break; case "Properties..."://Show the properties for the selected node - OnNodeProperties(this,new vlnTreeEventArgs(SelectedNode)); + SetLastValues((VETreeNode)SelectedNode); + SetupNodeProperties(); break; default: MessageBox.Show(string.Format("Unrecognized Menu Item '{0}'", mi.Text)); @@ -179,6 +346,357 @@ namespace Volian.Controls.Library } } #endregion + #region PropertyPagesInterface + private void SetupNodeProperties() + { + VETreeNode tn = SelectedNode as VETreeNode; + if (tn==null)return; + + if ((tn.VEObject as FolderInfo) != null) + OpenProperties(tn.VEObject as FolderInfo); + else if ((tn.VEObject as DocVersionInfo) != null) + OpenProperties(tn.VEObject as DocVersionInfo); + else if ((tn.VEObject as ProcedureInfo) != null) + OpenProperties(tn.VEObject as ProcedureInfo); + else if ((tn.VEObject as SectionInfo) != null) + OpenProperties(tn.VEObject as SectionInfo); + else if ((tn.VEObject as StepInfo) != null) + MessageBox.Show("Open up info tab or whatever is associated with step"); + tn.RefreshNode(); + } + private void OpenProperties(FolderInfo folderInfo) + { + using (Folder folder = folderInfo.Get()) + { + if(OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(string.Format("{0} Properties", folder.FolderConfig.Name),folder.FolderConfig))==DialogResult.OK) + folder.Save().Dispose(); + } + } + private void OpenProperties(DocVersionInfo dvInfo) + { + using (DocVersion dv = dvInfo.Get()) + { + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(string.Format("{0} Properties", dv.DocVersionConfig.Name), dv.DocVersionConfig)) == DialogResult.OK) + dv.Save().Dispose(); + } + } + private void OpenProperties(ProcedureInfo procInfo) + { + using (Procedure proc = procInfo.Get()) + { + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(string.Format("{0} {1} Properties", proc.ProcedureConfig.Number, proc.ProcedureConfig.Title), proc.ProcedureConfig)) == DialogResult.OK) + proc.Save().Dispose(); + } + } + private void OpenProperties(SectionInfo sectInfo) + { + using (Section sect = sectInfo.Get()) + { + string title = null; + if (sectInfo.SectionConfig.Number.Length > 0) + title = string.Format("{0} {1} Properties", sectInfo.SectionConfig.Number, sectInfo.SectionConfig.Title); + else + title = string.Format("{0} Properties", sectInfo.SectionConfig.Title); + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(title, sect.SectionConfig)) == DialogResult.OK) + sect.Save().Dispose(); + sect.MyContent.Dispose(); // Force Dispose of related content + } + } + #endregion + #region OpenNode + private void tv_KeyPress(object sender, KeyPressEventArgs e) + { + if (e.KeyChar == '\r') + { + OpenNode(); + e.Handled = true; + } + } + public void OpenNode() + { + VETreeNode tn = SelectedNode as VETreeNode; + if (tn != null) + { + if (tn.VEObject.GetType() == typeof(FolderInfo) || tn.VEObject.GetType() == typeof(DocVersionInfo)) + { + if (tn.Nodes.Count > 0) + { + tn.Expand(); + SelectedNode = tn.Nodes[0]; + Focus(); + } + } + else + OnNodeSelect(this, new vlnTreeEventArgs(SelectedNode)); + } + } + #endregion + #region InsertAllLevels + public void tv_NodeNew(MenuSelections newtype) + { + VETreeNode tn = null; + SetLastValues((VETreeNode)SelectedNode); + + #region InsertFolderOrDocVersion + if (_LastFolderInfo != null) + { + using (Folder parentfolder = _LastFolderInfo.Get()) + { + if (newtype == MenuSelections.DocVersion) + { + using (DocVersion docversion = DocVersion.MakeDocVersion(parentfolder, "New Document Version", "Title", null, null, null)) + { + ShowBrokenRules(docversion.BrokenRulesCollection); + SetLastValues(DocVersionInfo.Get(docversion.VersionID)); + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Document Version", docversion.DocVersionConfig)) == DialogResult.OK) + docversion.Save().Dispose(); + tn = new VETreeNode(_LastDocVersionInfo); + + } + } + else if (newtype == MenuSelections.Folder) + { + string uniquename = _LastFolderInfo.UniqueChildName("New Folder"); + using (Folder folder = Folder.MakeFolder(parentfolder, parentfolder.MyConnection, uniquename, string.Empty, "Short Name", null, string.Empty, DateTime.Now, "Test")) + { + ShowBrokenRules(folder.BrokenRulesCollection); + SetLastValues(FolderInfo.Get(folder.FolderID)); + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs(uniquename, folder.FolderConfig)) == DialogResult.OK) + folder.Save().Dispose(); + tn = new VETreeNode((IVEDrillDownReadOnly)_LastFolderInfo); + } + } + SelectedNode.Nodes.Add(tn); // add tree node to end of list. + } + } + #endregion + #region InsertProcedure + else if (newtype == MenuSelections.Procedure) + { + using (Procedure procedure = Procedure.MakeProcedure(_LastDocVersionInfo, _LastDocVersionInfo.Procedures.Count!=0?_LastDocVersionInfo.Procedures[_LastDocVersionInfo.Procedures.Count-1]:null, null, "New Procedure", 0)) + { + ShowBrokenRules(procedure.BrokenRulesCollection); + SetLastValues(ProcedureInfo.Get(procedure.ItemID)); + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Procedure", procedure.ProcedureConfig)) == DialogResult.OK) + procedure.Save().Dispose(); + tn = new VETreeNode(_LastProcedureInfo); + SelectedNode.Nodes.Add(tn); // add tree node to end of list. + } + } + else if (newtype == MenuSelections.ProcedureAfter || newtype == MenuSelections.ProcedureBefore) + { + int tvindex = SelectedNode.Index; + // if inserting before, the parent is set in case previous is null, i.e. beginning of the list. + using (Procedure procedure = Procedure.MakeProcedure((newtype == MenuSelections.ProcedureAfter) ? null : _LastProcedureInfo.ActiveParent, (newtype == MenuSelections.ProcedureAfter) ? _LastProcedureInfo : _LastProcedureInfo.MyPrevious, null, "New Procedure", 0)) + { + ShowBrokenRules(procedure.BrokenRulesCollection); + SetLastValues(ProcedureInfo.Get(procedure.ItemID)); + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Procedure", procedure.ProcedureConfig)) == DialogResult.OK) + procedure.Save().Dispose(); + tn = new VETreeNode(_LastProcedureInfo); + TreeNode par = SelectedNode.Parent; + par.Nodes.Insert(tvindex + ((newtype == MenuSelections.ProcedureBefore) ? 0 : 1), tn); + } + } + #endregion + #region InsertSection + else if (newtype == MenuSelections.Section) // Insert subsection at end of parents section list + { + if (!(_LastProcedureInfo == null) || !(_LastSectionInfo == null)) + { + using (Section section = Section.MakeSection(_LastItemInfo, _LastItemInfo.LastChild(E_FromType.Section), null, "New Section", 10000))// not sure of type - dataloader has: 10000+docstyleindx + { + ShowBrokenRules(section.BrokenRulesCollection); + SetLastValues(SectionInfo.Get(section.ItemID)); + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Section", section.SectionConfig)) == DialogResult.OK) + { + section.Save().Dispose(); + FinishSectionSave(section); // make a word document if type was set to word document. + } + + tn = new VETreeNode(_LastSectionInfo); + SelectedNode.Nodes.Add(tn); // add tree node to end of list. + } + } + } + else if (newtype == MenuSelections.SectionAfter || newtype == MenuSelections.SectionBefore) + { + int tvindex = SelectedNode.Index; + // if inserting before, the parent is set in case previous is null, i.e. beginning of the list. + //ItemInfo parent = (newtype == MenuSelections.SectionAfter) ? null : _LastSectionInfo.MyParent; + using (Section section = Section.MakeSection((newtype == MenuSelections.SectionAfter) ? null : _LastSectionInfo.MyParent, (newtype == MenuSelections.SectionAfter) ? _LastSectionInfo : _LastSectionInfo.MyPrevious, null, "New Section", 10000)) + { + ShowBrokenRules(section.BrokenRulesCollection); + SetLastValues(SectionInfo.Get(section.ItemID)); + if (OnNodeOpenProperty(this, new vlnTreePropertyEventArgs("New Section", section.SectionConfig)) == DialogResult.OK) + { + section.Save().Dispose(); + FinishSectionSave(section); // make a word document if type was set to word document. + } + tn = new VETreeNode(_LastSectionInfo); + TreeNode par = SelectedNode.Parent; + par.Nodes.Insert(tvindex + ((newtype == MenuSelections.SectionBefore) ? 0 : 1), tn); + } + } + #endregion + #region InsertStep + else if (newtype == MenuSelections.Step) // insert step from section - no substeps from tree. + { + using (Step step = Step.MakeStep(_LastItemInfo, _LastItemInfo.LastChild(E_FromType.Step), null, "New Step", 20001, E_FromType.Step)) + { + ShowBrokenRules(step.BrokenRulesCollection); + SetLastValues(StepInfo.Get(step.ItemID)); + tn = new VETreeNode(_LastStepInfo); + SelectedNode.Nodes.Add(tn); // add tree node to end of list. + } + } + else if (newtype == MenuSelections.StepAfter || newtype == MenuSelections.StepBefore && _LastStepInfo != null) + { + int tvindex = SelectedNode.Index; + // if inserting before, the parent is set in case previous is null, i.e. beginning of the list. + ItemInfo parent = (newtype == MenuSelections.StepAfter) ? null : _LastStepInfo.MyParent; + using (Step step = Step.MakeStep(parent, (newtype == MenuSelections.StepAfter) ? _LastStepInfo : _LastStepInfo.MyPrevious, null, "New Step", 20001, E_FromType.Step)) + { + ShowBrokenRules(step.BrokenRulesCollection); + SetLastValues(StepInfo.Get(step.ItemID)); + tn = new VETreeNode(_LastStepInfo); + TreeNode par = SelectedNode.Parent; + par.Nodes.Insert(tvindex + ((newtype == MenuSelections.StepBefore) ? 0 : 1), tn); + } + } + #endregion + + SelectedNode = tn; + OnNodeSelect(this, new vlnTreeEventArgs(SelectedNode)); + Refresh(); + } + /// + /// NewName will check the existing children to assure that the name is not a duplicate name. + /// + /// + /// + /// + //private string NewName(FolderInfo parentFolderInfo, string folderName) + //{ + // string retval = folderName; + // int iSuffix = -1; + // parentFolderInfo.RefreshChildFolders(); + // foreach (FolderInfo fi in parentFolderInfo.ChildFolders) + // { + // if (fi.Name.StartsWith(folderName)) + // { + // if (fi.Name == folderName) + // iSuffix = 0; + // else if (Regex.IsMatch(fi.Name, folderName + "[_][0-9]+")) + // { + // int ii = int.Parse(fi.Name.Substring(1 + folderName.Length)); + // if (ii > iSuffix) iSuffix = ii; + // } + // } + // } + // if (iSuffix >= 0) + // retval = string.Format("{0}_{1}", folderName, iSuffix + 1); + // // Console.WriteLine("FolderName = '{0}'", retval); + // return retval; + //} + private void FinishSectionSave(Section section) + { + ItemInfo sectinfo = ItemInfo.Get(section.ItemID); + + // need to find out if this is a word document type section & if it is, create a new word doc. + bool isWordSect = true; + int sectype = (int) sectinfo.MyContent.Type - 10000; + PlantFormat pf = sectinfo.ActiveFormat.PlantFormat; + for (int i = 0; i < pf.DocStyles.DocStyleList.Count; i++) + { + if (pf.DocStyles.DocStyleList[i].Index == sectype) + { + isWordSect = !pf.DocStyles.DocStyleList[i].IsStepSection; + break; + } + } + if (isWordSect && !sectinfo.HasWordContent) + { + Content cont = Content.Get(sectinfo.MyContent.ContentID); + + Byte[] tstbyte = System.Text.Encoding.Default.GetBytes("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033\\uc1 }\r\n"); + Document doc = Document.MakeDocument(null, tstbyte, null, null); + Entry entry = cont.MyEntry; + entry.MyDocument = Document.Get(doc.DocID); + cont.Save().Dispose(); + } + } + private void ShowBrokenRules(BrokenRulesCollection brs) + { + if (brs != null) + { + foreach (BrokenRule br in brs) + { + Console.WriteLine("broken rule {0}", br.Description); + } + } + } + #endregion + #region DeleteAllLevels + private bool tv_NodeDelete() + { + OnNodeSelect(this, new vlnTreeEventArgs(SelectedNode)); + SetLastValues((VETreeNode)SelectedNode); + + DialogResult result = MessageBox.Show("Are you sure you want to delete " + SelectedNode.Text, "Verify Delete", + MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (result == DialogResult.Yes) + { + if (_LastFolderInfo != null) + { + Folder.Delete(_LastFolderInfo.FolderID); + _LastFolderInfo = null; + return true; + } + else if (_LastDocVersionInfo != null) + { + DocVersion.Delete(_LastDocVersionInfo.VersionID); + _LastDocVersionInfo = null; + return true; + } + else if (_LastProcedureInfo != null) + { + Procedure.Delete(_LastProcedureInfo.ItemID); + _LastProcedureInfo = null; + return true; + } + else if (_LastSectionInfo != null) + { + Section.Delete(_LastSectionInfo.ItemID); + _LastSectionInfo = null; + return true; + } + else if (_LastStepInfo != null) + { + Step.Delete(_LastStepInfo.ItemID); + _LastStepInfo = null; + return true; + } + } + return false; + } + #endregion + #region SetLastValuesAndSaveIfChangedStuff + private void SetLastValues(VETreeNode node) + { + _LastTreeNode = node; + SetLastValues(node.VEObject); + } + private void SetLastValues(IVEDrillDownReadOnly veobject) + { + _LastFolderInfo = veobject as FolderInfo; + _LastDocVersionInfo = veobject as DocVersionInfo; + _LastProcedureInfo = veobject as ProcedureInfo; + _LastSectionInfo = veobject as SectionInfo; + _LastStepInfo = veobject as StepInfo; + _LastItemInfo = veobject as ItemInfo; + } + #endregion #region Cursor private bool SetupDragCursor(ImageList il, TreeNode tn) { @@ -240,6 +758,8 @@ namespace Volian.Controls.Library } } #endregion + #region DragDrop + ImageList _dragImageList = new ImageList(); public enum DropPosition : int { Child = 0, Before = 1, After = 2 @@ -298,14 +818,14 @@ namespace Volian.Controls.Library } else // Last Third - After Now I need to check the X value { - if (_dropNode.NextVisibleNode !=null && _dropNode.Nodes.Count > 0)// Has Children - Insert first child + if (_dropNode.NextVisibleNode != null && _dropNode.Nodes.Count > 0 && _dropNode.IsExpanded)// Has Children & Expanded - Insert first child { // _dropNode = _dropNode.Nodes[0]; _index = 0; _position = DropPosition.Before; _location = string.Format("Before2 {0}[{1}] y={2}", _dropNode.Text, _index, OffsetY); } - else // No Children - Insert Next at various levels + else // No Children or Children Collapsed - Insert Next at various levels depending upon horizontal location. { Point pt = tv.PointToClient(new Point(e.X, e.Y)); TreeNode nextParent = _dropNode.NextNode; @@ -387,7 +907,7 @@ namespace Volian.Controls.Library { return; } - // if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Line at {0} Node {1}[{2}] {3}", _location, _dropNode.Text, _index, _position.ToString()); + if(_MyLog.IsInfoEnabled)_MyLog.InfoFormat("Line at {0} Node {1}[{2}] {3}", _location, _dropNode.Text, _index, _position.ToString()); Color lc = (_position == DropPosition.After ? Color.Red : Color.Blue); Brush lb = (_position == DropPosition.After ? Brushes.Red : Brushes.Blue); Point[] RightTriangle; @@ -493,8 +1013,25 @@ namespace Volian.Controls.Library ee = DragDropEffects.Copy; // Copy it else ee = DragDropEffects.Move; // Move it - if (IsChild(dragNode, dl.DropNode)) - ee = DragDropEffects.None; // Don't copy or move to a child node + if (IsChild(dragNode, dl.DropNode)) // Don't copy or move to a child node + ee = DragDropEffects.None; + else if (IsDocVersion((VETreeNode)dragNode)) // Don't move docversions + ee = DragDropEffects.None; + else if (IsFolder((VETreeNode)dragNode)) // Folder move is only valid if moving to folder with NO docversions + { + FolderInfo fdropi = ((VETreeNode)dl.DropNode).VEObject as FolderInfo; + if (fdropi == null || fdropi.FolderDocVersionCount > 0) ee = DragDropEffects.None; + } + else if (IsSection((VETreeNode)dragNode)) + { + // A section can be moved within a procedure or to a section within the same procedure... + // For HLP, just move within the same procedure + // TODO: allow for section move within subsections. + ProcedureInfo pdropi = ((VETreeNode)dl.DropNode).VEObject as ProcedureInfo; + if (pdropi == null || (dragNode.Parent != dl.DropNode)) ee = DragDropEffects.None; + } + else if (!IsFolder((VETreeNode)dragNode) && (dragNode.Parent != dl.DropNode)) + ee = DragDropEffects.None; if (e.Effect != ee) e.Effect = ee; dl.ShowLocation(e, dl.Equals(_LastDropLocation)); _LastDropLocation = dl; @@ -505,6 +1042,25 @@ namespace Volian.Controls.Library if(_MyLog.IsErrorEnabled)_MyLog.Error("tv_DragOver", ex); } } + + private bool IsSection(VETreeNode vETreeNode) + { + SectionInfo sectInfo = vETreeNode.VEObject as SectionInfo; + if (sectInfo != null) return true; + return false; + } + private bool IsProcedure(VETreeNode vETreeNode) + { + ProcedureInfo procInfo = vETreeNode.VEObject as ProcedureInfo; + if (procInfo != null) return true; + return false; + } + private bool IsDocVersion(VETreeNode dragNode) + { + DocVersionInfo dvInfo = dragNode.VEObject as DocVersionInfo; + if (dvInfo != null) return true; + return false; + } private static TreeNode GetTreeNodeFromData(IDataObject datobj) { foreach (string s in datobj.GetFormats()) @@ -520,6 +1076,10 @@ namespace Volian.Controls.Library } return null; } + private bool IsFolder(VETreeNode veTreeNode) + { + return (veTreeNode.VEObject.GetType() == typeof(FolderInfo)); + } private void tv_DragDrop(object sender, System.Windows.Forms.DragEventArgs e) { try @@ -527,6 +1087,7 @@ namespace Volian.Controls.Library TreeNode dragNode = GetTreeNodeFromData(e.Data); DragHelper.ImageList_DragLeave(this.Handle); int index = _LastDropLocation.Index + (_LastDropLocation.Position == DropPosition.After ? 1 : 0); + int myIndex = index; if (dragNode.Parent == _LastDropLocation.DropNode && dragNode.Index <= _LastDropLocation.Index) index--; if (e.Effect == DragDropEffects.Move)// If Move Remove drag node from parent dragNode.Remove(); @@ -534,7 +1095,87 @@ namespace Volian.Controls.Library dragNode = Clone(dragNode); _LastDropLocation.DropNode.Nodes.Insert(index, dragNode); this.SelectedNode = dragNode; - OnNodeDragDrop(sender, new vlnTreeEventArgs(dragNode, _LastDropLocation.DropNode,index)); + FolderInfo fdragi = ((VETreeNode)dragNode).VEObject as FolderInfo; + FolderInfo fdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as FolderInfo; + if (fdragi != null && fdropi != null && fdropi.FolderDocVersionCount==0) + { + using (Folder fdrag = fdragi.Get()) + { + using (Folder fdrop = fdropi.Get()) + { + fdrag.ManualOrder = fdropi.NewManualOrder(myIndex); + fdrag.MyParent = fdrop; + fdrag.Save(); + } + } + return; + } + // No drag/drop supported for document versions. + + // Allow drag/drop of procedures within a Document Version (must have same parent). Note that drop location + // may either be a document version or a procedure depending on where the user wants to position the procedure. + ProcedureInfo pdragi = ((VETreeNode)dragNode).VEObject as ProcedureInfo; + ProcedureInfo pdropi = null; + if (pdragi != null) // moving a procedure + { + pdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as ProcedureInfo; + if (pdropi != null && pdragi.ActiveParent == pdropi.ActiveParent) + { + pdragi.MoveProcedure(pdragi.ActiveParent, myIndex); + return; + } + DocVersionInfo dvdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as DocVersionInfo; + DocVersionInfo dvdragpar = pdragi.ActiveParent as DocVersionInfo; + if (dvdropi != null && dvdragpar.VersionID == dvdropi.VersionID) + { + pdragi.MoveProcedure(dvdropi, myIndex); + return; + } + } + + // Allow drag/drop of sections within the same procedure or same section (if subsection) (must have same parent) + SectionInfo sdragi = ((VETreeNode)dragNode).VEObject as SectionInfo; + SectionInfo sdropi = null; + if (sdragi != null) // moving a section + { + sdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as SectionInfo; + if (sdropi != null && sdragi.ActiveParent == sdropi.ActiveParent) + { + sdragi.MoveSection(sdragi, myIndex); + return; + } + pdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as ProcedureInfo; + if (pdropi != null && sdragi.MyParent.ItemID == pdropi.ItemID) + { + sdragi.MoveSection(pdropi, myIndex); + return; + } + } + + // Allow drag/drop of steps within the same parent only + StepInfo stdragi = ((VETreeNode)dragNode).VEObject as StepInfo; + StepInfo stdropi = null; + if (stdragi != null) // moving a step + { + stdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as StepInfo; + if (stdropi != null && stdragi.ActiveParent == stdropi.ActiveParent) + { + stdragi.MoveStep(stdragi.ActiveParent, myIndex); + return; + } + sdropi = ((VETreeNode)_LastDropLocation.DropNode).VEObject as SectionInfo; + if (sdropi != null && stdragi.MyParent.ItemID == sdropi.ItemID) + { + stdragi.MoveStep(stdragi.ActiveParent, myIndex); + return; + } + // the following handles items under the app nodes of 'steps', 'notes', 'cautions', etc. + if (sdropi == null && dragNode.Parent == _LastDropLocation.DropNode) + { + stdragi.MoveStep(stdragi.ActiveParent, myIndex); + return; + } + } } catch (Exception ex) { @@ -601,7 +1242,9 @@ namespace Volian.Controls.Library foreach (TreeNode tc in parent.Nodes) if (IsChild(tc, child)) return true;//Check all children return false;// Must not be a child at this level } + #endregion } + #region DragHelper public class DragHelper { [DllImport("comctl32.dll")] @@ -630,4 +1273,5 @@ namespace Volian.Controls.Library InitCommonControls(); } } + #endregion }