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:
0042: package org.netbeans.modules.visualweb.designer;
0043:
0044: import org.netbeans.modules.visualweb.api.designer.cssengine.CssEngineService;
0045: import org.netbeans.modules.visualweb.api.designer.cssengine.CssListValue;
0046: import org.netbeans.modules.visualweb.api.designer.cssengine.CssProvider;
0047: import org.netbeans.modules.visualweb.api.designer.cssengine.CssValue;
0048: import org.netbeans.modules.visualweb.api.designer.cssengine.XhtmlCss;
0049: import org.netbeans.modules.visualweb.css2.BackgroundImagePainter;
0050: import org.netbeans.modules.visualweb.css2.CssBorder;
0051: import org.netbeans.modules.visualweb.css2.CssBox;
0052: import org.netbeans.modules.visualweb.designer.CssUtilities;
0053: import org.netbeans.modules.visualweb.css2.PageBox;
0054: import org.netbeans.modules.visualweb.css2.TableBox;
0055:
0056: import java.awt.Color;
0057: import java.awt.FontMetrics;
0058: import java.awt.Graphics2D;
0059: import java.awt.GraphicsConfiguration;
0060: import java.awt.Image;
0061: import java.awt.image.BufferedImage;
0062: import java.net.URL;
0063: import java.util.Iterator;
0064: import java.util.Map;
0065: import javax.swing.ImageIcon;
0066: import javax.swing.UIManager;
0067:
0068: import org.apache.xerces.dom.DocumentImpl;
0069: import org.netbeans.modules.visualweb.api.designer.Designer;
0070: import org.openide.windows.WindowManager;
0071: import org.w3c.dom.Document;
0072: import org.w3c.dom.DocumentFragment;
0073: import org.w3c.dom.Element;
0074:
0075: /**
0076: * Implementation of the DesignerService API.
0077: * <p>
0078: *
0079: * @todo The css value lookup methods need to do something smarter
0080: * for shorthand properties
0081: * @author Tor Norbye
0082: */
0083: public final class DesignerServiceHackProviderImpl /*extends DesignerServiceHack*/{
0084: // private static final String[] LENGTH_UNITS =
0085: // { "%", "em", "ex", "px", "cm", "mm", "in", "pt", "pc" };
0086: // private static volatile String[] properties;
0087:
0088: // /**
0089: // * The following mime types are valid mime types for files
0090: // * that will be considered webforms in the WebAppProject
0091: // */
0092: // private static final String[] FORM_MIME_TYPES = new String[] { "text/x-jsp" }; // NOI18N
0093:
0094: // /** For temporary use by getCurrentDesigner runnable */
0095: // private static transient TopComponent temptc;
0096:
0097: private DesignerServiceHackProviderImpl() {
0098: }
0099:
0100: // private static FacesPageUnit getFacesUnit(DesignContext context) {
0101: // LiveUnit lu = (LiveUnit)context;
0102: //
0103: // // Find the model
0104: // BeansUnit bu = lu.getBeansUnit();
0105: //
0106: // if (!(bu instanceof FacesPageUnit)) {
0107: // return null;
0108: // }
0109: //
0110: // return (FacesPageUnit)bu;
0111: // }
0112:
0113: // public static Image getCssPreviewImage(String cssStyle, String[] cssStyleClasses,
0114: // MarkupDesignBean bean, int width, int height) {
0115: // if (bean.getElement() == null) {
0116: // return null;
0117: // }
0118: //
0119: // FacesPageUnit fu = getFacesUnit(bean.getDesignContext());
0120: //
0121: // if (fu == null) {
0122: // return null;
0123: // }
0124: //
0125: // MarkupUnit mu = fu.getPageUnit();
0126: // FileObject fo = mu.getFileObject();
0127: // DataObject dobj = null;
0128: //
0129: // try {
0130: // dobj = DataObject.find(fo);
0131: // } catch (DataObjectNotFoundException ex) {
0132: // return null;
0133: // }
0134: //
0135: // WebForm webform = DesignerUtils.getWebForm(dobj);
0136: public static Image getCssPreviewImage(
0137: /*DataObject dataObject,*/Designer designer,
0138: Graphics2D g2d, String cssStyle, String[] cssStyleClasses,
0139: /*MarkupDesignBean bean,*/Element componentRootElement,
0140: DocumentFragment df, Element element, int width, int height) {
0141: // WebForm webform = WebForm.getWebFormForDataObject(dataObject);
0142: //
0143: // if (webform == null) {
0144: // return null;
0145: // }
0146: if (!(designer instanceof WebForm)) {
0147: return null;
0148: }
0149:
0150: WebForm webform = (WebForm) designer;
0151:
0152: // Phew! On to the preview painting.
0153: PageBox pageBox = PageBox.getPageBox(null, webform, webform
0154: .getHtmlBody());
0155: // WindowManager wm = WindowManager.getDefault();
0156: // Graphics2D g2d = (Graphics2D)wm.getMainWindow().getGraphics();
0157:
0158: return pageBox.paintCssPreview(g2d, cssStyle,
0159: /*bean,*/componentRootElement, df, element, width, height);
0160: }
0161:
0162: public static Image getCssPreviewImage(
0163: Map<String, String> properties, URL base, int width,
0164: int height, int defaultFontSize) {
0165: WindowManager wm = WindowManager.getDefault();
0166: Graphics2D g2d = (Graphics2D) wm.getMainWindow().getGraphics();
0167:
0168: return paintCssPreview(g2d, base, properties, width, height,
0169: defaultFontSize);
0170: }
0171:
0172: /** Computes a preview image of the specified size for given <code>DataObject</code>.
0173: * @return the image or <code>null</code> if the specified DataObject is not a webform one. */
0174: // public static Image getPageBoxPreviewImage(DataObject dobj, int width, int height) {
0175: // // Copied from navigation/../PageFlowGraph to get rid of dependencies.
0176: // // Obtain a page box for the given page
0177: // WebForm webform = DesignerUtils.getWebForm(dobj);
0178: public static Image getPageBoxPreviewImage(
0179: /*DataObject dobj,*/Designer designer, int width,
0180: int height) {
0181: // WebForm webform = WebForm.getWebFormForDataObject(dobj);
0182: //
0183: // if (webform == null) {
0184: // return null;
0185: // }
0186: if (!(designer instanceof WebForm)) {
0187: return null;
0188: }
0189:
0190: WebForm webform = (WebForm) designer;
0191:
0192: // XXX Moved to designer/jsf/../DesignerHackImpl.
0193: //// webform.getModel().sync();
0194: // webform.syncModel();
0195: //
0196: //// if (webform.getModel().isBusted()) {
0197: // if (webform.isModelBusted()) {
0198: // return null;
0199: // }
0200:
0201: Element body = webform.getHtmlBody();
0202:
0203: if (body == null) {
0204: return null;
0205: }
0206:
0207: PageBox pageBox = PageBox.getPageBox(null, webform, body);
0208:
0209: return pageBox.createPreviewImage(width, height);
0210: }
0211:
0212: // public String[] getCssIdentifiers(String propertyName) {
0213: //// StringMap map = getIdentifiers(propertyName);
0214: ////
0215: //// if (map == null) {
0216: //// return new String[0];
0217: //// }
0218: ////
0219: //// int count = map.size();
0220: //// ArrayList keys = new ArrayList(count);
0221: //// Iterator it = map.keys();
0222: ////
0223: //// while (it.hasNext()) {
0224: //// Object o = it.next();
0225: //// keys.add(o);
0226: //// }
0227: ////
0228: //// keys.add("inherit");
0229: //// Collections.sort(keys);
0230: ////
0231: //// return (String[])keys.toArray(new String[keys.size()]);
0232: // return CssProvider.getEngineService().getCssIdentifiers(propertyName);
0233: // }
0234:
0235: // // public Object[] getCssIdentifierValues(String propertyName) {
0236: // // StringMap map = getIdentifiers(propertyName);
0237: // // if (map == null) {
0238: // // return new Object[0];
0239: // // }
0240: // // int count = map.size();
0241: // // ArrayList values = new ArrayList(count);
0242: // // Iterator it = map.values();
0243: // // while (it.hasNext()) {
0244: // // Object o = it.next();
0245: // // values.add(o);
0246: // // }
0247: // // // TODO -- sort in the same order as the identifier names??
0248: // // return (Object[])values.toArray(new Object[values.size()]);
0249: // // }
0250: // private StringMap getIdentifiers(String property) {
0251: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
0252: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
0253: //
0254: // if (index == -1) {
0255: //// index = XhtmlCssEngine.getXhtmlShorthandIndex(property);
0256: // index = CssProvider.getEngineService().getXhtmlShorthandIndex(property);
0257: //
0258: // if (index == -1) {
0259: // return null;
0260: // }
0261: //
0262: // // XXX TODO! What do we do here?
0263: // return null;
0264: // }
0265: //
0266: //// ValueManager vm = XhtmlCssEngine.XHTML_VALUE_MANAGERS[index];
0267: // ValueManager vm = CssProvider.getEngineService().getXhtmlValueManagers()[index];
0268: //
0269: // if (vm instanceof IdentifierProvider) {
0270: // return ((IdentifierProvider)vm).getIdentifierMap();
0271: // }
0272: //
0273: // return null;
0274: // }
0275:
0276: // public String[] getCssLengthUnits() {
0277: // return LENGTH_UNITS;
0278: // }
0279:
0280: // /**
0281: // * {@inheritDoc}
0282: // *
0283: // * @todo Include properties that I'm not supporting/tracking in the
0284: // * designer yet!
0285: // */
0286: // public String[] getCssProperties() {
0287: //// if (properties == null) {
0288: ////// ValueManager[] vms = XhtmlCssEngine.XHTML_VALUE_MANAGERS;
0289: //// ValueManager[] vms = CssProvider.getEngineService().getXhtmlValueManagers();
0290: //// ArrayList list = new ArrayList(vms.length);
0291: ////
0292: //// for (int i = 0, n = vms.length; i < n; i++) {
0293: //// String property = vms[i].getPropertyName();
0294: ////
0295: //// if (property.charAt(0) != '-') { // don't include vendor-specific properties
0296: //// list.add(property);
0297: //// }
0298: //// }
0299: ////
0300: //// Collections.sort(list);
0301: //// properties = (String[])list.toArray(new String[list.size()]);
0302: //// }
0303: ////
0304: //// return properties;
0305: // return CssProvider.getEngineService().getCssProperties();
0306: // }
0307:
0308: // public CssValue getCssValue(MarkupDesignBean bean, String property) {
0309: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
0310: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
0311: //
0312: // if (index == -1) {
0313: // return null;
0314: // }
0315: //
0316: //// return CssLookup.getValue(bean.getElement(), index);
0317: // CssLookup.getCssValue(bean.getElement(), index);
0318: // }
0319:
0320: // public Map convertCssStyleToMap(DesignContext context, String cssStyle) {
0321: // if(DesignerUtils.DEBUG) {
0322: // DesignerUtils.debugLog(getClass().getName() + ".convertCssStyleToMap(DesignContext, String)");
0323: // }
0324: // if(context == null) {
0325: // throw(new IllegalArgumentException("Null context."));
0326: // }
0327: // if(cssStyle == null) {
0328: // throw(new IllegalArgumentException("Null style."));
0329: // }
0330: // return ((LiveUnit)context).convertCssStyleToMap(cssStyle);
0331: // }
0332: //
0333: // public String convertMapToCssStyle(DesignContext context, Map cssStyleMap) {
0334: // if(DesignerUtils.DEBUG) {
0335: // DesignerUtils.debugLog(getClass().getName() + ".convertMapToCssStyle(DesignContext, String)");
0336: // }
0337: // if(context == null) {
0338: // throw(new IllegalArgumentException("Null context."));
0339: // }
0340: // if(cssStyleMap == null) {
0341: // throw(new IllegalArgumentException("Null style."));
0342: // }
0343: // return ((LiveUnit)context).convertMapToCssStyle(cssStyleMap);
0344: // }
0345:
0346: // public String[] getHtmlTags() {
0347: // HtmlTag[] tags = HtmlTag.getTags();
0348: // ArrayList result = new ArrayList(tags.length);
0349: //
0350: // for (int i = 0; i < tags.length; i++) {
0351: // if (tags[i] == null) {
0352: // break;
0353: // }
0354: //
0355: // String name = tags[i].name;
0356: //
0357: // if (!name.startsWith("jsp:")) { // NOI18N
0358: // result.add(name);
0359: // }
0360: // }
0361: //
0362: // return (String[])result.toArray(new String[result.size()]);
0363: // }
0364:
0365: // /**
0366: // * Show the given line in a particular file.
0367: // *
0368: // * @param filename The full path to the file, or null. Exactly one of filename or fileObject
0369: // * should be non null.
0370: // * @param fileObject The FileObject for the file or null. Exactly one of filename or fileObject
0371: // * should be non null.
0372: // * @param lineno The line number
0373: // * @param openFirst Usually you'll want to pass false. When set to true, this will first open
0374: // * the file, then request the given line number; this works around certain bugs for
0375: // * some editor types like CSS files.
0376: // */
0377: // public void show(String filename, FileObject fileObject, int lineno, int column,
0378: // boolean openFirst) {
0379: // assert ((filename != null) && (fileObject == null)) ||
0380: // ((filename == null) && (fileObject != null));
0381: //
0382: // if (fileObject != null) {
0383: // show(fileObject, lineno, column, openFirst);
0384: // } else {
0385: // File file = new File(filename);
0386: // FileObject fo = FileUtil.toFileObject(file);
0387: //
0388: // if (fo != null) {
0389: // show(fo, lineno, column, openFirst);
0390: // }
0391: // }
0392: // }
0393: //
0394: // private static boolean show(FileObject fo, int lineno, int column, boolean openFirst) {
0395: // throw new RuntimeException("show not yet implemented");
0396: //
0397: // /*
0398: // boolean opened = false;
0399: // DataObject dobj;
0400: // try {
0401: // dobj = DataObject.find(fo);
0402: // }
0403: // catch (DataObjectNotFoundException ex) {
0404: // ErrorManager.getDefault().notify(ex);
0405: // return false;
0406: // }
0407: //
0408: // GenericItem item = GenericItem.findItem(dobj);
0409: // if (item != null) {
0410: // WebAppProject p = (WebAppProject)item.getProject();
0411: // if (p != null) {
0412: // FacesModelSet models = FacesModelSet.getInstance(p);
0413: // if (models != null) {
0414: // FacesModel model = models.getFacesModel(fo);
0415: // WebForm wf = WebForm.get(model);
0416: // if (wf != null && wf.getDataObject() != null) {
0417: // DataObject dobj2 = wf.getDataObject();
0418: // dobj = dobj2; ???
0419: // }
0420: // }
0421: // }
0422: // }
0423: //
0424: // if (dobj instanceof JSFDataObject) {
0425: // EditorCookie ec = (EditorCookie)dobj.getCookie(EditorCookie.class);
0426: // if (ec instanceof JSFEditorSupport) {
0427: // JSFEditorSupport jes = (JSFEditorSupport)ec;
0428: // if ("java".equalsIgnoreCase(fo.getExt())) {
0429: // jes.viewJavaSource(-1);
0430: // } else {
0431: // jes.viewJSPSource();
0432: // }
0433: // opened = true;
0434: // // How do we force the line number now? Do we have to or can we rely on the above?
0435: // }
0436: // }
0437: //
0438: // // Try to open doc before showing the line. This SHOULD not be
0439: // // necessary, except without this the IDE hangs in its attempt
0440: // // to open the file when the file in question is a CSS file.
0441: // // Probably a bug in the xml/css module's editorsupport code.
0442: // // This has the negative effect of first flashing the top
0443: // // of the file before showing the destination line, so
0444: // // this operation is made conditional so only clients who
0445: // // actually need it need to use it.
0446: // if (openFirst && !opened) {
0447: // EditorCookie ec = (EditorCookie)dobj.getCookie(EditorCookie.class);
0448: // if (ec != null) {
0449: // try {
0450: // ec.openDocument(); // ensure that it has been opened - REDUNDANT?
0451: // //ec.open();
0452: // }
0453: // catch (IOException ex) {
0454: // ErrorManager.getDefault().notify(ex);
0455: // }
0456: // }
0457: // }
0458: //
0459: // LineCookie lc = (LineCookie)dobj.getCookie(LineCookie.class);
0460: // if (lc != null) {
0461: // Line.Set ls = lc.getLineSet();
0462: // if (ls != null) {
0463: // // -1: convert line numbers to be zero-based
0464: // Line line = ls.getCurrent(lineno-1);
0465: // // TODO - pass in a column too?
0466: // line.show(Line.SHOW_GOTO, column);
0467: // return true;
0468: // }
0469: // }
0470: //
0471: // return false;
0472: // */
0473: // }
0474:
0475: // public static boolean canDrop(DataFlavor flavor) {
0476: // // Fish for the designer pane
0477: // DesignerTopComp dtc = findCurrent();
0478: //
0479: // if (dtc == null) {
0480: // return false;
0481: // }
0482: //
0483: // // TODO -- additional flavor checking?
0484: // return true;
0485: // }
0486:
0487: // public static void drop(Transferable transferable) {
0488: // // Fish for the "current" designer pane
0489: // DesignerTopComp dtc = findCurrent();
0490: //
0491: // if (dtc == null) {
0492: // return;
0493: // }
0494: //
0495: // DesignerPane pane = dtc.getWebForm().getPane();
0496: // TransferHandler dth = pane.getTransferHandler();
0497: //
0498: // // Drop it
0499: // dth.importData(pane, transferable);
0500: // }
0501:
0502: // public static void registerTransferable(Transferable transferable) {
0503: // if(DesignerUtils.DEBUG) {
0504: // DesignerUtils.debugLog(DesignerServiceHackProviderImpl.class.getName() + ".registerTransferable(Transferable)");
0505: // }
0506: // if(transferable == null) {
0507: // throw(new IllegalArgumentException("Null transferable."));
0508: // }
0509: //// DndHandler.setActiveTransferable(transferable);
0510: // }
0511:
0512: // private static TopComponent getCurrentDesigner() {
0513: // if (SwingUtilities.isEventDispatchThread()) {
0514: // return findCurrent();
0515: // } else {
0516: // // FIXME This is incorrect, it can't work.
0517: // // If this can work only in AWT thread,
0518: // // then it should be required on the client to be called only in that
0519: // // thread and not pretend othwerise.
0520: // try {
0521: // SwingUtilities.invokeAndWait(new Runnable() {
0522: // public void run() {
0523: // temptc = findCurrent();
0524: // }
0525: // });
0526: //
0527: // return temptc;
0528: // } catch (Exception e) {
0529: // ErrorManager.getDefault().notify(e);
0530: //
0531: // return null;
0532: // } finally {
0533: // temptc = null; // done after return value
0534: // }
0535: // }
0536: // }
0537:
0538: // public static FileObject getCurrentFile() {
0539: // DesignerTopComp tc = (DesignerTopComp)getCurrentDesigner();
0540: //
0541: //// if ((tc == null) || (tc.getWebForm().getMarkup() == null)) {
0542: // if (tc == null) {
0543: // return null;
0544: // }
0545: //
0546: //// return tc.getWebForm().getMarkup().getFileObject();
0547: // DataObject jspDataObject = tc.getWebForm().getJspDataObject();
0548: // return jspDataObject == null ? null : jspDataObject.getPrimaryFile();
0549: // }
0550:
0551: // public static void testPreview() {
0552: // DesignerService ds = DesignerService.getDefault();
0553: // HashMap properties = new HashMap();
0554: // properties.put("background-color", "red");
0555: // URL base = null;
0556: // int width = 200;
0557: // int height = 200;
0558: // BufferedImage img1 = (BufferedImage)ds.getCssPreviewImage(properties, base, width, height);
0559: // showScreenshot(img1);
0560: //
0561: // properties = new HashMap();
0562: // properties.put("border-color", "blue");
0563: // properties.put("border-width", "3px");
0564: // properties.put("border-style", "solid");
0565: // properties.put("font-size", "24pt");
0566: // properties.put("text-decoration", "underline");
0567: // base = null;
0568: // width = 300;
0569: // height = 300;
0570: // BufferedImage img2 = (BufferedImage)ds.getCssPreviewImage(properties, base, width, height);
0571: // showScreenshot(img2);
0572: //
0573: //
0574: // }
0575: //
0576: // protected static void showScreenshot(BufferedImage bi) {
0577: // try {
0578: // File tmp = File.createTempFile("designer", ".png");
0579: // tmp.deleteOnExit();
0580: // saveImage(bi, tmp);
0581: // showScreenshot(tmp);
0582: // } catch (java.io.IOException ioe) {
0583: // ErrorManager.getDefault().notify(ioe);
0584: // }
0585: // }
0586: //
0587: // /** Save the given image to disk */
0588: // protected static void saveImage(BufferedImage image, File file) {
0589: // try {
0590: // if (file.exists()) {
0591: // file.delete();
0592: // }
0593: // ImageIO.write(image, "png", file);
0594: // } catch (IOException e) {
0595: // System.err.println(e);
0596: // }
0597: // }
0598: //
0599: // protected static void showScreenshot(File file) {
0600: // URL url;
0601: // try {
0602: // url = new URL("file:" + file.getPath()); // NOI18N
0603: // } catch (MalformedURLException e) {
0604: // // Can't show URL
0605: // ErrorManager.getDefault().notify(e);
0606: // return;
0607: // }
0608: // URLDisplayer.getDefault().showURL(url);
0609: // }
0610: // public void parseCss(javax.swing.text.Document document, Object handler) {
0611: // if (!(handler instanceof org.w3c.css.sac.ErrorHandler)) {
0612: // throw new IllegalArgumentException("Handler must be org.w3c.css.sac.ErrorHandler");
0613: // }
0614: //
0615: // if (document == null) {
0616: // throw new IllegalArgumentException("document parameter should not be null!");
0617: // }
0618: //
0619: // // Parse document
0620: //// RaveDocument doc = null;
0621: // // <markup_separation>
0622: //// XhtmlCssEngine engine = XhtmlCssEngine.create(doc, null, null);
0623: // // ====
0624: //// XhtmlCssEngine engine = XhtmlCssEngine.create(null, null);
0625: ////// <moved from engine impl> it doesn't (shoudn't) know about RaveDocument.
0626: ////// if (doc != null) {
0627: ////// doc.setCssEngine(engine);
0628: ////// }
0629: ////// </moved from engine impl>
0630: // Document fakeDocument = new FakeDocument();
0631: // CssProvider.getEngineService().createCssEngineForDocument(fakeDocument, null);
0632: //// XhtmlCssEngine engine = CssEngineServiceProvider.getDefault().getCssEngine(fakeDocument);
0633: ////
0634: //// // </markup_separation>
0635: //// engine.setErrorHandler((ErrorHandler)handler);
0636: // CssProvider.getEngineService().setErrorHandlerForDocument(fakeDocument, (ErrorHandler)handler);
0637: //
0638: // String rules;
0639: //
0640: // try {
0641: // rules = document.getText(0, document.getLength());
0642: // } catch (javax.swing.text.BadLocationException e) {
0643: // ErrorManager.getDefault().notify(e);
0644: //
0645: // return;
0646: // }
0647: //
0648: //// engine.parseStyleSheet(rules, null, "all", null);
0649: // CssProvider.getEngineService().parseStyleSheetForDocument(fakeDocument, rules, null, "all", null); // NOI18N
0650: //// engine.setErrorHandler(null);
0651: // CssProvider.getEngineService().setErrorHandlerForDocument(fakeDocument, null);
0652: // }
0653:
0654: /** XXX Fake document, to be able to create engine.
0655: * TODO Better is just to impl the <code>Document</code> interface, without dep on xerces. */
0656: private static class FakeDocument extends DocumentImpl {
0657: } // End of FakeDocument.
0658:
0659: //// public static Object getTableInfo(MarkupDesignBean bean) {
0660: // public static Object getTableInfo(Element componentRootElement) {
0661: //// assert bean.getElement() != null;
0662: //
0663: //// Element element = bean.getElement();
0664: //// if (element == null) {
0665: //// ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL,
0666: //// new NullPointerException("There is no element in markup design bean=" + bean)); // NOI18N
0667: //// return null;
0668: //// }
0669: //
0670: // WebForm webForm = WebForm.findWebFormForElement(componentRootElement);
0671: // if (webForm == null) {
0672: // return null;
0673: // }
0674: //
0675: //// CssBox box = CssBox.getBox(bean.getElement());
0676: // CssBox box = webForm.findCssBoxForElement(componentRootElement);
0677: //
0678: // if (box instanceof TableBox) {
0679: // return box;
0680: // }
0681: //
0682: // return null;
0683: // }
0684: // XXX
0685: public static boolean isTableBox(Object box) {
0686: return box instanceof TableBox;
0687: }
0688:
0689: public static org.w3c.dom.Element getCellElement(Object tableInfo,
0690: int row, int column) {
0691: assert tableInfo instanceof TableBox;
0692:
0693: TableBox table = (TableBox) tableInfo;
0694: CssBox box = table.getCell(row, column);
0695:
0696: if (box == null) {
0697: return null;
0698: }
0699:
0700: return box.getElement();
0701: }
0702:
0703: // public static MarkupDesignBean getCellBean(Object tableInfo, int row, int column) {
0704: public static Element getCellComponent(Object tableInfo, int row,
0705: int column) {
0706: assert tableInfo instanceof TableBox;
0707:
0708: TableBox table = (TableBox) tableInfo;
0709: CssBox box = table.getCell(row, column);
0710:
0711: if (box == null) {
0712: return null;
0713: }
0714:
0715: // return box.getDesignBean();
0716: // return CssBox.getMarkupDesignBeanForCssBox(box);
0717: return CssBox.getElementForComponentRootCssBox(box);
0718: }
0719:
0720: public static int getColSpan(Object tableInfo, int row, int column) {
0721: assert tableInfo instanceof TableBox;
0722:
0723: TableBox table = (TableBox) tableInfo;
0724:
0725: return table.getCellSpan(CssBox.Y_AXIS, row, column);
0726: }
0727:
0728: public static int getRowSpan(Object tableInfo, int row, int column) {
0729: assert tableInfo instanceof TableBox;
0730:
0731: TableBox table = (TableBox) tableInfo;
0732:
0733: return table.getCellSpan(CssBox.X_AXIS, row, column);
0734: }
0735:
0736: public static int getColumnCount(Object tableInfo) {
0737: assert tableInfo instanceof TableBox;
0738:
0739: TableBox table = (TableBox) tableInfo;
0740:
0741: return table.getColumns();
0742: }
0743:
0744: public static int getRowCount(Object tableInfo) {
0745: assert tableInfo instanceof TableBox;
0746:
0747: TableBox table = (TableBox) tableInfo;
0748:
0749: return table.getRows();
0750: }
0751:
0752: // public void removeCssProperty(MarkupDesignBean bean, String property) {
0753: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
0754: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
0755: //
0756: // if (index != -1) {
0757: // // TODO -- update the -rendered- element!
0758: //// CssLookup.removeLocalStyleValue(bean.getElement(), index);
0759: // CssProvider.getEngineService().removeLocalStyleValueForElement(bean.getElement(), index);
0760: // }
0761: // }
0762: //
0763: // public void setCssProperty(MarkupDesignBean bean, String property, String value) {
0764: //// int index = XhtmlCssEngine.getXhtmlPropertyIndex(property);
0765: // int index = CssProvider.getEngineService().getXhtmlPropertyIndex(property);
0766: //
0767: // if (index != -1) {
0768: // // TODO -- update the -rendered- element!
0769: //// CssLookup.setLocalStyleValue(bean.getElement(), index, value);
0770: // CssProvider.getEngineService().addLocalStyleValueForElement(bean.getElement(), index, value);
0771: // }
0772: // }
0773:
0774: // public URL resolveUrl(URL base, Document document, String src) {
0775: // if (src == null) {
0776: // src = "";
0777: // }
0778: //
0779: // // TODO after Reef: push this into superclass
0780: // URL reference = null;
0781: //
0782: // // Relative to the web folder?
0783: // if (src.startsWith("/")) { // NOI18N
0784: //
0785: // // What if it's a local file, e.g. /home/tor/foo.jspf?? that wouldn't work at deploy time anyway..
0786: // try {
0787: // // <markup_separation>
0788: //// MarkupUnit markup = ((RaveDocument)document).getMarkup();
0789: //// FileObject fo = markup.getFileObject();
0790: // // ====
0791: // FileObject fo = InSyncServiceProvider.getProvider().getFileObject(document);
0792: // // </markup_separation>
0793: // Project project = FileOwnerQuery.getOwner(fo);
0794: //
0795: // if (project != null) {
0796: // FileObject webroot = JsfProjectUtils.getDocumentRoot(project);
0797: // reference = FileUtil.toFile(webroot).toURI().toURL();
0798: // }
0799: //
0800: // src = src.substring(1); // strip off leading "/" or URL class will ignore base
0801: // } catch (Exception ex) {
0802: // reference = base;
0803: // }
0804: // } else {
0805: // reference = base;
0806: // }
0807: //
0808: // try {
0809: // URL u = new URL(reference, src); // XXX what if it's absolute?
0810: //
0811: // return u;
0812: // } catch (MalformedURLException e) {
0813: // ErrorManager.getDefault().notify(e);
0814: //
0815: // return null;
0816: // }
0817: // }
0818:
0819: // public Element getBody(Document document) {
0820: // // <markup_separation>
0821: //// MarkupUnit markup = ((RaveDocument)document).getMarkup();
0822: //// DataObject dobj = markup.getDataObject();
0823: // // ====
0824: // FileObject fo = InSyncServiceProvider.getProvider().getFileObject(document);
0825: // DataObject dobj;
0826: // // XXX Copied form insync.
0827: // if (fo != null && !fo.isValid()) {
0828: // dobj = null;
0829: // } else {
0830: // try {
0831: // dobj = DataObject.find(fo);
0832: // } catch (DataObjectNotFoundException dnfe) {
0833: // dobj = null;
0834: // }
0835: // }
0836: // // </markup_separation>
0837: //
0838: // if (WebForm.isWebFormDataObject(dobj)) {
0839: // WebForm webform = WebForm.getWebFormForDataObject(dobj);
0840: //
0841: // return webform.getBody();
0842: // } else {
0843: // throw new IllegalStateException(
0844: // "Wrong document parameter in DesignerService.getBody dobj=" + dobj); // NOI18N
0845: // }
0846: // }
0847:
0848: // public boolean isWebPage(FileObject fo) {
0849: // String mime = fo.getMIMEType();
0850: //
0851: // String[] mimeTypes = FORM_MIME_TYPES;
0852: //
0853: // for (int i = 0; i < mimeTypes.length; i++) {
0854: // if (mimeTypes[i].equals(mime)) {
0855: // return true;
0856: // }
0857: // }
0858: //
0859: // return false;
0860: // }
0861: //
0862: // public String[] getMimeTypes() {
0863: // return FORM_MIME_TYPES;
0864: // }
0865: //
0866: // public List getWebPages(Project project, boolean includePages, boolean includeFragments) {
0867: // ArrayList list = new ArrayList(20);
0868: // FileObject fobj = JsfProjectUtils.getDocumentRoot(project);
0869: // addWebPages(list, fobj, includePages, includeFragments);
0870: //
0871: // return list;
0872: // }
0873: //
0874: // private void addWebPages(List list, FileObject folder, boolean includePages,
0875: // boolean includeFragments) {
0876: // if(DesignerUtils.DEBUG) {
0877: // DesignerUtils.debugLog(getClass().getName() + ".addWebPages(List, FileObject, boolean, boolean)");
0878: // }
0879: // if(folder == null) {
0880: // throw(new IllegalArgumentException("Null folder."));
0881: // }
0882: // if(list == null) {
0883: // throw(new IllegalArgumentException("Null list."));
0884: // }
0885: //
0886: // FileObject[] children = folder.getChildren();
0887: //
0888: // for (int i = 0; i < children.length; i++) {
0889: // FileObject fo = children[i];
0890: //
0891: // if (fo.isFolder()) {
0892: // addWebPages(list, fo, includePages, includeFragments);
0893: // } else {
0894: // if (isWebPage(fo)) {
0895: // boolean isFragment = "jspf".equals(fo.getExt()); // NOI18N
0896: //
0897: // if (isFragment) {
0898: // if (includeFragments) {
0899: // list.add(fo);
0900: // }
0901: // } else if (includePages) {
0902: // list.add(fo);
0903: // }
0904: // }
0905: // }
0906: // }
0907: // }
0908:
0909: // Moved to insync.
0910: // public boolean isBraveheartPage(Document document) {
0911: // return DesignerUtils.isBraveheartPage(document);
0912: // }
0913: //
0914: // public boolean isBraveheartPage(FileObject fo) {
0915: // DataObject dobj = null;
0916: //
0917: // try {
0918: // dobj = DataObject.find(fo);
0919: // } catch (DataObjectNotFoundException ex) {
0920: // return false;
0921: // }
0922: //
0923: // WebForm webform = DesignerUtils.getWebForm(dobj, false);
0924: //
0925: // if (webform == null) {
0926: // return false;
0927: // }
0928: //
0929: // Document dom = webform.getJspDom();
0930: //
0931: // if (dom != null) {
0932: // return isBraveheartPage(dom);
0933: // }
0934: //
0935: // return false;
0936: // }
0937:
0938: // public static void notifyCssEdited(DataObject dobj) {
0939: // DesignerTopComp.setPendingRefreshAll();
0940: // }
0941:
0942: // public static void refresh(Project project, DataObject dobj, boolean deep) {
0943: // if (dobj != null) {
0944: // WebForm.refresh(dobj, deep);
0945: // } else {
0946: // WebForm.refreshAll(project, deep);
0947: // }
0948: // }
0949: // public static void refreshDataObject(DataObject dobj, boolean deep) {
0950: // WebForm.refresh(dobj, deep);
0951: // }
0952: // public static void refreshProject(Project project, boolean deep) {
0953: // WebForm.refreshAll(project, deep);
0954: // }
0955:
0956: // public static void destroyWebFormForFileObject(FileObject fo) {
0957: // WebForm webform = WebForm.findWebFormForFileObject(fo);
0958: // if (webform != null) {
0959: // webform.destroy();
0960: // WebForm.removeWebFormForFileObject(fo);
0961: // }
0962: // }
0963:
0964: // public void detachTopComponentForDataObject(DataObject dobj) {
0965: // if (WebForm.hasWebFormForDataObject(dobj)) {
0966: // WebForm webform = WebForm.getWebFormForDataObject(dobj);
0967: // webform.detachTopComponent();
0968: // }
0969: // }
0970:
0971: // public MultiViewElement getMultiViewElementForDataObject(DataObject dobj) {
0972: // if (WebForm.isWebFormDataObject(dobj)) {
0973: // WebForm webform = WebForm.getWebFormForDataObject(dobj);
0974: // webform.createTopComponent();
0975: //
0976: // return webform.getTopComponent();
0977: // }
0978: //
0979: // return null;
0980: // }
0981:
0982: // /**
0983: // * Attempt to locate the current design view in use; may return
0984: // * null if no designer is found.
0985: // */
0986: // private static DesignerTopComp findCurrent() {
0987: // // Fish for the designer pane
0988: // DesignerTopComp formView = null;
0989: //
0990: // // Search through workspaces, then modes, then topcomponents
0991: // Set modes = WindowManager.getDefault().getModes();
0992: // Iterator it2 = modes.iterator();
0993: //
0994: // while (it2.hasNext()) {
0995: // Mode m = (Mode)it2.next();
0996: // TopComponent[] tcs = m.getTopComponents();
0997: //
0998: // if (tcs != null) {
0999: // for (int j = 0; j < tcs.length; j++) {
1000: // if (!tcs[j].isShowing()) {
1001: // continue;
1002: // }
1003: //
1004: // // Go hunting for our DesignerTopComp
1005: // DesignerTopComp comp = findDesigner(tcs[j], 0);
1006: //
1007: // if (comp != null) {
1008: // if (comp.isShowing()) {
1009: // return comp;
1010: // }
1011: // }
1012: // }
1013: // }
1014: //
1015: // if (formView != null) {
1016: // break;
1017: // }
1018: // }
1019: //
1020: // return formView;
1021: // }
1022: //
1023: // /** Fish for a DesignerPane within a container hierarchy
1024: // */
1025: // private static DesignerTopComp findDesigner(Container c, int depth) {
1026: // if (c == null) {
1027: // return null;
1028: // }
1029: //
1030: // // Only look slightly into the hiearchy since TopComponents should
1031: // // be near the top
1032: // if (depth == 4) {
1033: // return null;
1034: // }
1035: //
1036: // depth++;
1037: //
1038: // int n = c.getComponentCount();
1039: //
1040: // for (int i = 0; i < n; i++) {
1041: // java.awt.Component child = c.getComponent(i);
1042: //
1043: // if (child instanceof DesignerTopComp) {
1044: // return (DesignerTopComp)child;
1045: // } else if (child instanceof Container) {
1046: // DesignerTopComp result = findDesigner((Container)child, depth);
1047: //
1048: // if (result != null) {
1049: // return result;
1050: // }
1051: // }
1052: // }
1053: //
1054: // return null;
1055: // }
1056:
1057: // public float getBlockWidth(Element element) {
1058: // return CssBox.getBlockWidth(element);
1059: // }
1060: //
1061: // public float getBlockHeight(Element element) {
1062: // return CssBox.getBlockHeight(element);
1063: // }
1064:
1065: // public static void copyBoxForElement(Element fromElement, Element toElement) {
1066: // WebForm[] webForms = WebForm.findAllWebFormsForElement(toElement);
1067: // for (WebForm webForm : webForms) {
1068: //// CssBox.copyBoxForElement(fromElement, toElement);
1069: // webForm.copyBoxForElement(fromElement, toElement);
1070: // }
1071: // }
1072:
1073: // <missing designtime api>
1074:
1075: // <separation of models>
1076: // public static FileObject getContextFileForFragmentFile(FileObject fragmentFile) {
1077: // WebForm webform = WebForm.findWebFormForFileObject(fragmentFile);
1078: // WebForm contextWebform;
1079: // if (webform == null) {
1080: // contextWebform = null;
1081: // } else {
1082: // contextWebform = webform.getContextPage();
1083: // }
1084: //
1085: //// return contextWebform == null ? null : contextWebform.getModel().getMarkupFile();
1086: // if (contextWebform == null) {
1087: // return null;
1088: // }
1089: // DataObject jspDataObject = contextWebform.getJspDataObject();
1090: // return jspDataObject == null ? null : jspDataObject.getPrimaryFile();
1091: // }
1092:
1093: // XXX Moved to designer/jsf/../DesignerServiceHackImpl.
1094: // public static FileObject getExternalFormFileForElement(Element element) {
1095: // WebForm webForm = WebForm.findWebFormForElement(element);
1096: // if (webForm == null) {
1097: // return null;
1098: // }
1099: //// CssBox includeBox = CssBox.getBox(element);
1100: // CssBox includeBox = webForm.findCssBoxForElement(element);
1101: //
1102: // if ((includeBox != null) && includeBox instanceof JspIncludeBox) {
1103: // WebForm frameForm = ((JspIncludeBox)includeBox).getExternalForm();
1104: //
1105: //// if ((frameForm != null) && (frameForm != WebForm.EXTERNAL)) {
1106: // if (frameForm != null) {
1107: //// return frameForm.getModel().getMarkupFile();
1108: // DataObject jspDataObject = frameForm.getJspDataObject();
1109: // return jspDataObject == null ? null : jspDataObject.getPrimaryFile();
1110: // }
1111: // }
1112: // return null;
1113: // }
1114:
1115: // </separation of models>
1116:
1117: // </missing designtime api>
1118:
1119: // Copied from TextBox.
1120: private static final int TEXT_UNDERLINE = 1;
1121: private static final int TEXT_STRIKE = 2;
1122: private static final int TEXT_OVERLINE = 4;
1123:
1124: /**
1125: * XXX Horrible method, too long, needs to be refactored, it is unreadable now.
1126: * Paint a preview of the given component, with the given CSS style
1127: * applied, and return it as an image. Use the preferred initial
1128: * width, unless the component is larger.
1129: */
1130: private static BufferedImage paintCssPreview(Graphics2D g2d,
1131: URL base, Map<String, String> properties, int width,
1132: int height, int defaultFontSize) {
1133: // Restore?
1134: BufferedImage image = null;
1135:
1136: if (g2d != null) {
1137: GraphicsConfiguration config = g2d.getDeviceConfiguration();
1138: image = config.createCompatibleImage(width, height);
1139: } else {
1140: image = new BufferedImage(width, height,
1141: BufferedImage.TYPE_INT_RGB);
1142: }
1143:
1144: if (image == null) {
1145: return null;
1146: }
1147:
1148: Graphics2D og = (Graphics2D) image.getGraphics();
1149:
1150: try {
1151: // RaveDocument doc = null;
1152: // <markup_separation>
1153: // XhtmlCssEngine engine = XhtmlCssEngine.create(doc, null, base);
1154: // ====
1155: // XhtmlCssEngine engine = XhtmlCssEngine.create(null, base);
1156: //// <moved from engine impl> it doesn't (shoudn't) know about RaveDocument.
1157: //// if (doc != null) {
1158: //// doc.setCssEngine(engine);
1159: //// }
1160: //// </moved from engine impl>
1161: Document fakeDocument = new FakeDocument();
1162: CssEngineService cssEngineService = CssProvider
1163: .getEngineService();
1164: cssEngineService.createCssEngineForDocument(fakeDocument,
1165: null);
1166: // XhtmlCssEngine engine = CssEngineServiceProvider.getDefault().getCssEngine(fakeDocument);
1167:
1168: // </markup_separation>
1169: // engine.setErrorHandler(XhtmlCssEngine.SILENT_ERROR_HANDLER);
1170: cssEngineService
1171: .setSilentErrorHandlerForDocument(fakeDocument);
1172:
1173: // String styles = engine.mapToStyle(properties);
1174: String styles = cssEngineService
1175: .getStringFromStyleMapForDocument(fakeDocument,
1176: properties);
1177: // PreviewElement element = new PreviewElement(fakeDocument, /*engine,*/ base, styles);
1178: Element element = cssEngineService
1179: .createPreviewElementForDocument(fakeDocument,
1180: base, styles);
1181:
1182: // Color bg = CssLookup.getColor(element, XhtmlCss.BACKGROUND_COLOR_INDEX);
1183: Color bg = CssProvider.getValueService()
1184: .getColorForElement(element,
1185: XhtmlCss.BACKGROUND_COLOR_INDEX);
1186:
1187: if (bg != null) {
1188: og.setColor(bg);
1189: og.fillRect(0, 0, width, height);
1190: } else {
1191: // Use a transparent color.... any will do!
1192: // Color curr = g2d.getColor();
1193: // og.setColor(new Color(curr.getRed(), curr.getGreen(), curr.getBlue(), 0));
1194: //og.setColor(new Color(0, 0, 0, 0));
1195: bg = (Color) UIManager.getDefaults().get(
1196: "Label.background"); // NOI18N
1197: og.setColor(bg);
1198: og.fillRect(0, 0, width, height);
1199: }
1200:
1201: // ImageIcon bgImage = BackgroundImagePainter.getBackgroundImage(doc, element);
1202: // ImageIcon bgImage = BackgroundImagePainter.getBackgroundImage(base, element);
1203: // URL imageUrl = CssBoxUtilities.getBackgroundImageUrl(element, base);
1204: URL imageUrl = CssProvider.getEngineService()
1205: .getBackgroundImageUrlForElement(element, base);
1206: ImageIcon bgImage = imageUrl == null ? null
1207: : new ImageIcon(imageUrl);
1208:
1209: if (bgImage != null) {
1210: // Value repeatValue = CssLookup.getValue(element, XhtmlCss.BACKGROUND_REPEAT_INDEX);
1211: CssValue cssRepeatValue = CssProvider
1212: .getEngineService().getComputedValueForElement(
1213: element,
1214: XhtmlCss.BACKGROUND_REPEAT_INDEX);
1215: // ListValue positionValue =
1216: // CssLookup.getListValue(CssLookup.getValue(element,
1217: // XhtmlCss.BACKGROUND_POSITION_INDEX));
1218: CssListValue cssPositionValue = CssProvider
1219: .getValueService()
1220: .getComputedCssListValue(
1221: CssProvider
1222: .getEngineService()
1223: .getComputedValueForElement(
1224: element,
1225: XhtmlCss.BACKGROUND_POSITION_INDEX));
1226: // BackgroundImagePainter bgPainter =
1227: // new BackgroundImagePainter(bgImage, repeatValue, positionValue);
1228: BackgroundImagePainter bgPainter = new BackgroundImagePainter(
1229: bgImage, cssRepeatValue, cssPositionValue,
1230: element, defaultFontSize);
1231:
1232: if (bgPainter != null) {
1233: bgPainter.paint(og, 0, 0, width, height);
1234: }
1235: }
1236:
1237: boolean hasText = false;
1238: boolean hasBorder = false;
1239: boolean hasPosition = false;
1240: Iterator<String> it = properties.keySet().iterator();
1241:
1242: while (it.hasNext()) {
1243: String property = it.next();
1244:
1245: // if (isPositionProperty(property)) {
1246: if (CssProvider.getValueService().isPositionProperty(
1247: property)) {
1248: hasPosition = true;
1249: }
1250:
1251: // if (isTextProperty(property)) {
1252: if (CssProvider.getValueService().isTextProperty(
1253: property)) {
1254: // Insert text
1255: hasText = true;
1256: }
1257:
1258: // if (isBorderProperty(property)) {
1259: if (property.startsWith("border-")) { // NOI18N
1260: hasBorder = true;
1261: }
1262: }
1263:
1264: // if (hasPosition) {
1265: // // Do some position painting (abbreviated)
1266: // }
1267:
1268: CssBorder border = null;
1269:
1270: if (hasBorder) {
1271: // Paint border
1272: // XXX If you just set ONE property (like color) but
1273: // not solid or anything else, we don't preview! That's not good...
1274: border = CssBorder.getBorder(element);
1275:
1276: if (border != null) {
1277: border.paintBorder(og, 0, 0, width, height);
1278: }
1279: }
1280:
1281: if (hasText) {
1282: // Paint text
1283: // Check font size and attributes
1284: int decoration = 0;
1285: Color fg = Color.black;
1286: FontMetrics metrics = null;
1287: //boolean collapseSpaces = true;
1288: //boolean hidden = false;
1289: // metrics = CssLookup.getFontMetrics(element);
1290: // metrics = CssProvider.getValueService().getFontMetricsForElement(element);
1291: // XXX Missing text.
1292: metrics = CssUtilities
1293: .getDesignerFontMetricsForElement(element,
1294: null, defaultFontSize);
1295:
1296: // fg = CssLookup.getColor(element, XhtmlCss.COLOR_INDEX);
1297: fg = CssProvider.getValueService().getColorForElement(
1298: element, XhtmlCss.COLOR_INDEX);
1299:
1300: if (fg == null) {
1301: if (fg == null) {
1302: fg = Color.black;
1303: }
1304: }
1305:
1306: // Value val = CssLookup.getValue(element, XhtmlCss.TEXT_DECORATION_INDEX);
1307: CssValue cssValue = CssProvider.getEngineService()
1308: .getComputedValueForElement(element,
1309: XhtmlCss.TEXT_DECORATION_INDEX);
1310:
1311: // switch (val.getCssValueType()) {
1312: // case CSSValue.CSS_VALUE_LIST:
1313: //
1314: // ListValue lst = CssLookup.getListValue(val);
1315: //
1316: // if (lst == null) {
1317: // break;
1318: // }
1319: CssListValue cssList = CssProvider.getValueService()
1320: .getComputedCssListValue(cssValue);
1321: if (cssList != null) {
1322:
1323: // int len = lst.getLength();
1324: int len = cssList.getLength();
1325:
1326: for (int i = 0; i < len; i++) {
1327: // Value v = lst.item(i);
1328: CssValue cssV = cssList.item(i);
1329: // String s = v.getStringValue();
1330: String s = cssV.getStringValue();
1331:
1332: switch (s.charAt(0)) {
1333: case 'u':
1334: decoration |= TEXT_UNDERLINE;
1335:
1336: break;
1337:
1338: case 'o':
1339: decoration |= TEXT_OVERLINE;
1340:
1341: break;
1342:
1343: case 'l':
1344: decoration |= TEXT_STRIKE;
1345:
1346: break;
1347: }
1348: }
1349:
1350: // break;
1351: // default:
1352: } else {
1353: // XXX what happened?
1354: }
1355:
1356: // XXX Technically, should check for decoration=="overline" too...
1357: // (See section 16.3.1). However, does that have ANY practical
1358: // utility?
1359: // val = CssLookup.getValue(element, XhtmlCss.WHITE_SPACE_INDEX);
1360: //
1361: // if ((val == CssValueConstants.PRE_VALUE) ||
1362: // (val == CssValueConstants.PRE_WRAP_VALUE)) {
1363: // collapseSpaces = false;
1364: // }
1365:
1366: String content = "ABCabc123";
1367: // Value v1 = CssLookup.getValue(element, XhtmlCss.FONT_VARIANT_INDEX);
1368: // Value v2 = CssLookup.getValue(element, XhtmlCss.TEXT_TRANSFORM_INDEX);
1369: CssValue cssV1 = CssProvider.getEngineService()
1370: .getComputedValueForElement(element,
1371: XhtmlCss.FONT_VARIANT_INDEX);
1372: CssValue cssV2 = CssProvider.getEngineService()
1373: .getComputedValueForElement(element,
1374: XhtmlCss.TEXT_TRANSFORM_INDEX);
1375:
1376: // if ((v1 == CssValueConstants.SMALL_CAPS_VALUE) ||
1377: // (v2 == CssValueConstants.UPPERCASE_VALUE)) {
1378: if (CssProvider.getValueService().isSmallCapsValue(
1379: cssV1)
1380: || CssProvider.getValueService()
1381: .isUpperCaseValue(cssV2)) {
1382: // Uppercase the text
1383: content = content.toUpperCase();
1384:
1385: // TODO (much later): split the text up like under capitalization
1386: // and apply different fonts to the initial letters
1387: // and the rest of the words. I can't trivially do that
1388: // here because I would create separate TextBoxes for the
1389: // initial character and the rest of the words, and this
1390: // COULD be split up both in text justification and in word
1391: // wrapping by the LineBox and LineBoxGroup containers, which
1392: // would be visually disasterous. I think the painting of
1393: // this would really have to be done in the TextBox itself.
1394: // } else if (v2 == CssValueConstants.LOWERCASE_VALUE) {
1395: } else if (CssProvider.getValueService()
1396: .isLowerCaseValue(cssV2)) {
1397: content = content.toLowerCase();
1398: // } else if (v2 == CssValueConstants.CAPITALIZE_VALUE) {
1399: } else if (CssProvider.getValueService()
1400: .isCapitalizeValue(cssV2)) {
1401: content = "Abcabc123";
1402: }
1403:
1404: // int leftMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_LEFT_INDEX);
1405: int leftMargin = CssUtilities.getCssLength(element,
1406: XhtmlCss.MARGIN_LEFT_INDEX);
1407: // int rightMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_RIGHT_INDEX);
1408: // int topMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_TOP_INDEX);
1409: int topMargin = CssUtilities.getCssLength(element,
1410: XhtmlCss.MARGIN_TOP_INDEX);
1411: // int bottomMargin = CssLookup.getLength(element, XhtmlCss.MARGIN_BOTTOM_INDEX);
1412:
1413: // int leftPadding = CssLookup.getLength(element, XhtmlCss.PADDING_LEFT_INDEX);
1414: // int rightPadding = CssLookup.getLength(element, XhtmlCss.PADDING_RIGHT_INDEX);
1415: int leftPadding = CssUtilities.getCssLength(element,
1416: XhtmlCss.PADDING_LEFT_INDEX);
1417: int rightPadding = CssUtilities.getCssLength(element,
1418: XhtmlCss.PADDING_RIGHT_INDEX);
1419:
1420: // Unlike margins, padding values are not allowed to be negative!
1421: if (leftPadding < 0) {
1422: leftPadding = 0;
1423: }
1424:
1425: if (rightPadding < 0) {
1426: rightPadding = 0;
1427: }
1428:
1429: // int topPadding = CssLookup.getLength(element, XhtmlCss.PADDING_TOP_INDEX);
1430: // int bottomPadding = CssLookup.getLength(element, XhtmlCss.PADDING_BOTTOM_INDEX);
1431: int topPadding = CssUtilities.getCssLength(element,
1432: XhtmlCss.PADDING_TOP_INDEX);
1433: int bottomPadding = CssUtilities.getCssLength(element,
1434: XhtmlCss.PADDING_BOTTOM_INDEX);
1435:
1436: if (topPadding < 0) {
1437: topPadding = 0;
1438: }
1439:
1440: if (bottomPadding < 0) {
1441: bottomPadding = 0;
1442: }
1443:
1444: int leftBorderWidth = 0;
1445: int topBorderWidth = 0;
1446: // int rightBorderWidth = 0;
1447: // int bottomBorderWidth = 0;
1448:
1449: if (border != null) {
1450: leftBorderWidth = border.getLeftBorderWidth();
1451: topBorderWidth = border.getTopBorderWidth();
1452: // bottomBorderWidth = border.getBottomBorderWidth();
1453: // rightBorderWidth = border.getRightBorderWidth();
1454: }
1455:
1456: int x = leftMargin + leftBorderWidth + leftPadding;
1457: int y = topMargin + topBorderWidth + topPadding;
1458: og.setColor(fg);
1459: og.setFont(metrics.getFont());
1460:
1461: // determine the y coordinate to render the glyphs
1462: int yadj = (y + metrics.getHeight())
1463: - metrics.getDescent();
1464:
1465: // Draw text!
1466: char[] contentChars = content.toCharArray();
1467: og.drawChars(contentChars, 0, contentChars.length, x,
1468: yadj);
1469:
1470: // render underline or strikethrough if set.
1471: if (decoration != 0) {
1472: int textWidth = DesignerUtils
1473: .getNonTabbedTextWidth(contentChars, 0,
1474: contentChars.length, metrics);
1475:
1476: if ((decoration & TEXT_UNDERLINE) != 0) {
1477: int yTmp = yadj;
1478: yTmp += 1;
1479: og.drawLine(x, yTmp, x + textWidth, yTmp);
1480: }
1481:
1482: if ((decoration & TEXT_STRIKE) != 0) {
1483: int yTmp = yadj;
1484:
1485: // move y coordinate above baseline
1486: yTmp -= (int) (metrics.getAscent() * 0.4f);
1487: og.drawLine(x, yTmp, x + textWidth, yTmp);
1488: }
1489:
1490: if ((decoration & TEXT_OVERLINE) != 0) {
1491: og.drawLine(x, y, x + textWidth, y);
1492: }
1493: }
1494: }
1495: } finally {
1496: og.dispose();
1497: }
1498:
1499: return image;
1500: }
1501:
1502: // public static MultiViewElement getDesignerMultiViewElement(DataObject dataObject) {
1503: // return WebForm.getDesignerMultiViewElement(dataObject);
1504: // }
1505:
1506: }
|