public static TestModule Clone(TestModule testModule) { var newTestModule = new TestModule { Text = testModule.Text, Id = testModule.Id, TestType = testModule.TestType, MistakesNumber = testModule.MistakesNumber, TimeRestriction = testModule.TimeRestriction, Trainer = testModule.Trainer, QuestionSequence = testModule.QuestionSequence }; foreach (var testModuleGroup in testModule.Groups) { var group = Group.Clone(testModuleGroup); newTestModule.Nodes.Add(group); } foreach (var testModuleQuestion in testModule.Questions) { var question = Question.Clone(testModuleQuestion); testModule.Nodes.Add(question); } return newTestModule; }
public override void Execute(object @object) { if (!Enabled) { return; } var tm = new TestModule { Id = Guid.NewGuid() }; if (Warehouse.Warehouse.Instance.CourseTree.CurrentNode is CourseRoot) { var cr = Warehouse.Warehouse.Instance.CourseTree.CurrentNode as CourseRoot; tm.Text = string.Concat("Выходной контроль ", cr.OutTestModules.Count + 1); } if (Warehouse.Warehouse.Instance.CourseTree.CurrentNode is TrainingModule) { var trm = Warehouse.Warehouse.Instance.CourseTree.CurrentNode as TrainingModule; tm.Text = string.Concat("Выходной контроль ", trm.OutTestModules.Count + 1); } tm.TestType = Enums.TestType.OutTest; Warehouse.Warehouse.Instance.CourseTree.CurrentNode.Nodes.Add(tm); if (!Warehouse.Warehouse.Instance.CourseTree.CurrentNode.IsExpanded) { Warehouse.Warehouse.Instance.CourseTree.CurrentNode.Toggle(); } Warehouse.Warehouse.Instance.CourseTree.LabelEdit = true; if (!tm.IsEditing) { tm.BeginEdit(); } Warehouse.Warehouse.Instance.CourseTree.CurrentNode = tm; Warehouse.Warehouse.IsProjectModified = true; }
/// <summary> /// считывает файл вопроса /// </summary> /// <returns>считанный вопрос</returns> public Question ReadQuestionFile(string qfPath, TestModule test) { // пока сделан вариант только для вопроса типов Choice // когда будут реализованы все варианты вопросов, сделать Question question = null Question question = new MultichoiceQuestion(); XmlTextReader reader = null; string interaction = string.Empty; string title = string.Empty; string cardinality = string.Empty; bool isAdaptive = false; bool isSupported = false; if (!File.Exists(qfPath)) { MessageBox.Show("Файла " + qfPath + " не существует!"); } else { try { bool isQuestion = false; // проверяем, является ли файл вопросом reader = new XmlTextReader(qfPath); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (reader.Name.Equals("assessmentItem", StringComparison.OrdinalIgnoreCase)) { isQuestion = true; } } if (isQuestion == true) break; } reader.Close(); if (isQuestion) { // считываем из файла тип вопроса reader = new XmlTextReader(qfPath); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { // считываем название вопроса if (reader.Name.Equals("assessmentItem", StringComparison.OrdinalIgnoreCase)) { if (reader.GetAttribute("title") != null) { title = reader.GetAttribute("title"); } if (reader.GetAttribute("adaptive") != null) { isAdaptive = bool.Parse(reader.GetAttribute("adaptive")); } } if (!isAdaptive) { // считываем признак типа вопроса if (reader.Name.Equals("responseDeclaration", StringComparison.OrdinalIgnoreCase)) { cardinality = reader.GetAttribute("cardinality"); } // вопросы типа "Выбор" if (reader.Name.Equals("choiceInteraction", StringComparison.OrdinalIgnoreCase)) { isSupported = true; // Одновариантный выбор if (cardinality.Equals("single", StringComparison.OrdinalIgnoreCase)) { question = new ChoiceQuestion(); } // Множественный выбор else if (cardinality.Equals("multiple", StringComparison.OrdinalIgnoreCase)) { question = new MultichoiceQuestion(); } } // вопросы типа "Упорядочивание элементов ответа" if (reader.Name.Equals("orderInteraction", StringComparison.OrdinalIgnoreCase)) { isSupported = true; question = new OrderingQuestion(); } // Открытые вопросы if (reader.Name.Equals("textEntryInteraction", StringComparison.OrdinalIgnoreCase)) { isSupported = true; question = new OpenQuestion(); } } } } if (!isSupported) { // question = new UnknownQuestion(title); MessageBox.Show("Данный тип вопросов не поддерживается приложением Visual Editor.", "Visual Editor", MessageBoxButtons.OK, MessageBoxIcon.Error); question = null; } question.TestModule = test; if (!question.ReadQti(qfPath)) { question = null; } } else { MessageBox.Show("Данный файл не является файлом вопроса в стандарте IMS QTI 2.1.", "Visual Editor", MessageBoxButtons.OK, MessageBoxIcon.Error); question = null; } } catch { MessageBox.Show("При чтении файла вопроса произошла ошибка. (" + qfPath + ")", "Visual Editor", MessageBoxButtons.OK, MessageBoxIcon.Error); question = null; } finally { if (reader != null) { reader.Close(); } } } return question; }
public override void Execute(object @object) { if (!Enabled) { return; } if (IsBusy) { return; } IsBusy = true; if (Warehouse.Warehouse.Instance.CourseTree.CurrentNode is TrainingModule || Warehouse.Warehouse.Instance.CourseTree.CurrentNode is CourseRoot) { using (var openFileDialog = new OpenFileDialog()) { openFileDialog.Title = "Импортировать тест из упаковки IMS QTI"; openFileDialog.InitialDirectory = AppSettingsHelper.GetInitialDirectory(); openFileDialog.Filter = "ZIP (*.zip)|*.zip"; if (openFileDialog.ShowDialog().Equals(DialogResult.OK)) { tmd = new TestModule(); string path = openFileDialog.FileName; ImportTestFromQtiPackage(path); tmd.Text = testName; tmd.Id = Guid.NewGuid(); tmd.QuestionSequence = questionSequence; tmd.TestType = Enums.TestType.OutTest; if (groups.Count > 0) foreach (Group gr in groups) { if (gr!=null) tmd.Nodes.Add(gr); if (!Warehouse.Warehouse.Instance.CourseTree.CurrentNode.IsExpanded) { Warehouse.Warehouse.Instance.CourseTree.CurrentNode.Toggle(); } } if (questions.Count > 0) foreach (Question qu in questions) { if (qu!=null) tmd.Nodes.Add(qu); if (!Warehouse.Warehouse.Instance.CourseTree.CurrentNode.IsExpanded) { Warehouse.Warehouse.Instance.CourseTree.CurrentNode.Toggle(); } } if (tmd!=null) { Warehouse.Warehouse.Instance.CourseTree.CurrentNode.Nodes.Add(tmd); Warehouse.Warehouse.IsProjectModified = true; } } } } if (Warehouse.Warehouse.Instance.CourseTree.CurrentNode is TestModule || Warehouse.Warehouse.Instance.CourseTree.CurrentNode is Group) { using (var openFileDialog = new OpenFileDialog()) { openFileDialog.Title = "Импортировать вопрос из IMS QTI"; openFileDialog.InitialDirectory = AppSettingsHelper.GetInitialDirectory(); openFileDialog.Filter = "XML (*.xml)|*.xml"; if (openFileDialog.ShowDialog().Equals(DialogResult.OK)) { tmd = new TestModule(); string path = openFileDialog.FileName; qn = ReadQuestionFile(path, tmd); if (Warehouse.Warehouse.Instance.CourseTree.CurrentNode is Group) { var g = Warehouse.Warehouse.Instance.CourseTree.CurrentNode as Group; qn.Text = string.Concat("Вопрос ", g.Questions.Count + 1); qn.TimeRestriction = g.TimeRestriction; qn.Profile = g.Profile; qn.Marks = g.Marks; } if (qn!=null) { Warehouse.Warehouse.Instance.CourseTree.CurrentNode.Nodes.Add(qn); Warehouse.Warehouse.IsProjectModified = true; } } } } IsBusy = false; }
public TestModuleXmlReader(TestModule testModule) { this.testModule = testModule; }
public void ExportTestToQti(string archiveName) { tm = (TestModule)Warehouse.Warehouse.Instance.CourseTree.CurrentNode; groups = tm.Groups; questions = tm.Questions; identificator = "VETEST" + testNumber.ToString(); fileName = "resources\\" + identificator + ".xml"; //массив всех вопросов в тесте ArrayList allQuestions = new ArrayList(0); //имя папки, в которую сохраняются промежуточные файлы string folderName = System.Guid.NewGuid().ToString() + "\\"; //создаём папку ресурсов Directory.CreateDirectory(folderName + "resources"); //добавляем все вопросы, включая содержащиеся в группах allQuestions.AddRange(questions); foreach (Group group in groups) { allQuestions.AddRange(group.Questions); } //записываем файлы вопросов foreach (Question question in allQuestions) { question.WriteQti(folderName + question.FileName);//"\\" + "resources" + "\\" + question.Text); } WriteManifestFile(folderName); //записываем файл манифеста WriteQti(folderName); //записываем файл теста //пока можем создать только zip-архив if (Path.GetExtension(archiveName).ToLower() != ".zip") { if (Path.HasExtension(archiveName)) { archiveName = Path.ChangeExtension(archiveName, ".zip"); } else { archiveName += ".zip"; } } //создаём архив FastZip fz = new FastZip { CreateEmptyDirectories = true }; fz.CreateZip(archiveName, folderName, true, ""); //удаляем временную папку Directory.Delete(folderName, true); // string t = // File.Move(Path.GetDirectoryName(archiveName), path); }
public override void Execute(object @object) { if (!Enabled) { return; } var path = Path.Combine(Warehouse.Warehouse.ProjectEditorLocation, Warehouse.Warehouse.ProjectArchiveName); #region Заполнение дерева компетенций var ct = Warehouse.Warehouse.Instance.ConceptTree; var xmlReader = new XmlTextReader(path); try { while (xmlReader.Read()) { System.Windows.Forms.Application.DoEvents(); if (xmlReader.NodeType == XmlNodeType.Element) { if (xmlReader.Name.Equals("concept")) { var io = xmlReader.GetAttribute("io"); // В старых файлах проекта атрибута "io" нет. if (io == null || io.Equals("o")) { var c = new Logic.Course.Items.Concept { Id = new Guid(xmlReader.GetAttribute("id").Substring(6, 36)), Text = xmlReader.GetAttribute("name"), Type = Enums.ConceptType.Internal, ImageIndex = 1, SelectedImageIndex = 1 }; ct.Nodes.Add(c); } else if (io.Equals("i")) { var c = new Logic.Course.Items.Concept { Id = new Guid(xmlReader.GetAttribute("id").Substring(6, 36)), Text = xmlReader.GetAttribute("name"), Type = Enums.ConceptType.External, ImageIndex = 1, SelectedImageIndex = 1 }; ct.Nodes.Add(c); } } else if (xmlReader.Name.Equals("profile")) { var id = new Guid(xmlReader.GetAttribute("concept_id").Substring(6, 36)); foreach (Logic.Course.Items.Concept c in ct.Nodes) { if (c.Id.Equals(id)) { var lb = xmlReader.GetAttribute("min"); var separator = NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator; lb = lb.Replace(".", separator); lb = lb.Replace(",", separator); c.LowerBound = (float)Convert.ToDouble(lb); c.IsProfile = true; c.ImageIndex = 0; c.SelectedImageIndex = 0; break; } } } } } } catch { } finally { xmlReader.Close(); } #endregion //// RibbonStatusStripEx.Instance.SetProgress(10); //// #region Определение свойства ModuleId компетенций var mid = Guid.Empty; xmlReader = new XmlTextReader(path); var modulesCount = 0; try { while (xmlReader.Read()) { System.Windows.Forms.Application.DoEvents(); if (xmlReader.NodeType == XmlNodeType.Element) { if (xmlReader.Name.Equals("module")) { if (xmlReader.GetAttribute("type").Equals("text")) { mid = new Guid(xmlReader.GetAttribute("id").Substring(8, 36)); } modulesCount++; } else if (xmlReader.Name.Equals("output")) { var id = new Guid(xmlReader.GetAttribute("concept_id").Substring(6, 36)); foreach (Logic.Course.Items.Concept c in ct.Nodes) { if (c.Id.Equals(id)) { c.ModuleId = new Guid(mid.ToString()); break; } } } } } } catch { } finally { xmlReader.Close(); } RibbonStatusStripEx.Instance.ModulesCount = modulesCount; #endregion #region Чтение структуры проекта, закладок, контента контролей var depth = 1; var cst = Warehouse.Warehouse.Instance.CourseTree; // Узел, в который добавляется следующий создаваемый узел. TreeNode activeNode = null; xmlReader = new XmlTextReader(path); try { while (xmlReader.Read()) { System.Windows.Forms.Application.DoEvents(); if (xmlReader.NodeType == XmlNodeType.Element) { if (xmlReader.Name.Equals("project")) { #region Корень учебного курса var cr = new Logic.Course.Items.CourseRoot { Text = xmlReader.GetAttribute("name") }; cst.Nodes.Add(cr); activeNode = cr; #endregion } else if (xmlReader.Name.Equals("module")) { if (xmlReader.GetAttribute("type").Equals("text")) { #region Учебный модуль mid = new Guid(xmlReader.GetAttribute("id").Substring(8, 36)); var tm = new TrainingModule { Id = mid, Text = xmlReader.GetAttribute("name") }; TrainingModule.Count++; Warehouse.Warehouse.Instance.TrainingModules.Add(tm); if (xmlReader.Depth == depth) { activeNode.Nodes.Add(tm); } else if (xmlReader.Depth - depth > 0) { activeNode = activeNode.Nodes[activeNode.Nodes.Count - 1]; activeNode.Nodes.Add(tm); } else if (xmlReader.Depth - depth < 0) { for (var i = 0; i < depth - xmlReader.Depth; i++) { activeNode = activeNode.Parent; } activeNode.Nodes.Add(tm); } depth = xmlReader.Depth; #endregion } else if (xmlReader.GetAttribute("type").Equals("test", StringComparison.OrdinalIgnoreCase) || xmlReader.GetAttribute("type").Equals("training", StringComparison.OrdinalIgnoreCase)) { #region Контроль mid = Guid.Empty; var tm = new TestModule { Text = xmlReader.GetAttribute("name"), Id = new Guid(xmlReader.GetAttribute("id").Substring(8, 36)) }; #region Входной/выходной контроль if (xmlReader.GetAttribute("io") != null) { if (xmlReader.GetAttribute("io").Equals("i", StringComparison.OrdinalIgnoreCase)) { tm.TestType = Enums.TestType.InTest; } else if (xmlReader.GetAttribute("io").Equals("o", StringComparison.OrdinalIgnoreCase)) { tm.TestType = Enums.TestType.OutTest; } } else { tm.TestType = Enums.TestType.OutTest; } #endregion #region Тренажер if (xmlReader.GetAttribute("type").Equals("test", StringComparison.OrdinalIgnoreCase)) { tm.Trainer = false; } else if (xmlReader.GetAttribute("type").Equals("training", StringComparison.OrdinalIgnoreCase)) { tm.Trainer = true; } #endregion #region Последовательность вопросов if (xmlReader.GetAttribute("order").Equals("natural", StringComparison.OrdinalIgnoreCase)) { tm.QuestionSequence = Enums.QuestionSequence.Natural; } else if (xmlReader.GetAttribute("order").Equals("random", StringComparison.OrdinalIgnoreCase)) { tm.QuestionSequence = Enums.QuestionSequence.Random; } else if (xmlReader.GetAttribute("order").Equals("network", StringComparison.OrdinalIgnoreCase)) { tm.QuestionSequence = Enums.QuestionSequence.Network; } #endregion tm.MistakesNumber = int.Parse(xmlReader.GetAttribute("errlimit")); tm.TimeRestriction = int.Parse(xmlReader.GetAttribute("time")); #region Вложенность контролей if (xmlReader.Depth == depth) { activeNode.Nodes.Add(tm); } else if (xmlReader.Depth - depth > 0) { activeNode = activeNode.Nodes[activeNode.Nodes.Count - 1]; activeNode.Nodes.Add(tm); } else if (xmlReader.Depth - depth < 0) { for (int i = 0; i < depth - xmlReader.Depth; i++) { activeNode = activeNode.Parent; } activeNode.Nodes.Add(tm); } depth = xmlReader.Depth; #endregion tm.XmlReader.ReadXml(xmlReader); #region Замена q.NextQuestion на реальные, после того, как все вопросы считаны foreach (var q in tm.Questions) { if (q.NextQuestion != null) { q.NextQuestion = Warehouse.Warehouse.GetQuestionById(q.NextQuestion.Id); } } #endregion #endregion RibbonStatusStripEx.Instance.MakeProgressStep(10); } } else if (xmlReader.Name.Equals("input")) { #region Входная компетенция var id = new Guid(xmlReader.GetAttribute("concept_id").Substring(6, 36)); Logic.Course.Items.Concept con = null; foreach (Logic.Course.Items.Concept c in ct.Nodes) { if (c.Id.Equals(id)) { con = c; break; } } var idc = new InDummyConcept { Text = con.Text, Concept = con }; idc.Concept.InDummyConcepts.Add(idc); if (con.Type.Equals(Enums.ConceptType.Internal)) { // Добавляет компетенцию-пустышку во входы учебного модуля. var tm = Warehouse.Warehouse.GetTrainingModuleById(mid); tm.InConceptParent.Nodes.Add(idc); } else if (con.Type.Equals(Enums.ConceptType.External)) { // Добавляет компетенцию-пустышку во входы учебного курса. cst.InConceptsParent.Nodes.Add(idc); } #endregion } else if (xmlReader.Name.Equals("output")) { #region Выходная компетенция var id = new Guid(xmlReader.GetAttribute("concept_id").Substring(6, 36)); Logic.Course.Items.Concept con = null; foreach (Logic.Course.Items.Concept c in ct.Nodes) { if (c.Id.Equals(id)) { con = c; break; } } var odc = new OutDummyConcept { Text = con.Text, Concept = con }; odc.Concept.OutDummyConcept = odc; // Добавляет компетенцию-пустышку в выходы учебного модуля. var tm = Warehouse.Warehouse.GetTrainingModuleById(mid); tm.OutConceptParent.Nodes.Add(odc); #endregion } else if (xmlReader.Name.Equals("html_text")) { #region Чтение закладок // Разбирает DocumentHtml только учебного модуля. if (!mid.Equals(Guid.Empty)) { var documentHtml = xmlReader.ReadElementString(); documentHtml = documentHtml.Trim(); TrainingModuleXmlReader.ReadBookmarksIds(documentHtml); } #endregion } } } } catch (Exception ex) { ExceptionManager.Instance.LogException(ex); } finally { xmlReader.Close(); } #endregion #region Чтение контента учебных модулей xmlReader = new XmlTextReader(path); try { while (xmlReader.Read()) { System.Windows.Forms.Application.DoEvents(); if (xmlReader.NodeType == XmlNodeType.Element) { if (xmlReader.Name.Equals("module")) { if (xmlReader.GetAttribute("type").Equals("text")) { #region Учебный модуль mid = new Guid(xmlReader.GetAttribute("id").Substring(8, 36)); #endregion } else if (xmlReader.GetAttribute("type").Equals("test", StringComparison.OrdinalIgnoreCase) || xmlReader.GetAttribute("type").Equals("training", StringComparison.OrdinalIgnoreCase)) { #region Контроль mid = Guid.Empty; #endregion } } else if (xmlReader.Name.Equals("html_text")) { #region Контент документа // Разбирает DocumentHtml только учебного модуля. if (!mid.Equals(Guid.Empty)) { var documentHtml = xmlReader.ReadElementString(); documentHtml = documentHtml.Trim(); var tm = Warehouse.Warehouse.GetTrainingModuleById(mid); documentHtml = tm.XmlReader.XmlToHtml(documentHtml); tm.DocumentHtml = documentHtml; } #endregion RibbonStatusStripEx.Instance.MakeProgressStep(10); } } } } catch { } finally { xmlReader.Close(); } #endregion }
public TestModuleXmlWriter(TestModule testModule) { this.testModule = testModule; }
public override void Execute(object @object) { if (!Enabled) { return; } var path = Path.Combine(Warehouse.Warehouse.OuterProjectEditorLocation, Warehouse.Warehouse.OuterProjectArchiveName); #region Чтение структуры проекта, закладок, контента контролей var depth = 1; var ocst = AddItemFromOuterCourseDialog.OuterCourseTree; // Узел, в который добавляется следующий создаваемый узел. TreeNode activeNode = null; var xmlReader = new XmlTextReader(path); try { while (xmlReader.Read()) { System.Windows.Forms.Application.DoEvents(); if (xmlReader.NodeType == XmlNodeType.Element) { if (xmlReader.Name.Equals("project")) { #region Корень учебного курса var cr = new CourseRoot { Text = xmlReader.GetAttribute("name") }; ocst.Nodes.Add(cr); activeNode = cr; #endregion } else if (xmlReader.Name.Equals("module")) { if (xmlReader.GetAttribute("type").Equals("test", StringComparison.OrdinalIgnoreCase) || xmlReader.GetAttribute("type").Equals("training", StringComparison.OrdinalIgnoreCase)) { #region Контроль var tm = new TestModule { Text = xmlReader.GetAttribute("name") }; #region Входной/выходной контроль if (xmlReader.GetAttribute("io") != null) { if (xmlReader.GetAttribute("io").Equals("i", StringComparison.OrdinalIgnoreCase)) { tm.TestType = Enums.TestType.InTest; } else if (xmlReader.GetAttribute("io").Equals("o", StringComparison.OrdinalIgnoreCase)) { tm.TestType = Enums.TestType.OutTest; } } else { tm.TestType = Enums.TestType.OutTest; } #endregion #region Тренажер if (xmlReader.GetAttribute("type").Equals("test", StringComparison.OrdinalIgnoreCase)) { tm.Trainer = false; } else if (xmlReader.GetAttribute("type").Equals("training", StringComparison.OrdinalIgnoreCase)) { tm.Trainer = true; } #endregion #region Последовательность вопросов if (xmlReader.GetAttribute("order").Equals("natural", StringComparison.OrdinalIgnoreCase)) { tm.QuestionSequence = Enums.QuestionSequence.Natural; } else if (xmlReader.GetAttribute("order").Equals("random", StringComparison.OrdinalIgnoreCase)) { tm.QuestionSequence = Enums.QuestionSequence.Random; } else if (xmlReader.GetAttribute("order").Equals("network", StringComparison.OrdinalIgnoreCase)) { tm.QuestionSequence = Enums.QuestionSequence.Network; } #endregion tm.MistakesNumber = int.Parse(xmlReader.GetAttribute("errlimit")); tm.TimeRestriction = int.Parse(xmlReader.GetAttribute("time")); #region Вложенность контролей if (xmlReader.Depth == depth) { activeNode.Nodes.Add(tm); } else if (xmlReader.Depth - depth > 0) { activeNode = activeNode.Nodes[activeNode.Nodes.Count - 1]; activeNode.Nodes.Add(tm); } else if (xmlReader.Depth - depth < 0) { for (var i = 0; i < depth - xmlReader.Depth; i++) { activeNode = activeNode.Parent; } activeNode.Nodes.Add(tm); } depth = xmlReader.Depth; #endregion tm.XmlReader.ReadXml(xmlReader); #region Замена q.NextQuestion на реальные, после того, как все вопросы считаны foreach (var q in tm.Questions) { if (q.NextQuestion != null) { q.NextQuestion = Warehouse.Warehouse.GetQuestionById(q.NextQuestion.Id); } } #endregion #endregion } } } } } catch { } finally { xmlReader.Close(); } #endregion }