static const int EXPANDER_OFFSET = 1;
#endif
-//-----------------------------------------------------------------------------
-// wxDataViewHeaderWindow
-//-----------------------------------------------------------------------------
-
//Below is the compare stuff
//For the generic implements, both the leaf nodes and the nodes are sorted for fast search when needed
static wxDataViewModel * g_model;
static int g_column = -2;
static bool g_asending = true;
+//-----------------------------------------------------------------------------
+// wxDataViewHeaderWindow
+//-----------------------------------------------------------------------------
+
class wxDataViewHeaderWindow : public wxHeaderCtrl
{
public:
{ return static_cast<wxDataViewCtrl *>(GetParent()); }
protected:
- virtual wxHeaderColumnBase& GetColumn(unsigned int idx)
+ // implement/override wxHeaderCtrl functions by forwarding them to the main
+ // control
+ virtual const wxHeaderColumn& GetColumn(unsigned int idx) const
{
return *(GetOwner()->GetColumn(idx));
}
+ virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
+ {
+ wxDataViewCtrl * const owner = GetOwner();
+
+ int widthContents = owner->GetBestColumnWidth(idx);
+ owner->GetColumn(idx)->SetWidth(wxMax(widthTitle, widthContents));
+ owner->OnColumnChange(idx);
+
+ return true;
+ }
+
private:
+ bool SendEvent(wxEventType type, unsigned int n)
+ {
+ wxDataViewCtrl * const owner = GetOwner();
+ wxDataViewEvent event(type, owner->GetId());
+
+ event.SetEventObject(owner);
+ event.SetColumn(n);
+ event.SetDataViewColumn(owner->GetColumn(n));
+ event.SetModel(owner->GetModel());
+
+ // for events created by wxDataViewHeaderWindow the
+ // row / value fields are not valid
+ return owner->GetEventHandler()->ProcessEvent(event);
+ }
+
+ void OnClick(wxHeaderCtrlEvent& event)
+ {
+ const unsigned idx = event.GetColumn();
+
+ if ( SendEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, idx) )
+ return;
+
+ // default handling for the column click is to sort by this column or
+ // toggle its sort order
+ wxDataViewCtrl * const owner = GetOwner();
+ wxDataViewColumn * const col = owner->GetColumn(idx);
+ if ( !col->IsSortable() )
+ {
+ // no default handling for non-sortable columns
+ event.Skip();
+ return;
+ }
+
+ if ( col->IsSortKey() )
+ {
+ // already using this column for sorting, just change the order
+ col->ToggleSortOrder();
+ }
+ else // not using this column for sorting yet
+ {
+ // first unset the old sort column if any
+ int oldSortKey = owner->GetSortingColumnIndex();
+ if ( oldSortKey != wxNOT_FOUND )
+ {
+ owner->GetColumn(oldSortKey)->UnsetAsSortKey();
+ owner->OnColumnChange(oldSortKey);
+ }
+
+ owner->SetSortingColumnIndex(idx);
+ col->SetAsSortKey();
+ }
+
+ wxDataViewModel * const model = owner->GetModel();
+ if ( model )
+ model->Resort();
+
+ owner->OnColumnChange(idx);
+ }
+
+ void OnRClick(wxHeaderCtrlEvent& event)
+ {
+ if ( !SendEvent(wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK,
+ event.GetColumn()) )
+ event.Skip();
+ }
+
+ void OnEndResize(wxHeaderCtrlEvent& event)
+ {
+ wxDataViewCtrl * const owner = GetOwner();
+
+ const unsigned col = event.GetColumn();
+ owner->GetColumn(col)->SetWidth(event.GetWidth());
+ GetOwner()->OnColumnChange(col);
+ }
+
+ void OnEndReorder(wxHeaderCtrlEvent& event)
+ {
+ wxDataViewCtrl * const owner = GetOwner();
+ owner->ColumnMoved(owner->GetColumn(event.GetColumn()),
+ event.GetNewOrder());
+ }
+
+ DECLARE_EVENT_TABLE()
DECLARE_NO_COPY_CLASS(wxDataViewHeaderWindow)
};
+BEGIN_EVENT_TABLE(wxDataViewHeaderWindow, wxHeaderCtrl)
+ EVT_HEADER_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnClick)
+ EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxDataViewHeaderWindow::OnRClick)
+
+ EVT_HEADER_END_RESIZE(wxID_ANY, wxDataViewHeaderWindow::OnEndResize)
+
+ EVT_HEADER_END_REORDER(wxID_ANY, wxDataViewHeaderWindow::OnEndReorder)
+END_EVENT_TABLE()
+
//-----------------------------------------------------------------------------
// wxDataViewRenameTimer
//-----------------------------------------------------------------------------
void Expand( unsigned int row ) { OnExpanding( row ); }
void Collapse( unsigned int row ) { OnCollapsing( row ); }
+ bool IsExpanded( unsigned int row ) const;
private:
wxDataViewTreeNode * GetTreeNodeByRow( unsigned int row ) const;
//We did not need this temporarily
unsigned int x_start;
for (x_start = 0; col_start < cols; col_start++)
{
- wxDataViewColumn *col = GetOwner()->GetColumn(col_start);
+ wxDataViewColumn *col = GetOwner()->GetColumnAt(col_start);
if (col->IsHidden())
continue; // skip it!
unsigned int x_last = x_start;
for (; col_last < cols; col_last++)
{
- wxDataViewColumn *col = GetOwner()->GetColumn(col_last);
+ wxDataViewColumn *col = GetOwner()->GetColumnAt(col_last);
if (col->IsHidden())
continue; // skip it!
int x = x_start;
for (unsigned int i = col_start; i < col_last; i++)
{
- wxDataViewColumn *col = GetOwner()->GetColumn(i);
+ wxDataViewColumn *col = GetOwner()->GetColumnAt(i);
if (col->IsHidden())
continue; // skip it
wxDataViewColumn *expander = GetOwner()->GetExpanderColumn();
if (!expander)
{
- // TODO: last column for RTL support
- expander = GetOwner()->GetColumn( 0 );
+ // TODO-RTL: last column for RTL support
+ expander = GetOwner()->GetColumnAt( 0 );
GetOwner()->SetExpanderColumn(expander);
}
for (unsigned int i = col_start; i < col_last; i++)
{
- wxDataViewColumn *col = GetOwner()->GetColumn( i );
+ wxDataViewColumn *col = GetOwner()->GetColumnAt( i );
wxDataViewRenderer *cell = col->GetRenderer();
cell_rect.width = col->GetWidth();
unsigned int i;
for (i = 0; i < cols; i++)
{
- wxDataViewColumn *c = GetOwner()->GetColumn( i );
+ wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
if (c->IsHidden())
continue; // skip it!
m_owner->CalcUnscrolledPosition( rect.x, rect.y, &xx, &yy );
for (x_start = 0; colnum < column; colnum++)
{
- wxDataViewColumn *col = GetOwner()->GetColumn(colnum);
+ wxDataViewColumn *col = GetOwner()->GetColumnAt(colnum);
if (col->IsHidden())
continue; // skip it!
for (i = 0; i < GetOwner()->GetColumnCount(); i++)
{
const wxDataViewColumn *c =
- const_cast<wxDataViewCtrl*>(GetOwner())->GetColumn( i );
+ const_cast<wxDataViewCtrl*>(GetOwner())->GetColumnAt( i );
if (!c->IsHidden())
width += c->GetWidth();
return le;
}
+
+bool wxDataViewMainWindow::IsExpanded( unsigned int row ) const
+{
+ if (IsVirtualList())
+ return false;
+
+ wxDataViewTreeNode * node = GetTreeNodeByRow(row);
+ if (!node)
+ return false;
+
+ if (!node->HasChildren())
+ return false;
+
+ return node->IsOpen();
+}
+
+
void wxDataViewMainWindow::OnExpanding( unsigned int row )
{
if (IsVirtualList())
m_owner->CalcUnscrolledPosition( point.x, point.y, &x, &y );
for (unsigned x_start = 0; colnum < cols; colnum++)
{
- col = GetOwner()->GetColumn(colnum);
+ col = GetOwner()->GetColumnAt(colnum);
if (col->IsHidden())
continue; // skip it!
wxDataViewColumn *col = NULL;
for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ )
{
- col = GetOwner()->GetColumn( i );
+ col = GetOwner()->GetColumnAt( i );
x += col->GetWidth();
- if( GetOwner()->GetColumn(i+1) == column )
+ if( GetOwner()->GetColumnAt(i+1) == column )
break;
}
int w = col->GetWidth();
{
case WXK_RETURN:
{
- if (m_currentRow > 0)
+ if (m_currentRow >= 0)
{
wxWindow *parent = GetParent();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId());
unsigned int i;
for (i = 0; i < cols; i++)
{
- wxDataViewColumn *c = GetOwner()->GetColumn( i );
+ wxDataViewColumn *c = GetOwner()->GetColumnAt( i );
if (c->IsHidden())
continue; // skip it!
wxDataViewRenderer *cell = col->GetRenderer();
unsigned int current = GetLineAt( y );
- if ((current > GetRowCount()) || (x > GetEndOfLastCol()))
+ if ((current >= GetRowCount()) || (x > GetEndOfLastCol()))
{
// Unselect all if below the last row ?
return;
// select single line
SelectAllRows( false );
SelectRow( m_lineSelectSingleOnUp, true );
+ SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) );
}
//Process the event of user clicking the expander
m_notifier = NULL;
// No sorting column at start
- m_sortingColumn = NULL;
+ m_sortingColumnIdx = wxNOT_FOUND;
+
m_headerArea = NULL;
}
return false;
m_cols.Append( col );
- OnColumnChange();
+ OnColumnsCountChanged();
return true;
}
return false;
m_cols.Insert( col );
- OnColumnChange();
+ OnColumnsCountChanged();
return true;
}
return false;
m_cols.Insert( pos, col );
- OnColumnChange();
+ OnColumnsCountChanged();
return true;
}
-void wxDataViewCtrl::OnColumnChange()
+void wxDataViewCtrl::OnColumnChange(unsigned int idx)
+{
+ if ( m_headerArea )
+ m_headerArea->UpdateColumn(idx);
+
+ m_clientArea->UpdateDisplay();
+}
+
+void wxDataViewCtrl::OnColumnsCountChanged()
{
if (m_headerArea)
m_headerArea->SetColumnCount(GetColumnCount());
return m_cols.GetCount();
}
-wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int pos ) const
+wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int idx ) const
{
- wxDataViewColumnList::const_iterator iter;
- unsigned int i = 0;
- for (iter = m_cols.begin(); iter!=m_cols.end(); iter++)
- {
- if (i == pos)
- return *iter;
+ return m_cols[idx];
+}
- if ((*iter)->IsHidden())
- continue;
- i ++;
- }
- return NULL;
+wxDataViewColumn *wxDataViewCtrl::GetColumnAt(unsigned int pos) const
+{
+ // columns can't be reordered if there is no header window which allows
+ // to do this
+ const unsigned idx = m_headerArea ? m_headerArea->GetColumnsOrder()[pos]
+ : pos;
+
+ return GetColumn(idx);
}
-void wxDataViewCtrl::ColumnMoved( wxDataViewColumn* col, unsigned int new_pos )
+int wxDataViewCtrl::GetColumnIndex(const wxDataViewColumn *column) const
{
- if (new_pos > m_cols.GetCount()) return;
+ const unsigned count = m_cols.size();
+ for ( unsigned n = 0; n < count; n++ )
+ {
+ if ( m_cols[n] == column )
+ return n;
+ }
- // Exchange position
- m_cols.DeleteContents(false);
- m_cols.DeleteObject( col );
- m_cols.Insert( new_pos, col );
- m_cols.DeleteContents(true);
+ return wxNOT_FOUND;
+}
+void wxDataViewCtrl::ColumnMoved(wxDataViewColumn * WXUNUSED(col),
+ unsigned int WXUNUSED(new_pos))
+{
+ // do _not_ reorder m_cols elements here, they should always be in the
+ // order in which columns were added, we only display the columns in
+ // different order
m_clientArea->UpdateDisplay();
}
return false;
m_cols.Erase(ret);
- OnColumnChange();
+ OnColumnsCountChanged();
return true;
}
bool wxDataViewCtrl::ClearColumns()
{
m_cols.Clear();
- OnColumnChange();
+ OnColumnsCountChanged();
return true;
}
int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const
{
- int ret = 0, dead = 0;
- int len = GetColumnCount();
- for (int i=0; i<len; i++)
+ int ret = 0,
+ dummy = 0;
+ unsigned int len = GetColumnCount();
+ for ( unsigned int i = 0; i < len; i++ )
{
- wxDataViewColumn * col = GetColumn(i);
+ wxDataViewColumn * col = GetColumnAt(i);
if (col->IsHidden())
continue;
ret += col->GetWidth();
if (column==col)
{
- CalcScrolledPosition( ret, dead, &ret, &dead );
+ CalcScrolledPosition( ret, dummy, &ret, &dummy );
break;
}
}
wxDataViewColumn *wxDataViewCtrl::GetSortingColumn() const
{
- return NULL;
+ return m_sortingColumnIdx == wxNOT_FOUND ? NULL
+ : GetColumn(m_sortingColumnIdx);
}
//Selection code with wxDataViewItem as parameters
void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel )
{
wxDataViewSelection selection(wxDataViewSelectionCmp);
+
+ wxDataViewItem last_parent;
+
int len = sel.GetCount();
for( int i = 0; i < len; i ++ )
{
- int row = m_clientArea->GetRowByItem( sel[i] );
+ wxDataViewItem item = sel[i];
+ wxDataViewItem parent = GetModel()->GetParent( item );
+ if (parent)
+ {
+ if (parent != last_parent)
+ ExpandAncestors(item);
+ }
+
+ last_parent = parent;
+ int row = m_clientArea->GetRowByItem( item );
if( row >= 0 )
selection.Add( static_cast<unsigned int>(row) );
}
+
m_clientArea->SetSelections( selection );
}
void wxDataViewCtrl::Select( const wxDataViewItem & item )
{
+ ExpandAncestors( item );
+
int row = m_clientArea->GetRowByItem( item );
if( row >= 0 )
{
void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataViewColumn * column )
{
+ ExpandAncestors( item );
+
+ m_clientArea->RecalculateDisplay();
+
int row = m_clientArea->GetRowByItem(item);
if( row >= 0 )
{
if( column == NULL )
EnsureVisible(row, -1);
else
- {
- int col = 0;
- int len = GetColumnCount();
- for( int i = 0; i < len; i ++ )
- if( GetColumn(i) == column )
- {
- col = i;
- break;
- }
- EnsureVisible( row, col );
- }
+ EnsureVisible( row, GetColumnIndex(column) );
}
}
m_clientArea->Collapse(row);
}
+bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const
+{
+ int row = m_clientArea->GetRowByItem( item );
+ if (row != -1)
+ return m_clientArea->IsExpanded(row);
+ return false;
+}
+
+
#endif
// !wxUSE_GENERICDATAVIEWCTRL