htmlwin.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 1,495 行 · 第 1/3 页
CPP
1,495 行
}
else
{
int y;
for (y = 0; c != NULL; c = c->GetParent()) y += c->GetPosY();
Scroll(-1, y / wxHTML_SCROLL_STEP);
m_OpenedAnchor = anchor;
return true;
}
}
void wxHtmlWindow::OnSetTitle(const wxString& title)
{
if (m_RelatedFrame)
{
wxString tit;
tit.Printf(m_TitleFormat, title.c_str());
m_RelatedFrame->SetTitle(tit);
}
m_OpenedPageTitle = title;
}
void wxHtmlWindow::CreateLayout()
{
int ClientWidth, ClientHeight;
if (!m_Cell) return;
if (m_Style & wxHW_SCROLLBAR_NEVER)
{
SetScrollbars(wxHTML_SCROLL_STEP, 1, m_Cell->GetWidth() / wxHTML_SCROLL_STEP, 0); // always off
GetClientSize(&ClientWidth, &ClientHeight);
m_Cell->Layout(ClientWidth);
}
else {
GetClientSize(&ClientWidth, &ClientHeight);
m_Cell->Layout(ClientWidth);
if (ClientHeight < m_Cell->GetHeight() + GetCharHeight())
{
SetScrollbars(
wxHTML_SCROLL_STEP, wxHTML_SCROLL_STEP,
m_Cell->GetWidth() / wxHTML_SCROLL_STEP,
(m_Cell->GetHeight() + GetCharHeight()) / wxHTML_SCROLL_STEP
/*cheat: top-level frag is always container*/);
}
else /* we fit into window, no need for scrollbars */
{
SetScrollbars(wxHTML_SCROLL_STEP, 1, m_Cell->GetWidth() / wxHTML_SCROLL_STEP, 0); // disable...
GetClientSize(&ClientWidth, &ClientHeight);
m_Cell->Layout(ClientWidth); // ...and relayout
}
}
}
void wxHtmlWindow::ReadCustomization(wxConfigBase *cfg, wxString path)
{
wxString oldpath;
wxString tmp;
int p_fontsizes[7];
wxString p_fff, p_ffn;
if (path != wxEmptyString)
{
oldpath = cfg->GetPath();
cfg->SetPath(path);
}
m_Borders = cfg->Read(wxT("wxHtmlWindow/Borders"), m_Borders);
p_fff = cfg->Read(wxT("wxHtmlWindow/FontFaceFixed"), m_Parser->m_FontFaceFixed);
p_ffn = cfg->Read(wxT("wxHtmlWindow/FontFaceNormal"), m_Parser->m_FontFaceNormal);
for (int i = 0; i < 7; i++)
{
tmp.Printf(wxT("wxHtmlWindow/FontsSize%i"), i);
p_fontsizes[i] = cfg->Read(tmp, m_Parser->m_FontsSizes[i]);
}
SetFonts(p_ffn, p_fff, p_fontsizes);
if (path != wxEmptyString)
cfg->SetPath(oldpath);
}
void wxHtmlWindow::WriteCustomization(wxConfigBase *cfg, wxString path)
{
wxString oldpath;
wxString tmp;
if (path != wxEmptyString)
{
oldpath = cfg->GetPath();
cfg->SetPath(path);
}
cfg->Write(wxT("wxHtmlWindow/Borders"), (long) m_Borders);
cfg->Write(wxT("wxHtmlWindow/FontFaceFixed"), m_Parser->m_FontFaceFixed);
cfg->Write(wxT("wxHtmlWindow/FontFaceNormal"), m_Parser->m_FontFaceNormal);
for (int i = 0; i < 7; i++)
{
tmp.Printf(wxT("wxHtmlWindow/FontsSize%i"), i);
cfg->Write(tmp, (long) m_Parser->m_FontsSizes[i]);
}
if (path != wxEmptyString)
cfg->SetPath(oldpath);
}
bool wxHtmlWindow::HistoryBack()
{
wxString a, l;
if (m_HistoryPos < 1) return false;
// store scroll position into history item:
int x, y;
GetViewStart(&x, &y);
(*m_History)[m_HistoryPos].SetPos(y);
// go to previous position:
m_HistoryPos--;
l = (*m_History)[m_HistoryPos].GetPage();
a = (*m_History)[m_HistoryPos].GetAnchor();
m_HistoryOn = false;
m_tmpCanDrawLocks++;
if (a == wxEmptyString) LoadPage(l);
else LoadPage(l + wxT("#") + a);
m_HistoryOn = true;
m_tmpCanDrawLocks--;
Scroll(0, (*m_History)[m_HistoryPos].GetPos());
Refresh();
return true;
}
bool wxHtmlWindow::HistoryCanBack()
{
if (m_HistoryPos < 1) return false;
return true ;
}
bool wxHtmlWindow::HistoryForward()
{
wxString a, l;
if (m_HistoryPos == -1) return false;
if (m_HistoryPos >= (int)m_History->GetCount() - 1)return false;
m_OpenedPage = wxEmptyString; // this will disable adding new entry into history in LoadPage()
m_HistoryPos++;
l = (*m_History)[m_HistoryPos].GetPage();
a = (*m_History)[m_HistoryPos].GetAnchor();
m_HistoryOn = false;
m_tmpCanDrawLocks++;
if (a == wxEmptyString) LoadPage(l);
else LoadPage(l + wxT("#") + a);
m_HistoryOn = true;
m_tmpCanDrawLocks--;
Scroll(0, (*m_History)[m_HistoryPos].GetPos());
Refresh();
return true;
}
bool wxHtmlWindow::HistoryCanForward()
{
if (m_HistoryPos == -1) return false;
if (m_HistoryPos >= (int)m_History->GetCount() - 1)return false;
return true ;
}
void wxHtmlWindow::HistoryClear()
{
m_History->Empty();
m_HistoryPos = -1;
}
void wxHtmlWindow::AddProcessor(wxHtmlProcessor *processor)
{
if (!m_Processors)
{
m_Processors = new wxHtmlProcessorList;
}
wxHtmlProcessorList::compatibility_iterator node;
for (node = m_Processors->GetFirst(); node; node = node->GetNext())
{
if (processor->GetPriority() > node->GetData()->GetPriority())
{
m_Processors->Insert(node, processor);
return;
}
}
m_Processors->Append(processor);
}
/*static */ void wxHtmlWindow::AddGlobalProcessor(wxHtmlProcessor *processor)
{
if (!m_GlobalProcessors)
{
m_GlobalProcessors = new wxHtmlProcessorList;
}
wxHtmlProcessorList::compatibility_iterator node;
for (node = m_GlobalProcessors->GetFirst(); node; node = node->GetNext())
{
if (processor->GetPriority() > node->GetData()->GetPriority())
{
m_GlobalProcessors->Insert(node, processor);
return;
}
}
m_GlobalProcessors->Append(processor);
}
wxList wxHtmlWindow::m_Filters;
wxHtmlFilter *wxHtmlWindow::m_DefaultFilter = NULL;
wxHtmlProcessorList *wxHtmlWindow::m_GlobalProcessors = NULL;
void wxHtmlWindow::CleanUpStatics()
{
wxDELETE(m_DefaultFilter);
WX_CLEAR_LIST(wxList, m_Filters);
if (m_GlobalProcessors)
WX_CLEAR_LIST(wxHtmlProcessorList, *m_GlobalProcessors);
wxDELETE(m_GlobalProcessors);
}
void wxHtmlWindow::AddFilter(wxHtmlFilter *filter)
{
m_Filters.Append(filter);
}
bool wxHtmlWindow::IsSelectionEnabled() const
{
#if wxUSE_CLIPBOARD
return !(m_Style & wxHW_NO_SELECTION);
#else
return false;
#endif
}
#if wxUSE_CLIPBOARD
wxString wxHtmlWindow::DoSelectionToText(wxHtmlSelection *sel)
{
if ( !sel )
return wxEmptyString;
wxClientDC dc(this);
const wxHtmlCell *end = sel->GetToCell();
wxString text;
wxHtmlTerminalCellsInterator i(sel->GetFromCell(), end);
if ( i )
{
text << i->ConvertToText(sel);
++i;
}
const wxHtmlCell *prev = *i;
while ( i )
{
if ( prev->GetParent() != i->GetParent() )
text << _T('\n');
text << i->ConvertToText(*i == end ? sel : NULL);
prev = *i;
++i;
}
return text;
}
wxString wxHtmlWindow::ToText()
{
if (m_Cell)
{
wxHtmlSelection sel;
sel.Set(m_Cell->GetFirstTerminal(), m_Cell->GetLastTerminal());
return DoSelectionToText(&sel);
}
else
return wxEmptyString;
}
#endif // wxUSE_CLIPBOARD
bool wxHtmlWindow::CopySelection(ClipboardType t)
{
#if wxUSE_CLIPBOARD
if ( m_selection )
{
#if defined(__UNIX__) && !defined(__WXMAC__)
wxTheClipboard->UsePrimarySelection(t == Primary);
#else // !__UNIX__
// Primary selection exists only under X11, so don't do anything under
// the other platforms when we try to access it
//
// TODO: this should be abstracted at wxClipboard level!
if ( t == Primary )
return false;
#endif // __UNIX__/!__UNIX__
if ( wxTheClipboard->Open() )
{
const wxString txt(SelectionToText());
wxTheClipboard->SetData(new wxTextDataObject(txt));
wxTheClipboard->Close();
wxLogTrace(_T("wxhtmlselection"),
_("Copied to clipboard:\"%s\""), txt.c_str());
return true;
}
}
#else
wxUnusedVar(t);
#endif // wxUSE_CLIPBOARD
return false;
}
void wxHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link)
{
const wxMouseEvent *e = link.GetEvent();
if (e == NULL || e->LeftUp())
LoadPage(link.GetHref());
}
void wxHtmlWindow::OnCellClicked(wxHtmlCell *cell,
wxCoord x, wxCoord y,
const wxMouseEvent& event)
{
wxCHECK_RET( cell, _T("can't be called with NULL cell") );
cell->OnMouseClick(this, x, y, event);
}
void wxHtmlWindow::OnCellMouseHover(wxHtmlCell * WXUNUSED(cell),
wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
{
// do nothing here
}
void wxHtmlWindow::OnEraseBackground(wxEraseEvent& event)
{
if ( !m_bmpBg.Ok() )
{
// don't even skip the event, if we don't have a bg bitmap we're going
// to overwrite background in OnPaint() below anyhow, so letting the
// default handling take place would only result in flicker, just set a
// flag to erase the background below
m_eraseBgInOnPaint = true;
return;
}
wxDC& dc = *event.GetDC();
// if the image is not fully opaque, we have to erase the background before
// drawing it, however avoid doing it for opaque images as this would just
// result in extra flicker without any other effect as background is
// completely covered anyhow
if ( m_bmpBg.GetMask() )
{
dc.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID));
dc.Clear();
}
const wxSize sizeWin(GetClientSize());
const wxSize sizeBmp(m_bmpBg.GetWidth(), m_bmpBg.GetHeight());
for ( wxCoord x = 0; x < sizeWin.x; x += sizeBmp.x )
{
for ( wxCoord y = 0; y < sizeWin.y; y += sizeBmp.y )
{
dc.DrawBitmap(m_bmpBg, x, y, true /* use mask */);
}
}
}
void wxHtmlWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
if (m_tmpCanDrawLocks > 0 || m_Cell == NULL)
return;
int x, y;
GetViewStart(&x, &y);
wxRect rect = GetUpdateRegion().GetBox();
wxSize sz = GetSize();
wxMemoryDC dcm;
if ( !m_backBuffer )
m_backBuffer = new wxBitmap(sz.x, sz.y);
dcm.SelectObject(*m_backBuffer);
if ( m_eraseBgInOnPaint )
{
dcm.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID));
dcm.Clear();
m_eraseBgInOnPaint = false;
}
else // someone has already erased the background, keep it
{
// preserve the existing background, otherwise we'd erase anything the
// user code had drawn in its EVT_ERASE_BACKGROUND handler when we do
// the Blit back below
dcm.Blit(0, rect.GetTop(),
sz.x, rect.GetBottom() - rect.GetTop() + 1,
&dc,
0, rect.GetTop());
}
PrepareDC(dcm);
dcm.SetMapMode(wxMM_TEXT);
dcm.SetBackgroundMode(wxTRANSPARENT);
wxHtmlRenderingInfo rinfo;
wxDefaultHtmlRenderingStyle rstyle;
rinfo.SetSelection(m_selection);
rinfo.SetStyle(&rstyle);
m_Cell->Draw(dcm, 0, 0,
y * wxHTML_SCROLL_STEP + rect.GetTop(),
y * wxHTML_SCROLL_STEP + rect.GetBottom(),
rinfo);
//#define DEBUG_HTML_SELECTION
#ifdef DEBUG_HTML_SELECTION
{
int xc, yc, x, y;
wxGetMousePosition(&xc, &yc);
ScreenToClient(&xc, &yc);
CalcUnscrolledPosition(xc, yc, &x, &y);
wxHtmlCell *at = m_Cell->FindCellByPos(x, y);
wxHtmlCell *before =
m_Cell->FindCellByPos(x, y, wxHTML_FIND_NEAREST_BEFORE);
wxHtmlCell *after =
m_Cell->FindCellByPos(x, y, wxHTML_FIND_NEAREST_AFTER);
dcm.SetBrush(*wxTRANSPARENT_BRUSH);
dcm.SetPen(*wxBLACK_PEN);
if (at)
dcm.DrawRectangle(at->GetAbsPos(),
wxSize(at->GetWidth(),at->GetHeight()));
dcm.SetPen(*wxGREEN_PEN);
if (before)
dcm.DrawRectangle(before->GetAbsPos().x+1, before->GetAbsPos().y+1,
before->GetWidth()-2,before->GetHeight()-2);
dcm.SetPen(*wxRED_PEN);
if (after)
dcm.DrawRectangle(after->GetAbsPos().x+2, after->GetAbsPos().y+2,
after->GetWidth()-4,after->GetHeight()-4);
}
#endif
dcm.SetDeviceOrigin(0,0);
dc.Blit(0, rect.GetTop(),
sz.x, rect.GetBottom() - rect.GetTop() + 1,
&dcm,
0, rect.GetTop());
}
void wxHtmlWindow::OnSize(wxSizeEvent& event)
{
wxDELETE(m_backBuffer);
wxScrolledWindow::OnSize(event);
CreateLayout();
// Recompute selection if necessary:
if ( m_selection )
{
m_selection->Set(m_selection->GetFromCell(),
m_selection->GetToCell());
m_selection->ClearPrivPos();
}
Refresh();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?