1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.ide.eclipse.adt.internal.editors.layout.gle2; 17 18 import com.android.annotations.NonNull; 19 import com.android.ide.eclipse.adt.AdtPlugin; 20 import com.android.ide.eclipse.adt.AdtUtils; 21 import com.android.ide.eclipse.adt.internal.editors.formatting.EclipseXmlPrettyPrinter; 22 import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Configuration; 23 import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationChooser; 24 import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationDescription; 25 import com.android.sdklib.devices.Device; 26 import com.google.common.base.Charsets; 27 import com.google.common.collect.Lists; 28 import com.google.common.io.Files; 29 30 import org.eclipse.core.resources.IProject; 31 import org.eclipse.core.runtime.CoreException; 32 import org.eclipse.core.runtime.QualifiedName; 33 import org.w3c.dom.Document; 34 import org.w3c.dom.Element; 35 36 import java.io.File; 37 import java.io.IOException; 38 import java.util.ArrayList; 39 import java.util.List; 40 41 /** A list of render previews */ 42 class RenderPreviewList { 43 /** Name of file saved in project directory storing previews */ 44 private static final String PREVIEW_FILE_NAME = "previews.xml"; //$NON-NLS-1$ 45 46 /** Qualified name for the per-project persistent property include-map */ 47 private final static QualifiedName PREVIEW_LIST = new QualifiedName(AdtPlugin.PLUGIN_ID, 48 "previewlist");//$NON-NLS-1$ 49 50 private final IProject mProject; 51 private final List<ConfigurationDescription> mList = Lists.newArrayList(); 52 53 private RenderPreviewList(@NonNull IProject project) { 54 mProject = project; 55 } 56 57 /** 58 * Returns the {@link RenderPreviewList} for the given project 59 * 60 * @param project the project the list is associated with 61 * @return a {@link RenderPreviewList} for the given project, never null 62 */ 63 @NonNull 64 public static RenderPreviewList get(@NonNull IProject project) { 65 RenderPreviewList list = null; 66 try { 67 list = (RenderPreviewList) project.getSessionProperty(PREVIEW_LIST); 68 } catch (CoreException e) { 69 // Not a problem; we will just create a new one 70 } 71 72 if (list == null) { 73 list = new RenderPreviewList(project); 74 try { 75 project.setSessionProperty(PREVIEW_LIST, list); 76 } catch (CoreException e) { 77 AdtPlugin.log(e, null); 78 } 79 } 80 81 return list; 82 } 83 84 private File getManualFile() { 85 return new File(AdtUtils.getAbsolutePath(mProject).toFile(), PREVIEW_FILE_NAME); 86 } 87 88 void load(List<Device> deviceList) throws IOException { 89 File file = getManualFile(); 90 if (file.exists()) { 91 load(file, deviceList); 92 } 93 } 94 95 void save() throws IOException { 96 deleteFile(); 97 if (!mList.isEmpty()) { 98 File file = getManualFile(); 99 save(file); 100 } 101 } 102 103 private void save(File file) throws IOException { 104 //Document document = DomUtilities.createEmptyPlainDocument(); 105 Document document = DomUtilities.createEmptyDocument(); 106 if (document != null) { 107 for (ConfigurationDescription description : mList) { 108 description.toXml(document); 109 } 110 String xml = EclipseXmlPrettyPrinter.prettyPrint(document, true); 111 Files.write(xml, file, Charsets.UTF_8); 112 } 113 } 114 115 void load(File file, List<Device> deviceList) throws IOException { 116 mList.clear(); 117 118 String xml = Files.toString(file, Charsets.UTF_8); 119 Document document = DomUtilities.parseDocument(xml, true); 120 if (document == null || document.getDocumentElement() == null) { 121 return; 122 } 123 List<Element> elements = DomUtilities.getChildren(document.getDocumentElement()); 124 for (Element element : elements) { 125 ConfigurationDescription description = ConfigurationDescription.fromXml( 126 mProject, element, deviceList); 127 if (description != null) { 128 mList.add(description); 129 } 130 } 131 } 132 133 /** 134 * Create a list of previews for the given canvas that matches the internal 135 * configuration preview list 136 * 137 * @param canvas the associated canvas 138 * @return a new list of previews linked to the given canvas 139 */ 140 @NonNull 141 List<RenderPreview> createPreviews(LayoutCanvas canvas) { 142 if (mList.isEmpty()) { 143 return new ArrayList<RenderPreview>(); 144 } 145 List<RenderPreview> previews = Lists.newArrayList(); 146 RenderPreviewManager manager = canvas.getPreviewManager(); 147 ConfigurationChooser chooser = canvas.getEditorDelegate().getGraphicalEditor() 148 .getConfigurationChooser(); 149 150 Configuration chooserConfig = chooser.getConfiguration(); 151 for (ConfigurationDescription description : mList) { 152 Configuration configuration = Configuration.create(chooser); 153 configuration.setDisplayName(description.displayName); 154 configuration.setActivity(description.activity); 155 configuration.setLocale( 156 description.locale != null ? description.locale : chooserConfig.getLocale(), 157 true); 158 // TODO: Make sure this layout isn't in some v-folder which is incompatible 159 // with this target! 160 configuration.setTarget( 161 description.target != null ? description.target : chooserConfig.getTarget(), 162 true); 163 configuration.setTheme( 164 description.theme != null ? description.theme : chooserConfig.getTheme()); 165 configuration.setDevice( 166 description.device != null ? description.device : chooserConfig.getDevice(), 167 true); 168 configuration.setDeviceState( 169 description.state != null ? description.state : chooserConfig.getDeviceState(), 170 true); 171 configuration.setNightMode( 172 description.nightMode != null ? description.nightMode 173 : chooserConfig.getNightMode(), true); 174 configuration.setUiMode( 175 description.uiMode != null ? description.uiMode : chooserConfig.getUiMode(), true); 176 177 //configuration.syncFolderConfig(); 178 configuration.getFullConfig().set(description.folder); 179 180 RenderPreview preview = RenderPreview.create(manager, configuration); 181 182 preview.setDescription(description); 183 previews.add(preview); 184 } 185 186 return previews; 187 } 188 189 void remove(@NonNull RenderPreview preview) { 190 ConfigurationDescription description = preview.getDescription(); 191 if (description != null) { 192 mList.remove(description); 193 } 194 } 195 196 boolean isEmpty() { 197 return mList.isEmpty(); 198 } 199 200 void add(@NonNull RenderPreview preview) { 201 Configuration configuration = preview.getConfiguration(); 202 ConfigurationDescription description = 203 ConfigurationDescription.fromConfiguration(mProject, configuration); 204 // RenderPreviews can have display names that aren't reflected in the configuration 205 description.displayName = preview.getDisplayName(); 206 mList.add(description); 207 preview.setDescription(description); 208 } 209 210 void delete() { 211 mList.clear(); 212 deleteFile(); 213 } 214 215 private void deleteFile() { 216 File file = getManualFile(); 217 if (file.exists()) { 218 file.delete(); 219 } 220 } 221 } 222