]>
git.saurik.com Git - wxWidgets.git/blob - src/html/htmlwin.cpp
53921edc616a86929039bb89566cecba6002bf14
   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 
= 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     m_Parser 
-> SetFonts(normal_face
, normal_italic_mode
, fixed_face
, fixed_italic_mode
, sizes
); 
 100     if (!m_OpenedPage
.IsEmpty()) LoadPage(m_OpenedPage
); 
 105 bool wxHtmlWindow::SetPage(const wxString
& source
) 
 107     wxClientDC 
*dc 
= new wxClientDC(this); 
 109     dc 
-> SetMapMode(wxMM_TEXT
); 
 110     SetBackgroundColour(wxColour(0xFF, 0xFF, 0xFF)); 
 111     m_OpenedPage 
= m_OpenedAnchor 
= wxEmptyString
; 
 112     m_Parser 
-> SetDC(dc
); 
 117     m_Cell 
= (wxHtmlContainerCell
*) m_Parser 
-> Parse(source
); 
 119     m_Cell 
-> SetIndent(m_Borders
, wxHTML_INDENT_ALL
, wxHTML_UNITS_PIXELS
); 
 120     m_Cell 
-> SetAlignHor(wxHTML_ALIGN_CENTER
); 
 127 bool wxHtmlWindow::LoadPage(const wxString
& location
) 
 133     m_tmpCanDraw 
= FALSE
; 
 134     if (m_HistoryOn 
&& (m_HistoryPos 
!= -1)) { // store scroll position into history item 
 137         m_History
[m_HistoryPos
].SetPos(y
); 
 140     if (location
[0] == '#') { // local anchor 
 141         wxString anch 
= location
.Mid(1) /*1 to end*/; 
 143         rt_val 
= ScrollToAnchor(anch
); 
 148         if (m_RelatedStatusBar 
!= -1) { 
 149             m_RelatedFrame 
-> SetStatusText(_("Connecting..."), m_RelatedStatusBar
); 
 153         f 
= m_FS 
-> OpenFile(location
); 
 157             err
.Printf(_("The browser is unable to open requested location :\n\n%s"), WXSTRINGCAST location
); 
 160             wxMessageBox(err
, "Error"); 
 166             wxString src 
= wxEmptyString
; 
 168             if (m_RelatedStatusBar 
!= -1) { 
 169                 wxString msg 
= _("Loading : ") + location
; 
 170                 m_RelatedFrame 
-> SetStatusText(msg
, m_RelatedStatusBar
); 
 174             node 
= m_Filters
.GetFirst(); 
 176                 wxHtmlFilter 
*h 
= (wxHtmlFilter
*) node 
-> GetData(); 
 177                 if (h 
-> CanRead(*f
)) { 
 178                     src 
= h 
-> ReadFile(*f
); 
 181                 node 
= node 
-> GetNext(); 
 183             if (src 
== wxEmptyString
) { 
 184                 if (m_DefaultFilter 
== NULL
) m_DefaultFilter 
= GetDefaultFilter(); 
 185                 src 
= m_DefaultFilter 
-> ReadFile(*f
); 
 188             m_FS 
-> ChangePathTo(f 
-> GetLocation()); 
 189             rt_val 
= SetPage(src
); 
 190             m_OpenedPage 
= f 
-> GetLocation(); 
 191             if (f 
-> GetAnchor() != wxEmptyString
) { 
 193                 ScrollToAnchor(f 
-> GetAnchor()); 
 194                 m_tmpCanDraw 
= FALSE
; 
 199             if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(_("Done"), m_RelatedStatusBar
); 
 203     if (m_HistoryOn
) { // add this page to history there: 
 204         int c 
= m_History
.GetCount() - (m_HistoryPos 
+ 1); 
 207         for (int i 
= 0; i 
< c
; i
++) 
 208             m_History
.Remove(m_HistoryPos
); 
 209         m_History
.Add(new HtmlHistoryItem(m_OpenedPage
, m_OpenedAnchor
)); 
 219 bool wxHtmlWindow::ScrollToAnchor(const wxString
& anchor
) 
 221     const wxHtmlCell 
*c 
= m_Cell 
-> Find(wxHTML_COND_ISANCHOR
, &anchor
); 
 222     if (!c
) return FALSE
; 
 226         for (y 
= 0; c 
!= NULL
; c 
= c 
-> GetParent()) y 
+= c 
-> GetPosY(); 
 227         Scroll(-1, y 
/ wxHTML_SCROLL_STEP
); 
 228         m_OpenedAnchor 
= anchor
; 
 234 void wxHtmlWindow::SetTitle(const wxString
& title
) 
 236     if (m_RelatedFrame
) { 
 238         tit
.Printf(m_TitleFormat
, title
.c_str()); 
 239         m_RelatedFrame 
-> SetTitle(tit
); 
 247 void wxHtmlWindow::CreateLayout() 
 249     int ClientWidth
, ClientHeight
; 
 253     if (m_Style 
== wxHW_SCROLLBAR_NEVER
) { 
 254         SetScrollbars(1, 1, 0, 0); // always off 
 255         GetClientSize(&ClientWidth
, &ClientHeight
); 
 256         m_Cell 
-> Layout(ClientWidth
); 
 260         GetClientSize(&ClientWidth
, &ClientHeight
); 
 262         // VS : this looks extremely ugly under windoze, better fix needed! 
 263         SetScrollbars(1, 1, 0, ClientHeight 
* 2); // always on 
 265         GetClientSize(&ClientWidth
, &ClientHeight
); 
 266         m_Cell 
-> Layout(ClientWidth
); 
 267         if (ClientHeight 
< m_Cell 
-> GetHeight()) { 
 268             SetScrollbars(wxHTML_SCROLL_STEP
, wxHTML_SCROLL_STEP
, 
 269                           m_Cell 
-> GetWidth() / wxHTML_SCROLL_STEP
, 
 270                           m_Cell 
-> GetHeight() / wxHTML_SCROLL_STEP
 
 271                           /*cheat: top-level frag is always container*/); 
 273             else { /* we fit into window, no need for scrollbars */ 
 274                 SetScrollbars(1, 1, 0, 0); // disable... 
 275                 GetClientSize(&ClientWidth
, &ClientHeight
); 
 276                 m_Cell 
-> Layout(ClientWidth
); // ...and relayout 
 283 void wxHtmlWindow::ReadCustomization(wxConfigBase 
*cfg
, wxString path
) 
 288     if (path 
!= wxEmptyString
) { 
 289         oldpath 
= cfg 
-> GetPath(); 
 290         cfg 
-> SetPath(path
); 
 293     m_Borders 
= cfg 
-> Read("wxHtmlWindow/Borders", m_Borders
); 
 294     m_Parser 
-> m_FontFaceFixed 
= cfg 
-> Read("wxHtmlWindow/FontFaceFixed", m_Parser 
-> m_FontFaceFixed
); 
 295     m_Parser 
-> m_FontFaceNormal 
= cfg 
-> Read("wxHtmlWindow/FontFaceNormal", m_Parser 
-> m_FontFaceNormal
); 
 296     m_Parser 
-> m_ItalicModeFixed 
= cfg 
-> Read("wxHtmlWindow/ItalicModeFixed", m_Parser 
-> m_ItalicModeFixed
); 
 297     m_Parser 
-> m_ItalicModeNormal 
= cfg 
-> Read("wxHtmlWindow/ItalicModeNormal", m_Parser 
-> m_ItalicModeNormal
); 
 298     for (int i 
= 0; i 
< 7; i
++) { 
 299         tmp
.Printf(wxT("wxHtmlWindow/FontsSize%i"), i
); 
 300         m_Parser 
-> m_FontsSizes
[i
] = cfg 
-> Read(tmp
, m_Parser 
-> m_FontsSizes
[i
]); 
 303     if (path 
!= wxEmptyString
) 
 304         cfg 
-> SetPath(oldpath
); 
 309 void wxHtmlWindow::WriteCustomization(wxConfigBase 
*cfg
, wxString path
) 
 314     if (path 
!= wxEmptyString
) { 
 315         oldpath 
= cfg 
-> GetPath(); 
 316         cfg 
-> SetPath(path
); 
 319     cfg 
-> Write("wxHtmlWindow/Borders", (long) m_Borders
); 
 320     cfg 
-> Write("wxHtmlWindow/FontFaceFixed", m_Parser 
-> m_FontFaceFixed
); 
 321     cfg 
-> Write("wxHtmlWindow/FontFaceNormal", m_Parser 
-> m_FontFaceNormal
); 
 322     cfg 
-> Write("wxHtmlWindow/ItalicModeFixed", (long) m_Parser 
-> m_ItalicModeFixed
); 
 323     cfg 
-> Write("wxHtmlWindow/ItalicModeNormal", (long) m_Parser 
-> m_ItalicModeNormal
); 
 324     for (int i 
= 0; i 
< 7; i
++) { 
 325         tmp
.Printf(wxT("wxHtmlWindow/FontsSize%i"), i
); 
 326         cfg 
-> Write(tmp
, (long) m_Parser 
-> m_FontsSizes
[i
]); 
 329     if (path 
!= wxEmptyString
) 
 330         cfg 
-> SetPath(oldpath
); 
 335 bool wxHtmlWindow::HistoryBack() 
 339     if (m_HistoryPos 
< 1) return FALSE
; 
 343     l 
= m_History
[m_HistoryPos
].GetPage(); 
 344     a 
= m_History
[m_HistoryPos
].GetAnchor(); 
 346     if (a 
== wxEmptyString
) LoadPage(l
); 
 347     else LoadPage(l 
+ "#" + a
); 
 349     Scroll(0, m_History
[m_HistoryPos
].GetPos()); 
 356 bool wxHtmlWindow::HistoryForward() 
 360     if (m_HistoryPos 
== -1) return FALSE
; 
 361     if (m_HistoryPos 
>= (int)m_History
.GetCount() - 1)return FALSE
; 
 363     m_OpenedPage 
= wxEmptyString
; // this will disable adding new entry into history in LoadPage() 
 366     l 
= m_History
[m_HistoryPos
].GetPage(); 
 367     a 
= m_History
[m_HistoryPos
].GetAnchor(); 
 369     if (a 
== wxEmptyString
) LoadPage(l
); 
 370     else LoadPage(l 
+ "#" + a
); 
 372     Scroll(0, m_History
[m_HistoryPos
].GetPos()); 
 379 void wxHtmlWindow::HistoryClear() 
 387 wxList 
wxHtmlWindow::m_Filters
; 
 388 wxHtmlFilter 
*wxHtmlWindow::m_DefaultFilter 
= NULL
; 
 390 void wxHtmlWindow::CleanUpStatics() 
 392     if (m_DefaultFilter
) delete m_DefaultFilter
; 
 393     m_DefaultFilter 
= NULL
; 
 394     m_Filters
.DeleteContents(TRUE
); 
 401 void wxHtmlWindow::AddFilter(wxHtmlFilter 
*filter
) 
 403     m_Filters
.Append(filter
); 
 409 void wxHtmlWindow::OnLinkClicked(const wxString
& link
) 
 416 void wxHtmlWindow::OnDraw(wxDC
& dc
) 
 419     wxRegionIterator 
upd(GetUpdateRegion()); // get the update rect list 
 422     if (!m_tmpCanDraw
) return; 
 423     dc
.SetMapMode(wxMM_TEXT
); 
 424 #if defined(_MSC_VER) && (_MSC_VER == 1200) 
 425     ::SetMapMode((HDC
)dc
.GetHDC(), MM_TEXT
); 
 427     dc
.SetBackgroundMode(wxTRANSPARENT
); 
 433         if (m_Cell
) m_Cell 
-> Draw(dc
, 0, 0, y 
* wxHTML_SCROLL_STEP 
+ v_y
, y 
* wxHTML_SCROLL_STEP 
+ v_h 
+ v_y
); 
 441 void wxHtmlWindow::OnSize(wxSizeEvent
& event
) 
 443     wxScrolledWindow::OnSize(event
); 
 449 void wxHtmlWindow::OnKeyDown(wxKeyEvent
& event
) 
 454     ViewStart(&dummy
, &sty
); 
 455     GetClientSize(&dummy
, &cliy
); cliy 
/= wxHTML_SCROLL_STEP
; 
 456     GetVirtualSize(&dummy
, &szy
); szy 
/= wxHTML_SCROLL_STEP
; 
 458     switch (event
.KeyCode()) { 
 461                 Scroll(-1, sty 
- cliy
); 
 465                 Scroll(-1, sty 
+ cliy
); 
 471                 Scroll(-1, szy 
- cliy
); 
 484 void wxHtmlWindow::OnMouseEvent(wxMouseEvent
& event
) 
 486     m_tmpMouseMoved 
= TRUE
; 
 488     if (event
.ButtonDown()) { 
 493         ViewStart(&sx
, &sy
); sx 
*= wxHTML_SCROLL_STEP
; sy 
*= wxHTML_SCROLL_STEP
; 
 494         pos 
= event
.GetPosition(); 
 497             m_Cell 
-> OnMouseClick(this, sx 
+ pos
.x
, sy 
+ pos
.y
, event
.ButtonDown(1), event
.ButtonDown(2), event
.ButtonDown(3)); 
 503 void wxHtmlWindow::OnIdle(wxIdleEvent
& event
) 
 505     static wxCursor 
cur_hand(wxCURSOR_HAND
), cur_arrow(wxCURSOR_ARROW
); 
 507     if (m_tmpMouseMoved 
&& (m_Cell 
!= NULL
)) { 
 512         ViewStart(&sx
, &sy
); sx 
*= wxHTML_SCROLL_STEP
; sy 
*= wxHTML_SCROLL_STEP
; 
 513         wxGetMousePosition(&x
, &y
); 
 514         ScreenToClient(&x
, &y
); 
 515         lnk 
= m_Cell 
-> GetLink(sx 
+ x
, sy 
+ y
); 
 517         if (lnk 
!= m_tmpLastLink
) { 
 518             if (lnk 
== wxEmptyString
) { 
 519                 SetCursor(cur_arrow
); 
 520                 if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(wxEmptyString
, m_RelatedStatusBar
); 
 524                 if (m_RelatedStatusBar 
!= -1) m_RelatedFrame 
-> SetStatusText(lnk
, m_RelatedStatusBar
); 
 528         m_tmpMouseMoved 
= FALSE
; 
 535 IMPLEMENT_DYNAMIC_CLASS(wxHtmlWindow
,wxScrolledWindow
) 
 537 BEGIN_EVENT_TABLE(wxHtmlWindow
, wxScrolledWindow
) 
 538     EVT_SIZE(wxHtmlWindow::OnSize
) 
 539     EVT_LEFT_DOWN(wxHtmlWindow::OnMouseEvent
) 
 540     EVT_MOTION(wxHtmlWindow::OnMouseEvent
) 
 541     EVT_IDLE(wxHtmlWindow::OnIdle
) 
 542     EVT_KEY_DOWN(wxHtmlWindow::OnKeyDown
) 
 549 // A module to allow initialization/cleanup 
 550 // without calling these functions from app.cpp or from 
 551 // the user's application. 
 553 class wxHtmlWinModule
: public wxModule
 
 555 DECLARE_DYNAMIC_CLASS(wxHtmlWinModule
) 
 557     wxHtmlWinModule() : wxModule() {} 
 558     bool OnInit() { return TRUE
; } 
 559     void OnExit() { wxHtmlWindow::CleanUpStatics(); } 
 562 IMPLEMENT_DYNAMIC_CLASS(wxHtmlWinModule
, wxModule
) 
 567 ///// default mod handlers are forced there: 
 569 FORCE_LINK(mod_layout
) 
 570 FORCE_LINK(mod_fonts
) 
 571 FORCE_LINK(mod_image
) 
 574 FORCE_LINK(mod_hline
) 
 575 FORCE_LINK(mod_links
) 
 576 FORCE_LINK(mod_tables
)