blob: 0d24e303de586c81a3e3f619054e745d3cf32e57 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* BSI Business Systems Integration AG - initial API and implementation
*******************************************************************************/
package org.eclipse.scout.rt.ui.rap.window.messagebox;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.rap.rwt.RWT;
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.rt.client.ui.messagebox.IMessageBox;
import org.eclipse.scout.rt.client.ui.messagebox.MessageBoxEvent;
import org.eclipse.scout.rt.client.ui.messagebox.MessageBoxListener;
import org.eclipse.scout.rt.ui.rap.IRwtEnvironment;
import org.eclipse.scout.rt.ui.rap.ext.custom.StyledText;
import org.eclipse.scout.rt.ui.rap.extension.UiDecorationExtensionPoint;
import org.eclipse.scout.rt.ui.rap.form.fields.groupbox.layout.ButtonBarLayout;
import org.eclipse.scout.rt.ui.rap.form.fields.groupbox.layout.ButtonBarLayoutData;
import org.eclipse.scout.rt.ui.rap.util.HtmlTextUtility;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.internal.widgets.MarkupValidator;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
/**
* <h3>MessageBoxDialog</h3> ...
*
* @since 3.7.0 June 2011
*/
@SuppressWarnings("restriction")
public class RwtScoutMessageBoxDialog extends Dialog {
private static final long serialVersionUID = 1L;
/**
* must be sync with the patched version of RAP (org.eclipse.swt.widgets.Text.WRAP_TEXT_WITHOUT_SPACES)
* double kept because the open source release does not know anything about this constant. It is only available in the
* internal patched version of RAP 2.3.
*/
public static final String WRAP_TEXT_WITHOUT_SPACES = "WrapWithoutSpaces";
private P_ScoutMessageBoxListener m_scoutMessageBoxListener;
private final IMessageBox m_scoutObject;
private final IRwtEnvironment m_uiEnvironment;
private Label m_imageLabel;
private ILabelWrapper m_actionLabelWrapper;
private ILabelWrapper m_introLabelWrapper;
public RwtScoutMessageBoxDialog(Shell parentShell, IMessageBox scoutObject, IRwtEnvironment uiEnvironment) {
super(parentShell);
m_scoutObject = scoutObject;
m_uiEnvironment = uiEnvironment;
int dialogStyle = SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE;
setShellStyle(dialogStyle);
setBlockOnOpen(false);
}
@Override
public void create() {
super.create();
attachScout();
getShell().addDisposeListener(new P_DisposeListener());
}
void attachScout() {
if (m_scoutMessageBoxListener == null) {
m_scoutMessageBoxListener = new P_ScoutMessageBoxListener();
getScoutObject().addMessageBoxListener(m_scoutMessageBoxListener);
}
setTitleTextFromScout(getScoutObject().getTitle());
setIntroTextFromScout(getScoutObject().getIntroText());
setActionTextFromScout(getScoutObject().getActionText());
setImageFromScout(getScoutObject().getIconId());
}
protected void setImageFromScout(String iconId) {
Image icon = getUiEnvironment().getIcon(iconId);
setImageInternal(icon);
}
private void setImageInternal(Image img) {
boolean exclude = false;
if (img == null) {
exclude = true;
}
m_imageLabel.setImage(img);
if (m_imageLabel.getLayoutData() instanceof GridData) {
if (((GridData) m_imageLabel.getLayoutData()).exclude != exclude) {
GridData gridData = ((GridData) m_imageLabel.getLayoutData());
if (gridData.exclude != exclude) {
gridData.exclude = exclude;
m_imageLabel.getParent().getParent().layout(true, true);
getShell().layout(true);
}
}
}
}
protected void setTitleTextFromScout(String titleText) {
if (titleText == null) {
titleText = "";
}
getShell().setText(titleText);
getShell().layout(true);
}
protected void setIntroTextFromScout(String introText) {
boolean exclude = false;
if (introText == null) {
introText = "";
exclude = true;
}
if (m_introLabelWrapper.isHtmlEnabled()) {
// escape introText if HTML is enabled, i.e. text will be set on the Label control which renders HTML. This is not needed for the StyledText control since StyledText is not able to render HTML
introText = HtmlTextUtility.escapeHtmlCapableText(getUiEnvironment().getHtmlValidator(), getScoutObject(), introText);
}
m_introLabelWrapper.setLabelText(introText);
final Control introLabel = m_introLabelWrapper.getLabel();
if (introLabel.getLayoutData() instanceof GridData) {
GridData gridData = ((GridData) introLabel.getLayoutData());
if (gridData.exclude != exclude) {
gridData.exclude = exclude;
getShell().layout(true);
introLabel.getParent().getParent().layout(true, true);
}
}
// Hide empty labels
introLabel.setVisible(StringUtility.hasText(m_introLabelWrapper.getLabelText()));
}
protected void setActionTextFromScout(String actionText) {
// When the header text is not set we would like to have the action text in
// the header area
if (getScoutObject().getIntroText() == null) {
setIntroTextFromScout(actionText);
actionText = null;
}
boolean exclude = false;
if (actionText == null) {
actionText = "";
exclude = true;
}
if (m_actionLabelWrapper.isHtmlEnabled()) {
// escape actionText if HTML is enabled, i.e. text will be set on the Label control which renders HTML. This is not needed for the StyledText control since StyledText is not able to render HTML
actionText = HtmlTextUtility.escapeHtmlCapableText(getUiEnvironment().getHtmlValidator(), getScoutObject(), actionText);
}
m_actionLabelWrapper.setLabelText(actionText);
// Hide empty labels
m_actionLabelWrapper.getLabel().setVisible(StringUtility.hasText(m_actionLabelWrapper.getLabelText()));
if (m_actionLabelWrapper.getLabel().getLayoutData() instanceof GridData) {
GridData gridData = ((GridData) m_actionLabelWrapper.getLabel().getLayoutData());
if (gridData.exclude != exclude) {
gridData.exclude = exclude;
getShell().layout(true, true);
m_actionLabelWrapper.getLabel().getParent().getParent().layout(true, true);
}
}
}
protected void dettachScout() {
if (m_scoutMessageBoxListener != null) {
getScoutObject().removeMessageBoxListener(m_scoutMessageBoxListener);
m_scoutMessageBoxListener = null;
}
}
@Override
protected Control createDialogArea(Composite parent) {
Composite container = getUiEnvironment().getFormToolkit().createComposite(parent);
Control header = createHeaderArea(container);
m_actionLabelWrapper = createActionLabel(getScoutObject().isHtmlEnabled(), container);
// layout
container.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH));
GridLayout dialogAreaLayout = new GridLayout(1, true);
dialogAreaLayout.marginHeight = 12;
dialogAreaLayout.marginWidth = 12;
container.setLayout(dialogAreaLayout);
GridData gridData = new GridData(GridData.GRAB_HORIZONTAL);
header.setLayoutData(gridData);
gridData = new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_BOTH);
gridData.horizontalIndent = 5;
m_actionLabelWrapper.getLabel().setLayoutData(gridData);
// No control in the dialog area should be in the tab list
container.setTabList(new Control[]{});
return container;
}
private Control createHeaderArea(Composite parent) {
Composite container = getUiEnvironment().getFormToolkit().createComposite(parent);
m_imageLabel = getUiEnvironment().getFormToolkit().createLabel(container, "");
m_introLabelWrapper = createIntroLabel(getScoutObject().isHtmlEnabled(), container);
// layout
GridLayout headerLayout = new GridLayout(2, false);
headerLayout.marginBottom = 7;
headerLayout.marginWidth = 0;
headerLayout.horizontalSpacing = 5;
container.setLayout(headerLayout);
GridData gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
gridData.exclude = true;
m_imageLabel.setLayoutData(gridData);
gridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL | GridData.FILL_BOTH);
gridData.horizontalIndent = 7;
gridData.verticalIndent = 0;
gridData.exclude = true;
m_introLabelWrapper.getLabel().setLayoutData(gridData);
return container;
}
protected ILabelWrapper createIntroLabel(boolean htmlEnabled, Composite container) {
return new P_LabelWrapper(htmlEnabled, container);
}
protected ILabelWrapper createActionLabel(boolean htmlEnabled, Composite container) {
return new P_LabelWrapper(htmlEnabled, container);
}
@Override
protected Control createButtonBar(Composite parent) {
if (getScoutObject().getYesButtonText() == null
&& getScoutObject().getNoButtonText() == null
&& getScoutObject().getCancelButtonText() == null
&& getScoutObject().getHiddenText() == null) {
return null;
}
Composite buttonArea = getUiEnvironment().getFormToolkit().createComposite(parent);
int inset = 10;
Button defaultButton = null;
// Set the background color of the button bar
buttonArea.setBackground(getUiEnvironment().getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
// yes button
if (getScoutObject().getYesButtonText() != null) {
Button yesButton = createButton(buttonArea, getScoutObject().getYesButtonText(), null, IMessageBox.YES_OPTION);
ButtonBarLayoutData data = new ButtonBarLayoutData();
data.insetTop = inset;
data.insetBottom = inset;
data.insetRight = inset;
yesButton.setLayoutData(data);
defaultButton = (defaultButton == null ? yesButton : defaultButton);
}
if (getScoutObject().getNoButtonText() != null) {
Button noButton = createButton(buttonArea, getScoutObject().getNoButtonText(), null, IMessageBox.NO_OPTION);
ButtonBarLayoutData data = new ButtonBarLayoutData();
data.insetTop = inset;
data.insetBottom = inset;
data.insetRight = inset;
noButton.setLayoutData(data);
defaultButton = (defaultButton == null ? noButton : defaultButton);
}
if (getScoutObject().getCancelButtonText() != null) {
Button cancelButton = createButton(buttonArea, getScoutObject().getCancelButtonText(), null, IMessageBox.CANCEL_OPTION);
ButtonBarLayoutData data = new ButtonBarLayoutData();
data.insetTop = inset;
data.insetBottom = inset;
data.insetRight = inset;
cancelButton.setLayoutData(data);
defaultButton = (defaultButton == null ? cancelButton : defaultButton);
}
// Set default button
if (defaultButton != null) {
defaultButton.setFocus();
getShell().setDefaultButton(defaultButton);
}
// layout
GridData gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL);
buttonArea.setLayoutData(gridData);
ButtonBarLayout layout = new ButtonBarLayout(SWT.RIGHT);
layout.horizontalGap = 0;
buttonArea.setLayout(layout);
return buttonArea;
}
protected Button createButton(Composite parent, String text, String iconId, int buttonId) {
Button b = getUiEnvironment().getFormToolkit().createButton(parent, text, SWT.PUSH);
if (iconId != null) {
b.setImage(getUiEnvironment().getIcon(iconId));
}
if (buttonId >= 0) {
b.addSelectionListener(new P_RwtButtonListener(buttonId));
}
return b;
}
@Override
protected Point getInitialSize() {
// get the preferred width of the button bar
Point buttonBarSize = getButtonBar() == null ? new Point(0, 0) : getButtonBar().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
// get the preferred height of the control
Point initialSize = getShell().computeSize(UiDecorationExtensionPoint.getLookAndFeel().getMessageBoxMinWidth(), SWT.DEFAULT, true);
// The width and height of the messageBox is defined in the lookAndFeel extension point.
// If we have a lot of big buttons we would like to scale the dialog in order to show every button. In this case the width of the button bar is used.
initialSize.x = Math.max(buttonBarSize.x + 20, UiDecorationExtensionPoint.getLookAndFeel().getMessageBoxMinWidth());
initialSize.y = Math.max(initialSize.y, UiDecorationExtensionPoint.getLookAndFeel().getMessageBoxMinHeight());
return initialSize;
}
@Override
public int open() {
if (getShell() == null || getShell().isDisposed()) {
create();
}
initializeBounds();
return super.open();
}
@Override
public boolean close() {
handleUiButtonSelection(IMessageBox.CANCEL_OPTION);
return false;
}
public void closeNoFire() {
super.close();
}
private IRwtEnvironment getUiEnvironment() {
return m_uiEnvironment;
}
public IMessageBox getScoutObject() {
return m_scoutObject;
}
/*
* event handlers
*/
protected void handleScoutMessageBoxClosed(MessageBoxEvent e) {
// dialog model detach
dettachScout();
closeNoFire();
}
private void handleUiButtonSelection(final int buttonId) {
Runnable j = new Runnable() {
@Override
public void run() {
getScoutObject().getUIFacade().setResultFromUI(buttonId);
}
};
getUiEnvironment().invokeScoutLater(j, 0);
}
private class P_RwtButtonListener extends SelectionAdapter {
private static final long serialVersionUID = 1L;
private final int m_buttonId;
P_RwtButtonListener(int buttonId) {
m_buttonId = buttonId;
}
@Override
public void widgetSelected(SelectionEvent e) {
handleUiButtonSelection(m_buttonId);
}
} // end class P_RwtButtonListener
/*
* other observers
*/
private class P_ScoutMessageBoxListener implements MessageBoxListener {
@Override
public void messageBoxChanged(final MessageBoxEvent e) {
switch (e.getType()) {
case MessageBoxEvent.TYPE_CLOSED: {
Runnable t = new Runnable() {
@Override
public void run() {
switch (e.getType()) {
case MessageBoxEvent.TYPE_CLOSED: {
handleScoutMessageBoxClosed(e);
break;
}
}
}
};
getUiEnvironment().invokeUiLater(t);
break;
}
}
}
}// end private class
private class P_DisposeListener implements DisposeListener {
private static final long serialVersionUID = 1L;
@Override
public void widgetDisposed(DisposeEvent event) {
dettachScout();
}
}
private class P_LabelWrapper extends AbstractLabelWrapper {
public P_LabelWrapper(boolean htmlEnabled, Composite container) {
super(htmlEnabled, container);
}
@Override
protected Label createHtmlLabel(boolean htmlEnabled, Composite container) {
if (!htmlEnabled) {
return null;
}
// create Label control only if html is enabled since Label is able to render html.
Label htmlIntroLabel = getUiEnvironment().getFormToolkit().createLabel(container, "", SWT.WRAP | SWT.LEFT);
htmlIntroLabel.setData(RWT.MARKUP_ENABLED, Boolean.TRUE);
// Unsafe configuration. Size for h1, h2, h3.. tags isn't well calculated at the first time
htmlIntroLabel.setData(MarkupValidator.MARKUP_VALIDATION_DISABLED, Boolean.TRUE);
return htmlIntroLabel;
}
@Override
protected StyledText createTextLabel(boolean htmlEnabled, Composite container) {
if (htmlEnabled) {
return null;
}
// create StyledText control only if html is disabled since StyledText is not able to render html.
StyledText introLabel = getUiEnvironment().getFormToolkit().createStyledText(container, SWT.WRAP | SWT.LEFT | SWT.V_SCROLL);
introLabel.setData(WRAP_TEXT_WITHOUT_SPACES, Boolean.TRUE);
introLabel.setEditable(false);
return introLabel;
}
}
}