Split this out from other changes to keep things sane..
[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 #ifdef __GNUG__
13 #pragma implementation "variant.h"
14 #pragma implementation "time.h"
15 #pragma implementation "date.h"
16 #endif
17
18 // For compilers that support precompilation, includes "wx/wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if wxUSE_STD_IOSTREAM
26 #if wxUSE_IOSTREAMH
27 #include <fstream.h>
28 #else
29 #include <fstream>
30 #endif
31 #endif
32
33 #if wxUSE_STREAMS
34 #include "wx/stream.h"
35 #include "wx/txtstrm.h"
36 #endif
37
38 #include "wx/string.h"
39 #include "wx/tokenzr.h"
40
41 #include "wx/variant.h"
42
43 #if wxUSE_TIMEDATE
44 IMPLEMENT_DYNAMIC_CLASS(wxDate, wxObject)
45 IMPLEMENT_DYNAMIC_CLASS(wxTime, wxObject)
46
47 wxTime::tFormat wxTime::ms_Format = wxTime::wx12h;
48 wxTime::tPrecision wxTime::ms_Precision = wxTime::wxStdMinSec;
49 wxChar wxTime::ms_bufTime[128];
50 #endif
51
52 IMPLEMENT_ABSTRACT_CLASS(wxVariantData, wxObject)
53
54 wxVariant WXDLLEXPORT wxNullVariant;
55
56 /*
57 * wxVariantDataList
58 */
59
60 class WXDLLEXPORT wxVariantDataList: public wxVariantData
61 {
62 DECLARE_DYNAMIC_CLASS(wxVariantDataList)
63 public:
64 wxVariantDataList() {}
65 wxVariantDataList(const wxList& list);
66 ~wxVariantDataList();
67
68 wxList& GetValue() const { return (wxList&) m_value; }
69 void SetValue(const wxList& value) ;
70
71 virtual void Copy(wxVariantData& data);
72 virtual bool Eq(wxVariantData& data) const;
73 #if wxUSE_STD_IOSTREAM
74 virtual bool Write(wxSTD ostream& str) const;
75 #endif
76 virtual bool Write(wxString& str) const;
77 #if wxUSE_STD_IOSTREAM
78 virtual bool Read(wxSTD istream& str);
79 #endif
80 virtual bool Read(wxString& str);
81 virtual wxString GetType() const { return wxT("list"); };
82
83 void Clear();
84
85 protected:
86 wxList m_value;
87 };
88
89 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataList, wxVariantData)
90
91 wxVariantDataList::wxVariantDataList(const wxList& list)
92 {
93 SetValue(list);
94 }
95
96 wxVariantDataList::~wxVariantDataList()
97 {
98 Clear();
99 }
100
101 void wxVariantDataList::SetValue(const wxList& value)
102 {
103 Clear();
104 wxNode* node = value.GetFirst();
105 while (node)
106 {
107 wxVariant* var = (wxVariant*) node->GetData();
108 m_value.Append(new wxVariant(*var));
109 node = node->GetNext();
110 }
111 }
112
113 void wxVariantDataList::Clear()
114 {
115 wxNode* node = m_value.GetFirst();
116 while (node)
117 {
118 wxVariant* var = (wxVariant*) node->GetData();
119 delete var;
120 node = node->GetNext();
121 }
122 m_value.Clear();
123 }
124
125 void wxVariantDataList::Copy(wxVariantData& data)
126 {
127 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Copy: Can't copy to this type of data") );
128
129 wxVariantDataList& listData = (wxVariantDataList&) data;
130
131 listData.Clear();
132 wxNode* node = m_value.GetFirst();
133 while (node)
134 {
135 wxVariant* var = (wxVariant*) node->GetData();
136 listData.m_value.Append(new wxVariant(*var));
137 node = node->GetNext();
138 }
139 }
140
141 bool wxVariantDataList::Eq(wxVariantData& data) const
142 {
143 wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
144
145 wxVariantDataList& listData = (wxVariantDataList&) data;
146 wxNode* node1 = m_value.GetFirst();
147 wxNode* node2 = listData.GetValue().GetFirst();
148 while (node1 && node2)
149 {
150 wxVariant* var1 = (wxVariant*) node1->GetData();
151 wxVariant* var2 = (wxVariant*) node2->GetData();
152 if ((*var1) != (*var2))
153 return false;
154 node1 = node1->GetNext();
155 node2 = node2->GetNext();
156 }
157 if (node1 || node2) return false;
158 return true;
159 }
160
161 #if wxUSE_STD_IOSTREAM
162 bool wxVariantDataList::Write(wxSTD ostream& str) const
163 {
164 wxString s;
165 Write(s);
166 str << (const char*) s.mb_str();
167 return true;
168 }
169 #endif
170
171 bool wxVariantDataList::Write(wxString& str) const
172 {
173 str = wxT("");
174 wxNode* node = m_value.GetFirst();
175 while (node)
176 {
177 wxVariant* var = (wxVariant*) node->GetData();
178 if (node != m_value.GetFirst())
179 str += wxT(" ");
180 wxString str1;
181 str += var->MakeString();
182 node = node->GetNext();
183 }
184
185 return true;
186 }
187
188 #if wxUSE_STD_IOSTREAM
189 bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
190 {
191 wxFAIL_MSG(wxT("Unimplemented"));
192 // TODO
193 return false;
194 }
195 #endif
196
197 bool wxVariantDataList::Read(wxString& WXUNUSED(str))
198 {
199 wxFAIL_MSG(wxT("Unimplemented"));
200 // TODO
201 return false;
202 }
203
204 /*
205 * wxVariantDataStringList
206 */
207
208 class WXDLLEXPORT wxVariantDataStringList: public wxVariantData
209 {
210 DECLARE_DYNAMIC_CLASS(wxVariantDataStringList)
211 public:
212 wxVariantDataStringList() {}
213 wxVariantDataStringList(const wxStringList& list) { m_value = list; }
214
215 wxStringList& GetValue() const { return (wxStringList&) m_value; }
216 void SetValue(const wxStringList& value);
217
218 virtual void Copy(wxVariantData& data);
219 virtual bool Eq(wxVariantData& data) const;
220 #if wxUSE_STD_IOSTREAM
221 virtual bool Write(wxSTD ostream& str) const;
222 #endif
223 virtual bool Write(wxString& str) const;
224 #if wxUSE_STD_IOSTREAM
225 virtual bool Read(wxSTD istream& str);
226 #endif
227 virtual bool Read(wxString& str);
228 virtual wxString GetType() const { return wxT("stringlist"); };
229
230 protected:
231 wxStringList m_value;
232 };
233
234 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataStringList, wxVariantData)
235
236 void wxVariantDataStringList::SetValue(const wxStringList& value)
237 {
238 m_value = value;
239 }
240
241 void wxVariantDataStringList::Copy(wxVariantData& data)
242 {
243 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Copy: Can't copy to this type of data") );
244
245 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
246
247 listData.m_value = m_value ;
248 }
249
250 bool wxVariantDataStringList::Eq(wxVariantData& data) const
251 {
252 wxASSERT_MSG( (data.GetType() == wxT("stringlist")), wxT("wxVariantDataStringList::Eq: argument mismatch") );
253
254 wxVariantDataStringList& listData = (wxVariantDataStringList&) data;
255 wxStringList::Node *node1 = m_value.GetFirst();
256 wxStringList::Node *node2 = listData.GetValue().GetFirst();
257 while (node1 && node2)
258 {
259 wxString str1 ( node1->GetData() );
260 wxString str2 ( node2->GetData() );
261 if (str1 != str2)
262 return false;
263 node1 = node1->GetNext();
264 node2 = node2->GetNext();
265 }
266 if (node1 || node2) return false;
267 return true;
268 }
269
270 #if wxUSE_STD_IOSTREAM
271 bool wxVariantDataStringList::Write(wxSTD ostream& str) const
272 {
273 wxString s;
274 Write(s);
275 str << (const char*) s.mb_str();
276 return true;
277 }
278 #endif
279
280 bool wxVariantDataStringList::Write(wxString& str) const
281 {
282 str.Empty();
283 wxStringList::Node *node = m_value.GetFirst();
284 while (node)
285 {
286 wxChar* s = node->GetData();
287 if (node != m_value.GetFirst())
288 str += wxT(" ");
289 str += s;
290 node = node->GetNext();
291 }
292
293 return true;
294 }
295
296 #if wxUSE_STD_IOSTREAM
297 bool wxVariantDataStringList::Read(wxSTD istream& WXUNUSED(str))
298 {
299 wxFAIL_MSG(wxT("Unimplemented"));
300 // TODO
301 return false;
302 }
303 #endif
304
305 bool wxVariantDataStringList::Read(wxString& WXUNUSED(str))
306 {
307 wxFAIL_MSG(wxT("Unimplemented"));
308 // TODO
309 return false;
310 }
311
312 /*
313 * wxVariantDataLong
314 */
315
316 class WXDLLEXPORT 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 WXDLLEXPORT 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 (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("%.4f"), 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 WXDLLEXPORT 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 WXDLLEXPORT 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[(size_t)0];
716 return true;
717 }
718
719 /*
720 * wxVariantDataString
721 */
722
723 #if defined(__BORLANDC__) && defined(__WIN16__)
724 // Change name because of truncation
725 #define wxVariantDataString wxVariantStringData
726 #endif
727
728 class WXDLLEXPORT wxVariantDataString: public wxVariantData
729 {
730 #if defined(__BORLANDC__) && defined(__WIN16__)
731 DECLARE_DYNAMIC_CLASS(wxVariantStringData)
732 #else
733 DECLARE_DYNAMIC_CLASS(wxVariantDataString)
734 #endif
735 public:
736 wxVariantDataString() { }
737 wxVariantDataString(const wxString& value) { m_value = value; }
738
739 inline wxString GetValue() const { return m_value; }
740 inline void SetValue(const wxString& value) { m_value = value; }
741
742 virtual void Copy(wxVariantData& data);
743 virtual bool Eq(wxVariantData& data) const;
744 #if wxUSE_STD_IOSTREAM
745 virtual bool Write(wxSTD ostream& str) const;
746 #endif
747 virtual bool Read(wxString& str);
748 virtual bool Write(wxString& str) const;
749 #if wxUSE_STD_IOSTREAM
750 virtual bool Read(wxSTD istream& str);
751 #endif
752 #if wxUSE_STREAMS
753 virtual bool Read(wxInputStream& str);
754 virtual bool Write(wxOutputStream& str) const;
755 #endif // wxUSE_STREAMS
756 virtual wxString GetType() const { return wxT("string"); };
757
758 protected:
759 wxString m_value;
760 };
761
762 void wxVariantDataString::Copy(wxVariantData& data)
763 {
764 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Copy: Can't copy to this type of data") );
765
766 wxVariantDataString& otherData = (wxVariantDataString&) data;
767
768 otherData.m_value = m_value;
769 }
770
771 bool wxVariantDataString::Eq(wxVariantData& data) const
772 {
773 wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
774
775 wxVariantDataString& otherData = (wxVariantDataString&) data;
776
777 return (otherData.m_value == m_value);
778 }
779
780 #if wxUSE_STD_IOSTREAM
781 bool wxVariantDataString::Write(wxSTD ostream& str) const
782 {
783 str << (const char*) m_value.mb_str();
784 return true;
785 }
786 #endif
787
788 bool wxVariantDataString::Write(wxString& str) const
789 {
790 str = m_value;
791 return true;
792 }
793
794 #if wxUSE_STD_IOSTREAM
795 bool wxVariantDataString::Read(wxSTD istream& str)
796 {
797 str >> m_value;
798 return true;
799 }
800 #endif
801
802 #if wxUSE_STREAMS
803 bool wxVariantDataString::Write(wxOutputStream& str) const
804 {
805 // why doesn't wxOutputStream::operator<< take "const wxString&"
806 wxTextOutputStream s(str);
807 s.WriteString(m_value);
808 return true;
809 }
810
811 bool wxVariantDataString::Read(wxInputStream& str)
812 {
813 wxTextInputStream s(str);
814
815 m_value = s.ReadString();
816 return true;
817 }
818 #endif // wxUSE_STREAMS
819
820 bool wxVariantDataString::Read(wxString& str)
821 {
822 m_value = str;
823 return true;
824 }
825
826 #if defined(__BORLANDC__) && defined(__WIN16__)
827 IMPLEMENT_DYNAMIC_CLASS(wxVariantStringData, wxVariantData)
828 #else
829 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataString, wxVariantData)
830 #endif
831
832 /*
833 * wxVariantDataTime
834 */
835
836 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
837 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
838
839 class wxVariantDataTime: public wxVariantData
840 {
841 DECLARE_DYNAMIC_CLASS(wxVariantDataTime)
842 public:
843 wxVariantDataTime() { }
844 wxVariantDataTime(const wxTime& value) { m_value = value; }
845
846 inline wxTime GetValue() const { return m_value; }
847 inline void SetValue(const wxTime& value) { m_value = value; }
848
849 virtual void Copy(wxVariantData& data);
850 virtual bool Eq(wxVariantData& data) const;
851 #if wxUSE_STD_IOSTREAM
852 virtual bool Write(wxSTD ostream& str) const;
853 #endif
854 virtual bool Write(wxString& str) const;
855 #if wxUSE_STD_IOSTREAM
856 virtual bool Read(wxSTD istream& str);
857 #endif
858 virtual bool Read(wxString& str);
859 virtual wxString GetType() const { return wxT("time"); };
860 virtual wxVariantData* Clone() { return new wxVariantDataTime; }
861
862 protected:
863 wxTime m_value;
864 };
865
866 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataTime, wxVariantData)
867
868 void wxVariantDataTime::Copy(wxVariantData& data)
869 {
870 wxASSERT_MSG( (data.GetType() == wxT("time")), wxT("wxVariantDataTime::Copy: Can't copy to this type of data") );
871
872 wxVariantDataTime& otherData = (wxVariantDataTime&) data;
873
874 otherData.m_value = m_value;
875 }
876
877 bool wxVariantDataTime::Eq(wxVariantData& data) const
878 {
879 wxASSERT_MSG( (data.GetType() == wxT("time")), wxT("wxVariantDataTime::Eq: argument mismatch") );
880
881 wxVariantDataTime& otherData = (wxVariantDataTime&) data;
882
883 return (otherData.m_value == m_value);
884 }
885
886 #if wxUSE_STD_IOSTREAM
887 bool wxVariantDataTime::Write(wxSTD ostream& str) const
888 {
889 wxString s;
890 Write(s);
891 str << (const char*) s.mb_str();
892 return true;
893 }
894 #endif
895
896 bool wxVariantDataTime::Write(wxString& str) const
897 {
898 wxChar*s = m_value.FormatTime();
899 str = s;
900 return true;
901 }
902
903 #if wxUSE_STD_IOSTREAM
904 bool wxVariantDataTime::Read(wxSTD istream& WXUNUSED(str))
905 {
906 // Not implemented
907 return false;
908 }
909 #endif
910
911 bool wxVariantDataTime::Read(wxString& WXUNUSED(str))
912 {
913 // Not implemented
914 return false;
915 }
916
917 /*
918 * wxVariantDataDate
919 */
920
921 class wxVariantDataDate: public wxVariantData
922 {
923 DECLARE_DYNAMIC_CLASS(wxVariantDataDate)
924 public:
925 wxVariantDataDate() { }
926 wxVariantDataDate(const wxDate& value) { m_value = value; }
927
928 inline wxDate GetValue() const { return m_value; }
929 inline void SetValue(const wxDate& value) { m_value = value; }
930
931 virtual void Copy(wxVariantData& data);
932 virtual bool Eq(wxVariantData& data) const;
933 #if wxUSE_STD_IOSTREAM
934 virtual bool Write(wxSTD ostream& str) const;
935 #endif
936 virtual bool Write(wxString& str) const;
937 #if wxUSE_STD_IOSTREAM
938 virtual bool Read(wxSTD istream& str);
939 #endif
940 virtual bool Read(wxString& str);
941 virtual wxString GetType() const { return wxT("date"); };
942 virtual wxVariantData* Clone() { return new wxVariantDataDate; }
943
944 protected:
945 wxDate m_value;
946 };
947
948 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDate, wxVariantData)
949
950 void wxVariantDataDate::Copy(wxVariantData& data)
951 {
952 wxASSERT_MSG( (data.GetType() == wxT("date")), wxT("wxVariantDataDate::Copy: Can't copy to this type of data") );
953
954 wxVariantDataDate& otherData = (wxVariantDataDate&) data;
955
956 otherData.m_value = m_value;
957 }
958
959 bool wxVariantDataDate::Eq(wxVariantData& data) const
960 {
961 wxASSERT_MSG( (data.GetType() == wxT("date")), wxT("wxVariantDataDate::Eq: argument mismatch") );
962
963 wxVariantDataDate& otherData = (wxVariantDataDate&) data;
964
965 return (otherData.m_value == m_value);
966 }
967
968 #if wxUSE_STD_IOSTREAM
969 bool wxVariantDataDate::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 wxVariantDataDate::Write(wxString& str) const
979 {
980 str = m_value.FormatDate();
981 return true;
982 }
983
984 #if wxUSE_STD_IOSTREAM
985 bool wxVariantDataDate::Read(wxSTD istream& WXUNUSED(str))
986 {
987 // Not implemented
988 return false;
989 }
990 #endif
991
992 bool wxVariantDataDate::Read(wxString& WXUNUSED(str))
993 {
994 // Not implemented
995 return false;
996 }
997 #endif
998 // wxUSE_TIMEDATE
999
1000 /*
1001 * wxVariantDataVoidPtr
1002 */
1003
1004 class wxVariantDataVoidPtr: public wxVariantData
1005 {
1006 DECLARE_DYNAMIC_CLASS(wxVariantDataVoidPtr)
1007 public:
1008 wxVariantDataVoidPtr() { }
1009 wxVariantDataVoidPtr(void* value) { m_value = value; }
1010
1011 inline void* GetValue() const { return m_value; }
1012 inline void SetValue(void* value) { m_value = value; }
1013
1014 virtual void Copy(wxVariantData& data);
1015 virtual bool Eq(wxVariantData& data) const;
1016 #if wxUSE_STD_IOSTREAM
1017 virtual bool Write(wxSTD ostream& str) const;
1018 #endif
1019 virtual bool Write(wxString& str) const;
1020 #if wxUSE_STD_IOSTREAM
1021 virtual bool Read(wxSTD istream& str);
1022 #endif
1023 virtual bool Read(wxString& str);
1024 virtual wxString GetType() const { return wxT("void*"); };
1025 virtual wxVariantData* Clone() { return new wxVariantDataVoidPtr; }
1026
1027 protected:
1028 void* m_value;
1029
1030 DECLARE_NO_COPY_CLASS(wxVariantDataVoidPtr)
1031 };
1032
1033 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
1034
1035 void wxVariantDataVoidPtr::Copy(wxVariantData& data)
1036 {
1037 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Copy: Can't copy to this type of data") );
1038
1039 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1040
1041 otherData.m_value = m_value;
1042 }
1043
1044 bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
1045 {
1046 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1047
1048 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1049
1050 return (otherData.m_value == m_value);
1051 }
1052
1053 #if wxUSE_STD_IOSTREAM
1054 bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
1055 {
1056 wxString s;
1057 Write(s);
1058 str << (const char*) s.mb_str();
1059 return true;
1060 }
1061 #endif
1062
1063 bool wxVariantDataVoidPtr::Write(wxString& str) const
1064 {
1065 str.Printf(wxT("%ld"), (long) m_value);
1066 return true;
1067 }
1068
1069 #if wxUSE_STD_IOSTREAM
1070 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
1071 {
1072 // Not implemented
1073 return false;
1074 }
1075 #endif
1076
1077 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
1078 {
1079 // Not implemented
1080 return false;
1081 }
1082
1083 /*
1084 * wxVariantDataDateTime
1085 */
1086
1087 class wxVariantDataDateTime: public wxVariantData
1088 {
1089 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1090
1091 public:
1092 wxVariantDataDateTime() { }
1093 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1094 #if wxUSE_ODBC
1095 wxVariantDataDateTime(const TIME_STRUCT* valptr)
1096 { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1097 wxVariantDataDateTime(const DATE_STRUCT* valptr)
1098 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1099 wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1100 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1101 valptr->hour, valptr->minute, valptr->second, valptr->fraction ); }
1102 #endif //ODBC
1103
1104 inline wxDateTime GetValue() const { return m_value; }
1105 inline void SetValue(const wxDateTime& value) { m_value = value; }
1106
1107 virtual void Copy(wxVariantData& data);
1108 virtual bool Eq(wxVariantData& data) const;
1109 #if wxUSE_STD_IOSTREAM
1110 virtual bool Write(wxSTD ostream& str) const;
1111 #endif
1112 virtual bool Write(wxString& str) const;
1113 #if wxUSE_STD_IOSTREAM
1114 virtual bool Read(wxSTD istream& str);
1115 #endif
1116 virtual bool Read(wxString& str);
1117 virtual wxString GetType() const { return wxT("datetime"); };
1118 virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
1119
1120 protected:
1121 wxDateTime m_value;
1122 };
1123
1124
1125 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1126
1127 void wxVariantDataDateTime::Copy(wxVariantData& data)
1128 {
1129 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Copy: Can't copy to this type of data") );
1130
1131 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1132
1133 otherData.m_value = m_value;
1134 }
1135
1136
1137 bool wxVariantDataDateTime::Eq(wxVariantData& data) const
1138 {
1139 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1140
1141 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1142
1143 return (otherData.m_value == m_value);
1144 }
1145
1146
1147 #if wxUSE_STD_IOSTREAM
1148 bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
1149 {
1150 // Not implemented
1151 return false;
1152 }
1153 #endif
1154
1155
1156 bool wxVariantDataDateTime::Write(wxString& str) const
1157 {
1158 str = m_value.Format();
1159 return true;
1160 }
1161
1162
1163 #if wxUSE_STD_IOSTREAM
1164 bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1165 {
1166 // Not implemented
1167 return false;
1168 }
1169 #endif
1170
1171
1172 bool wxVariantDataDateTime::Read(wxString& str)
1173 {
1174 if(! m_value.ParseDateTime(str))
1175 return false;
1176 return true;
1177 }
1178
1179 // ----------------------------------------------------------------------------
1180 // wxVariantDataArrayString
1181 // ----------------------------------------------------------------------------
1182
1183 class wxVariantDataArrayString: public wxVariantData
1184 {
1185 public:
1186 wxVariantDataArrayString() { }
1187 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
1188
1189 wxArrayString GetValue() const { return m_value; }
1190 void SetValue(const wxArrayString& value) { m_value = value; }
1191
1192 virtual void Copy(wxVariantData& data);
1193 virtual bool Eq(wxVariantData& data) const;
1194 #if wxUSE_STD_IOSTREAM
1195 virtual bool Write(wxSTD ostream& str) const;
1196 #endif
1197 virtual bool Write(wxString& str) const;
1198 #if wxUSE_STD_IOSTREAM
1199 virtual bool Read(wxSTD istream& str);
1200 #endif
1201 virtual bool Read(wxString& str);
1202 virtual wxString GetType() const { return wxT("arrstring"); };
1203 virtual wxVariantData* Clone() { return new wxVariantDataArrayString; }
1204
1205 protected:
1206 wxArrayString m_value;
1207
1208 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1209 };
1210
1211 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1212
1213 void wxVariantDataArrayString::Copy(wxVariantData& data)
1214 {
1215 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Copy: Can't copy to this type of data") );
1216
1217 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1218
1219 otherData.m_value = m_value;
1220 }
1221
1222
1223 bool wxVariantDataArrayString::Eq(wxVariantData& data) const
1224 {
1225 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1226
1227 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1228
1229 return otherData.m_value == m_value;
1230 }
1231
1232
1233 #if wxUSE_STD_IOSTREAM
1234 bool wxVariantDataArrayString::Write(wxSTD ostream& str) const
1235 {
1236 // Not implemented
1237 return false;
1238 }
1239 #endif
1240
1241
1242 bool wxVariantDataArrayString::Write(wxString& str) const
1243 {
1244 size_t count = m_value.GetCount();
1245 for ( size_t n = 0; n < count; n++ )
1246 {
1247 if ( n )
1248 str += _T(';');
1249
1250 str += m_value[n];
1251 }
1252
1253 return true;
1254 }
1255
1256
1257 #if wxUSE_STD_IOSTREAM
1258 bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1259 {
1260 // Not implemented
1261 return false;
1262 }
1263 #endif
1264
1265
1266 bool wxVariantDataArrayString::Read(wxString& str)
1267 {
1268 wxStringTokenizer tk(str, _T(";"));
1269 while ( tk.HasMoreTokens() )
1270 {
1271 m_value.Add(tk.GetNextToken());
1272 }
1273
1274 return true;
1275 }
1276
1277
1278
1279 /*
1280 * wxVariant
1281 */
1282
1283 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
1284
1285 // Construction & destruction
1286 wxVariant::wxVariant()
1287 {
1288 m_data = (wxVariantData*) NULL;
1289 }
1290
1291 wxVariant::wxVariant(double val, const wxString& name)
1292 {
1293 m_data = new wxVariantDataReal(val);
1294 m_name = name;
1295 }
1296
1297 wxVariant::wxVariant(long val, const wxString& name)
1298 {
1299 m_data = new wxVariantDataLong(val);
1300 m_name = name;
1301 }
1302
1303 #ifdef HAVE_BOOL
1304 wxVariant::wxVariant(bool val, const wxString& name)
1305 {
1306 m_data = new wxVariantDataBool(val);
1307 m_name = name;
1308 }
1309 #endif
1310
1311 wxVariant::wxVariant(char val, const wxString& name)
1312 {
1313 m_data = new wxVariantDataChar(val);
1314 m_name = name;
1315 }
1316
1317 wxVariant::wxVariant(const wxString& val, const wxString& name)
1318 {
1319 m_data = new wxVariantDataString(val);
1320 m_name = name;
1321 }
1322
1323 wxVariant::wxVariant(const wxChar* val, const wxString& name)
1324 {
1325 m_data = new wxVariantDataString(wxString(val));
1326 m_name = name;
1327 }
1328
1329 wxVariant::wxVariant(const wxStringList& val, const wxString& name)
1330 {
1331 m_data = new wxVariantDataStringList(val);
1332 m_name = name;
1333 }
1334
1335 wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1336 {
1337 m_data = new wxVariantDataList(val);
1338 m_name = name;
1339 }
1340
1341 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1342 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
1343 wxVariant::wxVariant(const wxTime& val, const wxString& name) // Time
1344 {
1345 m_data = new wxVariantDataTime(val);
1346 m_name = name;
1347 }
1348
1349 wxVariant::wxVariant(const wxDate& val, const wxString& name) // Date
1350 {
1351 m_data = new wxVariantDataDate(val);
1352 m_name = name;
1353 }
1354 #endif
1355
1356 wxVariant::wxVariant(void* val, const wxString& name) // Void ptr
1357 {
1358 m_data = new wxVariantDataVoidPtr(val);
1359 m_name = name;
1360 }
1361
1362 wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1363 {
1364 m_data = new wxVariantDataDateTime(val);
1365 m_name = name;
1366 }
1367
1368 #if wxUSE_ODBC
1369 wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1370 {
1371 m_data = new wxVariantDataDateTime(valptr);
1372 m_name = name;
1373 }
1374
1375 wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1376 {
1377 m_data = new wxVariantDataDateTime(valptr);
1378 m_name = name;
1379 }
1380
1381 wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1382 {
1383 m_data = new wxVariantDataDateTime(valptr);
1384 m_name = name;
1385 }
1386 #endif // wxUSE_ODBC
1387
1388 wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1389 {
1390 m_data = new wxVariantDataArrayString(val);
1391 m_name = name;
1392 }
1393
1394 wxVariant::wxVariant(const wxVariant& variant)
1395 : wxObject()
1396 {
1397 if (!variant.IsNull())
1398 {
1399 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1400 variant.m_data->Copy(*m_data);
1401 }
1402 else
1403 m_data = (wxVariantData*) NULL;
1404 m_name = variant.m_name;
1405 }
1406
1407 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
1408 {
1409 m_data = data;
1410 m_name = name;
1411 }
1412
1413 wxVariant::~wxVariant()
1414 {
1415 delete m_data;
1416 }
1417
1418
1419 // Make NULL (i.e. delete the data)
1420 void wxVariant::MakeNull()
1421 {
1422 delete m_data;
1423 m_data = NULL;
1424 }
1425
1426 // Generic operators
1427 // Assignment
1428 void wxVariant::operator= (const wxVariant& variant)
1429 {
1430 if (variant.IsNull())
1431 {
1432 MakeNull();
1433 return;
1434 }
1435
1436 if (IsNull() || (GetType() != variant.GetType()))
1437 {
1438 if (m_data)
1439 delete m_data;
1440 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1441 }
1442
1443 variant.GetData()->Copy(* GetData());
1444
1445 m_name = variant.m_name;
1446 }
1447
1448 // Assignment using data, e.g.
1449 // myVariant = new wxStringVariantData("hello")
1450 void wxVariant::operator= (wxVariantData* variantData)
1451 {
1452 MakeNull();
1453 m_data = variantData;
1454 }
1455
1456 bool wxVariant::operator== (const wxVariant& variant) const
1457 {
1458 if (IsNull() || variant.IsNull())
1459 return (IsNull() == variant.IsNull());
1460
1461 return (GetData()->Eq(* variant.GetData()));
1462 }
1463
1464 bool wxVariant::operator!= (const wxVariant& variant) const
1465 {
1466 return (!(*this == variant));
1467 }
1468
1469
1470 // Specific operators
1471 bool wxVariant::operator== (double value) const
1472 {
1473 double thisValue;
1474 if (!Convert(&thisValue))
1475 return false;
1476 else
1477 return (value == thisValue);
1478 }
1479
1480 bool wxVariant::operator!= (double value) const
1481 {
1482 return (!((*this) == value));
1483 }
1484
1485 void wxVariant::operator= (double value)
1486 {
1487 if (GetType() == wxT("double"))
1488 {
1489 ((wxVariantDataReal*)GetData())->SetValue(value);
1490 }
1491 else
1492 {
1493 if (m_data)
1494 delete m_data;
1495 m_data = new wxVariantDataReal(value);
1496 }
1497 }
1498
1499 bool wxVariant::operator== (long value) const
1500 {
1501 long thisValue;
1502 if (!Convert(&thisValue))
1503 return false;
1504 else
1505 return (value == thisValue);
1506 }
1507
1508 bool wxVariant::operator!= (long value) const
1509 {
1510 return (!((*this) == value));
1511 }
1512
1513 void wxVariant::operator= (long value)
1514 {
1515 if (GetType() == wxT("long"))
1516 {
1517 ((wxVariantDataLong*)GetData())->SetValue(value);
1518 }
1519 else
1520 {
1521 if (m_data)
1522 delete m_data;
1523 m_data = new wxVariantDataLong(value);
1524 }
1525 }
1526
1527 bool wxVariant::operator== (char value) const
1528 {
1529 char thisValue;
1530 if (!Convert(&thisValue))
1531 return false;
1532 else
1533 return (value == thisValue);
1534 }
1535
1536 bool wxVariant::operator!= (char value) const
1537 {
1538 return (!((*this) == value));
1539 }
1540
1541 void wxVariant::operator= (char value)
1542 {
1543 if (GetType() == wxT("char"))
1544 {
1545 ((wxVariantDataChar*)GetData())->SetValue(value);
1546 }
1547 else
1548 {
1549 if (m_data)
1550 delete m_data;
1551 m_data = new wxVariantDataChar(value);
1552 }
1553 }
1554
1555 #ifdef HAVE_BOOL
1556 bool wxVariant::operator== (bool value) const
1557 {
1558 bool thisValue;
1559 if (!Convert(&thisValue))
1560 return false;
1561 else
1562 return (value == thisValue);
1563 }
1564
1565 bool wxVariant::operator!= (bool value) const
1566 {
1567 return (!((*this) == value));
1568 }
1569
1570 void wxVariant::operator= (bool value)
1571 {
1572 if (GetType() == wxT("bool"))
1573 {
1574 ((wxVariantDataBool*)GetData())->SetValue(value);
1575 }
1576 else
1577 {
1578 if (m_data)
1579 delete m_data;
1580 m_data = new wxVariantDataBool(value);
1581 }
1582 }
1583 #endif // HAVE_BOOL
1584
1585 bool wxVariant::operator== (const wxString& value) const
1586 {
1587 wxString thisValue;
1588 if (!Convert(&thisValue))
1589 return false;
1590
1591 return value == thisValue;
1592 }
1593
1594 bool wxVariant::operator!= (const wxString& value) const
1595 {
1596 return (!((*this) == value));
1597 }
1598
1599 void wxVariant::operator= (const wxString& value)
1600 {
1601 if (GetType() == wxT("string"))
1602 {
1603 ((wxVariantDataString*)GetData())->SetValue(value);
1604 }
1605 else
1606 {
1607 if (m_data)
1608 delete m_data;
1609 m_data = new wxVariantDataString(value);
1610 }
1611 }
1612
1613 void wxVariant::operator= (const wxChar* value)
1614 {
1615 if (GetType() == wxT("string"))
1616 {
1617 ((wxVariantDataString*)GetData())->SetValue(wxString(value));
1618 }
1619 else
1620 {
1621 if (m_data)
1622 delete m_data;
1623 m_data = new wxVariantDataString(wxString(value));
1624 }
1625 }
1626
1627 bool wxVariant::operator== (const wxStringList& value) const
1628 {
1629 wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
1630
1631 wxVariantDataStringList other(value);
1632 return (m_data->Eq(other));
1633 }
1634
1635 bool wxVariant::operator!= (const wxStringList& value) const
1636 {
1637 return (!((*this) == value));
1638 }
1639
1640 void wxVariant::operator= (const wxStringList& value)
1641 {
1642 if (GetType() == wxT("stringlist"))
1643 {
1644 ((wxVariantDataStringList*)GetData())->SetValue(value);
1645 }
1646 else
1647 {
1648 if (m_data)
1649 delete m_data;
1650 m_data = new wxVariantDataStringList(value);
1651 }
1652 }
1653
1654 bool wxVariant::operator== (const wxList& value) const
1655 {
1656 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1657
1658 wxVariantDataList other(value);
1659 return (m_data->Eq(other));
1660 }
1661
1662 bool wxVariant::operator!= (const wxList& value) const
1663 {
1664 return (!((*this) == value));
1665 }
1666
1667 void wxVariant::operator= (const wxList& value)
1668 {
1669 if (GetType() == wxT("list"))
1670 {
1671 ((wxVariantDataList*)GetData())->SetValue(value);
1672 }
1673 else
1674 {
1675 if (m_data)
1676 delete m_data;
1677 m_data = new wxVariantDataList(value);
1678 }
1679 }
1680
1681 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1682 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
1683 bool wxVariant::operator== (const wxTime& value) const
1684 {
1685 wxTime thisValue;
1686 if (!Convert(&thisValue))
1687 return false;
1688
1689 return value == thisValue;
1690 }
1691
1692 bool wxVariant::operator!= (const wxTime& value) const
1693 {
1694 return (!((*this) == value));
1695 }
1696
1697 void wxVariant::operator= (const wxTime& value)
1698 {
1699 if (GetType() == wxT("time"))
1700 {
1701 ((wxVariantDataTime*)GetData())->SetValue(value);
1702 }
1703 else
1704 {
1705 if (m_data)
1706 delete m_data;
1707 m_data = new wxVariantDataTime(value);
1708 }
1709 }
1710
1711 bool wxVariant::operator== (const wxDate& value) const
1712 {
1713 wxDate thisValue;
1714 if (!Convert(&thisValue))
1715 return false;
1716
1717 return (value == thisValue);
1718 }
1719
1720 bool wxVariant::operator!= (const wxDate& value) const
1721 {
1722 return (!((*this) == value));
1723 }
1724
1725 void wxVariant::operator= (const wxDate& value)
1726 {
1727 if (GetType() == wxT("date"))
1728 {
1729 ((wxVariantDataTime*)GetData())->SetValue(value);
1730 }
1731 else
1732 {
1733 if (m_data)
1734 delete m_data;
1735 m_data = new wxVariantDataDate(value);
1736 }
1737 }
1738 #endif
1739
1740 bool wxVariant::operator== (void* value) const
1741 {
1742 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1743 }
1744
1745 bool wxVariant::operator!= (void* value) const
1746 {
1747 return (!((*this) == (void*) value));
1748 }
1749
1750 void wxVariant::operator= (void* value)
1751 {
1752 if (GetType() == wxT("void*"))
1753 {
1754 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1755 }
1756 else
1757 {
1758 if (m_data)
1759 delete m_data;
1760 m_data = new wxVariantDataVoidPtr(value);
1761 }
1762 }
1763
1764 bool wxVariant::operator== (const wxDateTime& value) const
1765 {
1766 wxDateTime thisValue;
1767 if (!Convert(&thisValue))
1768 return false;
1769
1770 return value.IsEqualTo(thisValue);
1771 }
1772
1773 bool wxVariant::operator!= (const wxDateTime& value) const
1774 {
1775 return (!((*this) == value));
1776 }
1777
1778 void wxVariant::operator= (const wxDateTime& value)
1779 {
1780 if (GetType() == wxT("datetime"))
1781 {
1782 ((wxVariantDataDateTime*)GetData())->SetValue(value);
1783 }
1784 else
1785 {
1786 if (m_data)
1787 delete m_data;
1788 m_data = new wxVariantDataDateTime(value);
1789 }
1790 }
1791
1792 #if wxUSE_ODBC
1793 void wxVariant::operator= (const DATE_STRUCT* value)
1794 {
1795 if (m_data)
1796 delete m_data;
1797 m_data = new wxVariantDataDateTime(value);
1798 }
1799
1800
1801 void wxVariant::operator= (const TIME_STRUCT* value)
1802 {
1803 if (m_data)
1804 delete m_data;
1805 m_data = new wxVariantDataDateTime(value);
1806 }
1807
1808
1809 void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1810 {
1811 if (m_data)
1812 delete m_data;
1813 m_data = new wxVariantDataDateTime(value);
1814 }
1815
1816 #endif // wxUSE_ODBC
1817
1818 bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1819 {
1820 wxFAIL_MSG( _T("TODO") );
1821
1822 return false;
1823 }
1824
1825 bool wxVariant::operator!=(const wxArrayString& value) const
1826 {
1827 return !(*this == value);
1828 }
1829
1830 void wxVariant::operator=(const wxArrayString& value)
1831 {
1832 if (GetType() == wxT("arrstring"))
1833 {
1834 ((wxVariantDataArrayString *)GetData())->SetValue(value);
1835 }
1836 else
1837 {
1838 delete m_data;
1839 m_data = new wxVariantDataArrayString(value);
1840 }
1841 }
1842
1843 wxArrayString wxVariant::GetArrayString() const
1844 {
1845 if ( GetType() == wxT("arrstring") )
1846 return ((wxVariantDataArrayString *)GetData())->GetValue();
1847
1848 return wxArrayString();
1849 }
1850
1851
1852 // Treat a list variant as an array
1853 wxVariant wxVariant::operator[] (size_t idx) const
1854 {
1855 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for array operator") );
1856
1857 if (GetType() == wxT("list"))
1858 {
1859 wxVariantDataList* data = (wxVariantDataList*) m_data;
1860 wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1861 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1862 }
1863 else if (GetType() == wxT("stringlist"))
1864 {
1865 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1866 wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1867
1868 wxVariant variant( wxString( (wxChar*) (data->GetValue().Item(idx)->GetData()) ));
1869 return variant;
1870 }
1871 return wxNullVariant;
1872 }
1873
1874 wxVariant& wxVariant::operator[] (size_t idx)
1875 {
1876 // We can't return a reference to a variant for a string list, since the string
1877 // is actually stored as a char*, not a variant.
1878
1879 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1880
1881 wxVariantDataList* data = (wxVariantDataList*) m_data;
1882 wxASSERT_MSG( (idx < (size_t) data->GetValue().GetCount()), wxT("Invalid index for array") );
1883
1884 return * (wxVariant*) (data->GetValue().Item(idx)->GetData());
1885 }
1886
1887 // Return the number of elements in a list
1888 int wxVariant::GetCount() const
1889 {
1890 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for GetCount()") );
1891
1892 if (GetType() == wxT("list"))
1893 {
1894 wxVariantDataList* data = (wxVariantDataList*) m_data;
1895 return data->GetValue().GetCount();
1896 }
1897 else if (GetType() == wxT("stringlist"))
1898 {
1899 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1900 return data->GetValue().GetCount();
1901 }
1902 return 0;
1903 }
1904
1905 wxString wxVariant::MakeString() const
1906 {
1907 if (!IsNull())
1908 {
1909 wxString str;
1910 if (GetData()->Write(str))
1911 return str;
1912 }
1913 return wxString(wxT(""));
1914 }
1915
1916 // Accessors
1917
1918 void wxVariant::SetData(wxVariantData* data)
1919 {
1920 if (m_data) delete m_data;
1921 m_data = data;
1922 }
1923
1924
1925 // Returns a string representing the type of the variant,
1926 // e.g. "string", "bool", "stringlist", "list", "double", "long"
1927 wxString wxVariant::GetType() const
1928 {
1929 if (IsNull())
1930 return wxString(wxT("null"));
1931 else
1932 return m_data->GetType();
1933 }
1934
1935
1936 bool wxVariant::IsType(const wxString& type) const
1937 {
1938 return (GetType() == type);
1939 }
1940
1941
1942 // Value accessors
1943 double wxVariant::GetReal() const
1944 {
1945 double value;
1946 if (Convert(& value))
1947 return value;
1948 else
1949 {
1950 wxFAIL_MSG(wxT("Could not convert to a real number"));
1951 return 0.0;
1952 }
1953 }
1954
1955 long wxVariant::GetInteger() const
1956 {
1957 long value;
1958 if (Convert(& value))
1959 return value;
1960 else
1961 {
1962 wxFAIL_MSG(wxT("Could not convert to an integer"));
1963 return 0;
1964 }
1965 }
1966
1967 char wxVariant::GetChar() const
1968 {
1969 char value;
1970 if (Convert(& value))
1971 return value;
1972 else
1973 {
1974 wxFAIL_MSG(wxT("Could not convert to a char"));
1975 return 0;
1976 }
1977 }
1978
1979 bool wxVariant::GetBool() const
1980 {
1981 bool value;
1982 if (Convert(& value))
1983 return value;
1984 else
1985 {
1986 wxFAIL_MSG(wxT("Could not convert to a bool"));
1987 return 0;
1988 }
1989 }
1990
1991 wxString wxVariant::GetString() const
1992 {
1993 wxString value;
1994 if (!Convert(& value))
1995 {
1996 wxFAIL_MSG(wxT("Could not convert to a string"));
1997 }
1998
1999 return value;
2000 }
2001
2002 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
2003 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
2004 wxTime wxVariant::GetTime() const
2005 {
2006 wxTime value;
2007 if (!Convert(& value))
2008 {
2009 wxFAIL_MSG(wxT("Could not convert to a time"));
2010 }
2011
2012 return value;
2013 }
2014
2015 wxDate wxVariant::GetDate() const
2016 {
2017 wxDate value;
2018 if (!Convert(& value))
2019 {
2020 wxFAIL_MSG(wxT("Could not convert to a date"));
2021 }
2022
2023 return value;
2024 }
2025 #endif // wxUSE_TIMEDATE
2026
2027 void* wxVariant::GetVoidPtr() const
2028 {
2029 wxASSERT( (GetType() == wxT("void*")) );
2030
2031 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
2032 }
2033
2034 wxDateTime wxVariant::GetDateTime() const
2035 {
2036 wxDateTime value;
2037 if (!Convert(& value))
2038 {
2039 wxFAIL_MSG(wxT("Could not convert to a datetime"));
2040 }
2041
2042 return value;
2043 }
2044
2045 wxList& wxVariant::GetList() const
2046 {
2047 wxASSERT( (GetType() == wxT("list")) );
2048
2049 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
2050 }
2051
2052 wxStringList& wxVariant::GetStringList() const
2053 {
2054 wxASSERT( (GetType() == wxT("stringlist")) );
2055
2056 return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
2057 }
2058
2059 // Make empty list
2060 void wxVariant::NullList()
2061 {
2062 SetData(new wxVariantDataList());
2063 };
2064
2065 // Append to list
2066 void wxVariant::Append(const wxVariant& value)
2067 {
2068 wxList& list = GetList();
2069
2070 list.Append(new wxVariant(value));
2071 }
2072
2073 // Insert at front of list
2074 void wxVariant::Insert(const wxVariant& value)
2075 {
2076 wxList& list = GetList();
2077
2078 list.Insert(new wxVariant(value));
2079 }
2080
2081 // Returns true if the variant is a member of the list
2082 bool wxVariant::Member(const wxVariant& value) const
2083 {
2084 wxList& list = GetList();
2085
2086 wxNode* node = list.GetFirst();
2087 while (node)
2088 {
2089 wxVariant* other = (wxVariant*) node->GetData();
2090 if (value == *other)
2091 return true;
2092 node = node->GetNext();
2093 }
2094 return false;
2095 }
2096
2097 // Deletes the nth element of the list
2098 bool wxVariant::Delete(int item)
2099 {
2100 wxList& list = GetList();
2101
2102 wxASSERT_MSG( (item < (int) list.GetCount()), wxT("Invalid index to Delete") );
2103 wxNode* node = list.Item(item);
2104 wxVariant* variant = (wxVariant*) node->GetData();
2105 delete variant;
2106 delete node;
2107 return true;
2108 }
2109
2110 // Clear list
2111 void wxVariant::ClearList()
2112 {
2113 if (!IsNull() && (GetType() == wxT("list")))
2114 {
2115 ((wxVariantDataList*) m_data)->Clear();
2116 }
2117 else
2118 {
2119 if (GetType() != wxT("list"))
2120 {
2121 delete m_data;
2122 m_data = NULL;
2123 }
2124 m_data = new wxVariantDataList;
2125 }
2126 }
2127
2128 // Type conversion
2129 bool wxVariant::Convert(long* value) const
2130 {
2131 wxString type(GetType());
2132 if (type == wxT("double"))
2133 *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
2134 else if (type == wxT("long"))
2135 *value = ((wxVariantDataLong*)GetData())->GetValue();
2136 #ifdef HAVE_BOOL
2137 else if (type == wxT("bool"))
2138 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2139 #endif
2140 else if (type == wxT("string"))
2141 *value = wxAtol((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2142 else
2143 return false;
2144
2145 return true;
2146 }
2147
2148 bool wxVariant::Convert(bool* value) const
2149 {
2150 wxString type(GetType());
2151 if (type == wxT("double"))
2152 *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
2153 else if (type == wxT("long"))
2154 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
2155 #ifdef HAVE_BOOL
2156 else if (type == wxT("bool"))
2157 *value = ((wxVariantDataBool*)GetData())->GetValue();
2158 #endif
2159 else if (type == wxT("string"))
2160 {
2161 wxString val(((wxVariantDataString*)GetData())->GetValue());
2162 val.MakeLower();
2163 if (val == wxT("true") || val == wxT("yes"))
2164 *value = true;
2165 else if (val == wxT("false") || val == wxT("no"))
2166 *value = false;
2167 else
2168 return false;
2169 }
2170 else
2171 return false;
2172
2173 return true;
2174 }
2175
2176 bool wxVariant::Convert(double* value) const
2177 {
2178 wxString type(GetType());
2179 if (type == wxT("double"))
2180 *value = ((wxVariantDataReal*)GetData())->GetValue();
2181 else if (type == wxT("long"))
2182 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
2183 #ifdef HAVE_BOOL
2184 else if (type == wxT("bool"))
2185 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
2186 #endif
2187 else if (type == wxT("string"))
2188 *value = (double) wxAtof((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2189 else
2190 return false;
2191
2192 return true;
2193 }
2194
2195 bool wxVariant::Convert(char* value) const
2196 {
2197 wxString type(GetType());
2198 if (type == wxT("char"))
2199 *value = ((wxVariantDataChar*)GetData())->GetValue();
2200 else if (type == wxT("long"))
2201 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
2202 #ifdef HAVE_BOOL
2203 else if (type == wxT("bool"))
2204 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2205 #endif
2206 else
2207 return false;
2208
2209 return true;
2210 }
2211
2212 bool wxVariant::Convert(wxString* value) const
2213 {
2214 *value = MakeString();
2215 return true;
2216 }
2217
2218 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
2219 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
2220 bool wxVariant::Convert(wxTime* value) const
2221 {
2222 wxString type(GetType());
2223 if (type == wxT("time"))
2224 *value = ((wxVariantDataTime*)GetData())->GetValue();
2225 else if (type == wxT("date"))
2226 *value = wxTime(((wxVariantDataDate*)GetData())->GetValue());
2227 else
2228 return false;
2229
2230 return true;
2231 }
2232
2233 bool wxVariant::Convert(wxDate* value) const
2234 {
2235 wxString type(GetType());
2236 if (type == wxT("date"))
2237 *value = ((wxVariantDataDate*)GetData())->GetValue();
2238 else
2239 return false;
2240
2241 return true;
2242 }
2243 #endif // wxUSE_TIMEDATE
2244
2245 bool wxVariant::Convert(wxDateTime* value) const
2246 {
2247 wxString type(GetType());
2248 if (type == wxT("datetime"))
2249 {
2250 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
2251 return true;
2252 }
2253 // Fallback to string conversion
2254 wxString val;
2255 return Convert(&val) && (value->ParseDate(val));
2256 }