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