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