/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.ie.view.controller; import java.awt.Component; import java.awt.Cursor; import java.awt.Image; import java.awt.Point; import java.awt.Toolkit; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.Serializable; import java.util.logging.Logger; import javax.naming.InvalidNameException; import javax.swing.JComponent; import org.openflexo.foundation.FlexoEditor; import org.openflexo.foundation.FlexoModelObject; import org.openflexo.foundation.FlexoObserver; import org.openflexo.foundation.InvalidArgumentException; import org.openflexo.foundation.dkv.DKVModel; import org.openflexo.foundation.dkv.DKVObject; import org.openflexo.foundation.dkv.DuplicateDKVObjectException; import org.openflexo.foundation.dkv.Key; import org.openflexo.foundation.ie.ComponentInstance; import org.openflexo.foundation.ie.IEObject; import org.openflexo.foundation.ie.IEWOComponent; import org.openflexo.foundation.ie.OperationComponentInstance; import org.openflexo.foundation.ie.cl.DuplicateFolderNameException; import org.openflexo.foundation.ie.cl.FlexoComponentFolder; import org.openflexo.foundation.ie.menu.FlexoItemMenu; import org.openflexo.foundation.ie.operator.IEOperator; import org.openflexo.foundation.ie.widget.ColumnIsNotEmpty; import org.openflexo.foundation.ie.widget.IETextAreaWidget; import org.openflexo.foundation.ie.widget.IEWidget; import org.openflexo.foundation.ie.widget.InvalidOperation; import org.openflexo.foundation.ie.widget.InvalidPercentage; import org.openflexo.foundation.ie.widget.NotEnoughRoomOnTheLeft; import org.openflexo.foundation.ie.widget.NotEnoughRoomOnTheRight; import org.openflexo.foundation.ie.widget.RowIsNotEmpty; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.validation.ValidationModel; import org.openflexo.icon.IconLibrary; import org.openflexo.ie.IEPreferences; import org.openflexo.ie.menu.IEMenuBar; import org.openflexo.ie.view.ComponentBrowserView; import org.openflexo.ie.view.ComponentLibraryBrowserView; import org.openflexo.ie.view.IEContainer; import org.openflexo.ie.view.IEMainPane; import org.openflexo.ie.view.IEPanel; import org.openflexo.ie.view.IESelectable; import org.openflexo.ie.view.IEWOComponentView; import org.openflexo.ie.view.controller.action.IEControllerActionInitializer; import org.openflexo.ie.view.controller.dnd.IEDTListener; import org.openflexo.ie.view.dkv.DKVEditorBrowser; import org.openflexo.ie.view.dkv.DKVModelView; import org.openflexo.ie.view.palette.IEDSWidget; import org.openflexo.ie.view.widget.IEWidgetView; import org.openflexo.inspector.InspectableObject; import org.openflexo.localization.FlexoLocalization; import org.openflexo.module.FlexoModule; import org.openflexo.module.UserType; import org.openflexo.module.external.ExternalIEController; import org.openflexo.print.PrintManager; import org.openflexo.print.PrintManagingController; import org.openflexo.selection.SelectionManager; import org.openflexo.view.FlexoMainPane; import org.openflexo.view.controller.ControllerActionInitializer; import org.openflexo.view.controller.FlexoController; import org.openflexo.view.menu.FlexoMenuBar; /** * The main controller for the IE module * * @author benoit, sylvain */ public class IEController extends FlexoController implements Serializable, FlexoObserver, ExternalIEController, PrintManagingController, PropertyChangeListener { protected static final Logger logger = Logger.getLogger(IEController.class.getPackage().getName()); private static final Image DROP_OK_IMAGE = IconLibrary.DROP_OK_CURSOR.getImage(); private static final Image DROP_KO_IMAGE = IconLibrary.DROP_KO_CURSOR.getImage(); private static final Cursor dropOK = Toolkit.getDefaultToolkit().createCustomCursor(DROP_OK_IMAGE, new Point(16, 16), "Drop OK"); private static final Cursor dropKO = Toolkit.getDefaultToolkit().createCustomCursor(DROP_KO_IMAGE, new Point(16, 16), "Drop KO"); private ComponentLibraryBrowser componentLibraryBrowser; private ComponentBrowser componentBrowser; private MenuEditorBrowser menuEditorBrowser; private DKVEditorBrowser dkvEditorBrowser; private IEContainer currentlyDroppingTarget; public ComponentPerspective COMPONENT_EDITOR_PERSPECTIVE; public DefaultValuePerspective EXAMPLE_VALUE_PERSPECTIVE; public MenuPerspective MENU_EDITOR_PERSPECTIVE; public DKVPerspective DKV_EDITOR_PERSPECTIVE; private ComponentLibraryBrowserView componentLibraryBrowserView; private ComponentBrowserView componentBrowserView; /** * Default constructor * * @param workflowFile * @throws Exception */ public IEController(FlexoModule module) { super(module); } @Override protected void initializePerspectives() { componentLibraryBrowser = new ComponentLibraryBrowser(this); componentBrowser = new ComponentBrowser(this); menuEditorBrowser = new MenuEditorBrowser(this); dkvEditorBrowser = new DKVEditorBrowser(this); IEPreferences.getPreferences().getPropertyChangeSupport().addPropertyChangeListener(IEPreferences.SHOW_BINDINGVALUE_KEY, this); componentLibraryBrowserView = new ComponentLibraryBrowserView(this);// new componentBrowserView = new ComponentBrowserView(this);// new addToPerspectives(COMPONENT_EDITOR_PERSPECTIVE = new ComponentPerspective(this)); EXAMPLE_VALUE_PERSPECTIVE = new DefaultValuePerspective(this); if (UserType.isDevelopperRelease() || UserType.isMaintainerRelease()) { addToPerspectives(EXAMPLE_VALUE_PERSPECTIVE); } addToPerspectives(MENU_EDITOR_PERSPECTIVE = new MenuPerspective(this)); addToPerspectives(DKV_EDITOR_PERSPECTIVE = new DKVPerspective(this)); } public ComponentLibraryBrowserView getComponentLibraryBrowserView() { return componentLibraryBrowserView; } public ComponentBrowserView getComponentBrowserView() { return componentBrowserView; } @Override protected SelectionManager createSelectionManager() { return new IESelectionManager(this); } public IESelectionManager getIESelectionManager() { return (IESelectionManager) getSelectionManager(); } public boolean currentPaletteIsBasicPalette() { return COMPONENT_EDITOR_PERSPECTIVE.getCurrentPalette() != null && COMPONENT_EDITOR_PERSPECTIVE.getCurrentPalette().currentPaletteIsBasicPalette(); } @Override public void updateEditor(FlexoEditor from, FlexoEditor to) { super.updateEditor(from, to); FlexoProject project = to != null ? to.getProject() : null; componentLibraryBrowser.setRootObject(project != null ? project.getFlexoComponentLibrary() : null); menuEditorBrowser.setRootObject(project != null ? project.getFlexoNavigationMenu().getRootMenu() : null); dkvEditorBrowser.setRootObject(project != null ? project.getDKVModel() : null); } @Override public FlexoModelObject getDefaultObjectToSelect(FlexoProject project) { return project.getFlexoComponentLibrary(); } @Override public void dispose() { componentLibraryBrowser.setRootObject(null); COMPONENT_EDITOR_PERSPECTIVE.disposePalettes(); super.dispose(); } @Override public ControllerActionInitializer createControllerActionInitializer() { return new IEControllerActionInitializer(this); } @Override public ValidationModel getDefaultValidationModel() { if (getProject() != null) { if (getMainPane() != null && getMainPane().getModuleView() instanceof DKVModelView) { return getProject().getDKVValidationModel(); } return getProject().getIEValidationModel(); } return null; } /** * Creates a new instance of MenuBar for the module this controller refers to * * @return */ @Override protected FlexoMenuBar createNewMenuBar() { return new IEMenuBar(this); } public ComponentLibraryBrowser getComponentLibraryBrowser() { return componentLibraryBrowser; } public ComponentBrowser getComponentBrowser() { return componentBrowser; } public MenuEditorBrowser getMenuEditorBrowser() { return menuEditorBrowser; } @Override protected FlexoMainPane createMainPane() { return new IEMainPane(this); } public void setSelectedComponent(ComponentInstance component) { setCurrentEditedObjectAsModuleView(component); } public void setSelectedMenu(FlexoItemMenu menu) { setCurrentEditedObjectAsModuleView(menu); } public void setSelectedDKVObject(DKVObject dkvObject) { setCurrentEditedObjectAsModuleView(dkvObject.getDkvModel()); } /** * @return */ public ComponentInstance getCurrentEditedComponent() { if (getCurrentModuleView() instanceof IEWOComponentView) { return ((IEWOComponentView) getCurrentModuleView()).getComponentInstance(); } return null; } public JComponent getCurrentEditZone() { return (JComponent) getCurrentModuleView(); } /** * Select the view representing supplied object, if this view exists. Try all to really display supplied object, even if required view * is not the current displayed view * * @param object * : the object to focus on */ @Override public void selectAndFocusObject(FlexoModelObject object) { if (object instanceof IEOperator && ((IEOperator) object).getOperatedSequence() != null) { setSelectedComponent(((IEWidget) object).getWOComponent().getComponentDefinition().getDummyComponentInstance()); getSelectionManager().setSelectedObject(((IEOperator) object).getOperatedSequence()); } else if (object instanceof IEWidget) { setSelectedComponent(((IEWidget) object).getWOComponent().getComponentDefinition().getDummyComponentInstance()); getSelectionManager().setSelectedObject(object); } else if (object instanceof IEWOComponent) { setSelectedComponent(((IEWOComponent) object).getComponentDefinition().getDummyComponentInstance()); getSelectionManager().setSelectedObject(object); } else if (object instanceof ComponentInstance) { setSelectedComponent((ComponentInstance) object); getSelectionManager().setSelectedObject(object); } else { super.selectAndFocusObject(object); getSelectionManager().setSelectedObject(object); } } // ========================================================================== // ===================== Model to view conversions ========================= // ========================================================================== public IESelectable selectableViewForObject(IEObject object) { IEPanel view = viewForObject(object); if (view != null) { if (view instanceof IESelectable) { return (IESelectable) view; } } return null; } public IEPanel viewForObject(IEObject object) { return viewForObject(object, false); } public IEPanel viewForObject(IEObject object, boolean performDeepSearch) { IEPanel returned = null; if (getCurrentEditZone() instanceof IEWOComponentView) { if (object instanceof IEWidget) { returned = ((IEWOComponentView) getCurrentEditZone()).findViewForModel(object); } else if (getCurrentEditedComponent() != null && object == getCurrentEditedComponent().getWOComponent()) { returned = (IEWOComponentView) getCurrentEditZone(); } if (returned == null && performDeepSearch) { returned = searchRecursivelyViewForObjectInComponent(getCurrentEditZone(), object); } } return returned; } private IEPanel searchRecursivelyViewForObjectInComponent(JComponent component, IEObject object) { for (Component c : component.getComponents()) { if (c instanceof IEWidgetView && ((IEWidgetView) c).getModel() == object) { return (IEWidgetView) c; } if (c instanceof JComponent) { IEPanel p = searchRecursivelyViewForObjectInComponent((JComponent) c, object); if (p != null) { return p; } } } return null; } @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getSource() == IEPreferences.getPreferences()) { if (evt.getPropertyName().equals(IEPreferences.SHOW_BINDINGVALUE_KEY)) { for (IEWOComponentView v : getViews(IEWOComponentView.class)) { v.notifyDisplayPrefHasChanged(); } } } else { super.propertyChange(evt); } } public DKVEditorBrowser getDkvEditorBrowser() { return dkvEditorBrowser; } /** * Overrides handleException * * @see org.openflexo.view.controller.FlexoController#handleException(org.openflexo.inspector.InspectableObject, java.lang.String, * java.lang.Object, java.lang.Throwable) */ @Override public boolean handleException(InspectableObject inspectable, String propertyName, Object value, Throwable exception) { if (inspectable instanceof IETextAreaWidget && exception instanceof InvalidArgumentException) { notify(FlexoLocalization.localizedForKey("invalid_number_of_rows")); return true; } else if (exception instanceof RowIsNotEmpty) { notify(FlexoLocalization.localizedForKey("row_") + ((RowIsNotEmpty) exception).getRow() + FlexoLocalization.localizedForKey("_is_not_empty")); return true; } else if (exception instanceof ColumnIsNotEmpty) { notify(FlexoLocalization.localizedForKey("col_") + ((ColumnIsNotEmpty) exception).getColumn() + FlexoLocalization.localizedForKey("_is_not_empty")); return true; } else if (exception instanceof InvalidOperation) { notify(FlexoLocalization.localizedForKey("invalid_operation:") + FlexoLocalization.localizedForKey(((InvalidOperation) exception).getMessage())); return true; } else if (exception instanceof InvalidPercentage) { notify(FlexoLocalization.localizedForKey("invalid_percentage:") + ((InvalidPercentage) exception).getPercentage()); return true; } else if (exception instanceof NotEnoughRoomOnTheRight) { notify(FlexoLocalization.localizedForKey("cannot_increase_width:no_more_room_on_the_right")); return true; } else if (exception instanceof NotEnoughRoomOnTheLeft) { notify(FlexoLocalization.localizedForKey("cannot_increase_width:no_more_room_on_the_left")); return true; } else if (exception instanceof DuplicateFolderNameException) { notify(FlexoLocalization.localizedForKey("there_is_already_a_folder_with that name")); return true; } else if (exception instanceof InvalidNameException) { notify(FlexoLocalization.localizedForKey("this_name_is_not_valid")); return true; } else if (exception instanceof DuplicateDKVObjectException) { if (inspectable instanceof Key) { notify(FlexoLocalization.localizedForKey("there_is_already_a_key_named") + " " + value); return true; } } return super.handleException(inspectable, propertyName, value, exception); } public IEContainer getCurrentlyDroppingTarget() { return currentlyDroppingTarget; } public void setCurrentlyDroppingTarget(IEContainer droppingTarget) { if (droppingTarget == null) { if (currentlyDroppingTarget == null) { return; } _currentDropTargetAsChanged = true; } else { if (droppingTarget.equals(currentlyDroppingTarget)) { return; } _currentDropTargetAsChanged = true; } currentlyDroppingTarget = droppingTarget; } private boolean _currentDropTargetAsChanged = false; public boolean currentDropTargetAsChanged() { if (_currentDropTargetAsChanged) { _currentDropTargetAsChanged = false; return true; } return false; } public Cursor getCurrentDragCursor(IEDSWidget _model) { if (currentlyDroppingTarget != null && IEDTListener.isValidTargetClassForDropTargetContainer(currentlyDroppingTarget.getContainerModel(), _model.getTargetClassModel(), _model.isTopComponent())) { return dropOK; } else { return dropKO; } } public Cursor getCurrentDragCursor(IEWidget _model) { if (currentlyDroppingTarget != null && IEDTListener.isValidTargetClassForDropTargetContainer(currentlyDroppingTarget.getContainerModel(), _model.getClass(), _model.isTopComponent())) { return dropOK; } else { return dropKO; } } /** * @param folder */ public void setSelectedFolder(FlexoComponentFolder folder) { setCurrentEditedObjectAsModuleView(folder); } @Override public PrintManager getPrintManager() { return PrintManager.getPrintManager(); } public IEPanel getComponentForWidgetInCurrentComponent(IEWidget widget) { if (widget == null) { return null; } return viewForObject(widget); } @Override public String getWindowTitleforObject(FlexoModelObject object) { if (object instanceof ComponentInstance) { ComponentInstance ci = (ComponentInstance) object; if (ci.getComponentDefinition() == null) { return "???"; } if (ci instanceof OperationComponentInstance) { return ci.getComponentDefinition().getName() + " (" + FlexoLocalization.localizedForKey("operation") + " " + ((OperationComponentInstance) ci).getOperationNode().getName() + ")"; } else { return ci.getComponentDefinition().getName(); } } else if (object instanceof FlexoItemMenu) { return FlexoLocalization.localizedForKey("menu") + " " + ((FlexoItemMenu) object).getMenuLabel(); } else if (object instanceof DKVModel) { return FlexoLocalization.localizedForKey("dkv_model"); } return null; } }