<commit_before>using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using SIL.IO;
using SIL.PlatformUtilities;
using SIL.Reporting;
using SIL.Windows.Forms.ImageToolbox;

namespace SIL.Windows.Forms.Miscellaneous
{
	/// <summary>Uses the GTK classes when accessing the clipboard on Linux</summary>
	public static class PortableClipboard
	{
		public static bool ContainsText()
		{
			return Platform.IsWindows ? Clipboard.ContainsText() : GtkContainsText();
		}

		public static string GetText()
		{
			return Platform.IsWindows ? Clipboard.GetText() : GtkGetText();
		}

		public static string GetText(TextDataFormat format)
		{
			return Platform.IsWindows ? Clipboard.GetText(format) : GtkGetText();
		}

		public static void SetText(string text)
		{
			if (Platform.IsWindows)
				Clipboard.SetText(text);
			else
			GtkSetText(text);
		}

		public static void SetText(string text, TextDataFormat format)
		{
			if (Platform.IsWindows)
				Clipboard.SetText(text, format);
			else
			GtkSetText(text);
		}

		public static bool ContainsImage()
		{
			return Platform.IsWindows ? Clipboard.ContainsImage() : GtkContainsImage();
		}

		public static Image GetImage()
		{
			return Platform.IsWindows ? Clipboard.GetImage() : GtkGetImage();
		}

		public static void CopyImageToClipboard(PalasoImage image)
		{
			// N.B.: PalasoImage does not handle .svg files
			if(image == null)
				return;

			if (!Platform.IsWindows)
			{
			// Review: Someone who knows how needs to implement this!
				throw new NotImplementedException(
					"SIL.Windows.Forms.Miscellaneous.PortableClipboard.CopyImageToClipboard() is not yet implemented for Linux");
			}

			if (image.Image == null)
			{
				if (string.IsNullOrEmpty(image.OriginalFilePath))
					return;
				// no image, but a path
				Clipboard.SetFileDropList(new StringCollection() {image.OriginalFilePath});
			}
			else
			{
				if (string.IsNullOrEmpty(image.OriginalFilePath))
					Clipboard.SetImage(image.Image);
				else
				{
					IDataObject clips = new DataObject();
					clips.SetData(DataFormats.UnicodeText, image.OriginalFilePath);
					clips.SetData(DataFormats.Bitmap, image.Image);
					// true here means that the image should remain on the clipboard if the application exits
					Clipboard.SetDataObject(clips,true);
				}
			}
		}

		// Get an image from the clipboard, ignoring any errors that occur while we attempt to
		// convert whatever is on the clipboard into an image.
		public static PalasoImage GetImageFromClipboard()
		{
			try
			{
				return GetImageFromClipboardWithExceptions();
			}
			catch (Exception)
			{}

			return null;
		}

		// Try to get an image from the clipboard. If there simply isn't anything on the clipboard that
		// can reasonably be interpreted as an image, return null. If there is something that makes sense
		// as an image, but trying to load it causes an exception, let the exception propagate.
		public static PalasoImage GetImageFromClipboardWithExceptions() {
			// N.B.: PalasoImage does not handle .svg files
			if (!Platform.IsWindows)
			{
			if (GtkContainsImage())
				return PalasoImage.FromImage(GtkGetImage());

			if (GtkContainsText())
			{
				//REVIEW: I can find no documentation on GtkClipboard. If ContainsText means we have a file
				//	path, then it would be better to do PalasoImage.FromFileRobustly(); on the file path
				return PalasoImage.FromImage(GtkGetImageFromText());
			}

			return null;
			}

			var dataObject = Clipboard.GetDataObject();
			if (dataObject == null)
				return null;
			Exception ex = null;
			var textData = String.Empty;
			if (dataObject.GetDataPresent(DataFormats.UnicodeText))
				textData = dataObject.GetData(DataFormats.UnicodeText) as String;
			if (Clipboard.ContainsImage())
			{
				PalasoImage plainImage = null;
				try
				{
					plainImage = PalasoImage.FromImage(Clipboard.GetImage()); // this method won't copy any metadata
					var haveFileUrl = !String.IsNullOrEmpty(textData) && RobustFile.Exists(textData);

					// If we have an image on the clipboard, and we also have text that is a valid url to an image file,
					// use the url to create a PalasoImage (which will pull in any metadata associated with the image too)
					if (haveFileUrl)
					{
						var imageWithPathAndMaybeMetadata = PalasoImage.FromFileRobustly(textData);
						plainImage.Dispose();//important: don't do this until we've successfully created the imageWithPathAndMaybeMetadata
						return imageWithPathAndMaybeMetadata;
					}

						return plainImage;
					}
				catch (Exception e)
				{
					Logger.WriteEvent("PortableClipboard.GetImageFromClipboard() failed with message " + e.Message);
					if (plainImage != null)
					return plainImage; // at worst, we should return null; if FromFile() failed, we return an image
					throw;
				}
			}
			// the ContainsImage() returns false when copying an PNG from MS Word
			// so here we explicitly ask for a PNG and see if we can convert it.
			if (dataObject.GetDataPresent("PNG"))
			{
				var o = dataObject.GetData("PNG") as Stream;
				try
				{
					return PalasoImage.FromImage(Image.FromStream(o));
				}
				catch (Exception e)
				{
					// I'm not sure why, but previous versions of this code would continue trying other
					// options at this point.
					ex = e;
				}
			}

			//People can do a "copy" from the WIndows Photo Viewer but what it puts on the clipboard is a path, not an image
			if (dataObject.GetDataPresent(DataFormats.FileDrop))
			{
				//This line gets all the file paths that were selected in explorer
				string[] files = dataObject.GetData(DataFormats.FileDrop) as string[];
				if (files == null) return null;

				foreach (var file in files.Where(f => RobustFile.Exists(f)))
				{
						return PalasoImage.FromFileRobustly(file);
					}

				return null; //not an image
			}

			if (Clipboard.ContainsText() && RobustFile.Exists(Clipboard.GetText()))
				return PalasoImage.FromImage( Image.FromStream(new FileStream(Clipboard.GetText(), FileMode.Open)));

			if (ex != null)<commit_msg>Fix indentation<commit_after>using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using SIL.IO;
using SIL.PlatformUtilities;
using SIL.Reporting;
using SIL.Windows.Forms.ImageToolbox;

namespace SIL.Windows.Forms.Miscellaneous
{
	/// <summary>Uses the GTK classes when accessing the clipboard on Linux</summary>
	public static class PortableClipboard
	{
		public static bool ContainsText()
		{
			return Platform.IsWindows ? Clipboard.ContainsText() : GtkContainsText();
		}

		public static string GetText()
		{
			return Platform.IsWindows ? Clipboard.GetText() : GtkGetText();
		}

		public static string GetText(TextDataFormat format)
		{
			return Platform.IsWindows ? Clipboard.GetText(format) : GtkGetText();
		}

		public static void SetText(string text)
		{
			if (Platform.IsWindows)
				Clipboard.SetText(text);
			else
				GtkSetText(text);
		}

		public static void SetText(string text, TextDataFormat format)
		{
			if (Platform.IsWindows)
				Clipboard.SetText(text, format);
			else
				GtkSetText(text);
		}

		public static bool ContainsImage()
		{
			return Platform.IsWindows ? Clipboard.ContainsImage() : GtkContainsImage();
		}

		public static Image GetImage()
		{
			return Platform.IsWindows ? Clipboard.GetImage() : GtkGetImage();
		}

		public static void CopyImageToClipboard(PalasoImage image)
		{
			// N.B.: PalasoImage does not handle .svg files
			if(image == null)
				return;

			if (!Platform.IsWindows)
			{
				// Review: Someone who knows how needs to implement this!
				throw new NotImplementedException(
					"SIL.Windows.Forms.Miscellaneous.PortableClipboard.CopyImageToClipboard() is not yet implemented for Linux");
			}

			if (image.Image == null)
			{
				if (string.IsNullOrEmpty(image.OriginalFilePath))
					return;
				// no image, but a path
				Clipboard.SetFileDropList(new StringCollection() {image.OriginalFilePath});
			}
			else
			{
				if (string.IsNullOrEmpty(image.OriginalFilePath))
					Clipboard.SetImage(image.Image);
				else
				{
					IDataObject clips = new DataObject();
					clips.SetData(DataFormats.UnicodeText, image.OriginalFilePath);
					clips.SetData(DataFormats.Bitmap, image.Image);
					// true here means that the image should remain on the clipboard if the application exits
					Clipboard.SetDataObject(clips,true);
				}
			}
		}

		// Get an image from the clipboard, ignoring any errors that occur while we attempt to
		// convert whatever is on the clipboard into an image.
		public static PalasoImage GetImageFromClipboard()
		{
			try
			{
				return GetImageFromClipboardWithExceptions();
			}
			catch (Exception)
			{}

			return null;
		}

		// Try to get an image from the clipboard. If there simply isn't anything on the clipboard that
		// can reasonably be interpreted as an image, return null. If there is something that makes sense
		// as an image, but trying to load it causes an exception, let the exception propagate.
		public static PalasoImage GetImageFromClipboardWithExceptions() {
			// N.B.: PalasoImage does not handle .svg files
			if (!Platform.IsWindows)
			{
				if (GtkContainsImage())
					return PalasoImage.FromImage(GtkGetImage());

				if (GtkContainsText())
				{
					//REVIEW: I can find no documentation on GtkClipboard. If ContainsText means we have a file
					//	path, then it would be better to do PalasoImage.FromFileRobustly(); on the file path
					return PalasoImage.FromImage(GtkGetImageFromText());
				}

				return null;
			}

			var dataObject = Clipboard.GetDataObject();
			if (dataObject == null)
				return null;
			Exception ex = null;
			var textData = string.Empty;
			if (dataObject.GetDataPresent(DataFormats.UnicodeText))
				textData = dataObject.GetData(DataFormats.UnicodeText) as string;
			if (Clipboard.ContainsImage())
			{
				PalasoImage plainImage = null;
				try
				{
					plainImage = PalasoImage.FromImage(Clipboard.GetImage()); // this method won't copy any metadata
					var haveFileUrl = !string.IsNullOrEmpty(textData) && RobustFile.Exists(textData);

					// If we have an image on the clipboard, and we also have text that is a valid url to an image file,
					// use the url to create a PalasoImage (which will pull in any metadata associated with the image too)
					if (haveFileUrl)
					{
						var imageWithPathAndMaybeMetadata = PalasoImage.FromFileRobustly(textData);
						plainImage.Dispose();//important: don't do this until we've successfully created the imageWithPathAndMaybeMetadata
						return imageWithPathAndMaybeMetadata;
					}

					return plainImage;
				}
				catch (Exception e)
				{
					Logger.WriteEvent("PortableClipboard.GetImageFromClipboard() failed with message " + e.Message);
					if (plainImage != null)
						return plainImage; // at worst, we should return null; if FromFile() failed, we return an image
					throw;
				}
			}
			// the ContainsImage() returns false when copying an PNG from MS Word
			// so here we explicitly ask for a PNG and see if we can convert it.
			if (dataObject.GetDataPresent("PNG"))
			{
				var o = dataObject.GetData("PNG") as Stream;
				try
				{
					return PalasoImage.FromImage(Image.FromStream(o));
				}
				catch (Exception e)
				{
					// I'm not sure why, but previous versions of this code would continue trying other
					// options at this point.
					ex = e;
				}
			}

			//People can do a "copy" from the Windows Photo Viewer but what it puts on the clipboard is a path, not an image
			if (dataObject.GetDataPresent(DataFormats.FileDrop))
			{
				//This line gets all the file paths that were selected in explorer
				string[] files = dataObject.GetData(DataFormats.FileDrop) as string[];
				if (files == null) return null;

				foreach (var file in files.Where(f => RobustFile.Exists(f)))
				{
						return PalasoImage.FromFileRobustly(file);
				}

				return null; //not an image
			}

			if (Clipboard.ContainsText() && RobustFile.Exists(Clipboard.GetText()))
				return PalasoImage.FromImage( Image.FromStream(new FileStream(Clipboard.GetText(), FileMode.Open)));

			if (ex != null)
{'fraction_non_alphanumeric': 0.09127821991229496, 'fraction_numerical': 0.0, 'mean_word_length': 3.3763326226012795, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '2762671', 'n_tokens_mistral': 4479, 'n_tokens_neox': 3642, 'n_words': 1138}