From 3a2a7847ee909734636ebfc27669c1423ded6f64 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 20 May 2019 15:30:14 +0200 Subject: [PATCH] SEBSERV-45 added applications view --- .../gbl/model/sebconfig/AttributeType.java | 4 +- .../gui/content/SebExamConfigForm.java | 176 ++++++++---------- .../gui/content/SebExamConfigList.java | 8 +- .../gui/content/SebExamConfigPropForm.java | 175 +++++++++++++++++ .../content/SebExamConfigPropertiesForm.java | 141 -------------- .../gui/content/action/ActionDefinition.java | 21 ++- .../content/activity/PageStateDefinition.java | 9 +- .../examconfig/ExamConfigurationService.java | 8 + .../gui/service/examconfig/InputField.java | 2 + .../service/examconfig/InputFieldBuilder.java | 8 +- .../examconfig/impl/AbstractInputField.java | 6 + .../examconfig/impl/AttributeMapping.java | 16 +- .../impl/CellFieldBuilderAdapter.java | 38 +++- .../examconfig/impl/CheckBoxBuilder.java | 24 ++- .../impl/InlineTableFieldBuilder.java | 17 ++ .../impl/MultiCheckboxSelection.java | 6 +- .../examconfig/impl/PassworFieldBuilder.java | 2 +- .../impl/RadioSelectionFieldBuilder.java | 8 +- .../impl/SelectionFieldBuilder.java | 13 +- .../impl/SingleSelectionFieldBuilder.java | 12 +- .../examconfig/impl/SliderFieldBuilder.java | 2 +- .../service/examconfig/impl/TableContext.java | 31 ++- .../examconfig/impl/TableFieldBuilder.java | 86 +++++---- .../examconfig/impl/TableRowFormBuilder.java | 29 +-- .../examconfig/impl/TextFieldBuilder.java | 2 +- .../service/examconfig/impl/ViewContext.java | 8 +- .../examconfig/impl/ViewGridBuilder.java | 33 ++-- .../impl/rules/AllowFlashFullscreenRule.java | 46 +++++ .../seb/sebserver/gui/widget/Selection.java | 4 + .../sebserver/gui/widget/SingleSelection.java | 11 ++ .../impl/ExitKeySequenceValidator.java | 4 +- src/main/resources/messages.properties | 38 ++++ 32 files changed, 619 insertions(+), 369 deletions(-) create mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java delete mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropertiesForm.java create mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/InlineTableFieldBuilder.java create mode 100644 src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/rules/AllowFlashFullscreenRule.java diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeType.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeType.java index 3f687af1..03b7e8b1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeType.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/AttributeType.java @@ -46,7 +46,9 @@ public enum AttributeType { /** Table type is a list of a composite of single types */ TABLE(COMPOSITE_LIST), - STATIC_TABLE(COMPOSITE_LIST); + INLINE_TABLE(COMPOSITE_LIST), + + ; public final AttributeValueType attributeValueType; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigForm.java index 9f98fff2..65f0b04f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigForm.java @@ -8,33 +8,38 @@ package ch.ethz.seb.sebserver.gui.content; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; +import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.API; -import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; -import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType; -import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.View; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; -import ch.ethz.seb.sebserver.gui.form.FormBuilder; -import ch.ethz.seb.sebserver.gui.form.FormHandle; -import ch.ethz.seb.sebserver.gui.service.ResourceService; +import ch.ethz.seb.sebserver.gbl.util.Utils; +import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; +import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping; +import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig; import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @Lazy @@ -44,127 +49,92 @@ public class SebExamConfigForm implements TemplateComposer { private static final Logger log = LoggerFactory.getLogger(SebExamConfigForm.class); - private static final LocTextKey FORM_TITLE_NEW = - new LocTextKey("sebserver.examconfig.form.title.new"); - private static final LocTextKey FORM_TITLE = - new LocTextKey("sebserver.examconfig.form.title"); - private static final LocTextKey FORM_NAME_TEXT_KEY = - new LocTextKey("sebserver.examconfig.form.name"); - private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY = - new LocTextKey("sebserver.examconfig.form.description"); - private static final LocTextKey FORM_STATUS_TEXT_KEY = - new LocTextKey("sebserver.examconfig.form.status"); + private static final String VIEW_TEXT_KEY_PREFIX = "sebserver.examconfig.props.form.views."; + private static final String VIEW_TOOLTIP_TEXT_KEY_SUFFIX = ".tooltip"; + + private static final LocTextKey TITLE_TEXT_KEY = + new LocTextKey("sebserver.examconfig.props.from.title"); private final PageService pageService; private final RestService restService; private final CurrentUser currentUser; + private final ExamConfigurationService examConfigurationService; protected SebExamConfigForm( final PageService pageService, final RestService restService, - final CurrentUser currentUser) { + final CurrentUser currentUser, + final ExamConfigurationService examConfigurationService) { this.pageService = pageService; this.restService = restService; this.currentUser = currentUser; + this.examConfigurationService = examConfigurationService; } @Override public void compose(final PageContext pageContext) { final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); - final ResourceService resourceService = this.pageService.getResourceService(); - final UserInfo user = this.currentUser.get(); final EntityKey entityKey = pageContext.getEntityKey(); final EntityKey parentEntityKey = pageContext.getParentEntityKey(); - final boolean isNew = entityKey == null; - - // get data or create new. Handle error if happen - final ConfigurationNode examConfig = (isNew) - ? ConfigurationNode.createNewExamConfig((parentEntityKey != null) - ? Long.valueOf(parentEntityKey.modelId) - : user.institutionId) - : this.restService - .getBuilder(GetExamConfigNode.class) - .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) - .call() - .get(pageContext::notifyError); - - if (examConfig == null) { - log.error("Failed to get ConfigurationNode. " - + "Error was notified to the User. " - + "See previous logs for more infomation"); - return; - } - - final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig); - final boolean writeGrant = entityGrant.w(); - final boolean modifyGrant = entityGrant.m(); - final boolean isReadonly = pageContext.isReadonly(); - - // new PageContext with actual EntityKey - final PageContext formContext = pageContext.withEntityKey(examConfig.getEntityKey()); - - // the default page layout with interactive title - final LocTextKey titleKey = (isNew) - ? FORM_TITLE_NEW - : FORM_TITLE; final Composite content = widgetFactory.defaultPageLayout( - formContext.getParent(), - titleKey); + pageContext.getParent(), + TITLE_TEXT_KEY); - // The SebClientConfig form - final FormHandle formHandle = this.pageService.formBuilder( - formContext.copyOf(content), 4) - .readonly(isReadonly) - .putStaticValueIf(() -> !isNew, - Domain.CONFIGURATION_NODE.ATTR_ID, - examConfig.getModelId()) - .putStaticValue( - Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID, - String.valueOf(examConfig.getInstitutionId())) - .putStaticValue( - Domain.CONFIGURATION_NODE.ATTR_TYPE, - ConfigurationType.EXAM_CONFIG.name()) - .addField(FormBuilder.text( - Domain.CONFIGURATION_NODE.ATTR_NAME, - FORM_NAME_TEXT_KEY, - examConfig.name)) - .addField(FormBuilder.text( - Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, - FORM_DESCRIPTION_TEXT_KEY, - examConfig.description).asArea()) - .addField(FormBuilder.singleSelection( - Domain.CONFIGURATION_NODE.ATTR_STATUS, - FORM_STATUS_TEXT_KEY, - examConfig.status.name(), - resourceService::examConfigStatusResources)) - .buildFor((isNew) - ? this.restService.getRestCall(NewExamConfig.class) - : this.restService.getRestCall(SaveExamConfig.class)); + try { - this.pageService.pageActionBuilder(formContext.clearEntityKeys()) + final ConfigurationNode configNode = this.restService.getBuilder(GetExamConfigNode.class) + .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) + .call() + .onError(pageContext::notifyError) + .getOrThrow(); - .newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW) - .publishIf(() -> writeGrant && isReadonly) + final Configuration configuration = this.restService.getBuilder(GetConfigurations.class) + .withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, configNode.getModelId()) + .withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING) + .call() + .map(Utils::toSingleton) + .onError(pageContext::notifyError) + .getOrThrow(); - .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY) - .withEntityKey(entityKey) - .publishIf(() -> modifyGrant && isReadonly) + final AttributeMapping attributes = this.examConfigurationService + .getAttributes(configNode.templateId) + .onError(pageContext::notifyError) + .getOrThrow(); - .newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE) - .withEntityKey(entityKey) - .withExec(formHandle::processFormSave) - .ignoreMoveAwayFromEdit() - .publishIf(() -> !isReadonly) + final List views = this.examConfigurationService.getViews(attributes); - .newAction(ActionDefinition.SEB_EXAM_CONFIG_CANCEL_MODIFY) - .withEntityKey(entityKey) - .withExec(action -> this.pageService.onEmptyEntityKeyGoTo( - action, - ActionDefinition.SEB_EXAM_CONFIG_LIST)) - .publishIf(() -> !isReadonly); + final TabFolder tabFolder = widgetFactory.tabFolderLocalized(content); + tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + final List viewContexts = new ArrayList<>(); + for (final View view : views) { + final ViewContext viewContext = this.examConfigurationService.createViewContext( + pageContext, + configuration, + view, + attributes, + 20); + viewContexts.add(viewContext); + + final Composite viewGrid = this.examConfigurationService.createViewGrid( + tabFolder, + viewContext); + + final TabItem tabItem = widgetFactory.tabItemLocalized( + tabFolder, + new LocTextKey(VIEW_TEXT_KEY_PREFIX + view.name)); + tabItem.setControl(viewGrid); + } + + this.examConfigurationService.initInputFieldValues(configuration.id, viewContexts); + + } catch (final Exception e) { + log.error("Unexpected error while trying to fetch exam configuration data and create views", e); + pageContext.notifyError(e); + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java index 16715118..39664767 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigList.java @@ -136,7 +136,7 @@ public class SebExamConfigList implements TemplateComposer { this.statusFilter, true)) .withDefaultAction(pageActionBuilder - .newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_FROM_LIST) + .newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST) .create()) .compose(content); @@ -147,15 +147,15 @@ public class SebExamConfigList implements TemplateComposer { .newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW) .publishIf(examConfigGrant::iw) - .newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_FROM_LIST) + .newAction(ActionDefinition.SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .publishIf(() -> table.hasAnyContent()) - .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST) + .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .publishIf(() -> examConfigGrant.im() && table.hasAnyContent()) - .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROPERTIES_FROM_LIST) + .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .publishIf(() -> examConfigGrant.im() && table.hasAnyContent()); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java new file mode 100644 index 00000000..043463f5 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropForm.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gui.content; + +import org.eclipse.swt.widgets.Composite; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import ch.ethz.seb.sebserver.gbl.api.API; +import ch.ethz.seb.sebserver.gbl.model.Domain; +import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode.ConfigurationType; +import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; +import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; +import ch.ethz.seb.sebserver.gui.form.FormBuilder; +import ch.ethz.seb.sebserver.gui.form.FormHandle; +import ch.ethz.seb.sebserver.gui.service.ResourceService; +import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; +import ch.ethz.seb.sebserver.gui.service.page.PageContext; +import ch.ethz.seb.sebserver.gui.service.page.PageService; +import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.NewExamConfig; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfig; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck; +import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; + +@Lazy +@Component +@GuiProfile +public class SebExamConfigPropForm implements TemplateComposer { + + private static final Logger log = LoggerFactory.getLogger(SebExamConfigPropForm.class); + + private static final LocTextKey FORM_TITLE_NEW = + new LocTextKey("sebserver.examconfig.form.title.new"); + private static final LocTextKey FORM_TITLE = + new LocTextKey("sebserver.examconfig.form.title"); + private static final LocTextKey FORM_NAME_TEXT_KEY = + new LocTextKey("sebserver.examconfig.form.name"); + private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY = + new LocTextKey("sebserver.examconfig.form.description"); + private static final LocTextKey FORM_STATUS_TEXT_KEY = + new LocTextKey("sebserver.examconfig.form.status"); + + private final PageService pageService; + private final RestService restService; + private final CurrentUser currentUser; + + protected SebExamConfigPropForm( + final PageService pageService, + final RestService restService, + final CurrentUser currentUser) { + + this.pageService = pageService; + this.restService = restService; + this.currentUser = currentUser; + } + + @Override + public void compose(final PageContext pageContext) { + final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); + final ResourceService resourceService = this.pageService.getResourceService(); + + final UserInfo user = this.currentUser.get(); + final EntityKey entityKey = pageContext.getEntityKey(); + final EntityKey parentEntityKey = pageContext.getParentEntityKey(); + + final boolean isNew = entityKey == null; + + // get data or create new. Handle error if happen + final ConfigurationNode examConfig = (isNew) + ? ConfigurationNode.createNewExamConfig((parentEntityKey != null) + ? Long.valueOf(parentEntityKey.modelId) + : user.institutionId) + : this.restService + .getBuilder(GetExamConfigNode.class) + .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) + .call() + .get(pageContext::notifyError); + + if (examConfig == null) { + log.error("Failed to get ConfigurationNode. " + + "Error was notified to the User. " + + "See previous logs for more infomation"); + return; + } + + final EntityGrantCheck entityGrant = this.currentUser.entityGrantCheck(examConfig); + final boolean writeGrant = entityGrant.w(); + final boolean modifyGrant = entityGrant.m(); + final boolean isReadonly = pageContext.isReadonly(); + + // new PageContext with actual EntityKey + final PageContext formContext = pageContext.withEntityKey(examConfig.getEntityKey()); + + // the default page layout with interactive title + final LocTextKey titleKey = (isNew) + ? FORM_TITLE_NEW + : FORM_TITLE; + final Composite content = widgetFactory.defaultPageLayout( + formContext.getParent(), + titleKey); + + // The SebClientConfig form + final FormHandle formHandle = this.pageService.formBuilder( + formContext.copyOf(content), 4) + .readonly(isReadonly) + .putStaticValueIf(() -> !isNew, + Domain.CONFIGURATION_NODE.ATTR_ID, + examConfig.getModelId()) + .putStaticValue( + Domain.CONFIGURATION_NODE.ATTR_INSTITUTION_ID, + String.valueOf(examConfig.getInstitutionId())) + .putStaticValue( + Domain.CONFIGURATION_NODE.ATTR_TYPE, + ConfigurationType.EXAM_CONFIG.name()) + .addField(FormBuilder.text( + Domain.CONFIGURATION_NODE.ATTR_NAME, + FORM_NAME_TEXT_KEY, + examConfig.name)) + .addField(FormBuilder.text( + Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, + FORM_DESCRIPTION_TEXT_KEY, + examConfig.description).asArea()) + .addField(FormBuilder.singleSelection( + Domain.CONFIGURATION_NODE.ATTR_STATUS, + FORM_STATUS_TEXT_KEY, + examConfig.status.name(), + resourceService::examConfigStatusResources)) + .buildFor((isNew) + ? this.restService.getRestCall(NewExamConfig.class) + : this.restService.getRestCall(SaveExamConfig.class)); + + this.pageService.pageActionBuilder(formContext.clearEntityKeys()) + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_NEW) + .publishIf(() -> writeGrant && isReadonly) + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_PROP_MODIFY) + .withEntityKey(entityKey) + .publishIf(() -> modifyGrant && isReadonly) + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY) + .withEntityKey(entityKey) + .publishIf(() -> modifyGrant && isReadonly) + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_SAVE) + .withEntityKey(entityKey) + .withExec(formHandle::processFormSave) + .ignoreMoveAwayFromEdit() + .publishIf(() -> !isReadonly) + + .newAction(ActionDefinition.SEB_EXAM_CONFIG_CANCEL_MODIFY) + .withEntityKey(entityKey) + .withExec(action -> this.pageService.onEmptyEntityKeyGoTo( + action, + ActionDefinition.SEB_EXAM_CONFIG_LIST)) + .publishIf(() -> !isReadonly); + + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropertiesForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropertiesForm.java deleted file mode 100644 index f4350aab..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/SebExamConfigPropertiesForm.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package ch.ethz.seb.sebserver.gui.content; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.TabFolder; -import org.eclipse.swt.widgets.TabItem; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; - -import ch.ethz.seb.sebserver.gbl.Constants; -import ch.ethz.seb.sebserver.gbl.api.API; -import ch.ethz.seb.sebserver.gbl.model.EntityKey; -import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration; -import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; -import ch.ethz.seb.sebserver.gbl.model.sebconfig.View; -import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gbl.util.Utils; -import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; -import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping; -import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext; -import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; -import ch.ethz.seb.sebserver.gui.service.page.PageContext; -import ch.ethz.seb.sebserver.gui.service.page.PageService; -import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; -import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; - -@Lazy -@Component -@GuiProfile -public class SebExamConfigPropertiesForm implements TemplateComposer { - - private static final Logger log = LoggerFactory.getLogger(SebExamConfigPropertiesForm.class); - - private static final String VIEW_TEXT_KEY_PREFIX = "sebserver.examconfig.props.form.views."; - private static final String VIEW_TOOLTIP_TEXT_KEY_SUFFIX = ".tooltip"; - - private static final LocTextKey TITLE_TEXT_KEY = - new LocTextKey("sebserver.examconfig.props.from.title"); - - private final PageService pageService; - private final RestService restService; - private final CurrentUser currentUser; - private final ExamConfigurationService examConfigurationService; - - protected SebExamConfigPropertiesForm( - final PageService pageService, - final RestService restService, - final CurrentUser currentUser, - final ExamConfigurationService examConfigurationService) { - - this.pageService = pageService; - this.restService = restService; - this.currentUser = currentUser; - this.examConfigurationService = examConfigurationService; - } - - @Override - public void compose(final PageContext pageContext) { - final WidgetFactory widgetFactory = this.pageService.getWidgetFactory(); - - final EntityKey entityKey = pageContext.getEntityKey(); - final EntityKey parentEntityKey = pageContext.getParentEntityKey(); - - final Composite content = widgetFactory.defaultPageLayout( - pageContext.getParent(), - TITLE_TEXT_KEY); - - try { - - final ConfigurationNode configNode = this.restService.getBuilder(GetExamConfigNode.class) - .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) - .call() - .onError(pageContext::notifyError) - .getOrThrow(); - - final Configuration configuration = this.restService.getBuilder(GetConfigurations.class) - .withQueryParam(Configuration.FILTER_ATTR_CONFIGURATION_NODE_ID, configNode.getModelId()) - .withQueryParam(Configuration.FILTER_ATTR_FOLLOWUP, Constants.TRUE_STRING) - .call() - .map(Utils::toSingleton) - .onError(pageContext::notifyError) - .getOrThrow(); - - final AttributeMapping attributes = this.examConfigurationService - .getAttributes(configNode.templateId) - .onError(pageContext::notifyError) - .getOrThrow(); - - final List views = this.examConfigurationService.getViews(attributes); - - final TabFolder tabFolder = widgetFactory.tabFolderLocalized(content); - tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - final List viewContexts = new ArrayList<>(); - for (final View view : views) { - final ViewContext viewContext = this.examConfigurationService.createViewContext( - pageContext, - configuration, - view, - attributes, - 20); - viewContexts.add(viewContext); - - final Composite viewGrid = this.examConfigurationService.createViewGrid( - tabFolder, - viewContext); - - final TabItem tabItem = widgetFactory.tabItemLocalized( - tabFolder, - new LocTextKey(VIEW_TEXT_KEY_PREFIX + view.name)); - tabItem.setControl(viewGrid); - } - - this.examConfigurationService.initInputFieldValues(configuration.id, viewContexts); - - } catch (final Exception e) { - log.error("Unexpected error while trying to fetch exam configuration data and create views", e); - pageContext.notifyError(e); - } - - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java index bf9bb806..7a958e9e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/action/ActionDefinition.java @@ -307,17 +307,22 @@ public enum ActionDefinition { SEB_EXAM_CONFIG_NEW( new LocTextKey("sebserver.examconfig.action.list.new"), ImageIcon.NEW, - PageStateDefinition.SEB_EXAM_CONFIG_EDIT), - SEB_EXAM_CONFIG_VIEW_FROM_LIST( + PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT), + SEB_EXAM_CONFIG_VIEW_PROP_FROM_LIST( new LocTextKey("sebserver.examconfig.action.list.view"), ImageIcon.SHOW, PageStateDefinition.SEB_EXAM_CONFIG_VIEW, ActionCategory.SEB_EXAM_CONFIG_LIST), - SEB_EXAM_CONFIG_MODIFY_FROM_LIST( - new LocTextKey("sebserver.examconfig.action.list.modify"), + SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST( + new LocTextKey("sebserver.examconfig.action.list.modify.properties"), ImageIcon.EDIT, - PageStateDefinition.SEB_EXAM_CONFIG_EDIT, + PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT, ActionCategory.SEB_EXAM_CONFIG_LIST), + SEB_EXAM_CONFIG_PROP_MODIFY( + new LocTextKey("sebserver.examconfig.action.modify.properties"), + ImageIcon.EDIT, + PageStateDefinition.SEB_EXAM_CONFIG_PROP_EDIT, + ActionCategory.FORM), SEB_EXAM_CONFIG_MODIFY( new LocTextKey("sebserver.examconfig.action.modify"), ImageIcon.EDIT, @@ -334,10 +339,10 @@ public enum ActionDefinition { PageStateDefinition.SEB_EXAM_CONFIG_VIEW, ActionCategory.FORM), - SEB_EXAM_CONFIG_MODIFY_PROPERTIES_FROM_LIST( - new LocTextKey("sebserver.examconfig.action.list.modify.properties"), + SEB_EXAM_CONFIG_MODIFY_FROM_LIST( + new LocTextKey("sebserver.examconfig.action.list.modify"), ImageIcon.EDIT, - PageStateDefinition.SEB_EXAM_CONFIG_PROPERTIES_EDIT, + PageStateDefinition.SEB_EXAM_CONFIG_EDIT, ActionCategory.SEB_EXAM_CONFIG_LIST), ; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinition.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinition.java index 78e70df7..05864310 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinition.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/PageStateDefinition.java @@ -20,7 +20,7 @@ import ch.ethz.seb.sebserver.gui.content.SebClientConfigForm; import ch.ethz.seb.sebserver.gui.content.SebClientConfigList; import ch.ethz.seb.sebserver.gui.content.SebExamConfigForm; import ch.ethz.seb.sebserver.gui.content.SebExamConfigList; -import ch.ethz.seb.sebserver.gui.content.SebExamConfigPropertiesForm; +import ch.ethz.seb.sebserver.gui.content.SebExamConfigPropForm; import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm; import ch.ethz.seb.sebserver.gui.content.UserAccountForm; import ch.ethz.seb.sebserver.gui.content.UserAccountList; @@ -56,10 +56,9 @@ public enum PageStateDefinition implements PageState { SEB_CLIENT_CONFIG_EDIT(Type.FORM_EDIT, SebClientConfigForm.class, ActivityDefinition.SEB_CLIENT_CONFIG), SEB_EXAM_CONFIG_LIST(Type.LIST_VIEW, SebExamConfigList.class, ActivityDefinition.SEB_EXAM_CONFIG), - SEB_EXAM_CONFIG_VIEW(Type.FORM_VIEW, SebExamConfigForm.class, ActivityDefinition.SEB_EXAM_CONFIG), - SEB_EXAM_CONFIG_EDIT(Type.FORM_EDIT, SebExamConfigForm.class, ActivityDefinition.SEB_EXAM_CONFIG), - SEB_EXAM_CONFIG_PROPERTIES_EDIT(Type.FORM_VIEW, SebExamConfigPropertiesForm.class, - ActivityDefinition.SEB_EXAM_CONFIG), + SEB_EXAM_CONFIG_VIEW(Type.FORM_VIEW, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG), + SEB_EXAM_CONFIG_PROP_EDIT(Type.FORM_EDIT, SebExamConfigPropForm.class, ActivityDefinition.SEB_EXAM_CONFIG), + SEB_EXAM_CONFIG_EDIT(Type.FORM_VIEW, SebExamConfigForm.class, ActivityDefinition.SEB_EXAM_CONFIG), ; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java index 4ffdf43e..7ba05c46 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/ExamConfigurationService.java @@ -31,6 +31,7 @@ public interface ExamConfigurationService { public static final String ATTRIBUTE_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.label."; public static final String GROUP_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.group."; public static final String TOOL_TIP_SUFFIX = ".tooltip"; + public static final String TABLE_ROW_TITLE_SUFFIX = ".row.title"; WidgetFactory getWidgetFactory(); @@ -85,4 +86,11 @@ public interface ExamConfigurationService { } } + static LocTextKey getTablePopupTitleKey( + final ConfigurationAttribute attribute, + final I18nSupport i18nSupport) { + + return new LocTextKey(ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + TABLE_ROW_TITLE_SUFFIX); + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputField.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputField.java index 994adae9..f00b681c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputField.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputField.java @@ -27,6 +27,8 @@ public interface InputField { String getValue(); + String getReadableValue(); + void showError(String errorMessage); void clearError(); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputFieldBuilder.java index e9a5421f..4cf60790 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/InputFieldBuilder.java @@ -48,13 +48,15 @@ public interface InputFieldBuilder { static Composite createInnerGrid( final Composite parent, + final ConfigurationAttribute attribute, final Orientation orientation) { - return createInnerGrid(parent, orientation, 1); + return createInnerGrid(parent, attribute, orientation, 1); } static Composite createInnerGrid( final Composite parent, + final ConfigurationAttribute attribute, final Orientation orientation, final int numColumns) { @@ -69,8 +71,8 @@ public interface InputFieldBuilder { final GridData gridData = new GridData( SWT.FILL, SWT.FILL, true, false, - (orientation != null) ? orientation.width() : 1, - (orientation != null) ? orientation.height() : 1); + (orientation != null && attribute.parentId == null) ? orientation.width() : 1, + (orientation != null && attribute.parentId == null) ? orientation.height() : 1); comp.setLayoutData(gridData); return comp; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AbstractInputField.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AbstractInputField.java index d217ba32..d746862a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AbstractInputField.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AbstractInputField.java @@ -129,6 +129,12 @@ public abstract class AbstractInputField implements InputFiel } } + @Override + public String getReadableValue() { + return getValue(); + + } + protected abstract void setValueToControl(String value); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java index e4b5ef05..bc330dd2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/AttributeMapping.java @@ -45,11 +45,6 @@ public class AttributeMapping { Objects.requireNonNull(orientations); this.templateId = templateId; - this.attributeIdMapping = Utils.immutableMapOf(attributes - .stream() - .collect(Collectors.toMap( - attr -> attr.id, - Function.identity()))); this.orientationAttributeMapping = Utils.immutableMapOf(orientations .stream() @@ -57,8 +52,16 @@ public class AttributeMapping { o -> o.attributeId, Function.identity()))); + this.attributeIdMapping = Utils.immutableMapOf(attributes + .stream() + .filter(attr -> this.orientationAttributeMapping.containsKey(attr.id)) + .collect(Collectors.toMap( + attr -> attr.id, + Function.identity()))); + this.attributeNameIdMapping = Utils.immutableMapOf(attributes .stream() + .filter(attr -> this.orientationAttributeMapping.containsKey(attr.id)) .collect(Collectors.toMap( attr -> attr.name, attr -> attr.id))); @@ -71,6 +74,7 @@ public class AttributeMapping { this.childAttributeMapping = Utils.immutableMapOf(attributes .stream() + .filter(attr -> this.orientationAttributeMapping.containsKey(attr.id)) .collect(Collectors.toMap( attr -> attr.id, this::getChildAttributes))); @@ -184,7 +188,7 @@ public class AttributeMapping { .values() .stream() .filter(o -> groupName.equals(o.groupId)) - .sorted((o1, o2) -> (o1.yPosition == o2.yPosition) + .sorted((o1, o2) -> (o1.yPosition != null && o1.yPosition.equals(o2.yPosition)) ? o1.xPosition.compareTo(o2.xPosition) : o1.yPosition.compareTo(o2.yPosition)) .map(o -> this.attributeIdMapping.get(o.attributeId)) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CellFieldBuilderAdapter.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CellFieldBuilderAdapter.java index 2c79ce07..a8f15e56 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CellFieldBuilderAdapter.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CellFieldBuilderAdapter.java @@ -8,6 +8,8 @@ package ch.ethz.seb.sebserver.gui.service.examconfig.impl; +import static ch.ethz.seb.sebserver.gui.service.examconfig.impl.CellFieldBuilderAdapter.dummyBuilderAdapter; + import java.util.Collection; import org.eclipse.swt.SWT; @@ -28,6 +30,10 @@ interface CellFieldBuilderAdapter { void createCell(ViewGridBuilder builder); + default void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) { + + } + static CellFieldBuilderAdapter dummyBuilderAdapter() { return new CellFieldBuilderAdapter() { @Override @@ -71,6 +77,9 @@ interface CellFieldBuilderAdapter { final Orientation orientation) { return new CellFieldBuilderAdapter() { + + private int span = 1; + @Override public void createCell(final ViewGridBuilder builder) { @@ -88,21 +97,16 @@ interface CellFieldBuilderAdapter { gridData.verticalIndent = 5; break; } + case RIGHT_SPAN: case LEFT_SPAN: { label.setAlignment(SWT.LEFT); - gridData.horizontalSpan = orientation.width; + gridData.horizontalSpan = (span > 1) ? span : orientation.width; gridData.verticalIndent = 5; break; } - case RIGHT_SPAN: { - label.setAlignment(SWT.LEFT); - gridData.verticalIndent = 5; - gridData.horizontalSpan = orientation.width; - break; - } case TOP: { gridData.horizontalSpan = orientation.width; - label.setAlignment(SWT.LEFT); + gridData.verticalAlignment = SWT.BOTTOM; break; } @@ -114,6 +118,22 @@ interface CellFieldBuilderAdapter { label.pack(); } + @Override + public void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) { + if (grid[y][x] != this) { + return; + } + if (orientation.title == TitleOrientation.LEFT_SPAN) { + int xpos = x - 1; + while (xpos >= 0 && grid[y][xpos] == null && span < orientation.width) { + grid[y][xpos] = this; + grid[y][xpos + 1] = dummyBuilderAdapter(); + this.span++; + xpos--; + } + } + } + @Override public String toString() { return "[LABEL]"; @@ -185,7 +205,7 @@ interface CellFieldBuilderAdapter { builder.parent, this.width, groupLabelKey); - group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, this.width, this.height)); + group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, this.width, this.height)); final ViewGridBuilder groupBuilder = new ViewGridBuilder( group, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CheckBoxBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CheckBoxBuilder.java index 8da9807a..fcc19879 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CheckBoxBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/CheckBoxBuilder.java @@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.examconfig.impl; import java.util.Objects; import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.springframework.context.annotation.Lazy; @@ -20,6 +21,7 @@ import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; import ch.ethz.seb.sebserver.gui.service.examconfig.InputField; @@ -64,14 +66,20 @@ public class CheckBoxBuilder implements InputFieldBuilder { final Orientation orientation = viewContext .getOrientation(attribute.id); final Composite innerGrid = InputFieldBuilder - .createInnerGrid(parent, orientation); + .createInnerGrid(parent, attribute, orientation); final Button checkbox = this.widgetFactory.buttonLocalized( innerGrid, SWT.CHECK, - ExamConfigurationService.attributeNameLocKey(attribute), + (orientation.title == TitleOrientation.NONE) + ? ExamConfigurationService.attributeNameLocKey(attribute) + : null, ExamConfigurationService.getToolTipKey(attribute, i18nSupport)); + final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); + gridData.verticalIndent = 0; + checkbox.setLayoutData(gridData); + final CheckboxField checkboxField = new CheckboxField( attribute, viewContext.getOrientation(attribute.id), @@ -95,9 +103,7 @@ public class CheckBoxBuilder implements InputFieldBuilder { final Orientation orientation, final Button control) { - super(attribute, orientation, control, (orientation.groupId == null) - ? InputFieldBuilder.createErrorLabel(control.getParent()) - : null); + super(attribute, orientation, control, null); } @Override @@ -111,6 +117,14 @@ public class CheckBoxBuilder implements InputFieldBuilder { ? Constants.TRUE_STRING : Constants.FALSE_STRING; } + + @Override + public String getReadableValue() { + return this.control.getSelection() + ? "Active" + : "Inactive"; + } + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/InlineTableFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/InlineTableFieldBuilder.java new file mode 100644 index 00000000..5e2599ab --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/InlineTableFieldBuilder.java @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gui.service.examconfig.impl; + +public class InlineTableFieldBuilder { + + public InlineTableFieldBuilder() { + // TODO Auto-generated constructor stub + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/MultiCheckboxSelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/MultiCheckboxSelection.java index 42860234..873f05ee 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/MultiCheckboxSelection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/MultiCheckboxSelection.java @@ -54,14 +54,14 @@ public class MultiCheckboxSelection extends SelectionFieldBuilder implements Inp final Orientation orientation = viewContext .getOrientation(attribute.id); final Composite innerGrid = InputFieldBuilder - .createInnerGrid(parent, orientation); + .createInnerGrid(parent, attribute, orientation); final MultiSelectionCheckbox selection = this.widgetFactory.selectionLocalized( Selection.Type.MULTI_CHECKBOX, innerGrid, - () -> this.getLocalizedResources(attribute, i18nSupport), + () -> this.getLocalizedResources(attribute, viewContext), null, - () -> this.getLocalizedResourcesAsToolTip(attribute, i18nSupport)) + () -> this.getLocalizedResourcesAsToolTip(attribute, viewContext)) .getTypeInstance(); selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/PassworFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/PassworFieldBuilder.java index 46752b4f..3d558667 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/PassworFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/PassworFieldBuilder.java @@ -64,7 +64,7 @@ public class PassworFieldBuilder implements InputFieldBuilder { final Orientation orientation = viewContext .getOrientation(attribute.id); final Composite innerGrid = InputFieldBuilder - .createInnerGrid(parent, orientation); + .createInnerGrid(parent, attribute, orientation); final Text passwordInput = new Text(innerGrid, SWT.LEFT | SWT.BORDER | SWT.PASSWORD); passwordInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/RadioSelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/RadioSelectionFieldBuilder.java index 61588b50..2b342858 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/RadioSelectionFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/RadioSelectionFieldBuilder.java @@ -56,14 +56,14 @@ public class RadioSelectionFieldBuilder extends SelectionFieldBuilder implements final Orientation orientation = viewContext .getOrientation(attribute.id); final Composite innerGrid = InputFieldBuilder - .createInnerGrid(parent, orientation); + .createInnerGrid(parent, attribute, orientation); final RadioSelection selection = this.widgetFactory.selectionLocalized( Selection.Type.RADIO, innerGrid, - () -> this.getLocalizedResources(attribute, i18nSupport), + () -> this.getLocalizedResources(attribute, viewContext), null, - () -> this.getLocalizedResourcesAsToolTip(attribute, i18nSupport)) + () -> this.getLocalizedResourcesAsToolTip(attribute, viewContext)) .getTypeInstance(); selection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); @@ -71,7 +71,7 @@ public class RadioSelectionFieldBuilder extends SelectionFieldBuilder implements attribute, orientation, selection, - InputFieldBuilder.createErrorLabel(innerGrid)); + null); selection.setSelectionListener(event -> { radioSelectionInputField.clearError(); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SelectionFieldBuilder.java index 7e5d8395..50fe2a2a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SelectionFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SelectionFieldBuilder.java @@ -21,27 +21,26 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; import ch.ethz.seb.sebserver.gbl.util.Tuple; import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; -import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; public abstract class SelectionFieldBuilder { protected List> getLocalizedResources( final ConfigurationAttribute attribute, - final I18nSupport i18nSupport) { + final ViewContext viewContext) { - return getLocalizedRes(attribute, i18nSupport, false); + return getLocalizedRes(attribute, viewContext, false); } protected List> getLocalizedResourcesAsToolTip( final ConfigurationAttribute attribute, - final I18nSupport i18nSupport) { + final ViewContext viewContext) { - return getLocalizedRes(attribute, i18nSupport, true); + return getLocalizedRes(attribute, viewContext, true); } private List> getLocalizedRes( final ConfigurationAttribute attribute, - final I18nSupport i18nSupport, + final ViewContext viewContext, final boolean toolTipResources) { if (attribute == null) { @@ -62,7 +61,7 @@ public abstract class SelectionFieldBuilder { final String key = prefix + value + ((toolTipResources) ? ExamConfigurationService.TOOL_TIP_SUFFIX : ""); - final String text = i18nSupport.getText(key, ""); + final String text = viewContext.i18nSupport.getText(key, ""); return new Tuple<>(value, (StringUtils.isBlank(text)) ? (toolTipResources) ? text diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SingleSelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SingleSelectionFieldBuilder.java index baab45ed..6b86751b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SingleSelectionFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SingleSelectionFieldBuilder.java @@ -57,14 +57,14 @@ public class SingleSelectionFieldBuilder extends SelectionFieldBuilder implement final Orientation orientation = viewContext .getOrientation(attribute.id); final Composite innerGrid = InputFieldBuilder - .createInnerGrid(parent, orientation); + .createInnerGrid(parent, attribute, orientation); final SingleSelection selection = this.widgetFactory.selectionLocalized( (attribute.type == AttributeType.COMBO_SELECTION) ? Selection.Type.SINGLE_COMBO : Selection.Type.SINGLE, innerGrid, - () -> this.getLocalizedResources(attribute, i18nSupport), + () -> this.getLocalizedResources(attribute, viewContext), ExamConfigurationService.getToolTipKey(attribute, i18nSupport)) .getTypeInstance(); @@ -107,6 +107,14 @@ public class SingleSelectionFieldBuilder extends SelectionFieldBuilder implement protected void setValueToControl(final String value) { this.control.select(value); } + + @Override + public String getReadableValue() { + + // TODO Auto-generated method stub + return super.getReadableValue(); + } + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SliderFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SliderFieldBuilder.java index c83faa83..04a07754 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SliderFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/SliderFieldBuilder.java @@ -51,7 +51,7 @@ public class SliderFieldBuilder implements InputFieldBuilder { final Orientation orientation = viewContext .getOrientation(attribute.id); final Composite innerGrid = InputFieldBuilder - .createInnerGrid(parent, orientation); + .createInnerGrid(parent, attribute, orientation); final Slider slider = new Slider(innerGrid, SWT.NONE); slider.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableContext.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableContext.java index 48f034d7..17758443 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableContext.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableContext.java @@ -16,6 +16,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.lang3.BooleanUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,6 +24,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue; import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; +import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; import ch.ethz.seb.sebserver.gui.service.examconfig.InputField; import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder; import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener; @@ -58,8 +60,8 @@ public class TableContext { this.attribute = Objects.requireNonNull(attribute); this.viewContext = Objects.requireNonNull(viewContext); - this.orientation = viewContext - .getOrientation(attribute.id); + this.orientation = Objects.requireNonNull(viewContext + .getOrientation(attribute.id)); this.rowAttributes = viewContext.getChildAttributes(attribute.id) .stream() @@ -183,4 +185,29 @@ public class TableContext { }; } + public String getRowValue(final TableValue tableValue) { + final ConfigurationAttribute attribute = this.viewContext.getAttribute(tableValue.attributeId); + if (attribute != null) { + switch (attribute.type) { + case CHECKBOX: { + return BooleanUtils.toBoolean(tableValue.value) + ? "Active" + : "Inactive"; + } + case SINGLE_SELECTION: { + final ConfigurationAttribute tableAttr = + this.viewContext.attributeMapping.getAttribute(attribute.parentId); + final String key = ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + + attribute.getName() + "." + + tableValue.value; + return this.viewContext.i18nSupport.getText(key, tableValue.value); + } + default: + return tableValue.value; + } + } + + return tableValue.value; + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableFieldBuilder.java index e7433536..64c49a6e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableFieldBuilder.java @@ -20,7 +20,6 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; @@ -40,7 +39,6 @@ import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; import ch.ethz.seb.sebserver.gui.service.examconfig.InputField; import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; -import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; @@ -105,15 +103,16 @@ public class TableFieldBuilder implements InputFieldBuilder { true, false, (tableContext.orientation != null) ? tableContext.orientation.width() : 1, (tableContext.orientation != null) ? tableContext.orientation.height() : 1); - gridData.heightHint = tableContext.orientation.height * 40; + gridData.heightHint = tableContext.orientation.height * 20 + 40; table.setLayoutData(gridData); table.setHeaderVisible(true); - table.addListener(SWT.Resize, this::adaptColumnWidth); + table.addListener(SWT.Resize, event -> adaptColumnWidth(table, tableContext)); for (final ConfigurationAttribute columnAttribute : tableContext.getColumnAttributes()) { final TableColumn column = new TableColumn(table, SWT.NONE); final String text = i18nSupport.getText( - ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + columnAttribute.name, + ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + + columnAttribute.name, columnAttribute.name); column.setText(text); column.setWidth(100); @@ -159,14 +158,25 @@ public class TableFieldBuilder implements InputFieldBuilder { return tableField; } - private void adaptColumnWidth(final Event event) { + private void adaptColumnWidth( + final Table table, + final TableContext tableContext) { + try { - final Table table = (Table) event.widget; final int currentTableWidth = table.getClientArea().width - 50; final TableColumn[] columns = table.getColumns(); - final int columnWidth = currentTableWidth / (columns.length - 2); + final List orientations = tableContext + .getColumnAttributes() + .stream() + .map(attr -> tableContext.getOrientation(attr.id)) + .collect(Collectors.toList()); + final Integer div = orientations + .stream() + .map(o -> o.width) + .reduce(0, (acc, val) -> acc + val); + final int widthUnit = currentTableWidth / div; for (int i = 0; i < columns.length - 2; i++) { - columns[i].setWidth(columnWidth); + columns[i].setWidth(widthUnit * orientations.get(i).width); } } catch (final Exception e) { log.warn("Failed to adaptColumnWidth: ", e); @@ -196,6 +206,12 @@ public class TableFieldBuilder implements InputFieldBuilder { .map(TableValue::of) .collect(Collectors.toList()); + initValue(tableValues); + + return null; + } + + void initValue(final List tableValues) { final Map> _initValue = new HashMap<>(); for (final TableValue tableValue : tableValues) { final Map rowValues = _initValue.computeIfAbsent( @@ -215,13 +231,24 @@ public class TableFieldBuilder implements InputFieldBuilder { this.values.add(rowValues); addTableRow(rowValues); }); - - return null; } private boolean isChildValue(final ConfigurationValue value) { - return this.attribute.id.equals( - this.tableContext.getAttribute(value.attributeId).parentId); + if (!this.tableContext.getViewContext().attributeMapping.attributeIdMapping + .containsKey(value.attributeId)) { + + return false; + } + + ConfigurationAttribute attr = this.tableContext.getAttribute(value.attributeId); + while (attr.parentId != null) { + if (this.attribute.id.equals(attr.parentId)) { + return true; + } + attr = this.tableContext.getAttribute(attr.parentId); + } + + return false; } private void deleteRow(final int selectionIndex) { @@ -254,22 +281,7 @@ public class TableFieldBuilder implements InputFieldBuilder { final TableItem tableItem = new TableItem(this.control, SWT.NONE); applyTableRowValues(this.values.size() - 1); -// TODO delete icon is not working on row as expected -// final TableEditor editor = new TableEditor(this.control); -// editor.horizontalAlignment = SWT.CENTER; -// editor.grabHorizontal = true; -// editor.minimumWidth = 20; -// final Image image = ImageIcon.REMOVE_BOX.getImage(this.control.getDisplay()); -// final Label imageLabel = new Label(this.control, SWT.NONE); -// imageLabel.setAlignment(SWT.CENTER); -// imageLabel.setImage(image); -// imageLabel.addListener(SWT.MouseDown, event -> System.out.println("*************** removeRow")); -// editor.setEditor(imageLabel, tableItem, this.columnAttributes.size()); -// tableItem.setData("EDITOR", editor); -// -// editor.layout(); -// this.control.layout(true, true); - + // TODO try to add delete button within table row? } private void applyTableRowValues(final int index) { @@ -279,7 +291,9 @@ public class TableFieldBuilder implements InputFieldBuilder { int cellIndex = 0; for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) { if (rowValues.containsKey(attr.id)) { - item.setText(cellIndex, rowValues.get(attr.id).value); + item.setText( + cellIndex, + this.tableContext.getRowValue(rowValues.get(attr.id))); } cellIndex++; } @@ -299,7 +313,9 @@ public class TableFieldBuilder implements InputFieldBuilder { this.tableContext.getWidgetFactory()) .setDialogWidth(500) .open( - new LocTextKey("Title"), + ExamConfigurationService.getTablePopupTitleKey( + this.attribute, + this.tableContext.getViewContext().i18nSupport), values -> applyFormValues(values, selectionIndex), builder); } @@ -313,6 +329,9 @@ public class TableFieldBuilder implements InputFieldBuilder { this.values.remove(index); this.values.add(index, tableRowValues); applyTableRowValues(index); + // send new values to web-service + this.tableContext.getValueChangeListener() + .tableChanged(extractTableValue()); } private ConfigurationTableValues extractTableValue() { @@ -353,12 +372,13 @@ public class TableFieldBuilder implements InputFieldBuilder { @Override protected void setValueToControl(final String value) { - throw new UnsupportedOperationException(); + //throw new UnsupportedOperationException(); } @Override public String getValue() { - throw new UnsupportedOperationException(); + return null; + //throw new UnsupportedOperationException(); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableRowFormBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableRowFormBuilder.java index fd4edccd..8341180a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableRowFormBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/TableRowFormBuilder.java @@ -29,6 +29,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation; import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService; import ch.ethz.seb.sebserver.gui.service.examconfig.InputField; import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder; +import ch.ethz.seb.sebserver.gui.service.examconfig.impl.TableFieldBuilder.TableInputField; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; @@ -82,25 +83,27 @@ public class TableRowFormBuilder implements ModalInputDialogComposer(this.rowValues.values())); + } else { + inputField.initValue( + this.rowValues.get(attribute.id).value, + this.listIndex); + } // we have to register the input field within the ViewContext to receive error messages this.tableContext.registerInputField(inputField); @@ -108,9 +111,13 @@ public class TableRowFormBuilder implements ModalInputDialogComposer inputFieldMapping; - private final ValueChangeListener valueChangeListener; - private final I18nSupport i18nSupport; + final AttributeMapping attributeMapping; + final Map inputFieldMapping; + final ValueChangeListener valueChangeListener; + final I18nSupport i18nSupport; ViewContext( final Configuration configuration, diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewGridBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewGridBuilder.java index 32998046..941942c2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewGridBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/ViewGridBuilder.java @@ -67,6 +67,10 @@ public class ViewGridBuilder { } ViewGridBuilder add(final ConfigurationAttribute attribute) { + if (log.isDebugEnabled()) { + log.debug("Add SEB Configuration Attribute: " + attribute); + } + // ignore nested attributes here if (attribute.parentId != null) { return this; @@ -115,7 +119,8 @@ public class ViewGridBuilder { orientation); break; } - case LEFT: { + case LEFT: + case LEFT_SPAN: { this.grid[ypos][xpos - 1] = CellFieldBuilderAdapter.labelBuilder( attribute, orientation); @@ -127,17 +132,17 @@ public class ViewGridBuilder { } break; } - case LEFT_SPAN: { - int spanxpos = xpos - orientation.width; - if (spanxpos < 0) { - spanxpos = 0; - } - fillDummy(spanxpos, ypos, orientation.width, 1); - this.grid[ypos][spanxpos] = CellFieldBuilderAdapter.labelBuilder( - attribute, - orientation); - break; - } +// case LEFT_SPAN: { +// int spanxpos = xpos - orientation.width; +// if (spanxpos < 0) { +// spanxpos = 0; +// } +// fillDummy(spanxpos, ypos, orientation.width, 1); +// this.grid[ypos][spanxpos] = CellFieldBuilderAdapter.labelBuilder( +// attribute, +// orientation); +// break; +// } case TOP: { fillDummy(xpos, ypos - 1, orientation.width, 1); this.grid[ypos - 1][xpos] = CellFieldBuilderAdapter.labelBuilder( @@ -160,9 +165,11 @@ public class ViewGridBuilder { log.debug("Compose grid view: \n" + gridToString()); } + // balance grid (optimize span and grab empty spaces for labels where applicable) for (int y = 0; y < this.grid.length; y++) { for (int x = 0; x < this.grid[y].length; x++) { if (this.grid[y][x] != null) { + this.grid[y][x].balanceGrid(this.grid, x, y); } } } @@ -174,7 +181,7 @@ public class ViewGridBuilder { final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); gridData.verticalIndent = 8; empty.setLayoutData(gridData); - empty.setText(""); + empty.setText("" /* "empty " + x + " " + y */); } else { this.grid[y][x].createCell(this); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/rules/AllowFlashFullscreenRule.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/rules/AllowFlashFullscreenRule.java new file mode 100644 index 00000000..b4f1cba2 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/examconfig/impl/rules/AllowFlashFullscreenRule.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.gui.service.examconfig.impl.rules; + +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; +import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeRule; +import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext; + +@Lazy +@Service +@GuiProfile +public class AllowFlashFullscreenRule implements ValueChangeRule { + + public static final String KEY_THIRD_PART = "allowSwitchToApplications"; + public static final String KEY_FULL_SCREEN = "allowFlashFullscreen"; + + @Override + public boolean observesAttribute(final ConfigurationAttribute attribute) { + return KEY_THIRD_PART.equals(attribute.name); + } + + @Override + public void applyRule( + final ViewContext context, + final ConfigurationAttribute attribut, + final ConfigurationValue value) { + + if (BooleanUtils.toBoolean(value.value)) { + context.enable(KEY_FULL_SCREEN); + } else { + context.disable(KEY_FULL_SCREEN); + } + } +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java index 1f73166a..03b68cf3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java @@ -37,6 +37,10 @@ public interface Selection { String getSelectionValue(); + default String getSelectionReadableValue() { + return getSelectionValue(); + } + void clear(); void setVisible(boolean visible); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java index 8afcbb7e..ffb5082f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java @@ -17,6 +17,7 @@ import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Listener; +import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.util.Tuple; public final class SingleSelection extends Combo implements Selection { @@ -73,6 +74,16 @@ public final class SingleSelection extends Combo implements Selection { return this.keyMapping.get(selectionindex); } + @Override + public String getSelectionReadableValue() { + final int selectionindex = super.getSelectionIndex(); + if (selectionindex < 0) { + return Constants.EMPTY_NOTE; + } + + return this.valueMapping.get(selectionindex); + } + @Override public void clear() { super.clearSelection(); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExitKeySequenceValidator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExitKeySequenceValidator.java index ce651c29..3059f545 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExitKeySequenceValidator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExitKeySequenceValidator.java @@ -56,7 +56,7 @@ public class ExitKeySequenceValidator implements ConfigurationValueValidator { } try { - return this.configurationValueRecordMapper.selectByExample() + return !this.configurationValueRecordMapper.selectByExample() .join(ConfigurationAttributeRecordDynamicSqlSupport.configurationAttributeRecord) .on( ConfigurationAttributeRecordDynamicSqlSupport.id, @@ -75,7 +75,7 @@ public class ExitKeySequenceValidator implements ConfigurationValueValidator { .stream() .filter(val -> value.value.equals(val.getValue())) .findFirst() - .isEmpty(); + .isPresent(); } catch (final Exception e) { log.error("unexpected error while trying to validate SEB exam configuration attributes: {}", ATTR_NAMES, e); return true; diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index ef2756d7..389aa7be 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -358,6 +358,7 @@ sebserver.examconfig.action.list.view=View Configuration sebserver.examconfig.action.list.modify=Edit sebserver.examconfig.action.list.modify.properties=Edit Properties sebserver.examconfig.action.modify=Edit +sebserver.examconfig.action.modify.properties=Edit Properties sebserver.examconfig.action.save=Save sebserver.examconfig.form.title.new=New Exam Configuration @@ -376,6 +377,7 @@ sebserver.examconfig.props.form.views.user_interface=User Interface sebserver.examconfig.props.form.views.browser=Browser sebserver.examconfig.props.form.views.down_upload=Down/Uploads sebserver.examconfig.props.form.views.exam=Exam +sebserver.examconfig.props.form.views.applications=Applications sebserver.examconfig.props.label.hashedAdminPassword=Administrator password sebserver.examconfig.props.label.hashedAdminPassword.confirm=Confirm password @@ -532,6 +534,42 @@ sebserver.examconfig.props.label.restartExamURL=Enter custom URL or select 'Use sebserver.examconfig.props.label.restartExamText=Title/tool tip text for the back to start button (leave empty for localized standard text) sebserver.examconfig.props.label.restartExamPasswordProtected=Protect back to start button with the quit/unlock password +sebserver.examconfig.props.label.allowSwitchToApplications=Allow switching to third party application (Mac) +sebserver.examconfig.props.label.allowFlashFullscreen=Allow Flash to switch to fullscreen mode (Mac) +sebserver.examconfig.props.label.permittedProcesses.row.title=Permitted Processes +sebserver.examconfig.props.label.permittedProcesses=Permitted Processes +sebserver.examconfig.props.label.permittedProcesses.active=Activity +sebserver.examconfig.props.label.permittedProcesses.os=OS +sebserver.examconfig.props.label.permittedProcesses.os.0=Win +sebserver.examconfig.props.label.permittedProcesses.os.1=OS X +sebserver.examconfig.props.label.permittedProcesses.title=Title +sebserver.examconfig.props.label.permittedProcesses.description=Description +sebserver.examconfig.props.label.permittedProcesses.executable=Executable +sebserver.examconfig.props.label.permittedProcesses.originalName=Original Name +sebserver.examconfig.props.label.permittedProcesses.allowedExecutables=Window handling process +sebserver.examconfig.props.label.permittedProcesses.path=Path +sebserver.examconfig.props.label.permittedProcesses.arguments=Arguments +sebserver.examconfig.props.label.arguments.active=Activity +sebserver.examconfig.props.label.arguments.argument=Argument +sebserver.examconfig.props.label.permittedProcesses.identifier=Identifier +sebserver.examconfig.props.label.permittedProcesses.iconInTaskbar=Icon in taskbar +sebserver.examconfig.props.label.permittedProcesses.autostart=Autostart +sebserver.examconfig.props.label.permittedProcesses.runInBackground=Allow running in background +sebserver.examconfig.props.label.permittedProcesses.allowUserToChooseApp=Allow user to select location of application +sebserver.examconfig.props.label.permittedProcesses.strongKill=Force quit (risk of data loss) + +sebserver.examconfig.props.label.prohibitedProcesses.row.title=Prohibited Processes +sebserver.examconfig.props.label.prohibitedProcesses=Prohibited Processes +sebserver.examconfig.props.label.prohibitedProcesses.active=Activity +sebserver.examconfig.props.label.prohibitedProcesses.os=OS +sebserver.examconfig.props.label.prohibitedProcesses.os.0=Win +sebserver.examconfig.props.label.prohibitedProcesses.os.1=OS X +sebserver.examconfig.props.label.prohibitedProcesses.description=Description +sebserver.examconfig.props.label.prohibitedProcesses.executable=Executable +sebserver.examconfig.props.label.prohibitedProcesses.originalName=Original Name +sebserver.examconfig.props.label.prohibitedProcesses.identifier=Identifier +sebserver.examconfig.props.label.prohibitedProcesses.strongKill=Force quit (risk of data loss) + sebserver.examconfig.props.validation.password.confirm=Please enter correct confirm password sebserver.examconfig.props.validation.unexpected=Unexpected error happened. Value was not set correctly