0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.visualweb.designer.jsf;
0042:
0043: import com.sun.rave.designtime.DesignBean;
0044: import com.sun.rave.designtime.DesignProperty;
0045: import org.netbeans.modules.visualweb.designer.html.HtmlAttribute;
0046: import org.netbeans.modules.visualweb.designer.html.HtmlTag;
0047: import java.lang.reflect.Method;
0048: import javax.faces.component.html.HtmlCommandLink;
0049: import javax.faces.component.html.HtmlOutputLink;
0050: import javax.faces.component.html.HtmlOutputText;
0051: import org.netbeans.modules.visualweb.api.designer.DesignerServiceHackProvider;
0052: import org.netbeans.modules.visualweb.api.designer.cssengine.CssEngineService;
0053: import org.netbeans.modules.visualweb.api.designer.cssengine.CssProvider;
0054: import org.netbeans.modules.visualweb.api.designerapi.DesignerServiceHack;
0055: import com.sun.rave.designtime.DesignContext;
0056: import com.sun.rave.designtime.markup.MarkupDesignBean;
0057: import java.awt.Container;
0058: import org.netbeans.modules.visualweb.insync.beans.BeansUnit;
0059: import org.netbeans.modules.visualweb.insync.faces.FacesPageUnit;
0060: import org.netbeans.modules.visualweb.insync.live.LiveUnit;
0061: import org.netbeans.modules.visualweb.insync.markup.MarkupUnit;
0062: import org.netbeans.modules.visualweb.insync.models.FacesModel;
0063: import java.awt.EventQueue;
0064: import java.awt.Graphics2D;
0065: import java.awt.Image;
0066: import java.awt.datatransfer.DataFlavor;
0067: import java.awt.datatransfer.Transferable;
0068: import java.lang.ref.WeakReference;
0069: import java.net.URL;
0070: import java.util.Iterator;
0071: import java.util.Map;
0072: import java.util.Set;
0073: import javax.swing.JComponent;
0074: import javax.swing.SwingUtilities;
0075: import javax.swing.TransferHandler;
0076: import org.netbeans.api.project.FileOwnerQuery;
0077: import org.netbeans.api.project.Project;
0078: import org.netbeans.modules.visualweb.api.designer.Designer;
0079: import org.netbeans.modules.visualweb.api.designer.Designer.Box;
0080: import org.netbeans.modules.visualweb.api.designer.Designer.ExternalBox;
0081: import org.netbeans.modules.visualweb.api.designer.DomProvider;
0082: import org.netbeans.modules.visualweb.designer.jsf.ui.JsfTopComponent;
0083: import org.netbeans.modules.visualweb.insync.UndoEvent;
0084: import org.openide.ErrorManager;
0085: import org.openide.filesystems.FileObject;
0086: import org.openide.loaders.DataObject;
0087: import org.openide.loaders.DataObjectNotFoundException;
0088: import org.openide.util.NbBundle;
0089: import org.openide.util.RequestProcessor;
0090: import org.openide.windows.Mode;
0091: import org.openide.windows.TopComponent;
0092: import org.openide.windows.WindowManager;
0093: import org.w3c.dom.DocumentFragment;
0094: import org.w3c.dom.Element;
0095:
0096: /**
0097: * Implementation of the DesignerService API.
0098: * <p>
0099: *
0100: * @todo The css value lookup methods need to do something smarter
0101: * for shorthand properties
0102: * @author Tor Norbye
0103: */
0104: public class DesignerServiceHackImpl extends DesignerServiceHack {
0105: // private static final String[] LENGTH_UNITS =
0106: // { "%", "em", "ex", "px", "cm", "mm", "in", "pt", "pc" };
0107: // private static volatile String[] properties;
0108:
0109: // /**
0110: // * The following mime types are valid mime types for files
0111: // * that will be considered webforms in the WebAppProject
0112: // */
0113: // private static final String[] FORM_MIME_TYPES = new String[] { "text/x-jsp" }; // NOI18N
0114:
0115: public DesignerServiceHackImpl() {
0116: }
0117:
0118: private FacesPageUnit getFacesUnit(DesignContext context) {
0119: LiveUnit lu = (LiveUnit) context;
0120:
0121: // Find the model
0122: BeansUnit bu = lu.getBeansUnit();
0123:
0124: if (!(bu instanceof FacesPageUnit)) {
0125: return null;
0126: }
0127:
0128: return (FacesPageUnit) bu;
0129: }
0130:
0131: public Image getCssPreviewImage(String cssStyle,
0132: String[] cssStyleClasses, MarkupDesignBean bean, int width,
0133: int height) {
0134: if (bean.getElement() == null) {
0135: return null;
0136: }
0137:
0138: FacesPageUnit fu = getFacesUnit(bean.getDesignContext());
0139: if (fu == null) {
0140: return null;
0141: }
0142:
0143: MarkupUnit mu = fu.getPageUnit();
0144: FileObject fo = mu.getFileObject();
0145: DataObject dobj = null;
0146:
0147: try {
0148: dobj = DataObject.find(fo);
0149: } catch (DataObjectNotFoundException ex) {
0150: ErrorManager.getDefault().notify(
0151: ErrorManager.INFORMATIONAL, ex);
0152: return null;
0153: }
0154:
0155: // WebForm webform = DesignerUtils.getWebForm(dobj);
0156: //
0157: // if (webform == null) {
0158: // return null;
0159: // }
0160: //
0161: // // Phew! On to the preview painting.
0162: // PageBox pageBox = PageBox.getPageBox(null, webform, webform.getHtmlBody());
0163: // WindowManager wm = WindowManager.getDefault();
0164: // Graphics2D g2d = (Graphics2D)wm.getMainWindow().getGraphics();
0165: //
0166: // return pageBox.paintCssPreview(g2d, cssStyle, bean, width, height);
0167:
0168: // >>> Moved from designer/PageBox.paintCssPreview >>>
0169: // if (initialWidth == 0) {
0170: if (width == 0) {
0171: // Ensure that we don't force wrapping on components like a composite
0172: // breadcrumbs by giving it some space to work with.
0173: width = 600;
0174: }
0175:
0176: // Distinguish between the bean we're going to -render- and the one we're
0177: // going to apply the differente properties to
0178: MarkupDesignBean renderBean = bean;
0179:
0180: // // Handle hyperlinks. We really need to render its surrounding content
0181: // // to see the CS stylerules for <a> apply
0182: // if (renderBean.getInstance() instanceof HtmlOutputText) {
0183: // DesignBean parent = renderBean.getBeanParent();
0184: //
0185: // if ((parent != null) && (parent.getChildBeanCount() == 1) &&
0186: // (parent.getInstance() instanceof HtmlCommandLink ||
0187: // parent.getInstance() instanceof HtmlOutputLink)) {
0188: // renderBean = (MarkupDesignBean)parent;
0189: // }
0190: // }
0191: //
0192: // // Embedded table portions (rowgroups, columns) aren't happy being rendered
0193: // // without their surrounding table.
0194: // // It would be better to modify the preview code to actually go and -try- rendering
0195: // // components and then progressively retry on parents until it succeeds.
0196: // // But given that the code is freezing today I'm playing it safe
0197: // if (renderBean.getInstance() instanceof com.sun.rave.web.ui.component.TableColumn
0198: // || renderBean.getInstance() instanceof com.sun.webui.jsf.component.TableColumn) {
0199: // if (renderBean.getBeanParent() instanceof MarkupDesignBean) {
0200: // renderBean = (MarkupDesignBean)renderBean.getBeanParent();
0201: // } else {
0202: // return null;
0203: // }
0204: // } else if (renderBean.getBeanParent().getInstance() instanceof com.sun.rave.web.ui.component.TableColumn
0205: // || renderBean.getBeanParent().getInstance() instanceof com.sun.webui.jsf.component.TableColumn) {
0206: // // We also have to render components that are children of a TableColumn as part of the whole
0207: // // table as well, because their value binding expressions can involve data providers set up
0208: // // by the table. This is clearly not a clean solution. See comment above about trying arbitary
0209: // // rendering instead. This breaks once you nest components in a column inside a container
0210: // // component for example. Just doing a low risk, 90% fix now right before FCS.
0211: // if (renderBean.getBeanParent().getBeanParent() instanceof MarkupDesignBean) {
0212: // renderBean = (MarkupDesignBean)renderBean.getBeanParent().getBeanParent();
0213: // } else {
0214: // return null;
0215: // }
0216: // }
0217: //
0218: // // Not else: a TableColumn can be inside a TableRowGroup so keep moving outwards if necessary:
0219: // if (renderBean.getInstance() instanceof com.sun.rave.web.ui.component.TableRowGroup
0220: // || renderBean.getInstance() instanceof com.sun.webui.jsf.component.TableRowGroup) {
0221: // if (renderBean.getBeanParent() instanceof MarkupDesignBean) {
0222: // renderBean = (MarkupDesignBean)renderBean.getBeanParent();
0223: // } else {
0224: // return null;
0225: // }
0226: // }
0227: // XXX Hack, see the impl.
0228: // renderBean = WebForm.getDomProviderService().adjustRenderBeanHack(renderBean);
0229: renderBean = adjustRenderBeanHack(renderBean);
0230:
0231: Element e = bean.getElement();
0232: assert e != null;
0233:
0234: // XXX can I shut off errors in output window?
0235: String oldStyleAttribute = null;
0236: String oldStyleProperty = null;
0237:
0238: if (e.hasAttribute(HtmlAttribute.STYLE)) {
0239: oldStyleAttribute = e.getAttribute(HtmlAttribute.STYLE);
0240: }
0241:
0242: // XhtmlCssEngine engine = webform.getMarkup().getCssEngine();
0243:
0244: DesignContext designContext = bean.getDesignContext();
0245: if (!(designContext instanceof LiveUnit)) {
0246: ErrorManager.getDefault()
0247: .notify(
0248: ErrorManager.INFORMATIONAL,
0249: new IllegalStateException(
0250: "Design context should be LiveUnit instance, designContext="
0251: + designContext + ", bean="
0252: + bean)); // NOI18N
0253: return null;
0254: }
0255: FacesModel facesModel = ((LiveUnit) designContext).getModel();
0256: if (facesModel == null) {
0257: ErrorManager.getDefault()
0258: .notify(
0259: ErrorManager.INFORMATIONAL,
0260: new NullPointerException(
0261: "FacesModel is null, designContext="
0262: + designContext + ", bean="
0263: + bean)); // NOI18N
0264: return null;
0265: }
0266: UndoEvent writeLock = facesModel.writeLock(NbBundle.getMessage(
0267: DesignerServiceHackImpl.class, "LBL_CssPreviewImage")); // NOI18N
0268: try {
0269: // engine.setErrorHandler(XhtmlCssEngine.SILENT_ERROR_HANDLER);
0270: // CssProvider.getEngineService().setSilentErrorHandlerForDocument(webform.getMarkup().getSourceDom());
0271: // CssProvider.getEngineService().setSilentErrorHandlerForDocument(webform.getMarkup().getRenderedDom());
0272: // CssProvider.getEngineService().setSilentErrorHandlerForDocument(webform.getHtmlDom());
0273: CssProvider.getEngineService()
0274: .setSilentErrorHandlerForDocument(
0275: mu.getRenderedDom());
0276:
0277: // CssBox.noBoxPersistence = true;
0278:
0279: e.setAttribute(HtmlAttribute.STYLE, cssStyle);
0280:
0281: DesignProperty prop = bean.getProperty("style");
0282:
0283: if (prop != null) {
0284: oldStyleProperty = (String) prop.getValue();
0285:
0286: try {
0287: Method m = prop.getPropertyDescriptor()
0288: .getWriteMethod();
0289: m.invoke(bean.getInstance(),
0290: new Object[] { cssStyle });
0291: } catch (Exception ex) {
0292: ErrorManager.getDefault().notify(ex);
0293: }
0294: }
0295:
0296: // engine.clearComputedStyles(e, "");
0297: // CssProvider.getEngineService().clearComputedStylesForElement(e); // TEMP
0298:
0299: // Try to render JSF so I can process the DF before proceeding
0300: Element element = renderBean.getElement();
0301: String tagName = element.getTagName();
0302: HtmlTag tag = HtmlTag.getTag(tagName);
0303:
0304: DocumentFragment df;
0305: if (tag == null) {
0306: // Possibly a Jsf component.
0307: // Use getDocument() rather than doc directly since
0308: // e.g. jsp includes may point to external documents here,
0309: // not the document containing the jsp tag itself
0310:
0311: // XXX TODO There is not needed webform here.
0312: // FileObject markupFile = webform.getModel().getMarkupFile();
0313: //// DocumentFragment df = FacesSupport.renderHtml(markupFile, renderBean, !CssBox.noBoxPersistence);
0314: // DocumentFragment df = InSyncService.getProvider().renderHtml(markupFile, renderBean);
0315: // df = webform.renderHtmlForMarkupDesignBean(renderBean);
0316: df = FacesPageUnit.renderHtml((FacesModel) fu
0317: .getModel(), renderBean, false);
0318: } else {
0319: df = null;
0320: }
0321:
0322: // if (df != null) {
0323: // stripDesignStyleClasses(df);
0324: // }
0325:
0326: Element componentRootElement = JsfSupportUtilities
0327: .getComponentRootElementForDesignBean(bean);
0328:
0329: // XXX Moved from DesignerHackProviderImpl.
0330: Designer[] designers = JsfForm
0331: .getDesignersForDataObject(dobj);
0332: if (designers.length == 0) {
0333: return null;
0334: }
0335: // XXX Why it is used the main window graphics??
0336: WindowManager wm = WindowManager.getDefault();
0337: Graphics2D g2d = (Graphics2D) wm.getMainWindow()
0338: .getGraphics();
0339: // <<< Moved from designer/PageBox.paintCssPreview
0340: return DesignerServiceHackProvider.getCssPreviewImage(/*dobj,*/
0341: designers[0], g2d, cssStyle, cssStyleClasses,
0342: /*bean,*/componentRootElement, df, element, width, height);
0343: // >>> Moved from designer/PageBox.paintCssPreview
0344: } finally {
0345: // CssBox.noBoxPersistence = false;
0346:
0347: if (oldStyleAttribute != null) {
0348: e.setAttribute(HtmlAttribute.STYLE, oldStyleAttribute);
0349: } else {
0350: e.removeAttribute(HtmlAttribute.STYLE);
0351: }
0352:
0353: DesignProperty prop = bean.getProperty("style");
0354:
0355: if (prop != null) {
0356: try {
0357: Method m = prop.getPropertyDescriptor()
0358: .getWriteMethod();
0359: m.invoke(bean.getInstance(),
0360: new Object[] { oldStyleProperty });
0361: } catch (Exception ex) {
0362: ErrorManager.getDefault().notify(
0363: ErrorManager.INFORMATIONAL, ex);
0364: }
0365: }
0366:
0367: // engine.clearComputedStyles(e, null);
0368: CssEngineService cssEngineService = CssProvider
0369: .getEngineService();
0370: cssEngineService.clearComputedStylesForElement(e);
0371:
0372: if (renderBean != bean) {
0373: // engine.clearComputedStyles(renderBean.getElement(), null);
0374: cssEngineService
0375: .clearComputedStylesForElement(renderBean
0376: .getElement());
0377: }
0378:
0379: // engine.setErrorHandler(null);
0380: // cssEngineService.setNullErrorHandlerForDocument(webform.getMarkup().getSourceDom());
0381: // cssEngineService.setNullErrorHandlerForDocument(webform.getMarkup().getRenderedDom());
0382: // cssEngineService.setNullErrorHandlerForDocument(webform.getHtmlDom());
0383: cssEngineService.setNullErrorHandlerForDocument(mu
0384: .getRenderedDom());
0385:
0386: facesModel.writeUnlock(writeLock);
0387: }
0388: // <<< Moved from designer/PageBox.paintCssPreview
0389: }
0390:
0391: public Image getCssPreviewImage(Map<String, String> properties,
0392: URL base, int width, int height) {
0393: // WindowManager wm = WindowManager.getDefault();
0394: // Graphics2D g2d = (Graphics2D)wm.getMainWindow().getGraphics();
0395: //
0396: // return paintCssPreview(g2d, base, properties, width, height);
0397: return DesignerServiceHackProvider.getCssPreviewImage(
0398: properties, base, width, height, JsfDesignerPreferences
0399: .getInstance().getDefaultFontSize());
0400: }
0401:
0402: /** Computes a preview image of the specified size for given <code>DataObject</code>.
0403: * @return the image or <code>null</code> if the specified DataObject is not a webform one. */
0404: public Image getPageBoxPreviewImage(DataObject dobj, int width,
0405: int height) {
0406: // Copied from navigation/../PageFlowGraph to get rid of dependencies.
0407: // Obtain a page box for the given page
0408: // WebForm webform = DesignerUtils.getWebForm(dobj);
0409: //
0410: // if (webform == null) {
0411: // return null;
0412: // }
0413: //
0414: // webform.getModel().sync();
0415: //
0416: // if (webform.getModel().isBusted()) {
0417: // return null;
0418: // }
0419: //
0420: // Element body = webform.getHtmlBody();
0421: //
0422: // if (body == null) {
0423: // return null;
0424: // }
0425: //
0426: // PageBox pageBox = PageBox.getPageBox(null, webform, body);
0427: //
0428: // return pageBox.createPreviewImage(width, height);
0429: // XXX Moved from DesignerHackProviderImpl.
0430: // Designer[] designers = JsfForm.getDesignersForDataObject(dobj);
0431: // if (designers.length == 0) {
0432: // return null;
0433: // }
0434: JsfForm jsfForm = JsfForm.getJsfForm(dobj);
0435: if (jsfForm == null) {
0436: return null;
0437: }
0438: // XXX Moved from designer/../DesignerHackProviderImpl.
0439: // webform.getModel().sync();
0440: jsfForm.syncModel();
0441: // if (webform.getModel().isBusted()) {
0442: if (jsfForm.isModelBusted()) {
0443: return null;
0444: }
0445: Designer[] designers = JsfForm.getDesigners(jsfForm);
0446: if (designers.length == 0) {
0447: return null;
0448: }
0449:
0450: return DesignerServiceHackProvider.getPageBoxPreviewImage(
0451: /*dobj,*/designers[0], width, height);
0452: }
0453:
0454: // public String[] getCssIdentifiers(String propertyName) {
0455: //// StringMap map = getIdentifiers(propertyName);
0456: ////
0457: //// if (map == null) {
0458: //// return new String[0];
0459: //// }
0460: ////
0461: //// int count = map.size();
0462: //// ArrayList keys = new ArrayList(count);
0463: //// Iterator it = map.keys();
0464: ////
0465: //// while (it.hasNext()) {
0466: //// Object o = it.next();
0467: //// keys.add(o);
0468: //// }
0469: ////
0470: //// keys.add("inherit");
0471: //// Collections.sort(keys);
0472: ////
0473: //// return (String[])keys.toArray(new String[keys.size()]);
0474: // return CssProvider.getEngineService().getCssIdentifiers(propertyName);
0475: // }
0476:
0477: // // public Object[] getCssIdentifierValues(String propertyName) {
0478: // // StringMap map = getIdentifiers(propertyName);
0479: // // if (map == null) {
0480: // // return new Object[0];
0481: // // }
0482: // // int count = map.size();
0483: // // ArrayList values = new ArrayList(count);
0484: // // Iterator it = map.values();
0485: // // while (it.hasNext()) {
0486: // // Object o = it.next();
0487: // // values.add(o);
0488: // // }
0489: // // // TODO -- sort in the same order as the identifier names??
0490: // // return (Object[])values.toArray(new Object[values.size()]);
0491: // // }
0492: // private StringMap getIdentifiers(String property) {
0493: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
0494: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
0495: //
0496: // if (index == -1) {
0497: //// index = XhtmlCssEngine.getXhtmlShorthandIndex(property);
0498: // index = CssProvider.getEngineService().getXhtmlShorthandIndex(property);
0499: //
0500: // if (index == -1) {
0501: // return null;
0502: // }
0503: //
0504: // // XXX TODO! What do we do here?
0505: // return null;
0506: // }
0507: //
0508: //// ValueManager vm = XhtmlCssEngine.XHTML_VALUE_MANAGERS[index];
0509: // ValueManager vm = CssProvider.getEngineService().getXhtmlValueManagers()[index];
0510: //
0511: // if (vm instanceof IdentifierProvider) {
0512: // return ((IdentifierProvider)vm).getIdentifierMap();
0513: // }
0514: //
0515: // return null;
0516: // }
0517:
0518: // public String[] getCssLengthUnits() {
0519: // return LENGTH_UNITS;
0520: // }
0521:
0522: // /**
0523: // * {@inheritDoc}
0524: // *
0525: // * @todo Include properties that I'm not supporting/tracking in the
0526: // * designer yet!
0527: // */
0528: // public String[] getCssProperties() {
0529: //// if (properties == null) {
0530: ////// ValueManager[] vms = XhtmlCssEngine.XHTML_VALUE_MANAGERS;
0531: //// ValueManager[] vms = CssProvider.getEngineService().getXhtmlValueManagers();
0532: //// ArrayList list = new ArrayList(vms.length);
0533: ////
0534: //// for (int i = 0, n = vms.length; i < n; i++) {
0535: //// String property = vms[i].getPropertyName();
0536: ////
0537: //// if (property.charAt(0) != '-') { // don't include vendor-specific properties
0538: //// list.add(property);
0539: //// }
0540: //// }
0541: ////
0542: //// Collections.sort(list);
0543: //// properties = (String[])list.toArray(new String[list.size()]);
0544: //// }
0545: ////
0546: //// return properties;
0547: // return CssProvider.getEngineService().getCssProperties();
0548: // }
0549:
0550: // public CssValue getCssValue(MarkupDesignBean bean, String property) {
0551: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
0552: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
0553: //
0554: // if (index == -1) {
0555: // return null;
0556: // }
0557: //
0558: //// return CssLookup.getValue(bean.getElement(), index);
0559: // CssLookup.getCssValue(bean.getElement(), index);
0560: // }
0561:
0562: // public Map convertCssStyleToMap(DesignContext context, String cssStyle) {
0563: // if(DesignerUtils.DEBUG) {
0564: // DesignerUtils.debugLog(getClass().getName() + ".convertCssStyleToMap(DesignContext, String)");
0565: // }
0566: // if(context == null) {
0567: // throw(new IllegalArgumentException("Null context."));
0568: // }
0569: // if(cssStyle == null) {
0570: // throw(new IllegalArgumentException("Null style."));
0571: // }
0572: // return ((LiveUnit)context).convertCssStyleToMap(cssStyle);
0573: // }
0574: //
0575: // public String convertMapToCssStyle(DesignContext context, Map cssStyleMap) {
0576: // if(DesignerUtils.DEBUG) {
0577: // DesignerUtils.debugLog(getClass().getName() + ".convertMapToCssStyle(DesignContext, String)");
0578: // }
0579: // if(context == null) {
0580: // throw(new IllegalArgumentException("Null context."));
0581: // }
0582: // if(cssStyleMap == null) {
0583: // throw(new IllegalArgumentException("Null style."));
0584: // }
0585: // return ((LiveUnit)context).convertMapToCssStyle(cssStyleMap);
0586: // }
0587:
0588: // public String[] getHtmlTags() {
0589: // HtmlTag[] tags = HtmlTag.getTags();
0590: // ArrayList result = new ArrayList(tags.length);
0591: //
0592: // for (int i = 0; i < tags.length; i++) {
0593: // if (tags[i] == null) {
0594: // break;
0595: // }
0596: //
0597: // String name = tags[i].name;
0598: //
0599: // if (!name.startsWith("jsp:")) { // NOI18N
0600: // result.add(name);
0601: // }
0602: // }
0603: //
0604: // return (String[])result.toArray(new String[result.size()]);
0605: // }
0606:
0607: // /**
0608: // * Show the given line in a particular file.
0609: // *
0610: // * @param filename The full path to the file, or null. Exactly one of filename or fileObject
0611: // * should be non null.
0612: // * @param fileObject The FileObject for the file or null. Exactly one of filename or fileObject
0613: // * should be non null.
0614: // * @param lineno The line number
0615: // * @param openFirst Usually you'll want to pass false. When set to true, this will first open
0616: // * the file, then request the given line number; this works around certain bugs for
0617: // * some editor types like CSS files.
0618: // */
0619: // public void show(String filename, FileObject fileObject, int lineno, int column,
0620: // boolean openFirst) {
0621: // assert ((filename != null) && (fileObject == null)) ||
0622: // ((filename == null) && (fileObject != null));
0623: //
0624: // if (fileObject != null) {
0625: // show(fileObject, lineno, column, openFirst);
0626: // } else {
0627: // File file = new File(filename);
0628: // FileObject fo = FileUtil.toFileObject(file);
0629: //
0630: // if (fo != null) {
0631: // show(fo, lineno, column, openFirst);
0632: // }
0633: // }
0634: // }
0635: //
0636: // private static boolean show(FileObject fo, int lineno, int column, boolean openFirst) {
0637: // throw new RuntimeException("show not yet implemented");
0638: //
0639: // /*
0640: // boolean opened = false;
0641: // DataObject dobj;
0642: // try {
0643: // dobj = DataObject.find(fo);
0644: // }
0645: // catch (DataObjectNotFoundException ex) {
0646: // ErrorManager.getDefault().notify(ex);
0647: // return false;
0648: // }
0649: //
0650: // GenericItem item = GenericItem.findItem(dobj);
0651: // if (item != null) {
0652: // WebAppProject p = (WebAppProject)item.getProject();
0653: // if (p != null) {
0654: // FacesModelSet models = FacesModelSet.getInstance(p);
0655: // if (models != null) {
0656: // FacesModel model = models.getFacesModel(fo);
0657: // WebForm wf = WebForm.get(model);
0658: // if (wf != null && wf.getDataObject() != null) {
0659: // DataObject dobj2 = wf.getDataObject();
0660: // dobj = dobj2; ???
0661: // }
0662: // }
0663: // }
0664: // }
0665: //
0666: // if (dobj instanceof JSFDataObject) {
0667: // EditorCookie ec = (EditorCookie)dobj.getCookie(EditorCookie.class);
0668: // if (ec instanceof JSFEditorSupport) {
0669: // JSFEditorSupport jes = (JSFEditorSupport)ec;
0670: // if ("java".equalsIgnoreCase(fo.getExt())) {
0671: // jes.viewJavaSource(-1);
0672: // } else {
0673: // jes.viewJSPSource();
0674: // }
0675: // opened = true;
0676: // // How do we force the line number now? Do we have to or can we rely on the above?
0677: // }
0678: // }
0679: //
0680: // // Try to open doc before showing the line. This SHOULD not be
0681: // // necessary, except without this the IDE hangs in its attempt
0682: // // to open the file when the file in question is a CSS file.
0683: // // Probably a bug in the xml/css module's editorsupport code.
0684: // // This has the negative effect of first flashing the top
0685: // // of the file before showing the destination line, so
0686: // // this operation is made conditional so only clients who
0687: // // actually need it need to use it.
0688: // if (openFirst && !opened) {
0689: // EditorCookie ec = (EditorCookie)dobj.getCookie(EditorCookie.class);
0690: // if (ec != null) {
0691: // try {
0692: // ec.openDocument(); // ensure that it has been opened - REDUNDANT?
0693: // //ec.open();
0694: // }
0695: // catch (IOException ex) {
0696: // ErrorManager.getDefault().notify(ex);
0697: // }
0698: // }
0699: // }
0700: //
0701: // LineCookie lc = (LineCookie)dobj.getCookie(LineCookie.class);
0702: // if (lc != null) {
0703: // Line.Set ls = lc.getLineSet();
0704: // if (ls != null) {
0705: // // -1: convert line numbers to be zero-based
0706: // Line line = ls.getCurrent(lineno-1);
0707: // // TODO - pass in a column too?
0708: // line.show(Line.SHOW_GOTO, column);
0709: // return true;
0710: // }
0711: // }
0712: //
0713: // return false;
0714: // */
0715: // }
0716:
0717: public boolean canDrop(DataFlavor flavor) {
0718: // // Fish for the designer pane
0719: // DesignerTopComp dtc = findCurrent();
0720: //
0721: // if (dtc == null) {
0722: // return false;
0723: // }
0724: //
0725: // // TODO -- additional flavor checking?
0726: // return true;
0727: // return DesignerServiceHackProvider.canDrop(flavor);
0728: // Fish for the designer pane
0729: JsfTopComponent dtc = findCurrent();
0730:
0731: if (dtc == null) {
0732: return false;
0733: }
0734:
0735: // TODO -- additional flavor checking?
0736: return true;
0737:
0738: }
0739:
0740: public void drop(Transferable transferable) {
0741: // // Fish for the "current" designer pane
0742: // DesignerTopComp dtc = findCurrent();
0743: //
0744: // if (dtc == null) {
0745: // return;
0746: // }
0747: //
0748: // DesignerPane pane = dtc.getWebForm().getPane();
0749: // TransferHandler dth = pane.getTransferHandler();
0750: //
0751: // // Drop it
0752: // dth.importData(pane, transferable);
0753: // DesignerServiceHackProvider.drop(transferable);
0754: // Fish for the "current" designer pane
0755: JsfTopComponent dtc = findCurrent();
0756:
0757: if (dtc == null) {
0758: return;
0759: }
0760:
0761: // DesignerPane pane = dtc.getWebForm().getPane();
0762: JComponent pane = dtc.getPane();
0763: TransferHandler dth = pane.getTransferHandler();
0764:
0765: // Drop it
0766: dth.importData(pane, transferable);
0767: }
0768:
0769: /** For temporary use by getCurrentDesigner runnable */
0770: private static transient TopComponent temptc;
0771:
0772: private static TopComponent getCurrentDesigner() {
0773: if (SwingUtilities.isEventDispatchThread()) {
0774: return findCurrent();
0775: } else {
0776: // FIXME This is incorrect, it can't work.
0777: // If this can work only in AWT thread,
0778: // then it should be required on the client to be called only in that
0779: // thread and not pretend othwerise.
0780: try {
0781: SwingUtilities.invokeAndWait(new Runnable() {
0782: public void run() {
0783: temptc = findCurrent();
0784: }
0785: });
0786:
0787: return temptc;
0788: } catch (Exception e) {
0789: ErrorManager.getDefault().notify(e);
0790:
0791: return null;
0792: } finally {
0793: temptc = null; // done after return value
0794: }
0795: }
0796: }
0797:
0798: /**
0799: * Attempt to locate the current design view in use; may return
0800: * null if no designer is found.
0801: */
0802: private static JsfTopComponent findCurrent() {
0803: // Fish for the designer pane
0804: JsfTopComponent formView = null;
0805:
0806: // Search through workspaces, then modes, then topcomponents
0807: Set modes = WindowManager.getDefault().getModes();
0808: Iterator it2 = modes.iterator();
0809:
0810: while (it2.hasNext()) {
0811: Mode m = (Mode) it2.next();
0812: TopComponent[] tcs = m.getTopComponents();
0813:
0814: if (tcs != null) {
0815: for (int j = 0; j < tcs.length; j++) {
0816: if (!tcs[j].isShowing()) {
0817: continue;
0818: }
0819:
0820: // Go hunting for our DesignerTopComp
0821: JsfTopComponent comp = findDesigner(tcs[j], 0);
0822:
0823: if (comp != null) {
0824: if (comp.isShowing()) {
0825: return comp;
0826: }
0827: }
0828: }
0829: }
0830:
0831: if (formView != null) {
0832: break;
0833: }
0834: }
0835:
0836: return formView;
0837: }
0838:
0839: /** Fish for a DesignerPane within a container hierarchy
0840: */
0841: private static JsfTopComponent findDesigner(Container c, int depth) {
0842: if (c == null) {
0843: return null;
0844: }
0845:
0846: // Only look slightly into the hiearchy since TopComponents should
0847: // be near the top
0848: if (depth == 4) {
0849: return null;
0850: }
0851:
0852: depth++;
0853:
0854: int n = c.getComponentCount();
0855:
0856: for (int i = 0; i < n; i++) {
0857: java.awt.Component child = c.getComponent(i);
0858:
0859: if (child instanceof JsfTopComponent) {
0860: return (JsfTopComponent) child;
0861: } else if (child instanceof Container) {
0862: JsfTopComponent result = findDesigner(
0863: (Container) child, depth);
0864:
0865: if (result != null) {
0866: return result;
0867: }
0868: }
0869: }
0870:
0871: return null;
0872: }
0873:
0874: // public void registerTransferable(Transferable transferable) {
0875: //// if(DesignerUtils.DEBUG) {
0876: //// DesignerUtils.debugLog(getClass().getName() + ".registerTransferable(Transferable)");
0877: //// }
0878: //// if(transferable == null) {
0879: //// throw(new IllegalArgumentException("Null transferable."));
0880: //// }
0881: //// DndHandler.setActiveTransferable(transferable);
0882: // DesignerServiceHackProvider.registerTransferable(transferable);
0883: // }
0884:
0885: // /** For temporary use by getCurrentDesigner runnable */
0886: // private transient TopComponent temptc;
0887: //
0888: // private TopComponent getCurrentDesigner() {
0889: // if (SwingUtilities.isEventDispatchThread()) {
0890: // return findCurrent();
0891: // } else {
0892: // // FIXME This is incorrect, it can't work.
0893: // // If this can work only in AWT thread,
0894: // // then it should be required on the client to be called only in that
0895: // // thread and not pretend othwerise.
0896: // try {
0897: // SwingUtilities.invokeAndWait(new Runnable() {
0898: // public void run() {
0899: // temptc = findCurrent();
0900: // }
0901: // });
0902: //
0903: // return temptc;
0904: // } catch (Exception e) {
0905: // ErrorManager.getDefault().notify(e);
0906: //
0907: // return null;
0908: // } finally {
0909: // temptc = null; // done after return value
0910: // }
0911: // }
0912: // }
0913:
0914: public FileObject getCurrentFile() {
0915: // DesignerTopComp tc = (DesignerTopComp)getCurrentDesigner();
0916: //
0917: // if ((tc == null) || (tc.getWebForm().getMarkup() == null)) {
0918: // return null;
0919: // }
0920: //
0921: // return tc.getWebForm().getMarkup().getFileObject();
0922: // return DesignerServiceHackProvider.getCurrentFile();
0923: JsfTopComponent tc = (JsfTopComponent) getCurrentDesigner();
0924:
0925: // if ((tc == null) || (tc.getWebForm().getMarkup() == null)) {
0926: if (tc == null) {
0927: return null;
0928: }
0929:
0930: // return tc.getWebForm().getMarkup().getFileObject();
0931: DataObject jspDataObject = getJspDataObject(tc);
0932: return jspDataObject == null ? null : jspDataObject
0933: .getPrimaryFile();
0934: }
0935:
0936: private static DataObject getJspDataObject(
0937: JsfTopComponent jsfTopComponent) {
0938: return jsfTopComponent.getLookup().lookup(DataObject.class);
0939: }
0940:
0941: // public static void testPreview() {
0942: // DesignerService ds = DesignerService.getDefault();
0943: // HashMap properties = new HashMap();
0944: // properties.put("background-color", "red");
0945: // URL base = null;
0946: // int width = 200;
0947: // int height = 200;
0948: // BufferedImage img1 = (BufferedImage)ds.getCssPreviewImage(properties, base, width, height);
0949: // showScreenshot(img1);
0950: //
0951: // properties = new HashMap();
0952: // properties.put("border-color", "blue");
0953: // properties.put("border-width", "3px");
0954: // properties.put("border-style", "solid");
0955: // properties.put("font-size", "24pt");
0956: // properties.put("text-decoration", "underline");
0957: // base = null;
0958: // width = 300;
0959: // height = 300;
0960: // BufferedImage img2 = (BufferedImage)ds.getCssPreviewImage(properties, base, width, height);
0961: // showScreenshot(img2);
0962: //
0963: //
0964: // }
0965: //
0966: // protected static void showScreenshot(BufferedImage bi) {
0967: // try {
0968: // File tmp = File.createTempFile("designer", ".png");
0969: // tmp.deleteOnExit();
0970: // saveImage(bi, tmp);
0971: // showScreenshot(tmp);
0972: // } catch (java.io.IOException ioe) {
0973: // ErrorManager.getDefault().notify(ioe);
0974: // }
0975: // }
0976: //
0977: // /** Save the given image to disk */
0978: // protected static void saveImage(BufferedImage image, File file) {
0979: // try {
0980: // if (file.exists()) {
0981: // file.delete();
0982: // }
0983: // ImageIO.write(image, "png", file);
0984: // } catch (IOException e) {
0985: // System.err.println(e);
0986: // }
0987: // }
0988: //
0989: // protected static void showScreenshot(File file) {
0990: // URL url;
0991: // try {
0992: // url = new URL("file:" + file.getPath()); // NOI18N
0993: // } catch (MalformedURLException e) {
0994: // // Can't show URL
0995: // ErrorManager.getDefault().notify(e);
0996: // return;
0997: // }
0998: // URLDisplayer.getDefault().showURL(url);
0999: // }
1000: // public void parseCss(javax.swing.text.Document document, Object handler) {
1001: // if (!(handler instanceof org.w3c.css.sac.ErrorHandler)) {
1002: // throw new IllegalArgumentException("Handler must be org.w3c.css.sac.ErrorHandler");
1003: // }
1004: //
1005: // if (document == null) {
1006: // throw new IllegalArgumentException("document parameter should not be null!");
1007: // }
1008: //
1009: // // Parse document
1010: //// RaveDocument doc = null;
1011: // // <markup_separation>
1012: //// XhtmlCssEngine engine = XhtmlCssEngine.create(doc, null, null);
1013: // // ====
1014: //// XhtmlCssEngine engine = XhtmlCssEngine.create(null, null);
1015: ////// <moved from engine impl> it doesn't (shoudn't) know about RaveDocument.
1016: ////// if (doc != null) {
1017: ////// doc.setCssEngine(engine);
1018: ////// }
1019: ////// </moved from engine impl>
1020: // Document fakeDocument = new FakeDocument();
1021: // CssProvider.getEngineService().createCssEngineForDocument(fakeDocument, null);
1022: //// XhtmlCssEngine engine = CssEngineServiceProvider.getDefault().getCssEngine(fakeDocument);
1023: ////
1024: //// // </markup_separation>
1025: //// engine.setErrorHandler((ErrorHandler)handler);
1026: // CssProvider.getEngineService().setErrorHandlerForDocument(fakeDocument, (ErrorHandler)handler);
1027: //
1028: // String rules;
1029: //
1030: // try {
1031: // rules = document.getText(0, document.getLength());
1032: // } catch (javax.swing.text.BadLocationException e) {
1033: // ErrorManager.getDefault().notify(e);
1034: //
1035: // return;
1036: // }
1037: //
1038: //// engine.parseStyleSheet(rules, null, "all", null);
1039: // CssProvider.getEngineService().parseStyleSheetForDocument(fakeDocument, rules, null, "all", null); // NOI18N
1040: //// engine.setErrorHandler(null);
1041: // CssProvider.getEngineService().setErrorHandlerForDocument(fakeDocument, null);
1042: // }
1043:
1044: // /** XXX Fake document, to be able to create engine.
1045: // * TODO Better is just to impl the <code>Document</code> interface, without dep on xerces. */
1046: // private static class FakeDocument extends DocumentImpl {
1047: // } // End of FakeDocument.
1048:
1049: public Object getTableInfo(MarkupDesignBean bean) {
1050: // assert bean.getElement() != null;
1051: //
1052: // CssBox box = CssBox.getBox(bean.getElement());
1053: //
1054: // if (box instanceof TableBox) {
1055: // return box;
1056: // }
1057: //
1058: // return null;
1059: Element componentRootElement = JsfSupportUtilities
1060: .getComponentRootElementForDesignBean(bean);
1061: if (componentRootElement == null) {
1062: ErrorManager.getDefault().notify(
1063: ErrorManager.INFORMATIONAL,
1064: new NullPointerException(
1065: "There is no element in markup design bean="
1066: + bean)); // NOI18N
1067: return null;
1068: }
1069: // return DesignerServiceHackProvider.getTableInfo(componentRootElement);
1070: Designer[] designers = JsfForm
1071: .findDesignersForElement(componentRootElement);
1072: Designer designer = designers.length > 0 ? designers[0] : null;
1073: if (designer == null) {
1074: return null;
1075: }
1076: Box box = designer
1077: .findBoxForComponentRootElement(componentRootElement);
1078: return DesignerServiceHackProvider.isTableBox(box) ? box : null;
1079: }
1080:
1081: public Element getCellElement(Object tableInfo, int row, int column) {
1082: // assert tableInfo instanceof TableBox;
1083: //
1084: // TableBox table = (TableBox)tableInfo;
1085: // CssBox box = table.getCell(row, column);
1086: //
1087: // if (box == null) {
1088: // return null;
1089: // }
1090: //
1091: // return box.getElement();
1092: return DesignerServiceHackProvider.getCellElement(tableInfo,
1093: row, column);
1094: }
1095:
1096: public MarkupDesignBean getCellBean(Object tableInfo, int row,
1097: int column) {
1098: // assert tableInfo instanceof TableBox;
1099: //
1100: // TableBox table = (TableBox)tableInfo;
1101: // CssBox box = table.getCell(row, column);
1102: //
1103: // if (box == null) {
1104: // return null;
1105: // }
1106: //
1107: // return box.getDesignBean();
1108: Element componentRootElement = DesignerServiceHackProvider
1109: .getCellComponent(tableInfo, row, column);
1110: return MarkupUnit
1111: .getMarkupDesignBeanForElement(componentRootElement);
1112: }
1113:
1114: public int getColSpan(Object tableInfo, int row, int column) {
1115: // assert tableInfo instanceof TableBox;
1116: //
1117: // TableBox table = (TableBox)tableInfo;
1118: //
1119: // return table.getCellSpan(CssBox.Y_AXIS, row, column);
1120: return DesignerServiceHackProvider.getColSpan(tableInfo, row,
1121: column);
1122: }
1123:
1124: public int getRowSpan(Object tableInfo, int row, int column) {
1125: // assert tableInfo instanceof TableBox;
1126: //
1127: // TableBox table = (TableBox)tableInfo;
1128: //
1129: // return table.getCellSpan(CssBox.X_AXIS, row, column);
1130: return DesignerServiceHackProvider.getRowSpan(tableInfo, row,
1131: column);
1132: }
1133:
1134: public int getColumnCount(Object tableInfo) {
1135: // assert tableInfo instanceof TableBox;
1136: //
1137: // TableBox table = (TableBox)tableInfo;
1138: //
1139: // return table.getColumns();
1140: return DesignerServiceHackProvider.getColumnCount(tableInfo);
1141: }
1142:
1143: public int getRowCount(Object tableInfo) {
1144: // assert tableInfo instanceof TableBox;
1145: //
1146: // TableBox table = (TableBox)tableInfo;
1147: //
1148: // return table.getRows();
1149: return DesignerServiceHackProvider.getRowCount(tableInfo);
1150: }
1151:
1152: // public void removeCssProperty(MarkupDesignBean bean, String property) {
1153: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
1154: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
1155: //
1156: // if (index != -1) {
1157: // // TODO -- update the -rendered- element!
1158: //// CssLookup.removeLocalStyleValue(bean.getElement(), index);
1159: // CssProvider.getEngineService().removeLocalStyleValueForElement(bean.getElement(), index);
1160: // }
1161: // }
1162: //
1163: // public void setCssProperty(MarkupDesignBean bean, String property, String value) {
1164: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
1165: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
1166: //
1167: // if (index != -1) {
1168: // // TODO -- update the -rendered- element!
1169: //// CssLookup.setLocalStyleValue(bean.getElement(), index, value);
1170: // CssProvider.getEngineService().addLocalStyleValueForElement(bean.getElement(), index, value);
1171: // }
1172: // }
1173:
1174: // public URL resolveUrl(URL base, Document document, String src) {
1175: // if (src == null) {
1176: // src = "";
1177: // }
1178: //
1179: // // TODO after Reef: push this into superclass
1180: // URL reference = null;
1181: //
1182: // // Relative to the web folder?
1183: // if (src.startsWith("/")) { // NOI18N
1184: //
1185: // // What if it's a local file, e.g. /home/tor/foo.jspf?? that wouldn't work at deploy time anyway..
1186: // try {
1187: // // <markup_separation>
1188: //// MarkupUnit markup = ((RaveDocument)document).getMarkup();
1189: //// FileObject fo = markup.getFileObject();
1190: // // ====
1191: // FileObject fo = InSyncServiceProvider.getProvider().getFileObject(document);
1192: // // </markup_separation>
1193: // Project project = FileOwnerQuery.getOwner(fo);
1194: //
1195: // if (project != null) {
1196: // FileObject webroot = JSFProjectUtil.getDocumentRoot(project);
1197: // reference = FileUtil.toFile(webroot).toURI().toURL();
1198: // }
1199: //
1200: // src = src.substring(1); // strip off leading "/" or URL class will ignore base
1201: // } catch (Exception ex) {
1202: // reference = base;
1203: // }
1204: // } else {
1205: // reference = base;
1206: // }
1207: //
1208: // try {
1209: // URL u = new URL(reference, src); // XXX what if it's absolute?
1210: //
1211: // return u;
1212: // } catch (MalformedURLException e) {
1213: // ErrorManager.getDefault().notify(e);
1214: //
1215: // return null;
1216: // }
1217: // }
1218:
1219: // public Element getBody(Document document) {
1220: // // <markup_separation>
1221: //// MarkupUnit markup = ((RaveDocument)document).getMarkup();
1222: //// DataObject dobj = markup.getDataObject();
1223: // // ====
1224: // FileObject fo = InSyncServiceProvider.getProvider().getFileObject(document);
1225: // DataObject dobj;
1226: // // XXX Copied form insync.
1227: // if (fo != null && !fo.isValid()) {
1228: // dobj = null;
1229: // } else {
1230: // try {
1231: // dobj = DataObject.find(fo);
1232: // } catch (DataObjectNotFoundException dnfe) {
1233: // dobj = null;
1234: // }
1235: // }
1236: // // </markup_separation>
1237: //
1238: // if (WebForm.isWebFormDataObject(dobj)) {
1239: // WebForm webform = WebForm.getWebFormForDataObject(dobj);
1240: //
1241: // return webform.getBody();
1242: // } else {
1243: // throw new IllegalStateException(
1244: // "Wrong document parameter in DesignerService.getBody dobj=" + dobj); // NOI18N
1245: // }
1246: // }
1247:
1248: // public boolean isWebPage(FileObject fo) {
1249: // String mime = fo.getMIMEType();
1250: //
1251: // String[] mimeTypes = FORM_MIME_TYPES;
1252: //
1253: // for (int i = 0; i < mimeTypes.length; i++) {
1254: // if (mimeTypes[i].equals(mime)) {
1255: // return true;
1256: // }
1257: // }
1258: //
1259: // return false;
1260: // }
1261: //
1262: // public String[] getMimeTypes() {
1263: // return FORM_MIME_TYPES;
1264: // }
1265: //
1266: // public List getWebPages(Project project, boolean includePages, boolean includeFragments) {
1267: // ArrayList list = new ArrayList(20);
1268: // FileObject fobj = JSFProjectUtil.getDocumentRoot(project);
1269: // addWebPages(list, fobj, includePages, includeFragments);
1270: //
1271: // return list;
1272: // }
1273: //
1274: // private void addWebPages(List list, FileObject folder, boolean includePages,
1275: // boolean includeFragments) {
1276: // if(DesignerUtils.DEBUG) {
1277: // DesignerUtils.debugLog(getClass().getName() + ".addWebPages(List, FileObject, boolean, boolean)");
1278: // }
1279: // if(folder == null) {
1280: // throw(new IllegalArgumentException("Null folder."));
1281: // }
1282: // if(list == null) {
1283: // throw(new IllegalArgumentException("Null list."));
1284: // }
1285: //
1286: // FileObject[] children = folder.getChildren();
1287: //
1288: // for (int i = 0; i < children.length; i++) {
1289: // FileObject fo = children[i];
1290: //
1291: // if (fo.isFolder()) {
1292: // addWebPages(list, fo, includePages, includeFragments);
1293: // } else {
1294: // if (isWebPage(fo)) {
1295: // boolean isFragment = "jspf".equals(fo.getExt()); // NOI18N
1296: //
1297: // if (isFragment) {
1298: // if (includeFragments) {
1299: // list.add(fo);
1300: // }
1301: // } else if (includePages) {
1302: // list.add(fo);
1303: // }
1304: // }
1305: // }
1306: // }
1307: // }
1308:
1309: // Moved to insync.
1310: // public boolean isBraveheartPage(Document document) {
1311: // return DesignerUtils.isBraveheartPage(document);
1312: // }
1313: //
1314: // public boolean isBraveheartPage(FileObject fo) {
1315: // DataObject dobj = null;
1316: //
1317: // try {
1318: // dobj = DataObject.find(fo);
1319: // } catch (DataObjectNotFoundException ex) {
1320: // return false;
1321: // }
1322: //
1323: // WebForm webform = DesignerUtils.getWebForm(dobj, false);
1324: //
1325: // if (webform == null) {
1326: // return false;
1327: // }
1328: //
1329: // Document dom = webform.getJspDom();
1330: //
1331: // if (dom != null) {
1332: // return isBraveheartPage(dom);
1333: // }
1334: //
1335: // return false;
1336: // }
1337:
1338: /** Weak ref to the last task processing. */
1339: private static WeakReference<RequestProcessor.Task> lastTaskWRef = new WeakReference<RequestProcessor.Task>(
1340: null);
1341:
1342: public void notifyCssEdited(final DataObject dobj) {
1343: // DesignerTopComp.setPendingRefreshAll();
1344: // DesignerServiceHackProvider.notifyCssEdited(dobj);
1345: if (dobj == null) {
1346: return;
1347: }
1348:
1349: // This method is called when editing the css, and this take care not to cause performance
1350: // issues with processing too many refresh tasks.
1351: RequestProcessor.Task lastTask = lastTaskWRef.get();
1352: boolean previousTaskRunning;
1353: if (lastTask != null && !lastTask.isFinished()) {
1354: // XXX Cancel only the task which has the same dobj. But how, the RequestProcessor.Task is final.
1355: // Assuming this omission should be fine, there shouldn't occur sudden edit from different projects.
1356: previousTaskRunning = !lastTask.cancel();
1357: } else {
1358: previousTaskRunning = false;
1359: }
1360: int delay = previousTaskRunning ? 500 : 200;
1361:
1362: RequestProcessor.Task newTask = RequestProcessor.getDefault()
1363: .post(new Runnable() {
1364: public void run() {
1365: EventQueue.invokeLater(new Runnable() {
1366: public void run() {
1367: Project project = FileOwnerQuery
1368: .getOwner(dobj.getPrimaryFile());
1369: if (project != null) {
1370: JsfForm
1371: .refreshDesignersInProject(project);
1372: }
1373: }
1374: });
1375: }
1376: }, delay);
1377: lastTaskWRef = new WeakReference<RequestProcessor.Task>(newTask);
1378: }
1379:
1380: // public void refresh(Project project, DataObject dobj, boolean deep) {
1381: //// if (dobj != null) {
1382: //// DesignerActions.refresh(dobj, deep);
1383: //// } else {
1384: //// DesignerActions.refreshAll(project, deep);
1385: //// }
1386: // DesignerServiceHackProvider.refresh(project, dobj, deep);
1387: // }
1388: // public void refreshDataObject(DataObject dobj, boolean deep) {
1389: //// DesignerServiceHackProvider.refreshDataObject(dobj, deep);
1390: // RefreshServiceImpl.refreshDataObject(dobj, deep);
1391: // }
1392: // public void refreshProject(Project project, boolean deep) {
1393: // DesignerServiceHackProvider.refreshProject(project, deep);
1394: // }
1395:
1396: // public void destroyWebFormForFileObject(FileObject fo) {
1397: //// WebForm webform = WebForm.findWebFormForFileObject(fo);
1398: //// if (webform != null) {
1399: //// webform.destroy();
1400: //// WebForm.removeWebFormForFileObject(fo);
1401: //// }
1402: // DesignerServiceHackProvider.destroyWebFormForFileObject(fo);
1403: // }
1404:
1405: // public void detachTopComponentForDataObject(DataObject dobj) {
1406: // if (WebForm.hasWebFormForDataObject(dobj)) {
1407: // WebForm webform = WebForm.getWebFormForDataObject(dobj);
1408: // webform.detachTopComponent();
1409: // }
1410: // }
1411:
1412: // public MultiViewElement getMultiViewElementForDataObject(DataObject dobj) {
1413: // if (WebForm.isWebFormDataObject(dobj)) {
1414: // WebForm webform = WebForm.getWebFormForDataObject(dobj);
1415: // webform.createTopComponent();
1416: //
1417: // return webform.getTopComponent();
1418: // }
1419: //
1420: // return null;
1421: // }
1422:
1423: // /**
1424: // * Attempt to locate the current design view in use; may return
1425: // * null if no designer is found.
1426: // */
1427: // private static DesignerTopComp findCurrent() {
1428: // // Fish for the designer pane
1429: // DesignerTopComp formView = null;
1430: //
1431: // // Search through workspaces, then modes, then topcomponents
1432: // Set modes = WindowManager.getDefault().getModes();
1433: // Iterator it2 = modes.iterator();
1434: //
1435: // while (it2.hasNext()) {
1436: // Mode m = (Mode)it2.next();
1437: // TopComponent[] tcs = m.getTopComponents();
1438: //
1439: // if (tcs != null) {
1440: // for (int j = 0; j < tcs.length; j++) {
1441: // if (!tcs[j].isShowing()) {
1442: // continue;
1443: // }
1444: //
1445: // // Go hunting for our DesignerTopComp
1446: // DesignerTopComp comp = findDesigner(tcs[j], 0);
1447: //
1448: // if (comp != null) {
1449: // if (comp.isShowing()) {
1450: // return comp;
1451: // }
1452: // }
1453: // }
1454: // }
1455: //
1456: // if (formView != null) {
1457: // break;
1458: // }
1459: // }
1460: //
1461: // return formView;
1462: // }
1463: //
1464: // /** Fish for a DesignerPane within a container hierarchy
1465: // */
1466: // private static DesignerTopComp findDesigner(Container c, int depth) {
1467: // if (c == null) {
1468: // return null;
1469: // }
1470: //
1471: // // Only look slightly into the hiearchy since TopComponents should
1472: // // be near the top
1473: // if (depth == 4) {
1474: // return null;
1475: // }
1476: //
1477: // depth++;
1478: //
1479: // int n = c.getComponentCount();
1480: //
1481: // for (int i = 0; i < n; i++) {
1482: // java.awt.Component child = c.getComponent(i);
1483: //
1484: // if (child instanceof DesignerTopComp) {
1485: // return (DesignerTopComp)child;
1486: // } else if (child instanceof Container) {
1487: // DesignerTopComp result = findDesigner((Container)child, depth);
1488: //
1489: // if (result != null) {
1490: // return result;
1491: // }
1492: // }
1493: // }
1494: //
1495: // return null;
1496: // }
1497:
1498: // public float getBlockWidth(Element element) {
1499: // return CssBox.getBlockWidth(element);
1500: // }
1501: //
1502: // public float getBlockHeight(Element element) {
1503: // return CssBox.getBlockHeight(element);
1504: // }
1505:
1506: public void copyBoxForElement(Element fromElement, Element toElement) {
1507: // CssBox.copyBoxForElement(fromElement, toElement);
1508: // DesignerServiceHackProvider.copyBoxForElement(fromElement, toElement);
1509: Designer[] designers = JsfForm
1510: .findDesignersForElement(toElement);
1511: for (Designer designer : designers) {
1512: designer.copyBoxForElement(fromElement, toElement);
1513: }
1514: }
1515:
1516: // <missing designtime api>
1517:
1518: // <separation of models>
1519: public FileObject getContextFileForFragmentFile(
1520: FileObject fragmentFile) {
1521: // WebForm webform = WebForm.findWebFormForFileObject(fragmentFile);
1522: // WebForm contextWebform;
1523: // if (webform == null) {
1524: // contextWebform = null;
1525: // } else {
1526: // contextWebform = webform.getContextPage();
1527: // }
1528: //
1529: // return contextWebform == null ? null : contextWebform.getModel().getMarkupFile();
1530: // return DesignerServiceHackProvider.getContextFileForFragmentFile(fragmentFile);
1531: // WebForm webform = WebForm.findWebFormForFileObject(fragmentFile);
1532: JsfForm jsfForm = JsfForm.findJsfForm(fragmentFile);
1533:
1534: // WebForm contextWebform;
1535: // if (webform == null) {
1536: // contextWebform = null;
1537: // } else {
1538: // contextWebform = webform.getContextPage();
1539: // }
1540: JsfForm contextJsfForm = jsfForm == null ? null : jsfForm
1541: .getContextJsfForm();
1542:
1543: // return contextWebform == null ? null : contextWebform.getModel().getMarkupFile();
1544: // if (contextWebform == null) {
1545: if (contextJsfForm == null) {
1546: return null;
1547: }
1548: // DataObject jspDataObject = contextWebform.getJspDataObject();
1549: DataObject jspDataObject = contextJsfForm.getJspDataObject();
1550: return jspDataObject == null ? null : jspDataObject
1551: .getPrimaryFile();
1552: }
1553:
1554: public FileObject getExternalFormFileForElement(Element element) {
1555: // CssBox includeBox = CssBox.getBox(element);
1556: //
1557: // if ((includeBox != null) && includeBox instanceof JspIncludeBox) {
1558: // WebForm frameForm = ((JspIncludeBox)includeBox).getExternalForm();
1559: //
1560: // if ((frameForm != null) && (frameForm != WebForm.EXTERNAL)) {
1561: // return frameForm.getModel().getMarkupFile();
1562: // }
1563: // }
1564: // return null;
1565: // return DesignerServiceHackProvider.getExternalFormFileForElement(element);
1566: JsfForm jsfForm = JsfForm.findJsfForm(element);
1567: if (jsfForm == null) {
1568: return null;
1569: }
1570:
1571: // XXX Instead of traversing the boxes, traverse the elements directly.
1572: // CssBox includeBox = CssBox.getBox(element);
1573: Designer[] designers = JsfForm.findDesigners(jsfForm);
1574: if (designers.length == 0) {
1575: return null;
1576: }
1577: Designer designer = designers[0];
1578: Box includeBox = designer.findBoxForElement(element);
1579:
1580: if (includeBox instanceof ExternalBox) {
1581: DomProvider domProvider = ((ExternalBox) includeBox)
1582: .getExternalDomProvider();
1583: JsfForm frameForm = JsfForm
1584: .findJsfFormForDomProvider(domProvider);
1585:
1586: // if ((frameForm != null) && (frameForm != WebForm.EXTERNAL)) {
1587: if (frameForm != null) {
1588: // return frameForm.getModel().getMarkupFile();
1589: DataObject jspDataObject = frameForm.getJspDataObject();
1590: return jspDataObject == null ? null : jspDataObject
1591: .getPrimaryFile();
1592: }
1593: }
1594: return null;
1595: }
1596:
1597: // </separation of models>
1598:
1599: // </missing designtime api>
1600:
1601: // /**
1602: // * XXX Horrible method, too long, needs to be refactored, it is unreadable now.
1603: // * Paint a preview of the given component, with the given CSS style
1604: // * applied, and return it as an image. Use the preferred initial
1605: // * width, unless the component is larger.
1606: // */
1607: // private static BufferedImage paintCssPreview(Graphics2D g2d, URL base, Map properties, int width, int height) {
1608: // // Restore?
1609: // BufferedImage image = null;
1610: //
1611: // if (g2d != null) {
1612: // GraphicsConfiguration config = g2d.getDeviceConfiguration();
1613: // image = config.createCompatibleImage(width, height);
1614: // } else {
1615: // image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
1616: // }
1617: //
1618: // if (image == null) {
1619: // return null;
1620: // }
1621: //
1622: // Graphics2D og = (Graphics2D)image.getGraphics();
1623: //
1624: // try {
1625: //// RaveDocument doc = null;
1626: // // <markup_separation>
1627: //// XhtmlCssEngine engine = XhtmlCssEngine.create(doc, null, base);
1628: // // ====
1629: //// XhtmlCssEngine engine = XhtmlCssEngine.create(null, base);
1630: ////// <moved from engine impl> it doesn't (shoudn't) know about RaveDocument.
1631: ////// if (doc != null) {
1632: ////// doc.setCssEngine(engine);
1633: ////// }
1634: ////// </moved from engine impl>
1635: // Document fakeDocument = new FakeDocument();
1636: // CssEngineService cssEngineService = CssProvider.getEngineService();
1637: // cssEngineService.createCssEngineForDocument(fakeDocument, null);
1638: //// XhtmlCssEngine engine = CssEngineServiceProvider.getDefault().getCssEngine(fakeDocument);
1639: //
1640: // // </markup_separation>
1641: //// engine.setErrorHandler(XhtmlCssEngine.SILENT_ERROR_HANDLER);
1642: // cssEngineService.setSilentErrorHandlerForDocument(fakeDocument);
1643: //
1644: //// String styles = engine.mapToStyle(properties);
1645: // String styles = cssEngineService.getStringFromStyleMapForDocument(fakeDocument, properties);
1646: //// PreviewElement element = new PreviewElement(fakeDocument, /*engine,*/ base, styles);
1647: // Element element = cssEngineService.createPreviewElementForDocument(fakeDocument, base, styles);
1648: //
1649: //// Color bg = CssLookup.getColor(element, XhtmlCss.BACKGROUND_COLOR_INDEX);
1650: // Color bg = CssProvider.getValueService().getColorForElement(element, XhtmlCss.BACKGROUND_COLOR_INDEX);
1651: //
1652: // if (bg != null) {
1653: // og.setColor(bg);
1654: // og.fillRect(0, 0, width, height);
1655: // } else {
1656: // // Use a transparent color.... any will do!
1657: // // Color curr = g2d.getColor();
1658: // // og.setColor(new Color(curr.getRed(), curr.getGreen(), curr.getBlue(), 0));
1659: // //og.setColor(new Color(0, 0, 0, 0));
1660: // bg = (Color)UIManager.getDefaults().get("Label.background"); // NOI18N
1661: // og.setColor(bg);
1662: // og.fillRect(0, 0, width, height);
1663: // }
1664: //
1665: // // ImageIcon bgImage = BackgroundImagePainter.getBackgroundImage(doc, element);
1666: //// ImageIcon bgImage = BackgroundImagePainter.getBackgroundImage(base, element);
1667: // URL imageUrl = CssBoxUtilities.getBackgroundImageUrl(element, base);
1668: // ImageIcon bgImage = imageUrl == null ? null : new ImageIcon(imageUrl);
1669: //
1670: // if (bgImage != null) {
1671: //// Value repeatValue = CssLookup.getValue(element, XhtmlCss.BACKGROUND_REPEAT_INDEX);
1672: // CssValue cssRepeatValue = CssProvider.getEngineService().getComputedValueForElement(element, XhtmlCss.BACKGROUND_REPEAT_INDEX);
1673: //// ListValue positionValue =
1674: //// CssLookup.getListValue(CssLookup.getValue(element,
1675: //// XhtmlCss.BACKGROUND_POSITION_INDEX));
1676: // CssListValue cssPositionValue = CssProvider.getValueService().getComputedCssListValue(
1677: // CssProvider.getEngineService().getComputedValueForElement(element, XhtmlCss.BACKGROUND_POSITION_INDEX));
1678: //// BackgroundImagePainter bgPainter =
1679: //// new BackgroundImagePainter(bgImage, repeatValue, positionValue);
1680: // BackgroundImagePainter bgPainter = new BackgroundImagePainter(bgImage, cssRepeatValue, cssPositionValue);
1681: //
1682: // if (bgPainter != null) {
1683: // bgPainter.paint(og, 0, 0, width, height);
1684: // }
1685: // }
1686: //
1687: // boolean hasText = false;
1688: // boolean hasBorder = false;
1689: // boolean hasPosition = false;
1690: // Iterator it = properties.keySet().iterator();
1691: //
1692: // while (it.hasNext()) {
1693: // String property = (String)it.next();
1694: //
1695: //// if (isPositionProperty(property)) {
1696: // if (CssProvider.getValueService().isPositionProperty(property)) {
1697: // hasPosition = true;
1698: // }
1699: //
1700: //// if (isTextProperty(property)) {
1701: // if (CssProvider.getValueService().isTextProperty(property)) {
1702: // // Insert text
1703: // hasText = true;
1704: // }
1705: //
1706: //// if (isBorderProperty(property)) {
1707: // if (property.startsWith("border-")) { // NOI18N
1708: // hasBorder = true;
1709: // }
1710: // }
1711: //
1712: //// if (hasPosition) {
1713: //// // Do some position painting (abbreviated)
1714: //// }
1715: //
1716: // CssBorder border = null;
1717: //
1718: // if (hasBorder) {
1719: // // Paint border
1720: // // XXX If you just set ONE property (like color) but
1721: // // not solid or anything else, we don't preview! That's not good...
1722: // border = CssBorder.getBorder(element);
1723: //
1724: // if (border != null) {
1725: // border.paintBorder(og, 0, 0, width, height);
1726: // }
1727: // }
1728: //
1729: // if (hasText) {
1730: // // Paint text
1731: // // Check font size and attributes
1732: // int decoration = 0;
1733: // Color fg = Color.black;
1734: // FontMetrics metrics = null;
1735: // //boolean collapseSpaces = true;
1736: // //boolean hidden = false;
1737: //// metrics = CssLookup.getFontMetrics(element);
1738: // metrics = CssProvider.getValueService().getFontMetricsForElement(element);
1739: //// fg = CssLookup.getColor(element, XhtmlCss.COLOR_INDEX);
1740: // fg = CssProvider.getValueService().getColorForElement(element, XhtmlCss.COLOR_INDEX);
1741: //
1742: // if (fg == null) {
1743: // if (fg == null) {
1744: // fg = Color.black;
1745: // }
1746: // }
1747: //
1748: //// Value val = CssLookup.getValue(element, XhtmlCss.TEXT_DECORATION_INDEX);
1749: // CssValue cssValue = CssProvider.getEngineService().getComputedValueForElement(element, XhtmlCss.TEXT_DECORATION_INDEX);
1750: //
1751: //// switch (val.getCssValueType()) {
1752: //// case CSSValue.CSS_VALUE_LIST:
1753: ////
1754: //// ListValue lst = CssLookup.getListValue(val);
1755: ////
1756: //// if (lst == null) {
1757: //// break;
1758: //// }
1759: // CssListValue cssList = CssProvider.getValueService().getComputedCssListValue(cssValue);
1760: // if (cssList != null) {
1761: //
1762: //// int len = lst.getLength();
1763: // int len = cssList.getLength();
1764: //
1765: // for (int i = 0; i < len; i++) {
1766: //// Value v = lst.item(i);
1767: // CssValue cssV = cssList.item(i);
1768: //// String s = v.getStringValue();
1769: // String s = cssV.getStringValue();
1770: //
1771: // switch (s.charAt(0)) {
1772: // case 'u':
1773: // decoration |= TextBox.UNDERLINE;
1774: //
1775: // break;
1776: //
1777: // case 'o':
1778: // decoration |= TextBox.OVERLINE;
1779: //
1780: // break;
1781: //
1782: // case 'l':
1783: // decoration |= TextBox.STRIKE;
1784: //
1785: // break;
1786: // }
1787: // }
1788: //
1789: //// break;
1790: //// default:
1791: // } else {
1792: // // XXX what happened?
1793: // }
1794: //
1795: // // XXX Technically, should check for decoration=="overline" too...
1796: // // (See section 16.3.1). However, does that have ANY practical
1797: // // utility?
1798: //// val = CssLookup.getValue(element, XhtmlCss.WHITE_SPACE_INDEX);
1799: ////
1800: //// if ((val == CssValueConstants.PRE_VALUE) ||
1801: //// (val == CssValueConstants.PRE_WRAP_VALUE)) {
1802: //// collapseSpaces = false;
1803: //// }
1804: //
1805: // String content = "ABCabc123";
1806: //// Value v1 = CssLookup.getValue(element, XhtmlCss.FONT_VARIANT_INDEX);
1807: //// Value v2 = CssLookup.getValue(element, XhtmlCss.TEXT_TRANSFORM_INDEX);
1808: // CssValue cssV1 = CssProvider.getEngineService().getComputedValueForElement(element, XhtmlCss.FONT_VARIANT_INDEX);
1809: // CssValue cssV2 = CssProvider.getEngineService().getComputedValueForElement(element, XhtmlCss.TEXT_TRANSFORM_INDEX);
1810: //
1811: //// if ((v1 == CssValueConstants.SMALL_CAPS_VALUE) ||
1812: //// (v2 == CssValueConstants.UPPERCASE_VALUE)) {
1813: // if (CssProvider.getValueService().isSmallCapsValue(cssV1)
1814: // || CssProvider.getValueService().isUpperCaseValue(cssV2)) {
1815: // // Uppercase the text
1816: // content = content.toUpperCase();
1817: //
1818: // // TODO (much later): split the text up like under capitalization
1819: // // and apply different fonts to the initial letters
1820: // // and the rest of the words. I can't trivially do that
1821: // // here because I would create separate TextBoxes for the
1822: // // initial character and the rest of the words, and this
1823: // // COULD be split up both in text justification and in word
1824: // // wrapping by the LineBox and LineBoxGroup containers, which
1825: // // would be visually disasterous. I think the painting of
1826: // // this would really have to be done in the TextBox itself.
1827: //// } else if (v2 == CssValueConstants.LOWERCASE_VALUE) {
1828: // } else if (CssProvider.getValueService().isLowerCaseValue(cssV2)) {
1829: // content = content.toLowerCase();
1830: //// } else if (v2 == CssValueConstants.CAPITALIZE_VALUE) {
1831: // } else if (CssProvider.getValueService().isCapitalizeValue(cssV2)) {
1832: // content = "Abcabc123";
1833: // }
1834: //
1835: //// int leftMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_LEFT_INDEX);
1836: // int leftMargin = CssBox.getCssLength(element, XhtmlCss.MARGIN_LEFT_INDEX);
1837: //// int rightMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_RIGHT_INDEX);
1838: //// int topMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_TOP_INDEX);
1839: // int topMargin = CssBox.getCssLength(element, XhtmlCss.MARGIN_TOP_INDEX);
1840: //// int bottomMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_BOTTOM_INDEX);
1841: //
1842: //// int leftPadding = CssLookup.getLength(element, XhtmlCss.PADDING_LEFT_INDEX);
1843: //// int rightPadding = CssLookup.getLength(element, XhtmlCss.PADDING_RIGHT_INDEX);
1844: // int leftPadding = CssBox.getCssLength(element, XhtmlCss.PADDING_LEFT_INDEX);
1845: // int rightPadding = CssBox.getCssLength(element, XhtmlCss.PADDING_RIGHT_INDEX);
1846: //
1847: // // Unlike margins, padding values are not allowed to be negative!
1848: // if (leftPadding < 0) {
1849: // leftPadding = 0;
1850: // }
1851: //
1852: // if (rightPadding < 0) {
1853: // rightPadding = 0;
1854: // }
1855: //
1856: //// int topPadding = CssLookup.getLength(element, XhtmlCss.PADDING_TOP_INDEX);
1857: //// int bottomPadding = CssLookup.getLength(element, XhtmlCss.PADDING_BOTTOM_INDEX);
1858: // int topPadding = CssBox.getCssLength(element, XhtmlCss.PADDING_TOP_INDEX);
1859: // int bottomPadding = CssBox.getCssLength(element, XhtmlCss.PADDING_BOTTOM_INDEX);
1860: //
1861: // if (topPadding < 0) {
1862: // topPadding = 0;
1863: // }
1864: //
1865: // if (bottomPadding < 0) {
1866: // bottomPadding = 0;
1867: // }
1868: //
1869: // int leftBorderWidth = 0;
1870: // int topBorderWidth = 0;
1871: //// int rightBorderWidth = 0;
1872: //// int bottomBorderWidth = 0;
1873: //
1874: // if (border != null) {
1875: // leftBorderWidth = border.getLeftBorderWidth();
1876: // topBorderWidth = border.getTopBorderWidth();
1877: //// bottomBorderWidth = border.getBottomBorderWidth();
1878: //// rightBorderWidth = border.getRightBorderWidth();
1879: // }
1880: //
1881: // int x = leftMargin + leftBorderWidth + leftPadding;
1882: // int y = topMargin + topBorderWidth + topPadding;
1883: // og.setColor(fg);
1884: // og.setFont(metrics.getFont());
1885: //
1886: // // determine the y coordinate to render the glyphs
1887: // int yadj = (y + metrics.getHeight()) - metrics.getDescent();
1888: //
1889: // // Draw text!
1890: // char[] contentChars = content.toCharArray();
1891: // og.drawChars(contentChars, 0, contentChars.length, x, yadj);
1892: //
1893: // // render underline or strikethrough if set.
1894: // if (decoration != 0) {
1895: // int textWidth =
1896: // DesignerUtils.getNonTabbedTextWidth(contentChars, 0, contentChars.length,
1897: // metrics);
1898: //
1899: // if ((decoration & TextBox.UNDERLINE) != 0) {
1900: // int yTmp = yadj;
1901: // yTmp += 1;
1902: // og.drawLine(x, yTmp, x + textWidth, yTmp);
1903: // }
1904: //
1905: // if ((decoration & TextBox.STRIKE) != 0) {
1906: // int yTmp = yadj;
1907: //
1908: // // move y coordinate above baseline
1909: // yTmp -= (int)(metrics.getAscent() * 0.4f);
1910: // og.drawLine(x, yTmp, x + textWidth, yTmp);
1911: // }
1912: //
1913: // if ((decoration & TextBox.OVERLINE) != 0) {
1914: // og.drawLine(x, y, x + textWidth, y);
1915: // }
1916: // }
1917: // }
1918: // } finally {
1919: // og.dispose();
1920: // }
1921: //
1922: // return image;
1923: // }
1924:
1925: // XXX Hack.
1926: private static MarkupDesignBean adjustRenderBeanHack(
1927: MarkupDesignBean renderBean) {
1928: // Handle hyperlinks. We really need to render its surrounding content
1929: // to see the CS stylerules for <a> apply
1930: if (renderBean.getInstance() instanceof HtmlOutputText) {
1931: DesignBean parent = renderBean.getBeanParent();
1932:
1933: if ((parent != null)
1934: && (parent.getChildBeanCount() == 1)
1935: && (parent.getInstance() instanceof HtmlCommandLink || parent
1936: .getInstance() instanceof HtmlOutputLink)) {
1937: renderBean = (MarkupDesignBean) parent;
1938: }
1939: }
1940:
1941: // Embedded table portions (rowgroups, columns) aren't happy being rendered
1942: // without their surrounding table.
1943: // It would be better to modify the preview code to actually go and -try- rendering
1944: // components and then progressively retry on parents until it succeeds.
1945: // But given that the code is freezing today I'm playing it safe
1946: if (renderBean.getInstance() instanceof com.sun.rave.web.ui.component.TableColumn
1947: || renderBean.getInstance() instanceof com.sun.webui.jsf.component.TableColumn) {
1948: if (renderBean.getBeanParent() instanceof MarkupDesignBean) {
1949: renderBean = (MarkupDesignBean) renderBean
1950: .getBeanParent();
1951: } else {
1952: return null;
1953: }
1954: } else if (renderBean.getBeanParent().getInstance() instanceof com.sun.rave.web.ui.component.TableColumn
1955: || renderBean.getBeanParent().getInstance() instanceof com.sun.webui.jsf.component.TableColumn) {
1956: // We also have to render components that are children of a TableColumn as part of the whole
1957: // table as well, because their value binding expressions can involve data providers set up
1958: // by the table. This is clearly not a clean solution. See comment above about trying arbitary
1959: // rendering instead. This breaks once you nest components in a column inside a container
1960: // component for example. Just doing a low risk, 90% fix now right before FCS.
1961: if (renderBean.getBeanParent().getBeanParent() instanceof MarkupDesignBean) {
1962: renderBean = (MarkupDesignBean) renderBean
1963: .getBeanParent().getBeanParent();
1964: } else {
1965: return null;
1966: }
1967: }
1968:
1969: // Not else: a TableColumn can be inside a TableRowGroup so keep moving outwards if necessary:
1970: if (renderBean.getInstance() instanceof com.sun.rave.web.ui.component.TableRowGroup
1971: || renderBean.getInstance() instanceof com.sun.webui.jsf.component.TableRowGroup) {
1972: if (renderBean.getBeanParent() instanceof MarkupDesignBean) {
1973: renderBean = (MarkupDesignBean) renderBean
1974: .getBeanParent();
1975: } else {
1976: return null;
1977: }
1978: }
1979: return renderBean;
1980: }
1981:
1982: // XXX Moved from designer/../DesignerUtils.
1983: //// Same as style set in Text renderer and in default style sheet
1984: // private static final String ignoreClass = "rave-uninitialized-text"; // NOI18N
1985:
1986: // XXX Moved from designer/../DesignerUtils.
1987: /** Recursively remove the rave-uninitialized-text class attribute
1988: * from a node tree.
1989: * @return True iff any nodes were actually changed
1990: */
1991: // private static boolean stripDesignStyleClasses(Node node) {
1992: // boolean changedStyles = false;
1993: //
1994: //// if(DEBUG) {
1995: //// debugLog(DesignerUtils.class.getName() + ".stripDesignStyleClasses(Node)");
1996: //// }
1997: // if(node == null) {
1998: // throw(new IllegalArgumentException("Null node."));// NOI18N
1999: // }
2000: //
2001: // if (node.getNodeType() == Node.ELEMENT_NODE) {
2002: // Element e = (Element)node;
2003: //
2004: // if (e.getAttribute(HtmlAttribute.CLASS).indexOf(ignoreClass) != -1) {
2005: // String newClass = e.getAttribute(HtmlAttribute.CLASS).replaceAll(ignoreClass, ""); // ignore stripped out
2006: // e.setAttribute(HtmlAttribute.CLASS, newClass);
2007: // changedStyles = true;
2008: // }
2009: // }
2010: //
2011: // NodeList nl = node.getChildNodes();
2012: //
2013: // for (int i = 0, n = nl.getLength(); i < n; i++) {
2014: // changedStyles |= stripDesignStyleClasses(nl.item(i)); // recurse
2015: // }
2016: //
2017: // return changedStyles;
2018: // }
2019: }
|