]>
git.saurik.com Git - wxWidgets.git/blob - src/html/htmlwin.cpp
0f0b5d67a86e4167c72b785eab61f20246a885f9
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxHtmlWindow class for parsing & displaying HTML (implementation) 
   4 // Author:      Vaclav Slavik 
   6 // Copyright:   (c) 1999 Vaclav Slavik 
   7 // Licence:     wxWindows Licence 
   8 ///////////////////////////////////////////////////////////////////////////// 
  12 #pragma implementation 
  15 #include "wx/wxprec.h" 
  28 #include "wx/html/htmlwin.h" 
  29 #include "wx/html/forcelnk.h" 
  33 //----------------------------------------------------------------------------- 
  35 //----------------------------------------------------------------------------- 
  39 #include "wx/arrimpl.cpp" 
  40 WX_DEFINE_OBJARRAY(HtmlHistoryArray
) 
  43 wxHtmlWindow::wxHtmlWindow(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
  44                 long style
, const wxString
& name
) : wxScrolledWindow(parent
, id
, pos
, size
, wxVSCROLL
, name
) 
  46     m_tmpMouseMoved 
= FALSE
; 
  47     m_tmpLastLink 
= wxEmptyString
; 
  48     m_tmpCanDrawLocks 
= 0; 
  49     m_FS 
= new wxFileSystem(); 
  50     m_RelatedStatusBar 
= -1; 
  51     m_RelatedFrame 
= NULL
; 
  53     m_OpenedPage 
= m_OpenedAnchor 
= m_OpenedPageTitle 
= wxEmptyString
; 
  55     m_Parser 
= new wxHtmlWinParser(this); 
  56     m_Parser 
-> SetFS(m_FS
); 
  61     SetPage("<html><body></body></html>"); 
  66 wxHtmlWindow::~wxHtmlWindow() 
  70     if (m_Cell
) delete m_Cell
; 
  72     wxList 
*parser_data 
= m_Parser 
-> GetTempData(); 
  73     if (parser_data
) delete parser_data
; 
  81 void wxHtmlWindow::SetRelatedFrame(wxFrame
* frame
, const wxString
& format
) 
  83     m_RelatedFrame 
= frame
; 
  84     m_TitleFormat 
= format
; 
  89 void wxHtmlWindow::SetRelatedStatusBar(int bar
) 
  91     m_RelatedStatusBar 
= bar
; 
  96 void wxHtmlWindow::SetFonts(wxString normal_face
, wxString fixed_face
, const int *sizes
) 
  98     wxString op 
= m_OpenedPage
; 
 100     m_Parser 
-> SetFonts(normal_face
, fixed_face
, sizes
); 
 101     SetPage(wxT("<html><body></body></html>")); // fonts changed => contents invalid 
 102     if (!op
.IsEmpty()) LoadPage(op
); 
 107 bool wxHtmlWindow::SetPage(const wxString
& source
) 
 109     wxClientDC 
*dc 
= new wxClientDC(this); 
 111     dc 
-> SetMapMode(wxMM_TEXT
); 
 112     SetBackgroundColour(wxColour(0xFF, 0xFF, 0xFF)); 
 113     m_OpenedPage 
= m_OpenedAnchor 
= m_OpenedPageTitle 
= wxEmptyString
; 
 114     m_Parser 
-> SetDC(dc
); 
 119     m_Cell 
= (wxHtmlContainerCell
*) m_Parser 
-> Parse(source
); 
 121     m_Cell 
-> SetIndent(m_Borders
, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
); 
 122     m_Cell 
-> SetAlignHor(wxHTML_ALIGN_CENTER
); 
 124     if (m_tmpCanDrawLocks 
== 0) Refresh(); 
 129 bool wxHtmlWindow::LoadPage(const wxString
& location
) 
 134     SetCursor(*wxHOURGLASS_CURSOR
); 
 138     if (m_HistoryOn 
&& (m_HistoryPos 
!= -1)) { // store scroll position into history item 
 141         m_History
[m_HistoryPos
].SetPos(y
); 
 144     if (location
[0] == '#') { // local anchor 
 145         wxString anch 
= location
.Mid(1) /*1 to end*/; 
 147         rt_val 
= ScrollToAnchor(anch
); 
 152         if (m_RelatedStatusBar 
!= -1) { 
 153             m_RelatedFrame 
-> SetStatusText(_("Connecting..."), m_RelatedStatusBar
); 
 157         f 
= m_FS 
-> OpenFile(location
); 
 161             err
.Printf(_("The browser is unable to open requested location :\n\n%s"), WXSTRINGCAST location
); 
 164             wxMessageBox(err
, "Error"); 
 166             SetCursor(*wxSTANDARD_CURSOR
); 
 172             wxString src 
= wxEmptyString
; 
 174             if (m_RelatedStatusBar 
!= -1) { 
 175                 wxString msg 
= _("Loading : ") + location
; 
 176                 m_RelatedFrame 
-> SetStatusText(msg
, m_RelatedStatusBar
); 
 180             node 
= m_Filters
.GetFirst(); 
 182                 wxHtmlFilter 
*h 
= (wxHtmlFilter
*) node 
-> GetData(); 
 183                 if (h 
-> CanRead(*f
)) { 
 184                     src 
= h 
-> ReadFile(*f
); 
 187                 node 
= node 
-> GetNext(); 
 189             if (src 
== wxEmptyString
) { 
 190                 if (m_DefaultFilter 
== NULL
) m_DefaultFilter 
= GetDefaultFilter(); 
 191                 src 
= m_DefaultFilter 
-> ReadFile(*f
); 
 194             m_FS 
-> ChangePathTo(f 
-> GetLocation()); 
 195             rt_val 
= SetPage(src
); 
 196             m_OpenedPage 
= f 
-> GetLocation(); 
 197             if (f 
-> GetAnchor() != wxEmptyString
) { 
 198 //                m_tmpCanDrawLocks--; 
 199                 ScrollToAnchor(f 
-> GetAnchor()); 
 200 //                m_tmpCanDrawLocks++; 
 205             if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(_("Done"), m_RelatedStatusBar
); 
 209     if (m_HistoryOn
) { // add this page to history there: 
 210         int c 
= m_History
.GetCount() - (m_HistoryPos 
+ 1); 
 213         for (int i 
= 0; i 
< c
; i
++) 
 214             m_History
.Remove(m_HistoryPos
); 
 215         m_History
.Add(new HtmlHistoryItem(m_OpenedPage
, m_OpenedAnchor
)); 
 218     SetCursor(*wxSTANDARD_CURSOR
); 
 228 bool wxHtmlWindow::ScrollToAnchor(const wxString
& anchor
) 
 230     const wxHtmlCell 
*c 
= m_Cell 
-> Find(wxHTML_COND_ISANCHOR
, &anchor
); 
 231     if (!c
) return FALSE
; 
 235         for (y 
= 0; c 
!= NULL
; c 
= c 
-> GetParent()) y 
+= c 
-> GetPosY(); 
 236         Scroll(-1, y 
/ wxHTML_SCROLL_STEP
); 
 237         m_OpenedAnchor 
= anchor
; 
 243 void wxHtmlWindow::OnSetTitle(const wxString
& title
) 
 245     if (m_RelatedFrame
) { 
 247         tit
.Printf(m_TitleFormat
, title
.c_str()); 
 248         m_RelatedFrame 
-> SetTitle(tit
); 
 250     m_OpenedPageTitle 
= title
; 
 257 void wxHtmlWindow::CreateLayout() 
 259     int ClientWidth
, ClientHeight
; 
 263     if (m_Style 
== wxHW_SCROLLBAR_NEVER
) { 
 264         SetScrollbars(wxHTML_SCROLL_STEP
, 1, m_Cell 
-> GetWidth() / wxHTML_SCROLL_STEP
, 0); // always off 
 265         GetClientSize(&ClientWidth
, &ClientHeight
); 
 266         m_Cell 
-> Layout(ClientWidth
); 
 270         GetClientSize(&ClientWidth
, &ClientHeight
); 
 272         // VS : this looks extremely ugly under windoze, better fix needed! 
 273         SetScrollbars(wxHTML_SCROLL_STEP
, 1, m_Cell 
-> GetWidth() / wxHTML_SCROLL_STEP
, ClientHeight 
* 2); // always on 
 275         GetClientSize(&ClientWidth
, &ClientHeight
); 
 276         m_Cell 
-> Layout(ClientWidth
); 
 277         if (ClientHeight 
< m_Cell 
-> GetHeight()) { 
 278             SetScrollbars(wxHTML_SCROLL_STEP
, wxHTML_SCROLL_STEP
, 
 279                           m_Cell 
-> GetWidth() / wxHTML_SCROLL_STEP
, 
 280                           m_Cell 
-> GetHeight() / wxHTML_SCROLL_STEP
 
 281                           /*cheat: top-level frag is always container*/); 
 283         else { /* we fit into window, no need for scrollbars */ 
 284             SetScrollbars(wxHTML_SCROLL_STEP
, 1, m_Cell 
-> GetWidth() / wxHTML_SCROLL_STEP
, 0); // disable... 
 285             GetClientSize(&ClientWidth
, &ClientHeight
); 
 286             m_Cell 
-> Layout(ClientWidth
); // ...and relayout 
 293 void wxHtmlWindow::ReadCustomization(wxConfigBase 
*cfg
, wxString path
) 
 298     wxString p_fff
, p_ffn
; 
 300     if (path 
!= wxEmptyString
) { 
 301         oldpath 
= cfg 
-> GetPath(); 
 302         cfg 
-> SetPath(path
); 
 305     m_Borders 
= cfg 
-> Read("wxHtmlWindow/Borders", m_Borders
); 
 306     p_fff 
= cfg 
-> Read("wxHtmlWindow/FontFaceFixed", m_Parser 
-> m_FontFaceFixed
); 
 307     p_ffn 
= cfg 
-> Read("wxHtmlWindow/FontFaceNormal", m_Parser 
-> m_FontFaceNormal
); 
 308     for (int i 
= 0; i 
< 7; i
++) { 
 309         tmp
.Printf(wxT("wxHtmlWindow/FontsSize%i"), i
); 
 310         p_fontsizes
[i
] = cfg 
-> Read(tmp
, m_Parser 
-> m_FontsSizes
[i
]); 
 312     SetFonts(p_ffn
, p_fff
, p_fontsizes
); 
 314     if (path 
!= wxEmptyString
) 
 315         cfg 
-> SetPath(oldpath
); 
 320 void wxHtmlWindow::WriteCustomization(wxConfigBase 
*cfg
, wxString path
) 
 325     if (path 
!= wxEmptyString
) { 
 326         oldpath 
= cfg 
-> GetPath(); 
 327         cfg 
-> SetPath(path
); 
 330     cfg 
-> Write("wxHtmlWindow/Borders", (long) m_Borders
); 
 331     cfg 
-> Write("wxHtmlWindow/FontFaceFixed", m_Parser 
-> m_FontFaceFixed
); 
 332     cfg 
-> Write("wxHtmlWindow/FontFaceNormal", m_Parser 
-> m_FontFaceNormal
); 
 333     for (int i 
= 0; i 
< 7; i
++) { 
 334         tmp
.Printf(wxT("wxHtmlWindow/FontsSize%i"), i
); 
 335         cfg 
-> Write(tmp
, (long) m_Parser 
-> m_FontsSizes
[i
]); 
 338     if (path 
!= wxEmptyString
) 
 339         cfg 
-> SetPath(oldpath
); 
 344 bool wxHtmlWindow::HistoryBack() 
 348     if (m_HistoryPos 
< 1) return FALSE
; 
 352     l 
= m_History
[m_HistoryPos
].GetPage(); 
 353     a 
= m_History
[m_HistoryPos
].GetAnchor(); 
 356     if (a 
== wxEmptyString
) LoadPage(l
); 
 357     else LoadPage(l 
+ "#" + a
); 
 361     Scroll(0, m_History
[m_HistoryPos
].GetPos()); 
 368 bool wxHtmlWindow::HistoryForward() 
 372     if (m_HistoryPos 
== -1) return FALSE
; 
 373     if (m_HistoryPos 
>= (int)m_History
.GetCount() - 1)return FALSE
; 
 375     m_OpenedPage 
= wxEmptyString
; // this will disable adding new entry into history in LoadPage() 
 378     l 
= m_History
[m_HistoryPos
].GetPage(); 
 379     a 
= m_History
[m_HistoryPos
].GetAnchor(); 
 382     if (a 
== wxEmptyString
) LoadPage(l
); 
 383     else LoadPage(l 
+ "#" + a
); 
 387     Scroll(0, m_History
[m_HistoryPos
].GetPos()); 
 394 void wxHtmlWindow::HistoryClear() 
 402 wxList 
wxHtmlWindow::m_Filters
; 
 403 wxHtmlFilter 
*wxHtmlWindow::m_DefaultFilter 
= NULL
; 
 405 void wxHtmlWindow::CleanUpStatics() 
 407     if (m_DefaultFilter
) delete m_DefaultFilter
; 
 408     m_DefaultFilter 
= NULL
; 
 409     m_Filters
.DeleteContents(TRUE
); 
 416 void wxHtmlWindow::AddFilter(wxHtmlFilter 
*filter
) 
 418     m_Filters
.Append(filter
); 
 424 void wxHtmlWindow::OnLinkClicked(const wxString
& link
) 
 431 void wxHtmlWindow::OnDraw(wxDC
& dc
) 
 434     wxRegionIterator 
upd(GetUpdateRegion()); // get the update rect list 
 437     if (m_tmpCanDrawLocks 
> 0) return; 
 438     dc
.SetMapMode(wxMM_TEXT
); 
 439 #if defined(_MSC_VER) && (_MSC_VER == 1200) 
 440     ::SetMapMode((HDC
)dc
.GetHDC(), MM_TEXT
); 
 442     dc
.SetBackgroundMode(wxTRANSPARENT
); 
 448         if (m_Cell
) m_Cell 
-> Draw(dc
, 0, 0, y 
* wxHTML_SCROLL_STEP 
+ v_y
, y 
* wxHTML_SCROLL_STEP 
+ v_h 
+ v_y
); 
 456 void wxHtmlWindow::OnSize(wxSizeEvent
& event
) 
 458     wxScrolledWindow::OnSize(event
); 
 464 void wxHtmlWindow::OnKeyDown(wxKeyEvent
& event
) 
 469     ViewStart(&dummy
, &sty
); 
 470     GetClientSize(&dummy
, &cliy
); cliy 
/= wxHTML_SCROLL_STEP
; 
 471     GetVirtualSize(&dummy
, &szy
); szy 
/= wxHTML_SCROLL_STEP
; 
 473     switch (event
.KeyCode()) { 
 476                 Scroll(-1, sty 
- cliy
); 
 480                 Scroll(-1, sty 
+ cliy
); 
 486                 Scroll(-1, szy 
- cliy
); 
 499 void wxHtmlWindow::OnMouseEvent(wxMouseEvent
& event
) 
 501     m_tmpMouseMoved 
= TRUE
; 
 503     if (event
.ButtonDown()) { 
 508         ViewStart(&sx
, &sy
); sx 
*= wxHTML_SCROLL_STEP
; sy 
*= wxHTML_SCROLL_STEP
; 
 509         pos 
= event
.GetPosition(); 
 512             m_Cell 
-> OnMouseClick(this, sx 
+ pos
.x
, sy 
+ pos
.y
, event
.ButtonDown(1), event
.ButtonDown(2), event
.ButtonDown(3)); 
 518 void wxHtmlWindow::OnIdle(wxIdleEvent
& event
) 
 520     static wxCursor 
cur_hand(wxCURSOR_HAND
), cur_arrow(wxCURSOR_ARROW
); 
 522     if (m_tmpMouseMoved 
&& (m_Cell 
!= NULL
)) { 
 527         ViewStart(&sx
, &sy
); sx 
*= wxHTML_SCROLL_STEP
; sy 
*= wxHTML_SCROLL_STEP
; 
 528         wxGetMousePosition(&x
, &y
); 
 529         ScreenToClient(&x
, &y
); 
 530         lnk 
= m_Cell 
-> GetLink(sx 
+ x
, sy 
+ y
); 
 532         if (lnk 
!= m_tmpLastLink
) { 
 533             if (lnk 
== wxEmptyString
) { 
 534                 SetCursor(cur_arrow
); 
 535                 if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(wxEmptyString
, m_RelatedStatusBar
); 
 539                 if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(lnk
, m_RelatedStatusBar
); 
 543         m_tmpMouseMoved 
= FALSE
; 
 550 IMPLEMENT_DYNAMIC_CLASS(wxHtmlWindow
,wxScrolledWindow
) 
 552 BEGIN_EVENT_TABLE(wxHtmlWindow
, wxScrolledWindow
) 
 553     EVT_SIZE(wxHtmlWindow::OnSize
) 
 554     EVT_LEFT_DOWN(wxHtmlWindow::OnMouseEvent
) 
 555     EVT_MOTION(wxHtmlWindow::OnMouseEvent
) 
 556     EVT_IDLE(wxHtmlWindow::OnIdle
) 
 557     EVT_KEY_DOWN(wxHtmlWindow::OnKeyDown
) 
 564 // A module to allow initialization/cleanup 
 565 // without calling these functions from app.cpp or from 
 566 // the user's application. 
 568 class wxHtmlWinModule
: public wxModule
 
 570 DECLARE_DYNAMIC_CLASS(wxHtmlWinModule
) 
 572     wxHtmlWinModule() : wxModule() {} 
 573     bool OnInit() { return TRUE
; } 
 574     void OnExit() { wxHtmlWindow::CleanUpStatics(); } 
 577 IMPLEMENT_DYNAMIC_CLASS(wxHtmlWinModule
, wxModule
) 
 582 ///// default mod handlers are forced there: