<commit_before>/*******************************************************************************
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

package org.eclipse.mylyn.internal.tasks.ui.wizards;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
import org.eclipse.mylyn.internal.provisional.commons.ui.ScreenshotCreationPage;
import org.eclipse.mylyn.internal.tasks.core.sync.SubmitTaskAttachmentJob;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.util.AttachmentUtil;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobEvent;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobListener;
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
import org.eclipse.mylyn.tasks.ui.TasksUiImages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;

/**
 * A wizard to add a new attachment to a task report.
 * 
 * @since 3.0
 * @author <NAME>
 */
public class TaskAttachmentWizard extends Wizard {

	static class ClipboardTaskAttachmentSource extends AbstractTaskAttachmentSource {

		public static boolean isSupportedType(Display display) {
			Clipboard clipboard = new Clipboard(display);
			TransferData[] types = clipboard.getAvailableTypes();
			for (TransferData transferData : types) {
				List<Transfer> transfers = getTransfers();
				for (Transfer transfer : transfers) {
					if (transfer.isSupportedType(transferData)) {
						return true;
					}
				}
			}
			return false;
		}

		private static List<Transfer> transfers;

		private static List<Transfer> getTransfers() {
			if (transfers != null) {
				return transfers;
			}

			transfers = new ArrayList<Transfer>();
			try {
				Class<?> clazz = Class.forName("org.eclipse.swt.dnd.ImageTransfer");
				Method method = clazz.getMethod("getInstance");
				if (method != null) {
					transfers.add((Transfer) method.invoke(null));
				}
			} catch (Exception e) {
				// ignore
			} catch (LinkageError e) {
				// ignore
			}
			transfers.add(TextTransfer.getInstance());
			return transfers;
		}

		private Object contents;

		public ClipboardTaskAttachmentSource() {
			BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() {
				public void run() {
					Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
					List<Transfer> transfers = getTransfers();
					for (Transfer transfer : transfers) {
						contents = clipboard.getContents(transfer);
						if (contents != null) {
							break;
						}
					}
					clipboard.dispose();
				}
			});
		}

		@Override
		public InputStream createInputStream(IProgressMonitor monitor) throws CoreException {
			if (contents instanceof String) {
				return new ByteArrayInputStream(((String) contents).getBytes());
			} else if (contents instanceof ImageData) {
				ImageLoader loader = new ImageLoader();
				loader.data = new ImageData[] { (ImageData) contents };
				// TODO create image in memory?
				ByteArrayOutputStream out = new ByteArrayOutputStream();
				loader.save(out, SWT.IMAGE_PNG);
				return new ByteArrayInputStream(out.toByteArray());
			}
			throw new CoreException(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Invalid content type."));
		}

		@Override
		public String getContentType() {
			if (contents instanceof String) {
				return "text/plain";
			} else if (contents instanceof ImageData) {
				return "image/png";
			}
			return "application/octet-stream";
		}

		@Override
		public String getDescription() {
			return null;
		}

		@Override
		public long getLength() {
			if (contents instanceof String) {
				return ((String) contents).length();
			}
			return -1;
		}

		@Override
		public String getName() {
			if (contents instanceof String) {
				return "clipboard.txt";
			} else if (contents instanceof ImageData) {
				return "clipboard.png";
			}
			return "";
		}

		@Override
		public boolean isLocal() {
			return true;
		}

	};

	static class ImageSource extends AbstractTaskAttachmentSource {

		private File file;

		private final ScreenshotCreationPage page;

		public ImageSource(ScreenshotCreationPage page) {
			this.page = page;
		}

		@Override<commit_msg>NEW - bug 238016: [patch] attaching images from clipboard fails https://bugs.eclipse.org/bugs/show_bug.cgi?id=238016<commit_after>/*******************************************************************************
 * Copyright (c) 2004, 2007 Mylyn project committers and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

package org.eclipse.mylyn.internal.tasks.ui.wizards;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.provisional.commons.ui.CommonImages;
import org.eclipse.mylyn.internal.provisional.commons.ui.ScreenshotCreationPage;
import org.eclipse.mylyn.internal.tasks.core.sync.SubmitTaskAttachmentJob;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.util.AttachmentUtil;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.sync.SubmitJob;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobEvent;
import org.eclipse.mylyn.tasks.core.sync.SubmitJobListener;
import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi;
import org.eclipse.mylyn.tasks.ui.TasksUiImages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;

/**
 * A wizard to add a new attachment to a task report.
 * 
 * @since 3.0
 * @author <NAME>
 */
public class TaskAttachmentWizard extends Wizard {

	static class ClipboardTaskAttachmentSource extends AbstractTaskAttachmentSource {

		private byte[] data;

		public static boolean isSupportedType(Display display) {
			Clipboard clipboard = new Clipboard(display);
			TransferData[] types = clipboard.getAvailableTypes();
			for (TransferData transferData : types) {
				List<Transfer> transfers = getTransfers();
				for (Transfer transfer : transfers) {
					if (transfer.isSupportedType(transferData)) {
						return true;
					}
				}
			}
			return false;
		}

		private static List<Transfer> transfers;

		private static List<Transfer> getTransfers() {
			if (transfers != null) {
				return transfers;
			}

			transfers = new ArrayList<Transfer>();
			try {
				Class<?> clazz = Class.forName("org.eclipse.swt.dnd.ImageTransfer");
				Method method = clazz.getMethod("getInstance");
				if (method != null) {
					transfers.add((Transfer) method.invoke(null));
				}
			} catch (Exception e) {
				// ignore
			} catch (LinkageError e) {
				// ignore
			}
			transfers.add(TextTransfer.getInstance());
			return transfers;
		}

		private Object contents;

		public ClipboardTaskAttachmentSource() {
			BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(), new Runnable() {
				public void run() {
					Clipboard clipboard = new Clipboard(PlatformUI.getWorkbench().getDisplay());
					List<Transfer> transfers = getTransfers();
					for (Transfer transfer : transfers) {
						contents = clipboard.getContents(transfer);
						if (contents != null) {
							break;
						}
					}
					clipboard.dispose();
				}
			});
		}

		@Override
		public InputStream createInputStream(IProgressMonitor monitor) throws CoreException {
			byte[] bytes = getData();
			if (bytes != null) {
				return new ByteArrayInputStream(data);
			}
			throw new CoreException(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Invalid content type."));
		}

		@Override
		public String getContentType() {
			if (contents instanceof String) {
				return "text/plain";
			} else if (contents instanceof ImageData) {
				return "image/png";
			}
			return "application/octet-stream";
		}

		@Override
		public String getDescription() {
			return null;
		}

		@Override
		public long getLength() {
			byte[] bytes = getData();
			return (bytes != null) ? bytes.length : -1;
		}

		private byte[] getData() {
			if (data == null) {
				if (contents instanceof String) {
					data = ((String) contents).getBytes();
				} else if (contents instanceof ImageData) {
					ImageLoader loader = new ImageLoader();
					loader.data = new ImageData[] { (ImageData) contents };
					ByteArrayOutputStream out = new ByteArrayOutputStream();
					loader.save(out, SWT.IMAGE_PNG);
					data = out.toByteArray();
				}
			}
			return data;
		}

		@Override
		public String getName() {
			if (contents instanceof String) {
				return "clipboard.txt";
			} else if (contents instanceof ImageData) {
				return "clipboard.png";
			}
			return "";
		}

		@Override
		public boolean isLocal() {
			return true;
		}

	};

	static class ImageSource extends AbstractTaskAttachmentSource {

		private File file;

		private final ScreenshotCreationPage page;

		public ImageSource(ScreenshotCreationPage page) {
			this.page = page;
		}

		@Override
{'fraction_non_alphanumeric': 0.13205310573731627, 'fraction_numerical': 0.003319108582266477, 'mean_word_length': 4.378240543986401, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 1, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5017588', 'n_tokens_mistral': 4247, 'n_tokens_neox': 3668, 'n_words': 810}