Bug 427546 - SmartField Menu Button (Arrow) is enabled initialy also whitout any Menus defined
https://bugs.eclipse.org/bugs/show_bug.cgi?id=427546
Add property change listener on actions.
Enable handle drop down when enabling scout field.
Change-Id: I3f1645734d17f989a11de295aa730f512947cf0e
Reviewed-on: https://git.eclipse.org/r/23206
Tested-by: Hudson CI
Reviewed-by: Matthias Villiger <mvi@bsiag.com>
Reviewed-by: Ken Lee <kle@bsiag.com>
IP-Clean: Ken Lee <kle@bsiag.com>
diff --git a/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java b/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java
index b3177c7..79ff68b 100644
--- a/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java
+++ b/org.eclipse.scout.rt.client.test/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtilityTest.java
@@ -10,9 +10,13 @@
******************************************************************************/
package org.eclipse.scout.rt.client.ui.action.menu;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
import org.easymock.EasyMock;
import org.eclipse.scout.rt.client.ui.action.keystroke.IKeyStroke;
-import org.junit.Assert;
+import org.eclipse.scout.rt.client.ui.form.fields.IValueField;
+import org.eclipse.scout.rt.client.ui.form.fields.button.IButton;
import org.junit.Test;
/**
@@ -28,19 +32,156 @@
EasyMock.replay(menu);
IMenu[] menus = new IMenu[]{menu};
IKeyStroke[] keyStrokes = MenuUtility.getKeyStrokesFromMenus(menus);
- Assert.assertEquals("should return 1 menu", keyStrokes.length, 1);
- Assert.assertEquals("keyStroke should be f11", keyStrokes[0].getKeyStroke(), "f1");
+ assertEquals("should return 1 menu", keyStrokes.length, 1);
+ assertEquals("keyStroke should be f11", keyStrokes[0].getKeyStroke(), "f1");
keyStrokes = MenuUtility.getKeyStrokesFromMenus(null);
- Assert.assertNotNull(keyStrokes);
- Assert.assertEquals("null Paramter should return empty array", keyStrokes.length, 0);
+ assertNotNull(keyStrokes);
+ assertEquals("null Parameter should return empty array", keyStrokes.length, 0);
menu = EasyMock.createNiceMock(IMenu.class);
EasyMock.expect(menu.getKeyStroke()).andReturn(" "); //invalid keyStroke definition
EasyMock.replay(menu);
menus = new IMenu[]{menu};
keyStrokes = MenuUtility.getKeyStrokesFromMenus(menus);
- Assert.assertNotNull(keyStrokes);
- Assert.assertEquals("KeyStrokes should be empty, since ' ' is an invalid keyStroke", keyStrokes.length, 0);
+ assertNotNull(keyStrokes);
+ assertEquals("KeyStrokes should be empty, since ' ' is an invalid keyStroke", keyStrokes.length, 0);
}
+
+ @Test
+ public void testFilterValidMenusValueFieldDisabled() {
+ @SuppressWarnings("unchecked")
+ IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+ EasyMock.expect(valueField.getValue()).andReturn("testValue");
+ EasyMock.expect(valueField.isEnabled()).andReturn(false);
+
+ IMenu menu = EasyMock.createMock(IMenu.class);
+ EasyMock.expect(menu.isInheritAccessibility()).andReturn(true);
+ EasyMock.replay(valueField, menu);
+
+ IMenu[] menus = new IMenu[]{menu};
+ IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+
+ assertNotNull(filteredMenus);
+ assertEquals(0, filteredMenus.length);
+ }
+
+ @Test
+ public void testFilterValidMenusInheritAccessibilityAndSingleSelectionMenu() {
+ @SuppressWarnings("unchecked")
+ IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+ EasyMock.expect(valueField.getValue()).andReturn("testValue").times(1);
+ EasyMock.expect(valueField.getValue()).andReturn(null).times(1);
+ EasyMock.expect(valueField.isEnabled()).andReturn(false).anyTimes();
+
+ IMenu menu = EasyMock.createMock(IMenu.class);
+ EasyMock.expect(menu.isInheritAccessibility()).andReturn(false).anyTimes();
+ EasyMock.expect(menu.isEmptySpaceAction()).andReturn(false).anyTimes();
+ EasyMock.expect(menu.isSingleSelectionAction()).andReturn(true).anyTimes();
+ EasyMock.expect(menu.isVisible()).andReturn(true).anyTimes();
+ EasyMock.replay(valueField, menu);
+
+ IMenu[] menus = new IMenu[]{menu};
+ IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+ assertNotNull(filteredMenus);
+ assertEquals(1, filteredMenus.length);
+ assertEquals(menu, filteredMenus[0]);
+
+ filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false); // value of field is null
+ assertNotNull(filteredMenus);
+ assertEquals(0, filteredMenus.length);
+ }
+
+ @Test
+ public void testFilterValidMenusEmptySpaceActionMenu() {
+ @SuppressWarnings("unchecked")
+ IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+ EasyMock.expect(valueField.getValue()).andReturn("testValue").anyTimes();
+ EasyMock.expect(valueField.isEnabled()).andReturn(true).anyTimes();
+
+ IMenu menuWithEmptySpaceAction = EasyMock.createMock(IMenu.class);
+ EasyMock.expect(menuWithEmptySpaceAction.isInheritAccessibility()).andReturn(false).anyTimes();
+ EasyMock.expect(menuWithEmptySpaceAction.isEmptySpaceAction()).andReturn(true).anyTimes();
+ EasyMock.expect(menuWithEmptySpaceAction.isVisible()).andReturn(true).times(1);
+ EasyMock.expect(menuWithEmptySpaceAction.isVisible()).andReturn(false).times(2);
+ EasyMock.replay(valueField, menuWithEmptySpaceAction);
+
+ IMenu[] menus = new IMenu[]{menuWithEmptySpaceAction};
+ IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+ assertNotNull(filteredMenus);
+ assertEquals(1, filteredMenus.length);
+ assertEquals(menuWithEmptySpaceAction, filteredMenus[0]);
+
+ filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+ assertNotNull(filteredMenus);
+ assertEquals(0, filteredMenus.length);
+ }
+
+ @Test
+ public void testFilterValidMenusPrepareAction() {
+ @SuppressWarnings("unchecked")
+ IValueField<String> valueField = (IValueField<String>) EasyMock.createMock(IValueField.class);
+ EasyMock.expect(valueField.getValue()).andReturn("testValue").anyTimes();
+ EasyMock.expect(valueField.isEnabled()).andReturn(true).anyTimes();
+
+ final IMenu menuWithEmptySpaceAction = EasyMock.createMock(IMenu.class);
+ EasyMock.expect(menuWithEmptySpaceAction.isInheritAccessibility()).andReturn(false).anyTimes();
+ EasyMock.expect(menuWithEmptySpaceAction.isEmptySpaceAction()).andReturn(true).anyTimes();
+ EasyMock.expect(menuWithEmptySpaceAction.isVisible()).andReturn(true).anyTimes();
+
+ menuWithEmptySpaceAction.prepareAction();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(valueField, menuWithEmptySpaceAction);
+
+ IMenu[] menus = new IMenu[]{menuWithEmptySpaceAction};
+ IMenu[] filteredMenus = MenuUtility.filterValidMenus(valueField, menus, true);
+ assertNotNull(filteredMenus);
+ assertEquals(1, filteredMenus.length);
+ assertEquals(menuWithEmptySpaceAction, filteredMenus[0]);
+ EasyMock.verify(menuWithEmptySpaceAction);
+
+ filteredMenus = MenuUtility.filterValidMenus(valueField, menus, false);
+ EasyMock.verify(menuWithEmptySpaceAction);
+ }
+
+ @Test
+ public void testFilterValidMenusOnButton() {
+ IButton button = EasyMock.createMock(IButton.class);
+ final IMenu menu = EasyMock.createMock(IMenu.class);
+ EasyMock.expect(menu.isVisible()).andReturn(true).times(1);
+ EasyMock.expect(menu.isVisible()).andReturn(false).times(1);
+ EasyMock.replay(button, menu);
+
+ IMenu[] menus = new IMenu[]{menu};
+ IMenu[] filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, false);
+ assertNotNull(filteredMenus);
+ assertEquals(1, filteredMenus.length);
+ assertEquals(menu, filteredMenus[0]);
+
+ filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, false);
+ assertNotNull(filteredMenus);
+ assertEquals(0, filteredMenus.length);
+ }
+
+ @Test
+ public void testFilterValidMenusOnButtonPrepareAction() {
+ IButton button = EasyMock.createMock(IButton.class);
+ final IMenu menu = EasyMock.createMock(IMenu.class);
+ EasyMock.expect(menu.isVisible()).andReturn(true).anyTimes();
+
+ menu.prepareAction();
+ EasyMock.expectLastCall().once();
+ EasyMock.replay(button, menu);
+
+ IMenu[] menus = new IMenu[]{menu};
+ IMenu[] filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, true);
+ assertNotNull(filteredMenus);
+ assertEquals(1, filteredMenus.length);
+ assertEquals(menu, filteredMenus[0]);
+ EasyMock.verify(menu);
+
+ filteredMenus = MenuUtility.filterValidMenusOnButton(button, menus, false);
+ EasyMock.verify(menu);
+ }
+
}
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java
index e7fe8f0..6065e42 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/AbstractAction.java
@@ -35,16 +35,13 @@
private boolean m_initialized;
private final EventListenerList m_listenerList = new EventListenerList();
private final IActionUIFacade m_uiFacade;
- private boolean m_inheritAccessibility;
// enabled is defined as: enabledGranted && enabledProperty && enabledProcessing
private boolean m_enabledGranted;
private boolean m_enabledProperty;
private boolean m_enabledProcessingAction;
private boolean m_visibleProperty;
private boolean m_visibleGranted;
- private boolean m_singleSelectionAction;
private boolean m_multiSelectionAction;
- private boolean m_emptySpaceAction;
private boolean m_toggleAction;
public AbstractAction() {
@@ -459,12 +456,12 @@
@Override
public boolean isInheritAccessibility() {
- return m_inheritAccessibility;
+ return propertySupport.getPropertyBool(PROP_INHERIT_ACCESSIBILITY);
}
@Override
public void setInheritAccessibility(boolean b) {
- m_inheritAccessibility = b;
+ propertySupport.setPropertyBool(PROP_INHERIT_ACCESSIBILITY, b);
}
/**
@@ -552,12 +549,12 @@
@Override
public boolean isSingleSelectionAction() {
- return m_singleSelectionAction;
+ return propertySupport.getPropertyBool(PROP_SINGLE_SELECTION);
}
@Override
public void setSingleSelectionAction(boolean b) {
- m_singleSelectionAction = b;
+ propertySupport.setProperty(PROP_SINGLE_SELECTION, b);
}
@Override
@@ -572,12 +569,12 @@
@Override
public boolean isEmptySpaceAction() {
- return m_emptySpaceAction;
+ return propertySupport.getPropertyBool(PROP_EMPTY_SPACE);
}
@Override
public void setEmptySpaceAction(boolean b) {
- m_emptySpaceAction = b;
+ propertySupport.setProperty(PROP_EMPTY_SPACE, b);
}
@Override
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java
index c84ac15..263d61d 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/IAction.java
@@ -41,6 +41,9 @@
* property-type: String
*/
String PROP_SEPARATOR = "separator";
+ String PROP_INHERIT_ACCESSIBILITY = "inheritAccessibility";
+ String PROP_EMPTY_SPACE = "emptySpace";
+ String PROP_SINGLE_SELECTION = "singleSelection";
/**
* called to perform action
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java
index 4762624..c91024f 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/action/menu/MenuUtility.java
@@ -10,10 +10,13 @@
******************************************************************************/
package org.eclipse.scout.rt.client.ui.action.menu;
+import java.util.ArrayList;
import java.util.HashMap;
import org.eclipse.scout.rt.client.ui.action.keystroke.IKeyStroke;
import org.eclipse.scout.rt.client.ui.action.keystroke.KeyStroke;
+import org.eclipse.scout.rt.client.ui.form.fields.IValueField;
+import org.eclipse.scout.rt.client.ui.form.fields.button.IButton;
/**
* Utility class for menus
@@ -39,4 +42,65 @@
}
return ksMap.values().toArray(new IKeyStroke[ksMap.size()]);
}
+
+ /**
+ * Filters a given array of menus belonging to a specific value field by returning an array containing only valid
+ * menus.
+ * A menu is considered to be valid if at least the value field is enabled or if the menu does not inherit its
+ * accessibility.
+ * Additionally, the menu has either to be
+ * <ul>
+ * <li>an empty space action and visible menu or</li>
+ * <li>a single selection action and visible menu and the value field contains a non-null value</li>
+ * </ul>
+ * The method prepareAction of a valid menu is executed if the parameter executePrepareAction is <code>true</code>
+ *
+ * @since 4.0.0-M6
+ */
+ public static <T> IMenu[] filterValidMenus(IValueField<T> valueField, IMenu[] menusToFilter, boolean executePrepareAction) {
+ T value = valueField.getValue();
+ ArrayList<IMenu> filteredMenus = new ArrayList<IMenu>();
+ for (IMenu m : menusToFilter) {
+ IMenu validMenu = null;
+ if ((!m.isInheritAccessibility()) || valueField.isEnabled()) {
+ if (m.isEmptySpaceAction()) {
+ validMenu = m;
+ }
+ else if (m.isSingleSelectionAction()) {
+ if (value != null) {
+ validMenu = m;
+ }
+ }
+ }
+ if (validMenu != null) {
+ if (executePrepareAction) {
+ validMenu.prepareAction();
+ }
+ if (validMenu.isVisible()) {
+ filteredMenus.add(validMenu);
+ }
+ }
+ }
+ return filteredMenus.toArray(new IMenu[0]);
+ }
+
+ /**
+ * Filters a given array of menus belonging to a button by returning an array containing only valid
+ * menus. A menu is considered to be valid if the menu is visible.
+ * The method prepareAction of a valid menu is executed if the parameter executePrepareAction is <code>true</code>
+ *
+ * @since 4.0.0-M6
+ */
+ public static IMenu[] filterValidMenusOnButton(IButton button, IMenu[] menusToFilter, boolean executePrepareAction) {
+ ArrayList<IMenu> filteredMenus = new ArrayList<IMenu>();
+ for (IMenu menu : menusToFilter) {
+ if (executePrepareAction) {
+ menu.prepareAction();
+ }
+ if (menu.isVisible()) {
+ filteredMenus.add(menu);
+ }
+ }
+ return filteredMenus.toArray(new IMenu[0]);
+ }
}
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java
index 8605ece..03e6bc8 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/AbstractButton.java
@@ -413,14 +413,8 @@
private IMenu[] fireButtonPopup() {
ButtonEvent e = new ButtonEvent(this, ButtonEvent.TYPE_POPUP);
// single observer add our menus
- IMenu[] a = getMenus();
- for (int i = 0; i < a.length; i++) {
- IMenu m = a[i];
- m.prepareAction();
- if (m.isVisible()) {
- e.addPopupMenu(m);
- }
- }
+ IMenu[] menus = MenuUtility.filterValidMenusOnButton(this, getMenus(), true);
+ e.addPopupMenus(menus);
fireButtonEvent(e);
return e.getPopupMenus();
}
@@ -457,6 +451,16 @@
}
/**
+ * {@inheritDoc} Uses {@link MenuUtility#filterValidMenus} to check if there are valid menus. Does not execute the
+ * method <code>prepareAction</code> on the menu objects.
+ */
+ @Override
+ public boolean hasValidMenusFromUI() {
+ IMenu[] menus = MenuUtility.filterValidMenusOnButton(AbstractButton.this, getMenus(), false);
+ return menus.length > 0;
+ }
+
+ /**
* Toggle and Radio Buttons
*/
@Override
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java
index 20c4633..70a408e 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/button/IButtonUIFacade.java
@@ -4,7 +4,7 @@
* 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
******************************************************************************/
@@ -27,6 +27,14 @@
IMenu[] fireButtonPopupFromUI();
+ /**
+ * Called from the UI to check whether there are valid menus defined in the model.
+ *
+ * @return <code>true</code> if there is at least one valid menu. Otherwise, <code>false</code>.
+ * @since 4.0.0-M6
+ */
+ boolean hasValidMenusFromUI();
+
void setSelectedFromUI(boolean b);
}
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java
index 8176707..8921ad7 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/AbstractFileChooserField.java
@@ -476,16 +476,23 @@
private class P_UIFacade implements IFileChooserFieldUIFacade {
+ /**
+ * Uses {@link MenuUtility#filterValidMenus} to filter the given menus for valid menus.
+ * The method <code>prepareAction</code> on the menu objects are executed.
+ */
@Override
public IMenu[] firePopupFromUI() {
- ArrayList<IMenu> menus = new ArrayList<IMenu>();
- for (IMenu menu : getMenus()) {
- menu.prepareAction();
- if (menu.isVisible()) {
- menus.add(menu);
- }
- }
- return menus.toArray(new IMenu[0]);
+ return MenuUtility.filterValidMenus(AbstractFileChooserField.this, getMenus(), true);
+ }
+
+ /**
+ * {@inheritDoc} Uses {@link MenuUtility#filterValidMenus} to check if there are valid menus. Does not execute the
+ * method <code>prepareAction</code> on the menu objects.
+ */
+ @Override
+ public boolean hasValidMenusFromUI() {
+ IMenu[] validMenus = MenuUtility.filterValidMenus(AbstractFileChooserField.this, getMenus(), false);
+ return validMenus.length > 0;
}
@Override
@@ -496,5 +503,4 @@
return parseValue(newText);
}
}
-
}
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java
index 9834513..0a6425a 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/filechooserfield/IFileChooserFieldUIFacade.java
@@ -4,7 +4,7 @@
* 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
******************************************************************************/
@@ -16,6 +16,14 @@
IMenu[] firePopupFromUI();
+ /**
+ * Called from the UI to check whether there are valid menus defined in the model.
+ *
+ * @return <code>true</code> if there is at least one valid menu. Otherwise, <code>false</code>.
+ * @since 4.0.0-M6
+ */
+ boolean hasValidMenusFromUI();
+
boolean setTextFromUI(String newText);
}
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java
index 3f2cfca..b34df8b 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/AbstractSmartField.java
@@ -1489,31 +1489,23 @@
private class P_UIFacade implements ISmartFieldUIFacade {
private Map<ICell, LookupRow> m_validProposals;
+ /**
+ * Uses {@link MenuUtility#filterValidMenus} to filter the given menus for valid menus.
+ * The method <code>prepareAction</code> on the menu objects are executed.
+ */
@Override
public IMenu[] firePopupFromUI() {
- T smartValue = getValue();
- ArrayList<IMenu> filteredMenus = new ArrayList<IMenu>();
- for (IMenu m : getMenus()) {
- IMenu validMenu = null;
- if ((!m.isInheritAccessibility()) || isEnabled()) {
- if (m.isEmptySpaceAction()) {
- validMenu = m;
- }
- else if (m.isSingleSelectionAction()) {
- if (smartValue != null) {
- validMenu = m;
- }
- }
- }
- //
- if (validMenu != null) {
- validMenu.prepareAction();
- if (validMenu.isVisible()) {
- filteredMenus.add(validMenu);
- }
- }
- }
- return filteredMenus.toArray(new IMenu[0]);
+ return MenuUtility.filterValidMenus(AbstractSmartField.this, getMenus(), true);
+ }
+
+ /**
+ * {@inheritDoc} Uses {@link MenuUtility#filterValidMenus} to check if there are valid menus. Does not execute the
+ * method <code>prepareAction</code> on the menu objects.
+ */
+ @Override
+ public boolean hasValidMenusFromUI() {
+ IMenu[] validMenus = MenuUtility.filterValidMenus(AbstractSmartField.this, getMenus(), false);
+ return validMenus.length > 0;
}
@Override
diff --git a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java
index e9f538a..7fd8583 100644
--- a/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java
+++ b/org.eclipse.scout.rt.client/src/org/eclipse/scout/rt/client/ui/form/fields/smartfield/ISmartFieldUIFacade.java
@@ -27,4 +27,12 @@
boolean setTextFromUI(String text);
void unregisterProposalFormFromUI(ISmartFieldProposalForm form);
+
+ /**
+ * Called from the UI to check whether there are valid menus defined in the model.
+ *
+ * @return <code>true</code> if there is at least one valid menu. Otherwise, <code>false</code>.
+ * @since 4.0.0-M6
+ */
+ boolean hasValidMenusFromUI();
}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/action/AbstractRwtScoutActionPropertyChangeListener.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/action/AbstractRwtScoutActionPropertyChangeListener.java
new file mode 100644
index 0000000..71f4ade
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/action/AbstractRwtScoutActionPropertyChangeListener.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 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.action;
+
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
+
+/**
+ * Property change listener that can be attached to particular Scout menus.
+ *
+ * @since 4.0.0-M6
+ */
+public abstract class AbstractRwtScoutActionPropertyChangeListener implements PropertyChangeListener {
+
+ public void attachToScoutMenus(IMenu[] menus) {
+ for (IMenu menu : menus) {
+ menu.addPropertyChangeListener(this);
+ }
+ }
+
+ public void detachFromScoutMenus(IMenu[] menus) {
+ for (IMenu menu : menus) {
+ menu.removePropertyChangeListener(this);
+ }
+ }
+}
diff --git a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java
index fbe58ef..8d90edd 100644
--- a/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java
+++ b/org.eclipse.scout.rt.ui.rap/src/org/eclipse/scout/rt/ui/rap/form/fields/smartfield/RwtScoutSmartField.java
@@ -10,8 +10,10 @@
*******************************************************************************/
package org.eclipse.scout.rt.ui.rap.form.fields.smartfield;
+import java.beans.PropertyChangeEvent;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -23,6 +25,7 @@
import org.eclipse.scout.commons.job.JobEx;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.form.FormEvent;
import org.eclipse.scout.rt.client.ui.form.FormListener;
@@ -31,6 +34,7 @@
import org.eclipse.scout.rt.client.ui.form.fields.smartfield.ISmartFieldProposalForm;
import org.eclipse.scout.rt.ui.rap.LogicalGridLayout;
import org.eclipse.scout.rt.ui.rap.RwtMenuUtility;
+import org.eclipse.scout.rt.ui.rap.action.AbstractRwtScoutActionPropertyChangeListener;
import org.eclipse.scout.rt.ui.rap.ext.IDropDownButtonForPatch;
import org.eclipse.scout.rt.ui.rap.ext.MenuAdapterEx;
import org.eclipse.scout.rt.ui.rap.ext.StatusLabelEx;
@@ -94,6 +98,7 @@
private P_KeyListener m_shiftTabKeyListener;
private Set<IPopupSupportListener> m_popupEventListeners;
private Object m_popupEventListenerLock;
+ private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
public RwtScoutSmartField() {
m_pendingProposalJobLock = new Object();
@@ -190,21 +195,47 @@
protected void attachScout() {
super.attachScout();
setIconIdFromScout(getScoutObject().getIconId());
- getUiBrowseButton().setDropdownEnabled(getScoutObject().hasMenus());
+ getUiBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
setProposalFormFromScout(getScoutObject().getProposalForm());
+ if (m_scoutActionPropertyListener == null) {
+ m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+ }
+ m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+ }
+
+ private boolean calculateDropDownButtonEnabled() {
+ final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+ }
+ };
+ JobEx job = getUiEnvironment().invokeScoutLater(t, 1200);
+ try {
+ job.join(1200);
+ }
+ catch (InterruptedException ex) {
+ //nop
+ }
+ return hasValidMenus.get();
}
@Override
protected void detachScout() {
// workaround since disposeFieldInternal in AbstractSmartField is never called.
hideProposalPopup();
+ if (m_scoutActionPropertyListener != null) {
+ m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+ m_scoutActionPropertyListener = null;
+ }
super.detachScout();
}
@Override
protected void setDisplayTextFromScout(String s) {
+ getUiBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
if (!CompareUtility.equals(s, getUiField().getText())) {
- getUiBrowseButton().setDropdownEnabled(getScoutObject().hasMenus());
if (s == null) {
s = "";
}
@@ -219,6 +250,7 @@
super.setEnabledFromScout(b);
m_browseButton.setButtonEnabled(b);
getUiField().setEnabled(b);
+ handleDropDownButtonEnabled();
if (b) {
m_smartContainer.setData(RWT.CUSTOM_VARIANT, getSmartfieldVariant());
}
@@ -556,6 +588,17 @@
}
}
+ protected void handleScoutActionPropertyChange(String name, Object newValue) {
+ if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+ IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+ handleDropDownButtonEnabled();
+ }
+ }
+
+ protected void handleDropDownButtonEnabled() {
+ getUiBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+ }
+
protected void handleTextModifiedFromUi(ModifyEvent event) {
if (getUpdateUiFromScoutLock().isAcquired()) {
return;
@@ -819,4 +862,28 @@
}
}
+
+ private class P_ScoutActionPropertyChangeListener extends AbstractRwtScoutActionPropertyChangeListener {
+ @Override
+ public void propertyChange(final PropertyChangeEvent e) {
+ if (getUiEnvironment().getDisplay() != null && !getUiEnvironment().getDisplay().isDisposed()) {
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ if (!isUiDisposed()) {
+ try {
+ getUpdateUiFromScoutLock().acquire();
+ //
+ handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+ }
+ finally {
+ getUpdateUiFromScoutLock().release();
+ }
+ }
+ }
+ };
+ getUiEnvironment().invokeUiLater(t);
+ }
+ }
+ } // end class P_ScoutActionPropertyChangeListener
}
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/action/AbstractSwingScoutActionPropertyChangeListener.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/action/AbstractSwingScoutActionPropertyChangeListener.java
new file mode 100644
index 0000000..1e8e6d4
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/action/AbstractSwingScoutActionPropertyChangeListener.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 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.swing.action;
+
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.scout.commons.WeakEventListener;
+import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
+
+/**
+ * Property change listener that can be attached to particular Scout menus.
+ *
+ * @since 4.0.0-M6
+ */
+public abstract class AbstractSwingScoutActionPropertyChangeListener implements PropertyChangeListener, WeakEventListener {
+
+ public void attachToScoutMenus(IMenu[] menus) {
+ for (IMenu menu : menus) {
+ menu.addPropertyChangeListener(this);
+ }
+ }
+
+ public void detachFromScoutMenus(IMenu[] menus) {
+ for (IMenu menu : menus) {
+ menu.removePropertyChangeListener(this);
+ }
+ }
+}
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java
index 6690722..8446286 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/button/SwingScoutButton.java
@@ -17,6 +17,8 @@
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
+import java.beans.PropertyChangeEvent;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
@@ -27,8 +29,10 @@
import org.eclipse.scout.commons.StringUtility;
import org.eclipse.scout.commons.WeakEventListener;
+import org.eclipse.scout.commons.job.JobEx;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonEvent;
import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonListener;
@@ -38,6 +42,7 @@
import org.eclipse.scout.rt.ui.swing.SwingLayoutUtility;
import org.eclipse.scout.rt.ui.swing.SwingPopupWorker;
import org.eclipse.scout.rt.ui.swing.SwingUtility;
+import org.eclipse.scout.rt.ui.swing.action.AbstractSwingScoutActionPropertyChangeListener;
import org.eclipse.scout.rt.ui.swing.basic.IconGroup;
import org.eclipse.scout.rt.ui.swing.basic.IconGroup.IconState;
import org.eclipse.scout.rt.ui.swing.ext.JButtonEx;
@@ -57,6 +62,8 @@
private ButtonListener m_scoutButtonListener;
//ticket 86811: avoid double-action in queue
private boolean m_handleActionPending;
+ private JDropDownButton m_dropDownButton;
+ private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
public SwingScoutButton() {
}
@@ -99,15 +106,16 @@
swingFieldAsButton.addActionListener(new P_SwingActionListener());
// check if button has menus
if (getScoutObject().hasMenus()) {
- JDropDownButton dropDownButton = new JDropDownButton(swingFieldAsButton);
- dropDownButton.getMenuButton().addActionListener(new ActionListener() {
+ m_dropDownButton = new JDropDownButton(swingFieldAsButton);
+ m_dropDownButton.getMenuButton().setEnabled(calculateDropDownButtonEnabled());
+ m_dropDownButton.getMenuButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
handleSwingPopup((Component) e.getSource());
}
});
container = new JPanelEx();
- container.add(dropDownButton);
+ container.add(m_dropDownButton);
}
else {
container = new JPanelEx();
@@ -137,6 +145,24 @@
container.setLayout(new LogicalGridLayout(getSwingEnvironment(), 0, 0));
}
+ private boolean calculateDropDownButtonEnabled() {
+ final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+ }
+ };
+ JobEx job = getSwingEnvironment().invokeScoutLater(t, 1200);
+ try {
+ job.join(1200);
+ }
+ catch (InterruptedException ex) {
+ //nop
+ }
+ return hasValidMenus.get();
+ }
+
@Override
protected void detachScout() {
super.detachScout();
@@ -144,6 +170,10 @@
getScoutButton().removeButtonListener(m_scoutButtonListener);
m_scoutButtonListener = null;
}
+ if (m_scoutActionPropertyListener != null) {
+ m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+ m_scoutActionPropertyListener = null;
+ }
}
public IButton getScoutButton() {
@@ -155,6 +185,10 @@
return (AbstractButton) getSwingField();
}
+ protected JDropDownButton getDropDownButton() {
+ return m_dropDownButton;
+ }
+
@Override
protected void attachScout() {
super.attachScout();
@@ -166,6 +200,12 @@
setIconIdFromScout(b.getIconId());
setImageFromScout(b.getImage());
setSelectionFromScout(b.isSelected());
+ if (getDropDownButton() != null) {
+ if (m_scoutActionPropertyListener == null) {
+ m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+ }
+ m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+ }
}
@Override
@@ -346,6 +386,18 @@
// end notify
}
+ protected void handleScoutActionPropertyChange(String name, Object newValue) {
+ if (IAction.PROP_VISIBLE.equals(name)) {
+ handleDropDownButtonEnabled();
+ }
+ }
+
+ protected void handleDropDownButtonEnabled() {
+ if (getDropDownButton() != null) {
+ getDropDownButton().getMenuButton().setEnabled(calculateDropDownButtonEnabled());
+ }
+ }
+
/*
* Listeners
*/
@@ -408,6 +460,25 @@
}
}
}
- }
+ } // end private class P_ScoutButtonListener
+ private class P_ScoutActionPropertyChangeListener extends AbstractSwingScoutActionPropertyChangeListener {
+ @Override
+ public void propertyChange(final PropertyChangeEvent e) {
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ getUpdateSwingFromScoutLock().acquire();
+ //
+ handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+ }
+ finally {
+ getUpdateSwingFromScoutLock().release();
+ }
+ }
+ };
+ getSwingEnvironment().invokeSwingLater(t);
+ }
+ } // end private class P_ScoutActionPropertyChangeListener
}
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java
index 9bdf50d..acaf1be 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/filechooserfield/SwingScoutFileChooserField.java
@@ -12,7 +12,9 @@
import java.awt.Point;
import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeEvent;
import java.io.File;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
@@ -27,12 +29,14 @@
import org.eclipse.scout.commons.CompareUtility;
import org.eclipse.scout.commons.holders.Holder;
import org.eclipse.scout.commons.job.JobEx;
+import org.eclipse.scout.rt.client.ui.action.IAction;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.basic.filechooser.IFileChooser;
import org.eclipse.scout.rt.client.ui.form.fields.filechooserfield.IFileChooserField;
import org.eclipse.scout.rt.ui.swing.LogicalGridLayout;
import org.eclipse.scout.rt.ui.swing.SwingPopupWorker;
import org.eclipse.scout.rt.ui.swing.SwingUtility;
+import org.eclipse.scout.rt.ui.swing.action.AbstractSwingScoutActionPropertyChangeListener;
import org.eclipse.scout.rt.ui.swing.basic.IconGroup;
import org.eclipse.scout.rt.ui.swing.ext.IDropDownButtonListener;
import org.eclipse.scout.rt.ui.swing.ext.JPanelEx;
@@ -43,6 +47,8 @@
public class SwingScoutFileChooserField extends SwingScoutValueFieldComposite<IFileChooserField> implements ISwingScoutFileChooserField {
private static final long serialVersionUID = 1L;
+ private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
+
@Override
protected void initializeSwing() {
JPanelEx container = new JPanelEx();
@@ -114,17 +120,51 @@
super.attachScout();
IFileChooserField f = getScoutObject();
setFileIconIdFromScout(f.getFileIconId());
+ if (m_scoutActionPropertyListener == null) {
+ m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+ }
+ m_scoutActionPropertyListener.attachToScoutMenus(f.getMenus());
if (getSwingField() instanceof JTextFieldWithDropDownButton) {
- ((JTextFieldWithDropDownButton) getSwingTextField()).setMenuEnabled(getScoutObject().hasMenus());
+ ((JTextFieldWithDropDownButton) getSwingTextField()).setMenuEnabled(calculateDropDownButtonEnabled());
}
}
@Override
+ protected void detachScout() {
+ if (m_scoutActionPropertyListener != null) {
+ m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+ m_scoutActionPropertyListener = null;
+ }
+ super.detachScout();
+ }
+
+ @Override
protected void setDisplayTextFromScout(String s) {
+ if (getSwingField() instanceof JTextFieldWithDropDownButton) {
+ ((JTextFieldWithDropDownButton) getSwingTextField()).setMenuEnabled(calculateDropDownButtonEnabled());
+ }
JTextComponent swingField = getSwingTextField();
swingField.setText(s);
}
+ private boolean calculateDropDownButtonEnabled() {
+ final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+ }
+ };
+ JobEx job = getSwingEnvironment().invokeScoutLater(t, 1200);
+ try {
+ job.join(1200);
+ }
+ catch (InterruptedException ex) {
+ //nop
+ }
+ return hasValidMenus.get();
+ }
+
@Override
protected void setHorizontalAlignmentFromScout(int scoutAlign) {
if (getSwingTextField() instanceof JTextField) {
@@ -139,6 +179,7 @@
if (getSwingField() instanceof JTextFieldWithDropDownButton) {
((JTextFieldWithDropDownButton) getSwingTextField()).setDropDownButtonEnabled(b);
}
+ handleDropDownButtonEnabled();
}
protected void setFileIconIdFromScout(String s) {
@@ -253,6 +294,20 @@
}
}
+ protected void handleScoutActionPropertyChange(String name, Object newValue) {
+ if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+ IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+ handleDropDownButtonEnabled();
+ }
+ }
+
+ protected void handleDropDownButtonEnabled() {
+ if (getSwingField() instanceof JTextFieldWithDropDownButton) {
+ ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(calculateDropDownButtonEnabled());
+ getSwingField().repaint();
+ }
+ }
+
/**
* Swing action
*/
@@ -265,4 +320,24 @@
}
}// end private class
+ private class P_ScoutActionPropertyChangeListener extends AbstractSwingScoutActionPropertyChangeListener {
+ @Override
+ public void propertyChange(final PropertyChangeEvent e) {
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ getUpdateSwingFromScoutLock().acquire();
+ //
+ handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+ }
+ finally {
+ getUpdateSwingFromScoutLock().release();
+ }
+ }
+ };
+ getSwingEnvironment().invokeSwingLater(t);
+ }
+ } // end private class P_ScoutActionPropertyChangeListener
+
}
diff --git a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java
index 38f89d0..e6578ad 100644
--- a/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java
+++ b/org.eclipse.scout.rt.ui.swing/src/org/eclipse/scout/rt/ui/swing/form/fields/smartfield/SwingScoutSmartField.java
@@ -17,6 +17,8 @@
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
@@ -46,6 +48,7 @@
import org.eclipse.scout.commons.exception.ProcessingException;
import org.eclipse.scout.commons.holders.BooleanHolder;
import org.eclipse.scout.commons.job.JobEx;
+import org.eclipse.scout.rt.client.ui.action.IAction;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.form.FormEvent;
import org.eclipse.scout.rt.client.ui.form.FormListener;
@@ -54,6 +57,7 @@
import org.eclipse.scout.rt.ui.swing.LogicalGridLayout;
import org.eclipse.scout.rt.ui.swing.SwingPopupWorker;
import org.eclipse.scout.rt.ui.swing.SwingUtility;
+import org.eclipse.scout.rt.ui.swing.action.AbstractSwingScoutActionPropertyChangeListener;
import org.eclipse.scout.rt.ui.swing.basic.IconGroup;
import org.eclipse.scout.rt.ui.swing.basic.document.BasicDocumentFilter;
import org.eclipse.scout.rt.ui.swing.ext.IDropDownButtonListener;
@@ -78,6 +82,7 @@
private SwingScoutDropDownPopup m_proposalPopup;
private P_PendingProposalJob m_pendingProposalJob;
private Object m_pendingProposalJobLock;
+ private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
@Override
@SuppressWarnings("serial")
@@ -172,14 +177,22 @@
ISmartField f = getScoutObject();
setIconIdFromScout(f.getIconId());
setProposalFormFromScout(f.getProposalForm());
+ if (m_scoutActionPropertyListener == null) {
+ m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+ }
+ m_scoutActionPropertyListener.attachToScoutMenus(f.getMenus());
if (getSwingField() instanceof JTextFieldWithDropDownButton) {
- ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(getScoutObject().hasMenus());
+ ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(calculateDropDownButtonEnabled());
}
}
@Override
protected void detachScout() {
hideProposalPopup();
+ if (m_scoutActionPropertyListener != null) {
+ m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+ m_scoutActionPropertyListener = null;
+ }
super.detachScout();
}
@@ -194,6 +207,9 @@
@Override
protected void setDisplayTextFromScout(String s) {
JTextComponent swingField = getSwingTextField();
+ if (swingField instanceof JTextFieldWithDropDownButton) {
+ ((JTextFieldWithDropDownButton) swingField).setMenuEnabled(calculateDropDownButtonEnabled());
+ }
if (!CompareUtility.equals(swingField.getText(), s)) {
swingField.setText(s);
// ticket 77424
@@ -207,12 +223,31 @@
}
}
+ private boolean calculateDropDownButtonEnabled() {
+ final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+ }
+ };
+ JobEx job = getSwingEnvironment().invokeScoutLater(t, 1200);
+ try {
+ job.join(1200);
+ }
+ catch (InterruptedException ex) {
+ //nop
+ }
+ return hasValidMenus.get();
+ }
+
@Override
protected void setEnabledFromScout(boolean b) {
super.setEnabledFromScout(b);
if (getSwingField() instanceof JTextFieldWithDropDownButton) {
((JTextFieldWithDropDownButton) getSwingField()).setDropDownButtonEnabled(b);
}
+ handleDropDownButtonEnabled();
}
protected void setIconIdFromScout(String iconId) {
@@ -600,6 +635,13 @@
}
}
+ protected void handleDropDownButtonEnabled() {
+ if (getSwingField() instanceof JTextFieldWithDropDownButton) {
+ ((JTextFieldWithDropDownButton) getSwingField()).setMenuEnabled(calculateDropDownButtonEnabled());
+ getSwingField().repaint();
+ }
+ }
+
@Override
protected void handleScoutPropertyChange(String name, Object newValue) {
super.handleScoutPropertyChange(name, newValue);
@@ -611,6 +653,13 @@
}
}
+ protected void handleScoutActionPropertyChange(String name, Object newValue) {
+ if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+ IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+ handleDropDownButtonEnabled();
+ }
+ }
+
private class P_PendingProposalJob extends JobEx implements Runnable {
private String m_text;
@@ -669,4 +718,23 @@
return b.toString();
}
+ private class P_ScoutActionPropertyChangeListener extends AbstractSwingScoutActionPropertyChangeListener {
+ @Override
+ public void propertyChange(final PropertyChangeEvent e) {
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ try {
+ getUpdateSwingFromScoutLock().acquire();
+ //
+ handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+ }
+ finally {
+ getUpdateSwingFromScoutLock().release();
+ }
+ }
+ };
+ getSwingEnvironment().invokeSwingLater(t);
+ }
+ } // end private class P_ScoutActionPropertyChangeListener
}
diff --git a/org.eclipse.scout.rt.ui.swt/resources/icons/internal/dropdownfield_arrowdown_disabled.gif b/org.eclipse.scout.rt.ui.swt/resources/icons/internal/dropdownfield_arrowdown_disabled.gif
new file mode 100644
index 0000000..08ec063
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swt/resources/icons/internal/dropdownfield_arrowdown_disabled.gif
Binary files differ
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java
index cba995d..02cbba5 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/SwtIcons.java
@@ -15,6 +15,7 @@
*/
public interface SwtIcons {
String DropDownFieldArrowDown = "dropdownfield_arrowdown";
+ String DropDownFieldArrowDownDisabled = "dropdownfield_arrowdown_disabled";
String Window = "window";
String CheckboxYes = "checkbox_yes";
String CheckboxNo = "checkbox_no";
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/action/AbstractSwtScoutActionPropertyChangeListener.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/action/AbstractSwtScoutActionPropertyChangeListener.java
new file mode 100644
index 0000000..0d6d902
--- /dev/null
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/action/AbstractSwtScoutActionPropertyChangeListener.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2014 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.swt.action;
+
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
+
+/**
+ * Property change listener that can be attached to particular Scout menus.
+ *
+ * @since 4.0.0-M6
+ */
+public abstract class AbstractSwtScoutActionPropertyChangeListener implements PropertyChangeListener {
+
+ public void attachToScoutMenus(IMenu[] menus) {
+ for (IMenu menu : menus) {
+ menu.addPropertyChangeListener(this);
+ }
+ }
+
+ public void detachFromScoutMenus(IMenu[] menus) {
+ for (IMenu menu : menus) {
+ menu.removePropertyChangeListener(this);
+ }
+ }
+}
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java
index 747a91b..227604b 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/ext/ButtonEx.java
@@ -46,6 +46,7 @@
private Listener[] m_actionSelectionListener;
private Listener[] m_menuSelectionListener;
private Image m_dropDownIcon;
+ private Image m_dropDownDisabledIcon;
private P_DropDownPaintListener m_dropDownPaintListener;
private Listener m_paintListener = new Listener() {
@@ -58,7 +59,8 @@
public ButtonEx(Composite parent, int style) {
super(parent, style);
m_dropDownIcon = Activator.getIcon(SwtIcons.DropDownFieldArrowDown);
- // dopdown
+ m_dropDownDisabledIcon = Activator.getIcon(SwtIcons.DropDownFieldArrowDownDisabled);
+ // dropdown
P_DelegateSelectionListener delegateListener = new P_DelegateSelectionListener();
if ((style & SWT.DROP_DOWN) != 0) {
m_hasDropDown = true;
@@ -185,6 +187,7 @@
public void setDropDownEnabled(boolean enabled) {
m_dropDownEnabled = enabled;
+ redraw();
}
public boolean isDropDownEnabled() {
@@ -288,11 +291,15 @@
Rectangle bounds = getBounds();
gc.drawLine(bounds.width - 12, 3, bounds.width - 12, bounds.height - 4);
- gc.drawImage(m_dropDownIcon, bounds.width - 11, (bounds.height - m_dropDownIcon.getBounds().height) / 2);
- // gc.fillPolygon(new int[] { bounds.width - 10, bounds.height / 2,
- // bounds.width - 6, bounds.height - 7, bounds.width - 3, bounds.height /
- // 2 });
+ if (m_dropDownEnabled) {
+ gc.drawImage(m_dropDownIcon, bounds.width - 11, (bounds.height - m_dropDownIcon.getBounds().height) / 2);
+ }
+ else {
+ gc.drawImage(m_dropDownDisabledIcon, bounds.width - 11, (bounds.height - m_dropDownDisabledIcon.getBounds().height) / 2);
+ }
+// gc.fillPolygon(new int[]{bounds.width - 10, bounds.height / 2,
+// bounds.width - 6, bounds.height - 7, bounds.width - 3, bounds.height / 2});
}
} // end class P_DropDownPaintListener
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java
index 2b90da8..73ba159 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/button/SwtScoutButton.java
@@ -10,6 +10,8 @@
******************************************************************************/
package org.eclipse.scout.rt.ui.swt.form.fields.button;
+import java.beans.PropertyChangeEvent;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.scout.commons.OptimisticLock;
@@ -18,6 +20,7 @@
import org.eclipse.scout.commons.job.JobEx;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonEvent;
import org.eclipse.scout.rt.client.ui.form.fields.button.ButtonListener;
@@ -25,6 +28,7 @@
import org.eclipse.scout.rt.ui.swt.LogicalGridData;
import org.eclipse.scout.rt.ui.swt.LogicalGridLayout;
import org.eclipse.scout.rt.ui.swt.SwtMenuUtility;
+import org.eclipse.scout.rt.ui.swt.action.AbstractSwtScoutActionPropertyChangeListener;
import org.eclipse.scout.rt.ui.swt.ext.ButtonEx;
import org.eclipse.scout.rt.ui.swt.ext.MultilineButton;
import org.eclipse.scout.rt.ui.swt.ext.MultilineRadioButton;
@@ -61,6 +65,8 @@
private boolean m_handleActionPending;
private Menu m_contextMenu;
+ private boolean m_hasDropDown = false;
+ private P_ScoutActionPropertyListener m_scoutActionPropertyListener;
public SwtScoutButton() {
m_selectionLock = new OptimisticLock();
@@ -94,9 +100,10 @@
int style = SWT.CENTER | SWT.PUSH;
if (getScoutObject().hasMenus()) {
style |= SWT.DROP_DOWN;
+ m_hasDropDown = true;
}
ButtonEx swtButton = getEnvironment().getFormToolkit().createButtonEx(container, style);
- swtButton.setDropDownEnabled(true);
+ swtButton.setDropDownEnabled(calculateDropDownButtonEnabled());
swtFieldAsButton = swtButton;
}
}
@@ -134,6 +141,24 @@
getSwtContainer().setLayout(new LogicalGridLayout(0, 0));
}
+ private boolean calculateDropDownButtonEnabled() {
+ final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+ }
+ };
+ JobEx job = getEnvironment().invokeScoutLater(t, 1200);
+ try {
+ job.join(1200);
+ }
+ catch (InterruptedException ex) {
+ //nop
+ }
+ return hasValidMenus.get();
+ }
+
@Override
protected void attachScout() {
super.attachScout();
@@ -141,7 +166,12 @@
m_scoutButtonListener = new P_ScoutButtonListener();
getScoutObject().addButtonListener(m_scoutButtonListener);
}
-
+ if (m_hasDropDown) {
+ if (m_scoutActionPropertyListener == null) {
+ m_scoutActionPropertyListener = new P_ScoutActionPropertyListener();
+ }
+ m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+ }
}
@Override
@@ -151,6 +181,10 @@
getScoutObject().removeButtonListener(m_scoutButtonListener);
m_scoutButtonListener = null;
}
+ if (m_scoutActionPropertyListener != null) {
+ m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+ m_scoutActionPropertyListener = null;
+ }
}
@Override
@@ -322,6 +356,18 @@
}
}
+ protected void handleScoutActionPropertyChange(String name, Object newValue) {
+ if (IAction.PROP_VISIBLE.equals(name)) {
+ handleDropDownButtonEnabled();
+ }
+ }
+
+ protected void handleDropDownButtonEnabled() {
+ if (m_hasDropDown) {
+ ((ButtonEx) getSwtField()).setDropDownEnabled(calculateDropDownButtonEnabled());
+ }
+ }
+
private class P_SwtSelectionListener implements Listener {
@Override
public void handleEvent(Event event) {
@@ -417,4 +463,26 @@
}
} // end class P_ContextMenuListener
+
+ private class P_ScoutActionPropertyListener extends AbstractSwtScoutActionPropertyChangeListener {
+ @Override
+ public void propertyChange(final PropertyChangeEvent e) {
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ if (isHandleScoutPropertyChangeSwtThread()) {
+ try {
+ getUpdateSwtFromScoutLock().acquire();
+ //
+ handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+ }
+ finally {
+ getUpdateSwtFromScoutLock().release();
+ }
+ }
+ }
+ };
+ getEnvironment().invokeSwtLater(t);
+ }
+ } // end private class P_ScoutActionPropertyListener
}
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java
index a69ad37..c684bc8 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/filechooserfield/SwtScoutFileChooserField.java
@@ -10,17 +10,21 @@
******************************************************************************/
package org.eclipse.scout.rt.ui.swt.form.fields.filechooserfield;
+import java.beans.PropertyChangeEvent;
import java.io.File;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.scout.commons.CompareUtility;
import org.eclipse.scout.commons.holders.Holder;
import org.eclipse.scout.commons.job.JobEx;
+import org.eclipse.scout.rt.client.ui.action.IAction;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.basic.filechooser.IFileChooser;
import org.eclipse.scout.rt.client.ui.form.fields.filechooserfield.IFileChooserField;
import org.eclipse.scout.rt.ui.swt.LogicalGridLayout;
import org.eclipse.scout.rt.ui.swt.SwtMenuUtility;
+import org.eclipse.scout.rt.ui.swt.action.AbstractSwtScoutActionPropertyChangeListener;
import org.eclipse.scout.rt.ui.swt.ext.DropDownButton;
import org.eclipse.scout.rt.ui.swt.ext.StatusLabelEx;
import org.eclipse.scout.rt.ui.swt.form.fields.LogicalGridDataBuilder;
@@ -44,6 +48,7 @@
private DropDownButton m_fileChooserButton;
private Menu m_contextMenu;
private TextFieldEditableSupport m_editableSupport;
+ private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
@Override
protected void initializeSwt(Composite parent) {
@@ -95,11 +100,43 @@
protected void attachScout() {
super.attachScout();
setFileIconIdFromScout(getScoutObject().getFileIconId());
- getSwtFileChooserButton().setDropdownEnabled(getScoutObject().hasMenus());
+ if (m_scoutActionPropertyListener == null) {
+ m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+ }
+ m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
+ getSwtFileChooserButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+ }
+
+ @Override
+ protected void detachScout() {
+ if (m_scoutActionPropertyListener != null) {
+ m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+ m_scoutActionPropertyListener = null;
+ }
+ super.detachScout();
+ }
+
+ private boolean calculateDropDownButtonEnabled() {
+ final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+ }
+ };
+ JobEx job = getEnvironment().invokeScoutLater(t, 1200);
+ try {
+ job.join(1200);
+ }
+ catch (InterruptedException ex) {
+ //nop
+ }
+ return hasValidMenus.get();
}
@Override
protected void setDisplayTextFromScout(String s) {
+ getSwtFileChooserButton().setDropdownEnabled(calculateDropDownButtonEnabled());
if (s == null) {
s = "";
}
@@ -112,6 +149,7 @@
protected void setEnabledFromScout(boolean b) {
super.setEnabledFromScout(b);
m_fileChooserButton.setEnabled(b);
+ m_fileChooserButton.setDropdownEnabled(calculateDropDownButtonEnabled());
}
@Override
@@ -216,6 +254,17 @@
}
}
+ protected void handleScoutActionPropertyChange(String name, Object newValue) {
+ if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+ IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+ handleDropDownButtonEnabled();
+ }
+ }
+
+ protected void handleDropDownButtonEnabled() {
+ getSwtFileChooserButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+ }
+
private class P_SwtFileChooserButtonListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -263,4 +312,26 @@
}
} // end class P_ContextMenuListener
+
+ private class P_ScoutActionPropertyChangeListener extends AbstractSwtScoutActionPropertyChangeListener {
+ @Override
+ public void propertyChange(final PropertyChangeEvent e) {
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ if (isHandleScoutPropertyChangeSwtThread()) {
+ try {
+ getUpdateSwtFromScoutLock().acquire();
+ //
+ handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+ }
+ finally {
+ getUpdateSwtFromScoutLock().release();
+ }
+ }
+ }
+ };
+ getEnvironment().invokeSwtLater(t);
+ }
+ } // end class P_ScoutActionPropertyChangeListener
}
diff --git a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java
index 0f27ee6..097b4bf 100644
--- a/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java
+++ b/org.eclipse.scout.rt.ui.swt/src/org/eclipse/scout/rt/ui/swt/form/fields/smartfield/SwtScoutSmartField.java
@@ -10,8 +10,10 @@
******************************************************************************/
package org.eclipse.scout.rt.ui.swt.form.fields.smartfield;
+import java.beans.PropertyChangeEvent;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -23,6 +25,7 @@
import org.eclipse.scout.commons.job.JobEx;
import org.eclipse.scout.commons.logger.IScoutLogger;
import org.eclipse.scout.commons.logger.ScoutLogManager;
+import org.eclipse.scout.rt.client.ui.action.IAction;
import org.eclipse.scout.rt.client.ui.action.menu.IMenu;
import org.eclipse.scout.rt.client.ui.form.FormEvent;
import org.eclipse.scout.rt.client.ui.form.FormListener;
@@ -30,6 +33,7 @@
import org.eclipse.scout.rt.client.ui.form.fields.smartfield.ISmartFieldProposalForm;
import org.eclipse.scout.rt.ui.swt.LogicalGridLayout;
import org.eclipse.scout.rt.ui.swt.SwtMenuUtility;
+import org.eclipse.scout.rt.ui.swt.action.AbstractSwtScoutActionPropertyChangeListener;
import org.eclipse.scout.rt.ui.swt.ext.DropDownButton;
import org.eclipse.scout.rt.ui.swt.ext.StatusLabelEx;
import org.eclipse.scout.rt.ui.swt.form.fields.IPopupSupport;
@@ -83,6 +87,7 @@
private Set<IPopupSupportListener> m_popupEventListeners;
private Object m_popupEventListenerLock;
+ private P_ScoutActionPropertyChangeListener m_scoutActionPropertyListener;
public SwtScoutSmartField() {
m_pendingProposalJobLock = new Object();
@@ -156,19 +161,27 @@
super.attachScout();
setIconIdFromScout(getScoutObject().getIconId());
setProposalFormFromScout(getScoutObject().getProposalForm());
+ if (m_scoutActionPropertyListener == null) {
+ m_scoutActionPropertyListener = new P_ScoutActionPropertyChangeListener();
+ }
+ m_scoutActionPropertyListener.attachToScoutMenus(getScoutObject().getMenus());
}
@Override
protected void detachScout() {
// workaround since disposeFieldInternal in AbstractSmartField is never called.
hideProposalPopup();
+ if (m_scoutActionPropertyListener != null) {
+ m_scoutActionPropertyListener.detachFromScoutMenus(getScoutObject().getMenus());
+ m_scoutActionPropertyListener = null;
+ }
super.detachScout();
}
@Override
protected void setDisplayTextFromScout(String s) {
+ getSwtBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
if (!CompareUtility.equals(s, getSwtField().getText())) {
- getSwtBrowseButton().setDropdownEnabled(getScoutObject().hasMenus());
if (s == null) {
s = "";
}
@@ -178,10 +191,29 @@
}
}
+ private boolean calculateDropDownButtonEnabled() {
+ final AtomicBoolean hasValidMenus = new AtomicBoolean(false);
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ hasValidMenus.set(getScoutObject().getUIFacade().hasValidMenusFromUI());
+ }
+ };
+ JobEx job = getEnvironment().invokeScoutLater(t, 1200);
+ try {
+ job.join(1200);
+ }
+ catch (InterruptedException ex) {
+ //nop
+ }
+ return hasValidMenus.get();
+ }
+
@Override
protected void setEnabledFromScout(boolean b) {
super.setEnabledFromScout(b);
m_browseButton.setButtonEnabled(b);
+ getSwtBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
}
@Override
@@ -465,6 +497,17 @@
}
}
+ protected void handleScoutActionPropertyChange(String name, Object newValue) {
+ if (IAction.PROP_INHERIT_ACCESSIBILITY.equals(name) || IAction.PROP_EMPTY_SPACE.equals(name) ||
+ IAction.PROP_SINGLE_SELECTION.equals(name) || IAction.PROP_VISIBLE.equals(name)) {
+ handleDropDownButtonEnabled();
+ }
+ }
+
+ protected void handleDropDownButtonEnabled() {
+ getSwtBrowseButton().setDropdownEnabled(calculateDropDownButtonEnabled());
+ }
+
protected void handleTextModifiedFromUi(Event event) {
if (getUpdateSwtFromScoutLock().isAcquired()) {
return;
@@ -677,4 +720,26 @@
handleSwtBrowseAction();
}
} // end class P_F2KeyStroke
+
+ private class P_ScoutActionPropertyChangeListener extends AbstractSwtScoutActionPropertyChangeListener {
+ @Override
+ public void propertyChange(final PropertyChangeEvent e) {
+ Runnable t = new Runnable() {
+ @Override
+ public void run() {
+ if (isHandleScoutPropertyChangeSwtThread()) {
+ try {
+ getUpdateSwtFromScoutLock().acquire();
+ //
+ handleScoutActionPropertyChange(e.getPropertyName(), e.getNewValue());
+ }
+ finally {
+ getUpdateSwtFromScoutLock().release();
+ }
+ }
+ }
+ };
+ getEnvironment().invokeSwtLater(t);
+ }
+ } // end class P_ScoutActionPropertyChangeListener
}