2008-12-08 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / Clipboard.cs
index 995839e91f66ffddb788f8f1951ca6c1a2101abd..62b52e4409cef1605b4aa209d3ae3ebc610d7a21 100644 (file)
@@ -30,6 +30,9 @@ using System;
 using System.Drawing;
 using System.IO;
 using System.Runtime.InteropServices;
+using System.Collections;
+using System.Collections.Specialized;
+using System.ComponentModel;
 
 namespace System.Windows.Forms {
        public sealed class Clipboard {
@@ -57,59 +60,181 @@ namespace System.Windows.Forms {
                #endregion      // Private Methods
 
                #region Public Static Methods
+#if NET_2_0
+               public static void Clear ()
+               {
+                       IntPtr clipboard_handle;
+
+                       clipboard_handle = XplatUI.ClipboardOpen (false);
+                       XplatUI.ClipboardStore (clipboard_handle, null, 0, null);
+               }
+
+               public static bool ContainsAudio ()
+               {
+                       return ClipboardContainsFormat (DataFormats.WaveAudio);
+               }
+               
+               public static bool ContainsData (string format)
+               {
+                       return ClipboardContainsFormat (format);
+               }
+               
+               public static bool ContainsFileDropList ()
+               {
+                       return ClipboardContainsFormat (DataFormats.FileDrop);
+               }
+               
+               public static bool ContainsImage ()
+               {
+                       return ClipboardContainsFormat (DataFormats.Bitmap);
+               }
+               
+               public static bool ContainsText ()
+               {
+                       return ClipboardContainsFormat (DataFormats.Text, DataFormats.UnicodeText);
+               }
+               
+               public static bool ContainsText (TextDataFormat format)
+               {
+                       switch (format) {
+                               case TextDataFormat.Text:
+                                       return ClipboardContainsFormat (DataFormats.Text);
+                               case TextDataFormat.UnicodeText:
+                                       return ClipboardContainsFormat (DataFormats.UnicodeText);
+                               case TextDataFormat.Rtf:
+                                       return ClipboardContainsFormat (DataFormats.Rtf);
+                               case TextDataFormat.Html:
+                                       return ClipboardContainsFormat (DataFormats.Html);
+                               case TextDataFormat.CommaSeparatedValue:
+                                       return ClipboardContainsFormat (DataFormats.CommaSeparatedValue);
+                       }
+                       
+                       return false;
+               }
+               
+               public static Stream GetAudioStream ()
+               {
+                       IDataObject data = GetDataObject ();
+
+                       if (data == null)
+                               return null;
+
+                       return (Stream)data.GetData (DataFormats.WaveAudio, true);
+               }
+               
+               public static Object GetData (string format)
+               {
+                       IDataObject data = GetDataObject ();
+
+                       if (data == null)
+                               return null;
+
+                       return data.GetData (format, true);
+               }
+#endif
 
                public static IDataObject GetDataObject ()
                {
                        return GetDataObject (false);
                }
 
-               internal static IDataObject GetDataObject (bool primary_selection)
+#if NET_2_0
+               public static StringCollection GetFileDropList ()
                {
-                       DataObject              clipboard;
-                       IntPtr                  clipboard_handle;
-                       int[]                   native_formats;
-                       DataFormats.Format      item_format;
-                       object                  managed_clipboard_item;
-                       XplatUI.ClipboardToObject converter;
-
-                       converter = new XplatUI.ClipboardToObject(ConvertFromClipboardData);
+                       IDataObject data = GetDataObject ();
 
-                       clipboard_handle = XplatUI.ClipboardOpen (primary_selection);
-                       native_formats = XplatUI.ClipboardAvailableFormats(clipboard_handle);
-                       if (native_formats == null) {
-                               return null;    // Clipboard empty
-                       }
+                       if (data == null)
+                               return null;
 
-                       // Build the IDataObject
-                       clipboard = new DataObject();
-                       for (int i = 0; i < native_formats.Length; i++) {
-                               // We might get a format we don't understand or know
-                               item_format = DataFormats.GetFormat(native_formats[i]);
+                       return (StringCollection)data.GetData (DataFormats.FileDrop, true);
+               }
+               
+               public static Image GetImage ()
+               {
+                       IDataObject data = GetDataObject ();
 
-                               if (item_format != null) {
-                                       managed_clipboard_item = XplatUI.ClipboardRetrieve(clipboard_handle, native_formats[i], converter);
+                       if (data == null)
+                               return null;
 
-                                       if (managed_clipboard_item != null) {
-                                               clipboard.SetData(item_format.Name, managed_clipboard_item);
-                                               // We don't handle 'bitmap' since it involves handles, so we'll equate it to dib
-                                               if (item_format.Name == DataFormats.Dib) {
-                                                       clipboard.SetData(DataFormats.Bitmap, managed_clipboard_item);
-                                               }
-                                       }
-                               }
+                       return (Image)data.GetData (DataFormats.Bitmap, true);
+               }
+               
+               public static string GetText ()
+               {
+                       return GetText (TextDataFormat.UnicodeText);
+               }
+               
+               public static string GetText (TextDataFormat format)
+               {
+                       if (!Enum.IsDefined (typeof (TextDataFormat), format))
+                               throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for TextDataFormat", format));
+                               
+                       IDataObject data = GetDataObject ();
+                       
+                       if (data == null)
+                               return string.Empty;
+                               
+                       string retval;
+                       
+                       switch (format) {
+                               case TextDataFormat.Text:
+                               default:
+                                       retval = (string)data.GetData (DataFormats.Text, true);
+                                       break;
+                               case TextDataFormat.UnicodeText:
+                                       retval = (string)data.GetData (DataFormats.UnicodeText, true);
+                                       break;
+                               case TextDataFormat.Rtf:
+                                       retval = (string)data.GetData (DataFormats.Rtf, true);
+                                       break;
+                               case TextDataFormat.Html:
+                                       retval = (string)data.GetData (DataFormats.Html, true);
+                                       break;
+                               case TextDataFormat.CommaSeparatedValue:
+                                       retval = (string)data.GetData (DataFormats.CommaSeparatedValue, true);
+                                       break;
                        }
+                       
+                       return retval == null ? string.Empty : retval;
+               }
+               
+               public static void SetAudio (byte[] audioBytes)
+               {
+                       if (audioBytes == null)
+                               throw new ArgumentNullException ("audioBytes");
+                               
+                       MemoryStream ms = new MemoryStream (audioBytes);
+                       
+                       SetAudio (ms);
+               }
+               
+               public static void SetAudio (Stream audioStream)
+               {
+                       if (audioStream == null)
+                               throw new ArgumentNullException ("audioStream");
 
-                       XplatUI.ClipboardClose(clipboard_handle);
+                       SetData (DataFormats.WaveAudio, audioStream);
+               }
 
-                       return clipboard;
+               [MonoInternalNote ("Does not use requested format")]
+               public static void SetData (string format, Object data)
+               {
+                       if (data == null)
+                               throw new ArgumentNullException ("data");
+                               
+                       SetDataObject (data);
                }
+#endif
 
                public static void SetDataObject(object data) {
-                       SetDataObject(data, true);
-                       
+                       SetDataObject(data, false);  // MSDN says default behavior is to place non-persistent data to clipboard
                }
 
                public static void SetDataObject(object data, bool copy) {
+                       SetDataObject(data, copy, 10, 100);   // MSDN says default behavior is to try 10 times with 100 ms delay
+               }
+
+               internal static void SetDataObjectImpl(object data, bool copy) {
                        IntPtr                  clipboard_handle;
                        XplatUI.ObjectToClipboard converter;
                        int                     native_format;
@@ -144,6 +269,158 @@ namespace System.Windows.Forms {
                        }
                        XplatUI.ClipboardClose(clipboard_handle);
                }
+
+#if NET_2_0
+               public 
+#else
+               internal 
+#endif
+               static void SetDataObject(object data, bool copy, int retryTimes, int retryDelay)
+               {
+                       if (data == null)
+                               throw new ArgumentNullException("data");
+                       if (retryTimes < 0)
+                               throw new ArgumentOutOfRangeException("retryTimes");
+                       if (retryDelay < 0)
+                               throw new ArgumentOutOfRangeException("retryDelay");
+
+                       // MS implementation actually puts data to clipboard even when retryTimes == 0
+                       bool retry = true;
+                       do
+                       {
+                               retry = false;
+                               --retryTimes;
+                               try
+                               {
+                                       SetDataObjectImpl(data, copy);
+                               } catch (ExternalException) {
+                                       if (retryTimes <= 0)
+                                               throw;
+                                       retry = true;
+                                       Threading.Thread.Sleep(retryDelay);
+                               }
+                       } while (retry && retryTimes > 0);
+               }
+
+#if NET_2_0
+               [MonoInternalNote ("Needs additional checks for valid paths, see MSDN")]
+               public static void SetFileDropList (StringCollection filePaths)
+               {
+                       if (filePaths == null)
+                               throw new ArgumentNullException ("filePaths");
+                               
+                       SetData (DataFormats.FileDrop, filePaths);
+               }
+               
+               public static void SetImage (Image image)
+               {
+                       if (image == null)
+                               throw new ArgumentNullException ("image");
+                       
+                       SetData (DataFormats.Bitmap, image);
+               }
+               
+               public static void SetText (string text)
+               {
+                       if (string.IsNullOrEmpty (text))
+                               throw new ArgumentNullException ("text");
+                               
+                       SetData (DataFormats.UnicodeText, text);
+               }
+               
+               public static void SetText (string text, TextDataFormat format)
+               {
+                       if (string.IsNullOrEmpty (text))
+                               throw new ArgumentNullException ("text");
+                       if (!Enum.IsDefined (typeof (TextDataFormat), format))
+                               throw new InvalidEnumArgumentException (string.Format ("Enum argument value '{0}' is not valid for TextDataFormat", format));
+
+                       switch (format) {
+                               case TextDataFormat.Text:
+                                       SetData (DataFormats.Text, text);
+                                       break;
+                               case TextDataFormat.UnicodeText:
+                                       SetData (DataFormats.UnicodeText, text);
+                                       break;
+                               case TextDataFormat.Rtf:
+                                       SetData (DataFormats.Rtf, text);
+                                       break;
+                               case TextDataFormat.Html:
+                                       SetData (DataFormats.Html, text);
+                                       break;
+                               case TextDataFormat.CommaSeparatedValue:
+                                       SetData (DataFormats.CommaSeparatedValue, text);
+                                       break;
+                       }
+               }
+#endif
                #endregion      // Public Static Methods
+
+               #region Internal Static Methods
+               internal static IDataObject GetDataObject (bool primary_selection)
+               {
+                       DataObject clipboard;
+                       IntPtr clipboard_handle;
+                       int[] native_formats;
+                       DataFormats.Format item_format;
+                       object managed_clipboard_item;
+                       XplatUI.ClipboardToObject converter;
+
+                       converter = new XplatUI.ClipboardToObject (ConvertFromClipboardData);
+
+                       clipboard_handle = XplatUI.ClipboardOpen (primary_selection);
+                       native_formats = XplatUI.ClipboardAvailableFormats (clipboard_handle);
+                       if (native_formats == null) {
+                               return null;    // Clipboard empty
+                       }
+
+                       // Build the IDataObject
+                       clipboard = new DataObject ();
+                       for (int i = 0; i < native_formats.Length; i++) {
+                               // We might get a format we don't understand or know
+                               item_format = DataFormats.GetFormat (native_formats[i]);
+
+                               if (item_format != null) {
+                                       managed_clipboard_item = XplatUI.ClipboardRetrieve (clipboard_handle, native_formats[i], converter);
+
+                                       if (managed_clipboard_item != null) {
+                                               clipboard.SetData (item_format.Name, managed_clipboard_item);
+                                               // We don't handle 'bitmap' since it involves handles, so we'll equate it to dib
+                                               if (item_format.Name == DataFormats.Dib) {
+                                                       clipboard.SetData (DataFormats.Bitmap, managed_clipboard_item);
+                                               }
+                                       }
+                               }
+                       }
+
+                       XplatUI.ClipboardClose (clipboard_handle);
+
+                       return clipboard;
+               }
+               
+               internal static bool ClipboardContainsFormat (params string[] formats)
+               {
+                       IntPtr clipboard_handle;
+                       int[] native_formats;
+                       DataFormats.Format item_format;
+
+                       clipboard_handle = XplatUI.ClipboardOpen (false);
+                       native_formats = XplatUI.ClipboardAvailableFormats (clipboard_handle);
+                       
+                       if (native_formats == null)
+                               return false;
+                               
+                       foreach (int i in native_formats) {
+                               // We might get a format we don't understand or know
+                               item_format = DataFormats.GetFormat (i);
+                               
+                               if (item_format != null)
+                                       if (((IList)formats).Contains (item_format.Name))
+                                               return true;
+                       }
+                               
+                       return false;
+               }
+               #endregion
        }
 }