]> git.saurik.com Git - wxWidgets.git/blame - src/common/variant.cpp
Gracefully disconnect clients in wxDDEServer dtor.
[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
2562c823
RR
989bool wxVariant::operator== (const wxString& value) const
990{
991 wxString thisValue;
992 if (!Convert(&thisValue))
993 return false;
a0a302dc 994
2562c823 995 return value == thisValue;
a0a302dc
JS
996}
997
2562c823 998bool wxVariant::operator!= (const wxString& value) const
a0a302dc 999{
2562c823 1000 return (!((*this) == value));
a0a302dc
JS
1001}
1002
af717fa8 1003wxVariant& wxVariant::operator= (const wxString& value)
a0a302dc 1004{
2562c823 1005 if (GetType() == wxT("string") &&
cf25a599 1006 m_refData->GetRefCount() == 1)
2562c823
RR
1007 {
1008 ((wxVariantDataString*)GetData())->SetValue(value);
1009 }
1010 else
1011 {
1012 UnRef();
cf25a599 1013 m_refData = new wxVariantDataString(value);
2562c823 1014 }
af717fa8 1015 return *this;
a0a302dc
JS
1016}
1017
2562c823 1018wxString wxVariant::GetString() const
a0a302dc 1019{
2562c823
RR
1020 wxString value;
1021 if (!Convert(& value))
1022 {
1023 wxFAIL_MSG(wxT("Could not convert to a string"));
1024 }
a0a302dc 1025
2562c823 1026 return value;
a0a302dc
JS
1027}
1028
2562c823
RR
1029// ----------------------------------------------------------------------------
1030// wxVariantDataWxObjectPtr
1031// ----------------------------------------------------------------------------
cf6ae290
RG
1032
1033class wxVariantDataWxObjectPtr: public wxVariantData
1034{
cf6ae290
RG
1035public:
1036 wxVariantDataWxObjectPtr() { }
1037 wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
1038
1039 inline wxObject* GetValue() const { return m_value; }
1040 inline void SetValue(wxObject* value) { m_value = value; }
1041
cf6ae290
RG
1042 virtual bool Eq(wxVariantData& data) const;
1043#if wxUSE_STD_IOSTREAM
1044 virtual bool Write(wxSTD ostream& str) const;
1045#endif
1046 virtual bool Write(wxString& str) const;
1047#if wxUSE_STD_IOSTREAM
1048 virtual bool Read(wxSTD istream& str);
1049#endif
1050 virtual bool Read(wxString& str);
1051 virtual wxString GetType() const ;
c8058a09 1052 virtual wxVariantData* Clone() const { return new wxVariantDataWxObjectPtr(m_value); }
cf6ae290 1053
3586d10f 1054 virtual wxClassInfo* GetValueClassInfo();
c8058a09 1055
0bf14ab8 1056 DECLARE_WXANY_CONVERSION()
cf6ae290
RG
1057protected:
1058 wxObject* m_value;
cf6ae290
RG
1059};
1060
0bf14ab8
JS
1061IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxObject*, wxVariantDataWxObjectPtr)
1062
cf6ae290
RG
1063bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
1064{
3586d10f 1065 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
cf6ae290
RG
1066
1067 wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
1068
1069 return (otherData.m_value == m_value);
1070}
1071
1072wxString wxVariantDataWxObjectPtr::GetType() const
1073{
3586d10f 1074 wxString returnVal(wxT("wxObject*"));
c8058a09 1075
3586d10f
RR
1076 if (m_value)
1077 {
cf6ae290 1078 returnVal = m_value->GetClassInfo()->GetClassName();
3586d10f 1079 returnVal += wxT("*");
cf6ae290 1080 }
c8058a09 1081
cf6ae290
RG
1082 return returnVal;
1083}
1084
1085wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
1086{
1087 wxClassInfo* returnVal=NULL;
cab1a605
WS
1088
1089 if (m_value) returnVal = m_value->GetClassInfo();
cf6ae290
RG
1090
1091 return returnVal;
1092}
1093
1094#if wxUSE_STD_IOSTREAM
1095bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
1096{
1097 wxString s;
1098 Write(s);
1099 str << (const char*) s.mb_str();
cab1a605 1100 return true;
cf6ae290
RG
1101}
1102#endif
1103
1104bool wxVariantDataWxObjectPtr::Write(wxString& str) const
1105{
5c33522f 1106 str.Printf(wxT("%s(%p)"), GetType().c_str(), static_cast<void*>(m_value));
cab1a605 1107 return true;
cf6ae290
RG
1108}
1109
1110#if wxUSE_STD_IOSTREAM
1111bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
1112{
1113 // Not implemented
cab1a605 1114 return false;
cf6ae290
RG
1115}
1116#endif
1117
1118bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
1119{
1120 // Not implemented
cab1a605 1121 return false;
cf6ae290
RG
1122}
1123
2562c823 1124// wxVariant
cf6ae290 1125
2562c823
RR
1126wxVariant::wxVariant( wxObject* val, const wxString& name)
1127{
cf25a599 1128 m_refData = new wxVariantDataWxObjectPtr(val);
2562c823
RR
1129 m_name = name;
1130}
edca7a82 1131
2562c823
RR
1132bool wxVariant::operator== (wxObject* value) const
1133{
1134 return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
1135}
e2b87f38 1136
2562c823 1137bool wxVariant::operator!= (wxObject* value) const
edca7a82 1138{
2562c823
RR
1139 return (!((*this) == (wxObject*) value));
1140}
1141
1142void wxVariant::operator= (wxObject* value)
1143{
1144 UnRef();
cf25a599 1145 m_refData = new wxVariantDataWxObjectPtr(value);
2562c823 1146}
edca7a82 1147
2562c823
RR
1148wxObject* wxVariant::GetWxObjectPtr() const
1149{
cf25a599 1150 return (wxObject*) ((wxVariantDataWxObjectPtr*) m_refData)->GetValue();
2562c823
RR
1151}
1152
1153// ----------------------------------------------------------------------------
1154// wxVariantDataVoidPtr
1155// ----------------------------------------------------------------------------
1156
1157class wxVariantDataVoidPtr: public wxVariantData
1158{
edca7a82 1159public:
2562c823
RR
1160 wxVariantDataVoidPtr() { }
1161 wxVariantDataVoidPtr(void* value) { m_value = value; }
edca7a82 1162
2562c823
RR
1163 inline void* GetValue() const { return m_value; }
1164 inline void SetValue(void* value) { m_value = value; }
edca7a82 1165
edca7a82
GT
1166 virtual bool Eq(wxVariantData& data) const;
1167#if wxUSE_STD_IOSTREAM
2b004197 1168 virtual bool Write(wxSTD ostream& str) const;
edca7a82
GT
1169#endif
1170 virtual bool Write(wxString& str) const;
1171#if wxUSE_STD_IOSTREAM
2b004197 1172 virtual bool Read(wxSTD istream& str);
edca7a82
GT
1173#endif
1174 virtual bool Read(wxString& str);
47b378bd 1175 virtual wxString GetType() const { return wxT("void*"); }
c8058a09 1176 virtual wxVariantData* Clone() const { return new wxVariantDataVoidPtr(m_value); }
edca7a82 1177
0bf14ab8 1178 DECLARE_WXANY_CONVERSION()
edca7a82 1179protected:
2562c823 1180 void* m_value;
2562c823 1181};
edca7a82 1182
0bf14ab8
JS
1183IMPLEMENT_TRIVIAL_WXANY_CONVERSION(void*, wxVariantDataVoidPtr)
1184
2562c823 1185bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
edca7a82 1186{
3586d10f 1187 wxASSERT_MSG( data.GetType() == wxT("void*"), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
edca7a82 1188
2562c823 1189 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
edca7a82 1190
2562c823 1191 return (otherData.m_value == m_value);
edca7a82
GT
1192}
1193
2562c823
RR
1194#if wxUSE_STD_IOSTREAM
1195bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
edca7a82 1196{
2562c823
RR
1197 wxString s;
1198 Write(s);
1199 str << (const char*) s.mb_str();
1200 return true;
edca7a82 1201}
2562c823 1202#endif
edca7a82 1203
2562c823
RR
1204bool wxVariantDataVoidPtr::Write(wxString& str) const
1205{
1206 str.Printf(wxT("%p"), m_value);
1207 return true;
1208}
edca7a82
GT
1209
1210#if wxUSE_STD_IOSTREAM
2562c823 1211bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
edca7a82
GT
1212{
1213 // Not implemented
cab1a605 1214 return false;
edca7a82
GT
1215}
1216#endif
1217
2562c823 1218bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
edca7a82 1219{
2562c823
RR
1220 // Not implemented
1221 return false;
edca7a82
GT
1222}
1223
2562c823 1224// wxVariant
edca7a82 1225
2562c823 1226wxVariant::wxVariant( void* val, const wxString& name)
edca7a82 1227{
cf25a599 1228 m_refData = new wxVariantDataVoidPtr(val);
2562c823
RR
1229 m_name = name;
1230}
1231
1232bool wxVariant::operator== (void* value) const
1233{
1234 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
edca7a82 1235}
edca7a82 1236
2562c823
RR
1237bool wxVariant::operator!= (void* value) const
1238{
1239 return (!((*this) == (void*) value));
1240}
edca7a82 1241
2562c823 1242void wxVariant::operator= (void* value)
edca7a82 1243{
cf25a599 1244 if (GetType() == wxT("void*") && (m_refData->GetRefCount() == 1))
2562c823
RR
1245 {
1246 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1247 }
1248 else
1249 {
1250 UnRef();
cf25a599 1251 m_refData = new wxVariantDataVoidPtr(value);
2562c823 1252 }
edca7a82
GT
1253}
1254
2562c823
RR
1255void* wxVariant::GetVoidPtr() const
1256{
d099c754
VZ
1257 // handling this specially is convenient when working with COM, see #9873
1258 if ( IsNull() )
1259 return NULL;
1260
1261 wxASSERT( GetType() == wxT("void*") );
2562c823 1262
cf25a599 1263 return (void*) ((wxVariantDataVoidPtr*) m_refData)->GetValue();
2562c823 1264}
e2b87f38 1265
fb42d7c3 1266// ----------------------------------------------------------------------------
2562c823 1267// wxVariantDataDateTime
fb42d7c3
VZ
1268// ----------------------------------------------------------------------------
1269
2562c823
RR
1270#if wxUSE_DATETIME
1271
1272class wxVariantDataDateTime: public wxVariantData
fb42d7c3
VZ
1273{
1274public:
2562c823
RR
1275 wxVariantDataDateTime() { }
1276 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
fb42d7c3 1277
2562c823
RR
1278 inline wxDateTime GetValue() const { return m_value; }
1279 inline void SetValue(const wxDateTime& value) { m_value = value; }
fb42d7c3 1280
fb42d7c3
VZ
1281 virtual bool Eq(wxVariantData& data) const;
1282#if wxUSE_STD_IOSTREAM
1283 virtual bool Write(wxSTD ostream& str) const;
1284#endif
1285 virtual bool Write(wxString& str) const;
1286#if wxUSE_STD_IOSTREAM
1287 virtual bool Read(wxSTD istream& str);
1288#endif
1289 virtual bool Read(wxString& str);
47b378bd 1290 virtual wxString GetType() const { return wxT("datetime"); }
c8058a09 1291 virtual wxVariantData* Clone() const { return new wxVariantDataDateTime(m_value); }
fb42d7c3 1292
0bf14ab8 1293 DECLARE_WXANY_CONVERSION()
fb42d7c3 1294protected:
2562c823 1295 wxDateTime m_value;
fb42d7c3
VZ
1296};
1297
0bf14ab8 1298IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxDateTime, wxVariantDataDateTime)
fb42d7c3 1299
2562c823 1300bool wxVariantDataDateTime::Eq(wxVariantData& data) const
fb42d7c3 1301{
2562c823 1302 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
fb42d7c3 1303
2562c823 1304 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
fb42d7c3 1305
2562c823 1306 return (otherData.m_value == m_value);
fb42d7c3
VZ
1307}
1308
1309
1310#if wxUSE_STD_IOSTREAM
2562c823 1311bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
fb42d7c3 1312{
2562c823
RR
1313 wxString value;
1314 Write( value );
1315 str << value.c_str();
1316 return true;
fb42d7c3
VZ
1317}
1318#endif
1319
1320
2562c823 1321bool wxVariantDataDateTime::Write(wxString& str) const
fb42d7c3 1322{
be53e8ae
JS
1323 if ( m_value.IsValid() )
1324 str = m_value.Format();
1325 else
1326 str = wxS("Invalid");
cab1a605 1327 return true;
fb42d7c3
VZ
1328}
1329
1330
1331#if wxUSE_STD_IOSTREAM
2562c823 1332bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
fb42d7c3
VZ
1333{
1334 // Not implemented
cab1a605 1335 return false;
fb42d7c3
VZ
1336}
1337#endif
1338
1339
2562c823 1340bool wxVariantDataDateTime::Read(wxString& str)
fb42d7c3 1341{
be53e8ae
JS
1342 if ( str == wxS("Invalid") )
1343 {
1344 m_value = wxInvalidDateTime;
1345 return true;
1346 }
1347
c398434d
VZ
1348 wxString::const_iterator end;
1349 return m_value.ParseDateTime(str, &end) && end == str.end();
fb42d7c3
VZ
1350}
1351
2562c823 1352// wxVariant
fb42d7c3 1353
ff818ab8
RG
1354wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1355{
cf25a599 1356 m_refData = new wxVariantDataDateTime(val);
cab1a605 1357 m_name = name;
ff818ab8 1358}
ff818ab8 1359
2562c823 1360bool wxVariant::operator== (const wxDateTime& value) const
fb42d7c3 1361{
2562c823
RR
1362 wxDateTime thisValue;
1363 if (!Convert(&thisValue))
1364 return false;
1365
1366 return value.IsEqualTo(thisValue);
fb42d7c3 1367}
edca7a82 1368
2562c823 1369bool wxVariant::operator!= (const wxDateTime& value) const
341287bf 1370{
2562c823
RR
1371 return (!((*this) == value));
1372}
1373
1374void wxVariant::operator= (const wxDateTime& value)
1375{
1376 if (GetType() == wxT("datetime") &&
cf25a599 1377 m_refData->GetRefCount() == 1)
341287bf 1378 {
2562c823 1379 ((wxVariantDataDateTime*)GetData())->SetValue(value);
341287bf 1380 }
4fabb575 1381 else
2562c823
RR
1382 {
1383 UnRef();
cf25a599 1384 m_refData = new wxVariantDataDateTime(value);
2562c823 1385 }
341287bf
JS
1386}
1387
2562c823
RR
1388wxDateTime wxVariant::GetDateTime() const
1389{
1390 wxDateTime value;
1391 if (!Convert(& value))
341287bf 1392 {
2562c823 1393 wxFAIL_MSG(wxT("Could not convert to a datetime"));
341287bf 1394 }
3d8daa0f 1395
2562c823 1396 return value;
341287bf
JS
1397}
1398
2562c823 1399#endif // wxUSE_DATETIME
341287bf 1400
2562c823
RR
1401// ----------------------------------------------------------------------------
1402// wxVariantDataArrayString
1403// ----------------------------------------------------------------------------
1404
1405class wxVariantDataArrayString: public wxVariantData
341287bf 1406{
2562c823
RR
1407public:
1408 wxVariantDataArrayString() { }
1409 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
341287bf 1410
2562c823
RR
1411 wxArrayString GetValue() const { return m_value; }
1412 void SetValue(const wxArrayString& value) { m_value = value; }
341287bf 1413
2562c823
RR
1414 virtual bool Eq(wxVariantData& data) const;
1415#if wxUSE_STD_IOSTREAM
1416 virtual bool Write(wxSTD ostream& str) const;
1417#endif
1418 virtual bool Write(wxString& str) const;
1419#if wxUSE_STD_IOSTREAM
1420 virtual bool Read(wxSTD istream& str);
1421#endif
1422 virtual bool Read(wxString& str);
47b378bd 1423 virtual wxString GetType() const { return wxT("arrstring"); }
c8058a09 1424 virtual wxVariantData* Clone() const { return new wxVariantDataArrayString(m_value); }
341287bf 1425
0bf14ab8 1426 DECLARE_WXANY_CONVERSION()
2562c823
RR
1427protected:
1428 wxArrayString m_value;
2562c823 1429};
bc14c8b2 1430
0bf14ab8
JS
1431IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxArrayString, wxVariantDataArrayString)
1432
2562c823 1433bool wxVariantDataArrayString::Eq(wxVariantData& data) const
341287bf 1434{
2562c823 1435 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
341287bf 1436
2562c823 1437 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
341287bf 1438
2562c823 1439 return otherData.m_value == m_value;
341287bf
JS
1440}
1441
2562c823
RR
1442#if wxUSE_STD_IOSTREAM
1443bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
341287bf 1444{
2562c823
RR
1445 // Not implemented
1446 return false;
341287bf 1447}
2562c823 1448#endif
341287bf 1449
2562c823 1450bool wxVariantDataArrayString::Write(wxString& str) const
341287bf 1451{
2562c823
RR
1452 size_t count = m_value.GetCount();
1453 for ( size_t n = 0; n < count; n++ )
341287bf 1454 {
2562c823 1455 if ( n )
9a83f860 1456 str += wxT(';');
2562c823
RR
1457
1458 str += m_value[n];
341287bf 1459 }
341287bf 1460
2562c823 1461 return true;
341287bf
JS
1462}
1463
2562c823
RR
1464
1465#if wxUSE_STD_IOSTREAM
1466bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
341287bf 1467{
2562c823
RR
1468 // Not implemented
1469 return false;
341287bf 1470}
2562c823 1471#endif
341287bf 1472
2562c823
RR
1473
1474bool wxVariantDataArrayString::Read(wxString& str)
341287bf 1475{
9a83f860 1476 wxStringTokenizer tk(str, wxT(";"));
2562c823 1477 while ( tk.HasMoreTokens() )
341287bf 1478 {
2562c823 1479 m_value.Add(tk.GetNextToken());
341287bf 1480 }
341287bf 1481
2562c823 1482 return true;
341287bf
JS
1483}
1484
2562c823
RR
1485// wxVariant
1486
1487wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1488{
cf25a599 1489 m_refData = new wxVariantDataArrayString(val);
2562c823 1490 m_name = name;
341287bf
JS
1491}
1492
2562c823 1493bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
341287bf 1494{
9a83f860 1495 wxFAIL_MSG( wxT("TODO") );
f6bcfd97 1496
2562c823 1497 return false;
341287bf
JS
1498}
1499
2562c823 1500bool wxVariant::operator!=(const wxArrayString& value) const
341287bf 1501{
2562c823 1502 return !(*this == value);
341287bf
JS
1503}
1504
2562c823 1505void wxVariant::operator=(const wxArrayString& value)
341287bf 1506{
2562c823 1507 if (GetType() == wxT("arrstring") &&
cf25a599 1508 m_refData->GetRefCount() == 1)
341287bf 1509 {
2562c823 1510 ((wxVariantDataArrayString *)GetData())->SetValue(value);
341287bf
JS
1511 }
1512 else
1513 {
2562c823 1514 UnRef();
cf25a599 1515 m_refData = new wxVariantDataArrayString(value);
341287bf
JS
1516 }
1517}
1518
2562c823 1519wxArrayString wxVariant::GetArrayString() const
341287bf 1520{
2562c823
RR
1521 if ( GetType() == wxT("arrstring") )
1522 return ((wxVariantDataArrayString *)GetData())->GetValue();
1523
1524 return wxArrayString();
341287bf
JS
1525}
1526
4e00b908
JS
1527// ----------------------------------------------------------------------------
1528// wxVariantDataLongLong
1529// ----------------------------------------------------------------------------
1530
1531#if wxUSE_LONGLONG
1532
1533class WXDLLIMPEXP_BASE wxVariantDataLongLong : public wxVariantData
1534{
1535public:
1536 wxVariantDataLongLong() { m_value = 0; }
1537 wxVariantDataLongLong(wxLongLong value) { m_value = value; }
1538
1539 wxLongLong GetValue() const { return m_value; }
1540 void SetValue(wxLongLong value) { m_value = value; }
1541
1542 virtual bool Eq(wxVariantData& data) const;
1543
1544 virtual bool Read(wxString& str);
1545 virtual bool Write(wxString& str) const;
1546#if wxUSE_STD_IOSTREAM
1547 virtual bool Read(wxSTD istream& str);
1548 virtual bool Write(wxSTD ostream& str) const;
1549#endif
1550#if wxUSE_STREAMS
1551 virtual bool Read(wxInputStream& str);
1552 virtual bool Write(wxOutputStream &str) const;
1553#endif // wxUSE_STREAMS
1554
1555 wxVariantData* Clone() const
1556 {
1557 return new wxVariantDataLongLong(m_value);
1558 }
1559
1560 virtual wxString GetType() const { return wxS("longlong"); }
1561
0bf14ab8 1562 DECLARE_WXANY_CONVERSION()
4e00b908
JS
1563protected:
1564 wxLongLong m_value;
1565};
1566
0bf14ab8
JS
1567//
1568// wxLongLong type requires customized wxAny conversion code
1569//
1570#if wxUSE_ANY
1571#ifdef wxLongLong_t
1572
1573bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
1574{
1575 *any = m_value.GetValue();
1576 return true;
1577}
1578
1579wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
1580{
1581 return new wxVariantDataLongLong(wxANY_AS(any, wxLongLong_t));
1582}
1583
1584REGISTER_WXANY_CONVERSION(wxLongLong_t, wxVariantDataLongLong)
1585
1586#else // if !defined(wxLongLong_t)
1587
1588bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
1589{
1590 *any = m_value;
1591 return true;
1592}
1593
1594wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
1595{
1596 return new wxVariantDataLongLong(wxANY_AS(any, wxLongLong));
1597}
1598
1599REGISTER_WXANY_CONVERSION(wxLongLong, wxVariantDataLongLong)
1600
1601#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
1602#endif // wxUSE_ANY
1603
4e00b908
JS
1604bool wxVariantDataLongLong::Eq(wxVariantData& data) const
1605{
03647350 1606 wxASSERT_MSG( (data.GetType() == wxS("longlong")),
4e00b908
JS
1607 "wxVariantDataLongLong::Eq: argument mismatch" );
1608
1609 wxVariantDataLongLong& otherData = (wxVariantDataLongLong&) data;
1610
1611 return (otherData.m_value == m_value);
1612}
1613
1614#if wxUSE_STD_IOSTREAM
1615bool wxVariantDataLongLong::Write(wxSTD ostream& str) const
1616{
1617 wxString s;
1618 Write(s);
1619 str << (const char*) s.mb_str();
1620 return true;
1621}
1622#endif
1623
1624bool wxVariantDataLongLong::Write(wxString& str) const
1625{
f81bd288
JS
1626#ifdef wxLongLong_t
1627 str.Printf(wxS("%lld"), m_value.GetValue());
4e00b908 1628 return true;
f81bd288
JS
1629#else
1630 return false;
1631#endif
4e00b908
JS
1632}
1633
1634#if wxUSE_STD_IOSTREAM
1635bool wxVariantDataLongLong::Read(wxSTD istream& WXUNUSED(str))
1636{
1637 wxFAIL_MSG(wxS("Unimplemented"));
1638 return false;
1639}
1640#endif
1641
1642#if wxUSE_STREAMS
1643bool wxVariantDataLongLong::Write(wxOutputStream& str) const
1644{
1645 wxTextOutputStream s(str);
1646 s.Write32(m_value.GetLo());
1647 s.Write32(m_value.GetHi());
1648 return true;
1649}
1650
1651bool wxVariantDataLongLong::Read(wxInputStream& str)
1652{
1653 wxTextInputStream s(str);
1654 unsigned long lo = s.Read32();
1655 long hi = s.Read32();
1656 m_value = wxLongLong(hi, lo);
1657 return true;
1658}
1659#endif // wxUSE_STREAMS
1660
1661bool wxVariantDataLongLong::Read(wxString& str)
1662{
1663#ifdef wxLongLong_t
1664 wxLongLong_t value_t;
1665 if ( !str.ToLongLong(&value_t) )
1666 return false;
1667 m_value = value_t;
1668 return true;
1669#else
1670 return false;
1671#endif
1672}
1673
1674// wxVariant
1675
1676wxVariant::wxVariant(wxLongLong val, const wxString& name)
1677{
1678 m_refData = new wxVariantDataLongLong(val);
1679 m_name = name;
1680}
1681
1682bool wxVariant::operator==(wxLongLong value) const
1683{
1684 wxLongLong thisValue;
1685 if ( !Convert(&thisValue) )
1686 return false;
1687 else
1688 return (value == thisValue);
1689}
1690
1691bool wxVariant::operator!=(wxLongLong value) const
1692{
1693 return (!((*this) == value));
1694}
1695
1696void wxVariant::operator=(wxLongLong value)
1697{
1698 if ( GetType() == wxS("longlong") &&
1699 m_refData->GetRefCount() == 1 )
1700 {
1701 ((wxVariantDataLongLong*)GetData())->SetValue(value);
1702 }
1703 else
1704 {
1705 UnRef();
1706 m_refData = new wxVariantDataLongLong(value);
1707 }
1708}
1709
1710wxLongLong wxVariant::GetLongLong() const
1711{
1712 wxLongLong value;
1713 if ( Convert(&value) )
1714 {
1715 return value;
1716 }
1717 else
1718 {
1719 wxFAIL_MSG(wxT("Could not convert to a long long"));
1720 return 0;
1721 }
1722}
1723
1724#endif // wxUSE_LONGLONG
1725
1726// ----------------------------------------------------------------------------
1727// wxVariantDataULongLong
1728// ----------------------------------------------------------------------------
1729
1730#if wxUSE_LONGLONG
1731
1732class WXDLLIMPEXP_BASE wxVariantDataULongLong : public wxVariantData
1733{
1734public:
1735 wxVariantDataULongLong() { m_value = 0; }
1736 wxVariantDataULongLong(wxULongLong value) { m_value = value; }
1737
1738 wxULongLong GetValue() const { return m_value; }
1739 void SetValue(wxULongLong value) { m_value = value; }
1740
1741 virtual bool Eq(wxVariantData& data) const;
1742
1743 virtual bool Read(wxString& str);
1744 virtual bool Write(wxString& str) const;
1745#if wxUSE_STD_IOSTREAM
1746 virtual bool Read(wxSTD istream& str);
1747 virtual bool Write(wxSTD ostream& str) const;
1748#endif
1749#if wxUSE_STREAMS
1750 virtual bool Read(wxInputStream& str);
1751 virtual bool Write(wxOutputStream &str) const;
1752#endif // wxUSE_STREAMS
1753
1754 wxVariantData* Clone() const
1755 {
1756 return new wxVariantDataULongLong(m_value);
1757 }
1758
1759 virtual wxString GetType() const { return wxS("ulonglong"); }
1760
0bf14ab8 1761 DECLARE_WXANY_CONVERSION()
4e00b908
JS
1762protected:
1763 wxULongLong m_value;
1764};
1765
0bf14ab8
JS
1766//
1767// wxULongLong type requires customized wxAny conversion code
1768//
1769#if wxUSE_ANY
1770#ifdef wxLongLong_t
1771
1772bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
1773{
1774 *any = m_value.GetValue();
1775 return true;
1776}
1777
1778wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
1779{
1780 return new wxVariantDataULongLong(wxANY_AS(any, wxULongLong_t));
1781}
1782
1783REGISTER_WXANY_CONVERSION(wxULongLong_t, wxVariantDataULongLong)
1784
1785#else // if !defined(wxLongLong_t)
1786
1787bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
1788{
1789 *any = m_value;
1790 return true;
1791}
1792
1793wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
1794{
1795 return new wxVariantDataULongLong(wxANY_AS(any, wxULongLong));
1796}
1797
1798REGISTER_WXANY_CONVERSION(wxULongLong, wxVariantDataULongLong)
1799
1800#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
1801#endif // wxUSE_ANY
1802
1803
4e00b908
JS
1804bool wxVariantDataULongLong::Eq(wxVariantData& data) const
1805{
03647350 1806 wxASSERT_MSG( (data.GetType() == wxS("ulonglong")),
4e00b908
JS
1807 "wxVariantDataULongLong::Eq: argument mismatch" );
1808
1809 wxVariantDataULongLong& otherData = (wxVariantDataULongLong&) data;
1810
1811 return (otherData.m_value == m_value);
1812}
1813
1814#if wxUSE_STD_IOSTREAM
1815bool wxVariantDataULongLong::Write(wxSTD ostream& str) const
1816{
1817 wxString s;
1818 Write(s);
1819 str << (const char*) s.mb_str();
1820 return true;
1821}
1822#endif
1823
1824bool wxVariantDataULongLong::Write(wxString& str) const
1825{
f81bd288
JS
1826#ifdef wxLongLong_t
1827 str.Printf(wxS("%llu"), m_value.GetValue());
4e00b908 1828 return true;
f81bd288
JS
1829#else
1830 return false;
1831#endif
4e00b908
JS
1832}
1833
1834#if wxUSE_STD_IOSTREAM
1835bool wxVariantDataULongLong::Read(wxSTD istream& WXUNUSED(str))
1836{
1837 wxFAIL_MSG(wxS("Unimplemented"));
1838 return false;
1839}
1840#endif
1841
1842#if wxUSE_STREAMS
1843bool wxVariantDataULongLong::Write(wxOutputStream& str) const
1844{
1845 wxTextOutputStream s(str);
1846 s.Write32(m_value.GetLo());
1847 s.Write32(m_value.GetHi());
1848 return true;
1849}
1850
1851bool wxVariantDataULongLong::Read(wxInputStream& str)
1852{
1853 wxTextInputStream s(str);
1854 unsigned long lo = s.Read32();
1855 long hi = s.Read32();
1856 m_value = wxULongLong(hi, lo);
1857 return true;
1858}
1859#endif // wxUSE_STREAMS
1860
1861bool wxVariantDataULongLong::Read(wxString& str)
1862{
1863#ifdef wxLongLong_t
1864 wxULongLong_t value_t;
1865 if ( !str.ToULongLong(&value_t) )
1866 return false;
1867 m_value = value_t;
1868 return true;
1869#else
1870 return false;
1871#endif
1872}
1873
1874// wxVariant
1875
1876wxVariant::wxVariant(wxULongLong val, const wxString& name)
1877{
1878 m_refData = new wxVariantDataULongLong(val);
1879 m_name = name;
1880}
1881
1882bool wxVariant::operator==(wxULongLong value) const
1883{
1884 wxULongLong thisValue;
1885 if ( !Convert(&thisValue) )
1886 return false;
1887 else
1888 return (value == thisValue);
1889}
1890
1891bool wxVariant::operator!=(wxULongLong value) const
1892{
1893 return (!((*this) == value));
1894}
1895
1896void wxVariant::operator=(wxULongLong value)
1897{
1898 if ( GetType() == wxS("ulonglong") &&
1899 m_refData->GetRefCount() == 1 )
1900 {
1901 ((wxVariantDataULongLong*)GetData())->SetValue(value);
1902 }
1903 else
1904 {
1905 UnRef();
1906 m_refData = new wxVariantDataULongLong(value);
1907 }
1908}
1909
1910wxULongLong wxVariant::GetULongLong() const
1911{
1912 wxULongLong value;
1913 if ( Convert(&value) )
1914 {
1915 return value;
1916 }
1917 else
1918 {
1919 wxFAIL_MSG(wxT("Could not convert to a long long"));
1920 return 0;
1921 }
1922}
1923
1924#endif // wxUSE_LONGLONG
1925
2562c823
RR
1926// ----------------------------------------------------------------------------
1927// wxVariantDataList
1928// ----------------------------------------------------------------------------
2c3a1064 1929
2562c823 1930class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
341287bf 1931{
2562c823
RR
1932public:
1933 wxVariantDataList() {}
9a0a58f5 1934 wxVariantDataList(const wxVariantList& list);
2562c823 1935 virtual ~wxVariantDataList();
341287bf 1936
9a0a58f5
RR
1937 wxVariantList& GetValue() { return m_value; }
1938 void SetValue(const wxVariantList& value) ;
341287bf 1939
2562c823
RR
1940 virtual bool Eq(wxVariantData& data) const;
1941#if wxUSE_STD_IOSTREAM
1942 virtual bool Write(wxSTD ostream& str) const;
1943#endif
1944 virtual bool Write(wxString& str) const;
1945#if wxUSE_STD_IOSTREAM
1946 virtual bool Read(wxSTD istream& str);
1947#endif
1948 virtual bool Read(wxString& str);
47b378bd 1949 virtual wxString GetType() const { return wxT("list"); }
52e81242 1950
2562c823 1951 void Clear();
341287bf 1952
c8058a09 1953 wxVariantData* Clone() const { return new wxVariantDataList(m_value); }
0bf14ab8
JS
1954
1955 DECLARE_WXANY_CONVERSION()
2562c823 1956protected:
9a0a58f5 1957 wxVariantList m_value;
2562c823 1958};
341287bf 1959
0bf14ab8
JS
1960#if wxUSE_ANY
1961
1962//
1963// Convert to/from list of wxAnys
1964//
1965
1966WX_DEFINE_LIST(wxAnyList)
1967
1968bool wxVariantDataList::GetAsAny(wxAny* any) const
1969{
1970 wxAnyList dst;
1971 wxVariantList::compatibility_iterator node = m_value.GetFirst();
1972 while (node)
1973 {
1974 wxVariant* pVar = node->GetData();
5ceb0345 1975 dst.push_back(new wxAny(((const wxVariant&)*pVar)));
0bf14ab8
JS
1976 node = node->GetNext();
1977 }
1978
1979 *any = dst;
1980 return true;
1981}
1982
1983wxVariantData* wxVariantDataList::VariantDataFactory(const wxAny& any)
1984{
1985 wxAnyList src = wxANY_AS(any, wxAnyList);
1986 wxVariantList dst;
1987 wxAnyList::compatibility_iterator node = src.GetFirst();
1988 while (node)
1989 {
1990 wxAny* pAny = node->GetData();
1991 dst.push_back(new wxVariant(*pAny));
1992 node = node->GetNext();
1993 }
1994
1995 return new wxVariantDataList(dst);
1996}
1997
1998REGISTER_WXANY_CONVERSION(wxAnyList, wxVariantDataList)
1999
2000#endif // wxUSE_ANY
2001
9a0a58f5 2002wxVariantDataList::wxVariantDataList(const wxVariantList& list)
341287bf 2003{
2562c823 2004 SetValue(list);
341287bf
JS
2005}
2006
2562c823 2007wxVariantDataList::~wxVariantDataList()
341287bf 2008{
2562c823 2009 Clear();
341287bf
JS
2010}
2011
9a0a58f5 2012void wxVariantDataList::SetValue(const wxVariantList& value)
341287bf 2013{
2562c823 2014 Clear();
9a0a58f5 2015 wxVariantList::compatibility_iterator node = value.GetFirst();
2562c823 2016 while (node)
341287bf 2017 {
9a0a58f5 2018 wxVariant* var = node->GetData();
2562c823
RR
2019 m_value.Append(new wxVariant(*var));
2020 node = node->GetNext();
341287bf 2021 }
2562c823
RR
2022}
2023
2024void wxVariantDataList::Clear()
2025{
9a0a58f5 2026 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 2027 while (node)
341287bf 2028 {
9a0a58f5 2029 wxVariant* var = node->GetData();
2562c823
RR
2030 delete var;
2031 node = node->GetNext();
341287bf 2032 }
2562c823 2033 m_value.Clear();
341287bf
JS
2034}
2035
2562c823 2036bool wxVariantDataList::Eq(wxVariantData& data) const
a0a302dc 2037{
2562c823
RR
2038 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
2039
2040 wxVariantDataList& listData = (wxVariantDataList&) data;
9a0a58f5
RR
2041 wxVariantList::compatibility_iterator node1 = m_value.GetFirst();
2042 wxVariantList::compatibility_iterator node2 = listData.GetValue().GetFirst();
2562c823
RR
2043 while (node1 && node2)
2044 {
9a0a58f5
RR
2045 wxVariant* var1 = node1->GetData();
2046 wxVariant* var2 = node2->GetData();
2562c823
RR
2047 if ((*var1) != (*var2))
2048 return false;
2049 node1 = node1->GetNext();
2050 node2 = node2->GetNext();
2051 }
2052 if (node1 || node2) return false;
2053 return true;
a0a302dc
JS
2054}
2055
2562c823
RR
2056#if wxUSE_STD_IOSTREAM
2057bool wxVariantDataList::Write(wxSTD ostream& str) const
a0a302dc 2058{
2562c823
RR
2059 wxString s;
2060 Write(s);
2061 str << (const char*) s.mb_str();
2062 return true;
a0a302dc 2063}
2562c823 2064#endif
a0a302dc 2065
2562c823 2066bool wxVariantDataList::Write(wxString& str) const
a0a302dc 2067{
2562c823 2068 str = wxEmptyString;
9a0a58f5 2069 wxVariantList::compatibility_iterator node = m_value.GetFirst();
2562c823 2070 while (node)
a0a302dc 2071 {
9a0a58f5 2072 wxVariant* var = node->GetData();
2562c823
RR
2073 if (node != m_value.GetFirst())
2074 str += wxT(" ");
2075 wxString str1;
2076 str += var->MakeString();
2077 node = node->GetNext();
a0a302dc 2078 }
2562c823
RR
2079
2080 return true;
a0a302dc 2081}
2f620946 2082
2562c823
RR
2083#if wxUSE_STD_IOSTREAM
2084bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
2f620946 2085{
2562c823
RR
2086 wxFAIL_MSG(wxT("Unimplemented"));
2087 // TODO
2088 return false;
2f620946 2089}
2562c823 2090#endif
2f620946 2091
2562c823 2092bool wxVariantDataList::Read(wxString& WXUNUSED(str))
2f620946 2093{
2562c823
RR
2094 wxFAIL_MSG(wxT("Unimplemented"));
2095 // TODO
2096 return false;
2f620946
RR
2097}
2098
2562c823
RR
2099// wxVariant
2100
9a0a58f5 2101wxVariant::wxVariant(const wxVariantList& val, const wxString& name) // List of variants
2f620946 2102{
cf25a599 2103 m_refData = new wxVariantDataList(val);
2562c823 2104 m_name = name;
2f620946 2105}
341287bf 2106
9a0a58f5 2107bool wxVariant::operator== (const wxVariantList& value) const
edca7a82 2108{
2562c823 2109 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
edca7a82 2110
2562c823
RR
2111 wxVariantDataList other(value);
2112 return (GetData()->Eq(other));
edca7a82
GT
2113}
2114
9a0a58f5 2115bool wxVariant::operator!= (const wxVariantList& value) const
edca7a82
GT
2116{
2117 return (!((*this) == value));
2118}
2119
9a0a58f5 2120void wxVariant::operator= (const wxVariantList& value)
edca7a82 2121{
2562c823 2122 if (GetType() == wxT("list") &&
cf25a599 2123 m_refData->GetRefCount() == 1)
edca7a82 2124 {
2562c823 2125 ((wxVariantDataList*)GetData())->SetValue(value);
edca7a82
GT
2126 }
2127 else
2128 {
2562c823 2129 UnRef();
cf25a599 2130 m_refData = new wxVariantDataList(value);
edca7a82
GT
2131 }
2132}
2133
9a0a58f5 2134wxVariantList& wxVariant::GetList() const
edca7a82 2135{
2562c823 2136 wxASSERT( (GetType() == wxT("list")) );
edca7a82 2137
cf25a599 2138 return (wxVariantList&) ((wxVariantDataList*) m_refData)->GetValue();
2562c823 2139}
edca7a82 2140
2562c823
RR
2141// Make empty list
2142void wxVariant::NullList()
edca7a82 2143{
2562c823 2144 SetData(new wxVariantDataList());
edca7a82
GT
2145}
2146
2562c823
RR
2147// Append to list
2148void wxVariant::Append(const wxVariant& value)
edca7a82 2149{
9a0a58f5 2150 wxVariantList& list = GetList();
2562c823
RR
2151
2152 list.Append(new wxVariant(value));
edca7a82
GT
2153}
2154
2562c823
RR
2155// Insert at front of list
2156void wxVariant::Insert(const wxVariant& value)
2157{
9a0a58f5 2158 wxVariantList& list = GetList();
fb42d7c3 2159
2562c823
RR
2160 list.Insert(new wxVariant(value));
2161}
2162
2163// Returns true if the variant is a member of the list
2164bool wxVariant::Member(const wxVariant& value) const
fb42d7c3 2165{
9a0a58f5 2166 wxVariantList& list = GetList();
fb42d7c3 2167
9a0a58f5 2168 wxVariantList::compatibility_iterator node = list.GetFirst();
2562c823
RR
2169 while (node)
2170 {
9a0a58f5 2171 wxVariant* other = node->GetData();
2562c823
RR
2172 if (value == *other)
2173 return true;
2174 node = node->GetNext();
2175 }
cab1a605 2176 return false;
fb42d7c3
VZ
2177}
2178
2562c823
RR
2179// Deletes the nth element of the list
2180bool wxVariant::Delete(size_t item)
fb42d7c3 2181{
9a0a58f5 2182 wxVariantList& list = GetList();
2562c823
RR
2183
2184 wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
9a0a58f5
RR
2185 wxVariantList::compatibility_iterator node = list.Item(item);
2186 wxVariant* variant = node->GetData();
2562c823
RR
2187 delete variant;
2188 list.Erase(node);
2189 return true;
fb42d7c3
VZ
2190}
2191
2562c823
RR
2192// Clear list
2193void wxVariant::ClearList()
fb42d7c3 2194{
2562c823 2195 if (!IsNull() && (GetType() == wxT("list")))
fb42d7c3 2196 {
cf25a599 2197 ((wxVariantDataList*) m_refData)->Clear();
fb42d7c3
VZ
2198 }
2199 else
2200 {
2562c823
RR
2201 if (!GetType().IsSameAs(wxT("list")))
2202 UnRef();
fb42d7c3 2203
cf25a599 2204 m_refData = new wxVariantDataList;
2562c823 2205 }
fb42d7c3
VZ
2206}
2207
60acae80
RR
2208// Treat a list variant as an array
2209wxVariant wxVariant::operator[] (size_t idx) const
2210{
60acae80 2211 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
60acae80
RR
2212
2213 if (GetType() == wxT("list"))
2214 {
cf25a599 2215 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80 2216 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
9a0a58f5 2217 return *(data->GetValue().Item(idx)->GetData());
60acae80 2218 }
60acae80
RR
2219 return wxNullVariant;
2220}
2221
2222wxVariant& wxVariant::operator[] (size_t idx)
2223{
2224 // We can't return a reference to a variant for a string list, since the string
2225 // is actually stored as a char*, not a variant.
2226
2227 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
2228
cf25a599 2229 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80
RR
2230 wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
2231
9a0a58f5 2232 return * (data->GetValue().Item(idx)->GetData());
60acae80
RR
2233}
2234
2235// Return the number of elements in a list
2236size_t wxVariant::GetCount() const
2237{
60acae80 2238 wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
60acae80
RR
2239
2240 if (GetType() == wxT("list"))
2241 {
cf25a599 2242 wxVariantDataList* data = (wxVariantDataList*) m_refData;
60acae80
RR
2243 return data->GetValue().GetCount();
2244 }
60acae80
RR
2245 return 0;
2246}
2247
2562c823 2248// ----------------------------------------------------------------------------
341287bf 2249// Type conversion
2562c823
RR
2250// ----------------------------------------------------------------------------
2251
341287bf
JS
2252bool wxVariant::Convert(long* value) const
2253{
2254 wxString type(GetType());
4e00b908 2255 if (type == wxS("double"))
2562c823 2256 *value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
4e00b908 2257 else if (type == wxS("long"))
341287bf 2258 *value = ((wxVariantDataLong*)GetData())->GetValue();
4e00b908 2259 else if (type == wxS("bool"))
341287bf 2260 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
4e00b908 2261 else if (type == wxS("string"))
52de37c7 2262 *value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
4e00b908
JS
2263#if wxUSE_LONGLONG
2264 else if (type == wxS("longlong"))
2265 {
2266 wxLongLong v = ((wxVariantDataLongLong*)GetData())->GetValue();
2267 // Don't convert if return value would be vague
2268 if ( v < LONG_MIN || v > LONG_MAX )
2269 return false;
2270 *value = v.ToLong();
2271 }
2272 else if (type == wxS("ulonglong"))
2273 {
2274 wxULongLong v = ((wxVariantDataULongLong*)GetData())->GetValue();
2275 // Don't convert if return value would be vague
2276 if ( v.GetHi() )
2277 return false;
2278 *value = (long) v.ToULong();
2279 }
2280#endif
341287bf 2281 else
cab1a605 2282 return false;
341287bf 2283
cab1a605 2284 return true;
341287bf
JS
2285}
2286
2287bool wxVariant::Convert(bool* value) const
2288{
2289 wxString type(GetType());
223d09f6 2290 if (type == wxT("double"))
2562c823 2291 *value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
223d09f6 2292 else if (type == wxT("long"))
341287bf 2293 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
223d09f6 2294 else if (type == wxT("bool"))
341287bf 2295 *value = ((wxVariantDataBool*)GetData())->GetValue();
223d09f6 2296 else if (type == wxT("string"))
341287bf
JS
2297 {
2298 wxString val(((wxVariantDataString*)GetData())->GetValue());
2299 val.MakeLower();
b1638abf 2300 if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
cab1a605 2301 *value = true;
b1638abf 2302 else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
cab1a605 2303 *value = false;
341287bf 2304 else
cab1a605 2305 return false;
341287bf
JS
2306 }
2307 else
cab1a605 2308 return false;
341287bf 2309
cab1a605 2310 return true;
341287bf
JS
2311}
2312
2313bool wxVariant::Convert(double* value) const
2314{
2315 wxString type(GetType());
223d09f6 2316 if (type == wxT("double"))
2562c823 2317 *value = ((wxVariantDoubleData*)GetData())->GetValue();
223d09f6 2318 else if (type == wxT("long"))
341287bf 2319 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
223d09f6 2320 else if (type == wxT("bool"))
341287bf 2321 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
223d09f6 2322 else if (type == wxT("string"))
52de37c7 2323 *value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
4e00b908
JS
2324#if wxUSE_LONGLONG
2325 else if (type == wxS("longlong"))
2326 {
2327 *value = ((wxVariantDataLongLong*)GetData())->GetValue().ToDouble();
2328 }
2329 else if (type == wxS("ulonglong"))
2330 {
2331 *value = ((wxVariantDataULongLong*)GetData())->GetValue().ToDouble();
2332 }
2333#endif
341287bf 2334 else
cab1a605 2335 return false;
341287bf 2336
cab1a605 2337 return true;
341287bf
JS
2338}
2339
af717fa8 2340bool wxVariant::Convert(wxUniChar* value) const
341287bf
JS
2341{
2342 wxString type(GetType());
223d09f6 2343 if (type == wxT("char"))
341287bf 2344 *value = ((wxVariantDataChar*)GetData())->GetValue();
223d09f6 2345 else if (type == wxT("long"))
341287bf 2346 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
223d09f6 2347 else if (type == wxT("bool"))
341287bf
JS
2348 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2349 else
cab1a605 2350 return false;
341287bf 2351
cab1a605 2352 return true;
341287bf
JS
2353}
2354
af717fa8
VS
2355bool wxVariant::Convert(char* value) const
2356{
2357 wxUniChar ch;
2358 if ( !Convert(&ch) )
2359 return false;
2360 *value = ch;
2361 return true;
2362}
2363
2364bool wxVariant::Convert(wchar_t* value) const
2365{
2366 wxUniChar ch;
2367 if ( !Convert(&ch) )
2368 return false;
2369 *value = ch;
2370 return true;
2371}
2372
341287bf
JS
2373bool wxVariant::Convert(wxString* value) const
2374{
2375 *value = MakeString();
cab1a605 2376 return true;
341287bf
JS
2377}
2378
4e00b908
JS
2379#if wxUSE_LONGLONG
2380bool wxVariant::Convert(wxLongLong* value) const
2381{
2382 wxString type(GetType());
2383 if (type == wxS("longlong"))
2384 *value = ((wxVariantDataLongLong*)GetData())->GetValue();
2385 else if (type == wxS("long"))
2386 *value = ((wxVariantDataLong*)GetData())->GetValue();
2387 else if (type == wxS("string"))
2388 {
2389 wxString s = ((wxVariantDataString*)GetData())->GetValue();
2390#ifdef wxLongLong_t
2391 wxLongLong_t value_t;
2392 if ( !s.ToLongLong(&value_t) )
2393 return false;
2394 *value = value_t;
2395#else
2396 long l_value;
2397 if ( !s.ToLong(&l_value) )
2398 return false;
2399 *value = l_value;
2400#endif
2401 }
2402 else if (type == wxS("bool"))
2403 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2404 else if (type == wxS("double"))
2405 {
2406 value->Assign(((wxVariantDoubleData*)GetData())->GetValue());
2407 }
2408 else if (type == wxS("ulonglong"))
2409 *value = ((wxVariantDataULongLong*)GetData())->GetValue();
2410 else
2411 return false;
2412
2413 return true;
2414}
2415
2416bool wxVariant::Convert(wxULongLong* value) const
2417{
2418 wxString type(GetType());
2419 if (type == wxS("ulonglong"))
2420 *value = ((wxVariantDataULongLong*)GetData())->GetValue();
2421 else if (type == wxS("long"))
2422 *value = ((wxVariantDataLong*)GetData())->GetValue();
2423 else if (type == wxS("string"))
2424 {
2425 wxString s = ((wxVariantDataString*)GetData())->GetValue();
2426#ifdef wxLongLong_t
2427 wxULongLong_t value_t;
2428 if ( !s.ToULongLong(&value_t) )
2429 return false;
2430 *value = value_t;
2431#else
2432 unsigned long l_value;
2433 if ( !s.ToULong(&l_value) )
2434 return false;
2435 *value = l_value;
2436#endif
2437 }
2438 else if (type == wxS("bool"))
2439 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2440 else if (type == wxS("double"))
2441 {
2442 double value_d = ((wxVariantDoubleData*)GetData())->GetValue();
2443
2444 if ( value_d < 0.0 )
2445 return false;
2446
2447#ifdef wxLongLong_t
2448 *value = (wxULongLong_t) value_d;
2449#else
2450 wxLongLong temp;
2451 temp.Assign(value_d);
2452 *value = temp;
2453#endif
2454 }
2455 else if (type == wxS("longlong"))
2456 *value = ((wxVariantDataLongLong*)GetData())->GetValue();
2457 else
2458 return false;
2459
2460 return true;
2461}
2462#endif // wxUSE_LONGLONG
2463
e2b87f38 2464#if wxUSE_DATETIME
edca7a82
GT
2465bool wxVariant::Convert(wxDateTime* value) const
2466{
2467 wxString type(GetType());
2468 if (type == wxT("datetime"))
9708db20 2469 {
edca7a82 2470 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
cab1a605 2471 return true;
dc259b79 2472 }
73799292 2473
9708db20
JS
2474 // Fallback to string conversion
2475 wxString val;
73799292
VZ
2476 if ( !Convert(&val) )
2477 return false;
2478
2479 // Try to parse this as either date and time, only date or only time
2480 // checking that the entire string was parsed
2481 wxString::const_iterator end;
2482 if ( value->ParseDateTime(val, &end) && end == val.end() )
2483 return true;
2484
2485 if ( value->ParseDate(val, &end) && end == val.end() )
2486 return true;
2487
2488 if ( value->ParseTime(val, &end) && end == val.end() )
2489 return true;
2490
2491 return false;
edca7a82 2492}
b1e343f2 2493#endif // wxUSE_DATETIME
d5dc103f
VZ
2494
2495#endif // wxUSE_VARIANT