public void populateControl(question q) { this.textBoxQuestionText.Text = q.text; if (q.help!=null) { this.textBoxHelp.Text = q.help; } }
public void populateQuestion(question q ) { q.text = this.textBoxQuestionText.Text; if (!string.IsNullOrWhiteSpace(this.textBoxHelp.Text)) { q.help = this.textBoxHelp.Text; } }
public void updateQuestionsPart(question q) { questionnaire questionnaire = new questionnaire(); questionnaire.Deserialize(questionsPart.XML, out questionnaire); questionnaire.questions.Add(q); // Save it in docx string result = questionnaire.Serialize(); log.Info(result); CustomXmlUtilities.replaceXmlDoc(questionsPart, result); }
public FormQuestionEdit(question q) { InitializeComponent(); init1(); this.q = q; populateQuestionTab(); // TODO Behaviour in repeats initResponsesTab(); }
public FormQuestionEdit(string questionId) { InitializeComponent(); init1(); // Get the question! q = questionnaire.getQuestion(questionId); populateQuestionTab(); // TODO Behaviour in repeats initResponsesTab(); }
public void populateQuestions(string type) { log.Debug("populateQuestions of type " + type); listBoxQuestions.Value = null; listBoxQuestions.Items.Clear(); if (type != null && type.Equals("repeats")) { populateRepeats(); return; } if (type != null && type.Equals("conditions")) { populateConditions(); return; } HashSet<question> questions = null; // Find questions which are in scope: questions = new HashSet<question>(); // Add their questions. Could do this by finding // the repeat answer via XPath, then getting // variables in it, but in this case its easier // just to string match in the XPaths part. xpaths xpaths = xppe.xpaths; // Get list of repeat ancestors List<Word.ContentControl> relevantRepeats = new List<Word.ContentControl>(); Word.ContentControl currentCC = cc.ParentContentControl; while (currentCC != null) { if (currentCC.Tag.Contains("od:repeat")) { relevantRepeats.Add(currentCC); } currentCC = currentCC.ParentContentControl; } foreach (Word.ContentControl rcc in relevantRepeats) { TagData td = new TagData(rcc.Tag); string rXPathID = td.getRepeatID(); xpathsXpath xp = xppe.getXPathByID(rXPathID); string rXPath = xp.dataBinding.xpath; int rXPathLength = rXPath.Length; // we want xpaths containing this xpath, // and no extra repeat foreach (xpathsXpath xx in xpaths.xpath) { if (xx.questionID != null) // includes repeats. Shouldn't if can add/remove row on XForm? { string thisXPath = xx.dataBinding.xpath; if (thisXPath.Contains(rXPath)) { if (thisXPath.LastIndexOf("oda:repeat") < rXPathLength) { questions.Add( questionnaire.getQuestion(xx.questionID)); } } } } } // Finally, add top level questions foreach (xpathsXpath xx in xpaths.xpath) { if (xx.questionID != null) { string thisXPath = xx.dataBinding.xpath; if (thisXPath.IndexOf("oda:repeat") < 0) { questions.Add( questionnaire.getQuestion(xx.questionID)); } } } if (questions.Count == 0) { // None of any type string message = "No questions in scope!"; this.listBoxQuestions.Items.Add(message); this.listBoxQuestions.Value = message; freezeAsNoQuestions(); } else { // filter and add foreach (question q in questions) { xpathsXpath xpath = xppe.getXPathByQuestionID(q.id); if (xpath.dataBinding.xpath.EndsWith("oda:row")) { // Ignore raw repeats } else if (type == null || type.Equals(ALL_QUESTION_TYPES)) { // all questions listBoxQuestions.Items.Add(q); } else { if (xpath.type != null && xpath.type.Equals(type)) { listBoxQuestions.Items.Add(q); log.Debug("Added to listbox " + q.id); } } } if (this.listBoxQuestions.Items.Count > 0) { object o = this.listBoxQuestions.Items[0]; this.listBoxQuestions.Value = o; if (o is question) { currentQuestion = (question)this.listBoxQuestions.Items[0]; populateValues(augmentResponses(currentQuestion), null); } else { currentQuestion = null; } populatePredicates(o); } else { // None of this type string message = "No questions of type " + type; this.listBoxQuestions.Items.Add(message); this.listBoxQuestions.Value = message; freezeAsNoQuestions(); } } this.listBoxQuestions.Items.Add(NEW_QUESTION); //if (this.listBoxQuestions.Items.Count == 2) //{ // this.listBoxQuestions.Value = NEW_QUESTION; //} }
///// <summary> ///// Generate a simple ID ///// </summary> ///// <returns></returns> //private string generateId() //{ // int i = this.answerID.Count; // do // { // i++; // } while (this.answerID.Contains("rpt" + i)); // return "rpt" + i; //} private void buttonNext_Click(object sender, EventArgs e) { int min = 1; int defautlVal = 2; int max = 4; int step = 1; //log.Info(".Text:" + answerID.Text); //log.Info(".SelectedText:" + answerID.SelectedText); //log.Info(".textBoxQuestionText:" + textBoxQuestionText.Text); if (//string.IsNullOrWhiteSpace(this.answerID.Text) || string.IsNullOrWhiteSpace(this.textBoxQuestionText.Text)) { Mbox.ShowSimpleMsgBoxError("Required data missing!"); DialogResult = DialogResult.None; // or use on closing event; see http://stackoverflow.com/questions/2499644/preventing-a-dialog-from-closing-in-the-buttons-click-event-handler return; } String repeatName = this.textBoxQuestionText.Text.Trim(); try { string foo = repeatNameToIdMap[repeatName]; Mbox.ShowSimpleMsgBoxError("You already have a repeat named '" + repeatName + "' . Click the 're-use' tab to re-use it, or choose another name."); DialogResult = DialogResult.None; return; } catch (KeyNotFoundException knfe) { // Good } // Basic data validation try { min = int.Parse(this.textBoxMin.Text); defautlVal = int.Parse(this.textBoxDefault.Text); max = int.Parse(this.textBoxMax.Text); step = int.Parse(this.textBoxRangeStep.Text); } catch (Exception) { log.Warn("Repeat range val didn't parse to int properly"); } if (min < 0) min = 0; if (min > 20) min = 20; if (max < min) max = min + 4; if (max > 30) max = 30; int av = (int)Math.Round((min + max) / 2.0); if (defautlVal < min || defautlVal > max) defautlVal = av; if (step > av) step = 1; TagData td; // Work out where to put this repeat // It will just go in /answers, unless it // has a repeat ancestor. // So look for one... Word.ContentControl repeatAncestor = null; Word.ContentControl currentCC = cc.ParentContentControl; while (repeatAncestor == null && currentCC != null) { if (currentCC.Tag.Contains("od:repeat")) { repeatAncestor = currentCC; break; } currentCC = currentCC.ParentContentControl; } // Generate a nice ID // .. first we need a list of existing IDs List<string> reserved = new List<string>(); foreach (question qx in questionnaire.questions) { reserved.Add(qx.id); } ID = IdHelper.SuggestID(repeatName, reserved) + "_" + IdHelper.GenerateShortID(2); string xpath; if (repeatAncestor == null) { // create it in /answers Office.CustomXMLNode node = answersPart.SelectSingleNode("/oda:answers"); //string xml = "<repeat qref=\"" + ID + "\" xmlns=\"http://opendope.org/answers\"><row/></repeat>"; string xml = "<oda:repeat qref=\"" + ID + "\" xmlns:oda=\"http://opendope.org/answers\" ><oda:row/></oda:repeat>"; node.AppendChildSubtree(xml); xpath = "/oda:answers/oda:repeat[@qref='" + ID + "']/oda:row"; // avoid trailing [1] } else { td = new TagData(repeatAncestor.Tag); string ancestorRepeatXPathID = td.getRepeatID(); // Get the XPath, to find the question ID, // which is what we use to find the repeat answer. xpathsXpath xp = xppe.getXPathByID(ancestorRepeatXPathID); Office.CustomXMLNode node = answersPart.SelectSingleNode("//oda:repeat[@qref='" + xp.questionID + "']/oda:row"); string parentXPath = NodeToXPath.getXPath(node); //string xml = "<repeat qref=\"" + ID + "\" xmlns=\"http://opendope.org/answers\"><row/></repeat>"; string xml = "<oda:repeat qref=\"" + ID + "\" xmlns:oda=\"http://opendope.org/answers\" ><oda:row/></oda:repeat>"; node.AppendChildSubtree(xml); xpath = parentXPath + "/oda:repeat[@qref='" + ID + "']/oda:row"; // avoid trailing [1] } log.Info(answersPart.XML); // Question q = new question(); //q.id = this.answerID.Text; // not SelectedText q.id = ID; q.text = repeatName; if (!string.IsNullOrWhiteSpace(this.textBoxHelp.Text)) { q.help = this.textBoxHelp.Text; } if (!string.IsNullOrWhiteSpace(this.textBoxHint.Text)) { q.hint = this.textBoxHint.Text; } if (this.isAppearanceCompact()) { q.appearance = appearanceType.compact; q.appearanceSpecified = true; } else { q.appearanceSpecified = false; } questionnaire.questions.Add(q); // Bind to answer XPath xpathsXpath xpathEntry = xppe.setup("", answersPart.Id, xpath, null, false); xpathEntry.questionID = q.id; xpathEntry.dataBinding.prefixMappings = "xmlns:oda='http://opendope.org/answers'"; xpathEntry.type = "nonNegativeInteger"; xppe.save(); // Repeat td = new TagData(""); td.set("od:repeat", xppe.xpathId); cc.Tag = td.asQueryString(); // At this point, answer should be present. Sanity check! cc.Title = "REPEAT " + repeatName; cc.SetPlaceholderText(null, null, "Repeating content goes here."); //Not for wdContentControlRichText! //cc.XMLMapping.SetMapping(xpath, null, model.userParts[0]); // Responses response responses = q.response; if (responses == null) { responses = new response(); q.response = responses; } // MCQ: display response form responseFixed responseFixed = new responseFixed(); responses.Item = responseFixed; //for (int i = min; i<=max; i=i+step) //{ // responseFixedItem item = new OpenDoPEModel.responseFixedItem(); // item.value = ""+i; // item.label = "" + i; // responseFixed.item.Add(item); //} responseFixed.canSelectMany = false; // Finally, add to part updateQuestionsPart(); this.Close(); }
public void updateQuestionFromForm(xpathsXpath xpathObj, question q, Office.CustomXMLNode node) { // Currently used only by QuestionEdit. Why not also initial populate? // sampleAnswer node.Text = getSampleAnswerProcessed(); //if (!string.IsNullOrWhiteSpace(getHint())) //{ q.hint = getHint(); //} populateXPath(xpathObj); }
public void updateQuestionFromForm(xpathsXpath xpathObj, question q, Office.CustomXMLNode node) { // data type xpathObj.type = getDataType(); // The items, and canSelectMany responseFixed.item.Clear(); injectItems(); // interview appearance q.appearance = getAppearanceType(); q.appearanceSpecified = true; if (string.IsNullOrWhiteSpace(getDefault())) { node.Text = "«multiple choice»"; } else { node.Text = getDefault(); } }
public override void populatePredicates(question q) { string type = null; if (listBoxTypeFilter.SelectedItem != null) { type = listBoxTypeFilter.SelectedItem.ToString(); } if (q != null) // can happen if there are no questions of this type { xpathsXpath xpath = xppe.getXPathByQuestionID(q.id); if (xpath.dataBinding.xpath.EndsWith("oda:row") && type == null) { type = REPEAT_POS; // default } else { type = xpath.type; } } this.listBoxPredicate.Items.Clear(); if (type == null) { } else if (type.Equals(REPEAT_POS)) { this.listBoxPredicate.Items.Add("first"); this.listBoxPredicate.Items.Add("not first"); this.listBoxPredicate.Items.Add("second"); this.listBoxPredicate.Items.Add("second last"); this.listBoxPredicate.Items.Add("last"); this.listBoxPredicate.Items.Add("not last"); listBoxTypeFilter.SelectedItem = REPEAT_POS; } else if (type.Equals("string")) { this.listBoxPredicate.Items.Add("equals"); this.listBoxPredicate.Items.Add("is not"); this.listBoxPredicate.Items.Add("starts-with"); this.listBoxPredicate.Items.Add("contains"); this.listBoxPredicate.Items.Add("not blank."); } else if (type.Equals("boolean")) { this.listBoxPredicate.Items.Add("equals"); } else if (type.Equals("decimal") || type.Equals("integer") || type.Equals("positiveInteger") || type.Equals("nonPositiveInteger") || type.Equals("negativeInteger") || type.Equals("nonNegativeInteger") // repeat || type.Equals(REPEAT_COUNT) ) { this.listBoxPredicate.Items.Add("="); this.listBoxPredicate.Items.Add(">"); this.listBoxPredicate.Items.Add(">="); this.listBoxPredicate.Items.Add("<"); this.listBoxPredicate.Items.Add("<="); } else if (type.Equals("date")) { this.listBoxPredicate.Items.Add("equals"); this.listBoxPredicate.Items.Add("is before"); this.listBoxPredicate.Items.Add("is after"); } // TODO: flesh this out with the full range of allowable datatypes // (card number, email address, custom types) }
private List<object> augmentResponses(question q) { List<object> stuff = null; try { stuff = augmentedValues[q]; } catch (KeyNotFoundException) { // Set it up stuff = new List<object>(); if (q.response.Item is responseFixed) { stuff.AddRange(((responseFixed)q.response.Item).item); } augmentedValues.Add(q, stuff); } return stuff; }
/// <summary> /// Deserializes xml markup from file into an question object /// </summary> /// <param name="fileName">string xml file to load and deserialize</param> /// <param name="obj">Output question object</param> /// <param name="exception">output Exception value if deserialize failed</param> /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns> public static bool LoadFromFile(string fileName, out question obj, out System.Exception exception) { exception = null; obj = default(question); try { obj = LoadFromFile(fileName); return true; } catch (System.Exception ex) { exception = ex; return false; } }
public static bool LoadFromFile(string fileName, out question obj) { System.Exception exception = null; return LoadFromFile(fileName, out obj, out exception); }
public static bool Deserialize(string xml, out question obj) { System.Exception exception = null; return Deserialize(xml, out obj, out exception); }
/// <summary> /// Deserializes workflow markup into an question object /// </summary> /// <param name="xml">string workflow markup to deserialize</param> /// <param name="obj">Output question object</param> /// <param name="exception">output Exception value if deserialize failed</param> /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns> public static bool Deserialize(string xml, out question obj, out System.Exception exception) { exception = null; obj = default(question); try { obj = Deserialize(xml); return true; } catch (System.Exception ex) { exception = ex; return false; } }
public List<Word.ContentControl> getControlsUsingQuestion(question q) { string xpathID = xppe.getXPathByQuestionID(q.id).id; return getControlsUsingQuestion(q.id, xpathID); }
//public void createRow() //{ // DataGridViewRow dr = (DataGridViewRow)dataGridView.Rows[0].Clone(); // //dr.Cells.Add(new DataGridViewComboBoxCell()); // //dr.Cells.Add(new DataGridViewComboBoxCell()); // //dr.Cells.Add(new DataGridViewComboBoxCell()); // //dr.Cells.Add(new DataGridViewComboBoxCell()); // //dr.Cells.Add(new DataGridViewComboBoxCell()); // dataGridView.Rows.Add(dr); // dataGridView.Refresh(); // populateRow(dr, null, null); //} //void EditingControl_TextChanged(object sender, EventArgs e) //{ // DataGridViewComboBoxEditingControl control = (DataGridViewComboBoxEditingControl)sender; // log.Debug("TextChanged .. Value is: " + control.Text); //} public void populateRow(DataGridViewRow row, question existingQuestion, string matchResponse) { log.Debug("populateRow: " ); listBoxTypeFilter = (DataGridViewComboBoxCell)row.Cells["Filter"]; listBoxQuestions = (DataGridViewComboBoxCell)row.Cells["Questions"]; listBoxPredicate = (DataGridViewComboBoxCell)row.Cells["Predicate"]; comboBoxValues = (DataGridViewComboBoxCell)row.Cells["Value"]; populateTypeFilter(null); if (existingQuestion == null) { // for init, populate with all questions populateQuestions(null); } else { // Just show the existing question listBoxQuestions.Items.Add(existingQuestion); } ////if (this.listBoxQuestions.Items.Count == 0) // Never happens if in a repeat, and nor do we want it to, since user might just want to use "repeat pos" stuff ////{ //// populateQuestions(null); //// if (this.listBoxQuestions.Items.Count == 0) //// { //// MessageBox.Show("You can't define a condition until you have set up at least one question. Let's do that now. "); //// FormQA formQA = new FormQA(cc, false); //// formQA.ShowDialog(); //// formQA.Dispose(); //// // Refresh these //// xppe = new XPathsPartEntry(model); //// questionnaire.Deserialize(questionsPart.XML, out questionnaire); //// filterAction(); //// return; //// } ////} //// value //object o; //if (existingQuestion == null) //{ // // for init, populate with all questions // o = this.listBoxQuestions.Items[0]; //} //else //{ // o = existingQuestion; //} //questionSelectedAction(o); //this.listBoxQuestions.Value = o; ////if (q.response.Item is responseFixed) ////{ //// populateValues((responseFixed)q.response.Item, matchResponse); ////} ////// predicate = ////populatePredicates(q); // TODO: set this correctly in editing mode }
public RepeatCount(question q) { Repeat = q; }
/// <summary> /// When user clicks a question, we need to /// (1) populate predicates for that type /// (2) if its MCQ, populate values /// </summary> /// <param name="q"></param> public void questionSelectedAction(object q) { // input is a question, or RepeatPosition or RepeatCount // or if (q is condition) { currentQuestion = null; return; } log.Debug("questionSelectedAction " + q); // (1) populate predicates populatePredicates(q); // (2) populate values if (q is question) { currentQuestion = (question)q; populateValues(augmentResponses(currentQuestion), null); } else { currentQuestion = null; clearComboBoxValues(); } // Choice of question should NEVER update filter. // Changes only flow from Filter -> Qs -> selected Q -> predicate & value //xpathsXpath xpath = xppe.getXPathByQuestionID(q.id); ////this.listBoxTypeFilter.SelectedIndexChanged -= new System.EventHandler(this.listBoxTypeFilter_SelectedIndexChanged); //if (xpath.dataBinding.xpath.EndsWith("oda:row")) //{ // if (listBoxTypeFilter.Value.Equals(REPEAT_COUNT) // || listBoxTypeFilter.Value.Equals(REPEAT_POS)) // { // // Do nothing // } // else // { // populateTypeFilter(true, REPEAT_POS); // } //} //else //{ // populateTypeFilter(false, xpath.type); //} ////this.listBoxTypeFilter.SelectedIndexChanged += new System.EventHandler(this.listBoxTypeFilter_SelectedIndexChanged); }
public void init( Office.CustomXMLPart answersPart, questionnaire questionnaire, question q, XPathsPartEntry xppe, ConditionsPartEntry cpe) { QuestionHelper qh = new QuestionHelper(xppe, cpe); thisQuestionControls = qh.getControlsUsingQuestion(q); List<Word.ContentControl> relevantRepeats = new List<Word.ContentControl>(); foreach (Word.ContentControl ccx in thisQuestionControls) { Word.ContentControl rpt = RepeatHelper.getYoungestRepeatAncestor(ccx); if (rpt == null) { // will have to make the answer top level and we're done. break; } else { relevantRepeats.Add(rpt); } } init( answersPart, relevantRepeats, questionnaire, q.id, xppe); }
public RepeatPosition(question q) { Repeat = q; }
private void buttonNext_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(this.textBoxQID.Text) || string.IsNullOrWhiteSpace(this.textBoxQText.Text)) { Mbox.ShowSimpleMsgBoxError("Required data missing!"); return; } q = new question(); q.id = this.textBoxQID.Text; questionText qt = new questionText(); qt.Value = this.textBoxQText.Text; q.text = qt; // Responses response responses = new response(); q.response = responses; if (this.radioButtonMCYes.Checked) { // MCQ: display response form responseFixed responseFixed = new responseFixed(); responses.Item = responseFixed; FormResponses formResponses = new FormResponses(responseFixed); formResponses.ShowDialog(); // TODO - handle cancel } else { // Not MCQ responseFree responseFree = new responseFree(); responses.Item = responseFree; // Free - just text for now // later, configure type responseFree.format = responseFreeFormat.text; } // Finally, add to part //updateQuestionsPart(q); this.Close(); }
public virtual void populatePredicates(question q) { }
public void populateControl(xpathsXpath xpathObj, question q, string defaultAnswer) { responseFixed = q.response.Item as responseFixed; if (xpathObj.type.Equals("string")) { this.radioTypeText.Checked = true; } else if (xpathObj.type.Equals("decimal")) { this.radioTypeNumber.Checked = true; } else if (xpathObj.type.Equals("date")) { this.radioTypeDate.Checked = true; } else if (xpathObj.type.Equals("boolean")) { this.radioTypeBoolean.Checked = true; } //else if (xpathObj.type.Equals("duration")) //{ // this.radioTypeText.Checked = true; //} //else if (xpathObj.type.Equals("email")) //{ // this.radioTypeText.Checked = true; //} //else if (xpathObj.type.Equals("cardnumber")) //{ // this.radioTypeText.Checked = true; //} else { log.Error("XPath " + xpathObj.id + " has unknown value for datatype: '" + xpathObj.type); } // The possible responses int i = 0; this.dataGridView1.Rows.Add(responseFixed.item.Count); foreach (responseFixedItem rFI in responseFixed.item) { this.dataGridView1.Rows[i].Cells[0].Value = rFI.value; this.dataGridView1.Rows[i].Cells[1].Value = rFI.label; i++; } // How many responses can be checked? if (responseFixed.canSelectMany) { this.radioButtonYes.Checked = true; } else { this.radioButtonNo.Checked = true; } // Interview appearance if (q.appearance.Equals(appearanceType.compact)) { this.radioButtonAppearanceCompact.Checked = true; } else if (q.appearance.Equals(appearanceType.full)) { this.radioButtonAppearanceFull.Checked = true; } else if (q.appearance.Equals(appearanceType.minimal) ){ this.radioButtonAppearanceMinimal.Checked = true; } // Default this.textBoxDefault.Text = defaultAnswer; }