X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/05f9197a346867069e89558a4e663cf54b2fd23b..6d41981d894198a4de266d399f0f5cd141f97df6:/src/html/htmlwin.cpp diff --git a/src/html/htmlwin.cpp b/src/html/htmlwin.cpp index 835b1d48ba..653eec918d 100644 --- a/src/html/htmlwin.cpp +++ b/src/html/htmlwin.cpp @@ -18,7 +18,7 @@ #include "wx/defs.h" #if wxUSE_HTML && wxUSE_STREAMS -#ifdef __BORDLANDC__ +#ifdef __BORLANDC__ #pragma hdrstop #endif @@ -92,13 +92,15 @@ void wxHtmlWindow::Init() m_Processors = NULL; m_Style = 0; SetBorders(10); + m_selection = NULL; + m_makingSelection = false; } -bool wxHtmlWindow::Create(wxWindow *parent, wxWindowID id, +bool wxHtmlWindow::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, - long style, const wxString& name) + long style, const wxString& name) { - if (!wxScrolledWindow::Create(parent, id, pos, size, + if (!wxScrolledWindow::Create(parent, id, pos, size, style | wxVSCROLL | wxHSCROLL, name)) return FALSE; @@ -153,6 +155,8 @@ bool wxHtmlWindow::SetPage(const wxString& source) { wxString newsrc(source); + wxDELETE(m_selection); + // pass HTML through registered processors: if (m_Processors || m_GlobalProcessors) { @@ -215,7 +219,7 @@ bool wxHtmlWindow::AppendToPage(const wxString& source) bool wxHtmlWindow::LoadPage(const wxString& location) { wxBusyCursor busyCursor; - + wxFSFile *f; bool rt_val; bool needs_refresh = FALSE; @@ -262,9 +266,17 @@ bool wxHtmlWindow::LoadPage(const wxString& location) m_RelatedFrame->SetStatusText(_("Connecting..."), m_RelatedStatusBar); Refresh(FALSE); } - + f = m_Parser->OpenURL(wxHTML_URL_PAGE, location); + // try to interpret 'location' as filename instead of URL: + if (f == NULL) + { + wxFileName fn(location); + wxString location2 = wxFileSystem::FileNameToURL(fn); + f = m_Parser->OpenURL(wxHTML_URL_PAGE, location2); + } + if (f == NULL) { wxLogError(_("Unable to open requested HTML document: %s"), location.c_str()); @@ -345,6 +357,12 @@ bool wxHtmlWindow::LoadPage(const wxString& location) } +bool wxHtmlWindow::LoadFile(const wxFileName& filename) +{ + wxString url = wxFileSystem::FileNameToURL(filename); + return LoadPage(url); +} + bool wxHtmlWindow::ScrollToAnchor(const wxString& anchor) { @@ -592,14 +610,12 @@ wxHtmlProcessorList *wxHtmlWindow::m_GlobalProcessors = NULL; void wxHtmlWindow::CleanUpStatics() { - delete m_DefaultFilter; - m_DefaultFilter = NULL; + wxDELETE(m_DefaultFilter); m_Filters.DeleteContents(TRUE); m_Filters.Clear(); - delete m_GlobalProcessors; - m_GlobalProcessors = NULL; - delete s_cur_hand; - delete s_cur_arrow; + wxDELETE(m_GlobalProcessors); + wxDELETE(s_cur_hand); + wxDELETE(s_cur_arrow); } @@ -610,11 +626,21 @@ void wxHtmlWindow::AddFilter(wxHtmlFilter *filter) } +bool wxHtmlWindow::IsSelectionEnabled() const +{ +#if wxUSE_CLIPBOARD + return !(m_Style & wxHW_NO_SELECTION); +#else + return false; +#endif +} void wxHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link) { - LoadPage(link.GetHref()); + const wxMouseEvent *e = link.GetEvent(); + if (e == NULL || e->LeftUp()) + LoadPage(link.GetHref()); } void wxHtmlWindow::OnCellClicked(wxHtmlCell *cell, @@ -643,9 +669,11 @@ void wxHtmlWindow::OnDraw(wxDC& dc) dc.SetBackgroundMode(wxTRANSPARENT); GetViewStart(&x, &y); - m_Cell->Draw(dc, 0, 0, - y * wxHTML_SCROLL_STEP + rect.GetTop(), - y * wxHTML_SCROLL_STEP + rect.GetBottom()); + wxHtmlRenderingState rstate(m_selection); + m_Cell->Draw(dc, 0, 0, + y * wxHTML_SCROLL_STEP + rect.GetTop(), + y * wxHTML_SCROLL_STEP + rect.GetBottom(), + rstate); } @@ -659,32 +687,57 @@ void wxHtmlWindow::OnSize(wxSizeEvent& event) } -void wxHtmlWindow::OnMouseEvent(wxMouseEvent& event) +void wxHtmlWindow::OnMouseMove(wxMouseEvent& event) { - m_tmpMouseMoved = TRUE; + m_tmpMouseMoved = true; +} - if (event.ButtonDown()) +void wxHtmlWindow::OnMouseDown(wxMouseEvent& event) +{ + if ( event.LeftDown() && IsSelectionEnabled() ) { - if ( m_Cell ) + m_makingSelection = true; + + if ( m_selection ) { - int sx, sy; - GetViewStart(&sx, &sy); - sx *= wxHTML_SCROLL_STEP; - sy *= wxHTML_SCROLL_STEP; + wxDELETE(m_selection); + Refresh(); + } + m_tmpSelFromPos = CalcUnscrolledPosition(event.GetPosition()); + m_tmpSelFromCell = NULL; - wxPoint pos = event.GetPosition(); - pos.x += sx; - pos.y += sy; + CaptureMouse(); + } +} - wxHtmlCell *cell = m_Cell->FindCellByPos(pos.x, pos.y); +void wxHtmlWindow::OnMouseUp(wxMouseEvent& event) +{ + if ( m_makingSelection ) + { + ReleaseMouse(); + m_makingSelection = false; - // VZ: is it possible that we don't find anything at all? - // VS: yes. FindCellByPos returns terminal cell and - // containers may have empty borders - if ( cell ) - OnCellClicked(cell, pos.x, pos.y, event); + // did the user move the mouse far enough from starting point? + if ( m_selection ) + { + // we don't want mouse up event that ended selecting to be + // handled as mouse click and e.g. follow hyperlink: + return; } } + + SetFocus(); + if ( m_Cell ) + { + wxPoint pos = CalcUnscrolledPosition(event.GetPosition()); + wxHtmlCell *cell = m_Cell->FindCellByPos(pos.x, pos.y); + + // VZ: is it possible that we don't find anything at all? + // VS: yes. FindCellByPos returns terminal cell and + // containers may have empty borders + if ( cell ) + OnCellClicked(cell, pos.x, pos.y, event); + } } @@ -699,18 +752,90 @@ void wxHtmlWindow::OnIdle(wxIdleEvent& WXUNUSED(event)) if (m_tmpMouseMoved && (m_Cell != NULL)) { - int sx, sy; - GetViewStart(&sx, &sy); - sx *= wxHTML_SCROLL_STEP; - sy *= wxHTML_SCROLL_STEP; - - int x, y; - wxGetMousePosition(&x, &y); - ScreenToClient(&x, &y); - x += sx; - y += sy; + int xc, yc, x, y; + wxGetMousePosition(&xc, &yc); + ScreenToClient(&xc, &yc); + CalcUnscrolledPosition(xc, yc, &x, &y); wxHtmlCell *cell = m_Cell->FindCellByPos(x, y); + + // handle selection update: + if ( m_makingSelection ) + { + bool goingDown = m_tmpSelFromPos.y < y || + m_tmpSelFromPos.y == y && m_tmpSelFromPos.x < x; + + if ( !m_tmpSelFromCell ) + { + if (goingDown) + { + m_tmpSelFromCell = m_Cell->FindCellByPos(x, y, + wxHTML_FIND_NEAREST_BEFORE); + if (!m_tmpSelFromCell) + m_tmpSelFromCell = m_Cell->GetFirstTerminal(); + } + else + { + m_tmpSelFromCell = m_Cell->FindCellByPos(x, y, + wxHTML_FIND_NEAREST_AFTER); + if (!m_tmpSelFromCell) + m_tmpSelFromCell = m_Cell->GetLastTerminal(); + } + } + + wxHtmlCell *selcell = cell; + if (!selcell) + { + if (goingDown) + { + selcell = m_Cell->FindCellByPos(x, y, + wxHTML_FIND_NEAREST_AFTER); + if (!selcell) + selcell = m_Cell->GetLastTerminal(); + } + else + { + selcell = m_Cell->FindCellByPos(x, y, + wxHTML_FIND_NEAREST_BEFORE); + if (!selcell) + selcell = m_Cell->GetFirstTerminal(); + } + } + + // NB: it may *rarely* happen that the code above didn't find one + // of the cells, e.g. if wxHtmlWindow doesn't contain any + // visible cells. + if ( selcell && m_tmpSelFromCell ) + { + if ( !m_selection ) + { + // start selecting only if mouse movement was big enough + // (otherwise it was meant as mouse click, not selection): + const int PRECISION = 2; + wxPoint diff = m_tmpSelFromPos - wxPoint(x,y); + if (abs(diff.x) > PRECISION || abs(diff.y) > PRECISION) + { + m_selection = new wxHtmlSelection(); + } + } + if ( m_selection ) + { + if (goingDown) + { + m_selection->Set(m_tmpSelFromPos, m_tmpSelFromCell, + wxPoint(x,y), selcell); + } + else + { + m_selection->Set(wxPoint(x,y), selcell, + m_tmpSelFromPos, m_tmpSelFromCell); + } + Refresh(); // FIXME - optimize! + } + } + } + + // handle cursor and status bar text changes: if ( cell != m_tmpLastCell ) { wxHtmlLinkInfo *lnk = cell ? cell->GetLink(x, y) : NULL; @@ -751,9 +876,10 @@ IMPLEMENT_DYNAMIC_CLASS(wxHtmlWindow,wxScrolledWindow) BEGIN_EVENT_TABLE(wxHtmlWindow, wxScrolledWindow) EVT_SIZE(wxHtmlWindow::OnSize) - EVT_LEFT_DOWN(wxHtmlWindow::OnMouseEvent) - EVT_RIGHT_DOWN(wxHtmlWindow::OnMouseEvent) - EVT_MOTION(wxHtmlWindow::OnMouseEvent) + EVT_LEFT_DOWN(wxHtmlWindow::OnMouseDown) + EVT_LEFT_UP(wxHtmlWindow::OnMouseUp) + EVT_RIGHT_UP(wxHtmlWindow::OnMouseUp) + EVT_MOTION(wxHtmlWindow::OnMouseMove) EVT_IDLE(wxHtmlWindow::OnIdle) END_EVENT_TABLE()