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