0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.visualweb.designer.jsf.ui;
0042:
0043: import java.util.logging.LogRecord;
0044: import java.util.prefs.PreferenceChangeEvent;
0045: import java.util.prefs.PreferenceChangeListener;
0046: import org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition;
0047: import java.awt.BorderLayout;
0048: import java.awt.Color;
0049: import java.awt.Component;
0050: import java.awt.Cursor;
0051: import java.awt.Dimension;
0052: import java.awt.EventQueue;
0053: import java.awt.GridBagConstraints;
0054: import java.awt.GridBagLayout;
0055: import java.awt.Insets;
0056: import java.awt.Point;
0057: import java.awt.SystemColor;
0058: import java.awt.datatransfer.Transferable;
0059: import java.awt.event.ActionEvent;
0060: import java.awt.event.KeyEvent;
0061: import java.beans.PropertyChangeEvent;
0062: import java.beans.PropertyChangeListener;
0063: import java.io.BufferedWriter;
0064: import java.io.PrintWriter;
0065: import java.io.StringWriter;
0066: import java.io.StringWriter;
0067: import java.lang.ref.WeakReference;
0068: import java.util.ArrayList;
0069: import java.util.Arrays;
0070: import java.util.List;
0071: import java.util.logging.Level;
0072: import java.util.logging.Logger;
0073:
0074: import javax.swing.AbstractAction;
0075: import javax.swing.Action;
0076: import javax.swing.ActionMap;
0077: import javax.swing.InputMap;
0078: import javax.swing.JButton;
0079: import javax.swing.JComponent;
0080: import javax.swing.JLabel;
0081: import javax.swing.JPanel;
0082: import javax.swing.JPopupMenu;
0083: import javax.swing.JScrollPane;
0084: import javax.swing.JToolBar;
0085: import javax.swing.JViewport;
0086: import javax.swing.KeyStroke;
0087: import javax.swing.SwingUtilities;
0088: import javax.swing.UIManager;
0089: import javax.swing.border.EmptyBorder;
0090:
0091: import org.netbeans.core.spi.multiview.CloseOperationState;
0092: import org.netbeans.core.spi.multiview.MultiViewElementCallback;
0093: import org.netbeans.core.spi.multiview.MultiViewFactory;
0094: import org.netbeans.modules.visualweb.api.designer.Designer;
0095: import org.netbeans.modules.visualweb.api.designer.Designer.Box;
0096: import org.netbeans.modules.visualweb.api.designer.Designer.DesignerListener;
0097: import org.netbeans.modules.visualweb.api.designer.cssengine.CssValue;
0098: import org.netbeans.modules.visualweb.designer.jsf.JsfDesignerPreferences;
0099: import org.netbeans.spi.navigator.NavigatorLookupHint;
0100: import org.netbeans.spi.navigator.NavigatorLookupPanelsPolicy;
0101: import org.netbeans.spi.palette.PaletteController;
0102: import org.openide.ErrorManager;
0103: import org.openide.explorer.ExplorerUtils;
0104: import org.openide.loaders.DataObject;
0105: import org.openide.nodes.Node;
0106: import org.openide.util.HelpCtx;
0107: import org.openide.util.Lookup;
0108: import org.openide.util.NbBundle;
0109: import org.openide.util.Utilities;
0110: import org.openide.util.WeakListeners;
0111: import org.openide.util.lookup.Lookups;
0112: import org.openide.util.lookup.ProxyLookup;
0113: import org.openide.windows.TopComponent;
0114:
0115: import org.netbeans.modules.visualweb.designer.jsf.JsfForm;
0116: import org.netbeans.modules.visualweb.designer.jsf.JsfSupportUtilities;
0117: import org.netbeans.modules.visualweb.extension.openide.loaders.SystemFileSystemSupport;
0118: import org.openide.awt.Actions;
0119: import org.openide.nodes.AbstractNode;
0120: import org.openide.nodes.Children;
0121: import org.openide.util.ContextAwareAction;
0122: import org.openide.util.actions.Presenter;
0123: import org.w3c.dom.Document;
0124: import org.w3c.dom.Element;
0125:
0126: /**
0127: * XXX Before as designer/../DesignerTopComp.
0128: *
0129: * This represents the Design View of a page. The actual
0130: * drawing surface is a DesignerPane, so this class encapsulates
0131: * everything around that: the scrollbar, focus management,
0132: * component open/close, save synchronization, etc.
0133: *
0134: * @author Tor Norbye
0135: */
0136: public class JsfTopComponent extends AbstractJsfTopComponent /*SelectionTopComp*/{
0137:
0138: // XXX Get rid of this.
0139: private static final boolean SHOW_RENDER_ERRORS = System
0140: .getProperty("rave.hideRenderErrors") == null;
0141:
0142: // /** Should we show a Tray (like in Reef 1.0) or not? */
0143: // static final boolean SHOW_TRAY = (System.getProperty("rave.showTray") != null); // NOI18N
0144:
0145: private static final NavigatorLookupHint NAVIGATOR_HINT = new DesignerNavigatorLookupHint();
0146:
0147: private static final NavigatorLookupPanelsPolicy NAVIGATOR_LOOKUP_PANELS_POLICY = new DesignerNavigatorLookupPanelsPolicy();
0148:
0149: // // XXX Get rid of this suspicious impl.
0150: // private static boolean pendingRefreshAll;
0151:
0152: private boolean componentInited;
0153: // private transient boolean initialized;
0154: private transient JToolBar toolbar;
0155: private transient boolean needListeners = true;
0156:
0157: // ----- Error Handling -----
0158: private boolean showingErrors = false;
0159:
0160: /** When we show the error page, take whatever component
0161: * was showing in the main area and stash it here so we can
0162: * restore it correctly. */
0163: private Component hiddenComp = null;
0164:
0165: // ------ Tray handling -----------
0166: // private boolean trayShowing = false;
0167: // private JSplitPane splitPanel = null;
0168: // private Tray tray;
0169: // long generationSeen = 0;
0170: // DesignerPane html = null;
0171: // XXX
0172: private JComponent html;
0173:
0174: // XXX
0175: // private JComponent html;
0176:
0177: // private JScrollPane scroller = null;
0178: // private boolean showing = false;
0179:
0180: // <multiview>
0181: private transient MultiViewElementCallback multiViewElementCallback;
0182: // private JToggleButton showVfButton;
0183: // private JButton refreshButton;
0184: // private JButton previewButton;
0185: // private long lastEscape = -1;
0186:
0187: // private final PropertyChangeListener settingsListener = new SettingsListener(this);
0188: private final PreferenceChangeListener settingsListener = new SettingsListener(
0189: this );
0190:
0191: private final PropertyChangeListener activatedNodesListener = new ActivatedNodesListener(
0192: this );
0193:
0194: private final DesignerListener designerListener = new JsfDesignerListener(
0195: this );
0196: // private final PaletteController designerPaletteController;
0197:
0198: private final JsfLookupProvider jsfLookupProvider/* = new JsfLookupProvider(this)*/; // TEMP
0199:
0200: // XXX #124931 We need to keep a link to DataObject until the FacesModel is created.
0201: // Consequence of a bad model creation in insync (it can't create not-fully loaded model,
0202: // which would maintain the link to the DataObject correctly).
0203: private DataObject jspDataObject;
0204:
0205: // memory leak probing
0206: private static final Logger TIMERS = Logger
0207: .getLogger("TIMER.visualweb"); // NOI18N
0208:
0209: private final JPanel panel = new JPanel();
0210:
0211: public JsfTopComponent(/*WebForm webform*/JsfForm jsfForm,
0212: Designer designer, DataObject jspDataObject) {
0213: // super(webform);
0214: super (jsfForm, designer);
0215:
0216: if (TIMERS.isLoggable(Level.FINER)) {
0217: LogRecord rec = new LogRecord(Level.FINER,
0218: "JsfTopComponent"); // NOI18N
0219: rec.setParameters(new Object[] { this });
0220: TIMERS.log(rec);
0221: }
0222:
0223: this .jspDataObject = jspDataObject;
0224:
0225: // XXX Moved to designer/jsf/PaletteControllerFactory.
0226: // /*
0227: // * Hack - We have created a dependency on project/jsf to get JsfProjectUtils.
0228: // * Ultimately this should be placed into a lookup.
0229: // */
0230: // String paletteDirectory;
0231: // if ( JsfProjectUtils.JAVA_EE_5.equals(JsfProjectUtils.getJ2eePlatformVersion(webform.getProject()))) {
0232: // paletteDirectory = "CreatorDesignerPalette5";
0233: // } else {
0234: // //Later to be renamed with a 1.4
0235: // paletteDirectory = "CreatorDesignerPalette";
0236: // }
0237: //
0238: // // XXX PaletteController
0239: // PaletteController controller;
0240: // try {
0241: // ComplibService complibService = (ComplibService)Lookup.getDefault().lookup(ComplibService.class);
0242: // PaletteFilter complibPaletteFilter;
0243: // if (complibService == null) {
0244: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
0245: // new NullPointerException("There is no ComplibService available!")); // NOI18N
0246: // complibPaletteFilter = null;
0247: // } else {
0248: // complibPaletteFilter = complibService.createComplibPaletteFilter(webform.getProject());
0249: // }
0250: // controller = PaletteFactory.createPalette(paletteDirectory,
0251: // new DesignerPaletteActions(paletteDirectory), complibPaletteFilter, null);
0252: //
0253: // // XXX #6466711 Listening to changes of complib to refresh the palette.
0254: // DesignerComplibListener.getDefault().install();
0255: // DesignerComplibListener.getDefault().setPaletteController(controller);
0256: // } catch (java.io.IOException ex) {
0257: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
0258: // controller = null;
0259: // }
0260: // designerPaletteController = controller;
0261:
0262: jsfLookupProvider = new JsfLookupProvider(this , jspDataObject);
0263:
0264: setName("Visual Design"); // NOI18N
0265: setDisplayName(NbBundle.getMessage(JsfTopComponent.class,
0266: "LBL_JsfDisplayName")); // NOI18N
0267: getAccessibleContext().setAccessibleDescription(
0268: NbBundle.getMessage(JsfTopComponent.class,
0269: "ACSD_DesignerTopComp"));
0270:
0271: initActivatedNodes(jspDataObject);
0272:
0273: initDesignerPreferences();
0274:
0275: panel.setOpaque(false);
0276: panel.setLayout(new GridBagLayout());
0277: setLayout(new BorderLayout());
0278: add(panel, BorderLayout.CENTER);
0279: }
0280:
0281: JsfForm getJsfForm() {
0282: return jsfForm;
0283: }
0284:
0285: Designer getDesigner() {
0286: return designer;
0287: }
0288:
0289: private void initActivatedNodes(DataObject jspDataObject) {
0290: // XXX Providing dummy node containing the DataObject in the lookup -> needed by Navigator?!.
0291: setActivatedNodes(new Node[] { new DummyNode(jspDataObject) });
0292: }
0293:
0294: private static class DummyNode extends AbstractNode {
0295: public DummyNode(DataObject jspDataObject) {
0296: super (Children.LEAF, Lookups.fixed(jspDataObject));
0297: }
0298: } // End of DummyNode.
0299:
0300: private void initDesignerPreferences() {
0301: JsfDesignerPreferences jsfDesignerPreferences = JsfDesignerPreferences
0302: .getInstance();
0303: // designer.setPageSizeWidth(jsfDesignerPreferences.getPageSizeWidth());
0304: // designer.setPageSizeHeight(jsfDesignerPreferences.getPageSizeHeight());
0305: designer.setPageSize(new Dimension(jsfDesignerPreferences
0306: .getPageSizeWidth(), jsfDesignerPreferences
0307: .getPageSizeHeight()));
0308: designer.setGridShow(jsfDesignerPreferences.getGridShow());
0309: designer.setGridSnap(jsfDesignerPreferences.getGridSnap());
0310: designer.setGridWidth(jsfDesignerPreferences.getGridWidth());
0311: setGridTraceWidth(jsfDesignerPreferences.getGridWidth());
0312: designer.setGridHeight(jsfDesignerPreferences.getGridHeight());
0313: setGridTraceHeight(jsfDesignerPreferences.getGridHeight());
0314: designer.setShowDecorations(jsfDesignerPreferences
0315: .isShowDecorations());
0316: designer.setDefaultFontSize(jsfDesignerPreferences
0317: .getDefaultFontSize());
0318: }
0319:
0320: private void initComponent() {
0321: if (jsfForm.isValid()) {
0322: initDesigner();
0323: } else {
0324: // XXX Model not available yet.
0325: initLoadingComponent();
0326: }
0327: }
0328:
0329: private void initDesigner() {
0330: initDesignerComponent();
0331: initDesignerListeners();
0332: }
0333:
0334: private void initDesignerListeners() {
0335: // DesignerSettings.getInstance().addPropertyChangeListener(
0336: // WeakListeners.propertyChange(settingsListener, DesignerSettings.getInstance()));
0337: // DesignerSettings.getInstance().addWeakPreferenceChangeListener(settingsListener);
0338: // designer.addWeakPreferenceChangeListener(settingsListener);
0339: JsfDesignerPreferences.getInstance()
0340: .addWeakPreferenceChangeListener(settingsListener);
0341:
0342: addPropertyChangeListener(WeakListeners.propertyChange(
0343: activatedNodesListener, this ));
0344:
0345: designer.addDesignerListener(WeakListeners.create(
0346: DesignerListener.class, designerListener, designer));
0347: }
0348:
0349: private void initDesignerComponent() {
0350: panel.removeAll();
0351: // setLayout(new BorderLayout());
0352: createDesignerPane();
0353:
0354: installActions();
0355:
0356: //#43157 - editor actions need to be accessible from outside using the
0357: // TopComponent.getLookup(ActionMap.class) call.
0358: // used in main menu enabling/disabling logic.
0359: ActionMap am = getActionMap();
0360: // ActionMap paneMap = html.getActionMap();
0361: ActionMap paneMap = designer.getPaneActionMap();
0362:
0363: am.setParent(paneMap);
0364:
0365: designer.setPaintSizeMask(jsfForm.isFragment()
0366: || jsfForm.isPortlet());
0367: }
0368:
0369: private void initLoadingComponent() {
0370: panel.removeAll();
0371: // setLayout(new BorderLayout());
0372: panel.add(createLoadingComponent(),
0373: getDefaultGridBagConstraints());
0374: }
0375:
0376: private JComponent createLoadingComponent() {
0377: JLabel loadingComponent = new JLabel(NbBundle.getMessage(
0378: JsfTopComponent.class, "LBL_LoadingModel"),
0379: JLabel.CENTER);
0380: loadingComponent.setForeground(SystemColor.textInactiveText);
0381: loadingComponent.setCursor(Cursor
0382: .getPredefinedCursor(Cursor.WAIT_CURSOR));
0383: return loadingComponent;
0384: }
0385:
0386: private JComponent createReloadingComponent() {
0387: JLabel reloadingComponent = new JLabel(NbBundle.getMessage(
0388: JsfTopComponent.class, "LBL_ReloadingModel"),
0389: JLabel.CENTER);
0390: reloadingComponent.setOpaque(true);
0391: Color backgroundColor = SystemColor.control;
0392: reloadingComponent.setBackground(new Color(backgroundColor
0393: .getRed(), backgroundColor.getGreen(), backgroundColor
0394: .getBlue(), 150) // Provide some constant for alpha?
0395: );
0396: reloadingComponent.setForeground(SystemColor.textInactiveText);
0397: reloadingComponent.setCursor(Cursor
0398: .getPredefinedCursor(Cursor.WAIT_CURSOR));
0399: return reloadingComponent;
0400: }
0401:
0402: @Override
0403: protected String preferredID() {
0404: return "DESIGNER"; //NOI18N
0405: }
0406:
0407: // Cheating persistence, designer is opened using 'multi_view' hack.
0408: @Override
0409: public int getPersistenceType() {
0410: return PERSISTENCE_NEVER;
0411: }
0412:
0413: @Override
0414: protected void componentOpened() {
0415: // if (!initialized) {
0416: // initialized = true;
0417: //// setLayout(new BorderLayout());
0418: //// createDesignerPane();
0419: ////
0420: //// installActions();
0421: ////
0422: //// //#43157 - editor actions need to be accessible from outside using the
0423: //// // TopComponent.getLookup(ActionMap.class) call.
0424: //// // used in main menu enabling/disabling logic.
0425: //// ActionMap am = getActionMap();
0426: ////// ActionMap paneMap = html.getActionMap();
0427: //// ActionMap paneMap = designer.getPaneActionMap();
0428: ////
0429: //// am.setParent(paneMap);
0430: // initComponent();
0431: // }
0432:
0433: // // The following will also initialize the context listeners,
0434: // // provided the context is available
0435: // updateErrors();
0436: //
0437: // // Set listening.
0438: //// webform.registerListeners();
0439: // // XXX
0440: // designer.registerListeners();
0441: //
0442: //// if (SHOW_TRAY) {
0443: //// refreshTray(hasTrayBeans(), null);
0444: //// }
0445: //
0446: // openAdditionalWindows();
0447: if (jsfForm.isValid()) {
0448: designerOpened();
0449: }
0450: }
0451:
0452: @Override
0453: protected void componentClosed() {
0454: // DesignContext context = webform.getModel().getLiveUnit();
0455: //
0456: // if ((context != null) && !needListeners) {
0457: // context.removeDesignContextListener(this);
0458:
0459: // XXX Do not recreate the synchronizer (causes errors).
0460: // TODO Do not recreate synchronizer in getters.
0461: // if (webform.hasDomSynchronizer()) {
0462: // webform.getDomSynchronizer().detachContext();
0463: // }
0464:
0465: //// webform.detachContext();
0466: // if (!needListeners) {
0467: // needListeners = true;
0468: // }
0469: //
0470: // // Stop listening.
0471: //// webform.unregisterListeners();
0472: // // XXX
0473: // designer.unregisterListeners();
0474: //
0475: //// webform.clearHtml();
0476: // jsfForm.clearHtml();
0477: if (jsfForm.isValid()) {
0478: designerClosed();
0479: }
0480: }
0481:
0482: // XXX Bad API, why one needs to override the deprecated API?
0483: @Override
0484: public void requestFocus() {
0485: // XXX TopComponent is not focusable. This call was needless.
0486: // super.requestFocus();
0487:
0488: // XXX see above.
0489: // DesignerPane designerPane = getDesignerPane();
0490: // if (designerPane != null) {
0491: // // XXX NB #90506 Possible NPE.
0492: // designerPane.requestFocus();
0493: // }
0494: designer.paneRequestFocus();
0495: }
0496:
0497: @Override
0498: public void requestVisible() {
0499: if (multiViewElementCallback != null) {
0500: multiViewElementCallback.requestVisible();
0501: } else {
0502: super .requestVisible();
0503: }
0504: }
0505:
0506: @Override
0507: public void requestActive() {
0508: if (multiViewElementCallback != null) {
0509: multiViewElementCallback.requestActive();
0510: } else {
0511: super .requestActive();
0512: }
0513: }
0514:
0515: /**
0516: * Update the error state for the form - possibly show an error panel or hide one
0517: * if already showing
0518: */
0519: public void updateErrors() {
0520: // boolean busted = webform.getModel().isBusted();
0521: // boolean busted = webform.isModelBusted();
0522: boolean busted = jsfForm.isModelBusted();
0523:
0524: if (!busted && needListeners) {
0525: needListeners = false;
0526:
0527: // DesignContext context = webform.getModel().getLiveUnit();
0528: //
0529: // if(context != null) {
0530: //// webform.getDomSynchronizer().attachContext(context);
0531: // webform.attachContext(context);
0532: //// context.addDesignContextListener(this);
0533: // }
0534: // webform.attachContext();
0535: jsfForm.attachContext();
0536: }
0537:
0538: // if (SHOW_RENDER_ERRORS && (webform.hasRenderingErrors() || webform.getHtmlBody(false) == null)) {
0539: // if (!webform.isRenderFailureShown()) {
0540: if (SHOW_RENDER_ERRORS
0541: && (jsfForm.hasRenderingErrors() || jsfForm
0542: .getHtmlBody(false) == null)) {
0543: // if (!webform.isRenderFailureShown()) {
0544: if (!jsfForm.isRenderFailureShown()) {
0545: showErrors(true);
0546: }
0547: } else {
0548: showErrors(busted);
0549: }
0550: }
0551:
0552: void showErrors(boolean on) {
0553: if (on == showingErrors) {
0554: if (on) {
0555: Component comp = panel.getComponent(0);
0556:
0557: // if (comp instanceof ErrorPanel) {
0558: // ((ErrorPanel)comp).updateErrors();
0559: // } else {
0560: // ((RenderErrorPanel)comp).updateErrors();
0561: // }
0562: // if (comp instanceof ErrorPanel) {
0563: // ((ErrorPanel)comp).updateErrors();
0564: // }
0565: if (comp instanceof JsfForm.ErrorPanel) {
0566: ((JsfForm.ErrorPanel) comp).updateErrors();
0567: }
0568: }
0569:
0570: return;
0571: }
0572:
0573: assert SwingUtilities.isEventDispatchThread();
0574:
0575: if (on) {
0576: // assert getComponentCount() >= 1;
0577: if (panel.getComponentCount() == 0) {
0578: ErrorManager
0579: .getDefault()
0580: .notify(
0581: ErrorManager.INFORMATIONAL,
0582: new IllegalStateException(
0583: "Designer top component is not initialized,"
0584: + " there is no designer pane or error panel in it")); // NOI18N
0585: return;
0586: }
0587:
0588: // XXX #125804 We need to get a component containing the designer,
0589: // and it is wrong to assume it is the first one, it is the last one.
0590: int componentCount = panel.getComponentCount();
0591: if (componentCount > 0) {
0592: hiddenComp = panel.getComponent(componentCount - 1);
0593: }
0594: panel.removeAll();
0595:
0596: // if (webform.getModel().isBusted()) {
0597: // ErrorPanel errorPanel = new ErrorPanel(webform, webform.getModel().getErrors());
0598: // add(errorPanel, BorderLayout.CENTER);
0599: // } else {
0600: // RenderErrorPanel errorPanel = new RenderErrorPanel(webform);
0601: // add(errorPanel, BorderLayout.CENTER);
0602: // }
0603: // JComponent errorPanel = webform.getErrorPanel();
0604: JComponent errorPanel = jsfForm
0605: .getErrorPanel(new ErrorPanelCallbackImpl(this ));
0606:
0607: panel.add(errorPanel, getDefaultGridBagConstraints());
0608: } else {
0609: assert panel.getComponentCount() >= 1;
0610: panel.removeAll();
0611: assert hiddenComp != null;
0612:
0613: // Add old contents back: could be design scroll pane, or could
0614: // be split pane showing scrollpane and tray.
0615: panel.add(hiddenComp, getDefaultGridBagConstraints());
0616:
0617: // Ensure that the exposed component has dimensions, otherwise
0618: // it won't receive any paint requests (and I drive layout from
0619: // the paint request). This can be a problem if you've loaded a
0620: // project that had errors that you just fixed for example.
0621: if ((hiddenComp.getWidth() == 0)
0622: || (hiddenComp.getHeight() == 0)) {
0623: hiddenComp.setSize(getWidth(), getHeight());
0624:
0625: // Anticipate the below statement such that if we recurse
0626: // we bail out
0627: showingErrors = on;
0628: // webform.refresh(false);
0629: // webform.refreshModel(false);
0630: jsfForm.refreshModel(false);
0631: }
0632: }
0633:
0634: showingErrors = on;
0635:
0636: /*
0637: invalidate();
0638: if (getParent() != null) {
0639: getParent().validate();
0640: }
0641: */
0642: revalidate();
0643: repaint();
0644: }
0645:
0646: // /** Hide or show the nonvisual component tray in the designer view
0647: // * @param on When true, show the view, when false hide the view.*/
0648: // private void refreshTray(final boolean on, final DesignBean highlight) {
0649: // if (!SHOW_TRAY) {
0650: // return;
0651: // }
0652: //
0653: // if (SwingUtilities.isEventDispatchThread()) {
0654: // showTrayAWT(on, highlight);
0655: // } else {
0656: // SwingUtilities.invokeLater(new Runnable() {
0657: // public void run() {
0658: // showTrayAWT(on, highlight);
0659: // }
0660: // });
0661: // }
0662: // }
0663: //
0664: // /** Return true iff the tray is showing */
0665: // private boolean isTrayShowing() {
0666: // return trayShowing;
0667: // }
0668: //
0669: // /** Can only be called from the event dispatch thread */
0670: // private void showTrayAWT(boolean on, DesignBean highlight) {
0671: // if (!SHOW_TRAY) {
0672: // return;
0673: // }
0674: //
0675: // if (showingErrors) { // Does not apply when errors are showing
0676: //
0677: // return;
0678: // }
0679: //
0680: // if (trayShowing == on) {
0681: // if (on && (tray != null)) {
0682: // tray.refresh(highlight);
0683: //
0684: // Dimension d = tray.getPreferredSize();
0685: //
0686: // if (tray.getHeight() != d.height) {
0687: // splitPanel.resetToPreferredSizes();
0688: // }
0689: // }
0690: //
0691: // return;
0692: // }
0693: //
0694: // trayShowing = on;
0695: //
0696: // if (trayShowing) {
0697: // // Tray wasn't showing, now should be
0698: // this.remove(scroller);
0699: //
0700: // if (splitPanel == null) {
0701: // splitPanel = new JSplitPane();
0702: // splitPanel.setOrientation(JSplitPane.VERTICAL_SPLIT);
0703: // splitPanel.setResizeWeight(1);
0704: // splitPanel.setOneTouchExpandable(true);
0705: //
0706: // // Add tray for nonvisual components
0707: // tray = new Tray(webform);
0708: // }
0709: //
0710: // tray.refresh(highlight);
0711: // splitPanel.setTopComponent(scroller);
0712: // splitPanel.setBottomComponent(tray);
0713: // this.add(splitPanel, BorderLayout.CENTER);
0714: // } else {
0715: // // Tray was showing, now shouldn't be
0716: // this.remove(splitPanel);
0717: //
0718: // splitPanel.remove(scroller);
0719: // splitPanel.remove(tray);
0720: // add(scroller, BorderLayout.CENTER);
0721: // }
0722: //
0723: // invalidate();
0724: //
0725: // if (getParent() != null) {
0726: // getParent().validate();
0727: // }
0728: //
0729: // repaint();
0730: // }
0731:
0732: // private boolean hasTrayBeans() {
0733: // if (!SHOW_TRAY) {
0734: // return false;
0735: // }
0736: //
0737: // DesignBean rootbean = webform.getModel().getRootBean();
0738: //
0739: // if (rootbean == null) {
0740: // return false;
0741: // }
0742: //
0743: // for (int i = 0, n = rootbean.getChildBeanCount(); i < n; i++) {
0744: // DesignBean bean = rootbean.getChildBean(i);
0745: //
0746: // if (LiveUnit.isTrayBean(bean)) {
0747: // return true;
0748: // }
0749: // }
0750: //
0751: // return false;
0752: // }
0753: //
0754: // Tray getTray() {
0755: // return tray;
0756: // }
0757:
0758: // ------ Implements DesignContextListener ---------------------------
0759: // public void contextActivated(DesignContext context) {
0760: // }
0761:
0762: // public void contextDeactivated(DesignContext context) {
0763: // }
0764:
0765: // public void contextChanged(DesignContext context) {
0766: public void designContextGenerationChanged() {
0767: // if(DesignerUtils.DEBUG) {
0768: // DesignerUtils.debugLog(getClass().getName() + ".contextChanged(DesignContext)");
0769: // }
0770: // if(context == null) {
0771: // throw(new IllegalArgumentException("Null context"));
0772: // }
0773: //// long currentGeneration = ((LiveUnit)context).getContextGeneration();
0774: // long currentGeneration = WebForm.getDomProviderService().getContextGenearation(context);
0775: //
0776: // if (generationSeen == currentGeneration) {
0777: // return;
0778: // }
0779: //
0780: // generationSeen = currentGeneration;
0781:
0782: //webform.getSelection().clearSelection(true);
0783: // Ensure that the app outline is current before we try to mess
0784: // with its selection (see 6197251)
0785: // OutlineTopComp.getInstance().contextChanged(context);
0786:
0787: // XXX #106332 Bad architecture, there were changed beans instanes in the hierarchy,
0788: // and at this moment the rendered doc is not regenerated.
0789: EventQueue.invokeLater(new Runnable() {
0790: public void run() {
0791: // Caret syncing needs to be delayed until we have updated the rendered dom!
0792: //webform.getSelection().syncCaret();
0793: // webform.getManager().syncSelection(true);
0794: // webform.getSelection().syncSelection(true);
0795: designer.syncSelection(true);
0796:
0797: // if (SHOW_TRAY) {
0798: // // XXX todo sync tray selection!
0799: // refreshTray(hasTrayBeans(), null);
0800: // }
0801:
0802: if (isShowing()) {
0803: updateErrors();
0804: }
0805: }
0806: });
0807: }
0808:
0809: // public void beanContextActivated(DesignBean designBean) {
0810: // }
0811:
0812: // public void beanContextDeactivated(DesignBean designBean) {
0813: // }
0814:
0815: // public void beanCreated(DesignBean bean) {
0816: // if(DesignerUtils.DEBUG) {
0817: // DesignerUtils.debugLog(getClass().getName() + ".beanCreated(DesignBean)");
0818: // }
0819: // if(bean == null) {
0820: // throw(new IllegalArgumentException("Null bean"));
0821: // }
0822: //// if (SHOW_TRAY) {
0823: //// if (LiveUnit.isTrayBean(bean)) {
0824: //// refreshTray(true, bean);
0825: //// }
0826: //// }
0827: //
0828: // // If the bean corresponds to a DOM element, we'll be
0829: // // notified from DOM itself when insync adds the
0830: // // DOM element. So we can ignore this event.
0831: // // Furthermore, it's difficult to process it here since
0832: // // we don't know exactly WHERE in the DOM insync is going
0833: // // to place the element - even if we know it typically is
0834: // // parented by the <h:form> element, we don't know which
0835: // // child position it's assigned - and that's important for
0836: // // static layout (e.g. palette double click instead of
0837: // // specific drop location).
0838: // // Log.err.log("Massive hack in beanCreated!");
0839: // // webform.getDocument().notifyDomChanged(true);
0840: // }
0841:
0842: // public void beanDeleted(DesignBean bean) {
0843: // if(DesignerUtils.DEBUG) {
0844: // DesignerUtils.debugLog(getClass().getName() + ".beandeleted(DesignBean)");
0845: // }
0846: // if(bean == null) {
0847: // throw(new IllegalArgumentException("Null bean"));
0848: // }
0849: //// if (SHOW_TRAY) {
0850: //// if (LiveUnit.isTrayBean(bean)) {
0851: //// refreshTray(hasTrayBeans(), null);
0852: //// }
0853: //// }
0854: //
0855: // // If the bean corresponds to a DOM element, we'll be
0856: // // notified from DOM itself when insync deletes the
0857: // // DOM element. So we can ignore this event.
0858: // // Log.err.log("Massive hack in beanDeleted!");
0859: // // webform.getDocument().notifyDomChanged(true);
0860: // }
0861:
0862: // public void instanceNameChanged(DesignBean bean, String oldInstanceName) {
0863: // }
0864:
0865: // public void beanChanged(DesignBean bean) {
0866: // if(DesignerUtils.DEBUG) {
0867: // DesignerUtils.debugLog(getClass().getName() + ".beanChanged(DesignBean)");
0868: // }
0869: // if(bean == null) {
0870: // throw(new IllegalArgumentException("Null bean"));
0871: // }
0872: //// if (SHOW_TRAY) {
0873: //// if (LiveUnit.isTrayBean(bean)) {
0874: //// DesignBean added = ((tray != null) && tray.isBlinking()) ? bean : null;
0875: //// refreshTray(hasTrayBeans(), added);
0876: //// }
0877: //// }
0878: // }
0879:
0880: // public void beanMoved(DesignBean lbean, DesignBean oldParent,
0881: // Position pos) {
0882: // // XXX What do we do here?
0883: // // Probably nothing, since we'll be notified of manipulations
0884: // // to the DOM itself separately via the DOM listeners
0885: // }
0886:
0887: // public void propertyChanged(final DesignProperty prop, Object oldValue) {
0888: //// DesignBean bean = prop.getDesignBean();
0889: //
0890: //// if (SHOW_TRAY) {
0891: //// if (LiveUnit.isTrayBean(bean)) {
0892: //// DesignBean added = ((tray != null) && tray.isBlinking()) ? bean : null;
0893: //// refreshTray(hasTrayBeans(), added);
0894: //// }
0895: //// }
0896: // }
0897:
0898: // public void eventChanged(DesignEvent event) {
0899: // // XXX What do we do here?
0900: // }
0901:
0902: // public void selectNonTrayBeans(DesignBean[] beans) {
0903: // // TODO -- blink the Application Outline?
0904: //// OutlineTopComp.getInstance().selectBeans(beans);
0905: //
0906: //// if (SHOW_TRAY) {
0907: //// // The above doesn't set the activated nodes etc. so we do that here
0908: //// ArrayList nodes = new ArrayList(beans.length);
0909: ////
0910: //// for (int i = 0, n = beans.length; i < n; i++) {
0911: //// DesignBeanNode node = (DesignBeanNode)DesigntimeIdeBridgeProvider.getDefault().getNodeRepresentation(beans[i]);
0912: //// node.setDataObject(webform.getDataObject());
0913: //// nodes.add(node);
0914: //// }
0915: ////
0916: //// Node[] nds = (Node[])nodes.toArray(new Node[nodes.size()]);
0917: ////
0918: //// DesignerUtils.setActivatedNodes(this, nds);
0919: ////
0920: //// if (isShowing()) { // Make sure tray has focus
0921: //// requestActive();
0922: //// }
0923: //// } else {
0924: //// OutlineTopComp.getInstance().requestActive();
0925: //// }
0926: // }
0927:
0928: // private static void openNewOutline() {
0929: // TopComponent newOutline = findNewOutline();
0930: // if (newOutline != null && !newOutline.isOpened()) {
0931: // // FIXME XXX Just for now to fake the old kind of behaviour. Use TopComponentGroup to fix it.
0932: // newOutline.open();
0933: // }
0934: // }
0935: //
0936: // private static void selectNewOutline() {
0937: // TopComponent newOutline = findNewOutline();
0938: // if (newOutline != null) {
0939: // // XXX #6392131 -> NB #62329.
0940: // if (!Boolean.TRUE.equals(newOutline.getClientProperty("isSliding"))) { // NOI18N
0941: // // FIXME XXX Just for now to fake the old kind of behaviour. Use TopComponentGroup to fix it.
0942: // newOutline.requestVisible();
0943: // }
0944: // }
0945: // }
0946: //
0947: // private static TopComponent findNewOutline() {
0948: // TopComponent newOutline = WindowManager.getDefault().findTopComponent("outlineNew");
0949: // if (newOutline == null) {
0950: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, new NullPointerException("" +
0951: // "New Outline TopComponent not found!")); // NOI18N
0952: // }
0953: //
0954: // return newOutline;
0955: // }
0956:
0957: // // XXX Implement TopComponentGroup.
0958: // private static void openNavigator() {
0959: // TopComponent navigator = findNavigator();
0960: // if (navigator != null && !navigator.isOpened()) {
0961: // // FIXME XXX Just for now to fake the old kind of behaviour. Use TopComponentGroup to fix it.
0962: // navigator.open();
0963: // }
0964: // }
0965:
0966: // private static void selectNavigator() {
0967: // TopComponent navigator = findNavigator();
0968: // if (navigator != null) {
0969: // // XXX #6392131 -> NB #62329.
0970: // if (!Boolean.TRUE.equals(navigator.getClientProperty("isSliding"))) { // NOI18N
0971: // // FIXME XXX Just for now to fake the old kind of behaviour. Use TopComponentGroup to fix it.
0972: // navigator.requestVisible();
0973: // }
0974: // }
0975: // }
0976:
0977: // private static TopComponent findNavigator() {
0978: // TopComponent navigator = WindowManager.getDefault().findTopComponent("navigatorTC"); // NOI18N
0979: // if (navigator == null) {
0980: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
0981: // new NullPointerException("Navigator TopComponent not found!")); // NOI18N
0982: // }
0983: //
0984: // return navigator;
0985: // }
0986:
0987: // /** Select the given bean in the tray, if it's present.
0988: // * @param bean The bean you want selected
0989: // */
0990: // public void selectTrayBean(DesignBean bean) {
0991: // if (!SHOW_TRAY || (tray == null)) {
0992: // return;
0993: // }
0994: //
0995: // requestActive();
0996: // tray.setSelection(bean);
0997: // }
0998: //
0999: // /** Clear the selection in the tray */
1000: // public void clearTraySelection() {
1001: // if (tray != null) {
1002: // tray.clearSelection(false);
1003: // }
1004: // }
1005:
1006: // /** Return the data object being edited by this view
1007: // * @return Data object being edited
1008: // */
1009: // public DataObject getDataObject() {
1010: // return webform.getDataObject();
1011: // }
1012:
1013: // public String getName() {
1014: // return NbBundle.getMessage(DesignerTopComp.class, "FormView"); // NOI18N
1015: // }
1016:
1017: // // XXX unused?
1018: // protected String iconResource() {
1019: // return "org/netbeans/modules/visualweb/designer/resources/designer.gif"; // NOI18N
1020: // }
1021:
1022: @Override
1023: public HelpCtx getHelpCtx() {
1024: Node[] activatedNodes = getActivatedNodes();
1025: Node[] nodes = activatedNodes == null ? new Node[0]
1026: : activatedNodes;
1027: return ExplorerUtils.getHelpCtx(nodes, new HelpCtx(
1028: "projrave_ui_elements_editors_about_visual_editor")); // NOI18N
1029: }
1030:
1031: /* Activates copy/cut/paste actions.
1032: */
1033: @Override
1034: protected void componentActivated() {
1035: //// OutlineTopComp.getInstance().setCurrent(webform);
1036: //// OutlineTopComp.getInstance().requestVisible();
1037: //// selectNewOutline();
1038: // // XXX Replace with TopComponentGroup.
1039: // selectNavigator();
1040: //
1041: //// webform.getSelection().updateNodes();
1042: // designer.updateSelectedNodes();
1043: //
1044: // super.componentActivated();
1045: //
1046: //// if (html != null) {
1047: //// html.requestFocus();
1048: //// }
1049: // designer.paneRequestFocus();
1050: if (jsfForm.isValid()) {
1051: // XXX #125593 See also #componentShowing, because of the also this moved later.
1052: // XXX This causes to fire events from insync, which work only when the model is in sync.
1053: // XXX It should be fixed in insync, but at this momemnt it is not quickly possible.
1054: EventQueue.invokeLater(new Runnable() {
1055: public void run() {
1056: designerActivated();
1057: }
1058: });
1059: }
1060: }
1061:
1062: // public PaletteController getPaletteController() {
1063: // return designerPaletteController;
1064: // }
1065: // XXX
1066: public JComponent getPane() {
1067: return html;
1068: }
1069:
1070: // private void sync() {
1071: // FacesModel model = webform.getModel();
1072: //
1073: // if (model == null) {
1074: // return;
1075: // }
1076: //
1077: // /*
1078: // MarkupUnit markup = model.getMarkupUnit();
1079: // Unit.State oldState = Unit.State.SOURCEDIRTY;
1080: // if (markup != null) {
1081: // oldState = markup.getState();
1082: // }
1083: // */
1084: // model.sync();
1085: //
1086: // /* This was an attempt to preparse the style strings,
1087: // so that we get error messages for them at sync time - which
1088: // in turn would mean they could affect whether or not an error page
1089: // is shown instead of the design view. Still needs some work.
1090: // markup = model.getMarkup(); // may have changed by syncFromDoc call
1091: // if (!model.hasErrors() && oldState == Unit.State.SOURCEDIRTY) {
1092: // model.flushToDoc(false); // if modified
1093: // try {
1094: // System.out.println("OLDSTATE=" + oldState);
1095: // System.out.println("NEWSTATE=" + markup.getState());
1096: // preparseStyles(markup, markup.getDocument());
1097: // } catch (org.w3c.css.sac.CSSParseException ex) {
1098: // //ex.printStackTrace(); // XXX remove!
1099: // }
1100: // }
1101: // */
1102: // }
1103:
1104: /**
1105: * CSS styles for elements were initialized lazily. The problem with
1106: * that is that I don't know if I have a fatal CSS error until I try
1107: * to render the page. Since we'll need the CSS styles on virtually
1108: * all the elements anyway, there's no benefit to the lazily initialization
1109: * to do it here instead.
1110: */
1111:
1112: /*
1113: private void preparseStyles(MarkupUnit markup, org.w3c.dom.Node node) {
1114: if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
1115: Element element = (Element)node;
1116: markup.getEffectiveStyles(element); // caches result
1117: }
1118:
1119: org.w3c.dom.NodeList list = node.getChildNodes();
1120: int len = list.getLength();
1121: for (int i = 0; i < len; i++) {
1122: org.w3c.dom.Node child = (org.w3c.dom.Node) list.item(i);
1123: preparseStyles(markup, child);
1124: }
1125: }
1126: */
1127: private void createDesignerPane() {
1128: // sync();
1129: // webform.syncModel();
1130: jsfForm.syncModel();
1131:
1132: // Document doc = webform.getDocument();
1133: // html = new DesignerPane(webform, doc);
1134: // html = new DesignerPane(webform);
1135: html = designer.createPaneComponent();
1136:
1137: // Defaults are sensible now so no need to set:
1138: //html.setDragEnabled(true);
1139: //html.setContentType(DesignerPane.MIME_TYPE);
1140: //html.setEditable(true);
1141: JScrollPane scrollPane = new JScrollPane();
1142:
1143: JViewport vp = scrollPane.getViewport();
1144: vp.add(html);
1145: panel.add(scrollPane, getDefaultGridBagConstraints());
1146: // html.updateViewport();
1147: designer.updatePaneViewPort();
1148: }
1149:
1150: // public DesignerPane getDesignerPane() {
1151: // return html;
1152: // }
1153:
1154: // /** XXX Set pending refdresh all state - whether we have a pending refresh all that needs to be
1155: // * processed whenever forms are made visible */
1156: // public static void setPendingRefreshAll() {
1157: // pendingRefreshAll = true;
1158: // }
1159:
1160: @Override
1161: protected void componentShowing() {
1162: // // PROJECTTODO: Why is componentShowing occuring before componentOpened, not sure
1163: // // THIS is a HACK !EAT
1164: // if (!initialized) {
1165: // componentOpened();
1166: // }
1167:
1168: // XXX It was here only because of incorrect impl of old rave window system.
1169: // if (showing) {
1170: // return;
1171: // }
1172: //
1173: // showing = true;
1174:
1175: // // XXX
1176: // if (pendingRefreshAll) {
1177: //// Project project = webform.getProject();
1178: ////
1179: //// // XXX uh oh, what if I refresh THIS project but not other projects.... and
1180: //// // you edit stylesheets from different projects? Notagood! Do I really need to
1181: //// // refresh ALL projects?
1182: //// if (project != null) {
1183: //// WebForm.refreshAll(project, false);
1184: ////
1185: //// // Prevent refreshing all for every update since a refresh could be
1186: //// // sort of expensive. (It doesn't actually update layout on all pages,
1187: //// // but does scan the entire project for pages and clears associated caches
1188: //// // etc.
1189: //// }
1190: // webform.refreshProject();
1191: //
1192: // pendingRefreshAll = false;
1193: // } else
1194: // if (webform.isFragment()) {
1195: // if (jsfForm.isFragment()) {
1196: // // Ensure that we have current page references
1197: //// webform.refresh(false);
1198: //// webform.refreshModel(false);
1199: // jsfForm.refreshModel(false);
1200: // }
1201: //
1202: //// openNewOutline();
1203: // // XXX Replace with TopComponentGroup.
1204: // openNavigator();
1205: // selectAndUpdateOutlineView();
1206: //
1207: // // XXX #6314795 See below, also this one should be scheduled later.
1208: // // Remove scheduling when the NB issue fixed.
1209: //
1210: // //Removing toolbox from view
1211: //// SwingUtilities.invokeLater(new Runnable() {
1212: //// public void run() {
1213: ////// // #5047873 Select also Toolbox (with palette component).
1214: ////// com.sun.rave.toolbox.ToolBox.findDefault().requestVisible();
1215: //// TopComponent toolbox = WindowManager.getDefault().findTopComponent("toolbox"); // NOI18N
1216: //// toolbox.requestVisible();
1217: //// }
1218: //// });
1219: //
1220: //// if (SHOW_TRAY) {
1221: //// clearTraySelection();
1222: //// }
1223: //
1224: // // Insync: parse the backing file such that we incorporate
1225: // // user changes in the backing file (and don't blow them away
1226: // // in componentHidden when we later flush the model to the doc)
1227: // //final DataObject dobj = webform.getDataObject();
1228: //// FacesModel model = webform.getModel();
1229: ////
1230: //// try {
1231: //// MarkupUnit markupUnit = model.getMarkupUnit();
1232: //// if (markupUnit != null) {
1233: //// if ((markupUnit.getState() == Unit.State.SOURCEDIRTY)
1234: //// if (webform.isSourceDirty()
1235: //// && (webform.getPane().getCaret() != null)) {
1236: //// if (webform.isSourceDirty() && (webform.getPane().hasCaret())) {
1237: // if (jsfForm.isSourceDirty() && designer.hasPaneCaret()) {
1238: // // Remove the caret if we do a sync since the caret could be
1239: // // pointing into an old DOM which causes various ugliness
1240: //// webform.getPane().setCaretPosition(Position.NONE);
1241: //// webform.getPane().setCaretPosition(DomPosition.NONE);
1242: //// webform.getPane().setCaretDot(DomPosition.NONE);
1243: // designer.setPaneCaret(DomPosition.NONE);
1244: // }
1245: //
1246: //// sync();
1247: //// webform.syncModel();
1248: // jsfForm.syncModel();
1249: //
1250: // // XXX #6474723 If sync was alredy synced we need to assure rebuild the boxes.
1251: // // FIXME If sync() also rebuilds the model then this is redundant. The boxes
1252: // // will be rebuild twice. Consider suspending listening during sync() call above.
1253: //// webform.getPane().getPaneUI().resetPageBox();
1254: // designer.resetPanePageBox();
1255: //
1256: // // It's not enough to do showErrors and showTray in contextChanged
1257: // // because contextChanged is not run when the form is first opened.
1258: // // XXX perhaps I can do this in componentOpened instead?
1259: // updateErrors(); // XXX shouldn't the contextChanged ensure this?
1260: //
1261: // //if (SHOW_TRAY) {
1262: // // showTray(hasTrayBeans()); The contextChanged should ensure this!
1263: // //}
1264: //// } else {
1265: //// // XXX #6478973 Model could be corrupted, until #6480764 is fixed.
1266: //// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
1267: //// new IllegalStateException("The FacesModel is corrupted, its markup unit is null, facesModel=" + model)); // NOI18N
1268: //// }
1269: //
1270: //// } catch (Exception e) {
1271: //// e.printStackTrace();
1272: ////
1273: //// // swallow
1274: //// // temporary hack which allows me to deal with documents
1275: //// // outside of projects
1276: //// }
1277: //
1278: // // Refresh layout for fragments and for pages that contain fragments whenever
1279: // // they are exposed
1280: //// if (webform.isFragment() || webform.getDocument().hasCachedFrameBoxes()) {
1281: //// if (webform.isFragment() || webform.hasCachedFrameBoxes()) {
1282: // if (jsfForm.isFragment() || jsfForm.hasCachedExternalFrames()) {
1283: // // Always refresh fragments on expose since whenever they are
1284: // // rendered as part of other (including) documents those documents
1285: // // may style our elements and stash box references on the elements
1286: // // that point to their own box hierarchies
1287: //// if (html.getPageBox() != null) {
1288: //// html.getPageBox().redoLayout(true);
1289: //// }
1290: // designer.redoPaneLayout(true);
1291: // }
1292: //
1293: //// webform.setGridMode(html.getDocument().isGridMode());
1294: //// webform.updateGridMode();
1295: //// designer.updateGridMode();
1296: // designer.setPaneGrid(jsfForm.isGridMode());
1297: //
1298: // // We cannot set the caret to the document position yet; we need
1299: // // to do layout before the mapper functions work... This is done
1300: // // after page layout instead.
1301: //// html.requestFocus();
1302: // designer.paneRequestFocus();
1303:
1304: if (!componentInited) {
1305: componentInited = true;
1306: if (!jsfForm.isValid()) {
1307: if (!JsfForm.tryFacesModelForJsfForm(jsfForm,
1308: jspDataObject)) {
1309: JsfForm.loadFacesModelForJsfForm(jsfForm,
1310: jspDataObject);
1311: }
1312: // XXX #124931 We don't need to keep the link anymore.
1313: jspDataObject = null;
1314: }
1315:
1316: initComponent();
1317: }
1318:
1319: if (jsfForm.isValid()) {
1320: designerShowing();
1321: }
1322: }
1323:
1324: @Override
1325: protected void componentHidden() {
1326: // XXX It was here only because of incorrect impl of old rave window system.
1327: // if (!showing) {
1328: // // For some reason, I'll often get componentHidden
1329: // // before any componentShowing events. Suppress these.
1330: // return;
1331: // }
1332: //
1333: // showing = false;
1334:
1335: // Now redundant, see the StatusDisplayer.setStatusText javadoc.
1336: // StatusDisplayer.getDefault().setStatusText("");
1337:
1338: // <TEMP>
1339: // Just workaround: #5015428
1340: // Otherwise it could access document with lock from CloneableEditorSupport.
1341: /*
1342: SwingUtilities.invokeLater(new Runnable() {
1343: public void run() {
1344: webform.getModel().flush(false, null);
1345: }
1346: });*/
1347: // </TEMP>
1348: // selectNavigatorWindow();
1349: if (jsfForm.isValid()) {
1350: designerHidden();
1351: }
1352: }
1353:
1354: public CloseOperationState canCloseElement() {
1355: // XXX I don't understand this yet. Copied from FormDesigner.
1356: // Returns a placeholder state - to be sure our CloseHandler is called.
1357: return MultiViewFactory.createUnsafeCloseState(
1358: "ID_CLOSING_DESIGNER", // dummy ID // NOI18N
1359: MultiViewFactory.NOOP_CLOSE_ACTION,
1360: MultiViewFactory.NOOP_CLOSE_ACTION);
1361: }
1362:
1363: // /**
1364: // * Close this designer window - including the JSP and Java tabs.
1365: // * This will redirect the close to the containing multiview top component.
1366: // * Calling the normal this.close() doesn't do this. (It appears
1367: // * to do nothing.)
1368: // */
1369: // boolean forceClose() {
1370: // if (multiViewElementCallback == null || multiViewElementCallback.getTopComponent() == null)
1371: // return true;
1372: // return ((CloneableTopComponent)multiViewElementCallback.getTopComponent()).close();
1373: // }
1374:
1375: public void setMultiViewCallback(MultiViewElementCallback callback) {
1376: multiViewElementCallback = callback;
1377:
1378: // TODO XXX What the heck of hack is this? Why for deserialization (comes from FormDesigner).
1379: // Is something like that needed here too? Is this call part of deserialization routine?
1380: // WebForm wf = getWebForm();
1381: // if(wf == null) {
1382: // return;
1383: // }
1384: // DataObject dObj = wf.getDataObject();
1385: // if(dObj instanceof JSFDataObject) {
1386: // JSFEditorSupport jsfEditorSupport = (JSFEditorSupport)dObj.getCookie(JSFEditorSupport.class);
1387: // if (jsfEditorSupportAccessor != null) {
1388: // // this is used (or misused?) to obtain the deserialized multiview
1389: // // topcomponent and set it to FormEditorSupport
1390: // jsfEditorSupportAccessor.setMultiView((CloneableTopComponent)multiViewElementCallback.getTopComponent());
1391: // }
1392:
1393: //}
1394: }
1395:
1396: private static final String PATH_TOOLBAR_FOLDER = "Designer/application/x-designer/Toolbars/Default"; // NOI18N
1397:
1398: public JComponent getToolbarRepresentation() {
1399: if (toolbar == null) {
1400: // TODO -- Look at NbEditorToolBar in the editor - it does stuff
1401: // with the UI to get better Aqua and Linux toolbar
1402: toolbar = new JToolBar();
1403: toolbar.setFloatable(false);
1404: toolbar.setRollover(true);
1405: toolbar.setBorder(new EmptyBorder(0, 0, 0, 0));
1406:
1407: // ToolbarListener listener = new ToolbarListener();
1408:
1409: toolbar.addSeparator();
1410: // previewButton =
1411: // new JButton(new ImageIcon(Utilities.loadImage("org/netbeans/modules/visualweb/designer/preview.png"))); // NOI18N
1412: // previewButton.addActionListener(listener);
1413: // previewButton.setToolTipText(NbBundle.getMessage(DesignerTopComp.class, "PreviewAction"));
1414: // toolbar.add(previewButton);
1415: // XXX TODO For now adding only BrowserPreviewAction, but later all of them.
1416: // Component[] comps = ToolBarInstancesProvider.getDefault().getToolbarComponentsForDesignerComponent(this);
1417: Action[] actions = SystemFileSystemSupport
1418: .getActions(PATH_TOOLBAR_FOLDER);
1419: Lookup context = getLookup();
1420: for (int i = 0; i < actions.length; i++) {
1421: Action action = actions[i];
1422: if (action == null) {
1423: toolbar.addSeparator();
1424: } else {
1425: if (action instanceof ContextAwareAction) {
1426: Action contextAwareAction = ((ContextAwareAction) action)
1427: .createContextAwareInstance(context);
1428: if (contextAwareAction != null) {
1429: action = contextAwareAction;
1430: }
1431: }
1432: if (action instanceof Presenter.Toolbar) {
1433: Component tbp = ((Presenter.Toolbar) action)
1434: .getToolbarPresenter();
1435: toolbar.add(tbp);
1436: } else {
1437: // toolbar.add(new Actions.ToolbarButton((Action)action));
1438: JButton toolbarButton = new JButton();
1439: Actions.connect(toolbarButton, (Action) action);
1440: toolbar.add(toolbarButton);
1441: }
1442: }
1443: }
1444:
1445: // refreshButton =
1446: // new JButton(new ImageIcon(Utilities.loadImage("org/netbeans/modules/visualweb/designer/refresh.png"))); // NOI18N
1447: // refreshButton.addActionListener(listener);
1448: // refreshButton.setToolTipText(NbBundle.getMessage(DesignerTopComp.class, "Refresh"));
1449: // toolbar.add(refreshButton);
1450:
1451: // showVfButton =
1452: // new JToggleButton(new ImageIcon(Utilities.loadImage("org/netbeans/modules/visualweb/designer/vf.png")), // NOI18N
1453: // webform.getVirtualFormSupport().isEnabled());
1454: // showVfButton.addActionListener(listener);
1455: // showVfButton.setToolTipText(NbBundle.getMessage(DesignerTopComp.class, "ShowVF"));
1456: // toolbar.add(showVfButton);
1457:
1458: // toolbar.addSeparator();
1459:
1460: // toolbar.add(new TargetSizeCombo(webform));
1461:
1462: // Perhaps we could add a snap to grid toggle button here...
1463: // And value binding feedback stuff?
1464: // DEBUGGING SUPPORT
1465: //import java.awt.image.BufferedImage;
1466: //import org.openide.awt.HtmlBrowser.URLDisplayer;
1467: //import javax.imageio.ImageIO;
1468: //import javax.swing.CellRendererPane;
1469: //import javax.swing.JFrame;
1470: //import org.openide.windows.WindowManager;
1471: //import org.netbeans.modules.visualweb.css2.PageBox;
1472: //import java.io.File;
1473: //import java.awt.Graphics2D;
1474: //import java.net.URL;
1475: //import java.net.MalformedURLException;
1476: //import org.openide.ErrorManager;
1477: //import java.io.IOException;
1478: // if (System.getProperty("designer.debug") != null) {
1479: // toolbar.add(new AbstractAction("ShowLayout", null) {
1480: // public void actionPerformed(ActionEvent actionEvent) {
1481: // PageBox pageBox = webform.getSelection().getPageBox();
1482: // StringBuffer sb = new StringBuffer();
1483: // pageBox.printLayout(sb);
1484: // org.openide.DialogDisplayer.getDefault().notify(new org.openide.NotifyDescriptor.Message(new javax.swing.JScrollPane(new javax.swing.JTextArea(sb.toString()))));
1485: //
1486: // }
1487: // });
1488: //
1489: // toolbar.add(new AbstractAction("ShowHtml", null) {
1490: // public void actionPerformed(ActionEvent actionEvent) {
1491: // org.w3c.dom.Node node = webform.getDom().getRoot();
1492: // String s = FacesSupport.getHtmlStream(node);
1493: // org.openide.DialogDisplayer.getDefault().notify(new org.openide.NotifyDescriptor.Message(new javax.swing.JScrollPane(new javax.swing.JTextArea(s))));
1494: // }
1495: // });
1496: //
1497: // toolbar.add(new AbstractAction("SaveImage", null) {
1498: // public void actionPerformed(ActionEvent actionEvent) {
1499: // PageBox pageBox = webform.getSelection().getPageBox();
1500: // BufferedImage img2 = paintImage(pageBox);
1501: // showScreenshot(img2);
1502: // }
1503: // protected BufferedImage paintImage(PageBox pageBox) {
1504: // int w = pageBox.getWidth();
1505: // int h = pageBox.getHeight();
1506: // BufferedImage image = new BufferedImage(w, h,
1507: // BufferedImage.TYPE_INT_RGB);
1508: // Graphics2D g2 = image.createGraphics();
1509: // DesignerPane.clip.setBounds(0, 0, w, h);
1510: // DesignerPane.clipBr.x = w;
1511: // DesignerPane.clipBr.y = h;
1512: // pageBox.paint(g2);
1513: // g2.dispose();
1514: // return image;
1515: // }
1516: // protected void showScreenshot(BufferedImage bi) {
1517: // try {
1518: // File tmp = File.createTempFile("designer", ".png");
1519: // tmp.deleteOnExit();
1520: // saveImage(bi, tmp);
1521: // showScreenshot(tmp);
1522: // } catch (java.io.IOException ioe) {
1523: // ErrorManager.getDefault().notify(ioe);
1524: // }
1525: // }
1526: //
1527: // /** Save the given image to disk */
1528: // protected void saveImage(BufferedImage image, File file) {
1529: // try {
1530: // if (file.exists()) {
1531: // file.delete();
1532: // }
1533: // ImageIO.write(image, "png", file);
1534: // } catch (IOException e) {
1535: // System.err.println(e);
1536: // }
1537: // }
1538: //
1539: // protected void showScreenshot(File file) {
1540: // URL url;
1541: // try {
1542: // url = new URL("file:" + file.getPath()); // NOI18N
1543: // } catch (MalformedURLException e) {
1544: // // Can't show URL
1545: // ErrorManager.getDefault().notify(e);
1546: // return;
1547: // }
1548: // URLDisplayer.getDefault().showURL(url);
1549: // }
1550: //
1551: // });
1552: // }
1553: }
1554:
1555: return toolbar;
1556: }
1557:
1558: public JComponent getVisualRepresentation() {
1559: return this ;
1560: }
1561:
1562: // </multiview>
1563: // Extends SelectionTopComp
1564: @Override
1565: protected void installActions() {
1566: super .installActions();
1567:
1568: ActionMap map = getActionMap();
1569:
1570: InputMap keys = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
1571:
1572: // keys.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape-multiplex"); // NOI18N
1573: //// map.put("escape-multiplex", // NOI18N
1574: //// new AbstractAction() {
1575: //// public void actionPerformed(ActionEvent evt) {
1576: //// escape(evt.getWhen());
1577: //// }
1578: //// }
1579: //// );
1580: // map.put("escape-multiplex", new EscapeAction(this)); // NOI18N
1581:
1582: keys = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
1583: keys.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0),
1584: "edit-value"); // NOI18N
1585: // map.put("edit-value", // NOI18N
1586: // new AbstractAction() {
1587: // public void actionPerformed(ActionEvent evt) {
1588: //// if (webform.getManager().isInlineEditing()) {
1589: // if (designer.isInlineEditing()) {
1590: // // Already inline editing - no point doing anything
1591: // return;
1592: // }
1593: //
1594: //// boolean success = webform.getActions().editValue();
1595: // boolean success = editValue();
1596: //
1597: // if (!success) {
1598: //// UIManager.getLookAndFeel().provideErrorFeedback(DesignerTopComp.this); // beep
1599: // UIManager.getLookAndFeel().provideErrorFeedback(JsfTopComponent.this); // beep
1600: // }
1601: // }
1602: // });
1603: map.put("edit-value", new EditValueAction(this )); // NOI18N
1604:
1605: // >>>Debugging helpers
1606: keys.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2,
1607: KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK),
1608: "rave-designer-dump-html"); // NOI18N
1609: // map.put("rave-designer-dump-html", // NOI18N
1610: // new AbstractAction() {
1611: // public void actionPerformed(ActionEvent evt) {
1612: // dumpActivatedMarkupDesignBeansHtml();
1613: // }
1614: // }
1615: // );
1616: map.put("rave-designer-dump-html", new DumpHtmlAction(this )); // NOI18N
1617:
1618: keys.put(KeyStroke.getKeyStroke(KeyEvent.VK_F3,
1619: KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK),
1620: "rave-designer-dump-boxes"); // NOI18N
1621: // map.put("rave-designer-dump-boxes", // NOI18N
1622: // new AbstractAction() {
1623: // public void actionPerformed(ActionEvent evt) {
1624: // dumpActivatedComponentCssBoxes();
1625: // }
1626: // }
1627: // );
1628: map.put("rave-designer-dump-boxes", new DumpBoxesAction(this )); // NOI18N
1629: // <<< Debugging helpers
1630: }
1631:
1632: /** XXX Moved from DesignerActions.
1633: * Edit the selected component's default inline edited property */
1634: private boolean editValue() {
1635: // SelectionManager sm = webform.getSelection();
1636: // ModelViewMapper mapper = webform.getMapper();
1637: Element[] componentRootElements = designer
1638: .getSelectedComponents();
1639:
1640: // if (sm.getNumSelected() == 1) {
1641: if (componentRootElements.length == 1) {
1642: // Iterator it = sm.iterator();
1643: //
1644: // while (it.hasNext()) {
1645: // MarkupDesignBean bean = (MarkupDesignBean)it.next();
1646: // for (Element componentRootElement : sm.getSelectedComponentRootElements()) {
1647: for (Element componentRootElement : componentRootElements) {
1648: // MarkupDesignBean bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
1649: // if (bean == null) {
1650: // continue;
1651: // }
1652: if (componentRootElement == null) {
1653: continue;
1654: }
1655:
1656: // CssBox box = mapper.findBox(bean);
1657: // CssBox box = ModelViewMapper.findBoxForComponentRootElement(webform.getPane().getPageBox(), componentRootElement);
1658:
1659: // webform.getTopComponent().requestActive();
1660: requestActive();
1661:
1662: // return webform.getManager().startInlineEditing(bean, null, box, true, true, null, false);
1663: // return webform.getManager().startInlineEditing(componentRootElement, null, box, true, true, null, false);
1664: designer.startInlineEditing(componentRootElement, null);
1665: }
1666: }
1667:
1668: return false;
1669: }
1670:
1671: // /** Horrible hack necessary because I get notified of the escape key
1672: // * twice: sometimes by my key handler above, sometimes by the default key
1673: // * handler, and sometimes by both!
1674: // * @todo This may no longer be an issue now that I'm using
1675: // * a better input map (ANCESTOR_OF.... instead of FOCUSED_)
1676: // */
1677: // public boolean seenEscape(long when) {
1678: // if (lastEscape == when) {
1679: // return true;
1680: // }
1681: //
1682: // lastEscape = when;
1683: //
1684: // return false;
1685: // }
1686: //
1687: // private void escape(long when) {
1688: // // Do escape-like things: cancel drag & drop, select parent, etc.
1689: // if (!seenEscape(when)) {
1690: //// webform.getManager().getMouseHandler().escape();
1691: // designer.performEscape();
1692: // }
1693: // }
1694:
1695: private void dumpActivatedMarkupDesignBeansHtml() {
1696: Node[] nodes = getActivatedNodes();
1697: if (nodes == null) {
1698: return;
1699: }
1700:
1701: for (Node node : nodes) {
1702: if (node == null) {
1703: continue;
1704: }
1705: // DesignBean designBean = (DesignBean)node.getLookup().lookup(DesignBean.class);
1706: // if (designBean instanceof MarkupDesignBean) {
1707: // MarkupDesignBean markupDesignBean = (MarkupDesignBean)designBean;
1708: // Element sourceElement = markupDesignBean.getElement();
1709: // Element renderedElement = MarkupService.getRenderedElementForElement(sourceElement);
1710: // if (renderedElement == null || sourceElement == renderedElement) {
1711: // System.err.println("\nMarkup design bean not renderable, markup design bean=" + markupDesignBean); // NOI18N
1712: // dumpHtmlMarkupDesignBeanHtml();
1713: // continue;
1714: // }
1715: // System.err.println("\nRendered markup design bean=" + markupDesignBean); // NOI18N
1716: //// System.err.println(Util.getHtmlStream(renderedElement));
1717: // System.err.println(WebForm.getDomProviderService().getHtmlStream(renderedElement));
1718: // } else {
1719: // System.err.println("\nDesign bean not renderable, design bean=" + designBean); // NOI18N
1720: // dumpHtmlMarkupDesignBeanHtml();
1721: // }
1722: // webform.dumpHtmlMarkupForNode(node);
1723: jsfForm.dumpHtmlMarkupForNode(node);
1724: }
1725: }
1726:
1727: // private void dumpHtmlMarkupDesignBeanHtml() {
1728: // DocumentFragment df = webform.getHtmlDomFragment();
1729: //// Element html = Util.findDescendant(HtmlTag.HTML.name, df);
1730: // Element html = WebForm.getDomProviderService().findHtmlElementDescendant(df);
1731: // if (html == null) {
1732: // return;
1733: // }
1734: //// System.err.println("\nRendered html element markup design bean=" + MarkupUnit.getMarkupDesignBeanForElement(html)); // NOI18N
1735: // System.err.println("\nRendered html element markup design bean=" + WebForm.getDomProviderService().getMarkupDesignBeanForElement(html)); // NOI18N
1736: //// System.err.println(Util.getHtmlStream(html)); // NOI18N
1737: // System.err.println(WebForm.getDomProviderService().getHtmlStream(html)); // NOI18N
1738: // }
1739:
1740: private void dumpActivatedComponentCssBoxes() {
1741: Node[] nodes = getActivatedNodes();
1742: if (nodes == null) {
1743: return;
1744: }
1745:
1746: for (Node node : nodes) {
1747: if (node == null) {
1748: continue;
1749: }
1750: // DesignBean designBean = (DesignBean)node.getLookup().lookup(DesignBean.class);
1751: // Element componentRootElement = WebForm.getDomProviderService().getComponentRootElementFromNode(node);
1752: Element componentRootElement = JsfSupportUtilities
1753: .getComponentRootElementFromNode(node);
1754:
1755: // if (designBean == null) {
1756: if (componentRootElement == null) {
1757: log("Node doesn't have design bean, node=" + node); // NOI18N
1758: dumpRootComponentCssBoxes();
1759: } else {
1760: // PageBox pageBox = webform.getPane().getPageBox();
1761: // if (pageBox == null) {
1762: // return;
1763: // }
1764: //// CssBox cssBox = ModelViewMapper.findBox(pageBox, designBean);
1765: // CssBox cssBox = ModelViewMapper.findBoxForComponentRootElement(pageBox, componentRootElement);
1766: Box box = designer
1767: .findBoxForComponentRootElement(componentRootElement);
1768:
1769: // if (cssBox == null) {
1770: if (box == null) {
1771: log("Component doesn't have a corresponding css box, componentRootElement="
1772: + componentRootElement); // NOI18N
1773: dumpRootComponentCssBoxes();
1774: } else {
1775: log("Css boxes for componentRootElement="
1776: + componentRootElement); // NOI18N
1777: // cssBox.list(System.err, 0);
1778: box.list(System.err, 0);
1779: }
1780: }
1781: }
1782: }
1783:
1784: private void dumpRootComponentCssBoxes() {
1785: // DocumentFragment df = webform.getHtmlDomFragment();
1786: // DocumentFragment df = jsfForm.getHtmlDomFragment();
1787: Document doc = jsfForm.getHtmlDom();
1788:
1789: // Element html = Util.findDescendant(HtmlTag.HTML.name, df);
1790: // Element html = WebForm.getDomProviderService().findHtmlElementDescendant(df);
1791: Element html = JsfSupportUtilities
1792: .findHtmlElementDescendant(doc);
1793: if (html == null) {
1794: html = jsfForm.getHtmlBody(false);
1795: }
1796: // PageBox pageBox = webform.getPane().getPageBox();
1797: Box pageBox = designer.getPageBox();
1798: if (pageBox == null) {
1799: return;
1800: }
1801: // System.err.println("\nCss boxes for html element markup design bean=" + MarkupUnit.getMarkupDesignBeanForElement(html));
1802: // System.err.println("\nCss boxes for html element markup design bean=" + WebForm.getDomProviderService().getMarkupDesignBeanForElement(html));
1803: log("CssBoxes for element=" + html);
1804: StringWriter stringWriter = new StringWriter();
1805: PrintWriter writer = new PrintWriter(new BufferedWriter(
1806: stringWriter));
1807: pageBox.list(writer, 0);
1808: writer.flush();
1809: log(stringWriter.toString());
1810: writer.close();
1811: }
1812:
1813: protected void showKeyboardPopup() {
1814: // <actions from layers>
1815: // if (isTrayShowing() && !tray.isSelectionEmpty()) {
1816: // tray.showPopup(null);
1817: // } else {
1818: // webform.getActions().createPopup();
1819: // }
1820: // ====
1821: Point point = getSelectionPoint();
1822: showPopup(null, null, point.x, point.y);
1823: // </actions from layers>
1824: }
1825:
1826: // <actions from layers>
1827: private static final String PATH_DESIGNER_ACTIONS = "Designer/application/x-designer/Popup"; // NOI18N
1828:
1829: // public void showPopupMenu(int x, int y) {
1830: // JPopupMenu popupMenu = Utilities.actionsToPopup(
1831: // SystemFileSystemSupport.getActions(PATH_DESIGNER_ACTIONS),
1832: // getLookup());
1833: // if (isShowing()) {
1834: // // #6473708 x, y values are computed to the DesignerPane (html).
1835: //// popupMenu.show(this, x, y);
1836: // popupMenu.show(html, x, y);
1837: // }
1838: // }
1839:
1840: public void showPopup(Action[] actions, Lookup context, int x, int y) {
1841: if (actions == null) {
1842: actions = SystemFileSystemSupport
1843: .getActions(PATH_DESIGNER_ACTIONS);
1844: }
1845: if (context == null) {
1846: context = getLookup();
1847: }
1848: JPopupMenu popupMenu = Utilities.actionsToPopup(actions,
1849: context);
1850:
1851: if (isShowing()) {
1852: popupMenu.show(this , x, y);
1853: }
1854: }
1855:
1856: private Point getSelectionPoint() {
1857: // SelectionManager sm = webform.getSelection();
1858: //
1859: // if (!sm.isSelectionEmpty()) {
1860: if (designer.getSelectedCount() > 0) {
1861: Element primarySelection = designer.getPrimarySelection();
1862: // if (sm.getPrimary() != null) {
1863: if (primarySelection != null) {
1864: // CssBox box = webform.getMapper().findBox(sm.getPrimary());
1865: // CssBox box = ModelViewMapper.findBox(webform.getPane().getPageBox(), sm.getPrimary());
1866: Box box = designer
1867: .findBoxForComponentRootElement(primarySelection);
1868:
1869: while ((box != null)
1870: && ((box.getX() == CssValue.AUTO)
1871: || (box.getY() == CssValue.AUTO)
1872: || (box.getX() == Box.UNINITIALIZED) || (box
1873: .getY() == Box.UNINITIALIZED))) {
1874: box = box.getParent();
1875: }
1876:
1877: if (box != null) {
1878: return new Point(box.getAbsoluteX(), box
1879: .getAbsoluteY());
1880: }
1881: }
1882:
1883: // Iterator it = sm.iterator();
1884: //
1885: // while (it.hasNext()) {
1886: // DesignBean bean = (DesignBean)it.next();
1887: // for (Element componentRootElement : sm.getSelectedComponentRootElements()) {
1888: for (Element componentRootElement : designer
1889: .getSelectedComponents()) {
1890: // DesignBean bean = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
1891: //
1892: // if (bean != null) {
1893: if (componentRootElement != null) {
1894: // CssBox box = webform.getMapper().findBox(bean);
1895: // CssBox box = ModelViewMapper.findBoxForComponentRootElement(webform.getPane().getPageBox(), componentRootElement);
1896: Box box = designer
1897: .findBoxForComponentRootElement(componentRootElement);
1898: while ((box != null)
1899: && ((box.getX() == CssValue.AUTO)
1900: || (box.getY() == CssValue.AUTO)
1901: || (box.getX() == Box.UNINITIALIZED) || (box
1902: .getY() == Box.UNINITIALIZED))) {
1903: box = box.getParent();
1904: }
1905:
1906: if (box != null) {
1907: // Element e;
1908: // if (bean instanceof MarkupDesignBean) {
1909: // e = ((MarkupDesignBean)bean).getElement();
1910: // } else {
1911: // e = null;
1912: // }
1913:
1914: return new Point(box.getAbsoluteX(), box
1915: .getAbsoluteY());
1916: }
1917: }
1918: }
1919: }
1920:
1921: // Just return near the top left corner
1922: return new Point(10, 10);
1923: }
1924:
1925: // </actions from layer>
1926:
1927: // protected boolean isSelectionEmpty() {
1928: //// return webform.getSelection().isSelectionEmpty();
1929: // return designer.getSelectedCount() == 0;
1930: // }
1931:
1932: // protected DesignBean getPasteParent() {
1933: public/*protected*/Element getPasteParentComponent() {
1934: // DesignBean lb = webform.getSelection().getSelectedContainer();
1935: // Element componentRootElement = webform.getSelection().getSelectedContainer();
1936: Element componentRootElement = designer.getSelectedContainer();
1937: // DesignBean lb = WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement);
1938:
1939: // if (lb == null) {
1940: if (componentRootElement == null) {
1941: // FacesPageUnit facesUnit = webform.getModel().getFacesUnit();
1942: // MarkupBean formBean = facesUnit.getDefaultParent();
1943: // lb = webform.getModel().getLiveUnit().getDesignBean(formBean);
1944: // lb = webform.getDefaultParentBean();
1945:
1946: // Element sourceElement = webform.getDefaultParentMarkupBeanElement();
1947: // componentRootElement = MarkupService.getRenderedElementForElement(sourceElement);
1948: // componentRootElement = webform.getDefaultParentComponent();
1949: componentRootElement = jsfForm.getDefaultParentComponent();
1950: }
1951:
1952: // return lb;
1953: return componentRootElement;
1954: }
1955:
1956: // protected MarkupPosition getPasteMarkupPosition() {
1957: // return null;
1958: // }
1959:
1960: // protected void selectBeans(DesignBean[] beans) {
1961: public/*protected*/void selectComponents(
1962: Element[] componentRootElements) {
1963: // SelectionManager selectionManager = webform.getSelection();
1964: //// MarkupDesignBean[] markupDesignBeans = selectionManager.getSelectedMarkupDesignBeans();
1965: // Element[] selectedComponentRootElements = selectionManager.getSelectedComponentRootElements();
1966: Element[] selectedComponentRootElements = designer
1967: .getSelectedComponents();
1968:
1969: // List<DesignBean> beansToSelect = Arrays.asList(beans);
1970: List<Element> componentsToSelect = Arrays
1971: .asList(componentRootElements);
1972: // List<MarkupDesignBean> selectedBeans = Arrays.asList(markupDesignBeans);
1973: // List<MarkupDesignBean> selectedBeans = new ArrayList<MarkupDesignBean>();
1974: // for (Element componentRootElement : selectedComponentRootElements) {
1975: // selectedBeans.add(WebForm.getDomProviderService().getMarkupDesignBeanForElement(componentRootElement));
1976: // }
1977: List<Element> selectedComponents = Arrays
1978: .asList(selectedComponentRootElements);
1979:
1980: // XXX Compare the content, the order is irrelevant.
1981: // if (beansToSelect.containsAll(selectedBeans)
1982: // && selectedBeans.containsAll(beansToSelect)) {
1983: // return;
1984: // }
1985: if (componentsToSelect.containsAll(selectedComponents)
1986: && selectedComponents.containsAll(componentsToSelect)) {
1987: return;
1988: }
1989:
1990: // selectionManager.selectComponents(beans, true);
1991: // selectionManager.selectComponents(componentRootElements, true);
1992: designer.setSelectedComponents(componentRootElements, true);
1993: }
1994:
1995: protected Transferable copy() {
1996: Node[] nodes = getActivatedNodes();
1997:
1998: if ((nodes == null) || (nodes.length == 0)) {
1999: return null;
2000: }
2001:
2002: // ArrayList list = new ArrayList(nodes.length);
2003: List<Element> componentRootElements = new ArrayList<Element>();
2004:
2005: // for (int i = 0; i < nodes.length; i++) {
2006: // if (nodes[i] instanceof DesignBeanNode) {
2007: // // XXX todo: make sure you don't copy the
2008: // // document bean!!!!!
2009: // DesignBeanNode node = (DesignBeanNode)nodes[i];
2010: // DesignBean bean = node.getDesignBean();
2011: //
2012: //// if (!FacesSupport.isSpecialBean(/*webform, */bean)) {
2013: // if (!Util.isSpecialBean(bean)) {
2014: // list.add(bean);
2015: // }
2016: // }
2017: // }
2018: for (Node node : nodes) {
2019: if (node == null) {
2020: continue;
2021: }
2022: // DesignBean designBean = (DesignBean)node.getLookup().lookup(DesignBean.class);
2023: // if (designBean == null) {
2024: // continue;
2025: // }
2026: // Element componentRootElement = WebForm.getDomProviderService().getComponentRootElementFromNode(node);
2027: Element componentRootElement = JsfSupportUtilities
2028: .getComponentRootElementFromNode(node);
2029: if (componentRootElement == null) {
2030: continue;
2031: }
2032: // if (!Util.isSpecialBean(designBean)) {
2033: // if (designBean instanceof MarkupDesignBean && !WebForm.getDomProviderService().isSpecialComponent(
2034: // WebForm.getDomProviderService().getComponentRootElementForMarkupDesignBean((MarkupDesignBean)designBean))) {
2035: // if (!WebForm.getDomProviderService().isSpecialComponent(componentRootElement)) {
2036: if (!JsfSupportUtilities
2037: .isSpecialComponent(componentRootElement)) {
2038: // list.add(designBean);
2039: componentRootElements.add(componentRootElement);
2040: }
2041: }
2042:
2043: // Ensure that no components in the list are a child of any
2044: // other
2045: // removeChildrenBeans(list);
2046: removeChildrenComponents(componentRootElements);
2047:
2048: // DesignBean[] beans = (DesignBean[])list.toArray(new DesignBean[list.size()]);
2049: // LiveUnit unit = webform.getModel().getLiveUnit();
2050: // Transferable t = unit.copyBeans(beans);
2051: // Transferable t = webform.copyBeans(beans);
2052: // Transferable t = webform.copyComponents(componentRootElements.toArray(new Element[componentRootElements.size()]));
2053: Transferable t = jsfForm.copyComponents(componentRootElements
2054: .toArray(new Element[componentRootElements.size()]));
2055:
2056: return t;
2057: }
2058:
2059: /** Remove the currently selected components */
2060: public void deleteSelection() {
2061: // Node[] nodes = getActivatedNodes();
2062: //
2063: // if ((nodes == null) || (nodes.length == 0)) {
2064: // return;
2065: // }
2066: //
2067: // // Do this AFTER we obtain the activated nodes - clearing
2068: // // the selection changes the activated nodes!
2069: //// webform.getSelection().clearSelection(true);
2070: // designer.clearSelection(true);
2071: //
2072: //// FacesModel model = webform.getModel();
2073: //// Document doc = webform.getDocument();
2074: //
2075: ////// UndoEvent undoEvent = webform.getModel().writeLock(NbBundle.getMessage(SelectionTopComp.class, "DeleteSelection")); // NOI18N
2076: //// DomProvider.WriteLock writeLock = webform.writeLock(NbBundle.getMessage(SelectionTopComp.class, "DeleteSelection")); // NOI18N
2077: //// try {
2078: //// doc.writeLock(NbBundle.getMessage(SelectionTopComp.class, "DeleteSelection")); // NOI18N
2079: //
2080: //// for (int i = 0; i < nodes.length; i++) {
2081: //// if (nodes[i] instanceof DesignBeanNode) {
2082: //// // XXX todo: make sure you don't delete the
2083: //// // document bean!!!!!
2084: //// DesignBeanNode node = (DesignBeanNode)nodes[i];
2085: //// DesignBean bean = node.getDesignBean();
2086: ////
2087: ////// if (!FacesSupport.isSpecialBean(/*webform, */bean)) {
2088: //// if (!Util.isSpecialBean(bean)) {
2089: //// model.getLiveUnit().deleteBean(bean);
2090: //// }
2091: //// }
2092: //// }
2093: // List<Element> componentRootElements = new ArrayList<Element>();
2094: // for (Node node : nodes) {
2095: // if (node == null) {
2096: // continue;
2097: // }
2098: //// DesignBean designBean = (DesignBean)node.getLookup().lookup(DesignBean.class);
2099: //// if (designBean == null) {
2100: //// continue;
2101: //// }
2102: //// Element componentRootElement = WebForm.getDomProviderService().getComponentRootElementFromNode(node);
2103: // Element componentRootElement = JsfSupportUtilities.getComponentRootElementFromNode(node);
2104: // if (componentRootElement == null) {
2105: // continue;
2106: // }
2107: //// if (!Util.isSpecialBean(designBean)) {
2108: //// if (designBean instanceof MarkupDesignBean && !WebForm.getDomProviderService().isSpecialComponent(
2109: //// WebForm.getDomProviderService().getComponentRootElementForMarkupDesignBean((MarkupDesignBean)designBean))) {
2110: //// if (!WebForm.getDomProviderService().isSpecialComponent(componentRootElement)) {
2111: ////// webform.getModel().getLiveUnit().deleteBean(designBean);
2112: ////// webform.deleteBean(designBean);
2113: //// webform.deleteComponent(componentRootElement);
2114: //// }
2115: // componentRootElements.add(componentRootElement);
2116: // }
2117: //// webform.getDomDocument().deleteComponents(componentRootElements.toArray(new Element[componentRootElements.size()]));
2118: // jsfForm.deleteComponents(componentRootElements.toArray(new Element[componentRootElements.size()]));
2119: //// } finally {
2120: ////// doc.writeUnlock();
2121: ////// webform.getModel().writeUnlock(undoEvent);
2122: //// webform.writeUnlock(writeLock);
2123: //// }
2124: Element[] componentRootElements = designer
2125: .getSelectedComponents();
2126: if (componentRootElements.length > 0) {
2127: designer.clearSelection(true);
2128: jsfForm.deleteComponents(componentRootElements);
2129: }
2130: }
2131:
2132: // XXX Public because implementing multiview.
2133:
2134: /* Deactivates copy/cut/paste actions.
2135: */
2136: @Override
2137: protected void componentDeactivated() {
2138: // super.componentDeactivated();
2139: //
2140: //// if (webform.hasSelection()) {
2141: //// webform.getManager().finishInlineEditing(false);
2142: //// }
2143: // if (designer.getSelectedCount() > 0) {
2144: // designer.finishInlineEditing(false);
2145: // }
2146: if (jsfForm.isValid()) {
2147: designerDeactivated();
2148: }
2149: }
2150:
2151: // Helper methods
2152:
2153: // /** Opens palette(toolbox), properties, outline and navigator windows. */
2154: // private static void openAdditionalWindows() {
2155: // // XXX #6314795 Until fixed NB #62975, schedule it later,
2156: // // it allows winsys to load all the modes. When NB issue fixed,
2157: // // remove the scheduling.
2158: // SwingUtilities.invokeLater(new Runnable() {
2159: // public void run() {
2160: // doOpenAdditionalWindows();
2161: // }
2162: // });
2163: // }
2164:
2165: // private static void doOpenAdditionalWindows() {
2166: // // XXX TODO Define TC group, and use that, not this way.
2167: //
2168: // WindowManager wm = WindowManager.getDefault();
2169: //// TopComponent palette = wm.findTopComponent("toolbox"); // NOI18N
2170: ////
2171: //// if (palette != null) {
2172: //// palette.open();
2173: //// }
2174: //
2175: //// TopComponent properties = wm.findTopComponent("properties"); // NOI18N
2176: //// if (properties != null && !properties.isOpened()) {
2177: //// properties.open();
2178: //// }
2179: //
2180: //// TopComponent dynamicHelp = wm.findTopComponent("dynamicHelp"); // NOI18N
2181: //// if (dynamicHelp != null && !dynamicHelp.isOpened()) {
2182: //// dynamicHelp.open();
2183: //// }
2184: //
2185: //// TopComponent outline = wm.findTopComponent("outline"); // NOI18N
2186: //// if (outline != null && !outline.isOpened()) {
2187: //// outline.open();
2188: //// }
2189: //
2190: //// TopComponent navigator = wm.findTopComponent("navigatorTC"); // NOI18N
2191: //// if (navigator != null && !navigator.isOpened()) {
2192: //// navigator.open();
2193: //// }
2194: // }
2195:
2196: // private void selectAndUpdateOutlineView() {
2197: //// OutlineTopComp.getInstance().setCurrent(webform);
2198: //// OutlineTopComp.getInstance().requestVisible();
2199: //// selectNewOutline();
2200: // // XXX Replace with TopComponentGroup.
2201: // selectNavigator();
2202: //
2203: // // #6318513 It doesn't keep selection expanded, when switching.
2204: //// WebForm wf = webform;
2205: ////
2206: //// if (wf != null) {
2207: //// // XXX Updates outline selection!
2208: //// wf.getSelection().updateSelection();
2209: //// }
2210: //// designer.updateSelection();
2211: // designer.updateSelectedNodes();
2212: // }
2213:
2214: // /** Selects the navigator window. */
2215: // private static void selectNavigatorWindow() {
2216: // TopComponent navigator = WindowManager.getDefault().findTopComponent("navigatorTC"); // NOI18N
2217: //
2218: // if (navigator != null) {
2219: // // XXX #6392131 -> NB #62329.
2220: // if (!Boolean.TRUE.equals(navigator.getClientProperty("isSliding"))) { // NOI18N
2221: // navigator.requestVisible();
2222: // }
2223: // }
2224: // }
2225:
2226: /** Weak reference to the lookup. */
2227: private WeakReference<Lookup> lookupWRef = new WeakReference<Lookup>(
2228: null);
2229:
2230: /** Adds <code>NavigatorLookupHint</code> into the original lookup,
2231: * for the navigator. */
2232: @Override
2233: public Lookup getLookup() {
2234: Lookup lookup = lookupWRef.get();
2235:
2236: if (lookup == null) {
2237: Lookup super Lookup = super .getLookup();
2238:
2239: // // XXX Needed in order to close the component automatically by project close.
2240: //// DataObject jspDataObject = webform.getJspDataObject();
2241: // DataObject jspDataObject = jsfForm.getJspDataObject();
2242: //
2243: //// PaletteController jsfPaletteController = webform.getPaletteController();
2244: // PaletteController jsfPaletteController = jsfForm.getPaletteController();
2245: //
2246: // if (jsfPaletteController == null) {
2247: // lookup = new ProxyLookup(new Lookup[] {superLookup, Lookups.fixed(new Object[] {jspDataObject, NAVIGATOR_HINT})});
2248: // } else {
2249: // lookup = new ProxyLookup(new Lookup[] {superLookup, Lookups.fixed(new Object[] {jspDataObject, NAVIGATOR_HINT, jsfPaletteController})});
2250: // }
2251: lookup = new ProxyLookup(new Lookup[] { super Lookup,
2252: Lookups.proxy(jsfLookupProvider) });
2253:
2254: lookupWRef = new WeakReference<Lookup>(lookup);
2255: }
2256:
2257: return lookup;
2258: }
2259:
2260: // private class ToolbarListener implements ActionListener {
2261: // /** Action to switch to selection, connection or add mode. */
2262: // public void actionPerformed(ActionEvent ev) {
2263: // Object source = ev.getSource();
2264: //
2265: // if (source == showVfButton) {
2266: // webform.getVirtualFormSupport().setEnabled(showVfButton.isSelected());
2267: // webform.getPane().repaint();
2268: // } else if (source == refreshButton) {
2269: // webform.getActions().refresh(true);
2270: // } else if (source == previewButton) {
2271: // new BrowserPreview(webform).preview();
2272: // }
2273: // }
2274: // }
2275:
2276: /** Listens on <code>DesignerSettings</code> changes. */
2277: // private static class SettingsListener implements PropertyChangeListener {
2278: private static class SettingsListener implements
2279: PreferenceChangeListener {
2280:
2281: // private final DesignerTopComp designerTC;
2282: private final JsfTopComponent designerTC;
2283:
2284: // public SettingsListener(DesignerTopComp designerTC) {
2285: public SettingsListener(JsfTopComponent designerTC) {
2286: this .designerTC = designerTC;
2287: }
2288:
2289: // public void propertyChange(PropertyChangeEvent evt) {
2290: public void preferenceChange(final PreferenceChangeEvent evt) {
2291: // XXX #112708 Prefernce change seems to be fired incorrectly
2292: // from other than event dispatch thread.
2293: if (EventQueue.isDispatchThread()) {
2294: doPreferenceChange(evt);
2295: } else {
2296: EventQueue.invokeLater(new Runnable() {
2297: public void run() {
2298: doPreferenceChange(evt);
2299: }
2300: });
2301: }
2302: }
2303:
2304: private void doPreferenceChange(PreferenceChangeEvent evt) {
2305: String key = evt.getKey();
2306: // XXX #6488437 Workaround for the cases the component is still held in the memory.
2307: // if (!designerTC.isOpened()) {
2308: if (!designerTC.isShowing()) {
2309: return;
2310: }
2311:
2312: JsfDesignerPreferences jsfDesignerPreferences = JsfDesignerPreferences
2313: .getInstance();
2314: // if(DesignerSettings.PROP_PAGE_SIZE.equals(key)) {
2315: // if(Designer.PROP_PAGE_SIZE.equals(key)) {
2316: if (JsfDesignerPreferences.PROP_PAGE_SIZE.equals(key)) {
2317: // designerTC.designer.setPageSizeWidth(jsfDesignerPreferences.getPageSizeWidth());
2318: // designerTC.designer.setPageSizeHeight(jsfDesignerPreferences.getPageSizeHeight());
2319: int width = jsfDesignerPreferences.getPageSizeWidth();
2320: int height = jsfDesignerPreferences.getPageSizeHeight();
2321: designerTC.designer.setPageSize(new Dimension(width,
2322: height));
2323: // There should be a cleaner way to request the revalidation,
2324: // why the standard API doesn't work?
2325: // XXX #6486462 Possible NPE.
2326: // DesignerPane designerPane = designerTC.getDesignerPane();
2327: // PageBox pageBox = designerPane == null ? null : designerPane.getPageBox();
2328: // if (pageBox != null) {
2329: // pageBox.redoLayout(true);
2330: // }
2331: // XXX Moved to designer/../WebForm
2332: // designerTC.designer.redoPaneLayout(true);
2333: // designerTC.repaint();
2334: // } else if (DesignerSettings.PROP_GRID_SHOW.equals(key)) {
2335: // } else if (Designer.PROP_GRID_SHOW.equals(key)) {
2336: } else if (JsfDesignerPreferences.PROP_GRID_SHOW
2337: .equals(key)) {
2338: boolean gridShow = jsfDesignerPreferences.getGridShow();
2339: // GridHandler.getDefault().setGrid(gridShow);
2340: designerTC.designer.setGridShow(gridShow);
2341: // XXX Moved to designer/../WebForm
2342: // designerTC.repaint();
2343: // } else if (DesignerSettings.PROP_GRID_SNAP.equals(key)) {
2344: // } else if (Designer.PROP_GRID_SNAP.equals(key)) {
2345: } else if (JsfDesignerPreferences.PROP_GRID_SNAP
2346: .equals(key)) {
2347: boolean gridSnap = jsfDesignerPreferences.getGridSnap();
2348: designerTC.designer.setGridSnap(gridSnap);
2349: // GridHandler.getDefault().setSnap(gridSnap);
2350: // XXX Moved to designer/../WebForm
2351: // designerTC.repaint();
2352: // } else if (DesignerSettings.PROP_GRID_WIDTH.equals(key)) {
2353: // } else if (Designer.PROP_GRID_WIDTH.equals(key)) {
2354: } else if (JsfDesignerPreferences.PROP_GRID_WIDTH
2355: .equals(key)) {
2356: int gridWidth = jsfDesignerPreferences.getGridWidth();
2357: designerTC.designer.setGridWidth(gridWidth);
2358: // GridHandler.getDefault().setGridWidth(gridWidth);
2359: designerTC.setGridTraceWidth(gridWidth);
2360: // XXX Moved to designer/../WebForm
2361: // designerTC.repaint();
2362: // } else if (DesignerSettings.PROP_GRID_HEIGHT.equals(key)) {
2363: // } else if (Designer.PROP_GRID_HEIGHT.equals(key)) {
2364: } else if (JsfDesignerPreferences.PROP_GRID_HEIGHT
2365: .equals(key)) {
2366: int gridHeight = jsfDesignerPreferences.getGridHeight();
2367: designerTC.designer.setGridHeight(gridHeight);
2368: // GridHandler.getDefault().setGridHeight(gridHeight);
2369: designerTC.setGridTraceHeight(gridHeight);
2370: // XXX Moved to designer/../WebForm
2371: // designerTC.repaint();
2372: // } else if (DesignerSettings.PROP_DEFAULT_FONT_SIZE.equals(key)) {
2373: // } else if (Designer.PROP_DEFAULT_FONT_SIZE.equals(key)) {
2374: } else if (JsfDesignerPreferences.PROP_DEFAULT_FONT_SIZE
2375: .equals(key)) {
2376: designerTC.designer
2377: .setDefaultFontSize(jsfDesignerPreferences
2378: .getDefaultFontSize());
2379: // designerTC.getWebForm().getPane().getPaneUI().resetPageBox();
2380: // XXX Moved to designer/../WebForm
2381: // designerTC.designer.resetPanePageBox();
2382: // designerTC.repaint();
2383: } else if (JsfDesignerPreferences.PROP_SHOW_DECORATIONS
2384: .equals(key)) {
2385: designerTC.designer
2386: .setShowDecorations(jsfDesignerPreferences
2387: .isShowDecorations());
2388: // XXX Moved to designer/../WebForm
2389: // designerTC.repaint();
2390: }
2391: }
2392: } // End of SettingsListener.
2393:
2394: /** Listener on activatedNodes property, to get the notifications from outside world,
2395: * concretely when set the nodes according to the outline component. */
2396: private static class ActivatedNodesListener implements
2397: PropertyChangeListener {
2398:
2399: // private final DesignerTopComp designerTC;
2400: private final JsfTopComponent designerTC;
2401:
2402: // public ActivatedNodesListener(DesignerTopComp designerTC) {
2403: public ActivatedNodesListener(JsfTopComponent designerTC) {
2404: this .designerTC = designerTC;
2405: }
2406:
2407: public void propertyChange(PropertyChangeEvent evt) {
2408: if ("activatedNodes".equals(evt.getPropertyName())) { // NOI18N
2409: Node[] activatedNodes = (Node[]) evt.getNewValue();
2410: // DesignBean[] beans = getBeansForNodes(activatedNodes);
2411: Element[] componentRootElements = getComponentsForNodes(activatedNodes);
2412:
2413: // TODO There are still some callbacks fromo and to the old outline which
2414: // disrupt this to work nicelly, but for now it should be OK,
2415: // it needs to be finally fixed when old outline removed.
2416: // designerTC.selectBeans(beans);
2417: designerTC.selectComponents(componentRootElements);
2418: }
2419: }
2420: } // End of ActivatedNodesListener.
2421:
2422: // private static DesignBean[] getBeansForNodes(Node[] nodes) {
2423: private static Element[] getComponentsForNodes(Node[] nodes) {
2424: if (nodes == null) {
2425: // return new DesignBean[0];
2426: return new Element[0];
2427: }
2428:
2429: // List beans = new ArrayList();
2430: List<Element> components = new ArrayList<Element>();
2431: for (int i = 0; i < nodes.length; i++) {
2432: Node node = nodes[i];
2433: // DesignBean bean = (DesignBean)node.getLookup().lookup(DesignBean.class);
2434: // if (bean == null) {
2435: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
2436: // new NullPointerException("No DesignBean for node=" + node)); // NOI18N
2437: // continue;
2438: // }
2439: // Element componentRootElement = WebForm.getDomProviderService().getComponentRootElementFromNode(node);
2440: Element componentRootElement = JsfSupportUtilities
2441: .getComponentRootElementFromNode(node);
2442: // beans.add(bean);
2443: if (componentRootElement != null) {
2444: components.add(componentRootElement);
2445: }
2446: }
2447:
2448: // return (DesignBean[])beans.toArray(new DesignBean[beans.size()]);
2449: return components.toArray(new Element[components.size()]);
2450: }
2451:
2452: // XXX Moved to designer/jsf/PaletteControllerFactory
2453: // private static class DesignerComplibListener implements ComplibListener {
2454: // private static DesignerComplibListener INSTANCE = new DesignerComplibListener();
2455: //
2456: // private WeakReference<PaletteController> paletteControllerWRef = new WeakReference<PaletteController>(null);
2457: //
2458: // private boolean installed;
2459: //
2460: // public static DesignerComplibListener getDefault() {
2461: // return INSTANCE;
2462: // }
2463: //
2464: // public void install() {
2465: // if (installed) {
2466: // return;
2467: // }
2468: // ComplibService complibService = getComplibService();
2469: // if (complibService == null) {
2470: // return;
2471: // }
2472: // complibService.addComplibListener(this);
2473: // installed = true;
2474: // }
2475: //
2476: // public void uninstall() {
2477: // ComplibService complibService = getComplibService();
2478: // if (complibService == null) {
2479: // return;
2480: // }
2481: // complibService.removeComplibListener(this);
2482: // installed = false;
2483: // }
2484: //
2485: // public void setPaletteController(PaletteController paletteController) {
2486: // paletteControllerWRef = new WeakReference<PaletteController>(paletteController);
2487: // }
2488: //
2489: // public void paletteChanged(ComplibEvent evt) {
2490: // PaletteController paletteController = paletteControllerWRef.get();
2491: // if (paletteController == null) {
2492: // return;
2493: // }
2494: // paletteController.refresh();
2495: // }
2496: //
2497: // private static ComplibService getComplibService() {
2498: // return (ComplibService)Lookup.getDefault().lookup(ComplibService.class);
2499: // }
2500: // } // End of DesignerComplibListener
2501:
2502: private static class ErrorPanelCallbackImpl implements
2503: JsfForm.ErrorPanelCallback {
2504: // private final WebForm webForm;
2505: // private final JsfForm jsfForm;
2506: // private final Designer designer;
2507: private final JsfTopComponent jsfTC;
2508:
2509: public ErrorPanelCallbackImpl(
2510: /*WebForm webForm*/JsfTopComponent jsfTC) {
2511: // this.webForm = webForm;
2512: this .jsfTC = jsfTC;
2513: }
2514:
2515: public void updateTopComponentForErrors() {
2516: // webForm.getTopComponent().updateErrors();
2517: jsfTC.updateErrors();
2518: }
2519:
2520: public void setRenderFailureShown(boolean shown) {
2521: // webForm.setRenderFailureShown(shown);
2522: jsfTC.jsfForm.setRenderFailureShown(shown);
2523: }
2524:
2525: // public Exception getRenderFailure() {
2526: // return webForm.getRenderFailure();
2527: // }
2528: //
2529: // public MarkupDesignBean getRenderFailureComponent() {
2530: // return webForm.getRenderFailureComponent();
2531: // }
2532:
2533: public void handleRefresh(boolean showErrors) {
2534: // Continue from the error panel to the designview
2535: // webForm.getTopComponent().showErrors(showErrors);
2536: jsfTC.showErrors(showErrors);
2537: // 6274302: See if the user has cleared the error
2538: // webform.refresh(true);
2539: // webForm.refreshModel(true);
2540: jsfTC.jsfForm.refreshModel(true);
2541: }
2542: } // End of ErrorPanelCallbackImpl.
2543:
2544: // public DataObject getJspDataObject() {
2545: // return jsfForm.getJspDataObject();
2546: // }
2547:
2548: // JSF notifications >>>
2549: public void modelChanged() {
2550: designer.resetPanePageBox();
2551: }
2552:
2553: public void modelRefreshed() {
2554: designer.resetAll();
2555: }
2556:
2557: public void nodeChanged(org.w3c.dom.Node node,
2558: org.w3c.dom.Node parent, Element[] changedElements) {
2559: designer.changeNode(node, parent, changedElements);
2560: }
2561:
2562: public void nodeRemoved(org.w3c.dom.Node node,
2563: org.w3c.dom.Node parent) {
2564: designer.removeNode(node, parent);
2565: }
2566:
2567: public void nodeInserted(org.w3c.dom.Node node,
2568: org.w3c.dom.Node parent) {
2569: designer.insertNode(node, parent);
2570: }
2571:
2572: public void gridModeUpdated(boolean gridMode) {
2573: designer.setPaneGrid(gridMode);
2574: }
2575:
2576: public void documentReplaced() {
2577: designer.detachDomDocument();
2578: }
2579:
2580: public void showDropMatch(Element componentRootElement,
2581: Element regionElement, int dropType) {
2582: designer.showDropMatch(componentRootElement, regionElement,
2583: dropType);
2584: }
2585:
2586: public void clearDropMatch() {
2587: designer.clearDropMatch();
2588: }
2589:
2590: public void selectComponent(Element componentRootElement) {
2591: // XXX Get rid of delayed.
2592: designer.selectComponentDelayed(componentRootElement);
2593: }
2594:
2595: public void inlineEditComponents(Element[] componentRootElements) {
2596: requestActive();
2597: designer.inlineEditComponents(componentRootElements);
2598: }
2599:
2600: // JSF notifications <<<
2601:
2602: // private static class JsfDesignerListener implements DesignerListener {
2603: // private final JsfTopComponent jsfTopComponent;
2604: //
2605: // public JsfDesignerListener(JsfTopComponent jsfTopComponent) {
2606: // this.jsfTopComponent = jsfTopComponent;
2607: // }
2608: // } // End of JsfDesignerListener.
2609:
2610: TopComponent getMultiViewTopComponent() {
2611: MultiViewElementCallback callback = multiViewElementCallback;
2612: if (callback == null) {
2613: return null;
2614: }
2615: return callback.getTopComponent();
2616: }
2617:
2618: void closeMultiView() {
2619: TopComponent multiView = getMultiViewTopComponent();
2620: if (multiView == null) {
2621: return;
2622: }
2623: multiView.close();
2624: }
2625:
2626: boolean isSelectedInMultiView() {
2627: MultiViewElementCallback callback = multiViewElementCallback;
2628: return callback == null ? false : callback.isSelectedElement();
2629: }
2630:
2631: private abstract static class JsfTopComponentAction extends
2632: AbstractAction {
2633: private final JsfTopComponent jsfTopComponent;
2634:
2635: public JsfTopComponentAction(JsfTopComponent jsfTopComponent) {
2636: this .jsfTopComponent = jsfTopComponent;
2637: }
2638:
2639: protected JsfTopComponent getJsfTopComponent() {
2640: return jsfTopComponent;
2641: }
2642: } // End of JsfTopComponentAction.
2643:
2644: // private static class EscapeAction extends JsfTopComponentAction {
2645: // public EscapeAction(JsfTopComponent jsfTopComponent) {
2646: // super(jsfTopComponent);
2647: // }
2648: // public void actionPerformed(ActionEvent evt) {
2649: // getJsfTopComponent().escape(evt.getWhen());
2650: // }
2651: // } // End of EscapeAction.
2652:
2653: private static class EditValueAction extends JsfTopComponentAction {
2654: public EditValueAction(JsfTopComponent jsfTopComponent) {
2655: super (jsfTopComponent);
2656: }
2657:
2658: public void actionPerformed(ActionEvent evt) {
2659: JsfTopComponent jsfTopComponent = getJsfTopComponent();
2660: if (jsfTopComponent.designer.isInlineEditing()) {
2661: // Already inline editing - no point doing anything
2662: return;
2663: }
2664:
2665: boolean success = jsfTopComponent.editValue();
2666:
2667: if (!success) {
2668: UIManager.getLookAndFeel().provideErrorFeedback(
2669: jsfTopComponent); // beep
2670: }
2671: }
2672:
2673: } // End of EditValueAction.
2674:
2675: private static class DumpHtmlAction extends JsfTopComponentAction {
2676: public DumpHtmlAction(JsfTopComponent jsfTopComponent) {
2677: super (jsfTopComponent);
2678: }
2679:
2680: public void actionPerformed(ActionEvent e) {
2681: getJsfTopComponent().dumpActivatedMarkupDesignBeansHtml();
2682: }
2683: } // End of DumpHtmlAction.
2684:
2685: private static class DumpBoxesAction extends JsfTopComponentAction {
2686: public DumpBoxesAction(JsfTopComponent jsfTopComponent) {
2687: super (jsfTopComponent);
2688: }
2689:
2690: public void actionPerformed(ActionEvent e) {
2691: getJsfTopComponent().dumpActivatedComponentCssBoxes();
2692: }
2693: } // End of DumpBoxesAction.
2694:
2695: private static class DesignerNavigatorLookupHint implements
2696: NavigatorLookupHint {
2697: public String getContentType() {
2698: // TODO Find out nice MIME type.
2699: return "application/x-designer"; // NOI18N
2700: }
2701: } // End of DesignerNavigatorLookupHint.
2702:
2703: @Override
2704: protected void designerActivated() {
2705: // // XXX Replace with TopComponentGroup.
2706: // selectNavigator();
2707:
2708: designer.updateSelectedNodes();
2709:
2710: super .designerActivated();
2711:
2712: designer.paneRequestFocus();
2713: }
2714:
2715: @Override
2716: protected void designerDeactivated() {
2717: super .designerDeactivated();
2718:
2719: if (designer.getSelectedCount() > 0) {
2720: designer.finishInlineEditing(false);
2721: }
2722: }
2723:
2724: private void designerOpened() {
2725: // // The following will also initialize the context listeners,
2726: // // provided the context is available
2727: // updateErrors();
2728: //
2729: //// // Set listening.
2730: //// // XXX
2731: //// designer.registerListeners();
2732:
2733: // // XXX Implement TopComponentGroup.
2734: // openAdditionalWindows();
2735: // No op.
2736: }
2737:
2738: private void designerClosed() {
2739: if (!needListeners) {
2740: needListeners = true;
2741: }
2742:
2743: // // Stop listening.
2744: // // XXX
2745: // designer.unregisterListeners();
2746:
2747: jsfForm.clearHtml();
2748: }
2749:
2750: private void designerShowing() {
2751: if (jsfForm.isFragment()) {
2752: jsfForm.refreshModel(false);
2753: }
2754:
2755: // // XXX Replace with TopComponentGroup.
2756: // openNavigator();
2757: // selectAndUpdateOutlineView();
2758:
2759: // XXX #6314795 See below, also this one should be scheduled later.
2760: // Remove scheduling when the NB issue fixed.
2761:
2762: // Insync: parse the backing file such that we incorporate
2763: // user changes in the backing file (and don't blow them away
2764: // in componentHidden when we later flush the model to the doc)
2765: //final DataObject dobj = webform.getDataObject();
2766: if (jsfForm.isSourceDirty() && designer.hasPaneCaret()) {
2767: // Remove the caret if we do a sync since the caret could be
2768: // pointing into an old DOM which causes various ugliness
2769: designer.setPaneCaret(DomPosition.NONE);
2770: }
2771:
2772: if (jsfForm.isModelInSync()) {
2773: // XXX #125601 Also one need to check for fragments,
2774: // those are not getting updated correctly (bad architecture of model changes).
2775: if (jsfForm.isFragment()
2776: || jsfForm.hasCachedExternalFrames()
2777: || designer.getPageBox() == null) {
2778: resetDesigner();
2779: }
2780: refreshDesignerPaneAsNeeded();
2781: } else {
2782: final JComponent reloadingComponent = createReloadingComponent();
2783: // Needs to be first (to be on top in overlay).
2784: panel.add(reloadingComponent,
2785: getDefaultGridBagConstraints(), 0);
2786: EventQueue.invokeLater(new Runnable() {
2787: public void run() {
2788: try {
2789: jsfForm.syncModel();
2790: resetDesigner();
2791: refreshDesignerPaneAsNeeded();
2792: } finally {
2793: panel.remove(reloadingComponent);
2794: }
2795: }
2796: });
2797: }
2798:
2799: // XXX This was wrong, showing doesn't necessarily mean activated.
2800: // // We cannot set the caret to the document position yet; we need
2801: // // to do layout before the mapper functions work... This is done
2802: // // after page layout instead.
2803: // designer.paneRequestFocus();
2804: }
2805:
2806: private void resetDesigner() {
2807: designer.resetPanePageBox();
2808: // It's not enough to do showErrors and showTray in contextChanged
2809: // because contextChanged is not run when the form is first opened.
2810: // XXX perhaps I can do this in componentOpened instead?
2811: updateErrors(); // XXX shouldn't the contextChanged ensure this?
2812: }
2813:
2814: // XXX Bad method from old code.
2815: private void refreshDesignerPaneAsNeeded() {
2816: // Refresh layout for fragments and for pages that contain fragments whenever
2817: // they are exposed
2818: if (jsfForm.isFragment() || jsfForm.hasCachedExternalFrames()) {
2819: // Always refresh fragments on expose since whenever they are
2820: // rendered as part of other (including) documents those documents
2821: // may style our elements and stash box references on the elements
2822: // that point to their own box hierarchies
2823: designer.redoPaneLayout(true);
2824: }
2825:
2826: designer.setPaneGrid(jsfForm.isGridMode());
2827: }
2828:
2829: private void designerHidden() {
2830: // No op.
2831: }
2832:
2833: private boolean isActivated() {
2834: MultiViewElementCallback callback = multiViewElementCallback;
2835: return callback == null ? false : callback.isSelectedElement()
2836: && callback.getTopComponent() == TopComponent
2837: .getRegistry().getActivated();
2838: }
2839:
2840: void modelLoaded() {
2841: initDesigner();
2842: designerOpened();
2843: designerShowing();
2844: if (isActivated()) {
2845: designerActivated();
2846: }
2847:
2848: revalidate();
2849: repaint();
2850: }
2851:
2852: // XXX Copied from GridHandler#setGridWidth.
2853: private void setGridTraceWidth(int gridWidth) {
2854: int i;
2855: int nt;
2856:
2857: int gridTraceWidth = gridWidth;
2858:
2859: for (i = 2; (nt = gridWidth / i) >= 8; i++) {
2860: gridTraceWidth = nt;
2861: }
2862:
2863: designer.setGridTraceWidth(gridTraceWidth);
2864: }
2865:
2866: // XXX Copied from GridHandler#setGridHeight;
2867: private void setGridTraceHeight(int gridHeight) {
2868: int i;
2869: int nt;
2870:
2871: int gridTraceHeight = gridHeight;
2872:
2873: for (i = 2; (nt = gridHeight / i) >= 8; i++) {
2874: gridTraceHeight = nt;
2875: }
2876:
2877: designer.setGridTraceHeight(gridTraceHeight);
2878: }
2879:
2880: private static class JsfLookupProvider implements Lookup.Provider {
2881: private final Lookup lookup;
2882:
2883: public JsfLookupProvider(JsfTopComponent jsfTopComponent,
2884: DataObject jspDataObject) {
2885: this .lookup = createLookup(jsfTopComponent, jspDataObject);
2886: }
2887:
2888: public Lookup getLookup() {
2889: return lookup;
2890: }
2891:
2892: private Lookup createLookup(JsfTopComponent jsfTopComponent,
2893: DataObject jspDataObject) {
2894: List<Object> objects = new ArrayList<Object>();
2895:
2896: objects.add(jspDataObject);
2897:
2898: objects.add(jsfTopComponent.NAVIGATOR_HINT);
2899:
2900: // Also add the policy to show only panels according to the provided hints.
2901: objects.add(jsfTopComponent.NAVIGATOR_LOOKUP_PANELS_POLICY);
2902:
2903: PaletteController paletteController = jsfTopComponent
2904: .getJsfForm().getPaletteController();
2905: if (paletteController == null) {
2906: warn("Loaded FacesModel doesn't Project needed to create PaletteController!"
2907: + "\nThe Designer lookup won't be fully inited. Palete won't be loaded."
2908: + "\nVariable jsfForm="
2909: + jsfTopComponent.getJsfForm()); // NOI18N
2910: } else {
2911: objects.add(paletteController);
2912: }
2913:
2914: return Lookups.fixed(objects.toArray());
2915: }
2916: } // End of JsfLookupProvider.
2917:
2918: private static void warn(String message) {
2919: Logger logger = getLogger();
2920: logger.log(Level.WARNING, message);
2921: }
2922:
2923: private static void log(String message) {
2924: Logger logger = getLogger();
2925: logger.log(Level.INFO, message);
2926: }
2927:
2928: private static Logger getLogger() {
2929: return Logger.getLogger(JsfTopComponent.class.getName());
2930: }
2931:
2932: private static class DesignerNavigatorLookupPanelsPolicy implements
2933: NavigatorLookupPanelsPolicy {
2934:
2935: public int getPanelsPolicy() {
2936: return NavigatorLookupPanelsPolicy.LOOKUP_HINTS_ONLY;
2937: }
2938:
2939: } // DesignerNavigatorLooupPanelPolicy
2940:
2941: private static GridBagConstraints getDefaultGridBagConstraints() {
2942: return new GridBagConstraints(0, 0, // cell
2943: 1, 1, // size of cell
2944: 1.0d, 1.0d, // weight
2945: GridBagConstraints.CENTER, // position
2946: GridBagConstraints.BOTH, // span
2947: new Insets(0, 0, 0, 0), 0, 0); // padding
2948: }
2949: }
|