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