diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java new file mode 100644 index 000000000..6b1001253 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ide.eclipse.adt.internal.assetstudio; + +import com.android.ide.eclipse.adt.AdtConstants; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.AdtUtils; +import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; +import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.utils.Pair; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.imageio.ImageIO; + +/** + * Wizard for creating a new icon set + */ +public class CreateAssetSetWizard extends Wizard implements INewWizard { + private ChooseAssetTypePage mChooseAssetPage; + private ConfigureAssetSetPage mConfigureAssetPage; + private IProject mInitialProject; + private List<IResource> mCreatedFiles; + private CreateAssetSetWizardState mValues = new CreateAssetSetWizardState(); + + /** Creates a new asset set wizard */ + public CreateAssetSetWizard() { + setWindowTitle("Create Asset Set"); + } + + @Override + public void addPages() { + mValues.project = mInitialProject; + + mChooseAssetPage = new ChooseAssetTypePage(mValues); + mConfigureAssetPage = new ConfigureAssetSetPage(mValues); + + addPage(mChooseAssetPage); + addPage(mConfigureAssetPage); + } + + @Override + public boolean performFinish() { + Map<String, Map<String, BufferedImage>> categories = + ConfigureAssetSetPage.generateImages(mValues, false, null); + + IProject project = mValues.project; + + // Write out the images into the project + boolean yesToAll = false; + mCreatedFiles = new ArrayList<IResource>(); + + for (Map<String, BufferedImage> previews : categories.values()) { + for (Map.Entry<String, BufferedImage> entry : previews.entrySet()) { + String relativePath = entry.getKey(); + IPath dest = new Path(relativePath); + IFile file = project.getFile(dest); + if (file.exists()) { + // Warn that the file already exists and ask the user what to do + if (!yesToAll) { + MessageDialog dialog = new MessageDialog(null, "File Already Exists", null, + String.format( + "%1$s already exists.\nWould you like to replace it?", + file.getProjectRelativePath().toOSString()), + MessageDialog.QUESTION, new String[] { + // Yes will be moved to the end because it's the default + "Yes", "No", "Cancel", "Yes to All" + }, 0); + int result = dialog.open(); + switch (result) { + case 0: + // Yes + break; + case 3: + // Yes to all + yesToAll = true; + break; + case 1: + // No + continue; + case SWT.DEFAULT: + case 2: + // Cancel + return false; + } + } + + try { + file.delete(true, new NullProgressMonitor()); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + } + + AdtUtils.createWsParentDirectory(file.getParent()); + BufferedImage image = entry.getValue(); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + try { + ImageIO.write(image, "PNG", stream); //$NON-NLS-1$ + byte[] bytes = stream.toByteArray(); + InputStream is = new ByteArrayInputStream(bytes); + file.create(is, true /*force*/, null /*progress*/); + mCreatedFiles.add(file); + } catch (IOException e) { + AdtPlugin.log(e, null); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + + try { + file.getParent().refreshLocal(1, new NullProgressMonitor()); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + } + } + + // Finally select the files themselves + selectFiles(project, mCreatedFiles); + + return true; + } + + private void selectFiles(IProject project, List<? extends IResource> createdFiles) { + // Attempt to select the newly created files in the Package Explorer + IWorkbench workbench = AdtPlugin.getDefault().getWorkbench(); + IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage(); + IViewPart viewPart = page.findView(JavaUI.ID_PACKAGES); + if (viewPart != null) { + IWorkbenchPartSite site = viewPart.getSite(); + IJavaProject javaProject = null; + try { + javaProject = BaseProjectHelper.getJavaProject(project); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + final ISelectionProvider provider = site.getSelectionProvider(); + if (provider != null) { + List<TreePath> pathList = new ArrayList<TreePath>(); + for (IResource file : createdFiles) { + // Create a TreePath for the given file, + // which should be the JavaProject, followed by the folders down to + // the final file. + List<Object> segments = new ArrayList<Object>(); + segments.add(file); + IContainer folder = file.getParent(); + if (folder != null && !(folder instanceof IProject)) { + segments.add(folder); + // res folder + folder = folder.getParent(); + if (folder != null && !(folder instanceof IProject)) { + segments.add(folder); + } + } + // project + segments.add(javaProject); + + Collections.reverse(segments); + TreePath path = new TreePath(segments.toArray()); + pathList.add(path); + + // IDEA: Maybe normalize the files backwards (IFile objects aren't unique) + // by maybe using the package explorer icons instead + } + + TreePath[] paths = pathList.toArray(new TreePath[pathList.size()]); + final TreeSelection selection = new TreeSelection(paths); + + provider.setSelection(selection); + + // Workaround: The above doesn't always work; it will frequently select + // some siblings of the real files. I've tried a number of workarounds: + // normalizing the IFile objects by looking up the canonical ones via + // their relative paths from the project; deferring execution with + // Display.asyncRun; first calling select on the parents, etc. + // However, it turns out a simple workaround works best: Calling this + // method TWICE. The first call seems to expand all the necessary parents, + // and the second call ensures that the correct children are selected! + provider.setSelection(selection); + + viewPart.setFocus(); + } + } + } + + /** Sets the initial project to be used by the wizard */ + void setProject(IProject project) { + mInitialProject = project; + mValues.project = project; + } + + @Override + public void init(IWorkbench workbench, IStructuredSelection selection) { + setHelpAvailable(false); + + mInitialProject = guessProject(selection); + mValues.project = mInitialProject; + } + + private IProject guessProject(IStructuredSelection selection) { + if (selection == null) { + return null; + } + + for (Object element : selection.toList()) { + if (element instanceof IAdaptable) { + IResource res = (IResource) ((IAdaptable) element).getAdapter(IResource.class); + IProject project = res != null ? res.getProject() : null; + + // Is this an Android project? + try { + if (project == null || !project.hasNature(AdtConstants.NATURE_DEFAULT)) { + continue; + } + } catch (CoreException e) { + // checking the nature failed, ignore this resource + continue; + } + + return project; + } else if (element instanceof Pair<?, ?>) { + // Pair of Project/String + @SuppressWarnings("unchecked") + Pair<IProject, String> pair = (Pair<IProject, String>) element; + return pair.getFirst(); + } + } + + // Try to figure out the project from the active editor + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window != null) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + IEditorPart activeEditor = page.getActiveEditor(); + if (activeEditor instanceof AndroidXmlEditor) { + Object input = ((AndroidXmlEditor) activeEditor).getEditorInput(); + if (input instanceof FileEditorInput) { + FileEditorInput fileInput = (FileEditorInput) input; + return fileInput.getFile().getProject(); + } + } + } + } + + IJavaProject[] projects = AdtUtils.getOpenAndroidProjects(); + if (projects != null && projects.length == 1) { + return projects[0].getProject(); + } + + return null; + } + + /** + * Returns the list of files created by the wizard. This method will return + * null if {@link #performFinish()} has not yet been called. + * + * @return a list of files created by the wizard, or null + */ + List<IResource> getCreatedFiles() { + return mCreatedFiles; + } +} |