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