code cleanup
This commit is contained in:
parent
df884bd8d2
commit
884f9c78e0
40 changed files with 4320 additions and 4290 deletions
|
@ -101,15 +101,15 @@ public class ExamForm implements TemplateComposer {
|
||||||
new LocTextKey("sebserver.exam.form.status");
|
new LocTextKey("sebserver.exam.form.status");
|
||||||
private static final LocTextKey FORM_TYPE_TEXT_KEY =
|
private static final LocTextKey FORM_TYPE_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.type");
|
new LocTextKey("sebserver.exam.form.type");
|
||||||
private static final LocTextKey FORM_ENDTIME_TEXT_KEY =
|
private static final LocTextKey FORM_END_TIME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.endtime");
|
new LocTextKey("sebserver.exam.form.endtime");
|
||||||
private static final LocTextKey FORM_STARTTIME_TEXT_KEY =
|
private static final LocTextKey FORM_START_TIME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.starttime");
|
new LocTextKey("sebserver.exam.form.starttime");
|
||||||
private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
private static final LocTextKey FORM_DESCRIPTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.description");
|
new LocTextKey("sebserver.exam.form.description");
|
||||||
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
private static final LocTextKey FORM_NAME_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.name");
|
new LocTextKey("sebserver.exam.form.name");
|
||||||
private static final LocTextKey FORM_QUIZID_TEXT_KEY =
|
private static final LocTextKey FORM_QUIZ_ID_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.quizid");
|
new LocTextKey("sebserver.exam.form.quizid");
|
||||||
private static final LocTextKey FORM_QUIZ_URL_TEXT_KEY =
|
private static final LocTextKey FORM_QUIZ_URL_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.form.quizurl");
|
new LocTextKey("sebserver.exam.form.quizurl");
|
||||||
|
@ -285,14 +285,14 @@ public class ExamForm implements TemplateComposer {
|
||||||
|
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
QuizData.QUIZ_ATTR_START_TIME,
|
QuizData.QUIZ_ATTR_START_TIME,
|
||||||
FORM_STARTTIME_TEXT_KEY,
|
FORM_START_TIME_TEXT_KEY,
|
||||||
i18nSupport.formatDisplayDateWithTimeZone(exam.startTime))
|
i18nSupport.formatDisplayDateWithTimeZone(exam.startTime))
|
||||||
.readonly(true)
|
.readonly(true)
|
||||||
.withInputSpan(3)
|
.withInputSpan(3)
|
||||||
.withEmptyCellSeparation(false))
|
.withEmptyCellSeparation(false))
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
QuizData.QUIZ_ATTR_END_TIME,
|
QuizData.QUIZ_ATTR_END_TIME,
|
||||||
FORM_ENDTIME_TEXT_KEY,
|
FORM_END_TIME_TEXT_KEY,
|
||||||
i18nSupport.formatDisplayDateWithTimeZone(exam.endTime))
|
i18nSupport.formatDisplayDateWithTimeZone(exam.endTime))
|
||||||
.readonly(true)
|
.readonly(true)
|
||||||
.withInputSpan(3)
|
.withInputSpan(3)
|
||||||
|
@ -300,7 +300,7 @@ public class ExamForm implements TemplateComposer {
|
||||||
|
|
||||||
.addField(FormBuilder.text(
|
.addField(FormBuilder.text(
|
||||||
Domain.EXAM.ATTR_EXTERNAL_ID,
|
Domain.EXAM.ATTR_EXTERNAL_ID,
|
||||||
FORM_QUIZID_TEXT_KEY,
|
FORM_QUIZ_ID_TEXT_KEY,
|
||||||
exam.externalId)
|
exam.externalId)
|
||||||
.readonly(true)
|
.readonly(true)
|
||||||
.withEmptyCellSeparation(false))
|
.withEmptyCellSeparation(false))
|
||||||
|
|
|
@ -62,11 +62,11 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class ExamList implements TemplateComposer {
|
public class ExamList implements TemplateComposer {
|
||||||
|
|
||||||
static final String EXAM_LIST_COLUMN_STARTTIME =
|
static final String EXAM_LIST_COLUMN_START_TIME =
|
||||||
"sebserver.exam.list.column.starttime";
|
"sebserver.exam.list.column.starttime";
|
||||||
static final LocTextKey PAGE_TITLE_KEY =
|
static final LocTextKey PAGE_TITLE_KEY =
|
||||||
new LocTextKey("sebserver.exam.list.title");
|
new LocTextKey("sebserver.exam.list.title");
|
||||||
static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION =
|
||||||
new LocTextKey("sebserver.exam.list.action.no.modify.privilege");
|
new LocTextKey("sebserver.exam.list.action.no.modify.privilege");
|
||||||
final static LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
final static LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.exam.info.pleaseSelect");
|
new LocTextKey("sebserver.exam.info.pleaseSelect");
|
||||||
|
@ -175,7 +175,7 @@ public class ExamList implements TemplateComposer {
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
QuizData.QUIZ_ATTR_START_TIME,
|
QuizData.QUIZ_ATTR_START_TIME,
|
||||||
new LocTextKey(
|
new LocTextKey(
|
||||||
EXAM_LIST_COLUMN_STARTTIME,
|
EXAM_LIST_COLUMN_START_TIME,
|
||||||
i18nSupport.getUsersTimeZoneTitleSuffix()),
|
i18nSupport.getUsersTimeZoneTitleSuffix()),
|
||||||
Exam::getStartTime)
|
Exam::getStartTime)
|
||||||
.withFilter(new TableFilterAttribute(
|
.withFilter(new TableFilterAttribute(
|
||||||
|
@ -213,7 +213,7 @@ public class ExamList implements TemplateComposer {
|
||||||
|
|
||||||
.newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST)
|
.newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST)
|
||||||
.withSelect(
|
.withSelect(
|
||||||
table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION),
|
||||||
action -> modifyExam(action, table),
|
action -> modifyExam(action, table),
|
||||||
EMPTY_SELECTION_TEXT_KEY)
|
EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> userGrant.im() && table.hasAnyContent(), false);
|
.publishIf(() -> userGrant.im() && table.hasAnyContent(), false);
|
||||||
|
|
|
@ -46,7 +46,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class LmsSetupList implements TemplateComposer {
|
public class LmsSetupList implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION =
|
||||||
new LocTextKey("sebserver.lmssetup.list.action.no.modify.privilege");
|
new LocTextKey("sebserver.lmssetup.list.action.no.modify.privilege");
|
||||||
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.lmssetup.info.pleaseSelect");
|
new LocTextKey("sebserver.lmssetup.info.pleaseSelect");
|
||||||
|
@ -173,7 +173,7 @@ public class LmsSetupList implements TemplateComposer {
|
||||||
|
|
||||||
.newAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST)
|
.newAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST)
|
||||||
.withSelect(
|
.withSelect(
|
||||||
table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION),
|
||||||
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> userGrant.im() && table.hasAnyContent(), false)
|
.publishIf(() -> userGrant.im() && table.hasAnyContent(), false)
|
||||||
|
|
||||||
|
|
|
@ -1,201 +1,196 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.eclipse.swt.widgets.MessageBox;
|
import org.eclipse.swt.widgets.MessageBox;
|
||||||
import org.eclipse.swt.widgets.Text;
|
import org.eclipse.swt.widgets.Text;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
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.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.DefaultRegisterPage;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.DefaultRegisterPage;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.Message;
|
import ch.ethz.seb.sebserver.gui.widget.Message;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class LoginPage implements TemplateComposer {
|
public class LoginPage implements TemplateComposer {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(LoginPage.class);
|
private static final Logger log = LoggerFactory.getLogger(LoginPage.class);
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final AuthorizationContextHolder authorizationContextHolder;
|
private final AuthorizationContextHolder authorizationContextHolder;
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
private final I18nSupport i18nSupport;
|
private final I18nSupport i18nSupport;
|
||||||
private final DefaultRegisterPage defaultRegisterPage;
|
private final DefaultRegisterPage defaultRegisterPage;
|
||||||
private final boolean registreringEnabled;
|
private final boolean registeringEnabled;
|
||||||
|
|
||||||
public LoginPage(
|
public LoginPage(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final DefaultRegisterPage defaultRegisterPage,
|
final DefaultRegisterPage defaultRegisterPage,
|
||||||
@Value("${sebserver.gui.self-registering:false}") final Boolean registreringEnabled) {
|
@Value("${sebserver.gui.self-registering:false}") final Boolean registeringEnabled) {
|
||||||
|
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.authorizationContextHolder = pageService.getAuthorizationContextHolder();
|
this.authorizationContextHolder = pageService.getAuthorizationContextHolder();
|
||||||
this.widgetFactory = pageService.getWidgetFactory();
|
this.widgetFactory = pageService.getWidgetFactory();
|
||||||
this.i18nSupport = pageService.getI18nSupport();
|
this.i18nSupport = pageService.getI18nSupport();
|
||||||
this.defaultRegisterPage = defaultRegisterPage;
|
this.defaultRegisterPage = defaultRegisterPage;
|
||||||
this.registreringEnabled = BooleanUtils.toBoolean(registreringEnabled);
|
this.registeringEnabled = BooleanUtils.toBoolean(registeringEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
final Composite parent = pageContext.getParent();
|
final Composite parent = pageContext.getParent();
|
||||||
WidgetFactory.setTestId(parent, "login-page");
|
WidgetFactory.setTestId(parent, "login-page");
|
||||||
WidgetFactory.setARIARole(parent, "composite");
|
WidgetFactory.setARIARole(parent, "composite");
|
||||||
|
|
||||||
final Composite loginGroup = new Composite(parent, SWT.NONE);
|
final Composite loginGroup = new Composite(parent, SWT.NONE);
|
||||||
final GridLayout rowLayout = new GridLayout();
|
final GridLayout rowLayout = new GridLayout();
|
||||||
rowLayout.marginWidth = 20;
|
rowLayout.marginWidth = 20;
|
||||||
rowLayout.marginRight = 100;
|
rowLayout.marginRight = 100;
|
||||||
loginGroup.setLayout(rowLayout);
|
loginGroup.setLayout(rowLayout);
|
||||||
loginGroup.setData(RWT.CUSTOM_VARIANT, WidgetFactory.CustomVariant.LOGIN.key);
|
loginGroup.setData(RWT.CUSTOM_VARIANT, WidgetFactory.CustomVariant.LOGIN.key);
|
||||||
|
|
||||||
final Label name = this.widgetFactory.labelLocalized(loginGroup, "sebserver.login.username");
|
final Label name = this.widgetFactory.labelLocalized(loginGroup, "sebserver.login.username");
|
||||||
name.setLayoutData(new GridData(300, -1));
|
name.setLayoutData(new GridData(300, -1));
|
||||||
name.setAlignment(SWT.BOTTOM);
|
name.setAlignment(SWT.BOTTOM);
|
||||||
final Text loginName = this.widgetFactory.textInput(loginGroup);
|
final Text loginName = this.widgetFactory.textInput(loginGroup);
|
||||||
loginName.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
|
loginName.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
|
||||||
GridData gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
|
GridData gridData = new GridData(SWT.FILL, SWT.TOP, false, false);
|
||||||
gridData.verticalIndent = 10;
|
gridData.verticalIndent = 10;
|
||||||
final Label pwd = this.widgetFactory.labelLocalized(loginGroup, "sebserver.login.pwd");
|
final Label pwd = this.widgetFactory.labelLocalized(loginGroup, "sebserver.login.pwd");
|
||||||
pwd.setLayoutData(gridData);
|
pwd.setLayoutData(gridData);
|
||||||
final Text loginPassword = this.widgetFactory.passwordInput(loginGroup);
|
final Text loginPassword = this.widgetFactory.passwordInput(loginGroup);
|
||||||
loginPassword.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
|
loginPassword.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, false));
|
||||||
|
|
||||||
final SEBServerAuthorizationContext authorizationContext = this.authorizationContextHolder
|
final SEBServerAuthorizationContext authorizationContext = this.authorizationContextHolder
|
||||||
.getAuthorizationContext(RWT.getUISession().getHttpSession());
|
.getAuthorizationContext(RWT.getUISession().getHttpSession());
|
||||||
|
|
||||||
final Composite buttons = new Composite(loginGroup, SWT.NONE);
|
final Composite buttons = new Composite(loginGroup, SWT.NONE);
|
||||||
buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||||
buttons.setLayout(new GridLayout(2, false));
|
buttons.setLayout(new GridLayout(2, false));
|
||||||
buttons.setData(RWT.CUSTOM_VARIANT, WidgetFactory.CustomVariant.LOGIN_BACK.key);
|
buttons.setData(RWT.CUSTOM_VARIANT, WidgetFactory.CustomVariant.LOGIN_BACK.key);
|
||||||
|
|
||||||
final Button loginButton = this.widgetFactory.buttonLocalized(buttons, "sebserver.login.login");
|
final Button loginButton = this.widgetFactory.buttonLocalized(buttons, "sebserver.login.login");
|
||||||
gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
|
gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
|
||||||
gridData.verticalIndent = 10;
|
gridData.verticalIndent = 10;
|
||||||
loginButton.setLayoutData(gridData);
|
loginButton.setLayoutData(gridData);
|
||||||
loginButton.addListener(SWT.Selection, event -> {
|
loginButton.addListener(SWT.Selection, event -> login(
|
||||||
login(
|
pageContext,
|
||||||
pageContext,
|
loginName.getText(),
|
||||||
loginName.getText(),
|
loginPassword.getText(),
|
||||||
loginPassword.getText(),
|
authorizationContext));
|
||||||
authorizationContext);
|
loginName.addListener(SWT.KeyDown, event -> {
|
||||||
});
|
if (event.character == '\n' || event.character == '\r') {
|
||||||
loginName.addListener(SWT.KeyDown, event -> {
|
if (StringUtils.isNotBlank(loginPassword.getText())) {
|
||||||
if (event.character == '\n' || event.character == '\r') {
|
login(
|
||||||
if (StringUtils.isNotBlank(loginPassword.getText())) {
|
pageContext,
|
||||||
login(
|
loginName.getText(),
|
||||||
pageContext,
|
loginPassword.getText(),
|
||||||
loginName.getText(),
|
authorizationContext);
|
||||||
loginPassword.getText(),
|
} else {
|
||||||
authorizationContext);
|
loginPassword.setFocus();
|
||||||
} else {
|
}
|
||||||
loginPassword.setFocus();
|
}
|
||||||
}
|
});
|
||||||
}
|
loginPassword.addListener(SWT.KeyDown, event -> {
|
||||||
});
|
if (event.character == '\n' || event.character == '\r') {
|
||||||
loginPassword.addListener(SWT.KeyDown, event -> {
|
if (StringUtils.isNotBlank(loginName.getText())) {
|
||||||
if (event.character == '\n' || event.character == '\r') {
|
login(
|
||||||
if (StringUtils.isNotBlank(loginName.getText())) {
|
pageContext,
|
||||||
login(
|
loginName.getText(),
|
||||||
pageContext,
|
loginPassword.getText(),
|
||||||
loginName.getText(),
|
authorizationContext);
|
||||||
loginPassword.getText(),
|
} else {
|
||||||
authorizationContext);
|
loginName.setFocus();
|
||||||
} else {
|
}
|
||||||
loginName.setFocus();
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
});
|
if (this.registeringEnabled) {
|
||||||
|
final Button registerButton = this.widgetFactory.buttonLocalized(buttons, "sebserver.login.register");
|
||||||
if (this.registreringEnabled) {
|
gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
|
||||||
final Button registerButton = this.widgetFactory.buttonLocalized(buttons, "sebserver.login.register");
|
gridData.verticalIndent = 10;
|
||||||
gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
|
registerButton.setLayoutData(gridData);
|
||||||
gridData.verticalIndent = 10;
|
registerButton.addListener(SWT.Selection, event -> pageContext.forwardToPage(this.defaultRegisterPage));
|
||||||
registerButton.setLayoutData(gridData);
|
}
|
||||||
registerButton.addListener(SWT.Selection, event -> {
|
}
|
||||||
pageContext.forwardToPage(this.defaultRegisterPage);
|
|
||||||
});
|
private void login(
|
||||||
}
|
final PageContext pageContext,
|
||||||
}
|
final String loginName,
|
||||||
|
final CharSequence loginPassword,
|
||||||
private void login(
|
final SEBServerAuthorizationContext authorizationContext) {
|
||||||
final PageContext pageContext,
|
|
||||||
final String loginName,
|
try {
|
||||||
final CharSequence loginPassword,
|
|
||||||
final SEBServerAuthorizationContext authorizationContext) {
|
final boolean loggedIn = authorizationContext.login(
|
||||||
|
loginName,
|
||||||
final String username = loginName;
|
loginPassword);
|
||||||
try {
|
|
||||||
|
if (loggedIn) {
|
||||||
final boolean loggedIn = authorizationContext.login(
|
// Set users locale on page after successful login
|
||||||
username,
|
try {
|
||||||
loginPassword);
|
RWT.getUISession()
|
||||||
|
.getHttpSession()
|
||||||
if (loggedIn) {
|
.setAttribute(I18nSupport.ATTR_CURRENT_SESSION_LOCALE, authorizationContext
|
||||||
// Set users locale on page after successful login
|
.getLoggedInUser()
|
||||||
try {
|
.getOrThrow().language);
|
||||||
RWT.getUISession()
|
|
||||||
.getHttpSession()
|
} catch (final IllegalStateException e) {
|
||||||
.setAttribute(I18nSupport.ATTR_CURRENT_SESSION_LOCALE, authorizationContext
|
log.error("Set current locale for session failed: ", e);
|
||||||
.getLoggedInUser()
|
}
|
||||||
.getOrThrow().language);
|
|
||||||
|
RWT.setLocale(this.i18nSupport.getUsersFormatLocale());
|
||||||
} catch (final IllegalStateException e) {
|
|
||||||
log.error("Set current locale for session failed: ", e);
|
pageContext.forwardToMainPage();
|
||||||
}
|
|
||||||
|
} else {
|
||||||
RWT.setLocale(this.i18nSupport.getUsersFormatLocale());
|
loginError(pageContext, "sebserver.login.failed.message");
|
||||||
|
}
|
||||||
pageContext.forwardToMainPage();
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while trying to login with user: {}", loginName, e);
|
||||||
} else {
|
loginError(pageContext, "Unexpected Error. Please call an Administrator");
|
||||||
loginError(pageContext, "sebserver.login.failed.message");
|
}
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
|
||||||
log.error("Unexpected error while trying to login with user: {}", username, e);
|
private void loginError(
|
||||||
loginError(pageContext, "Unexpected Error. Please call an Administrator");
|
final PageContext pageContext,
|
||||||
}
|
final String message) {
|
||||||
}
|
|
||||||
|
this.pageService.logout(pageContext);
|
||||||
private void loginError(
|
final MessageBox error = new Message(
|
||||||
final PageContext pageContext,
|
pageContext.getShell(),
|
||||||
final String message) {
|
this.i18nSupport.getText("sebserver.login.failed.title"),
|
||||||
|
this.i18nSupport.getText(message, message),
|
||||||
this.pageService.logout(pageContext);
|
SWT.ERROR,
|
||||||
final MessageBox error = new Message(
|
this.i18nSupport);
|
||||||
pageContext.getShell(),
|
error.open(null);
|
||||||
this.i18nSupport.getText("sebserver.login.failed.title"),
|
}
|
||||||
this.i18nSupport.getText(message, message),
|
|
||||||
SWT.ERROR,
|
}
|
||||||
this.i18nSupport);
|
|
||||||
error.open(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,184 +1,184 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content;
|
package ch.ethz.seb.sebserver.gui.content;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.custom.SashForm;
|
import org.eclipse.swt.custom.SashForm;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.content.activity.ActivitiesPane;
|
import ch.ethz.seb.sebserver.gui.content.activity.ActivitiesPane;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
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.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class MainPage implements TemplateComposer {
|
public class MainPage implements TemplateComposer {
|
||||||
|
|
||||||
static final Logger log = LoggerFactory.getLogger(MainPage.class);
|
static final Logger log = LoggerFactory.getLogger(MainPage.class);
|
||||||
|
|
||||||
private static final int ACTIVITY_PANE_WEIGHT = 18;
|
private static final int ACTIVITY_PANE_WEIGHT = 18;
|
||||||
private static final int CONTENT_PANE_WEIGHT = 65;
|
private static final int CONTENT_PANE_WEIGHT = 65;
|
||||||
private static final int ACTION_PANE_WEIGHT = 20;
|
private static final int ACTION_PANE_WEIGHT = 20;
|
||||||
private static final int[] DEFAULT_SASH_WEIGHTS = new int[] {
|
private static final int[] DEFAULT_SASH_WEIGHTS = new int[] {
|
||||||
ACTIVITY_PANE_WEIGHT,
|
ACTIVITY_PANE_WEIGHT,
|
||||||
CONTENT_PANE_WEIGHT,
|
CONTENT_PANE_WEIGHT,
|
||||||
ACTION_PANE_WEIGHT
|
ACTION_PANE_WEIGHT
|
||||||
};
|
};
|
||||||
private static final int[] OPENED_SASH_WEIGHTS = new int[] { 0, 100, 0 };
|
private static final int[] OPENED_SASH_WEIGHTS = new int[] { 0, 100, 0 };
|
||||||
|
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
private final PolyglotPageService polyglotPageService;
|
private final PolyglotPageService polyglotPageService;
|
||||||
|
|
||||||
public MainPage(
|
public MainPage(
|
||||||
final WidgetFactory widgetFactory,
|
final WidgetFactory widgetFactory,
|
||||||
final PolyglotPageService polyglotPageService) {
|
final PolyglotPageService polyglotPageService) {
|
||||||
|
|
||||||
this.widgetFactory = widgetFactory;
|
this.widgetFactory = widgetFactory;
|
||||||
this.polyglotPageService = polyglotPageService;
|
this.polyglotPageService = polyglotPageService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
|
|
||||||
final Composite parent = pageContext.getParent();
|
final Composite parent = pageContext.getParent();
|
||||||
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
WidgetFactory.setTestId(parent, "main-page");
|
WidgetFactory.setTestId(parent, "main-page");
|
||||||
|
|
||||||
final SashForm mainSash = new SashForm(parent, SWT.HORIZONTAL);
|
final SashForm mainSash = new SashForm(parent, SWT.HORIZONTAL);
|
||||||
final GridLayout gridLayout = new GridLayout();
|
final GridLayout gridLayout = new GridLayout();
|
||||||
|
|
||||||
mainSash.setLayout(gridLayout);
|
mainSash.setLayout(gridLayout);
|
||||||
mainSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
mainSash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
|
|
||||||
final Composite nav = new Composite(mainSash, SWT.NONE);
|
final Composite nav = new Composite(mainSash, SWT.NONE);
|
||||||
nav.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
nav.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
final GridLayout navLayout = new GridLayout();
|
final GridLayout navLayout = new GridLayout();
|
||||||
navLayout.marginHeight = 20;
|
navLayout.marginHeight = 20;
|
||||||
navLayout.marginWidth = 0;
|
navLayout.marginWidth = 0;
|
||||||
nav.setLayout(navLayout);
|
nav.setLayout(navLayout);
|
||||||
|
|
||||||
final Composite content = PageService.createManagedVScrolledComposite(
|
final Composite content = PageService.createManagedVScrolledComposite(
|
||||||
mainSash,
|
mainSash,
|
||||||
scrolledComposite -> {
|
scrolledComposite -> {
|
||||||
final Composite result = new Composite(scrolledComposite, SWT.NONE);
|
final Composite result = new Composite(scrolledComposite, SWT.NONE);
|
||||||
result.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
result.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
|
||||||
final GridLayout contentOuterlayout = new GridLayout();
|
final GridLayout contentOuterLayout = new GridLayout();
|
||||||
contentOuterlayout.marginHeight = 0;
|
contentOuterLayout.marginHeight = 0;
|
||||||
contentOuterlayout.marginWidth = 0;
|
contentOuterLayout.marginWidth = 0;
|
||||||
result.setLayout(contentOuterlayout);
|
result.setLayout(contentOuterLayout);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
|
|
||||||
final Label toggleView = this.widgetFactory.imageButton(
|
final Label toggleView = this.widgetFactory.imageButton(
|
||||||
ImageIcon.MAXIMIZE,
|
ImageIcon.MAXIMIZE,
|
||||||
content,
|
content,
|
||||||
new LocTextKey("sebserver.mainpage.maximize.tooltip"),
|
new LocTextKey("sebserver.mainpage.maximize.tooltip"),
|
||||||
event -> {
|
event -> {
|
||||||
final Label ib = (Label) event.widget;
|
final Label ib = (Label) event.widget;
|
||||||
if ((Boolean) ib.getData("fullScreen")) {
|
if ((Boolean) ib.getData("fullScreen")) {
|
||||||
mainSash.setWeights(DEFAULT_SASH_WEIGHTS);
|
mainSash.setWeights(DEFAULT_SASH_WEIGHTS);
|
||||||
ib.setData("fullScreen", false);
|
ib.setData("fullScreen", false);
|
||||||
ib.setImage(WidgetFactory.ImageIcon.MAXIMIZE.getImage(ib.getDisplay()));
|
ib.setImage(WidgetFactory.ImageIcon.MAXIMIZE.getImage(ib.getDisplay()));
|
||||||
this.polyglotPageService.injectI18n(
|
this.polyglotPageService.injectI18n(
|
||||||
ib,
|
ib,
|
||||||
null,
|
null,
|
||||||
new LocTextKey("sebserver.mainpage.maximize.tooltip"));
|
new LocTextKey("sebserver.mainpage.maximize.tooltip"));
|
||||||
} else {
|
} else {
|
||||||
mainSash.setWeights(OPENED_SASH_WEIGHTS);
|
mainSash.setWeights(OPENED_SASH_WEIGHTS);
|
||||||
ib.setData("fullScreen", true);
|
ib.setData("fullScreen", true);
|
||||||
ib.setImage(WidgetFactory.ImageIcon.MINIMIZE.getImage(ib.getDisplay()));
|
ib.setImage(WidgetFactory.ImageIcon.MINIMIZE.getImage(ib.getDisplay()));
|
||||||
this.polyglotPageService.injectI18n(
|
this.polyglotPageService.injectI18n(
|
||||||
ib,
|
ib,
|
||||||
null,
|
null,
|
||||||
new LocTextKey("sebserver.mainpage.minimize.tooltip"));
|
new LocTextKey("sebserver.mainpage.minimize.tooltip"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final GridData gridData = new GridData(SWT.RIGHT, SWT.TOP, true, false);
|
final GridData gridData = new GridData(SWT.RIGHT, SWT.TOP, true, false);
|
||||||
toggleView.setLayoutData(gridData);
|
toggleView.setLayoutData(gridData);
|
||||||
toggleView.setData("fullScreen", false);
|
toggleView.setData("fullScreen", false);
|
||||||
|
|
||||||
final Composite contentObjects = new Composite(content, SWT.NONE);
|
final Composite contentObjects = new Composite(content, SWT.NONE);
|
||||||
contentObjects.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
contentObjects.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
final GridLayout contentObjectslayout = new GridLayout();
|
final GridLayout contentObjectsLayout = new GridLayout();
|
||||||
contentObjectslayout.marginHeight = 0;
|
contentObjectsLayout.marginHeight = 0;
|
||||||
contentObjectslayout.marginWidth = 0;
|
contentObjectsLayout.marginWidth = 0;
|
||||||
contentObjects.setLayout(contentObjectslayout);
|
contentObjects.setLayout(contentObjectsLayout);
|
||||||
contentObjects.setData(
|
contentObjects.setData(
|
||||||
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
||||||
new ContentActionEventListener(event -> pageContext
|
new ContentActionEventListener(event -> pageContext
|
||||||
.composerService()
|
.composerService()
|
||||||
.compose(
|
.compose(
|
||||||
event.action.definition.targetState.contentPaneComposer(),
|
event.action.definition.targetState.contentPaneComposer(),
|
||||||
event.action.pageContext().copyOf(contentObjects)),
|
event.action.pageContext().copyOf(contentObjects)),
|
||||||
2));
|
2));
|
||||||
|
|
||||||
final Composite actionPane = new Composite(mainSash, SWT.NONE);
|
final Composite actionPane = new Composite(mainSash, SWT.NONE);
|
||||||
actionPane.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
actionPane.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||||
final GridLayout actionPaneGrid = new GridLayout();
|
final GridLayout actionPaneGrid = new GridLayout();
|
||||||
actionPane.setLayout(actionPaneGrid);
|
actionPane.setLayout(actionPaneGrid);
|
||||||
actionPane.setData(RWT.CUSTOM_VARIANT, "actionPane");
|
actionPane.setData(RWT.CUSTOM_VARIANT, "actionPane");
|
||||||
actionPane.setData(
|
actionPane.setData(
|
||||||
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
||||||
new ContentActionEventListener(event -> pageContext
|
new ContentActionEventListener(event -> pageContext
|
||||||
.composerService()
|
.composerService()
|
||||||
.compose(
|
.compose(
|
||||||
event.action.definition.targetState.actionPaneComposer(),
|
event.action.definition.targetState.actionPaneComposer(),
|
||||||
event.action.pageContext().copyOf(actionPane)),
|
event.action.pageContext().copyOf(actionPane)),
|
||||||
1));
|
1));
|
||||||
|
|
||||||
pageContext.composerService().compose(
|
pageContext.composerService().compose(
|
||||||
ActivitiesPane.class,
|
ActivitiesPane.class,
|
||||||
pageContext.copyOf(nav));
|
pageContext.copyOf(nav));
|
||||||
|
|
||||||
mainSash.setWeights(DEFAULT_SASH_WEIGHTS);
|
mainSash.setWeights(DEFAULT_SASH_WEIGHTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ContentActionEventListener implements ActionEventListener {
|
private static final class ContentActionEventListener implements ActionEventListener {
|
||||||
|
|
||||||
private final int priority;
|
private final int priority;
|
||||||
private final Consumer<ActionEvent> apply;
|
private final Consumer<ActionEvent> apply;
|
||||||
|
|
||||||
protected ContentActionEventListener(final Consumer<ActionEvent> apply, final int priority) {
|
protected ContentActionEventListener(final Consumer<ActionEvent> apply, final int priority) {
|
||||||
this.apply = apply;
|
this.apply = apply;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int priority() {
|
public int priority() {
|
||||||
return this.priority;
|
return this.priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void notify(final ActionEvent event) {
|
public void notify(final ActionEvent event) {
|
||||||
this.apply.accept(event);
|
this.apply.accept(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,8 +240,8 @@ public class QuizDiscoveryList implements TemplateComposer {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Function<QuizData, String> quizDataLmsSetupNameFunction(final ResourceService resourceService) {
|
private static Function<QuizData, String> quizDataLmsSetupNameFunction(final ResourceService resourceService) {
|
||||||
return quizzData -> resourceService.getLmsSetupNameFunction()
|
return quizData -> resourceService.getLmsSetupNameFunction()
|
||||||
.apply(String.valueOf(quizzData.lmsSetupId));
|
.apply(String.valueOf(quizData.lmsSetupId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private PageAction importQuizData(final PageAction action, final EntityTable<QuizData> table) {
|
private PageAction importQuizData(final PageAction action, final EntityTable<QuizData> table) {
|
||||||
|
|
|
@ -247,9 +247,7 @@ public class RegisterPage implements TemplateComposer {
|
||||||
gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
|
gridData = new GridData(SWT.LEFT, SWT.TOP, false, false);
|
||||||
gridData.verticalIndent = 10;
|
gridData.verticalIndent = 10;
|
||||||
cancelButton.setLayoutData(gridData);
|
cancelButton.setLayoutData(gridData);
|
||||||
cancelButton.addListener(SWT.Selection, event -> {
|
cancelButton.addListener(SWT.Selection, event -> pageContext.forwardToLoginPage());
|
||||||
pageContext.forwardToLoginPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class SebClientConfigList implements TemplateComposer {
|
public class SebClientConfigList implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION =
|
||||||
new LocTextKey("sebserver.clientconfig.list.action.no.modify.privilege");
|
new LocTextKey("sebserver.clientconfig.list.action.no.modify.privilege");
|
||||||
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
|
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.clientconfig.list.empty");
|
new LocTextKey("sebserver.clientconfig.list.empty");
|
||||||
|
@ -176,7 +176,7 @@ public class SebClientConfigList implements TemplateComposer {
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST)
|
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST)
|
||||||
.withSelect(
|
.withSelect(
|
||||||
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION),
|
||||||
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> clientConfigGrant.im() && table.hasAnyContent(), false)
|
.publishIf(() -> clientConfigGrant.im() && table.hasAnyContent(), false)
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ final class SebExamConfigImportPopup {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final boolean doImport(
|
private static boolean doImport(
|
||||||
final PageService pageService,
|
final PageService pageService,
|
||||||
final FormHandle<ConfigurationNode> formHandle,
|
final FormHandle<ConfigurationNode> formHandle,
|
||||||
final boolean newConfig) {
|
final boolean newConfig) {
|
||||||
|
@ -93,7 +93,7 @@ final class SebExamConfigImportPopup {
|
||||||
final PageContext context = formHandle.getContext();
|
final PageContext context = formHandle.getContext();
|
||||||
|
|
||||||
// Ad-hoc field validation
|
// Ad-hoc field validation
|
||||||
formHandle.process(name -> true, field -> field.resetError());
|
formHandle.process(name -> true, Form.FormFieldAccessor::resetError);
|
||||||
final String fieldValue = form.getFieldValue(Domain.CONFIGURATION_NODE.ATTR_NAME);
|
final String fieldValue = form.getFieldValue(Domain.CONFIGURATION_NODE.ATTR_NAME);
|
||||||
if (StringUtils.isBlank(fieldValue)) {
|
if (StringUtils.isBlank(fieldValue)) {
|
||||||
form.setFieldError(
|
form.setFieldError(
|
||||||
|
@ -116,7 +116,7 @@ final class SebExamConfigImportPopup {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldControl != null && fieldControl instanceof FileUploadSelection) {
|
if (fieldControl instanceof FileUploadSelection) {
|
||||||
final FileUploadSelection fileUpload = (FileUploadSelection) fieldControl;
|
final FileUploadSelection fileUpload = (FileUploadSelection) fieldControl;
|
||||||
final InputStream inputStream = fileUpload.getInputStream();
|
final InputStream inputStream = fileUpload.getInputStream();
|
||||||
if (inputStream != null) {
|
if (inputStream != null) {
|
||||||
|
@ -162,7 +162,6 @@ final class SebExamConfigImportPopup {
|
||||||
new ActionEvent(action),
|
new ActionEvent(action),
|
||||||
action.pageContext());
|
action.pageContext());
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
final Exception error = configuration.getError();
|
final Exception error = configuration.getError();
|
||||||
if (error instanceof RestCallError) {
|
if (error instanceof RestCallError) {
|
||||||
|
@ -188,12 +187,12 @@ final class SebExamConfigImportPopup {
|
||||||
SebExamConfigPropForm.FORM_TITLE,
|
SebExamConfigPropForm.FORM_TITLE,
|
||||||
configuration.getError());
|
configuration.getError());
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
formHandle.getContext().publishPageMessage(
|
formHandle.getContext().publishPageMessage(
|
||||||
new LocTextKey("sebserver.error.unexpected"),
|
new LocTextKey("sebserver.error.unexpected"),
|
||||||
new LocTextKey("Please selecte a valid SEB Exam Configuration File"));
|
new LocTextKey("Please select a valid SEB Exam Configuration File"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +270,7 @@ final class SebExamConfigImportPopup {
|
||||||
void cancelUpload() {
|
void cancelUpload() {
|
||||||
if (this.form != null) {
|
if (this.form != null) {
|
||||||
final Control fieldControl = this.form.getFieldInput(API.IMPORT_FILE_ATTR_NAME);
|
final Control fieldControl = this.form.getFieldInput(API.IMPORT_FILE_ATTR_NAME);
|
||||||
if (fieldControl != null && fieldControl instanceof FileUploadSelection) {
|
if (fieldControl instanceof FileUploadSelection) {
|
||||||
((FileUploadSelection) fieldControl).close();
|
((FileUploadSelection) fieldControl).close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class SebExamConfigList implements TemplateComposer {
|
public class SebExamConfigList implements TemplateComposer {
|
||||||
|
|
||||||
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
|
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION =
|
||||||
new LocTextKey("sebserver.examconfig.list.action.no.modify.privilege");
|
new LocTextKey("sebserver.examconfig.list.action.no.modify.privilege");
|
||||||
private static final LocTextKey EMPTY_CONFIG_LIST_TEXT_KEY =
|
private static final LocTextKey EMPTY_CONFIG_LIST_TEXT_KEY =
|
||||||
new LocTextKey("sebserver.examconfig.list.empty");
|
new LocTextKey("sebserver.examconfig.list.empty");
|
||||||
|
@ -165,7 +165,7 @@ public class SebExamConfigList implements TemplateComposer {
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST)
|
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST)
|
||||||
.withSelect(
|
.withSelect(
|
||||||
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
|
configTable.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUTION),
|
||||||
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
PageAction::applySingleSelectionAsEntityKey, EMPTY_SELECTION_TEXT_KEY)
|
||||||
.publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent(), false)
|
.publishIf(() -> examConfigGrant.im() && configTable.hasAnyContent(), false)
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,7 @@ public class SebExamConfigPropForm implements TemplateComposer {
|
||||||
.noEventPropagation()
|
.noEventPropagation()
|
||||||
.publishIf(() -> modifyGrant && isReadonly)
|
.publishIf(() -> modifyGrant && isReadonly)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
.newAction(ActionDefinition.SEA_EXAM_CONFIG_COPY_CONFIG_AS_TEMPLATE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
||||||
this.pageService,
|
this.pageService,
|
||||||
|
@ -313,7 +313,7 @@ public class SebExamConfigPropForm implements TemplateComposer {
|
||||||
.withColumn(new ColumnDefinition<>(
|
.withColumn(new ColumnDefinition<>(
|
||||||
QuizData.QUIZ_ATTR_START_TIME,
|
QuizData.QUIZ_ATTR_START_TIME,
|
||||||
new LocTextKey(
|
new LocTextKey(
|
||||||
ExamList.EXAM_LIST_COLUMN_STARTTIME,
|
ExamList.EXAM_LIST_COLUMN_START_TIME,
|
||||||
this.pageService.getI18nSupport().getUsersTimeZoneTitleSuffix()),
|
this.pageService.getI18nSupport().getUsersTimeZoneTitleSuffix()),
|
||||||
ExamConfigurationMap::getExamStartTime))
|
ExamConfigurationMap::getExamStartTime))
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ public class SebExamConfigSettingsForm implements TemplateComposer {
|
||||||
.ignoreMoveAwayFromEdit()
|
.ignoreMoveAwayFromEdit()
|
||||||
.publishIf(() -> examConfigGrant.iw() && !readonly)
|
.publishIf(() -> examConfigGrant.iw() && !readonly)
|
||||||
|
|
||||||
.newAction(ActionDefinition.SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE)
|
.newAction(ActionDefinition.SEA_EXAM_CONFIG_COPY_CONFIG_AS_TEMPLATE)
|
||||||
.withEntityKey(entityKey)
|
.withEntityKey(entityKey)
|
||||||
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
.withExec(SebExamConfigCreationPopup.configCreationFunction(
|
||||||
this.pageService,
|
this.pageService,
|
||||||
|
|
|
@ -1,41 +1,41 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content.action;
|
package ch.ethz.seb.sebserver.gui.content.action;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
|
|
||||||
public enum ActionCategory {
|
public enum ActionCategory {
|
||||||
FORM(null, 0),
|
FORM(null, 0),
|
||||||
INSTITUTION_LIST(new LocTextKey("sebserver.institution.list.actions"), 1),
|
INSTITUTION_LIST(new LocTextKey("sebserver.institution.list.actions"), 1),
|
||||||
USER_ACCOUNT_LIST(new LocTextKey("sebserver.useraccount.list.actions"), 1),
|
USER_ACCOUNT_LIST(new LocTextKey("sebserver.useraccount.list.actions"), 1),
|
||||||
LMS_SETUP_LIST(new LocTextKey("sebserver.lmssetup.list.actions"), 1),
|
LMS_SETUP_LIST(new LocTextKey("sebserver.lmssetup.list.actions"), 1),
|
||||||
QUIZ_LIST(new LocTextKey("sebserver.quizdiscovery.list.actions"), 1),
|
QUIZ_LIST(new LocTextKey("sebserver.quizdiscovery.list.actions"), 1),
|
||||||
EXAM_LIST(new LocTextKey("sebserver.exam.list.actions"), 1),
|
EXAM_LIST(new LocTextKey("sebserver.exam.list.actions"), 1),
|
||||||
EXAM_CONFIG_MAPPING_LIST(new LocTextKey("sebserver.exam.configuration.list.actions"), 1),
|
EXAM_CONFIG_MAPPING_LIST(new LocTextKey("sebserver.exam.configuration.list.actions"), 1),
|
||||||
INDICATOR_LIST(new LocTextKey("sebserver.exam.indicator.list.actions"), 2),
|
INDICATOR_LIST(new LocTextKey("sebserver.exam.indicator.list.actions"), 2),
|
||||||
SEB_CLIENT_CONFIG_LIST(new LocTextKey("sebserver.clientconfig.list.actions"), 1),
|
SEB_CLIENT_CONFIG_LIST(new LocTextKey("sebserver.clientconfig.list.actions"), 1),
|
||||||
SEB_EXAM_CONFIG_LIST(new LocTextKey("sebserver.examconfig.list.actions"), 1),
|
SEB_EXAM_CONFIG_LIST(new LocTextKey("sebserver.examconfig.list.actions"), 1),
|
||||||
SEB_CONFIG_TEMPLATE_LIST(new LocTextKey("sebserver.configtemplate.list.actions"), 1),
|
SEB_CONFIG_TEMPLATE_LIST(new LocTextKey("sebserver.configtemplate.list.actions"), 1),
|
||||||
SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST(new LocTextKey("sebserver.configtemplate.attr.list.actions"), 1),
|
SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST(new LocTextKey("sebserver.configtemplate.attr.list.actions"), 1),
|
||||||
RUNNING_EXAM_LIST(new LocTextKey("sebserver.monitoring.exam.list.actions"), 1),
|
RUNNING_EXAM_LIST(new LocTextKey("sebserver.monitoring.exam.list.actions"), 1),
|
||||||
CLIENT_EVENT_LIST(new LocTextKey("sebserver.monitoring.exam.connection.list.actions"), 1),
|
CLIENT_EVENT_LIST(new LocTextKey("sebserver.monitoring.exam.connection.list.actions"), 1),
|
||||||
LOGS_USER_ACTIVITY_LIST(new LocTextKey("sebserver.userlogs.list.actions"), 1),
|
LOGS_USER_ACTIVITY_LIST(new LocTextKey("sebserver.userlogs.list.actions"), 1),
|
||||||
LOGS_SEB_CLIENT_LIST(new LocTextKey("sebserver.userlogs.list.actions"), 1),
|
LOGS_SEB_CLIENT_LIST(new LocTextKey("sebserver.userlogs.list.actions"), 1),
|
||||||
VARIA(new LocTextKey("sebserver.overall.action.category.varia"), 0),
|
VARIA(new LocTextKey("sebserver.overall.action.category.varia"), 0),
|
||||||
FILTER(new LocTextKey("sebserver.overall.action.category.filter"), 50);
|
FILTER(new LocTextKey("sebserver.overall.action.category.filter"), 50);
|
||||||
|
|
||||||
public final LocTextKey title;
|
public final LocTextKey title;
|
||||||
public final int slotPosition;
|
public final int slotPosition;
|
||||||
|
|
||||||
private ActionCategory(final LocTextKey title, final int slotPosition) {
|
ActionCategory(final LocTextKey title, final int slotPosition) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.slotPosition = slotPosition;
|
this.slotPosition = slotPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -467,7 +467,7 @@ public enum ActionDefinition {
|
||||||
new LocTextKey("sebserver.examconfig.action.copy"),
|
new LocTextKey("sebserver.examconfig.action.copy"),
|
||||||
ImageIcon.COPY,
|
ImageIcon.COPY,
|
||||||
ActionCategory.FORM),
|
ActionCategory.FORM),
|
||||||
SEB_EXAM_CONFIG_COPY_CONFIG_AS_TEMPALTE(
|
SEA_EXAM_CONFIG_COPY_CONFIG_AS_TEMPLATE(
|
||||||
new LocTextKey("sebserver.examconfig.action.copy-as-template"),
|
new LocTextKey("sebserver.examconfig.action.copy-as-template"),
|
||||||
ImageIcon.TEMPLATE,
|
ImageIcon.TEMPLATE,
|
||||||
ActionCategory.FORM),
|
ActionCategory.FORM),
|
||||||
|
|
|
@ -8,10 +8,17 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content.action;
|
package ch.ethz.seb.sebserver.gui.content.action;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import java.util.HashMap;
|
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
||||||
import java.util.Map;
|
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.page.event.ActionActivationEventListener;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.rap.rwt.template.ImageCell;
|
import org.eclipse.rap.rwt.template.ImageCell;
|
||||||
|
@ -31,19 +38,9 @@ import org.eclipse.swt.widgets.TreeItem;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import java.util.ArrayList;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
|
import java.util.HashMap;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import java.util.Map;
|
||||||
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.page.event.ActionActivationEvent;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionActivationEventListener;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEventListener;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,42 +1,42 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.content.activity;
|
package ch.ethz.seb.sebserver.gui.content.activity;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.Activity;
|
import ch.ethz.seb.sebserver.gui.service.page.Activity;
|
||||||
|
|
||||||
public enum ActivityDefinition implements Activity {
|
public enum ActivityDefinition implements Activity {
|
||||||
SEB_ADMINISTRATION(new LocTextKey("sebserver.overall.activity.title.serveradmin")),
|
SEB_ADMINISTRATION(new LocTextKey("sebserver.overall.activity.title.serveradmin")),
|
||||||
INSTITUTION(new LocTextKey("sebserver.institution.action.list")),
|
INSTITUTION(new LocTextKey("sebserver.institution.action.list")),
|
||||||
USER_ACCOUNT(new LocTextKey("sebserver.useraccount.action.list")),
|
USER_ACCOUNT(new LocTextKey("sebserver.useraccount.action.list")),
|
||||||
USER_ACTIVITY_LOGS(new LocTextKey("sebserver.logs.activity.userlogs")),
|
USER_ACTIVITY_LOGS(new LocTextKey("sebserver.logs.activity.userlogs")),
|
||||||
LMS_SETUP(new LocTextKey("sebserver.lmssetup.action.list")),
|
LMS_SETUP(new LocTextKey("sebserver.lmssetup.action.list")),
|
||||||
QUIZ_DISCOVERY(new LocTextKey("sebserver.quizdiscovery.action.list")),
|
QUIZ_DISCOVERY(new LocTextKey("sebserver.quizdiscovery.action.list")),
|
||||||
EXAM_ADMINISTRATION(new LocTextKey("sebserver.overall.activity.title.examadmin")),
|
EXAM_ADMINISTRATION(new LocTextKey("sebserver.overall.activity.title.examadmin")),
|
||||||
EXAM(new LocTextKey("sebserver.exam.action.list")),
|
EXAM(new LocTextKey("sebserver.exam.action.list")),
|
||||||
SEB_CONFIGURATION(new LocTextKey("sebserver.overall.activity.title.sebconfig")),
|
SEB_CONFIGURATION(new LocTextKey("sebserver.overall.activity.title.sebconfig")),
|
||||||
SEB_CLIENT_CONFIG(new LocTextKey("sebserver.clientconfig.action.list")),
|
SEB_CLIENT_CONFIG(new LocTextKey("sebserver.clientconfig.action.list")),
|
||||||
SEB_EXAM_CONFIG(new LocTextKey("sebserver.examconfig.action.list")),
|
SEB_EXAM_CONFIG(new LocTextKey("sebserver.examconfig.action.list")),
|
||||||
SEB_EXAM_CONFIG_TEMPLATE(new LocTextKey("sebserver.configtemplate.action.list")),
|
SEB_EXAM_CONFIG_TEMPLATE(new LocTextKey("sebserver.configtemplate.action.list")),
|
||||||
MONITORING(new LocTextKey("sebserver.overall.activity.title.monitoring")),
|
MONITORING(new LocTextKey("sebserver.overall.activity.title.monitoring")),
|
||||||
MONITORING_EXAMS(new LocTextKey("sebserver.monitoring.action.list")),
|
MONITORING_EXAMS(new LocTextKey("sebserver.monitoring.action.list")),
|
||||||
SEB_CLIENT_LOGS(new LocTextKey("sebserver.logs.activity.seblogs"));
|
SEB_CLIENT_LOGS(new LocTextKey("sebserver.logs.activity.seblogs"));
|
||||||
|
|
||||||
public final LocTextKey displayName;
|
public final LocTextKey displayName;
|
||||||
|
|
||||||
private ActivityDefinition(final LocTextKey displayName) {
|
ActivityDefinition(final LocTextKey displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LocTextKey displayName() {
|
public LocTextKey displayName() {
|
||||||
return this.displayName;
|
return this.displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ public enum PageStateDefinitionImpl implements PageStateDefinition {
|
||||||
public final Class<? extends TemplateComposer> actionPaneComposer;
|
public final Class<? extends TemplateComposer> actionPaneComposer;
|
||||||
public final Activity activityAnchor;
|
public final Activity activityAnchor;
|
||||||
|
|
||||||
private PageStateDefinitionImpl(
|
PageStateDefinitionImpl(
|
||||||
final Type type,
|
final Type type,
|
||||||
final Class<? extends TemplateComposer> contentPaneComposer,
|
final Class<? extends TemplateComposer> contentPaneComposer,
|
||||||
final Activity activityAnchor) {
|
final Activity activityAnchor) {
|
||||||
|
@ -102,7 +102,7 @@ public enum PageStateDefinitionImpl implements PageStateDefinition {
|
||||||
this(type, contentPaneComposer, ActionPane.class, activityAnchor);
|
this(type, contentPaneComposer, ActionPane.class, activityAnchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PageStateDefinitionImpl(
|
PageStateDefinitionImpl(
|
||||||
final Type type,
|
final Type type,
|
||||||
final Class<? extends TemplateComposer> contentPaneComposer,
|
final Class<? extends TemplateComposer> contentPaneComposer,
|
||||||
final Class<? extends TemplateComposer> actionPaneComposer,
|
final Class<? extends TemplateComposer> actionPaneComposer,
|
||||||
|
|
|
@ -44,7 +44,6 @@ public class ThresholdListBuilder extends FieldBuilder<Collection<Threshold>> {
|
||||||
final Control titleLabel = createTitleLabel(builder.formParent, builder, this);
|
final Control titleLabel = createTitleLabel(builder.formParent, builder, this);
|
||||||
if (builder.readonly || this.readonly) {
|
if (builder.readonly || this.readonly) {
|
||||||
// No read-only view needed for this so far?
|
// No read-only view needed for this so far?
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput);
|
||||||
|
|
|
@ -1,109 +1,109 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig;
|
package ch.ethz.seb.sebserver.gui.service.examconfig;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
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.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.AttributeMapping;
|
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.examconfig.impl.ViewContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
public interface ExamConfigurationService {
|
public interface ExamConfigurationService {
|
||||||
|
|
||||||
public static final String ATTRIBUTE_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.label.";
|
String ATTRIBUTE_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.label.";
|
||||||
public static final String GROUP_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.group.";
|
String GROUP_LABEL_LOC_TEXT_PREFIX = "sebserver.examconfig.props.group.";
|
||||||
public static final String TOOL_TIP_SUFFIX = ".tooltip";
|
String TOOL_TIP_SUFFIX = ".tooltip";
|
||||||
public static final String TABLE_ROW_TITLE_SUFFIX = ".row.title";
|
String TABLE_ROW_TITLE_SUFFIX = ".row.title";
|
||||||
|
|
||||||
WidgetFactory getWidgetFactory();
|
WidgetFactory getWidgetFactory();
|
||||||
|
|
||||||
InputFieldBuilder getInputFieldBuilder(
|
InputFieldBuilder getInputFieldBuilder(
|
||||||
ConfigurationAttribute attribute,
|
ConfigurationAttribute attribute,
|
||||||
Orientation orientation);
|
Orientation orientation);
|
||||||
|
|
||||||
Result<AttributeMapping> getAttributes(Long templateId);
|
Result<AttributeMapping> getAttributes(Long templateId);
|
||||||
|
|
||||||
Result<AttributeMapping> getAttributes(
|
Result<AttributeMapping> getAttributes(
|
||||||
final TemplateAttribute attribute,
|
final TemplateAttribute attribute,
|
||||||
final Orientation defaultOrientation);
|
final Orientation defaultOrientation);
|
||||||
|
|
||||||
List<View> getViews(AttributeMapping allAttributes);
|
List<View> getViews(AttributeMapping allAttributes);
|
||||||
|
|
||||||
ViewContext createViewContext(
|
ViewContext createViewContext(
|
||||||
PageContext pageContext,
|
PageContext pageContext,
|
||||||
Configuration configuration,
|
Configuration configuration,
|
||||||
View view,
|
View view,
|
||||||
AttributeMapping attributeMapping,
|
AttributeMapping attributeMapping,
|
||||||
int rows,
|
int rows,
|
||||||
boolean readonly);
|
boolean readonly);
|
||||||
|
|
||||||
Composite createViewGrid(
|
Composite createViewGrid(
|
||||||
Composite parent,
|
Composite parent,
|
||||||
ViewContext viewContext);
|
ViewContext viewContext);
|
||||||
|
|
||||||
void initInputFieldValues(
|
void initInputFieldValues(
|
||||||
Long configurationId,
|
Long configurationId,
|
||||||
Collection<ViewContext> viewContexts);
|
Collection<ViewContext> viewContexts);
|
||||||
|
|
||||||
PageAction resetToDefaults(PageAction action);
|
PageAction resetToDefaults(PageAction action);
|
||||||
|
|
||||||
PageAction removeFromView(PageAction action);
|
PageAction removeFromView(PageAction action);
|
||||||
|
|
||||||
PageAction attachToDefaultView(final PageAction action);
|
PageAction attachToDefaultView(final PageAction action);
|
||||||
|
|
||||||
static String attributeNameKey(final ConfigurationAttribute attribute) {
|
static String attributeNameKey(final ConfigurationAttribute attribute) {
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name;
|
return ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LocTextKey attributeNameLocKey(final ConfigurationAttribute attribute) {
|
static LocTextKey attributeNameLocKey(final ConfigurationAttribute attribute) {
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LocTextKey(attributeNameKey(attribute));
|
return new LocTextKey(attributeNameKey(attribute));
|
||||||
}
|
}
|
||||||
|
|
||||||
static LocTextKey getToolTipKey(
|
static LocTextKey getToolTipKey(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final I18nSupport i18nSupport) {
|
final I18nSupport i18nSupport) {
|
||||||
|
|
||||||
final String attributeNameKey = ExamConfigurationService.attributeNameKey(attribute) + TOOL_TIP_SUFFIX;
|
final String attributeNameKey = ExamConfigurationService.attributeNameKey(attribute) + TOOL_TIP_SUFFIX;
|
||||||
if (StringUtils.isBlank(i18nSupport.getText(attributeNameKey, ""))) {
|
if (StringUtils.isBlank(i18nSupport.getText(attributeNameKey, ""))) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return new LocTextKey(attributeNameKey);
|
return new LocTextKey(attributeNameKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LocTextKey getTablePopupTitleKey(
|
static LocTextKey getTablePopupTitleKey(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final I18nSupport i18nSupport) {
|
final I18nSupport i18nSupport) {
|
||||||
|
|
||||||
return new LocTextKey(ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + TABLE_ROW_TITLE_SUFFIX);
|
return new LocTextKey(ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + TABLE_ROW_TITLE_SUFFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,338 +1,336 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.eclipse.swt.widgets.Table;
|
import org.eclipse.swt.widgets.Table;
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
||||||
|
|
||||||
public abstract class AbstractTableFieldBuilder implements InputFieldBuilder {
|
public abstract class AbstractTableFieldBuilder implements InputFieldBuilder {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AbstractTableFieldBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(AbstractTableFieldBuilder.class);
|
||||||
|
|
||||||
private static final int ROW_HEIGHT = 20;
|
private static final int ROW_HEIGHT = 20;
|
||||||
private static final int NAV_HEIGHT = 40;
|
private static final int NAV_HEIGHT = 40;
|
||||||
private static final int TABLE_WIDTH_SPACE = 50;
|
private static final int TABLE_WIDTH_SPACE = 50;
|
||||||
|
|
||||||
protected final RestService restService;
|
protected final RestService restService;
|
||||||
protected final WidgetFactory widgetFactory;
|
protected final WidgetFactory widgetFactory;
|
||||||
protected InputFieldBuilderSupplier inputFieldBuilderSupplier;
|
protected InputFieldBuilderSupplier inputFieldBuilderSupplier;
|
||||||
|
|
||||||
protected AbstractTableFieldBuilder(
|
protected AbstractTableFieldBuilder(
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final WidgetFactory widgetFactory) {
|
final WidgetFactory widgetFactory) {
|
||||||
|
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
this.widgetFactory = widgetFactory;
|
this.widgetFactory = widgetFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(final InputFieldBuilderSupplier inputFieldBuilderSupplier) {
|
public void init(final InputFieldBuilderSupplier inputFieldBuilderSupplier) {
|
||||||
this.inputFieldBuilderSupplier = inputFieldBuilderSupplier;
|
this.inputFieldBuilderSupplier = inputFieldBuilderSupplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Table createTable(final Composite parent, final TableContext tableContext) {
|
protected Table createTable(final Composite parent, final TableContext tableContext) {
|
||||||
final Table table = new Table(parent, SWT.NONE | SWT.V_SCROLL);
|
final Table table = new Table(parent, SWT.NONE | SWT.V_SCROLL);
|
||||||
table.setLayout(new GridLayout());
|
table.setLayout(new GridLayout());
|
||||||
final GridData gridData = new GridData(
|
final GridData gridData = new GridData(
|
||||||
SWT.FILL, SWT.FILL,
|
SWT.FILL, SWT.FILL,
|
||||||
true, false,
|
true, false,
|
||||||
tableContext.orientation.width(),
|
tableContext.orientation.width(),
|
||||||
tableContext.orientation.height());
|
tableContext.orientation.height());
|
||||||
|
|
||||||
gridData.heightHint = tableContext.orientation.height() * ROW_HEIGHT + NAV_HEIGHT;
|
gridData.heightHint = tableContext.orientation.height() * ROW_HEIGHT + NAV_HEIGHT;
|
||||||
table.setLayoutData(gridData);
|
table.setLayoutData(gridData);
|
||||||
table.setHeaderVisible(true);
|
table.setHeaderVisible(true);
|
||||||
table.addListener(SWT.Resize, event -> adaptColumnWidth(table, tableContext));
|
table.addListener(SWT.Resize, event -> adaptColumnWidth(table, tableContext));
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TableContext createTableContext(final ConfigurationAttribute attribute, final ViewContext viewContext) {
|
protected TableContext createTableContext(final ConfigurationAttribute attribute, final ViewContext viewContext) {
|
||||||
final TableContext tableContext = new TableContext(
|
return new TableContext(
|
||||||
this.inputFieldBuilderSupplier,
|
this.inputFieldBuilderSupplier,
|
||||||
this.widgetFactory,
|
this.widgetFactory,
|
||||||
attribute,
|
attribute,
|
||||||
viewContext);
|
viewContext);
|
||||||
return tableContext;
|
}
|
||||||
}
|
|
||||||
|
protected void setSelectionListener(final Table table, final AbstractTableInputField tableField) {
|
||||||
protected void setSelectionListener(final Table table, final AbstractTableInputField tableField) {
|
table.addListener(SWT.MouseDoubleClick, event -> {
|
||||||
table.addListener(SWT.MouseDoubleClick, event -> {
|
final int selectionIndex = table.getSelectionIndex();
|
||||||
final int selectionIndex = table.getSelectionIndex();
|
if (selectionIndex >= 0) {
|
||||||
if (selectionIndex >= 0) {
|
tableField.openForm(selectionIndex);
|
||||||
tableField.openForm(selectionIndex);
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
protected void adaptColumnWidth(
|
||||||
protected void adaptColumnWidth(
|
final Table table,
|
||||||
final Table table,
|
final TableContext tableContext) {
|
||||||
final TableContext tableContext) {
|
|
||||||
|
try {
|
||||||
try {
|
final boolean readonly = tableContext.getViewContext().readonly;
|
||||||
final boolean readonly = tableContext.getViewContext().readonly;
|
final int currentTableWidth = table.getClientArea().width - TABLE_WIDTH_SPACE;
|
||||||
final int currentTableWidth = table.getClientArea().width - TABLE_WIDTH_SPACE;
|
final TableColumn[] columns = table.getColumns();
|
||||||
final TableColumn[] columns = table.getColumns();
|
final List<Orientation> orientations = tableContext
|
||||||
final List<Orientation> orientations = tableContext
|
.getColumnAttributes()
|
||||||
.getColumnAttributes()
|
.stream()
|
||||||
.stream()
|
.map(attr -> tableContext.getOrientation(attr.id))
|
||||||
.map(attr -> tableContext.getOrientation(attr.id))
|
.collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
final Integer div = orientations
|
||||||
final Integer div = orientations
|
.stream()
|
||||||
.stream()
|
.map(o -> o.width)
|
||||||
.map(o -> o.width)
|
.reduce(0, Integer::sum);
|
||||||
.reduce(0, (acc, val) -> acc + val);
|
final int widthUnit = currentTableWidth / div;
|
||||||
final int widthUnit = currentTableWidth / div;
|
for (int i = 0; i < columns.length - ((readonly) ? 0 : 2); i++) {
|
||||||
for (int i = 0; i < columns.length - ((readonly) ? 0 : 2); i++) {
|
columns[i].setWidth(widthUnit * orientations.get(i).width);
|
||||||
columns[i].setWidth(widthUnit * orientations.get(i).width);
|
}
|
||||||
}
|
} catch (final Exception e) {
|
||||||
} catch (final Exception e) {
|
log.warn("Failed to adaptColumnWidth: ", e);
|
||||||
log.warn("Failed to adaptColumnWidth: ", e);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
protected static void setValueToCell(
|
||||||
protected static void setValueToCell(
|
final TableContext tableContext,
|
||||||
final TableContext tableContext,
|
final TableItem item,
|
||||||
final TableItem item,
|
final int cellIndex,
|
||||||
final int cellIndex,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationAttribute attribute,
|
final TableValue tableValue) {
|
||||||
final TableValue tableValue) {
|
|
||||||
|
switch (attribute.type) {
|
||||||
switch (attribute.type) {
|
case CHECKBOX: {
|
||||||
case CHECKBOX: {
|
item.setImage(
|
||||||
item.setImage(
|
cellIndex,
|
||||||
cellIndex,
|
(BooleanUtils.toBoolean((tableValue != null) ? tableValue.value : null))
|
||||||
(BooleanUtils.toBoolean((tableValue != null) ? tableValue.value : null))
|
? ImageIcon.YES.getImage(item.getDisplay())
|
||||||
? ImageIcon.YES.getImage(item.getDisplay())
|
: ImageIcon.NO.getImage(item.getDisplay()));
|
||||||
: ImageIcon.NO.getImage(item.getDisplay()));
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case SINGLE_SELECTION: {
|
||||||
case SINGLE_SELECTION: {
|
final String key = ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
final String key = ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
attribute.getName() + "." +
|
||||||
attribute.getName() + "." +
|
tableValue.value;
|
||||||
tableValue.value;
|
item.setText(
|
||||||
item.setText(
|
cellIndex,
|
||||||
cellIndex,
|
tableContext.i18nSupport().getText(key, getValue(attribute, tableValue)));
|
||||||
tableContext.i18nSupport().getText(key, getValue(attribute, tableValue)));
|
break;
|
||||||
break;
|
}
|
||||||
}
|
default: {
|
||||||
default: {
|
item.setText(cellIndex, getValue(attribute, tableValue));
|
||||||
item.setText(cellIndex, getValue(attribute, tableValue));
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private static String getValue(
|
||||||
private static String getValue(
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationAttribute attribute,
|
final TableValue tableValue) {
|
||||||
final TableValue tableValue) {
|
|
||||||
|
if (tableValue == null) {
|
||||||
if (tableValue == null) {
|
if (StringUtils.isBlank(attribute.defaultValue)) {
|
||||||
if (StringUtils.isBlank(attribute.defaultValue)) {
|
return Constants.EMPTY_NOTE;
|
||||||
return Constants.EMPTY_NOTE;
|
} else {
|
||||||
} else {
|
return attribute.defaultValue;
|
||||||
return attribute.defaultValue;
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
if (StringUtils.isBlank(tableValue.value)) {
|
||||||
if (StringUtils.isBlank(tableValue.value)) {
|
return Constants.EMPTY_NOTE;
|
||||||
return Constants.EMPTY_NOTE;
|
} else {
|
||||||
} else {
|
return tableValue.value;
|
||||||
return tableValue.value;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
static abstract class AbstractTableInputField extends AbstractInputField<Table> {
|
||||||
static abstract class AbstractTableInputField extends AbstractInputField<Table> {
|
|
||||||
|
protected final TableContext tableContext;
|
||||||
protected final TableContext tableContext;
|
|
||||||
|
protected AbstractTableInputField(
|
||||||
protected AbstractTableInputField(
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationAttribute attribute,
|
final Orientation orientation,
|
||||||
final Orientation orientation,
|
final Table control,
|
||||||
final Table control,
|
final Label errorLabel,
|
||||||
final Label errorLabel,
|
final TableContext tableContext) {
|
||||||
final TableContext tableContext) {
|
|
||||||
|
super(attribute, orientation, control, errorLabel);
|
||||||
super(attribute, orientation, control, errorLabel);
|
this.tableContext = tableContext;
|
||||||
this.tableContext = tableContext;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public ConfigurationValue initValue(final Collection<ConfigurationValue> values) {
|
||||||
public ConfigurationValue initValue(final Collection<ConfigurationValue> values) {
|
clearTable();
|
||||||
clearTable();
|
// get all child values as TableValues
|
||||||
// get all child values as TableValues
|
final List<TableValue> tableValues = getChildValues(
|
||||||
final List<TableValue> tableValues = getChildValues(
|
this.tableContext,
|
||||||
this.tableContext,
|
this.attribute,
|
||||||
this.attribute,
|
values);
|
||||||
values);
|
|
||||||
|
initValue(tableValues);
|
||||||
initValue(tableValues);
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
abstract void initValue(final List<TableValue> tableValues);
|
||||||
abstract void initValue(final List<TableValue> tableValues);
|
|
||||||
|
abstract void openForm(final int selectionIndex);
|
||||||
abstract void openForm(final int selectionIndex);
|
|
||||||
|
abstract void applyTableRowValues(final int index);
|
||||||
abstract void applyTableRowValues(final int index);
|
|
||||||
|
protected List<TableValue> getChildValues(
|
||||||
protected List<TableValue> getChildValues(
|
final TableContext tableContext,
|
||||||
final TableContext tableContext,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationAttribute attribute,
|
final Collection<ConfigurationValue> values) {
|
||||||
final Collection<ConfigurationValue> values) {
|
|
||||||
|
return values.stream()
|
||||||
return values.stream()
|
.filter(v -> isChildValue(tableContext, attribute, v))
|
||||||
.filter(v -> isChildValue(tableContext, attribute, v))
|
.map(TableValue::of)
|
||||||
.map(TableValue::of)
|
.collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
}
|
||||||
}
|
|
||||||
|
protected boolean isChildValue(
|
||||||
protected boolean isChildValue(
|
final TableContext tableContext,
|
||||||
final TableContext tableContext,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationValue value) {
|
||||||
final ConfigurationValue value) {
|
|
||||||
|
if (!tableContext.getViewContext().attributeMapping.attributeIdMapping
|
||||||
if (!tableContext.getViewContext().attributeMapping.attributeIdMapping
|
.containsKey(value.attributeId)) {
|
||||||
.containsKey(value.attributeId)) {
|
|
||||||
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
ConfigurationAttribute attr = tableContext.getAttribute(value.attributeId);
|
||||||
ConfigurationAttribute attr = tableContext.getAttribute(value.attributeId);
|
if (attr == null) {
|
||||||
if (attr == null) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
while (attr.parentId != null) {
|
||||||
while (attr.parentId != null) {
|
if (attribute.id.equals(attr.parentId)) {
|
||||||
if (attribute.id.equals(attr.parentId)) {
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
attr = tableContext.getAttribute(attr.parentId);
|
||||||
attr = tableContext.getAttribute(attr.parentId);
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
protected Map<Integer, Map<Long, TableValue>> createRowIndexMap(final List<TableValue> tableValues) {
|
||||||
protected Map<Integer, Map<Long, TableValue>> createRowIndexMap(final List<TableValue> tableValues) {
|
final Map<Integer, Map<Long, TableValue>> indexMapping = new HashMap<>();
|
||||||
final Map<Integer, Map<Long, TableValue>> indexMapping = new HashMap<>();
|
for (final TableValue tableValue : tableValues) {
|
||||||
for (final TableValue tableValue : tableValues) {
|
final Map<Long, TableValue> rowValues = indexMapping.computeIfAbsent(
|
||||||
final Map<Long, TableValue> rowValues = indexMapping.computeIfAbsent(
|
tableValue.listIndex,
|
||||||
tableValue.listIndex,
|
key -> new HashMap<>());
|
||||||
key -> new HashMap<>());
|
rowValues.put(tableValue.attributeId, tableValue);
|
||||||
rowValues.put(tableValue.attributeId, tableValue);
|
}
|
||||||
}
|
return indexMapping;
|
||||||
return indexMapping;
|
}
|
||||||
}
|
|
||||||
|
protected void valuesFromIndexMap(
|
||||||
protected void valuesFromIndexMap(
|
final List<Map<Long, TableValue>> values,
|
||||||
final List<Map<Long, TableValue>> values,
|
final Map<Integer, Map<Long, TableValue>> indexMapping) {
|
||||||
final Map<Integer, Map<Long, TableValue>> indexMapping) {
|
|
||||||
|
values.clear();
|
||||||
values.clear();
|
final List<Integer> rows = new ArrayList<>(indexMapping.keySet());
|
||||||
final List<Integer> rows = new ArrayList<>(indexMapping.keySet());
|
rows.sort(Integer::compareTo);
|
||||||
rows.sort((i1, i2) -> i1.compareTo(i2));
|
rows
|
||||||
rows
|
.forEach(i -> {
|
||||||
.stream()
|
final Map<Long, TableValue> rowValues = indexMapping.get(i);
|
||||||
.forEach(i -> {
|
values.add(rowValues);
|
||||||
final Map<Long, TableValue> rowValues = indexMapping.get(i);
|
});
|
||||||
values.add(rowValues);
|
}
|
||||||
});
|
|
||||||
}
|
protected void applyFormValues(
|
||||||
|
final List<Map<Long, TableValue>> values,
|
||||||
protected void applyFormValues(
|
final Map<Long, TableValue> rowValues,
|
||||||
final List<Map<Long, TableValue>> values,
|
final int index) {
|
||||||
final Map<Long, TableValue> rowValues,
|
|
||||||
final int index) {
|
if (!values.isEmpty()) {
|
||||||
|
values.remove(index);
|
||||||
if (!values.isEmpty()) {
|
values.add(index, rowValues);
|
||||||
values.remove(index);
|
applyTableRowValues(index);
|
||||||
values.add(index, rowValues);
|
}
|
||||||
applyTableRowValues(index);
|
|
||||||
}
|
// send values to web-service
|
||||||
|
this.tableContext.getValueChangeListener()
|
||||||
// send values to web-service
|
.tableChanged(extractTableValue(values));
|
||||||
this.tableContext.getValueChangeListener()
|
}
|
||||||
.tableChanged(extractTableValue(values));
|
|
||||||
}
|
protected ConfigurationTableValues extractTableValue(final List<Map<Long, TableValue>> values) {
|
||||||
|
final List<TableValue> collect = values
|
||||||
protected ConfigurationTableValues extractTableValue(final List<Map<Long, TableValue>> values) {
|
.stream()
|
||||||
final List<TableValue> collect = values
|
.flatMap(map -> map.values().stream())
|
||||||
.stream()
|
.collect(Collectors.toList());
|
||||||
.flatMap(map -> map.values().stream())
|
|
||||||
.collect(Collectors.toList());
|
return new ConfigurationTableValues(
|
||||||
|
this.tableContext.getInstitutionId(),
|
||||||
return new ConfigurationTableValues(
|
this.tableContext.getConfigurationId(),
|
||||||
this.tableContext.getInstitutionId(),
|
this.attribute.id,
|
||||||
this.tableContext.getConfigurationId(),
|
collect);
|
||||||
this.attribute.id,
|
}
|
||||||
collect);
|
|
||||||
}
|
@Override
|
||||||
|
public void setDefaultValue() {
|
||||||
@Override
|
// NOTE this just empty the list for now
|
||||||
public void setDefaultValue() {
|
// TODO do we need default values for lists?
|
||||||
// NOTE this just empty the list for now
|
clearTable();
|
||||||
// TODO do we need default values for lists?
|
final List<TableValue> values = new ArrayList<>();
|
||||||
clearTable();
|
this.tableContext.getValueChangeListener().tableChanged(
|
||||||
final List<TableValue> values = new ArrayList<>();
|
new ConfigurationTableValues(
|
||||||
this.tableContext.getValueChangeListener().tableChanged(
|
this.tableContext.getInstitutionId(),
|
||||||
new ConfigurationTableValues(
|
this.tableContext.getConfigurationId(),
|
||||||
this.tableContext.getInstitutionId(),
|
this.attribute.id,
|
||||||
this.tableContext.getConfigurationId(),
|
values));
|
||||||
this.attribute.id,
|
}
|
||||||
values));
|
|
||||||
}
|
void clearTable() {
|
||||||
|
this.control.setSelection(-1);
|
||||||
void clearTable() {
|
if (this.control.getItemCount() > 0) {
|
||||||
this.control.setSelection(-1);
|
for (final TableItem item : this.control.getItems()) {
|
||||||
if (this.control.getItemCount() > 0) {
|
item.dispose();
|
||||||
for (final TableItem item : this.control.getItems()) {
|
}
|
||||||
item.dispose();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
@Override
|
||||||
|
protected void setValueToControl(final String value) {
|
||||||
@Override
|
throw new UnsupportedOperationException();
|
||||||
protected void setValueToControl(final String value) {
|
}
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
@Override
|
||||||
|
public String getValue() {
|
||||||
@Override
|
throw new UnsupportedOperationException();
|
||||||
public String getValue() {
|
}
|
||||||
throw new UnsupportedOperationException();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,225 +1,225 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Group;
|
import org.eclipse.swt.widgets.Group;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
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.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
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.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
interface CellFieldBuilderAdapter {
|
interface CellFieldBuilderAdapter {
|
||||||
|
|
||||||
static CellFieldBuilderAdapter DUMMY_BUILDER_ADAPTER = new CellFieldBuilderAdapter() {
|
CellFieldBuilderAdapter DUMMY_BUILDER_ADAPTER = new CellFieldBuilderAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void createCell(final ViewGridBuilder builder) {
|
public void createCell(final ViewGridBuilder builder) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[DUMMY]";
|
return "[DUMMY]";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void createCell(ViewGridBuilder builder);
|
void createCell(ViewGridBuilder builder);
|
||||||
|
|
||||||
default void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
default void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static CellFieldBuilderAdapter fieldBuilderAdapter(
|
static CellFieldBuilderAdapter fieldBuilderAdapter(
|
||||||
final InputFieldBuilder inputFieldBuilder,
|
final InputFieldBuilder inputFieldBuilder,
|
||||||
final ConfigurationAttribute attribute) {
|
final ConfigurationAttribute attribute) {
|
||||||
|
|
||||||
return new CellFieldBuilderAdapter() {
|
return new CellFieldBuilderAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void createCell(final ViewGridBuilder builder) {
|
public void createCell(final ViewGridBuilder builder) {
|
||||||
|
|
||||||
final InputField inputField = inputFieldBuilder.createInputField(
|
final InputField inputField = inputFieldBuilder.createInputField(
|
||||||
builder.parent,
|
builder.parent,
|
||||||
attribute,
|
attribute,
|
||||||
builder.viewContext);
|
builder.viewContext);
|
||||||
|
|
||||||
if (inputField != null) {
|
if (inputField != null) {
|
||||||
builder.viewContext.registerInputField(inputField);
|
builder.viewContext.registerInputField(inputField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[FIELD]";
|
return "[FIELD]";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static CellFieldBuilderAdapter labelBuilder(
|
static CellFieldBuilderAdapter labelBuilder(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
return new CellFieldBuilderAdapter() {
|
return new CellFieldBuilderAdapter() {
|
||||||
|
|
||||||
private int span = 1;
|
private int span = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createCell(final ViewGridBuilder builder) {
|
public void createCell(final ViewGridBuilder builder) {
|
||||||
|
|
||||||
final WidgetFactory widgetFactory = builder.examConfigurationService.getWidgetFactory();
|
final WidgetFactory widgetFactory = builder.examConfigurationService.getWidgetFactory();
|
||||||
final Label label = widgetFactory.labelLocalized(
|
final Label label = widgetFactory.labelLocalized(
|
||||||
builder.parent,
|
builder.parent,
|
||||||
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name,
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name,
|
||||||
attribute.name));
|
attribute.name));
|
||||||
|
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
switch (orientation.title) {
|
switch (orientation.title) {
|
||||||
case LEFT:
|
case LEFT:
|
||||||
case RIGHT: {
|
case RIGHT: {
|
||||||
label.setAlignment(SWT.LEFT);
|
label.setAlignment(SWT.LEFT);
|
||||||
gridData.verticalIndent = 5;
|
gridData.verticalIndent = 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RIGHT_SPAN:
|
case RIGHT_SPAN:
|
||||||
case LEFT_SPAN: {
|
case LEFT_SPAN: {
|
||||||
label.setAlignment(SWT.LEFT);
|
label.setAlignment(SWT.LEFT);
|
||||||
gridData.horizontalSpan = (span > 1) ? span : orientation.width;
|
gridData.horizontalSpan = (span > 1) ? span : orientation.width;
|
||||||
gridData.verticalIndent = 5;
|
gridData.verticalIndent = 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOP: {
|
case TOP: {
|
||||||
gridData.horizontalSpan = orientation.width;
|
gridData.horizontalSpan = orientation.width;
|
||||||
gridData.verticalAlignment = SWT.BOTTOM;
|
gridData.verticalAlignment = SWT.BOTTOM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
label.setAlignment(SWT.LEFT);
|
label.setAlignment(SWT.LEFT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label.setLayoutData(gridData);
|
label.setLayoutData(gridData);
|
||||||
label.pack();
|
label.pack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
public void balanceGrid(final CellFieldBuilderAdapter[][] grid, final int x, final int y) {
|
||||||
if (grid[y][x] != this) {
|
if (grid[y][x] != this) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (orientation.title == TitleOrientation.LEFT_SPAN) {
|
if (orientation.title == TitleOrientation.LEFT_SPAN) {
|
||||||
int xpos = x - 1;
|
int xpos = x - 1;
|
||||||
while (xpos >= 0 && grid[y][xpos] == null && span < orientation.width) {
|
while (xpos >= 0 && grid[y][xpos] == null && span < orientation.width) {
|
||||||
grid[y][xpos] = this;
|
grid[y][xpos] = this;
|
||||||
grid[y][xpos + 1] = DUMMY_BUILDER_ADAPTER;
|
grid[y][xpos + 1] = DUMMY_BUILDER_ADAPTER;
|
||||||
this.span++;
|
this.span++;
|
||||||
xpos--;
|
xpos--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[LABEL]";
|
return "[LABEL]";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static CellFieldBuilderAdapter passwordConfirmLabel(
|
static CellFieldBuilderAdapter passwordConfirmLabel(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
return new CellFieldBuilderAdapter() {
|
return new CellFieldBuilderAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void createCell(final ViewGridBuilder builder) {
|
public void createCell(final ViewGridBuilder builder) {
|
||||||
final WidgetFactory widgetFactory = builder.examConfigurationService.getWidgetFactory();
|
final WidgetFactory widgetFactory = builder.examConfigurationService.getWidgetFactory();
|
||||||
final Label label = widgetFactory.labelLocalized(
|
final Label label = widgetFactory.labelLocalized(
|
||||||
builder.parent,
|
builder.parent,
|
||||||
new LocTextKey(
|
new LocTextKey(
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name
|
||||||
+ ".confirm"));
|
+ ".confirm"));
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
label.setAlignment(SWT.LEFT);
|
label.setAlignment(SWT.LEFT);
|
||||||
gridData.verticalIndent = 20;
|
gridData.verticalIndent = 20;
|
||||||
label.setLayoutData(gridData);
|
label.setLayoutData(gridData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[PASSWORD CONFIRM LABEL]";
|
return "[PASSWORD CONFIRM LABEL]";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static class GroupCellFieldBuilderAdapter implements CellFieldBuilderAdapter {
|
class GroupCellFieldBuilderAdapter implements CellFieldBuilderAdapter {
|
||||||
|
|
||||||
final Collection<Orientation> orientationsOfGroup;
|
final Collection<Orientation> orientationsOfGroup;
|
||||||
|
|
||||||
int x = 100;
|
int x = 100;
|
||||||
int y = 100;
|
int y = 100;
|
||||||
int width = 1;
|
int width = 1;
|
||||||
int height = 1;
|
int height = 1;
|
||||||
|
|
||||||
GroupCellFieldBuilderAdapter(final Collection<Orientation> orientationsOfGroup) {
|
GroupCellFieldBuilderAdapter(final Collection<Orientation> orientationsOfGroup) {
|
||||||
this.orientationsOfGroup = orientationsOfGroup;
|
this.orientationsOfGroup = orientationsOfGroup;
|
||||||
|
|
||||||
for (final Orientation o : this.orientationsOfGroup) {
|
for (final Orientation o : this.orientationsOfGroup) {
|
||||||
final int xpos = o.xPosition - ((o.title == TitleOrientation.LEFT) ? 1 : 0);
|
final int xpos = o.xPosition - ((o.title == TitleOrientation.LEFT) ? 1 : 0);
|
||||||
this.x = (xpos < this.x) ? xpos : this.x;
|
this.x = Math.min(xpos, this.x);
|
||||||
final int ypos = o.yPosition - ((o.title == TitleOrientation.TOP) ? 1 : 0);
|
final int ypos = o.yPosition - ((o.title == TitleOrientation.TOP) ? 1 : 0);
|
||||||
this.y = (ypos < this.y) ? ypos : this.y;
|
this.y = Math.min(ypos, this.y);
|
||||||
this.width = (this.width < o.xpos() + o.width()) ? o.xpos() + o.width() : this.width;
|
this.width = Math.max(this.width, o.xpos() + o.width());
|
||||||
this.height = (this.height < o.ypos() + o.height()) ? o.ypos() + o.height() : this.height;
|
this.height = Math.max(this.height, o.ypos() + o.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.width = this.width - this.x;
|
this.width = this.width - this.x;
|
||||||
this.height = this.height - this.y + 1;
|
this.height = this.height - this.y + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createCell(final ViewGridBuilder builder) {
|
public void createCell(final ViewGridBuilder builder) {
|
||||||
final WidgetFactory widgetFactory = builder.examConfigurationService.getWidgetFactory();
|
final WidgetFactory widgetFactory = builder.examConfigurationService.getWidgetFactory();
|
||||||
final Orientation o = this.orientationsOfGroup.stream().findFirst().get();
|
final Orientation o = this.orientationsOfGroup.stream().findFirst().orElse(null);
|
||||||
final LocTextKey groupLabelKey = new LocTextKey(
|
final LocTextKey groupLabelKey = new LocTextKey(
|
||||||
ExamConfigurationService.GROUP_LABEL_LOC_TEXT_PREFIX +
|
ExamConfigurationService.GROUP_LABEL_LOC_TEXT_PREFIX +
|
||||||
o.groupId,
|
o.groupId,
|
||||||
o.groupId);
|
o.groupId);
|
||||||
final LocTextKey groupTooltipKey = new LocTextKey(
|
final LocTextKey groupTooltipKey = new LocTextKey(
|
||||||
ExamConfigurationService.GROUP_LABEL_LOC_TEXT_PREFIX +
|
ExamConfigurationService.GROUP_LABEL_LOC_TEXT_PREFIX +
|
||||||
o.groupId +
|
o.groupId +
|
||||||
ExamConfigurationService.TOOL_TIP_SUFFIX,
|
ExamConfigurationService.TOOL_TIP_SUFFIX,
|
||||||
o.groupId);
|
o.groupId);
|
||||||
|
|
||||||
final Group group = widgetFactory.groupLocalized(
|
final Group group = widgetFactory.groupLocalized(
|
||||||
builder.parent,
|
builder.parent,
|
||||||
this.width,
|
this.width,
|
||||||
groupLabelKey,
|
groupLabelKey,
|
||||||
groupTooltipKey);
|
groupTooltipKey);
|
||||||
group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, this.width, this.height));
|
group.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, this.width, this.height));
|
||||||
|
|
||||||
final ViewGridBuilder groupBuilder = new ViewGridBuilder(
|
final ViewGridBuilder groupBuilder = new ViewGridBuilder(
|
||||||
group,
|
group,
|
||||||
builder.viewContext,
|
builder.viewContext,
|
||||||
this,
|
this,
|
||||||
builder.examConfigurationService);
|
builder.examConfigurationService);
|
||||||
|
|
||||||
for (final Orientation orientation : this.orientationsOfGroup) {
|
for (final Orientation orientation : this.orientationsOfGroup) {
|
||||||
final ConfigurationAttribute attribute = builder.viewContext.getAttribute(orientation.attributeId);
|
final ConfigurationAttribute attribute = builder.viewContext.getAttribute(orientation.attributeId);
|
||||||
groupBuilder.add(attribute);
|
groupBuilder.add(attribute);
|
||||||
}
|
}
|
||||||
groupBuilder.compose();
|
groupBuilder.compose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,134 +1,134 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Button;
|
import org.eclipse.swt.widgets.Button;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
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.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TitleOrientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
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.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class CheckBoxBuilder implements InputFieldBuilder {
|
public class CheckBoxBuilder implements InputFieldBuilder {
|
||||||
|
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
|
|
||||||
protected CheckBoxBuilder(final WidgetFactory widgetFactory) {
|
protected CheckBoxBuilder(final WidgetFactory widgetFactory) {
|
||||||
this.widgetFactory = widgetFactory;
|
this.widgetFactory = widgetFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean builderFor(
|
public boolean builderFor(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return attribute.type == AttributeType.CHECKBOX;
|
return attribute.type == AttributeType.CHECKBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputField createInputField(
|
public InputField createInputField(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
Objects.requireNonNull(parent);
|
Objects.requireNonNull(parent);
|
||||||
Objects.requireNonNull(attribute);
|
Objects.requireNonNull(attribute);
|
||||||
Objects.requireNonNull(viewContext);
|
Objects.requireNonNull(viewContext);
|
||||||
|
|
||||||
final I18nSupport i18nSupport = this.widgetFactory.getI18nSupport();
|
final I18nSupport i18nSupport = this.widgetFactory.getI18nSupport();
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, attribute, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final Button checkbox = this.widgetFactory.buttonLocalized(
|
final Button checkbox = this.widgetFactory.buttonLocalized(
|
||||||
innerGrid,
|
innerGrid,
|
||||||
SWT.CHECK,
|
SWT.CHECK,
|
||||||
(orientation.title == TitleOrientation.NONE)
|
(orientation.title == TitleOrientation.NONE)
|
||||||
? ExamConfigurationService.attributeNameLocKey(attribute)
|
? ExamConfigurationService.attributeNameLocKey(attribute)
|
||||||
: null,
|
: null,
|
||||||
ExamConfigurationService.getToolTipKey(attribute, i18nSupport));
|
ExamConfigurationService.getToolTipKey(attribute, i18nSupport));
|
||||||
|
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
|
||||||
gridData.verticalIndent = 0;
|
gridData.verticalIndent = 0;
|
||||||
checkbox.setLayoutData(gridData);
|
checkbox.setLayoutData(gridData);
|
||||||
|
|
||||||
final CheckboxField checkboxField = new CheckboxField(
|
final CheckboxField checkboxField = new CheckboxField(
|
||||||
attribute,
|
attribute,
|
||||||
viewContext.getOrientation(attribute.id),
|
viewContext.getOrientation(attribute.id),
|
||||||
checkbox);
|
checkbox);
|
||||||
|
|
||||||
if (viewContext.readonly) {
|
if (viewContext.readonly) {
|
||||||
checkbox.setEnabled(false);
|
checkbox.setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
checkbox.addListener(
|
checkbox.addListener(
|
||||||
SWT.Selection,
|
SWT.Selection,
|
||||||
event -> viewContext.getValueChangeListener().valueChanged(
|
event -> viewContext.getValueChangeListener().valueChanged(
|
||||||
viewContext,
|
viewContext,
|
||||||
attribute,
|
attribute,
|
||||||
checkboxField.getValue(),
|
checkboxField.getValue(),
|
||||||
checkboxField.listIndex));
|
checkboxField.listIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
return checkboxField;
|
return checkboxField;
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class CheckboxField extends AbstractInputField<Button> {
|
static final class CheckboxField extends AbstractInputField<Button> {
|
||||||
|
|
||||||
CheckboxField(
|
CheckboxField(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation,
|
final Orientation orientation,
|
||||||
final Button control) {
|
final Button control) {
|
||||||
|
|
||||||
super(attribute, orientation, control, null);
|
super(attribute, orientation, control, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setValueToControl(final String value) {
|
protected void setValueToControl(final String value) {
|
||||||
this.control.setSelection(Boolean.valueOf(this.initValue));
|
this.control.setSelection(Boolean.parseBoolean(this.initValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return this.control.getSelection()
|
return this.control.getSelection()
|
||||||
? Constants.TRUE_STRING
|
? Constants.TRUE_STRING
|
||||||
: Constants.FALSE_STRING;
|
: Constants.FALSE_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getReadableValue() {
|
public String getReadableValue() {
|
||||||
return this.control.getSelection()
|
return this.control.getSelection()
|
||||||
? "Active"
|
? "Active"
|
||||||
: "Inactive";
|
: "Inactive";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,270 +1,270 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Table;
|
import org.eclipse.swt.widgets.Table;
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
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.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog;
|
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.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class CompositeTableFieldBuilder extends AbstractTableFieldBuilder {
|
public class CompositeTableFieldBuilder extends AbstractTableFieldBuilder {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(CompositeTableFieldBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(CompositeTableFieldBuilder.class);
|
||||||
|
|
||||||
private static final String TABLE_ENTRY_NAME = "TABLE_ENTRY";
|
private static final String TABLE_ENTRY_NAME = "TABLE_ENTRY";
|
||||||
private static final String TABLE_COLUMN_NAME_KEY = "TABLE_COLUMN_NAME";
|
private static final String TABLE_COLUMN_NAME_KEY = "TABLE_COLUMN_NAME";
|
||||||
|
|
||||||
protected CompositeTableFieldBuilder(
|
protected CompositeTableFieldBuilder(
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final WidgetFactory widgetFactory) {
|
final WidgetFactory widgetFactory) {
|
||||||
|
|
||||||
super(restService, widgetFactory);
|
super(restService, widgetFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean builderFor(
|
public boolean builderFor(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AttributeType.COMPOSITE_TABLE == attribute.type;
|
return AttributeType.COMPOSITE_TABLE == attribute.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputField createInputField(
|
public InputField createInputField(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
final I18nSupport i18nSupport = viewContext.getI18nSupport();
|
final I18nSupport i18nSupport = viewContext.getI18nSupport();
|
||||||
final TableContext tableContext = createTableContext(attribute, viewContext);
|
final TableContext tableContext = createTableContext(attribute, viewContext);
|
||||||
final Table table = createTable(parent, tableContext);
|
final Table table = createTable(parent, tableContext);
|
||||||
|
|
||||||
final String resources = attribute.getResources();
|
final String resources = attribute.getResources();
|
||||||
final String[] columnsAndRows = StringUtils.split(
|
final String[] columnsAndRows = StringUtils.split(
|
||||||
resources,
|
resources,
|
||||||
Constants.EMBEDDED_LIST_SEPARATOR);
|
Constants.EMBEDDED_LIST_SEPARATOR);
|
||||||
final String[] columns = (columnsAndRows.length == 2)
|
final String[] columns = (columnsAndRows.length == 2)
|
||||||
? StringUtils.split(columnsAndRows[0], Constants.LIST_SEPARATOR)
|
? StringUtils.split(columnsAndRows[0], Constants.LIST_SEPARATOR)
|
||||||
: new String[] { TABLE_ENTRY_NAME };
|
: new String[] { TABLE_ENTRY_NAME };
|
||||||
final String[] rows = (columnsAndRows.length == 2)
|
final String[] rows = (columnsAndRows.length == 2)
|
||||||
? StringUtils.split(columnsAndRows[1], Constants.LIST_SEPARATOR)
|
? StringUtils.split(columnsAndRows[1], Constants.LIST_SEPARATOR)
|
||||||
: StringUtils.split(columnsAndRows[0], Constants.LIST_SEPARATOR);
|
: StringUtils.split(columnsAndRows[0], Constants.LIST_SEPARATOR);
|
||||||
|
|
||||||
final String attributeNameKey = ExamConfigurationService.attributeNameKey(attribute);
|
final String attributeNameKey = ExamConfigurationService.attributeNameKey(attribute);
|
||||||
for (int i = 0; i < columns.length; i++) {
|
for (int i = 0; i < columns.length; i++) {
|
||||||
final TableColumn column = this.widgetFactory.tableColumnLocalized(
|
final TableColumn column = this.widgetFactory.tableColumnLocalized(
|
||||||
table,
|
table,
|
||||||
new LocTextKey(attributeNameKey + "." + columns[i]),
|
new LocTextKey(attributeNameKey + "." + columns[i]),
|
||||||
new LocTextKey(attributeNameKey + "." + columns[i] + ".tootlip"));
|
new LocTextKey(attributeNameKey + "." + columns[i] + ".tootlip"));
|
||||||
|
|
||||||
column.setData(TABLE_COLUMN_NAME_KEY, columns[i]);
|
column.setData(TABLE_COLUMN_NAME_KEY, columns[i]);
|
||||||
column.setWidth(100);
|
column.setWidth(100);
|
||||||
column.setResizable(false);
|
column.setResizable(false);
|
||||||
column.setMoveable(false);
|
column.setMoveable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < rows.length; i++) {
|
for (int i = 0; i < rows.length; i++) {
|
||||||
final TableItem item = new TableItem(table, SWT.NONE);
|
final TableItem item = new TableItem(table, SWT.NONE);
|
||||||
for (int j = 0; j < columns.length; j++) {
|
for (int j = 0; j < columns.length; j++) {
|
||||||
if (TABLE_ENTRY_NAME.equals(columns[j])) {
|
if (TABLE_ENTRY_NAME.equals(columns[j])) {
|
||||||
item.setText(j, i18nSupport.getText(
|
item.setText(j, i18nSupport.getText(
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + rows[i],
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + rows[i],
|
||||||
rows[i]));
|
rows[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final CompositeTableInputField tableField = new CompositeTableInputField(
|
final CompositeTableInputField tableField = new CompositeTableInputField(
|
||||||
tableContext,
|
tableContext,
|
||||||
table,
|
table,
|
||||||
Arrays.asList(columns),
|
Arrays.asList(columns),
|
||||||
Arrays.asList(rows));
|
Arrays.asList(rows));
|
||||||
|
|
||||||
setSelectionListener(table, tableField);
|
setSelectionListener(table, tableField);
|
||||||
return tableField;
|
return tableField;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void adaptColumnWidth(
|
protected void adaptColumnWidth(
|
||||||
final Table table,
|
final Table table,
|
||||||
final TableContext tableContext) {
|
final TableContext tableContext) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final int currentTableWidth = table.getClientArea().width - 50;
|
final int currentTableWidth = table.getClientArea().width - 50;
|
||||||
final TableColumn[] columns = table.getColumns();
|
final TableColumn[] columns = table.getColumns();
|
||||||
final int widthUnit = currentTableWidth / (columns.length + 2);
|
final int widthUnit = currentTableWidth / (columns.length + 2);
|
||||||
for (int i = 0; i < columns.length; i++) {
|
for (int i = 0; i < columns.length; i++) {
|
||||||
final int factor = (TABLE_ENTRY_NAME.equals(columns[i].getData(TABLE_COLUMN_NAME_KEY))) ? 4 : 1;
|
final int factor = (TABLE_ENTRY_NAME.equals(columns[i].getData(TABLE_COLUMN_NAME_KEY))) ? 4 : 1;
|
||||||
columns[i].setWidth(widthUnit * factor);
|
columns[i].setWidth(widthUnit * factor);
|
||||||
}
|
}
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.warn("Failed to adaptColumnWidth: ", e);
|
log.warn("Failed to adaptColumnWidth: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class CompositeTableInputField extends AbstractTableInputField {
|
static final class CompositeTableInputField extends AbstractTableInputField {
|
||||||
|
|
||||||
final List<String> columns;
|
final List<String> columns;
|
||||||
final List<String> rows;
|
final List<String> rows;
|
||||||
final List<Map<Long, TableValue>> values;
|
final List<Map<Long, TableValue>> values;
|
||||||
|
|
||||||
CompositeTableInputField(
|
CompositeTableInputField(
|
||||||
final TableContext tableContext,
|
final TableContext tableContext,
|
||||||
final Table control,
|
final Table control,
|
||||||
final List<String> columns,
|
final List<String> columns,
|
||||||
final List<String> rows) {
|
final List<String> rows) {
|
||||||
|
|
||||||
super(tableContext.attribute, tableContext.orientation, control, null, tableContext);
|
super(tableContext.attribute, tableContext.orientation, control, null, tableContext);
|
||||||
this.values = new ArrayList<>();
|
this.values = new ArrayList<>();
|
||||||
this.columns = columns;
|
this.columns = columns;
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void initValue(final List<TableValue> tableValues) {
|
void initValue(final List<TableValue> tableValues) {
|
||||||
valuesFromIndexMap(this.values, createRowIndexMap(tableValues));
|
valuesFromIndexMap(this.values, createRowIndexMap(tableValues));
|
||||||
for (int i = 0; i < this.values.size(); i++) {
|
for (int i = 0; i < this.values.size(); i++) {
|
||||||
setRowValues(i, this.values.get(i));
|
setRowValues(i, this.values.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyTableRowValues(final int index) {
|
protected void applyTableRowValues(final int index) {
|
||||||
setRowValues(index, this.values.get(index));
|
setRowValues(index, this.values.get(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRowValues(final int index, final Map<Long, TableValue> map) {
|
private void setRowValues(final int index, final Map<Long, TableValue> map) {
|
||||||
final TableItem rowItem = this.control.getItem(index);
|
final TableItem rowItem = this.control.getItem(index);
|
||||||
for (final TableValue val : map.values()) {
|
for (final TableValue val : map.values()) {
|
||||||
final Orientation orientation = this.tableContext.getOrientation(val.attributeId);
|
final Orientation orientation = this.tableContext.getOrientation(val.attributeId);
|
||||||
final String groupId = orientation.getGroupId();
|
final String groupId = orientation.getGroupId();
|
||||||
if (StringUtils.isNotBlank(groupId)) {
|
if (StringUtils.isNotBlank(groupId)) {
|
||||||
final int cellIndex = this.columns.indexOf(groupId);
|
final int cellIndex = this.columns.indexOf(groupId);
|
||||||
if (cellIndex >= 0) {
|
if (cellIndex >= 0) {
|
||||||
setValueToCell(
|
setValueToCell(
|
||||||
this.tableContext,
|
this.tableContext,
|
||||||
rowItem,
|
rowItem,
|
||||||
cellIndex,
|
cellIndex,
|
||||||
this.tableContext.getAttribute(val.attributeId),
|
this.tableContext.getAttribute(val.attributeId),
|
||||||
val);
|
val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void openForm(final int selectionIndex) {
|
protected void openForm(final int selectionIndex) {
|
||||||
final String row = this.rows.get(selectionIndex);
|
final String row = this.rows.get(selectionIndex);
|
||||||
final Map<Long, TableValue> rowValues = this.values.get(selectionIndex);
|
final Map<Long, TableValue> rowValues = this.values.get(selectionIndex);
|
||||||
final TableRowFormBuilder builder = new TableRowFormBuilder(
|
final TableRowFormBuilder builder = new TableRowFormBuilder(
|
||||||
this.tableContext,
|
this.tableContext,
|
||||||
rowValues,
|
rowValues,
|
||||||
row);
|
row);
|
||||||
|
|
||||||
final ModalInputDialog<Map<Long, TableValue>> dialog = new ModalInputDialog<Map<Long, TableValue>>(
|
final ModalInputDialog<Map<Long, TableValue>> dialog = new ModalInputDialog<Map<Long, TableValue>>(
|
||||||
this.control.getShell(),
|
this.control.getShell(),
|
||||||
this.tableContext.getWidgetFactory())
|
this.tableContext.getWidgetFactory())
|
||||||
.setDialogWidth(500);
|
.setDialogWidth(500);
|
||||||
|
|
||||||
if (this.tableContext.getViewContext().readonly) {
|
if (this.tableContext.getViewContext().readonly) {
|
||||||
dialog.open(
|
dialog.open(
|
||||||
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + row),
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + row),
|
||||||
builder);
|
builder);
|
||||||
} else {
|
} else {
|
||||||
dialog.open(
|
dialog.open(
|
||||||
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + row),
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + row),
|
||||||
(Consumer<Map<Long, TableValue>>) rowVals -> applyFormValues(
|
(Consumer<Map<Long, TableValue>>) _rowValues -> applyFormValues(
|
||||||
this.values,
|
this.values,
|
||||||
rowVals,
|
_rowValues,
|
||||||
selectionIndex),
|
selectionIndex),
|
||||||
() -> this.tableContext.getValueChangeListener()
|
() -> this.tableContext.getValueChangeListener()
|
||||||
.tableChanged(extractTableValue(this.values)),
|
.tableChanged(extractTableValue(this.values)),
|
||||||
builder);
|
builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<Integer, Map<Long, TableValue>> createRowIndexMap(final List<TableValue> tableValues) {
|
protected Map<Integer, Map<Long, TableValue>> createRowIndexMap(final List<TableValue> tableValues) {
|
||||||
final Map<Integer, Map<Long, TableValue>> indexMapping = new HashMap<>();
|
final Map<Integer, Map<Long, TableValue>> indexMapping = new HashMap<>();
|
||||||
for (final TableValue tableValue : tableValues) {
|
for (final TableValue tableValue : tableValues) {
|
||||||
final ConfigurationAttribute attribute = this.tableContext
|
final ConfigurationAttribute attribute = this.tableContext
|
||||||
.getViewContext()
|
.getViewContext()
|
||||||
.getAttribute(tableValue.attributeId);
|
.getAttribute(tableValue.attributeId);
|
||||||
final String groupId = ConfigurationAttribute.getDependencyValue(
|
final String groupId = ConfigurationAttribute.getDependencyValue(
|
||||||
ConfigurationAttribute.DEPENDENCY_GROUP_ID,
|
ConfigurationAttribute.DEPENDENCY_GROUP_ID,
|
||||||
attribute);
|
attribute);
|
||||||
final int index = this.rows.indexOf(groupId);
|
final int index = this.rows.indexOf(groupId);
|
||||||
final Map<Long, TableValue> rowValues = indexMapping.computeIfAbsent(
|
final Map<Long, TableValue> rowValues = indexMapping.computeIfAbsent(
|
||||||
index,
|
index,
|
||||||
key -> new HashMap<>());
|
key -> new HashMap<>());
|
||||||
rowValues.put(tableValue.attributeId, tableValue);
|
rowValues.put(tableValue.attributeId, tableValue);
|
||||||
}
|
}
|
||||||
return indexMapping;
|
return indexMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void clearTable() {
|
void clearTable() {
|
||||||
// nothing to clear for this table type
|
// nothing to clear for this table type
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isChildValue(
|
protected boolean isChildValue(
|
||||||
final TableContext tableContext,
|
final TableContext tableContext,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) {
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
final boolean childValue = super.isChildValue(tableContext, attribute, value);
|
final boolean childValue = super.isChildValue(tableContext, attribute, value);
|
||||||
if (childValue) {
|
if (childValue) {
|
||||||
final ConfigurationAttribute attr = tableContext.getAttribute(value.attributeId);
|
final ConfigurationAttribute attr = tableContext.getAttribute(value.attributeId);
|
||||||
return ConfigurationAttribute.hasDependency(
|
return ConfigurationAttribute.hasDependency(
|
||||||
ConfigurationAttribute.DEPENDENCY_GROUP_ID,
|
ConfigurationAttribute.DEPENDENCY_GROUP_ID,
|
||||||
attr);
|
attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
return childValue;
|
return childValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,423 +1,414 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.Comparator;
|
||||||
import java.util.Set;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.apache.tomcat.util.buf.StringUtils;
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.apache.tomcat.util.buf.StringUtils;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.slf4j.Logger;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.Logger;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeRule;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeRule;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.FieldValidationError;
|
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.FieldValidationError;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.AttachDefaultOrientation;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigAttributes;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.AttachDefaultOrientation;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurationValues;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigAttributes;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetOrientations;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurationValues;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetViewList;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetOrientations;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.RemoveOrientation;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetViewList;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ResetTemplateValues;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.RemoveOrientation;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigTableValues;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ResetTemplateValues;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigValue;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigTableValues;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.SaveExamConfigValue;
|
||||||
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
@Lazy
|
|
||||||
@Service
|
@Lazy
|
||||||
@GuiProfile
|
@Service
|
||||||
public class ExamConfigurationServiceImpl implements ExamConfigurationService {
|
@GuiProfile
|
||||||
|
public class ExamConfigurationServiceImpl implements ExamConfigurationService {
|
||||||
private static final Logger log = LoggerFactory.getLogger(ExamConfigurationServiceImpl.class);
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ExamConfigurationServiceImpl.class);
|
||||||
private final RestService restService;
|
|
||||||
private final JSONMapper jsonMapper;
|
private final RestService restService;
|
||||||
private final WidgetFactory widgetFactory;
|
private final JSONMapper jsonMapper;
|
||||||
|
private final WidgetFactory widgetFactory;
|
||||||
private final InputFieldBuilderSupplier inputFieldBuilderSupplier;
|
|
||||||
private final Collection<ValueChangeRule> valueChangeRules;
|
private final InputFieldBuilderSupplier inputFieldBuilderSupplier;
|
||||||
|
private final Collection<ValueChangeRule> valueChangeRules;
|
||||||
public ExamConfigurationServiceImpl(
|
|
||||||
final RestService restService,
|
public ExamConfigurationServiceImpl(
|
||||||
final JSONMapper jsonMapper,
|
final RestService restService,
|
||||||
final WidgetFactory widgetFactory,
|
final JSONMapper jsonMapper,
|
||||||
final InputFieldBuilderSupplier inputFieldBuilderSupplier,
|
final WidgetFactory widgetFactory,
|
||||||
final Collection<ValueChangeRule> valueChangeRules) {
|
final InputFieldBuilderSupplier inputFieldBuilderSupplier,
|
||||||
|
final Collection<ValueChangeRule> valueChangeRules) {
|
||||||
this.restService = restService;
|
|
||||||
this.jsonMapper = jsonMapper;
|
this.restService = restService;
|
||||||
this.widgetFactory = widgetFactory;
|
this.jsonMapper = jsonMapper;
|
||||||
this.inputFieldBuilderSupplier = inputFieldBuilderSupplier;
|
this.widgetFactory = widgetFactory;
|
||||||
this.valueChangeRules = Utils.immutableCollectionOf(valueChangeRules);
|
this.inputFieldBuilderSupplier = inputFieldBuilderSupplier;
|
||||||
}
|
this.valueChangeRules = Utils.immutableCollectionOf(valueChangeRules);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public WidgetFactory getWidgetFactory() {
|
@Override
|
||||||
return this.widgetFactory;
|
public WidgetFactory getWidgetFactory() {
|
||||||
}
|
return this.widgetFactory;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public InputFieldBuilder getInputFieldBuilder(
|
@Override
|
||||||
final ConfigurationAttribute attribute,
|
public InputFieldBuilder getInputFieldBuilder(
|
||||||
final Orientation orientation) {
|
final ConfigurationAttribute attribute,
|
||||||
|
final Orientation orientation) {
|
||||||
return this.inputFieldBuilderSupplier.getInputFieldBuilder(attribute, orientation);
|
|
||||||
}
|
return this.inputFieldBuilderSupplier.getInputFieldBuilder(attribute, orientation);
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public Result<AttributeMapping> getAttributes(final Long templateId) {
|
@Override
|
||||||
return Result.tryCatch(() -> {
|
public Result<AttributeMapping> getAttributes(final Long templateId) {
|
||||||
return new AttributeMapping(
|
return Result.tryCatch(() -> new AttributeMapping(
|
||||||
templateId,
|
templateId,
|
||||||
getAttributes(),
|
getAttributes(),
|
||||||
getOrientations(templateId));
|
getOrientations(templateId)));
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Result<AttributeMapping> getAttributes(
|
||||||
public Result<AttributeMapping> getAttributes(
|
final TemplateAttribute attribute,
|
||||||
final TemplateAttribute attribute,
|
final Orientation defaultOrientation) {
|
||||||
final Orientation defaultOrientation) {
|
|
||||||
|
final List<Orientation> orientations = getOrientations(attribute.templateId);
|
||||||
final List<Orientation> orientations = getOrientations(attribute.templateId);
|
if (attribute.getOrientation() == null) {
|
||||||
if (attribute.getOrientation() == null) {
|
orientations.add(defaultOrientation);
|
||||||
orientations.add(defaultOrientation);
|
}
|
||||||
}
|
|
||||||
|
return Result.tryCatch(() -> new AttributeMapping(
|
||||||
return Result.tryCatch(() -> {
|
attribute.templateId,
|
||||||
return new AttributeMapping(
|
getAttributes(),
|
||||||
attribute.templateId,
|
orientations));
|
||||||
getAttributes(),
|
}
|
||||||
orientations);
|
|
||||||
});
|
private List<Orientation> getOrientations(final Long templateId) {
|
||||||
}
|
return this.restService
|
||||||
|
.getBuilder(GetOrientations.class)
|
||||||
private List<Orientation> getOrientations(final Long templateId) {
|
.withQueryParam(Orientation.FILTER_ATTR_TEMPLATE_ID, String.valueOf(templateId))
|
||||||
return this.restService
|
.call()
|
||||||
.getBuilder(GetOrientations.class)
|
.onError(t -> log.error("Failed to get all Orientation of template {}", templateId, t))
|
||||||
.withQueryParam(Orientation.FILTER_ATTR_TEMPLATE_ID, String.valueOf(templateId))
|
.getOrThrow();
|
||||||
.call()
|
}
|
||||||
.onError(t -> log.error("Failed to get all Orientation of template {}", templateId, t))
|
|
||||||
.getOrThrow();
|
private List<ConfigurationAttribute> getAttributes() {
|
||||||
}
|
return this.restService
|
||||||
|
.getBuilder(GetConfigAttributes.class)
|
||||||
private List<ConfigurationAttribute> getAttributes() {
|
.call()
|
||||||
return this.restService
|
.onError(t -> log.error("Failed to get all ConfigurationAttribute"))
|
||||||
.getBuilder(GetConfigAttributes.class)
|
.getOrThrow();
|
||||||
.call()
|
}
|
||||||
.onError(t -> log.error("Failed to get all ConfigurationAttribute"))
|
|
||||||
.getOrThrow();
|
@Override
|
||||||
}
|
public List<View> getViews(final AttributeMapping allAttributes) {
|
||||||
|
final Collection<Long> viewIds = allAttributes.getViewIds();
|
||||||
@Override
|
if (viewIds == null || viewIds.isEmpty()) {
|
||||||
public List<View> getViews(final AttributeMapping allAttributes) {
|
return Collections.emptyList();
|
||||||
final Collection<Long> viewIds = allAttributes.getViewIds();
|
}
|
||||||
if (viewIds == null || viewIds.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
final String ids = StringUtils.join(
|
||||||
}
|
viewIds
|
||||||
|
.stream()
|
||||||
final String ids = StringUtils.join(
|
.map(String::valueOf)
|
||||||
viewIds
|
.collect(Collectors.toList()),
|
||||||
.stream()
|
Constants.LIST_SEPARATOR_CHAR);
|
||||||
.map(String::valueOf)
|
|
||||||
.collect(Collectors.toList()),
|
return this.restService.getBuilder(GetViewList.class)
|
||||||
Constants.LIST_SEPARATOR_CHAR);
|
.withQueryParam(API.PARAM_MODEL_ID_LIST, ids)
|
||||||
|
.call()
|
||||||
return this.restService.getBuilder(GetViewList.class)
|
.getOrThrow()
|
||||||
.withQueryParam(API.PARAM_MODEL_ID_LIST, ids)
|
.stream()
|
||||||
.call()
|
.sorted(Comparator.comparing(v -> v.position))
|
||||||
.getOrThrow()
|
.collect(Collectors.toList());
|
||||||
.stream()
|
}
|
||||||
.sorted((v1, v2) -> v1.position.compareTo(v2.position))
|
|
||||||
.collect(Collectors.toList());
|
@Override
|
||||||
}
|
public ViewContext createViewContext(
|
||||||
|
final PageContext pageContext,
|
||||||
@Override
|
final Configuration configuration,
|
||||||
public ViewContext createViewContext(
|
final View view,
|
||||||
final PageContext pageContext,
|
final AttributeMapping attributeMapping,
|
||||||
final Configuration configuration,
|
final int rows,
|
||||||
final View view,
|
final boolean readonly) {
|
||||||
final AttributeMapping attributeMapping,
|
|
||||||
final int rows,
|
return new ViewContext(
|
||||||
final boolean readonly) {
|
configuration,
|
||||||
|
view,
|
||||||
return new ViewContext(
|
rows,
|
||||||
configuration,
|
attributeMapping,
|
||||||
view,
|
new ValueChangeListenerImpl(
|
||||||
rows,
|
pageContext,
|
||||||
attributeMapping,
|
this.restService,
|
||||||
new ValueChangeListenerImpl(
|
this.jsonMapper,
|
||||||
pageContext,
|
this.valueChangeRules),
|
||||||
this.restService,
|
this.widgetFactory.getI18nSupport(),
|
||||||
this.jsonMapper,
|
readonly);
|
||||||
this.valueChangeRules),
|
|
||||||
this.widgetFactory.getI18nSupport(),
|
}
|
||||||
readonly);
|
|
||||||
|
@Override
|
||||||
}
|
public Composite createViewGrid(final Composite parent, final ViewContext viewContext) {
|
||||||
|
final Composite composite = new Composite(parent, SWT.NONE);
|
||||||
@Override
|
final GridLayout gridLayout = new GridLayout(viewContext.getColumns(), true);
|
||||||
public Composite createViewGrid(final Composite parent, final ViewContext viewContext) {
|
gridLayout.verticalSpacing = 0;
|
||||||
final Composite composite = new Composite(parent, SWT.NONE);
|
composite.setLayout(gridLayout);
|
||||||
final GridLayout gridLayout = new GridLayout(viewContext.getColumns(), true);
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
gridLayout.verticalSpacing = 0;
|
composite.setLayoutData(gridData);
|
||||||
composite.setLayout(gridLayout);
|
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
final ViewGridBuilder viewGridBuilder = new ViewGridBuilder(
|
||||||
composite.setLayoutData(gridData);
|
composite,
|
||||||
|
viewContext,
|
||||||
final ViewGridBuilder viewGridBuilder = new ViewGridBuilder(
|
this);
|
||||||
composite,
|
|
||||||
viewContext,
|
for (final ConfigurationAttribute attribute : viewContext.getAttributes()) {
|
||||||
this);
|
final Orientation orientation = viewContext.getOrientation(attribute.id);
|
||||||
|
if (orientation != null && viewContext.getId().equals(orientation.viewId)) {
|
||||||
for (final ConfigurationAttribute attribute : viewContext.getAttributes()) {
|
viewGridBuilder.add(attribute);
|
||||||
final Orientation orientation = viewContext.getOrientation(attribute.id);
|
}
|
||||||
if (orientation != null && viewContext.getId().equals(orientation.viewId)) {
|
}
|
||||||
viewGridBuilder.add(attribute);
|
|
||||||
}
|
viewGridBuilder.compose();
|
||||||
}
|
return composite;
|
||||||
|
}
|
||||||
viewGridBuilder.compose();
|
|
||||||
return composite;
|
@Override
|
||||||
}
|
public void initInputFieldValues(
|
||||||
|
final Long configurationId,
|
||||||
@Override
|
final Collection<ViewContext> viewContexts) {
|
||||||
public void initInputFieldValues(
|
|
||||||
final Long configurationId,
|
if (viewContexts == null || viewContexts.size() < 1) {
|
||||||
final Collection<ViewContext> viewContexts) {
|
log.warn("No viewContexts available");
|
||||||
|
return;
|
||||||
if (viewContexts == null || viewContexts.size() < 1) {
|
}
|
||||||
log.warn("No viewContexts available");
|
|
||||||
return;
|
final Collection<ConfigurationValue> attributeValues = this.restService
|
||||||
}
|
.getBuilder(GetConfigurationValues.class)
|
||||||
|
.withQueryParam(
|
||||||
final Collection<ConfigurationValue> attributeValues = this.restService
|
ConfigurationValue.FILTER_ATTR_CONFIGURATION_ID,
|
||||||
.getBuilder(GetConfigurationValues.class)
|
String.valueOf(configurationId))
|
||||||
.withQueryParam(
|
.call()
|
||||||
ConfigurationValue.FILTER_ATTR_CONFIGURATION_ID,
|
.onError(t -> log.error(
|
||||||
String.valueOf(configurationId))
|
"Failed to get all ConfigurationValue for configuration with id: {}",
|
||||||
.call()
|
configurationId))
|
||||||
.onError(t -> log.error(
|
.getOrElse(Collections::emptyList);
|
||||||
"Failed to get all ConfigurationValue for configuration with id: {}",
|
|
||||||
configurationId))
|
viewContexts
|
||||||
.getOrElse(Collections::emptyList);
|
.forEach(vc -> vc.setValuesToInputFields(attributeValues));
|
||||||
|
}
|
||||||
viewContexts
|
|
||||||
.forEach(vc -> vc.setValuesToInputFields(attributeValues));
|
@Override
|
||||||
}
|
public final PageAction resetToDefaults(final PageAction action) {
|
||||||
|
final EntityKey parentEntityKey = action.pageContext().getParentEntityKey();
|
||||||
@Override
|
final Set<EntityKey> selection = action.getMultiSelection();
|
||||||
public final PageAction resetToDefaults(final PageAction action) {
|
if (selection != null && !selection.isEmpty()) {
|
||||||
final EntityKey parentEntityKey = action.pageContext().getParentEntityKey();
|
selection.forEach(entityKey -> callTemplateAction(
|
||||||
final Set<EntityKey> selection = action.getMultiSelection();
|
ResetTemplateValues.class,
|
||||||
if (selection != null && !selection.isEmpty()) {
|
parentEntityKey.modelId,
|
||||||
selection.stream().forEach(entityKey -> {
|
entityKey.modelId));
|
||||||
callTemplateAction(
|
} else {
|
||||||
ResetTemplateValues.class,
|
final EntityKey entityKey = action.getEntityKey();
|
||||||
parentEntityKey.modelId,
|
callTemplateAction(
|
||||||
entityKey.modelId);
|
ResetTemplateValues.class,
|
||||||
});
|
parentEntityKey.modelId,
|
||||||
} else {
|
entityKey.modelId);
|
||||||
final EntityKey entityKey = action.getEntityKey();
|
}
|
||||||
callTemplateAction(
|
|
||||||
ResetTemplateValues.class,
|
return action;
|
||||||
parentEntityKey.modelId,
|
}
|
||||||
entityKey.modelId);
|
|
||||||
}
|
@Override
|
||||||
|
public final PageAction removeFromView(final PageAction action) {
|
||||||
return action;
|
final EntityKey parentEntityKey = action.pageContext().getParentEntityKey();
|
||||||
}
|
final Set<EntityKey> selection = action.getMultiSelection();
|
||||||
|
if (selection != null && !selection.isEmpty()) {
|
||||||
@Override
|
selection.forEach(entityKey -> callTemplateAction(
|
||||||
public final PageAction removeFromView(final PageAction action) {
|
RemoveOrientation.class,
|
||||||
final EntityKey parentEntityKey = action.pageContext().getParentEntityKey();
|
parentEntityKey.modelId,
|
||||||
final Set<EntityKey> selection = action.getMultiSelection();
|
entityKey.modelId));
|
||||||
if (selection != null && !selection.isEmpty()) {
|
} else {
|
||||||
selection.stream().forEach(entityKey -> {
|
final EntityKey entityKey = action.getEntityKey();
|
||||||
callTemplateAction(
|
callTemplateAction(
|
||||||
RemoveOrientation.class,
|
RemoveOrientation.class,
|
||||||
parentEntityKey.modelId,
|
parentEntityKey.modelId,
|
||||||
entityKey.modelId);
|
entityKey.modelId);
|
||||||
});
|
}
|
||||||
} else {
|
|
||||||
final EntityKey entityKey = action.getEntityKey();
|
return action;
|
||||||
callTemplateAction(
|
}
|
||||||
RemoveOrientation.class,
|
|
||||||
parentEntityKey.modelId,
|
@Override
|
||||||
entityKey.modelId);
|
public final PageAction attachToDefaultView(final PageAction action) {
|
||||||
}
|
final EntityKey parentEntityKey = action.pageContext().getParentEntityKey();
|
||||||
|
final Set<EntityKey> selection = action.getMultiSelection();
|
||||||
return action;
|
if (selection != null && !selection.isEmpty()) {
|
||||||
}
|
selection.forEach(entityKey -> callTemplateAction(
|
||||||
|
AttachDefaultOrientation.class,
|
||||||
@Override
|
parentEntityKey.modelId,
|
||||||
public final PageAction attachToDefaultView(final PageAction action) {
|
entityKey.modelId));
|
||||||
final EntityKey parentEntityKey = action.pageContext().getParentEntityKey();
|
} else {
|
||||||
final Set<EntityKey> selection = action.getMultiSelection();
|
final EntityKey entityKey = action.getEntityKey();
|
||||||
if (selection != null && !selection.isEmpty()) {
|
callTemplateAction(
|
||||||
selection.stream().forEach(entityKey -> {
|
AttachDefaultOrientation.class,
|
||||||
callTemplateAction(
|
parentEntityKey.modelId,
|
||||||
AttachDefaultOrientation.class,
|
entityKey.modelId);
|
||||||
parentEntityKey.modelId,
|
}
|
||||||
entityKey.modelId);
|
|
||||||
});
|
return action;
|
||||||
} else {
|
}
|
||||||
final EntityKey entityKey = action.getEntityKey();
|
|
||||||
callTemplateAction(
|
private void callTemplateAction(
|
||||||
AttachDefaultOrientation.class,
|
final Class<? extends RestCall<TemplateAttribute>> actionType,
|
||||||
parentEntityKey.modelId,
|
final String templateId,
|
||||||
entityKey.modelId);
|
final String attributeId) {
|
||||||
}
|
|
||||||
|
this.restService.getBuilder(actionType)
|
||||||
return action;
|
.withURIVariable(API.PARAM_PARENT_MODEL_ID, templateId)
|
||||||
}
|
.withURIVariable(API.PARAM_MODEL_ID, attributeId)
|
||||||
|
.call()
|
||||||
private void callTemplateAction(
|
.getOrThrow();
|
||||||
final Class<? extends RestCall<TemplateAttribute>> actionType,
|
}
|
||||||
final String templateId,
|
|
||||||
final String attributeId) {
|
private static final class ValueChangeListenerImpl implements ValueChangeListener {
|
||||||
|
|
||||||
this.restService.getBuilder(actionType)
|
public static final String VALIDATION_ERROR_KEY_PREFIX = "sebserver.examconfig.props.validation.";
|
||||||
.withURIVariable(API.PARAM_PARENT_MODEL_ID, templateId)
|
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, attributeId)
|
private final PageContext pageContext;
|
||||||
.call()
|
private final RestService restService;
|
||||||
.getOrThrow();
|
private final JSONMapper jsonMapper;
|
||||||
}
|
private final Collection<ValueChangeRule> valueChangeRules;
|
||||||
|
|
||||||
private static final class ValueChangeListenerImpl implements ValueChangeListener {
|
protected ValueChangeListenerImpl(
|
||||||
|
final PageContext pageContext,
|
||||||
public static final String VALIDATION_ERROR_KEY_PREFIX = "sebserver.examconfig.props.validation.";
|
final RestService restService,
|
||||||
|
final JSONMapper jsonMapper,
|
||||||
private final PageContext pageContext;
|
final Collection<ValueChangeRule> valueChangeRules) {
|
||||||
private final RestService restService;
|
|
||||||
private final JSONMapper jsonMapper;
|
this.pageContext = pageContext;
|
||||||
private final Collection<ValueChangeRule> valueChangeRules;
|
this.restService = restService;
|
||||||
|
this.jsonMapper = jsonMapper;
|
||||||
protected ValueChangeListenerImpl(
|
this.valueChangeRules = valueChangeRules;
|
||||||
final PageContext pageContext,
|
}
|
||||||
final RestService restService,
|
|
||||||
final JSONMapper jsonMapper,
|
@Override
|
||||||
final Collection<ValueChangeRule> valueChangeRules) {
|
public void valueChanged(
|
||||||
|
final ViewContext context,
|
||||||
this.pageContext = pageContext;
|
final ConfigurationAttribute attribute,
|
||||||
this.restService = restService;
|
final String value,
|
||||||
this.jsonMapper = jsonMapper;
|
final int listIndex) {
|
||||||
this.valueChangeRules = valueChangeRules;
|
|
||||||
}
|
final ConfigurationValue configurationValue = new ConfigurationValue(
|
||||||
|
null,
|
||||||
@Override
|
context.getInstitutionId(),
|
||||||
public void valueChanged(
|
context.getConfigurationId(),
|
||||||
final ViewContext context,
|
attribute.id,
|
||||||
final ConfigurationAttribute attribute,
|
listIndex,
|
||||||
final String value,
|
value);
|
||||||
final int listIndex) {
|
|
||||||
|
try {
|
||||||
final ConfigurationValue configurationValue = new ConfigurationValue(
|
final String jsonValue = this.jsonMapper.writeValueAsString(configurationValue);
|
||||||
null,
|
|
||||||
context.getInstitutionId(),
|
final Result<ConfigurationValue> savedValue = this.restService.getBuilder(SaveExamConfigValue.class)
|
||||||
context.getConfigurationId(),
|
.withBody(jsonValue)
|
||||||
attribute.id,
|
.call();
|
||||||
listIndex,
|
|
||||||
value);
|
if (savedValue.hasError()) {
|
||||||
|
context.showError(attribute.id, verifyErrorMessage(savedValue.getError()));
|
||||||
try {
|
} else {
|
||||||
final String jsonValue = this.jsonMapper.writeValueAsString(configurationValue);
|
this.notifyGUI(context, attribute, savedValue.get());
|
||||||
|
}
|
||||||
final Result<ConfigurationValue> savedValue = this.restService.getBuilder(SaveExamConfigValue.class)
|
|
||||||
.withBody(jsonValue)
|
} catch (final Exception e) {
|
||||||
.call();
|
this.pageContext.notifySaveError(EntityType.CONFIGURATION_VALUE, e);
|
||||||
|
}
|
||||||
if (savedValue.hasError()) {
|
}
|
||||||
context.showError(attribute.id, verifyErrorMessage(savedValue.getError()));
|
|
||||||
} else {
|
@Override
|
||||||
this.notifyGUI(context, attribute, savedValue.get());
|
public void tableChanged(final ConfigurationTableValues tableValue) {
|
||||||
}
|
this.restService.getBuilder(SaveExamConfigTableValues.class)
|
||||||
|
.withBody(tableValue)
|
||||||
} catch (final Exception e) {
|
.call();
|
||||||
this.pageContext.notifySaveError(EntityType.CONFIGURATION_VALUE, e);
|
}
|
||||||
}
|
|
||||||
}
|
private String verifyErrorMessage(final Exception error) {
|
||||||
|
if (error instanceof RestCallError) {
|
||||||
@Override
|
final List<APIMessage> errorMessages = ((RestCallError) error).getErrorMessages();
|
||||||
public void tableChanged(final ConfigurationTableValues tableValue) {
|
if (errorMessages.isEmpty()) {
|
||||||
this.restService.getBuilder(SaveExamConfigTableValues.class)
|
return "";
|
||||||
.withBody(tableValue)
|
}
|
||||||
.call();
|
|
||||||
}
|
final APIMessage apiMessage = errorMessages.get(0);
|
||||||
|
if (!ErrorMessage.FIELD_VALIDATION.isOf(apiMessage)) {
|
||||||
private String verifyErrorMessage(final Exception error) {
|
return "";
|
||||||
if (error instanceof RestCallError) {
|
}
|
||||||
final List<APIMessage> errorMessages = ((RestCallError) error).getErrorMessages();
|
|
||||||
if (errorMessages.isEmpty()) {
|
final FieldValidationError fieldValidationError = new FieldValidationError(apiMessage);
|
||||||
return "";
|
return this.pageContext.getI18nSupport().getText(new LocTextKey(
|
||||||
}
|
VALIDATION_ERROR_KEY_PREFIX + fieldValidationError.errorType,
|
||||||
|
(Object[]) fieldValidationError.getAttributes()));
|
||||||
final APIMessage apiMessage = errorMessages.get(0);
|
}
|
||||||
if (!ErrorMessage.FIELD_VALIDATION.isOf(apiMessage)) {
|
|
||||||
return "";
|
log.warn("Unexpected error happened while trying to set SEB configuration value: ", error);
|
||||||
}
|
return VALIDATION_ERROR_KEY_PREFIX + "unexpected";
|
||||||
|
}
|
||||||
final FieldValidationError fieldValidationError = new FieldValidationError(apiMessage);
|
|
||||||
return this.pageContext.getI18nSupport().getText(new LocTextKey(
|
@Override
|
||||||
VALIDATION_ERROR_KEY_PREFIX + fieldValidationError.errorType,
|
public void notifyGUI(
|
||||||
(Object[]) fieldValidationError.getAttributes()));
|
final ViewContext viewContext,
|
||||||
}
|
final ConfigurationAttribute attribute,
|
||||||
|
final ConfigurationValue value) {
|
||||||
log.warn("Unexpected error happened while trying to set SEB configuration value: ", error);
|
|
||||||
return VALIDATION_ERROR_KEY_PREFIX + "unexpected";
|
this.valueChangeRules.stream()
|
||||||
}
|
.filter(rule -> rule.observesAttribute(attribute))
|
||||||
|
.forEach(rule -> rule.applyRule(viewContext, attribute, value));
|
||||||
@Override
|
|
||||||
public void notifyGUI(
|
}
|
||||||
final ViewContext viewContext,
|
}
|
||||||
final ConfigurationAttribute attribute,
|
|
||||||
final ConfigurationValue value) {
|
}
|
||||||
|
|
||||||
this.valueChangeRules.stream()
|
|
||||||
.filter(rule -> rule.observesAttribute(attribute))
|
|
||||||
.forEach(rule -> rule.applyRule(viewContext, attribute, value));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,132 +1,130 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
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.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
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.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.GridTable;
|
import ch.ethz.seb.sebserver.gui.widget.GridTable;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.GridTable.ColumnDef;
|
import ch.ethz.seb.sebserver.gui.widget.GridTable.ColumnDef;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class InlineTableFieldBuilder implements InputFieldBuilder {
|
public class InlineTableFieldBuilder implements InputFieldBuilder {
|
||||||
|
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
|
|
||||||
protected InlineTableFieldBuilder(final WidgetFactory widgetFactory) {
|
protected InlineTableFieldBuilder(final WidgetFactory widgetFactory) {
|
||||||
this.widgetFactory = widgetFactory;
|
this.widgetFactory = widgetFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean builderFor(
|
public boolean builderFor(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
return attribute != null && attribute.type == AttributeType.INLINE_TABLE;
|
return attribute != null && attribute.type == AttributeType.INLINE_TABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputField createInputField(
|
public InputField createInputField(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
final Orientation orientation = viewContext
|
final Orientation orientation = viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
final Composite innerGrid = InputFieldBuilder
|
final Composite innerGrid = InputFieldBuilder
|
||||||
.createInnerGrid(parent, attribute, orientation);
|
.createInnerGrid(parent, attribute, orientation);
|
||||||
|
|
||||||
final Map<String, String> defaultValues = StringUtils.isBlank(attribute.defaultValue)
|
final Map<String, String> defaultValues = StringUtils.isBlank(attribute.defaultValue)
|
||||||
? Collections.emptyMap()
|
? Collections.emptyMap()
|
||||||
: Arrays.asList(StringUtils.split(
|
: Arrays.stream(StringUtils.split(
|
||||||
attribute.defaultValue,
|
attribute.defaultValue,
|
||||||
Constants.EMBEDDED_LIST_SEPARATOR))
|
Constants.EMBEDDED_LIST_SEPARATOR))
|
||||||
.stream()
|
.map(valueString -> StringUtils.split(
|
||||||
.map(valueString -> StringUtils.split(
|
valueString,
|
||||||
valueString,
|
Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR))
|
||||||
Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR))
|
.collect(Collectors.toMap(
|
||||||
.collect(Collectors.toMap(
|
valueMap -> valueMap[0],
|
||||||
valueMap -> valueMap[0],
|
valueMap -> (valueMap.length > 1) ? valueMap[1] : StringUtils.EMPTY));
|
||||||
valueMap -> (valueMap.length > 1) ? valueMap[1] : StringUtils.EMPTY));
|
|
||||||
|
final List<ColumnDef> columns = Arrays.stream(StringUtils.split(
|
||||||
final List<ColumnDef> columns = Arrays.asList(StringUtils.split(
|
attribute.getResources(),
|
||||||
attribute.getResources(),
|
Constants.EMBEDDED_LIST_SEPARATOR))
|
||||||
Constants.EMBEDDED_LIST_SEPARATOR))
|
.map(columnString -> ColumnDef.fromString(columnString, defaultValues))
|
||||||
.stream()
|
.collect(Collectors.toList());
|
||||||
.map(columnString -> ColumnDef.fromString(columnString, defaultValues))
|
|
||||||
.collect(Collectors.toList());
|
final GridTable gridTable = new GridTable(
|
||||||
|
innerGrid,
|
||||||
final GridTable gridTable = new GridTable(
|
columns,
|
||||||
innerGrid,
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + ".",
|
||||||
columns,
|
this.widgetFactory);
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + ".",
|
|
||||||
this.widgetFactory);
|
final InlineTableInputField inlineTableInputField = new InlineTableInputField(
|
||||||
|
attribute,
|
||||||
final InlineTableInputField inlineTableInputField = new InlineTableInputField(
|
viewContext.getOrientation(attribute.id),
|
||||||
attribute,
|
gridTable);
|
||||||
viewContext.getOrientation(attribute.id),
|
|
||||||
gridTable);
|
if (viewContext.readonly) {
|
||||||
|
gridTable.setEnabled(false);
|
||||||
if (viewContext.readonly) {
|
gridTable.setListener(event -> {
|
||||||
gridTable.setEnabled(false);
|
});
|
||||||
gridTable.setListener(event -> {
|
} else {
|
||||||
});
|
gridTable.setListener(event -> viewContext.getValueChangeListener().valueChanged(
|
||||||
} else {
|
viewContext,
|
||||||
gridTable.setListener(event -> viewContext.getValueChangeListener().valueChanged(
|
attribute,
|
||||||
viewContext,
|
inlineTableInputField.getValue(),
|
||||||
attribute,
|
inlineTableInputField.listIndex));
|
||||||
inlineTableInputField.getValue(),
|
}
|
||||||
inlineTableInputField.listIndex));
|
|
||||||
}
|
return inlineTableInputField;
|
||||||
|
|
||||||
return inlineTableInputField;
|
}
|
||||||
|
|
||||||
}
|
static final class InlineTableInputField extends AbstractInputField<GridTable> {
|
||||||
|
|
||||||
static final class InlineTableInputField extends AbstractInputField<GridTable> {
|
protected InlineTableInputField(
|
||||||
|
final ConfigurationAttribute attribute,
|
||||||
protected InlineTableInputField(
|
final Orientation orientation,
|
||||||
final ConfigurationAttribute attribute,
|
final GridTable control) {
|
||||||
final Orientation orientation,
|
|
||||||
final GridTable control) {
|
super(attribute, orientation, control, null);
|
||||||
|
}
|
||||||
super(attribute, orientation, control, null);
|
|
||||||
}
|
@Override
|
||||||
|
public String getValue() {
|
||||||
@Override
|
return this.control.getValue();
|
||||||
public String getValue() {
|
}
|
||||||
return this.control.getValue();
|
|
||||||
}
|
@Override
|
||||||
|
protected void setValueToControl(final String value) {
|
||||||
@Override
|
this.control.setValue(value);
|
||||||
protected void setValueToControl(final String value) {
|
}
|
||||||
this.control.setValue(value);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,47 +1,46 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
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.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class InputFieldBuilderSupplier {
|
public class InputFieldBuilderSupplier {
|
||||||
|
|
||||||
private final Collection<InputFieldBuilder> inputFieldBuilder;
|
private final Collection<InputFieldBuilder> inputFieldBuilder;
|
||||||
|
|
||||||
protected InputFieldBuilderSupplier(final Collection<InputFieldBuilder> inputFieldBuilder) {
|
protected InputFieldBuilderSupplier(final Collection<InputFieldBuilder> inputFieldBuilder) {
|
||||||
this.inputFieldBuilder = inputFieldBuilder;
|
this.inputFieldBuilder = inputFieldBuilder;
|
||||||
inputFieldBuilder
|
inputFieldBuilder
|
||||||
.stream()
|
.forEach(builder -> builder.init(this));
|
||||||
.forEach(builder -> builder.init(this));
|
}
|
||||||
}
|
|
||||||
|
public InputFieldBuilder getInputFieldBuilder(
|
||||||
public InputFieldBuilder getInputFieldBuilder(
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationAttribute attribute,
|
final Orientation orientation) {
|
||||||
final Orientation orientation) {
|
|
||||||
|
return this.inputFieldBuilder
|
||||||
return this.inputFieldBuilder
|
.stream()
|
||||||
.stream()
|
.filter(b -> b.builderFor(attribute, orientation))
|
||||||
.filter(b -> b.builderFor(attribute, orientation))
|
.findFirst()
|
||||||
.findFirst()
|
.orElseThrow(() -> new NoSuchElementException("No InputFieldBuilder found for : " + attribute.type));
|
||||||
.orElseThrow(() -> new NoSuchElementException("No InputFieldBuilder found for : " + attribute.type));
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,86 +1,86 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
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.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
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.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class LabelBuilder implements InputFieldBuilder {
|
public class LabelBuilder implements InputFieldBuilder {
|
||||||
|
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
|
|
||||||
protected LabelBuilder(final WidgetFactory widgetFactory) {
|
protected LabelBuilder(final WidgetFactory widgetFactory) {
|
||||||
this.widgetFactory = widgetFactory;
|
this.widgetFactory = widgetFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean builderFor(
|
public boolean builderFor(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return attribute.type == AttributeType.LABEL;
|
return attribute.type == AttributeType.LABEL;
|
||||||
};
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputField createInputField(
|
public InputField createInputField(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
final Label label = this.widgetFactory.labelLocalized(
|
final Label label = this.widgetFactory.labelLocalized(
|
||||||
parent,
|
parent,
|
||||||
ExamConfigurationService.attributeNameLocKey(attribute));
|
ExamConfigurationService.attributeNameLocKey(attribute));
|
||||||
|
|
||||||
return new LabelField(
|
return new LabelField(
|
||||||
attribute,
|
attribute,
|
||||||
viewContext.getOrientation(attribute.id),
|
viewContext.getOrientation(attribute.id),
|
||||||
label);
|
label);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class LabelField extends AbstractInputField<Label> {
|
static final class LabelField extends AbstractInputField<Label> {
|
||||||
|
|
||||||
LabelField(
|
LabelField(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation,
|
final Orientation orientation,
|
||||||
final Label control) {
|
final Label control) {
|
||||||
|
|
||||||
super(attribute, orientation, control, null);
|
super(attribute, orientation, control, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setValueToControl(final String value) {
|
protected void setValueToControl(final String value) {
|
||||||
// Does Nothing, Label has no default value
|
// Does Nothing, Label has no default value
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return this.control.getText();
|
return this.control.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ public class PasswordFieldBuilder implements InputFieldBuilder {
|
||||||
final CharSequence pwd = passwordInput.getValue();
|
final CharSequence pwd = passwordInput.getValue();
|
||||||
final CharSequence confirm = confirmInput.getValue();
|
final CharSequence confirm = confirmInput.getValue();
|
||||||
|
|
||||||
if (passwordInputField.initValue != null && passwordInputField.initValue.equals(pwd)) {
|
if (passwordInputField.initValue != null && passwordInputField.initValue.contentEquals(pwd)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,75 +1,74 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ExamConfigurationService;
|
||||||
|
|
||||||
public abstract class SelectionFieldBuilder {
|
public abstract class SelectionFieldBuilder {
|
||||||
|
|
||||||
protected List<Tuple<String>> getLocalizedResources(
|
protected List<Tuple<String>> getLocalizedResources(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
return getLocalizedRes(attribute, viewContext, false);
|
return getLocalizedRes(attribute, viewContext, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Tuple<String>> getLocalizedResourcesAsToolTip(
|
protected List<Tuple<String>> getLocalizedResourcesAsToolTip(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
return getLocalizedRes(attribute, viewContext, true);
|
return getLocalizedRes(attribute, viewContext, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Tuple<String>> getLocalizedRes(
|
private List<Tuple<String>> getLocalizedRes(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext,
|
final ViewContext viewContext,
|
||||||
final boolean toolTipResources) {
|
final boolean toolTipResources) {
|
||||||
|
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final String prefix =
|
final String prefix =
|
||||||
(ConfigurationAttribute.hasDependency(
|
(ConfigurationAttribute.hasDependency(
|
||||||
ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY,
|
ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY,
|
||||||
attribute))
|
attribute))
|
||||||
? ConfigurationAttribute.getDependencyValue(
|
? ConfigurationAttribute.getDependencyValue(
|
||||||
ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY,
|
ConfigurationAttribute.DEPENDENCY_RESOURCE_LOC_TEXT_KEY,
|
||||||
attribute) + "."
|
attribute) + "."
|
||||||
: ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + ".";
|
: ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX + attribute.name + ".";
|
||||||
|
|
||||||
return Arrays.asList(StringUtils.split(
|
return Arrays.stream(StringUtils.split(
|
||||||
attribute.resources,
|
attribute.resources,
|
||||||
Constants.LIST_SEPARATOR))
|
Constants.LIST_SEPARATOR))
|
||||||
.stream()
|
.map(value -> {
|
||||||
.map(value -> {
|
final String key = prefix + value + ((toolTipResources)
|
||||||
final String key = prefix + value + ((toolTipResources)
|
? ExamConfigurationService.TOOL_TIP_SUFFIX
|
||||||
? ExamConfigurationService.TOOL_TIP_SUFFIX
|
: "");
|
||||||
: "");
|
final String text = viewContext.i18nSupport.getText(key, "");
|
||||||
final String text = viewContext.i18nSupport.getText(key, "");
|
return new Tuple<>(value, (StringUtils.isBlank(text))
|
||||||
return new Tuple<>(value, (StringUtils.isBlank(text))
|
? (toolTipResources)
|
||||||
? (toolTipResources)
|
? text
|
||||||
? text
|
: value
|
||||||
: value
|
: text);
|
||||||
: text);
|
})
|
||||||
})
|
.collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,226 +1,224 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Table;
|
import org.eclipse.swt.widgets.Table;
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
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.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
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.page.impl.ModalInputDialog;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class TableFieldBuilder extends AbstractTableFieldBuilder {
|
public class TableFieldBuilder extends AbstractTableFieldBuilder {
|
||||||
|
|
||||||
private static final String TOOLTIP_SUFFIX = ".tooltip";
|
private static final String TOOLTIP_SUFFIX = ".tooltip";
|
||||||
private static final String ADD_TOOLTIP_SUFFIX = ".add" + TOOLTIP_SUFFIX;
|
private static final String ADD_TOOLTIP_SUFFIX = ".add" + TOOLTIP_SUFFIX;
|
||||||
private static final String REMOVE_TOOLTIP_SUFFIX = ".remove" + TOOLTIP_SUFFIX;
|
private static final String REMOVE_TOOLTIP_SUFFIX = ".remove" + TOOLTIP_SUFFIX;
|
||||||
|
|
||||||
protected TableFieldBuilder(
|
protected TableFieldBuilder(
|
||||||
final RestService restService,
|
final RestService restService,
|
||||||
final WidgetFactory widgetFactory) {
|
final WidgetFactory widgetFactory) {
|
||||||
|
|
||||||
super(restService, widgetFactory);
|
super(restService, widgetFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean builderFor(
|
public boolean builderFor(
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final Orientation orientation) {
|
final Orientation orientation) {
|
||||||
|
|
||||||
if (attribute == null) {
|
if (attribute == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AttributeType.TABLE == attribute.type;
|
return AttributeType.TABLE == attribute.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputField createInputField(
|
public InputField createInputField(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ViewContext viewContext) {
|
final ViewContext viewContext) {
|
||||||
|
|
||||||
final TableContext tableContext = createTableContext(attribute, viewContext);
|
final TableContext tableContext = createTableContext(attribute, viewContext);
|
||||||
final Table table = createTable(parent, tableContext);
|
final Table table = createTable(parent, tableContext);
|
||||||
|
|
||||||
for (final ConfigurationAttribute columnAttribute : tableContext.getColumnAttributes()) {
|
for (final ConfigurationAttribute columnAttribute : tableContext.getColumnAttributes()) {
|
||||||
final TableColumn column = this.widgetFactory.tableColumnLocalized(
|
final TableColumn column = this.widgetFactory.tableColumnLocalized(
|
||||||
table,
|
table,
|
||||||
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
columnAttribute.name),
|
columnAttribute.name),
|
||||||
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
new LocTextKey(ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
columnAttribute.name +
|
columnAttribute.name +
|
||||||
TOOLTIP_SUFFIX));
|
TOOLTIP_SUFFIX));
|
||||||
column.setWidth(100);
|
column.setWidth(100);
|
||||||
column.setResizable(false);
|
column.setResizable(false);
|
||||||
column.setMoveable(false);
|
column.setMoveable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
final TableInputField tableField = new TableInputField(
|
final TableInputField tableField = new TableInputField(
|
||||||
tableContext,
|
tableContext,
|
||||||
table);
|
table);
|
||||||
if (!viewContext.readonly) {
|
if (!viewContext.readonly) {
|
||||||
TableColumn column = new TableColumn(table, SWT.NONE);
|
TableColumn column = new TableColumn(table, SWT.NONE);
|
||||||
column.setImage(ImageIcon.ADD_BOX_WHITE.getImage(parent.getDisplay()));
|
column.setImage(ImageIcon.ADD_BOX_WHITE.getImage(parent.getDisplay()));
|
||||||
column.setToolTipText(Utils.formatLineBreaks(viewContext.i18nSupport.getText(
|
column.setToolTipText(Utils.formatLineBreaks(viewContext.i18nSupport.getText(
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
attribute.name +
|
attribute.name +
|
||||||
ADD_TOOLTIP_SUFFIX,
|
ADD_TOOLTIP_SUFFIX,
|
||||||
"Add new")));
|
"Add new")));
|
||||||
column.setWidth(20);
|
column.setWidth(20);
|
||||||
column.setResizable(false);
|
column.setResizable(false);
|
||||||
column.setMoveable(false);
|
column.setMoveable(false);
|
||||||
|
|
||||||
column.addListener(SWT.Selection, event -> {
|
column.addListener(SWT.Selection, event -> tableField.addRow());
|
||||||
tableField.addRow();
|
|
||||||
});
|
column = new TableColumn(table, SWT.NONE);
|
||||||
|
column.setImage(ImageIcon.REMOVE_BOX_WHITE.getImage(parent.getDisplay()));
|
||||||
column = new TableColumn(table, SWT.NONE);
|
column.setToolTipText(Utils.formatLineBreaks(viewContext.i18nSupport.getText(
|
||||||
column.setImage(ImageIcon.REMOVE_BOX_WHITE.getImage(parent.getDisplay()));
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
column.setToolTipText(Utils.formatLineBreaks(viewContext.i18nSupport.getText(
|
attribute.name +
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
REMOVE_TOOLTIP_SUFFIX,
|
||||||
attribute.name +
|
"Remove Selected")));
|
||||||
REMOVE_TOOLTIP_SUFFIX,
|
column.setWidth(20);
|
||||||
"Remove Selected")));
|
column.setResizable(false);
|
||||||
column.setWidth(20);
|
column.setMoveable(false);
|
||||||
column.setResizable(false);
|
|
||||||
column.setMoveable(false);
|
column.addListener(SWT.Selection, event -> {
|
||||||
|
final int selectionIndex = table.getSelectionIndex();
|
||||||
column.addListener(SWT.Selection, event -> {
|
if (selectionIndex >= 0) {
|
||||||
final int selectionIndex = table.getSelectionIndex();
|
tableField.deleteRow(selectionIndex);
|
||||||
if (selectionIndex >= 0) {
|
}
|
||||||
tableField.deleteRow(selectionIndex);
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
setSelectionListener(table, tableField);
|
||||||
|
return tableField;
|
||||||
setSelectionListener(table, tableField);
|
}
|
||||||
return tableField;
|
|
||||||
}
|
static final class TableInputField extends AbstractTableInputField {
|
||||||
|
|
||||||
static final class TableInputField extends AbstractTableInputField {
|
private final List<Map<Long, TableValue>> values;
|
||||||
|
|
||||||
private final List<Map<Long, TableValue>> values;
|
TableInputField(
|
||||||
|
final TableContext tableContext,
|
||||||
TableInputField(
|
final Table control) {
|
||||||
final TableContext tableContext,
|
|
||||||
final Table control) {
|
super(tableContext.attribute, tableContext.orientation, control, null, tableContext);
|
||||||
|
this.values = new ArrayList<>();
|
||||||
super(tableContext.attribute, tableContext.orientation, control, null, tableContext);
|
}
|
||||||
this.values = new ArrayList<>();
|
|
||||||
}
|
@Override
|
||||||
|
void initValue(final List<TableValue> tableValues) {
|
||||||
@Override
|
valuesFromIndexMap(this.values, createRowIndexMap(tableValues));
|
||||||
void initValue(final List<TableValue> tableValues) {
|
for (int i = 0; i < this.values.size(); i++) {
|
||||||
valuesFromIndexMap(this.values, createRowIndexMap(tableValues));
|
addTableRow(i, this.values.get(i));
|
||||||
for (int i = 0; i < this.values.size(); i++) {
|
}
|
||||||
addTableRow(i, this.values.get(i));
|
}
|
||||||
}
|
|
||||||
}
|
private void deleteRow(final int selectionIndex) {
|
||||||
|
this.control.remove(selectionIndex);
|
||||||
private void deleteRow(final int selectionIndex) {
|
this.values.remove(selectionIndex);
|
||||||
this.control.remove(selectionIndex);
|
// send new values to web-service
|
||||||
this.values.remove(selectionIndex);
|
this.tableContext.getValueChangeListener()
|
||||||
// send new values to web-service
|
.tableChanged(extractTableValue(this.values));
|
||||||
this.tableContext.getValueChangeListener()
|
}
|
||||||
.tableChanged(extractTableValue(this.values));
|
|
||||||
}
|
private void addRow() {
|
||||||
|
final int index = this.values.size();
|
||||||
private void addRow() {
|
// create new values form default values
|
||||||
final int index = this.values.size();
|
final Map<Long, TableValue> rowValues = this.tableContext.getRowAttributes()
|
||||||
// create new values form default values
|
.stream()
|
||||||
final Map<Long, TableValue> rowValues = this.tableContext.getRowAttributes()
|
.map(attr -> new TableValue(attr.id, index, attr.defaultValue))
|
||||||
.stream()
|
.collect(Collectors.toMap(
|
||||||
.map(attr -> new TableValue(attr.id, index, attr.defaultValue))
|
tv -> tv.attributeId,
|
||||||
.collect(Collectors.toMap(
|
Function.identity()));
|
||||||
tv -> tv.attributeId,
|
|
||||||
Function.identity()));
|
this.values.add(rowValues);
|
||||||
|
addTableRow(this.values.size() - 1, rowValues);
|
||||||
this.values.add(rowValues);
|
this.control.layout();
|
||||||
addTableRow(this.values.size() - 1, rowValues);
|
// send new values to web-service
|
||||||
this.control.layout();
|
this.tableContext.getValueChangeListener()
|
||||||
// send new values to web-service
|
.tableChanged(extractTableValue(this.values));
|
||||||
this.tableContext.getValueChangeListener()
|
}
|
||||||
.tableChanged(extractTableValue(this.values));
|
|
||||||
}
|
protected void addTableRow(final int index, final Map<Long, TableValue> rowValues) {
|
||||||
|
new TableItem(this.control, SWT.NONE);
|
||||||
protected void addTableRow(final int index, final Map<Long, TableValue> rowValues) {
|
applyTableRowValues(index);
|
||||||
new TableItem(this.control, SWT.NONE);
|
}
|
||||||
applyTableRowValues(index);
|
|
||||||
}
|
@Override
|
||||||
|
protected void applyTableRowValues(final int index) {
|
||||||
@Override
|
final TableItem item = this.control.getItem(index);
|
||||||
protected void applyTableRowValues(final int index) {
|
final Map<Long, TableValue> rowValues = this.values.get(index);
|
||||||
final TableItem item = this.control.getItem(index);
|
|
||||||
final Map<Long, TableValue> rowValues = this.values.get(index);
|
int cellIndex = 0;
|
||||||
|
for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) {
|
||||||
int cellIndex = 0;
|
if (rowValues.containsKey(attr.id)) {
|
||||||
for (final ConfigurationAttribute attr : this.tableContext.getColumnAttributes()) {
|
final TableValue tableValue = rowValues.get(attr.id);
|
||||||
if (rowValues.containsKey(attr.id)) {
|
setValueToCell(this.tableContext, item, cellIndex, attr, tableValue);
|
||||||
final TableValue tableValue = rowValues.get(attr.id);
|
}
|
||||||
setValueToCell(this.tableContext, item, cellIndex, attr, tableValue);
|
cellIndex++;
|
||||||
}
|
}
|
||||||
cellIndex++;
|
}
|
||||||
}
|
|
||||||
}
|
@Override
|
||||||
|
protected void openForm(final int selectionIndex) {
|
||||||
@Override
|
final Map<Long, TableValue> rowValues = this.values.get(selectionIndex);
|
||||||
protected void openForm(final int selectionIndex) {
|
final TableRowFormBuilder builder = new TableRowFormBuilder(
|
||||||
final Map<Long, TableValue> rowValues = this.values.get(selectionIndex);
|
this.tableContext,
|
||||||
final TableRowFormBuilder builder = new TableRowFormBuilder(
|
rowValues,
|
||||||
this.tableContext,
|
selectionIndex);
|
||||||
rowValues,
|
|
||||||
selectionIndex);
|
new ModalInputDialog<Map<Long, TableValue>>(
|
||||||
|
this.control.getShell(),
|
||||||
new ModalInputDialog<Map<Long, TableValue>>(
|
this.tableContext.getWidgetFactory())
|
||||||
this.control.getShell(),
|
.setDialogWidth(600)
|
||||||
this.tableContext.getWidgetFactory())
|
.setDialogHeight(550)
|
||||||
.setDialogWidth(600)
|
.open(
|
||||||
.setDialogHeight(550)
|
ExamConfigurationService.getTablePopupTitleKey(
|
||||||
.open(
|
this.attribute,
|
||||||
ExamConfigurationService.getTablePopupTitleKey(
|
this.tableContext.getViewContext().i18nSupport),
|
||||||
this.attribute,
|
(Consumer<Map<Long, TableValue>>) _rowValues -> applyFormValues(
|
||||||
this.tableContext.getViewContext().i18nSupport),
|
this.values,
|
||||||
(Consumer<Map<Long, TableValue>>) rowVals -> applyFormValues(
|
_rowValues,
|
||||||
this.values,
|
selectionIndex),
|
||||||
rowVals,
|
() -> this.tableContext.getValueChangeListener()
|
||||||
selectionIndex),
|
.tableChanged(extractTableValue(this.values)),
|
||||||
() -> this.tableContext.getValueChangeListener()
|
builder);
|
||||||
.tableChanged(extractTableValue(this.values)),
|
}
|
||||||
builder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,162 +1,160 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
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.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationTableValues.TableValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
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.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.ModalInputDialogComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
|
|
||||||
public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, TableValue>> {
|
public class TableRowFormBuilder implements ModalInputDialogComposer<Map<Long, TableValue>> {
|
||||||
|
|
||||||
private final TableContext tableContext;
|
private final TableContext tableContext;
|
||||||
private final Map<Long, TableValue> rowValues;
|
private final Map<Long, TableValue> rowValues;
|
||||||
private final int listIndex;
|
private final int listIndex;
|
||||||
private final String rowGroupId;
|
private final String rowGroupId;
|
||||||
|
|
||||||
public TableRowFormBuilder(
|
public TableRowFormBuilder(
|
||||||
final TableContext tableContext,
|
final TableContext tableContext,
|
||||||
final Map<Long, TableValue> rowValues,
|
final Map<Long, TableValue> rowValues,
|
||||||
final int listIndex) {
|
final int listIndex) {
|
||||||
|
|
||||||
this.tableContext = tableContext;
|
this.tableContext = tableContext;
|
||||||
this.rowValues = rowValues;
|
this.rowValues = rowValues;
|
||||||
this.listIndex = listIndex;
|
this.listIndex = listIndex;
|
||||||
this.rowGroupId = null;
|
this.rowGroupId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableRowFormBuilder(
|
public TableRowFormBuilder(
|
||||||
final TableContext tableContext,
|
final TableContext tableContext,
|
||||||
final Map<Long, TableValue> rowValues,
|
final Map<Long, TableValue> rowValues,
|
||||||
final String rowGroupId) {
|
final String rowGroupId) {
|
||||||
|
|
||||||
this.tableContext = tableContext;
|
this.tableContext = tableContext;
|
||||||
this.rowValues = rowValues;
|
this.rowValues = rowValues;
|
||||||
this.listIndex = 0;
|
this.listIndex = 0;
|
||||||
this.rowGroupId = rowGroupId;
|
this.rowGroupId = rowGroupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Supplier<Map<Long, TableValue>> compose(final Composite parent) {
|
public Supplier<Map<Long, TableValue>> compose(final Composite parent) {
|
||||||
|
|
||||||
final Composite grid = PageService.createManagedVScrolledComposite(
|
final Composite grid = PageService.createManagedVScrolledComposite(
|
||||||
parent,
|
parent,
|
||||||
scrolledComposite -> {
|
scrolledComposite -> {
|
||||||
final Composite result = this.tableContext
|
final Composite result = this.tableContext
|
||||||
.getWidgetFactory()
|
.getWidgetFactory()
|
||||||
.formGrid(scrolledComposite, 2);
|
.formGrid(scrolledComposite, 2);
|
||||||
final GridLayout layout = (GridLayout) result.getLayout();
|
final GridLayout layout = (GridLayout) result.getLayout();
|
||||||
layout.verticalSpacing = 0;
|
layout.verticalSpacing = 0;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
|
|
||||||
final List<InputField> inputFields = new ArrayList<>();
|
final List<InputField> inputFields = new ArrayList<>();
|
||||||
for (final ConfigurationAttribute attribute : this.tableContext.getRowAttributes(this.rowGroupId)) {
|
for (final ConfigurationAttribute attribute : this.tableContext.getRowAttributes(this.rowGroupId)) {
|
||||||
createLabel(grid, attribute);
|
createLabel(grid, attribute);
|
||||||
inputFields.add(createInputField(grid, attribute));
|
inputFields.add(createInputField(grid, attribute));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final InputField inputField : inputFields) {
|
for (final InputField inputField : inputFields) {
|
||||||
final ConfigurationAttribute attribute = inputField.getAttribute();
|
final ConfigurationAttribute attribute = inputField.getAttribute();
|
||||||
this.tableContext.getValueChangeListener().notifyGUI(
|
this.tableContext.getValueChangeListener().notifyGUI(
|
||||||
this.tableContext.getViewContext(),
|
this.tableContext.getViewContext(),
|
||||||
attribute,
|
attribute,
|
||||||
new ConfigurationValue(
|
new ConfigurationValue(
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
attribute.id,
|
attribute.id,
|
||||||
this.listIndex,
|
this.listIndex,
|
||||||
inputField.getValue()));
|
inputField.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// when the pop-up gets closed we have to remove the input fields from the view context
|
// when the pop-up gets closed we have to remove the input fields from the view context
|
||||||
grid.addDisposeListener(event -> {
|
grid.addDisposeListener(event -> this.tableContext.flushInputFields(this.rowValues.keySet()));
|
||||||
this.tableContext.flushInputFields(this.rowValues.keySet());
|
|
||||||
});
|
return () -> inputFields.stream()
|
||||||
|
.map(field -> (field.hasError())
|
||||||
return () -> inputFields.stream()
|
? this.rowValues.get(field.getAttribute().id)
|
||||||
.map(field -> (field.hasError())
|
: new TableValue(
|
||||||
? this.rowValues.get(field.getAttribute().id)
|
field.getAttribute().id,
|
||||||
: new TableValue(
|
this.listIndex,
|
||||||
field.getAttribute().id,
|
field.getValue()))
|
||||||
this.listIndex,
|
.collect(Collectors.toMap(
|
||||||
field.getValue()))
|
tv -> tv.attributeId,
|
||||||
.collect(Collectors.toMap(
|
Function.identity()));
|
||||||
tv -> tv.attributeId,
|
}
|
||||||
Function.identity()));
|
|
||||||
}
|
private InputField createInputField(
|
||||||
|
final Composite parent,
|
||||||
private InputField createInputField(
|
final ConfigurationAttribute attribute) {
|
||||||
final Composite parent,
|
|
||||||
final ConfigurationAttribute attribute) {
|
if (attribute.type == AttributeType.TABLE) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
if (attribute.type == AttributeType.TABLE) {
|
"Table type is currently not supported within a table row form view!");
|
||||||
throw new UnsupportedOperationException(
|
}
|
||||||
"Table type is currently not supported within a table row form view!");
|
|
||||||
}
|
final Orientation orientation = this.tableContext
|
||||||
|
.getOrientation(attribute.id);
|
||||||
final Orientation orientation = this.tableContext
|
final InputFieldBuilder inputFieldBuilder = this.tableContext
|
||||||
.getOrientation(attribute.id);
|
.getInputFieldBuilder(attribute, orientation);
|
||||||
final InputFieldBuilder inputFieldBuilder = this.tableContext
|
final InputField inputField = inputFieldBuilder.createInputField(
|
||||||
.getInputFieldBuilder(attribute, orientation);
|
parent,
|
||||||
final InputField inputField = inputFieldBuilder.createInputField(
|
attribute,
|
||||||
parent,
|
this.tableContext.getViewContext());
|
||||||
attribute,
|
|
||||||
this.tableContext.getViewContext());
|
final TableValue initValue = this.rowValues.get(attribute.id);
|
||||||
|
inputField.initValue((initValue != null) ? initValue.value : null, this.listIndex);
|
||||||
final TableValue initValue = this.rowValues.get(attribute.id);
|
// we have to register the input field within the ViewContext to receive error messages
|
||||||
inputField.initValue((initValue != null) ? initValue.value : null, this.listIndex);
|
this.tableContext.registerInputField(inputField);
|
||||||
// we have to register the input field within the ViewContext to receive error messages
|
|
||||||
this.tableContext.registerInputField(inputField);
|
return inputField;
|
||||||
|
}
|
||||||
return inputField;
|
|
||||||
}
|
private void createLabel(
|
||||||
|
final Composite parent,
|
||||||
private void createLabel(
|
final ConfigurationAttribute attribute) {
|
||||||
final Composite parent,
|
|
||||||
final ConfigurationAttribute attribute) {
|
final LocTextKey locTextKey = new LocTextKey(
|
||||||
|
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
||||||
final LocTextKey locTextKey = new LocTextKey(
|
attribute.name,
|
||||||
ExamConfigurationService.ATTRIBUTE_LABEL_LOC_TEXT_PREFIX +
|
attribute.name);
|
||||||
attribute.name,
|
final Label label = this.tableContext
|
||||||
attribute.name);
|
.getWidgetFactory()
|
||||||
final Label label = this.tableContext
|
.labelLocalized(parent, locTextKey);
|
||||||
.getWidgetFactory()
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
.labelLocalized(parent, locTextKey);
|
gridData.verticalIndent = 4;
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
label.setLayoutData(gridData);
|
||||||
gridData.verticalIndent = 4;
|
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.TITLE_LABEL.key);
|
||||||
label.setLayoutData(gridData);
|
}
|
||||||
label.setData(RWT.CUSTOM_VARIANT, CustomVariant.TITLE_LABEL.key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,250 +1,248 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Configuration;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.View;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputField;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.ValueChangeListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||||
|
|
||||||
public final class ViewContext {
|
public final class ViewContext {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ViewContext.class);
|
private static final Logger log = LoggerFactory.getLogger(ViewContext.class);
|
||||||
|
|
||||||
private final Configuration configuration;
|
private final Configuration configuration;
|
||||||
private final View view;
|
private final View view;
|
||||||
private final int rows;
|
private final int rows;
|
||||||
|
|
||||||
final AttributeMapping attributeMapping;
|
final AttributeMapping attributeMapping;
|
||||||
final Map<Long, InputField> inputFieldMapping;
|
final Map<Long, InputField> inputFieldMapping;
|
||||||
final ValueChangeListener valueChangeListener;
|
final ValueChangeListener valueChangeListener;
|
||||||
final I18nSupport i18nSupport;
|
final I18nSupport i18nSupport;
|
||||||
final boolean readonly;
|
final boolean readonly;
|
||||||
|
|
||||||
ViewContext(
|
ViewContext(
|
||||||
final Configuration configuration,
|
final Configuration configuration,
|
||||||
final View view,
|
final View view,
|
||||||
final int rows,
|
final int rows,
|
||||||
final AttributeMapping attributeContext,
|
final AttributeMapping attributeContext,
|
||||||
final ValueChangeListener valueChangeListener,
|
final ValueChangeListener valueChangeListener,
|
||||||
final I18nSupport i18nSupport,
|
final I18nSupport i18nSupport,
|
||||||
final boolean readonly) {
|
final boolean readonly) {
|
||||||
|
|
||||||
Objects.requireNonNull(configuration);
|
Objects.requireNonNull(configuration);
|
||||||
Objects.requireNonNull(view);
|
Objects.requireNonNull(view);
|
||||||
Objects.requireNonNull(attributeContext);
|
Objects.requireNonNull(attributeContext);
|
||||||
Objects.requireNonNull(valueChangeListener);
|
Objects.requireNonNull(valueChangeListener);
|
||||||
|
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
|
|
||||||
this.attributeMapping = attributeContext;
|
this.attributeMapping = attributeContext;
|
||||||
this.inputFieldMapping = new HashMap<>();
|
this.inputFieldMapping = new HashMap<>();
|
||||||
this.valueChangeListener = valueChangeListener;
|
this.valueChangeListener = valueChangeListener;
|
||||||
this.i18nSupport = i18nSupport;
|
this.i18nSupport = i18nSupport;
|
||||||
this.readonly = readonly;
|
this.readonly = readonly;
|
||||||
}
|
}
|
||||||
|
|
||||||
public I18nSupport getI18nSupport() {
|
public I18nSupport getI18nSupport() {
|
||||||
return this.i18nSupport;
|
return this.i18nSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return this.view.id;
|
return this.view.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.view.name;
|
return this.view.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getConfigurationId() {
|
public Long getConfigurationId() {
|
||||||
return this.configuration.id;
|
return this.configuration.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getInstitutionId() {
|
public Long getInstitutionId() {
|
||||||
return this.configuration.institutionId;
|
return this.configuration.institutionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getColumns() {
|
public int getColumns() {
|
||||||
return this.view.columns;
|
return this.view.columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRows() {
|
public int getRows() {
|
||||||
return this.rows;
|
return this.rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Configuration getConfiguration() {
|
public Configuration getConfiguration() {
|
||||||
return this.configuration;
|
return this.configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public View getView() {
|
public View getView() {
|
||||||
return this.view;
|
return this.view;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ConfigurationAttribute> getChildAttributes(final Long id) {
|
public Collection<ConfigurationAttribute> getChildAttributes(final Long id) {
|
||||||
return this.attributeMapping.childAttributeMapping.get(id);
|
return this.attributeMapping.childAttributeMapping.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ConfigurationAttribute> getAttributes() {
|
public Collection<ConfigurationAttribute> getAttributes() {
|
||||||
return this.attributeMapping.getAttributes();
|
return this.attributeMapping.getAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationAttribute getAttribute(final Long attributeId) {
|
public ConfigurationAttribute getAttribute(final Long attributeId) {
|
||||||
return this.attributeMapping.getAttribute(attributeId);
|
return this.attributeMapping.getAttribute(attributeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getAttributeIdByName(final String name) {
|
public Long getAttributeIdByName(final String name) {
|
||||||
return this.attributeMapping.attributeNameIdMapping.get(name);
|
return this.attributeMapping.attributeNameIdMapping.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfigurationAttribute getAttributeByName(final String name) {
|
public ConfigurationAttribute getAttributeByName(final String name) {
|
||||||
final Long attributeId = this.attributeMapping.attributeNameIdMapping.get(name);
|
final Long attributeId = this.attributeMapping.attributeNameIdMapping.get(name);
|
||||||
if (attributeId != null) {
|
if (attributeId != null) {
|
||||||
return getAttribute(attributeId);
|
return getAttribute(attributeId);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Orientation> getOrientationsOfGroup(final ConfigurationAttribute attribute) {
|
public Collection<Orientation> getOrientationsOfGroup(final ConfigurationAttribute attribute) {
|
||||||
return this.attributeMapping.getOrientationsOfGroup(attribute);
|
return this.attributeMapping.getOrientationsOfGroup(attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Orientation getOrientation(final Long attributeId) {
|
public Orientation getOrientation(final Long attributeId) {
|
||||||
return this.attributeMapping.getOrientation(attributeId);
|
return this.attributeMapping.getOrientation(attributeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueChangeListener getValueChangeListener() {
|
public ValueChangeListener getValueChangeListener() {
|
||||||
return this.valueChangeListener;
|
return this.valueChangeListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disable(final String attributeName) {
|
public void disable(final String attributeName) {
|
||||||
disable(this.getAttributeIdByName(attributeName));
|
disable(this.getAttributeIdByName(attributeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disable(final Long attributeId) {
|
public void disable(final Long attributeId) {
|
||||||
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
||||||
if (inputField == null) {
|
if (inputField == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField.disable(false);
|
inputField.disable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enable(final String attributeName) {
|
public void enable(final String attributeName) {
|
||||||
enable(this.getAttributeIdByName(attributeName));
|
enable(this.getAttributeIdByName(attributeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enable(final Long attributeId) {
|
public void enable(final Long attributeId) {
|
||||||
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
||||||
if (inputField == null) {
|
if (inputField == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField.enable(false);
|
inputField.enable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disableGroup(final String attributeName) {
|
public void disableGroup(final String attributeName) {
|
||||||
disableGroup(this.getAttributeIdByName(attributeName));
|
disableGroup(this.getAttributeIdByName(attributeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disableGroup(final Long attributeId) {
|
public void disableGroup(final Long attributeId) {
|
||||||
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
||||||
if (inputField == null) {
|
if (inputField == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField.disable(true);
|
inputField.disable(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.attributeMapping.attributeGroupMapping
|
this.attributeMapping.attributeGroupMapping
|
||||||
.get(inputField.getOrientation().groupId)
|
.get(inputField.getOrientation().groupId)
|
||||||
.stream()
|
.stream()
|
||||||
.map(ConfigurationAttribute::getId)
|
.map(ConfigurationAttribute::getId)
|
||||||
.map(this.inputFieldMapping::get)
|
.map(this.inputFieldMapping::get)
|
||||||
.forEach(InputField::setDefaultValue);
|
.forEach(InputField::setDefaultValue);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.warn("Failed to send attribute value update to server: ", e);
|
log.warn("Failed to send attribute value update to server: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableGroup(final String attributeName) {
|
public void enableGroup(final String attributeName) {
|
||||||
enableGroup(this.getAttributeIdByName(attributeName));
|
enableGroup(this.getAttributeIdByName(attributeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableGroup(final Long attributeId) {
|
public void enableGroup(final Long attributeId) {
|
||||||
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
||||||
if (inputField == null) {
|
if (inputField == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField.enable(true);
|
inputField.enable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showError(final Long attributeId, final String errorMessage) {
|
public void showError(final Long attributeId, final String errorMessage) {
|
||||||
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
||||||
if (inputField == null) {
|
if (inputField == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField.showError(errorMessage);
|
inputField.showError(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearError(final Long attributeId) {
|
public void clearError(final Long attributeId) {
|
||||||
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
final InputField inputField = this.inputFieldMapping.get(attributeId);
|
||||||
if (inputField == null) {
|
if (inputField == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
inputField.clearError();
|
inputField.clearError();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerInputField(final InputField inputField) {
|
public void registerInputField(final InputField inputField) {
|
||||||
this.inputFieldMapping.put(
|
this.inputFieldMapping.put(
|
||||||
inputField.getAttribute().id,
|
inputField.getAttribute().id,
|
||||||
inputField);
|
inputField);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setValuesToInputFields(final Collection<ConfigurationValue> values) {
|
void setValuesToInputFields(final Collection<ConfigurationValue> values) {
|
||||||
this.inputFieldMapping
|
this.inputFieldMapping
|
||||||
.values()
|
.values()
|
||||||
.stream()
|
.forEach(field -> {
|
||||||
.forEach(field -> {
|
final ConfigurationValue initValue = field.initValue(values);
|
||||||
final ConfigurationValue initValue = field.initValue(values);
|
if (initValue != null) {
|
||||||
if (initValue != null) {
|
this.valueChangeListener.notifyGUI(this, field.getAttribute(), initValue);
|
||||||
this.valueChangeListener.notifyGUI(this, field.getAttribute(), initValue);
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
/** Removes all registered InputFields with the given attribute ids
|
||||||
/** Removes all registered InputFields with the given attribute ids
|
*
|
||||||
*
|
* @param values Collection of attribute ids */
|
||||||
* @param values Collection of attribute ids */
|
void flushInputFields(final Collection<Long> values) {
|
||||||
void flushInputFields(final Collection<Long> values) {
|
if (values == null) {
|
||||||
if (values == null) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
values.forEach(this.inputFieldMapping::remove);
|
||||||
values.stream()
|
}
|
||||||
.forEach(attrId -> this.inputFieldMapping.remove(attrId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,213 +1,213 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.layout.GridData;
|
import org.eclipse.swt.layout.GridData;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
|
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.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Orientation;
|
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.ExamConfigurationService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.InputFieldBuilder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.CellFieldBuilderAdapter.GroupCellFieldBuilderAdapter;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.CellFieldBuilderAdapter.GroupCellFieldBuilderAdapter;
|
||||||
|
|
||||||
public class ViewGridBuilder {
|
public class ViewGridBuilder {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ViewGridBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(ViewGridBuilder.class);
|
||||||
|
|
||||||
final ExamConfigurationService examConfigurationService;
|
final ExamConfigurationService examConfigurationService;
|
||||||
final Composite parent;
|
final Composite parent;
|
||||||
final ViewContext viewContext;
|
final ViewContext viewContext;
|
||||||
|
|
||||||
private final CellFieldBuilderAdapter[][] grid;
|
private final CellFieldBuilderAdapter[][] grid;
|
||||||
private final GroupCellFieldBuilderAdapter groupBuilderAdapter;
|
private final GroupCellFieldBuilderAdapter groupBuilderAdapter;
|
||||||
private final Set<String> registeredGroups;
|
private final Set<String> registeredGroups;
|
||||||
|
|
||||||
ViewGridBuilder(
|
ViewGridBuilder(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ViewContext viewContext,
|
final ViewContext viewContext,
|
||||||
final ExamConfigurationService examConfigurationService) {
|
final ExamConfigurationService examConfigurationService) {
|
||||||
|
|
||||||
this.examConfigurationService = examConfigurationService;
|
this.examConfigurationService = examConfigurationService;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.viewContext = viewContext;
|
this.viewContext = viewContext;
|
||||||
this.grid = new CellFieldBuilderAdapter[viewContext.getRows()][viewContext.getColumns()];
|
this.grid = new CellFieldBuilderAdapter[viewContext.getRows()][viewContext.getColumns()];
|
||||||
this.groupBuilderAdapter = null;
|
this.groupBuilderAdapter = null;
|
||||||
this.registeredGroups = new HashSet<>();
|
this.registeredGroups = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewGridBuilder(
|
ViewGridBuilder(
|
||||||
final Composite parent,
|
final Composite parent,
|
||||||
final ViewContext viewContext,
|
final ViewContext viewContext,
|
||||||
final GroupCellFieldBuilderAdapter groupBuilderAdapter,
|
final GroupCellFieldBuilderAdapter groupBuilderAdapter,
|
||||||
final ExamConfigurationService examConfigurationService) {
|
final ExamConfigurationService examConfigurationService) {
|
||||||
|
|
||||||
this.examConfigurationService = examConfigurationService;
|
this.examConfigurationService = examConfigurationService;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.viewContext = viewContext;
|
this.viewContext = viewContext;
|
||||||
this.groupBuilderAdapter = groupBuilderAdapter;
|
this.groupBuilderAdapter = groupBuilderAdapter;
|
||||||
this.grid = new CellFieldBuilderAdapter[groupBuilderAdapter.height - 1][groupBuilderAdapter.width];
|
this.grid = new CellFieldBuilderAdapter[groupBuilderAdapter.height - 1][groupBuilderAdapter.width];
|
||||||
this.registeredGroups = null;
|
this.registeredGroups = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewGridBuilder add(final ConfigurationAttribute attribute) {
|
ViewGridBuilder add(final ConfigurationAttribute attribute) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Add SEB Configuration Attribute: " + attribute);
|
log.debug("Add SEB Configuration Attribute: " + attribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore nested attributes here (if not propagated to show up in view)
|
// ignore nested attributes here (if not propagated to show up in view)
|
||||||
if (attribute.parentId != null &&
|
if (attribute.parentId != null &&
|
||||||
!BooleanUtils.toBoolean(ConfigurationAttribute.getDependencyValue(
|
!BooleanUtils.toBoolean(ConfigurationAttribute.getDependencyValue(
|
||||||
ConfigurationAttribute.DEPENDENCY_SHOW_IN_VIEW,
|
ConfigurationAttribute.DEPENDENCY_SHOW_IN_VIEW,
|
||||||
attribute))) {
|
attribute))) {
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Orientation orientation = this.viewContext
|
final Orientation orientation = this.viewContext
|
||||||
.getOrientation(attribute.id);
|
.getOrientation(attribute.id);
|
||||||
|
|
||||||
// create group if this is not a group builder
|
// create group if this is not a group builder
|
||||||
if (this.groupBuilderAdapter == null && StringUtils.isNotBlank(orientation.groupId)) {
|
if (this.groupBuilderAdapter == null && StringUtils.isNotBlank(orientation.groupId)) {
|
||||||
if (this.registeredGroups.contains(orientation.groupId)) {
|
if (this.registeredGroups.contains(orientation.groupId)) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
final GroupCellFieldBuilderAdapter groupBuilder =
|
final GroupCellFieldBuilderAdapter groupBuilder =
|
||||||
new GroupCellFieldBuilderAdapter(this.viewContext.getOrientationsOfGroup(attribute));
|
new GroupCellFieldBuilderAdapter(this.viewContext.getOrientationsOfGroup(attribute));
|
||||||
|
|
||||||
fillDummy(groupBuilder.x, groupBuilder.y, groupBuilder.width, groupBuilder.height);
|
fillDummy(groupBuilder.x, groupBuilder.y, groupBuilder.width, groupBuilder.height);
|
||||||
this.grid[groupBuilder.y][groupBuilder.x] = groupBuilder;
|
this.grid[groupBuilder.y][groupBuilder.x] = groupBuilder;
|
||||||
this.registeredGroups.add(orientation.groupId);
|
this.registeredGroups.add(orientation.groupId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create single input field with label
|
// create single input field with label
|
||||||
final int xpos = orientation.xpos() + ((this.groupBuilderAdapter != null) ? -this.groupBuilderAdapter.x : 0);
|
final int xpos = orientation.xpos() + ((this.groupBuilderAdapter != null) ? -this.groupBuilderAdapter.x : 0);
|
||||||
final int ypos = orientation.ypos() + ((this.groupBuilderAdapter != null) ? -this.groupBuilderAdapter.y : 0);
|
final int ypos = orientation.ypos() + ((this.groupBuilderAdapter != null) ? -this.groupBuilderAdapter.y : 0);
|
||||||
|
|
||||||
if (orientation.width > 1 || orientation.height > 1) {
|
if (orientation.width > 1 || orientation.height > 1) {
|
||||||
fillDummy(xpos, ypos, orientation.width, orientation.height);
|
fillDummy(xpos, ypos, orientation.width, orientation.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder(
|
final InputFieldBuilder inputFieldBuilder = this.examConfigurationService.getInputFieldBuilder(
|
||||||
attribute,
|
attribute,
|
||||||
orientation);
|
orientation);
|
||||||
|
|
||||||
this.grid[ypos][xpos] = CellFieldBuilderAdapter.fieldBuilderAdapter(
|
this.grid[ypos][xpos] = CellFieldBuilderAdapter.fieldBuilderAdapter(
|
||||||
inputFieldBuilder,
|
inputFieldBuilder,
|
||||||
attribute);
|
attribute);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch (orientation.title) {
|
switch (orientation.title) {
|
||||||
case RIGHT:
|
case RIGHT:
|
||||||
case RIGHT_SPAN: {
|
case RIGHT_SPAN: {
|
||||||
this.grid[ypos][xpos + 1] = CellFieldBuilderAdapter.labelBuilder(
|
this.grid[ypos][xpos + 1] = CellFieldBuilderAdapter.labelBuilder(
|
||||||
attribute,
|
attribute,
|
||||||
orientation);
|
orientation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LEFT:
|
case LEFT:
|
||||||
case LEFT_SPAN: {
|
case LEFT_SPAN: {
|
||||||
this.grid[ypos][xpos - 1] = CellFieldBuilderAdapter.labelBuilder(
|
this.grid[ypos][xpos - 1] = CellFieldBuilderAdapter.labelBuilder(
|
||||||
attribute,
|
attribute,
|
||||||
orientation);
|
orientation);
|
||||||
// special case for password, also add confirm label
|
// special case for password, also add confirm label
|
||||||
if (attribute.type == AttributeType.PASSWORD_FIELD) {
|
if (attribute.type == AttributeType.PASSWORD_FIELD) {
|
||||||
this.grid[ypos + 1][xpos - 1] = CellFieldBuilderAdapter.passwordConfirmLabel(
|
this.grid[ypos + 1][xpos - 1] = CellFieldBuilderAdapter.passwordConfirmLabel(
|
||||||
attribute,
|
attribute,
|
||||||
orientation);
|
orientation);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOP: {
|
case TOP: {
|
||||||
fillDummy(xpos, ypos - 1, orientation.width, 1);
|
fillDummy(xpos, ypos - 1, orientation.width, 1);
|
||||||
this.grid[ypos - 1][xpos] = CellFieldBuilderAdapter.labelBuilder(
|
this.grid[ypos - 1][xpos] = CellFieldBuilderAdapter.labelBuilder(
|
||||||
attribute,
|
attribute,
|
||||||
orientation);
|
orientation);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
// do nothing
|
// do nothing
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (final ArrayIndexOutOfBoundsException e) {
|
} catch (final ArrayIndexOutOfBoundsException e) {
|
||||||
log.error("Failed to set title as configured in: {} for attribute: {}", orientation, attribute, e);
|
log.error("Failed to set title as configured in: {} for attribute: {}", orientation, attribute, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void compose() {
|
void compose() {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace("Compose grid view: \n" + gridToString());
|
log.trace("Compose grid view: \n" + gridToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// balance grid (optimize span and grab empty spaces for labels where applicable)
|
// balance grid (optimize span and grab empty spaces for labels where applicable)
|
||||||
for (int y = 0; y < this.grid.length; y++) {
|
for (int y = 0; y < this.grid.length; y++) {
|
||||||
for (int x = 0; x < this.grid[y].length; x++) {
|
for (int x = 0; x < this.grid[y].length; x++) {
|
||||||
if (this.grid[y][x] != null) {
|
if (this.grid[y][x] != null) {
|
||||||
this.grid[y][x].balanceGrid(this.grid, x, y);
|
this.grid[y][x].balanceGrid(this.grid, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = 0; y < this.grid.length; y++) {
|
for (int y = 0; y < this.grid.length; y++) {
|
||||||
for (int x = 0; x < this.grid[y].length; x++) {
|
for (int x = 0; x < this.grid[y].length; x++) {
|
||||||
if (this.grid[y][x] == null) {
|
if (this.grid[y][x] == null) {
|
||||||
final Label empty = new Label(this.parent, SWT.LEFT);
|
final Label empty = new Label(this.parent, SWT.LEFT);
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
gridData.verticalIndent = 8;
|
gridData.verticalIndent = 8;
|
||||||
empty.setLayoutData(gridData);
|
empty.setLayoutData(gridData);
|
||||||
empty.setText(StringUtils.EMPTY /* "empty " + x + " " + y */);
|
empty.setText(StringUtils.EMPTY /* "empty " + x + " " + y */);
|
||||||
} else {
|
} else {
|
||||||
this.grid[y][x].createCell(this);
|
this.grid[y][x].createCell(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillDummy(final int x, final int y, final int width, final int height) {
|
private void fillDummy(final int x, final int y, final int width, final int height) {
|
||||||
final int upperBoundX = x + width;
|
final int upperBoundX = x + width;
|
||||||
final int upperBoundY = y + height;
|
final int upperBoundY = y + height;
|
||||||
for (int _y = y; _y < upperBoundY; _y++) {
|
for (int _y = y; _y < upperBoundY; _y++) {
|
||||||
for (int _x = x; _x < upperBoundX; _x++) {
|
for (int _x = x; _x < upperBoundX; _x++) {
|
||||||
if (_y < 0 || _x < 0 || _y >= this.grid.length || _x >= this.grid[_y].length) {
|
if (_y < 0 || _x < 0 || _y >= this.grid.length || _x >= this.grid[_y].length) {
|
||||||
log.warn("Out of bounds: {} {}", _x, _y);
|
log.warn("Out of bounds: {} {}", _x, _y);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this.grid[_y][_x] = CellFieldBuilderAdapter.DUMMY_BUILDER_ADAPTER;
|
this.grid[_y][_x] = CellFieldBuilderAdapter.DUMMY_BUILDER_ADAPTER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String gridToString() {
|
private String gridToString() {
|
||||||
final StringBuffer sb = new StringBuffer();
|
final StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < this.grid.length; i++) {
|
for (int i = 0; i < this.grid.length; i++) {
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
sb.append(",\n");
|
sb.append(",\n");
|
||||||
}
|
}
|
||||||
sb.append(Arrays.toString(this.grid[i]));
|
sb.append(Arrays.toString(this.grid[i]));
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,78 +1,74 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.examconfig.impl.rules;
|
package ch.ethz.seb.sebserver.gui.service.examconfig.impl.rules;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
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.ValueChangeRule;
|
||||||
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
import ch.ethz.seb.sebserver.gui.service.examconfig.impl.ViewContext;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class BrowserViewModeRule implements ValueChangeRule {
|
public class BrowserViewModeRule implements ValueChangeRule {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(BrowserViewModeRule.class);
|
private static final Logger log = LoggerFactory.getLogger(BrowserViewModeRule.class);
|
||||||
|
|
||||||
public static final String KEY_BROWSER_VIEW_MODE = "browserViewMode";
|
public static final String KEY_BROWSER_VIEW_MODE = "browserViewMode";
|
||||||
public static final String KEY_TOUCH_EXIT = "enableTouchExit";
|
public static final String KEY_TOUCH_EXIT = "enableTouchExit";
|
||||||
public static final String KEY_MAIN_WINDOW_GROUP = "mainBrowserWindowWidth";
|
public static final String KEY_MAIN_WINDOW_GROUP = "mainBrowserWindowWidth";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean observesAttribute(final ConfigurationAttribute attribute) {
|
public boolean observesAttribute(final ConfigurationAttribute attribute) {
|
||||||
return KEY_BROWSER_VIEW_MODE.equals(attribute.name);
|
return KEY_BROWSER_VIEW_MODE.equals(attribute.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyRule(
|
public void applyRule(
|
||||||
final ViewContext context,
|
final ViewContext context,
|
||||||
final ConfigurationAttribute attribute,
|
final ConfigurationAttribute attribute,
|
||||||
final ConfigurationValue value) {
|
final ConfigurationValue value) {
|
||||||
|
|
||||||
if (StringUtils.isBlank(value.value)) {
|
if (StringUtils.isBlank(value.value)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.enable(KEY_TOUCH_EXIT);
|
context.enable(KEY_TOUCH_EXIT);
|
||||||
context.enableGroup(KEY_MAIN_WINDOW_GROUP);
|
context.enableGroup(KEY_MAIN_WINDOW_GROUP);
|
||||||
|
|
||||||
switch (Integer.parseInt(value.value)) {
|
switch (Integer.parseInt(value.value)) {
|
||||||
case 0: {
|
case 1: {
|
||||||
context.disable(KEY_TOUCH_EXIT);
|
context.disable(KEY_TOUCH_EXIT);
|
||||||
break;
|
context.disableGroup(KEY_MAIN_WINDOW_GROUP);
|
||||||
}
|
break;
|
||||||
case 1: {
|
}
|
||||||
context.disable(KEY_TOUCH_EXIT);
|
case 2: {
|
||||||
context.disableGroup(KEY_MAIN_WINDOW_GROUP);
|
context.disableGroup(KEY_MAIN_WINDOW_GROUP);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: {
|
default: {
|
||||||
context.disableGroup(KEY_MAIN_WINDOW_GROUP);
|
context.disable(KEY_TOUCH_EXIT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
}
|
||||||
context.disable(KEY_TOUCH_EXIT);
|
} catch (final Exception e) {
|
||||||
break;
|
log.warn("Failed to apply rule: ", e);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (final Exception e) {
|
}
|
||||||
log.warn("Failed to apply rule: ", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,10 +17,10 @@ import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
|
||||||
public interface I18nSupport {
|
public interface I18nSupport {
|
||||||
|
|
||||||
public static final String SUPPORTED_LANGUAGES_KEY = "sebserver.gui.supported.languages";
|
String SUPPORTED_LANGUAGES_KEY = "sebserver.gui.supported.languages";
|
||||||
public static final String MULTILINGUAL_KEY = "sebserver.gui.multilingual";
|
String MULTILINGUAL_KEY = "sebserver.gui.multilingual";
|
||||||
public static final String FORMAL_LOCALE_KEY = "sebserver.gui.date.displayformat";
|
String FORMAL_LOCALE_KEY = "sebserver.gui.date.displayformat";
|
||||||
public static final String ATTR_CURRENT_SESSION_LOCALE = "CURRENT_SESSION_LOCALE";
|
String ATTR_CURRENT_SESSION_LOCALE = "CURRENT_SESSION_LOCALE";
|
||||||
|
|
||||||
/** Get all supported languages as a collection of Locale
|
/** Get all supported languages as a collection of Locale
|
||||||
*
|
*
|
||||||
|
@ -40,7 +40,7 @@ public interface I18nSupport {
|
||||||
Locale getUsersFormatLocale();
|
Locale getUsersFormatLocale();
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display.
|
/** Format a DateTime to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.date.display format'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
||||||
|
@ -50,7 +50,7 @@ public interface I18nSupport {
|
||||||
String formatDisplayDate(DateTime date);
|
String formatDisplayDate(DateTime date);
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display with additional time zone name at the end.
|
/** Format a DateTime to a text format to display with additional time zone name at the end.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.date.display format'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
* Adds time-zone offset information if the currents user time-zone is different form UTC
|
||||||
|
@ -62,19 +62,19 @@ public interface I18nSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a time-stamp (milliseconds) to a text format to display.
|
/** Format a time-stamp (milliseconds) to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.date.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.date.display format'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param timestamp the unix-timestamp in milliseconds
|
||||||
* @return date formatted date String to display */
|
* @return date formatted date String to display */
|
||||||
default String formatDisplayDate(final Long timestamp) {
|
default String formatDisplayDate(final Long timestamp) {
|
||||||
return formatDisplayDate(Utils.toDateTimeUTC(timestamp));
|
return formatDisplayDate(Utils.toDateTimeUTC(timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display.
|
/** Format a DateTime to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.display format'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
|
@ -84,19 +84,19 @@ public interface I18nSupport {
|
||||||
String formatDisplayDateTime(DateTime date);
|
String formatDisplayDateTime(DateTime date);
|
||||||
|
|
||||||
/** Format a time-stamp (milliseconds) to a text format to display.
|
/** Format a time-stamp (milliseconds) to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.datetime.display format'
|
||||||
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_DATE_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param timestamp the unix-timestamp in milliseconds
|
||||||
* @return date formatted date time String to display */
|
* @return date formatted date time String to display */
|
||||||
default String formatDisplayDateTime(final Long timestamp) {
|
default String formatDisplayDateTime(final Long timestamp) {
|
||||||
return formatDisplayDateTime(Utils.toDateTimeUTC(timestamp));
|
return formatDisplayDateTime(Utils.toDateTimeUTC(timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Format a DateTime to a text format to display.
|
/** Format a DateTime to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.time.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.time.display format'
|
||||||
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
|
@ -106,12 +106,12 @@ public interface I18nSupport {
|
||||||
String formatDisplayTime(DateTime date);
|
String formatDisplayTime(DateTime date);
|
||||||
|
|
||||||
/** Format a time-stamp (milliseconds) to a text format to display.
|
/** Format a time-stamp (milliseconds) to a text format to display.
|
||||||
* This uses the date-format defined by either the attribute 'sebserver.gui.time.displayformat'
|
* This uses the date-format defined by either the attribute 'sebserver.gui.time.display format'
|
||||||
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
* or the Constants.DEFAULT_DISPLAY_TIME_FORMAT
|
||||||
*
|
*
|
||||||
* Adds time-zone information if the currents user time-zone is different form UTC
|
* Adds time-zone information if the currents user time-zone is different form UTC
|
||||||
*
|
*
|
||||||
* @param date the DateTime instance
|
* @param timestamp the unix-timestamp in milliseconds
|
||||||
* @return date formatted time String to display */
|
* @return date formatted time String to display */
|
||||||
default String formatDisplayTime(final Long timestamp) {
|
default String formatDisplayTime(final Long timestamp) {
|
||||||
return formatDisplayTime(Utils.toDateTimeUTC(timestamp));
|
return formatDisplayTime(Utils.toDateTimeUTC(timestamp));
|
||||||
|
|
|
@ -39,34 +39,116 @@ public interface PolyglotPageService {
|
||||||
* @param locale the Locale to set */
|
* @param locale the Locale to set */
|
||||||
void setPageLocale(Composite root, Locale locale);
|
void setPageLocale(Composite root, Locale locale);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param imageUpload the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
*/
|
||||||
void injectI18n(ImageUploadSelection imageUpload, LocTextKey locTextKey);
|
void injectI18n(ImageUploadSelection imageUpload, LocTextKey locTextKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param label the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
*/
|
||||||
void injectI18n(Label label, LocTextKey locTextKey);
|
void injectI18n(Label label, LocTextKey locTextKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param label the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
* @param locToolTipKey the localized text key for the tooltip to inject
|
||||||
|
*/
|
||||||
void injectI18n(Label label, LocTextKey locTextKey, LocTextKey locToolTipKey);
|
void injectI18n(Label label, LocTextKey locTextKey, LocTextKey locToolTipKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param group the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
* @param locTooltipKey the localized text key for the tooltip to inject
|
||||||
|
*/
|
||||||
void injectI18n(Group group, LocTextKey locTextKey, LocTextKey locTooltipKey);
|
void injectI18n(Group group, LocTextKey locTextKey, LocTextKey locTooltipKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param button the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
*/
|
||||||
void injectI18n(Button button, LocTextKey locTextKey);
|
void injectI18n(Button button, LocTextKey locTextKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param button the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
* @param locToolTipKey the localized text key for the tooltip to inject
|
||||||
|
*/
|
||||||
void injectI18n(Button button, LocTextKey locTextKey, LocTextKey locToolTipKey);
|
void injectI18n(Button button, LocTextKey locTextKey, LocTextKey locToolTipKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param tree the Control instance
|
||||||
|
*/
|
||||||
void injectI18n(Tree tree);
|
void injectI18n(Tree tree);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param treeItem the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
*/
|
||||||
void injectI18n(TreeItem treeItem, LocTextKey locTextKey);
|
void injectI18n(TreeItem treeItem, LocTextKey locTextKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param table the Control instance
|
||||||
|
*/
|
||||||
void injectI18n(Table table);
|
void injectI18n(Table table);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param tabFolder the Control instance
|
||||||
|
*/
|
||||||
void injectI18n(TabFolder tabFolder);
|
void injectI18n(TabFolder tabFolder);
|
||||||
|
|
||||||
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param tableColumn the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
* @param locTooltipKey the localized text key for the tooltip to inject
|
||||||
|
*/
|
||||||
void injectI18n(TableColumn tableColumn, LocTextKey locTextKey, LocTextKey locTooltipKey);
|
void injectI18n(TableColumn tableColumn, LocTextKey locTextKey, LocTextKey locTooltipKey);
|
||||||
|
|
||||||
void injectI18n(TableItem tableItem, LocTextKey... locTextKey);
|
/** Used to inject a localised text within the given Control (Widget) that automatically gets changed on language
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @param tabItem the Control instance
|
||||||
|
* @param locTextKey the localized text key to inject
|
||||||
|
* @param locTooltipKey the localized text key for the tooltip to inject
|
||||||
|
*/
|
||||||
void injectI18n(TabItem tabItem, LocTextKey locTextKey, LocTextKey locTooltipKey);
|
void injectI18n(TabItem tabItem, LocTextKey locTextKey, LocTextKey locTooltipKey);
|
||||||
|
|
||||||
|
/** Used to inject a localised tooltip text within the given Control (Widget) that automatically gets changed on
|
||||||
|
* language change.
|
||||||
|
*
|
||||||
|
* @param control the Control instance
|
||||||
|
* @param locTooltipKey the localized text key for the tooltip to inject
|
||||||
|
*/
|
||||||
void injectI18nTooltip(Control control, LocTextKey locTooltipKey);
|
void injectI18nTooltip(Control control, LocTextKey locTooltipKey);
|
||||||
|
|
||||||
|
/** Used to create the page language selector if needed
|
||||||
|
*
|
||||||
|
* @param composerCtx the PageContext
|
||||||
|
*/
|
||||||
void createLanguageSelector(PageContext composerCtx);
|
void createLanguageSelector(PageContext composerCtx);
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,186 +1,185 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.i18n.impl;
|
package ch.ethz.seb.sebserver.gui.service.i18n.impl;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
import org.joda.time.format.DateTimeFormatter;
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class I18nSupportImpl implements I18nSupport {
|
public class I18nSupportImpl implements I18nSupport {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(I18nSupportImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(I18nSupportImpl.class);
|
||||||
|
|
||||||
private final Locale defaultFormatLocale;
|
private final Locale defaultFormatLocale;
|
||||||
private final CurrentUser currentUser;
|
private final CurrentUser currentUser;
|
||||||
private final MessageSource messageSource;
|
private final MessageSource messageSource;
|
||||||
private final Locale defaultLocale = Locale.ENGLISH;
|
private final Locale defaultLocale = Locale.ENGLISH;
|
||||||
private final Collection<Locale> supportedLanguages;
|
private final Collection<Locale> supportedLanguages;
|
||||||
|
|
||||||
public I18nSupportImpl(
|
public I18nSupportImpl(
|
||||||
final CurrentUser currentUser,
|
final CurrentUser currentUser,
|
||||||
final MessageSource messageSource,
|
final MessageSource messageSource,
|
||||||
final Environment environment) {
|
final Environment environment) {
|
||||||
|
|
||||||
this.currentUser = currentUser;
|
this.currentUser = currentUser;
|
||||||
this.messageSource = messageSource;
|
this.messageSource = messageSource;
|
||||||
|
|
||||||
final String defaultForamtLocaleString = environment.getProperty(
|
final String defaultFormatLocaleString = environment.getProperty(
|
||||||
FORMAL_LOCALE_KEY,
|
FORMAL_LOCALE_KEY,
|
||||||
Constants.DEFAULT_LANG_CODE);
|
Constants.DEFAULT_LANG_CODE);
|
||||||
|
|
||||||
this.defaultFormatLocale = Locale.forLanguageTag(defaultForamtLocaleString);
|
this.defaultFormatLocale = Locale.forLanguageTag(defaultFormatLocaleString);
|
||||||
|
|
||||||
final boolean multilingual = BooleanUtils.toBoolean(environment.getProperty(
|
final boolean multilingual = BooleanUtils.toBoolean(environment.getProperty(
|
||||||
MULTILINGUAL_KEY,
|
MULTILINGUAL_KEY,
|
||||||
Constants.FALSE_STRING));
|
Constants.FALSE_STRING));
|
||||||
if (multilingual) {
|
if (multilingual) {
|
||||||
final String languagesString = environment.getProperty(
|
final String languagesString = environment.getProperty(
|
||||||
SUPPORTED_LANGUAGES_KEY,
|
SUPPORTED_LANGUAGES_KEY,
|
||||||
Locale.ENGLISH.getLanguage());
|
Locale.ENGLISH.getLanguage());
|
||||||
|
|
||||||
this.supportedLanguages = Utils.immutableCollectionOf(
|
this.supportedLanguages = Utils.immutableCollectionOf(
|
||||||
Arrays.asList(StringUtils.split(languagesString, Constants.LIST_SEPARATOR))
|
Arrays.stream(StringUtils.split(languagesString, Constants.LIST_SEPARATOR))
|
||||||
.stream()
|
.map(Locale::forLanguageTag)
|
||||||
.map(s -> Locale.forLanguageTag(s))
|
.collect(Collectors.toList()));
|
||||||
.collect(Collectors.toList()));
|
|
||||||
|
} else {
|
||||||
} else {
|
this.supportedLanguages = Utils.immutableCollectionOf(Locale.ENGLISH);
|
||||||
this.supportedLanguages = Utils.immutableCollectionOf(Locale.ENGLISH);
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Collection<Locale> supportedLanguages() {
|
||||||
public Collection<Locale> supportedLanguages() {
|
return this.supportedLanguages;
|
||||||
return this.supportedLanguages;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Locale getUsersFormatLocale() {
|
||||||
public Locale getUsersFormatLocale() {
|
// TODO here also a user based format locale can be verified on the future
|
||||||
// TODO here also a user based format locale can be verified on the future
|
return this.defaultFormatLocale;
|
||||||
return this.defaultFormatLocale;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public Locale getUsersLanguageLocale() {
|
||||||
public Locale getUsersLanguageLocale() {
|
// first session-locale if available
|
||||||
// first session-locale if available
|
try {
|
||||||
try {
|
final Locale sessionLocale = (Locale) RWT.getUISession()
|
||||||
final Locale sessionLocale = (Locale) RWT.getUISession()
|
.getHttpSession()
|
||||||
.getHttpSession()
|
.getAttribute(ATTR_CURRENT_SESSION_LOCALE);
|
||||||
.getAttribute(ATTR_CURRENT_SESSION_LOCALE);
|
if (sessionLocale != null) {
|
||||||
if (sessionLocale != null) {
|
return sessionLocale;
|
||||||
return sessionLocale;
|
}
|
||||||
}
|
} catch (final IllegalStateException e) {
|
||||||
} catch (final IllegalStateException e) {
|
log.warn("Get current locale for session failed: {}", e.getMessage());
|
||||||
log.warn("Get current locale for session failed: {}", e.getMessage());
|
}
|
||||||
}
|
|
||||||
|
// second user-locale if available
|
||||||
// second user-locale if available
|
if (this.currentUser.isAvailable()) {
|
||||||
if (this.currentUser.isAvailable()) {
|
return this.currentUser.get().language;
|
||||||
return this.currentUser.get().language;
|
}
|
||||||
}
|
|
||||||
|
// last the default locale
|
||||||
// last the default locale
|
return this.defaultLocale;
|
||||||
return this.defaultLocale;
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public String formatDisplayDate(final DateTime date) {
|
||||||
public String formatDisplayDate(final DateTime date) {
|
final String pattern = DateTimeFormat.patternForStyle("M-", getUsersFormatLocale());
|
||||||
final String pattern = DateTimeFormat.patternForStyle("M-", getUsersFormatLocale());
|
return formatDisplayDate(date, DateTimeFormat.forPattern(pattern));
|
||||||
return formatDisplayDate(date, DateTimeFormat.forPattern(pattern));
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public String formatDisplayDateTime(final DateTime date) {
|
||||||
public String formatDisplayDateTime(final DateTime date) {
|
final String pattern = DateTimeFormat.patternForStyle("MS", getUsersFormatLocale());
|
||||||
final String pattern = DateTimeFormat.patternForStyle("MS", getUsersFormatLocale());
|
return formatDisplayDate(date, DateTimeFormat.forPattern(pattern));
|
||||||
return formatDisplayDate(date, DateTimeFormat.forPattern(pattern));
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public String formatDisplayTime(final DateTime date) {
|
||||||
public String formatDisplayTime(final DateTime date) {
|
final String pattern = DateTimeFormat.patternForStyle("-S", getUsersFormatLocale());
|
||||||
final String pattern = DateTimeFormat.patternForStyle("-S", getUsersFormatLocale());
|
return formatDisplayDate(date, DateTimeFormat.forPattern(pattern));
|
||||||
return formatDisplayDate(date, DateTimeFormat.forPattern(pattern));
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public String getUsersTimeZoneTitleSuffix() {
|
||||||
public String getUsersTimeZoneTitleSuffix() {
|
final UserInfo userInfo = this.currentUser.get();
|
||||||
final UserInfo userInfo = this.currentUser.get();
|
if (userInfo.timeZone == null || userInfo.timeZone.equals(DateTimeZone.UTC)) {
|
||||||
if (userInfo.timeZone == null || userInfo.timeZone.equals(DateTimeZone.UTC)) {
|
return "";
|
||||||
return "";
|
} else {
|
||||||
} else {
|
return "(" + this.currentUser.get().timeZone.getID() + ")";
|
||||||
return "(" + this.currentUser.get().timeZone.getID() + ")";
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public String getText(final String key, final String def, final Object... args) {
|
||||||
public String getText(final String key, final String def, final Object... args) {
|
return this.messageSource.getMessage(key, args, def, this.getUsersLanguageLocale());
|
||||||
return this.messageSource.getMessage(key, args, def, this.getUsersLanguageLocale());
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public String getText(final String key, final Locale locale, final String def, final Object... args) {
|
||||||
public String getText(final String key, final Locale locale, final String def, final Object... args) {
|
return this.messageSource.getMessage(key, args, def, locale);
|
||||||
return this.messageSource.getMessage(key, args, def, locale);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
@Override
|
public boolean hasText(final LocTextKey key) {
|
||||||
public boolean hasText(final LocTextKey key) {
|
if (key == null) {
|
||||||
if (key == null) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
return StringUtils.isNotBlank(getText(key.name, (String) null));
|
||||||
return StringUtils.isNotBlank(getText(key.name, (String) null));
|
}
|
||||||
}
|
|
||||||
|
private String formatDisplayDate(final DateTime date, final DateTimeFormatter formatter) {
|
||||||
private String formatDisplayDate(final DateTime date, final DateTimeFormatter formatter) {
|
if (date == null) {
|
||||||
if (date == null) {
|
return Constants.EMPTY_NOTE;
|
||||||
return Constants.EMPTY_NOTE;
|
}
|
||||||
}
|
|
||||||
|
DateTime dateUTC = date;
|
||||||
DateTime dateUTC = date;
|
if (date.getZone() != DateTimeZone.UTC) {
|
||||||
if (date.getZone() != DateTimeZone.UTC) {
|
log.warn("Date that has not UTC timezone used. "
|
||||||
log.warn("Date that has not UTC timezone used. "
|
+ "Reset to UTC timezone with any change on time instance for further processing");
|
||||||
+ "Reset to UTC timezone with any change on time instance for further processing");
|
dateUTC = date.withZone(DateTimeZone.UTC);
|
||||||
dateUTC = date.withZone(DateTimeZone.UTC);
|
}
|
||||||
}
|
|
||||||
|
final UserInfo userInfo = this.currentUser.get();
|
||||||
final UserInfo userInfo = this.currentUser.get();
|
if (userInfo != null && userInfo.timeZone != null && !userInfo.timeZone.equals(DateTimeZone.UTC)) {
|
||||||
if (userInfo != null && userInfo.timeZone != null && !userInfo.timeZone.equals(DateTimeZone.UTC)) {
|
return dateUTC.toString(formatter.withZone(userInfo.timeZone));
|
||||||
return dateUTC.toString(formatter.withZone(userInfo.timeZone));
|
} else {
|
||||||
} else {
|
return dateUTC.toString(formatter);
|
||||||
return dateUTC.toString(formatter);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -165,18 +165,6 @@ public final class PolyglotPageServiceImpl implements PolyglotPageService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void injectI18n(final TableItem tableItem, final LocTextKey... locTextKey) {
|
|
||||||
if (locTextKey == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tableItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
|
||||||
for (int i = 0; i < locTextKey.length; i++) {
|
|
||||||
tableItem.setText(i, this.i18nSupport.getText(locTextKey[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectI18n(final TabItem tabItem, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
public void injectI18n(final TabItem tabItem, final LocTextKey locTextKey, final LocTextKey locTooltipKey) {
|
||||||
tabItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
tabItem.setData(POLYGLOT_ITEM_TEXT_DATA_KEY, locTextKey);
|
||||||
|
|
|
@ -1,202 +1,202 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* 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
|
* 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/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.page.impl;
|
package ch.ethz.seb.sebserver.gui.service.page.impl;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.MessageBox;
|
import org.eclipse.swt.widgets.MessageBox;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
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.i18n.LocTextKey;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
|
import ch.ethz.seb.sebserver.gui.service.page.ComposerService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
|
import ch.ethz.seb.sebserver.gui.service.page.PageDefinition;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
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.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.IllegalUserSessionStateException;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.IllegalUserSessionStateException;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.Message;
|
import ch.ethz.seb.sebserver.gui.widget.Message;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Service
|
@Service
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class ComposerServiceImpl implements ComposerService {
|
public class ComposerServiceImpl implements ComposerService {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ComposerServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(ComposerServiceImpl.class);
|
||||||
|
|
||||||
private final Class<? extends PageDefinition> loginPageType = DefaultLoginPage.class;
|
private final Class<? extends PageDefinition> loginPageType = DefaultLoginPage.class;
|
||||||
private final Class<? extends PageDefinition> mainPageType = DefaultMainPage.class;
|
private final Class<? extends PageDefinition> mainPageType = DefaultMainPage.class;
|
||||||
|
|
||||||
final AuthorizationContextHolder authorizationContextHolder;
|
final AuthorizationContextHolder authorizationContextHolder;
|
||||||
private final I18nSupport i18nSupport;
|
private final I18nSupport i18nSupport;
|
||||||
private final Map<String, TemplateComposer> composer;
|
private final Map<String, TemplateComposer> composer;
|
||||||
private final Map<String, PageDefinition> pages;
|
private final Map<String, PageDefinition> pages;
|
||||||
|
|
||||||
public ComposerServiceImpl(
|
public ComposerServiceImpl(
|
||||||
final AuthorizationContextHolder authorizationContextHolder,
|
final AuthorizationContextHolder authorizationContextHolder,
|
||||||
final I18nSupport i18nSupport,
|
final I18nSupport i18nSupport,
|
||||||
final Collection<TemplateComposer> composer,
|
final Collection<TemplateComposer> composer,
|
||||||
final Collection<PageDefinition> pageDefinitions) {
|
final Collection<PageDefinition> pageDefinitions) {
|
||||||
|
|
||||||
this.authorizationContextHolder = authorizationContextHolder;
|
this.authorizationContextHolder = authorizationContextHolder;
|
||||||
this.i18nSupport = i18nSupport;
|
this.i18nSupport = i18nSupport;
|
||||||
this.composer = composer
|
this.composer = composer
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
comp -> comp.getClass().getName(),
|
comp -> comp.getClass().getName(),
|
||||||
Function.identity()));
|
Function.identity()));
|
||||||
|
|
||||||
this.pages = pageDefinitions
|
this.pages = pageDefinitions
|
||||||
.stream()
|
.stream()
|
||||||
.collect(Collectors.toMap(
|
.collect(Collectors.toMap(
|
||||||
page -> page.getClass().getName(),
|
page -> page.getClass().getName(),
|
||||||
Function.identity()));
|
Function.identity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageDefinition mainPage() {
|
public PageDefinition mainPage() {
|
||||||
return this.pages.get(this.mainPageType.getName());
|
return this.pages.get(this.mainPageType.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageDefinition loginPage() {
|
public PageDefinition loginPage() {
|
||||||
return this.pages.get(this.loginPageType.getName());
|
return this.pages.get(this.loginPageType.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean validate(final String composerName, final PageContext pageContext) {
|
public boolean validate(final String composerName, final PageContext pageContext) {
|
||||||
if (!this.composer.containsKey(composerName)) {
|
if (!this.composer.containsKey(composerName)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.composer
|
return this.composer
|
||||||
.get(composerName)
|
.get(composerName)
|
||||||
.validate(pageContext);
|
.validate(pageContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(
|
public void compose(
|
||||||
final Class<? extends TemplateComposer> composerType,
|
final Class<? extends TemplateComposer> composerType,
|
||||||
final PageContext pageContext) {
|
final PageContext pageContext) {
|
||||||
|
|
||||||
if (composerType != null && pageContext != null) {
|
if (composerType != null && pageContext != null) {
|
||||||
compose(composerType.getName(), pageContext);
|
compose(composerType.getName(), pageContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(
|
public void compose(
|
||||||
final String name,
|
final String name,
|
||||||
final PageContext pageContext) {
|
final PageContext pageContext) {
|
||||||
|
|
||||||
// Check first if there is still a valid authorization context
|
// Check first if there is still a valid authorization context
|
||||||
if (!this.authorizationContextHolder.getAuthorizationContext().isValid()) {
|
if (!this.authorizationContextHolder.getAuthorizationContext().isValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.composer.containsKey(name)) {
|
if (!this.composer.containsKey(name)) {
|
||||||
log.error("No TemplateComposer with name: " + name + " found. Check Spring confiuration and beans");
|
log.error("No TemplateComposer with name: " + name + " found. Check Spring configuration and beans");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final TemplateComposer composer = this.composer.get(name);
|
final TemplateComposer composer = this.composer.get(name);
|
||||||
|
|
||||||
if (composer.validate(pageContext)) {
|
if (composer.validate(pageContext)) {
|
||||||
|
|
||||||
PageService.clearComposite(pageContext.getParent());
|
PageService.clearComposite(pageContext.getParent());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
composer.compose(pageContext);
|
composer.compose(pageContext);
|
||||||
PageService.updateScrolledComposite(pageContext.getParent());
|
PageService.updateScrolledComposite(pageContext.getParent());
|
||||||
|
|
||||||
} catch (final IllegalUserSessionStateException e) {
|
} catch (final IllegalUserSessionStateException e) {
|
||||||
log.warn("Illegal user session state detected... ceanup user session and forward to login page.");
|
log.warn("Illegal user session state detected... cleanup user session and forward to login page.");
|
||||||
pageContext.forwardToLoginPage();
|
pageContext.forwardToLoginPage();
|
||||||
final MessageBox logoutSuccess = new Message(
|
final MessageBox logoutSuccess = new Message(
|
||||||
pageContext.getShell(),
|
pageContext.getShell(),
|
||||||
this.i18nSupport.getText("sebserver.logout"),
|
this.i18nSupport.getText("sebserver.logout"),
|
||||||
this.i18nSupport.getText("sebserver.logout.invalid-session.message"),
|
this.i18nSupport.getText("sebserver.logout.invalid-session.message"),
|
||||||
SWT.ICON_INFORMATION,
|
SWT.ICON_INFORMATION,
|
||||||
this.i18nSupport);
|
this.i18nSupport);
|
||||||
logoutSuccess.open(null);
|
logoutSuccess.open(null);
|
||||||
return;
|
return;
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
log.warn("Failed to compose: {}, pageContext: {}", name, pageContext, e);
|
log.warn("Failed to compose: {}, pageContext: {}", name, pageContext, e);
|
||||||
pageContext.notifyError(new LocTextKey("sebserver.error.unexpected"), e);
|
pageContext.notifyError(new LocTextKey("sebserver.error.unexpected"), e);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.error("Failed to compose: {}, pageContext: {}", name, pageContext, e);
|
log.error("Failed to compose: {}, pageContext: {}", name, pageContext, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
pageContext.getParent().layout();
|
pageContext.getParent().layout();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.warn("Failed to layout new composition: {}, pageContext: {}", name, pageContext, e);
|
log.warn("Failed to layout new composition: {}, pageContext: {}", name, pageContext, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log.error(
|
log.error(
|
||||||
"Invalid or missing mandatory attributes to handle compose request of ViewComposer: {} pageContext: {}",
|
"Invalid or missing mandatory attributes to handle compose request of ViewComposer: {} pageContext: {}",
|
||||||
name,
|
name,
|
||||||
pageContext);
|
pageContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void composePage(
|
public void composePage(
|
||||||
final PageDefinition pageDefinition,
|
final PageDefinition pageDefinition,
|
||||||
final Composite root) {
|
final Composite root) {
|
||||||
|
|
||||||
compose(
|
compose(
|
||||||
pageDefinition.composer(),
|
pageDefinition.composer(),
|
||||||
pageDefinition.applyPageContext(createPageContext(root)));
|
pageDefinition.applyPageContext(createPageContext(root)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void composePage(
|
public void composePage(
|
||||||
final Class<? extends PageDefinition> pageType,
|
final Class<? extends PageDefinition> pageType,
|
||||||
final Composite root) {
|
final Composite root) {
|
||||||
|
|
||||||
final String pageName = pageType.getName();
|
final String pageName = pageType.getName();
|
||||||
if (!this.pages.containsKey(pageName)) {
|
if (!this.pages.containsKey(pageName)) {
|
||||||
log.error("Unknown page with name: {}", pageName);
|
log.error("Unknown page with name: {}", pageName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final PageDefinition pageDefinition = this.pages.get(pageName);
|
final PageDefinition pageDefinition = this.pages.get(pageName);
|
||||||
compose(
|
compose(
|
||||||
pageDefinition.composer(),
|
pageDefinition.composer(),
|
||||||
pageDefinition.applyPageContext(createPageContext(root)));
|
pageDefinition.applyPageContext(createPageContext(root)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadLoginPage(final Composite parent) {
|
public void loadLoginPage(final Composite parent) {
|
||||||
composePage(this.loginPageType, parent);
|
composePage(this.loginPageType, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadMainPage(final Composite parent) {
|
public void loadMainPage(final Composite parent) {
|
||||||
composePage(this.mainPageType, parent);
|
composePage(this.mainPageType, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PageContext createPageContext(final Composite root) {
|
private PageContext createPageContext(final Composite root) {
|
||||||
return new PageContextImpl(this.i18nSupport, this, root, root, null);
|
return new PageContextImpl(this.i18nSupport, this, root, root, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue