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