]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
added automatic growing of in-place wxTextCtrls for generic wxListCtrl and wxTreeCtrl
[wxWidgets.git] / src / common / variant.cpp
CommitLineData
341287bf
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: variant.cpp
3// Purpose: wxVariant class, container for any type
4// Author: Julian Smart
5// Modified by:
6// Created: 10/09/98
7// RCS-ID: $Id$
8// Copyright: (c)
3f4a0c5b 9// Licence: wxWindows licence
341287bf
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "variant.h"
68ee7c47
VZ
14#pragma implementation "time.h"
15#pragma implementation "date.h"
341287bf
JS
16#endif
17
18// For compilers that support precompilation, includes "wx/wx.h".
19#include "wx/wxprec.h"
20
21#ifdef __BORLANDC__
3f4a0c5b 22 #pragma hdrstop
341287bf
JS
23#endif
24
be087207
RR
25#if wxUSE_STD_IOSTREAM
26 #if wxUSE_IOSTREAMH
27 #include <fstream.h>
28 #else
29 #include <fstream>
30 #endif
fbc535ff 31#endif
341287bf 32
fae05df5 33#if wxUSE_STREAMS
75ed1d15 34#include "wx/stream.h"
fae05df5
GL
35#include "wx/txtstrm.h"
36#endif
37
341287bf
JS
38#include "wx/string.h"
39#include "wx/variant.h"
40
f6bcfd97 41#if wxUSE_TIMEDATE
cd0b1709
VZ
42IMPLEMENT_DYNAMIC_CLASS(wxDate, wxObject)
43IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
44
45wxTime::tFormat wxTime::ms_Format = wxTime::wx12h;
46wxTime::tPrecision wxTime::ms_Precision = wxTime::wxStdMinSec;
f6bcfd97 47#endif
cd0b1709 48
341287bf
JS
49IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
50
3ba055ac 51wxVariant WXDLLEXPORT wxNullVariant;
341287bf
JS
52
53/*
54 * wxVariantDataList
55 */
56
57class WXDLLEXPORT wxVariantDataList: public wxVariantData
58{
59DECLARE_DYNAMIC_CLASS(wxVariantDataList)
60public:
61 wxVariantDataList() {}
62 wxVariantDataList(const wxList& list);
63 ~wxVariantDataList();
64
65 wxList& GetValue() const { return (wxList&) m_value; }
66 void SetValue(const wxList& value) ;
67
68 virtual void Copy(wxVariantData& data);
69 virtual bool Eq(wxVariantData& data) const;
38830220 70#if wxUSE_STD_IOSTREAM
341287bf 71 virtual bool Write(ostream& str) const;
38830220 72#endif
341287bf 73 virtual bool Write(wxString& str) const;
38830220 74#if wxUSE_STD_IOSTREAM
341287bf 75 virtual bool Read(istream& str);
38830220 76#endif
341287bf 77 virtual bool Read(wxString& str);
223d09f6 78 virtual wxString GetType() const { return wxT("list"); };
341287bf
JS
79
80 void Clear();
81
82protected:
83 wxList m_value;
84};
85
86IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
87
88wxVariantDataList::wxVariantDataList(const wxList& list)
89{
90 SetValue(list);
91}
92
93wxVariantDataList::~wxVariantDataList()
94{
95 Clear();
96}
97
98void wxVariantDataList::SetValue(const wxList& value)
99{
100 Clear();
101 wxNode* node = value.First();
102 while (node)
103 {
104 wxVariant* var = (wxVariant*) node->Data();
105 m_value.Append(new wxVariant(*var));
106 node = node->Next();
107 }
108}
109
110void wxVariantDataList::Clear()
111{
112 wxNode* node = m_value.First();
113 while (node)
114 {
115 wxVariant* var = (wxVariant*) node->Data();
116 delete var;
117 node = node->Next();
118 }
119 m_value.Clear();
120}
121
122void wxVariantDataList::Copy(wxVariantData& data)
123{
223d09f6 124 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Copy: Can't copy to this type of data") );
341287bf
JS
125
126 wxVariantDataList& listData = (wxVariantDataList&) data;
127
128 listData.Clear();
129 wxNode* node = m_value.First();
130 while (node)
131 {
132 wxVariant* var = (wxVariant*) node->Data();
133 listData.m_value.Append(new wxVariant(*var));
134 node = node->Next();
135 }
136}
137
138bool wxVariantDataList::Eq(wxVariantData& data) const
139{
223d09f6 140 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
341287bf
JS
141
142 wxVariantDataList& listData = (wxVariantDataList&) data;
143 wxNode* node1 = m_value.First();
144 wxNode* node2 = listData.GetValue().First();
145 while (node1 && node2)
146 {
147 wxVariant* var1 = (wxVariant*) node1->Data();
148 wxVariant* var2 = (wxVariant*) node2->Data();
149 if ((*var1) != (*var2))
150 return FALSE;
151 node1 = node1->Next();
152 node2 = node2->Next();
153 }
154 if (node1 || node2) return FALSE;
155 return TRUE;
156}
157
38830220 158#if wxUSE_STD_IOSTREAM
341287bf
JS
159bool wxVariantDataList::Write(ostream& str) const
160{
161 wxString s;
162 Write(s);
783b6cfd 163 str << (const char*) s.mb_str();
341287bf
JS
164 return TRUE;
165}
38830220 166#endif
341287bf
JS
167
168bool wxVariantDataList::Write(wxString& str) const
169{
223d09f6 170 str = wxT("");
341287bf
JS
171 wxNode* node = m_value.First();
172 while (node)
173 {
174 wxVariant* var = (wxVariant*) node->Data();
175 if (node != m_value.First())
223d09f6 176 str += wxT(" ");
341287bf
JS
177 wxString str1;
178 str += var->MakeString();
179 node = node->Next();
180 }
181
182 return TRUE;
183}
184
38830220 185#if wxUSE_STD_IOSTREAM
341287bf
JS
186bool wxVariantDataList::Read(istream& WXUNUSED(str))
187{
223d09f6 188 wxFAIL_MSG(wxT("Unimplemented"));
341287bf
JS
189 // TODO
190 return FALSE;
191}
38830220 192#endif
341287bf
JS
193
194bool wxVariantDataList::Read(wxString& WXUNUSED(str))
195{
223d09f6 196 wxFAIL_MSG(wxT("Unimplemented"));
341287bf
JS
197 // TODO
198 return FALSE;
199}
200
201/*
202 * wxVariantDataStringList
203 */
204
205class WXDLLEXPORT wxVariantDataStringList: public wxVariantData
206{
207DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
208public:
209 wxVariantDataStringList() {}
210 wxVariantDataStringList(const wxStringList& list) { m_value = list; }
211
212 wxStringList& GetValue() const { return (wxStringList&) m_value; }
213 void SetValue(const wxStringList& value);
214
215 virtual void Copy(wxVariantData& data);
216 virtual bool Eq(wxVariantData& data) const;
38830220 217#if wxUSE_STD_IOSTREAM
341287bf 218 virtual bool Write(ostream& str) const;
38830220 219#endif
341287bf 220 virtual bool Write(wxString& str) const;
38830220 221#if wxUSE_STD_IOSTREAM
341287bf 222 virtual bool Read(istream& str);
38830220 223#endif
341287bf 224 virtual bool Read(wxString& str);
223d09f6 225 virtual wxString GetType() const { return wxT("stringlist"); };
341287bf
JS
226
227protected:
228 wxStringList m_value;
229};
230
231IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
232
233void wxVariantDataStringList::SetValue(const wxStringList& value)
234{
235 m_value = value;
236}
237
238void wxVariantDataStringList::Copy(wxVariantData& data)
239{
223d09f6 240 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Copy: Can't copy to this type of data") );
341287bf
JS
241
242 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
243
244 listData.m_value = m_value ;
245}
246
247bool wxVariantDataStringList::Eq(wxVariantData& data) const
248{
223d09f6 249 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Eq: argument mismatch") );
341287bf
JS
250
251 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
252 wxNode* node1 = m_value.First();
253 wxNode* node2 = listData.GetValue().First();
254 while (node1 && node2)
255 {
783b6cfd
OK
256 wxString str1 ((wxChar*) node1->Data());
257 wxString str2 ((wxChar*) node2->Data());
341287bf
JS
258 if (str1 != str2)
259 return FALSE;
260 node1 = node1->Next();
261 node2 = node2->Next();
262 }
263 if (node1 || node2) return FALSE;
264 return TRUE;
265}
266
38830220 267#if wxUSE_STD_IOSTREAM
341287bf
JS
268bool wxVariantDataStringList::Write(ostream& str) const
269{
270 wxString s;
271 Write(s);
783b6cfd 272 str << (const char*) s.mb_str();
341287bf
JS
273 return TRUE;
274}
38830220 275#endif
341287bf
JS
276
277bool wxVariantDataStringList::Write(wxString& str) const
278{
223d09f6 279 str = wxT("");
341287bf
JS
280 wxNode* node = m_value.First();
281 while (node)
282 {
783b6cfd 283 wxChar* s = (wxChar*) node->Data();
341287bf 284 if (node != m_value.First())
223d09f6 285 str += wxT(" ");
341287bf
JS
286 str += s;
287 node = node->Next();
288 }
289
290 return TRUE;
291}
292
38830220 293#if wxUSE_STD_IOSTREAM
341287bf
JS
294bool wxVariantDataStringList::Read(istream& WXUNUSED(str))
295{
223d09f6 296 wxFAIL_MSG(wxT("Unimplemented"));
341287bf
JS
297 // TODO
298 return FALSE;
299}
38830220 300#endif
341287bf
JS
301
302bool wxVariantDataStringList::Read(wxString& WXUNUSED(str))
303{
223d09f6 304 wxFAIL_MSG(wxT("Unimplemented"));
341287bf
JS
305 // TODO
306 return FALSE;
307}
308
309/*
310 * wxVariantDataLong
311 */
312
313class WXDLLEXPORT wxVariantDataLong: public wxVariantData
314{
315DECLARE_DYNAMIC_CLASS(wxVariantDataLong)
316public:
317 wxVariantDataLong() { m_value = 0; }
318 wxVariantDataLong(long value) { m_value = value; }
319
320 inline long GetValue() const { return m_value; }
321 inline void SetValue(long value) { m_value = value; }
322
323 virtual void Copy(wxVariantData& data);
324 virtual bool Eq(wxVariantData& data) const;
1ccbb61a
VZ
325
326 virtual bool Read(wxString& str);
341287bf 327 virtual bool Write(wxString& str) const;
38830220 328#if wxUSE_STD_IOSTREAM
341287bf 329 virtual bool Read(istream& str);
1ccbb61a 330 virtual bool Write(ostream& str) const;
38830220 331#endif
e02afc7a 332#if wxUSE_STREAMS
75ed1d15 333 virtual bool Read(wxInputStream& str);
1ccbb61a 334 virtual bool Write(wxOutputStream &str) const;
e02afc7a 335#endif // wxUSE_STREAMS
1ccbb61a 336
223d09f6 337 virtual wxString GetType() const { return wxT("long"); };
341287bf
JS
338
339protected:
340 long m_value;
341};
342
343IMPLEMENT_DYNAMIC_CLASS(wxVariantDataLong, wxVariantData)
344
345void wxVariantDataLong::Copy(wxVariantData& data)
346{
223d09f6 347 wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Copy: Can't copy to this type of data") );
341287bf
JS
348
349 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
350
351 otherData.m_value = m_value;
352}
353
354bool wxVariantDataLong::Eq(wxVariantData& data) const
355{
223d09f6 356 wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
341287bf
JS
357
358 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
359
360 return (otherData.m_value == m_value);
361}
362
38830220 363#if wxUSE_STD_IOSTREAM
341287bf
JS
364bool wxVariantDataLong::Write(ostream& str) const
365{
366 wxString s;
367 Write(s);
783b6cfd 368 str << (const char*) s.mb_str();
341287bf
JS
369 return TRUE;
370}
38830220 371#endif
341287bf
JS
372
373bool wxVariantDataLong::Write(wxString& str) const
374{
223d09f6 375 str.Printf(wxT("%ld"), m_value);
341287bf
JS
376 return TRUE;
377}
378
38830220 379#if wxUSE_STD_IOSTREAM
341287bf
JS
380bool wxVariantDataLong::Read(istream& str)
381{
382 str >> m_value;
383 return TRUE;
384}
38830220 385#endif
341287bf 386
e02afc7a 387#if wxUSE_STREAMS
1ccbb61a
VZ
388bool wxVariantDataLong::Write(wxOutputStream& str) const
389{
fae05df5
GL
390 wxTextOutputStream s(str);
391
479cd5de 392 s.Write32((size_t)m_value);
1ccbb61a
VZ
393 return TRUE;
394}
395
75ed1d15
GL
396bool wxVariantDataLong::Read(wxInputStream& str)
397{
fae05df5
GL
398 wxTextInputStream s(str);
399 m_value = s.Read32();
75ed1d15
GL
400 return TRUE;
401}
e02afc7a 402#endif // wxUSE_STREAMS
75ed1d15 403
341287bf
JS
404bool wxVariantDataLong::Read(wxString& str)
405{
783b6cfd 406 m_value = wxAtol((const wxChar*) str);
341287bf
JS
407 return TRUE;
408}
409
410/*
411 * wxVariantDataReal
412 */
413
414class WXDLLEXPORT wxVariantDataReal: public wxVariantData
415{
416DECLARE_DYNAMIC_CLASS(wxVariantDataReal)
417public:
418 wxVariantDataReal() { m_value = 0.0; }
419 wxVariantDataReal(double value) { m_value = value; }
420
421 inline double GetValue() const { return m_value; }
422 inline void SetValue(double value) { m_value = value; }
423
424 virtual void Copy(wxVariantData& data);
425 virtual bool Eq(wxVariantData& data) const;
1ccbb61a 426 virtual bool Read(wxString& str);
38830220 427#if wxUSE_STD_IOSTREAM
341287bf 428 virtual bool Write(ostream& str) const;
38830220 429#endif
341287bf 430 virtual bool Write(wxString& str) const;
38830220 431#if wxUSE_STD_IOSTREAM
341287bf 432 virtual bool Read(istream& str);
38830220 433#endif
e02afc7a 434#if wxUSE_STREAMS
75ed1d15 435 virtual bool Read(wxInputStream& str);
1ccbb61a 436 virtual bool Write(wxOutputStream &str) const;
e02afc7a 437#endif // wxUSE_STREAMS
223d09f6 438 virtual wxString GetType() const { return wxT("double"); };
341287bf
JS
439
440protected:
441 double m_value;
442};
443
444IMPLEMENT_DYNAMIC_CLASS(wxVariantDataReal, wxVariantData)
445
446void wxVariantDataReal::Copy(wxVariantData& data)
447{
223d09f6 448 wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDataReal::Copy: Can't copy to this type of data") );
341287bf
JS
449
450 wxVariantDataReal& otherData = (wxVariantDataReal&) data;
451
452 otherData.m_value = m_value;
453}
454
455bool wxVariantDataReal::Eq(wxVariantData& data) const
456{
223d09f6 457 wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDataReal::Eq: argument mismatch") );
341287bf
JS
458
459 wxVariantDataReal& otherData = (wxVariantDataReal&) data;
460
461 return (otherData.m_value == m_value);
462}
463
38830220 464#if wxUSE_STD_IOSTREAM
341287bf
JS
465bool wxVariantDataReal::Write(ostream& str) const
466{
467 wxString s;
468 Write(s);
783b6cfd 469 str << (const char*) s.mb_str();
341287bf
JS
470 return TRUE;
471}
38830220 472#endif
341287bf
JS
473
474bool wxVariantDataReal::Write(wxString& str) const
475{
223d09f6 476 str.Printf(wxT("%.4f"), m_value);
341287bf
JS
477 return TRUE;
478}
479
38830220 480#if wxUSE_STD_IOSTREAM
341287bf
JS
481bool wxVariantDataReal::Read(istream& str)
482{
483 str >> m_value;
484 return TRUE;
485}
38830220 486#endif
341287bf 487
e02afc7a 488#if wxUSE_STREAMS
1ccbb61a
VZ
489bool wxVariantDataReal::Write(wxOutputStream& str) const
490{
fae05df5
GL
491 wxTextOutputStream s(str);
492 s.WriteDouble((double)m_value);
1ccbb61a
VZ
493 return TRUE;
494}
495
75ed1d15
GL
496bool wxVariantDataReal::Read(wxInputStream& str)
497{
fae05df5
GL
498 wxTextInputStream s(str);
499 m_value = (float)s.ReadDouble();
75ed1d15
GL
500 return TRUE;
501}
e02afc7a 502#endif // wxUSE_STREAMS
75ed1d15 503
341287bf
JS
504bool wxVariantDataReal::Read(wxString& str)
505{
783b6cfd 506 m_value = wxAtof((const wxChar*) str);
341287bf
JS
507 return TRUE;
508}
509
57493f9f 510#ifdef HAVE_BOOL
341287bf
JS
511/*
512 * wxVariantDataBool
513 */
514
515class WXDLLEXPORT wxVariantDataBool: public wxVariantData
516{
517DECLARE_DYNAMIC_CLASS(wxVariantDataBool)
518public:
519 wxVariantDataBool() { m_value = 0; }
520 wxVariantDataBool(bool value) { m_value = value; }
521
522 inline bool GetValue() const { return m_value; }
523 inline void SetValue(bool value) { m_value = value; }
524
525 virtual void Copy(wxVariantData& data);
526 virtual bool Eq(wxVariantData& data) const;
38830220 527#if wxUSE_STD_IOSTREAM
341287bf 528 virtual bool Write(ostream& str) const;
38830220 529#endif
341287bf 530 virtual bool Write(wxString& str) const;
1ccbb61a 531 virtual bool Read(wxString& str);
38830220 532#if wxUSE_STD_IOSTREAM
341287bf 533 virtual bool Read(istream& str);
38830220 534#endif
e02afc7a 535#if wxUSE_STREAMS
75ed1d15 536 virtual bool Read(wxInputStream& str);
1ccbb61a 537 virtual bool Write(wxOutputStream& str) const;
e02afc7a 538#endif // wxUSE_STREAMS
223d09f6 539 virtual wxString GetType() const { return wxT("bool"); };
341287bf
JS
540
541protected:
542 bool m_value;
543};
544
545IMPLEMENT_DYNAMIC_CLASS(wxVariantDataBool, wxVariantData)
546
547void wxVariantDataBool::Copy(wxVariantData& data)
548{
223d09f6 549 wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Copy: Can't copy to this type of data") );
341287bf
JS
550
551 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
552
553 otherData.m_value = m_value;
554}
555
556bool wxVariantDataBool::Eq(wxVariantData& data) const
557{
223d09f6 558 wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
341287bf
JS
559
560 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
561
562 return (otherData.m_value == m_value);
563}
564
38830220 565#if wxUSE_STD_IOSTREAM
341287bf
JS
566bool wxVariantDataBool::Write(ostream& str) const
567{
568 wxString s;
569 Write(s);
783b6cfd 570 str << (const char*) s.mb_str();
341287bf
JS
571 return TRUE;
572}
38830220 573#endif
341287bf
JS
574
575bool wxVariantDataBool::Write(wxString& str) const
576{
223d09f6 577 str.Printf(wxT("%d"), (int) m_value);
341287bf
JS
578 return TRUE;
579}
580
38830220 581#if wxUSE_STD_IOSTREAM
341287bf
JS
582bool wxVariantDataBool::Read(istream& WXUNUSED(str))
583{
223d09f6 584 wxFAIL_MSG(wxT("Unimplemented"));
341287bf
JS
585// str >> (long) m_value;
586 return FALSE;
587}
38830220 588#endif
341287bf 589
e02afc7a 590#if wxUSE_STREAMS
1ccbb61a
VZ
591bool wxVariantDataBool::Write(wxOutputStream& str) const
592{
fae05df5
GL
593 wxTextOutputStream s(str);
594
595 s.Write8(m_value);
1ccbb61a
VZ
596 return TRUE;
597}
598
75ed1d15
GL
599bool wxVariantDataBool::Read(wxInputStream& str)
600{
fae05df5
GL
601 wxTextInputStream s(str);
602
a1b82138 603 m_value = s.Read8() != 0;
75ed1d15
GL
604 return TRUE;
605}
e02afc7a 606#endif // wxUSE_STREAMS
75ed1d15 607
341287bf
JS
608bool wxVariantDataBool::Read(wxString& str)
609{
783b6cfd 610 m_value = (wxAtol((const wxChar*) str) != 0);
341287bf
JS
611 return TRUE;
612}
57493f9f 613#endif // HAVE_BOOL
341287bf
JS
614
615/*
616 * wxVariantDataChar
617 */
618
619class WXDLLEXPORT wxVariantDataChar: public wxVariantData
620{
621DECLARE_DYNAMIC_CLASS(wxVariantDataChar)
622public:
623 wxVariantDataChar() { m_value = 0; }
624 wxVariantDataChar(char value) { m_value = value; }
625
626 inline char GetValue() const { return m_value; }
627 inline void SetValue(char value) { m_value = value; }
628
629 virtual void Copy(wxVariantData& data);
630 virtual bool Eq(wxVariantData& data) const;
38830220 631#if wxUSE_STD_IOSTREAM
1ccbb61a 632 virtual bool Read(istream& str);
341287bf 633 virtual bool Write(ostream& str) const;
38830220 634#endif
1ccbb61a 635 virtual bool Read(wxString& str);
341287bf 636 virtual bool Write(wxString& str) const;
e02afc7a 637#if wxUSE_STREAMS
75ed1d15 638 virtual bool Read(wxInputStream& str);
1ccbb61a 639 virtual bool Write(wxOutputStream& str) const;
e02afc7a 640#endif // wxUSE_STREAMS
223d09f6 641 virtual wxString GetType() const { return wxT("char"); };
341287bf
JS
642
643protected:
644 char m_value;
645};
646
647IMPLEMENT_DYNAMIC_CLASS(wxVariantDataChar, wxVariantData)
648
649void wxVariantDataChar::Copy(wxVariantData& data)
650{
223d09f6 651 wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Copy: Can't copy to this type of data") );
341287bf
JS
652
653 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
654
655 otherData.m_value = m_value;
656}
657
658bool wxVariantDataChar::Eq(wxVariantData& data) const
659{
223d09f6 660 wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
341287bf
JS
661
662 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
663
664 return (otherData.m_value == m_value);
665}
666
38830220 667#if wxUSE_STD_IOSTREAM
341287bf
JS
668bool wxVariantDataChar::Write(ostream& str) const
669{
670 wxString s;
671 Write(s);
783b6cfd 672 str << (const char*) s.mb_str();
341287bf
JS
673 return TRUE;
674}
38830220 675#endif
341287bf
JS
676
677bool wxVariantDataChar::Write(wxString& str) const
678{
223d09f6 679 str.Printf(wxT("%c"), m_value);
341287bf
JS
680 return TRUE;
681}
682
38830220 683#if wxUSE_STD_IOSTREAM
341287bf
JS
684bool wxVariantDataChar::Read(istream& WXUNUSED(str))
685{
223d09f6 686 wxFAIL_MSG(wxT("Unimplemented"));
341287bf
JS
687// str >> m_value;
688 return FALSE;
689}
38830220 690#endif
341287bf 691
e02afc7a 692#if wxUSE_STREAMS
1ccbb61a
VZ
693bool wxVariantDataChar::Write(wxOutputStream& str) const
694{
fae05df5
GL
695 wxTextOutputStream s(str);
696
697 s.Write8(m_value);
1ccbb61a
VZ
698 return TRUE;
699}
700
75ed1d15
GL
701bool wxVariantDataChar::Read(wxInputStream& str)
702{
fae05df5
GL
703 wxTextInputStream s(str);
704
705 m_value = s.Read8();
75ed1d15
GL
706 return TRUE;
707}
e02afc7a 708#endif // wxUSE_STREAMS
75ed1d15 709
341287bf
JS
710bool wxVariantDataChar::Read(wxString& str)
711{
712 m_value = str[(size_t)0];
713 return TRUE;
714}
715
716/*
717 * wxVariantDataString
718 */
719
62448488
JS
720#if defined(__BORLANDC__) && defined(__WIN16__)
721// Change name because of truncation
722#define wxVariantDataString wxVariantStringData
723#endif
724
341287bf
JS
725class WXDLLEXPORT wxVariantDataString: public wxVariantData
726{
62448488
JS
727#if defined(__BORLANDC__) && defined(__WIN16__)
728DECLARE_DYNAMIC_CLASS(wxVariantStringData)
729#else
341287bf 730DECLARE_DYNAMIC_CLASS(wxVariantDataString)
62448488 731#endif
341287bf
JS
732public:
733 wxVariantDataString() { }
734 wxVariantDataString(const wxString& value) { m_value = value; }
735
736 inline wxString GetValue() const { return m_value; }
737 inline void SetValue(const wxString& value) { m_value = value; }
738
739 virtual void Copy(wxVariantData& data);
740 virtual bool Eq(wxVariantData& data) const;
38830220 741#if wxUSE_STD_IOSTREAM
341287bf 742 virtual bool Write(ostream& str) const;
38830220 743#endif
1ccbb61a 744 virtual bool Read(wxString& str);
341287bf 745 virtual bool Write(wxString& str) const;
38830220 746#if wxUSE_STD_IOSTREAM
341287bf 747 virtual bool Read(istream& str);
38830220 748#endif
e02afc7a 749#if wxUSE_STREAMS
75ed1d15 750 virtual bool Read(wxInputStream& str);
1ccbb61a 751 virtual bool Write(wxOutputStream& str) const;
e02afc7a 752#endif // wxUSE_STREAMS
223d09f6 753 virtual wxString GetType() const { return wxT("string"); };
341287bf
JS
754
755protected:
756 wxString m_value;
757};
758
759void wxVariantDataString::Copy(wxVariantData& data)
760{
223d09f6 761 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Copy: Can't copy to this type of data") );
341287bf
JS
762
763 wxVariantDataString& otherData = (wxVariantDataString&) data;
764
765 otherData.m_value = m_value;
766}
767
768bool wxVariantDataString::Eq(wxVariantData& data) const
769{
223d09f6 770 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
341287bf
JS
771
772 wxVariantDataString& otherData = (wxVariantDataString&) data;
773
774 return (otherData.m_value == m_value);
775}
776
38830220 777#if wxUSE_STD_IOSTREAM
341287bf
JS
778bool wxVariantDataString::Write(ostream& str) const
779{
783b6cfd 780 str << (const char*) m_value.mb_str();
341287bf
JS
781 return TRUE;
782}
38830220 783#endif
341287bf
JS
784
785bool wxVariantDataString::Write(wxString& str) const
786{
787 str = m_value;
788 return TRUE;
789}
790
38830220 791#if wxUSE_STD_IOSTREAM
341287bf
JS
792bool wxVariantDataString::Read(istream& str)
793{
794 str >> m_value;
795 return TRUE;
796}
38830220 797#endif
341287bf 798
e02afc7a 799#if wxUSE_STREAMS
1ccbb61a
VZ
800bool wxVariantDataString::Write(wxOutputStream& str) const
801{
783b6cfd 802 // why doesn't wxOutputStream::operator<< take "const wxString&"
fae05df5
GL
803 wxTextOutputStream s(str);
804 s.WriteString(m_value);
1ccbb61a
VZ
805 return TRUE;
806}
807
75ed1d15
GL
808bool wxVariantDataString::Read(wxInputStream& str)
809{
fae05df5
GL
810 wxTextInputStream s(str);
811
812 m_value = s.ReadString();
75ed1d15
GL
813 return TRUE;
814}
e02afc7a 815#endif // wxUSE_STREAMS
75ed1d15 816
341287bf
JS
817bool wxVariantDataString::Read(wxString& str)
818{
819 m_value = str;
820 return TRUE;
821}
822
62448488
JS
823#if defined(__BORLANDC__) && defined(__WIN16__)
824IMPLEMENT_DYNAMIC_CLASS(wxVariantStringData, wxVariantData)
825#else
341287bf 826IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
62448488 827#endif
341287bf 828
a0a302dc
JS
829/*
830 * wxVariantDataTime
831 */
832
457e6c54
JS
833// For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
834#if wxUSE_TIMEDATE && !defined(__WATCOMC__)
a0a302dc
JS
835
836class wxVariantDataTime: public wxVariantData
837{
838 DECLARE_DYNAMIC_CLASS(wxVariantDataTime)
839public:
840 wxVariantDataTime() { }
841 wxVariantDataTime(const wxTime& value) { m_value = value; }
842
843 inline wxTime GetValue() const { return m_value; }
844 inline void SetValue(const wxTime& value) { m_value = value; }
845
846 virtual void Copy(wxVariantData& data);
847 virtual bool Eq(wxVariantData& data) const;
38830220 848#if wxUSE_STD_IOSTREAM
a0a302dc 849 virtual bool Write(ostream& str) const;
38830220 850#endif
a0a302dc 851 virtual bool Write(wxString& str) const;
38830220 852#if wxUSE_STD_IOSTREAM
a0a302dc 853 virtual bool Read(istream& str);
38830220 854#endif
a0a302dc 855 virtual bool Read(wxString& str);
223d09f6 856 virtual wxString GetType() const { return wxT("time"); };
a0a302dc
JS
857 virtual wxVariantData* Clone() { return new wxVariantDataTime; }
858
859protected:
860 wxTime m_value;
861};
862
863IMPLEMENT_DYNAMIC_CLASS(wxVariantDataTime, wxVariantData)
864
865void wxVariantDataTime::Copy(wxVariantData& data)
866{
223d09f6 867 wxASSERT_MSG( (data.GetType() == wxT("time")), wxT("wxVariantDataTime::Copy: Can't copy to this type of data") );
a0a302dc
JS
868
869 wxVariantDataTime& otherData = (wxVariantDataTime&) data;
870
871 otherData.m_value = m_value;
872}
873
874bool wxVariantDataTime::Eq(wxVariantData& data) const
875{
223d09f6 876 wxASSERT_MSG( (data.GetType() == wxT("time")), wxT("wxVariantDataTime::Eq: argument mismatch") );
a0a302dc
JS
877
878 wxVariantDataTime& otherData = (wxVariantDataTime&) data;
879
880 return (otherData.m_value == m_value);
881}
882
38830220 883#if wxUSE_STD_IOSTREAM
a0a302dc
JS
884bool wxVariantDataTime::Write(ostream& str) const
885{
886 wxString s;
887 Write(s);
783b6cfd 888 str << (const char*) s.mb_str();
a0a302dc
JS
889 return TRUE;
890}
38830220 891#endif
a0a302dc
JS
892
893bool wxVariantDataTime::Write(wxString& str) const
894{
783b6cfd 895 wxChar*s = m_value.FormatTime();
a0a302dc
JS
896 str = s;
897 return TRUE;
898}
899
38830220 900#if wxUSE_STD_IOSTREAM
8b53e5a2 901bool wxVariantDataTime::Read(istream& WXUNUSED(str))
a0a302dc
JS
902{
903 // Not implemented
904 return FALSE;
905}
38830220 906#endif
a0a302dc 907
8b53e5a2 908bool wxVariantDataTime::Read(wxString& WXUNUSED(str))
a0a302dc
JS
909{
910 // Not implemented
911 return FALSE;
912}
913
914/*
915 * wxVariantDataDate
916 */
917
918class wxVariantDataDate: public wxVariantData
919{
920 DECLARE_DYNAMIC_CLASS(wxVariantDataDate)
921public:
922 wxVariantDataDate() { }
923 wxVariantDataDate(const wxDate& value) { m_value = value; }
924
925 inline wxDate GetValue() const { return m_value; }
926 inline void SetValue(const wxDate& value) { m_value = value; }
927
928 virtual void Copy(wxVariantData& data);
929 virtual bool Eq(wxVariantData& data) const;
38830220 930#if wxUSE_STD_IOSTREAM
a0a302dc 931 virtual bool Write(ostream& str) const;
38830220 932#endif
a0a302dc 933 virtual bool Write(wxString& str) const;
38830220 934#if wxUSE_STD_IOSTREAM
a0a302dc 935 virtual bool Read(istream& str);
38830220 936#endif
a0a302dc 937 virtual bool Read(wxString& str);
223d09f6 938 virtual wxString GetType() const { return wxT("date"); };
a0a302dc
JS
939 virtual wxVariantData* Clone() { return new wxVariantDataDate; }
940
941protected:
942 wxDate m_value;
943};
944
945IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDate, wxVariantData)
946
947void wxVariantDataDate::Copy(wxVariantData& data)
948{
223d09f6 949 wxASSERT_MSG( (data.GetType() == wxT("date")), wxT("wxVariantDataDate::Copy: Can't copy to this type of data") );
a0a302dc
JS
950
951 wxVariantDataDate& otherData = (wxVariantDataDate&) data;
952
953 otherData.m_value = m_value;
954}
955
956bool wxVariantDataDate::Eq(wxVariantData& data) const
957{
223d09f6 958 wxASSERT_MSG( (data.GetType() == wxT("date")), wxT("wxVariantDataDate::Eq: argument mismatch") );
a0a302dc
JS
959
960 wxVariantDataDate& otherData = (wxVariantDataDate&) data;
961
962 return (otherData.m_value == m_value);
963}
964
38830220 965#if wxUSE_STD_IOSTREAM
a0a302dc
JS
966bool wxVariantDataDate::Write(ostream& str) const
967{
968 wxString s;
969 Write(s);
783b6cfd 970 str << (const char*) s.mb_str();
a0a302dc
JS
971 return TRUE;
972}
38830220 973#endif
a0a302dc
JS
974
975bool wxVariantDataDate::Write(wxString& str) const
976{
977 str = m_value.FormatDate();
978 return TRUE;
979}
980
38830220 981#if wxUSE_STD_IOSTREAM
8b53e5a2 982bool wxVariantDataDate::Read(istream& WXUNUSED(str))
a0a302dc
JS
983{
984 // Not implemented
985 return FALSE;
986}
38830220 987#endif
a0a302dc 988
8b53e5a2 989bool wxVariantDataDate::Read(wxString& WXUNUSED(str))
a0a302dc
JS
990{
991 // Not implemented
992 return FALSE;
993}
994#endif
995 // wxUSE_TIMEDATE
996
997/*
998 * wxVariantDataVoidPtr
999 */
1000
1001class wxVariantDataVoidPtr: public wxVariantData
1002{
1003DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
1004public:
1005 wxVariantDataVoidPtr() { }
1006 wxVariantDataVoidPtr(void* value) { m_value = value; }
1007
1008 inline void* GetValue() const { return m_value; }
1009 inline void SetValue(void* value) { m_value = value; }
1010
1011 virtual void Copy(wxVariantData& data);
1012 virtual bool Eq(wxVariantData& data) const;
38830220 1013#if wxUSE_STD_IOSTREAM
a0a302dc 1014 virtual bool Write(ostream& str) const;
38830220 1015#endif
a0a302dc 1016 virtual bool Write(wxString& str) const;
38830220 1017#if wxUSE_STD_IOSTREAM
a0a302dc 1018 virtual bool Read(istream& str);
38830220 1019#endif
a0a302dc 1020 virtual bool Read(wxString& str);
223d09f6 1021 virtual wxString GetType() const { return wxT("void*"); };
a0a302dc
JS
1022 virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
1023
1024protected:
1025 void* m_value;
1026};
1027
1028IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
1029
1030void wxVariantDataVoidPtr::Copy(wxVariantData& data)
1031{
223d09f6 1032 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Copy: Can't copy to this type of data") );
a0a302dc
JS
1033
1034 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1035
1036 otherData.m_value = m_value;
1037}
1038
1039bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
1040{
223d09f6 1041 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
a0a302dc
JS
1042
1043 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1044
1045 return (otherData.m_value == m_value);
1046}
1047
38830220 1048#if wxUSE_STD_IOSTREAM
a0a302dc
JS
1049bool wxVariantDataVoidPtr::Write(ostream& str) const
1050{
1051 wxString s;
1052 Write(s);
783b6cfd 1053 str << (const char*) s.mb_str();
a0a302dc
JS
1054 return TRUE;
1055}
38830220 1056#endif
a0a302dc
JS
1057
1058bool wxVariantDataVoidPtr::Write(wxString& str) const
1059{
223d09f6 1060 str.Printf(wxT("%ld"), (long) m_value);
a0a302dc
JS
1061 return TRUE;
1062}
1063
38830220 1064#if wxUSE_STD_IOSTREAM
8b53e5a2 1065bool wxVariantDataVoidPtr::Read(istream& WXUNUSED(str))
a0a302dc
JS
1066{
1067 // Not implemented
1068 return FALSE;
1069}
38830220 1070#endif
a0a302dc 1071
8b53e5a2 1072bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
a0a302dc
JS
1073{
1074 // Not implemented
1075 return FALSE;
1076}
1077
1078
341287bf
JS
1079/*
1080 * wxVariant
1081 */
1082
1083IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
1084
1085// Construction & destruction
1086wxVariant::wxVariant()
1087{
1088 m_data = (wxVariantData*) NULL;
1089}
1090
a0a302dc 1091wxVariant::wxVariant(double val, const wxString& name)
341287bf
JS
1092{
1093 m_data = new wxVariantDataReal(val);
a0a302dc 1094 m_name = name;
341287bf
JS
1095}
1096
a0a302dc 1097wxVariant::wxVariant(long val, const wxString& name)
341287bf
JS
1098{
1099 m_data = new wxVariantDataLong(val);
a0a302dc 1100 m_name = name;
341287bf
JS
1101}
1102
57493f9f 1103#ifdef HAVE_BOOL
a0a302dc 1104wxVariant::wxVariant(bool val, const wxString& name)
341287bf
JS
1105{
1106 m_data = new wxVariantDataBool(val);
a0a302dc 1107 m_name = name;
341287bf 1108}
57493f9f 1109#endif
341287bf 1110
a0a302dc 1111wxVariant::wxVariant(char val, const wxString& name)
341287bf
JS
1112{
1113 m_data = new wxVariantDataChar(val);
a0a302dc 1114 m_name = name;
341287bf
JS
1115}
1116
a0a302dc 1117wxVariant::wxVariant(const wxString& val, const wxString& name)
341287bf
JS
1118{
1119 m_data = new wxVariantDataString(val);
a0a302dc 1120 m_name = name;
341287bf
JS
1121}
1122
783b6cfd 1123wxVariant::wxVariant(const wxChar* val, const wxString& name)
341287bf
JS
1124{
1125 m_data = new wxVariantDataString(wxString(val));
a0a302dc 1126 m_name = name;
341287bf
JS
1127}
1128
a0a302dc 1129wxVariant::wxVariant(const wxStringList& val, const wxString& name)
341287bf
JS
1130{
1131 m_data = new wxVariantDataStringList(val);
a0a302dc 1132 m_name = name;
341287bf 1133}
341287bf 1134
a0a302dc 1135wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
341287bf
JS
1136{
1137 m_data = new wxVariantDataList(val);
a0a302dc
JS
1138 m_name = name;
1139}
1140
457e6c54
JS
1141// For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1142#if wxUSE_TIMEDATE && !defined(__WATCOMC__)
a0a302dc
JS
1143wxVariant::wxVariant(const wxTime& val, const wxString& name) // Time
1144{
1145 m_data = new wxVariantDataTime(val);
1146 m_name = name;
1147}
1148
1149wxVariant::wxVariant(const wxDate& val, const wxString& name) // Date
1150{
1151 m_data = new wxVariantDataDate(val);
1152 m_name = name;
1153}
1154#endif
1155
1156wxVariant::wxVariant(void* val, const wxString& name) // Void ptr
1157{
1158 m_data = new wxVariantDataVoidPtr(val);
1159 m_name = name;
341287bf
JS
1160}
1161
1162wxVariant::wxVariant(const wxVariant& variant)
1163{
1164 if (!variant.IsNull())
1165 {
1166 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1167 variant.m_data->Copy(*m_data);
1168 }
4fabb575
JS
1169 else
1170 m_data = (wxVariantData*) NULL;
a0a302dc 1171 m_name = variant.m_name;
341287bf
JS
1172}
1173
a0a302dc 1174wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
341287bf
JS
1175{
1176 m_data = data;
a0a302dc 1177 m_name = name;
341287bf
JS
1178}
1179
1180wxVariant::~wxVariant()
1181{
1182 delete m_data;
1183}
1184
1185
1186// Make NULL (i.e. delete the data)
1187void wxVariant::MakeNull()
1188{
1189 delete m_data;
1190 m_data = NULL;
1191}
1192
1193// Generic operators
1194// Assignment
1195void wxVariant::operator= (const wxVariant& variant)
1196{
1197 if (variant.IsNull())
1198 {
1199 MakeNull();
1200 return;
1201 }
1202
1203 if (IsNull() || (GetType() != variant.GetType()))
1204 {
1205 if (m_data)
1206 delete m_data;
1207 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1208 }
4fabb575
JS
1209// GetData()->Copy(* variant.GetData());
1210 variant.GetData()->Copy(* GetData());
341287bf
JS
1211}
1212
1213// Assignment using data, e.g.
1214// myVariant = new wxStringVariantData("hello")
1215void wxVariant::operator= (wxVariantData* variantData)
1216{
1217 MakeNull();
1218 m_data = variantData;
1219}
1220
1221bool wxVariant::operator== (const wxVariant& variant) const
1222{
1223 if (IsNull() || variant.IsNull())
1224 return (IsNull() == variant.IsNull());
1225
1226 return (GetData()->Eq(* variant.GetData()));
1227}
1228
1229bool wxVariant::operator!= (const wxVariant& variant) const
1230{
1231 return (!(*this == variant));
1232}
1233
1234
1235// Specific operators
1236bool wxVariant::operator== (double value) const
1237{
1238 double thisValue;
1239 if (!Convert(&thisValue))
1240 return FALSE;
1241 else
1242 return (value == thisValue);
1243}
1244
1245bool wxVariant::operator!= (double value) const
1246{
1247 return (!((*this) == value));
1248}
1249
1250void wxVariant::operator= (double value)
1251{
223d09f6 1252 if (GetType() == wxT("double"))
341287bf
JS
1253 {
1254 ((wxVariantDataReal*)GetData())->SetValue(value);
1255 }
1256 else
1257 {
1258 if (m_data)
1259 delete m_data;
1260 m_data = new wxVariantDataReal(value);
1261 }
1262}
1263
1264bool wxVariant::operator== (long value) const
1265{
1266 long thisValue;
1267 if (!Convert(&thisValue))
1268 return FALSE;
1269 else
1270 return (value == thisValue);
1271}
1272
1273bool wxVariant::operator!= (long value) const
1274{
1275 return (!((*this) == value));
1276}
1277
1278void wxVariant::operator= (long value)
1279{
223d09f6 1280 if (GetType() == wxT("long"))
341287bf
JS
1281 {
1282 ((wxVariantDataLong*)GetData())->SetValue(value);
1283 }
1284 else
1285 {
1286 if (m_data)
1287 delete m_data;
1288 m_data = new wxVariantDataLong(value);
1289 }
1290}
1291
1292bool wxVariant::operator== (char value) const
1293{
1294 char thisValue;
1295 if (!Convert(&thisValue))
1296 return FALSE;
1297 else
1298 return (value == thisValue);
1299}
1300
1301bool wxVariant::operator!= (char value) const
1302{
1303 return (!((*this) == value));
1304}
1305
1306void wxVariant::operator= (char value)
1307{
223d09f6 1308 if (GetType() == wxT("char"))
341287bf
JS
1309 {
1310 ((wxVariantDataChar*)GetData())->SetValue(value);
1311 }
1312 else
1313 {
1314 if (m_data)
1315 delete m_data;
1316 m_data = new wxVariantDataChar(value);
1317 }
1318}
1319
57493f9f 1320#ifdef HAVE_BOOL
341287bf
JS
1321bool wxVariant::operator== (bool value) const
1322{
1323 bool thisValue;
1324 if (!Convert(&thisValue))
1325 return FALSE;
1326 else
1327 return (value == thisValue);
1328}
1329
1330bool wxVariant::operator!= (bool value) const
1331{
1332 return (!((*this) == value));
1333}
1334
1335void wxVariant::operator= (bool value)
1336{
223d09f6 1337 if (GetType() == wxT("bool"))
341287bf
JS
1338 {
1339 ((wxVariantDataBool*)GetData())->SetValue(value);
1340 }
1341 else
1342 {
1343 if (m_data)
1344 delete m_data;
1345 m_data = new wxVariantDataBool(value);
1346 }
1347}
57493f9f 1348#endif // HAVE_BOOL
341287bf
JS
1349
1350bool wxVariant::operator== (const wxString& value) const
1351{
1352 wxString thisValue;
1353 if (!Convert(&thisValue))
1354 return FALSE;
f6bcfd97
BP
1355
1356 return value == thisValue;
341287bf
JS
1357}
1358
1359bool wxVariant::operator!= (const wxString& value) const
1360{
1361 return (!((*this) == value));
1362}
1363
1364void wxVariant::operator= (const wxString& value)
1365{
223d09f6 1366 if (GetType() == wxT("string"))
341287bf
JS
1367 {
1368 ((wxVariantDataString*)GetData())->SetValue(value);
1369 }
1370 else
1371 {
1372 if (m_data)
1373 delete m_data;
1374 m_data = new wxVariantDataString(value);
1375 }
1376}
1377
783b6cfd 1378void wxVariant::operator= (const wxChar* value)
341287bf 1379{
223d09f6 1380 if (GetType() == wxT("string"))
341287bf
JS
1381 {
1382 ((wxVariantDataString*)GetData())->SetValue(wxString(value));
1383 }
1384 else
1385 {
1386 if (m_data)
1387 delete m_data;
1388 m_data = new wxVariantDataString(wxString(value));
1389 }
1390}
1391
1392bool wxVariant::operator== (const wxStringList& value) const
1393{
223d09f6 1394 wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
341287bf
JS
1395
1396 wxVariantDataStringList other(value);
1397 return (m_data->Eq(other));
1398}
1399
1400bool wxVariant::operator!= (const wxStringList& value) const
1401{
1402 return (!((*this) == value));
1403}
1404
1405void wxVariant::operator= (const wxStringList& value)
1406{
223d09f6 1407 if (GetType() == wxT("stringlist"))
341287bf
JS
1408 {
1409 ((wxVariantDataStringList*)GetData())->SetValue(value);
1410 }
1411 else
1412 {
1413 if (m_data)
1414 delete m_data;
1415 m_data = new wxVariantDataStringList(value);
1416 }
1417}
1418
1419bool wxVariant::operator== (const wxList& value) const
1420{
223d09f6 1421 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
341287bf
JS
1422
1423 wxVariantDataList other(value);
1424 return (m_data->Eq(other));
1425}
1426
1427bool wxVariant::operator!= (const wxList& value) const
1428{
1429 return (!((*this) == value));
1430}
1431
1432void wxVariant::operator= (const wxList& value)
1433{
223d09f6 1434 if (GetType() == wxT("list"))
341287bf
JS
1435 {
1436 ((wxVariantDataList*)GetData())->SetValue(value);
1437 }
1438 else
1439 {
1440 if (m_data)
1441 delete m_data;
1442 m_data = new wxVariantDataList(value);
1443 }
1444}
1445
457e6c54
JS
1446// For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1447#if wxUSE_TIMEDATE && !defined(__WATCOMC__)
a0a302dc
JS
1448bool wxVariant::operator== (const wxTime& value) const
1449{
1450 wxTime thisValue;
1451 if (!Convert(&thisValue))
1452 return FALSE;
f6bcfd97
BP
1453
1454 return value == thisValue;
a0a302dc
JS
1455}
1456
1457bool wxVariant::operator!= (const wxTime& value) const
1458{
1459 return (!((*this) == value));
1460}
1461
1462void wxVariant::operator= (const wxTime& value)
1463{
223d09f6 1464 if (GetType() == wxT("time"))
a0a302dc
JS
1465 {
1466 ((wxVariantDataTime*)GetData())->SetValue(value);
1467 }
1468 else
1469 {
1470 if (m_data)
1471 delete m_data;
1472 m_data = new wxVariantDataTime(value);
1473 }
1474}
1475
1476bool wxVariant::operator== (const wxDate& value) const
1477{
1478 wxDate thisValue;
1479 if (!Convert(&thisValue))
1480 return FALSE;
f6bcfd97
BP
1481
1482 return (value == thisValue);
a0a302dc
JS
1483}
1484
1485bool wxVariant::operator!= (const wxDate& value) const
1486{
1487 return (!((*this) == value));
1488}
1489
1490void wxVariant::operator= (const wxDate& value)
1491{
223d09f6 1492 if (GetType() == wxT("date"))
a0a302dc
JS
1493 {
1494 ((wxVariantDataTime*)GetData())->SetValue(value);
1495 }
1496 else
1497 {
1498 if (m_data)
1499 delete m_data;
1500 m_data = new wxVariantDataDate(value);
1501 }
1502}
1503#endif
1504
1505bool wxVariant::operator== (void* value) const
1506{
1507 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1508}
1509
1510bool wxVariant::operator!= (void* value) const
1511{
f6bcfd97 1512 return (!((*this) == (void*) value));
a0a302dc
JS
1513}
1514
1515void wxVariant::operator= (void* value)
1516{
223d09f6 1517 if (GetType() == wxT("void*"))
a0a302dc
JS
1518 {
1519 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1520 }
1521 else
1522 {
1523 if (m_data)
1524 delete m_data;
1525 m_data = new wxVariantDataVoidPtr(value);
1526 }
1527}
341287bf
JS
1528
1529// Treat a list variant as an array
1530wxVariant wxVariant::operator[] (size_t idx) const
1531{
223d09f6 1532 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for array operator") );
341287bf 1533
223d09f6 1534 if (GetType() == wxT("list"))
341287bf
JS
1535 {
1536 wxVariantDataList* data = (wxVariantDataList*) m_data;
223d09f6 1537 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
341287bf
JS
1538 return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1539 }
223d09f6 1540 else if (GetType() == wxT("stringlist"))
341287bf
JS
1541 {
1542 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
223d09f6 1543 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
341287bf 1544
783b6cfd 1545 wxVariant variant( wxString( (wxChar*) (data->GetValue().Nth(idx)->Data()) ));
341287bf
JS
1546 return variant;
1547 }
1548 return wxNullVariant;
1549}
1550
1551wxVariant& wxVariant::operator[] (size_t idx)
1552{
1553 // We can't return a reference to a variant for a string list, since the string
1554 // is actually stored as a char*, not a variant.
1555
223d09f6 1556 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
341287bf
JS
1557
1558 wxVariantDataList* data = (wxVariantDataList*) m_data;
223d09f6 1559 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
341287bf
JS
1560
1561 return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1562}
1563
1564// Return the number of elements in a list
1565int wxVariant::GetCount() const
1566{
223d09f6 1567 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for GetCount()") );
341287bf 1568
223d09f6 1569 if (GetType() == wxT("list"))
341287bf
JS
1570 {
1571 wxVariantDataList* data = (wxVariantDataList*) m_data;
1572 return data->GetValue().Number();
1573 }
223d09f6 1574 else if (GetType() == wxT("stringlist"))
341287bf
JS
1575 {
1576 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1577 return data->GetValue().Number();
1578 }
1579 return 0;
1580}
1581
1582wxString wxVariant::MakeString() const
1583{
1584 if (!IsNull())
1585 {
1586 wxString str;
1587 if (GetData()->Write(str))
1588 return str;
1589 }
223d09f6 1590 return wxString(wxT(""));
341287bf
JS
1591}
1592
1593// Accessors
1594
1595void wxVariant::SetData(wxVariantData* data)
1596{
1597 if (m_data) delete m_data;
1598 m_data = data;
1599}
1600
1601
1602// Returns a string representing the type of the variant,
1603// e.g. "string", "bool", "stringlist", "list", "double", "long"
1604wxString wxVariant::GetType() const
1605{
1606 if (IsNull())
223d09f6 1607 return wxString(wxT("null"));
341287bf
JS
1608 else
1609 return m_data->GetType();
1610}
1611
1612
1613bool wxVariant::IsType(const wxString& type) const
1614{
1615 return (GetType() == type);
1616}
1617
1618
1619// Value accessors
1620double wxVariant::GetReal() const
1621{
1622 double value;
1623 if (Convert(& value))
1624 return value;
1625 else
1626 {
223d09f6 1627 wxFAIL_MSG(wxT("Could not convert to a real number"));
341287bf
JS
1628 return 0.0;
1629 }
1630}
1631
1632long wxVariant::GetInteger() const
1633{
1634 long value;
1635 if (Convert(& value))
1636 return value;
1637 else
1638 {
223d09f6 1639 wxFAIL_MSG(wxT("Could not convert to an integer"));
341287bf
JS
1640 return 0;
1641 }
1642}
1643
1644char wxVariant::GetChar() const
1645{
1646 char value;
1647 if (Convert(& value))
1648 return value;
1649 else
1650 {
223d09f6 1651 wxFAIL_MSG(wxT("Could not convert to a char"));
341287bf
JS
1652 return 0;
1653 }
1654}
1655
1656bool wxVariant::GetBool() const
1657{
1658 bool value;
1659 if (Convert(& value))
1660 return value;
1661 else
1662 {
223d09f6 1663 wxFAIL_MSG(wxT("Could not convert to a bool"));
341287bf
JS
1664 return 0;
1665 }
1666}
1667
1668wxString wxVariant::GetString() const
1669{
1670 wxString value;
f6bcfd97 1671 if (!Convert(& value))
341287bf 1672 {
223d09f6 1673 wxFAIL_MSG(wxT("Could not convert to a string"));
341287bf 1674 }
f6bcfd97
BP
1675
1676 return value;
341287bf
JS
1677}
1678
457e6c54
JS
1679// For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1680#if wxUSE_TIMEDATE && !defined(__WATCOMC__)
a0a302dc
JS
1681wxTime wxVariant::GetTime() const
1682{
1683 wxTime value;
f6bcfd97 1684 if (!Convert(& value))
a0a302dc 1685 {
223d09f6 1686 wxFAIL_MSG(wxT("Could not convert to a time"));
a0a302dc 1687 }
f6bcfd97
BP
1688
1689 return value;
a0a302dc
JS
1690}
1691
1692wxDate wxVariant::GetDate() const
1693{
1694 wxDate value;
f6bcfd97 1695 if (!Convert(& value))
a0a302dc 1696 {
223d09f6 1697 wxFAIL_MSG(wxT("Could not convert to a date"));
a0a302dc 1698 }
f6bcfd97
BP
1699
1700 return value;
a0a302dc 1701}
f6bcfd97 1702#endif // wxUSE_TIMEDATE
a0a302dc
JS
1703
1704void* wxVariant::GetVoidPtr() const
1705{
223d09f6 1706 wxASSERT( (GetType() == wxT("void*")) );
a0a302dc
JS
1707
1708 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
1709}
1710
341287bf
JS
1711wxList& wxVariant::GetList() const
1712{
223d09f6 1713 wxASSERT( (GetType() == wxT("list")) );
341287bf
JS
1714
1715 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
1716}
1717
1718wxStringList& wxVariant::GetStringList() const
1719{
223d09f6 1720 wxASSERT( (GetType() == wxT("stringlist")) );
341287bf
JS
1721
1722 return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
1723}
1724
1725// Append to list
1726void wxVariant::Append(const wxVariant& value)
1727{
1728 wxList& list = GetList();
1729
1730 list.Append(new wxVariant(value));
1731}
1732
1733// Insert at front of list
1734void wxVariant::Insert(const wxVariant& value)
1735{
1736 wxList& list = GetList();
1737
1738 list.Insert(new wxVariant(value));
1739}
1740
1741// Returns TRUE if the variant is a member of the list
1742bool wxVariant::Member(const wxVariant& value) const
1743{
1744 wxList& list = GetList();
1745
1746 wxNode* node = list.First();
1747 while (node)
1748 {
1749 wxVariant* other = (wxVariant*) node->Data();
1750 if (value == *other)
1751 return TRUE;
1752 node = node->Next();
1753 }
1754 return FALSE;
1755}
1756
1757// Deletes the nth element of the list
1758bool wxVariant::Delete(int item)
1759{
1760 wxList& list = GetList();
1761
223d09f6 1762 wxASSERT_MSG( (item < list.Number()), wxT("Invalid index to Delete") );
341287bf
JS
1763 wxNode* node = list.Nth(item);
1764 wxVariant* variant = (wxVariant*) node->Data();
1765 delete variant;
1766 delete node;
1767 return TRUE;
1768}
1769
1770// Clear list
1771void wxVariant::ClearList()
1772{
223d09f6 1773 if (!IsNull() && (GetType() == wxT("list")))
341287bf
JS
1774 {
1775 ((wxVariantDataList*) m_data)->Clear();
1776 }
1777 else
1778 {
223d09f6 1779 if (GetType() != wxT("list"))
341287bf
JS
1780 {
1781 delete m_data;
1782 m_data = NULL;
1783 }
1784 m_data = new wxVariantDataList;
1785 }
1786}
1787
1788// Type conversion
1789bool wxVariant::Convert(long* value) const
1790{
1791 wxString type(GetType());
223d09f6 1792 if (type == wxT("double"))
341287bf 1793 *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
223d09f6 1794 else if (type == wxT("long"))
341287bf 1795 *value = ((wxVariantDataLong*)GetData())->GetValue();
862416e0 1796#ifdef HAVE_BOOL
223d09f6 1797 else if (type == wxT("bool"))
341287bf 1798 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1799#endif
223d09f6 1800 else if (type == wxT("string"))
783b6cfd 1801 *value = wxAtol((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
341287bf
JS
1802 else
1803 return FALSE;
1804
1805 return TRUE;
1806}
1807
1808bool wxVariant::Convert(bool* value) const
1809{
1810 wxString type(GetType());
223d09f6 1811 if (type == wxT("double"))
341287bf 1812 *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
223d09f6 1813 else if (type == wxT("long"))
341287bf 1814 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
862416e0 1815#ifdef HAVE_BOOL
223d09f6 1816 else if (type == wxT("bool"))
341287bf 1817 *value = ((wxVariantDataBool*)GetData())->GetValue();
862416e0 1818#endif
223d09f6 1819 else if (type == wxT("string"))
341287bf
JS
1820 {
1821 wxString val(((wxVariantDataString*)GetData())->GetValue());
1822 val.MakeLower();
223d09f6 1823 if (val == wxT("true") || val == wxT("yes"))
341287bf 1824 *value = TRUE;
223d09f6 1825 else if (val == wxT("false") || val == wxT("no"))
341287bf
JS
1826 *value = FALSE;
1827 else
1828 return FALSE;
1829 }
1830 else
1831 return FALSE;
1832
1833 return TRUE;
1834}
1835
1836bool wxVariant::Convert(double* value) const
1837{
1838 wxString type(GetType());
223d09f6 1839 if (type == wxT("double"))
341287bf 1840 *value = ((wxVariantDataReal*)GetData())->GetValue();
223d09f6 1841 else if (type == wxT("long"))
341287bf 1842 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1843#ifdef HAVE_BOOL
223d09f6 1844 else if (type == wxT("bool"))
341287bf 1845 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1846#endif
223d09f6 1847 else if (type == wxT("string"))
783b6cfd 1848 *value = (double) wxAtof((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
341287bf
JS
1849 else
1850 return FALSE;
1851
1852 return TRUE;
1853}
1854
1855bool wxVariant::Convert(char* value) const
1856{
1857 wxString type(GetType());
223d09f6 1858 if (type == wxT("char"))
341287bf 1859 *value = ((wxVariantDataChar*)GetData())->GetValue();
223d09f6 1860 else if (type == wxT("long"))
341287bf 1861 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
862416e0 1862#ifdef HAVE_BOOL
223d09f6 1863 else if (type == wxT("bool"))
341287bf 1864 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
862416e0 1865#endif
341287bf
JS
1866 else
1867 return FALSE;
1868
1869 return TRUE;
1870}
1871
1872bool wxVariant::Convert(wxString* value) const
1873{
1874 *value = MakeString();
1875 return TRUE;
1876}
1877
457e6c54
JS
1878// For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1879#if wxUSE_TIMEDATE && !defined(__WATCOMC__)
a0a302dc
JS
1880bool wxVariant::Convert(wxTime* value) const
1881{
1882 wxString type(GetType());
223d09f6 1883 if (type == wxT("time"))
a0a302dc 1884 *value = ((wxVariantDataTime*)GetData())->GetValue();
223d09f6 1885 else if (type == wxT("date"))
a0a302dc
JS
1886 *value = wxTime(((wxVariantDataDate*)GetData())->GetValue());
1887 else
1888 return FALSE;
1889
1890 return TRUE;
1891}
1892
1893bool wxVariant::Convert(wxDate* value) const
1894{
1895 wxString type(GetType());
223d09f6 1896 if (type == wxT("date"))
a0a302dc
JS
1897 *value = ((wxVariantDataDate*)GetData())->GetValue();
1898 else
1899 return FALSE;
1900
1901 return TRUE;
1902}
1903#endif
1904 // wxUSE_TIMEDATE
457e6c54 1905