/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.course.nodes.gta.ui;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.olat.core.commons.services.help.HelpModule;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.DateChooser;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
import org.olat.core.gui.components.form.flexible.elements.StaticTextElement;
import org.olat.core.gui.components.form.flexible.elements.TextElement;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
import org.olat.core.gui.control.generic.modal.DialogBoxController;
import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
import org.olat.core.util.Formatter;
import org.olat.core.util.StringHelper;
import org.olat.course.condition.AreaSelectionController;
import org.olat.course.condition.GroupSelectionController;
import org.olat.course.editor.CourseEditorEnv;
import org.olat.course.nodes.GTACourseNode;
import org.olat.course.nodes.gta.GTAManager;
import org.olat.course.nodes.gta.GTARelativeToDates;
import org.olat.course.nodes.gta.GTAType;
import org.olat.group.BusinessGroupService;
import org.olat.group.BusinessGroupShort;
import org.olat.group.area.BGArea;
import org.olat.group.area.BGAreaManager;
import org.olat.modules.ModuleConfiguration;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryService;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 24.02.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class GTAWorkflowEditController extends FormBasicController {
private static final String[] onKeys = new String[]{ "on" };
private static final String[] executionKeys = new String[]{ GTAType.group.name(), GTAType.individual.name() };
private CloseableModalController cmc;
private DialogBoxController confirmChangesCtrl;
private AreaSelectionController areaSelectionCtrl;
private GroupSelectionController groupSelectionCtrl;
private SingleSelection typeEl;
private FormLink chooseGroupButton, chooseAreaButton;
private StaticTextElement groupListEl, areaListEl;
private DateChooser assignmentDeadlineEl, submissionDeadlineEl, solutionVisibleAfterEl;
private MultipleSelectionElement relativeDatesEl, taskAssignmentEl, submissionEl, reviewEl, revisionEl, sampleEl, gradingEl;
private FormLayoutContainer stepsCont, assignmentRelDeadlineCont, submissionRelDeadlineCont, solutionVisibleRelCont;
private TextElement assignementDeadlineDaysEl, submissionDeadlineDaysEl, solutionVisibleRelDaysEl;
private SingleSelection assignementDeadlineRelToEl, submissionDeadlineRelToEl, solutionVisibleRelToEl;
private final GTACourseNode gtaNode;
private final ModuleConfiguration config;
private final CourseEditorEnv courseEditorEnv;
private List<Long> areaKeys;
private List<Long> groupKeys;
private final RepositoryEntry courseRe;
@Autowired
private HelpModule helpModule;
@Autowired
private GTAManager gtaManager;
@Autowired
private BGAreaManager areaManager;
@Autowired
private BusinessGroupService businessGroupService;
@Autowired
private RepositoryService repositoryService;
public GTAWorkflowEditController(UserRequest ureq, WindowControl wControl, GTACourseNode gtaNode, CourseEditorEnv courseEditorEnv) {
super(ureq, wControl, LAYOUT_BAREBONE);
this.gtaNode = gtaNode;
this.config = gtaNode.getModuleConfiguration();
this.courseEditorEnv = courseEditorEnv;
//reload to make sure we have the last changes
courseRe = repositoryService
.loadByKey(courseEditorEnv.getCourseGroupManager().getCourseEntry().getKey());
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
String type = config.getStringValue(GTACourseNode.GTASK_TYPE);
FormLayoutContainer typeCont = FormLayoutContainer.createDefaultFormLayout("type", getTranslator());
typeCont.setFormTitle(translate("task.type.title"));
typeCont.setFormDescription(translate("task.type.description"));
typeCont.setElementCssClass("o_sel_course_gta_groups_areas");
typeCont.setRootForm(mainForm);
formLayout.add(typeCont);
String[] executionValues = new String[]{
translate("task.execution.group"),
translate("task.execution.individual")
};
typeEl = uifactory.addDropdownSingleselect("execution", "task.execution", typeCont, executionKeys, executionValues, null);
typeEl.addActionListener(FormEvent.ONCHANGE);
typeEl.setEnabled(false);
if(StringHelper.containsNonWhitespace(type)) {
for(String executionKey:executionKeys) {
if(executionKey.equals(type)) {
typeEl.select(executionKey, true);
}
}
}
if(!typeEl.isOneSelected()) {
typeEl.select(executionKeys[0], true);
}
chooseGroupButton = uifactory.addFormLink("choose.groups", "choose.groups", "choosed.groups", typeCont, Link.BUTTON_XSMALL);
chooseGroupButton.setCustomEnabledLinkCSS("btn btn-default o_xsmall o_form_groupchooser");
chooseGroupButton.setElementCssClass("o_omit_margin");
chooseGroupButton.setIconLeftCSS("o_icon o_icon-fw o_icon_group");
if(!courseEditorEnv.getCourseGroupManager().hasBusinessGroups()){
chooseGroupButton.setI18nKey("create.groups");
}
groupKeys = config.getList(GTACourseNode.GTASK_GROUPS, Long.class);
String groupList = getGroupNames(groupKeys);
groupListEl = uifactory.addStaticTextElement("group.list", null, groupList, typeCont);
groupListEl.setElementCssClass("text-muted");
groupListEl.setLabel(null, null);
chooseAreaButton = uifactory.addFormLink("choose.areas", "choose.areas", "choosed.areas", typeCont, Link.BUTTON_XSMALL);
chooseAreaButton.setCustomEnabledLinkCSS("btn btn-default o_xsmall o_form_areachooser");
chooseAreaButton.setElementCssClass("o_omit_margin");
chooseAreaButton.setIconLeftCSS("o_icon o_icon-fw o_icon_courseareas");
if(!courseEditorEnv.getCourseGroupManager().hasAreas()){
chooseAreaButton.setI18nKey("create.areas");
}
areaKeys = config.getList(GTACourseNode.GTASK_AREAS, Long.class);
String areaList = getAreaNames(areaKeys);
areaListEl = uifactory.addStaticTextElement("areas.list", null, areaList, typeCont);
areaListEl.setElementCssClass("text-muted");
areaListEl.setLabel(null, null);
boolean mismatch = ((GTAType.group.name().equals(type) && !gtaNode.getType().equals(GTACourseNode.TYPE_GROUP))
|| (GTAType.individual.name().equals(type) && !gtaNode.getType().equals(GTACourseNode.TYPE_INDIVIDUAL)));
if(GTAType.group.name().equals(type)) {
typeEl.setVisible(mismatch);
} else if(GTAType.individual.name().equals(type)) {
if(mismatch) {
typeEl.setVisible(true);
chooseGroupButton.setVisible(false);
groupListEl.setVisible(false);
chooseAreaButton.setVisible(false);
areaListEl.setVisible(false);
} else {
typeCont.setVisible(false);
}
}
//Steps
stepsCont = FormLayoutContainer.createDefaultFormLayout("steps", getTranslator());
stepsCont.setFormTitle(translate("task.steps.title"));
stepsCont.setFormDescription(translate("task.steps.description"));
stepsCont.setElementCssClass("o_sel_course_gta_steps");
stepsCont.setRootForm(mainForm);
stepsCont.setFormContextHelp("Assessment#_task_workflow");
formLayout.add(stepsCont);
relativeDatesEl = uifactory.addCheckboxesHorizontal("relative.dates", "relative.dates", stepsCont, onKeys, new String[]{ "" });
relativeDatesEl.addActionListener(FormEvent.ONCHANGE);
boolean useRelativeDates = config.getBooleanSafe(GTACourseNode.GTASK_RELATIVE_DATES);
relativeDatesEl.select(onKeys[0], useRelativeDates);
uifactory.addSpacerElement("s1", stepsCont, true);
//assignment
String[] assignmentValues = new String[] { translate("task.assignment.enabled") };
taskAssignmentEl = uifactory.addCheckboxesHorizontal("task.assignment", "task.assignment", stepsCont, onKeys, assignmentValues);
taskAssignmentEl.addActionListener(FormEvent.ONCHANGE);
boolean assignement = config.getBooleanSafe(GTACourseNode.GTASK_ASSIGNMENT);
taskAssignmentEl.select(onKeys[0], assignement);
Date assignmentDeadline = config.getDateValue(GTACourseNode.GTASK_ASSIGNMENT_DEADLINE);
assignmentDeadlineEl = uifactory.addDateChooser("assignementdeadline", "assignment.deadline", assignmentDeadline, stepsCont);
assignmentDeadlineEl.setDateChooserTimeEnabled(true);
assignmentDeadlineEl.setVisible(assignement && !useRelativeDates);
String relativeDatePage = velocity_root + "/assignment_relative_date.html";
assignmentRelDeadlineCont = FormLayoutContainer.createCustomFormLayout("assignmentRelativeDeadline", getTranslator(), relativeDatePage);
assignmentRelDeadlineCont.setRootForm(mainForm);
assignmentRelDeadlineCont.setLabel("assignment.deadline", null);
assignmentRelDeadlineCont.setVisible(assignement && useRelativeDates);
stepsCont.add(assignmentRelDeadlineCont);
int numOfDays = config.getIntegerSafe(GTACourseNode.GTASK_ASSIGNMENT_DEADLINE_RELATIVE, -1);
String assignmentNumOfDays = numOfDays >= 0 ? Integer.toString(numOfDays) : "";
String assignmentRelativeTo = config.getStringValue(GTACourseNode.GTASK_ASSIGNMENT_DEADLINE_RELATIVE_TO);
assignementDeadlineDaysEl = uifactory.addTextElement("assignment.numOfDays", null, 4, assignmentNumOfDays, assignmentRelDeadlineCont);
assignementDeadlineDaysEl.setDisplaySize(4);
assignementDeadlineDaysEl.setDomReplacementWrapperRequired(false);
RelativeDateKeysAndValues assignmentKeysAndValues = getRelativesDatesOption(true);
assignementDeadlineRelToEl = uifactory
.addDropdownSingleselect("assignmentrelativeto", "assignment.relative.to", null, assignmentRelDeadlineCont,
assignmentKeysAndValues.getKeys(), assignmentKeysAndValues.getValues(), null);
assignementDeadlineRelToEl.setDomReplacementWrapperRequired(false);
boolean found = false;
if(StringHelper.containsNonWhitespace(assignmentRelativeTo)) {
for(String relativeDatesKey:assignmentKeysAndValues.getKeys()) {
if(relativeDatesKey.equals(assignmentRelativeTo)) {
assignementDeadlineRelToEl.select(relativeDatesKey, true);
found = true;
}
}
}
if(!found) {
assignementDeadlineRelToEl.select(assignmentKeysAndValues.getKeys()[0], true);
}
uifactory.addSpacerElement("s2", stepsCont, true);
//turning in
String[] submissionValues = new String[] { translate("submission.enabled") };
submissionEl = uifactory.addCheckboxesHorizontal("submission", "submission", stepsCont, onKeys, submissionValues);
submissionEl.addActionListener(FormEvent.ONCHANGE);
boolean submit = config.getBooleanSafe(GTACourseNode.GTASK_SUBMIT);
submissionEl.select(onKeys[0], submit);
Date submissionDeadline = config.getDateValue(GTACourseNode.GTASK_SUBMIT_DEADLINE);
submissionDeadlineEl = uifactory.addDateChooser("submitdeadline", "submit.deadline", submissionDeadline, stepsCont);
submissionDeadlineEl.setDateChooserTimeEnabled(true);
submissionDeadlineEl.setVisible(submit && !useRelativeDates);
//relative deadline
String submitPage = velocity_root + "/submit_relative_date.html";
submissionRelDeadlineCont = FormLayoutContainer.createCustomFormLayout("submitRelativeDeadline", getTranslator(), submitPage);
submissionRelDeadlineCont.setRootForm(mainForm);
submissionRelDeadlineCont.setLabel("submit.deadline", null);
submissionRelDeadlineCont.setVisible(submit && useRelativeDates);
stepsCont.add(submissionRelDeadlineCont);
numOfDays = config.getIntegerSafe(GTACourseNode.GTASK_SUBMIT_DEADLINE_RELATIVE, -1);
String submitRelDays = numOfDays >= 0 ? Integer.toString(numOfDays) : "";
String submitRelTo = config.getStringValue(GTACourseNode.GTASK_SUBMIT_DEADLINE_RELATIVE_TO);
submissionDeadlineDaysEl = uifactory.addTextElement("submit.numOfDays", null, 4, submitRelDays, submissionRelDeadlineCont);
submissionDeadlineDaysEl.setDomReplacementWrapperRequired(false);
submissionDeadlineDaysEl.setDisplaySize(4);
RelativeDateKeysAndValues submissionKeysAndValues = getRelativesDatesOption(false);
submissionDeadlineRelToEl = uifactory
.addDropdownSingleselect("submitrelativeto", "submit.relative.to", null, submissionRelDeadlineCont,
submissionKeysAndValues.getKeys(), submissionKeysAndValues.getValues(), null);
submissionDeadlineRelToEl.setDomReplacementWrapperRequired(false);
found = false;
if(StringHelper.containsNonWhitespace(submitRelTo)) {
for(String relativeDatesKey:submissionKeysAndValues.getKeys()) {
if(relativeDatesKey.equals(submitRelTo)) {
submissionDeadlineRelToEl.select(relativeDatesKey, true);
found = true;
}
}
}
if(!found) {
submissionDeadlineRelToEl.select(submissionKeysAndValues.getKeys()[0], true);
}
uifactory.addSpacerElement("s3", stepsCont, true);
//review and correction
String[] reviewValues = new String[] { translate("review.enabled") };
reviewEl = uifactory.addCheckboxesHorizontal("review", "review.and.correction", stepsCont, onKeys, reviewValues);
reviewEl.addActionListener(FormEvent.ONCHANGE);
boolean review = config.getBooleanSafe(GTACourseNode.GTASK_REVIEW_AND_CORRECTION);
reviewEl.select(onKeys[0], review);
//revision
String[] revisionValues = new String[] { translate("revision.enabled") };
revisionEl = uifactory.addCheckboxesHorizontal("revision", "revision.period", stepsCont, onKeys, revisionValues);
revisionEl.addActionListener(FormEvent.ONCHANGE);
boolean revision = config.getBooleanSafe(GTACourseNode.GTASK_REVISION_PERIOD);
revisionEl.select(onKeys[0], revision);
revisionEl.setVisible(review);
uifactory.addSpacerElement("s4", stepsCont, true);
//sample solution
String[] sampleValues = new String[] { translate("sample.solution.enabled") };
sampleEl = uifactory.addCheckboxesHorizontal("sample", "sample.solution", stepsCont, onKeys, sampleValues);
sampleEl.addActionListener(FormEvent.ONCHANGE);
boolean sample = config.getBooleanSafe(GTACourseNode.GTASK_SAMPLE_SOLUTION);
sampleEl.select(onKeys[0], sample);
Date solutionVisibleAfter = config.getDateValue(GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_AFTER);
solutionVisibleAfterEl = uifactory.addDateChooser("visibleafter", "sample.solution.visible.after", solutionVisibleAfter, stepsCont);
solutionVisibleAfterEl.setDateChooserTimeEnabled(true);
solutionVisibleAfterEl.setVisible(sample && !useRelativeDates);
//relative deadline
String solutionPage = velocity_root + "/solution_relative_date.html";
solutionVisibleRelCont = FormLayoutContainer.createCustomFormLayout("solutionRelativeDeadline", getTranslator(), solutionPage);
solutionVisibleRelCont.setRootForm(mainForm);
solutionVisibleRelCont.setLabel("sample.solution.visible.after", null);
solutionVisibleRelCont.setVisible(sample && useRelativeDates);
stepsCont.add(solutionVisibleRelCont);
numOfDays = config.getIntegerSafe(GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_AFTER_RELATIVE, -1);
String solutionRelDays = numOfDays >= 0 ? Integer.toString(numOfDays) : "";
String solutionRelTo = config.getStringValue(GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_AFTER_RELATIVE_TO);
solutionVisibleRelDaysEl = uifactory.addTextElement("solution.numOfDays", null, 4, solutionRelDays, solutionVisibleRelCont);
solutionVisibleRelDaysEl.setDisplaySize(4);
solutionVisibleRelDaysEl.setDomReplacementWrapperRequired(false);
RelativeDateKeysAndValues solutionKeysAndValues = getRelativesDatesOption(false);
solutionVisibleRelToEl = uifactory
.addDropdownSingleselect("solutionrelativeto", "solution.relative.to", null, solutionVisibleRelCont,
solutionKeysAndValues.getKeys(), solutionKeysAndValues.getValues(), null);
solutionVisibleRelToEl.setDomReplacementWrapperRequired(false);
found = false;
if(StringHelper.containsNonWhitespace(solutionRelTo)) {
for(String relativeDatesKey:solutionKeysAndValues.getKeys()) {
if(relativeDatesKey.equals(solutionRelTo)) {
solutionVisibleRelToEl.select(relativeDatesKey, true);
found = true;
}
}
}
if(!found) {
solutionVisibleRelToEl.select(solutionKeysAndValues.getKeys()[0], true);
}
uifactory.addSpacerElement("s5", stepsCont, true);
//grading
String[] gradingValues = new String[] { translate("grading.enabled") };
gradingEl = uifactory.addCheckboxesHorizontal("grading", "grading", stepsCont, onKeys, gradingValues);
gradingEl.addActionListener(FormEvent.ONCHANGE);
boolean grading = config.getBooleanSafe(GTACourseNode.GTASK_GRADING);
gradingEl.select(onKeys[0], grading);
//save
FormLayoutContainer buttonCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
buttonCont.setRootForm(mainForm);
buttonCont.setElementCssClass("o_sel_course_gta_save_workflow");
stepsCont.add(buttonCont);
uifactory.addFormSubmitButton("save", "save", buttonCont);
uifactory.addFormCancelButton("cancel", buttonCont, ureq, getWindowControl());
}
@Override
protected void doDispose() {
//
}
@Override
protected boolean validateFormLogic(UserRequest ureq) {
boolean allOk = true;
typeEl.clearError();
if(!typeEl.isOneSelected()) {
typeEl.setErrorKey("form.mandatory.hover", null);
allOk &= false;
}
boolean relativeDates = relativeDatesEl.isAtLeastSelected(1);
assignementDeadlineDaysEl.clearError();
if(relativeDates && taskAssignmentEl.isAtLeastSelected(1)) {
allOk &= validateIntegerOrEmpty(assignementDeadlineDaysEl);
}
submissionDeadlineDaysEl.clearError();
if(relativeDates && submissionEl.isAtLeastSelected(1)) {
allOk &= validateIntegerOrEmpty(submissionDeadlineDaysEl);
}
solutionVisibleRelDaysEl.clearError();
if(relativeDates && sampleEl.isAtLeastSelected(1)) {
allOk &= validateIntegerOrEmpty(solutionVisibleRelDaysEl);
}
taskAssignmentEl.clearError();
if(!taskAssignmentEl.isAtLeastSelected(1) && !submissionEl.isAtLeastSelected(1)
&& !reviewEl.isAtLeastSelected(1) && !revisionEl.isAtLeastSelected(1)
&& !sampleEl.isAtLeastSelected(1) && !gradingEl.isAtLeastSelected(1)) {
taskAssignmentEl.setErrorKey("error.select.atleastonestep", null);
allOk &= false;
}
return allOk & super.validateFormLogic(ureq);
}
private boolean validateIntegerOrEmpty(TextElement textEl) {
boolean allOk = true;
textEl.clearError();
String val = textEl.getValue();
if(StringHelper.containsNonWhitespace(val)) {
if(StringHelper.isLong(val)) {
} else {
textEl.setErrorKey("integer.element.int.error", null);
allOk &= false;
}
}
return allOk;
}
@Override
protected void formCancelled(UserRequest ureq) {
fireEvent(ureq, Event.CANCELLED_EVENT);
}
@Override
protected void formOK(UserRequest ureq) {
RepositoryEntry entry = courseEditorEnv.getCourseGroupManager().getCourseEntry();
if(gtaManager.isTasksInProcess(entry, gtaNode)) {
doConfirmChanges(ureq);
} else {
commitChanges();
fireEvent(ureq, Event.DONE_EVENT);
}
}
private void doConfirmChanges(UserRequest ureq) {
String title = translate("warning.tasks.in.process.title");
String url = helpModule.getHelpProvider().getURL(getLocale(), "Task - Further Configurations#_concurrent_edits");
String text = translate("warning.tasks.in.process.text", new String[]{ url });
confirmChangesCtrl = activateOkCancelDialog(ureq, title, text, confirmChangesCtrl);
}
private void commitChanges() {
if(typeEl.isSelected(0)) {
config.setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name());
config.setList(GTACourseNode.GTASK_AREAS, areaKeys);
config.setList(GTACourseNode.GTASK_GROUPS, groupKeys);
} else {
config.setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name());
config.setList(GTACourseNode.GTASK_AREAS, new ArrayList<Long>(0));
config.setList(GTACourseNode.GTASK_GROUPS, new ArrayList<Long>(0));
}
boolean relativeDates = relativeDatesEl.isAtLeastSelected(1);
config.setBooleanEntry(GTACourseNode.GTASK_RELATIVE_DATES, relativeDates);
boolean assignment = taskAssignmentEl.isAtLeastSelected(1);
config.setBooleanEntry(GTACourseNode.GTASK_ASSIGNMENT, assignment);
if(assignment) {
if(relativeDates) {
setRelativeDates(assignementDeadlineDaysEl, GTACourseNode.GTASK_ASSIGNMENT_DEADLINE_RELATIVE,
assignementDeadlineRelToEl, GTACourseNode.GTASK_ASSIGNMENT_DEADLINE_RELATIVE_TO);
} else {
config.setDateValue(GTACourseNode.GTASK_ASSIGNMENT_DEADLINE, assignmentDeadlineEl.getDate());
}
} else {
config.remove(GTACourseNode.GTASK_ASSIGNMENT_DEADLINE);
}
boolean turningIn = submissionEl.isAtLeastSelected(1);
config.setBooleanEntry(GTACourseNode.GTASK_SUBMIT, turningIn);
if(turningIn) {
if(relativeDates) {
setRelativeDates(submissionDeadlineDaysEl, GTACourseNode.GTASK_SUBMIT_DEADLINE_RELATIVE,
submissionDeadlineRelToEl, GTACourseNode.GTASK_SUBMIT_DEADLINE_RELATIVE_TO);
} else {
config.setDateValue(GTACourseNode.GTASK_SUBMIT_DEADLINE, submissionDeadlineEl.getDate());
}
} else {
config.remove(GTACourseNode.GTASK_SUBMIT_DEADLINE);
}
boolean review = reviewEl.isAtLeastSelected(1);
config.setBooleanEntry(GTACourseNode.GTASK_REVIEW_AND_CORRECTION, review);
if(review) {
config.setBooleanEntry(GTACourseNode.GTASK_REVISION_PERIOD, revisionEl.isAtLeastSelected(1));
} else {
config.setBooleanEntry(GTACourseNode.GTASK_REVISION_PERIOD, false);
}
boolean sample = sampleEl.isAtLeastSelected(1);
config.setBooleanEntry(GTACourseNode.GTASK_SAMPLE_SOLUTION, sample);
if(sample) {
if(relativeDates) {
setRelativeDates(solutionVisibleRelDaysEl, GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_AFTER_RELATIVE,
solutionVisibleRelToEl, GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_AFTER_RELATIVE_TO);
} else {
config.setDateValue(GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_AFTER, solutionVisibleAfterEl.getDate());
}
} else {
config.remove(GTACourseNode.GTASK_SAMPLE_SOLUTION_VISIBLE_AFTER);
}
config.setBooleanEntry(GTACourseNode.GTASK_GRADING, gradingEl.isAtLeastSelected(1));
}
private void setRelativeDates(TextElement daysEl, String daysKey, SingleSelection relativeToEl, String relativeToKey) {
String val = daysEl.getValue();
if(StringHelper.isLong(val)) {
try {
config.setIntValue(daysKey, Integer.parseInt(val));
} catch (NumberFormatException e) {
logWarn("", e);
}
String relativeTo = relativeToEl.getSelectedKey();
config.setStringValue(relativeToKey, relativeTo);
}
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if(submissionEl == source) {
updateSubmissionDeadline();
} else if(taskAssignmentEl == source) {
updateAssignmentDeadline();
} else if(sampleEl == source) {
updateSolutionDeadline();
} else if(relativeDatesEl == source) {
updateAssignmentDeadline();
updateSubmissionDeadline();
updateSolutionDeadline();
} else if (reviewEl == source) {
updateRevisions();
} else if(chooseGroupButton == source) {
doChooseGroup(ureq);
} else if(chooseAreaButton == source) {
doChooseArea(ureq);
}
super.formInnerEvent(ureq, source, event);
}
private void updateAssignmentDeadline() {
boolean useRelativeDate = relativeDatesEl.isAtLeastSelected(1);
boolean assignment = taskAssignmentEl.isAtLeastSelected(1);
assignmentDeadlineEl.setVisible(assignment && !useRelativeDate);
assignmentRelDeadlineCont.setVisible(assignment && useRelativeDate);
updateDeadline(assignementDeadlineRelToEl, false);
}
private void updateSubmissionDeadline() {
boolean useRelativeDate = relativeDatesEl.isAtLeastSelected(1);
boolean submit = submissionEl.isAtLeastSelected(1);
submissionDeadlineEl.setVisible(submit && !useRelativeDate);
submissionRelDeadlineCont.setVisible(submit && useRelativeDate);
updateDeadline(submissionDeadlineRelToEl, false);
}
private void updateSolutionDeadline() {
boolean useRelativeDate = relativeDatesEl.isAtLeastSelected(1);
boolean solution = sampleEl.isAtLeastSelected(1);
solutionVisibleAfterEl.setVisible(solution && !useRelativeDate);
solutionVisibleRelCont.setVisible(solution && useRelativeDate);
updateDeadline(solutionVisibleRelToEl, false);
}
private void updateDeadline(SingleSelection selectionEl, boolean excludeAssignment) {
String selectedKey = null;
if(selectionEl.isOneSelected()) {
selectedKey = selectionEl.getSelectedKey();
}
RelativeDateKeysAndValues keysAndValues = getRelativesDatesOption(excludeAssignment);
selectionEl.setKeysAndValues(keysAndValues.getKeys(), keysAndValues.getValues(), null);
boolean found = false;
for(String key:keysAndValues.getKeys()) {
if(key.equals(selectedKey)) {
selectionEl.select(key, true);
found = true;
}
}
if(!found) {
selectionEl.select(keysAndValues.getKeys()[0], true);
}
}
private RelativeDateKeysAndValues getRelativesDatesOption(boolean excludeAssignment) {
List<String> optionKeys = new ArrayList<>(4);
List<String> optionValues = new ArrayList<>(4);
if(courseRe.getLifecycle() != null && courseRe.getLifecycle().getValidFrom() != null) {
Date validFrom = courseRe.getLifecycle().getValidFrom();
String from = Formatter.getInstance(getLocale()).formatDate(validFrom);
optionKeys.add(GTARelativeToDates.courseStart.name());
optionValues.add(translate("relative.to.course.start", new String[]{ from }));
}
optionKeys.add(GTARelativeToDates.courseLaunch.name());
optionValues.add(translate("relative.to.course.launch"));
optionKeys.add(GTARelativeToDates.enrollment.name());
optionValues.add(translate("relative.to.enrollment"));
if(!excludeAssignment) {
boolean assignment = taskAssignmentEl.isAtLeastSelected(1);
if(assignment) {
optionKeys.add(GTARelativeToDates.assignment.name());
optionValues.add(translate("relative.to.assignment"));
}
}
String[] keys = optionKeys.toArray(new String[optionKeys.size()]);
String[] values = optionValues.toArray(new String[optionValues.size()]);
return new RelativeDateKeysAndValues(keys, values);
}
private void updateRevisions() {
boolean review = reviewEl.isAtLeastSelected(1);
revisionEl.setVisible(review);
revisionEl.select(onKeys[0], review);
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(groupSelectionCtrl == source) {
if (event == Event.DONE_EVENT) {
groupKeys = groupSelectionCtrl.getSelectedKeys();
groupListEl.setValue(getGroupNames(groupKeys));
if(courseEditorEnv.getCourseGroupManager().hasBusinessGroups()) {
chooseGroupButton.setI18nKey("choose.groups");
} else {
chooseGroupButton.setI18nKey("create.groups");
}
cmc.deactivate();
cleanUp();
groupListEl.getRootForm().submit(ureq);
} else if(event == Event.CANCELLED_EVENT) {
cmc.deactivate();
cleanUp();
}
} else if(areaSelectionCtrl == source) {
if (event == Event.DONE_EVENT) {
areaKeys = areaSelectionCtrl.getSelectedKeys();
areaListEl.setValue(getAreaNames(areaKeys));
if(courseEditorEnv.getCourseGroupManager().hasAreas()) {
chooseAreaButton.setI18nKey("choose.areas");
} else {
chooseAreaButton.setI18nKey("create.areas");
}
cmc.deactivate();
cleanUp();
areaListEl.getRootForm().submit(ureq);
} else if (event == Event.CANCELLED_EVENT) {
cmc.deactivate();
cleanUp();
}
} else if(confirmChangesCtrl == source) {
if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) {
commitChanges();
fireEvent(ureq, Event.DONE_EVENT);
}
} else if(cmc == source) {
cleanUp();
}
super.event(ureq, source, event);
}
private void cleanUp() {
removeAsListenerAndDispose(groupSelectionCtrl);
removeAsListenerAndDispose(areaSelectionCtrl);
removeAsListenerAndDispose(cmc);
groupSelectionCtrl = null;
areaSelectionCtrl = null;
cmc = null;
}
private void doChooseGroup(UserRequest ureq) {
removeAsListenerAndDispose(cmc);
removeAsListenerAndDispose(groupSelectionCtrl);
groupSelectionCtrl = new GroupSelectionController(ureq, getWindowControl(), true,
courseEditorEnv.getCourseGroupManager(), groupKeys);
listenTo(groupSelectionCtrl);
cmc = new CloseableModalController(getWindowControl(), "close", groupSelectionCtrl.getInitialComponent());
listenTo(cmc);
cmc.activate();
}
private void doChooseArea(UserRequest ureq) {
removeAsListenerAndDispose(cmc);
removeAsListenerAndDispose(areaSelectionCtrl);
areaSelectionCtrl = new AreaSelectionController (ureq, getWindowControl(), true,
courseEditorEnv.getCourseGroupManager(), areaKeys);
listenTo(areaSelectionCtrl);
cmc = new CloseableModalController(getWindowControl(), "close", areaSelectionCtrl.getInitialComponent());
listenTo(cmc);
cmc.activate();
}
private String getGroupNames(List<Long> groupKeyList) {
StringBuilder sb = new StringBuilder(64);
List<BusinessGroupShort> groups = businessGroupService.loadShortBusinessGroups(groupKeyList);
for(BusinessGroupShort group:groups) {
if(sb.length() > 0) sb.append(" ");
sb.append("<i class='o_icon o_icon-fw o_icon_group'> </i> ")
.append(StringHelper.escapeHtml(group.getName()));
}
return sb.toString();
}
private String getAreaNames(List<Long> areaKeyList) {
StringBuilder sb = new StringBuilder(64);
List<BGArea> areas = areaManager.loadAreas(areaKeyList);
for(BGArea area:areas) {
if(sb.length() > 0) sb.append(" ");
sb.append("<i class='o_icon o_icon-fw o_icon_courseareas'> </i> ")
.append(StringHelper.escapeHtml(area.getName()));
}
return sb.toString();
}
private class RelativeDateKeysAndValues {
private final String[] keys;
private final String[] values;
public RelativeDateKeysAndValues(String[] keys, String[] values) {
this.keys = keys;
this.values = values;
}
public String[] getKeys() {
return keys;
}
public String[] getValues() {
return values;
}
}
}