]> git.saurik.com Git - wxWidgets.git/blame - src/html/htmlwin.cpp
moved AdjustToClientAreaOrigin to wxWindowBase, needed worldwide for wxUniv
[wxWidgets.git] / src / html / htmlwin.cpp
CommitLineData
5526e819
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: htmlwin.cpp
3// Purpose: wxHtmlWindow class for parsing & displaying HTML (implementation)
4// Author: Vaclav Slavik
69941f05 5// RCS-ID: $Id$
5526e819
VS
6// Copyright: (c) 1999 Vaclav Slavik
7// Licence: wxWindows Licence
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
892aeafc
VS
12#pragma implementation "htmlwin.h"
13#pragma implementation "htmlproc.h"
5526e819
VS
14#endif
15
3096bd2f 16#include "wx/wxprec.h"
5526e819
VS
17
18#include "wx/defs.h"
f6bcfd97 19#if wxUSE_HTML && wxUSE_STREAMS
5526e819
VS
20
21#ifdef __BORDLANDC__
22#pragma hdrstop
23#endif
24
25#ifndef WXPRECOMP
04dbb646
VZ
26 #include "wx/log.h"
27 #include "wx/intl.h"
28 #include "wx/dcclient.h"
29 #include "wx/frame.h"
5526e819
VS
30#endif
31
69941f05 32#include "wx/html/htmlwin.h"
69941f05 33#include "wx/html/forcelnk.h"
892aeafc 34#include "wx/html/htmlproc.h"
892aeafc 35#include "wx/list.h"
04dbb646
VZ
36
37#include "wx/arrimpl.cpp"
892aeafc
VS
38#include "wx/listimpl.cpp"
39
40//-----------------------------------------------------------------------------
41// wxHtmlHistoryItem
42//-----------------------------------------------------------------------------
43
44// item of history list
45class WXDLLEXPORT wxHtmlHistoryItem : public wxObject
46{
47public:
48 wxHtmlHistoryItem(const wxString& p, const wxString& a) {m_Page = p, m_Anchor = a, m_Pos = 0;}
49 int GetPos() const {return m_Pos;}
50 void SetPos(int p) {m_Pos = p;}
51 const wxString& GetPage() const {return m_Page;}
52 const wxString& GetAnchor() const {return m_Anchor;}
53
54private:
55 wxString m_Page;
56 wxString m_Anchor;
57 int m_Pos;
58};
5526e819 59
5526e819
VS
60
61//-----------------------------------------------------------------------------
892aeafc 62// our private arrays:
5526e819
VS
63//-----------------------------------------------------------------------------
64
892aeafc
VS
65WX_DECLARE_OBJARRAY(wxHtmlHistoryItem, wxHtmlHistoryArray);
66WX_DEFINE_OBJARRAY(wxHtmlHistoryArray);
5526e819 67
892aeafc
VS
68WX_DECLARE_LIST(wxHtmlProcessor, wxHtmlProcessorList);
69WX_DEFINE_LIST(wxHtmlProcessorList);
5526e819 70
892aeafc
VS
71//-----------------------------------------------------------------------------
72// wxHtmlWindow
73//-----------------------------------------------------------------------------
5526e819
VS
74
75
269e8200 76wxHtmlWindow::wxHtmlWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
f6bcfd97 77 long style, const wxString& name) : wxScrolledWindow(parent, id, pos, size, style | wxVSCROLL | wxHSCROLL, name)
5526e819
VS
78{
79 m_tmpMouseMoved = FALSE;
846914d1 80 m_tmpLastLink = NULL;
f6010d8f 81 m_tmpLastCell = NULL;
89de9af3 82 m_tmpCanDrawLocks = 0;
5526e819
VS
83 m_FS = new wxFileSystem();
84 m_RelatedStatusBar = -1;
85 m_RelatedFrame = NULL;
892aeafc 86 m_TitleFormat = wxT("%s");
d5db80c2 87 m_OpenedPage = m_OpenedAnchor = m_OpenedPageTitle = wxEmptyString;
5526e819
VS
88 m_Cell = NULL;
89 m_Parser = new wxHtmlWinParser(this);
4f9297b0 90 m_Parser->SetFS(m_FS);
5526e819
VS
91 SetBorders(10);
92 m_HistoryPos = -1;
93 m_HistoryOn = TRUE;
892aeafc
VS
94 m_History = new wxHtmlHistoryArray;
95 m_Processors = NULL;
a547ebff 96 m_Style = style;
4f9297b0 97 SetPage(wxT("<html><body></body></html>"));
5526e819
VS
98}
99
100
101
102wxHtmlWindow::~wxHtmlWindow()
103{
104 HistoryClear();
105
106 if (m_Cell) delete m_Cell;
107
5526e819
VS
108 delete m_Parser;
109 delete m_FS;
892aeafc
VS
110 delete m_History;
111 delete m_Processors;
5526e819
VS
112}
113
114
115
116void wxHtmlWindow::SetRelatedFrame(wxFrame* frame, const wxString& format)
117{
118 m_RelatedFrame = frame;
119 m_TitleFormat = format;
120}
121
122
123
124void wxHtmlWindow::SetRelatedStatusBar(int bar)
125{
126 m_RelatedStatusBar = bar;
127}
269e8200
RD
128
129
130
8eb2940f 131void wxHtmlWindow::SetFonts(wxString normal_face, wxString fixed_face, const int *sizes)
5526e819 132{
d5db80c2
VS
133 wxString op = m_OpenedPage;
134
4f9297b0 135 m_Parser->SetFonts(normal_face, fixed_face, sizes);
892aeafc 136 // fonts changed => contents invalid, so reload the page:
bfb9ee96 137 SetPage(wxT("<html><body></body></html>"));
d5db80c2 138 if (!op.IsEmpty()) LoadPage(op);
5526e819
VS
139}
140
141
142
143bool wxHtmlWindow::SetPage(const wxString& source)
144{
892aeafc
VS
145 wxString newsrc(source);
146
147 // pass HTML through registered processors:
960ba969 148 if (m_Processors || m_GlobalProcessors)
892aeafc 149 {
960ba969
VS
150 wxHtmlProcessorList::Node *nodeL, *nodeG;
151 int prL, prG;
892aeafc
VS
152
153 nodeL = (m_Processors) ? m_Processors->GetFirst() : NULL;
960ba969
VS
154 nodeG = (m_GlobalProcessors) ? m_GlobalProcessors->GetFirst() : NULL;
155
156 // VS: there are two lists, global and local, both of them sorted by
e421922f 157 // priority. Since we have to go through _both_ lists with
960ba969
VS
158 // decreasing priority, we "merge-sort" the lists on-line by
159 // processing that one of the two heads that has higher priority
160 // in every iteration
161 while (nodeL || nodeG)
892aeafc
VS
162 {
163 prL = (nodeL) ? nodeL->GetData()->GetPriority() : -1;
960ba969
VS
164 prG = (nodeG) ? nodeG->GetData()->GetPriority() : -1;
165 if (prL > prG)
892aeafc 166 {
73348d09
VS
167 if (nodeL->GetData()->IsEnabled())
168 newsrc = nodeL->GetData()->Process(newsrc);
892aeafc
VS
169 nodeL = nodeL->GetNext();
170 }
960ba969 171 else // prL <= prG
892aeafc 172 {
73348d09
VS
173 if (nodeG->GetData()->IsEnabled())
174 newsrc = nodeG->GetData()->Process(newsrc);
960ba969 175 nodeG = nodeG->GetNext();
892aeafc
VS
176 }
177 }
178 }
5526e819 179
892aeafc
VS
180 // ...and run the parser on it:
181 wxClientDC *dc = new wxClientDC(this);
4f9297b0 182 dc->SetMapMode(wxMM_TEXT);
5526e819 183 SetBackgroundColour(wxColour(0xFF, 0xFF, 0xFF));
d5db80c2 184 m_OpenedPage = m_OpenedAnchor = m_OpenedPageTitle = wxEmptyString;
4f9297b0 185 m_Parser->SetDC(dc);
33ac7e6f 186 if (m_Cell)
4f9297b0 187 {
89de9af3
VS
188 delete m_Cell;
189 m_Cell = NULL;
f61815af 190 }
892aeafc 191 m_Cell = (wxHtmlContainerCell*) m_Parser->Parse(newsrc);
5526e819 192 delete dc;
4f9297b0
VS
193 m_Cell->SetIndent(m_Borders, wxHTML_INDENT_ALL, wxHTML_UNITS_PIXELS);
194 m_Cell->SetAlignHor(wxHTML_ALIGN_CENTER);
5526e819 195 CreateLayout();
bfb9ee96 196 if (m_tmpCanDrawLocks == 0)
892aeafc 197 Refresh();
5526e819
VS
198 return TRUE;
199}
200
201
202bool wxHtmlWindow::LoadPage(const wxString& location)
203{
204 wxFSFile *f;
205 bool rt_val;
fc7dfaf8 206 bool needs_refresh = FALSE;
33ac7e6f 207
169ee06c 208 SetCursor(*wxHOURGLASS_CURSOR);
fc7dfaf8 209 wxYield(); Refresh(FALSE);
5526e819 210
89de9af3 211 m_tmpCanDrawLocks++;
e421922f 212 if (m_HistoryOn && (m_HistoryPos != -1))
4f9297b0 213 {
960ba969 214 // store scroll position into history item:
5526e819 215 int x, y;
e421922f 216 GetViewStart(&x, &y);
892aeafc 217 (*m_History)[m_HistoryPos].SetPos(y);
5526e819
VS
218 }
219
e421922f 220 if (location[0] == wxT('#'))
4f9297b0 221 {
960ba969 222 // local anchor:
5526e819 223 wxString anch = location.Mid(1) /*1 to end*/;
89de9af3 224 m_tmpCanDrawLocks--;
5526e819 225 rt_val = ScrollToAnchor(anch);
fc7dfaf8
VS
226 m_tmpCanDrawLocks++;
227 }
33ac7e6f 228 else if (location.Find(wxT('#')) != wxNOT_FOUND && location.BeforeFirst(wxT('#')) == m_OpenedPage)
4f9297b0 229 {
fc7dfaf8
VS
230 wxString anch = location.AfterFirst(wxT('#'));
231 m_tmpCanDrawLocks--;
232 rt_val = ScrollToAnchor(anch);
233 m_tmpCanDrawLocks++;
234 }
33ac7e6f
KB
235 else if (location.Find(wxT('#')) != wxNOT_FOUND &&
236 (m_FS->GetPath() + location.BeforeFirst(wxT('#'))) == m_OpenedPage)
e421922f 237 {
fc7dfaf8
VS
238 wxString anch = location.AfterFirst(wxT('#'));
239 m_tmpCanDrawLocks--;
240 rt_val = ScrollToAnchor(anch);
241 m_tmpCanDrawLocks++;
5526e819
VS
242 }
243
33ac7e6f 244 else
4f9297b0 245 {
fc7dfaf8 246 needs_refresh = TRUE;
5526e819 247 // load&display it:
33ac7e6f 248 if (m_RelatedStatusBar != -1)
e421922f 249 {
4f9297b0 250 m_RelatedFrame->SetStatusText(_("Connecting..."), m_RelatedStatusBar);
fc7dfaf8 251 Refresh(FALSE);
5526e819
VS
252 }
253
4f9297b0 254 f = m_FS->OpenFile(location);
33ac7e6f
KB
255
256 if (f == NULL)
e421922f 257 {
f6bcfd97 258 wxLogError(_("Unable to open requested HTML document: %s"), location.c_str());
89de9af3 259 m_tmpCanDrawLocks--;
169ee06c
VS
260
261 SetCursor(*wxSTANDARD_CURSOR);
5526e819
VS
262 return FALSE;
263 }
264
33ac7e6f 265 else
e421922f 266 {
5526e819
VS
267 wxNode *node;
268 wxString src = wxEmptyString;
269
33ac7e6f 270 if (m_RelatedStatusBar != -1)
e421922f 271 {
5526e819 272 wxString msg = _("Loading : ") + location;
4f9297b0 273 m_RelatedFrame->SetStatusText(msg, m_RelatedStatusBar);
fc7dfaf8 274 Refresh(FALSE);
5526e819
VS
275 }
276
277 node = m_Filters.GetFirst();
4f9297b0 278 while (node)
e421922f 279 {
4f9297b0
VS
280 wxHtmlFilter *h = (wxHtmlFilter*) node->GetData();
281 if (h->CanRead(*f))
e421922f 282 {
4f9297b0 283 src = h->ReadFile(*f);
5526e819
VS
284 break;
285 }
4f9297b0 286 node = node->GetNext();
5526e819 287 }
33ac7e6f 288 if (src == wxEmptyString)
e421922f 289 {
89de9af3 290 if (m_DefaultFilter == NULL) m_DefaultFilter = GetDefaultFilter();
4f9297b0 291 src = m_DefaultFilter->ReadFile(*f);
89de9af3 292 }
5526e819 293
4f9297b0 294 m_FS->ChangePathTo(f->GetLocation());
5526e819 295 rt_val = SetPage(src);
4f9297b0 296 m_OpenedPage = f->GetLocation();
33ac7e6f 297 if (f->GetAnchor() != wxEmptyString)
e421922f 298 {
fc7dfaf8 299 wxYield();
4f9297b0 300 ScrollToAnchor(f->GetAnchor());
5526e819
VS
301 }
302
303 delete f;
304
4f9297b0 305 if (m_RelatedStatusBar != -1) m_RelatedFrame->SetStatusText(_("Done"), m_RelatedStatusBar);
5526e819
VS
306 }
307 }
308
4f9297b0
VS
309 if (m_HistoryOn) // add this page to history there:
310 {
892aeafc 311 int c = m_History->GetCount() - (m_HistoryPos + 1);
5526e819 312
0cb9cfb2 313 if (m_HistoryPos < 0 ||
ee19c324
VS
314 (*m_History)[m_HistoryPos].GetPage() != m_OpenedPage ||
315 (*m_History)[m_HistoryPos].GetAnchor() != m_OpenedAnchor)
316 {
317 m_HistoryPos++;
318 for (int i = 0; i < c; i++)
b54e41c5 319 m_History->RemoveAt(m_HistoryPos);
ee19c324
VS
320 m_History->Add(new wxHtmlHistoryItem(m_OpenedPage, m_OpenedAnchor));
321 }
5526e819
VS
322 }
323
096824d7
VS
324 if (m_OpenedPageTitle == wxEmptyString)
325 OnSetTitle(wxFileNameFromPath(m_OpenedPage));
169ee06c 326 SetCursor(*wxSTANDARD_CURSOR);
fc7dfaf8 327
33ac7e6f 328 if (needs_refresh)
4f9297b0 329 {
fc7dfaf8
VS
330 wxYield();
331 m_tmpCanDrawLocks--;
332 Refresh();
333 }
334 else
335 m_tmpCanDrawLocks--;
336
5526e819
VS
337 return rt_val;
338}
339
340
341
342bool wxHtmlWindow::ScrollToAnchor(const wxString& anchor)
343{
4f9297b0 344 const wxHtmlCell *c = m_Cell->Find(wxHTML_COND_ISANCHOR, &anchor);
f3c82859
VS
345 if (!c)
346 {
f6bcfd97 347 wxLogWarning(_("HTML anchor %s does not exist."), anchor.c_str());
f3c82859
VS
348 return FALSE;
349 }
33ac7e6f 350 else
4f9297b0 351 {
5526e819 352 int y;
269e8200 353
4f9297b0 354 for (y = 0; c != NULL; c = c->GetParent()) y += c->GetPosY();
efba2b89 355 Scroll(-1, y / wxHTML_SCROLL_STEP);
5526e819
VS
356 m_OpenedAnchor = anchor;
357 return TRUE;
358 }
359}
360
361
d5db80c2 362void wxHtmlWindow::OnSetTitle(const wxString& title)
5526e819 363{
33ac7e6f 364 if (m_RelatedFrame)
4f9297b0 365 {
5526e819
VS
366 wxString tit;
367 tit.Printf(m_TitleFormat, title.c_str());
4f9297b0 368 m_RelatedFrame->SetTitle(tit);
5526e819 369 }
d5db80c2 370 m_OpenedPageTitle = title;
5526e819
VS
371}
372
373
374
375
376
377void wxHtmlWindow::CreateLayout()
378{
379 int ClientWidth, ClientHeight;
380
381 if (!m_Cell) return;
a547ebff 382
33ac7e6f 383 if (m_Style & wxHW_SCROLLBAR_NEVER)
4f9297b0
VS
384 {
385 SetScrollbars(wxHTML_SCROLL_STEP, 1, m_Cell->GetWidth() / wxHTML_SCROLL_STEP, 0); // always off
a547ebff 386 GetClientSize(&ClientWidth, &ClientHeight);
4f9297b0 387 m_Cell->Layout(ClientWidth);
a547ebff
VS
388 }
389
390 else {
391 GetClientSize(&ClientWidth, &ClientHeight);
4f9297b0 392 m_Cell->Layout(ClientWidth);
33ac7e6f 393 if (ClientHeight < m_Cell->GetHeight() + GetCharHeight())
e421922f 394 {
f3bcfd9b
VS
395 SetScrollbars(
396 wxHTML_SCROLL_STEP, wxHTML_SCROLL_STEP,
4f9297b0
VS
397 m_Cell->GetWidth() / wxHTML_SCROLL_STEP,
398 (m_Cell->GetHeight() + GetCharHeight()) / wxHTML_SCROLL_STEP
f3bcfd9b 399 /*cheat: top-level frag is always container*/);
a547ebff 400 }
4f9297b0 401 else /* we fit into window, no need for scrollbars */
e421922f 402 {
4f9297b0 403 SetScrollbars(wxHTML_SCROLL_STEP, 1, m_Cell->GetWidth() / wxHTML_SCROLL_STEP, 0); // disable...
89de9af3 404 GetClientSize(&ClientWidth, &ClientHeight);
4f9297b0 405 m_Cell->Layout(ClientWidth); // ...and relayout
89de9af3 406 }
a547ebff 407 }
5526e819
VS
408}
409
269e8200 410
5526e819
VS
411
412void wxHtmlWindow::ReadCustomization(wxConfigBase *cfg, wxString path)
413{
414 wxString oldpath;
415 wxString tmp;
d5db80c2
VS
416 int p_fontsizes[7];
417 wxString p_fff, p_ffn;
5526e819 418
33ac7e6f 419 if (path != wxEmptyString)
4f9297b0
VS
420 {
421 oldpath = cfg->GetPath();
422 cfg->SetPath(path);
5526e819
VS
423 }
424
892aeafc
VS
425 m_Borders = cfg->Read(wxT("wxHtmlWindow/Borders"), m_Borders);
426 p_fff = cfg->Read(wxT("wxHtmlWindow/FontFaceFixed"), m_Parser->m_FontFaceFixed);
427 p_ffn = cfg->Read(wxT("wxHtmlWindow/FontFaceNormal"), m_Parser->m_FontFaceNormal);
bfb9ee96 428 for (int i = 0; i < 7; i++)
4f9297b0 429 {
66a77a74 430 tmp.Printf(wxT("wxHtmlWindow/FontsSize%i"), i);
4f9297b0 431 p_fontsizes[i] = cfg->Read(tmp, m_Parser->m_FontsSizes[i]);
5526e819 432 }
8eb2940f 433 SetFonts(p_ffn, p_fff, p_fontsizes);
5526e819
VS
434
435 if (path != wxEmptyString)
4f9297b0 436 cfg->SetPath(oldpath);
5526e819
VS
437}
438
439
440
441void wxHtmlWindow::WriteCustomization(wxConfigBase *cfg, wxString path)
442{
443 wxString oldpath;
444 wxString tmp;
445
33ac7e6f 446 if (path != wxEmptyString)
4f9297b0
VS
447 {
448 oldpath = cfg->GetPath();
449 cfg->SetPath(path);
5526e819
VS
450 }
451
892aeafc
VS
452 cfg->Write(wxT("wxHtmlWindow/Borders"), (long) m_Borders);
453 cfg->Write(wxT("wxHtmlWindow/FontFaceFixed"), m_Parser->m_FontFaceFixed);
454 cfg->Write(wxT("wxHtmlWindow/FontFaceNormal"), m_Parser->m_FontFaceNormal);
bfb9ee96 455 for (int i = 0; i < 7; i++)
4f9297b0 456 {
66a77a74 457 tmp.Printf(wxT("wxHtmlWindow/FontsSize%i"), i);
4f9297b0 458 cfg->Write(tmp, (long) m_Parser->m_FontsSizes[i]);
5526e819
VS
459 }
460
461 if (path != wxEmptyString)
4f9297b0 462 cfg->SetPath(oldpath);
5526e819
VS
463}
464
465
466
467bool wxHtmlWindow::HistoryBack()
468{
469 wxString a, l;
470
471 if (m_HistoryPos < 1) return FALSE;
472
bbda1088
VS
473 // store scroll position into history item:
474 int x, y;
e421922f 475 GetViewStart(&x, &y);
892aeafc 476 (*m_History)[m_HistoryPos].SetPos(y);
bbda1088
VS
477
478 // go to previous position:
5526e819
VS
479 m_HistoryPos--;
480
892aeafc
VS
481 l = (*m_History)[m_HistoryPos].GetPage();
482 a = (*m_History)[m_HistoryPos].GetAnchor();
5526e819 483 m_HistoryOn = FALSE;
89de9af3 484 m_tmpCanDrawLocks++;
5526e819 485 if (a == wxEmptyString) LoadPage(l);
fc7dfaf8 486 else LoadPage(l + wxT("#") + a);
5526e819 487 m_HistoryOn = TRUE;
c88293a4 488 wxYield();
89de9af3 489 m_tmpCanDrawLocks--;
892aeafc 490 Scroll(0, (*m_History)[m_HistoryPos].GetPos());
5526e819
VS
491 Refresh();
492 return TRUE;
493}
494
1b113a81
VS
495bool wxHtmlWindow::HistoryCanBack()
496{
497 if (m_HistoryPos < 1) return FALSE;
498 return TRUE ;
499}
5526e819
VS
500
501
502bool wxHtmlWindow::HistoryForward()
503{
504 wxString a, l;
505
506 if (m_HistoryPos == -1) return FALSE;
892aeafc 507 if (m_HistoryPos >= (int)m_History->GetCount() - 1)return FALSE;
5526e819
VS
508
509 m_OpenedPage = wxEmptyString; // this will disable adding new entry into history in LoadPage()
510
511 m_HistoryPos++;
892aeafc
VS
512 l = (*m_History)[m_HistoryPos].GetPage();
513 a = (*m_History)[m_HistoryPos].GetAnchor();
5526e819 514 m_HistoryOn = FALSE;
89de9af3 515 m_tmpCanDrawLocks++;
5526e819 516 if (a == wxEmptyString) LoadPage(l);
fc7dfaf8 517 else LoadPage(l + wxT("#") + a);
5526e819 518 m_HistoryOn = TRUE;
c88293a4 519 wxYield();
89de9af3 520 m_tmpCanDrawLocks--;
892aeafc 521 Scroll(0, (*m_History)[m_HistoryPos].GetPos());
5526e819
VS
522 Refresh();
523 return TRUE;
524}
525
1b113a81
VS
526bool wxHtmlWindow::HistoryCanForward()
527{
528 if (m_HistoryPos == -1) return FALSE;
892aeafc 529 if (m_HistoryPos >= (int)m_History->GetCount() - 1)return FALSE;
1b113a81
VS
530 return TRUE ;
531}
5526e819
VS
532
533
534void wxHtmlWindow::HistoryClear()
535{
892aeafc 536 m_History->Empty();
5526e819
VS
537 m_HistoryPos = -1;
538}
539
892aeafc
VS
540void wxHtmlWindow::AddProcessor(wxHtmlProcessor *processor)
541{
542 if (!m_Processors)
543 {
544 m_Processors = new wxHtmlProcessorList;
545 m_Processors->DeleteContents(TRUE);
546 }
547 wxHtmlProcessorList::Node *node;
bfb9ee96 548
892aeafc
VS
549 for (node = m_Processors->GetFirst(); node; node = node->GetNext())
550 {
bfb9ee96 551 if (processor->GetPriority() > node->GetData()->GetPriority())
892aeafc
VS
552 {
553 m_Processors->Insert(node, processor);
960ba969 554 return;
892aeafc
VS
555 }
556 }
960ba969 557 m_Processors->Append(processor);
892aeafc
VS
558}
559
960ba969 560/*static */ void wxHtmlWindow::AddGlobalProcessor(wxHtmlProcessor *processor)
892aeafc 561{
960ba969 562 if (!m_GlobalProcessors)
892aeafc 563 {
960ba969
VS
564 m_GlobalProcessors = new wxHtmlProcessorList;
565 m_GlobalProcessors->DeleteContents(TRUE);
892aeafc
VS
566 }
567 wxHtmlProcessorList::Node *node;
e421922f 568
960ba969 569 for (node = m_GlobalProcessors->GetFirst(); node; node = node->GetNext())
892aeafc 570 {
bfb9ee96 571 if (processor->GetPriority() > node->GetData()->GetPriority())
892aeafc 572 {
960ba969
VS
573 m_GlobalProcessors->Insert(node, processor);
574 return;
892aeafc
VS
575 }
576 }
960ba969 577 m_GlobalProcessors->Append(processor);
892aeafc
VS
578}
579
5526e819
VS
580
581
582wxList wxHtmlWindow::m_Filters;
a76015e6 583wxHtmlFilter *wxHtmlWindow::m_DefaultFilter = NULL;
66806a0b
VS
584wxCursor *wxHtmlWindow::s_cur_hand = NULL;
585wxCursor *wxHtmlWindow::s_cur_arrow = NULL;
960ba969 586wxHtmlProcessorList *wxHtmlWindow::m_GlobalProcessors = NULL;
a76015e6
VS
587
588void wxHtmlWindow::CleanUpStatics()
589{
892aeafc 590 delete m_DefaultFilter;
a76015e6 591 m_DefaultFilter = NULL;
269e8200
RD
592 m_Filters.DeleteContents(TRUE);
593 m_Filters.Clear();
960ba969
VS
594 delete m_GlobalProcessors;
595 m_GlobalProcessors = NULL;
892aeafc
VS
596 delete s_cur_hand;
597 delete s_cur_arrow;
a76015e6
VS
598}
599
600
5526e819
VS
601
602void wxHtmlWindow::AddFilter(wxHtmlFilter *filter)
603{
5526e819
VS
604 m_Filters.Append(filter);
605}
606
607
608
609
0b2dadd3 610void wxHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link)
5526e819 611{
0b2dadd3 612 LoadPage(link.GetHref());
5526e819
VS
613}
614
f6010d8f
VZ
615void wxHtmlWindow::OnCellClicked(wxHtmlCell *cell,
616 wxCoord x, wxCoord y,
617 const wxMouseEvent& event)
618{
619 wxCHECK_RET( cell, _T("can't be called with NULL cell") );
5526e819 620
f6010d8f
VZ
621 cell->OnMouseClick(this, x, y, event);
622}
623
624void wxHtmlWindow::OnCellMouseHover(wxHtmlCell * WXUNUSED(cell),
625 wxCoord WXUNUSED(x), wxCoord WXUNUSED(y))
626{
627 // do nothing here
628}
5526e819
VS
629
630void wxHtmlWindow::OnDraw(wxDC& dc)
631{
632 int x, y;
633 wxRegionIterator upd(GetUpdateRegion()); // get the update rect list
634 int v_y, v_h;
635
89de9af3 636 if (m_tmpCanDrawLocks > 0) return;
33ac7e6f 637
5526e819 638 dc.SetMapMode(wxMM_TEXT);
5526e819 639 dc.SetBackgroundMode(wxTRANSPARENT);
e421922f 640 GetViewStart(&x, &y);
5526e819 641
33ac7e6f 642 while (upd)
4f9297b0 643 {
5526e819
VS
644 v_y = upd.GetY();
645 v_h = upd.GetH();
4f9297b0 646 if (m_Cell) m_Cell->Draw(dc, 0, 0, y * wxHTML_SCROLL_STEP + v_y, y * wxHTML_SCROLL_STEP + v_h + v_y);
5526e819
VS
647 upd++;
648 }
649}
650
651
652
653
654void wxHtmlWindow::OnSize(wxSizeEvent& event)
655{
656 wxScrolledWindow::OnSize(event);
657 CreateLayout();
f6bcfd97 658 Refresh();
5526e819
VS
659}
660
661
5526e819
VS
662void wxHtmlWindow::OnMouseEvent(wxMouseEvent& event)
663{
664 m_tmpMouseMoved = TRUE;
665
33ac7e6f 666 if (event.ButtonDown())
4f9297b0 667 {
f6010d8f
VZ
668 if ( m_Cell )
669 {
670 int sx, sy;
671 GetViewStart(&sx, &sy);
672 sx *= wxHTML_SCROLL_STEP;
673 sy *= wxHTML_SCROLL_STEP;
5526e819 674
f6010d8f
VZ
675 wxPoint pos = event.GetPosition();
676 pos.x += sx;
677 pos.y += sy;
5526e819 678
f6010d8f
VZ
679 wxHtmlCell *cell = m_Cell->FindCellByPos(pos.x, pos.y);
680
681 // VZ: is it possible that we don't find anything at all?
d168485f
VS
682 // VS: yes. FindCellByPos returns terminal cell and
683 // containers may have empty borders
f6010d8f
VZ
684 if ( cell )
685 OnCellClicked(cell, pos.x, pos.y, event);
686 }
5526e819
VS
687 }
688}
689
690
691
33ac7e6f 692void wxHtmlWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
5526e819 693{
33ac7e6f 694 if (s_cur_hand == NULL)
66806a0b
VS
695 {
696 s_cur_hand = new wxCursor(wxCURSOR_HAND);
697 s_cur_arrow = new wxCursor(wxCURSOR_ARROW);
698 }
5526e819 699
33ac7e6f 700 if (m_tmpMouseMoved && (m_Cell != NULL))
4f9297b0 701 {
5526e819 702 int sx, sy;
0cb9cfb2
VZ
703 GetViewStart(&sx, &sy);
704 sx *= wxHTML_SCROLL_STEP;
705 sy *= wxHTML_SCROLL_STEP;
5526e819 706
0cb9cfb2 707 int x, y;
5526e819
VS
708 wxGetMousePosition(&x, &y);
709 ScreenToClient(&x, &y);
f6010d8f
VZ
710 x += sx;
711 y += sy;
0cb9cfb2 712
f6010d8f
VZ
713 wxHtmlCell *cell = m_Cell->FindCellByPos(x, y);
714 if ( cell != m_tmpLastCell )
e421922f 715 {
f6010d8f
VZ
716 wxHtmlLinkInfo *lnk = cell ? cell->GetLink(x, y) : NULL;
717
718 if (lnk != m_tmpLastLink)
e421922f 719 {
f6010d8f
VZ
720 if (lnk == NULL)
721 {
722 SetCursor(*s_cur_arrow);
723 if (m_RelatedStatusBar != -1)
724 m_RelatedFrame->SetStatusText(wxEmptyString, m_RelatedStatusBar);
725 }
726 else
727 {
728 SetCursor(*s_cur_hand);
729 if (m_RelatedStatusBar != -1)
730 m_RelatedFrame->SetStatusText(lnk->GetHref(), m_RelatedStatusBar);
731 }
732 m_tmpLastLink = lnk;
622ea783 733 }
f6010d8f
VZ
734
735 m_tmpLastCell = cell;
5526e819 736 }
f6010d8f
VZ
737 else // mouse moved but stayed in the same cell
738 {
739 if ( cell )
740 OnCellMouseHover(cell, x, y);
741 }
742
5526e819
VS
743 m_tmpMouseMoved = FALSE;
744 }
745}
746
747
bfb9ee96 748IMPLEMENT_ABSTRACT_CLASS(wxHtmlProcessor,wxObject)
5526e819
VS
749
750IMPLEMENT_DYNAMIC_CLASS(wxHtmlWindow,wxScrolledWindow)
751
752BEGIN_EVENT_TABLE(wxHtmlWindow, wxScrolledWindow)
753 EVT_SIZE(wxHtmlWindow::OnSize)
754 EVT_LEFT_DOWN(wxHtmlWindow::OnMouseEvent)
0cb9cfb2 755 EVT_RIGHT_DOWN(wxHtmlWindow::OnMouseEvent)
5526e819
VS
756 EVT_MOTION(wxHtmlWindow::OnMouseEvent)
757 EVT_IDLE(wxHtmlWindow::OnIdle)
5526e819
VS
758END_EVENT_TABLE()
759
760
761
762
763
a76015e6
VS
764// A module to allow initialization/cleanup
765// without calling these functions from app.cpp or from
766// the user's application.
767
768class wxHtmlWinModule: public wxModule
769{
770DECLARE_DYNAMIC_CLASS(wxHtmlWinModule)
771public:
772 wxHtmlWinModule() : wxModule() {}
773 bool OnInit() { return TRUE; }
774 void OnExit() { wxHtmlWindow::CleanUpStatics(); }
775};
776
777IMPLEMENT_DYNAMIC_CLASS(wxHtmlWinModule, wxModule)
778
5526e819
VS
779
780
781
782///// default mod handlers are forced there:
783
c88293a4
VS
784FORCE_LINK(m_layout)
785FORCE_LINK(m_fonts)
786FORCE_LINK(m_image)
787FORCE_LINK(m_list)
788FORCE_LINK(m_dflist)
789FORCE_LINK(m_pre)
790FORCE_LINK(m_hline)
791FORCE_LINK(m_links)
792FORCE_LINK(m_tables)
fa146dd7 793FORCE_LINK(m_meta)
5526e819
VS
794
795
483ff5a5 796#endif