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