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