X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b5f62a0b2db198609b45dec622a018dae37008e..11e3c6ef36393fb5863ea2f9601d8facd73acb12:/samples/html/test/test.cpp diff --git a/samples/html/test/test.cpp b/samples/html/test/test.cpp index 26f225e4b7..d42117b966 100644 --- a/samples/html/test/test.cpp +++ b/samples/html/test/test.cpp @@ -1,13 +1,13 @@ ///////////////////////////////////////////////////////////////////////////// // Name: test.cpp // Purpose: wxHtml testing example +// Author: Vaclav Slavik +// Created: 1999-07-07 +// RCS-ID: $Id$ +// Copyright: (c) Vaclav Slavik +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(__APPLE__) - #pragma implementation "test.cpp" - #pragma interface "test.cpp" -#endif - // For compilers that support precompilation, includes "wx/wx.h". #include "wx/wxprec.h" @@ -15,8 +15,8 @@ #pragma hdrstop #endif -// for all others, include the necessary headers (this file is usually all you -// need because it includes almost all "standard" wxWindows headers +// For all others, include the necessary headers (this file is usually all you +// need because it includes almost all "standard" wxWidgets headers #ifndef WX_PRECOMP #include "wx/wx.h" #endif @@ -27,6 +27,12 @@ #include "wx/html/htmlproc.h" #include "wx/fs_inet.h" #include "wx/filedlg.h" +#include "wx/utils.h" +#include "wx/clipbrd.h" +#include "wx/dataobj.h" +#include "wx/stopwatch.h" + +#include "../../sample.xpm" // ---------------------------------------------------------------------------- // private classes @@ -36,49 +42,85 @@ class MyApp : public wxApp { public: - // override base class virtuals - // ---------------------------- + virtual bool OnInit(); +}; + +// Define a new html window type: this is a wrapper for handling wxHtmlWindow events +class MyHtmlWindow : public wxHtmlWindow +{ +public: + MyHtmlWindow(wxWindow *parent) : wxHtmlWindow( parent ) + { + // no custom background initially to avoid confusing people + m_drawCustomBg = false; + } + + virtual wxHtmlOpeningStatus OnOpeningURL(wxHtmlURLType WXUNUSED(type), + const wxString& WXUNUSED(url), + wxString *WXUNUSED(redirect)) const; + + // toggle drawing of custom background + void DrawCustomBg(bool draw) + { + m_drawCustomBg = draw; + Refresh(); + } + +private: +#if wxUSE_CLIPBOARD + void OnClipboardEvent(wxClipboardTextEvent& event); +#endif // wxUSE_CLIPBOARD + void OnEraseBgEvent(wxEraseEvent& event); - // this one is called on application startup and is a good place for the app - // initialization (doing it here and not in the ctor allows to have an error - // return: if OnInit() returns false, the application terminates) - virtual bool OnInit(); + bool m_drawCustomBg; + + DECLARE_EVENT_TABLE() + wxDECLARE_NO_COPY_CLASS(MyHtmlWindow); }; // Define a new frame type: this is going to be our main frame class MyFrame : public wxFrame { public: - // ctor(s) + // ctor(s) MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size); - // event handlers (these functions should _not_ be virtual) + // event handlers (these functions should _not_ be virtual) void OnQuit(wxCommandEvent& event); void OnPageOpen(wxCommandEvent& event); + void OnDefaultLocalBrowser(wxCommandEvent& event); + void OnDefaultWebBrowser(wxCommandEvent& event); void OnBack(wxCommandEvent& event); void OnForward(wxCommandEvent& event); void OnProcessor(wxCommandEvent& event); + void OnDrawCustomBg(wxCommandEvent& event); + + void OnHtmlLinkClicked(wxHtmlLinkEvent& event); + void OnHtmlCellHover(wxHtmlCellEvent &event); + void OnHtmlCellClicked(wxHtmlCellEvent &event); private: - wxHtmlWindow *m_Html; - wxHtmlProcessor *m_Processor; - // any class wishing to process wxWindows events must use this macro - DECLARE_EVENT_TABLE() + MyHtmlWindow *m_Html; + wxHtmlProcessor *m_Processor; + + // Any class wishing to process wxWidgets events must use this macro + DECLARE_EVENT_TABLE() }; class BoldProcessor : public wxHtmlProcessor { - public: - virtual wxString Process(const wxString& s) const - { - wxString r(s); - r.Replace(wxT(""), wxEmptyString); - r.Replace(wxT(""), wxEmptyString); - r.Replace(wxT(""), wxEmptyString); - r.Replace(wxT(""), wxEmptyString); - return r; - } +public: + virtual wxString Process(const wxString& s) const + { + wxString r(s); + r.Replace(wxT(""), wxEmptyString); + r.Replace(wxT(""), wxEmptyString); + r.Replace(wxT(""), wxEmptyString); + r.Replace(wxT(""), wxEmptyString); + + return r; + } }; // ---------------------------------------------------------------------------- @@ -86,149 +128,211 @@ class BoldProcessor : public wxHtmlProcessor // ---------------------------------------------------------------------------- // IDs for the controls and the menu commands - enum - { +enum +{ // menu items - Minimal_Quit = 1, - Minimal_PageOpen, - Minimal_Back, - Minimal_Forward, - Minimal_Processor, - - // controls start here (the numbers are, of course, arbitrary) - Minimal_Text = 1000 - }; + ID_PageOpen = wxID_HIGHEST, + ID_DefaultLocalBrowser, + ID_DefaultWebBrowser, + ID_Back, + ID_Forward, + ID_Processor, + ID_DrawCustomBg +}; // ---------------------------------------------------------------------------- -// event tables and other macros for wxWindows +// event tables and other macros for wxWidgets // ---------------------------------------------------------------------------- -// the event tables connect the wxWindows events with the functions (event -// handlers) which process them. It can be also done at run-time, but for the -// simple menu events like this the static method is much simpler. - BEGIN_EVENT_TABLE(MyFrame, wxFrame) - EVT_MENU(Minimal_Quit, MyFrame::OnQuit) - EVT_MENU(Minimal_PageOpen, MyFrame::OnPageOpen) - EVT_MENU(Minimal_Back, MyFrame::OnBack) - EVT_MENU(Minimal_Forward, MyFrame::OnForward) - EVT_MENU(Minimal_Processor, MyFrame::OnProcessor) - END_EVENT_TABLE() - - // Create a new application object: this macro will allow wxWindows to create - // the application object during program execution (it's better than using a - // static object for many reasons) and also declares the accessor function - // wxGetApp() which will return the reference of the right type (i.e. MyApp and - // not wxApp) - IMPLEMENT_APP(MyApp) - - // ============================================================================ - // implementation - // ============================================================================ - - // ---------------------------------------------------------------------------- - // the application class - // ---------------------------------------------------------------------------- - // `Main program' equivalent: the program execution "starts" here - bool MyApp::OnInit() - { +BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU(wxID_EXIT, MyFrame::OnQuit) + EVT_MENU(ID_PageOpen, MyFrame::OnPageOpen) + EVT_MENU(ID_DefaultLocalBrowser, MyFrame::OnDefaultLocalBrowser) + EVT_MENU(ID_DefaultWebBrowser, MyFrame::OnDefaultWebBrowser) + EVT_MENU(ID_Back, MyFrame::OnBack) + EVT_MENU(ID_Forward, MyFrame::OnForward) + EVT_MENU(ID_Processor, MyFrame::OnProcessor) + EVT_MENU(ID_DrawCustomBg, MyFrame::OnDrawCustomBg) + + EVT_HTML_LINK_CLICKED(wxID_ANY, MyFrame::OnHtmlLinkClicked) + EVT_HTML_CELL_HOVER(wxID_ANY, MyFrame::OnHtmlCellHover) + EVT_HTML_CELL_CLICKED(wxID_ANY, MyFrame::OnHtmlCellClicked) +END_EVENT_TABLE() + +IMPLEMENT_APP(MyApp) + +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// the application class +// ---------------------------------------------------------------------------- + +// `Main program' equivalent: the program execution "starts" here +bool MyApp::OnInit() +{ + if ( !wxApp::OnInit() ) + return false; + #if wxUSE_SYSTEM_OPTIONS - wxSystemOptions::SetOption(wxT("no-maskblt"), 1); + wxSystemOptions::SetOption(wxT("no-maskblt"), 1); #endif - wxInitAllImageHandlers(); + wxInitAllImageHandlers(); #if wxUSE_FS_INET && wxUSE_STREAMS && wxUSE_SOCKETS - wxFileSystem::AddHandler(new wxInternetFSHandler); + wxFileSystem::AddHandler(new wxInternetFSHandler); #endif - SetVendorName(wxT("wxWindows")); - SetAppName(wxT("wxHtmlTest")); - // the following call to wxConfig::Get will use it to create an object... + SetVendorName(wxT("wxWidgets")); + SetAppName(wxT("wxHtmlTest")); + // the following call to wxConfig::Get will use it to create an object... // Create the main application window - MyFrame *frame = new MyFrame(_("wxHtmlWindow testing application"), - wxPoint(50, 50), wxSize(640, 480)); - - // Show it and tell the application that it's our main window - // @@@ what does it do exactly, in fact? is it necessary here? - frame->Show(TRUE); - SetTopWindow(frame); - - - // success: wxApp::OnRun() will be called which will enter the main message - // loop and the application will run. If we returned FALSE here, the - // application would exit immediately. - return TRUE; - } + MyFrame *frame = new MyFrame(_("wxHtmlWindow testing application"), + wxDefaultPosition, wxSize(640, 480)); + + frame->Show(); + + return true /* continue running */; +} // ---------------------------------------------------------------------------- // main frame // ---------------------------------------------------------------------------- - // frame constructor - MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) - : wxFrame((wxFrame *)NULL, -1, title, pos, size, wxDEFAULT_FRAME_STYLE, - wxT("html_test_app")) - { +MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size) + : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size, + wxDEFAULT_FRAME_STYLE, wxT("html_test_app")) +{ // create a menu bar - wxMenu *menuFile = new wxMenu; - wxMenu *menuNav = new wxMenu; - - menuFile->Append(Minimal_PageOpen, _("&Open HTML page...")); - menuFile->AppendSeparator(); - menuFile->Append(Minimal_Processor, _("&Remove bold attribute"), wxT(""), TRUE); - - menuFile->AppendSeparator(); - menuFile->Append(Minimal_Quit, _("&Close frame")); - menuNav->Append(Minimal_Back, _("Go &BACK")); - menuNav->Append(Minimal_Forward, _("Go &FORWARD")); + wxMenu *menuFile = new wxMenu; + wxMenu *menuNav = new wxMenu; + + menuFile->Append(ID_PageOpen, _("&Open HTML page...\tCtrl-O")); + menuFile->Append(ID_DefaultLocalBrowser, _("&Open current page with default browser")); + menuFile->Append(ID_DefaultWebBrowser, _("Open a &web page with default browser")); + menuFile->AppendSeparator(); + menuFile->Append(ID_Processor, _("&Remove bold attribute"), + wxEmptyString, wxITEM_CHECK); + menuFile->AppendSeparator(); + menuFile->AppendCheckItem(ID_DrawCustomBg, "&Draw custom background"); + menuFile->AppendSeparator(); + menuFile->Append(wxID_EXIT, _("&Close frame")); + menuNav->Append(ID_Back, _("Go &BACK")); + menuNav->Append(ID_Forward, _("Go &FORWARD")); // now append the freshly created menu to the menu bar... - wxMenuBar *menuBar = new wxMenuBar; - menuBar->Append(menuFile, _("&File")); - menuBar->Append(menuNav, _("&Navigate")); + wxMenuBar *menuBar = new wxMenuBar; + menuBar->Append(menuFile, _("&File")); + menuBar->Append(menuNav, _("&Navigate")); // ... and attach this menu bar to the frame - SetMenuBar(menuBar); - - CreateStatusBar(1); - - m_Processor = new BoldProcessor; - m_Processor->Enable(FALSE); - m_Html = new wxHtmlWindow(this); - m_Html->SetRelatedFrame(this, _("HTML : %s")); - m_Html->SetRelatedStatusBar(0); - m_Html->ReadCustomization(wxConfig::Get()); - m_Html->LoadPage(wxT("test.htm")); - m_Html->AddProcessor(m_Processor); - } + SetMenuBar(menuBar); + + SetIcon(wxIcon(sample_xpm)); + +#if wxUSE_ACCEL + // Create convenient accelerators for Back and Forward navigation + wxAcceleratorEntry entries[2]; + entries[0].Set(wxACCEL_ALT, WXK_LEFT, ID_Back); + entries[1].Set(wxACCEL_ALT, WXK_RIGHT, ID_Forward); + + wxAcceleratorTable accel(WXSIZEOF(entries), entries); + SetAcceleratorTable(accel); +#endif // wxUSE_ACCEL + +#if wxUSE_STATUSBAR + CreateStatusBar(2); +#endif // wxUSE_STATUSBAR + + m_Processor = new BoldProcessor; + m_Processor->Enable(false); + m_Html = new MyHtmlWindow(this); + m_Html->SetRelatedFrame(this, _("HTML : %s")); +#if wxUSE_STATUSBAR + m_Html->SetRelatedStatusBar(1); +#endif // wxUSE_STATUSBAR + m_Html->ReadCustomization(wxConfig::Get()); + m_Html->LoadFile(wxFileName(wxT("test.htm"))); + m_Html->AddProcessor(m_Processor); + + wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, wxT(""), + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE); + + delete wxLog::SetActiveTarget(new wxLogTextCtrl(text)); + + wxSizer *sz = new wxBoxSizer(wxVERTICAL); + sz->Add(m_Html, 3, wxGROW); + sz->Add(text, 1, wxGROW); + SetSizer(sz); +} // event handlers void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { - // TRUE is to force the frame to close - m_Html -> WriteCustomization(wxConfig::Get()); - delete wxConfig::Set(NULL); - Close(TRUE); + m_Html->WriteCustomization(wxConfig::Get()); + delete wxConfig::Set(NULL); + + // true is to force the frame to close + Close(true); } void MyFrame::OnPageOpen(wxCommandEvent& WXUNUSED(event)) { - wxString p = wxFileSelector(_("Open HTML document"), wxT(""), wxT(""), wxT(""), wxT("HTML files|*.htm")); - if (p != wxEmptyString) - m_Html -> LoadPage(p); +#if wxUSE_FILEDLG + wxString p = wxFileSelector(_("Open HTML document"), wxEmptyString, + wxEmptyString, wxEmptyString, wxT("HTML files|*.htm;*.html")); + + if (!p.empty()) + { +#if wxUSE_STOPWATCH + wxStopWatch sw; +#endif + m_Html->LoadFile(wxFileName(p)); +#if wxUSE_STOPWATCH + wxLogStatus("Loaded \"%s\" in %lums", p, sw.Time()); +#endif + } +#endif // wxUSE_FILEDLG +} + +void MyFrame::OnDefaultLocalBrowser(wxCommandEvent& WXUNUSED(event)) +{ + wxString page = m_Html->GetOpenedPage(); + if (!page.empty()) + { + wxLaunchDefaultBrowser(page); + } +} + +void MyFrame::OnDefaultWebBrowser(wxCommandEvent& WXUNUSED(event)) +{ + wxString page = m_Html->GetOpenedPage(); + if (!page.empty()) + { + wxLaunchDefaultBrowser(wxT("http://www.google.com")); + } } void MyFrame::OnBack(wxCommandEvent& WXUNUSED(event)) { -if (!m_Html -> HistoryBack()) wxMessageBox(_("You reached prehistory era!")); + if (!m_Html->HistoryBack()) + { + wxMessageBox(_("You reached prehistory era!")); + } } void MyFrame::OnForward(wxCommandEvent& WXUNUSED(event)) { -if (!m_Html -> HistoryForward()) wxMessageBox(_("No more items in history!")); + if (!m_Html->HistoryForward()) + { + wxMessageBox(_("No more items in history!")); + } } void MyFrame::OnProcessor(wxCommandEvent& WXUNUSED(event)) @@ -236,3 +340,101 @@ void MyFrame::OnProcessor(wxCommandEvent& WXUNUSED(event)) m_Processor->Enable(!m_Processor->IsEnabled()); m_Html->LoadPage(m_Html->GetOpenedPage()); } + +void MyFrame::OnDrawCustomBg(wxCommandEvent& event) +{ + m_Html->DrawCustomBg(event.IsChecked()); +} + +void MyFrame::OnHtmlLinkClicked(wxHtmlLinkEvent &event) +{ + wxLogMessage(wxT("The url '%s' has been clicked!"), event.GetLinkInfo().GetHref().c_str()); + + // skipping this event the default behaviour (load the clicked URL) + // will happen... + event.Skip(); +} + +void MyFrame::OnHtmlCellHover(wxHtmlCellEvent &event) +{ + wxLogMessage(wxT("Mouse moved over cell %p at %d;%d"), + event.GetCell(), event.GetPoint().x, event.GetPoint().y); +} + +void MyFrame::OnHtmlCellClicked(wxHtmlCellEvent &event) +{ + wxLogMessage(wxT("Click over cell %p at %d;%d"), + event.GetCell(), event.GetPoint().x, event.GetPoint().y); + + // if we don't skip the event, OnHtmlLinkClicked won't be called! + event.Skip(); +} + +wxHtmlOpeningStatus MyHtmlWindow::OnOpeningURL(wxHtmlURLType WXUNUSED(type), + const wxString& url, + wxString *WXUNUSED(redirect)) const +{ + GetRelatedFrame()->SetStatusText(url + wxT(" lately opened"),1); + return wxHTML_OPEN; +} + +BEGIN_EVENT_TABLE(MyHtmlWindow, wxHtmlWindow) +#if wxUSE_CLIPBOARD + EVT_TEXT_COPY(wxID_ANY, MyHtmlWindow::OnClipboardEvent) +#endif // wxUSE_CLIPBOARD + EVT_ERASE_BACKGROUND(MyHtmlWindow::OnEraseBgEvent) +END_EVENT_TABLE() + +#if wxUSE_CLIPBOARD +void MyHtmlWindow::OnClipboardEvent(wxClipboardTextEvent& WXUNUSED(event)) +{ + // explicitly call wxHtmlWindow::CopySelection() method + // and show the first 100 characters of the text copied in the status bar + if ( CopySelection() ) + { + wxTextDataObject data; + if ( wxTheClipboard && wxTheClipboard->Open() && wxTheClipboard->GetData(data) ) + { + const wxString text = data.GetText(); + const size_t maxTextLength = 100; + + wxLogStatus(wxString::Format(wxT("Clipboard: '%s%s'"), + wxString(text, maxTextLength).c_str(), + (text.length() > maxTextLength) ? wxT("...") + : wxT(""))); + wxTheClipboard->Close(); + + return; + } + } + + wxLogStatus(wxT("Clipboard: nothing")); +} +#endif // wxUSE_CLIPBOARD + +void MyHtmlWindow::OnEraseBgEvent(wxEraseEvent& event) +{ + if ( !m_drawCustomBg ) + { + event.Skip(); + return; + } + + // draw a background grid to show that this handler is indeed executed + + wxDC& dc = *event.GetDC(); + dc.SetPen(*wxBLUE_PEN); + dc.Clear(); + + const wxSize size = GetVirtualSize(); + for ( int x = 0; x < size.x; x += 15 ) + { + dc.DrawLine(x, 0, x, size.y); + } + + for ( int y = 0; y < size.y; y += 15 ) + { + dc.DrawLine(0, y, size.x, y); + } +} +