1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        generic/htmllbox.cpp
3 // Purpose:     implementation of wxHtmlListBox
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     31.05.03
7 // RCS-ID:      $Id: htmllbox.cpp 44026 2006-12-21 18:24:27Z VS $
8 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
9 // License:     wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 // ============================================================================
13 // declarations
14 // ============================================================================
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22 
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26 
27 #ifndef WX_PRECOMP
28     #include "wx/dcclient.h"
29 #endif //WX_PRECOMP
30 
31 #if wxUSE_HTML
32 
33 #include "wx/htmllbox.h"
34 
35 #include "wx/html/htmlcell.h"
36 #include "wx/html/winpars.h"
37 
38 // this hack forces the linker to always link in m_* files
39 #include "wx/html/forcelnk.h"
40 FORCE_WXHTML_MODULES()
41 
42 // ----------------------------------------------------------------------------
43 // constants
44 // ----------------------------------------------------------------------------
45 
46 // small border always added to the cells:
47 static const wxCoord CELL_BORDER = 2;
48 
49 const wxChar wxHtmlListBoxNameStr[] = wxT("htmlListBox");
50 const wxChar wxSimpleHtmlListBoxNameStr[] = wxT("simpleHtmlListBox");
51 
52 // ============================================================================
53 // private classes
54 // ============================================================================
55 
56 // ----------------------------------------------------------------------------
57 // wxHtmlListBoxCache
58 // ----------------------------------------------------------------------------
59 
60 // this class is used by wxHtmlListBox to cache the parsed representation of
61 // the items to avoid doing it anew each time an item must be drawn
62 class wxHtmlListBoxCache
63 {
64 private:
65     // invalidate a single item, used by Clear() and InvalidateRange()
InvalidateItem(size_t n)66     void InvalidateItem(size_t n)
67     {
68         m_items[n] = (size_t)-1;
69         delete m_cells[n];
70         m_cells[n] = NULL;
71     }
72 
73 public:
wxHtmlListBoxCache()74     wxHtmlListBoxCache()
75     {
76         for ( size_t n = 0; n < SIZE; n++ )
77         {
78             m_items[n] = (size_t)-1;
79             m_cells[n] = NULL;
80         }
81 
82         m_next = 0;
83     }
84 
~wxHtmlListBoxCache()85     ~wxHtmlListBoxCache()
86     {
87         for ( size_t n = 0; n < SIZE; n++ )
88         {
89             delete m_cells[n];
90         }
91     }
92 
93     // completely invalidate the cache
Clear()94     void Clear()
95     {
96         for ( size_t n = 0; n < SIZE; n++ )
97         {
98             InvalidateItem(n);
99         }
100     }
101 
102     // return the cached cell for this index or NULL if none
Get(size_t item) const103     wxHtmlCell *Get(size_t item) const
104     {
105         for ( size_t n = 0; n < SIZE; n++ )
106         {
107             if ( m_items[n] == item )
108                 return m_cells[n];
109         }
110 
111         return NULL;
112     }
113 
114     // returns true if we already have this item cached
Has(size_t item) const115     bool Has(size_t item) const { return Get(item) != NULL; }
116 
117     // ensure that the item is cached
Store(size_t item,wxHtmlCell * cell)118     void Store(size_t item, wxHtmlCell *cell)
119     {
120         delete m_cells[m_next];
121         m_cells[m_next] = cell;
122         m_items[m_next] = item;
123 
124         // advance to the next item wrapping around if there are no more
125         if ( ++m_next == SIZE )
126             m_next = 0;
127     }
128 
129     // forget the cached value of the item(s) between the given ones (inclusive)
InvalidateRange(size_t from,size_t to)130     void InvalidateRange(size_t from, size_t to)
131     {
132         for ( size_t n = 0; n < SIZE; n++ )
133         {
134             if ( m_items[n] >= from && m_items[n] <= to )
135             {
136                 InvalidateItem(n);
137             }
138         }
139     }
140 
141 private:
142     // the max number of the items we cache
143     enum { SIZE = 50 };
144 
145     // the index of the LRU (oldest) cell
146     size_t m_next;
147 
148     // the parsed representation of the cached item or NULL
149     wxHtmlCell *m_cells[SIZE];
150 
151     // the index of the currently cached item (only valid if m_cells != NULL)
152     size_t m_items[SIZE];
153 };
154 
155 // ----------------------------------------------------------------------------
156 // wxHtmlListBoxStyle
157 // ----------------------------------------------------------------------------
158 
159 // just forward wxDefaultHtmlRenderingStyle callbacks to the main class so that
160 // they could be overridden by the user code
161 class wxHtmlListBoxStyle : public wxDefaultHtmlRenderingStyle
162 {
163 public:
wxHtmlListBoxStyle(const wxHtmlListBox & hlbox)164     wxHtmlListBoxStyle(const wxHtmlListBox& hlbox) : m_hlbox(hlbox) { }
165 
GetSelectedTextColour(const wxColour & colFg)166     virtual wxColour GetSelectedTextColour(const wxColour& colFg)
167     {
168         return m_hlbox.GetSelectedTextColour(colFg);
169     }
170 
GetSelectedTextBgColour(const wxColour & colBg)171     virtual wxColour GetSelectedTextBgColour(const wxColour& colBg)
172     {
173         return m_hlbox.GetSelectedTextBgColour(colBg);
174     }
175 
176 private:
177     const wxHtmlListBox& m_hlbox;
178 
179     DECLARE_NO_COPY_CLASS(wxHtmlListBoxStyle)
180 };
181 
182 // ----------------------------------------------------------------------------
183 // event tables
184 // ----------------------------------------------------------------------------
185 
BEGIN_EVENT_TABLE(wxHtmlListBox,wxVListBox)186 BEGIN_EVENT_TABLE(wxHtmlListBox, wxVListBox)
187     EVT_SIZE(wxHtmlListBox::OnSize)
188     EVT_MOTION(wxHtmlListBox::OnMouseMove)
189     EVT_LEFT_DOWN(wxHtmlListBox::OnLeftDown)
190 END_EVENT_TABLE()
191 
192 // ============================================================================
193 // implementation
194 // ============================================================================
195 
196 IMPLEMENT_ABSTRACT_CLASS(wxHtmlListBox, wxVListBox)
197 
198 
199 // ----------------------------------------------------------------------------
200 // wxHtmlListBox creation
201 // ----------------------------------------------------------------------------
202 
203 wxHtmlListBox::wxHtmlListBox()
204     : wxHtmlWindowMouseHelper(this)
205 {
206     Init();
207 }
208 
209 // normal constructor which calls Create() internally
wxHtmlListBox(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)210 wxHtmlListBox::wxHtmlListBox(wxWindow *parent,
211                              wxWindowID id,
212                              const wxPoint& pos,
213                              const wxSize& size,
214                              long style,
215                              const wxString& name)
216     : wxHtmlWindowMouseHelper(this)
217 {
218     Init();
219 
220     (void)Create(parent, id, pos, size, style, name);
221 }
222 
Init()223 void wxHtmlListBox::Init()
224 {
225     m_htmlParser = NULL;
226     m_htmlRendStyle = new wxHtmlListBoxStyle(*this);
227     m_cache = new wxHtmlListBoxCache;
228 }
229 
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)230 bool wxHtmlListBox::Create(wxWindow *parent,
231                            wxWindowID id,
232                            const wxPoint& pos,
233                            const wxSize& size,
234                            long style,
235                            const wxString& name)
236 {
237     return wxVListBox::Create(parent, id, pos, size, style, name);
238 }
239 
~wxHtmlListBox()240 wxHtmlListBox::~wxHtmlListBox()
241 {
242     delete m_cache;
243 
244     if ( m_htmlParser )
245     {
246         delete m_htmlParser->GetDC();
247         delete m_htmlParser;
248     }
249 
250     delete m_htmlRendStyle;
251 }
252 
253 // ----------------------------------------------------------------------------
254 // wxHtmlListBox appearance
255 // ----------------------------------------------------------------------------
256 
GetSelectedTextColour(const wxColour & colFg) const257 wxColour wxHtmlListBox::GetSelectedTextColour(const wxColour& colFg) const
258 {
259     return m_htmlRendStyle->
260                 wxDefaultHtmlRenderingStyle::GetSelectedTextColour(colFg);
261 }
262 
263 wxColour
GetSelectedTextBgColour(const wxColour & WXUNUSED (colBg)) const264 wxHtmlListBox::GetSelectedTextBgColour(const wxColour& WXUNUSED(colBg)) const
265 {
266     return GetSelectionBackground();
267 }
268 
269 // ----------------------------------------------------------------------------
270 // wxHtmlListBox items markup
271 // ----------------------------------------------------------------------------
272 
OnGetItemMarkup(size_t n) const273 wxString wxHtmlListBox::OnGetItemMarkup(size_t n) const
274 {
275     // we don't even need to wrap the value returned by OnGetItem() inside
276     // "<html><body>" and "</body></html>" because wxHTML can parse it even
277     // without these tags
278     return OnGetItem(n);
279 }
280 
281 // ----------------------------------------------------------------------------
282 // wxHtmlListBox cache handling
283 // ----------------------------------------------------------------------------
284 
CacheItem(size_t n) const285 void wxHtmlListBox::CacheItem(size_t n) const
286 {
287     if ( !m_cache->Has(n) )
288     {
289         if ( !m_htmlParser )
290         {
291             wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox);
292 
293             self->m_htmlParser = new wxHtmlWinParser(self);
294             m_htmlParser->SetDC(new wxClientDC(self));
295             m_htmlParser->SetFS(&self->m_filesystem);
296 #if !wxUSE_UNICODE
297             if (GetFont().Ok())
298                 m_htmlParser->SetInputEncoding(GetFont().GetEncoding());
299 #endif
300             // use system's default GUI font by default:
301             m_htmlParser->SetStandardFonts();
302         }
303 
304         wxHtmlContainerCell *cell = (wxHtmlContainerCell *)m_htmlParser->
305                 Parse(OnGetItemMarkup(n));
306         wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") );
307 
308         // set the cell's ID to item's index so that CellCoordsToPhysical()
309         // can quickly find the item:
310         cell->SetId(wxString::Format(_T("%lu"), (unsigned long)n));
311 
312         cell->Layout(GetClientSize().x - 2*GetMargins().x);
313 
314         m_cache->Store(n, cell);
315     }
316 }
317 
OnSize(wxSizeEvent & event)318 void wxHtmlListBox::OnSize(wxSizeEvent& event)
319 {
320     // we need to relayout all the cached cells
321     m_cache->Clear();
322 
323     event.Skip();
324 }
325 
RefreshLine(size_t line)326 void wxHtmlListBox::RefreshLine(size_t line)
327 {
328     m_cache->InvalidateRange(line, line);
329 
330     wxVListBox::RefreshLine(line);
331 }
332 
RefreshLines(size_t from,size_t to)333 void wxHtmlListBox::RefreshLines(size_t from, size_t to)
334 {
335     m_cache->InvalidateRange(from, to);
336 
337     wxVListBox::RefreshLines(from, to);
338 }
339 
RefreshAll()340 void wxHtmlListBox::RefreshAll()
341 {
342     m_cache->Clear();
343 
344     wxVListBox::RefreshAll();
345 }
346 
SetItemCount(size_t count)347 void wxHtmlListBox::SetItemCount(size_t count)
348 {
349     // the items are going to change, forget the old ones
350     m_cache->Clear();
351 
352     wxVListBox::SetItemCount(count);
353 }
354 
355 // ----------------------------------------------------------------------------
356 // wxHtmlListBox implementation of wxVListBox pure virtuals
357 // ----------------------------------------------------------------------------
358 
OnDrawItem(wxDC & dc,const wxRect & rect,size_t n) const359 void wxHtmlListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
360 {
361     CacheItem(n);
362 
363     wxHtmlCell *cell = m_cache->Get(n);
364     wxCHECK_RET( cell, _T("this cell should be cached!") );
365 
366     wxHtmlRenderingInfo htmlRendInfo;
367 
368     // draw the selected cell in selected state
369     if ( IsSelected(n) )
370     {
371         wxHtmlSelection htmlSel;
372         htmlSel.Set(wxPoint(0,0), cell, wxPoint(INT_MAX, INT_MAX), cell);
373         htmlRendInfo.SetSelection(&htmlSel);
374         if ( m_htmlRendStyle )
375             htmlRendInfo.SetStyle(m_htmlRendStyle);
376         htmlRendInfo.GetState().SetSelectionState(wxHTML_SEL_IN);
377     }
378 
379     // note that we can't stop drawing exactly at the window boundary as then
380     // even the visible cells part could be not drawn, so always draw the
381     // entire cell
382     cell->Draw(dc,
383                rect.x + CELL_BORDER, rect.y + CELL_BORDER,
384                0, INT_MAX, htmlRendInfo);
385 }
386 
OnMeasureItem(size_t n) const387 wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
388 {
389     CacheItem(n);
390 
391     wxHtmlCell *cell = m_cache->Get(n);
392     wxCHECK_MSG( cell, 0, _T("this cell should be cached!") );
393 
394     return cell->GetHeight() + cell->GetDescent() + 4;
395 }
396 
397 // ----------------------------------------------------------------------------
398 // wxHtmlListBox implementation of wxHtmlListBoxWinInterface
399 // ----------------------------------------------------------------------------
400 
SetHTMLWindowTitle(const wxString & WXUNUSED (title))401 void wxHtmlListBox::SetHTMLWindowTitle(const wxString& WXUNUSED(title))
402 {
403     // nothing to do
404 }
405 
OnHTMLLinkClicked(const wxHtmlLinkInfo & link)406 void wxHtmlListBox::OnHTMLLinkClicked(const wxHtmlLinkInfo& link)
407 {
408     OnLinkClicked(GetItemForCell(link.GetHtmlCell()), link);
409 }
410 
OnLinkClicked(size_t WXUNUSED (n),const wxHtmlLinkInfo & link)411 void wxHtmlListBox::OnLinkClicked(size_t WXUNUSED(n),
412                                   const wxHtmlLinkInfo& link)
413 {
414     wxHtmlLinkEvent event(GetId(), link);
415     GetEventHandler()->ProcessEvent(event);
416 }
417 
418 wxHtmlOpeningStatus
OnHTMLOpeningURL(wxHtmlURLType WXUNUSED (type),const wxString & WXUNUSED (url),wxString * WXUNUSED (redirect)) const419 wxHtmlListBox::OnHTMLOpeningURL(wxHtmlURLType WXUNUSED(type),
420                                 const wxString& WXUNUSED(url),
421                                 wxString *WXUNUSED(redirect)) const
422 {
423     return wxHTML_OPEN;
424 }
425 
HTMLCoordsToWindow(wxHtmlCell * cell,const wxPoint & pos) const426 wxPoint wxHtmlListBox::HTMLCoordsToWindow(wxHtmlCell *cell,
427                                           const wxPoint& pos) const
428 {
429     return CellCoordsToPhysical(pos, cell);
430 }
431 
GetHTMLWindow()432 wxWindow* wxHtmlListBox::GetHTMLWindow() { return this; }
433 
GetHTMLBackgroundColour() const434 wxColour wxHtmlListBox::GetHTMLBackgroundColour() const
435 {
436     return GetBackgroundColour();
437 }
438 
SetHTMLBackgroundColour(const wxColour & WXUNUSED (clr))439 void wxHtmlListBox::SetHTMLBackgroundColour(const wxColour& WXUNUSED(clr))
440 {
441     // nothing to do
442 }
443 
SetHTMLBackgroundImage(const wxBitmap & WXUNUSED (bmpBg))444 void wxHtmlListBox::SetHTMLBackgroundImage(const wxBitmap& WXUNUSED(bmpBg))
445 {
446     // nothing to do
447 }
448 
SetHTMLStatusText(const wxString & WXUNUSED (text))449 void wxHtmlListBox::SetHTMLStatusText(const wxString& WXUNUSED(text))
450 {
451     // nothing to do
452 }
453 
GetHTMLCursor(HTMLCursor type) const454 wxCursor wxHtmlListBox::GetHTMLCursor(HTMLCursor type) const
455 {
456     // we don't want to show text selection cursor in listboxes
457     if (type == HTMLCursor_Text)
458         return wxHtmlWindow::GetDefaultHTMLCursor(HTMLCursor_Default);
459 
460     // in all other cases, use the same cursor as wxHtmlWindow:
461     return wxHtmlWindow::GetDefaultHTMLCursor(type);
462 }
463 
464 // ----------------------------------------------------------------------------
465 // wxHtmlListBox handling of HTML links
466 // ----------------------------------------------------------------------------
467 
GetRootCellCoords(size_t n) const468 wxPoint wxHtmlListBox::GetRootCellCoords(size_t n) const
469 {
470     wxPoint pos(CELL_BORDER, CELL_BORDER);
471     pos += GetMargins();
472     pos.y += GetLinesHeight(GetFirstVisibleLine(), n);
473     return pos;
474 }
475 
PhysicalCoordsToCell(wxPoint & pos,wxHtmlCell * & cell) const476 bool wxHtmlListBox::PhysicalCoordsToCell(wxPoint& pos, wxHtmlCell*& cell) const
477 {
478     int n = HitTest(pos);
479     if ( n == wxNOT_FOUND )
480         return false;
481 
482     // convert mouse coordinates to coords relative to item's wxHtmlCell:
483     pos -= GetRootCellCoords(n);
484 
485     CacheItem(n);
486     cell = m_cache->Get(n);
487 
488     return true;
489 }
490 
GetItemForCell(const wxHtmlCell * cell) const491 size_t wxHtmlListBox::GetItemForCell(const wxHtmlCell *cell) const
492 {
493     wxCHECK_MSG( cell, 0, _T("no cell") );
494 
495     cell = cell->GetRootCell();
496 
497     wxCHECK_MSG( cell, 0, _T("no root cell") );
498 
499     // the cell's ID contains item index, see CacheItem():
500     unsigned long n;
501     if ( !cell->GetId().ToULong(&n) )
502     {
503         wxFAIL_MSG( _T("unexpected root cell's ID") );
504         return 0;
505     }
506 
507     return n;
508 }
509 
510 wxPoint
CellCoordsToPhysical(const wxPoint & pos,wxHtmlCell * cell) const511 wxHtmlListBox::CellCoordsToPhysical(const wxPoint& pos, wxHtmlCell *cell) const
512 {
513     return pos + GetRootCellCoords(GetItemForCell(cell));
514 }
515 
OnInternalIdle()516 void wxHtmlListBox::OnInternalIdle()
517 {
518     wxVListBox::OnInternalIdle();
519 
520     if ( wxHtmlWindowMouseHelper::DidMouseMove() )
521     {
522         wxPoint pos = ScreenToClient(wxGetMousePosition());
523         wxHtmlCell *cell;
524 
525         if ( !PhysicalCoordsToCell(pos, cell) )
526             return;
527 
528         wxHtmlWindowMouseHelper::HandleIdle(cell, pos);
529     }
530 }
531 
OnMouseMove(wxMouseEvent & event)532 void wxHtmlListBox::OnMouseMove(wxMouseEvent& event)
533 {
534     wxHtmlWindowMouseHelper::HandleMouseMoved();
535     event.Skip();
536 }
537 
OnLeftDown(wxMouseEvent & event)538 void wxHtmlListBox::OnLeftDown(wxMouseEvent& event)
539 {
540     wxPoint pos = event.GetPosition();
541     wxHtmlCell *cell;
542 
543     if ( !PhysicalCoordsToCell(pos, cell) )
544     {
545         event.Skip();
546         return;
547     }
548 
549     if ( !wxHtmlWindowMouseHelper::HandleMouseClick(cell, pos, event) )
550     {
551         // no link was clicked, so let the listbox code handle the click (e.g.
552         // by selecting another item in the list):
553         event.Skip();
554     }
555 }
556 
557 
558 // ----------------------------------------------------------------------------
559 // wxSimpleHtmlListBox
560 // ----------------------------------------------------------------------------
561 
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,int n,const wxString choices[],long style,const wxValidator & validator,const wxString & name)562 bool wxSimpleHtmlListBox::Create(wxWindow *parent, wxWindowID id,
563                                  const wxPoint& pos,
564                                  const wxSize& size,
565                                  int n, const wxString choices[],
566                                  long style,
567                                  const wxValidator& validator,
568                                  const wxString& name)
569 {
570     if (!wxHtmlListBox::Create(parent, id, pos, size, style, name))
571         return false;
572 
573 #if wxUSE_VALIDATORS
574     SetValidator(validator);
575 #endif
576     for (int i=0; i<n; i++)
577         Append(choices[i]);
578 
579     return true;
580 }
581 
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,const wxArrayString & choices,long style,const wxValidator & validator,const wxString & name)582 bool wxSimpleHtmlListBox::Create(wxWindow *parent, wxWindowID id,
583                                     const wxPoint& pos,
584                                     const wxSize& size,
585                                     const wxArrayString& choices,
586                                     long style,
587                                     const wxValidator& validator,
588                                     const wxString& name)
589 {
590     if (!wxHtmlListBox::Create(parent, id, pos, size, style, name))
591         return false;
592 
593 #if wxUSE_VALIDATORS
594     SetValidator(validator);
595 #endif
596     Append(choices);
597 
598     return true;
599 }
600 
~wxSimpleHtmlListBox()601 wxSimpleHtmlListBox::~wxSimpleHtmlListBox()
602 {
603     wxASSERT(m_items.GetCount() == m_HTMLclientData.GetCount());
604     if (HasClientObjectData())
605     {
606         // clear the array of client data objects
607         for (size_t i=0; i<m_items.GetCount(); i++)
608             delete DoGetItemClientObject(i);
609     }
610 
611     m_items.Clear();
612     m_HTMLclientData.Clear();
613 }
614 
Clear()615 void wxSimpleHtmlListBox::Clear()
616 {
617     m_items.Clear();
618     m_HTMLclientData.Clear();
619     UpdateCount();
620 }
621 
Delete(unsigned int n)622 void wxSimpleHtmlListBox::Delete(unsigned int n)
623 {
624     m_items.RemoveAt(n);
625     m_HTMLclientData.RemoveAt(n);
626     UpdateCount();
627 }
628 
Append(const wxArrayString & strings)629 void wxSimpleHtmlListBox::Append(const wxArrayString& strings)
630 {
631     // append all given items at once
632     WX_APPEND_ARRAY(m_items, strings);
633     m_HTMLclientData.Add(NULL, strings.GetCount());
634     UpdateCount();
635 }
636 
DoAppend(const wxString & item)637 int wxSimpleHtmlListBox::DoAppend(const wxString& item)
638 {
639     m_items.Add(item);
640     m_HTMLclientData.Add(NULL);
641     UpdateCount();
642     return GetCount()-1;
643 }
644 
DoInsert(const wxString & item,unsigned int pos)645 int wxSimpleHtmlListBox::DoInsert(const wxString& item, unsigned int pos)
646 {
647     m_items.Insert(item, pos);
648     m_HTMLclientData.Insert(NULL, pos);
649     UpdateCount();
650     return pos;
651 }
652 
SetString(unsigned int n,const wxString & s)653 void wxSimpleHtmlListBox::SetString(unsigned int n, const wxString& s)
654 {
655     wxCHECK_RET( IsValid(n),
656                  wxT("invalid index in wxSimpleHtmlListBox::SetString") );
657 
658     m_items[n]=s;
659     RefreshLine(n);
660 }
661 
GetString(unsigned int n) const662 wxString wxSimpleHtmlListBox::GetString(unsigned int n) const
663 {
664     wxCHECK_MSG( IsValid(n), wxEmptyString,
665                  wxT("invalid index in wxSimpleHtmlListBox::GetString") );
666 
667     return m_items[n];
668 }
669 
UpdateCount()670 void wxSimpleHtmlListBox::UpdateCount()
671 {
672     wxASSERT(m_items.GetCount() == m_HTMLclientData.GetCount());
673     wxHtmlListBox::SetItemCount(m_items.GetCount());
674 
675     // very small optimization: if you need to add lot of items to
676     // a wxSimpleHtmlListBox be sure to use the
677     // wxSimpleHtmlListBox::Append(const wxArrayString&) method instead!
678     if (!this->IsFrozen())
679         RefreshAll();
680 }
681 
682 #endif // wxUSE_HTML
683