fix docu and code cleanup
This commit is contained in:
parent
b811bb5f29
commit
df884bd8d2
4 changed files with 316 additions and 298 deletions
|
@ -11,3 +11,7 @@ TODO
|
||||||
Exam Configuration
|
Exam Configuration
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
Configuration Templates
|
||||||
|
------------------------
|
||||||
|
|
|
@ -82,13 +82,35 @@ After successful login, one will see the main graphical user interface of the SE
|
||||||
:align: center
|
:align: center
|
||||||
:target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/overview/overview.png
|
:target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/overview/overview.png
|
||||||
|
|
||||||
The main content usually is a list or a form.
|
In the header above on the right hand, we see the username of the currently logged in user and an action button the sign out and go back to the login page.
|
||||||
|
|
||||||
Overview
|
The main content usually consist of a list or a form.
|
||||||
^^^^^^^^
|
|
||||||
|
|
||||||
Lists
|
Lists
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
|
A list shows all the objects of a particular activity in a table page. If the list contains as for one page, a page navigation is shown at the bottom of the list with the information of the current page and the number of pages along with a page navigation that can be used to navigate forward and backward thought the list pages.
|
||||||
|
Almost all lists have the ability to filter the content by certain column filter that are right above the corresponding columns. To filter a list one can use the column filter input to narrow down a specific collection of content. Accordingly to the value type of the column, there are different types of filter:
|
||||||
|
|
||||||
|
- Selection, to select one instance of a defined collection of values (drop-down).
|
||||||
|
- Text input, to write some text that a value must contain.
|
||||||
|
- Date selection, To select a from-date from a date-picker. A date selection can also have an additional time selection within separate input field
|
||||||
|
- Date range selection, To select a from- and a to-date within different inputs and a date-picker. A date range selection can also have an additional time range selection within separate input fields
|
||||||
|
|
||||||
|
.. image:: images/overview/list.png
|
||||||
|
:align: center
|
||||||
|
:target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/overview/list.png
|
||||||
|
|
||||||
|
A list can also be sorted by a column by clicking in the column header and the order of sorting can be changed by clicking again on the same column header. Depending on the column type, not all columns has the sort functionality.
|
||||||
|
Most columns have a short tool-tip description that pops up while the mouse pointer stays over the column header for a moment.
|
||||||
|
|
||||||
Forms
|
Forms
|
||||||
^^^^^^
|
^^^^^^
|
||||||
|
|
||||||
|
.. image:: images/overview/form_readonly.png
|
||||||
|
:align: center
|
||||||
|
:target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/overview/form_readonly.png
|
||||||
|
|
||||||
|
.. image:: images/overview/form_edit.png
|
||||||
|
:align: center
|
||||||
|
:target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/overview/form_edit.png
|
||||||
|
|
|
@ -311,19 +311,18 @@ public class SebClientConfigForm implements TemplateComposer {
|
||||||
);
|
);
|
||||||
|
|
||||||
formHandle.getForm().getFieldInput(SebClientConfig.ATTR_FALLBACK)
|
formHandle.getForm().getFieldInput(SebClientConfig.ATTR_FALLBACK)
|
||||||
.addListener(SWT.Selection, event -> {
|
.addListener(SWT.Selection, event -> formHandle.process(
|
||||||
formHandle.process(
|
FALLBACK_ATTRIBUTES::contains,
|
||||||
FALLBACK_ATTRIBUTES::contains,
|
ffa -> {
|
||||||
ffa -> {
|
boolean selected = ((Button) event.widget).getSelection();
|
||||||
boolean selected = ((Button) event.widget).getSelection();
|
ffa.setVisible(selected);
|
||||||
ffa.setVisible(selected);
|
if (!selected && ffa.hasError()) {
|
||||||
if (!selected && ffa.hasError()) {
|
ffa.resetError();
|
||||||
ffa.resetError();
|
ffa.setStringValue(StringUtils.EMPTY);
|
||||||
ffa.setStringValue(StringUtils.EMPTY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
}
|
||||||
});
|
));
|
||||||
|
|
||||||
|
|
||||||
final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class);
|
final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class);
|
||||||
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
this.pageService.pageActionBuilder(formContext.clearEntityKeys())
|
||||||
|
|
|
@ -1,283 +1,276 @@
|
||||||
/*
|
/*
|
||||||
* 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.content.action;
|
package ch.ethz.seb.sebserver.gui.content.action;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
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;
|
||||||
import org.eclipse.rap.rwt.template.Template;
|
import org.eclipse.rap.rwt.template.Template;
|
||||||
import org.eclipse.rap.rwt.template.TextCell;
|
import org.eclipse.rap.rwt.template.TextCell;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.graphics.Color;
|
import org.eclipse.swt.graphics.Color;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
import org.eclipse.swt.graphics.RGBA;
|
import org.eclipse.swt.graphics.RGBA;
|
||||||
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.Control;
|
import org.eclipse.swt.widgets.Control;
|
||||||
import org.eclipse.swt.widgets.Label;
|
import org.eclipse.swt.widgets.Label;
|
||||||
import org.eclipse.swt.widgets.Tree;
|
import org.eclipse.swt.widgets.Tree;
|
||||||
import org.eclipse.swt.widgets.TreeItem;
|
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 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.ActionActivationEvent;
|
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.ActionActivationEventListener;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
|
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.ActionPublishEventListener;
|
||||||
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.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;
|
||||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
public class ActionPane implements TemplateComposer {
|
public class ActionPane implements TemplateComposer {
|
||||||
|
|
||||||
private static final String ACTION_EVENT_CALL_KEY = "ACTION_EVENT_CALL";
|
private static final String ACTION_EVENT_CALL_KEY = "ACTION_EVENT_CALL";
|
||||||
private static final LocTextKey TITLE_KEY = new LocTextKey("sebserver.actionpane.title");
|
private static final LocTextKey TITLE_KEY = new LocTextKey("sebserver.actionpane.title");
|
||||||
|
|
||||||
private final PageService pageService;
|
private final PageService pageService;
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
|
|
||||||
private final Map<String, Tree> actionTrees = new HashMap<>();
|
private final Map<String, Tree> actionTrees = new HashMap<>();
|
||||||
|
|
||||||
protected ActionPane(final PageService pageService) {
|
protected ActionPane(final PageService pageService) {
|
||||||
this.pageService = pageService;
|
this.pageService = pageService;
|
||||||
this.widgetFactory = pageService.getWidgetFactory();
|
this.widgetFactory = pageService.getWidgetFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compose(final PageContext pageContext) {
|
public void compose(final PageContext pageContext) {
|
||||||
|
|
||||||
final Label label = this.widgetFactory.labelLocalized(
|
final Label label = this.widgetFactory.labelLocalized(
|
||||||
pageContext.getParent(),
|
pageContext.getParent(),
|
||||||
CustomVariant.TEXT_H2,
|
CustomVariant.TEXT_H2,
|
||||||
TITLE_KEY);
|
TITLE_KEY);
|
||||||
|
|
||||||
final GridData titleLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
|
final GridData titleLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
titleLayout.verticalIndent = 10;
|
titleLayout.verticalIndent = 10;
|
||||||
titleLayout.horizontalIndent = 10;
|
titleLayout.horizontalIndent = 10;
|
||||||
if (StringUtils.isBlank(label.getText())) {
|
if (StringUtils.isBlank(label.getText())) {
|
||||||
titleLayout.heightHint = 0;
|
titleLayout.heightHint = 0;
|
||||||
}
|
}
|
||||||
label.setLayoutData(titleLayout);
|
label.setLayoutData(titleLayout);
|
||||||
|
|
||||||
label.setData(
|
label.setData(
|
||||||
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
||||||
new ActionPublishEventListener() {
|
(ActionPublishEventListener) event -> {
|
||||||
@Override
|
final Composite parent = pageContext.getParent();
|
||||||
public void notify(final ActionPublishEvent event) {
|
final Tree treeForGroup = getTreeForGroup(parent, event.action.definition);
|
||||||
final Composite parent = pageContext.getParent();
|
final TreeItem actionItem = ActionPane.this.widgetFactory.treeItemLocalized(
|
||||||
final Tree treeForGroup = getTreeForGroup(parent, event.action.definition);
|
treeForGroup,
|
||||||
final TreeItem actionItem = ActionPane.this.widgetFactory.treeItemLocalized(
|
event.action.definition.title);
|
||||||
treeForGroup,
|
|
||||||
event.action.definition.title);
|
final Image image = event.active
|
||||||
|
? event.action.definition.icon.getImage(parent.getDisplay())
|
||||||
final Image image = event.active
|
: event.action.definition.icon.getGreyedImage(parent.getDisplay());
|
||||||
? event.action.definition.icon.getImage(parent.getDisplay())
|
|
||||||
: event.action.definition.icon.getGreyedImage(parent.getDisplay());
|
if (!event.active) {
|
||||||
|
actionItem.setForeground(new Color(parent.getDisplay(), new RGBA(150, 150, 150, 50)));
|
||||||
if (!event.active) {
|
}
|
||||||
actionItem.setForeground(new Color(parent.getDisplay(), new RGBA(150, 150, 150, 50)));
|
|
||||||
}
|
actionItem.setImage(image);
|
||||||
|
actionItem.setData(ACTION_EVENT_CALL_KEY, event.action);
|
||||||
actionItem.setImage(image);
|
parent.layout();
|
||||||
actionItem.setData(ACTION_EVENT_CALL_KEY, event.action);
|
});
|
||||||
parent.layout();
|
|
||||||
}
|
final Composite composite = new Composite(pageContext.getParent(), SWT.NONE);
|
||||||
});
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
|
final GridLayout gridLayout = new GridLayout();
|
||||||
final Composite composite = new Composite(pageContext.getParent(), SWT.NONE);
|
gridLayout.horizontalSpacing = 0;
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
gridData.heightHint = 0;
|
||||||
final GridLayout gridLayout = new GridLayout();
|
composite.setLayoutData(gridData);
|
||||||
gridLayout.horizontalSpacing = 0;
|
composite.setLayout(gridLayout);
|
||||||
gridData.heightHint = 0;
|
|
||||||
composite.setLayoutData(gridData);
|
composite.setData(
|
||||||
composite.setLayout(gridLayout);
|
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
||||||
|
(ActionActivationEventListener) event -> {
|
||||||
composite.setData(
|
final Composite parent = pageContext.getParent();
|
||||||
PageEventListener.LISTENER_ATTRIBUTE_KEY,
|
for (final ActionDefinition ad : event.actions) {
|
||||||
new ActionActivationEventListener() {
|
final TreeItem actionItem = findAction(parent, ad);
|
||||||
@Override
|
if (actionItem == null) {
|
||||||
public void notify(final ActionActivationEvent event) {
|
continue;
|
||||||
final Composite parent = pageContext.getParent();
|
}
|
||||||
for (final ActionDefinition ad : event.actions) {
|
|
||||||
final TreeItem actionItem = findAction(parent, ad);
|
final Image image = event.activation
|
||||||
if (actionItem == null) {
|
? ad.icon.getImage(parent.getDisplay())
|
||||||
continue;
|
: ad.icon.getGreyedImage(parent.getDisplay());
|
||||||
}
|
actionItem.setImage(image);
|
||||||
|
if (event.activation) {
|
||||||
final Image image = event.activation
|
actionItem.setForeground(null);
|
||||||
? ad.icon.getImage(parent.getDisplay())
|
} else {
|
||||||
: ad.icon.getGreyedImage(parent.getDisplay());
|
actionItem.setForeground(new Color(parent.getDisplay(), new RGBA(150, 150, 150, 50)));
|
||||||
actionItem.setImage(image);
|
ActionPane.this.pageService.getPolyglotPageService().injectI18n(actionItem, ad.title);
|
||||||
if (event.activation) {
|
}
|
||||||
actionItem.setForeground(null);
|
}
|
||||||
} else {
|
|
||||||
actionItem.setForeground(new Color(parent.getDisplay(), new RGBA(150, 150, 150, 50)));
|
if (event.decoration != null) {
|
||||||
ActionPane.this.pageService.getPolyglotPageService().injectI18n(actionItem, ad.title);
|
final TreeItem actionItemToDecorate = findAction(parent, event.decoration._1);
|
||||||
}
|
if (actionItemToDecorate != null && event.decoration._2 != null) {
|
||||||
}
|
actionItemToDecorate.setImage(0,
|
||||||
|
event.decoration._2.icon.getImage(parent.getDisplay()));
|
||||||
if (event.decoration != null) {
|
ActionPane.this.pageService.getPolyglotPageService().injectI18n(
|
||||||
final TreeItem actionItemToDecorate = findAction(parent, event.decoration._1);
|
actionItemToDecorate,
|
||||||
if (actionItemToDecorate != null && event.decoration._2 != null) {
|
event.decoration._2.title);
|
||||||
actionItemToDecorate.setImage(0,
|
}
|
||||||
event.decoration._2.icon.getImage(parent.getDisplay()));
|
}
|
||||||
ActionPane.this.pageService.getPolyglotPageService().injectI18n(
|
});
|
||||||
actionItemToDecorate,
|
}
|
||||||
event.decoration._2.title);
|
|
||||||
}
|
private TreeItem findAction(final Composite parent, final ActionDefinition actionDefinition) {
|
||||||
}
|
final Tree treeForGroup = getTreeForGroup(parent, actionDefinition);
|
||||||
}
|
if (treeForGroup == null) {
|
||||||
});
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeItem findAction(final Composite parent, final ActionDefinition actionDefinition) {
|
for (int i = 0; i < treeForGroup.getItemCount(); i++) {
|
||||||
final Tree treeForGroup = getTreeForGroup(parent, actionDefinition);
|
final TreeItem item = treeForGroup.getItem(i);
|
||||||
if (treeForGroup == null) {
|
if (item == null) {
|
||||||
return null;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < treeForGroup.getItemCount(); i++) {
|
final PageAction action = (PageAction) item.getData(ACTION_EVENT_CALL_KEY);
|
||||||
final TreeItem item = treeForGroup.getItem(i);
|
if (action == null) {
|
||||||
if (item == null) {
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
if (action.definition == actionDefinition) {
|
||||||
final PageAction action = (PageAction) item.getData(ACTION_EVENT_CALL_KEY);
|
return item;
|
||||||
if (action == null) {
|
}
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
return null;
|
||||||
if (action.definition == actionDefinition) {
|
}
|
||||||
return item;
|
|
||||||
}
|
private Tree getTreeForGroup(final Composite parent, final ActionDefinition actionDefinition) {
|
||||||
}
|
clearDisposedTrees();
|
||||||
|
|
||||||
return null;
|
final ActionCategory category = actionDefinition.category;
|
||||||
}
|
if (!this.actionTrees.containsKey(category.name())) {
|
||||||
|
final Tree actionTree = createActionTree(parent, actionDefinition.category);
|
||||||
private Tree getTreeForGroup(final Composite parent, final ActionDefinition actionDefinition) {
|
this.actionTrees.put(category.name(), actionTree);
|
||||||
clearDisposedTrees();
|
}
|
||||||
|
|
||||||
final ActionCategory category = actionDefinition.category;
|
return this.actionTrees.get(category.name());
|
||||||
if (!this.actionTrees.containsKey(category.name())) {
|
}
|
||||||
final Tree actionTree = createActionTree(parent, actionDefinition.category);
|
|
||||||
this.actionTrees.put(category.name(), actionTree);
|
private Tree createActionTree(final Composite parent, final ActionCategory category) {
|
||||||
}
|
|
||||||
|
final Composite composite = new Composite(parent, SWT.NONE);
|
||||||
return this.actionTrees.get(category.name());
|
final GridData layout = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
}
|
composite.setLayoutData(layout);
|
||||||
|
final GridLayout gridLayout = new GridLayout();
|
||||||
private Tree createActionTree(final Composite parent, final ActionCategory category) {
|
gridLayout.marginHeight = 0;
|
||||||
|
composite.setLayout(gridLayout);
|
||||||
final Composite composite = new Composite(parent, SWT.NONE);
|
composite.setData(RWT.CUSTOM_VARIANT, "actionPane");
|
||||||
final GridData layout = new GridData(SWT.FILL, SWT.TOP, true, false);
|
composite.setData("CATEGORY", category);
|
||||||
composite.setLayoutData(layout);
|
|
||||||
final GridLayout gridLayout = new GridLayout();
|
final Control[] children = parent.getChildren();
|
||||||
gridLayout.marginHeight = 0;
|
for (final Control child : children) {
|
||||||
composite.setLayout(gridLayout);
|
final ActionCategory c = (ActionCategory) child.getData("CATEGORY");
|
||||||
composite.setData(RWT.CUSTOM_VARIANT, "actionPane");
|
if (c != null && c.slotPosition > category.slotPosition) {
|
||||||
composite.setData("CATEGORY", category);
|
composite.moveAbove(child);
|
||||||
|
break;
|
||||||
final Control[] children = parent.getChildren();
|
}
|
||||||
for (final Control child : children) {
|
}
|
||||||
final ActionCategory c = (ActionCategory) child.getData("CATEGORY");
|
|
||||||
if (c != null && c.slotPosition > category.slotPosition) {
|
// title
|
||||||
composite.moveAbove(child);
|
if (this.pageService.getI18nSupport().hasText(category.title)) {
|
||||||
break;
|
final Label actionsTitle = this.widgetFactory.labelLocalized(
|
||||||
}
|
composite,
|
||||||
}
|
CustomVariant.TEXT_H3,
|
||||||
|
category.title);
|
||||||
// title
|
final GridData titleLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
if (this.pageService.getI18nSupport().hasText(category.title)) {
|
actionsTitle.setLayoutData(titleLayout);
|
||||||
final Label actionsTitle = this.widgetFactory.labelLocalized(
|
}
|
||||||
composite,
|
|
||||||
CustomVariant.TEXT_H3,
|
// action tree
|
||||||
category.title);
|
final Tree actions = this.widgetFactory.treeLocalized(
|
||||||
final GridData titleLayout = new GridData(SWT.FILL, SWT.TOP, true, false);
|
composite,
|
||||||
actionsTitle.setLayoutData(titleLayout);
|
SWT.SINGLE | SWT.FULL_SELECTION);
|
||||||
}
|
actions.setData(RWT.CUSTOM_VARIANT, "actions");
|
||||||
|
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
||||||
// action tree
|
actions.setLayoutData(gridData);
|
||||||
final Tree actions = this.widgetFactory.treeLocalized(
|
final Template template = new Template();
|
||||||
composite,
|
final ImageCell imageCell = new ImageCell(template);
|
||||||
SWT.SINGLE | SWT.FULL_SELECTION);
|
imageCell.setLeft(0, 0)
|
||||||
actions.setData(RWT.CUSTOM_VARIANT, "actions");
|
.setWidth(40)
|
||||||
final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
|
.setTop(0)
|
||||||
actions.setLayoutData(gridData);
|
.setBottom(0, 0)
|
||||||
final Template template = new Template();
|
.setHorizontalAlignment(SWT.LEFT)
|
||||||
final ImageCell imageCell = new ImageCell(template);
|
.setBackground(null);
|
||||||
imageCell.setLeft(0, 0)
|
imageCell.setBindingIndex(0);
|
||||||
.setWidth(40)
|
final TextCell textCell = new TextCell(template);
|
||||||
.setTop(0)
|
textCell.setLeft(0, 30)
|
||||||
.setBottom(0, 0)
|
.setWidth(150)
|
||||||
.setHorizontalAlignment(SWT.LEFT)
|
.setTop(7)
|
||||||
.setBackground(null);
|
.setBottom(0, 0)
|
||||||
imageCell.setBindingIndex(0);
|
.setHorizontalAlignment(SWT.LEFT);
|
||||||
final TextCell textCell = new TextCell(template);
|
textCell.setBindingIndex(0);
|
||||||
textCell.setLeft(0, 30)
|
actions.setData(RWT.ROW_TEMPLATE, template);
|
||||||
.setWidth(150)
|
|
||||||
.setTop(7)
|
actions.addListener(SWT.Selection, event -> {
|
||||||
.setBottom(0, 0)
|
final TreeItem treeItem = (TreeItem) event.item;
|
||||||
.setHorizontalAlignment(SWT.LEFT);
|
|
||||||
textCell.setBindingIndex(0);
|
final PageAction action = (PageAction) treeItem.getData(ACTION_EVENT_CALL_KEY);
|
||||||
actions.setData(RWT.ROW_TEMPLATE, template);
|
this.pageService.executePageAction(action);
|
||||||
|
|
||||||
actions.addListener(SWT.Selection, event -> {
|
if (!treeItem.isDisposed()) {
|
||||||
final TreeItem treeItem = (TreeItem) event.item;
|
treeItem.getParent().deselectAll();
|
||||||
|
final PageAction switchAction = action.getSwitchAction();
|
||||||
final PageAction action = (PageAction) treeItem.getData(ACTION_EVENT_CALL_KEY);
|
if (switchAction != null) {
|
||||||
this.pageService.executePageAction(action);
|
final PolyglotPageService polyglotPageService = this.pageService.getPolyglotPageService();
|
||||||
|
polyglotPageService.injectI18n(treeItem, switchAction.definition.title);
|
||||||
if (!treeItem.isDisposed()) {
|
treeItem.setImage(switchAction.definition.icon.getImage(treeItem.getDisplay()));
|
||||||
treeItem.getParent().deselectAll();
|
treeItem.setData(ACTION_EVENT_CALL_KEY, switchAction);
|
||||||
final PageAction switchAction = action.getSwitchAction();
|
}
|
||||||
if (switchAction != null) {
|
}
|
||||||
final PolyglotPageService polyglotPageService = this.pageService.getPolyglotPageService();
|
});
|
||||||
polyglotPageService.injectI18n(treeItem, switchAction.definition.title);
|
|
||||||
treeItem.setImage(switchAction.definition.icon.getImage(treeItem.getDisplay()));
|
return actions;
|
||||||
treeItem.setData(ACTION_EVENT_CALL_KEY, switchAction);
|
}
|
||||||
}
|
|
||||||
}
|
private void clearDisposedTrees() {
|
||||||
});
|
new ArrayList<>(this.actionTrees.entrySet())
|
||||||
|
.forEach(entry -> {
|
||||||
return actions;
|
final Control c = entry.getValue();
|
||||||
}
|
// of tree is already disposed.. remove it
|
||||||
|
if (c.isDisposed()) {
|
||||||
private void clearDisposedTrees() {
|
this.actionTrees.remove(entry.getKey());
|
||||||
new ArrayList<>(this.actionTrees.entrySet())
|
}
|
||||||
.stream()
|
// check access from current thread
|
||||||
.forEach(entry -> {
|
try {
|
||||||
final Control c = entry.getValue();
|
c.getBounds();
|
||||||
// of tree is already disposed.. remove it
|
} catch (final Exception e) {
|
||||||
if (c.isDisposed()) {
|
this.actionTrees.remove(entry.getKey());
|
||||||
this.actionTrees.remove(entry.getKey());
|
}
|
||||||
}
|
});
|
||||||
// check access from current thread
|
}
|
||||||
try {
|
|
||||||
c.getBounds();
|
}
|
||||||
} catch (final Exception e) {
|
|
||||||
this.actionTrees.remove(entry.getKey());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue