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