private List <ResultModel> FilterForCorrectResponsesClick(SlideQuestionModel slideQuestionModel, List <ResultModel> responses) { var correctResponses = new List <ResultModel>(); var correctAnswerOptionPositions = slideQuestionModel.AnswerOptions.Where(ao => ao.IsTrue).Select(ao => ao.Position).Select(correctAnswerOptionPosition => correctAnswerOptionPosition - 1).ToList(); var correctAnswerOptionPositionsCount = correctAnswerOptionPositions.Count(); switch (slideQuestionModel.QuestionType) { case QuestionTypeEnum.SingleChoiceClick: case QuestionTypeEnum.YesNoClick: case QuestionTypeEnum.TrueFalseClick: var correctAnswerOptionPosition = correctAnswerOptionPositions.First(); foreach (var response in responses) { if (response.answerOptionNumber.First() == correctAnswerOptionPosition) { correctResponses.Add(response); } } break; case QuestionTypeEnum.MultipleChoiceClick: foreach (var response in responses) { if (correctAnswerOptionPositionsCount == response.answerOptionNumber.Count) { var allCorrect = true; foreach (var answerOption in response.answerOptionNumber) { if (correctAnswerOptionPositions.All(ca => ca != answerOption)) { allCorrect = false; } } if (allCorrect) { correctResponses.Add(response); } } } break; case QuestionTypeEnum.RangedQuestionClick: correctResponses.AddRange(this.GetCorrectRangedAnswerResults(slideQuestionModel, responses)); break; case QuestionTypeEnum.FreeTextClick: correctResponses.AddRange(this.GetCorrectFreeTextResults(slideQuestionModel, responses)); break; case QuestionTypeEnum.SurveyClick: correctResponses = responses; break; } return(correctResponses); }
public static SlideQuestionModel CopySlideQuestionModel(SlideQuestionModel currentSlideQuestionModel) { var newSlideQuestionModel = new SlideQuestionModel { Id = currentSlideQuestionModel.Id, Hashtag = currentSlideQuestionModel.Hashtag, QuestionType = currentSlideQuestionModel.QuestionType, QuestionTypeSet = currentSlideQuestionModel.QuestionTypeSet, QuestionText = currentSlideQuestionModel.QuestionText, AnswerOptionsSet = currentSlideQuestionModel.AnswerOptionsSet, AnswerOptionAmount = currentSlideQuestionModel.AnswerOptionAmount, QuestionInitType = currentSlideQuestionModel.QuestionInitType, Index = currentSlideQuestionModel.Index, RecalculatedOnlineIndex = currentSlideQuestionModel.RecalculatedOnlineIndex, ChartType = currentSlideQuestionModel.ChartType, ResultsSlideId = currentSlideQuestionModel.ResultsSlideId, QuestionTimerSlideId = currentSlideQuestionModel.QuestionTimerSlideId, QuestionInfoSlideId = currentSlideQuestionModel.QuestionInfoSlideId, AnswerOptions = new ObservableCollection <GeneralAnswerOption>() }; if (currentSlideQuestionModel.AnswerOptions != null) { foreach (var answerOption in currentSlideQuestionModel.AnswerOptions) { newSlideQuestionModel.AnswerOptions.Add(CopyAnswerOptionModel(newSlideQuestionModel, answerOption)); } } return(newSlideQuestionModel); }
public void GetAndDisplayArsnovaVotingResults(SlideQuestionModel slideQuestionModel) { var slideSessionModel = this.GetSlideSessionModel(); var resultsSlide = SlideTracker.GetSlideById(slideQuestionModel.ResultsSlideId.Value); this.sessionManager.GetAndDisplayArsnovaVotingResults(slideSessionModel, slideQuestionModel, resultsSlide); }
private void HandleTimerEvent(object source, ElapsedEventArgs e) { this.countdown--; if (this.countdown >= 0) { this.slideManipulator.SetTimerOnSlide(this.currentQuestionModel, this.questionTimerSlide, this.countdown); } if (this.countdown == 0) { this.timer.Stop(); var responses = this.arsnovaClickService.GetResultsForHashtag(this.currentSlideSessionModel.Hashtag, this.currentQuestionModel.RecalculatedOnlineIndex); if (responses != null) { this.slideManipulator.SetClickResults(this.currentQuestionModel, this.resultsSlide, responses); } // move to next slide (results) this.ShowNextSlideEventHandler?.Invoke(this, EventArgs.Empty); // clean up this.timer = null; this.currentQuestionModel = null; this.currentSlideSessionModel = null; this.questionTimerSlide = null; this.resultsSlide = null; } }
private static GeneralAnswerOption CopyAnswerOptionModel(SlideQuestionModel slideQuestionModel, GeneralAnswerOption answerOption) { if (answerOption.AnswerOptionType == AnswerOptionType.ShowRangedAnswerOption) { var newAnswerOption = new GeneralAnswerOption { Id = answerOption.Id, RangedLowerLimit = answerOption.RangedLowerLimit, RangedCorrectValue = answerOption.RangedCorrectValue, RangedHigherLimit = answerOption.RangedHigherLimit, AnswerOptionType = AnswerOptionType.ShowRangedAnswerOption }; return(newAnswerOption); } else { var newAnswerOption = new GeneralAnswerOption(); newAnswerOption.ObjectChangedEventHandler += delegate { slideQuestionModel.AnswerOptionsSet = true; slideQuestionModel.AnswerOptionModelChanged(); }; newAnswerOption.Id = answerOption.Id; newAnswerOption.Position = answerOption.Position; newAnswerOption.AlphabeticPosition = answerOption.AlphabeticPosition; newAnswerOption.Text = answerOption.Text; newAnswerOption.IsTrue = answerOption.IsTrue; return(newAnswerOption); } throw new ArgumentException($"Unknow answer option type {answerOption.GetType()}"); }
public void SetTimerOnSlide(SlideQuestionModel slideQuestionModel, Slide questionTimerSlide, int countdown) { var answerOptionType = this.sessionInformationProvider.GetAnswerOptionType(slideQuestionModel.QuestionType); var isRangedOrFreetextQuestion = answerOptionType == AnswerOptionType.ShowRangedAnswerOption || answerOptionType == AnswerOptionType.ShowFreeTextAnswerOptions; questionTimerSlide.Shapes[isRangedOrFreetextQuestion ? 4 : 5].TextFrame.TextRange.Text = countdown.ToString(); }
public AnswerOptionViewViewModel(ViewModelRequirements requirements, Guid questionId, bool isNew, SlideQuestionModel questionBeforeEdit) : base(requirements) { this.questionId = questionId; this.isNew = isNew; this.questionBeforeEdit = questionBeforeEdit; this.InitializeWindowCommandBindings(); this.InitAnswerOptionList(); }
private LectureQuestionModel SlideQuestionModelToLectureQuestionModel(SlideQuestionModel questionModel, string sessionKey) { var leqtureQuestion = new LectureQuestionModel { abstention = false, // TODO should abstention be allowed? active = false, imageQuestion = false, number = questionModel.Index - 1, questionType = this.QuestionTypeToVotingQuestionType(questionModel.QuestionType), questionVariant = "preparation", releasedFor = "all", sessionKeyword = sessionKey, showStatistic = true, subject = "powerpoint generated questions", // TODO text = questionModel.QuestionText, type = "skill_question", votingDisabled = true // Disabled by default! }; if (questionModel.QuestionType != QuestionTypeEnum.FreeTextVoting) { var answerOptionList = new List <PossibleAnswerObject>(); foreach (var answerOption in questionModel.AnswerOptions) { answerOptionList.Add(new PossibleAnswerObject { correct = answerOption.IsTrue, text = answerOption.Text, value = answerOption.IsTrue ? 10 : -10 }); } leqtureQuestion.possibleAnswers = answerOptionList; } else { // freetext var answerOption = questionModel.AnswerOptions.First(); leqtureQuestion.strictMode = true; leqtureQuestion.textAnswerEnabled = true; leqtureQuestion.correctAnswer = answerOption.Text; leqtureQuestion.fixedAnswer = true; leqtureQuestion.ignoreCaseSensitive = answerOption.ConfigCaseSensitive; leqtureQuestion.ignorePunctuation = answerOption.ConfigUsePunctuation; leqtureQuestion.ignoreWhitespaces = answerOption.ConfigTrimWhitespaces; } return(leqtureQuestion); }
protected void AddSessionToSlides(SlideQuestionModel slideQuestionModel) { var hasIntroSlide = this.HasIntroSlide(); if (!hasIntroSlide) { var introSlide = this.RibbonHelper.CreateNewSlide(1); this.SlideManipulator.AddIntroSlide(this.SlideSessionModel, introSlide); this.SlideSessionModel.IntroSlideId = introSlide.SlideID; PresentationInformationStore.SetArsnovaIntroSlideAdded(); } var questionInfoSlide = SlideTracker.GetSlideById(slideQuestionModel.QuestionInfoSlideId); if (this.SessionInformationProvider.IsClickQuestion(slideQuestionModel.QuestionType)) { // arsnova.click var questionTimerSlide = slideQuestionModel.QuestionTimerSlideId.HasValue ? SlideTracker.GetSlideById(slideQuestionModel.QuestionTimerSlideId.Value) : this.RibbonHelper.CreateNewSlide(questionInfoSlide.SlideIndex + 1); slideQuestionModel.QuestionTimerSlideId = questionTimerSlide.SlideID; var resultsSlide = slideQuestionModel.ResultsSlideId.HasValue ? SlideTracker.GetSlideById(slideQuestionModel.ResultsSlideId.Value) : this.RibbonHelper.CreateNewSlide(questionInfoSlide.SlideIndex + 2); slideQuestionModel.ResultsSlideId = resultsSlide.SlideID; this.SlideManipulator.AddQuizToStyledSlides(slideQuestionModel, questionInfoSlide, questionTimerSlide, resultsSlide); } else { // arsnova.voting slideQuestionModel.QuestionTimerSlideId = slideQuestionModel.QuestionInfoSlideId; var resultsSlide = slideQuestionModel.ResultsSlideId.HasValue ? SlideTracker.GetSlideById(slideQuestionModel.ResultsSlideId.Value) : this.RibbonHelper.CreateNewSlide(questionInfoSlide.SlideIndex + 1); slideQuestionModel.ResultsSlideId = resultsSlide.SlideID; this.SlideManipulator.AddQuizToStyledSlides(slideQuestionModel, questionInfoSlide, resultsSlide); } PresentationInformationStore.StoreSlideSessionModel(this.SlideSessionModel); this.ViewPresenter.CloseWithoutPrompt(); }
private List <ResultModel> GetCorrectRangedAnswerResults(SlideQuestionModel slideQuestionModel, List <ResultModel> responses) { var correctResponses = new List <ResultModel>(); var answerOption = slideQuestionModel.AnswerOptions.First(); foreach (var response in responses) { if (response.rangedInputValue >= answerOption.RangedLowerLimit && response.rangedInputValue <= answerOption.RangedHigherLimit) { correctResponses.Add(response); } } return(correctResponses); }
public QuestionViewViewModel(ViewModelRequirements requirements, Guid questionId, bool isNew, SlideQuestionModel questionBeforeEdit = null) : base(requirements) { this.questionId = questionId; this.isNew = isNew; this.questionBeforeEdit = questionBeforeEdit ?? CopyHelper.CopySlideQuestionModel(this.SlideQuestionModel); this.InitializeWindowCommandBindings(); this.QuestionTypes = this.SlideSessionModel.SessionType == SessionType.ArsnovaClick ? this.SessionInformationProvider.GetAvailableQuestionsClick() : this.SessionInformationProvider.GetAvailableQuestionsVoting(); this.ExcelChartTypes = this.SessionInformationProvider.GetExcelChartTypes(); }
public void AddQuizToStyledSlides(SlideQuestionModel slideQuestionModel, Slide questionInfoSlide, Slide resultsSlide) { var answerOptionType = this.sessionInformationProvider.GetAnswerOptionType(slideQuestionModel.QuestionType); var isRangedOrFreetextQuestion = answerOptionType == AnswerOptionType.ShowRangedAnswerOption || answerOptionType == AnswerOptionType.ShowFreeTextAnswerOptions; this.RemoveShapesFromSlide(questionInfoSlide); this.RemoveShapesFromSlide(resultsSlide); questionInfoSlide.FollowMasterBackground = MsoTriState.msoTrue; resultsSlide.FollowMasterBackground = MsoTriState.msoTrue; this.SetQuestionInfoSlidecontent(slideQuestionModel, questionInfoSlide, isRangedOrFreetextQuestion); this.CleanResultsPage(resultsSlide); }
private List <ArsnovaVotingResultReturnElement> GetCorrectFreeTextResultsVoting( SlideQuestionModel slideQuestionModel, List <ArsnovaVotingResultReturnElement> responses) { var correctResponses = new List <ArsnovaVotingResultReturnElement>(); var answerOption = slideQuestionModel.AnswerOptions.First(); var answerOptionText = answerOption.Text; var punctutationRegex = new Regex(@"(\.)*(,)*(!)*("")*(;)*(\?)*"); var whiteSpaceRegex = new Regex(@" "); if (!answerOption.ConfigCaseSensitive) { answerOptionText = answerOptionText.ToLower(); } if (!answerOption.ConfigUsePunctuation) { answerOptionText = punctutationRegex.Replace(answerOptionText, ""); } foreach (var response in responses) { var responseText = response.answerText; if (!answerOption.ConfigCaseSensitive) { responseText = responseText.ToLower(); } if (!answerOption.ConfigUsePunctuation) { responseText = punctutationRegex.Replace(responseText, ""); } if (!answerOption.ConfigTrimWhitespaces) { responseText = whiteSpaceRegex.Replace(responseText, ""); } if (answerOptionText == responseText) { correctResponses.Add(response); } } return(correctResponses); }
public void StartQuiz(SlideQuestionModel slideQuestionModel) { var slideSessionModel = this.GetSlideSessionModel(); var resultsSlide = SlideTracker.GetSlideById(slideQuestionModel.ResultsSlideId.Value); if (this.sessionInformationProvider.IsClickQuestion(slideQuestionModel.QuestionType)) { // arsnova click var questionTimerSlide = SlideTracker.GetSlideById(slideQuestionModel.QuestionTimerSlideId.Value); this.sessionManager.StartClickQuestion(slideSessionModel, slideQuestionModel.Index, questionTimerSlide, resultsSlide); } else { // arsnova.voting this.sessionManager.StartVotingQuestion(slideSessionModel, slideQuestionModel); } }
public void AddQuizToStyledSlides(SlideQuestionModel slideQuestionModel, Slide questionInfoSlide, Slide questionTimerSlide, Slide resultsSlide) { var isClickQuestion = this.sessionInformationProvider.IsClickQuestion(slideQuestionModel.QuestionType); var sessionInfoString = isClickQuestion ? "https://arsnova.click/" + slideQuestionModel.Hashtag : "https://arsnova.eu/mobile/#id/" + slideQuestionModel.Hashtag; var answerOptionType = this.sessionInformationProvider.GetAnswerOptionType(slideQuestionModel.QuestionType); var isRangedOrFreetextQuestion = answerOptionType == AnswerOptionType.ShowRangedAnswerOption || answerOptionType == AnswerOptionType.ShowFreeTextAnswerOptions; this.RemoveShapesFromSlide(questionTimerSlide); this.RemoveShapesFromSlide(resultsSlide); questionInfoSlide.FollowMasterBackground = MsoTriState.msoTrue; questionTimerSlide.FollowMasterBackground = MsoTriState.msoTrue; resultsSlide.FollowMasterBackground = MsoTriState.msoTrue; this.SetQuestionInfoSlidecontent(slideQuestionModel, questionInfoSlide, isRangedOrFreetextQuestion); questionTimerSlide.Layout = PpSlideLayout.ppLayoutBlank; this.AddQuestionSlideContent(slideQuestionModel, questionTimerSlide, isRangedOrFreetextQuestion, sessionInfoString); // Timer var timerLabelTextBox = questionTimerSlide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 300, 450, 150, 90); var timerLabelTextRange = timerLabelTextBox.TextFrame.TextRange; timerLabelTextRange.Text = this.localizationService.Translate("Countdown:"); timerLabelTextRange.Font.Name = this.font; timerLabelTextRange.Font.Size = 26; timerLabelTextBox.TextEffect.FontBold = MsoTriState.msoTrue; timerLabelTextBox.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered; var timerTextBox = questionTimerSlide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 500, 450, 150, 90); var timerTextRange = timerTextBox.TextFrame.TextRange; timerTextRange.Text = slideQuestionModel.Countdown.ToString(); timerTextRange.Font.Name = this.font; timerTextRange.Font.Size = 26; timerTextBox.TextEffect.FontBold = MsoTriState.msoTrue; timerTextBox.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered; this.CleanResultsPage(resultsSlide); }
private List <ResultModel> GetBest10Responses(SlideQuestionModel slideQuestionModel, List <ResultModel> responses) { var correctResponsesresponses = this.FilterForCorrectResponsesClick(slideQuestionModel, responses); var best10Responses = new List <ResultModel>(); for (var i = 0; i < 10; i++) { if (correctResponsesresponses.Count == 0) { break; } var minResponse = correctResponsesresponses.First(r => r.responseTime == correctResponsesresponses.Min(r2 => r2.responseTime)); best10Responses.Add(minResponse); correctResponsesresponses.Remove(minResponse); } return(best10Responses.OrderBy(r => r.responseTime).ToList()); }
private void AddQuestionSlideContent(SlideQuestionModel slideQuestionModel, Slide questionSlide, bool isRangedOrFreetextQuestion, string sessionInfoString) { // session info var sessionInfoTextBox = questionSlide.Shapes.AddTextbox( MsoTextOrientation.msoTextOrientationHorizontal, 50, 25, 850, 60); var sessionInfoTextRange = sessionInfoTextBox.TextFrame.TextRange; sessionInfoTextRange.Text = sessionInfoString; sessionInfoTextRange.Font.Name = this.font; sessionInfoTextRange.Font.Size = 22; sessionInfoTextBox.TextEffect.FontBold = MsoTriState.msoTrue; sessionInfoTextBox.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered; // question var questionTextBox = questionSlide.Shapes.AddTextbox( MsoTextOrientation.msoTextOrientationHorizontal, 50, isRangedOrFreetextQuestion ? 240 : 100, 850, isRangedOrFreetextQuestion ? 100 : 60); var questionTextRange = questionTextBox.TextFrame.TextRange; questionTextRange.Text = slideQuestionModel.QuestionText; questionTextRange.Font.Name = this.font; questionTextRange.Font.Size = 22; questionTextBox.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered; // answer options // no answer options on ranged questions or on free text if (!isRangedOrFreetextQuestion) { var answerOptionsString = slideQuestionModel.AnswerOptions .Aggregate(string.Empty, (current, castedAnswerOption) => current + $"{this.PositionNumberToLetter(castedAnswerOption.Position - 1)}: {castedAnswerOption.Text}{Environment.NewLine}"); var answerOptionsTextBox = questionSlide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 50, 170, 850, 150); var answerOptionsTextRange = answerOptionsTextBox.TextFrame.TextRange; answerOptionsTextRange.Text = answerOptionsString; answerOptionsTextRange.Font.Name = this.font; answerOptionsTextRange.Font.Size = 20; } }
private QuestionModel SlideQuestionModelToQuestionModel(SlideQuestionModel slideQuestionModel, string hashtag) { var questionModel = new QuestionModel { hashtag = Uri.EscapeDataString(hashtag), questionText = Uri.EscapeDataString(slideQuestionModel.QuestionText), timer = slideQuestionModel.Countdown, startTime = 0, questionIndex = slideQuestionModel.RecalculatedOnlineIndex, displayAnswerText = false, type = this.QuestionTypeToClickQuestionType(slideQuestionModel.QuestionType) }; if (slideQuestionModel.QuestionType == QuestionTypeEnum.RangedQuestionClick) { var rangedAnswerOption = slideQuestionModel.AnswerOptions.First(); if (rangedAnswerOption == null) { throw new ArgumentException("no answer options provided"); } questionModel.rangeMin = rangedAnswerOption.RangedLowerLimit; questionModel.rangeMax = rangedAnswerOption.RangedHigherLimit; questionModel.correctValue = rangedAnswerOption.RangedCorrectValue; questionModel.answerOptionList = new List <AnswerOptionModel>(); } else { var isFreetextAnswerOption = slideQuestionModel.QuestionType == QuestionTypeEnum.FreeTextClick; var answerOptionModelList = slideQuestionModel.AnswerOptions.Select(a => this.SlideAnswerOptionModelToAnswerOptionModel(a, hashtag, slideQuestionModel.RecalculatedOnlineIndex, isFreetextAnswerOption)) .ToList(); questionModel.answerOptionList = answerOptionModelList; } return(questionModel); }
private void SetQuestionInfoSlidecontent(SlideQuestionModel slideQuestionModel, Slide questionInfoSlide, bool isRangedOrFreetextQuestion) { var isClickQuestion = this.sessionInformationProvider.IsClickQuestion(slideQuestionModel.QuestionType); var sessionInfoString = isClickQuestion ? "https://arsnova.click/" + slideQuestionModel.Hashtag : "https://arsnova.eu/mobile/#id/" + slideQuestionModel.Hashtag; this.RemoveShapesFromSlide(questionInfoSlide); questionInfoSlide.Layout = PpSlideLayout.ppLayoutBlank; this.AddQuestionSlideContent(slideQuestionModel, questionInfoSlide, isRangedOrFreetextQuestion, sessionInfoString); // Button not possible, just added a textbox to start quiz on next slide (when in click, voting will start immediately) if (isClickQuestion) { var startQuizTextBox = questionInfoSlide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 50, 450, 850, 50); var startQuizTextRange = startQuizTextBox.TextFrame.TextRange; startQuizTextRange.Text = this.localizationService.Translate("Move to the next slide to start the quiz."); startQuizTextRange.Font.Name = this.font; startQuizTextRange.Font.Size = 20; startQuizTextBox.TextEffect.FontBold = MsoTriState.msoTrue; startQuizTextBox.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered; } }
private void AddQuizToSlide(Slide slide) { var slideSessionModel = this.GetSlideSessionModel(); if (!slideSessionModel.SessionTypeSet) { this.viewPresenter.ShowInNewWindow( new SelectArsnovaTypeViewViewModel( new ViewModelRequirements( this.viewPresenter, this.questionTypeTranslator, this.localizationService, this.sessionManager, this.sessionInformationProvider, this.slideManipulator, slideSessionModel)), vm => { vm.OnSelectArsnovaTypeViewClose += () => this.AddQuizToSlide(slide); }); return; } var newQuestion = new SlideQuestionModel { QuestionType = slideSessionModel.SessionType == SessionType.ArsnovaClick ? QuestionTypeEnum.SingleChoiceClick : QuestionTypeEnum.SingleChoiceVoting, Index = slideSessionModel.Questions.Count, Hashtag = slideSessionModel.Hashtag, RecalculatedOnlineIndex = slideSessionModel.Questions.Count(q => !q.Hidden), QuestionInfoSlideId = slide.SlideID }; slideSessionModel.Questions.Add(newQuestion); this.viewPresenter.ShowInNewWindow( new QuestionViewViewModel(this.CreateViewModelRequirements(slideSessionModel), newQuestion.Id, true)); }
public void StartClickQuestion(SlideSessionModel slideSessionModel, int questionIndex, Slide questionTimerSlideParam, Slide resultsSlideParam) { var validationResult = new ValidationResult(); this.currentQuestionModel = slideSessionModel.Questions.First(q => q.Index == questionIndex); this.questionTimerSlide = questionTimerSlideParam; this.resultsSlide = resultsSlideParam; this.currentSlideSessionModel = slideSessionModel; validationResult = this.arsnovaClickService.StartNextQuestion(slideSessionModel, this.currentQuestionModel.RecalculatedOnlineIndex); this.countdown = this.currentQuestionModel.Countdown; this.timer = new Timer(1000); this.timer.Elapsed += this.HandleTimerEvent; this.timer.Start(); if (!validationResult.Success) { throw new CommunicationException(validationResult.FailureMessage); } }
private void SetQuestionState(SlideSessionModel slideSessionModel, SlideQuestionModel slideQuestionModel, bool sessionStatus) { this.CheckAuthentification(slideSessionModel); var lectureObject = this.GetLectureQuestion(slideSessionModel, slideQuestionModel.ArsnovaVotingId); lectureObject.active = sessionStatus; var apiPath = "lecturerquestion/" + slideQuestionModel.ArsnovaVotingId + "/publish?_dc=" + this.ConvertToUnixTimestampString(DateTime.Now); var requestBody = JsonConvert.SerializeObject(lectureObject); try { var request = this.CreateWebRequest(slideSessionModel, apiPath, HttpMethod.Post); request = this.AddContentToRequest(request, requestBody); this.SendRequest(request); } catch (JsonReaderException exception) { throw new CommunicationException("Start question failed", exception); } }
public void SetVotingResults(SlideQuestionModel slideQuestionModel, Slide resultsSlide, List <ArsnovaVotingResultReturnElement> results) { var floatLeft = 150; var floatTop = 300; var width = 650; var height = 350; switch (slideQuestionModel.ChartType) { case Excel.XlChartType.xl3DColumnClustered: case Excel.XlChartType.xl3DBarClustered: floatLeft = 150; floatTop = 150; break; case Excel.XlChartType.xl3DPie: floatLeft = 200; width = 350; height = 350; break; } this.AddChartToShape(slideQuestionModel, resultsSlide, null, results, floatLeft, floatTop, width, height); }
public void SetClickResults(SlideQuestionModel slideQuestionModel, Slide resultsSlide, List <ResultModel> results) { // chart init dimensions var floatLeft = 150; var floatTop = 280; var width = 650; var height = 250; var best10Responses = this.GetBest10Responses(slideQuestionModel, results); var resultsColumn1Text = string.Empty; var resultsColumn2Text = string.Empty; var i = 1; foreach (var response in best10Responses) { if (i % 2 == 0) { resultsColumn2Text += $"{i}. {response.userNick}{Environment.NewLine}"; } else { resultsColumn1Text += $"{i}. {response.userNick}{Environment.NewLine}"; } i++; } var leaderBoardColumn1TextBox = resultsSlide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 50, 120, 400, 200); var leaderBoardColumn1TextRange = leaderBoardColumn1TextBox.TextFrame.TextRange; leaderBoardColumn1TextRange.Text = resultsColumn1Text; leaderBoardColumn1TextRange.Font.Name = this.font; leaderBoardColumn1TextRange.Font.Size = 20; leaderBoardColumn1TextBox.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered; var leaderBoardColumn2TextBox = resultsSlide.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 500, 120, 400, 200); var leaderBoardColumn2TextRange = leaderBoardColumn2TextBox.TextFrame.TextRange; leaderBoardColumn2TextRange.Text = resultsColumn2Text; leaderBoardColumn2TextRange.Font.Name = this.font; leaderBoardColumn2TextRange.Font.Size = 20; leaderBoardColumn2TextBox.TextEffect.Alignment = MsoTextEffectAlignment.msoTextEffectAlignmentCentered; // chart dimensions switch (slideQuestionModel.ChartType) { case Excel.XlChartType.xl3DColumnClustered: case Excel.XlChartType.xl3DBarClustered: // use default values break; case Excel.XlChartType.xlPie: floatLeft = 275; width = 250; break; } this.AddChartToShape(slideQuestionModel, resultsSlide, results, null, floatLeft, floatTop, width, height); }
private void InitializeWindowCommandBindings() { this.WindowCommandBindings.AddRange( new List <CommandBinding> { new CommandBinding( NavigationButtonCommands.Finish, (e, o) => { PresentationInformationStore.StoreSlideSessionModel(this.SlideSessionModel); this.ViewPresenter.CloseWithoutPrompt(); }, (e, o) => o.CanExecute = true), /*new CommandBinding( * NavigationButtonCommands.Back, * (e, o) => * { * this.ViewPresenter.Show( * new SelectArsnovaTypeViewViewModel(this.GetViewModelRequirements())); * }, * (e, o) => o.CanExecute = true), * new CommandBinding( * NavigationButtonCommands.New, * (e, o) => * { * var newQuestion = new SlideQuestionModel(this.QuestionTypeTranslator) * { * QuestionType = this.SlideSessionModel.SessionType * == SessionType.ArsnovaClick * ? QuestionTypeEnum.SingleChoiceClick * : QuestionTypeEnum.SingleChoiceVoting, * Index = this.SlideSessionModel.Questions.Count * // no new question without selected slide! * }; * * * this.SlideSessionModel.Questions.Add(newQuestion); * * this.OpenQuestionEditDialog(newQuestion.Id, true); * }, * (e, o) => o.CanExecute = true),*/ new CommandBinding( NavigationButtonCommands.Edit, (e, o) => { this.OpenQuestionEditDialog(this.SelectedSlideQuestionModel.Id, false); }, (e, o) => o.CanExecute = this.SelectedSlideQuestionModel != null), new CommandBinding( NavigationButtonCommands.Delete, (e, o) => { var questionText = $"{this.LocalizationService.Translate("Do you really want to delete this question?")}{Environment.NewLine}{Environment.NewLine}"; questionText += this.SelectedSlideQuestionModel.QuestionText; var deleteQuestion = PopUpWindow.ConfirmationWindow( this.LocalizationService.Translate("Delete"), questionText); if (deleteQuestion) { var questionModel = this.SelectedSlideQuestionModel; SlideTracker.RemoveSlide(questionModel.QuestionInfoSlideId); SlideTracker.RemoveSlide(questionModel.QuestionTimerSlideId.Value); SlideTracker.RemoveSlide(questionModel.ResultsSlideId.Value); this.SelectedSlideQuestionModel = null; this.SlideSessionModel.Questions.Remove(questionModel); } }, (e, o) => o.CanExecute = this.SelectedSlideQuestionModel != null) }); }
public void StartQuestion(SlideSessionModel slideSessionModel, SlideQuestionModel slideQuestionModel) { this.SetQuestionState(slideSessionModel, slideQuestionModel, true); }
public List <ArsnovaVotingResultReturnElement> GetResults(SlideSessionModel slideSessionModel, SlideQuestionModel slideQuestionModel) { this.SetQuestionState(slideSessionModel, slideQuestionModel, false); var apiPath = "lecturerquestion/" + slideQuestionModel.ArsnovaVotingId + "/answer/?piround=1&_dc=" + this.ConvertToUnixTimestampString(DateTime.Now); try { var request = this.CreateWebRequest(slideSessionModel, apiPath, HttpMethod.Get, false); request.Headers.Add(HttpRequestHeader.AcceptEncoding, " sdch"); var responseString = this.GetResponseString(slideSessionModel, request); return(JsonConvert.DeserializeObject <List <ArsnovaVotingResultReturnElement> >(responseString)); } catch (JsonReaderException exception) { throw new CommunicationException("Get results or json deserialization failed", exception); } }
private Tuple <string, string> UpdateQuestion(SlideSessionModel slideSessionModel, SlideQuestionModel questionModel, string arsnovaVotingQuestionId) { var oldQuestion = this.GetLectureQuestion(slideSessionModel, arsnovaVotingQuestionId); // update entries oldQuestion.questionType = this.QuestionTypeToVotingQuestionType(questionModel.QuestionType); oldQuestion.text = questionModel.QuestionText; if (questionModel.QuestionType == QuestionTypeEnum.FreeTextVoting) { var answerOption = questionModel.AnswerOptions.First(); oldQuestion.strictMode = true; oldQuestion.textAnswerEnabled = true; oldQuestion.correctAnswer = answerOption.Text; oldQuestion.fixedAnswer = true; oldQuestion.ignoreCaseSensitive = answerOption.ConfigCaseSensitive; oldQuestion.ignorePunctuation = answerOption.ConfigUsePunctuation; oldQuestion.ignoreWhitespaces = answerOption.ConfigTrimWhitespaces; } else { var answerOptionList = new List <PossibleAnswerObject>(); foreach (var answerOption in questionModel.AnswerOptions) { answerOptionList.Add(new PossibleAnswerObject { correct = answerOption.IsTrue, text = answerOption.Text, value = answerOption.IsTrue ? 10 : -10 }); } oldQuestion.possibleAnswers = answerOptionList; } var apiPath = "lecturerquestion/" + arsnovaVotingQuestionId; var requestBody = JsonConvert.SerializeObject(oldQuestion); try { var request = this.CreateWebRequest(slideSessionModel, apiPath, HttpMethod.Put); request = this.AddContentToRequest(request, requestBody); var responseString = this.GetResponseString(slideSessionModel, request); var newQuestionModel = JsonConvert.DeserializeObject <LectureQuestionModelWithId>(responseString); return(new Tuple <string, string>(newQuestionModel._id, newQuestionModel._rev)); } catch (JsonReaderException exception) { throw new CommunicationException("Update question failed", exception); } }
private List <ResultModel> GetCorrectFreeTextResults(SlideQuestionModel slideQuestionModel, List <ResultModel> responses) { var correctResponses = new List <ResultModel>(); var answerOption = slideQuestionModel.AnswerOptions.First(); var answerOptionText = answerOption.Text; var punctutationRegex = new Regex(@"(\.)*(,)*(!)*("")*(;)*(\?)*"); var whiteSpaceRegex = new Regex(@" "); if (!answerOption.ConfigCaseSensitive) { answerOptionText = answerOptionText.ToLower(); } if (!answerOption.ConfigUsePunctuation) { answerOptionText = punctutationRegex.Replace(answerOptionText, ""); } if (answerOption.ConfigUseKeywords && !answerOption.ConfigTrimWhitespaces) { answerOptionText = whiteSpaceRegex.Replace(answerOptionText, ""); } foreach (var response in responses) { var isCorrect = false; var responseText = response.freeTextInputValue; if (!answerOption.ConfigCaseSensitive) { responseText = responseText.ToLower(); } if (!answerOption.ConfigUsePunctuation) { responseText = punctutationRegex.Replace(responseText, ""); } if (answerOption.ConfigUseKeywords) { if (!answerOption.ConfigTrimWhitespaces) { responseText = whiteSpaceRegex.Replace(responseText, ""); } isCorrect = answerOptionText == responseText; } else { isCorrect = true; var responseWords = responseText.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); var answerOptionWords = answerOptionText.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); foreach (var answerOptionWord in answerOptionWords) { if (responseWords.Any(r => r != answerOptionWord)) { isCorrect = false; } } } if (isCorrect) { correctResponses.Add(response); } } return(correctResponses); }
private void AddChartToShape( SlideQuestionModel slideQuestionModel, Slide resultsSlide, List <ResultModel> clickResults, List <ArsnovaVotingResultReturnElement> votingResults, int floatLeft, int floatTop, int width, int height) { var chartName = "ARSnova Results Chart"; var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location; var excelWorkBookPath = Path.GetDirectoryName(currentAssembly) + "\\" + "resultsChartData.xlsx"; var excelApp = new Excel.Application(); var workBook = excelApp.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet); try { if (File.Exists(excelWorkBookPath)) { File.Delete(excelWorkBookPath); } var workSheet = (Excel.Worksheet)(workBook.Worksheets[1]); workSheet.Name = "ARSnovaResults"; Excel.Range dataRange; switch (slideQuestionModel.QuestionType) { case QuestionTypeEnum.MultipleChoiceClick: case QuestionTypeEnum.FreeTextClick: case QuestionTypeEnum.RangedQuestionClick: var correctAnswerOptionsAmount = this.FilterForCorrectResponsesClick(slideQuestionModel, clickResults).Count; var wrongAnswerOptionsAmount = clickResults.Count - correctAnswerOptionsAmount; this.SetExcelCellValue(workSheet, "A1", this.localizationService.Translate("Right")); this.SetExcelCellValue(workSheet, "B1", correctAnswerOptionsAmount); this.SetExcelCellValue(workSheet, "A2", this.localizationService.Translate("Wrong")); this.SetExcelCellValue(workSheet, "B2", wrongAnswerOptionsAmount); dataRange = workSheet.get_Range("A1", "B2"); break; case QuestionTypeEnum.SingleChoiceClick: case QuestionTypeEnum.YesNoClick: case QuestionTypeEnum.TrueFalseClick: case QuestionTypeEnum.SurveyClick: // Range: One Column for each answer option // One row for the amount of students voted for that answer option for (var i = 0; i < slideQuestionModel.AnswerOptions.Count; i++) { var answerOption = slideQuestionModel.AnswerOptions.First(ao => ao.Position - 1 == i); this.SetExcelCellValue(workSheet, $"A{i + 1}", answerOption.Text); this.SetExcelCellValue(workSheet, $"B{i + 1}", clickResults.Count(r => r.answerOptionNumber.Contains(answerOption.Position - 1))); } dataRange = workSheet.get_Range("A1", $"B{slideQuestionModel.AnswerOptions.Count}"); break; // arsnova.voting case QuestionTypeEnum.SingleChoiceVoting: case QuestionTypeEnum.YesNoVoting: case QuestionTypeEnum.EvaluationVoting: case QuestionTypeEnum.GradsVoting: for (var i = 0; i < slideQuestionModel.AnswerOptions.Count; i++) { var answerOption = slideQuestionModel.AnswerOptions.First(ao => ao.Position - 1 == i); var resultItem = votingResults.FirstOrDefault(vr => vr.answerText == answerOption.Text); var answerCount = resultItem?.answerCount ?? 0; this.SetExcelCellValue(workSheet, $"A{i + 1}", answerOption.Text); this.SetExcelCellValue(workSheet, $"B{i + 1}", answerCount); } dataRange = workSheet.get_Range("A1", $"B{slideQuestionModel.AnswerOptions.Count}"); break; case QuestionTypeEnum.MultipleChoiceVoting: var correctAnswerOptionsCount = 0; var wrongAnswerOptionsCount = 0; var correctAnswerOptionString = string.Empty; for (var i = 0; i < slideQuestionModel.AnswerOptions.Count; i++) { var answerOption = slideQuestionModel.AnswerOptions.First(ao => ao.Position - 1 == i); if (answerOption.IsTrue) { correctAnswerOptionString += "1"; } else { correctAnswerOptionString += "0"; } } foreach (var resultElement in votingResults) { var answerTextString = resultElement.answerText.Replace(",", string.Empty); if (correctAnswerOptionString == answerTextString) { correctAnswerOptionsCount += resultElement.answerCount; } else { wrongAnswerOptionsCount += resultElement.answerCount; } } this.SetExcelCellValue(workSheet, "A1", this.localizationService.Translate("Right")); this.SetExcelCellValue(workSheet, "B1", correctAnswerOptionsCount); this.SetExcelCellValue(workSheet, "A2", this.localizationService.Translate("Wrong")); this.SetExcelCellValue(workSheet, "B2", wrongAnswerOptionsCount); dataRange = workSheet.get_Range("A1", "B2"); break; case QuestionTypeEnum.FreeTextVoting: var correctFreeTextAnswers = this.GetCorrectFreeTextResultsVoting(slideQuestionModel, votingResults).Count; var falseFreeTextAnswers = votingResults.Count - correctFreeTextAnswers; this.SetExcelCellValue(workSheet, "A1", this.localizationService.Translate("Right")); this.SetExcelCellValue(workSheet, "B1", correctFreeTextAnswers); this.SetExcelCellValue(workSheet, "A2", this.localizationService.Translate("Wrong")); this.SetExcelCellValue(workSheet, "B2", falseFreeTextAnswers); dataRange = workSheet.get_Range("A1", "B2"); break; default: dataRange = workSheet.get_Range("A1", "B2"); break; // 0,0,0,1 -> answeroption 4; 1,0,0,0 -> answeroption 1 etc.; create tuples of position and answerElemt // 1,1,0,0 is a answerText of a mulitple choice question1 } var chartObjects = (Excel.ChartObjects)workSheet.ChartObjects(Type.Missing); var newChartObject = chartObjects.Add(floatLeft, floatTop, width, height); newChartObject.Name = chartName; newChartObject.Chart.ChartWizard( dataRange, slideQuestionModel.ChartType, this.GetChartFormat(slideQuestionModel.ChartType), // chart format Excel.XlRowCol.xlColumns, 1, //slideQuestionModel.AnswerOptions.Count - 1, // category labels 0, // series labels false, // has legend slideQuestionModel.QuestionText, // title this.localizationService.Translate("Answers"), // category title this.localizationService.Translate("Amount"), // value title Type.Missing); // extra titel // save before edit - user needs to confirm the overwriting of the file -> don't save the file twice! //workBook.SaveAs(excelWorkBookPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, //Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // editing newChartObject.Chart.Perspective = 0; Excel.Series serie = newChartObject.Chart.SeriesCollection(1); // Evaluation, grades and surveys shouldn't be colorized switch (slideQuestionModel.QuestionType) { case QuestionTypeEnum.SingleChoiceVoting: case QuestionTypeEnum.YesNoVoting: case QuestionTypeEnum.SingleChoiceClick: case QuestionTypeEnum.YesNoClick: case QuestionTypeEnum.TrueFalseClick: // normal evaluated graph (correct = green, any other answer option = red) for (var i = 0; i < slideQuestionModel.AnswerOptions.Count; i++) { var point = (Excel.Point)serie.Points(i + 1); point.Interior.Color = slideQuestionModel.AnswerOptions.First(ao => ao.Position == i + 1).IsTrue ? Color.FromArgb(0, 255, 0).ToArgb() : Color.FromArgb(0, 0, 255).ToArgb(); } break; case QuestionTypeEnum.MultipleChoiceVoting: case QuestionTypeEnum.FreeTextVoting: case QuestionTypeEnum.MultipleChoiceClick: case QuestionTypeEnum.FreeTextClick: case QuestionTypeEnum.RangedQuestionClick: // freetext, ranged and multiple: right and wrong only // the part above sets the first point of the series as the correct answer and the second one as the false one serie.Points(1).Interior.Color = Color.FromArgb(0, 255, 0).ToArgb(); // green serie.Points(2).Interior.Color = Color.FromArgb(0, 0, 255).ToArgb(); // red break; } // save again to avoid question before closing workBook.SaveAs(excelWorkBookPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); // Copy chart to PowerPoint slide newChartObject.Copy(); var shapeRange = resultsSlide.Shapes.Paste(); shapeRange.Left = floatLeft; shapeRange.Top = floatTop; shapeRange.LinkFormat.Update(); excelApp.Quit(); } catch (Exception e) { // Error handling? workBook.SaveAs(excelWorkBookPath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); excelApp.Quit(); } }