1 /*
2 * Copyright (C) 2007 Kevin Ollivier All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *
25 * This class provides a default new window implementation for wxWebView clients
26 * who don't want/need to roll their own browser frame UI.
27 */
28
29 #include "config.h"
30
31 #include "wx/wxprec.h"
32 #ifndef WX_PRECOMP
33 #include "wx/wx.h"
34 #endif
35
36 #include "wx/artprov.h"
37
38 #include "WebBrowserShell.h"
39 #include "WebFrame.h"
40 #include "WebView.h"
41 #include "WebViewPrivate.h"
42
wxPageSourceViewFrame(const wxString & source)43 wxPageSourceViewFrame::wxPageSourceViewFrame(const wxString& source)
44 : wxFrame(NULL, wxID_ANY, _("Page Source View"), wxDefaultPosition, wxSize(600, 500))
45 {
46 wxTextCtrl* control = new wxTextCtrl(this, -1, source, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
47 }
48
49 enum {
50 ID_LOADFILE = wxID_HIGHEST + 1,
51 ID_TEXTCTRL = wxID_HIGHEST + 2,
52 ID_BACK = wxID_HIGHEST + 3,
53 ID_FORWARD = wxID_HIGHEST + 4,
54 ID_TOGGLE_BEFORE_LOAD = wxID_HIGHEST + 5,
55 ID_MAKE_TEXT_LARGER = wxID_HIGHEST + 6,
56 ID_MAKE_TEXT_SMALLER = wxID_HIGHEST + 7,
57 ID_STOP = wxID_HIGHEST + 8,
58 ID_RELOAD = wxID_HIGHEST + 9,
59 ID_GET_SOURCE = wxID_HIGHEST + 10,
60 ID_SET_SOURCE = wxID_HIGHEST + 11,
61 ID_SEARCHCTRL = wxID_HIGHEST + 12,
62 ID_LOADURL = wxID_HIGHEST + 13,
63 ID_NEW_WINDOW = wxID_HIGHEST + 14,
64 ID_BROWSE = wxID_HIGHEST + 15,
65 ID_EDIT = wxID_HIGHEST + 16,
66 ID_RUN_SCRIPT = wxID_HIGHEST + 17,
67 ID_WEBVIEW = wxID_HIGHEST + 18,
68 ID_EDIT_COMMAND = wxID_HIGHEST + 19,
69 ID_GET_EDIT_COMMAND_STATE = wxID_HIGHEST + 20
70 };
71
BEGIN_EVENT_TABLE(wxWebBrowserShell,wxFrame)72 BEGIN_EVENT_TABLE(wxWebBrowserShell, wxFrame)
73 EVT_MENU(wxID_CUT, wxWebBrowserShell::OnCut)
74 EVT_MENU(wxID_COPY, wxWebBrowserShell::OnCopy)
75 EVT_MENU(wxID_PASTE, wxWebBrowserShell::OnPaste)
76 EVT_MENU(wxID_EXIT, wxWebBrowserShell::OnQuit)
77 EVT_MENU(wxID_ABOUT, wxWebBrowserShell::OnAbout)
78 EVT_MENU(ID_LOADFILE, wxWebBrowserShell::OnLoadFile)
79 EVT_TEXT_ENTER(ID_TEXTCTRL, wxWebBrowserShell::OnAddressBarEnter)
80 EVT_TEXT_ENTER(ID_SEARCHCTRL, wxWebBrowserShell::OnSearchCtrlEnter)
81 EVT_WEBVIEW_LOAD(ID_WEBVIEW, wxWebBrowserShell::OnLoadEvent)
82 EVT_WEBVIEW_BEFORE_LOAD(ID_WEBVIEW, wxWebBrowserShell::OnBeforeLoad)
83 EVT_MENU(ID_BACK, wxWebBrowserShell::OnBack)
84 EVT_MENU(ID_FORWARD, wxWebBrowserShell::OnForward)
85 EVT_MENU(ID_STOP, wxWebBrowserShell::OnStop)
86 EVT_MENU(ID_RELOAD, wxWebBrowserShell::OnReload)
87 EVT_MENU(ID_MAKE_TEXT_LARGER, wxWebBrowserShell::OnMakeTextLarger)
88 EVT_MENU(ID_MAKE_TEXT_SMALLER, wxWebBrowserShell::OnMakeTextSmaller)
89 EVT_MENU(ID_GET_SOURCE, wxWebBrowserShell::OnGetSource)
90 EVT_MENU(ID_SET_SOURCE, wxWebBrowserShell::OnSetSource)
91 EVT_MENU(ID_BROWSE, wxWebBrowserShell::OnBrowse)
92 EVT_MENU(ID_EDIT, wxWebBrowserShell::OnEdit)
93 EVT_MENU(ID_RUN_SCRIPT, wxWebBrowserShell::OnRunScript)
94 EVT_MENU(ID_EDIT_COMMAND, wxWebBrowserShell::OnEditCommand)
95 EVT_MENU(ID_GET_EDIT_COMMAND_STATE, wxWebBrowserShell::OnGetEditCommandState)
96 END_EVENT_TABLE()
97
98
99 wxWebBrowserShell::wxWebBrowserShell(const wxString& title) :
100 wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600, 500)),
101 m_checkBeforeLoad(false)
102 {
103
104 // create a menu bar
105 wxMenu *fileMenu = new wxMenu;
106 fileMenu->Append(ID_NEW_WINDOW, _T("New Window\tCTRL+N"));
107 fileMenu->Append(ID_LOADFILE, _T("Open File...\tCTRL+O"));
108 fileMenu->Append(ID_LOADURL, _("Open Location...\tCTRL+L"));
109 fileMenu->Append(wxID_EXIT, _T("E&xit\tAlt-X"), _T("Quit this program"));
110
111 wxMenu *editMenu = new wxMenu;
112 editMenu->Append(wxID_CUT, _T("Cut\tCTRL+X"));
113 editMenu->Append(wxID_COPY, _T("Copy\tCTRL+C"));
114 editMenu->Append(wxID_PASTE, _T("Paste\tCTRL+V"));
115
116 wxMenu* viewMenu = new wxMenu;
117 viewMenu->AppendRadioItem(ID_BROWSE, _("Browse"));
118 viewMenu->AppendRadioItem(ID_EDIT, _("Edit"));
119 viewMenu->AppendSeparator();
120 viewMenu->Append(ID_STOP, _("Stop"));
121 viewMenu->Append(ID_RELOAD, _("Reload Page"));
122 viewMenu->Append(ID_MAKE_TEXT_SMALLER, _("Make Text Smaller\tCTRL+-"));
123 viewMenu->Append(ID_MAKE_TEXT_LARGER, _("Make Text Bigger\tCTRL++"));
124 viewMenu->AppendSeparator();
125 viewMenu->Append(ID_GET_SOURCE, _("View Page Source"));
126 viewMenu->AppendSeparator();
127
128 m_debugMenu = new wxMenu;
129 m_debugMenu->Append(ID_SET_SOURCE, _("Test SetPageSource"));
130 m_debugMenu->Append(ID_RUN_SCRIPT, _("Test RunScript"));
131 m_debugMenu->Append(ID_EDIT_COMMAND, _("Test EditCommand::Execute"));
132 m_debugMenu->Append(ID_GET_EDIT_COMMAND_STATE, _("Test EditCommand::GetState"));
133
134 // the "About" item should be in the help menu
135 wxMenu *helpMenu = new wxMenu;
136 helpMenu->Append(wxID_ABOUT, _T("&About...\tF1"), _T("Show about dialog"));
137
138 // now append the freshly created menu to the menu bar...
139 wxMenuBar *menuBar = new wxMenuBar();
140 menuBar->Append(fileMenu, _T("&File"));
141 menuBar->Append(editMenu, _T("&Edit"));
142 menuBar->Append(viewMenu, _T("&View"));
143 menuBar->Append(helpMenu, _T("&Help"));
144
145 // ... and attach this menu bar to the frame
146 SetMenuBar(menuBar);
147
148 wxToolBar* toolbar = CreateToolBar();
149 toolbar->SetToolBitmapSize(wxSize(32, 32));
150
151 wxBitmap back = wxArtProvider::GetBitmap(wxART_GO_BACK, wxART_TOOLBAR, wxSize(32,32));
152 toolbar->AddTool(ID_BACK, back, wxT("Back"));
153
154 wxBitmap forward = wxArtProvider::GetBitmap(wxART_GO_FORWARD, wxART_TOOLBAR, wxSize(32,32));
155 toolbar->AddTool(ID_FORWARD, forward, wxT("Next"));
156
157 addressBar = new wxTextCtrl(toolbar, ID_TEXTCTRL, _T(""), wxDefaultPosition, wxSize(400, -1), wxTE_PROCESS_ENTER);
158 toolbar->AddControl(addressBar);
159
160 searchCtrl = new wxSearchCtrl(toolbar, ID_SEARCHCTRL, _("Search"), wxDefaultPosition, wxSize(200, -1), wxTE_PROCESS_ENTER);
161 toolbar->AddControl(searchCtrl);
162 toolbar->Realize();
163
164 SetToolBar(toolbar);
165
166 // Create the wxWebView Window
167 webview = new wxWebView((wxWindow*)this, ID_WEBVIEW, wxDefaultPosition, wxSize(200, 200));
168 webview->SetBackgroundColour(*wxWHITE);
169
170 // create a status bar just for fun (by default with 1 pane only)
171 CreateStatusBar(2);
172 }
173
~wxWebBrowserShell()174 wxWebBrowserShell::~wxWebBrowserShell()
175 {
176 if (m_debugMenu && GetMenuBar()->FindMenu(_("&Debug")) == wxNOT_FOUND)
177 delete m_debugMenu;
178 }
179
ShowDebugMenu(bool show)180 void wxWebBrowserShell::ShowDebugMenu(bool show)
181 {
182 int debugMenu = GetMenuBar()->FindMenu(_("&Debug"));
183 if (show && debugMenu == wxNOT_FOUND) {
184 int prevMenu = GetMenuBar()->FindMenu(_("&View"));
185 if (prevMenu != wxNOT_FOUND)
186 GetMenuBar()->Insert((size_t)prevMenu+1, m_debugMenu, _("&Debug"));
187 }
188 else if (!show && debugMenu != wxNOT_FOUND) {
189 GetMenuBar()->Remove(debugMenu);
190 }
191 }
192
193 // event handlers
194
OnQuit(wxCommandEvent & WXUNUSED (event))195 void wxWebBrowserShell::OnQuit(wxCommandEvent& WXUNUSED(event))
196 {
197 // true is to force the frame to close
198 Close(true);
199 }
200
OnAbout(wxCommandEvent & WXUNUSED (event))201 void wxWebBrowserShell::OnAbout(wxCommandEvent& WXUNUSED(event))
202 {
203 wxString msg;
204 msg.Printf(_T("This is the About dialog of the wxWebKit sample.\n")
205 _T("Welcome to %s"), wxVERSION_STRING);
206
207 wxMessageBox(msg, _T("About wxWebKit Sample"), wxOK | wxICON_INFORMATION, this);
208
209 }
210
OnLoadFile(wxCommandEvent & WXUNUSED (event))211 void wxWebBrowserShell::OnLoadFile(wxCommandEvent& WXUNUSED(event))
212 {
213 wxFileDialog* dialog = new wxFileDialog(this, wxT("Choose a file"));
214 if (dialog->ShowModal() == wxID_OK) {
215 wxString path = dialog->GetPath().Prepend(wxT("file://"));
216
217 if (webview)
218 webview->LoadURL(path);
219 }
220 }
221
OnLoadEvent(wxWebViewLoadEvent & event)222 void wxWebBrowserShell::OnLoadEvent(wxWebViewLoadEvent& event)
223 {
224 if (GetStatusBar() != NULL){
225 if (event.GetState() == wxWEBVIEW_LOAD_NEGOTIATING) {
226 GetStatusBar()->SetStatusText(_("Contacting ") + event.GetURL());
227 }
228 else if (event.GetState() == wxWEBVIEW_LOAD_TRANSFERRING) {
229 GetStatusBar()->SetStatusText(_("Loading ") + event.GetURL());
230 }
231 else if (event.GetState() == wxWEBVIEW_LOAD_ONLOAD_HANDLED) {
232 GetStatusBar()->SetStatusText(_("Load complete."));
233 addressBar->SetValue(event.GetURL());
234 SetTitle(webview->GetPageTitle());
235 }
236 else if (event.GetState() == wxWEBVIEW_LOAD_FAILED) {
237 GetStatusBar()->SetStatusText(_("Failed to load ") + event.GetURL());
238 }
239 }
240 }
241
OnBeforeLoad(wxWebViewBeforeLoadEvent & myEvent)242 void wxWebBrowserShell::OnBeforeLoad(wxWebViewBeforeLoadEvent& myEvent)
243 {
244 if (m_checkBeforeLoad) {
245 int reply = wxMessageBox(_("Would you like to continue loading ") + myEvent.GetURL() + wxT("?"), _("Continue Loading?"), wxYES_NO);
246 if (reply == wxNO) {
247 myEvent.Cancel();
248 }
249 }
250 }
251
OnAddressBarEnter(wxCommandEvent & event)252 void wxWebBrowserShell::OnAddressBarEnter(wxCommandEvent& event)
253 {
254 if (webview)
255 webview->LoadURL(addressBar->GetValue());
256 }
257
OnSearchCtrlEnter(wxCommandEvent & event)258 void wxWebBrowserShell::OnSearchCtrlEnter(wxCommandEvent& event)
259 {
260 if (webview) {
261 webview->LoadURL(wxString::Format(wxT("http://www.google.com/search?rls=en&q=%s&ie=UTF-8&oe=UTF-8"), searchCtrl->GetValue().wc_str()));
262 }
263 }
264
OnCut(wxCommandEvent & event)265 void wxWebBrowserShell::OnCut(wxCommandEvent& event)
266 {
267 if (webview && webview->CanCut())
268 webview->Cut();
269 }
270
OnCopy(wxCommandEvent & event)271 void wxWebBrowserShell::OnCopy(wxCommandEvent& event)
272 {
273 if (webview && webview->CanCopy())
274 webview->Copy();
275 }
276
OnPaste(wxCommandEvent & event)277 void wxWebBrowserShell::OnPaste(wxCommandEvent& event)
278 {
279 if (webview && webview->CanPaste())
280 webview->Paste();
281 }
282
OnBack(wxCommandEvent & event)283 void wxWebBrowserShell::OnBack(wxCommandEvent& event)
284 {
285 if (webview)
286 webview->GoBack();
287 }
288
OnForward(wxCommandEvent & event)289 void wxWebBrowserShell::OnForward(wxCommandEvent& event)
290 {
291 if (webview)
292 webview->GoForward();
293 }
294
OnStop(wxCommandEvent & myEvent)295 void wxWebBrowserShell::OnStop(wxCommandEvent& myEvent)
296 {
297 if (webview)
298 webview->Stop();
299 }
300
OnReload(wxCommandEvent & myEvent)301 void wxWebBrowserShell::OnReload(wxCommandEvent& myEvent)
302 {
303 if (webview)
304 webview->Reload();
305 }
306
OnMakeTextLarger(wxCommandEvent & myEvent)307 void wxWebBrowserShell::OnMakeTextLarger(wxCommandEvent& myEvent)
308 {
309 if (webview) {
310 if (webview->CanIncreaseTextSize())
311 webview->IncreaseTextSize();
312 }
313 }
314
OnMakeTextSmaller(wxCommandEvent & myEvent)315 void wxWebBrowserShell::OnMakeTextSmaller(wxCommandEvent& myEvent)
316 {
317 if (webview) {
318 if (webview->CanDecreaseTextSize())
319 webview->DecreaseTextSize();
320 }
321 }
322
OnGetSource(wxCommandEvent & myEvent)323 void wxWebBrowserShell::OnGetSource(wxCommandEvent& myEvent)
324 {
325 if (webview) {
326 wxPageSourceViewFrame* pageSourceFrame = new wxPageSourceViewFrame(webview->GetPageSource());
327 pageSourceFrame->Show();
328 }
329 }
330
OnSetSource(wxCommandEvent & event)331 void wxWebBrowserShell::OnSetSource(wxCommandEvent& event)
332 {
333 if (webview)
334 webview->SetPageSource(wxString(wxT("<p>Hello World!</p>")));
335 }
336
OnBrowse(wxCommandEvent & event)337 void wxWebBrowserShell::OnBrowse(wxCommandEvent& event)
338 {
339 if (webview)
340 webview->MakeEditable(!event.IsChecked());
341 }
342
OnEdit(wxCommandEvent & event)343 void wxWebBrowserShell::OnEdit(wxCommandEvent& event)
344 {
345 if (webview)
346 webview->MakeEditable(event.IsChecked());
347 }
348
OnRunScript(wxCommandEvent & myEvent)349 void wxWebBrowserShell::OnRunScript(wxCommandEvent& myEvent)
350 {
351 if (webview) {
352 wxTextEntryDialog* dialog = new wxTextEntryDialog(this, _("Type in a JavaScript to exectute."));
353 if (dialog->ShowModal() == wxID_OK)
354 wxMessageBox(wxT("Result is: ") + webview->RunScript(dialog->GetValue()));
355
356 dialog->Destroy();
357 }
358 }
359
OnEditCommand(wxCommandEvent & myEvent)360 void wxWebBrowserShell::OnEditCommand(wxCommandEvent& myEvent)
361 {
362 if (webview) {
363 if (!webview->IsEditable()) {
364 wxMessageBox(wxT("Please enable editing before running editing commands."));
365 return;
366 }
367
368 wxTextEntryDialog* dialog = new wxTextEntryDialog(this, _("Type in a editing command to exectute."));
369 if (dialog->ShowModal() == wxID_OK) {
370 bool result = webview->ExecuteEditCommand(dialog->GetValue());
371 if (!result)
372 wxMessageBox(wxT("Editing command failed."));
373 }
374 dialog->Destroy();
375 }
376 }
377
OnGetEditCommandState(wxCommandEvent & myEvent)378 void wxWebBrowserShell::OnGetEditCommandState(wxCommandEvent& myEvent)
379 {
380 if (webview) {
381 if (!webview->IsEditable()) {
382 wxMessageBox(wxT("Please enable editing before running editing commands."));
383 return;
384 }
385
386 wxTextEntryDialog* dialog = new wxTextEntryDialog(this, _("Type in a editing command whose state you want to get."));
387 if (dialog->ShowModal() == wxID_OK) {
388 EditState result = webview->GetEditCommandState(dialog->GetValue());
389 if (result == EditStateTrue)
390 wxMessageBox(wxT("State is true."));
391 else if (result == EditStateFalse)
392 wxMessageBox(wxT("State is false."));
393 else if (result == EditStateMixed)
394 wxMessageBox(wxT("State is mixed."));
395 }
396 dialog->Destroy();
397 }
398 }
399