]>
git.saurik.com Git - wxWidgets.git/blob - src/html/htmlwin.cpp
86885419ac69e510ce647c3d3a74525793364c57
   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" 
  30 #include "wx/html/forcelnk.h" 
  34 //----------------------------------------------------------------------------- 
  36 //----------------------------------------------------------------------------- 
  40 #include "wx/arrimpl.cpp" 
  41 WX_DEFINE_OBJARRAY(HtmlHistoryArray
) 
  44 wxHtmlWindow::wxHtmlWindow(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
  45                 long style
, const wxString
& name
) : wxScrolledWindow(parent
, id
, pos
, size
, wxVSCROLL
, name
) 
  47     m_tmpMouseMoved 
= FALSE
; 
  48     m_tmpLastLink 
= wxEmptyString
; 
  50     m_FS 
= new wxFileSystem(); 
  51     m_RelatedStatusBar 
= -1; 
  52     m_RelatedFrame 
= NULL
; 
  54     m_OpenedPage 
= m_OpenedAnchor 
= m_OpenedPageTitle 
= wxEmptyString
; 
  56     m_Parser 
= new wxHtmlWinParser(this); 
  57     m_Parser 
-> SetFS(m_FS
); 
  62     SetPage("<html><body></body></html>"); 
  67 wxHtmlWindow::~wxHtmlWindow() 
  71     if (m_Cell
) delete m_Cell
; 
  73     wxList 
*parser_data 
= m_Parser 
-> GetTempData(); 
  74     if (parser_data
) delete parser_data
; 
  82 void wxHtmlWindow::SetRelatedFrame(wxFrame
* frame
, const wxString
& format
) 
  84     m_RelatedFrame 
= frame
; 
  85     m_TitleFormat 
= format
; 
  90 void wxHtmlWindow::SetRelatedStatusBar(int bar
) 
  92     m_RelatedStatusBar 
= bar
; 
  97 void wxHtmlWindow::SetFonts(wxString normal_face
, int normal_italic_mode
, wxString fixed_face
, int fixed_italic_mode
, const int *sizes
) 
  99     wxString op 
= m_OpenedPage
; 
 101     m_Parser 
-> SetFonts(normal_face
, normal_italic_mode
, fixed_face
, fixed_italic_mode
, sizes
); 
 102     SetPage(wxT("")); // fonts changed => contents invalid 
 103     if (!op
.IsEmpty()) LoadPage(op
); 
 108 bool wxHtmlWindow::SetPage(const wxString
& source
) 
 110     wxClientDC 
*dc 
= new wxClientDC(this); 
 112     dc 
-> SetMapMode(wxMM_TEXT
); 
 113     SetBackgroundColour(wxColour(0xFF, 0xFF, 0xFF)); 
 114     m_OpenedPage 
= m_OpenedAnchor 
= m_OpenedPageTitle 
= wxEmptyString
; 
 115     m_Parser 
-> SetDC(dc
); 
 120     m_Cell 
= (wxHtmlContainerCell
*) m_Parser 
-> Parse(source
); 
 122     m_Cell 
-> SetIndent(m_Borders
, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
); 
 123     m_Cell 
-> SetAlignHor(wxHTML_ALIGN_CENTER
); 
 130 bool wxHtmlWindow::LoadPage(const wxString
& location
) 
 135     SetCursor(*wxHOURGLASS_CURSOR
); 
 138     m_tmpCanDraw 
= FALSE
; 
 139     if (m_HistoryOn 
&& (m_HistoryPos 
!= -1)) { // store scroll position into history item 
 142         m_History
[m_HistoryPos
].SetPos(y
); 
 145     if (location
[0] == '#') { // local anchor 
 146         wxString anch 
= location
.Mid(1) /*1 to end*/; 
 148         rt_val 
= ScrollToAnchor(anch
); 
 153         if (m_RelatedStatusBar 
!= -1) { 
 154             m_RelatedFrame 
-> SetStatusText(_("Connecting..."), m_RelatedStatusBar
); 
 158         f 
= m_FS 
-> OpenFile(location
); 
 162             err
.Printf(_("The browser is unable to open requested location :\n\n%s"), WXSTRINGCAST location
); 
 165             wxMessageBox(err
, "Error"); 
 167             SetCursor(*wxSTANDARD_CURSOR
); 
 173             wxString src 
= wxEmptyString
; 
 175             if (m_RelatedStatusBar 
!= -1) { 
 176                 wxString msg 
= _("Loading : ") + location
; 
 177                 m_RelatedFrame 
-> SetStatusText(msg
, m_RelatedStatusBar
); 
 181             node 
= m_Filters
.GetFirst(); 
 183                 wxHtmlFilter 
*h 
= (wxHtmlFilter
*) node 
-> GetData(); 
 184                 if (h 
-> CanRead(*f
)) { 
 185                     src 
= h 
-> ReadFile(*f
); 
 188                 node 
= node 
-> GetNext(); 
 190             if (src 
== wxEmptyString
) { 
 191                 if (m_DefaultFilter 
== NULL
) m_DefaultFilter 
= GetDefaultFilter(); 
 192                 src 
= m_DefaultFilter 
-> ReadFile(*f
); 
 195             m_FS 
-> ChangePathTo(f 
-> GetLocation()); 
 196             rt_val 
= SetPage(src
); 
 197             m_OpenedPage 
= f 
-> GetLocation(); 
 198             if (f 
-> GetAnchor() != wxEmptyString
) { 
 200                 ScrollToAnchor(f 
-> GetAnchor()); 
 201                 m_tmpCanDraw 
= FALSE
; 
 206             if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(_("Done"), m_RelatedStatusBar
); 
 210     if (m_HistoryOn
) { // add this page to history there: 
 211         int c 
= m_History
.GetCount() - (m_HistoryPos 
+ 1); 
 214         for (int i 
= 0; i 
< c
; i
++) 
 215             m_History
.Remove(m_HistoryPos
); 
 216         m_History
.Add(new HtmlHistoryItem(m_OpenedPage
, m_OpenedAnchor
)); 
 219     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(1, 1, 0, 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(1, 1, 0, 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(1, 1, 0, 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
; 
 301     if (path 
!= wxEmptyString
) { 
 302         oldpath 
= cfg 
-> GetPath(); 
 303         cfg 
-> SetPath(path
); 
 306     m_Borders 
= cfg 
-> Read("wxHtmlWindow/Borders", m_Borders
); 
 307     p_fff 
= cfg 
-> Read("wxHtmlWindow/FontFaceFixed", m_Parser 
-> m_FontFaceFixed
); 
 308     p_ffn 
= cfg 
-> Read("wxHtmlWindow/FontFaceNormal", m_Parser 
-> m_FontFaceNormal
); 
 309     p_imf 
= cfg 
-> Read("wxHtmlWindow/ItalicModeFixed", m_Parser 
-> m_ItalicModeFixed
); 
 310     p_imn 
= cfg 
-> Read("wxHtmlWindow/ItalicModeNormal", m_Parser 
-> m_ItalicModeNormal
); 
 311     for (int i 
= 0; i 
< 7; i
++) { 
 312         tmp
.Printf(wxT("wxHtmlWindow/FontsSize%i"), i
); 
 313         p_fontsizes
[i
] = cfg 
-> Read(tmp
, m_Parser 
-> m_FontsSizes
[i
]); 
 315     m_Parser 
-> SetFonts(p_ffn
, p_imn
, p_fff
, p_imf
, p_fontsizes
); 
 317     if (path 
!= wxEmptyString
) 
 318         cfg 
-> SetPath(oldpath
); 
 323 void wxHtmlWindow::WriteCustomization(wxConfigBase 
*cfg
, wxString path
) 
 328     if (path 
!= wxEmptyString
) { 
 329         oldpath 
= cfg 
-> GetPath(); 
 330         cfg 
-> SetPath(path
); 
 333     cfg 
-> Write("wxHtmlWindow/Borders", (long) m_Borders
); 
 334     cfg 
-> Write("wxHtmlWindow/FontFaceFixed", m_Parser 
-> m_FontFaceFixed
); 
 335     cfg 
-> Write("wxHtmlWindow/FontFaceNormal", m_Parser 
-> m_FontFaceNormal
); 
 336     cfg 
-> Write("wxHtmlWindow/ItalicModeFixed", (long) m_Parser 
-> m_ItalicModeFixed
); 
 337     cfg 
-> Write("wxHtmlWindow/ItalicModeNormal", (long) m_Parser 
-> m_ItalicModeNormal
); 
 338     for (int i 
= 0; i 
< 7; i
++) { 
 339         tmp
.Printf(wxT("wxHtmlWindow/FontsSize%i"), i
); 
 340         cfg 
-> Write(tmp
, (long) m_Parser 
-> m_FontsSizes
[i
]); 
 343     if (path 
!= wxEmptyString
) 
 344         cfg 
-> SetPath(oldpath
); 
 349 bool wxHtmlWindow::HistoryBack() 
 353     if (m_HistoryPos 
< 1) return FALSE
; 
 357     l 
= m_History
[m_HistoryPos
].GetPage(); 
 358     a 
= m_History
[m_HistoryPos
].GetAnchor(); 
 360     if (a 
== wxEmptyString
) LoadPage(l
); 
 361     else LoadPage(l 
+ "#" + a
); 
 363     Scroll(0, m_History
[m_HistoryPos
].GetPos()); 
 370 bool wxHtmlWindow::HistoryForward() 
 374     if (m_HistoryPos 
== -1) return FALSE
; 
 375     if (m_HistoryPos 
>= (int)m_History
.GetCount() - 1)return FALSE
; 
 377     m_OpenedPage 
= wxEmptyString
; // this will disable adding new entry into history in LoadPage() 
 380     l 
= m_History
[m_HistoryPos
].GetPage(); 
 381     a 
= m_History
[m_HistoryPos
].GetAnchor(); 
 383     if (a 
== wxEmptyString
) LoadPage(l
); 
 384     else LoadPage(l 
+ "#" + a
); 
 386     Scroll(0, m_History
[m_HistoryPos
].GetPos()); 
 393 void wxHtmlWindow::HistoryClear() 
 401 wxList 
wxHtmlWindow::m_Filters
; 
 402 wxHtmlFilter 
*wxHtmlWindow::m_DefaultFilter 
= NULL
; 
 404 void wxHtmlWindow::CleanUpStatics() 
 406     if (m_DefaultFilter
) delete m_DefaultFilter
; 
 407     m_DefaultFilter 
= NULL
; 
 408     m_Filters
.DeleteContents(TRUE
); 
 415 void wxHtmlWindow::AddFilter(wxHtmlFilter 
*filter
) 
 417     m_Filters
.Append(filter
); 
 423 void wxHtmlWindow::OnLinkClicked(const wxString
& link
) 
 430 void wxHtmlWindow::OnDraw(wxDC
& dc
) 
 433     wxRegionIterator 
upd(GetUpdateRegion()); // get the update rect list 
 436     if (!m_tmpCanDraw
) return; 
 437     dc
.SetMapMode(wxMM_TEXT
); 
 438 #if defined(_MSC_VER) && (_MSC_VER == 1200) 
 439     ::SetMapMode((HDC
)dc
.GetHDC(), MM_TEXT
); 
 441     dc
.SetBackgroundMode(wxTRANSPARENT
); 
 447         if (m_Cell
) m_Cell 
-> Draw(dc
, 0, 0, y 
* wxHTML_SCROLL_STEP 
+ v_y
, y 
* wxHTML_SCROLL_STEP 
+ v_h 
+ v_y
); 
 455 void wxHtmlWindow::OnSize(wxSizeEvent
& event
) 
 457     wxScrolledWindow::OnSize(event
); 
 463 void wxHtmlWindow::OnKeyDown(wxKeyEvent
& event
) 
 468     ViewStart(&dummy
, &sty
); 
 469     GetClientSize(&dummy
, &cliy
); cliy 
/= wxHTML_SCROLL_STEP
; 
 470     GetVirtualSize(&dummy
, &szy
); szy 
/= wxHTML_SCROLL_STEP
; 
 472     switch (event
.KeyCode()) { 
 475                 Scroll(-1, sty 
- cliy
); 
 479                 Scroll(-1, sty 
+ cliy
); 
 485                 Scroll(-1, szy 
- cliy
); 
 498 void wxHtmlWindow::OnMouseEvent(wxMouseEvent
& event
) 
 500     m_tmpMouseMoved 
= TRUE
; 
 502     if (event
.ButtonDown()) { 
 507         ViewStart(&sx
, &sy
); sx 
*= wxHTML_SCROLL_STEP
; sy 
*= wxHTML_SCROLL_STEP
; 
 508         pos 
= event
.GetPosition(); 
 511             m_Cell 
-> OnMouseClick(this, sx 
+ pos
.x
, sy 
+ pos
.y
, event
.ButtonDown(1), event
.ButtonDown(2), event
.ButtonDown(3)); 
 517 void wxHtmlWindow::OnIdle(wxIdleEvent
& event
) 
 519     static wxCursor 
cur_hand(wxCURSOR_HAND
), cur_arrow(wxCURSOR_ARROW
); 
 521     if (m_tmpMouseMoved 
&& (m_Cell 
!= NULL
)) { 
 526         ViewStart(&sx
, &sy
); sx 
*= wxHTML_SCROLL_STEP
; sy 
*= wxHTML_SCROLL_STEP
; 
 527         wxGetMousePosition(&x
, &y
); 
 528         ScreenToClient(&x
, &y
); 
 529         lnk 
= m_Cell 
-> GetLink(sx 
+ x
, sy 
+ y
); 
 531         if (lnk 
!= m_tmpLastLink
) { 
 532             if (lnk 
== wxEmptyString
) { 
 533                 SetCursor(cur_arrow
); 
 534                 if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(wxEmptyString
, m_RelatedStatusBar
); 
 538                 if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(lnk
, m_RelatedStatusBar
); 
 542         m_tmpMouseMoved 
= FALSE
; 
 549 IMPLEMENT_DYNAMIC_CLASS(wxHtmlWindow
,wxScrolledWindow
) 
 551 BEGIN_EVENT_TABLE(wxHtmlWindow
, wxScrolledWindow
) 
 552     EVT_SIZE(wxHtmlWindow::OnSize
) 
 553     EVT_LEFT_DOWN(wxHtmlWindow::OnMouseEvent
) 
 554     EVT_MOTION(wxHtmlWindow::OnMouseEvent
) 
 555     EVT_IDLE(wxHtmlWindow::OnIdle
) 
 556     EVT_KEY_DOWN(wxHtmlWindow::OnKeyDown
) 
 563 // A module to allow initialization/cleanup 
 564 // without calling these functions from app.cpp or from 
 565 // the user's application. 
 567 class wxHtmlWinModule
: public wxModule
 
 569 DECLARE_DYNAMIC_CLASS(wxHtmlWinModule
) 
 571     wxHtmlWinModule() : wxModule() {} 
 572     bool OnInit() { return TRUE
; } 
 573     void OnExit() { wxHtmlWindow::CleanUpStatics(); } 
 576 IMPLEMENT_DYNAMIC_CLASS(wxHtmlWinModule
, wxModule
) 
 581 ///// default mod handlers are forced there: 
 583 FORCE_LINK(mod_layout
) 
 584 FORCE_LINK(mod_fonts
) 
 585 FORCE_LINK(mod_image
) 
 588 FORCE_LINK(mod_hline
) 
 589 FORCE_LINK(mod_links
) 
 590 FORCE_LINK(mod_tables
)