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;
0042:
0043: import java.awt.Rectangle;
0044: import java.awt.event.ActionEvent;
0045: import javax.swing.ActionMap;
0046: import org.netbeans.modules.visualweb.api.designer.Designer;
0047: import org.netbeans.modules.visualweb.api.designer.Designer.DesignerEvent;
0048: import org.netbeans.modules.visualweb.api.designer.DomProvider;
0049: import org.netbeans.modules.visualweb.api.designer.DomProvider.DomDocument;
0050: import org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition;
0051: import org.netbeans.modules.visualweb.api.designer.DomProvider.DomPosition.Bias;
0052: import org.netbeans.modules.visualweb.api.designer.DomProvider.DomRange;
0053: import org.netbeans.modules.visualweb.api.designer.DomProvider.InlineEditorSupport;
0054: import org.netbeans.modules.visualweb.api.designer.DomProviderService;
0055: import org.netbeans.modules.visualweb.css2.CssBox;
0056: import org.netbeans.modules.visualweb.css2.ModelViewMapper;
0057: import org.netbeans.modules.visualweb.css2.PageBox;
0058: import java.awt.Dimension;
0059: import java.awt.EventQueue;
0060: import java.awt.FontMetrics;
0061: import java.awt.Graphics2D;
0062: import java.awt.Point;
0063: import java.awt.datatransfer.DataFlavor;
0064: import java.awt.datatransfer.Transferable;
0065: import java.lang.ref.WeakReference;
0066: import java.net.URL;
0067: import java.util.ArrayList;
0068: import java.util.List;
0069: import java.util.Map;
0070:
0071: import java.util.WeakHashMap;
0072: import javax.swing.CellRendererPane;
0073: import javax.swing.JComponent;
0074: import javax.swing.event.EventListenerList;
0075: import org.netbeans.modules.visualweb.css2.BoxType;
0076: import org.netbeans.modules.visualweb.css2.ContainerBox;
0077: import org.netbeans.modules.visualweb.spi.designer.Decoration;
0078:
0079: import org.netbeans.spi.palette.PaletteController;
0080: import org.openide.ErrorManager;
0081: import org.w3c.dom.Element;
0082: import org.w3c.dom.Node;
0083:
0084: /**
0085: * Holds web-form related state.
0086: * <p>
0087: *
0088: * @author Peter Zavadsky
0089: * @author Tor Norbye (the original code)
0090: */
0091: public class WebForm implements Designer {
0092: /** Represents a webform that is external - and cannot be previewed
0093: * in the designer.
0094: */
0095: // public static final WebForm EXTERNAL = new WebForm();
0096: // /** A weak Map<DataObject,WebForm>. <b>Access locked by LOCK_WEB_FORMS</b>. */
0097: // private static final Map webForms = new WeakHashMap();
0098: // /** A weak Map<FileObject, WebForm>. This is needed because we need to
0099: // * be able to clean up when we find out that a FileObject has been deleted. And there
0100: // * is no way to find the DataObject for a FileObject that was deleted. The alternative
0101: // * would be iterate through the <DataObject,WebForm> map, and for each data object
0102: // * key check if dataObject.getPrimaryFile() is the FileObject we're after.
0103: // * But that seems risky since this is a weak map - it could already have been
0104: // * discarded, since the system seems to already have disconnected the data object
0105: // * once the file is deleted.
0106: // * So for now we simply keep two maps in sync.
0107: // * <b>Access locked by LOCK_WEB_FORMS</b>.
0108: // */
0109: // private static final Map webFormsByFileObject = new WeakHashMap();
0110:
0111: // /** Lock for the webForms and webFormsByFileObject maps */
0112: // private static final Object LOCK_WEB_FORMS = new Object();
0113: // private static final Map<DomProvider, WebForm> domProvider2webForm = new WeakHashMap<DomProvider, WebForm>();
0114: private final DomProvider domProvider;
0115:
0116: // private final DomProvider.DomProviderListener domProviderListener = new domProviderListener(this);
0117:
0118: // protected FacesModel model;
0119: private SelectionManager selection;
0120: // private DesignerTopComp view;
0121:
0122: // private Document document;
0123: // private final DomDocument domDocument = DesignerPaneBase.createDomDocument(this);
0124:
0125: // private boolean gridMode = false;
0126: // private ModelViewMapper mapper;
0127: // private CssLookup css;
0128:
0129: private final CellRendererPane rendererPane = new CellRendererPane();
0130:
0131: private final DesignerPane designerPane;
0132:
0133: // private DocumentFragment html;
0134: // private DomSynchronizer domSyncer;
0135: // private RaveElement body;
0136:
0137: // private VirtualFormSupport virtualForms;
0138: // private boolean virtualFormsEnabled;
0139:
0140: private ColorManager colors;
0141: // private DesignerActions actions;
0142: private InteractionManager manager;
0143: // private GridHandler gridHandler;
0144: // private boolean isFragment;
0145: // private boolean isPortlet;
0146: // private WebForm contextPage;
0147: // private Exception renderFailure;
0148: // private boolean renderFailureShown;
0149: // private MarkupDesignBean renderFailureComponent;
0150:
0151: // /** Maps elements to css boxes. */
0152: // private final Map<Element, CssBox> element2cssBox = new WeakHashMap<Element, CssBox>();
0153: // private static final String KEY_CSS_BOX_MAP = "vwpCssBoxMap"; // NOI18N
0154:
0155: // // XXX Suspicious listener, it should be removed.
0156: // private JspDataObjectListener jspDataObjectListener;
0157:
0158: // XXX Moved from Document.
0159: private ImageCache imageCache;
0160: // private DocumentCache frameCache;
0161:
0162: private final EventListenerList listenerList = new EventListenerList();
0163:
0164: /** Determines whether to paint size mask or not. Typically used for fragments and portlets.
0165: * The mask is painted in case the returned body element has width and height properties smaller
0166: * than the size of the viewport. */
0167: private boolean paintSizeMask;
0168:
0169: // XXX #117371 Keeping the ref to css box with intial focus mark.
0170: private WeakReference<CssBox> initialFocusMarkCssBoxWRef = new WeakReference<CssBox>(
0171: null);
0172:
0173: // private int pageSizeWidth;
0174: // private int pageSizeHeight;
0175: private final Dimension pageSize = new Dimension(0, 0);
0176: private boolean gridShow;
0177: private boolean gridSnap;
0178: private int gridWidth;
0179: private int gridHeight;
0180: private int gridTraceWidth;
0181: private int gridTraceHeight;
0182: private boolean showDecorations;
0183: private int defaultFontSize;
0184:
0185: // private static class JspDataObjectListener implements PropertyChangeListener {
0186: // private final WebForm webForm;
0187: // public JspDataObjectListener(WebForm webForm) {
0188: // this.webForm = webForm;
0189: // }
0190: // public void propertyChange(final PropertyChangeEvent evt) {
0191: // // Immediately wipe out the paint box
0192: // if (evt.getPropertyName().equals(DataObject.PROP_PRIMARY_FILE)) {
0193: // if ((webForm.getPane() != null) && (webForm.getPane().getPaneUI() != null)) {
0194: // webForm.getPane().getPaneUI().setPageBox(null);
0195: // }
0196: //
0197: //// // Reconfigure the data object: throw away the old model
0198: //// // and find the new model associated with the new file object.
0199: //// InSyncService.getProvider().doOutsideOfRefactoringSession(new Runnable() {
0200: //// public void run() {
0201: //// // Do the stuff on UI thread as some stuff gets updated that requires to be on UI thread
0202: //// SwingUtilities.invokeLater(new Runnable() {
0203: //// public void run() {
0204: //// replaceModel((FileObject)evt.getOldValue(), (FileObject)evt.getNewValue());
0205: //// }
0206: //// });
0207: //// }
0208: //// });
0209: // }
0210: // }
0211: // } // End of JspDataObjectListener.
0212:
0213: // private boolean cisClosing = false;
0214:
0215: // private WebForm() {
0216: // // XXX Get rid of this constructor.
0217: // this.domProvider = null;
0218: // }
0219:
0220: /**
0221: * Create a new webform object. dobj cannot be null.
0222: */
0223: private WebForm(DomProvider domProvider /*, FileObject fo*/) {
0224: // assert fo != null;
0225: if (domProvider == null /*|| fo == null*/) {
0226: throw new NullPointerException(
0227: "The domProvider parameter can't be null!" // NOI18N
0228: /*+ ", fo=" + fo*/); // NOI18N
0229: }
0230:
0231: this .domProvider = domProvider;
0232:
0233: this .designerPane = new DesignerPane(this );
0234: // associateModel(fo);
0235: // init(fo);
0236: }
0237:
0238: // private void associateModel(FileObject fo) {
0239: // model = FacesModel.getInstance(fo);
0240: //
0241: // if (model == null) {
0242: // throw new IllegalArgumentException("Specified file is not webform-like fo=" + fo); // NOI18N
0243: // }
0244: //
0245: // init(fo);
0246: // }
0247:
0248: public static WebForm createWebForm(DomProvider domProvider) {
0249: return new WebForm(domProvider);
0250: }
0251:
0252: // // Moved from DesignerUtils.
0253: // /** Locate the webform associated with the given data object. Will return
0254: // * null if no such object is found.
0255: // * @param dobj The data object for which a webform should be located
0256: // * @param initialize If false, don't initialize a webform that has
0257: // * not yet been open - return null instead.
0258: // */
0259: // public static WebForm findWebForm(DataObject dobj) {
0260: // if (isWebFormDataObject(dobj)) {
0261: // return getWebFormForDataObject(dobj);
0262: // }
0263: //
0264: // return null;
0265: // }
0266:
0267: // private static DesignerFinder getDesignerFinder() {
0268: // DesignerFinder designerFinder = (DesignerFinder)Lookup.getDefault().lookup(DesignerFinder.class);
0269: // if (designerFinder == null) {
0270: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
0271: // new NullPointerException("DesignerFinder impl not available!")); // NOI18N
0272: // return null;
0273: // }
0274: // return designerFinder;
0275: // }
0276: //
0277: // private static WebForm findDesigner(DataObject dataObject) {
0278: // DesignerFinder designerFinder = getDesignerFinder();
0279: // if (designerFinder == null) {
0280: // return null;
0281: // }
0282: //
0283: // Designer designer = designerFinder.getDesigner(dataObject);
0284: // return getWebFormForDesigner(designer);
0285: // }
0286: //
0287: // private static WebForm getWebFormForDesigner(Designer designer) {
0288: // if (designer instanceof WebForm) {
0289: // return (WebForm)designer;
0290: // } else {
0291: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
0292: // new IllegalStateException("Found designer is not of WebForm type, designer=" + designer)); // TEMP
0293: // return null;
0294: // }
0295: // }
0296:
0297: // private static boolean isWebFormDataObject(DataObject dobj) {
0298: //// return (dobj != null) && (FacesModel.getInstance(dobj.getPrimaryFile()) != null);
0299: // return (dobj != null) && getDomProviderService().isWebFormFileObject(dobj.getPrimaryFile());
0300: // }
0301:
0302: // public static boolean hasWebFormForDataObject(DataObject dobj) {
0303: //// synchronized (LOCK_WEB_FORMS) {
0304: //// return webForms.containsKey(dobj);
0305: //// }
0306: //
0307: //// return getDesignerFinder().hasDesigner(dobj);
0308: //
0309: // DomProviderFinder domProviderFinder = getDomProviderFinder();
0310: // if (domProviderFinder == null) {
0311: // return false;
0312: // }
0313: //
0314: // if (!domProviderFinder.hasDomProvider(dobj)) {
0315: // return false;
0316: // }
0317: //
0318: // DomProvider domProvider = domProviderFinder.findDomProvider(dobj);
0319: // synchronized (domProvider2webForm) {
0320: // // XXX Check whether the model is still valid
0321: // return domProvider2webForm.containsKey(domProvider);
0322: // }
0323: // }
0324: // private static boolean hasWebFormForDataObject(DataObject jsfJspDataObject) {
0325: // if (jsfJspDataObject == null) {
0326: // return false;
0327: // }
0328: // return findWebFormForFileObject(jsfJspDataObject.getPrimaryFile()) != null;
0329: // }
0330:
0331: // public static WebForm getWebFormForDataObject(/*DomProvider domProvider,*/ DataObject dobj) {
0332: // if (/*domProvider == null ||*/ dobj == null) {
0333: // throw new NullPointerException("Parameter dobj can't be null!"); // NOI18N
0334: // }
0335: //
0336: //// synchronized (LOCK_WEB_FORMS) {
0337: //// WebForm webform = (WebForm)webForms.get(dobj);
0338: ////
0339: //// if (webform == null) {
0340: //// FileObject fo = dobj.getPrimaryFile();
0341: //// webform = new WebForm(domProvider, fo);
0342: //// webForms.put(dobj, webform);
0343: //// webFormsByFileObject.put(fo, webform);
0344: ////
0345: //// dobj.addPropertyChangeListener(webform.propertyListener);
0346: //// }
0347: ////
0348: //// return webform;
0349: //// }
0350: //
0351: //// return findDesigner(dobj);
0352: //
0353: // DomProvider domProvider = getDomProviderFinder().getDomProvider(dobj);
0354: // if (domProvider == null) {
0355: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
0356: // new NullPointerException("No instance of DomProvider for data object, dobj=" + dobj)); // NOI18N
0357: // return null;
0358: // }
0359: // return getWebFormForDomProvider(domProvider);
0360: // }
0361:
0362: // public static WebForm getWebFormForDomProvider(DomProvider domProvider) {
0363: // if (domProvider == null) {
0364: // throw new NullPointerException("Can't create WebForm for null DomProvider!"); // NOI18N
0365: // }
0366: // synchronized (domProvider2webForm) {
0367: // WebForm webForm = domProvider2webForm.get(DomProvider);
0368: // if (webForm == null) {
0369: // webForm = new WebForm(domProvider);
0370: // domProvider2webForm.put(DomProvider, webForm);
0371: // }
0372: // return webForm;
0373: // }
0374: // }
0375:
0376: // public static DomProviderService getDomProviderService() {
0377: // DomProviderService domProviderService = (DomProviderService)Lookup.getDefault().lookup(DomProviderService.class);
0378: // if (domProviderService == null) {
0379: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
0380: // new NullPointerException("No instance of DomProviderService available!")); // NOI18N
0381: // return new DummyDomProviderService();
0382: // }
0383: // return domProviderService;
0384: // }
0385: public DomProviderService getDomProviderService() {
0386: return domProvider.getDomProviderService();
0387: }
0388:
0389: // /** The DataObject/Model we're attached to has been reconfigured: it's now
0390: // * pointing to a new primary file. (This happens when you rename a folder
0391: // * for example.) Since models are tied to FileObjects, not DataObjects,
0392: // * we need to switch models behind the scenes.
0393: // */
0394: // private void replaceModel(FileObject oldFo, FileObject newFo) {
0395: // if (oldFo != null) {
0396: // destroy();
0397: // }
0398: //
0399: // if (newFo != null) {
0400: // associateModel(newFo);
0401: //// getDomSynchronizer().requestRefresh();
0402: // domProvider.requestRefresh();
0403: // }
0404: // }
0405:
0406: // static MultiViewElement getDesignerMultiViewElement(DataObject dataObject) {
0407: // WebForm webForm = getWebFormForDataObject(dataObject);
0408: // if (webForm == null) {
0409: // return null;
0410: // }
0411: // return webForm.getTopComponent();
0412: // }
0413:
0414: // /** Finds <code>WebForm</code> for provided <code>DesignContext</code>.
0415: // * XXX Get rid of this method. */
0416: // public static WebForm findWebFormForDesignContext(DesignContext designContext) {
0417: //// Collection col;
0418: //// synchronized (LOCK_WEB_FORMS) {
0419: //// col = webFormsByFileObject.values();
0420: //// }
0421: ////
0422: //// for (Iterator it = col.iterator(); it.hasNext(); ) {
0423: //// WebForm webform = (WebForm)it.next();
0424: //// // XXX LiveUnit is DesignContext.
0425: //// if ((DesignContext)webform.getModel().getLiveUnit() == designContext) {
0426: //// return webform;
0427: //// }
0428: //// }
0429: //// return null;
0430: //
0431: //// return getWebFormForDesigner(getDesignerFinder().findDesignerForDesignContext(designContext));
0432: //
0433: //// DomProvider domProvider = getDomProviderFinder().findDomProvider(designContext);
0434: //// if (domProvider == null) {
0435: //// return null;
0436: //// }
0437: //// synchronized (domProvider2webForm) {
0438: //// return domProvider2webForm.get(domProvider);
0439: //// }
0440: //
0441: // Designer[] designers = getDomProviderService().findDesignersForDesignContext(designContext);
0442: // if (designers.length > 0 && designers[0] instanceof WebForm) {
0443: // return (WebForm)designers[0];
0444: // } else {
0445: // return null;
0446: // }
0447: // }
0448:
0449: // public static WebForm[] findAllWebFormsForElement(Element element) {
0450: // Designer[] designers = getDomProviderService().findDesignersForElement(element);
0451: // List<WebForm> webForms = new ArrayList<WebForm>();
0452: // for (Designer designer : designers) {
0453: // if (designer instanceof WebForm) {
0454: // webForms.add((WebForm)designer);
0455: // }
0456: // }
0457: // return webForms.toArray(new WebForm[webForms.size()]);
0458: // }
0459:
0460: // public static WebForm findWebFormForElement(Element element) {
0461: // Designer[] designers = getDomProviderService().findDesignersForElement(element);
0462: // if (designers.length > 0 && designers[0] instanceof WebForm) {
0463: // return (WebForm)designers[0];
0464: // } else {
0465: // return null;
0466: // }
0467: // }
0468:
0469: // public static WebForm findWebFormForNode(org.openide.nodes.Node node) {
0470: // Designer[] designers = getDomProviderService().findDesignersForNode(node);
0471: // if (designers.length > 0 && designers[0] instanceof WebForm) {
0472: // return (WebForm)designers[0];
0473: // } else {
0474: // return null;
0475: // }
0476: // }
0477:
0478: // public static WebForm getWebFormForDataObject(DataObject jsfJspDataObject) {
0479: // Designer[] designers = getDomProviderService().getDesignersForDataObject(jsfJspDataObject);
0480: // if (designers.length > 0 && designers[0] instanceof WebForm) {
0481: // return (WebForm)designers[0];
0482: // } else {
0483: // return null;
0484: // }
0485: // }
0486:
0487: // public static WebForm findWebFormForFileObject(FileObject jsfJspFileObject) {
0488: //// synchronized (LOCK_WEB_FORMS) {
0489: //// WebForm webform = (WebForm)webFormsByFileObject.get(fo);
0490: ////
0491: //// return webform;
0492: //// }
0493: //
0494: //// return getWebFormForDesigner(getDesignerFinder().findDesignerForFileObject(fo));
0495: //
0496: //// DataObject dobj;
0497: //// try {
0498: //// dobj = DataObject.find(fo);
0499: //// } catch (DataObjectNotFoundException ex) {
0500: //// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
0501: //// return null;
0502: //// }
0503: ////
0504: //// DomProvider domProvider = getDomProviderFinder().findDomProvider(dobj);
0505: //// synchronized (domProvider2webForm) {
0506: //// return domProvider2webForm.get(domProvider);
0507: //// }
0508: //
0509: // Designer[] designers = getDomProviderService().findDesignersForFileObject(jsfJspFileObject);
0510: // if (designers.length > 0 && designers[0] instanceof WebForm) {
0511: // return (WebForm)designers[0];
0512: // } else {
0513: // return null;
0514: // }
0515: // }
0516:
0517: // // XXX This is very suspicious, but is just copies previous perf fixes.
0518: // // The FacesModel should fire events about being to be destroyed, and then
0519: // // this should be removed.
0520: // static void removeWebFormForFileObject(FileObject fo) {
0521: // synchronized (LOCK_WEB_FORMS) {
0522: // WebForm webform = (WebForm)webFormsByFileObject.get(fo);
0523: // webFormsByFileObject.remove(fo);
0524: //
0525: // if ((webform != null) && fo.isValid()) {
0526: // try {
0527: // DataObject dobj = DataObject.find(fo);
0528: // dobj.addPropertyChangeListener(webform.propertyListener);
0529: // webForms.remove(dobj);
0530: //
0531: //// // XXX Also JsfForm needs to be removed the same way.
0532: //// webform.destroyDomProvider(dobj);
0533: // } catch (DataObjectNotFoundException ex) {
0534: // ErrorManager.getDefault().notify(ex);
0535: // }
0536: // }
0537: //
0538: // // If fo.isValid() was false, or if the DataObject was not found,
0539: // // we'll leave the data object in the map. Not great... but it shouldn't
0540: // // cause any trouble since it's a weak map, and nobody should hold any
0541: // // references to it.
0542: // }
0543: // }
0544:
0545: public DomProvider getDomProvider() {
0546: return domProvider;
0547: }
0548:
0549: @Override
0550: public String toString() {
0551: // if (getMarkup() != null) {
0552: // return "WebForm[" + getMarkup().getFileObject().getNameExt() + "]";
0553: // }
0554: // return super.toString() + "[domProvider=" + domProvider + " ,selection=" + selection
0555: // + ", designerPane=" + designerPane + ", gridmode=" + isGridMode() + "]";
0556: return super .toString() + "[domProvider=" + domProvider + "]"; // NOI18N
0557: }
0558:
0559: // /** Look up a webform for a given model */
0560: // public static WebForm get(FacesModel model) {
0561: // if (model == null) {
0562: // return null;
0563: // }
0564: //
0565: // FileObject fo = model.getMarkupFile();
0566: // DataObject dobj = null;
0567: //
0568: // try {
0569: // dobj = DataObject.find(fo);
0570: // } catch (DataObjectNotFoundException ex) {
0571: // return null;
0572: // }
0573: //
0574: // return DesignerUtils.getWebForm(dobj);
0575: // }
0576:
0577: // private void init(FileObject fo) {
0578: // isFragment = "jspf".equals(fo.getExt()); // NOI18N
0579: //
0580: // FacesModel model = getModel();
0581: // if ((model != null) && (model.getFacesModelSet() != null)) {
0582: // isPortlet = model.getFacesModelSet().getFacesContainer().isPortletContainer();
0583: // }
0584: // }
0585:
0586: private static Map<Element, Map<WebForm, WeakReference<CssBox>>> element2webformMap = new WeakHashMap<Element, Map<WebForm, WeakReference<CssBox>>>(
0587: 500);
0588:
0589: public void setCssBoxForElement(Element element, CssBox box) {
0590: // XXX Copied from the original impl (in RaveElement).
0591: Node parent = element.getParentNode();
0592: if ((parent instanceof Element)
0593: && getCssBoxForElement((Element) parent) == box) {
0594: return; // Don't duplicate a bean reference on all the children!
0595: }
0596:
0597: // synchronized (element2cssBox) {
0598: // element2cssBox.put(element, box);
0599: // }
0600: // #106433 There needs to be 1:N mapping for element : box.
0601: // TODO Revise potential memory leak, boxes linked to the elements!
0602: // Map<WebForm, WeakReference<CssBox>> webform2box = (Map<WebForm, WeakReference<CssBox>>)element.getUserData(KEY_CSS_BOX_MAP);
0603: Map<WebForm, WeakReference<CssBox>> webform2box = element2webformMap
0604: .get(element);
0605: if (webform2box == null) {
0606: // #123003 Avoiding possible leak, the insync FacesModel
0607: // is not garbaged unless the project is closed.
0608: webform2box = new WeakHashMap<WebForm, WeakReference<CssBox>>();
0609: }
0610: webform2box.put(this , new WeakReference<CssBox>(box));
0611: // element.setUserData(KEY_CSS_BOX_MAP, webform2box, CssBoxDataHandler.getDefault());
0612: element2webformMap.put(element, webform2box);
0613: }
0614:
0615: public CssBox getCssBoxForElement(Element element) {
0616: // synchronized (element2cssBox) {
0617: // return element2cssBox.get(element);
0618: // }
0619: if (element == null) {
0620: return null;
0621: }
0622: // Map<WebForm, WeakReference<CssBox>> webform2box = (Map<WebForm, WeakReference<CssBox>>)element.getUserData(KEY_CSS_BOX_MAP);
0623: Map<WebForm, WeakReference<CssBox>> webform2box = element2webformMap
0624: .get(element);
0625: // return webform2box == null ? null : webform2box.get(this);
0626: WeakReference<CssBox> cssBoxWRef = webform2box == null ? null
0627: : webform2box.get(this );
0628: return cssBoxWRef == null ? null : cssBoxWRef.get();
0629: }
0630:
0631: // XXX Temporary, see DesignerService.copyBoxForElement.
0632: public void copyBoxForElement(Element fromElement, Element toElement) {
0633: CssBox box = getCssBoxForElement(fromElement);
0634: setCssBoxForElement(toElement, box);
0635: }
0636:
0637: /**
0638: * Locate the box that was created for the given element,
0639: * if any. May return null if the element has not been
0640: * rendered.
0641: */
0642: public CssBox findCssBoxForElement(Element element) {
0643: // RaveElement e = (RaveElement)element;
0644: // CssBox box = (CssBox)e.getBox();
0645: CssBox box = getCssBoxForElement(element);
0646:
0647: if (box != null) {
0648: // Work around the problem that children boxes when created may
0649: // overwrite the existing box reference in the element. I can't
0650: // simply at that point go and look to see if a reference already exists
0651: // and if so not point to my new box, since that would break
0652: // incremental layout etc. -- I create multiple generations of
0653: // boxes for each element, and in the box constructor I don't
0654: // know the parentage of the box yet.
0655: while ((box.getParent() != null)
0656: && (box.getParent().getElement() == element)) {
0657: box = box.getParent();
0658: }
0659:
0660: // e.setBox(box);
0661: setCssBoxForElement(element, box);
0662:
0663: return box;
0664: }
0665:
0666: return null;
0667: }
0668:
0669: // public FileObject getFile() {
0670: // return getModel().getMarkupFile();
0671: // }
0672:
0673: // public DataObject getDataObject() {
0674: //// FileObject file = getModel().getMarkupFile();
0675: ////
0676: //// try {
0677: //// return DataObject.find(file);
0678: //// } catch (DataObjectNotFoundException e) {
0679: //// return null;
0680: //// }
0681: // return getJspDataObject();
0682: // }
0683:
0684: // public DataObject getJspDataObject() {
0685: //// FileObject file = getModel().getMarkupFile();
0686: ////
0687: //// try {
0688: //// return DataObject.find(file);
0689: //// } catch (DataObjectNotFoundException dnfe) {
0690: //// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, dnfe);
0691: ////
0692: //// return null;
0693: //// }
0694: // return domProvider.getJspDataObject();
0695: // }
0696:
0697: // public DataObject getJavaDataObject() {
0698: // FileObject file = getModel().getJavaFile();
0699: //
0700: // try {
0701: // return DataObject.find(file);
0702: // } catch (DataObjectNotFoundException dnfe) {
0703: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, dnfe);
0704: //
0705: // return null;
0706: // }
0707: // }
0708:
0709: // /**
0710: // * Create the TopComponent for this webform, using the given
0711: // * editor support (may be null).
0712: // */
0713: // public void createTopComponent() {
0714: // //assert view == null;
0715: // view = new DesignerTopComp(this);
0716: // }
0717:
0718: // private void detachTopComponent() {
0719: // if (!isClosing && (view != null)) {
0720: // // Prevent recursion since detachTopComponent can be called via designer
0721: // // service from the data object editor support when it finds out that
0722: // // the buffer is being closed
0723: // isClosing = true;
0724: //
0725: // try {
0726: // boolean success = view.forceClose();
0727: // } finally {
0728: // isClosing = false;
0729: // }
0730: // }
0731: //
0732: // view = null;
0733: // document = null;
0734: //// css = null;
0735: //// mapper = null;
0736: // rendererPane = null;
0737: //
0738: // if (selection != null) {
0739: // selection.releaseNodes();
0740: // }
0741: //
0742: // selection = null;
0743: //
0744: //// // !EAT This should most likely go somewhere else
0745: //// if ((OutlineTopComp.getInstance() != null) &&
0746: //// (OutlineTopComp.getInstance().getWebForm() == this)) {
0747: //// OutlineTopComp.getInstance().setCurrent(null);
0748: //// }
0749: // }
0750:
0751: // /**
0752: // * Return the top component associated with the design view
0753: // */
0754: // public DesignerTopComp getTopComponent() {
0755: // if (view == null) {
0756: // view = new DesignerTopComp(this);
0757: // }
0758: //
0759: // return view;
0760: // }
0761:
0762: public DesignerPane getPane() {
0763: // return getTopComponent().getDesignerPane();
0764: return designerPane;
0765: }
0766:
0767: // public FacesModel getModel() {
0768: //// return model;
0769: // return domProvider.getFacesModel();
0770: // }
0771:
0772: public boolean hasSelection() {
0773: return selection != null;
0774: }
0775:
0776: public SelectionManager getSelection() {
0777: if (selection == null) {
0778: selection = new SelectionManager(this );
0779: }
0780:
0781: return selection;
0782: }
0783:
0784: // /**
0785: // * Get the document associated with this webform.
0786: // */
0787: // public Document getDocument() {
0788: // if (document == null) {
0789: // document = new Document(this);
0790: // }
0791: //
0792: // return document;
0793: // }
0794: //
0795: // public void setDocument(Document document) {
0796: // this.document = document;
0797: // }
0798: /**
0799: * Gets the DomDocument associated with this webform.
0800: */
0801: public DomDocument getDomDocument() {
0802: // return domDocument;
0803: return domProvider.getDomDocument();
0804: }
0805:
0806: // /**
0807: // * Get the document associated with this webform.
0808: // */
0809: // public org.w3c.dom.Document getJspDom() {
0810: //// <separation of models>
0811: //// MarkupUnit unit = model.getMarkupUnit();
0812: ////
0813: //// if (unit == null) { // possible when project has closed
0814: //// return null;
0815: //// }
0816: ////
0817: //// return (RaveDocument)unit.getDocument();
0818: //// ====
0819: //// return InSyncService.getProvider().getJspDomForMarkupFile(getModel().getMarkupFile());
0820: // return domProvider.getJspDom();
0821: //// </separation of models>
0822: // }
0823:
0824: public org.w3c.dom.Document getHtmlDom() {
0825: // return InSyncService.getProvider().getHtmlDomForMarkupFile(getModel().getMarkupFile());
0826: return domProvider.getHtmlDom();
0827: }
0828:
0829: // /**
0830: // * Return the HTML DOM associated with the source JSPX DOM
0831: // * returned by {@link getDom}.
0832: // * @return A DocumentFragment which represents an HTML rendered,
0833: // * JavaScript mutated, <f:verbatim>/<ui:tag> expanded
0834: // * view of the source DOM.
0835: // */
0836: // public DocumentFragment getHtmlDomFragment() {
0837: //// <separation of models>
0838: //// if (html == null) {
0839: //// // XXX TODO There is not needed webform here.
0840: //// FileObject markupFile = this.getModel().getMarkupFile();
0841: ////// html = FacesSupport.renderHtml(markupFile, null, !CssBox.noBoxPersistence);
0842: //// html = InSyncService.getProvider().renderHtml(markupFile, null, !CssBox.noBoxPersistence);
0843: //// // XXX FIXME Is this correct here?
0844: //// FacesSupport.updateErrorsInComponent(this);
0845: ////
0846: //// if (html != null) {
0847: //// // Is this a page fragment?
0848: //// if (isFragment || isPortlet) {
0849: //// // Just use the first element
0850: //// NodeList nl = html.getChildNodes();
0851: ////
0852: //// for (int i = 0, n = nl.getLength(); i < n; i++) {
0853: //// Node node = nl.item(i);
0854: ////
0855: //// if (node.getNodeType() == Node.ELEMENT_NODE) {
0856: //// body = (RaveElement)node;
0857: ////
0858: //// getDom().setRoot(body);
0859: ////
0860: //// break;
0861: //// }
0862: //// }
0863: ////
0864: //// WebForm page = getContextPage();
0865: ////
0866: //// if (page != null) {
0867: //// // XXX Force sync first??
0868: //// Element surroundingBody = page.getBody();
0869: ////
0870: //// if (surroundingBody != null) {
0871: //// RaveElement.setStyleParent(body, surroundingBody);
0872: ////
0873: //// // Make sure styles inherit right into the included content
0874: //// ((RaveDocument)getDom()).setCssEngine(page.getDom().getCssEngine());
0875: ////
0876: //// XhtmlCssEngine engine = CssLookup.getCssEngine(body);
0877: ////
0878: //// if (engine != null) {
0879: //// engine.clearTransientStyleSheetNodes();
0880: //// }
0881: //// }
0882: //// }
0883: //// } else {
0884: //// body = null;
0885: //// }
0886: ////
0887: //// if (body == null) {
0888: //// body = findBody(html);
0889: ////
0890: //// //if (body == null) {
0891: //// // // Insert one! Is this going to cause locking problems??? I
0892: //// // // need to do this under a write lock...
0893: //// //}
0894: //// NodeList nl = html.getChildNodes();
0895: ////
0896: //// for (int i = 0, n = nl.getLength(); i < n; i++) {
0897: //// Node node = nl.item(i);
0898: ////
0899: //// if (node.getNodeType() == Node.ELEMENT_NODE) {
0900: //// getDom().setRoot((RaveElement)node);
0901: ////
0902: //// break;
0903: //// }
0904: //// }
0905: //// }
0906: //// }
0907: //// }
0908: ////
0909: //// return html;
0910: //// ====
0911: //// DocumentFragment df = InSyncService.getProvider().getHtmlDomFragmentForMarkupFile(getModel().getMarkupFile());
0912: //// DocumentFragment df = InSyncService.getProvider().getHtmlDomFragmentForDocument(getHtmlDom());
0913: // DocumentFragment df = domProvider.getHtmlDocumentFragment();
0914: //
0915: // // XXX #6472138 This doesn't need to be here now, used only in the dump.
0916: //// // XXX FIXME Is this correct here?
0917: //// updateErrorsInComponent();
0918: //
0919: // return df;
0920: //// </separation of models>
0921: // }
0922:
0923: /**
0924: * Return the <body> element associated with the rendered HTML
0925: * document
0926: */
0927: public Element getHtmlBody() {
0928: // return getHtmlBody(true);
0929: return domProvider.getHtmlBody();
0930: }
0931:
0932: // // XXX Helper method, see DesignerTopComp#updateErrors.
0933: // Element getHtmlBody(boolean updateErrors) {
0934: //// <separation of models>
0935: //// if (body == null) {
0936: //// // XXX Initing by side effect.
0937: //// getHtmlDom(); // will set body too, if possible
0938: //// }
0939: ////
0940: //// return body;
0941: //// ====
0942: //// return InSyncService.getProvider().getHtmlBodyForMarkupFile(getModel().getMarkupFile());
0943: // Element bodyElement = domProvider.getHtmlBody();
0944: //
0945: // // XXX #6472138 FIXME Is this correct here?
0946: // if (updateErrors) {
0947: // updateErrorsInComponent();
0948: // }
0949: //
0950: // return bodyElement;
0951: //// </separation of models>
0952: // }
0953:
0954: // private static RaveElement findBody(Node node) {
0955: // Element body = Util.findDescendant(HtmlTag.BODY.name, node);
0956: //
0957: // if (body == null) {
0958: // body = Util.findDescendant(HtmlTag.FRAMESET.name, node);
0959: // }
0960: //
0961: // // TODO -- make sure body is lowercase tag. If not offer to tidy it!
0962: // return (RaveElement)body;
0963: // }
0964:
0965: // /**
0966: // * Clears the HTML DOM associated with the source JSPX DOM
0967: // * returned by {@link getDom}.
0968: // * @param html A DocumentFragment which represents a rendered
0969: // * view of the JSPX DOM.
0970: // */
0971: // public void clearHtml() {
0972: //// this.html = null;
0973: //// this.body = null; // force new search
0974: //// InSyncService.getProvider().clearHtmlForMarkupFile(getModel().getMarkupFile());
0975: // domProvider.clearHtml();
0976: // }
0977:
0978: // public MarkupUnit getMarkup() {
0979: // return getModel().getMarkupUnit();
0980: // }
0981:
0982: // XXX TODO Revise and provide safe solution.
0983: // boolean hasDomSynchronizer() {
0984: // return domSyncer != null;
0985: // }
0986: //
0987: // public DomSynchronizer getDomSynchronizer() {
0988: // if (domSyncer == null) {
0989: // domSyncer = new DomSynchronizer(this);
0990: // }
0991: //
0992: // return domSyncer;
0993: // }
0994:
0995: // /**
0996: // * Set whether or not grid mode is in effect
0997: // */
0998: // private void setGridMode(boolean on) {
0999: // gridMode = on;
1000: //
1001: // DesignerPane pane = getPane();
1002: //
1003: // if (pane != null) {
1004: // pane.setGridMode(on);
1005: // }
1006: //
1007: // // Gotta set the cursor to a pointer instead! How can I do
1008: // // this in a PLAF agnostic way?
1009: // }
1010: // private void updatePaneGrid(boolean gridMode) {
1011: public void setPaneGrid(boolean gridMode) {
1012: DesignerPane pane = getPane();
1013: if (pane != null) {
1014: pane.setGridMode(gridMode);
1015: }
1016: }
1017:
1018: /**
1019: * Return whether or not grid mode is in effect
1020: * @todo For increased readability, instead of !isGridMode() everywhere,
1021: * have an isFlowMode() method with reverse logic that I use instead.
1022: */
1023: public boolean isGridMode() {
1024: // return gridMode;
1025: return domProvider.isGridMode();
1026: }
1027:
1028: // // XXX Moved from document.
1029: // /**
1030: // * Return true if this document is in "grid mode" (objects
1031: // * should be positioned by absolute coordinates instead of in
1032: // * "flow" order.
1033: // *
1034: // * @return true iff the document should be in grid mode
1035: // */
1036: // public boolean isGridModeDocument() {
1037: // Element body = getHtmlBody();
1038: //
1039: // if (body == null) {
1040: // return false;
1041: // }
1042: //
1043: //// Value val = CssLookup.getValue(b, XhtmlCss.RAVELAYOUT_INDEX);
1044: // CssValue cssValue = CssProvider.getEngineService().getComputedValueForElement(body, XhtmlCss.RAVELAYOUT_INDEX);
1045: //
1046: //// return val == CssValueConstants.GRID_VALUE;
1047: // return CssProvider.getValueService().isGridValue(cssValue);
1048: // }
1049:
1050: // public boolean isBraveheartPage() {
1051: // return domProvider.isBraveheartPage();
1052: // }
1053:
1054: // public boolean isWoodstockPage() {
1055: // return domProvider.isWoodstockPage();
1056: // }
1057:
1058: // /**
1059: // * Return the mapper responsible for converting coordinates to
1060: // * and from the model.
1061: // * @return the mapper instance
1062: // */
1063: // public ModelViewMapper getMapper() {
1064: // if (mapper == null) {
1065: // mapper = new ModelViewMapper(this);
1066: // }
1067: //
1068: // return mapper;
1069: // }
1070:
1071: // <refactoring>
1072: // public CssLookup getCss() {
1073: // if (css == null) {
1074: // css = new CssLookup(this);
1075: // }
1076: //
1077: // return css;
1078: // }
1079: // </refactoring>
1080:
1081: // /**
1082: // * Return true iff this webform represents a fragment. Note - portlets are
1083: // * frequently fragments too so don't conclude from this method returning true
1084: // * that you are not dealing with a portlet!
1085: // */
1086: // public boolean isFragment() {
1087: //// return isFragment;
1088: // return domProvider.isFragment();
1089: // }
1090: //
1091: // /**
1092: // * Retru true iff this webform represents a portlet
1093: // */
1094: // public boolean isPortlet() {
1095: //// return isPortlet;
1096: // return domProvider.isPortlet();
1097: // }
1098:
1099: // /**
1100: // * Return the project associated with this webform
1101: // */
1102: // public Project getProject() {
1103: // return getModel().getProject();
1104: // }
1105:
1106: /** Return a cell renderer pane suitable for use with the designer.
1107: * Used to stamp out combo boxes etc. into offscreen buffers, since
1108: * they refuse to paint themselves properly if they are not parented
1109: * to a heavyweight component (e.g. JFrame). The CellRendererPane prevents
1110: * additions/removals from causing unnecessary traffic and recomputations
1111: * in other components.
1112: */
1113: public CellRendererPane getRenderPane() {
1114: return rendererPane;
1115: }
1116:
1117: // public void setRenderPane(CellRendererPane rendererPane) {
1118: // this.rendererPane = rendererPane;
1119: // }
1120:
1121: // /** Return the virtual forms support associated with this webform */
1122: // public VirtualFormSupport getVirtualFormSupport() {
1123: // if (virtualForms == null) {
1124: // virtualForms = new VirtualFormSupport(this);
1125: // }
1126: //
1127: // return virtualForms;
1128: // }
1129:
1130: // public void setVirtualFormsEnabled(boolean virtualFormsEnabled) {
1131: // this.virtualFormsEnabled = virtualFormsEnabled;
1132: // }
1133: //
1134: // public boolean isVirtualFormsEnabled() {
1135: // return virtualFormsEnabled;
1136: // }
1137:
1138: /**
1139: * Return the color manager for the webform which stores
1140: * color preferences and determines suitable colors for
1141: * glyphs and nibs painted on top of the webform
1142: */
1143: public ColorManager getColors() {
1144: if (colors == null) {
1145: colors = new ColorManager(this );
1146: }
1147:
1148: return colors;
1149: }
1150:
1151: // /**
1152: // * Return the action handler for the designer which implements
1153: // * various user-operations that can be performed on the webform
1154: // */
1155: // public DesignerActions getActions() {
1156: // if (actions == null) {
1157: // actions = new DesignerActions(this);
1158: // }
1159: //
1160: // return actions;
1161: // }
1162:
1163: // /** Return true iff the webform has rendering problems associated with it */
1164: // public boolean hasRenderingErrors() {
1165: //// return renderFailureComponent != null;
1166: //// return getRenderFailureComponent() != null;
1167: // return domProvider.hasRenderingErrors();
1168: // }
1169:
1170: // // XXX Very suspicious, revise it.
1171: // /** Sets render failed values about a failure in rendering it to HTML.
1172: // * @param component The component which failed to render
1173: // * @param exception The exception thrown by the component
1174: // */
1175: // private void setRenderFailedValues(MarkupDesignBean renderFailureComponent, Exception renderFailureException) {
1176: //// renderFailure = exception;
1177: //// renderFailureComponent = component;
1178: // domProvider.setRenderFailedValues(renderFailureComponent, renderFailureException);
1179: // }
1180:
1181: // private void setRenderFailureValues() {
1182: // domProvider.setRenderFailureValues();
1183: // }
1184: //
1185: // private boolean hasRenderFailure() {
1186: // return domProvider.hasRenderFailure();
1187: // }
1188:
1189: // /** Return the exception associated with the current render failure for this page */
1190: // public Exception getRenderFailure() {
1191: //// return renderFailure;
1192: // return domProvider.getRenderFailureException();
1193: // }
1194:
1195: // /** Return the component associated with the current render failure for this page */
1196: // public MarkupDesignBean getRenderFailureComponent() {
1197: //// return renderFailureComponent;
1198: // return domProvider.getRenderFailureComponent();
1199: // }
1200:
1201: // /** Return true iff the current render failure (returned by
1202: // * {@link #getRenderFailure} has been shown to the user yet
1203: // */
1204: // public boolean isRenderFailureShown() {
1205: //// return renderFailureShown;
1206: // return domProvider.isRenderFailureShown();
1207: // }
1208: //
1209: // /** Record whether the current render failure (returned by
1210: // * {@link #getRenderFailure} has been shown to the user yet
1211: // */
1212: // public void setRenderFailureShown(boolean renderFailureShown) {
1213: //// this.renderFailureShown = renderFailureShown;
1214: // domProvider.setRenderFailureShown(renderFailureShown);
1215: // }
1216:
1217: // XXX Moved to designer/jsf/../JsfForm.
1218: // /** XXX Moved from FacesSupport. Updates erros in the corresponding component.
1219: // * TODO Usage of this after renderHtml call is very suspicious, revise. */
1220: // public void updateErrorsInComponent() {
1221: //// FileObject markupFile = getModel().getMarkupFile();
1222: ////// <missing designtime api>
1223: ////// Exception renderFailure = facesunit.getRenderFailure();
1224: ////// MarkupDesignBean renderFailureComponent =
1225: ////// (MarkupDesignBean)facesunit.getRenderFailureComponent();
1226: ////// ====
1227: //// Exception renderFailure = InSyncService.getProvider().getRenderFailure(markupFile);
1228: //
1229: //// Exception renderFailure = domProvider.getRenderFailure();
1230: ////// MarkupDesignBean renderFailureComponent = (MarkupDesignBean)InSyncService.getProvider().getRenderFailureComponent(markupFile);
1231: //// MarkupDesignBean renderFailureComponent = domProvider.getRenderFailureMarkupDesignBean();
1232: ////
1233: ////// </missing designtime api>
1234: ////
1235: //// setRenderFailedValues(renderFailureComponent, renderFailure);
1236: // setRenderFailureValues();
1237: //
1238: //// if (renderFailure == null) {
1239: // if (!hasRenderFailure()) {
1240: // // Since we had a successful render now, we should remember this such
1241: // // that if a rendering error happens again, we will show the errorpanel
1242: // setRenderFailureShown(false);
1243: // }
1244: //
1245: // // XXX #6472138 Put into AWT.
1246: // updateComponentForErrors();
1247: // }
1248: //
1249: // private void updateComponentForErrors() {
1250: // if (EventQueue.isDispatchThread()) {
1251: // doUpdateComponentForErrors();
1252: // } else {
1253: // EventQueue.invokeLater(new Runnable() {
1254: // public void run() {
1255: // doUpdateComponentForErrors();
1256: // }
1257: // });
1258: // }
1259: // }
1260: //
1261: // private void doUpdateComponentForErrors() {
1262: //// if (getTopComponent().isShowing()) {
1263: //// // In case some kind of rendering error happened
1264: //// // Ugh... I need to track this differently!
1265: //// getTopComponent().updateErrors();
1266: //// }
1267: // domProvider.tcUpdateErrors(this);
1268: // }
1269:
1270: /**
1271: * Return the interaction manager which is responsible for
1272: * coordinating mouse and keyboard gestures with designer modes
1273: * and actions.
1274: */
1275: public InteractionManager getManager() {
1276: if (manager == null) {
1277: manager = new InteractionManager(this );
1278: }
1279:
1280: return manager;
1281: }
1282:
1283: // public GridHandler getGridHandler() {
1284: // if (gridHandler == null) {
1285: // gridHandler = new GridHandler(/*this*/);
1286: // }
1287: // return gridHandler;
1288: // }
1289:
1290: // XXX Moved to designer/jsf/../JsfForm.
1291: // /** Get the context page for this fragment. This method should only return non-null
1292: // * for page fragments. The context page is a page which provides a "style context" for
1293: // * the fragment. Typically, the page is one of the pages which includes the page fragment,
1294: // * but that's not strictly necessary. The key thing is that the page fragment will pick
1295: // * up stylesheets etc. defined in the head of the context page.
1296: // * @return A context page for the fragment
1297: // */
1298: // public WebForm getContextPage() {
1299: //// if (isFragment && (contextPage == null)) {
1300: // if (isFragment() && (contextPage == null)) {
1301: // // Find a page
1302: // Iterator it =
1303: //// DesignerService.getDefault().getWebPages(getProject(), true, false).iterator();
1304: //// InSyncService.getProvider().getWebPages(getProject(), true, false).iterator();
1305: // domProvider.getWebPageFileObjectsInThisProject().iterator();
1306: //
1307: // while (it.hasNext()) {
1308: // FileObject fo = (FileObject)it.next();
1309: //
1310: // try {
1311: // DataObject dobj = DataObject.find(fo);
1312: //
1313: // // XXX Very suspicious, how come that context page is any random page
1314: // // whitin project?? What actually the context page is good for?
1315: // // It seems it is a wrong architecture.
1316: // if (isWebFormDataObject(dobj)) {
1317: // contextPage = getWebFormForDataObject(dobj);
1318: //
1319: // break;
1320: // }
1321: // } catch (DataObjectNotFoundException dnfe) {
1322: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, dnfe);
1323: // }
1324: // }
1325: // }
1326: //
1327: // return contextPage;
1328: // }
1329:
1330: // XXX Moved to designer/jsf/../JsfForm.
1331: // /** Set the associated context page for this page fragment. (Only allowed on
1332: // * page fragments.)
1333: // * @see getContextPage()
1334: // */
1335: // public void setContextPage(WebForm contextPage) {
1336: //// assert isFragment;
1337: // assert isFragment();
1338: //
1339: // // XXX Context page notion from fragment should be removed.
1340: // if (this.contextPage != contextPage) {
1341: // // Force refresh such that the style links are recomputed
1342: // clearHtml();
1343: // }
1344: //
1345: // this.contextPage = contextPage;
1346: // }
1347:
1348: // // Tor: The name is up to you.
1349: // public void destroy() {
1350: // detachTopComponent();
1351: //
1352: //// if (domSyncer != null) {
1353: //// domSyncer.destroy();
1354: //// domSyncer = null;
1355: //// }
1356: // domProvider.destroyDomSynchronizer();
1357: //
1358: // if (colors != null) {
1359: // colors.resetPageBox();
1360: // colors = null;
1361: // }
1362: // }
1363:
1364: // XXX Moved from Document.
1365: /**
1366: * Return a cache of images for this document
1367: */
1368: public ImageCache getImageCache() {
1369: if (imageCache == null) {
1370: imageCache = new ImageCache();
1371: }
1372:
1373: return imageCache;
1374: }
1375:
1376: // // XXX Moved from Document.
1377: // /** Return a cache of webform boxes associated with this document
1378: // * @todo Rename; it's no longer a box cache but rather a document
1379: // * cache! */
1380: // public DocumentCache getFrameBoxCache() {
1381: // if (frameCache == null) {
1382: // frameCache = new DocumentCache();
1383: // }
1384: //
1385: // return frameCache;
1386: // }
1387:
1388: // XXX Moved from Document.
1389: /** Return true iff the document has cached frame boxes */
1390: public boolean hasCachedFrameBoxes() {
1391: // return (frameCache != null) && (frameCache.size() > 0);
1392: return domProvider.hasCachedExternalFrames();
1393: }
1394:
1395: // XXX Moved from Document.
1396: /** Clear out caches for a "refresh" operation */
1397: private void flushCaches() {
1398: // XXX Moved to designer/jsf/../JsfForm.
1399: // if (frameCache != null) {
1400: // frameCache.flush();
1401: // }
1402:
1403: if (imageCache != null) {
1404: imageCache.flush();
1405: }
1406: }
1407:
1408: // //////
1409: // // XXX See Designer interface.
1410: // public void modelChanged() {
1411: // getPane().getPaneUI().resetPageBox();
1412: // }
1413:
1414: // public void nodeChanged(Node rendered, Node parent, boolean wasMove) {
1415: public void changeNode(Node rendered, Node parent,
1416: Element[] changedElements) {
1417: PageBox pageBox = getPane().getPaneUI().getPageBox();
1418: if (pageBox == null) {
1419: // XXX #125713 Potential NPE.
1420: return;
1421: }
1422: pageBox.changed(rendered, parent, changedElements);
1423: }
1424:
1425: // public void nodeRemoved(Node previouslyRendered, Node parent) {
1426: public void removeNode(Node previouslyRendered, Node parent) {
1427: PageBox pageBox = getPane().getPaneUI().getPageBox();
1428: if (pageBox == null) {
1429: // XXX #125713 Potential NPE.
1430: return;
1431: }
1432: pageBox.removed(previouslyRendered, parent);
1433: }
1434:
1435: // public void nodeInserted(Node rendered, Node parent) {
1436: public void insertNode(Node rendered, Node parent) {
1437: PageBox pageBox = getPane().getPaneUI().getPageBox();
1438: if (pageBox == null) {
1439: // XXX #125713 Potential NPE.
1440: return;
1441: }
1442: pageBox.inserted(rendered, parent);
1443: }
1444:
1445: // public void updateGridMode() {
1446: //// setGridMode(getDocument().isGridMode()); // XXX
1447: //// setGridMode(isGridModeDocument());
1448: // // XXX
1449: // updatePaneGrid(domProvider.isGridMode());
1450: // }
1451:
1452: // public void documentReplaced() {
1453: public void detachDomDocument() {
1454: // Ensure that the caret is in the new DOM
1455: DesignerPane pane = getPane();
1456:
1457: if (pane != null) {
1458: // if (pane.getCaret() != null) {
1459: // pane.getCaret().detachDom();
1460: if (pane.hasCaret()) {
1461: pane.caretDetachDom();
1462:
1463: //pane.setCaret(null);
1464: }
1465: // pane.showCaretAtBeginning();
1466: }
1467: }
1468:
1469: // XXX
1470: //////
1471:
1472: // /** XXX Temporary only until all modification stuff is moved from designer to designer/jsf. */
1473: // public void setUpdatesSuspended(MarkupDesignBean markupDesignBean, boolean suspend) {
1474: // domProvider.setUpdatesSuspended(markupDesignBean, suspend);
1475: // }
1476:
1477: // public void setUpdatesSuspended(Element componentRootElement, boolean suspend) {
1478: // domProvider.setUpdatesSuspended(componentRootElement, suspend);
1479: // }
1480:
1481: // public boolean isRefreshPending() {
1482: // return domProvider.isRefreshPending();
1483: // }
1484:
1485: //// public void attachContext(DesignContext context) {
1486: //// domProvider.attachContext(context);
1487: // public void attachContext() {
1488: // domProvider.attachContext();
1489: // }
1490:
1491: // public void detachContext() {
1492: // domProvider.detachContext();
1493: // }
1494:
1495: // public DocumentFragment createSourceFragment(MarkupDesignBean bean) {
1496: // return domProvider.createSourceFragment(bean);
1497: // }
1498:
1499: // public void requestChange(MarkupDesignBean bean) {
1500: // domProvider.requestChange(bean);
1501: // }
1502:
1503: // public void beanChanged(MarkupDesignBean bean) {
1504: // domProvider.beanChanged(bean);
1505: // }
1506:
1507: // public void requestTextUpdate(MarkupDesignBean bean) {
1508: // domProvider.requestTextUpdate(bean);
1509: // }
1510:
1511: // ////// Moved form DesignerActions
1512: // // XXX Refreshing. Get rid of it, it represents an arch flaw.
1513: // /** Refresh the document
1514: // * @deep If true, go all the way down to the insync markup unit
1515: // * and force a sync at that level, then invalidate all the page
1516: // * and image caches etc. If false, only flush the designer
1517: // * portion: the layout tree, the rendered html sections from
1518: // * markup, and the style, fragment and image caches.
1519: // */
1520: // public void refresh(boolean deep) {
1521: // getManager().finishInlineEditing(false);
1522: //
1523: //// // >>> Insync part
1524: //// if (deep) {
1525: //// MarkupUnit unit = getMarkup();
1526: ////
1527: //// if (unit.getState() == Unit.State.MODELDIRTY) {
1528: //// getModel().flush();
1529: //// }
1530: ////
1531: //// if (unit.getState() == Unit.State.CLEAN) {
1532: //// unit.setSourceDirty();
1533: //// }
1534: ////
1535: //// if (unit.getState() == Unit.State.SOURCEDIRTY) {
1536: //// getModel().sync();
1537: //// }
1538: //// }
1539: ////
1540: ////// CssLookup.refreshEffectiveStyles(webform.getDom());
1541: //// CssProvider.getEngineService().refreshStylesForDocument(getJspDom());
1542: //// // XXX Should this be here too (or the above?).
1543: //// CssProvider.getEngineService().refreshStylesForDocument(getHtmlDom());
1544: ////
1545: //// // XXX
1546: ////// StyleSheetCache.getInstance().flush();
1547: //// CssProvider.getEngineService().flushStyleSheetCache();
1548: //// clearHtml();
1549: //// // <<< Insync part.
1550: // getModel().refresh(deep);
1551: //
1552: //
1553: // getDocument().flushCaches();
1554: //
1555: // DesignerPane pane = getPane();
1556: //
1557: // if (pane != null) {
1558: // // PageBox pageBox = pane.getPageBox();
1559: // //
1560: // // if (pageBox != null) {
1561: // // pageBox.redoLayout(pane.isShowing());
1562: // // }
1563: // //
1564: // pane.getPaneUI().resetPageBox();
1565: // }
1566: //
1567: // getSelection().updateSelection(); // trigger refresh in CSS viewer for example
1568: //
1569: // if (pane != null) {
1570: // pane.repaint();
1571: // }
1572: // }
1573: // public void refreshProject() {
1574: // domProvider.refreshProject();
1575: // }
1576:
1577: // public void refreshModel(final boolean deep) {
1578: // // #6483029 Refresh contained external forms (e.g. fragments) first.
1579: // refreshExternalForms(deep);
1580: //
1581: // domProvider.refreshModel(deep);
1582: // }
1583: //
1584: // private void refreshExternalForms(boolean deep) {
1585: // DesignerPane designerPane = getPane();
1586: // if (designerPane == null) {
1587: // // XXX #6495248 This is not opened yet, so not initialized yet.
1588: // // TODO The external forms may not be stored in ui components (boxes),
1589: // // they need to be findable from the model directly.
1590: // return;
1591: // }
1592: //
1593: // PageBox pageBox = designerPane.getPageBox();
1594: // if (pageBox == null) {
1595: // return;
1596: // }
1597: // WebForm[] externalForms = pageBox.findExternalForms();
1598: // for (WebForm externalForm : externalForms) {
1599: // if (this == externalForm) {
1600: // // XXX To prevent neverending loop if there is such case.
1601: // continue;
1602: // }
1603: // externalForm.refreshModel(deep);
1604: // }
1605: // }
1606:
1607: public DomProvider[] getExternalDomProviders() {
1608: DesignerPane designerPane = getPane();
1609: if (designerPane == null) {
1610: // XXX #6495248 This is not opened yet, so not initialized yet.
1611: // TODO The external forms may not be stored in ui components (boxes),
1612: // they need to be findable from the model directly.
1613: return new DomProvider[0];
1614: }
1615:
1616: PageBox pageBox = designerPane.getPageBox();
1617: if (pageBox == null) {
1618: return new DomProvider[0];
1619: }
1620: WebForm[] externalForms = pageBox.findExternalForms();
1621:
1622: List<DomProvider> domProviders = new ArrayList<DomProvider>();
1623: for (WebForm externalForm : externalForms) {
1624: if (externalForm == null || externalForm == this ) {
1625: continue;
1626: }
1627: domProviders.add(externalForm.domProvider);
1628: }
1629: return domProviders
1630: .toArray(new DomProvider[domProviders.size()]);
1631: }
1632:
1633: // private void modelRefreshed() {
1634: public void resetAll() {
1635: getManager().finishInlineEditing(false);
1636:
1637: flushCaches();
1638:
1639: final DesignerPane pane = getPane();
1640:
1641: // #106167 This seems to be redundant here (see designer/jsf/../DomSynchronizer#processRefresh,
1642: // and /../JsfTopComponent#modelChanged.
1643: // if (pane != null) {
1644: // // PageBox pageBox = pane.getPageBox();
1645: // //
1646: // // if (pageBox != null) {
1647: // // pageBox.redoLayout(pane.isShowing());
1648: // // }
1649: // //
1650: // pane.getPaneUI().resetPageBox();
1651: // }
1652:
1653: // XXX #106332 Bad architecture, there were changed beans instanes in the hierarchy,
1654: // and at this moment the rendered doc is not regenerated.
1655: EventQueue.invokeLater(new Runnable() {
1656: public void run() {
1657: // getSelection().updateSelection(); // trigger refresh in CSS viewer for example
1658: getSelection().updateNodes();
1659:
1660: if (pane != null) {
1661: pane.repaint();
1662: }
1663: }
1664: });
1665: }
1666:
1667: // /** Refresh all forms in the project */
1668: // public static void refreshProject(Project project, boolean deep) {
1669: // FileObject fobj = JsfProjectUtils.getDocumentRoot(project);
1670: // refreshFolder(fobj, deep);
1671: // }
1672: //
1673: // /** Refresh the given DataObject, if it's a webform */
1674: // public static void refreshDataObject(DataObject dobj, boolean deep) {
1675: // if (hasWebFormForDataObject(dobj)) {
1676: //// WebForm webform = WebForm.getWebFormForDataObject(WebForm.findDomProvider(dobj), dobj);
1677: //// webform.getActions().refresh(deep);
1678: //// WebForm webform = WebForm.findWebForm(dobj);
1679: // // XXX Really get, not find only? Revise.
1680: // WebForm webform = getWebFormForDataObject(dobj);
1681: // if (webform != null) {
1682: //// webform.refresh(deep);
1683: // webform.refreshModel(deep);
1684: // }
1685: // }
1686: // }
1687: //
1688: // private static void refreshFolder(FileObject folder, boolean deep) {
1689: // FileObject[] children = folder.getChildren();
1690: //
1691: // for (int i = 0; i < children.length; i++) {
1692: // FileObject fo = children[i];
1693: //
1694: // if (fo.isFolder()) {
1695: // refreshFolder(fo, deep);
1696: // } else {
1697: // try {
1698: // DataObject dobj = DataObject.find(fo);
1699: //// refresh(dobj, deep);
1700: // refreshDataObject(dobj, deep);
1701: // } catch (DataObjectNotFoundException dnfe) {
1702: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, dnfe);
1703: // }
1704: // }
1705: // }
1706: // }
1707: // XXX
1708: //////
1709:
1710: //////
1711: // XXX Temporary, see Designer interface
1712: // public void contextActivated(DesignContext designContext) {
1713: // if (view != null) {
1714: // view.contextActivated(designContext);
1715: // }
1716: // }
1717:
1718: // public void contextDeactivated(DesignContext designContext) {
1719: // if (view != null) {
1720: // view.contextDeactivated(designContext);
1721: // }
1722: // }
1723:
1724: //// public void contextChanged(DesignContext designContext) {
1725: // private void designContextGenerationChanged() {
1726: //// if (view != null) {
1727: //// view.designContextGenerationChanged();
1728: //// }
1729: // domProvider.tcDesignContextGenerationChanged(this);
1730: // }
1731:
1732: // public void beanCreated(DesignBean designBean) {
1733: // if (view != null) {
1734: // view.beanCreated(designBean);
1735: // }
1736: // }
1737:
1738: // public void beanDeleted(DesignBean designBean) {
1739: // if (view != null) {
1740: // view.beanDeleted(designBean);
1741: // }
1742: // }
1743:
1744: // public void beanMoved(DesignBean designBean, DesignBean designBean0, Position position) {
1745: // if (view != null) {
1746: // view.beanMoved(designBean, designBean0, position);
1747: // }
1748: // }
1749:
1750: // public void beanContextActivated(DesignBean designBean) {
1751: // if (view != null) {
1752: // view.beanContextActivated(designBean);
1753: // }
1754: // }
1755:
1756: // public void beanContextDeactivated(DesignBean designBean) {
1757: // if (view != null) {
1758: // view.beanContextDeactivated(designBean);
1759: // }
1760: // }
1761:
1762: // public void instanceNameChanged(DesignBean designBean, String string) {
1763: // if (view != null) {
1764: // view.instanceNameChanged(designBean, string);
1765: // }
1766: // }
1767:
1768: // public void beanChanged(DesignBean designBean) {
1769: // if (view != null) {
1770: // view.beanChanged(designBean);
1771: // }
1772: // }
1773:
1774: // public void propertyChanged(DesignProperty designProperty, Object object) {
1775: // if (view != null) {
1776: // view.propertyChanged(designProperty, object);
1777: // }
1778: // }
1779:
1780: // public void eventChanged(DesignEvent designEvent) {
1781: // if (view != null) {
1782: // view.eventChanged(designEvent);
1783: // }
1784: // }
1785: // XXX
1786: //////
1787:
1788: // >>> DnD
1789: // DataFlavor getImportFlavor(DataFlavor[] flavors) {
1790: // return domProvider.getImportFlavor(flavors);
1791: // }
1792:
1793: boolean canImport(JComponent comp, DataFlavor[] transferFlavors,
1794: Transferable transferable) {
1795: return domProvider.canImport(comp, transferFlavors,
1796: transferable);
1797: }
1798:
1799: // DesignBean[] pasteBeans(Transferable t, DesignBean parent, MarkupPosition pos, Point location, DomProvider.CoordinateTranslator coordinateTranslator) {
1800: // return domProvider.pasteBeans(t, parent, pos, location, coordinateTranslator);
1801: // }
1802: // Element[] pasteComponents(Transferable t, Element parentComponentRootElement, Point location) {
1803: // return domProvider.pasteComponents(t, parentComponentRootElement, location);
1804: // }
1805:
1806: // void importData(JComponent comp, Transferable t, Object transferData, Dimension dimension, DomProvider.Location location, DomProvider.CoordinateTranslator coordinateTranslator, int dropAction) {
1807: // domProvider.importData(comp, t, transferData, dimension, location, coordinateTranslator, dropAction);
1808: // }
1809:
1810: // void importString(String string, DomProvider.Location location, DomProvider.CoordinateTranslator coordinateTranslator) {
1811: // domProvider.importString(string, location, coordinateTranslator);
1812: // }
1813:
1814: // public DesignBean findHtmlContainer(DesignBean parent) {
1815: // return domProvider.findHtmlContainer(parent);
1816: // }
1817:
1818: // String[] getClassNames(DisplayItem[] displayItems) {
1819: // return domProvider.getClassNames(displayItems);
1820: // }
1821:
1822: // boolean importBean(DisplayItem[] items, DesignBean origParent, int nodePos, String facet, List createdBeans, DomProvider.Location location, DomProvider.CoordinateTranslator coordinateTranslator)
1823: // throws IOException {
1824: // return domProvider.importBean(items, origParent, nodePos, facet, createdBeans, location, coordinateTranslator);
1825: // }
1826:
1827: // MarkupPosition getDefaultMarkupPositionUnderParent(DesignBean parent) {
1828: // return domProvider.getDefaultPositionUnderParent(parent);
1829: // }
1830:
1831: // int computeActions(DesignBean droppee, Transferable transferable, boolean searchUp, int nodePos) {
1832: // return domProvider.computeActions(droppee, transferable, searchUp, nodePos);
1833: // }
1834: int computeActions(Element dropeeComponentRootElement,
1835: Transferable transferable) {
1836: return domProvider.computeActions(dropeeComponentRootElement,
1837: transferable);
1838: }
1839:
1840: // DesignBean findParent(String className, DesignBean droppee, Node parentNode, boolean searchUp) {
1841: // return domProvider.findParent(className, droppee, parentNode, searchUp);
1842: // }
1843:
1844: // int processLinks(Element origElement, Class[] classes, List beans, boolean selectFirst, boolean handleLinks, boolean showLinkTarget) {
1845: int processLinks(Element origElement, Element componentRootElement) {
1846: return domProvider.processLinks(origElement,
1847: componentRootElement);
1848: }
1849:
1850: // <<< DnD
1851:
1852: // >>> DnD callbacks
1853: public void showDropMatch(Element componentRootElement,
1854: Element regionElement, int dropType) {
1855: getPane().getDndHandler().showDropMatch(componentRootElement,
1856: regionElement, dropType);
1857: }
1858:
1859: public void clearDropMatch() {
1860: getPane().getDndHandler().clearDropMatch();
1861: }
1862:
1863: // /*public*/private void select(final /*DesignBean designBean*/Element componentRootElement) {
1864: public void selectComponentDelayed(
1865: final/*DesignBean designBean*/Element componentRootElement) {
1866: // getSelection().selectBean(designBean);
1867: // if (designBean instanceof MarkupDesignBean) {
1868: if (componentRootElement != null) {
1869: // XXX Bad arch. Events are fired too early, no rendered tree was created yet.
1870: // Scheduling later to by pass the issue (of retrieving the component root element).
1871: EventQueue.invokeLater(new Runnable() {
1872: public void run() {
1873: // getSelection().selectBean(
1874: // WebForm.getDomProviderService().getComponentRootElementForMarkupDesignBean((MarkupDesignBean)designBean));
1875: getSelection().selectBean(componentRootElement);
1876: }
1877: });
1878: }
1879: // #6338212 Do not request unnecessary activation.
1880: // getTopComponent().requestActive();
1881: }
1882:
1883: // public void refreshForm(boolean deep) {
1884: // refresh(deep);
1885: // }
1886:
1887: // /*public*/private void inlineEdit(/*DesignBean[] designBeans*/Element[] componentRootElements) {
1888: public void inlineEditComponents(Element[] componentRootElements) {
1889: // List<Element> componentRootElements = new ArrayList<Element>();
1890: // for (DesignBean designBean : designBeans) {
1891: // if (designBean instanceof MarkupDesignBean) {
1892: // Element componentRootElement = WebForm.getDomProviderService().getComponentRootElementForMarkupDesignBean((MarkupDesignBean)designBean);
1893: // if (componentRootElement != null) {
1894: // componentRootElements.add(componentRootElement);
1895: // }
1896: // }
1897: // }
1898: // getManager().inlineEdit(componentRootElements.toArray(new Element[componentRootElements.size()]));
1899: getManager().inlineEdit(componentRootElements);
1900: // XXX #6484250 To activate the window after drop.
1901: // getTopComponent().requestActive();
1902: // tcRequestActive();
1903: }
1904:
1905: // <<< DnD callbacks
1906:
1907: // private void destroyDomProvider(DataObject dobj) {
1908: // domProvider.removeForDataObject(dobj);
1909: // }
1910:
1911: // public void destroyDesigner() {
1912: // destroy();
1913: // }
1914:
1915: // public void registerListeners() {
1916: //// domProviderListener = new DomProviderListener(this);
1917: //// domProvider.addDomProviderListener((DomProvider.DomProviderListener)WeakListeners.create(
1918: //// DomProvider.DomProviderListener.class, domProviderListener, domProvider));
1919: //
1920: //// // XXX FIXME There are more calls then needed. This is a hack to avoid multiple registering.
1921: //// domProvider.removeDomProviderListener(domProviderListener);
1922: //// domProvider.addDomProviderListener(domProviderListener);
1923: //
1924: // DataObject jspDataObject = getJspDataObject();
1925: // if (jspDataObject != null) {
1926: // jspDataObjectListener = new JspDataObjectListener(this);
1927: // jspDataObject.addPropertyChangeListener(WeakListeners.propertyChange(jspDataObjectListener, jspDataObject));
1928: // }
1929: // }
1930: //
1931: // public void unregisterListeners() {
1932: //// // XXX Or don't use weak listener, and remove it explicitely.
1933: ////// domProviderListener = null;
1934: //// domProvider.removeDomProviderListener(domProviderListener);
1935: //
1936: // jspDataObjectListener = null;
1937: // }
1938:
1939: public URL getBaseUrl() {
1940: return domProvider.getBaseUrl();
1941: }
1942:
1943: public URL resolveUrl(String urlString) {
1944: return domProvider.resolveUrl(urlString);
1945: }
1946:
1947: // public DocumentFragment renderHtmlForMarkupDesignBean(MarkupDesignBean markupDesignBean) {
1948: // return domProvider.renderHtmlForMarkupDesignBean(markupDesignBean);
1949: // }
1950:
1951: public PaletteController getPaletteController() {
1952: return domProvider.getPaletteController();
1953: }
1954:
1955: // // XXX
1956: //// boolean editEventHandlerForDesignBean(DesignBean designBean) {
1957: //// return domProvider.editEventHandlerForDesignBean(designBean);
1958: //// }
1959: // boolean editEventHandlerForComponent(Element componentRootElement) {
1960: // return domProvider.editEventHandlerForComponent(componentRootElement);
1961: // }
1962:
1963: // >>> Designer impl
1964: // public JComponent getDesignerComponent() {
1965: // return getTopComponent();
1966: // }
1967:
1968: // XXX Temp after moved TopComponent impl out >>>
1969: // public JComponent getVisualRepresentation() {
1970: // return getTopComponent().getVisualRepresentation();
1971: // }
1972:
1973: // public JComponent getToolbarRepresentation() {
1974: // return getTopComponent().getToolbarRepresentation();
1975: // }
1976:
1977: // public Action[] getActions() {
1978: // return getTopComponent().getActions();
1979: // }
1980:
1981: // public Lookup getLookup() {
1982: // return getTopComponent().getLookup();
1983: // }
1984:
1985: // public void componentOpened() {
1986: // getTopComponent().componentOpened();
1987: // }
1988:
1989: // public void componentClosed() {
1990: // getTopComponent().componentClosed();
1991: // }
1992:
1993: // public void componentShowing() {
1994: // getTopComponent().componentShowing();
1995: // }
1996:
1997: // public void componentHidden() {
1998: // getTopComponent().componentHidden();
1999: // }
2000:
2001: // public void componentActivated() {
2002: // getTopComponent().componentActivated();
2003: // }
2004:
2005: // public void componentDeactivated() {
2006: // getTopComponent().componentDeactivated();
2007: // }
2008:
2009: // public UndoRedo getUndoRedo() {
2010: // return getTopComponent().getUndoRedo();
2011: // }
2012:
2013: // public void setMultiViewCallback(MultiViewElementCallback multiViewElementCallback) {
2014: // getTopComponent().setMultiViewCallback(multiViewElementCallback);
2015: // }
2016:
2017: // public CloseOperationState canCloseElement() {
2018: // return getTopComponent().canCloseElement();
2019: // }
2020:
2021: // XXX Temp after moved TopComponent impl out <<<
2022: // <<< Designer impl.
2023:
2024: // boolean canDropDesignBeansAtNode(DesignBean[] designBeans, Node node) {
2025: // return domProvider.canDropDesignBeansAtNode(designBeans, node);
2026: // }
2027: boolean canDropComponentsAtNode(Element[] componentRootElements,
2028: Node node) {
2029: return domProvider.canDropComponentsAtNode(
2030: componentRootElements, node);
2031: }
2032:
2033: // boolean handleMouseClickForElement(Element element, int clickCount) {
2034: // return domProvider.handleMouseClickForElement(element, clickCount);
2035: // }
2036:
2037: // // XXX, Also better name needed.
2038: //// boolean isNormalAndHasFacesBean(MarkupDesignBean markupDesignBean) {
2039: //// return domProvider.isNormalAndHasFacesBean(markupDesignBean);
2040: //// }
2041: // boolean isNormalAndHasFacesComponent(Element componentRootElement) {
2042: // return domProvider.isNormalAndHasFacesComponent(componentRootElement);
2043: // }
2044:
2045: // boolean canHighlightMarkupDesignBean(MarkupDesignBean markupDesignBean) {
2046: // return domProvider.canHighlightMarkupDesignBean(markupDesignBean);
2047: // }
2048:
2049: // public DesignBean createBean(String className, Node parent, Node before) {
2050: // return domProvider.createBean(className, parent, before);
2051: // }
2052: // public Element createComponent(String className, Node parent, Node before) {
2053: // return domProvider.createComponent(className, parent, before);
2054: // }
2055:
2056: // public boolean isFormBean(DesignBean designBean) {
2057: // return domProvider.isFormBean(designBean);
2058: // }
2059:
2060: // public Element getDefaultParentMarkupBeanElement() {
2061: // return domProvider.getDefaultParentMarkupBeanElement();
2062: // }
2063:
2064: // public boolean moveBean(DesignBean bean, Node parentNode, Node before) {
2065: // return domProvider.moveBean(bean, parentNode, before);
2066: // }
2067: public boolean moveComponent(Element componentRootElement,
2068: Node parentNode, Node before) {
2069: return domProvider.moveComponent(componentRootElement,
2070: parentNode, before);
2071: }
2072:
2073: // boolean setPrerenderedBean(MarkupDesignBean markupDesignBean, DocumentFragment documentFragment) {
2074: // return domProvider.setPrerenderedBean(markupDesignBean, documentFragment);
2075: // }
2076:
2077: // MarkupDesignBean getMarkupDesignBeanEquivalentTo(MarkupDesignBean oldBean) {
2078: // return domProvider.getMarkupDesignBeanEquivalentTo(oldBean);
2079: // }
2080:
2081: // org.openide.nodes.Node getRootBeanNode() {
2082: // return domProvider.getRootBeanNode();
2083: // }
2084:
2085: // public void deleteBean(DesignBean designBean) {
2086: // domProvider.deleteBean(designBean);
2087: // }
2088: // public void deleteComponent(Element componentRootElement) {
2089: // domProvider.deleteComponent(componentRootElement);
2090: // }
2091:
2092: // boolean canCreateBean(String className, DesignBean parent, Position pos) {
2093: // return domProvider.canCreateBean(className, parent, pos);
2094: // }
2095:
2096: // DesignBean getDefaultParentBean() {
2097: // return domProvider.getDefaultParentBean();
2098: // }
2099: // public Element getDefaultParentComponent() {
2100: // return domProvider.getDefaultParentComponent();
2101: // }
2102:
2103: // JComponent getErrorPanel() {
2104: // DomProvider.ErrorPanel errorPanel = domProvider.getErrorPanel(new ErrorPanelCallbackImpl(this));
2105: // if (errorPanel instanceof JComponent) {
2106: // return (JComponent)errorPanel;
2107: // } else {
2108: // ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
2109: // new IllegalStateException("The provided error panel is not of JComponent type, errorPanel=" + errorPanel)); // NOI18N
2110: // return null;
2111: // }
2112: // }
2113:
2114: // public void syncModel() {
2115: // domProvider.syncModel();
2116: // }
2117:
2118: // boolean isSourceDirty() {
2119: // return domProvider.isSourceDirty();
2120: // }
2121:
2122: // Transferable copyBeans(DesignBean[] beans) {
2123: // return domProvider.copyBeans(beans);
2124: // }
2125: // Transferable copyComponents(Element[] componentRootElements) {
2126: // return domProvider.copyComponents(componentRootElements);
2127: // }
2128:
2129: // public DomProvider.WriteLock writeLock(String message) {
2130: // return domProvider.writeLock(message);
2131: // }
2132: //
2133: // public void writeUnlock(DomProvider.WriteLock writeLock) {
2134: // domProvider.writeUnlock(writeLock);
2135: // }
2136:
2137: // public boolean isModelValid() {
2138: // return domProvider.isModelValid();
2139: // }
2140:
2141: // XXX There should be no locking here, the designer is not thread safe (it should run in AWT thread only).
2142: // void readLock() {
2143: // domProvider.readLock();
2144: // }
2145: //
2146: // void readUnlock() {
2147: // domProvider.readUnlock();
2148: // }
2149:
2150: // void setModelActivated(boolean activated) {
2151: // domProvider.setModelActivated(activated);
2152: // }
2153:
2154: // UndoRedo getUndoManager() {
2155: // return domProvider.getUndoManager();
2156: // }
2157:
2158: // public boolean isModelBusted() {
2159: // return domProvider.isModelBusted();
2160: // }
2161:
2162: // DesignBean[] getBeansOfType(Class clazz) {
2163: // return domProvider.getBeansOfType(clazz);
2164: // }
2165:
2166: // Project getProject() {
2167: // return domProvider.getProject();
2168: // }
2169:
2170: // boolean isWriteLocked() {
2171: // return domProvider.isWriteLocked();
2172: // }
2173:
2174: // Class getBeanClass(String className) throws ClassNotFoundException {
2175: // return domProvider.getBeanClass(className);
2176: // }
2177:
2178: // public boolean isPage() {
2179: // return domProvider.isPage();
2180: // }
2181:
2182: // public boolean isAlive() {
2183: // return domProvider.isAlive();
2184: // }
2185:
2186: // String getImageComponentClassName() {
2187: // return domProvider.getImageComponentClassName();
2188: // }
2189:
2190: // void paintVirtualForms(Graphics2D g,DomProvider.RenderContext renderContext) {
2191: // domProvider.paintVirtualForms(g, renderContext);
2192: // }
2193:
2194: public boolean isFormComponent(Element componentRootElement) {
2195: return domProvider.isFormComponent(componentRootElement);
2196: }
2197:
2198: int getDropType(
2199: /*DesignBean origDroppee,*/Element origDropeeComponentRootElement,
2200: Element droppeeElement, Transferable t, boolean linkOnly) {
2201: return domProvider.getDropType(
2202: /*origDroppee,*/origDropeeComponentRootElement,
2203: droppeeElement, t, linkOnly);
2204: }
2205:
2206: // int getDropTypeForClassNames(DesignBean origDroppee, Element droppeeElement, String[] classNames, DesignBean[] beans, boolean linkOnly) {
2207: // return domProvider.getDropTypeForClassNames(origDroppee, droppeeElement, classNames, beans, linkOnly);
2208: // }
2209: int getDropTypeForComponent(
2210: /*DesignBean origDroppee,*/Element origDropeeComponentRootElement,
2211: Element droppeeElement, Element componentRootElement,
2212: boolean linkOnly) {
2213: return domProvider.getDropTypeForComponent(
2214: /*origDroppee,*/origDropeeComponentRootElement,
2215: droppeeElement, componentRootElement, linkOnly);
2216: }
2217:
2218: Element getComponentRootElementEquivalentTo(
2219: Element oldComponentRootElement) {
2220: return domProvider
2221: .getComponentRootElementEquivalentTo(oldComponentRootElement);
2222: }
2223:
2224: boolean canHighlightComponentRootElement(
2225: Element componentRootElement) {
2226: return domProvider
2227: .canHighlightComponentRootElmenet(componentRootElement);
2228: }
2229:
2230: InlineEditorSupport createInlineEditorSupport(
2231: Element componentRootElement, String propertyName,
2232: String xpath) {
2233: return domProvider.createInlineEditorSupport(
2234: componentRootElement, propertyName, xpath);
2235: }
2236:
2237: // void dumpHtmlMarkupForNode(org.openide.nodes.Node node) {
2238: // domProvider.dumpHtmlMarkupForNode(node);
2239: // }
2240:
2241: // boolean canPasteTransferable(Transferable trans) {
2242: // return domProvider.canPasteTransferable(trans);
2243: // }
2244:
2245: void importString(String string, Point canvasPos,
2246: Node documentPosNode, int documentPosOffset,
2247: Dimension dimension, boolean isGrid,
2248: Element droppeeElement, Element dropeeComponentRootElement/*, Element defaultParentComponentRootElement*/) {
2249: domProvider
2250: .importString(this , string, canvasPos, documentPosNode,
2251: documentPosOffset, dimension, isGrid,
2252: droppeeElement, dropeeComponentRootElement /*, defaultParentComponentRootElement*/);
2253: }
2254:
2255: boolean importData(
2256: JComponent comp,
2257: Transferable t, /*Object transferData,*/
2258: Point canvasPos,
2259: Node documentPosNode,
2260: int documentPosOffset,
2261: Dimension dimension,
2262: boolean isGrid,
2263: Element droppeeElement,
2264: Element dropeeComponentRootElement/*, Element defaultParentComponentRootElement*/,
2265: int dropAction) {
2266: return domProvider
2267: .importData(
2268: this ,
2269: comp,
2270: t, /*transferData,*/
2271: canvasPos,
2272: documentPosNode,
2273: documentPosOffset,
2274: dimension,
2275: isGrid,
2276: droppeeElement,
2277: dropeeComponentRootElement/*, defaultParentComponentRootElement*/,
2278: dropAction);
2279: }
2280:
2281: // >> Designer implementation
2282: public void startInlineEditing(Element componentRootElement,
2283: String propertyName) {
2284: getManager().startInlineEditing(componentRootElement,
2285: propertyName);
2286: }
2287:
2288: public void selectComponent(Element componentRootElement) {
2289: getSelection().selectComponent(componentRootElement);
2290: }
2291:
2292: public int getSelectedCount() {
2293: return getSelection().getNumSelected();
2294: }
2295:
2296: public Element[] getSelectedComponents() {
2297: return getSelection().getSelectedComponentRootElements();
2298: }
2299:
2300: // public void snapToGrid() {
2301: // getGridHandler().snapToGrid();
2302: // }
2303:
2304: // public void align(Designer.Alignment alignment) {
2305: // getGridHandler().align(alignment);
2306: // }
2307: // << Designer Implmenetation
2308:
2309: // XXX Model <-> View mapping >>>
2310: /**
2311: * Converts the given location in the model to a place in
2312: * the view coordinate system.
2313: * The component must have a non-zero positive size for
2314: * this translation to be computed.
2315: *
2316: * @param tc the text component for which this UI is installed
2317: * @param pos the local location in the model to translate >= 0
2318: * @return the coordinates as a rectangle, null if the model is not painted
2319: * @exception BadLocationException if the given position does not
2320: * represent a valid location in the associated document
2321: * @see DesignerPaneBaseUI#modelToView
2322: */
2323: public Rectangle modelToView(
2324: /*DesignerPaneBase tc, Position pos*/DomPosition pos) {
2325: if (DesignerUtils.DEBUG) {
2326: DesignerUtils.debugLog(getClass().getName()
2327: + ".modelToView(DesignerPaneBase, Position)");
2328: }
2329: // if(tc == null) {
2330: // throw(new IllegalArgumentException("Null designer pane."));
2331: // }
2332: if (pos == null) {
2333: throw (new IllegalArgumentException("Null position."));
2334: }
2335:
2336: // WebForm webform = editor.getWebForm();
2337:
2338: // if (!webform.getModel().isValid()) {
2339: // if (!webform.isModelValid()) {
2340: // XXX Model validity shouldn't controlled here.
2341: // if (!isModelValid()) {
2342: // return null;
2343: // }
2344:
2345: // Document doc = editor.getDocument();
2346:
2347: // XXX There should be no locking here, the designer is not thread safe (it should run in AWT thread only).
2348: // // XXX Lock insync
2349: //// doc.readLock();
2350: //// webform.getMarkup().readLock();
2351: //// webform.readLock();
2352: // readLock();
2353: //
2354: // try {
2355: // return pageBox.modelToView(pos);
2356: // return ModelViewMapper.modelToView(pageBox, pos);
2357: return ModelViewMapper.modelToView(getPane().getPageBox(), pos);
2358: // } finally {
2359: // // XXX Unlock insync
2360: //// doc.readUnlock();
2361: //// webform.getMarkup().readUnlock();
2362: //// webform.readUnlock();
2363: // readUnlock();
2364: // }
2365: }
2366:
2367: /**
2368: * Converts the given place in the view coordinate system
2369: * to the nearest representative location in the model.
2370: * The component must have a non-zero positive size for
2371: * this translation to be computed.
2372: *
2373: * @param tc the text component for which this UI is installed
2374: * @param pt the location in the view to translate. This
2375: * should be in the same coordinate system as the mouse events.
2376: * @return the offset from the start of the document >= 0,
2377: * -1 if not painted
2378: * @see DesignerPaneBaseUI#viewToModel
2379: */
2380: // public Position viewToModel(/*DesignerPaneBase tc,*/ Point pt) {
2381: public DomPosition viewToModel(/*DesignerPaneBase tc,*/Point pt) {
2382: // Position pos = Position.NONE;
2383: // Document doc = editor.getDocument();
2384:
2385: // XXX Lock insync
2386: // doc.readLock();
2387: // WebForm webform = editor.getWebForm();
2388: // webform.getMarkup().readLock();
2389: // webform.readLock();
2390: // XXX There should be no locking here, the designer is not thread safe (it should run in AWT thread only).
2391: // readLock();
2392: //
2393: // try {
2394: // pos = ModelViewMapper.viewToModel(doc.getWebForm(), pt.x, pt.y); //, alloc, biasReturn);
2395: return ModelViewMapper.viewToModel(this , pt.x, pt.y); //, alloc, biasReturn);
2396:
2397: // I'm now relying on clients to do this themselves!
2398: //assert offs == Position.NONE || Position.isSourceNode(offs.getNode());
2399: // } finally {
2400: //// doc.readUnlock();
2401: //// webform.getMarkup().readUnlock();
2402: //// webform.readUnlock();
2403: // readUnlock();
2404: // }
2405:
2406: // return pos;
2407: }
2408:
2409: public boolean isInlineEditing() {
2410: return getManager().isInlineEditing();
2411: }
2412:
2413: public DomPosition createDomPosition(Node node, int offset,
2414: Bias bias) {
2415: return domProvider.createDomPosition(node, offset, bias);
2416: }
2417:
2418: public DomPosition createDomPosition(Node node, boolean after) {
2419: return domProvider.createDomPosition(node, after);
2420: }
2421:
2422: public DomRange createDomRange(Node dotNode, int dotOffset,
2423: Node markNode, int markOffset) {
2424: return domProvider.createDomRange(dotNode, dotOffset, markNode,
2425: markOffset);
2426: }
2427:
2428: public int compareBoundaryPoints(Node endPointA, int offsetA,
2429: Node endPointB, int offsetB) {
2430: return domProvider.compareBoundaryPoints(endPointA, offsetA,
2431: endPointB, offsetB);
2432: }
2433:
2434: DomPosition first(DomPosition dot, DomPosition mark) {
2435: return domProvider.first(dot, mark);
2436: }
2437:
2438: DomPosition last(DomPosition dot, DomPosition mark) {
2439: return domProvider.last(dot, mark);
2440: }
2441:
2442: // XXX Model <-> View mapping <<<
2443:
2444: public WebForm findExternalForm(URL url) {
2445: // XXX There could be more designers per one domProvider.
2446: Designer[] externalDesigners = domProvider
2447: .getExternalDesigners(url);
2448: if (externalDesigners.length > 0
2449: && externalDesigners[0] instanceof WebForm) {
2450: return (WebForm) externalDesigners[0];
2451: } else {
2452: // return WebForm.EXTERNAL;
2453: return null;
2454: }
2455: }
2456:
2457: // public void reuseCssStyle(WebForm webForm) {
2458: // if (webForm == null) {
2459: // return;
2460: // }
2461: // domProvider.reuseCssStyle(webForm.domProvider);
2462: // }
2463:
2464: // private static class DomProviderListener implements DomProvider.DomProviderListener {
2465: // private final WebForm webForm;
2466: //
2467: // public DomProviderListener(WebForm webForm) {
2468: // this.webForm = webForm;
2469: // }
2470: //
2471: //// public void modelChanged() {
2472: //// webForm.modelChanged();
2473: //// }
2474: //
2475: //// public void modelRefreshed() {
2476: //// webForm.modelRefreshed();
2477: //// }
2478: //
2479: //// public void nodeChanged(Node rendered, Node parent, boolean wasMove) {
2480: //// webForm.nodeChanged(rendered, parent, wasMove);
2481: //// }
2482: //
2483: //// public void nodeRemoved(Node previouslyRendered, Node parent) {
2484: //// webForm.nodeRemoved(previouslyRendered, parent);
2485: //// }
2486: //
2487: //// public void nodeInserted(Node rendered, Node parent) {
2488: //// webForm.nodeInserted(rendered, parent);
2489: //// }
2490: //
2491: //// public void updateErrorsInComponent() {
2492: //// webForm.updateErrorsInComponent();
2493: //// }
2494: //
2495: //// public void updateGridMode() {
2496: //// webForm.updateGridMode();
2497: //// }
2498: //// public void gridModeUpdated(boolean gridMode) {
2499: //// webForm.updatePaneGrid(gridMode);
2500: //// }
2501: //
2502: //// public void documentReplaced() {
2503: //// webForm.documentReplaced();
2504: //// }
2505: //
2506: //// public void showDropMatch(Element componentRootElement, Element regionElement, int dropType) {
2507: //// webForm.showDropMatch(componentRootElement, regionElement, dropType);
2508: //// }
2509: //
2510: //// public void clearDropMatch() {
2511: //// webForm.clearDropMatch();
2512: //// }
2513: //
2514: //// public void select(/*DesignBean designBean*/ Element componentRootElement) {
2515: ////// webForm.select(designBean);
2516: //// webForm.select(componentRootElement);
2517: //// }
2518: //
2519: //// public void refreshForm(boolean deep) {
2520: //// webForm.refreshForm(deep);
2521: //// }
2522: //
2523: //// public void inlineEdit(/*DesignBean[] designBeans*/ Element[] componentRootElements) {
2524: ////// webForm.inlineEdit(designBeans);
2525: //// webForm.inlineEdit(componentRootElements);
2526: //// }
2527: //
2528: //// public void designContextActivated(DesignContext designContext) {
2529: //// webForm.contextActivated(designContext);
2530: //// }
2531: //
2532: //// public void designContextDeactivated(DesignContext designContext) {
2533: //// webForm.contextDeactivated(designContext);
2534: //// }
2535: //
2536: //// public void designContextGenerationChanged() {
2537: //// webForm.designContextGenerationChanged();
2538: //// }
2539: //
2540: //// public void designBeanCreated(DesignBean designBean) {
2541: //// webForm.beanCreated(designBean);
2542: //// }
2543: //
2544: //// public void designBeanDeleted(DesignBean designBean) {
2545: //// webForm.beanDeleted(designBean);
2546: //// }
2547: //
2548: //// public void designBeanMoved(DesignBean designBean, DesignBean designBean0, Position position) {
2549: //// webForm.beanMoved(designBean, designBean0, position);
2550: //// }
2551: //
2552: //// public void designBeanContextActivated(DesignBean designBean) {
2553: //// webForm.beanContextActivated(designBean);
2554: //// }
2555: //
2556: //// public void designBeanContextDeactivated(DesignBean designBean) {
2557: //// webForm.beanContextDeactivated(designBean);
2558: //// }
2559: //
2560: //// public void designBeanNameChanged(DesignBean designBean, String string) {
2561: //// webForm.instanceNameChanged(designBean, string);
2562: //// }
2563: //
2564: //// public void designBeanChanged(DesignBean designBean) {
2565: //// webForm.beanChanged(designBean);
2566: //// }
2567: //
2568: //// public void designPropertyChanged(DesignProperty designProperty, Object object) {
2569: //// webForm.propertyChanged(designProperty, object);
2570: //// }
2571: //
2572: //// public void designEventChanged(DesignEvent designEvent) {
2573: //// webForm.eventChanged(designEvent);
2574: //// }
2575: // } // End of DomProviderListener.
2576:
2577: // private static class ErrorPanelCallbackImpl implements DomProvider.ErrorPanelCallback {
2578: // private final WebForm webForm;
2579: //
2580: // public ErrorPanelCallbackImpl(WebForm webForm) {
2581: // this.webForm = webForm;
2582: // }
2583: //
2584: // public void updateTopComponentForErrors() {
2585: // webForm.getTopComponent().updateErrors();
2586: // }
2587: //
2588: // public void setRenderFailureShown(boolean shown) {
2589: // webForm.setRenderFailureShown(shown);
2590: // }
2591: //
2592: //// public Exception getRenderFailure() {
2593: //// return webForm.getRenderFailure();
2594: //// }
2595: ////
2596: //// public MarkupDesignBean getRenderFailureComponent() {
2597: //// return webForm.getRenderFailureComponent();
2598: //// }
2599: //
2600: // public void handleRefresh(boolean showErrors) {
2601: // // Continue from the error panel to the designview
2602: // webForm.getTopComponent().showErrors(showErrors);
2603: // // 6274302: See if the user has cleared the error
2604: //// webform.refresh(true);
2605: // webForm.refreshModel(true);
2606: // }
2607: // } // End of ErrorPanelCallbackImpl.
2608:
2609: public Box findBox(int x, int y) {
2610: return ModelViewMapper.findBox(getPane().getPageBox(), x, y);
2611: }
2612:
2613: public Box findBoxForSourceElement(Element sourceElement) {
2614: return findCssBoxForElement(sourceElement);
2615: }
2616:
2617: public Box findBoxForComponentRootElement(
2618: Element componentRootElement) {
2619: return ModelViewMapper.findBoxForComponentRootElement(getPane()
2620: .getPageBox(), componentRootElement);
2621: }
2622:
2623: public Box findBoxForElement(Element element) {
2624: return findCssBoxForElement(element);
2625: }
2626:
2627: // public int snapX(int x, Box positionedBy) {
2628: //// return getGridHandler().snapX(x, positionedBy);
2629: // return GridHandler.getDefault().snapX(x, positionedBy);
2630: // }
2631: //
2632: // public int snapY(int y, Box positionedBy) {
2633: //// return getGridHandler().snapY(y, positionedBy);
2634: // return GridHandler.getDefault().snapY(y, positionedBy);
2635: // }
2636:
2637: public Element getPrimarySelectedComponent() {
2638: // XXX
2639: getSelection().pickPrimary();
2640: return getSelection().getPrimary();
2641: }
2642:
2643: public DomPosition computeNextPosition(DomPosition pos) {
2644: return ModelViewMapper.computeArrowRight(this , pos);
2645: }
2646:
2647: public DomPosition computePreviousPosition(DomPosition pos) {
2648: return ModelViewMapper.computeArrowLeft(this , pos);
2649: }
2650:
2651: /** Return true iff the position is within the editable portion of the document. */
2652: // public boolean isWithinEditableRegion(Position pos) {
2653: public boolean isInsideEditableRegion(DomPosition pos) {
2654: // WebForm webform = component.getDocument().getWebForm();
2655:
2656: InlineEditor editor = getManager().getInlineEditor();
2657:
2658: if (editor != null) {
2659: // Position editableRegionStart = editor.getBegin();
2660: // Position editableRegionEnd = editor.getEnd();
2661: DomPosition editableRegionStart = editor.getBegin();
2662: DomPosition editableRegionEnd = editor.getEnd();
2663:
2664: // assert editableRegionStart != Position.NONE;
2665: // assert editableRegionEnd != Position.NONE;
2666:
2667: return pos.isLaterThan(editableRegionStart)
2668: && pos.isEarlierThan(editableRegionEnd);
2669: }
2670:
2671: // assert !pos.isRendered() : pos;
2672: // if (MarkupService.isRenderedNode(pos.getNode())) {
2673: if (isRenderedNode(pos.getNode())) {
2674: ErrorManager.getDefault().notify(
2675: ErrorManager.INFORMATIONAL,
2676: new IllegalStateException(
2677: "Node is expected to be not rendered, node="
2678: + pos.getNode()));
2679: }
2680:
2681: if (!isGridMode()) {
2682: // In page flow mode, all regions are editable. Note - this
2683: // may not be true when I start allowing sub-grids
2684: return true;
2685: }
2686:
2687: CssBox box = getManager().getInsertModeBox();
2688:
2689: if (box == null) {
2690: return false;
2691: }
2692:
2693: //Position editableRegionStart = Position.create(box.getSourceElement());
2694: //Position editableRegionEnd = new Position(null, editableRegionStart.getNode(),
2695: // editableRegionStart.getOffset()+1);
2696: Element componentRootElement = CssBox
2697: .getElementForComponentRootCssBox(box);
2698: // Position editableRegionStart =
2699: // new Position(box.getDesignBean().getElement(), 0, Bias.FORWARD);
2700: // XXX Possible NPE?
2701: // new Position(CssBox.getMarkupDesignBeanForCssBox(box).getElement(), 0, Bias.FORWARD);
2702: // new Position(WebForm.getDomProviderService().getSourceElement(componentRootElement), 0, Bias.FORWARD);
2703: // DomPosition editableRegionStart = DesignerPaneBase.createDomPosition(WebForm.getDomProviderService().getSourceElement(componentRootElement), 0, Bias.FORWARD);
2704: WebForm webForm = box.getWebForm();
2705: if (webForm == null) {
2706: return false;
2707: }
2708: // DomPosition editableRegionStart = createDomPosition(WebForm.getDomProviderService().getSourceElement(componentRootElement), 0, Bias.FORWARD);
2709: DomPosition editableRegionStart = createDomPosition(webForm
2710: .getDomProviderService().getSourceElement(
2711: componentRootElement), 0, Bias.FORWARD);
2712:
2713: // Position editableRegionEnd =
2714: // new Position(editableRegionStart.getNode(),
2715: // editableRegionStart.getNode().getChildNodes().getLength(), Bias.BACKWARD);
2716: // DomPosition editableRegionEnd = DesignerPaneBase.createDomPosition(editableRegionStart.getNode(), editableRegionStart.getNode().getChildNodes().getLength(), Bias.BACKWARD);
2717: DomPosition editableRegionEnd = createDomPosition(
2718: editableRegionStart.getNode(), editableRegionStart
2719: .getNode().getChildNodes().getLength(),
2720: Bias.BACKWARD);
2721:
2722: return pos.isLaterThan(editableRegionStart)
2723: && pos.isEarlierThan(editableRegionEnd);
2724: }
2725:
2726: public void finishInlineEditing(boolean cancel) {
2727: getManager().finishInlineEditing(cancel);
2728: }
2729:
2730: public void invokeDeleteNextCharAction(ActionEvent evt) {
2731: InlineEditor inlineEditor = getManager().getInlineEditor();
2732: if (inlineEditor != null) {
2733: inlineEditor.invokeDeleteNextCharAction(evt);
2734: }
2735: }
2736:
2737: public Transferable inlineCopyText(boolean isCut) {
2738: InlineEditor inlineEditor = getManager().getInlineEditor();
2739: if (inlineEditor != null) {
2740: return inlineEditor.copyText(isCut);
2741: }
2742: return null;
2743: }
2744:
2745: public Element getPrimarySelection() {
2746: return getSelection().getPrimary();
2747: }
2748:
2749: public Element getSelectedContainer() {
2750: return getSelection().getSelectedContainer();
2751: }
2752:
2753: public void setSelectedComponents(Element[] componentRootElements,
2754: boolean update) {
2755: getSelection().selectComponents(componentRootElements, update);
2756: }
2757:
2758: public void clearSelection(boolean update) {
2759: getSelection().clearSelection(update);
2760: }
2761:
2762: public void syncSelection(boolean update) {
2763: getManager().syncSelection(update);
2764: getSelection().syncSelection(update);
2765: }
2766:
2767: public void updateSelectedNodes() {
2768: getSelection().updateNodes();
2769: }
2770:
2771: //// public void updateSelection() {
2772: // public void updateNodes() {
2773: //// getSelection().updateSelection();
2774: // getSelection().updateNodes();
2775: // }
2776:
2777: public Box getPageBox() {
2778: return getPane().getPageBox();
2779: }
2780:
2781: // public Point getCurrentPos() {
2782: // return getManager().getMouseHandler().getCurrentPos();
2783: // }
2784: //
2785: // public void clearCurrentPos() {
2786: // getManager().getMouseHandler().clearCurrentPos();
2787: // }
2788: //
2789: // public Element getPositionElement() {
2790: // return getSelection().getPositionElement();
2791: // }
2792: //
2793: // public int getGridWidth() {
2794: //// return getGridHandler().getGridWidth();
2795: // return GridHandler.getDefault().getGridWidth();
2796: // }
2797: //
2798: // public int getGridHeight() {
2799: //// return getGridHandler().getGridHeight();
2800: // return GridHandler.getDefault().getGridHeight();
2801: // }
2802:
2803: public Point getPastePoint() {
2804: return getManager().getPastePoint();
2805: }
2806:
2807: // public void addWeakPreferenceChangeListener(PreferenceChangeListener l) {
2808: // DesignerSettings.getInstance().addWeakPreferenceChangeListener(l);
2809: // }
2810:
2811: public ActionMap getPaneActionMap() {
2812: return getPane().getActionMap();
2813: }
2814:
2815: public void paneRequestFocus() {
2816: getPane().requestFocus();
2817: }
2818:
2819: public JComponent createPaneComponent() {
2820: return getPane();
2821: }
2822:
2823: public void updatePaneViewPort() {
2824: getPane().updateViewport();
2825: }
2826:
2827: public boolean hasPaneCaret() {
2828: return getPane().hasCaret();
2829: }
2830:
2831: public DomRange getPaneCaretRange() {
2832: return getPane().getCaretRange();
2833: }
2834:
2835: public void setPaneCaret(DomPosition pos) {
2836: getPane().setCaretDot(pos);
2837: }
2838:
2839: public void resetPanePageBox() {
2840: getPane().getPaneUI().resetPageBox();
2841: }
2842:
2843: public void redoPaneLayout(boolean immediate) {
2844: PageBox pageBox = getPane().getPageBox();
2845: // #123289 Possible NPE (for fragments?).
2846: if (pageBox == null) {
2847: return;
2848: }
2849: pageBox.redoLayout(immediate);
2850: }
2851:
2852: // public void performEscape() {
2853: // getManager().getMouseHandler().escape();
2854: // }
2855:
2856: // XXX
2857: public boolean isRenderedNode(Node node) {
2858: return domProvider.isRenderedNode(node);
2859: }
2860:
2861: // // XXX
2862: // public void tcEnableCutCopyDelete() {
2863: // domProvider.tcEnableCutCopyDelete(this);
2864: // }
2865: // public void tcDisableCutCopyDelete() {
2866: // domProvider.tcDisableCutCopyDelete(this);
2867: // }
2868:
2869: // public void tcSetActivatedNodes(org.openide.nodes.Node[] nodes) {
2870: // domProvider.tcSetActivatedNodes(this, nodes);
2871: // }
2872:
2873: // public org.openide.nodes.Node[] tcGetActivatedNodes() {
2874: // return domProvider.tcGetActivatedNodes(this);
2875: // }
2876:
2877: // public void tcRequestActive() {
2878: // domProvider.tcRequestActive(this);
2879: // }
2880:
2881: // public void tcShowPopupMenu(int x, int y) {
2882: // domProvider.tcShowPopupMenu(this, x, y);
2883: // }
2884: //
2885: // public void tcShowPopupMenu(JPopupMenu popup, int x, int y) {
2886: // domProvider.tcShowPopupMenu(this, popup, x, y);
2887: // }
2888: //
2889: // public void tcShowPopupMenuForEvent(MouseEvent evt) {
2890: // domProvider.tcShowPopupMenuForEvent(this, evt);
2891: // }
2892:
2893: // public boolean tcImportComponentData(JComponent comp, Transferable t) {
2894: // return domProvider.tcImportComponentData(this, comp, t);
2895: // }
2896:
2897: // public Point tcGetPastePosition() {
2898: // return domProvider.tcGetPastePosition(this);
2899: // }
2900:
2901: // public void tcRepaint() {
2902: // domProvider.tcRepaint(this);
2903: // }
2904:
2905: // public boolean tcSeenEscape(ActionEvent evt) {
2906: // return domProvider.tcSeenEscape(this, evt);
2907: // }
2908:
2909: // public void tcDeleteSelection() {
2910: // domProvider.tcDeleteSelection(this);
2911: // }
2912:
2913: public void addDesignerListener(DesignerListener l) {
2914: listenerList.add(DesignerListener.class, l);
2915: }
2916:
2917: public void removeDesignerListener(DesignerListener l) {
2918: listenerList.remove(DesignerListener.class, l);
2919: }
2920:
2921: private DesignerListener[] getDesignerListeners() {
2922: // Guaranteed to return a non-null array
2923: Object[] listeners = listenerList.getListenerList();
2924:
2925: List<DesignerListener> designerListeners = new ArrayList<DesignerListener>();
2926: // Process the listeners last to first, notifying
2927: // those that are interested in this event
2928: for (int i = listeners.length - 2; i >= 0; i -= 2) {
2929: if (listeners[i] == DesignerListener.class) {
2930: designerListeners
2931: .add((DesignerListener) listeners[i + 1]);
2932: }
2933: }
2934: return designerListeners
2935: .toArray(new DesignerListener[designerListeners.size()]);
2936: }
2937:
2938: public static class DefaultDesignerEvent implements DesignerEvent {
2939: private final Designer designer;
2940: private final Box box;
2941:
2942: public DefaultDesignerEvent(Designer designer, Box box) {
2943: this .designer = designer;
2944: this .box = box;
2945: }
2946:
2947: public Designer getDesigner() {
2948: return designer;
2949: }
2950:
2951: public Box getBox() {
2952: return box;
2953: }
2954: } // End of DefaultDesignerEvent.
2955:
2956: public void fireUserActionPerformed(DesignerEvent evt) {
2957: DesignerListener[] designerListeners = getDesignerListeners();
2958: for (DesignerListener l : designerListeners) {
2959: l.userActionPerformed(evt);
2960: }
2961: }
2962:
2963: public void fireUserPopupActionPerformed(DesignerPopupEvent evt) {
2964: DesignerListener[] designerListeners = getDesignerListeners();
2965: for (DesignerListener l : designerListeners) {
2966: l.userPopupActionPerformed(evt);
2967: }
2968: }
2969:
2970: public void fireUserElementClicked(DesignerClickEvent evt) {
2971: DesignerListener[] designerListeners = getDesignerListeners();
2972: for (DesignerListener l : designerListeners) {
2973: l.userElementClicked(evt);
2974: }
2975: }
2976:
2977: public void fireSelectionChanged(DesignerEvent evt) {
2978: DesignerListener[] designerListeners = getDesignerListeners();
2979: for (DesignerListener l : designerListeners) {
2980: l.selectionChanged(evt);
2981: }
2982: }
2983:
2984: // private static class CssBoxDataHandler implements UserDataHandler {
2985: // private static final CssBoxDataHandler INSTANCE = new CssBoxDataHandler();
2986: //
2987: // public static CssBoxDataHandler getDefault() {
2988: // return INSTANCE;
2989: // }
2990: //
2991: // public void handle(short operation, String key, Object data, Node src, Node dst) {
2992: // // No op.
2993: // }
2994: // } // End of CssBoxDataHandler.
2995:
2996: void paintDesignerDecorations(Graphics2D g) {
2997: domProvider.paintDesignerDecorations(g, this );
2998: }
2999:
3000: public Designer.RenderContext createRenderContext() {
3001: return new RenderContextImpl(this );
3002: }
3003:
3004: private static class RenderContextImpl implements
3005: Designer.RenderContext {
3006: private final WebForm webForm;
3007:
3008: public RenderContextImpl(WebForm webForm) {
3009: this .webForm = webForm;
3010: }
3011:
3012: // public DesignContext getDesignContext() {
3013: // return webForm.getModel().getLiveUnit();
3014: // }
3015: // public DesignBean[] getBeansOfType(Class clazz) {
3016: // return webForm.getBeansOfType(clazz);
3017: // }
3018:
3019: // public Project getProject() {
3020: // return webForm.getProject();
3021: // }
3022:
3023: public Dimension getVieportDimension() {
3024: return webForm.getPane().getPageBox().getViewport()
3025: .getExtentSize();
3026: }
3027:
3028: public Point getViewportPosition() {
3029: return webForm.getPane().getPageBox().getViewport()
3030: .getViewPosition();
3031: }
3032:
3033: public int getNonTabbedTextWidth(char[] s, int offset,
3034: int length, FontMetrics metrics) {
3035: return DesignerUtils.getNonTabbedTextWidth(s, offset,
3036: length, metrics);
3037: }
3038:
3039: public Rectangle getBoundsForComponent(
3040: Element componentRootElement) {
3041: if (componentRootElement != null) {
3042: return ModelViewMapper.getComponentBounds(webForm
3043: .getPane().getPageBox(), componentRootElement);
3044: } else {
3045: return null;
3046: }
3047: }
3048: } // End of RenderContextImpl.
3049:
3050: public void setPaintSizeMask(boolean paintSizeMask) {
3051: this .paintSizeMask = paintSizeMask;
3052: }
3053:
3054: public boolean isPaintSizeMask() {
3055: return paintSizeMask;
3056: }
3057:
3058: public Decoration getDecoration(Element element) {
3059: return domProvider.getDecoration(element);
3060: }
3061:
3062: // public boolean isShowDecorations() {
3063: // return domProvider.isShowDecorations();
3064: // }
3065: //
3066: // public int getDefaultFontSize() {
3067: // return domProvider.getDefaultFontSize();
3068: // }
3069: //
3070: // public int getPageSizeWidth() {
3071: // return domProvider.getPageSizeWidth();
3072: // }
3073: //
3074: // public int getPageSizeHeight() {
3075: // return domProvider.getPageSizeHeight();
3076: // }
3077: //
3078: // public boolean isGridShow() {
3079: // return domProvider.isGridShow();
3080: // }
3081: //
3082: // public boolean isGridSnap() {
3083: // return domProvider.isGridSnap();
3084: // }
3085: //
3086: // public int getGridWidth() {
3087: // return domProvider.getGridWidth();
3088: // }
3089: //
3090: // public int getGridHeight() {
3091: // return domProvider.getGridHeight();
3092: // }
3093:
3094: // public int getGridTraceWidth() {
3095: // return domProvider.getGridTraceWidth();
3096: // }
3097: //
3098: // public int getGridTraceHeight() {
3099: // return domProvider.getGridTraceHeight();
3100: // }
3101:
3102: // public int getGridOffset() {
3103: // return domProvider.getGridOffset();
3104: // }
3105:
3106: /** Adjust the given mouse X position to account for insets in parent
3107: * components etc., such that the resulting position matches the canvas
3108: * pixel in the view the mouse is over.
3109: */
3110: public int adjustX(int x) {
3111: x += DesignerPane.getAdjustX();
3112:
3113: return x;
3114: }
3115:
3116: /** Adjust the given mouse X position to account for insets in parent
3117: * components etc., such that the resulting position matches the canvas
3118: * pixel in the view the mouse is over.
3119: */
3120: public int adjustY(int y) {
3121: y += DesignerPane.getAdjustY();
3122:
3123: return y;
3124: }
3125:
3126: /** Snap the given X position. If snap to grid is turned off, it simply
3127: * returns the original position.
3128: * @param x The horizontal position to be snapped to the grid
3129: * @param parent A positioning parent to snap to, or null to use
3130: * the default viewport (0,0)
3131: * @todo Handle case where the x coordinate is less than the parent box left.
3132: * This can happen when the user drags the component outside the grid area.
3133: */
3134: // public int snapX(int x, CssBox parent) {
3135: public int snapX(int x, Box parent) {
3136: boolean snap = isGridSnap();
3137: int gridWidth = getGridWidth();
3138: // int gridOffset = getGridOffset();
3139: // return doSnapX(x, parent == null ? 0 : parent.getAbsoluteX(), snap, gridWidth, gridOffset);
3140: return doSnapX(x, parent == null ? 0 : parent.getAbsoluteX(),
3141: snap, gridWidth);
3142: }
3143:
3144: public int snapX(int x) {
3145: return snapX(x, null);
3146: }
3147:
3148: // private static int doSnapX(int x, int absX, boolean snap, int gridWidth, int gridOffset) {
3149: private static int doSnapX(int x, int absX, boolean snap,
3150: int gridWidth) {
3151: // int root = 0; // X coordinate of positioning parent
3152:
3153: // if (parent != null) {
3154: // root = parent.getAbsoluteX();
3155: // x -= root;
3156: // }
3157: // X coordinate of positioning parent
3158: int root = absX;
3159: x -= root;
3160:
3161: if (snap) {
3162: // x = (((x + gridOffset + (gridWidth / 2)) / gridWidth) * gridWidth) - gridOffset;
3163: x = (((x + (gridWidth / 2)) / gridWidth) * gridWidth);
3164: }
3165:
3166: x += root;
3167:
3168: return x;
3169: }
3170:
3171: /** Snap the given Y position. If snap to grid is turned off, it simply
3172: * returns the original position.
3173: * @param y The vertical position to be snapped to the grid
3174: * @param parent A positioning parent to snap to, or null to use
3175: * the default viewport (0,0)
3176: * @todo Handle case where the y coordinate is less than the parent box top.
3177: * This can happen when the user drags the component above the grid area.
3178: */
3179: // public int snapY(int y, CssBox parent) {
3180: public int snapY(int y, Box parent) {
3181: boolean snap = isGridSnap();
3182: int gridHeight = getGridHeight();
3183: // int gridOffset = getGridOffset();
3184: // return doSnapY(y, parent == null ? 0 : parent.getAbsoluteY(), snap, gridHeight, gridOffset);
3185: return doSnapY(y, parent == null ? 0 : parent.getAbsoluteY(),
3186: snap, gridHeight);
3187: }
3188:
3189: public int snapY(int y) {
3190: return snapY(y, null);
3191: }
3192:
3193: // private static int doSnapY(int y, int absY, boolean snap, int gridHeight, int gridOffset) {
3194: private static int doSnapY(int y, int absY, boolean snap,
3195: int gridHeight) {
3196: // int root = 0; // Y coordinate of positioning parent
3197:
3198: // if (parent != null) {
3199: // root = parent.getAbsoluteY();
3200: // y -= root;
3201: // }
3202: // Y coordinate of positioning parent
3203: int root = absY;
3204: y -= root;
3205:
3206: if (snap) {
3207: // y = (((y + gridOffset + (gridHeight / 2)) / gridHeight) * gridHeight) - gridOffset;
3208: y = (((y + (gridHeight / 2)) / gridHeight) * gridHeight);
3209: }
3210:
3211: y += root;
3212:
3213: return y;
3214: }
3215:
3216: public void setInitialFocusMarkCssBox(CssBox cssBox) {
3217: initialFocusMarkCssBoxWRef = new WeakReference<CssBox>(cssBox);
3218: }
3219:
3220: public CssBox getInitialFocusMarkCssBox() {
3221: return initialFocusMarkCssBoxWRef.get();
3222: }
3223:
3224: // public void setPageSizeWidth(int pageSizeWidth) {
3225: // this.pageSizeWidth = pageSizeWidth;
3226: // }
3227: //
3228: // public int getPageSizeWidth() {
3229: // return pageSizeWidth;
3230: // }
3231: //
3232: // public void setPageSizeHeight(int pageSizeHeight) {
3233: // this.pageSizeHeight = pageSizeHeight;
3234: // }
3235: //
3236: // public int getPageSizeHeight() {
3237: // return pageSizeHeight;
3238: // }
3239: public void setPageSize(Dimension pageSize) {
3240: this .pageSize.setSize(pageSize);
3241:
3242: // TODO This property should be bound, and the handler (in the designerPane) should take care of this.
3243: PageBox pageBox = designerPane.getPageBox();
3244: if (pageBox != null) {
3245: pageBox.redoLayout(true);
3246: }
3247: designerPane.repaint();
3248: }
3249:
3250: public int getPageSizeWidth() {
3251: return pageSize.width;
3252: }
3253:
3254: public int getPageSizeHeight() {
3255: return pageSize.height;
3256: }
3257:
3258: public void setGridShow(boolean gridShow) {
3259: this .gridShow = gridShow;
3260:
3261: // TODO This property should be bound, and the handler (in the designerPane) should take care of this.
3262: designerPane.repaint();
3263: }
3264:
3265: public boolean isGridShow() {
3266: return gridShow;
3267: }
3268:
3269: public void setGridSnap(boolean gridSnap) {
3270: this .gridSnap = gridSnap;
3271:
3272: // TODO This property should be bound, and the handler (in the designerPane) should take care of this.
3273: designerPane.repaint();
3274: }
3275:
3276: public boolean isGridSnap() {
3277: return gridSnap;
3278: }
3279:
3280: public void setGridWidth(int gridWidth) {
3281: this .gridWidth = gridWidth;
3282:
3283: // TODO This property should be bound, and the handler (in the designerPane) should take care of this.
3284: designerPane.repaint();
3285: }
3286:
3287: public int getGridWidth() {
3288: return gridWidth;
3289: }
3290:
3291: public void setGridHeight(int gridHeight) {
3292: this .gridHeight = gridHeight;
3293:
3294: // TODO This property should be bound, and the handler (in the designerPane) should take care of this.
3295: designerPane.repaint();
3296: }
3297:
3298: public void setGridTraceWidth(int gridTraceWidth) {
3299: this .gridTraceWidth = gridTraceWidth;
3300: }
3301:
3302: public int getGridTraceWidth() {
3303: return gridTraceWidth;
3304: }
3305:
3306: public void setGridTraceHeight(int gridTraceHeight) {
3307: this .gridTraceHeight = gridTraceHeight;
3308: }
3309:
3310: public int getGridTraceHeight() {
3311: return gridTraceHeight;
3312: }
3313:
3314: public int getGridHeight() {
3315: return gridWidth;
3316: }
3317:
3318: public void setShowDecorations(boolean showDecorations) {
3319: this .showDecorations = showDecorations;
3320:
3321: // TODO This property should be bound, and the handler (in the designerPane) should take care of this.
3322: designerPane.repaint();
3323: }
3324:
3325: public boolean isShowDecorations() {
3326: return showDecorations;
3327: }
3328:
3329: public void setDefaultFontSize(int defaultFontSize) {
3330: this .defaultFontSize = defaultFontSize;
3331:
3332: // TODO This property should be bound, and the handler (in the designerPane) should take care of this.
3333: DesignerPaneUI designerPaneUI = designerPane.getPaneUI();
3334: if (designerPaneUI != null) {
3335: designerPaneUI.resetPageBox();
3336: }
3337: designerPane.repaint();
3338: }
3339:
3340: public int getDefaultFontSize() {
3341: return defaultFontSize;
3342: }
3343:
3344: /** XXX #113773 Find component root element for specified box. */
3345: public static Element getComponentRootElementForCssBox(CssBox cssBox) {
3346: WebForm webForm = cssBox == null ? null : cssBox.getWebForm();
3347: if (webForm == null) {
3348: return null;
3349: }
3350: while (cssBox != null) {
3351: Element element = cssBox.getElement();
3352: // if (WebForm.getDomProviderService().isPrincipalElement(element, null)) {
3353: if (webForm.getDomProviderService().isPrincipalElement(
3354: element, null)) {
3355: return element;
3356: }
3357: cssBox = cssBox.getParent();
3358: }
3359:
3360: return null;
3361: }
3362:
3363: /** XXX This will replace the JSF specific above methods.
3364: * Gets associated element for the css box. It returns the element only if the specified box
3365: * represents component top level element except lines, texts and spaces. */
3366: public static Element getElementForComponentRootCssBox(CssBox cssBox) {
3367: if (cssBox == null) {
3368: return null;
3369: }
3370:
3371: Element element = cssBox.getElement();
3372: BoxType boxType = cssBox.getBoxType();
3373: if (element == null || boxType == BoxType.LINEBOX
3374: || boxType == BoxType.TEXT || boxType == BoxType.SPACE) {
3375: // XXX As before no assigned MarkupDesignBean for the above cases.
3376: return null;
3377: }
3378: return getElementForPrincipalCssBox(cssBox);
3379: }
3380:
3381: private static Element getElementForPrincipalCssBox(CssBox cssBox) {
3382: if (cssBox == null) {
3383: return null;
3384: }
3385: WebForm webForm = cssBox.getWebForm();
3386: if (webForm == null) {
3387: return null;
3388: }
3389: Element element = cssBox.getElement();
3390: ContainerBox parentBox = cssBox.getParent();
3391: Element parentBoxElement = parentBox == null ? null : parentBox
3392: .getElement();
3393: // return WebForm.getDomProviderService().isPrincipalElement(element, parentBoxElement) ? element : null;
3394: return webForm.getDomProviderService().isPrincipalElement(
3395: element, parentBoxElement) ? element : null;
3396: }
3397: }
|