]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
adapting to init pattern
[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"
0bf751e7 26 #include "wx/crt.h"
530ecef0
WS
27 #if wxUSE_STREAMS
28 #include "wx/stream.h"
29 #endif
df91131c
WS
30#endif
31
be087207
RR
32#if wxUSE_STD_IOSTREAM
33 #if wxUSE_IOSTREAMH
34 #include <fstream.h>
35 #else
36 #include <fstream>
37 #endif
fbc535ff 38#endif
341287bf 39
31907d03 40#if defined(__MWERKS__) && __MSL__ >= 0x6000
52cbcda3 41namespace std {}
31907d03
SC
42using namespace std ;
43#endif
44
fae05df5 45#if wxUSE_STREAMS
530ecef0 46 #include "wx/txtstrm.h"
fae05df5
GL
47#endif
48
341287bf 49#include "wx/string.h"
fb42d7c3
VZ
50#include "wx/tokenzr.h"
51
fd242375 52wxVariant WXDLLIMPEXP_BASE wxNullVariant;
341287bf 53
2562c823 54
7e6b4780 55#include "wx/listimpl.cpp"
43ea4e37 56WX_DEFINE_LIST(wxVariantList)
7e6b4780 57
341287bf 58/*
2562c823 59 * wxVariant
341287bf
JS
60 */
61
2562c823 62IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
341287bf 63
2562c823 64wxVariant::wxVariant()
cf25a599 65 : wxObject()
341287bf 66{
341287bf
JS
67}
68
2562c823 69bool wxVariant::IsNull() const
341287bf 70{
cf25a599 71 return (m_refData == NULL);
341287bf
JS
72}
73
2562c823 74void wxVariant::MakeNull()
341287bf 75{
2562c823 76 UnRef();
341287bf
JS
77}
78
2562c823 79void wxVariant::Clear()
341287bf 80{
2562c823 81 m_name = wxEmptyString;
341287bf
JS
82}
83
2562c823
RR
84wxVariant::wxVariant(const wxVariant& variant)
85 : wxObject()
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
cf25a599 94 : wxObject()
341287bf 95{
cf25a599 96 m_refData = data;
2562c823 97 m_name = name;
341287bf
JS
98}
99
2562c823 100wxVariant::~wxVariant()
341287bf 101{
cf25a599
JS
102}
103
104wxObjectRefData *wxVariant::CreateRefData() const
105{
106 // We cannot create any particular wxVariantData.
107 wxFAIL_MSG("wxVariant::CreateRefData() cannot be implemented");
108 return NULL;
109}
110
111wxObjectRefData *wxVariant::CloneRefData(const wxObjectRefData *data) const
112{
113 return ((wxVariantData*) data)->Clone();
341287bf
JS
114}
115
2562c823
RR
116// Assignment
117void wxVariant::operator= (const wxVariant& variant)
341287bf 118{
2562c823
RR
119 Ref(variant);
120 m_name = variant.m_name;
341287bf
JS
121}
122
2562c823
RR
123// myVariant = new wxStringVariantData("hello")
124void wxVariant::operator= (wxVariantData* variantData)
341287bf 125{
2562c823 126 UnRef();
cf25a599 127 m_refData = variantData;
341287bf
JS
128}
129
2562c823 130bool wxVariant::operator== (const wxVariant& variant) const
341287bf 131{
2562c823
RR
132 if (IsNull() || variant.IsNull())
133 return (IsNull() == variant.IsNull());
341287bf 134
af4d7484
RR
135 if (GetType() != variant.GetType())
136 return false;
137
2562c823
RR
138 return (GetData()->Eq(* variant.GetData()));
139}
341287bf 140
2562c823 141bool wxVariant::operator!= (const wxVariant& variant) const
341287bf 142{
2562c823
RR
143 return (!(*this == variant));
144}
341287bf 145
2562c823 146wxString wxVariant::MakeString() const
341287bf 147{
2562c823
RR
148 if (!IsNull())
149 {
150 wxString str;
151 if (GetData()->Write(str))
152 return str;
153 }
154 return wxEmptyString;
341287bf
JS
155}
156
2562c823 157void wxVariant::SetData(wxVariantData* data)
341287bf 158{
2562c823 159 UnRef();
cf25a599 160 m_refData = data;
2562c823 161}
341287bf 162
c8058a09
JS
163bool wxVariant::Unshare()
164{
cf25a599
JS
165 if ( !m_refData || m_refData->GetRefCount() == 1 )
166 return true;
c8058a09 167
cf25a599 168 wxObject::UnShare();
c8058a09 169
cf25a599 170 return (m_refData && m_refData->GetRefCount() == 1);
c8058a09
JS
171}
172
2562c823
RR
173
174// Returns a string representing the type of the variant,
175// e.g. "string", "bool", "list", "double", "long"
176wxString wxVariant::GetType() const
177{
178 if (IsNull())
179 return wxString(wxT("null"));
180 else
181 return GetData()->GetType();
341287bf
JS
182}
183
2562c823
RR
184
185bool wxVariant::IsType(const wxString& type) const
341287bf 186{
2562c823 187 return (GetType() == type);
341287bf
JS
188}
189
2562c823 190bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
341287bf 191{
2562c823
RR
192 wxClassInfo* info=GetData()->GetValueClassInfo();
193 return info ? info->IsKindOf(type) : false ;
341287bf
JS
194}
195
0bf14ab8
JS
196// -----------------------------------------------------------------
197// wxVariant <-> wxAny conversion code
198// -----------------------------------------------------------------
199
200#if wxUSE_ANY
201
202wxAnyToVariantRegistration::
203 wxAnyToVariantRegistration(wxVariantDataFactory factory)
204 : m_factory(factory)
205{
206 wxPreRegisterAnyToVariant(this);
207}
208
2a227e8c
RR
209wxAnyToVariantRegistration::~wxAnyToVariantRegistration()
210{
211}
212
0bf14ab8
JS
213wxVariant::wxVariant(const wxAny& any)
214 : wxObject()
215{
216 wxVariant variant;
217 if ( !any.GetAs(&variant) )
218 {
219 wxFAIL_MSG("wxAny of this type cannot be converted to wxVariant");
220 return;
221 }
222
223 *this = variant;
224}
225
226wxAny wxVariant::GetAny() const
227{
228 if ( IsNull() )
0aaed451 229 return wxAny();
0bf14ab8 230
0aaed451 231 wxAny any;
0bf14ab8 232 wxVariantData* data = GetData();
0bf14ab8
JS
233
234 if ( data->GetAsAny(&any) )
ea412ac4 235 return any;
0bf14ab8
JS
236
237 // If everything else fails, wrap the whole wxVariantData
ea412ac4 238 return wxAny(data);
0bf14ab8
JS
239}
240
241#endif // wxUSE_ANY
2c3a1064 242
2562c823
RR
243// -----------------------------------------------------------------
244// wxVariantDataLong
245// -----------------------------------------------------------------
341287bf 246
fd242375 247class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
341287bf 248{
341287bf
JS
249public:
250 wxVariantDataLong() { m_value = 0; }
251 wxVariantDataLong(long value) { m_value = value; }
252
253 inline long GetValue() const { return m_value; }
254 inline void SetValue(long value) { m_value = value; }
255
341287bf 256 virtual bool Eq(wxVariantData& data) const;
1ccbb61a
VZ
257
258 virtual bool Read(wxString& str);
341287bf 259 virtual bool Write(wxString& str) const;
38830220 260#if wxUSE_STD_IOSTREAM
dd107c50
VZ
261 virtual bool Read(wxSTD istream& str);
262 virtual bool Write(wxSTD ostream& str) const;
38830220 263#endif
e02afc7a 264#if wxUSE_STREAMS
75ed1d15 265 virtual bool Read(wxInputStream& str);
1ccbb61a 266 virtual bool Write(wxOutputStream &str) const;
e02afc7a 267#endif // wxUSE_STREAMS
1ccbb61a 268
c8058a09
JS
269 wxVariantData* Clone() const { return new wxVariantDataLong(m_value); }
270
47b378bd 271 virtual wxString GetType() const { return wxT("long"); }
341287bf 272
6589f1a4 273#if wxUSE_ANY
0bf14ab8
JS
274 // Since wxAny does not have separate type for integers shorter than
275 // longlong, we do not usually implement wxVariant->wxAny conversion
276 // here (but in wxVariantDataLongLong instead).
6589f1a4 277 #ifndef wxLongLong_t
0bf14ab8 278 DECLARE_WXANY_CONVERSION()
6589f1a4 279 #else
0bf14ab8
JS
280 bool GetAsAny(wxAny* any) const
281 {
282 *any = m_value;
283 return true;
284 }
6589f1a4
JS
285 #endif
286#endif // wxUSE_ANY
0bf14ab8 287
341287bf
JS
288protected:
289 long m_value;
290};
291
0bf14ab8
JS
292#ifndef wxLongLong_t
293IMPLEMENT_TRIVIAL_WXANY_CONVERSION(long, wxVariantDataLong)
294#endif
295
341287bf
JS
296bool wxVariantDataLong::Eq(wxVariantData& data) const
297{
223d09f6 298 wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
341287bf
JS
299
300 wxVariantDataLong& otherData = (wxVariantDataLong&) data;
301
302 return (otherData.m_value == m_value);
303}
304
38830220 305#if wxUSE_STD_IOSTREAM
dd107c50 306bool wxVariantDataLong::Write(wxSTD ostream& str) const
341287bf
JS
307{
308 wxString s;
309 Write(s);
783b6cfd 310 str << (const char*) s.mb_str();
cab1a605 311 return true;
341287bf 312}
38830220 313#endif
341287bf
JS
314
315bool wxVariantDataLong::Write(wxString& str) const
316{
223d09f6 317 str.Printf(wxT("%ld"), m_value);
cab1a605 318 return true;
341287bf
JS
319}
320
38830220 321#if wxUSE_STD_IOSTREAM
dd107c50 322bool wxVariantDataLong::Read(wxSTD istream& str)
341287bf
JS
323{
324 str >> m_value;
cab1a605 325 return true;
341287bf 326}
38830220 327#endif
341287bf 328
e02afc7a 329#if wxUSE_STREAMS
1ccbb61a
VZ
330bool wxVariantDataLong::Write(wxOutputStream& str) const
331{
fae05df5
GL
332 wxTextOutputStream s(str);
333
479cd5de 334 s.Write32((size_t)m_value);
cab1a605 335 return true;
1ccbb61a
VZ
336}
337
75ed1d15
GL
338bool wxVariantDataLong::Read(wxInputStream& str)
339{
fae05df5
GL
340 wxTextInputStream s(str);
341 m_value = s.Read32();
cab1a605 342 return true;
75ed1d15 343}
e02afc7a 344#endif // wxUSE_STREAMS
75ed1d15 345
341287bf
JS
346bool wxVariantDataLong::Read(wxString& str)
347{
52de37c7 348 m_value = wxAtol(str);
cab1a605 349 return true;
341287bf
JS
350}
351
07502d73 352// wxVariant
341287bf 353
2562c823 354wxVariant::wxVariant(long val, const wxString& name)
341287bf 355{
cf25a599 356 m_refData = new wxVariantDataLong(val);
2562c823
RR
357 m_name = name;
358}
341287bf 359
2562c823
RR
360wxVariant::wxVariant(int val, const wxString& name)
361{
cf25a599 362 m_refData = new wxVariantDataLong((long)val);
2562c823
RR
363 m_name = name;
364}
365
366wxVariant::wxVariant(short val, const wxString& name)
367{
cf25a599 368 m_refData = new wxVariantDataLong((long)val);
2562c823
RR
369 m_name = name;
370}
371
372bool wxVariant::operator== (long value) const
373{
374 long thisValue;
375 if (!Convert(&thisValue))
376 return false;
377 else
378 return (value == thisValue);
379}
380
381bool wxVariant::operator!= (long value) const
382{
383 return (!((*this) == value));
384}
385
386void wxVariant::operator= (long value)
387{
388 if (GetType() == wxT("long") &&
cf25a599 389 m_refData->GetRefCount() == 1)
2562c823
RR
390 {
391 ((wxVariantDataLong*)GetData())->SetValue(value);
392 }
393 else
394 {
395 UnRef();
cf25a599 396 m_refData = new wxVariantDataLong(value);
2562c823
RR
397 }
398}
399
400long wxVariant::GetLong() const
401{
402 long value;
403 if (Convert(& value))
404 return value;
405 else
406 {
407 wxFAIL_MSG(wxT("Could not convert to a long"));
408 return 0;
409 }
410}
411
412// -----------------------------------------------------------------
413// wxVariantDoubleData
414// -----------------------------------------------------------------
415
416class WXDLLIMPEXP_BASE wxVariantDoubleData: public wxVariantData
417{
2562c823
RR
418public:
419 wxVariantDoubleData() { m_value = 0.0; }
420 wxVariantDoubleData(double value) { m_value = value; }
421
422 inline double GetValue() const { return m_value; }
423 inline void SetValue(double value) { m_value = value; }
341287bf 424
341287bf 425 virtual bool Eq(wxVariantData& data) const;
1ccbb61a 426 virtual bool Read(wxString& str);
38830220 427#if wxUSE_STD_IOSTREAM
dd107c50 428 virtual bool Write(wxSTD ostream& str) const;
38830220 429#endif
341287bf 430 virtual bool Write(wxString& str) const;
38830220 431#if wxUSE_STD_IOSTREAM
dd107c50 432 virtual bool Read(wxSTD istream& str);
38830220 433#endif
e02afc7a 434#if wxUSE_STREAMS
75ed1d15 435 virtual bool Read(wxInputStream& str);
1ccbb61a 436 virtual bool Write(wxOutputStream &str) const;
e02afc7a 437#endif // wxUSE_STREAMS
47b378bd 438 virtual wxString GetType() const { return wxT("double"); }
341287bf 439
c8058a09 440 wxVariantData* Clone() const { return new wxVariantDoubleData(m_value); }
0bf14ab8
JS
441
442 DECLARE_WXANY_CONVERSION()
341287bf
JS
443protected:
444 double m_value;
445};
446
0bf14ab8
JS
447IMPLEMENT_TRIVIAL_WXANY_CONVERSION(double, wxVariantDoubleData)
448
2562c823 449bool wxVariantDoubleData::Eq(wxVariantData& data) const
341287bf 450{
2562c823 451 wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDoubleData::Eq: argument mismatch") );
341287bf 452
2562c823 453 wxVariantDoubleData& otherData = (wxVariantDoubleData&) data;
341287bf 454
bc14c8b2 455 return wxIsSameDouble(otherData.m_value, m_value);
341287bf
JS
456}
457
38830220 458#if wxUSE_STD_IOSTREAM
2562c823 459bool wxVariantDoubleData::Write(wxSTD ostream& str) const
341287bf
JS
460{
461 wxString s;
462 Write(s);
783b6cfd 463 str << (const char*) s.mb_str();
cab1a605 464 return true;
341287bf 465}
38830220 466#endif
341287bf 467
2562c823 468bool wxVariantDoubleData::Write(wxString& str) const
341287bf 469{
654056ee 470 str.Printf(wxT("%.14g"), m_value);
cab1a605 471 return true;
341287bf
JS
472}
473
38830220 474#if wxUSE_STD_IOSTREAM
2562c823 475bool wxVariantDoubleData::Read(wxSTD istream& str)
341287bf
JS
476{
477 str >> m_value;
cab1a605 478 return true;
341287bf 479}
38830220 480#endif
341287bf 481
e02afc7a 482#if wxUSE_STREAMS
2562c823 483bool wxVariantDoubleData::Write(wxOutputStream& str) const
1ccbb61a 484{
fae05df5
GL
485 wxTextOutputStream s(str);
486 s.WriteDouble((double)m_value);
cab1a605 487 return true;
1ccbb61a
VZ
488}
489
2562c823 490bool wxVariantDoubleData::Read(wxInputStream& str)
75ed1d15 491{
fae05df5
GL
492 wxTextInputStream s(str);
493 m_value = (float)s.ReadDouble();
cab1a605 494 return true;
75ed1d15 495}
e02afc7a 496#endif // wxUSE_STREAMS
75ed1d15 497
2562c823 498bool wxVariantDoubleData::Read(wxString& str)
341287bf 499{
52de37c7 500 m_value = wxAtof(str);
cab1a605 501 return true;
341287bf
JS
502}
503
2562c823
RR
504// wxVariant double code
505
506wxVariant::wxVariant(double val, const wxString& name)
507{
cf25a599 508 m_refData = new wxVariantDoubleData(val);
2562c823
RR
509 m_name = name;
510}
511
512bool wxVariant::operator== (double value) const
513{
514 double thisValue;
515 if (!Convert(&thisValue))
516 return false;
517
518 return wxIsSameDouble(value, thisValue);
519}
520
521bool wxVariant::operator!= (double value) const
522{
523 return (!((*this) == value));
524}
525
526void wxVariant::operator= (double value)
527{
528 if (GetType() == wxT("double") &&
cf25a599 529 m_refData->GetRefCount() == 1)
2562c823
RR
530 {
531 ((wxVariantDoubleData*)GetData())->SetValue(value);
532 }
533 else
534 {
535 UnRef();
cf25a599 536 m_refData = new wxVariantDoubleData(value);
2562c823
RR
537 }
538}
539
540double wxVariant::GetDouble() const
541{
542 double value;
543 if (Convert(& value))
544 return value;
545 else
546 {
547 wxFAIL_MSG(wxT("Could not convert to a double number"));
548 return 0.0;
549 }
550}
551
552// -----------------------------------------------------------------
553// wxVariantBoolData
554// -----------------------------------------------------------------
555
fd242375 556class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
341287bf 557{
341287bf
JS
558public:
559 wxVariantDataBool() { m_value = 0; }
560 wxVariantDataBool(bool value) { m_value = value; }
561
562 inline bool GetValue() const { return m_value; }
563 inline void SetValue(bool value) { m_value = value; }
564
341287bf 565 virtual bool Eq(wxVariantData& data) const;
38830220 566#if wxUSE_STD_IOSTREAM
dd107c50 567 virtual bool Write(wxSTD ostream& str) const;
38830220 568#endif
341287bf 569 virtual bool Write(wxString& str) const;
1ccbb61a 570 virtual bool Read(wxString& str);
38830220 571#if wxUSE_STD_IOSTREAM
dd107c50 572 virtual bool Read(wxSTD istream& str);
38830220 573#endif
e02afc7a 574#if wxUSE_STREAMS
75ed1d15 575 virtual bool Read(wxInputStream& str);
1ccbb61a 576 virtual bool Write(wxOutputStream& str) const;
e02afc7a 577#endif // wxUSE_STREAMS
47b378bd 578 virtual wxString GetType() const { return wxT("bool"); }
341287bf 579
c8058a09 580 wxVariantData* Clone() const { return new wxVariantDataBool(m_value); }
0bf14ab8
JS
581
582 DECLARE_WXANY_CONVERSION()
341287bf
JS
583protected:
584 bool m_value;
585};
586
0bf14ab8
JS
587IMPLEMENT_TRIVIAL_WXANY_CONVERSION(bool, wxVariantDataBool)
588
341287bf
JS
589bool wxVariantDataBool::Eq(wxVariantData& data) const
590{
223d09f6 591 wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
341287bf
JS
592
593 wxVariantDataBool& otherData = (wxVariantDataBool&) data;
594
595 return (otherData.m_value == m_value);
596}
597
38830220 598#if wxUSE_STD_IOSTREAM
dd107c50 599bool wxVariantDataBool::Write(wxSTD ostream& str) const
341287bf
JS
600{
601 wxString s;
602 Write(s);
783b6cfd 603 str << (const char*) s.mb_str();
cab1a605 604 return true;
341287bf 605}
38830220 606#endif
341287bf
JS
607
608bool wxVariantDataBool::Write(wxString& str) const
609{
223d09f6 610 str.Printf(wxT("%d"), (int) m_value);
cab1a605 611 return true;
341287bf
JS
612}
613
38830220 614#if wxUSE_STD_IOSTREAM
dd107c50 615bool wxVariantDataBool::Read(wxSTD istream& WXUNUSED(str))
341287bf 616{
223d09f6 617 wxFAIL_MSG(wxT("Unimplemented"));
341287bf 618// str >> (long) m_value;
cab1a605 619 return false;
341287bf 620}
38830220 621#endif
341287bf 622
e02afc7a 623#if wxUSE_STREAMS
1ccbb61a
VZ
624bool wxVariantDataBool::Write(wxOutputStream& str) const
625{
fae05df5
GL
626 wxTextOutputStream s(str);
627
2b004197 628 s.Write8(m_value);
cab1a605 629 return true;
1ccbb61a
VZ
630}
631
75ed1d15
GL
632bool wxVariantDataBool::Read(wxInputStream& str)
633{
fae05df5
GL
634 wxTextInputStream s(str);
635
a1b82138 636 m_value = s.Read8() != 0;
cab1a605 637 return true;
75ed1d15 638}
e02afc7a 639#endif // wxUSE_STREAMS
75ed1d15 640
341287bf
JS
641bool wxVariantDataBool::Read(wxString& str)
642{
52de37c7 643 m_value = (wxAtol(str) != 0);
cab1a605 644 return true;
341287bf 645}
2562c823
RR
646
647// wxVariant ****
648
649wxVariant::wxVariant(bool val, const wxString& name)
650{
cf25a599 651 m_refData = new wxVariantDataBool(val);
2562c823
RR
652 m_name = name;
653}
654
655bool wxVariant::operator== (bool value) const
656{
657 bool thisValue;
658 if (!Convert(&thisValue))
659 return false;
660 else
661 return (value == thisValue);
662}
663
664bool wxVariant::operator!= (bool value) const
665{
666 return (!((*this) == value));
667}
668
669void wxVariant::operator= (bool value)
670{
671 if (GetType() == wxT("bool") &&
cf25a599 672 m_refData->GetRefCount() == 1)
2562c823
RR
673 {
674 ((wxVariantDataBool*)GetData())->SetValue(value);
675 }
676 else
677 {
678 UnRef();
cf25a599 679 m_refData = new wxVariantDataBool(value);
2562c823
RR
680 }
681}
682
683bool wxVariant::GetBool() const
684{
685 bool value;
686 if (Convert(& value))
687 return value;
688 else
689 {
690 wxFAIL_MSG(wxT("Could not convert to a bool"));
691 return 0;
692 }
693}
694
2562c823
RR
695// -----------------------------------------------------------------
696// wxVariantDataChar
697// -----------------------------------------------------------------
341287bf 698
fd242375 699class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
341287bf 700{
341287bf
JS
701public:
702 wxVariantDataChar() { m_value = 0; }
af717fa8 703 wxVariantDataChar(const wxUniChar& value) { m_value = value; }
341287bf 704
af717fa8
VS
705 inline wxUniChar GetValue() const { return m_value; }
706 inline void SetValue(const wxUniChar& value) { m_value = value; }
341287bf 707
341287bf 708 virtual bool Eq(wxVariantData& data) const;
38830220 709#if wxUSE_STD_IOSTREAM
dd107c50
VZ
710 virtual bool Read(wxSTD istream& str);
711 virtual bool Write(wxSTD ostream& str) const;
38830220 712#endif
1ccbb61a 713 virtual bool Read(wxString& str);
341287bf 714 virtual bool Write(wxString& str) const;
e02afc7a 715#if wxUSE_STREAMS
75ed1d15 716 virtual bool Read(wxInputStream& str);
1ccbb61a 717 virtual bool Write(wxOutputStream& str) const;
e02afc7a 718#endif // wxUSE_STREAMS
47b378bd 719 virtual wxString GetType() const { return wxT("char"); }
c8058a09 720 wxVariantData* Clone() const { return new wxVariantDataChar(m_value); }
341287bf 721
0bf14ab8 722 DECLARE_WXANY_CONVERSION()
341287bf 723protected:
af717fa8 724 wxUniChar m_value;
341287bf
JS
725};
726
0bf14ab8
JS
727IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxUniChar, wxVariantDataChar)
728
341287bf
JS
729bool wxVariantDataChar::Eq(wxVariantData& data) const
730{
223d09f6 731 wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
341287bf
JS
732
733 wxVariantDataChar& otherData = (wxVariantDataChar&) data;
734
735 return (otherData.m_value == m_value);
736}
737
38830220 738#if wxUSE_STD_IOSTREAM
dd107c50 739bool wxVariantDataChar::Write(wxSTD ostream& str) const
341287bf 740{
af717fa8 741 str << wxString(m_value);
cab1a605 742 return true;
341287bf 743}
38830220 744#endif
341287bf
JS
745
746bool wxVariantDataChar::Write(wxString& str) const
747{
af717fa8 748 str = m_value;
cab1a605 749 return true;
341287bf
JS
750}
751
38830220 752#if wxUSE_STD_IOSTREAM
dd107c50 753bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
341287bf 754{
223d09f6 755 wxFAIL_MSG(wxT("Unimplemented"));
07502d73 756
cab1a605 757 return false;
341287bf 758}
38830220 759#endif
341287bf 760
e02afc7a 761#if wxUSE_STREAMS
1ccbb61a
VZ
762bool wxVariantDataChar::Write(wxOutputStream& str) const
763{
fae05df5
GL
764 wxTextOutputStream s(str);
765
af717fa8
VS
766 // FIXME-UTF8: this should be just "s << m_value;" after removal of
767 // ANSI build and addition of wxUniChar to wxTextOutputStream:
768 s << (wxChar)m_value;
07502d73 769
cab1a605 770 return true;
1ccbb61a
VZ
771}
772
75ed1d15
GL
773bool wxVariantDataChar::Read(wxInputStream& str)
774{
fae05df5
GL
775 wxTextInputStream s(str);
776
af717fa8
VS
777 // FIXME-UTF8: this should be just "s >> m_value;" after removal of
778 // ANSI build and addition of wxUniChar to wxTextInputStream:
779 wxChar ch;
780 s >> ch;
781 m_value = ch;
71520754 782
cab1a605 783 return true;
75ed1d15 784}
e02afc7a 785#endif // wxUSE_STREAMS
75ed1d15 786
341287bf
JS
787bool wxVariantDataChar::Read(wxString& str)
788{
af717fa8 789 m_value = str[0u];
cab1a605 790 return true;
341287bf
JS
791}
792
af717fa8 793wxVariant::wxVariant(const wxUniChar& val, const wxString& name)
2562c823 794{
cf25a599 795 m_refData = new wxVariantDataChar(val);
2562c823
RR
796 m_name = name;
797}
798
af717fa8 799wxVariant::wxVariant(char val, const wxString& name)
2562c823 800{
cf25a599 801 m_refData = new wxVariantDataChar(val);
af717fa8
VS
802 m_name = name;
803}
804
805wxVariant::wxVariant(wchar_t val, const wxString& name)
806{
cf25a599 807 m_refData = new wxVariantDataChar(val);
af717fa8
VS
808 m_name = name;
809}
810
811bool wxVariant::operator==(const wxUniChar& value) const
812{
813 wxUniChar thisValue;
2562c823
RR
814 if (!Convert(&thisValue))
815 return false;
816 else
817 return (value == thisValue);
818}
819
af717fa8 820wxVariant& wxVariant::operator=(const wxUniChar& value)
2562c823
RR
821{
822 if (GetType() == wxT("char") &&
cf25a599 823 m_refData->GetRefCount() == 1)
2562c823
RR
824 {
825 ((wxVariantDataChar*)GetData())->SetValue(value);
826 }
827 else
828 {
829 UnRef();
cf25a599 830 m_refData = new wxVariantDataChar(value);
2562c823 831 }
af717fa8
VS
832
833 return *this;
2562c823
RR
834}
835
af717fa8 836wxUniChar wxVariant::GetChar() const
2562c823 837{
af717fa8 838 wxUniChar value;
2562c823
RR
839 if (Convert(& value))
840 return value;
841 else
842 {
843 wxFAIL_MSG(wxT("Could not convert to a char"));
af717fa8 844 return wxUniChar(0);
2562c823
RR
845 }
846}
847
848// ----------------------------------------------------------------------------
849// wxVariantDataString
850// ----------------------------------------------------------------------------
341287bf 851
fd242375 852class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
341287bf 853{
341287bf
JS
854public:
855 wxVariantDataString() { }
856 wxVariantDataString(const wxString& value) { m_value = value; }
857
858 inline wxString GetValue() const { return m_value; }
859 inline void SetValue(const wxString& value) { m_value = value; }
860
341287bf 861 virtual bool Eq(wxVariantData& data) const;
38830220 862#if wxUSE_STD_IOSTREAM
dd107c50 863 virtual bool Write(wxSTD ostream& str) const;
38830220 864#endif
1ccbb61a 865 virtual bool Read(wxString& str);
341287bf 866 virtual bool Write(wxString& str) const;
38830220 867#if wxUSE_STD_IOSTREAM
47b378bd 868 virtual bool Read(wxSTD istream& WXUNUSED(str)) { return false; }
38830220 869#endif
e02afc7a 870#if wxUSE_STREAMS
75ed1d15 871 virtual bool Read(wxInputStream& str);
1ccbb61a 872 virtual bool Write(wxOutputStream& str) const;
e02afc7a 873#endif // wxUSE_STREAMS
47b378bd 874 virtual wxString GetType() const { return wxT("string"); }
c8058a09 875 wxVariantData* Clone() const { return new wxVariantDataString(m_value); }
341287bf 876
0bf14ab8 877 DECLARE_WXANY_CONVERSION()
341287bf
JS
878protected:
879 wxString m_value;
880};
881
0bf14ab8
JS
882IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxString, wxVariantDataString)
883
153107b4
JS
884#if wxUSE_ANY
885// This allows converting string literal wxAnys to string variants
886wxVariantData* wxVariantDataFromConstCharPAny(const wxAny& any)
887{
888 return new wxVariantDataString(wxANY_AS(any, const char*));
889}
890
891wxVariantData* wxVariantDataFromConstWchar_tPAny(const wxAny& any)
892{
893 return new wxVariantDataString(wxANY_AS(any, const wchar_t*));
894}
895
896_REGISTER_WXANY_CONVERSION(const char*,
897 ConstCharP,
898 wxVariantDataFromConstCharPAny)
899_REGISTER_WXANY_CONVERSION(const wchar_t*,
900 ConstWchar_tP,
901 wxVariantDataFromConstWchar_tPAny)
902#endif
903
341287bf
JS
904bool wxVariantDataString::Eq(wxVariantData& data) const
905{
223d09f6 906 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
341287bf
JS
907
908 wxVariantDataString& otherData = (wxVariantDataString&) data;
909
910 return (otherData.m_value == m_value);
911}
912
38830220 913#if wxUSE_STD_IOSTREAM
dd107c50 914bool wxVariantDataString::Write(wxSTD ostream& str) const
341287bf 915{
783b6cfd 916 str << (const char*) m_value.mb_str();
cab1a605 917 return true;
341287bf 918}
38830220 919#endif
341287bf
JS
920
921bool wxVariantDataString::Write(wxString& str) const
922{
923 str = m_value;
cab1a605 924 return true;
341287bf
JS
925}
926
e02afc7a 927#if wxUSE_STREAMS
1ccbb61a
VZ
928bool wxVariantDataString::Write(wxOutputStream& str) const
929{
783b6cfd 930 // why doesn't wxOutputStream::operator<< take "const wxString&"
fae05df5
GL
931 wxTextOutputStream s(str);
932 s.WriteString(m_value);
cab1a605 933 return true;
1ccbb61a
VZ
934}
935
75ed1d15
GL
936bool wxVariantDataString::Read(wxInputStream& str)
937{
fae05df5
GL
938 wxTextInputStream s(str);
939
40ff126a 940 m_value = s.ReadLine();
cab1a605 941 return true;
75ed1d15 942}
e02afc7a 943#endif // wxUSE_STREAMS
75ed1d15 944
341287bf
JS
945bool wxVariantDataString::Read(wxString& str)
946{
947 m_value = str;
cab1a605 948 return true;
341287bf
JS
949}
950
2562c823 951// wxVariant ****
07502d73 952
2562c823 953wxVariant::wxVariant(const wxString& val, const wxString& name)
a0a302dc 954{
cf25a599 955 m_refData = new wxVariantDataString(val);
2562c823
RR
956 m_name = name;
957}
a0a302dc 958
af717fa8
VS
959wxVariant::wxVariant(const char* val, const wxString& name)
960{
cf25a599 961 m_refData = new wxVariantDataString(wxString(val));
af717fa8
VS
962 m_name = name;
963}
964
965wxVariant::wxVariant(const wchar_t* val, const wxString& name)
966{
cf25a599 967 m_refData = new wxVariantDataString(wxString(val));
af717fa8
VS
968 m_name = name;
969}
970
971wxVariant::wxVariant(const wxCStrData& val, const wxString& name)
972{
cf25a599 973 m_refData = new wxVariantDataString(val.AsString());
af717fa8
VS
974 m_name = name;
975}
976
de4983f3 977wxVariant::wxVariant(const wxScopedCharBuffer& val, const wxString& name)
af717fa8 978{
cf25a599 979 m_refData = new wxVariantDataString(wxString(val));
af717fa8
VS
980 m_name = name;
981}
982
de4983f3 983wxVariant::wxVariant(const wxScopedWCharBuffer& val, const wxString& name)
a0a302dc 984{
cf25a599 985 m_refData = new wxVariantDataString(wxString(val));
2562c823
RR
986 m_name = name;
987}
a0a302dc 988
28144838
VS
989#if wxUSE_STD_STRING
990wxVariant::wxVariant(const std::string& val, const wxString& name)
991{
992 m_refData = new wxVariantDataString(wxString(val));
993 m_name = name;
994}
995
996wxVariant::wxVariant(const wxStdWideString& val, const wxString& name)
997{
998 m_refData = new wxVariantDataString(wxString(val));
999 m_name = name;
1000}
1001#endif // wxUSE_STD_STRING
1002
2562c823
RR
1003bool wxVariant::operator== (const wxString& value) const
1004{
1005 wxString thisValue;
1006 if (!Convert(&thisValue))
1007 return false;
a0a302dc 1008
2562c823 1009 return value == thisValue;
a0a302dc
JS
1010}
1011
2562c823 1012bool wxVariant::operator!= (const wxString& value) const
a0a302dc 1013{
2562c823 1014 return (!((*this) == value));
a0a302dc
JS
1015}
1016
af717fa8 1017wxVariant& wxVariant::operator= (const wxString& value)
a0a302dc 1018{
2562c823 1019 if (GetType() == wxT("string") &&
cf25a599 1020 m_refData->GetRefCount() == 1)
2562c823
RR
1021 {
1022 ((wxVariantDataString*)GetData())->SetValue(value);
1023 }
1024 else
1025 {
1026 UnRef();
cf25a599 1027 m_refData = new wxVariantDataString(value);
2562c823 1028 }
af717fa8 1029 return *this;
a0a302dc
JS
1030}
1031
2562c823 1032wxString wxVariant::GetString() const
a0a302dc 1033{
2562c823
RR
1034 wxString value;
1035 if (!Convert(& value))
1036 {
1037 wxFAIL_MSG(wxT("Could not convert to a string"));
1038 }
a0a302dc 1039
2562c823 1040 return value;
a0a302dc
JS
1041}
1042
2562c823
RR
1043// ----------------------------------------------------------------------------
1044// wxVariantDataWxObjectPtr
1045// ----------------------------------------------------------------------------
cf6ae290
RG
1046
1047class wxVariantDataWxObjectPtr: public wxVariantData
1048{
cf6ae290
RG
1049public:
1050 wxVariantDataWxObjectPtr() { }
1051 wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
1052
1053 inline wxObject* GetValue() const { return m_value; }
1054 inline void SetValue(wxObject* value) { m_value = value; }
1055
cf6ae290
RG
1056 virtual bool Eq(wxVariantData& data) const;
1057#if wxUSE_STD_IOSTREAM
1058 virtual bool Write(wxSTD ostream& str) const;
1059#endif
1060 virtual bool Write(wxString& str) const;
1061#if wxUSE_STD_IOSTREAM
1062 virtual bool Read(wxSTD istream& str);
1063#endif
1064 virtual bool Read(wxString& str);
1065 virtual wxString GetType() const ;
c8058a09 1066 virtual wxVariantData* Clone() const { return new wxVariantDataWxObjectPtr(m_value); }
cf6ae290 1067
3586d10f 1068 virtual wxClassInfo* GetValueClassInfo();
c8058a09 1069
0bf14ab8 1070 DECLARE_WXANY_CONVERSION()
cf6ae290
RG
1071protected:
1072 wxObject* m_value;
cf6ae290
RG
1073};
1074
0bf14ab8
JS
1075IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxObject*, wxVariantDataWxObjectPtr)
1076
cf6ae290
RG
1077bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
1078{
3586d10f 1079 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
cf6ae290
RG
1080
1081 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
1082
1083 return (otherData.m_value == m_value);
1084}
1085
1086wxString wxVariantDataWxObjectPtr::GetType() const
1087{
3586d10f 1088 wxString returnVal(wxT("wxObject*"));
c8058a09 1089
3586d10f
RR
1090 if (m_value)
1091 {
cf6ae290 1092 returnVal = m_value->GetClassInfo()->GetClassName();
3586d10f 1093 returnVal += wxT("*");
cf6ae290 1094 }
c8058a09 1095
cf6ae290
RG
1096 return returnVal;
1097}
1098
1099wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
1100{
1101 wxClassInfo* returnVal=NULL;
cab1a605
WS
1102
1103 if (m_value) returnVal = m_value->GetClassInfo();
cf6ae290
RG
1104
1105 return returnVal;
1106}
1107
1108#if wxUSE_STD_IOSTREAM
1109bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
1110{
1111 wxString s;
1112 Write(s);
1113 str << (const char*) s.mb_str();
cab1a605 1114 return true;
cf6ae290
RG
1115}
1116#endif
1117
1118bool wxVariantDataWxObjectPtr::Write(wxString& str) const
1119{
5c33522f 1120 str.Printf(wxT("%s(%p)"), GetType().c_str(), static_cast<void*>(m_value));
cab1a605 1121 return true;
cf6ae290
RG
1122}
1123
1124#if wxUSE_STD_IOSTREAM
1125bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1126{
1127 // Not implemented
cab1a605 1128 return false;
cf6ae290
RG
1129}
1130#endif
1131
1132bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1133{
1134 // Not implemented
cab1a605 1135 return false;
cf6ae290
RG
1136}
1137
2562c823 1138// wxVariant
cf6ae290 1139
2562c823
RR
1140wxVariant::wxVariant( wxObject* val, const wxString& name)
1141{
cf25a599 1142 m_refData = new wxVariantDataWxObjectPtr(val);
2562c823
RR
1143 m_name = name;
1144}
edca7a82 1145
2562c823
RR
1146bool wxVariant::operator== (wxObject* value) const
1147{
1148 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1149}
e2b87f38 1150
2562c823 1151bool wxVariant::operator!= (wxObject* value) const
edca7a82 1152{
2562c823
RR
1153 return (!((*this) == (wxObject*) value));
1154}
1155
1156void wxVariant::operator= (wxObject* value)
1157{
1158 UnRef();
cf25a599 1159 m_refData = new wxVariantDataWxObjectPtr(value);
2562c823 1160}
edca7a82 1161
2562c823
RR
1162wxObject* wxVariant::GetWxObjectPtr() const
1163{
cf25a599 1164 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_refData)->GetValue();
2562c823
RR
1165}
1166
1167// ----------------------------------------------------------------------------
1168// wxVariantDataVoidPtr
1169// ----------------------------------------------------------------------------
1170
1171class wxVariantDataVoidPtr: public wxVariantData
1172{
edca7a82 1173public:
2562c823
RR
1174 wxVariantDataVoidPtr() { }
1175 wxVariantDataVoidPtr(void* value) { m_value = value; }
edca7a82 1176
2562c823
RR
1177 inline void* GetValue() const { return m_value; }
1178 inline void SetValue(void* value) { m_value = value; }
edca7a82 1179
edca7a82
GT
1180 virtual bool Eq(wxVariantData& data) const;
1181#if wxUSE_STD_IOSTREAM
2b004197 1182 virtual bool Write(wxSTD ostream& str) const;
edca7a82
GT
1183#endif
1184 virtual bool Write(wxString& str) const;
1185#if wxUSE_STD_IOSTREAM
2b004197 1186 virtual bool Read(wxSTD istream& str);
edca7a82
GT
1187#endif
1188 virtual bool Read(wxString& str);
47b378bd 1189 virtual wxString GetType() const { return wxT("void*"); }
c8058a09 1190 virtual wxVariantData* Clone() const { return new wxVariantDataVoidPtr(m_value); }
edca7a82 1191
0bf14ab8 1192 DECLARE_WXANY_CONVERSION()
edca7a82 1193protected:
2562c823 1194 void* m_value;
2562c823 1195};
edca7a82 1196
0bf14ab8
JS
1197IMPLEMENT_TRIVIAL_WXANY_CONVERSION(void*, wxVariantDataVoidPtr)
1198
2562c823 1199bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
edca7a82 1200{
3586d10f 1201 wxASSERT_MSG( data.GetType() == wxT("void*"), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
edca7a82 1202
2562c823 1203 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
edca7a82 1204
2562c823 1205 return (otherData.m_value == m_value);
edca7a82
GT
1206}
1207
2562c823
RR
1208#if wxUSE_STD_IOSTREAM
1209bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
edca7a82 1210{
2562c823
RR
1211 wxString s;
1212 Write(s);
1213 str << (const char*) s.mb_str();
1214 return true;
edca7a82 1215}
2562c823 1216#endif
edca7a82 1217
2562c823
RR
1218bool wxVariantDataVoidPtr::Write(wxString& str) const
1219{
1220 str.Printf(wxT("%p"), m_value);
1221 return true;
1222}
edca7a82
GT
1223
1224#if wxUSE_STD_IOSTREAM
2562c823 1225bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
edca7a82
GT
1226{
1227 // Not implemented
cab1a605 1228 return false;
edca7a82
GT
1229}
1230#endif
1231
2562c823 1232bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
edca7a82 1233{
2562c823
RR
1234 // Not implemented
1235 return false;
edca7a82
GT
1236}
1237
2562c823 1238// wxVariant
edca7a82 1239
2562c823 1240wxVariant::wxVariant( void* val, const wxString& name)
edca7a82 1241{
cf25a599 1242 m_refData = new wxVariantDataVoidPtr(val);
2562c823
RR
1243 m_name = name;
1244}
1245
1246bool wxVariant::operator== (void* value) const
1247{
1248 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
edca7a82 1249}
edca7a82 1250
2562c823
RR
1251bool wxVariant::operator!= (void* value) const
1252{
1253 return (!((*this) == (void*) value));
1254}
edca7a82 1255
2562c823 1256void wxVariant::operator= (void* value)
edca7a82 1257{
cf25a599 1258 if (GetType() == wxT("void*") && (m_refData->GetRefCount() == 1))
2562c823
RR
1259 {
1260 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1261 }
1262 else
1263 {
1264 UnRef();
cf25a599 1265 m_refData = new wxVariantDataVoidPtr(value);
2562c823 1266 }
edca7a82
GT
1267}
1268
2562c823
RR
1269void* wxVariant::GetVoidPtr() const
1270{
d099c754
VZ
1271 // handling this specially is convenient when working with COM, see #9873
1272 if ( IsNull() )
1273 return NULL;
1274
1275 wxASSERT( GetType() == wxT("void*") );
2562c823 1276
cf25a599 1277 return (void*) ((wxVariantDataVoidPtr*) m_refData)->GetValue();
2562c823 1278}
e2b87f38 1279
fb42d7c3 1280// ----------------------------------------------------------------------------
2562c823 1281// wxVariantDataDateTime
fb42d7c3
VZ
1282// ----------------------------------------------------------------------------
1283
2562c823
RR
1284#if wxUSE_DATETIME
1285
1286class wxVariantDataDateTime: public wxVariantData
fb42d7c3
VZ
1287{
1288public:
2562c823
RR
1289 wxVariantDataDateTime() { }
1290 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
fb42d7c3 1291
2562c823
RR
1292 inline wxDateTime GetValue() const { return m_value; }
1293 inline void SetValue(const wxDateTime& value) { m_value = value; }
fb42d7c3 1294
fb42d7c3
VZ
1295 virtual bool Eq(wxVariantData& data) const;
1296#if wxUSE_STD_IOSTREAM
1297 virtual bool Write(wxSTD ostream& str) const;
1298#endif
1299 virtual bool Write(wxString& str) const;
1300#if wxUSE_STD_IOSTREAM
1301 virtual bool Read(wxSTD istream& str);
1302#endif
1303 virtual bool Read(wxString& str);
47b378bd 1304 virtual wxString GetType() const { return wxT("datetime"); }
c8058a09 1305 virtual wxVariantData* Clone() const { return new wxVariantDataDateTime(m_value); }
fb42d7c3 1306
0bf14ab8 1307 DECLARE_WXANY_CONVERSION()
fb42d7c3 1308protected:
2562c823 1309 wxDateTime m_value;
fb42d7c3
VZ
1310};
1311
0bf14ab8 1312IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxDateTime, wxVariantDataDateTime)
fb42d7c3 1313
2562c823 1314bool wxVariantDataDateTime::Eq(wxVariantData& data) const
fb42d7c3 1315{
2562c823 1316 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
fb42d7c3 1317
2562c823 1318 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
fb42d7c3 1319
2562c823 1320 return (otherData.m_value == m_value);
fb42d7c3
VZ
1321}
1322
1323
1324#if wxUSE_STD_IOSTREAM
2562c823 1325bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
fb42d7c3 1326{
2562c823
RR
1327 wxString value;
1328 Write( value );
1329 str << value.c_str();
1330 return true;
fb42d7c3
VZ
1331}
1332#endif
1333
1334
2562c823 1335bool wxVariantDataDateTime::Write(wxString& str) const
fb42d7c3 1336{
be53e8ae
JS
1337 if ( m_value.IsValid() )
1338 str = m_value.Format();
1339 else
1340 str = wxS("Invalid");
cab1a605 1341 return true;
fb42d7c3
VZ
1342}
1343
1344
1345#if wxUSE_STD_IOSTREAM
2562c823 1346bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
fb42d7c3
VZ
1347{
1348 // Not implemented
cab1a605 1349 return false;
fb42d7c3
VZ
1350}
1351#endif
1352
1353
2562c823 1354bool wxVariantDataDateTime::Read(wxString& str)
fb42d7c3 1355{
be53e8ae
JS
1356 if ( str == wxS("Invalid") )
1357 {
1358 m_value = wxInvalidDateTime;
1359 return true;
1360 }
1361
c398434d
VZ
1362 wxString::const_iterator end;
1363 return m_value.ParseDateTime(str, &end) && end == str.end();
fb42d7c3
VZ
1364}
1365
2562c823 1366// wxVariant
fb42d7c3 1367
ff818ab8
RG
1368wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1369{
cf25a599 1370 m_refData = new wxVariantDataDateTime(val);
cab1a605 1371 m_name = name;
ff818ab8 1372}
ff818ab8 1373
2562c823 1374bool wxVariant::operator== (const wxDateTime& value) const
fb42d7c3 1375{
2562c823
RR
1376 wxDateTime thisValue;
1377 if (!Convert(&thisValue))
1378 return false;
1379
1380 return value.IsEqualTo(thisValue);
fb42d7c3 1381}
edca7a82 1382
2562c823 1383bool wxVariant::operator!= (const wxDateTime& value) const
341287bf 1384{
2562c823
RR
1385 return (!((*this) == value));
1386}
1387
1388void wxVariant::operator= (const wxDateTime& value)
1389{
1390 if (GetType() == wxT("datetime") &&
cf25a599 1391 m_refData->GetRefCount() == 1)
341287bf 1392 {
2562c823 1393 ((wxVariantDataDateTime*)GetData())->SetValue(value);
341287bf 1394 }
4fabb575 1395 else
2562c823
RR
1396 {
1397 UnRef();
cf25a599 1398 m_refData = new wxVariantDataDateTime(value);
2562c823 1399 }
341287bf
JS
1400}
1401
2562c823
RR
1402wxDateTime wxVariant::GetDateTime() const
1403{
1404 wxDateTime value;
1405 if (!Convert(& value))
341287bf 1406 {
2562c823 1407 wxFAIL_MSG(wxT("Could not convert to a datetime"));
341287bf 1408 }
3d8daa0f 1409
2562c823 1410 return value;
341287bf
JS
1411}
1412
2562c823 1413#endif // wxUSE_DATETIME
341287bf 1414
2562c823
RR
1415// ----------------------------------------------------------------------------
1416// wxVariantDataArrayString
1417// ----------------------------------------------------------------------------
1418
1419class wxVariantDataArrayString: public wxVariantData
341287bf 1420{
2562c823
RR
1421public:
1422 wxVariantDataArrayString() { }
1423 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
341287bf 1424
2562c823
RR
1425 wxArrayString GetValue() const { return m_value; }
1426 void SetValue(const wxArrayString& value) { m_value = value; }
341287bf 1427
2562c823
RR
1428 virtual bool Eq(wxVariantData& data) const;
1429#if wxUSE_STD_IOSTREAM
1430 virtual bool Write(wxSTD ostream& str) const;
1431#endif
1432 virtual bool Write(wxString& str) const;
1433#if wxUSE_STD_IOSTREAM
1434 virtual bool Read(wxSTD istream& str);
1435#endif
1436 virtual bool Read(wxString& str);
47b378bd 1437 virtual wxString GetType() const { return wxT("arrstring"); }
c8058a09 1438 virtual wxVariantData* Clone() const { return new wxVariantDataArrayString(m_value); }
341287bf 1439
0bf14ab8 1440 DECLARE_WXANY_CONVERSION()
2562c823
RR
1441protected:
1442 wxArrayString m_value;
2562c823 1443};
bc14c8b2 1444
0bf14ab8
JS
1445IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxArrayString, wxVariantDataArrayString)
1446
2562c823 1447bool wxVariantDataArrayString::Eq(wxVariantData& data) const
341287bf 1448{
2562c823 1449 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
341287bf 1450
2562c823 1451 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
341287bf 1452
2562c823 1453 return otherData.m_value == m_value;
341287bf
JS
1454}
1455
2562c823
RR
1456#if wxUSE_STD_IOSTREAM
1457bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
341287bf 1458{
2562c823
RR
1459 // Not implemented
1460 return false;
341287bf 1461}
2562c823 1462#endif
341287bf 1463
2562c823 1464bool wxVariantDataArrayString::Write(wxString& str) const
341287bf 1465{
2562c823
RR
1466 size_t count = m_value.GetCount();
1467 for ( size_t n = 0; n < count; n++ )
341287bf 1468 {
2562c823 1469 if ( n )
9a83f860 1470 str += wxT(';');
2562c823
RR
1471
1472 str += m_value[n];
341287bf 1473 }
341287bf 1474
2562c823 1475 return true;
341287bf
JS
1476}
1477
2562c823
RR
1478
1479#if wxUSE_STD_IOSTREAM
1480bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
341287bf 1481{
2562c823
RR
1482 // Not implemented
1483 return false;
341287bf 1484}
2562c823 1485#endif
341287bf 1486
2562c823
RR
1487
1488bool wxVariantDataArrayString::Read(wxString& str)
341287bf 1489{
9a83f860 1490 wxStringTokenizer tk(str, wxT(";"));
2562c823 1491 while ( tk.HasMoreTokens() )
341287bf 1492 {
2562c823 1493 m_value.Add(tk.GetNextToken());
341287bf 1494 }
341287bf 1495
2562c823 1496 return true;
341287bf
JS
1497}
1498
2562c823
RR
1499// wxVariant
1500
1501wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1502{
cf25a599 1503 m_refData = new wxVariantDataArrayString(val);
2562c823 1504 m_name = name;
341287bf
JS
1505}
1506
2562c823 1507bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
341287bf 1508{
9a83f860 1509 wxFAIL_MSG( wxT("TODO") );
f6bcfd97 1510
2562c823 1511 return false;
341287bf
JS
1512}
1513
2562c823 1514bool wxVariant::operator!=(const wxArrayString& value) const
341287bf 1515{
2562c823 1516 return !(*this == value);
341287bf
JS
1517}
1518
2562c823 1519void wxVariant::operator=(const wxArrayString& value)
341287bf 1520{
2562c823 1521 if (GetType() == wxT("arrstring") &&
cf25a599 1522 m_refData->GetRefCount() == 1)
341287bf 1523 {
2562c823 1524 ((wxVariantDataArrayString *)GetData())->SetValue(value);
341287bf
JS
1525 }
1526 else
1527 {
2562c823 1528 UnRef();
cf25a599 1529 m_refData = new wxVariantDataArrayString(value);
341287bf
JS
1530 }
1531}
1532
2562c823 1533wxArrayString wxVariant::GetArrayString() const
341287bf 1534{
2562c823
RR
1535 if ( GetType() == wxT("arrstring") )
1536 return ((wxVariantDataArrayString *)GetData())->GetValue();
1537
1538 return wxArrayString();
341287bf
JS
1539}
1540
4e00b908
JS
1541// ----------------------------------------------------------------------------
1542// wxVariantDataLongLong
1543// ----------------------------------------------------------------------------
1544
1545#if wxUSE_LONGLONG
1546
1547class WXDLLIMPEXP_BASE wxVariantDataLongLong : public wxVariantData
1548{
1549public:
1550 wxVariantDataLongLong() { m_value = 0; }
1551 wxVariantDataLongLong(wxLongLong value) { m_value = value; }
1552
1553 wxLongLong GetValue() const { return m_value; }
1554 void SetValue(wxLongLong value) { m_value = value; }
1555
1556 virtual bool Eq(wxVariantData& data) const;
1557
1558 virtual bool Read(wxString& str);
1559 virtual bool Write(wxString& str) const;
1560#if wxUSE_STD_IOSTREAM
1561 virtual bool Read(wxSTD istream& str);
1562 virtual bool Write(wxSTD ostream& str) const;
1563#endif
1564#if wxUSE_STREAMS
1565 virtual bool Read(wxInputStream& str);
1566 virtual bool Write(wxOutputStream &str) const;
1567#endif // wxUSE_STREAMS
1568
1569 wxVariantData* Clone() const
1570 {
1571 return new wxVariantDataLongLong(m_value);
1572 }
1573
1574 virtual wxString GetType() const { return wxS("longlong"); }
1575
0bf14ab8 1576 DECLARE_WXANY_CONVERSION()
4e00b908
JS
1577protected:
1578 wxLongLong m_value;
1579};
1580
0bf14ab8
JS
1581//
1582// wxLongLong type requires customized wxAny conversion code
1583//
1584#if wxUSE_ANY
1585#ifdef wxLongLong_t
1586
1587bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
1588{
1589 *any = m_value.GetValue();
1590 return true;
1591}
1592
1593wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
1594{
1595 return new wxVariantDataLongLong(wxANY_AS(any, wxLongLong_t));
1596}
1597
1598REGISTER_WXANY_CONVERSION(wxLongLong_t, wxVariantDataLongLong)
1599
1600#else // if !defined(wxLongLong_t)
1601
1602bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
1603{
1604 *any = m_value;
1605 return true;
1606}
1607
1608wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
1609{
1610 return new wxVariantDataLongLong(wxANY_AS(any, wxLongLong));
1611}
1612
1613REGISTER_WXANY_CONVERSION(wxLongLong, wxVariantDataLongLong)
1614
1615#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
1616#endif // wxUSE_ANY
1617
4e00b908
JS
1618bool wxVariantDataLongLong::Eq(wxVariantData& data) const
1619{
03647350 1620 wxASSERT_MSG( (data.GetType() == wxS("longlong")),
4e00b908
JS
1621 "wxVariantDataLongLong::Eq: argument mismatch" );
1622
1623 wxVariantDataLongLong& otherData = (wxVariantDataLongLong&) data;
1624
1625 return (otherData.m_value == m_value);
1626}
1627
1628#if wxUSE_STD_IOSTREAM
1629bool wxVariantDataLongLong::Write(wxSTD ostream& str) const
1630{
1631 wxString s;
1632 Write(s);
1633 str << (const char*) s.mb_str();
1634 return true;
1635}
1636#endif
1637
1638bool wxVariantDataLongLong::Write(wxString& str) const
1639{
f81bd288
JS
1640#ifdef wxLongLong_t
1641 str.Printf(wxS("%lld"), m_value.GetValue());
4e00b908 1642 return true;
f81bd288
JS
1643#else
1644 return false;
1645#endif
4e00b908
JS
1646}
1647
1648#if wxUSE_STD_IOSTREAM
1649bool wxVariantDataLongLong::Read(wxSTD istream& WXUNUSED(str))
1650{
1651 wxFAIL_MSG(wxS("Unimplemented"));
1652 return false;
1653}
1654#endif
1655
1656#if wxUSE_STREAMS
1657bool wxVariantDataLongLong::Write(wxOutputStream& str) const
1658{
1659 wxTextOutputStream s(str);
1660 s.Write32(m_value.GetLo());
1661 s.Write32(m_value.GetHi());
1662 return true;
1663}
1664
1665bool wxVariantDataLongLong::Read(wxInputStream& str)
1666{
1667 wxTextInputStream s(str);
1668 unsigned long lo = s.Read32();
1669 long hi = s.Read32();
1670 m_value = wxLongLong(hi, lo);
1671 return true;
1672}
1673#endif // wxUSE_STREAMS
1674
1675bool wxVariantDataLongLong::Read(wxString& str)
1676{
1677#ifdef wxLongLong_t
1678 wxLongLong_t value_t;
1679 if ( !str.ToLongLong(&value_t) )
1680 return false;
1681 m_value = value_t;
1682 return true;
1683#else
1684 return false;
1685#endif
1686}
1687
1688// wxVariant
1689
1690wxVariant::wxVariant(wxLongLong val, const wxString& name)
1691{
1692 m_refData = new wxVariantDataLongLong(val);
1693 m_name = name;
1694}
1695
1696bool wxVariant::operator==(wxLongLong value) const
1697{
1698 wxLongLong thisValue;
1699 if ( !Convert(&thisValue) )
1700 return false;
1701 else
1702 return (value == thisValue);
1703}
1704
1705bool wxVariant::operator!=(wxLongLong value) const
1706{
1707 return (!((*this) == value));
1708}
1709
1710void wxVariant::operator=(wxLongLong value)
1711{
1712 if ( GetType() == wxS("longlong") &&
1713 m_refData->GetRefCount() == 1 )
1714 {
1715 ((wxVariantDataLongLong*)GetData())->SetValue(value);
1716 }
1717 else
1718 {
1719 UnRef();
1720 m_refData = new wxVariantDataLongLong(value);
1721 }
1722}
1723
1724wxLongLong wxVariant::GetLongLong() const
1725{
1726 wxLongLong value;
1727 if ( Convert(&value) )
1728 {
1729 return value;
1730 }
1731 else
1732 {
1733 wxFAIL_MSG(wxT("Could not convert to a long long"));
1734 return 0;
1735 }
1736}
1737
1738#endif // wxUSE_LONGLONG
1739
1740// ----------------------------------------------------------------------------
1741// wxVariantDataULongLong
1742// ----------------------------------------------------------------------------
1743
1744#if wxUSE_LONGLONG
1745
1746class WXDLLIMPEXP_BASE wxVariantDataULongLong : public wxVariantData
1747{
1748public:
1749 wxVariantDataULongLong() { m_value = 0; }
1750 wxVariantDataULongLong(wxULongLong value) { m_value = value; }
1751
1752 wxULongLong GetValue() const { return m_value; }
1753 void SetValue(wxULongLong value) { m_value = value; }
1754
1755 virtual bool Eq(wxVariantData& data) const;
1756
1757 virtual bool Read(wxString& str);
1758 virtual bool Write(wxString& str) const;
1759#if wxUSE_STD_IOSTREAM
1760 virtual bool Read(wxSTD istream& str);
1761 virtual bool Write(wxSTD ostream& str) const;
1762#endif
1763#if wxUSE_STREAMS
1764 virtual bool Read(wxInputStream& str);
1765 virtual bool Write(wxOutputStream &str) const;
1766#endif // wxUSE_STREAMS
1767
1768 wxVariantData* Clone() const
1769 {
1770 return new wxVariantDataULongLong(m_value);
1771 }
1772
1773 virtual wxString GetType() const { return wxS("ulonglong"); }
1774
0bf14ab8 1775 DECLARE_WXANY_CONVERSION()
4e00b908
JS
1776protected:
1777 wxULongLong m_value;
1778};
1779
0bf14ab8
JS
1780//
1781// wxULongLong type requires customized wxAny conversion code
1782//
1783#if wxUSE_ANY
1784#ifdef wxLongLong_t
1785
1786bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
1787{
1788 *any = m_value.GetValue();
1789 return true;
1790}
1791
1792wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
1793{
1794 return new wxVariantDataULongLong(wxANY_AS(any, wxULongLong_t));
1795}
1796
1797REGISTER_WXANY_CONVERSION(wxULongLong_t, wxVariantDataULongLong)
1798
1799#else // if !defined(wxLongLong_t)
1800
1801bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
1802{
1803 *any = m_value;
1804 return true;
1805}
1806
1807wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
1808{
1809 return new wxVariantDataULongLong(wxANY_AS(any, wxULongLong));
1810}
1811
1812REGISTER_WXANY_CONVERSION(wxULongLong, wxVariantDataULongLong)
1813
1814#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
1815#endif // wxUSE_ANY
1816
1817
4e00b908
JS
1818bool wxVariantDataULongLong::Eq(wxVariantData& data) const
1819{
03647350 1820 wxASSERT_MSG( (data.GetType() == wxS("ulonglong")),
4e00b908
JS
1821 "wxVariantDataULongLong::Eq: argument mismatch" );
1822
1823 wxVariantDataULongLong& otherData = (wxVariantDataULongLong&) data;
1824
1825 return (otherData.m_value == m_value);
1826}
1827
1828#if wxUSE_STD_IOSTREAM
1829bool wxVariantDataULongLong::Write(wxSTD ostream& str) const
1830{
1831 wxString s;
1832 Write(s);
1833 str << (const char*) s.mb_str();
1834 return true;
1835}
1836#endif
1837
1838bool wxVariantDataULongLong::Write(wxString& str) const
1839{
f81bd288
JS
1840#ifdef wxLongLong_t
1841 str.Printf(wxS("%llu"), m_value.GetValue());
4e00b908 1842 return true;
f81bd288
JS
1843#else
1844 return false;
1845#endif
4e00b908
JS
1846}
1847
1848#if wxUSE_STD_IOSTREAM
1849bool wxVariantDataULongLong::Read(wxSTD istream& WXUNUSED(str))
1850{
1851 wxFAIL_MSG(wxS("Unimplemented"));
1852 return false;
1853}
1854#endif
1855
1856#if wxUSE_STREAMS
1857bool wxVariantDataULongLong::Write(wxOutputStream& str) const
1858{
1859 wxTextOutputStream s(str);
1860 s.Write32(m_value.GetLo());
1861 s.Write32(m_value.GetHi());
1862 return true;
1863}
1864
1865bool wxVariantDataULongLong::Read(wxInputStream& str)
1866{
1867 wxTextInputStream s(str);
1868 unsigned long lo = s.Read32();
1869 long hi = s.Read32();
1870 m_value = wxULongLong(hi, lo);
1871 return true;
1872}
1873#endif // wxUSE_STREAMS
1874
1875bool wxVariantDataULongLong::Read(wxString& str)
1876{
1877#ifdef wxLongLong_t
1878 wxULongLong_t value_t;
1879 if ( !str.ToULongLong(&value_t) )
1880 return false;
1881 m_value = value_t;
1882 return true;
1883#else
1884 return false;
1885#endif
1886}
1887
1888// wxVariant
1889
1890wxVariant::wxVariant(wxULongLong val, const wxString& name)
1891{
1892 m_refData = new wxVariantDataULongLong(val);
1893 m_name = name;
1894}
1895
1896bool wxVariant::operator==(wxULongLong value) const
1897{
1898 wxULongLong thisValue;
1899 if ( !Convert(&thisValue) )
1900 return false;
1901 else
1902 return (value == thisValue);
1903}
1904
1905bool wxVariant::operator!=(wxULongLong value) const
1906{
1907 return (!((*this) == value));
1908}
1909
1910void wxVariant::operator=(wxULongLong value)
1911{
1912 if ( GetType() == wxS("ulonglong") &&
1913 m_refData->GetRefCount() == 1 )
1914 {
1915 ((wxVariantDataULongLong*)GetData())->SetValue(value);
1916 }
1917 else
1918 {
1919 UnRef();
1920 m_refData = new wxVariantDataULongLong(value);
1921 }
1922}
1923
1924wxULongLong wxVariant::GetULongLong() const
1925{
1926 wxULongLong value;
1927 if ( Convert(&value) )
1928 {
1929 return value;
1930 }
1931 else
1932 {
1933 wxFAIL_MSG(wxT("Could not convert to a long long"));
1934 return 0;
1935 }
1936}
1937
1938#endif // wxUSE_LONGLONG
1939
2562c823
RR
1940// ----------------------------------------------------------------------------
1941// wxVariantDataList
1942// ----------------------------------------------------------------------------
2c3a1064 1943
2562c823 1944class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
341287bf 1945{
2562c823
RR
1946public:
1947 wxVariantDataList() {}
9a0a58f5 1948 wxVariantDataList(const wxVariantList& list);
2562c823 1949 virtual ~wxVariantDataList();
341287bf 1950
9a0a58f5
RR
1951 wxVariantList& GetValue() { return m_value; }
1952 void SetValue(const wxVariantList& value) ;
341287bf 1953
2562c823
RR
1954 virtual bool Eq(wxVariantData& data) const;
1955#if wxUSE_STD_IOSTREAM
1956 virtual bool Write(wxSTD ostream& str) const;
1957#endif
1958 virtual bool Write(wxString& str) const;
1959#if wxUSE_STD_IOSTREAM
1960 virtual bool Read(wxSTD istream& str);
1961#endif
1962 virtual bool Read(wxString& str);
47b378bd 1963 virtual wxString GetType() const { return wxT("list"); }
52e81242 1964
2562c823 1965 void Clear();
341287bf 1966
c8058a09 1967 wxVariantData* Clone() const { return new wxVariantDataList(m_value); }
0bf14ab8
JS
1968
1969 DECLARE_WXANY_CONVERSION()
2562c823 1970protected:
9a0a58f5 1971 wxVariantList m_value;
2562c823 1972};
341287bf 1973
0bf14ab8
JS
1974#if wxUSE_ANY
1975
1976//
1977// Convert to/from list of wxAnys
1978//
1979
0bf14ab8
JS
1980bool wxVariantDataList::GetAsAny(wxAny* any) const
1981{
1982 wxAnyList dst;
1983 wxVariantList::compatibility_iterator node = m_value.GetFirst();
1984 while (node)
1985 {
1986 wxVariant* pVar = node->GetData();
5ceb0345 1987 dst.push_back(new wxAny(((const wxVariant&)*pVar)));
0bf14ab8
JS
1988 node = node->GetNext();
1989 }
1990
1991 *any = dst;
1992 return true;
1993}
1994
1995wxVariantData* wxVariantDataList::VariantDataFactory(const wxAny& any)
1996{
1997 wxAnyList src = wxANY_AS(any, wxAnyList);
1998 wxVariantList dst;
1999 wxAnyList::compatibility_iterator node = src.GetFirst();
2000 while (node)
2001 {
2002 wxAny* pAny = node->GetData();
2003 dst.push_back(new wxVariant(*pAny));
2004 node = node->GetNext();
2005 }
2006
2007 return new wxVariantDataList(dst);
2008}
2009
2010REGISTER_WXANY_CONVERSION(wxAnyList, wxVariantDataList)
2011
2012#endif // wxUSE_ANY
2013
9a0a58f5 2014wxVariantDataList::wxVariantDataList(const wxVariantList& list)
341287bf 2015{
2562c823 2016 SetValue(list);
341287bf
JS
2017}
2018
2562c823 2019wxVariantDataList::~wxVariantDataList()
341287bf 2020{
2562c823 2021 Clear();
341287bf
JS
2022}
2023
9a0a58f5 2024void wxVariantDataList::SetValue(const wxVariantList& value)
341287bf 2025{
2562c823 2026 Clear();
9a0a58f5 2027 wxVariantList::compatibility_iterator node = value.GetFirst();
2562c823 2028 while (node)
341287bf 2029 {
9a0a58f5 2030 wxVariant* var = node->GetData();
2562c823
RR
2031 m_value.Append(new wxVariant(*var));
2032 node = node->GetNext();
341287bf 2033 }
2562c823
RR
2034}
2035
2036void wxVariantDataList::Clear()
2037{
9a0a58f5 2038 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 2039 while (node)
341287bf 2040 {
9a0a58f5 2041 wxVariant* var = node->GetData();
2562c823
RR
2042 delete var;
2043 node = node->GetNext();
341287bf 2044 }
2562c823 2045 m_value.Clear();
341287bf
JS
2046}
2047
2562c823 2048bool wxVariantDataList::Eq(wxVariantData& data) const
a0a302dc 2049{
2562c823
RR
2050 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
2051
2052 wxVariantDataList& listData = (wxVariantDataList&) data;
9a0a58f5
RR
2053 wxVariantList::compatibility_iterator node1 = m_value.GetFirst();
2054 wxVariantList::compatibility_iterator node2 = listData.GetValue().GetFirst();
2562c823
RR
2055 while (node1 && node2)
2056 {
9a0a58f5
RR
2057 wxVariant* var1 = node1->GetData();
2058 wxVariant* var2 = node2->GetData();
2562c823
RR
2059 if ((*var1) != (*var2))
2060 return false;
2061 node1 = node1->GetNext();
2062 node2 = node2->GetNext();
2063 }
2064 if (node1 || node2) return false;
2065 return true;
a0a302dc
JS
2066}
2067
2562c823
RR
2068#if wxUSE_STD_IOSTREAM
2069bool wxVariantDataList::Write(wxSTD ostream& str) const
a0a302dc 2070{
2562c823
RR
2071 wxString s;
2072 Write(s);
2073 str << (const char*) s.mb_str();
2074 return true;
a0a302dc 2075}
2562c823 2076#endif
a0a302dc 2077
2562c823 2078bool wxVariantDataList::Write(wxString& str) const
a0a302dc 2079{
2562c823 2080 str = wxEmptyString;
9a0a58f5 2081 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 2082 while (node)
a0a302dc 2083 {
9a0a58f5 2084 wxVariant* var = node->GetData();
2562c823
RR
2085 if (node != m_value.GetFirst())
2086 str += wxT(" ");
2087 wxString str1;
2088 str += var->MakeString();
2089 node = node->GetNext();
a0a302dc 2090 }
2562c823
RR
2091
2092 return true;
a0a302dc 2093}
2f620946 2094
2562c823
RR
2095#if wxUSE_STD_IOSTREAM
2096bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
2f620946 2097{
2562c823
RR
2098 wxFAIL_MSG(wxT("Unimplemented"));
2099 // TODO
2100 return false;
2f620946 2101}
2562c823 2102#endif
2f620946 2103
2562c823 2104bool wxVariantDataList::Read(wxString& WXUNUSED(str))
2f620946 2105{
2562c823
RR
2106 wxFAIL_MSG(wxT("Unimplemented"));
2107 // TODO
2108 return false;
2f620946
RR
2109}
2110
2562c823
RR
2111// wxVariant
2112
9a0a58f5 2113wxVariant::wxVariant(const wxVariantList& val, const wxString& name) // List of variants
2f620946 2114{
cf25a599 2115 m_refData = new wxVariantDataList(val);
2562c823 2116 m_name = name;
2f620946 2117}
341287bf 2118
9a0a58f5 2119bool wxVariant::operator== (const wxVariantList& value) const
edca7a82 2120{
2562c823 2121 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
edca7a82 2122
2562c823
RR
2123 wxVariantDataList other(value);
2124 return (GetData()->Eq(other));
edca7a82
GT
2125}
2126
9a0a58f5 2127bool wxVariant::operator!= (const wxVariantList& value) const
edca7a82
GT
2128{
2129 return (!((*this) == value));
2130}
2131
9a0a58f5 2132void wxVariant::operator= (const wxVariantList& value)
edca7a82 2133{
2562c823 2134 if (GetType() == wxT("list") &&
cf25a599 2135 m_refData->GetRefCount() == 1)
edca7a82 2136 {
2562c823 2137 ((wxVariantDataList*)GetData())->SetValue(value);
edca7a82
GT
2138 }
2139 else
2140 {
2562c823 2141 UnRef();
cf25a599 2142 m_refData = new wxVariantDataList(value);
edca7a82
GT
2143 }
2144}
2145
9a0a58f5 2146wxVariantList& wxVariant::GetList() const
edca7a82 2147{
2562c823 2148 wxASSERT( (GetType() == wxT("list")) );
edca7a82 2149
cf25a599 2150 return (wxVariantList&) ((wxVariantDataList*) m_refData)->GetValue();
2562c823 2151}
edca7a82 2152
2562c823
RR
2153// Make empty list
2154void wxVariant::NullList()
edca7a82 2155{
2562c823 2156 SetData(new wxVariantDataList());
edca7a82
GT
2157}
2158
2562c823
RR
2159// Append to list
2160void wxVariant::Append(const wxVariant& value)
edca7a82 2161{
9a0a58f5 2162 wxVariantList& list = GetList();
2562c823
RR
2163
2164 list.Append(new wxVariant(value));
edca7a82
GT
2165}
2166
2562c823
RR
2167// Insert at front of list
2168void wxVariant::Insert(const wxVariant& value)
2169{
9a0a58f5 2170 wxVariantList& list = GetList();
fb42d7c3 2171
2562c823
RR
2172 list.Insert(new wxVariant(value));
2173}
2174
2175// Returns true if the variant is a member of the list
2176bool wxVariant::Member(const wxVariant& value) const
fb42d7c3 2177{
9a0a58f5 2178 wxVariantList& list = GetList();
fb42d7c3 2179
9a0a58f5 2180 wxVariantList::compatibility_iterator node = list.GetFirst();
2562c823
RR
2181 while (node)
2182 {
9a0a58f5 2183 wxVariant* other = node->GetData();
2562c823
RR
2184 if (value == *other)
2185 return true;
2186 node = node->GetNext();
2187 }
cab1a605 2188 return false;
fb42d7c3
VZ
2189}
2190
2562c823
RR
2191// Deletes the nth element of the list
2192bool wxVariant::Delete(size_t item)
fb42d7c3 2193{
9a0a58f5 2194 wxVariantList& list = GetList();
2562c823
RR
2195
2196 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
9a0a58f5
RR
2197 wxVariantList::compatibility_iterator node = list.Item(item);
2198 wxVariant* variant = node->GetData();
2562c823
RR
2199 delete variant;
2200 list.Erase(node);
2201 return true;
fb42d7c3
VZ
2202}
2203
2562c823
RR
2204// Clear list
2205void wxVariant::ClearList()
fb42d7c3 2206{
2562c823 2207 if (!IsNull() && (GetType() == wxT("list")))
fb42d7c3 2208 {
cf25a599 2209 ((wxVariantDataList*) m_refData)->Clear();
fb42d7c3
VZ
2210 }
2211 else
2212 {
2562c823
RR
2213 if (!GetType().IsSameAs(wxT("list")))
2214 UnRef();
fb42d7c3 2215
cf25a599 2216 m_refData = new wxVariantDataList;
2562c823 2217 }
fb42d7c3
VZ
2218}
2219
60acae80
RR
2220// Treat a list variant as an array
2221wxVariant wxVariant::operator[] (size_t idx) const
2222{
60acae80 2223 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
60acae80
RR
2224
2225 if (GetType() == wxT("list"))
2226 {
cf25a599 2227 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80 2228 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
9a0a58f5 2229 return *(data->GetValue().Item(idx)->GetData());
60acae80 2230 }
60acae80
RR
2231 return wxNullVariant;
2232}
2233
2234wxVariant& wxVariant::operator[] (size_t idx)
2235{
2236 // We can't return a reference to a variant for a string list, since the string
2237 // is actually stored as a char*, not a variant.
2238
2239 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
2240
cf25a599 2241 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80
RR
2242 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
2243
9a0a58f5 2244 return * (data->GetValue().Item(idx)->GetData());
60acae80
RR
2245}
2246
2247// Return the number of elements in a list
2248size_t wxVariant::GetCount() const
2249{
60acae80 2250 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
60acae80
RR
2251
2252 if (GetType() == wxT("list"))
2253 {
cf25a599 2254 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80
RR
2255 return data->GetValue().GetCount();
2256 }
60acae80
RR
2257 return 0;
2258}
2259
2562c823 2260// ----------------------------------------------------------------------------
341287bf 2261// Type conversion
2562c823
RR
2262// ----------------------------------------------------------------------------
2263
341287bf
JS
2264bool wxVariant::Convert(long* value) const
2265{
2266 wxString type(GetType());
4e00b908 2267 if (type == wxS("double"))
2562c823 2268 *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
4e00b908 2269 else if (type == wxS("long"))
341287bf 2270 *value = ((wxVariantDataLong*)GetData())->GetValue();
4e00b908 2271 else if (type == wxS("bool"))
341287bf 2272 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
4e00b908 2273 else if (type == wxS("string"))
52de37c7 2274 *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
4e00b908
JS
2275#if wxUSE_LONGLONG
2276 else if (type == wxS("longlong"))
2277 {
2278 wxLongLong v = ((wxVariantDataLongLong*)GetData())->GetValue();
2279 // Don't convert if return value would be vague
2280 if ( v < LONG_MIN || v > LONG_MAX )
2281 return false;
2282 *value = v.ToLong();
2283 }
2284 else if (type == wxS("ulonglong"))
2285 {
2286 wxULongLong v = ((wxVariantDataULongLong*)GetData())->GetValue();
2287 // Don't convert if return value would be vague
2288 if ( v.GetHi() )
2289 return false;
2290 *value = (long) v.ToULong();
2291 }
2292#endif
341287bf 2293 else
cab1a605 2294 return false;
341287bf 2295
cab1a605 2296 return true;
341287bf
JS
2297}
2298
2299bool wxVariant::Convert(bool* value) const
2300{
2301 wxString type(GetType());
223d09f6 2302 if (type == wxT("double"))
2562c823 2303 *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
223d09f6 2304 else if (type == wxT("long"))
341287bf 2305 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
223d09f6 2306 else if (type == wxT("bool"))
341287bf 2307 *value = ((wxVariantDataBool*)GetData())->GetValue();
223d09f6 2308 else if (type == wxT("string"))
341287bf
JS
2309 {
2310 wxString val(((wxVariantDataString*)GetData())->GetValue());
2311 val.MakeLower();
b1638abf 2312 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
cab1a605 2313 *value = true;
b1638abf 2314 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
cab1a605 2315 *value = false;
341287bf 2316 else
cab1a605 2317 return false;
341287bf
JS
2318 }
2319 else
cab1a605 2320 return false;
341287bf 2321
cab1a605 2322 return true;
341287bf
JS
2323}
2324
2325bool wxVariant::Convert(double* value) const
2326{
2327 wxString type(GetType());
223d09f6 2328 if (type == wxT("double"))
2562c823 2329 *value = ((wxVariantDoubleData*)GetData())->GetValue();
223d09f6 2330 else if (type == wxT("long"))
341287bf 2331 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
223d09f6 2332 else if (type == wxT("bool"))
341287bf 2333 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
223d09f6 2334 else if (type == wxT("string"))
52de37c7 2335 *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
4e00b908
JS
2336#if wxUSE_LONGLONG
2337 else if (type == wxS("longlong"))
2338 {
2339 *value = ((wxVariantDataLongLong*)GetData())->GetValue().ToDouble();
2340 }
2341 else if (type == wxS("ulonglong"))
2342 {
2343 *value = ((wxVariantDataULongLong*)GetData())->GetValue().ToDouble();
2344 }
2345#endif
341287bf 2346 else
cab1a605 2347 return false;
341287bf 2348
cab1a605 2349 return true;
341287bf
JS
2350}
2351
af717fa8 2352bool wxVariant::Convert(wxUniChar* value) const
341287bf
JS
2353{
2354 wxString type(GetType());
223d09f6 2355 if (type == wxT("char"))
341287bf 2356 *value = ((wxVariantDataChar*)GetData())->GetValue();
223d09f6 2357 else if (type == wxT("long"))
341287bf 2358 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
223d09f6 2359 else if (type == wxT("bool"))
341287bf 2360 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
15ec7f78
JS
2361 else if (type == wxS("string"))
2362 {
2363 // Also accept strings of length 1
2364 const wxString& str = (((wxVariantDataString*)GetData())->GetValue());
2365 if ( str.length() == 1 )
2366 *value = str[0];
2367 else
2368 return false;
2369 }
341287bf 2370 else
cab1a605 2371 return false;
341287bf 2372
cab1a605 2373 return true;
341287bf
JS
2374}
2375
af717fa8
VS
2376bool wxVariant::Convert(char* value) const
2377{
2378 wxUniChar ch;
2379 if ( !Convert(&ch) )
2380 return false;
2381 *value = ch;
2382 return true;
2383}
2384
2385bool wxVariant::Convert(wchar_t* value) const
2386{
2387 wxUniChar ch;
2388 if ( !Convert(&ch) )
2389 return false;
2390 *value = ch;
2391 return true;
2392}
2393
341287bf
JS
2394bool wxVariant::Convert(wxString* value) const
2395{
2396 *value = MakeString();
cab1a605 2397 return true;
341287bf
JS
2398}
2399
4e00b908
JS
2400#if wxUSE_LONGLONG
2401bool wxVariant::Convert(wxLongLong* value) const
2402{
2403 wxString type(GetType());
2404 if (type == wxS("longlong"))
2405 *value = ((wxVariantDataLongLong*)GetData())->GetValue();
2406 else if (type == wxS("long"))
2407 *value = ((wxVariantDataLong*)GetData())->GetValue();
2408 else if (type == wxS("string"))
2409 {
2410 wxString s = ((wxVariantDataString*)GetData())->GetValue();
2411#ifdef wxLongLong_t
2412 wxLongLong_t value_t;
2413 if ( !s.ToLongLong(&value_t) )
2414 return false;
2415 *value = value_t;
2416#else
2417 long l_value;
2418 if ( !s.ToLong(&l_value) )
2419 return false;
2420 *value = l_value;
2421#endif
2422 }
2423 else if (type == wxS("bool"))
2424 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2425 else if (type == wxS("double"))
2426 {
2427 value->Assign(((wxVariantDoubleData*)GetData())->GetValue());
2428 }
2429 else if (type == wxS("ulonglong"))
2430 *value = ((wxVariantDataULongLong*)GetData())->GetValue();
2431 else
2432 return false;
2433
2434 return true;
2435}
2436
2437bool wxVariant::Convert(wxULongLong* value) const
2438{
2439 wxString type(GetType());
2440 if (type == wxS("ulonglong"))
2441 *value = ((wxVariantDataULongLong*)GetData())->GetValue();
2442 else if (type == wxS("long"))
2443 *value = ((wxVariantDataLong*)GetData())->GetValue();
2444 else if (type == wxS("string"))
2445 {
2446 wxString s = ((wxVariantDataString*)GetData())->GetValue();
2447#ifdef wxLongLong_t
2448 wxULongLong_t value_t;
2449 if ( !s.ToULongLong(&value_t) )
2450 return false;
2451 *value = value_t;
2452#else
2453 unsigned long l_value;
2454 if ( !s.ToULong(&l_value) )
2455 return false;
2456 *value = l_value;
2457#endif
2458 }
2459 else if (type == wxS("bool"))
2460 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2461 else if (type == wxS("double"))
2462 {
2463 double value_d = ((wxVariantDoubleData*)GetData())->GetValue();
2464
2465 if ( value_d < 0.0 )
2466 return false;
2467
2468#ifdef wxLongLong_t
2469 *value = (wxULongLong_t) value_d;
2470#else
2471 wxLongLong temp;
2472 temp.Assign(value_d);
2473 *value = temp;
2474#endif
2475 }
2476 else if (type == wxS("longlong"))
2477 *value = ((wxVariantDataLongLong*)GetData())->GetValue();
2478 else
2479 return false;
2480
2481 return true;
2482}
2483#endif // wxUSE_LONGLONG
2484
e2b87f38 2485#if wxUSE_DATETIME
edca7a82
GT
2486bool wxVariant::Convert(wxDateTime* value) const
2487{
2488 wxString type(GetType());
2489 if (type == wxT("datetime"))
9708db20 2490 {
edca7a82 2491 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
cab1a605 2492 return true;
dc259b79 2493 }
73799292 2494
9708db20
JS
2495 // Fallback to string conversion
2496 wxString val;
73799292
VZ
2497 if ( !Convert(&val) )
2498 return false;
2499
2500 // Try to parse this as either date and time, only date or only time
2501 // checking that the entire string was parsed
2502 wxString::const_iterator end;
2503 if ( value->ParseDateTime(val, &end) && end == val.end() )
2504 return true;
2505
2506 if ( value->ParseDate(val, &end) && end == val.end() )
2507 return true;
2508
2509 if ( value->ParseTime(val, &end) && end == val.end() )
2510 return true;
2511
2512 return false;
edca7a82 2513}
b1e343f2 2514#endif // wxUSE_DATETIME
d5dc103f
VZ
2515
2516#endif // wxUSE_VARIANT