adding new files for xti merge
[wxWidgets.git] / samples / xti / xti.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: xti.cpp
3 // Purpose: eXtended RTTI support sample
4 // Author: Stefan Csomor, Francesco Montorsi
5 // Modified by:
6 // Created: 13/5/2007
7 // RCS-ID: $Id: xti.cpp 48407 2007-08-26 23:17:23Z FM $
8 // Copyright: (c) Stefan Csomor, Francesco Montorsi
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
29 #ifndef WX_PRECOMP
30 #include "wx/wx.h"
31 #endif
32
33 #include "wx/wx.h"
34 #include "wx/variant.h"
35 #include "wx/xml/xml.h"
36 #include "wx/frame.h"
37 #include "wx/notebook.h"
38 #include "wx/event.h"
39 #include "wx/spinbutt.h"
40 #include "wx/spinctrl.h"
41
42 #include "wx/xtistrm.h"
43 #include "wx/xtixml.h"
44 #include "wx/txtstrm.h"
45 #include "wx/wfstream.h"
46 #include "wx/sstream.h"
47 #include "wx/spinctrl.h"
48
49 #include "classlist.h"
50 #include "codereadercallback.h"
51
52 #if !wxUSE_EXTENDED_RTTI
53 #error This sample requires XTI (eXtended RTTI) enabled
54 #endif
55
56
57 // ----------------------------------------------------------------------------
58 // resources
59 // ----------------------------------------------------------------------------
60
61 #if !defined(__WXMSW__) && !defined(__WXPM__)
62 #include "../sample.xpm"
63 #endif
64
65 // ----------------------------------------------------------------------------
66 // private classes
67 // ----------------------------------------------------------------------------
68
69 // Define a new application type, each program should derive a class from wxApp
70 class MyApp : public wxApp
71 {
72 public:
73 virtual bool OnInit();
74 };
75
76 // Define a new frame type: this is going to be our main frame
77 class MyFrame : public wxFrame
78 {
79 public:
80 // ctor(s)
81 MyFrame(const wxString& title);
82
83 void OnPersist(wxCommandEvent& event);
84 void OnDepersist(wxCommandEvent& event);
85 void OnGenerateCode(wxCommandEvent& event);
86 void OnDumpClasses(wxCommandEvent& event);
87 void OnQuit(wxCommandEvent& event);
88 void OnAbout(wxCommandEvent& event);
89
90 private:
91 // any class wishing to process wxWidgets events must use this macro
92 wxDECLARE_EVENT_TABLE()
93 };
94
95 // ----------------------------------------------------------------------------
96 // constants
97 // ----------------------------------------------------------------------------
98
99 // IDs for the controls and the menu commands
100 enum
101 {
102 // menu items
103 Minimal_Persist = wxID_HIGHEST,
104 Minimal_Depersist,
105 Minimal_GenerateCode,
106 Minimal_DumpClasses,
107 Minimal_Quit = wxID_EXIT,
108 Minimal_About = wxID_ABOUT
109 };
110
111 // ----------------------------------------------------------------------------
112 // event tables and other macros for wxWidgets
113 // ----------------------------------------------------------------------------
114
115 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
116 EVT_MENU(Minimal_Persist, MyFrame::OnPersist)
117 EVT_MENU(Minimal_Depersist, MyFrame::OnDepersist)
118 EVT_MENU(Minimal_GenerateCode, MyFrame::OnGenerateCode)
119 EVT_MENU(Minimal_DumpClasses, MyFrame::OnDumpClasses)
120 EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
121 EVT_MENU(Minimal_About, MyFrame::OnAbout)
122 END_EVENT_TABLE()
123
124 wxIMPLEMENT_APP(MyApp)
125
126 // ============================================================================
127 // implementation
128 // ============================================================================
129
130 void RegisterFrameRTTI();
131
132 // ----------------------------------------------------------------------------
133 // the application class
134 // ----------------------------------------------------------------------------
135
136 bool MyApp::OnInit()
137 {
138 if ( !wxApp::OnInit() )
139 return false;
140
141 RegisterFrameRTTI();
142
143 // create the main application window
144 MyFrame *frame = new MyFrame(_T("Extended RTTI sample"));
145
146 // and show it (the frames, unlike simple controls, are not shown when
147 // created initially)
148 frame->Show(true);
149
150 // success: wxApp::OnRun() will be called which will enter the main message
151 // loop and the application will run. If we returned false here, the
152 // application would exit immediately.
153 return true;
154 }
155
156 // ----------------------------------------------------------------------------
157 // main frame
158 // ----------------------------------------------------------------------------
159
160 MyFrame::MyFrame(const wxString& title)
161 : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
162 {
163 // set the frame icon
164 SetIcon(wxICON(sample));
165
166 #if wxUSE_MENUS
167 // create a menu bar
168 wxMenu *fileMenu = new wxMenu;
169
170 // the "About" item should be in the help menu
171 wxMenu *helpMenu = new wxMenu;
172 helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about dialog"));
173
174 fileMenu->Append(Minimal_Persist, _T("Persist a wxFrame to XML..."),
175 _T("Creates a wxFrame using wxXTI and saves its description as XML"));
176 fileMenu->Append(Minimal_Depersist, _T("Depersist XML file..."),
177 _T("Loads the description of wxFrame from XML"));
178 fileMenu->Append(Minimal_GenerateCode, _T("Generate code for a wxFrame saved to XML..."),
179 _T("Generates the C++ code which belong to a persisted wxFrame"));
180 fileMenu->AppendSeparator();
181 fileMenu->Append(Minimal_DumpClasses, _T("Dump registered classes..."),
182 _T("Dumps the description of all wxWidgets classes registered in XTI"));
183 fileMenu->AppendSeparator();
184 fileMenu->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
185
186 // now append the freshly created menu to the menu bar...
187 wxMenuBar *menuBar = new wxMenuBar();
188 menuBar->Append(fileMenu, _T("&File"));
189 menuBar->Append(helpMenu, _T("&Help"));
190
191 // ... and attach this menu bar to the frame
192 SetMenuBar(menuBar);
193 #endif // wxUSE_MENUS
194
195 #if wxUSE_STATUSBAR
196 // create a status bar just for fun (by default with 1 pane only)
197 CreateStatusBar(2);
198 SetStatusText(_T("Welcome to wxWidgets!"));
199 #endif // wxUSE_STATUSBAR
200 }
201
202
203
204 // ----------------------------------------------------------------------------
205 // XTI sample code
206 // ----------------------------------------------------------------------------
207
208 // this is the kind of source code that would end up being generated by a
209 // designer corresponding to the information we are setting up via RTTI
210 // in the CreateFrameRTTI function:
211 //
212 // class MyXTIFrame : public wxFrame
213 // {
214 // public:
215 // // construction
216 // MyXTIFrame()
217 // {
218 // Init();
219 // m_button = NULL;
220 // }
221 //
222 // bool Create(wxWindow *parent,
223 // wxWindowID id,
224 // const wxString& title,
225 // const wxPoint& pos = wxDefaultPosition,
226 // const wxSize& size = wxDefaultSize,
227 // long style = wxDEFAULT_FRAME_STYLE,
228 // const wxString& name = wxFrameNameStr)
229 // {
230 // return wxFrame::Create( parent, id, title, pos, size, style, name );
231 // }
232 //
233 // void SetButton( wxButton * button ) { m_button = button; }
234 // wxButton* GetButton() const { return m_button; }
235 //
236 // void ButtonClickHandler( wxEvent & WXUNUSED(event) )
237 // {
238 // wxMessageBox( "Button Clicked ", "Hi!", wxOK );
239 // }
240 //
241 // protected:
242 // wxButton* m_button;
243 //
244 // DECLARE_EVENT_TABLE()
245 // DECLARE_DYNAMIC_CLASS_NO_COPY(MyXTIFrame)
246 // };
247 //
248 // IMPLEMENT_DYNAMIC_CLASS_XTI(MyXTIFrame, MyXTIFrame, "x.h")
249 //
250 // WX_BEGIN_PROPERTIES_TABLE(MyXTIFrame)
251 // WX_PROPERTY( Button, wxButton*, SetButton, GetButton, )
252 // WX_END_PROPERTIES_TABLE()
253 //
254 // WX_BEGIN_HANDLERS_TABLE(MyXTIFrame)
255 // WX_HANDLER( ButtonClickHandler, wxCommandEvent )
256 // WX_END_HANDLERS_TABLE()
257 //
258 // WX_CONSTRUCTOR_5( MyXTIFrame, wxWindow*, Parent, wxWindowID, Id,
259 // wxString, Title, wxPoint, Position, wxSize, Size )
260 //
261 // BEGIN_EVENT_TABLE(MyXTIFrame, wxFrame)
262 // END_EVENT_TABLE()
263
264 // the following class "persists" (i.e. saves) a wxFrame into a wxObjectWriter
265
266 class MyDesignerPersister : public wxObjectReaderCallback
267 {
268 public:
269 MyDesignerPersister( wxDynamicObject * frame)
270 {
271 m_frame = frame;
272 }
273
274 virtual bool BeforeWriteDelegate( wxObjectWriter *WXUNUSED(writer),
275 const wxObject *object,
276 const wxClassInfo* WXUNUSED(classInfo),
277 const wxPropertyInfo *propInfo,
278 const wxObject *&eventSink,
279 const wxHandlerInfo* &handlerInfo )
280 {
281 // this approach would be used it the handler would not
282 // be connected really in the designer, so we have to supply
283 // the information
284 if ( object == m_frame->GetProperty(wxT("Button")).GetAsObject() &&
285 propInfo == wxCLASSINFO( wxButton )->FindPropertyInfo("OnClick") )
286 {
287 eventSink = m_frame;
288 handlerInfo = m_frame->GetClassInfo()->
289 FindHandlerInfo("ButtonClickHandler");
290 return true;
291 }
292 return false;
293 }
294
295 private:
296 wxDynamicObject *m_frame;
297 };
298
299 // sometimes linkers (at least MSVC and GCC ones) optimize the final EXE
300 // even in debug mode pruning the object files which he "thinks" are useless;
301 // thus the classes defined in those files won't be available in the XTI
302 // table and the program will fail to allocate them.
303 // The following macro implements a simple hack to ensure that a given
304 // class is linked in.
305 //
306 // TODO: in wx/link.h there are already similar macros (also more "optimized":
307 // don't need the creation of fake object) which however require to use
308 // the wxFORCE_LINK_THIS_MODULE() macro inside the source files corresponding
309 // to the class being discarded.
310 //
311 #define wxENSURE_CLASS_IS_LINKED(x) { x test; }
312
313 void RegisterFrameRTTI()
314 {
315 // set up the RTTI info for a class (MyXTIFrame) which
316 // is not defined anywhere in this program
317 wxDynamicClassInfo *dyninfo =
318 wx_dynamic_cast( wxDynamicClassInfo *, wxClassInfo::FindClass(wxT("MyXTIFrame")));
319 if ( dyninfo == NULL )
320 {
321 dyninfo = new wxDynamicClassInfo(wxT("myxtiframe.h"),
322 wxT("MyXTIFrame"),
323 CLASSINFO(wxFrame) );
324
325 // this class has a property named "Button" and the relative handler:
326 dyninfo->AddProperty("Button", wxGetTypeInfo((wxButton**) NULL));
327 dyninfo->AddHandler("ButtonClickHandler",
328 NULL /* no instance of the handler method */, CLASSINFO( wxEvent ) );
329 }
330 }
331
332 wxDynamicObject* CreateFrameRTTI()
333 {
334 int baseID = 100;
335 wxVariantBase Params[10];
336
337 // the class is now part of XTI internal table so that we can
338 // get a pointer to it just searching it like any other class:
339 wxFrame* frame;
340 wxClassInfo *info = wxClassInfo::FindClass(wxT("MyXTIFrame"));
341 wxASSERT( info );
342 wxDynamicObject* frameWrapper =
343 wx_dynamic_cast(wxDynamicObject*, info->CreateObject() );
344 Params[0] = wxVariantBase((wxWindow*)(NULL));
345 Params[1] = wxVariantBase(wxWindowID(baseID++));
346 Params[2] = wxVariantBase(wxString(wxT("This is a frame created from XTI")));
347 Params[3] = wxVariantBase(wxPoint(-1,-1));
348 Params[4] = wxVariantBase(wxSize(400,300));
349 Params[5] = wxVariantBase((long)wxDEFAULT_FRAME_STYLE);
350 wxASSERT( info->Create(frameWrapper, 6, Params ));
351 frame = wx_dynamic_cast(wxFrame*, frameWrapper->GetSuperClassInstance());
352
353 // now build a notebook inside it:
354 wxNotebook* notebook;
355 info = wxClassInfo::FindClass("wxNotebook");
356 wxASSERT( info );
357 notebook = wxDynamicCast( info->CreateObject(), wxNotebook );
358 Params[0] = wxVariantBase((wxWindow*)frame);
359 Params[1] = wxVariantBase(wxWindowID(baseID++));
360 Params[2] = wxVariantBase(wxPoint( 10, 10 ));
361 Params[3] = wxVariantBase(wxDefaultSize);
362 Params[4] = wxVariantBase((long)0);
363 wxASSERT( info->Create(notebook, 5, Params ));
364
365 // button page
366
367 wxPanel* panel;
368 info = wxClassInfo::FindClass("wxPanel");
369 wxASSERT( info );
370 panel = wxDynamicCast( info->CreateObject(), wxPanel );
371 Params[0] = wxVariantBase((wxWindow*)(notebook));
372 Params[1] = wxVariantBase(wxWindowID(baseID++));
373 Params[2] = wxVariantBase(wxPoint(-1,-1));
374 Params[3] = wxVariantBase(wxSize(-1,-1));
375 Params[4] = wxVariantBase((long)0);
376 Params[5] = wxVariantBase(wxString(wxT("Hello")));
377 wxASSERT( info->Create(panel, 6, Params ));
378 notebook->AddPage( panel, "Buttons" );
379
380 wxButton* button;
381 info = wxClassInfo::FindClass("wxButton");
382 wxASSERT( info );
383 button = wxDynamicCast( info->CreateObject(), wxButton );
384 Params[0] = wxVariantBase((wxWindow*)(panel));
385 Params[1] = wxVariantBase(wxWindowID(baseID++));
386 Params[2] = wxVariantBase(wxString(wxT("Click Me!")));
387 Params[3] = wxVariantBase(wxPoint( 10, 10 ));
388 Params[4] = wxVariantBase(wxSize(-1,-1));
389 Params[5] = wxVariantBase((long)0);
390 wxASSERT( info->Create(button, 6, Params ));
391 frameWrapper->SetProperty( "Button", wxVariantBase( button ) );
392
393 // other controls page
394
395 info = wxClassInfo::FindClass("wxPanel");
396 wxASSERT( info );
397 panel = wxDynamicCast( info->CreateObject(), wxPanel );
398 Params[0] = wxVariantBase((wxWindow*)(notebook));
399 Params[1] = wxVariantBase(wxWindowID(baseID++));
400 Params[2] = wxVariantBase(wxPoint(-1,-1));
401 Params[3] = wxVariantBase(wxSize(-1,-1));
402 Params[4] = wxVariantBase((long)0);
403 Params[5] = wxVariantBase(wxString(wxT("Hello")));
404 wxASSERT( info->Create(panel, 6, Params ));
405 notebook->AddPage( panel, "Other Standard controls" );
406
407 wxControl* control;
408 info = wxClassInfo::FindClass("wxCheckBox");
409 wxASSERT( info );
410 control = wxDynamicCast( info->CreateObject(), wxControl );
411 Params[0] = wxVariantBase((wxWindow*)(panel));
412 Params[1] = wxVariantBase(wxWindowID(baseID++));
413 Params[2] = wxVariantBase(wxString(wxT("A Checkbox")));
414 Params[3] = wxVariantBase(wxPoint( 10, 10 ));
415 Params[4] = wxVariantBase(wxSize(-1,-1));
416 Params[5] = wxVariantBase((long)0);
417 wxASSERT( info->Create(control, 6, Params ));
418
419 info = wxClassInfo::FindClass("wxRadioButton");
420 wxASSERT( info );
421 control = wxDynamicCast( info->CreateObject(), wxControl );
422 Params[0] = wxVariantBase((wxWindow*)(panel));
423 Params[1] = wxVariantBase(wxWindowID(baseID++));
424 Params[2] = wxVariantBase(wxString(wxT("A Radiobutton")));
425 Params[3] = wxVariantBase(wxPoint( 10, 30 ));
426 Params[4] = wxVariantBase(wxSize(-1,-1));
427 Params[5] = wxVariantBase((long)0);
428 wxASSERT( info->Create(control, 6, Params ));
429
430 control = wxDynamicCast( info->CreateObject(), wxControl );
431 Params[1] = wxVariantBase(wxWindowID(baseID++));
432 Params[2] = wxVariantBase(wxString(wxT("Another One")));
433 Params[3] = wxVariantBase(wxPoint( 10, 50 ));
434 wxASSERT( info->Create(control, 6, Params ));
435
436 info = wxClassInfo::FindClass("wxStaticText");
437 wxASSERT( info );
438 control = wxDynamicCast( info->CreateObject(), wxControl );
439 Params[0] = wxVariantBase((wxWindow*)(panel));
440 Params[1] = wxVariantBase(wxWindowID(baseID++));
441 Params[2] = wxVariantBase(wxString(wxT("A Static Text!")));
442 Params[3] = wxVariantBase(wxPoint( 10, 70 ));
443 Params[4] = wxVariantBase(wxSize(-1,-1));
444 Params[5] = wxVariantBase((long)0);
445 wxASSERT( info->Create(control, 6, Params ));
446
447 info = wxClassInfo::FindClass("wxStaticBox");
448 wxASSERT( info );
449 control = wxDynamicCast( info->CreateObject(), wxControl );
450 Params[0] = wxVariantBase((wxWindow*)(panel));
451 Params[1] = wxVariantBase(wxWindowID(baseID++));
452 Params[2] = wxVariantBase(wxString(wxT("A Static Box")));
453 Params[3] = wxVariantBase(wxPoint( 10, 90 ));
454 Params[4] = wxVariantBase(wxSize(100,80));
455 Params[5] = wxVariantBase((long)0);
456 wxASSERT( info->Create(control, 6, Params ));
457
458 info = wxClassInfo::FindClass("wxTextCtrl");
459 wxASSERT( info );
460 control = wxDynamicCast( info->CreateObject(), wxControl );
461 Params[0] = wxVariantBase((wxWindow*)(panel));
462 Params[1] = wxVariantBase(wxWindowID(baseID++));
463 Params[2] = wxVariantBase(wxString(wxT("A Text Control")));
464 Params[3] = wxVariantBase(wxPoint( 10, 200 ));
465 Params[4] = wxVariantBase(wxSize(-1,-1));
466 Params[5] = wxVariantBase((long)0);
467 wxASSERT( info->Create(control, 6, Params ));
468
469 // spins and gauges page
470
471 info = wxClassInfo::FindClass("wxPanel");
472 wxASSERT( info );
473 panel = wxDynamicCast( info->CreateObject(), wxPanel );
474 Params[0] = wxVariantBase((wxWindow*)(notebook));
475 Params[1] = wxVariantBase(wxWindowID(baseID++));
476 Params[2] = wxVariantBase(wxPoint(-1,-1));
477 Params[3] = wxVariantBase(wxSize(-1,-1));
478 Params[4] = wxVariantBase((long)0);
479 Params[5] = wxVariantBase(wxString(wxT("Hello")));
480 wxASSERT( info->Create(panel, 6, Params ));
481 notebook->AddPage( panel, "Spins and Sliders" );
482
483 wxENSURE_CLASS_IS_LINKED(wxSpinButton);
484
485 info = wxClassInfo::FindClass("wxSpinButton");
486 wxASSERT( info );
487 control = wxDynamicCast( info->CreateObject(), wxControl );
488 Params[0] = wxVariantBase((wxWindow*)(panel));
489 Params[1] = wxVariantBase(wxWindowID(baseID++));
490 Params[2] = wxVariantBase(wxPoint( 10, 10 ));
491 Params[3] = wxVariantBase(wxSize(-1,-1));
492 Params[4] = wxVariantBase((long)wxSP_VERTICAL | wxSP_ARROW_KEYS);
493 wxASSERT( info->Create(control, 5, Params ));
494
495 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl);
496
497 info = wxClassInfo::FindClass("wxSpinCtrl");
498 wxASSERT( info );
499 control = wxDynamicCast( info->CreateObject(), wxControl );
500 Params[0] = wxVariantBase((wxWindow*)(panel));
501 Params[1] = wxVariantBase(wxWindowID(baseID++));
502 Params[2] = wxVariantBase(wxString("20"));
503 Params[3] = wxVariantBase(wxPoint( 40, 10 ));
504 Params[4] = wxVariantBase(wxSize(40,-1));
505 Params[5] = wxVariantBase((long) wxSP_ARROW_KEYS);
506 wxASSERT( info->Create(control, 6, Params ));
507
508 // MSVC likes to exclude from link wxGauge...
509 wxENSURE_CLASS_IS_LINKED(wxGauge)
510 wxENSURE_CLASS_IS_LINKED(wxCheckBox)
511 wxENSURE_CLASS_IS_LINKED(wxSpinCtrl)
512
513 #ifdef __WXMSW__
514 // under wxMSW wxGauge is simply #defined to wxGauge95
515 info = wxClassInfo::FindClass("wxGauge95");
516 #else
517 info = wxClassInfo::FindClass("wxGauge");
518 #endif
519 wxASSERT( info );
520 control = wxDynamicCast( info->CreateObject(), wxControl );
521 Params[0] = wxVariantBase((wxWindow*)(panel));
522 Params[1] = wxVariantBase(wxWindowID(baseID++));
523 Params[2] = wxVariantBase((int) 100);
524 Params[3] = wxVariantBase(wxPoint( 10, 50 ));
525 Params[4] = wxVariantBase(wxSize(-1,-1));
526 Params[5] = wxVariantBase((long) wxGA_HORIZONTAL);
527 wxASSERT( info->Create(control, 6, Params ));
528 wx_dynamic_cast(wxGauge*, control)->SetValue(20);
529
530 return frameWrapper;
531 }
532
533 bool SaveFrameRTTI(const wxString &testFileName, wxDynamicObject *frame)
534 {
535 // setup the XML document
536 wxXmlDocument xml;
537 wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE,
538 "TestXTI", "This is the content");
539 xml.SetRoot(root);
540
541 // setup the XTI writer and persister
542 wxObjectXmlWriter writer(root);
543 MyDesignerPersister persister(frame);
544
545 // write the given wxObject into the XML document
546 wxVariantBaseArray empty;
547 writer.WriteObject( frame, frame->GetClassInfo(), &persister,
548 wxString("myTestFrame"), empty );
549
550 return xml.Save(testFileName);
551 }
552
553 wxDynamicObject* LoadFrameRTTI(const wxString &fileName)
554 {
555 // load the XML document
556 wxXmlDocument xml;
557 if (!xml.Load(fileName))
558 return NULL;
559
560 wxXmlNode *root = xml.GetRoot();
561 if (root->GetName() != "TestXTI")
562 return NULL;
563
564 // now depersist the wxFrame we saved into it using wxObjectRuntimeReaderCallback
565 wxObjectRuntimeReaderCallback Callbacks;
566 wxObjectXmlReader Reader( root );
567 int obj = Reader.ReadObject( wxString("myTestFrame"), &Callbacks );
568 return (wxDynamicObject*)Callbacks.GetObject( obj );
569 }
570
571 bool GenerateFrameRTTICode(const wxString &inFileName, const wxString &outFileName)
572 {
573 // is loading the streamed out component from xml and writing code that
574 // will create the same component
575
576 wxFFileOutputStream fos( outFileName );
577 wxTextOutputStream tos( fos );
578 if (!fos.IsOk())
579 return false;
580
581 wxXmlDocument xml;
582 if (!xml.Load(inFileName))
583 return false;
584
585 wxXmlNode *root = xml.GetRoot();
586 if (root->GetName() != "TestXTI")
587 return false;
588
589 // read the XML file using the wxObjectCodeReaderCallback
590 wxObjectCodeReaderCallback Callbacks(&tos);
591 wxObjectXmlReader Reader(root);
592
593 // ReadObject will return the ID of the object read??
594 Reader.ReadObject( wxString("myTestFrame"), &Callbacks );
595
596 return true;
597 }
598
599
600
601
602 // ----------------------------------------------------------------------------
603 // MyFrame event handlers
604 // ----------------------------------------------------------------------------
605
606 void MyFrame::OnPersist(wxCommandEvent& WXUNUSED(event))
607 {
608 // first create a frame using XTI calls
609 wxDynamicObject *frame = CreateFrameRTTI();
610 if (!frame)
611 {
612 wxLogError(wxT("Cannot create the XTI frame!"));
613 return;
614 }
615
616 // show the frame we're going to save to the user
617 wxFrame *trueFrame = wx_dynamic_cast(wxFrame *, frame->GetSuperClassInstance() );
618 trueFrame->Show();
619
620 // ask the user where to save it
621 wxFileDialog dlg(this, wxT("Where should the frame be saved?"),
622 wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
623 wxFD_SAVE);
624 if (dlg.ShowModal() == wxID_CANCEL)
625 return;
626
627 // then save it to a test XML file
628 if (!SaveFrameRTTI(dlg.GetPath(), frame))
629 {
630 wxLogError(wxT("Cannot save the XTI frame into '%s'"), dlg.GetPath());
631 return;
632 }
633
634 // now simply delete it
635 delete frame;
636 }
637
638 void MyFrame::OnDepersist(wxCommandEvent& WXUNUSED(event))
639 {
640 // ask the user which file to load
641 wxFileDialog dlg(this, wxT("Which file contains the frame to depersist?"),
642 wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
643 wxFD_OPEN);
644 if (dlg.ShowModal() == wxID_CANCEL)
645 return;
646
647 wxObject *frame = LoadFrameRTTI(dlg.GetPath());
648 if (!frame)
649 {
650 wxLogError(wxT("Could not depersist the wxFrame from '%s'"), dlg.GetPath());
651 return;
652 }
653
654 wxFrame *trueFrame = wx_dynamic_cast(wxFrame*, frame );
655 if ( !trueFrame )
656 {
657 wxDynamicObject* dyno = wx_dynamic_cast(wxDynamicObject*, frame );
658 if ( dyno )
659 trueFrame = wx_dynamic_cast(wxFrame *, dyno->GetSuperClassInstance() );
660 }
661
662 if ( trueFrame )
663 trueFrame->Show();
664 else
665 wxLogError(wxT("Could not show the frame"));
666 }
667
668 void MyFrame::OnGenerateCode(wxCommandEvent& WXUNUSED(event))
669 {
670 // ask the user which file to load
671 wxFileDialog dlg(this, wxT("Which file contains the frame to work on?"),
672 wxEmptyString, wxT("test.xml"), wxT("XML files (*.xml)|*.xml"),
673 wxFD_OPEN);
674 if (dlg.ShowModal() == wxID_CANCEL)
675 return;
676
677 // ask the user which file to load
678 wxFileDialog dlg2(this, wxT("Where should the C++ code be saved?"),
679 wxEmptyString, wxT("test.cpp"), wxT("Source files (*.cpp)|*.cpp"),
680 wxFD_SAVE);
681 if (dlg2.ShowModal() == wxID_CANCEL)
682 return;
683
684 // do generate code
685 if (!GenerateFrameRTTICode(dlg.GetPath(), dlg2.GetPath()))
686 {
687 wxLogError(wxT("Could not generate the code for the frame!"));
688 return;
689 }
690
691 // show the generated code
692 {
693 wxFileInputStream f(dlg2.GetPath());
694 wxStringOutputStream str;
695 f.Read(str);
696
697 wxDialog dlg(this, wxID_ANY, wxT("Generated code"),
698 wxDefaultPosition, wxDefaultSize,
699 wxRESIZE_BORDER|wxDEFAULT_DIALOG_STYLE);
700 wxPanel *panel = new wxPanel(&dlg);
701 wxSizer *sz = new wxBoxSizer(wxVERTICAL);
702 sz->Add(new wxTextCtrl(panel, wxID_ANY, str.GetString(),
703 wxDefaultPosition, wxDefaultSize,
704 wxTE_MULTILINE|wxTE_READONLY|wxTE_DONTWRAP),
705 1, wxGROW|wxALL, 5);
706 sz->Add(new wxButton(panel, wxID_OK), 0, wxALIGN_RIGHT|wxALL, 5);
707 panel->SetSizerAndFit(sz);
708 dlg.ShowModal();
709 }
710 }
711
712 void MyFrame::OnDumpClasses(wxCommandEvent& WXUNUSED(event))
713 {
714 ClassListDialog dlg(this);
715 dlg.ShowModal();
716 }
717
718 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
719 {
720 // true is to force the frame to close
721 Close(true);
722 }
723
724 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
725 {
726 wxMessageBox(wxString::Format(
727 _T("Welcome to %s!\n")
728 _T("\n")
729 _T("This sample demonstrates wxWidgets eXtended RTTI (XTI) system."),
730 wxVERSION_STRING
731 ),
732 _T("About wxWidgets XTI sample"),
733 wxOK | wxICON_INFORMATION,
734 this);
735 }