bb7b0c462ce4bca2f70d21acc1e05fc4eab6bdd9
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataObject.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    (pbartok@novell.com)
24 //
25 //
26
27 // COMPLETE
28
29 using System;
30 using System.Collections;
31 using System.Runtime.InteropServices;
32
33 namespace System.Windows.Forms {
34         [ClassInterface(ClassInterfaceType.None)]
35         public class DataObject : IDataObject {
36                 #region DataObject.Entry Class
37                 private class Entry {
38                         #region Local Variables
39                         private string  type;
40                         private object  data;
41                         private bool    autoconvert;
42                         internal Entry  next;
43                         #endregion      // Local Variables
44
45                         #region Constructors
46                         internal Entry(string type, object data, bool autoconvert) {
47                                 Entry   e;
48
49                                 this.type = type;
50                                 this.data = data;
51                                 this.autoconvert = autoconvert;
52                         }
53                         #endregion      // Constructors
54
55                         #region Properties
56                         public object Data {
57                                 get {
58                                         return data;
59                                 }
60                         }
61                         #endregion      // Properties
62
63                         #region Methods
64                         public static int Count(Entry entries) {
65                                 int     result;
66
67                                 result = 0;
68
69                                 while (entries != null) {
70                                         result++;
71                                         entries = entries.next;
72                                 }
73
74                                 return result;
75                         }
76
77                         public static Entry Find(Entry entries, string type) {
78                                 while (entries != null) {
79                                         if (entries.type.Equals(type)) {
80                                                 return entries;
81                                         }
82                                         entries = entries.next;
83                                 }
84
85                                 return null;
86                         }
87
88                         public static Entry FindConvertible(Entry entries, string type) {
89                                 Entry e;
90
91                                 e = Find(entries, type);
92                                 if (e != null) {
93                                         return e;
94                                 }
95
96                                 e = entries;
97                                 while (e != null) {
98                                         if (type == DataFormats.Text) {
99                                                 if (e.type == DataFormats.UnicodeText) {
100                                                         return e;
101                                                 }
102                                         } else if (type == DataFormats.UnicodeText) {
103                                                 if (e.type == DataFormats.Text) {
104                                                         return e;
105                                                 }
106                                         } else if (type == DataFormats.StringFormat) {
107                                                 if (e.type == DataFormats.Text) {
108                                                         return e;
109                                                 } else if (e.type == DataFormats.UnicodeText) {
110                                                         return e;
111                                                 }
112                                         }
113                                         e = e.next;
114                                 }
115
116                                 return null;
117                         }
118
119                         public static string[] Entries(Entry entries, bool convertible) {
120                                 Entry           e;
121                                 ArrayList       list;
122                                 string[]        result;
123
124                                 // Initially store into something that we can grow easily
125                                 list = new ArrayList(Entry.Count(entries));
126                                 e = entries;
127
128                                 while (e != null) {
129                                         list.Add(e.type);
130                                         e = e.next;
131                                 }
132
133                                 if (convertible) {
134                                         // Add the convertibles
135                                         if ((Entry.Find(entries, DataFormats.Text) != null) && (Entry.Find(entries, DataFormats.UnicodeText) == null)) {
136                                                 list.Add(DataFormats.UnicodeText);
137                                         }
138
139                                         if ((Entry.Find(entries, DataFormats.Text) == null) && (Entry.Find(entries, DataFormats.UnicodeText) != null)) {
140                                                 list.Add(DataFormats.Text);
141                                         }
142
143                                         if (((Entry.Find(entries, DataFormats.Text) != null) || (Entry.Find(entries, DataFormats.UnicodeText) != null)) && (Entry.Find(entries, DataFormats.StringFormat) == null)) {
144                                                 list.Add(DataFormats.StringFormat);
145                                         }
146                                 }
147
148                                 // Copy the results into a string array
149                                 result = new string[list.Count];
150                                 for (int i = 0; i < list.Count; i++) {
151                                         result[i] = (string)list[i];
152                                 }
153
154                                 return result;
155                         }
156                         #endregion      // Methods
157                 }
158                 #endregion      // DataObject.Entry class
159
160                 #region Local Variables
161                 private Entry   entries;
162                 #endregion      // Local Variables
163
164                 #region Public Constructors
165                 public DataObject() {
166                         entries = null;
167                 }
168
169                 public DataObject(object data) {
170                         SetData(data);
171                 }
172
173                 public DataObject(string format, object data) {
174                         SetData(format, data);
175                 }
176                 #endregion      // Public Constructors
177
178                 #region Public Instance Properties
179                 public virtual object GetData(string format) {
180                         return GetData(format, true);
181                 }
182
183                 public virtual object GetData(string format, bool autoConvert) {
184                         if (autoConvert) {
185                                 return Entry.FindConvertible(entries, format).Data;
186                         } else {
187                                 return Entry.Find(entries, format).Data;
188                         }
189                 }
190
191                 public virtual object GetData(Type format) {
192                         return GetData(format.FullName, true);
193                 }
194
195                 public virtual bool GetDataPresent(string format) {
196                         return GetDataPresent(format, true);
197                 }
198
199                 public virtual bool GetDataPresent(string format, bool autoConvert) {
200                         if (autoConvert) {
201                                 return Entry.FindConvertible(entries, format) != null;
202                         } else {
203                                 return Entry.Find(entries, format) != null;
204                         }
205                 }
206
207                 public virtual bool GetDataPresent(Type format) {
208                         return GetDataPresent(format.FullName, true);
209                 }
210
211                 public virtual string[] GetFormats() {
212                         return GetFormats(true);
213                 }
214
215                 public virtual string[] GetFormats(bool autoConvert) {
216                         return Entry.Entries(entries, autoConvert);
217                 }
218
219                 public virtual void SetData(object data) {
220                         SetData(data.GetType(), data); 
221                 }
222
223                 public virtual void SetData(string format, bool autoConvert, object data) {
224                         Entry   entry;
225                         Entry   e;
226
227                         entry = new DataObject.Entry(format, data, autoConvert);
228
229                         lock (this) {
230                                 if (entries == null) {
231                                         entries = entry;
232                                 } else {
233                                         // Insert into the list of known/defined formats
234                                         e = entries;
235
236                                         while (e.next != null) {
237                                                 e = e.next;
238                                         }
239                                         e.next = entry;
240                                 }
241                         }
242                 }
243
244                 public virtual void SetData(string format, object data) {
245                         SetData(format, true, data);
246                 }
247
248                 public virtual void SetData(Type format, object data) {
249                         SetData(EnsureFormat(format), true, data);
250                 }
251                 #endregion      // Public Instance Properties
252
253                 #region Public Instance Methods
254                 #endregion      // Public Instance Methods
255
256                 #region Private Methods
257                 internal string EnsureFormat(string name) {
258                         DataFormats.Format f;
259
260                         f = DataFormats.Format.Find(name);
261                         if (f == null) {
262                                 // Register the format
263                                 f = DataFormats.Format.Add(name);
264                         }
265
266                         return f.Name;
267                 }
268
269                 internal string EnsureFormat(Type type) {
270                         return EnsureFormat(type.FullName);
271                 }
272
273                 #endregion      // Private Methods
274         }
275 }