19bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye/*
29bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * Copyright (C) 2012 The Android Open Source Project
39bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye *
49bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License");
59bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * you may not use this file except in compliance with the License.
69bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * You may obtain a copy of the License at
79bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye *
89bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye *      http://www.eclipse.org/org/documents/epl-v10.php
99bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye *
109bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * Unless required by applicable law or agreed to in writing, software
119bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS,
129bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * See the License for the specific language governing permissions and
149bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * limitations under the License.
159bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye */
169bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
179bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyepackage com.android.ide.eclipse.adt.internal.editors.layout.properties;
189bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
1912d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ANDROID_PREFIX;
2012d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ANDROID_THEME_PREFIX;
2112d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.ATTR_ID;
2212d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.DOT_PNG;
2312d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.DOT_XML;
2412d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.PREFIX_RESOURCE_REF;
2512d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.PREFIX_THEME_REF;
269bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
279bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.annotations.NonNull;
289bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.common.api.IAttributeInfo;
299bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.common.api.IAttributeInfo.Format;
309bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.common.rendering.api.ResourceValue;
319bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.common.resources.ResourceRepository;
329bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.common.resources.ResourceResolver;
339bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.AdtPlugin;
349bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate;
359bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart;
369bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils;
379bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderService;
389bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.layout.gle2.SwtUtils;
399bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.resources.ResourceHelper;
409bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
419bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.ui.ReferenceChooserDialog;
429bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.ui.ResourceChooser;
439bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.ide.eclipse.adt.internal.ui.ResourcePreviewHelper;
449bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.android.resources.ResourceType;
459bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport com.google.common.collect.Maps;
469bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
479bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.core.resources.IProject;
489bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.core.runtime.CoreException;
499bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.core.runtime.QualifiedName;
509bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.jface.window.Window;
519bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.swt.graphics.Color;
529bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.swt.graphics.GC;
539bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.swt.graphics.Image;
549bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.swt.graphics.ImageData;
559bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.swt.graphics.Point;
569bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.swt.graphics.RGB;
579bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.swt.widgets.Shell;
589bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.wb.draw2d.IColorConstants;
599bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.wb.internal.core.model.property.Property;
609bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.wb.internal.core.model.property.editor.AbstractTextPropertyEditor;
619bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.wb.internal.core.model.property.editor.presentation.ButtonPropertyEditorPresentation;
629bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.wb.internal.core.model.property.editor.presentation.PropertyEditorPresentation;
639bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.wb.internal.core.model.property.table.PropertyTable;
649bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport org.eclipse.wb.internal.core.utils.ui.DrawUtils;
659bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
669bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport java.awt.image.BufferedImage;
679bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport java.io.File;
689bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport java.io.IOException;
699bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport java.util.ArrayList;
709bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport java.util.EnumSet;
719bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport java.util.List;
729bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport java.util.Map;
739bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
749bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeimport javax.imageio.ImageIO;
759bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
769bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye/**
779bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * Special property editor used for the {@link XmlProperty} instances which handles
789bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye * editing the XML properties, rendering defaults by looking up the actual colors and images,
799bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye */
809bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbyeclass XmlPropertyEditor extends AbstractTextPropertyEditor {
819bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    public static final XmlPropertyEditor INSTANCE = new XmlPropertyEditor();
829bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    private static final int SAMPLE_SIZE = 10;
839bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    private static final int SAMPLE_MARGIN = 3;
849bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
859bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    protected XmlPropertyEditor() {
869bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
879bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
889bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    private final PropertyEditorPresentation mPresentation =
899bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            new ButtonPropertyEditorPresentation() {
909bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        @Override
919bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        protected void onClick(PropertyTable propertyTable, Property property) throws Exception {
929bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            openDialog(propertyTable, property);
939bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        }
949bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    };
959bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
969bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    @Override
979bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    public PropertyEditorPresentation getPresentation() {
989bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        return mPresentation;
999bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
1009bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
1019bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    @Override
1029bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    public String getText(Property property) throws Exception {
1039bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        Object value = property.getValue();
1049bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        if (value instanceof String) {
1059bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            return (String) value;
1069bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        }
1079bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        return null;
1089bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
1099bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
1109bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    @Override
1119bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    protected String getEditorText(Property property) throws Exception {
1129bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        return getText(property);
1139bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
1149bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
1159bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    @Override
1169bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    public void paint(Property property, GC gc, int x, int y, int width, int height)
1179bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            throws Exception {
1189bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        String text = getText(property);
1199bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        if (text != null) {
1209bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            ResourceValue resValue = null;
1219bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            String resolvedText = null;
1229bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
1239bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            // TODO: Use the constants for @, ?, @android: etc
1249bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            if (text.startsWith("@") || text.startsWith("?")) { //$NON-NLS-1$ //$NON-NLS-2$
1259bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                // Yes, try to resolve it in order to show better info
1269bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                XmlProperty xmlProperty = (XmlProperty) property;
127774424394537c69975f8fc0044765db8c252f66fTor Norbye                GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
128774424394537c69975f8fc0044765db8c252f66fTor Norbye                if (graphicalEditor != null) {
129774424394537c69975f8fc0044765db8c252f66fTor Norbye                    ResourceResolver resolver = graphicalEditor.getResourceResolver();
13012d4581faa6438941e65a9dc83213be34c6ca970Tor Norbye                    boolean isFramework = text.startsWith(ANDROID_PREFIX)
13112d4581faa6438941e65a9dc83213be34c6ca970Tor Norbye                            || text.startsWith(ANDROID_THEME_PREFIX);
132774424394537c69975f8fc0044765db8c252f66fTor Norbye                    resValue = resolver.findResValue(text, isFramework);
133774424394537c69975f8fc0044765db8c252f66fTor Norbye                    while (resValue != null && resValue.getValue() != null) {
134774424394537c69975f8fc0044765db8c252f66fTor Norbye                        String value = resValue.getValue();
135774424394537c69975f8fc0044765db8c252f66fTor Norbye                        if (value.startsWith(PREFIX_RESOURCE_REF)
136774424394537c69975f8fc0044765db8c252f66fTor Norbye                                || value.startsWith(PREFIX_THEME_REF)) {
137774424394537c69975f8fc0044765db8c252f66fTor Norbye                            // TODO: do I have to strip off the @ too?
138774424394537c69975f8fc0044765db8c252f66fTor Norbye                            isFramework = isFramework
13912d4581faa6438941e65a9dc83213be34c6ca970Tor Norbye                                    || value.startsWith(ANDROID_PREFIX)
14012d4581faa6438941e65a9dc83213be34c6ca970Tor Norbye                                    || value.startsWith(ANDROID_THEME_PREFIX);;
141774424394537c69975f8fc0044765db8c252f66fTor Norbye                            ResourceValue v = resolver.findResValue(text, isFramework);
142774424394537c69975f8fc0044765db8c252f66fTor Norbye                            if (v != null && !value.equals(v.getValue())) {
143774424394537c69975f8fc0044765db8c252f66fTor Norbye                                resValue = v;
144774424394537c69975f8fc0044765db8c252f66fTor Norbye                            } else {
145774424394537c69975f8fc0044765db8c252f66fTor Norbye                                break;
146774424394537c69975f8fc0044765db8c252f66fTor Norbye                            }
1479bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        } else {
1489bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            break;
1499bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
1509bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    }
1519bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                }
1529bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            } else if (text.startsWith("#") && text.matches("#\\p{XDigit}+")) { //$NON-NLS-1$
1539bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                resValue = new ResourceValue(ResourceType.COLOR, property.getName(), text, false);
1549bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            }
1559bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
1569bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            if (resValue != null && resValue.getValue() != null) {
1579bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                String value = resValue.getValue();
1589bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                // Decide whether it's a color, an image, a nine patch etc
1599bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                // and decide how to render it
1609bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                if (value.startsWith("#") || value.endsWith(DOT_XML) //$NON-NLS-1$
1619bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        && value.contains("res/color")) { //$NON-NLS-1$ // TBD: File.separator?
1629bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    XmlProperty xmlProperty = (XmlProperty) property;
163774424394537c69975f8fc0044765db8c252f66fTor Norbye                    GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
164774424394537c69975f8fc0044765db8c252f66fTor Norbye                    if (graphicalEditor != null) {
165774424394537c69975f8fc0044765db8c252f66fTor Norbye                        ResourceResolver resolver = graphicalEditor.getResourceResolver();
166774424394537c69975f8fc0044765db8c252f66fTor Norbye                        RGB rgb = ResourceHelper.resolveColor(resolver, resValue);
167774424394537c69975f8fc0044765db8c252f66fTor Norbye                        if (rgb != null) {
168774424394537c69975f8fc0044765db8c252f66fTor Norbye                            Color color = new Color(gc.getDevice(), rgb);
169774424394537c69975f8fc0044765db8c252f66fTor Norbye                            // draw color sample
170774424394537c69975f8fc0044765db8c252f66fTor Norbye                            Color oldBackground = gc.getBackground();
171774424394537c69975f8fc0044765db8c252f66fTor Norbye                            Color oldForeground = gc.getForeground();
172774424394537c69975f8fc0044765db8c252f66fTor Norbye                            try {
173774424394537c69975f8fc0044765db8c252f66fTor Norbye                                int width_c = SAMPLE_SIZE;
174774424394537c69975f8fc0044765db8c252f66fTor Norbye                                int height_c = SAMPLE_SIZE;
175774424394537c69975f8fc0044765db8c252f66fTor Norbye                                int x_c = x;
176774424394537c69975f8fc0044765db8c252f66fTor Norbye                                int y_c = y + (height - height_c) / 2;
177774424394537c69975f8fc0044765db8c252f66fTor Norbye                                // update rest bounds
178774424394537c69975f8fc0044765db8c252f66fTor Norbye                                int delta = SAMPLE_SIZE + SAMPLE_MARGIN;
179774424394537c69975f8fc0044765db8c252f66fTor Norbye                                x += delta;
180774424394537c69975f8fc0044765db8c252f66fTor Norbye                                width -= delta;
181774424394537c69975f8fc0044765db8c252f66fTor Norbye                                // fill
182774424394537c69975f8fc0044765db8c252f66fTor Norbye                                gc.setBackground(color);
183774424394537c69975f8fc0044765db8c252f66fTor Norbye                                gc.fillRectangle(x_c, y_c, width_c, height_c);
184774424394537c69975f8fc0044765db8c252f66fTor Norbye                                // draw line
185774424394537c69975f8fc0044765db8c252f66fTor Norbye                                gc.setForeground(IColorConstants.gray);
186774424394537c69975f8fc0044765db8c252f66fTor Norbye                                gc.drawRectangle(x_c, y_c, width_c, height_c);
187774424394537c69975f8fc0044765db8c252f66fTor Norbye                            } finally {
188774424394537c69975f8fc0044765db8c252f66fTor Norbye                                gc.setBackground(oldBackground);
189774424394537c69975f8fc0044765db8c252f66fTor Norbye                                gc.setForeground(oldForeground);
190774424394537c69975f8fc0044765db8c252f66fTor Norbye                            }
191774424394537c69975f8fc0044765db8c252f66fTor Norbye                            color.dispose();
1929bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
1939bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    }
1949bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                } else {
1959bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    Image swtImage = null;
1969bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    if (value.endsWith(DOT_XML) && value.contains("res/drawable")) { // TBD: Filesep?
1979bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        Map<String, Image> cache = getImageCache(property);
1989bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        swtImage = cache.get(value);
1999bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        if (swtImage == null) {
2009bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            XmlProperty xmlProperty = (XmlProperty) property;
2019bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
2029bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            RenderService service = RenderService.create(graphicalEditor);
2039bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            service.setSize(SAMPLE_SIZE, SAMPLE_SIZE);
2049bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            BufferedImage drawable = service.renderDrawable(resValue);
2059bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            if (drawable != null) {
2069bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                swtImage = SwtUtils.convertToSwt(gc.getDevice(), drawable,
2079bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                        true /*transferAlpha*/, -1);
2089bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                cache.put(value, swtImage);
2099bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            }
2109bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
2119bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    } else if (value.endsWith(DOT_PNG)) {
2129bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        // TODO: 9-patch handling?
2139bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        //if (text.endsWith(DOT_9PNG)) {
2149bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        //    // 9-patch image: How do we paint this?
2159bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        //    URL url = new File(text).toURI().toURL();
2169bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        //    NinePatch ninepatch = NinePatch.load(url, false /* ?? */);
2179bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        //    BufferedImage image = ninepatch.getImage();
2189bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        //}
2199bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        Map<String, Image> cache = getImageCache(property);
2209bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        swtImage = cache.get(value);
2219bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        if (swtImage == null) {
2229bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            File file = new File(value);
2239bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            if (file.exists()) {
2249bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                try {
2259bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                    BufferedImage awtImage = ImageIO.read(file);
2269bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                    if (awtImage != null && awtImage.getWidth() > 0
2279bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            && awtImage.getHeight() > 0) {
2289bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                        awtImage = ImageUtils.cropBlank(awtImage, null);
2299bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                        if (awtImage != null) {
2309bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            // Scale image
2319bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            int imageWidth = awtImage.getWidth();
2329bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            int imageHeight = awtImage.getHeight();
2339bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            int maxWidth = 3 * height;
2349bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
2359bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            if (imageWidth > maxWidth || imageHeight > height) {
2369bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                double scale = height / (double) imageHeight;
2379bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                int scaledWidth = (int) (imageWidth * scale);
2389bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                if (scaledWidth > maxWidth) {
2399bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                    scale = maxWidth / (double) imageWidth;
2409bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                }
2419bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                awtImage = ImageUtils.scale(awtImage, scale,
2429bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                        scale);
2439bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            }
2449bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                            swtImage = SwtUtils.convertToSwt(gc.getDevice(),
2459bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                                    awtImage, true /*transferAlpha*/, -1);
2469bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                        }
2479bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                    }
2489bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                } catch (IOException e) {
2499bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                    AdtPlugin.log(e, value);
2509bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                }
2519bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            }
2529bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            cache.put(value, swtImage);
2539bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
2549bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
2559bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    } else if (value != null) {
2569bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        // It's a normal string: if different from the text, paint
2579bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        // it in parentheses, e.g.
2589bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        //   @string/foo: Foo Bar (probably cropped)
2599bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        if (!value.equals(text) && !value.equals("@null")) { //$NON-NLS-1$
2609bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            resolvedText = value;
2619bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
2629bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    }
2639bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
2649bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    if (swtImage != null) {
2659bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        // Make a square the size of the height
2669bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        ImageData imageData = swtImage.getImageData();
2679bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        int imageWidth = imageData.width;
2689bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        int imageHeight = imageData.height;
2699bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        if (imageWidth > 0 && imageHeight > 0) {
2709bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            gc.drawImage(swtImage, x, y + (height - imageHeight) / 2);
2719bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            int delta = imageWidth + SAMPLE_MARGIN;
2729bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            x += delta;
2739bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            width -= delta;
2749bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
2759bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    }
2769bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                }
2779bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            }
2789bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
2799bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            DrawUtils.drawStringCV(gc, text, x, y, width, height);
2809bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
2819bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            if (resolvedText != null && resolvedText.length() > 0) {
2829bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                Point size = gc.stringExtent(text);
2839bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                x += size.x;
2849bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                width -= size.x;
2859bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
2869bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                x += SAMPLE_MARGIN;
2879bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                width -= SAMPLE_MARGIN;
2889bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
2899bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                if (width > 0) {
2909bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    Color oldForeground = gc.getForeground();
2919bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    try {
2929bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        gc.setForeground(PropertyTable.COLOR_PROPERTY_FG_DEFAULT);
2939bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        DrawUtils.drawStringCV(gc, '(' + resolvedText + ')', x, y, width, height);
2949bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    } finally {
2959bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        gc.setForeground(oldForeground);
2969bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    }
2979bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                }
2989bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            }
2999bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        }
3009bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
3019bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
3029bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    @Override
3039bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    protected boolean setEditorText(Property property, String text) throws Exception {
3049bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        property.setValue(text);
3059bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        return true;
3069bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
3079bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
3089bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    private void openDialog(PropertyTable propertyTable, Property property) throws Exception {
3099bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        XmlProperty xmlProperty = (XmlProperty) property;
3109bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        IAttributeInfo attributeInfo = xmlProperty.getDescriptor().getAttributeInfo();
3119bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
3129bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        boolean isId = xmlProperty.getDescriptor().getXmlLocalName().equals(ATTR_ID);
3139bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        if (isId) {
3149bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            // When editing the id attribute, don't offer a resource chooser: usually
3159bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            // you want to enter a *new* id here
3169bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            attributeInfo = null;
3179bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        }
3189bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
3199bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        boolean referenceAllowed = false;
3209bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        if (attributeInfo != null) {
3219bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            EnumSet<Format> formats = attributeInfo.getFormats();
3229bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            ResourceType type = null;
3239bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            List<ResourceType> types = null;
3249bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            if (formats.contains(Format.FLAG)) {
3257e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                String[] flagValues = attributeInfo.getFlagValues();
3267e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                if (flagValues != null) {
3277e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    FlagXmlPropertyDialog dialog =
3289bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        new FlagXmlPropertyDialog(propertyTable.getShell(),
3299bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                "Select Flag Values", false /* radio */,
3307e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                                flagValues, xmlProperty);
3319bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
3327e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    dialog.open();
3337e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    return;
3347e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                }
3359bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            } else if (formats.contains(Format.ENUM)) {
3367e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                String[] enumValues = attributeInfo.getEnumValues();
3377e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                if (enumValues != null) {
3387e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    FlagXmlPropertyDialog dialog =
3399bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        new FlagXmlPropertyDialog(propertyTable.getShell(),
3409bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                "Select Enum Value", true /* radio */,
3417e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                                enumValues, xmlProperty);
3427e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    dialog.open();
3437e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    return;
3447e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                }
3459bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            } else {
3469bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                for (Format format : formats) {
3479bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    ResourceType t = format.getResourceType();
3489bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    if (t != null) {
3499bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        if (type != null) {
3509bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            if (types == null) {
3519bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                types = new ArrayList<ResourceType>();
3529bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                                types.add(type);
3539bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            }
3549bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            types.add(t);
3559bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
3569bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        type = t;
3579bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    } else if (format == Format.REFERENCE) {
3589bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        referenceAllowed = true;
3599bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    }
3609bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                }
3619bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            }
3629bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            if (types != null || referenceAllowed) {
3639bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                // Multiple resource types (such as string *and* boolean):
3649bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                // just use a reference chooser
3659bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
366774424394537c69975f8fc0044765db8c252f66fTor Norbye                if (graphicalEditor != null) {
367774424394537c69975f8fc0044765db8c252f66fTor Norbye                    LayoutEditorDelegate delegate = graphicalEditor.getEditorDelegate();
368774424394537c69975f8fc0044765db8c252f66fTor Norbye                    IProject project = delegate.getEditor().getProject();
369774424394537c69975f8fc0044765db8c252f66fTor Norbye                    if (project != null) {
370774424394537c69975f8fc0044765db8c252f66fTor Norbye                        // get the resource repository for this project and the system resources.
371774424394537c69975f8fc0044765db8c252f66fTor Norbye                        ResourceRepository projectRepository =
372774424394537c69975f8fc0044765db8c252f66fTor Norbye                            ResourceManager.getInstance().getProjectResources(project);
373774424394537c69975f8fc0044765db8c252f66fTor Norbye                        Shell shell = AdtPlugin.getDisplay().getActiveShell();
374774424394537c69975f8fc0044765db8c252f66fTor Norbye                        ReferenceChooserDialog dlg = new ReferenceChooserDialog(
375774424394537c69975f8fc0044765db8c252f66fTor Norbye                                project,
376774424394537c69975f8fc0044765db8c252f66fTor Norbye                                projectRepository,
377774424394537c69975f8fc0044765db8c252f66fTor Norbye                                shell);
378774424394537c69975f8fc0044765db8c252f66fTor Norbye                        dlg.setPreviewHelper(new ResourcePreviewHelper(dlg, graphicalEditor));
379774424394537c69975f8fc0044765db8c252f66fTor Norbye
380774424394537c69975f8fc0044765db8c252f66fTor Norbye                        String currentValue = (String) property.getValue();
381774424394537c69975f8fc0044765db8c252f66fTor Norbye                        dlg.setCurrentResource(currentValue);
382774424394537c69975f8fc0044765db8c252f66fTor Norbye
383774424394537c69975f8fc0044765db8c252f66fTor Norbye                        if (dlg.open() == Window.OK) {
384774424394537c69975f8fc0044765db8c252f66fTor Norbye                            String resource = dlg.getCurrentResource();
385774424394537c69975f8fc0044765db8c252f66fTor Norbye                            if (resource != null) {
386774424394537c69975f8fc0044765db8c252f66fTor Norbye                                // Returns null for cancel, "" for clear and otherwise a new value
387774424394537c69975f8fc0044765db8c252f66fTor Norbye                                if (resource.length() > 0) {
388774424394537c69975f8fc0044765db8c252f66fTor Norbye                                    property.setValue(resource);
389774424394537c69975f8fc0044765db8c252f66fTor Norbye                                } else {
390774424394537c69975f8fc0044765db8c252f66fTor Norbye                                    property.setValue(null);
391774424394537c69975f8fc0044765db8c252f66fTor Norbye                                }
3929bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                            }
3939bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                        }
3949bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
395774424394537c69975f8fc0044765db8c252f66fTor Norbye                        return;
396774424394537c69975f8fc0044765db8c252f66fTor Norbye                    }
3979bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                }
3989bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            } else if (type != null) {
3999bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                // Single resource type: use a resource chooser
4009bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
4017e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                if (graphicalEditor != null) {
4027e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    String currentValue = (String) property.getValue();
4037e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    // TODO: Add validator factory?
4047e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    String resource = ResourceChooser.chooseResource(graphicalEditor,
4057e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                            type, currentValue, null /* validator */);
4067e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    // Returns null for cancel, "" for clear and otherwise a new value
4077e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                    if (resource != null) {
4087e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                        if (resource.length() > 0) {
4097e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                            property.setValue(resource);
4107e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                        } else {
4117e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                            property.setValue(null);
4127e4b8e9d595e45baa9d87cdb8282f02759e73abcTor Norbye                        }
4139bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                    }
4149bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                }
4159bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
4169bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                return;
4179bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            }
4189bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        }
4199bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
4209bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        // Fallback: Just use a plain string editor
4219bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        StringXmlPropertyDialog dialog =
4229bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                new StringXmlPropertyDialog(propertyTable.getShell(), property);
4239bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        if (dialog.open() == Window.OK) {
4249bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            // TODO: Do I need to activate?
4259bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        }
4269bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
4279bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
4289bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    /** Qualified name for the per-project persistent property include-map */
4299bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    private final static QualifiedName CACHE_NAME = new QualifiedName(AdtPlugin.PLUGIN_ID,
4309bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            "property-images");//$NON-NLS-1$
4319bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
4329bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    @NonNull
4339bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    private static Map<String, Image> getImageCache(@NonNull Property property) {
4349bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        XmlProperty xmlProperty = (XmlProperty) property;
435774424394537c69975f8fc0044765db8c252f66fTor Norbye        GraphicalEditorPart graphicalEditor = xmlProperty.getGraphicalEditor();
436774424394537c69975f8fc0044765db8c252f66fTor Norbye        IProject project = graphicalEditor.getProject();
4379bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        try {
4389bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            Map<String, Image> cache = (Map<String, Image>) project.getSessionProperty(CACHE_NAME);
4399bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            if (cache == null) {
4409bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                cache = Maps.newHashMap();
4419bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye                project.setSessionProperty(CACHE_NAME, cache);
4429bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            }
4439bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye
4449bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            return cache;
4459bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        } catch (CoreException e) {
4469bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            AdtPlugin.log(e, null);
4479bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye            return Maps.newHashMap();
4489bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye        }
4499bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye    }
4509bd06947302ca6ca3e0b90eef894e553c6c3e067Tor Norbye}
451