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