Java tutorial
/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * 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.tools.idea.rendering.webp; import com.android.tools.idea.lint.AndroidLintWebpUnsupportedInspection; import com.google.common.collect.Lists; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.Collection; import java.util.LinkedList; import java.util.List; import static com.android.SdkConstants.DOT_PNG; import static com.android.SdkConstants.DOT_WEBP; import static com.android.utils.SdkUtils.endsWithIgnoreCase; /** * Action which converts WEBP images to PNG */ public class ConvertFromWebpAction extends DumbAwareAction { @Nls(capitalization = Nls.Capitalization.Title) public static final String TITLE = "Convert from WebP to PNG"; @Override public void actionPerformed(AnActionEvent e) { Project project = e.getProject(); if (project == null) { return; } int answer = Messages.showYesNoCancelDialog(project, "Delete .webp files after saving as .png?", TITLE, null); if (answer == Messages.CANCEL) { return; } boolean delete = answer == Messages.YES; VirtualFile[] files = e.getRequiredData(CommonDataKeys.VIRTUAL_FILE_ARRAY); perform(project, files, delete); } public void perform(@NotNull Project project, @NotNull VirtualFile[] files, boolean deleteWebp) { convert(project, Arrays.asList(files), deleteWebp); } @Override public void update(AnActionEvent e) { VirtualFile[] files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY); if (files != null && e.getProject() != null) { for (VirtualFile file : files) { if (endsWithIgnoreCase(file.getName(), DOT_WEBP)) { e.getPresentation().setEnabledAndVisible(true); return; } } } e.getPresentation().setEnabledAndVisible(false); } public void convert(@NotNull Project project, @NotNull Collection<VirtualFile> files, boolean delete) { ProgressManager.getInstance().run(new WebpConversionTask(project, files, delete)); } static class WebpConversionTask extends Task.Backgroundable { private final Project myProject; private final Collection<VirtualFile> myFiles; private final boolean myDelete; private List<VirtualFile> myParentFolders; private List<VirtualFile> myConvertedFiles; public WebpConversionTask(Project project, Collection<VirtualFile> files, boolean delete) { super(project, TITLE, true); myProject = project; myFiles = files; myDelete = delete; } @Override public void onFinished() { writeImages(this, myProject, myConvertedFiles); refreshFolders(myParentFolders); } private void writeImages(@NotNull Object requestor, @NotNull Project project, @NotNull List<VirtualFile> files) { WriteCommandAction.runWriteCommandAction(project, () -> { for (VirtualFile file : files) { try { if (!file.isValid()) { continue; } BufferedImage image = ImageIO.read(file.getInputStream()); if (image != null) { ByteArrayOutputStream stream = new ByteArrayOutputStream(2048); ImageIO.write(image, "PNG", stream); byte[] encoded = stream.toByteArray(); VirtualFile folder = file.getParent(); VirtualFile output = folder.createChildData(requestor, file.getNameWithoutExtension() + DOT_PNG); try (OutputStream fos = new BufferedOutputStream(output.getOutputStream(this))) { fos.write(encoded); } if (myDelete) { file.delete(requestor); } } } catch (IOException e) { Logger.getInstance(AndroidLintWebpUnsupportedInspection.class).warn(e.getMessage()); } } }); } @Override public void run(@NotNull ProgressIndicator progressIndicator) { LinkedList<VirtualFile> images = new LinkedList<>(myFiles); myConvertedFiles = findImages(progressIndicator, images); myParentFolders = computeParentFolders(myConvertedFiles); } @NotNull private static List<VirtualFile> findImages(@NotNull ProgressIndicator progressIndicator, LinkedList<VirtualFile> images) { List<VirtualFile> files = Lists.newArrayList(); while (!images.isEmpty()) { progressIndicator.checkCanceled(); VirtualFile file = images.pop(); progressIndicator.setText(file.getPath()); if (file.isDirectory()) { for (VirtualFile f : file.getChildren()) { images.push(f); } } else if (endsWithIgnoreCase(file.getName(), DOT_WEBP)) { files.add(file); } } return files; } } private static void refreshFolders(List<VirtualFile> toRefresh) { for (VirtualFile dir : toRefresh) { dir.refresh(true, true); } } @NotNull private static List<VirtualFile> computeParentFolders(@NotNull List<VirtualFile> files) { List<VirtualFile> toRefresh = Lists.newArrayList(); for (VirtualFile file : files) { VirtualFile parent = file.getParent(); if (parent != null && !toRefresh.contains(parent)) { toRefresh.add(parent); } } return toRefresh; } }