private void butImport_Click(object sender, EventArgs e) { try { using (OpenFileDialog openDialog = ImportDialogSetup()) { if (openDialog.ShowDialog() != DialogResult.OK) { return; //User cancelled out of OpenFileDialog } string fileContents = File.ReadAllText(openDialog.FileName); TransferableAutoNotes import = JsonConvert.DeserializeObject <TransferableAutoNotes>(fileContents); AutoNoteControls.RemoveDuplicatesFromList(import.AutoNoteControls, import.AutoNotes); AutoNoteControls.InsertBatch(import.AutoNoteControls); AutoNotes.InsertBatch(import.AutoNotes); DataValid.SetInvalid(InvalidType.AutoNotes); AutoNoteL.FillListTree(treeNotes, _userOdCurPref); SecurityLogs.MakeLogEntry(Permissions.AutoNoteQuickNoteEdit, 0, $"Auto Note Import. {import.AutoNotes.Count} new Auto Notes, {import.AutoNoteControls.Count} new Prompts"); MsgBox.Show(Lans.g(this, "Auto Notes successfully imported!") + "\r\n" + import.AutoNotes.Count + " " + Lans.g(this, "new Auto Notes") + "\r\n" + import.AutoNoteControls.Count + " " + Lans.g(this, "new Prompts")); } } catch (Exception err) { FriendlyException.Show(Lans.g(this, "Auto Note(s) failed to import."), err); } }
private void FillListTree() { List <long> listExpandedDefNums = new List <long>(); if (_userOdCurPref != null) //if this is the fill on load, the node count will be 0, expanded node list from pref { listExpandedDefNums = _userOdCurPref.ValueString.Split(',').Where(x => x != "" && x != "0").Select(x => PIn.Long(x)).ToList(); } //clear current tree contents treeListMain.BeginUpdate(); treeListMain.SelectedNode = null; treeListMain.Nodes.Clear(); //add categories with all auto notes that are assigned to that category List <long> listCatDefNums = _listAutoNoteCatDefs.Select(x => x.DefNum).ToList(); //call recursive function GetNodeAndChildren for any root cat (where def.ItemValue is blank) and any def with invalid parent def num (ItemValue) _listAutoNoteCatDefs.FindAll(x => string.IsNullOrWhiteSpace(x.ItemValue) || !listCatDefNums.Contains(PIn.Long(x.ItemValue))) .ForEach(x => treeListMain.Nodes.Add(CreateNodeAndChildren(x))); //child cats and categorized auto notes added in recursive function //add any uncategorized auto notes after the categorized ones and only for the root nodes AutoNotes.GetWhere(x => x.Category == 0 || !listCatDefNums.Contains(x.Category)) .ForEach(x => treeListMain.Nodes.Add(new TreeNode(x.AutoNoteName, 1, 1) { Tag = x })); if (listExpandedDefNums.Count > 0) { treeListMain.Nodes.OfType <TreeNode>().SelectMany(x => GetNodeAndChildren(x)) .Where(x => x.Tag is Def && listExpandedDefNums.Contains(((Def)x.Tag).DefNum)).ToList() .ForEach(x => x.Expand()); } treeListMain.EndUpdate(); }
private void FillList() { AutoNotes.RefreshCache(); listMain.Items.Clear(); for (int i = 0; i < AutoNotes.Listt.Count; i++) { listMain.Items.Add(AutoNotes.Listt[i].AutoNoteName); } }
private void FillList() { listBoxAutoNotes.Items.Clear(); AutoNotes.Refresh(); for (int i = 0; i < AutoNotes.Listt.Count; i++) { listBoxAutoNotes.Items.Add(AutoNotes.Listt[i].AutoNoteName); } }
private void FormAutoNoteCompose_Load(object sender, EventArgs e) { AutoNotes.RefreshCache(); AutoNoteControls.RefreshCache(); listMain.Items.Clear(); for (int i = 0; i < AutoNotes.Listt.Count; i++) { listMain.Items.Add(AutoNotes.Listt[i].AutoNoteName); } }
private void butOK_Click(object sender, EventArgs e) { AutoNoteCur.AutoNoteName = textBoxAutoNoteName.Text; AutoNoteCur.MainText = textMain.Text; if (IsNew) { AutoNotes.Insert(AutoNoteCur); } else { AutoNotes.Update(AutoNoteCur); } DialogResult = DialogResult.OK; }
private void butDelete_Click(object sender, EventArgs e) { if (!MsgBox.Show(this, MsgBoxButtons.OKCancel, "Delete this autonote?")) { return; } if (IsNew) { DialogResult = DialogResult.Cancel; return; } AutoNotes.Delete(AutoNoteCur.AutoNoteNum); DialogResult = DialogResult.OK; }
///<summary>Recursive function, returns a tree node with all descendants, including all auto note children for this def cat and all children for ///any cat within this this cat. Auto Notes that are at the 'root' level (considered uncategorized) have to be added separately after filling the ///rest of the tree with this function and will be at the bottom of the root node list.</summary> private TreeNode CreateNodeAndChildren(Def defCur) { List <TreeNode> listChildNodes = _listAutoNoteCatDefs .Where(x => !string.IsNullOrWhiteSpace(x.ItemValue) && x.ItemValue == defCur.DefNum.ToString()) .Select(CreateNodeAndChildren).ToList(); listChildNodes.AddRange(AutoNotes.GetWhere(x => x.Category == defCur.DefNum) .Select(x => new TreeNode(x.AutoNoteName, 1, 1) { Tag = x })); return(new TreeNode(defCur.ItemName, 0, 0, listChildNodes.OrderBy(x => x.Tag is AutoNote).ThenBy(x => x.Name).ToArray()) { Tag = defCur }); }
private void FillGrid() { AutoNotes.RefreshCache(); List <AutoNote> listAutoNotes = AutoNotes.GetDeepCopy(); gridMain.BeginUpdate(); gridMain.ListGridColumns.Clear(); gridMain.ListGridColumns.Add(new GridColumn("", 100)); gridMain.ListGridRows.Clear(); GridRow row; foreach (AutoNote autoNote in listAutoNotes) { row = new GridRow(); row.Cells.Add(autoNote.AutoNoteName); row.Tag = autoNote; gridMain.ListGridRows.Add(row); } gridMain.EndUpdate(); }
private void butOK_Click(object sender, EventArgs e) { if (textBoxAutoNoteName.Text == "") { MsgBox.Show(this, "Please enter a name for the Auto Note into the text box"); return; } //bool IsUsed=AutoNotes.AutoNoteNameUsed(textBoxAutoNoteName.Text.ToString(),AutoNoteCur.AutoNoteName); //if(IsUsed) { // MsgBox.Show(this,"This name is already used please choose a different name"); // return; //} /*if (listBoxControlsToIncl.Items.Count==0) { * MsgBox.Show(this, "Please add some controls to the Auto Note"); * return; * }*/ //Save changes to database here //Saves the items in the listboxControlsToIncl in a array that will be passed on string controlsToIncText = ""; for (int i = 0; i < listBoxControlToIncNum.Items.Count; i++) { if (listBoxControlsToIncl.Items[i].ToString() != "") { controlsToIncText = controlsToIncText + listBoxControlToIncNum.Items[i].ToString() + ","; } } AutoNoteCur.ControlsToInc = controlsToIncText; AutoNoteCur.AutoNoteName = textBoxAutoNoteName.Text.ToString(); if (IsNew) { AutoNotes.Insert(AutoNoteCur); } else { AutoNotes.Update(AutoNoteCur); } DialogResult = DialogResult.OK; }
///<summary>Returns the AutoNoteName from the passed in promptRepsonse. Returns empty string if no valid AutoNote is found.</summary> private string GetAutoNoteName(string promptResponse) { string retVal = ""; Stack <int> stackBrackets = new Stack <int>(); //The AutoNoteResponseText should be in format "Auto Note Response Text : {AutoNoteName}". Go through each of the charactors in promptResponse //and find each of the possible AutoNote names. We need to do this in case the AutoNote name has brackets("{,}") in the name. for (int posCur = 0; posCur < promptResponse.Length; posCur++) { if (promptResponse[posCur] == '{') { stackBrackets.Push(posCur); //add the position of the '{' to the stack. continue; } if (promptResponse[posCur] != '}' || stackBrackets.Count() == 0) //continue if the the stack does not have an open '{', or this is not a '}' { continue; } //The posOpenBracket will include the '{'. We will have to remove it. int posOpenBracket = stackBrackets.Peek(); //Get the length of the possible autonote. The length will include the closing '}'. We will also need to remove it. int length = posCur - posOpenBracket; if (length < 1) { stackBrackets.Pop(); continue; } //Get string of possible AutoNoteName. Remove the bracket from the beginning and end. string autoNoteName = promptResponse.Substring(posOpenBracket + 1, length - 1); if (!string.IsNullOrEmpty(autoNoteName) && AutoNotes.IsValidAutoNote(autoNoteName)) { retVal = autoNoteName; break; } //no match found. Remove position from stack and continue. stackBrackets.Pop(); } return(retVal); //could be empty string if no valid autonote name is found }
private void butDelete_Click(object sender, EventArgs e) { //This is VERY new. Only allowed and visible for three categories so far: supply cats, claim payment types, and claim custom tracking. if (IsNew) { DialogResult = DialogResult.Cancel; return; } if (DefCur.Category == DefCat.ClaimCustomTracking && _defsList.Count(x => x.Category == DefCat.ClaimCustomTracking) == 1 || DefCur.Category == DefCat.InsurancePaymentType && _defsList.Count(x => x.Category == DefCat.InsurancePaymentType) == 1 || DefCur.Category == DefCat.SupplyCats && _defsList.Count(x => x.Category == DefCat.SupplyCats) == 1) { MsgBox.Show(this, "Cannot delete the last definition from this category."); return; } bool isAutoNoteRefresh = false; if (DefCur.Category == DefCat.AutoNoteCats && AutoNotes.GetExists(x => x.Category == DefCur.DefNum)) { if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "Deleting this Auto Note Category will uncategorize some auto notes. Delete anyway?")) { return; } isAutoNoteRefresh = true; } try{ Defs.Delete(DefCur); IsDeleted = true; if (isAutoNoteRefresh) //deleting an auto note category currently in use will uncategorize those auto notes, refresh cache { DataValid.SetInvalid(InvalidType.AutoNotes); } DialogResult = DialogResult.OK; } catch (ApplicationException ex) { MessageBox.Show(ex.Message); } }
private void butExport_Click(object sender, System.EventArgs e) { List <AutoNote> listCheckedAutoNotes = GetCheckedAutoNotes(treeNotes.Nodes); if (listCheckedAutoNotes.Count == 0) { MsgBox.Show(this, "You must select at least one Auto Note to export."); return; } try { string fileName; if (ODBuild.IsWeb()) { //file download dialog will come up later, after file is created. fileName = "autonotes.json"; } else { using (SaveFileDialog saveDialog = ExportDialogSetup()) { if (saveDialog.ShowDialog() != DialogResult.OK) { return; //user canceled out of SaveFileDialog } fileName = saveDialog.FileName; } } List <SerializableAutoNote> serializableAutoNotes = AutoNotes.GetSerializableAutoNotes(listCheckedAutoNotes); List <AutoNoteControl> listAutoNoteControls = AutoNoteControls.GetListByParsingAutoNoteText(serializableAutoNotes); List <SerializableAutoNoteControl> serializableAutoNoteControls = AutoNoteControls.GetSerializableAutoNoteControls(listAutoNoteControls); AutoNotes.WriteAutoNotesToJson(serializableAutoNotes, serializableAutoNoteControls, fileName); SecurityLogs.MakeLogEntry(Permissions.AutoNoteQuickNoteEdit, 0, "Auto Note Export"); MsgBox.Show(this, "Auto Note(s) successfully exported."); } catch (Exception err) { FriendlyException.Show("AutoNote(s) failed to export.", err); } }
private void treeNotes_DragDrop(object sender, DragEventArgs e) { if (_grayNode != null) { _grayNode.BackColor = Color.White; } if (!e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false)) { return; } TreeNode sourceNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode"); if (sourceNode == null || !(sourceNode.Tag is Def || sourceNode.Tag is AutoNote)) { return; } TreeNode topNodeCur = treeNotes.TopNode; if (treeNotes.TopNode == sourceNode && sourceNode.PrevVisibleNode != null) { //if moving the topNode to another category, make the previous visible node the topNode once the move is successful topNodeCur = sourceNode.PrevVisibleNode; } Point pt = ((TreeView)sender).PointToClient(new Point(e.X, e.Y)); TreeNode destNode = ((TreeView)sender).GetNodeAt(pt); if (destNode == null || !(destNode.Tag is Def || destNode.Tag is AutoNote)) //moving to root node (category 0) { if (sourceNode.Parent == null) //already at the root node, nothing to do { return; } if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "Move the selected " + (sourceNode.Tag is AutoNote?"Auto Note":"category") + " to the root level?")) { return; } if (sourceNode.Tag is Def) { ((Def)sourceNode.Tag).ItemValue = ""; } else //must be an AutoNote { ((AutoNote)sourceNode.Tag).Category = 0; } } else //moving to another folder (category) { if (destNode.Tag is AutoNote) { destNode = destNode.Parent; //if destination is AutoNote, set destination to the parent, which is the category def node for the note } if (!IsValidDestination(sourceNode, destNode, sourceNode.Tag is Def)) { return; } if (!MsgBox.Show(this, MsgBoxButtons.YesNo, "Move the selected " + (sourceNode.Tag is AutoNote?"Auto Note":"category") + (destNode == null?" to the root level":"") + "?")) { return; } //destNode will be null if a root AutoNote was selected as the destination long destDefNum = (destNode == null?0:((Def)destNode.Tag).DefNum); if (sourceNode.Tag is Def) { ((Def)sourceNode.Tag).ItemValue = (destDefNum == 0?"":destDefNum.ToString()); //make a DefNum of 0 be a blank string in the db, not a "0" string } else //must be an AutoNote { ((AutoNote)sourceNode.Tag).Category = destDefNum; } } if (sourceNode.Tag is Def) { Defs.Update((Def)sourceNode.Tag); DataValid.SetInvalid(InvalidType.Defs); } else //must be an AutoNote { AutoNotes.Update((AutoNote)sourceNode.Tag); DataValid.SetInvalid(InvalidType.AutoNotes); } treeNotes.TopNode = topNodeCur; //if sourceNode was the TopNode and was moved, make the TopNode the previous visible node AutoNoteL.FillListTree(treeNotes, _userOdCurPref); }
public static void FillListTree(TreeView treeNotes, UserOdPref _userOdCurPref) { List <long> listExpandedDefNums = new List <long>(); if (treeNotes.Nodes.Count == 0 && _userOdCurPref != null) //if this is the fill on load, the node count will be 0, expanded node list from pref { listExpandedDefNums = _userOdCurPref.ValueString.Split(',').Where(x => x != "" && x != "0").Select(x => PIn.Long(x)).ToList(); } else //either not fill on load or no user pref, store the expanded node state to restore after filling tree //only defs (category folders) can be expanded or have children nodes { listExpandedDefNums = treeNotes.Nodes.OfType <TreeNode>().SelectMany(x => GetNodeAndChildren(x)) .Where(x => x.IsExpanded && x.Tag is Def).Select(x => ((Def)x.Tag).DefNum).ToList(); } TreeNode selectedNode = treeNotes.SelectedNode; TreeNode topNode = null; string topNodePath = treeNotes.TopNode?.FullPath; treeNotes.BeginUpdate(); treeNotes.Nodes.Clear(); //clear current tree contents _dictChildNodesForDefNum = Defs.GetDefsForCategory(DefCat.AutoNoteCats, true).GroupBy(x => x.ItemValue ?? "0") .ToDictionary(x => PIn.Long(x.Key), x => new NodeChildren() { ListChildDefNodes = x.Select(y => new TreeNode(y.ItemName, 0, 0) { Tag = y }).ToList() }); Dictionary <long, List <TreeNode> > dictDefNumAutoNotes = AutoNotes.GetDeepCopy().GroupBy(x => x.Category) .ToDictionary(x => x.Key, x => x.Select(y => new TreeNode(y.AutoNoteName, 1, 1) { Tag = y }).ToList()); foreach (KeyValuePair <long, List <TreeNode> > kvp in dictDefNumAutoNotes) { if (_dictChildNodesForDefNum.ContainsKey(kvp.Key)) { _dictChildNodesForDefNum[kvp.Key].ListAutoNoteNodes = kvp.Value; } else { _dictChildNodesForDefNum[kvp.Key] = new NodeChildren() { ListAutoNoteNodes = kvp.Value }; } } List <TreeNode> listNodes = new List <TreeNode>(); //all nodes to add to tree, categories and autonotes NodeChildren nodeChildren; if (_dictChildNodesForDefNum.TryGetValue(0, out nodeChildren)) { nodeChildren.ListChildDefNodes.ForEach(SetAllDescendantsForNode); listNodes.AddRange(nodeChildren.ListChildDefNodes); listNodes.AddRange(nodeChildren.ListAutoNoteNodes); } treeNotes.Nodes.AddRange(listNodes.OrderBy(x => x, new NodeSorter()).ToArray()); //add node list to tree, after sorting List <TreeNode> listNodesCur = listNodes.SelectMany(x => GetNodeAndChildren(x)).ToList(); //get flat list of all nodes, copy entire tree foreach (TreeNode nodeCur in listNodesCur) { if (!string.IsNullOrEmpty(topNodePath) && nodeCur.FullPath == topNodePath) { topNode = nodeCur; } if (nodeCur.Tag is Def && listExpandedDefNums.Contains(((Def)nodeCur.Tag).DefNum)) { nodeCur.Expand(); } if (selectedNode == null) { continue; } if (Equals(nodeCur, selectedNode)) { treeNotes.SelectedNode = nodeCur; } } treeNotes.TopNode = topNode; if (topNode == null && treeNotes.Nodes.Count > 0) { treeNotes.TopNode = treeNotes.SelectedNode ?? treeNotes.Nodes[0]; } treeNotes.EndUpdate(); treeNotes.Focus(); }
///<summary>Returns the length prompt responses added to textMain.Text.</summary> private int PromptForAutoNotes(string noteToParse, List <AutoNoteListItem> listAutoNoteItem) { //AutoNote.MainText which should have all text and the prompts. string note = noteToParse; #region Insert Auto Note Text //Logic for determining where the note should go based on the users cursor location. int selectionStart = textMain.SelectionStart; if (selectionStart == 0) //Cursor is at the beginning of the textbox. { textMain.Text = note + textMain.Text; } else if (selectionStart == textMain.Text.Length - 1) //Cursor at end of textbox { textMain.Text = textMain.Text + note; } else if (selectionStart == -1) //If cursor location is unknown just append the text to the end { textMain.Text = textMain.Text + note; } else //Cursor is in between text. Insert at the selected position. { textMain.Text = textMain.Text.Substring(0, selectionStart) + note + textMain.Text.Substring(selectionStart); } #endregion //List of prompts for the auto note List <AutoNoteControl> prompts = new List <AutoNoteControl>(); //Prompts are stored in the form [Prompt: "PromptName"] List <Match> listPrompts = AutoNoteControls.GetPrompts(note); //Remove all matched prompts that do not exist in the database. listPrompts.RemoveAll(x => AutoNoteControls.GetByDescript(x.Value.Substring(9, x.Value.Length - 11)) == null); //Holds the PromptName from [Prompt: "PromptName"] string autoNoteDescript; AutoNoteControl control; string promptResponse; int matchloc; //This is the index of the Prompt location in textMain. int startLoc = 0; int retVal = 0; //the length of the notes added to textMain.Text. //used to keep track of the start position. This is needed set matchloc. Without this, match loc might find the wrong index. Stack <int> stackLoc = new Stack <int>(); stackLoc.Push(startLoc); bool isAutoNote = false; //Loop through all valid prompts for the given auto note. for (int i = 0; i < listPrompts.Count; i++) { //Find prompt location in the text and highlight yellow. matchloc = textMain.Text.IndexOf(listPrompts[i].Value, startLoc); if (matchloc == -1 || matchloc > textMain.TextLength) //The value wasn't found { continue; } startLoc = matchloc + 1; //Add one to look after the last match location. textMain.Select(matchloc, listPrompts[i].Value.Length); textMain.SelectionBackColor = Color.Yellow; textMain.SelectionLength = 0; Application.DoEvents(); //refresh the textbox so the yellow will show //Holds the PromptName from [Prompt: "PromptName"] autoNoteDescript = listPrompts[i].Value.Substring(9, listPrompts[i].Value.Length - 11); control = AutoNoteControls.GetByDescript(autoNoteDescript); //should never be null since we removed nulls above promptResponse = ""; if (control.ControlType == "Text") //Response just inserts text. No choosing options here. { FormAutoNotePromptText FormT = new FormAutoNotePromptText(autoNoteDescript); FormT.PromptText = control.ControlLabel; FormT.ResultText = control.ControlOptions; isAutoNote = false; if (i > 0) { FormT.IsGoBack = true; //user can go back if at least one item in the list exist } if (listAutoNoteItem.Count > i) { FormT.CurPromptResponse = listAutoNoteItem[i].AutoNotePromptResponseString; //pass the previous response to the form } FormT.ShowDialog(); if (FormT.DialogResult == DialogResult.Retry) //user clicked the go back button { GoBack(i, listAutoNoteItem); stackLoc.Pop(); //remove the start location startLoc = stackLoc.Peek(); //set the new start location i -= 2; continue; } if (FormT.DialogResult == DialogResult.OK) { promptResponse = FormT.ResultText; if (listAutoNoteItem.Count > i) //reponse already exist for this control type. Update it //We need to update retVal with the length of the new promptResponse. First, remove the previous prompts length. { retVal -= listAutoNoteItem[i].AutoNoteTextEndPos; //Update the retVal with the new promptResponse.Length. retVal += promptResponse.Length; //Update the rest of the AutoNoteItem with the new promptResponse. listAutoNoteItem[i].AutoNotePromptResponseString = promptResponse; listAutoNoteItem[i].AutoNoteTextStartPos = matchloc; listAutoNoteItem[i].AutoNoteTextEndPos = promptResponse.Length; } else { //This is a new response. Create a new AutoNoteListItem and add to retVal. retVal += promptResponse.Length; listAutoNoteItem.Add(new AutoNoteListItem(listPrompts[i].Value, promptResponse, matchloc, promptResponse.Length)); //add new response to the list } } else //User cancelled out of the auto note prompt text form or auto log off. { ResetTextMain(); return(-1); } } else if (control.ControlType == "OneResponse") { FormAutoNotePromptOneResp FormOR = new FormAutoNotePromptOneResp(autoNoteDescript); FormOR.PromptText = control.ControlLabel; FormOR.PromptOptions = control.ControlOptions; if (i > 0) { FormOR.IsGoBack = true; //user can go back if at least one item in the list exist } if (listAutoNoteItem.Count > i) { FormOR.CurPromptResponse = listAutoNoteItem[i].AutoNotePromptResponseString; //pass the previous response if exist to the form. } FormOR.ShowDialog(); if (FormOR.DialogResult == DialogResult.Retry) //user clicked the go back button { GoBack(i, listAutoNoteItem); stackLoc.Pop(); //remove the start location startLoc = stackLoc.Peek(); //set the new start location i -= 2; continue; } if (FormOR.DialogResult == DialogResult.OK) { promptResponse = FormOR.ResultText; //The promptResponse will have the AutoNoteName in the format "Auto Note Response : {AutoNoteName}". Use the name to get the note that //will be used in the recursive call below. string autoNoteString = ""; isAutoNote = false; string autoNoteName = GetAutoNoteName(promptResponse); if (!string.IsNullOrEmpty(autoNoteName)) { isAutoNote = true; //For some reason the Auto Note string always contains a new line and a return character at the end of the note. Must be trimmed autoNoteString = AutoNotes.GetByTitle(autoNoteName).TrimEnd('\n').TrimEnd('\r'); //Returns empty string If no AutoNote is found. } if (listAutoNoteItem.Count > i && !isAutoNote) //The response already exist for this control type and it is note an AutoNote. Update it //We need to update retval with the length of the new promptResponse. First, remove the previous promptResponse length. { retVal -= listAutoNoteItem[i].AutoNoteTextEndPos; //Update the retval with the new promptResponse.Length. retVal += promptResponse.Length; //Update the rest of the AutoNoteItem with the new promptResponse. listAutoNoteItem[i].AutoNotePromptResponseString = promptResponse; listAutoNoteItem[i].AutoNoteTextStartPos = matchloc; listAutoNoteItem[i].AutoNoteTextEndPos = promptResponse.Length; } else if (isAutoNote) //The response is an auto note. Recursively call this method. //Remove the response from textMain.Text. The response was already saved. Since this is an AutoNote, the response does not need to stay //in the textMain.Text since more than likely more prompts will happen after we call the recursive method below. { string textMainWithoutResponse = textMain.Text.Substring(0, matchloc) + GetAutoNoteResponseText(promptResponse); if (textMain.Text.Length > matchloc + listPrompts[i].Value.Length) { textMainWithoutResponse += textMain.Text.Substring(matchloc + listPrompts[i].Value.Length); } matchloc += GetAutoNoteResponseText(promptResponse).Length; //set the textMain.Text to the new result. This removes the promptResponse. textMain.Text = textMainWithoutResponse; textMain.SelectionStart = matchloc; //This is needed in order for the recursive method call below. //Pass in the AutoNotes note in the recursive call. int lenthOfAutoNoteAdded = PromptForAutoNotes(autoNoteString, new List <AutoNoteListItem>()); if (lenthOfAutoNoteAdded == -1) { return(-1); } //When we get back from the recursive method, we need to figure out what was added so we can create the AutoNoteListItem promptResponse = textMain.Text.Substring(matchloc, lenthOfAutoNoteAdded); //Update the retVal with the new promptResponse.Length. retVal += promptResponse.Length; //if response already exist, update it. if (listAutoNoteItem.Count > i) { //We need to update retVal with the length of the new promptResponse. First, remove the previous prompts length. retVal -= listAutoNoteItem[i].AutoNoteTextEndPos; //Update the rest of the AutoNoteItem with the new promptResponse. listAutoNoteItem[i].AutoNotePromptResponseString = promptResponse; //should be the same. Updating just in case. listAutoNoteItem[i].AutoNoteTextStartPos = matchloc; listAutoNoteItem[i].AutoNoteTextEndPos = promptResponse.Length; //This is the length of what was added. } else //New Response. Add a new AutoNoteListItem. //Add the response to listAutoNoteItem. This will allow the user to go back. Make the end position equal to the length of the AutoNote { listAutoNoteItem.Add(new AutoNoteListItem(listPrompts[i].Value, promptResponse, matchloc, promptResponse.Length)); } } else { //This is a new response. Create a new AutoNoteListItem and add to retVal. retVal += promptResponse.Length; listAutoNoteItem.Add(new AutoNoteListItem(listPrompts[i].Value, promptResponse, matchloc, promptResponse.Length)); //add new response to the list } } else //User cancelled out of the auto note response form or auto log off. { ResetTextMain(); return(-1); } } else if (control.ControlType == "MultiResponse") { FormAutoNotePromptMultiResp FormMR = new FormAutoNotePromptMultiResp(autoNoteDescript); FormMR.PromptText = control.ControlLabel; FormMR.PromptOptions = control.ControlOptions; isAutoNote = false; if (i > 0) { FormMR.IsGoBack = true; //user can go back if at least one item in the list exist } if (listAutoNoteItem.Count > i) { FormMR.CurPromptResponse = listAutoNoteItem[i].AutoNotePromptResponseString; //pass the previous response if exist to the form. } FormMR.ShowDialog(); if (FormMR.DialogResult == DialogResult.Retry) //user clicked the go back button { GoBack(i, listAutoNoteItem); stackLoc.Pop(); //remove the start location startLoc = stackLoc.Peek(); //set the new start location i -= 2; continue; } if (FormMR.DialogResult == DialogResult.OK) { promptResponse = FormMR.ResultText; if (listAutoNoteItem.Count > i) //reponse already exist for this control type. Update it //We need to update retval with the length of the new promptresponse.First, remove the previous prompts length. { retVal -= listAutoNoteItem[i].AutoNoteTextEndPos; //update the retval with the new promptResponse.Length. retVal += promptResponse.Length; //Update the rest of the AutoNoteItem with the new promptResponse. listAutoNoteItem[i].AutoNotePromptResponseString = promptResponse; listAutoNoteItem[i].AutoNoteTextStartPos = matchloc; listAutoNoteItem[i].AutoNoteTextEndPos = promptResponse.Length; } else { //This is a new response. Create a new AutoNoteListItem and add to retVal. retVal += promptResponse.Length; listAutoNoteItem.Add(new AutoNoteListItem(listPrompts[i].Value, promptResponse, matchloc, promptResponse.Length)); //add new response to the list } } else //User cancelled out of the auto note response form or auto log off. { ResetTextMain(); return(-1); } } string resultstr = textMain.Text.Substring(0, matchloc) + promptResponse; if (!isAutoNote && textMain.Text.Length > matchloc + listPrompts[i].Value.Length) { resultstr += textMain.Text.Substring(matchloc + listPrompts[i].Value.Length); } else if (isAutoNote && textMain.Text.Length > matchloc + promptResponse.Length) { //if any of the prompts had an AutoNote and textmain has more text, add the rest of textMain. resultstr += textMain.Text.Substring(matchloc + promptResponse.Length); //update the startLoc to include the promptResponse of the AutoNote. startLoc += promptResponse.Length - 1; } textMain.Text = resultstr; ResetTextMain(); if (string.IsNullOrEmpty(promptResponse)) { //if prompt was removed, add the previous start location onto the stack. startLoc = stackLoc.Peek(); } stackLoc.Push(startLoc); Application.DoEvents(); //refresh the textbox } ResetTextMain(); listAutoNoteItem.Clear(); return(retVal); }