+ if (node)
+ {
+ wxRect rect;
+ wxListLineData *line = (wxListLineData*)node->Data();
+ line->GetRect( rect );
+ pos.x = rect.x;
+ pos.y = rect.y;
+ }
+ else
+ {
+ pos.x = 0;
+ pos.y = 0;
+ }
+ return TRUE;
+}
+
+int wxListMainWindow::GetSelectedItemCount()
+{
+ int ret = 0;
+ wxNode *node = m_lines.First();
+ while (node)
+ {
+ wxListLineData *line = (wxListLineData*)node->Data();
+ if (line->IsHilighted()) ret++;
+ node = node->Next();
+ }
+ return ret;
+}
+
+void wxListMainWindow::SetMode( long mode )
+{
+ m_dirty = TRUE;
+ m_mode = mode;
+
+ DeleteEverything();
+
+ if (m_mode & wxLC_REPORT)
+ {
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ m_xScroll = 15;
+#else
+ m_xScroll = 0;
+#endif
+ m_yScroll = 15;
+ }
+ else
+ {
+ m_xScroll = 15;
+ m_yScroll = 0;
+ }
+}
+
+long wxListMainWindow::GetMode() const
+{
+ return m_mode;
+}
+
+void wxListMainWindow::CalculatePositions()
+{
+ if (!m_lines.First()) return;
+
+ wxClientDC dc( this );
+ dc.SetFont( GetFont() );
+
+ int iconSpacing = 0;
+ if (m_mode & wxLC_ICON) iconSpacing = m_normal_spacing;
+ if (m_mode & wxLC_SMALL_ICON) iconSpacing = m_small_spacing;
+
+ // we take the first line (which also can be an icon or
+ // an a text item in wxLC_ICON and wxLC_LIST modes) to
+ // measure the size of the line
+
+ int lineWidth = 0;
+ int lineHeight = 0;
+ int lineSpacing = 0;
+
+ wxListLineData *line = (wxListLineData*)m_lines.First()->Data();
+ line->CalculateSize( &dc, iconSpacing );
+ int dummy = 0;
+ line->GetSize( dummy, lineSpacing );
+ lineSpacing += 4;
+
+ int clientWidth = 0;
+ int clientHeight = 0;
+
+ if (m_mode & wxLC_REPORT)
+ {
+ int x = 4;
+ int y = 1;
+ int entireHeight = m_lines.Number() * lineSpacing + 2;
+ int scroll_pos = GetScrollPos( wxVERTICAL );
+ int x_scroll_pos = GetScrollPos( wxHORIZONTAL );
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+#else
+ SetScrollbars( m_xScroll, m_yScroll, 0, (entireHeight+15) / m_yScroll, 0, scroll_pos, TRUE );
+#endif
+ GetClientSize( &clientWidth, &clientHeight );
+
+ wxNode* node = m_lines.First();
+ int entireWidth = 0 ;
+ while (node)
+ {
+ wxListLineData *line = (wxListLineData*)node->Data();
+ line->CalculateSize( &dc, iconSpacing );
+ line->SetPosition( &dc, x, y, clientWidth );
+ int col_x = 2;
+ for (int i = 0; i < GetColumnCount(); i++)
+ {
+ line->SetColumnPosition( i, col_x );
+ col_x += GetColumnWidth( i );
+ }
+ entireWidth = wxMax( entireWidth , col_x ) ;
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ line->SetPosition( &dc, x, y, col_x );
+#endif
+ y += lineSpacing; // one pixel blank line between items
+ node = node->Next();
+ }
+ m_visibleLines = clientHeight / lineSpacing;
+#if wxUSE_GENERIC_LIST_EXTENSIONS
+ SetScrollbars( m_xScroll, m_yScroll, entireWidth / m_xScroll , (entireHeight+15) / m_yScroll, x_scroll_pos , scroll_pos, TRUE );
+#endif
+ }
+ else
+ {
+ // at first we try without any scrollbar. if the items don't
+ // fit into the window, we recalculate after subtracting an
+ // approximated 15 pt for the horizontal scrollbar
+
+ GetSize( &clientWidth, &clientHeight );
+ clientHeight -= 4; // sunken frame
+
+ int entireWidth = 0;
+
+ for (int tries = 0; tries < 2; tries++)
+ {
+ entireWidth = 0;
+ int x = 5; // painting is done at x-2
+ int y = 5; // painting is done at y-2
+ int maxWidth = 0;
+ m_visibleLines = 0;
+ int m_currentVisibleLines = 0;
+ wxNode *node = m_lines.First();
+ while (node)
+ {
+ m_currentVisibleLines++;
+ wxListLineData *line = (wxListLineData*)node->Data();
+ line->CalculateSize( &dc, iconSpacing );
+ line->SetPosition( &dc, x, y, clientWidth );
+ line->GetSize( lineWidth, lineHeight );
+ if (lineWidth > maxWidth) maxWidth = lineWidth;
+ y += lineSpacing;
+ if (y+lineSpacing-6 >= clientHeight) // -6 for earlier "line breaking"
+ {
+ if (m_currentVisibleLines > m_visibleLines)
+ m_visibleLines = m_currentVisibleLines;
+ m_currentVisibleLines = 0;
+ y = 5;
+ x += maxWidth+6;
+ entireWidth += maxWidth+6;
+ maxWidth = 0;
+ }
+ node = node->Next();
+ if (!node) entireWidth += maxWidth;
+ if ((tries == 0) && (entireWidth > clientWidth))
+ {
+ clientHeight -= 15; // scrollbar height
+ m_visibleLines = 0;
+ m_currentVisibleLines = 0;
+ break;
+ }
+ if (!node) tries = 1; // everything fits, no second try required
+ }
+ }
+// m_visibleLines = (5+clientHeight+6) / (lineSpacing); // +6 for earlier "line breaking"
+
+ int scroll_pos = GetScrollPos( wxHORIZONTAL );
+ SetScrollbars( m_xScroll, m_yScroll, (entireWidth+15) / m_xScroll, 0, scroll_pos, 0, TRUE );
+ }
+}
+
+void wxListMainWindow::RealizeChanges( void )
+{
+ if (!m_current)
+ {
+ wxNode *node = m_lines.First();
+ if (node) m_current = (wxListLineData*)node->Data();
+ }
+ if (m_current)
+ {
+ FocusLine( m_current );
+ if (m_mode & wxLC_SINGLE_SEL) m_current->Hilight( TRUE );
+ }
+}
+
+long wxListMainWindow::GetNextItem( long item, int WXUNUSED(geometry), int state )
+{
+ long ret = 0;
+ if (item > 0) ret = item;
+ if(ret >= GetItemCount()) return -1;
+ wxNode *node = m_lines.Nth( ret );
+ while (node)
+ {
+ wxListLineData *line = (wxListLineData*)node->Data();
+ if ((state & wxLIST_STATE_FOCUSED) && (line == m_current)) return ret;
+ if ((state & wxLIST_STATE_SELECTED) && (line->IsHilighted())) return ret;
+ if (!state) return ret;
+ ret++;
+ node = node->Next();
+ }
+ return -1;
+}
+
+void wxListMainWindow::DeleteItem( long index )
+{
+ m_dirty = TRUE;
+ wxNode *node = m_lines.Nth( index );
+ if (node)
+ {
+ wxListLineData *line = (wxListLineData*)node->Data();
+ if (m_current == line) m_current = (wxListLineData *) NULL;
+ DeleteLine( line );
+ m_lines.DeleteNode( node );
+ }
+}
+
+void wxListMainWindow::DeleteColumn( int col )
+{
+ wxCHECK_RET( col < (int)m_columns.GetCount(),
+ wxT("attempting to delete inexistent column in wxListView") );
+
+ m_dirty = TRUE;
+ wxNode *node = m_columns.Nth( col );
+ if (node) m_columns.DeleteNode( node );
+}
+
+void wxListMainWindow::DeleteAllItems( void )
+{
+ m_dirty = TRUE;
+ m_current = (wxListLineData *) NULL;
+ wxNode *node = m_lines.First();
+ while (node)