+ cur = *wxSTANDARD_CURSOR;
+ SetCursor(cur);
+
+ if (lnk != m_tmpLastLink)
+ {
+#if wxUSE_STATUSBAR
+ if (lnk == NULL)
+ {
+ if (m_RelatedStatusBar != -1)
+ m_RelatedFrame->SetStatusText(wxEmptyString,
+ m_RelatedStatusBar);
+ }
+ else
+ {
+ if (m_RelatedStatusBar != -1)
+ m_RelatedFrame->SetStatusText(lnk->GetHref(),
+ m_RelatedStatusBar);
+ }
+#endif // wxUSE_STATUSBAR
+ m_tmpLastLink = lnk;
+ }
+
+ m_tmpLastCell = cell;
+ }
+ else // mouse moved but stayed in the same cell
+ {
+ if ( cell )
+ OnCellMouseHover(cell, x, y);
+ }
+
+ m_tmpMouseMoved = false;
+ }
+}
+
+#if wxUSE_CLIPBOARD
+void wxHtmlWindow::StopAutoScrolling()
+{
+ if ( m_timerAutoScroll )
+ {
+ wxDELETE(m_timerAutoScroll);
+ }
+}
+
+void wxHtmlWindow::OnMouseEnter(wxMouseEvent& event)
+{
+ StopAutoScrolling();
+ event.Skip();
+}
+
+void wxHtmlWindow::OnMouseLeave(wxMouseEvent& event)
+{
+ // don't prevent the usual processing of the event from taking place
+ event.Skip();
+
+ // when a captured mouse leave a scrolled window we start generate
+ // scrolling events to allow, for example, extending selection beyond the
+ // visible area in some controls
+ if ( wxWindow::GetCapture() == this )
+ {
+ // where is the mouse leaving?
+ int pos, orient;
+ wxPoint pt = event.GetPosition();
+ if ( pt.x < 0 )
+ {
+ orient = wxHORIZONTAL;
+ pos = 0;
+ }
+ else if ( pt.y < 0 )
+ {
+ orient = wxVERTICAL;
+ pos = 0;
+ }
+ else // we're lower or to the right of the window
+ {
+ wxSize size = GetClientSize();
+ if ( pt.x > size.x )
+ {
+ orient = wxHORIZONTAL;
+ pos = GetVirtualSize().x / wxHTML_SCROLL_STEP;
+ }
+ else if ( pt.y > size.y )
+ {
+ orient = wxVERTICAL;
+ pos = GetVirtualSize().y / wxHTML_SCROLL_STEP;
+ }
+ else // this should be impossible
+ {
+ // but seems to happen sometimes under wxMSW - maybe it's a bug
+ // there but for now just ignore it
+
+ //wxFAIL_MSG( _T("can't understand where has mouse gone") );
+
+ return;
+ }
+ }
+
+ // only start the auto scroll timer if the window can be scrolled in
+ // this direction
+ if ( !HasScrollbar(orient) )
+ return;
+
+ delete m_timerAutoScroll;
+ m_timerAutoScroll = new wxHtmlWinAutoScrollTimer
+ (
+ this,
+ pos == 0 ? wxEVT_SCROLLWIN_LINEUP
+ : wxEVT_SCROLLWIN_LINEDOWN,
+ pos,
+ orient
+ );
+ m_timerAutoScroll->Start(50); // FIXME: make configurable
+ }
+}
+
+void wxHtmlWindow::OnKeyUp(wxKeyEvent& event)
+{
+ if ( IsSelectionEnabled() && event.GetKeyCode() == 'C' && event.CmdDown() )
+ {
+ (void) CopySelection();
+ }
+}
+
+void wxHtmlWindow::OnCopy(wxCommandEvent& WXUNUSED(event))
+{
+ (void) CopySelection();
+}
+
+void wxHtmlWindow::OnDoubleClick(wxMouseEvent& event)
+{
+ // select word under cursor:
+ if ( IsSelectionEnabled() )
+ {
+ SelectWord(CalcUnscrolledPosition(event.GetPosition()));
+
+ (void) CopySelection(Primary);
+
+ m_lastDoubleClick = wxGetLocalTimeMillis();
+ }
+ else
+ event.Skip();
+}
+
+void wxHtmlWindow::SelectWord(const wxPoint& pos)
+{
+ if ( m_Cell )
+ {
+ wxHtmlCell *cell = m_Cell->FindCellByPos(pos.x, pos.y);
+ if ( cell )
+ {
+ delete m_selection;
+ m_selection = new wxHtmlSelection();
+ m_selection->Set(cell, cell);
+ RefreshRect(wxRect(CalcScrolledPosition(cell->GetAbsPos()),
+ wxSize(cell->GetWidth(), cell->GetHeight())));
+ }
+ }
+}
+
+void wxHtmlWindow::SelectLine(const wxPoint& pos)
+{
+ if ( m_Cell )
+ {
+ wxHtmlCell *cell = m_Cell->FindCellByPos(pos.x, pos.y);
+ if ( cell )
+ {
+ // We use following heuristic to find a "line": let the line be all
+ // cells in same container as the cell under mouse cursor that are
+ // neither completely above nor completely bellow the clicked cell
+ // (i.e. are likely to be words positioned on same line of text).
+
+ int y1 = cell->GetAbsPos().y;
+ int y2 = y1 + cell->GetHeight();
+ int y;
+ const wxHtmlCell *c;
+ const wxHtmlCell *before = NULL;
+ const wxHtmlCell *after = NULL;
+
+ // find last cell of line:
+ for ( c = cell->GetNext(); c; c = c->GetNext())