Addition at simple wxObject*, support into wxVariant.

This includes 2 new methods wxVariant::IsValueKindOf() and
wxVariantData::GetValueClassInfo() to allow query of the
wxRTTI data of the variant's data.

Also included is a macro analogues to dynamicCast for fetching
objects out of a wxVariant.

Documentation patches for the above.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20860 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Roger Gammans
2003-06-02 21:17:28 +00:00
parent 8647bec62d
commit cf6ae2907c
4 changed files with 183 additions and 2 deletions

View File

@@ -80,12 +80,14 @@ Construction from a list of strings. This constructor
copies {\it value}, the application is still responsible for
deleting {\it value} and its contents.
%Note: this constructor is currently disabled because it causes a C++ ambiguity.
\func{}{wxVariant}{\param{void*}{ value}, \param{const wxString\& }{name = ``"}}
Construction from a void pointer.
\func{}{wxVariant}{\param{wxObject*}{ value}, \param{const wxString\& }{name = ``"}}
Construction from a wxObject pointer.
\func{}{wxVariant}{\param{wxVariantData*}{ data}, \param{const wxString\& }{name = ``"}}
Construction from user-defined data. The variant holds on to the {\it data} pointer.
@@ -176,6 +178,12 @@ If the variant is null, the value type returned is the string ``null" (not the e
Gets the void pointer value.
\membersection{wxVariant::GetWxObjectPtr}\label{wxvariantgetwxobjectptr}
\constfunc{void*}{GetWxObjectPtr}{\void}
Gets the wxObject pointer value.
\membersection{wxVariant::Insert}\label{wxvariantinsert}
\func{void}{Insert}{\param{const wxVariant\&}{ value}}
@@ -194,6 +202,12 @@ Returns true if there is no data associated with this variant, false if there is
Returns true if {\it type} matches the type of the variant, false otherwise.
\membersection{wxVariant::IsValueKindOf}\label{wxvariantisvaluekindof}
\constfunc{bool}{IsValueKindOf}{\param{const wxClassInfo* type}{ type}}
Returns true if the data is derived from the class described by {\it type}, false otherwise.
\membersection{wxVariant::MakeNull}\label{wxvariantmakenull}
\func{void}{MakeNull}{\void}
@@ -381,6 +395,13 @@ Returns true if this object is equal to {\it data}.
Returns the string type of the data.
\membersection{wxVariantData::GetValueClassInfo}\label{wxvariantdatagetvalueclassinfo}
\constfunc{wxClassInfo*}{GetValueClassInfo}{\void}
If the data is a wxObject returns a pointer to the objects wxClassInfo structure, if
the data isn't a wxObject the method returns NULL.
\membersection{wxVariantData::Read}\label{wxvariantdataread}
\func{bool}{Read}{\param{ostream\&}{ stream}}
@@ -398,4 +419,16 @@ Reads the data from {\it stream} or {\it string}.
Writes the data to {\it stream} or {\it string}.
\membersection{wxGetVariantCast}\label{wxgetvariantcast}
\func{classname *}{wxGetVariantCast}{wxVariant\&, classname}
This macro returns the data stored in {\it variant} cast to the type {\it classname *} if
the data is of this type (the check is done during the run-time) or
{\tt NULL} otherwise.
\wxheading{See also}
\helpref{RTTI overview}{runtimeclassoverview}\\
\helpref{wxDynamicCast}{wxdynamiccast}\\

View File

@@ -67,6 +67,8 @@ public:
virtual bool Read(wxString& str) = 0;
// What type is it? Return a string name.
virtual wxString GetType() const = 0;
// If it based on wxObject return the ClassInfo.
virtual wxClassInfo* GetValueClassInfo() { return NULL; }
};
/*
@@ -95,6 +97,7 @@ public:
wxVariant(const wxStringList& val, const wxString& name = wxEmptyString);
wxVariant(const wxList& val, const wxString& name = wxEmptyString); // List of variants
wxVariant(void* ptr, const wxString& name = wxEmptyString); // void* (general purpose)
wxVariant(wxObject* ptr, const wxString& name = wxEmptyString); //wxObject
wxVariant(wxVariantData* data, const wxString& name = wxEmptyString); // User-defined data
//TODO: Need to document
#if wxUSE_DATETIME
@@ -181,6 +184,9 @@ public:
inline operator long () const { return GetLong(); }
inline operator bool () const { return GetBool(); }
inline operator void* () const { return GetVoidPtr(); }
// No implicit conversion to wxObject, as that would really
// confuse people between conversion to our contained data
// and downcasting to see our base type.
//TODO: Need to document
#if wxUSE_DATETIME
inline operator wxDateTime () const { return GetDateTime(); }
@@ -203,6 +209,7 @@ public:
wxString GetType() const;
bool IsType(const wxString& type) const;
bool IsValueKindOf(const wxClassInfo* type) const;
// Return the number of elements in a list
int GetCount() const;
@@ -219,6 +226,7 @@ public:
wxStringList& GetStringList() const ;
void* GetVoidPtr() const ;
wxObject* GetWxObjectPtr() ;
//TODO: Need to document
#if wxUSE_DATETIME
wxDateTime GetDateTime() const ;
@@ -268,6 +276,14 @@ protected:
wxString m_name;
};
//Since we want type safety wxVariant we need to fetch and dynamic_cast
//in a seemingly safe way so the compiler can check, so we define
//a dynamic_cast /wxDynamicCast analogue.
#define wxGetVariantCast(var,classname) \
((classname*)(var.IsValueKindOf(&classname::sm_class##classname) ?\
var.GetWxObjectPtr() : NULL));
extern wxVariant WXDLLEXPORT wxNullVariant;
#endif

View File

@@ -1052,6 +1052,15 @@ void MyApp::DoVariantDemo(wxCommandEvent& WXUNUSED(event) )
{
textCtrl << _T("var1[") << (int) i << _T("] (type ") << var1[i].GetType() << _T(") = ") << var1[i].MakeString() << _T("\n");
}
var1 = wxVariant(new wxFont(wxSystemSettings::GetFont(wxSYS_OEM_FIXED_FONT)));
textCtrl << _T("var1 = (wxfont)\"");
wxFont* font = wxGetVariantCast(var1,wxFont);
if (font) {
textCtrl << font->GetNativeFontInfoDesc() << _T("\"\n");
} else {
textCtrl << _T("(null)\"\n");
}
}
BEGIN_EVENT_TABLE(MyFrame, wxFrame)

View File

@@ -905,6 +905,111 @@ bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
return FALSE;
}
/*
* wxVariantDataWxObjectPtr
*/
class wxVariantDataWxObjectPtr: public wxVariantData
{
DECLARE_DYNAMIC_CLASS(wxVariantDataWxObjectPtr)
public:
wxVariantDataWxObjectPtr() { }
wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
inline wxObject* GetValue() const { return m_value; }
inline void SetValue(wxObject* value) { m_value = value; }
virtual void Copy(wxVariantData& data);
virtual bool Eq(wxVariantData& data) const;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const;
#endif
virtual bool Write(wxString& str) const;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str);
#endif
virtual bool Read(wxString& str);
virtual wxString GetType() const ;
virtual wxVariantData* Clone() { return new wxVariantDataWxObjectPtr; }
virtual wxClassInfo* GetValueClassInfo() ;
protected:
wxObject* m_value;
DECLARE_NO_COPY_CLASS(wxVariantDataWxObjectPtr)
};
IMPLEMENT_DYNAMIC_CLASS(wxVariantDataWxObjectPtr, wxVariantData)
void wxVariantDataWxObjectPtr::Copy(wxVariantData& data)
{
wxASSERT_MSG( wxIsKindOf((&data), wxVariantDataWxObjectPtr) ,\
wxT("wxVariantDataWxObjectPtr::Copy: Can't copy to this type of data") \
);
wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
otherData.m_value = m_value;
}
bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
{
wxASSERT_MSG( wxIsKindOf((&data), wxVariantDataWxObjectPtr), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
return (otherData.m_value == m_value);
}
wxString wxVariantDataWxObjectPtr::GetType() const
{
wxString returnVal(wxT("wxObject"));
if (m_value) {
returnVal = m_value->GetClassInfo()->GetClassName();
}
return returnVal;
}
wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
{
wxClassInfo* returnVal=NULL;
if (m_value) returnVal = m_value->GetClassInfo();
return returnVal;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return TRUE;
}
#endif
bool wxVariantDataWxObjectPtr::Write(wxString& str) const
{
str.Printf(wxT("%s(%ld)"), GetType().mb_str() ,(long) m_value);
return TRUE;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
{
// Not implemented
return FALSE;
}
#endif
bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
{
// Not implemented
return FALSE;
}
/*
* wxVariantDataDateTime
*/
@@ -1173,6 +1278,12 @@ wxVariant::wxVariant( void* val, const wxString& name)
m_name = name;
}
wxVariant::wxVariant( wxObject* val, const wxString& name)
{
m_data = new wxVariantDataWxObjectPtr(val);
m_name = name;
}
#if wxUSE_DATETIME
wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
{
@@ -1697,6 +1808,12 @@ bool wxVariant::IsType(const wxString& type) const
return (GetType() == type);
}
bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
{
wxClassInfo* info=m_data->GetValueClassInfo();
return info ? info->IsKindOf(type) : false ;
}
// Value accessors
double wxVariant::GetReal() const
@@ -1765,6 +1882,12 @@ void* wxVariant::GetVoidPtr() const
return (void*) ((wxVariantDataVoidPtr*) m_data)->GetValue();
}
wxObject* wxVariant::GetWxObjectPtr()
{
wxASSERT(wxIsKindOf(m_data, wxVariantDataWxObjectPtr));
return (wxObject*) ((wxVariantDataWxObjectPtr*) m_data)->GetValue();
}
#if wxUSE_DATETIME
wxDateTime wxVariant::GetDateTime() const
{