3a011d6fc3ef25bbed606375dd55a0240c8a338a
[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                                 this.type = type;
48                                 this.data = data;
49                                 this.autoconvert = autoconvert;
50                         }
51                         #endregion      // Constructors
52
53                         #region Properties
54                         public object Data {
55                                 get {
56                                         return data;
57                                 }
58
59                                 set {
60                                         data = value;
61                                 }
62                         }
63                         #endregion      // Properties
64
65                         #region Methods
66                         public static int Count(Entry entries) {
67                                 int     result;
68
69                                 result = 0;
70
71                                 while (entries != null) {
72                                         result++;
73                                         entries = entries.next;
74                                 }
75
76                                 return result;
77                         }
78
79                         public static Entry Find(Entry entries, string type) {
80                                 while (entries != null) {
81                                         if (entries.type.Equals(type)) {
82                                                 return entries;
83                                         }
84                                         entries = entries.next;
85                                 }
86
87                                 return null;
88                         }
89
90                         public static Entry FindConvertible(Entry entries, string type) {
91                                 Entry e;
92
93                                 e = Find(entries, type);
94                                 if (e != null) {
95                                         return e;
96                                 }
97
98                                 e = entries;
99                                 while (e != null) {
100                                         if (type == DataFormats.Text) {
101                                                 if (e.type == DataFormats.UnicodeText) {
102                                                         return e;
103                                                 }
104                                         } else if (type == DataFormats.UnicodeText) {
105                                                 if (e.type == DataFormats.Text) {
106                                                         return e;
107                                                 }
108                                         } else if (type == DataFormats.StringFormat) {
109                                                 if (e.type == DataFormats.Text) {
110                                                         return e;
111                                                 } else if (e.type == DataFormats.UnicodeText) {
112                                                         return e;
113                                                 }
114                                         }
115                                         e = e.next;
116                                 }
117
118                                 return null;
119                         }
120
121                         public static string[] Entries(Entry entries, bool convertible) {
122                                 Entry           e;
123                                 ArrayList       list;
124                                 string[]        result;
125
126                                 // Initially store into something that we can grow easily
127                                 list = new ArrayList(Entry.Count(entries));
128                                 e = entries;
129
130                                 while (e != null) {
131                                         list.Add(e.type);
132                                         e = e.next;
133                                 }
134
135                                 if (convertible) {
136                                         // Add the convertibles
137                                         if ((Entry.Find(entries, DataFormats.Text) != null) && (Entry.Find(entries, DataFormats.UnicodeText) == null)) {
138                                                 list.Add(DataFormats.UnicodeText);
139                                         }
140
141                                         if ((Entry.Find(entries, DataFormats.Text) == null) && (Entry.Find(entries, DataFormats.UnicodeText) != null)) {
142                                                 list.Add(DataFormats.Text);
143                                         }
144
145                                         if (((Entry.Find(entries, DataFormats.Text) != null) || (Entry.Find(entries, DataFormats.UnicodeText) != null)) && (Entry.Find(entries, DataFormats.StringFormat) == null)) {
146                                                 list.Add(DataFormats.StringFormat);
147                                         }
148                                 }
149
150                                 // Copy the results into a string array
151                                 result = new string[list.Count];
152                                 for (int i = 0; i < list.Count; i++) {
153                                         result[i] = (string)list[i];
154                                 }
155
156                                 return result;
157                         }
158                         #endregion      // Methods
159                 }
160                 #endregion      // DataObject.Entry class
161
162                 #region Local Variables
163                 private Entry   entries;
164                 #endregion      // Local Variables
165
166                 #region Public Constructors
167                 public DataObject() {
168                         entries = null;
169                 }
170
171                 public DataObject(object data) {
172                         SetData(data);
173                 }
174
175                 public DataObject(string format, object data) {
176                         SetData(format, data);
177                 }
178                 #endregion      // Public Constructors
179
180                 #region Public Instance Properties
181                 public virtual object GetData(string format) {
182                         return GetData(format, true);
183                 }
184
185                 public virtual object GetData(string format, bool autoConvert) {
186                         Entry e;
187                         if (autoConvert) {
188                                 e = Entry.FindConvertible(entries, format);
189                         } else {
190                                 e = Entry.Find(entries, format);
191                         }
192                         if (e == null)
193                                 return null;
194                         return e.Data;
195                 }
196
197                 public virtual object GetData(Type format) {
198                         return GetData(format.FullName, true);
199                 }
200
201                 public virtual bool GetDataPresent(string format) {
202                         return GetDataPresent(format, true);
203                 }
204
205                 public virtual bool GetDataPresent(string format, bool autoConvert) {
206                         if (autoConvert) {
207                                 return Entry.FindConvertible(entries, format) != null;
208                         } else {
209                                 return Entry.Find(entries, format) != null;
210                         }
211                 }
212
213                 public virtual bool GetDataPresent(Type format) {
214                         return GetDataPresent(format.FullName, true);
215                 }
216
217                 public virtual string[] GetFormats() {
218                         return GetFormats(true);
219                 }
220
221                 public virtual string[] GetFormats(bool autoConvert) {
222                         return Entry.Entries(entries, autoConvert);
223                 }
224
225                 public virtual void SetData(object data) {
226                         SetData(data.GetType(), data); 
227                 }
228
229                 public virtual void SetData(string format, bool autoConvert, object data) {
230                         Entry   entry;
231                         Entry   e;
232
233                         entry = Entry.Find(entries, format);
234
235                         if (entry == null) {
236                                 entry = new DataObject.Entry(format, data, autoConvert);
237                         } else {
238                                 entry.Data = data;
239                                 return;
240                         }
241
242                         lock (this) {
243                                 if (entries == null) {
244                                         entries = entry;
245                                 } else {
246                                         // Insert into the list of known/defined formats
247                                         e = entries;
248
249                                         while (e.next != null) {
250                                                 e = e.next;
251                                         }
252                                         e.next = entry;
253                                 }
254                         }
255                 }
256
257                 public virtual void SetData(string format, object data) {
258                         SetData(format, true, data);
259                 }
260
261                 public virtual void SetData(Type format, object data) {
262                         SetData(EnsureFormat(format), true, data);
263                 }
264                 #endregion      // Public Instance Properties
265
266                 #region Public Instance Methods
267                 #endregion      // Public Instance Methods
268
269                 #region Private Methods
270                 internal string EnsureFormat(string name) {
271                         DataFormats.Format f;
272
273                         f = DataFormats.Format.Find(name);
274                         if (f == null) {
275                                 // Register the format
276                                 f = DataFormats.Format.Add(name);
277                         }
278
279                         return f.Name;
280                 }
281
282                 internal string EnsureFormat(Type type) {
283                         return EnsureFormat(type.FullName);
284                 }
285
286                 #endregion      // Private Methods
287         }
288 }