1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        virtua;.cpp
3 // Purpose:     wxHtml testing example
4 //              demonstrates virtual file systems feature
5 /////////////////////////////////////////////////////////////////////////////
6 
7 // For compilers that support precompilation, includes "wx/wx.h".
8 #include "wx/wxprec.h"
9 
10 #ifdef __BORLANDC__
11     #pragma hdrstop
12 #endif
13 
14 // for all others, include the necessary headers (this file is usually all you
15 // need because it includes almost all "standard" wxWidgets headers
16 #ifndef WX_PRECOMP
17     #include "wx/wx.h"
18 #endif
19 
20 
21 #include "wx/html/htmlwin.h"
22 
23 
24 // new handler class:
25 
26 #include "wx/wfstream.h"
27 #include "wx/mstream.h"
28 
29 
30 
31 class MyVFS : public wxFileSystemHandler
32 {
33 public:
MyVFS()34     MyVFS() : wxFileSystemHandler() {}
35 
36     wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
37     bool CanOpen(const wxString& location);
38 };
39 
40 
CanOpen(const wxString & location)41 bool MyVFS::CanOpen(const wxString& location)
42 {
43     return (GetProtocol(location) == wxT("myVFS"));
44 }
45 
46 
47 
OpenFile(wxFileSystem & WXUNUSED (fs),const wxString & location)48 wxFSFile* MyVFS::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
49 {
50     wxFSFile *f;
51     wxInputStream *str;
52     static char buf[1024];
53     const wxWX2MBbuf loc = location.ToAscii();
54 
55     sprintf(buf, "<html><body><h2><i>You're in Node <u>%s</u></i></h2><p>"
56                  "Where do you want to go?<br><blockquote>"
57                  "<a href=\"%s-1\">sub-1</a><br>"
58                  "<a href=\"%s-2\">sub-2</a><br>"
59                  "<a href=\"%s-3\">sub-3</a><br>"
60                  "</blockquote></body></html>",
61                  (const char*)loc, (const char*)loc, (const char*)loc,
62                  (const char*)loc);
63 
64     // NB: There's a terrible hack involved: we fill 'buf' with new data every
65     //     time this method is called and return new wxMemoryInputStream pointing to it.
66     //     This won't work as soon as there are 2+ myVFS files opened. Fortunately,
67     //     this won't happen because wxHTML keeps only one "page" file opened at the
68     //     time.
69     str = new wxMemoryInputStream(buf, strlen(buf));
70     f = new wxFSFile(str, location, wxT("text/html"), wxEmptyString, wxDateTime::Today());
71 
72     return f;
73 }
74 
75 
76 
77 // ----------------------------------------------------------------------------
78 // private classes
79 // ----------------------------------------------------------------------------
80 
81 // Define a new application type, each program should derive a class from wxApp
82    class MyApp : public wxApp
83    {
84    public:
85     // override base class virtuals
86     // ----------------------------
87 
88     // this one is called on application startup and is a good place for the app
89     // initialization (doing it here and not in the ctor allows to have an error
90     // return: if OnInit() returns false, the application terminates)
91       virtual bool OnInit();
92    };
93 
94 // Define a new frame type: this is going to be our main frame
95    class MyFrame : public wxFrame
96    {
97    public:
98     // ctor(s)
99       MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
100 
101     // event handlers (these functions should _not_ be virtual)
102       void OnQuit(wxCommandEvent& event);
103       void OnBack(wxCommandEvent& event);
104       void OnForward(wxCommandEvent& event);
105 
106    private:
107     // any class wishing to process wxWidgets events must use this macro
108     DECLARE_EVENT_TABLE()
109    };
110 
111 // ----------------------------------------------------------------------------
112 // constants
113 // ----------------------------------------------------------------------------
114 
115 // IDs for the controls and the menu commands
116    enum
117    {
118     // menu items
119    Minimal_Quit = 1,
120    Minimal_Back,
121    Minimal_Forward,
122 
123     // controls start here (the numbers are, of course, arbitrary)
124    Minimal_Text = 1000
125    };
126 
127 // ----------------------------------------------------------------------------
128 // event tables and other macros for wxWidgets
129 // ----------------------------------------------------------------------------
130 
131 // the event tables connect the wxWidgets events with the functions (event
132 // handlers) which process them. It can be also done at run-time, but for the
133 // simple menu events like this the static method is much simpler.
BEGIN_EVENT_TABLE(MyFrame,wxFrame)134    BEGIN_EVENT_TABLE(MyFrame, wxFrame)
135    EVT_MENU(Minimal_Quit,  MyFrame::OnQuit)
136    EVT_MENU(Minimal_Back, MyFrame::OnBack)
137    EVT_MENU(Minimal_Forward, MyFrame::OnForward)
138    END_EVENT_TABLE()
139 
140    // Create a new application object: this macro will allow wxWidgets to create
141    // the application object during program execution (it's better than using a
142    // static object for many reasons) and also declares the accessor function
143    // wxGetApp() which will return the reference of the right type (i.e. MyApp and
144    // not wxApp)
145    IMPLEMENT_APP(MyApp)
146 
147    // ============================================================================
148    // implementation
149    // ============================================================================
150 
151    // ----------------------------------------------------------------------------
152    // the application class
153    // ----------------------------------------------------------------------------
154 
155    // `Main program' equivalent: the program execution "starts" here
156    bool MyApp::OnInit()
157    {
158     // Create the main application window
159       MyFrame *frame = new MyFrame(_("wxHtmlWindow testing application"),
160          wxDefaultPosition, wxSize(640, 480));
161 
162     // Show it and tell the application that it's our main window
163     // @@@ what does it do exactly, in fact? is it necessary here?
164       frame->Show(true);
165       SetTopWindow(frame);
166       wxFileSystem::AddHandler(new MyVFS);
167 
168     // success: wxApp::OnRun() will be called which will enter the main message
169     // loop and the application will run. If we returned false here, the
170     // application would exit immediately.
171       return true;
172    }
173 
174 // ----------------------------------------------------------------------------
175 // main frame
176 // ----------------------------------------------------------------------------
177 
178 wxHtmlWindow *html;
179 
180 // frame constructor
MyFrame(const wxString & title,const wxPoint & pos,const wxSize & size)181    MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
182    : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
183    {
184     // create a menu bar
185       wxMenu *menuFile = new wxMenu;
186       wxMenu *menuNav = new wxMenu;
187 
188       menuFile->Append(Minimal_Quit, _("E&xit"));
189       menuNav->Append(Minimal_Back, _("Go &BACK"));
190       menuNav->Append(Minimal_Forward, _("Go &FORWARD"));
191 
192     // now append the freshly created menu to the menu bar...
193       wxMenuBar *menuBar = new wxMenuBar;
194       menuBar->Append(menuFile, _("&File"));
195       menuBar->Append(menuNav, _("&Navigate"));
196 
197     // ... and attach this menu bar to the frame
198       SetMenuBar(menuBar);
199 
200 #if wxUSE_STATUSBAR
201       CreateStatusBar(2);
202 #endif // wxUSE_STATUSBAR
203 
204       html = new wxHtmlWindow(this);
205       html -> SetRelatedFrame(this, _("VFS Demo: '%s'"));
206 #if wxUSE_STATUSBAR
207       html -> SetRelatedStatusBar(1);
208 #endif // wxUSE_STATUSBAR
209       html -> LoadPage(wxT("start.htm"));
210    }
211 
212 
213 // event handlers
214 
OnQuit(wxCommandEvent & WXUNUSED (event))215    void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
216    {
217     // true is to force the frame to close
218       Close(true);
219    }
220 
OnBack(wxCommandEvent & WXUNUSED (event))221    void MyFrame::OnBack(wxCommandEvent& WXUNUSED(event))
222    {
223    if (!html -> HistoryBack()) wxMessageBox(_("You reached prehistory era!"));
224    }
225 
226 
OnForward(wxCommandEvent & WXUNUSED (event))227    void MyFrame::OnForward(wxCommandEvent& WXUNUSED(event))
228    {
229    if (!html -> HistoryForward()) wxMessageBox(_("No more items in history!"));
230    }
231