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