| 1 | ///////////////////////////////////////////////////////////////////////////// |
| 2 | // Name: wx/variant.h |
| 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) Julian Smart |
| 9 | // Licence: wxWindows licence |
| 10 | ///////////////////////////////////////////////////////////////////////////// |
| 11 | |
| 12 | #ifndef _WX_VARIANT_H_ |
| 13 | #define _WX_VARIANT_H_ |
| 14 | |
| 15 | #include "wx/defs.h" |
| 16 | #include "wx/object.h" |
| 17 | #include "wx/string.h" |
| 18 | #include "wx/arrstr.h" |
| 19 | #include "wx/list.h" |
| 20 | |
| 21 | #if wxUSE_DATETIME |
| 22 | #include "wx/datetime.h" |
| 23 | #endif // wxUSE_DATETIME |
| 24 | |
| 25 | #if wxUSE_ODBC |
| 26 | #include "wx/db.h" // will #include sqltypes.h |
| 27 | #endif //ODBC |
| 28 | |
| 29 | #include "wx/iosfwrap.h" |
| 30 | |
| 31 | /* |
| 32 | * wxVariantData stores the actual data in a wxVariant object, |
| 33 | * to allow it to store any type of data. |
| 34 | * Derive from this to provide custom data handling. |
| 35 | * |
| 36 | * TODO: in order to replace wxPropertyValue, we would need |
| 37 | * to consider adding constructors that take pointers to C++ variables, |
| 38 | * or removing that functionality from the wxProperty library. |
| 39 | * Essentially wxPropertyValue takes on some of the wxValidator functionality |
| 40 | * by storing pointers and not just actual values, allowing update of C++ data |
| 41 | * to be handled automatically. Perhaps there's another way of doing this without |
| 42 | * overloading wxVariant with unnecessary functionality. |
| 43 | */ |
| 44 | |
| 45 | class WXDLLIMPEXP_BASE wxVariantData: public wxObject |
| 46 | { |
| 47 | DECLARE_ABSTRACT_CLASS(wxVariantData) |
| 48 | public: |
| 49 | |
| 50 | // Construction & destruction |
| 51 | wxVariantData() {} |
| 52 | |
| 53 | // Override these to provide common functionality |
| 54 | // Copy to data |
| 55 | virtual void Copy(wxVariantData& data) = 0; |
| 56 | virtual bool Eq(wxVariantData& data) const = 0; |
| 57 | #if wxUSE_STD_IOSTREAM |
| 58 | virtual bool Write(wxSTD ostream& str) const = 0; |
| 59 | #endif |
| 60 | virtual bool Write(wxString& str) const = 0; |
| 61 | #if wxUSE_STD_IOSTREAM |
| 62 | virtual bool Read(wxSTD istream& str) = 0; |
| 63 | #endif |
| 64 | virtual bool Read(wxString& str) = 0; |
| 65 | // What type is it? Return a string name. |
| 66 | virtual wxString GetType() const = 0; |
| 67 | // If it based on wxObject return the ClassInfo. |
| 68 | virtual wxClassInfo* GetValueClassInfo() { return NULL; } |
| 69 | }; |
| 70 | |
| 71 | /* |
| 72 | * wxVariant can store any kind of data, but has some basic types |
| 73 | * built in. |
| 74 | * NOTE: this eventually should have a reference-counting implementation. |
| 75 | * PLEASE, if you change it to ref-counting, make sure it doesn't involve bloating |
| 76 | * this class too much. |
| 77 | */ |
| 78 | |
| 79 | class WXDLLIMPEXP_BASE wxVariant: public wxObject |
| 80 | { |
| 81 | DECLARE_DYNAMIC_CLASS(wxVariant) |
| 82 | public: |
| 83 | |
| 84 | // Construction & destruction |
| 85 | wxVariant(); |
| 86 | wxVariant(double val, const wxString& name = wxEmptyString); |
| 87 | wxVariant(long val, const wxString& name = wxEmptyString); |
| 88 | #ifdef HAVE_BOOL |
| 89 | wxVariant(bool val, const wxString& name = wxEmptyString); |
| 90 | #endif |
| 91 | wxVariant(char val, const wxString& name = wxEmptyString); |
| 92 | wxVariant(const wxString& val, const wxString& name = wxEmptyString); |
| 93 | wxVariant(const wxChar* val, const wxString& name = wxEmptyString); // Necessary or VC++ assumes bool! |
| 94 | #if WXWIN_COMPATIBILITY_2_4 |
| 95 | wxDEPRECATED( wxVariant(const wxStringList& val, const wxString& name = wxEmptyString) ); |
| 96 | #endif |
| 97 | wxVariant(const wxList& val, const wxString& name = wxEmptyString); // List of variants |
| 98 | wxVariant(void* ptr, const wxString& name = wxEmptyString); // void* (general purpose) |
| 99 | wxVariant(wxObject* ptr, const wxString& name = wxEmptyString); //wxObject |
| 100 | wxVariant(wxVariantData* data, const wxString& name = wxEmptyString); // User-defined data |
| 101 | #if wxUSE_DATETIME |
| 102 | wxVariant(const wxDateTime& val, const wxString& name = wxEmptyString); // Date |
| 103 | #endif // wxUSE_DATETIME |
| 104 | wxVariant(const wxArrayString& val, const wxString& name = wxEmptyString); // String array |
| 105 | #if wxUSE_ODBC |
| 106 | wxVariant(const DATE_STRUCT* valptr, const wxString& name = wxEmptyString); // DateTime |
| 107 | wxVariant(const TIME_STRUCT* valptr, const wxString& name = wxEmptyString); // DateTime |
| 108 | wxVariant(const TIMESTAMP_STRUCT* valptr, const wxString& name = wxEmptyString); // DateTime |
| 109 | #endif |
| 110 | |
| 111 | wxVariant(const wxVariant& variant); |
| 112 | ~wxVariant(); |
| 113 | |
| 114 | // Generic operators |
| 115 | // Assignment |
| 116 | void operator= (const wxVariant& variant); |
| 117 | |
| 118 | #if wxUSE_DATETIME |
| 119 | bool operator== (const wxDateTime& value) const; |
| 120 | bool operator!= (const wxDateTime& value) const; |
| 121 | void operator= (const wxDateTime& value) ; |
| 122 | #endif // wxUSE_DATETIME |
| 123 | |
| 124 | bool operator== (const wxArrayString& value) const; |
| 125 | bool operator!= (const wxArrayString& value) const; |
| 126 | void operator= (const wxArrayString& value) ; |
| 127 | #if wxUSE_ODBC |
| 128 | void operator= (const DATE_STRUCT* value) ; |
| 129 | void operator= (const TIME_STRUCT* value) ; |
| 130 | void operator= (const TIMESTAMP_STRUCT* value) ; |
| 131 | #endif |
| 132 | |
| 133 | // Assignment using data, e.g. |
| 134 | // myVariant = new wxStringVariantData("hello"); |
| 135 | void operator= (wxVariantData* variantData); |
| 136 | bool operator== (const wxVariant& variant) const; |
| 137 | bool operator!= (const wxVariant& variant) const; |
| 138 | |
| 139 | // Specific operators |
| 140 | bool operator== (double value) const; |
| 141 | bool operator!= (double value) const; |
| 142 | void operator= (double value) ; |
| 143 | bool operator== (long value) const; |
| 144 | bool operator!= (long value) const; |
| 145 | void operator= (long value) ; |
| 146 | bool operator== (char value) const; |
| 147 | bool operator!= (char value) const; |
| 148 | void operator= (char value) ; |
| 149 | #ifdef HAVE_BOOL |
| 150 | bool operator== (bool value) const; |
| 151 | bool operator!= (bool value) const; |
| 152 | void operator= (bool value) ; |
| 153 | #endif |
| 154 | bool operator== (const wxString& value) const; |
| 155 | bool operator!= (const wxString& value) const; |
| 156 | void operator= (const wxString& value) ; |
| 157 | void operator= (const wxChar* value) ; // Necessary or VC++ assumes bool! |
| 158 | #if WXWIN_COMPATIBILITY_2_4 |
| 159 | wxDEPRECATED( bool operator== (const wxStringList& value) const ); |
| 160 | wxDEPRECATED( bool operator!= (const wxStringList& value) const ); |
| 161 | wxDEPRECATED( void operator= (const wxStringList& value) ); |
| 162 | #endif |
| 163 | bool operator== (const wxList& value) const; |
| 164 | bool operator!= (const wxList& value) const; |
| 165 | void operator= (const wxList& value) ; |
| 166 | bool operator== (void* value) const; |
| 167 | bool operator!= (void* value) const; |
| 168 | void operator= (void* value) ; |
| 169 | |
| 170 | // Treat a list variant as an array |
| 171 | wxVariant operator[] (size_t idx) const; |
| 172 | wxVariant& operator[] (size_t idx) ; |
| 173 | |
| 174 | // Implicit conversion to a wxString |
| 175 | inline operator wxString () const { return MakeString(); } |
| 176 | wxString MakeString() const; |
| 177 | |
| 178 | // Other implicit conversions |
| 179 | inline operator double () const { return GetDouble(); } |
| 180 | inline operator char () const { return GetChar(); } |
| 181 | inline operator long () const { return GetLong(); } |
| 182 | inline operator bool () const { return GetBool(); } |
| 183 | inline operator void* () const { return GetVoidPtr(); } |
| 184 | // No implicit conversion to wxObject, as that would really |
| 185 | // confuse people between conversion to our contained data |
| 186 | // and downcasting to see our base type. |
| 187 | #if wxUSE_DATETIME |
| 188 | inline operator wxDateTime () const { return GetDateTime(); } |
| 189 | #endif // wxUSE_DATETIME |
| 190 | |
| 191 | // Accessors |
| 192 | // Sets/gets name |
| 193 | inline void SetName(const wxString& name) { m_name = name; } |
| 194 | inline const wxString& GetName() const { return m_name; } |
| 195 | |
| 196 | // Tests whether there is data |
| 197 | inline bool IsNull() const { return (m_data == (wxVariantData*) NULL); } |
| 198 | |
| 199 | wxVariantData* GetData() const { return m_data; } |
| 200 | void SetData(wxVariantData* data) ; |
| 201 | |
| 202 | // Returns a string representing the type of the variant, |
| 203 | // e.g. "string", "bool", "stringlist", "list", "double", "long" |
| 204 | wxString GetType() const; |
| 205 | |
| 206 | bool IsType(const wxString& type) const; |
| 207 | bool IsValueKindOf(const wxClassInfo* type) const; |
| 208 | |
| 209 | // Return the number of elements in a list |
| 210 | size_t GetCount() const; |
| 211 | |
| 212 | // Value accessors |
| 213 | double GetReal() const ; |
| 214 | inline double GetDouble() const { return GetReal(); }; |
| 215 | long GetInteger() const ; |
| 216 | inline long GetLong() const { return GetInteger(); }; |
| 217 | char GetChar() const ; |
| 218 | bool GetBool() const ; |
| 219 | wxString GetString() const ; |
| 220 | wxList& GetList() const ; |
| 221 | #if WXWIN_COMPATIBILITY_2_4 |
| 222 | wxDEPRECATED( wxStringList& GetStringList() const ); |
| 223 | #endif |
| 224 | void* GetVoidPtr() const ; |
| 225 | wxObject* GetWxObjectPtr() ; |
| 226 | #if wxUSE_DATETIME |
| 227 | wxDateTime GetDateTime() const ; |
| 228 | #endif // wxUSE_DATETIME |
| 229 | wxArrayString GetArrayString() const; |
| 230 | |
| 231 | // Operations |
| 232 | // Make NULL (i.e. delete the data) |
| 233 | void MakeNull(); |
| 234 | |
| 235 | // Make empty list |
| 236 | void NullList(); |
| 237 | |
| 238 | // Append to list |
| 239 | void Append(const wxVariant& value); |
| 240 | |
| 241 | // Insert at front of list |
| 242 | void Insert(const wxVariant& value); |
| 243 | |
| 244 | // Returns true if the variant is a member of the list |
| 245 | bool Member(const wxVariant& value) const; |
| 246 | |
| 247 | // Deletes the nth element of the list |
| 248 | bool Delete(size_t item); |
| 249 | |
| 250 | // Clear list |
| 251 | void ClearList(); |
| 252 | |
| 253 | // Implementation |
| 254 | public: |
| 255 | // Type conversion |
| 256 | bool Convert(long* value) const; |
| 257 | bool Convert(bool* value) const; |
| 258 | bool Convert(double* value) const; |
| 259 | bool Convert(wxString* value) const; |
| 260 | bool Convert(char* value) const; |
| 261 | #if wxUSE_DATETIME |
| 262 | bool Convert(wxDateTime* value) const; |
| 263 | #endif // wxUSE_DATETIME |
| 264 | |
| 265 | // Attributes |
| 266 | protected: |
| 267 | wxVariantData* m_data; |
| 268 | wxString m_name; |
| 269 | }; |
| 270 | |
| 271 | //Since we want type safety wxVariant we need to fetch and dynamic_cast |
| 272 | //in a seemingly safe way so the compiler can check, so we define |
| 273 | //a dynamic_cast /wxDynamicCast analogue. |
| 274 | |
| 275 | #define wxGetVariantCast(var,classname) \ |
| 276 | ((classname*)(var.IsValueKindOf(&classname::ms_classInfo) ?\ |
| 277 | var.GetWxObjectPtr() : NULL)); |
| 278 | |
| 279 | extern wxVariant WXDLLIMPEXP_BASE wxNullVariant; |
| 280 | |
| 281 | #endif |
| 282 | // _WX_VARIANT_H_ |