]> git.saurik.com Git - wxWidgets.git/blob - src/common/variant.cpp
fixed GTK critical warning when closing MDI child (patch 529369)
[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.First();
105 while (node)
106 {
107 wxVariant* var = (wxVariant*) node->Data();
108 m_value.Append(new wxVariant(*var));
109 node = node->Next();
110 }
111 }
112
113 void wxVariantDataList::Clear()
114 {
115 wxNode* node = m_value.First();
116 while (node)
117 {
118 wxVariant* var = (wxVariant*) node->Data();
119 delete var;
120 node = node->Next();
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.First();
133 while (node)
134 {
135 wxVariant* var = (wxVariant*) node->Data();
136 listData.m_value.Append(new wxVariant(*var));
137 node = node->Next();
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.First();
147 wxNode* node2 = listData.GetValue().First();
148 while (node1 && node2)
149 {
150 wxVariant* var1 = (wxVariant*) node1->Data();
151 wxVariant* var2 = (wxVariant*) node2->Data();
152 if ((*var1) != (*var2))
153 return FALSE;
154 node1 = node1->Next();
155 node2 = node2->Next();
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.First();
175 while (node)
176 {
177 wxVariant* var = (wxVariant*) node->Data();
178 if (node != m_value.First())
179 str += wxT(" ");
180 wxString str1;
181 str += var->MakeString();
182 node = node->Next();
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 wxNode* node1 = m_value.First();
256 wxNode* node2 = listData.GetValue().First();
257 while (node1 && node2)
258 {
259 wxString str1 ((wxChar*) node1->Data());
260 wxString str2 ((wxChar*) node2->Data());
261 if (str1 != str2)
262 return FALSE;
263 node1 = node1->Next();
264 node2 = node2->Next();
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 = wxT("");
283 wxNode* node = m_value.First();
284 while (node)
285 {
286 wxChar* s = (wxChar*) node->Data();
287 if (node != m_value.First())
288 str += wxT(" ");
289 str += s;
290 node = node->Next();
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
1031 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataVoidPtr, wxVariantData)
1032
1033 void wxVariantDataVoidPtr::Copy(wxVariantData& data)
1034 {
1035 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Copy: Can't copy to this type of data") );
1036
1037 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1038
1039 otherData.m_value = m_value;
1040 }
1041
1042 bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
1043 {
1044 wxASSERT_MSG( (data.GetType() == wxT("void*")), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
1045
1046 wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
1047
1048 return (otherData.m_value == m_value);
1049 }
1050
1051 #if wxUSE_STD_IOSTREAM
1052 bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
1053 {
1054 wxString s;
1055 Write(s);
1056 str << (const char*) s.mb_str();
1057 return TRUE;
1058 }
1059 #endif
1060
1061 bool wxVariantDataVoidPtr::Write(wxString& str) const
1062 {
1063 str.Printf(wxT("%ld"), (long) m_value);
1064 return TRUE;
1065 }
1066
1067 #if wxUSE_STD_IOSTREAM
1068 bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
1069 {
1070 // Not implemented
1071 return FALSE;
1072 }
1073 #endif
1074
1075 bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
1076 {
1077 // Not implemented
1078 return FALSE;
1079 }
1080
1081 /*
1082 * wxVariantDataDateTime
1083 */
1084
1085 class wxVariantDataDateTime: public wxVariantData
1086 {
1087 DECLARE_DYNAMIC_CLASS(wxVariantDataDateTime)
1088
1089 public:
1090 wxVariantDataDateTime() { }
1091 wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
1092 #if wxUSE_ODBC
1093 wxVariantDataDateTime(const TIME_STRUCT* valptr)
1094 { m_value = wxDateTime(valptr->hour, valptr->minute, valptr->second); }
1095 wxVariantDataDateTime(const DATE_STRUCT* valptr)
1096 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1),valptr->year); }
1097 wxVariantDataDateTime(const TIMESTAMP_STRUCT* valptr)
1098 { m_value = wxDateTime(valptr->day, (wxDateTime::Month) (valptr->month - 1), valptr->year,
1099 valptr->hour, valptr->minute, valptr->second, valptr->fraction ); }
1100 #endif //ODBC
1101
1102 inline wxDateTime GetValue() const { return m_value; }
1103 inline void SetValue(const wxDateTime& value) { m_value = value; }
1104
1105 virtual void Copy(wxVariantData& data);
1106 virtual bool Eq(wxVariantData& data) const;
1107 #if wxUSE_STD_IOSTREAM
1108 virtual bool Write(wxSTD ostream& str) const;
1109 #endif
1110 virtual bool Write(wxString& str) const;
1111 #if wxUSE_STD_IOSTREAM
1112 virtual bool Read(wxSTD istream& str);
1113 #endif
1114 virtual bool Read(wxString& str);
1115 virtual wxString GetType() const { return wxT("datetime"); };
1116 virtual wxVariantData* Clone() { return new wxVariantDataDateTime; }
1117
1118 protected:
1119 wxDateTime m_value;
1120 };
1121
1122
1123 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataDateTime, wxVariantData)
1124
1125 void wxVariantDataDateTime::Copy(wxVariantData& data)
1126 {
1127 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Copy: Can't copy to this type of data") );
1128
1129 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1130
1131 otherData.m_value = m_value;
1132 }
1133
1134
1135 bool wxVariantDataDateTime::Eq(wxVariantData& data) const
1136 {
1137 wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
1138
1139 wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
1140
1141 return (otherData.m_value == m_value);
1142 }
1143
1144
1145 #if wxUSE_STD_IOSTREAM
1146 bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
1147 {
1148 // Not implemented
1149 return FALSE;
1150 }
1151 #endif
1152
1153
1154 bool wxVariantDataDateTime::Write(wxString& str) const
1155 {
1156 str = m_value.Format();
1157 return TRUE;
1158 }
1159
1160
1161 #if wxUSE_STD_IOSTREAM
1162 bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
1163 {
1164 // Not implemented
1165 return FALSE;
1166 }
1167 #endif
1168
1169
1170 bool wxVariantDataDateTime::Read(wxString& str)
1171 {
1172 if(! m_value.ParseDateTime(str))
1173 return FALSE;
1174 return TRUE;
1175 }
1176
1177 // ----------------------------------------------------------------------------
1178 // wxVariantDataArrayString
1179 // ----------------------------------------------------------------------------
1180
1181 class wxVariantDataArrayString: public wxVariantData
1182 {
1183 public:
1184 wxVariantDataArrayString() { }
1185 wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
1186
1187 wxArrayString GetValue() const { return m_value; }
1188 void SetValue(const wxArrayString& value) { m_value = value; }
1189
1190 virtual void Copy(wxVariantData& data);
1191 virtual bool Eq(wxVariantData& data) const;
1192 #if wxUSE_STD_IOSTREAM
1193 virtual bool Write(wxSTD ostream& str) const;
1194 #endif
1195 virtual bool Write(wxString& str) const;
1196 #if wxUSE_STD_IOSTREAM
1197 virtual bool Read(wxSTD istream& str);
1198 #endif
1199 virtual bool Read(wxString& str);
1200 virtual wxString GetType() const { return wxT("arrstring"); };
1201 virtual wxVariantData* Clone() { return new wxVariantDataArrayString; }
1202
1203 protected:
1204 wxArrayString m_value;
1205
1206 DECLARE_DYNAMIC_CLASS(wxVariantDataArrayString)
1207 };
1208
1209 IMPLEMENT_DYNAMIC_CLASS(wxVariantDataArrayString, wxVariantData)
1210
1211 void wxVariantDataArrayString::Copy(wxVariantData& data)
1212 {
1213 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Copy: Can't copy to this type of data") );
1214
1215 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1216
1217 otherData.m_value = m_value;
1218 }
1219
1220
1221 bool wxVariantDataArrayString::Eq(wxVariantData& data) const
1222 {
1223 wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
1224
1225 wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
1226
1227 return otherData.m_value == m_value;
1228 }
1229
1230
1231 #if wxUSE_STD_IOSTREAM
1232 bool wxVariantDataArrayString::Write(wxSTD ostream& str) const
1233 {
1234 // Not implemented
1235 return FALSE;
1236 }
1237 #endif
1238
1239
1240 bool wxVariantDataArrayString::Write(wxString& str) const
1241 {
1242 size_t count = m_value.GetCount();
1243 for ( size_t n = 0; n < count; n++ )
1244 {
1245 if ( n )
1246 str += _T(';');
1247
1248 str += m_value[n];
1249 }
1250
1251 return TRUE;
1252 }
1253
1254
1255 #if wxUSE_STD_IOSTREAM
1256 bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
1257 {
1258 // Not implemented
1259 return FALSE;
1260 }
1261 #endif
1262
1263
1264 bool wxVariantDataArrayString::Read(wxString& str)
1265 {
1266 wxStringTokenizer tk(str, _T(";"));
1267 while ( tk.HasMoreTokens() )
1268 {
1269 m_value.Add(tk.GetNextToken());
1270 }
1271
1272 return TRUE;
1273 }
1274
1275
1276
1277 /*
1278 * wxVariant
1279 */
1280
1281 IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
1282
1283 // Construction & destruction
1284 wxVariant::wxVariant()
1285 {
1286 m_data = (wxVariantData*) NULL;
1287 }
1288
1289 wxVariant::wxVariant(double val, const wxString& name)
1290 {
1291 m_data = new wxVariantDataReal(val);
1292 m_name = name;
1293 }
1294
1295 wxVariant::wxVariant(long val, const wxString& name)
1296 {
1297 m_data = new wxVariantDataLong(val);
1298 m_name = name;
1299 }
1300
1301 #ifdef HAVE_BOOL
1302 wxVariant::wxVariant(bool val, const wxString& name)
1303 {
1304 m_data = new wxVariantDataBool(val);
1305 m_name = name;
1306 }
1307 #endif
1308
1309 wxVariant::wxVariant(char val, const wxString& name)
1310 {
1311 m_data = new wxVariantDataChar(val);
1312 m_name = name;
1313 }
1314
1315 wxVariant::wxVariant(const wxString& val, const wxString& name)
1316 {
1317 m_data = new wxVariantDataString(val);
1318 m_name = name;
1319 }
1320
1321 wxVariant::wxVariant(const wxChar* val, const wxString& name)
1322 {
1323 m_data = new wxVariantDataString(wxString(val));
1324 m_name = name;
1325 }
1326
1327 wxVariant::wxVariant(const wxStringList& val, const wxString& name)
1328 {
1329 m_data = new wxVariantDataStringList(val);
1330 m_name = name;
1331 }
1332
1333 wxVariant::wxVariant(const wxList& val, const wxString& name) // List of variants
1334 {
1335 m_data = new wxVariantDataList(val);
1336 m_name = name;
1337 }
1338
1339 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1340 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
1341 wxVariant::wxVariant(const wxTime& val, const wxString& name) // Time
1342 {
1343 m_data = new wxVariantDataTime(val);
1344 m_name = name;
1345 }
1346
1347 wxVariant::wxVariant(const wxDate& val, const wxString& name) // Date
1348 {
1349 m_data = new wxVariantDataDate(val);
1350 m_name = name;
1351 }
1352 #endif
1353
1354 wxVariant::wxVariant(void* val, const wxString& name) // Void ptr
1355 {
1356 m_data = new wxVariantDataVoidPtr(val);
1357 m_name = name;
1358 }
1359
1360 wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
1361 {
1362 m_data = new wxVariantDataDateTime(val);
1363 m_name = name;
1364 }
1365
1366 #if wxUSE_ODBC
1367 wxVariant::wxVariant(const TIME_STRUCT* valptr, const wxString& name) // Date
1368 {
1369 m_data = new wxVariantDataDateTime(valptr);
1370 m_name = name;
1371 }
1372
1373 wxVariant::wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name) // Date
1374 {
1375 m_data = new wxVariantDataDateTime(valptr);
1376 m_name = name;
1377 }
1378
1379 wxVariant::wxVariant(const DATE_STRUCT* valptr, const wxString& name) // Date
1380 {
1381 m_data = new wxVariantDataDateTime(valptr);
1382 m_name = name;
1383 }
1384 #endif // wxUSE_ODBC
1385
1386 wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
1387 {
1388 m_data = new wxVariantDataArrayString(val);
1389 m_name = name;
1390 }
1391
1392 wxVariant::wxVariant(const wxVariant& variant)
1393 {
1394 if (!variant.IsNull())
1395 {
1396 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1397 variant.m_data->Copy(*m_data);
1398 }
1399 else
1400 m_data = (wxVariantData*) NULL;
1401 m_name = variant.m_name;
1402 }
1403
1404 wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
1405 {
1406 m_data = data;
1407 m_name = name;
1408 }
1409
1410 wxVariant::~wxVariant()
1411 {
1412 delete m_data;
1413 }
1414
1415
1416 // Make NULL (i.e. delete the data)
1417 void wxVariant::MakeNull()
1418 {
1419 delete m_data;
1420 m_data = NULL;
1421 }
1422
1423 // Generic operators
1424 // Assignment
1425 void wxVariant::operator= (const wxVariant& variant)
1426 {
1427 if (variant.IsNull())
1428 {
1429 MakeNull();
1430 return;
1431 }
1432
1433 if (IsNull() || (GetType() != variant.GetType()))
1434 {
1435 if (m_data)
1436 delete m_data;
1437 m_data = (wxVariantData*) variant.GetData()->GetClassInfo()->CreateObject();
1438 }
1439
1440 variant.GetData()->Copy(* GetData());
1441
1442 m_name = variant.m_name;
1443 }
1444
1445 // Assignment using data, e.g.
1446 // myVariant = new wxStringVariantData("hello")
1447 void wxVariant::operator= (wxVariantData* variantData)
1448 {
1449 MakeNull();
1450 m_data = variantData;
1451 }
1452
1453 bool wxVariant::operator== (const wxVariant& variant) const
1454 {
1455 if (IsNull() || variant.IsNull())
1456 return (IsNull() == variant.IsNull());
1457
1458 return (GetData()->Eq(* variant.GetData()));
1459 }
1460
1461 bool wxVariant::operator!= (const wxVariant& variant) const
1462 {
1463 return (!(*this == variant));
1464 }
1465
1466
1467 // Specific operators
1468 bool wxVariant::operator== (double value) const
1469 {
1470 double thisValue;
1471 if (!Convert(&thisValue))
1472 return FALSE;
1473 else
1474 return (value == thisValue);
1475 }
1476
1477 bool wxVariant::operator!= (double value) const
1478 {
1479 return (!((*this) == value));
1480 }
1481
1482 void wxVariant::operator= (double value)
1483 {
1484 if (GetType() == wxT("double"))
1485 {
1486 ((wxVariantDataReal*)GetData())->SetValue(value);
1487 }
1488 else
1489 {
1490 if (m_data)
1491 delete m_data;
1492 m_data = new wxVariantDataReal(value);
1493 }
1494 }
1495
1496 bool wxVariant::operator== (long value) const
1497 {
1498 long thisValue;
1499 if (!Convert(&thisValue))
1500 return FALSE;
1501 else
1502 return (value == thisValue);
1503 }
1504
1505 bool wxVariant::operator!= (long value) const
1506 {
1507 return (!((*this) == value));
1508 }
1509
1510 void wxVariant::operator= (long value)
1511 {
1512 if (GetType() == wxT("long"))
1513 {
1514 ((wxVariantDataLong*)GetData())->SetValue(value);
1515 }
1516 else
1517 {
1518 if (m_data)
1519 delete m_data;
1520 m_data = new wxVariantDataLong(value);
1521 }
1522 }
1523
1524 bool wxVariant::operator== (char value) const
1525 {
1526 char thisValue;
1527 if (!Convert(&thisValue))
1528 return FALSE;
1529 else
1530 return (value == thisValue);
1531 }
1532
1533 bool wxVariant::operator!= (char value) const
1534 {
1535 return (!((*this) == value));
1536 }
1537
1538 void wxVariant::operator= (char value)
1539 {
1540 if (GetType() == wxT("char"))
1541 {
1542 ((wxVariantDataChar*)GetData())->SetValue(value);
1543 }
1544 else
1545 {
1546 if (m_data)
1547 delete m_data;
1548 m_data = new wxVariantDataChar(value);
1549 }
1550 }
1551
1552 #ifdef HAVE_BOOL
1553 bool wxVariant::operator== (bool value) const
1554 {
1555 bool thisValue;
1556 if (!Convert(&thisValue))
1557 return FALSE;
1558 else
1559 return (value == thisValue);
1560 }
1561
1562 bool wxVariant::operator!= (bool value) const
1563 {
1564 return (!((*this) == value));
1565 }
1566
1567 void wxVariant::operator= (bool value)
1568 {
1569 if (GetType() == wxT("bool"))
1570 {
1571 ((wxVariantDataBool*)GetData())->SetValue(value);
1572 }
1573 else
1574 {
1575 if (m_data)
1576 delete m_data;
1577 m_data = new wxVariantDataBool(value);
1578 }
1579 }
1580 #endif // HAVE_BOOL
1581
1582 bool wxVariant::operator== (const wxString& value) const
1583 {
1584 wxString thisValue;
1585 if (!Convert(&thisValue))
1586 return FALSE;
1587
1588 return value == thisValue;
1589 }
1590
1591 bool wxVariant::operator!= (const wxString& value) const
1592 {
1593 return (!((*this) == value));
1594 }
1595
1596 void wxVariant::operator= (const wxString& value)
1597 {
1598 if (GetType() == wxT("string"))
1599 {
1600 ((wxVariantDataString*)GetData())->SetValue(value);
1601 }
1602 else
1603 {
1604 if (m_data)
1605 delete m_data;
1606 m_data = new wxVariantDataString(value);
1607 }
1608 }
1609
1610 void wxVariant::operator= (const wxChar* value)
1611 {
1612 if (GetType() == wxT("string"))
1613 {
1614 ((wxVariantDataString*)GetData())->SetValue(wxString(value));
1615 }
1616 else
1617 {
1618 if (m_data)
1619 delete m_data;
1620 m_data = new wxVariantDataString(wxString(value));
1621 }
1622 }
1623
1624 bool wxVariant::operator== (const wxStringList& value) const
1625 {
1626 wxASSERT_MSG( (GetType() == wxT("stringlist")), wxT("Invalid type for == operator") );
1627
1628 wxVariantDataStringList other(value);
1629 return (m_data->Eq(other));
1630 }
1631
1632 bool wxVariant::operator!= (const wxStringList& value) const
1633 {
1634 return (!((*this) == value));
1635 }
1636
1637 void wxVariant::operator= (const wxStringList& value)
1638 {
1639 if (GetType() == wxT("stringlist"))
1640 {
1641 ((wxVariantDataStringList*)GetData())->SetValue(value);
1642 }
1643 else
1644 {
1645 if (m_data)
1646 delete m_data;
1647 m_data = new wxVariantDataStringList(value);
1648 }
1649 }
1650
1651 bool wxVariant::operator== (const wxList& value) const
1652 {
1653 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
1654
1655 wxVariantDataList other(value);
1656 return (m_data->Eq(other));
1657 }
1658
1659 bool wxVariant::operator!= (const wxList& value) const
1660 {
1661 return (!((*this) == value));
1662 }
1663
1664 void wxVariant::operator= (const wxList& value)
1665 {
1666 if (GetType() == wxT("list"))
1667 {
1668 ((wxVariantDataList*)GetData())->SetValue(value);
1669 }
1670 else
1671 {
1672 if (m_data)
1673 delete m_data;
1674 m_data = new wxVariantDataList(value);
1675 }
1676 }
1677
1678 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
1679 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
1680 bool wxVariant::operator== (const wxTime& value) const
1681 {
1682 wxTime thisValue;
1683 if (!Convert(&thisValue))
1684 return FALSE;
1685
1686 return value == thisValue;
1687 }
1688
1689 bool wxVariant::operator!= (const wxTime& value) const
1690 {
1691 return (!((*this) == value));
1692 }
1693
1694 void wxVariant::operator= (const wxTime& value)
1695 {
1696 if (GetType() == wxT("time"))
1697 {
1698 ((wxVariantDataTime*)GetData())->SetValue(value);
1699 }
1700 else
1701 {
1702 if (m_data)
1703 delete m_data;
1704 m_data = new wxVariantDataTime(value);
1705 }
1706 }
1707
1708 bool wxVariant::operator== (const wxDate& value) const
1709 {
1710 wxDate thisValue;
1711 if (!Convert(&thisValue))
1712 return FALSE;
1713
1714 return (value == thisValue);
1715 }
1716
1717 bool wxVariant::operator!= (const wxDate& value) const
1718 {
1719 return (!((*this) == value));
1720 }
1721
1722 void wxVariant::operator= (const wxDate& value)
1723 {
1724 if (GetType() == wxT("date"))
1725 {
1726 ((wxVariantDataTime*)GetData())->SetValue(value);
1727 }
1728 else
1729 {
1730 if (m_data)
1731 delete m_data;
1732 m_data = new wxVariantDataDate(value);
1733 }
1734 }
1735 #endif
1736
1737 bool wxVariant::operator== (void* value) const
1738 {
1739 return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
1740 }
1741
1742 bool wxVariant::operator!= (void* value) const
1743 {
1744 return (!((*this) == (void*) value));
1745 }
1746
1747 void wxVariant::operator= (void* value)
1748 {
1749 if (GetType() == wxT("void*"))
1750 {
1751 ((wxVariantDataVoidPtr*)GetData())->SetValue(value);
1752 }
1753 else
1754 {
1755 if (m_data)
1756 delete m_data;
1757 m_data = new wxVariantDataVoidPtr(value);
1758 }
1759 }
1760
1761 bool wxVariant::operator== (const wxDateTime& value) const
1762 {
1763 wxDateTime thisValue;
1764 if (!Convert(&thisValue))
1765 return FALSE;
1766
1767 return value.IsEqualTo(thisValue);
1768 }
1769
1770 bool wxVariant::operator!= (const wxDateTime& value) const
1771 {
1772 return (!((*this) == value));
1773 }
1774
1775 void wxVariant::operator= (const wxDateTime& value)
1776 {
1777 if (GetType() == wxT("datetime"))
1778 {
1779 ((wxVariantDataDateTime*)GetData())->SetValue(value);
1780 }
1781 else
1782 {
1783 if (m_data)
1784 delete m_data;
1785 m_data = new wxVariantDataDateTime(value);
1786 }
1787 }
1788
1789 #if wxUSE_ODBC
1790 void wxVariant::operator= (const DATE_STRUCT* value)
1791 {
1792 if (m_data)
1793 delete m_data;
1794 m_data = new wxVariantDataDateTime(value);
1795 }
1796
1797
1798 void wxVariant::operator= (const TIME_STRUCT* value)
1799 {
1800 if (m_data)
1801 delete m_data;
1802 m_data = new wxVariantDataDateTime(value);
1803 }
1804
1805
1806 void wxVariant::operator= (const TIMESTAMP_STRUCT* value)
1807 {
1808 if (m_data)
1809 delete m_data;
1810 m_data = new wxVariantDataDateTime(value);
1811 }
1812
1813 #endif // wxUSE_ODBC
1814
1815 bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
1816 {
1817 wxFAIL_MSG( _T("TODO") );
1818
1819 return FALSE;
1820 }
1821
1822 bool wxVariant::operator!=(const wxArrayString& value) const
1823 {
1824 return !(*this == value);
1825 }
1826
1827 void wxVariant::operator=(const wxArrayString& value)
1828 {
1829 if (GetType() == wxT("arrstring"))
1830 {
1831 ((wxVariantDataArrayString *)GetData())->SetValue(value);
1832 }
1833 else
1834 {
1835 delete m_data;
1836 m_data = new wxVariantDataArrayString(value);
1837 }
1838 }
1839
1840 wxArrayString wxVariant::GetArrayString() const
1841 {
1842 if ( GetType() == wxT("arrstring") )
1843 return ((wxVariantDataArrayString *)GetData())->GetValue();
1844
1845 return wxArrayString();
1846 }
1847
1848
1849 // Treat a list variant as an array
1850 wxVariant wxVariant::operator[] (size_t idx) const
1851 {
1852 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for array operator") );
1853
1854 if (GetType() == wxT("list"))
1855 {
1856 wxVariantDataList* data = (wxVariantDataList*) m_data;
1857 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
1858 return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1859 }
1860 else if (GetType() == wxT("stringlist"))
1861 {
1862 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1863 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
1864
1865 wxVariant variant( wxString( (wxChar*) (data->GetValue().Nth(idx)->Data()) ));
1866 return variant;
1867 }
1868 return wxNullVariant;
1869 }
1870
1871 wxVariant& wxVariant::operator[] (size_t idx)
1872 {
1873 // We can't return a reference to a variant for a string list, since the string
1874 // is actually stored as a char*, not a variant.
1875
1876 wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
1877
1878 wxVariantDataList* data = (wxVariantDataList*) m_data;
1879 wxASSERT_MSG( (idx < (size_t) data->GetValue().Number()), wxT("Invalid index for array") );
1880
1881 return * (wxVariant*) (data->GetValue().Nth(idx)->Data());
1882 }
1883
1884 // Return the number of elements in a list
1885 int wxVariant::GetCount() const
1886 {
1887 wxASSERT_MSG( (GetType() == wxT("list") || GetType() == wxT("stringlist")), wxT("Invalid type for GetCount()") );
1888
1889 if (GetType() == wxT("list"))
1890 {
1891 wxVariantDataList* data = (wxVariantDataList*) m_data;
1892 return data->GetValue().Number();
1893 }
1894 else if (GetType() == wxT("stringlist"))
1895 {
1896 wxVariantDataStringList* data = (wxVariantDataStringList*) m_data;
1897 return data->GetValue().Number();
1898 }
1899 return 0;
1900 }
1901
1902 wxString wxVariant::MakeString() const
1903 {
1904 if (!IsNull())
1905 {
1906 wxString str;
1907 if (GetData()->Write(str))
1908 return str;
1909 }
1910 return wxString(wxT(""));
1911 }
1912
1913 // Accessors
1914
1915 void wxVariant::SetData(wxVariantData* data)
1916 {
1917 if (m_data) delete m_data;
1918 m_data = data;
1919 }
1920
1921
1922 // Returns a string representing the type of the variant,
1923 // e.g. "string", "bool", "stringlist", "list", "double", "long"
1924 wxString wxVariant::GetType() const
1925 {
1926 if (IsNull())
1927 return wxString(wxT("null"));
1928 else
1929 return m_data->GetType();
1930 }
1931
1932
1933 bool wxVariant::IsType(const wxString& type) const
1934 {
1935 return (GetType() == type);
1936 }
1937
1938
1939 // Value accessors
1940 double wxVariant::GetReal() const
1941 {
1942 double value;
1943 if (Convert(& value))
1944 return value;
1945 else
1946 {
1947 wxFAIL_MSG(wxT("Could not convert to a real number"));
1948 return 0.0;
1949 }
1950 }
1951
1952 long wxVariant::GetInteger() const
1953 {
1954 long value;
1955 if (Convert(& value))
1956 return value;
1957 else
1958 {
1959 wxFAIL_MSG(wxT("Could not convert to an integer"));
1960 return 0;
1961 }
1962 }
1963
1964 char wxVariant::GetChar() const
1965 {
1966 char value;
1967 if (Convert(& value))
1968 return value;
1969 else
1970 {
1971 wxFAIL_MSG(wxT("Could not convert to a char"));
1972 return 0;
1973 }
1974 }
1975
1976 bool wxVariant::GetBool() const
1977 {
1978 bool value;
1979 if (Convert(& value))
1980 return value;
1981 else
1982 {
1983 wxFAIL_MSG(wxT("Could not convert to a bool"));
1984 return 0;
1985 }
1986 }
1987
1988 wxString wxVariant::GetString() const
1989 {
1990 wxString value;
1991 if (!Convert(& value))
1992 {
1993 wxFAIL_MSG(wxT("Could not convert to a string"));
1994 }
1995
1996 return value;
1997 }
1998
1999 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
2000 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
2001 wxTime wxVariant::GetTime() const
2002 {
2003 wxTime value;
2004 if (!Convert(& value))
2005 {
2006 wxFAIL_MSG(wxT("Could not convert to a time"));
2007 }
2008
2009 return value;
2010 }
2011
2012 wxDate wxVariant::GetDate() const
2013 {
2014 wxDate value;
2015 if (!Convert(& value))
2016 {
2017 wxFAIL_MSG(wxT("Could not convert to a date"));
2018 }
2019
2020 return value;
2021 }
2022 #endif // wxUSE_TIMEDATE
2023
2024 void* wxVariant::GetVoidPtr() const
2025 {
2026 wxASSERT( (GetType() == wxT("void*")) );
2027
2028 return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
2029 }
2030
2031 wxDateTime wxVariant::GetDateTime() const
2032 {
2033 wxDateTime value;
2034 if (!Convert(& value))
2035 {
2036 wxFAIL_MSG(wxT("Could not convert to a datetime"));
2037 }
2038
2039 return value;
2040 }
2041
2042 wxList& wxVariant::GetList() const
2043 {
2044 wxASSERT( (GetType() == wxT("list")) );
2045
2046 return (wxList&) ((wxVariantDataList*) m_data)->GetValue();
2047 }
2048
2049 wxStringList& wxVariant::GetStringList() const
2050 {
2051 wxASSERT( (GetType() == wxT("stringlist")) );
2052
2053 return (wxStringList&) ((wxVariantDataStringList*) m_data)->GetValue();
2054 }
2055
2056 // Append to list
2057 void wxVariant::Append(const wxVariant& value)
2058 {
2059 wxList& list = GetList();
2060
2061 list.Append(new wxVariant(value));
2062 }
2063
2064 // Insert at front of list
2065 void wxVariant::Insert(const wxVariant& value)
2066 {
2067 wxList& list = GetList();
2068
2069 list.Insert(new wxVariant(value));
2070 }
2071
2072 // Returns TRUE if the variant is a member of the list
2073 bool wxVariant::Member(const wxVariant& value) const
2074 {
2075 wxList& list = GetList();
2076
2077 wxNode* node = list.First();
2078 while (node)
2079 {
2080 wxVariant* other = (wxVariant*) node->Data();
2081 if (value == *other)
2082 return TRUE;
2083 node = node->Next();
2084 }
2085 return FALSE;
2086 }
2087
2088 // Deletes the nth element of the list
2089 bool wxVariant::Delete(int item)
2090 {
2091 wxList& list = GetList();
2092
2093 wxASSERT_MSG( (item < list.Number()), wxT("Invalid index to Delete") );
2094 wxNode* node = list.Nth(item);
2095 wxVariant* variant = (wxVariant*) node->Data();
2096 delete variant;
2097 delete node;
2098 return TRUE;
2099 }
2100
2101 // Clear list
2102 void wxVariant::ClearList()
2103 {
2104 if (!IsNull() && (GetType() == wxT("list")))
2105 {
2106 ((wxVariantDataList*) m_data)->Clear();
2107 }
2108 else
2109 {
2110 if (GetType() != wxT("list"))
2111 {
2112 delete m_data;
2113 m_data = NULL;
2114 }
2115 m_data = new wxVariantDataList;
2116 }
2117 }
2118
2119 // Type conversion
2120 bool wxVariant::Convert(long* value) const
2121 {
2122 wxString type(GetType());
2123 if (type == wxT("double"))
2124 *value = (long) (((wxVariantDataReal*)GetData())->GetValue());
2125 else if (type == wxT("long"))
2126 *value = ((wxVariantDataLong*)GetData())->GetValue();
2127 #ifdef HAVE_BOOL
2128 else if (type == wxT("bool"))
2129 *value = (long) (((wxVariantDataBool*)GetData())->GetValue());
2130 #endif
2131 else if (type == wxT("string"))
2132 *value = wxAtol((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2133 else
2134 return FALSE;
2135
2136 return TRUE;
2137 }
2138
2139 bool wxVariant::Convert(bool* value) const
2140 {
2141 wxString type(GetType());
2142 if (type == wxT("double"))
2143 *value = ((int) (((wxVariantDataReal*)GetData())->GetValue()) != 0);
2144 else if (type == wxT("long"))
2145 *value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
2146 #ifdef HAVE_BOOL
2147 else if (type == wxT("bool"))
2148 *value = ((wxVariantDataBool*)GetData())->GetValue();
2149 #endif
2150 else if (type == wxT("string"))
2151 {
2152 wxString val(((wxVariantDataString*)GetData())->GetValue());
2153 val.MakeLower();
2154 if (val == wxT("true") || val == wxT("yes"))
2155 *value = TRUE;
2156 else if (val == wxT("false") || val == wxT("no"))
2157 *value = FALSE;
2158 else
2159 return FALSE;
2160 }
2161 else
2162 return FALSE;
2163
2164 return TRUE;
2165 }
2166
2167 bool wxVariant::Convert(double* value) const
2168 {
2169 wxString type(GetType());
2170 if (type == wxT("double"))
2171 *value = ((wxVariantDataReal*)GetData())->GetValue();
2172 else if (type == wxT("long"))
2173 *value = (double) (((wxVariantDataLong*)GetData())->GetValue());
2174 #ifdef HAVE_BOOL
2175 else if (type == wxT("bool"))
2176 *value = (double) (((wxVariantDataBool*)GetData())->GetValue());
2177 #endif
2178 else if (type == wxT("string"))
2179 *value = (double) wxAtof((const wxChar*) ((wxVariantDataString*)GetData())->GetValue());
2180 else
2181 return FALSE;
2182
2183 return TRUE;
2184 }
2185
2186 bool wxVariant::Convert(char* value) const
2187 {
2188 wxString type(GetType());
2189 if (type == wxT("char"))
2190 *value = ((wxVariantDataChar*)GetData())->GetValue();
2191 else if (type == wxT("long"))
2192 *value = (char) (((wxVariantDataLong*)GetData())->GetValue());
2193 #ifdef HAVE_BOOL
2194 else if (type == wxT("bool"))
2195 *value = (char) (((wxVariantDataBool*)GetData())->GetValue());
2196 #endif
2197 else
2198 return FALSE;
2199
2200 return TRUE;
2201 }
2202
2203 bool wxVariant::Convert(wxString* value) const
2204 {
2205 *value = MakeString();
2206 return TRUE;
2207 }
2208
2209 // For some reason, Watcom C++ can't link variant.cpp with time/date classes compiled
2210 #if wxUSE_TIMEDATE && !defined(__WATCOMC__)
2211 bool wxVariant::Convert(wxTime* value) const
2212 {
2213 wxString type(GetType());
2214 if (type == wxT("time"))
2215 *value = ((wxVariantDataTime*)GetData())->GetValue();
2216 else if (type == wxT("date"))
2217 *value = wxTime(((wxVariantDataDate*)GetData())->GetValue());
2218 else
2219 return FALSE;
2220
2221 return TRUE;
2222 }
2223
2224 bool wxVariant::Convert(wxDate* value) const
2225 {
2226 wxString type(GetType());
2227 if (type == wxT("date"))
2228 *value = ((wxVariantDataDate*)GetData())->GetValue();
2229 else
2230 return FALSE;
2231
2232 return TRUE;
2233 }
2234 #endif // wxUSE_TIMEDATE
2235
2236 bool wxVariant::Convert(wxDateTime* value) const
2237 {
2238 wxString type(GetType());
2239 if (type == wxT("datetime"))
2240 *value = ((wxVariantDataDateTime*)GetData())->GetValue();
2241 else
2242 return FALSE;
2243
2244 return TRUE;
2245 }