2009-06-01 Carlos Alberto Cortez <calberto.cortez@gmail.com>
authorCarlos Alberto Cortez <calberto.cortez@gmail.com>
Mon, 1 Jun 2009 21:03:09 +0000 (21:03 -0000)
committerCarlos Alberto Cortez <calberto.cortez@gmail.com>
Mon, 1 Jun 2009 21:03:09 +0000 (21:03 -0000)
* Clipboard.cs:
* XplatUIX11.cs:
* DataFormats.cs: Implement support for serializable types in our
clipboard.
Fixes #357642.

svn path=/trunk/mcs/; revision=135152

mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataFormats.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

index d78bb25052eebfd67f7727b75041e9f68c66c73f..dc0acd79c465f5c2ef6fb1dcf31c3aac81f18cf5 100644 (file)
@@ -1,3 +1,11 @@
+2009-06-01  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * Clipboard.cs:
+       * XplatUIX11.cs:
+       * DataFormats.cs: Implement support for serializable types in our
+       clipboard.
+       Fixes #357642.
+
 2009-05-25  Carlos Alberto Cortez <calberto.cortez@gmail.com>
 
        * ColorDialog.cs: Actually add the help button to the form, so it can
index 3febc4bee4abe3d62ee77f66a9ce9d531d318c3f..861bd99c888760d6e75a1bc96fe928c7ed95d105 100644 (file)
@@ -30,6 +30,7 @@ using System;
 using System.Drawing;
 using System.IO;
 using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
 using System.Collections;
 using System.Collections.Specialized;
 using System.ComponentModel;
@@ -250,14 +251,21 @@ namespace System.Windows.Forms {
                        if (data is IDataObject) {
                                string[] formats;
 
-                               formats = ((IDataObject)data).GetFormats();
+                               IDataObject data_object = data as IDataObject;
+                               formats = data_object.GetFormats();
                                for (int i = 0; i < formats.Length; i++) {
                                        item_format = DataFormats.GetFormat(formats[i]);
                                        if ((item_format != null) && (item_format.Name != DataFormats.StringFormat)) {
                                                native_format = item_format.Id;
                                        }
 
-                                       XplatUI.ClipboardStore(clipboard_handle, ((IDataObject)data).GetData(formats[i]), native_format, converter);
+                                       object obj = data_object.GetData (formats [i]);
+
+                                       // this is used only by custom formats
+                                       if (IsDataSerializable (obj))
+                                               item_format.is_serializable = true;
+
+                                       XplatUI.ClipboardStore(clipboard_handle, obj, native_format, converter);
                                }
                        } else {
                                item_format = DataFormats.Format.Find(data.GetType().FullName);
@@ -270,6 +278,15 @@ namespace System.Windows.Forms {
                        XplatUI.ClipboardClose(clipboard_handle);
                }
 
+               static bool IsDataSerializable (object obj)
+               {
+                       if (obj is ISerializable)
+                               return true;
+
+                       AttributeCollection attrs = TypeDescriptor.GetAttributes (obj);
+                       return attrs [typeof (SerializableAttribute)] != null;
+               }
+
 #if NET_2_0
                public 
 #else
index aa5f88dafa847dc78a730945b0b35708ae69b76c..ec20342994163f84b5029892f1b140bdd34ebce1 100644 (file)
@@ -42,6 +42,7 @@ namespace System.Windows.Forms
                        private string          name;
                        private int             id;
                        private Format          next;
+                       internal bool           is_serializable;
 
                        public Format (string name, int id)
                        {
@@ -162,6 +163,17 @@ namespace System.Windows.Forms
                private static object lock_object = new object ();
                private static bool initialized;
 
+               // we don't want to force the creation of a new format
+               internal static bool ContainsFormat (int id)
+               {
+                       lock (lock_object) {
+                               if (!initialized)
+                                       Init ();
+
+                               return Format.Find (id) != null;
+                       }
+               }
+
                public static Format GetFormat (int id)
                {
                        lock (lock_object) {
index b5398c9b7675c540b13734d7eeb0fd5a21915d85..90d23ba584ba64e6c690e8d081b1fc86612392a4 100644 (file)
@@ -62,6 +62,8 @@ using System.Net;
 using System.Net.Sockets;
 using System.Reflection;
 using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 using System.Text;
 using System.Threading;
 
@@ -1261,6 +1263,18 @@ namespace System.Windows.Forms {
                                        Clipboard.Item = Marshal.PtrToStringUni (prop, Encoding.Unicode.GetMaxCharCount ((int)nitems));
                                } else if (property == RICHTEXTFORMAT)
                                        Clipboard.Item = Marshal.PtrToStringAnsi(prop);
+                               else if (DataFormats.ContainsFormat (property.ToInt32 ())) {
+                                       if (DataFormats.GetFormat (property.ToInt32 ()).is_serializable) {
+                                               MemoryStream memory_stream = new MemoryStream ((int)nitems);
+                                               for (int i = 0; i < (int)nitems; i++)
+                                                       memory_stream.WriteByte (Marshal.ReadByte (prop, i));
+
+                                               memory_stream.Position = 0;
+                                               BinaryFormatter formatter = new BinaryFormatter ();
+                                               Clipboard.Item = formatter.Deserialize (memory_stream);
+                                               memory_stream.Close ();
+                                       }
+                               }
 
                                XFree(prop);
                        }
@@ -1701,8 +1715,10 @@ namespace System.Windows.Forms {
                                        sel_event.SelectionEvent.time = xevent.SelectionRequestEvent.time;
                                        sel_event.SelectionEvent.property = IntPtr.Zero;
 
+                                       IntPtr format_atom = xevent.SelectionRequestEvent.target;
+
                                        // Seems that some apps support asking for supported types
-                                       if (xevent.SelectionRequestEvent.target == TARGETS) {
+                                       if (format_atom == TARGETS) {
                                                int[]   atoms;
                                                int     atom_count;
 
@@ -1725,7 +1741,7 @@ namespace System.Windows.Forms {
                                                XChangeProperty(DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, 
                                                                (IntPtr)xevent.SelectionRequestEvent.target, 32, PropertyMode.Replace, atoms, atom_count);
                                                sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
-                                       } else if (xevent.SelectionRequestEvent.target == (IntPtr)RICHTEXTFORMAT) {
+                                       } else if (format_atom == (IntPtr)RICHTEXTFORMAT) {
                                                string rtf_text = Clipboard.GetRtfText ();
                                                if (rtf_text != null) {
                                                        // The RTF spec mentions that ascii is enough to contain it
@@ -1774,6 +1790,27 @@ namespace System.Windows.Forms {
                                                        sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
                                                        Marshal.FreeHGlobal(buffer);
                                                }
+                                       } else if (Clipboard.GetSource (format_atom.ToInt32 ()) != null) { // check if we have an available value of this format
+                                               if (DataFormats.GetFormat (format_atom.ToInt32 ()).is_serializable) {
+                                                       object serializable = Clipboard.GetSource (format_atom.ToInt32 ());
+
+                                                       BinaryFormatter formatter = new BinaryFormatter ();
+                                                       MemoryStream memory_stream = new MemoryStream ();
+                                                       formatter.Serialize (memory_stream, serializable);
+
+                                                       int buflen = (int)memory_stream.Length;
+                                                       IntPtr buffer = Marshal.AllocHGlobal (buflen);
+                                                       memory_stream.Position = 0;
+                                                       for (int i = 0; i < buflen; i++)
+                                                               Marshal.WriteByte (buffer, i, (byte)memory_stream.ReadByte ());
+                                                       memory_stream.Close ();
+
+                                                       XChangeProperty (DisplayHandle, xevent.SelectionRequestEvent.requestor, (IntPtr)xevent.SelectionRequestEvent.property, (IntPtr)xevent.SelectionRequestEvent.target,
+                                                                       8, PropertyMode.Replace, buffer, buflen);
+                                                       sel_event.SelectionEvent.property = xevent.SelectionRequestEvent.property;
+                                                       Marshal.FreeHGlobal (buffer);
+                                               }
+
                                        } else if (Clipboard.IsSourceImage) {
                                                if (xevent.SelectionEvent.target == (IntPtr)Atom.XA_PIXMAP) {
                                                        // FIXME - convert image and store as property