Allow handling EVT_UPDATE_UI for wxID_UNDO/REDO at wxDocument level.
[wxWidgets.git] / src / common / rendcmn.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/rendcmn.cpp
3 // Purpose: wxRendererNative common functions
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 28.07.03
7 // RCS-ID: $Id$
8 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/app.h"
28 #include "wx/log.h"
29 #include "wx/intl.h"
30 #endif //WX_PRECOMP
31
32 #include "wx/apptrait.h"
33 #include "wx/renderer.h"
34
35 #include "wx/scopedptr.h"
36
37 #if wxUSE_DYNLIB_CLASS
38 #include "wx/dynlib.h"
39 #endif // wxUSE_DYNLIB_CLASS
40
41 // ----------------------------------------------------------------------------
42 // wxRendererPtr: auto pointer holding the global renderer
43 // ----------------------------------------------------------------------------
44
45 typedef wxScopedPtr<wxRendererNative> wxRendererPtrBase;
46
47 class wxRendererPtr : public wxRendererPtrBase
48 {
49 public:
50 // return true if we have a renderer, false otherwise
51 bool IsOk()
52 {
53 if ( !m_initialized )
54 {
55 // only try to create the renderer once
56 m_initialized = true;
57
58 DoInit();
59 }
60
61 return get() != NULL;
62 }
63
64 // return the global and unique wxRendererPtr
65 static wxRendererPtr& Get();
66
67 private:
68 wxRendererPtr() : wxRendererPtrBase(NULL) { m_initialized = false; }
69
70 void DoInit()
71 {
72 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
73 if ( traits )
74 {
75 // ask the traits object to create a renderer for us
76 reset(traits->CreateRenderer());
77 }
78 }
79
80 bool m_initialized;
81
82 // just to suppress a gcc warning
83 friend class wxRendererPtrDummyFriend;
84
85 wxDECLARE_NO_COPY_CLASS(wxRendererPtr);
86 };
87
88 // return the global and unique wxRendererPtr
89 /*static*/ wxRendererPtr& wxRendererPtr::Get()
90 {
91 static wxRendererPtr s_renderer;
92
93 return s_renderer;
94 }
95
96 #if wxUSE_DYNLIB_CLASS
97
98 // ----------------------------------------------------------------------------
99 // wxRendererFromDynLib: represents a renderer dynamically loaded from a DLL
100 // ----------------------------------------------------------------------------
101
102 class wxRendererFromDynLib : public wxDelegateRendererNative
103 {
104 public:
105 // create the object wrapping the given renderer created from this DLL
106 //
107 // we take ownership of the pointer and will delete it (and also unload the
108 // DLL) when we're deleted
109 wxRendererFromDynLib(wxDynamicLibrary& dll, wxRendererNative *renderer)
110 : wxDelegateRendererNative(*renderer),
111 m_renderer(renderer),
112 m_dllHandle(dll.Detach())
113 {
114 }
115
116 virtual ~wxRendererFromDynLib()
117 {
118 delete m_renderer;
119 wxDynamicLibrary::Unload(m_dllHandle);
120 }
121
122 private:
123 wxRendererNative *m_renderer;
124 wxDllType m_dllHandle;
125 };
126
127 #endif // wxUSE_DYNLIB_CLASS
128
129 // ============================================================================
130 // wxRendererNative implementation
131 // ============================================================================
132
133 wxRendererNative::~wxRendererNative()
134 {
135 // empty but necessary
136 }
137
138 // ----------------------------------------------------------------------------
139 // Managing the global renderer
140 // ----------------------------------------------------------------------------
141
142 /* static */
143 wxRendererNative& wxRendererNative::Get()
144 {
145 wxRendererPtr& renderer = wxRendererPtr::Get();
146
147 return renderer.IsOk() ? *renderer.get() : GetDefault();
148 }
149
150 /* static */
151 wxRendererNative *wxRendererNative::Set(wxRendererNative *rendererNew)
152 {
153 wxRendererPtr& renderer = wxRendererPtr::Get();
154
155 wxRendererNative *rendererOld = renderer.release();
156
157 renderer.reset(rendererNew);
158
159 return rendererOld;
160 }
161
162
163 // ----------------------------------------------------------------------------
164 // Dynamic renderers loading
165 // ----------------------------------------------------------------------------
166
167 #if wxUSE_DYNLIB_CLASS
168
169 /* static */
170 wxRendererNative *wxRendererNative::Load(const wxString& name)
171 {
172 wxString fullname = wxDynamicLibrary::CanonicalizePluginName(name);
173
174 wxDynamicLibrary dll(fullname);
175 if ( !dll.IsLoaded() )
176 return NULL;
177
178 // each theme DLL must export a wxCreateRenderer() function with this
179 // signature
180 typedef wxRendererNative *(*wxCreateRenderer_t)();
181
182 wxDYNLIB_FUNCTION(wxCreateRenderer_t, wxCreateRenderer, dll);
183 if ( !pfnwxCreateRenderer )
184 return NULL;
185
186 // create a renderer object
187 wxRendererNative *renderer = (*pfnwxCreateRenderer)();
188 if ( !renderer )
189 return NULL;
190
191 // check that its version is compatible with ours
192 wxRendererVersion ver = renderer->GetVersion();
193 if ( !wxRendererVersion::IsCompatible(ver) )
194 {
195 wxLogError(_("Renderer \"%s\" has incompatible version %d.%d and couldn't be loaded."),
196 name.c_str(), ver.version, ver.age);
197 delete renderer;
198
199 return NULL;
200 }
201
202 // finally wrap the renderer in an object which will delete it and unload
203 // the library when it is deleted and return it to the caller
204 return new wxRendererFromDynLib(dll, renderer);
205 }
206
207 #endif // wxUSE_DYNLIB_CLASS