X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7d83595849b8c014f6b975c3d2acc9a8465d2bc4..f81bd28859d95c2a8f8b6ec71885f8770b5e5e1a:/src/generic/datavgen.cpp diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 8be7c4781d..feb59e3a52 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -70,7 +70,7 @@ static const int EXPANDER_OFFSET = 1; #endif // Below is the compare stuff. -// For the generic implementation, both the leaf nodes and the nodes are sorted for +// For the generic implementation, both the leaf nodes and the nodes are sorted for // fast search when needed static wxDataViewModel* g_model; static int g_column = -2; @@ -99,6 +99,7 @@ protected: return *(GetOwner()->GetColumn(idx)); } + // FIXME: currently unused virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle) { wxDataViewCtrl * const owner = GetOwner(); @@ -229,7 +230,7 @@ class wxDataViewTreeNode; WX_DEFINE_ARRAY( wxDataViewTreeNode *, wxDataViewTreeNodes ); WX_DEFINE_ARRAY( void* , wxDataViewTreeLeaves); -int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, +int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, wxDataViewTreeNode ** node2); int LINKAGEMODE wxGenericTreeModelItemCmp( void ** id1, void ** id2); @@ -350,7 +351,7 @@ private: int m_subTreeCount; }; -int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, +int LINKAGEMODE wxGenericTreeModelNodeCmp( wxDataViewTreeNode ** node1, wxDataViewTreeNode ** node2) { return g_model->Compare( (*node1)->GetItem(), (*node2)->GetItem(), g_column, g_asending ); @@ -450,15 +451,15 @@ public: int GetEndOfLastCol() const; unsigned int GetFirstVisibleRow() const; - // I change this method to un const because in the tree view, - // the displaying number of the tree are changing along with the + // I change this method to un const because in the tree view, + // the displaying number of the tree are changing along with the // expanding/collapsing of the tree nodes unsigned int GetLastVisibleRow(); unsigned int GetRowCount(); wxDataViewItem GetSelection() const; wxDataViewSelection GetSelections(){ return m_selection; } - void SetSelections( const wxDataViewSelection & sel ) + void SetSelections( const wxDataViewSelection & sel ) { m_selection = sel; UpdateDisplay(); } void Select( const wxArrayInt& aSelections ); void SelectAllRows( bool on ); @@ -494,9 +495,10 @@ public: void HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column ); wxRect GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ); - void Expand( unsigned int row ) { OnExpanding( row ); } - void Collapse( unsigned int row ) { OnCollapsing( row ); } + void Expand( unsigned int row ); + void Collapse( unsigned int row ); bool IsExpanded( unsigned int row ) const; + bool HasChildren( unsigned int row ) const; #if wxUSE_DRAG_AND_DROP bool EnableDragSource( const wxDataFormat &format ); @@ -517,8 +519,6 @@ private: int RecalculateCount(); wxDataViewEvent SendExpanderEvent( wxEventType type, const wxDataViewItem & item ); - void OnExpanding( unsigned int row ); - void OnCollapsing( unsigned int row ); wxDataViewTreeNode * FindNode( const wxDataViewItem & item ); @@ -671,7 +671,7 @@ wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype, { } -void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, +void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wxRect cell, wxDC *dc, int state ) { wxDataViewCtrl *view = GetOwner()->GetOwner(); @@ -679,8 +679,8 @@ void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT) : view->GetForegroundColour(); dc->SetTextForeground(col); - dc->DrawText( text, - cell.x + xoffset, + dc->DrawText( text, + cell.x + xoffset, cell.y + ((cell.height - dc->GetCharHeight()) / 2)); } @@ -716,9 +716,15 @@ bool wxDataViewTextRenderer::HasEditorCtrl() const wxControl* wxDataViewTextRenderer::CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value ) { - return new wxTextCtrl( parent, wxID_ANY, value, - wxPoint(labelRect.x,labelRect.y), - wxSize(labelRect.width,labelRect.height) ); + wxTextCtrl* ctrl = new wxTextCtrl( parent, wxID_ANY, value, + wxPoint(labelRect.x,labelRect.y), + wxSize(labelRect.width,labelRect.height) ); + + // select the text in the control an place the cursor at the end + ctrl->SetInsertionPointEnd(); + ctrl->SelectAll(); + + return ctrl; } bool wxDataViewTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVariant &value ) @@ -738,12 +744,8 @@ wxSize wxDataViewTextRenderer::GetSize() const { const wxDataViewCtrl *view = GetView(); if (!m_text.empty()) - { - int x,y; - view->GetTextExtent( m_text, &x, &y ); - return wxSize( x, y ); - } - return wxSize(80,20); + return view->wxWindowBase::GetTextExtent( m_text ); + return wxSize(wxDVC_DEFAULT_RENDERER_SIZE,wxDVC_DEFAULT_RENDERER_SIZE); } // --------------------------------------------------------- @@ -844,7 +846,7 @@ wxSize wxDataViewBitmapRenderer::GetSize() const else if (m_icon.Ok()) return wxSize( m_icon.GetWidth(), m_icon.GetHeight() ); - return wxSize(16,16); + return wxSize(wxDVC_DEFAULT_RENDERER_SIZE,wxDVC_DEFAULT_RENDERER_SIZE); } // --------------------------------------------------------- @@ -1134,19 +1136,39 @@ wxSize wxDataViewIconTextRenderer::GetSize() const return wxSize(80,20); } -wxControl * -wxDataViewIconTextRenderer::CreateEditorCtrl(wxWindow * WXUNUSED(parent), - wxRect WXUNUSED(labelRect), - const wxVariant& WXUNUSED(value)) +wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl(wxWindow *parent, wxRect labelRect, const wxVariant& value) { - return NULL; + wxDataViewIconText iconText; + iconText << value; + + wxString text = iconText.GetText(); + + // adjust the label rect to take the width of the icon into account + if (iconText.GetIcon().IsOk()) + { + int w = iconText.GetIcon().GetWidth() + 4; + labelRect.x += w; + labelRect.width -= w; + } + + wxTextCtrl* ctrl = new wxTextCtrl( parent, wxID_ANY, text, + wxPoint(labelRect.x,labelRect.y), + wxSize(labelRect.width,labelRect.height) ); + + // select the text in the control an place the cursor at the end + ctrl->SetInsertionPointEnd(); + ctrl->SelectAll(); + + return ctrl; } -bool -wxDataViewIconTextRenderer::GetValueFromEditorCtrl(wxControl* WXUNUSED(editor), - wxVariant& WXUNUSED(value)) +bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( wxControl *editor, wxVariant& value ) { - return false; + wxTextCtrl *text = (wxTextCtrl*) editor; + + wxDataViewIconText iconText(text->GetValue(), m_value.GetIcon()); + value << iconText; + return true; } //----------------------------------------------------------------------------- @@ -1242,30 +1264,30 @@ public: } virtual wxDragResult OnDragOver( wxCoord x, wxCoord y, wxDragResult def ) - { + { wxDataFormat format = GetMatchingPair(); if (format == wxDF_INVALID) return wxDragNone; return m_win->OnDragOver( format, x, y, def); - } + } virtual bool OnDrop( wxCoord x, wxCoord y ) - { + { wxDataFormat format = GetMatchingPair(); if (format == wxDF_INVALID) return false; return m_win->OnDrop( format, x, y ); - } + } virtual wxDragResult OnData( wxCoord x, wxCoord y, wxDragResult def ) - { + { wxDataFormat format = GetMatchingPair(); if (format == wxDF_INVALID) return wxDragNone; if (!GetData()) return wxDragNone; return m_win->OnData( format, x, y, def ); - } + } virtual void OnLeave() { m_win->OnLeave(); } @@ -1294,7 +1316,7 @@ void wxDataViewRenameTimer::Notify() //----------------------------------------------------------------------------- // The tree building helper, declared firstly -static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, +static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node); int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 ) @@ -1304,7 +1326,6 @@ int LINKAGEMODE wxDataViewSelectionCmp( unsigned int row1, unsigned int row2 ) return -1; } - IMPLEMENT_ABSTRACT_CLASS(wxDataViewMainWindow, wxWindow) BEGIN_EVENT_TABLE(wxDataViewMainWindow,wxWindow) @@ -1404,7 +1425,7 @@ void wxDataViewMainWindow::RemoveDropHint() } } -wxDragResult wxDataViewMainWindow::OnDragOver( wxDataFormat format, wxCoord x, +wxDragResult wxDataViewMainWindow::OnDragOver( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ) { int xx = x; @@ -1479,7 +1500,7 @@ bool wxDataViewMainWindow::OnDrop( wxDataFormat format, wxCoord x, wxCoord y ) return true; } -wxDragResult wxDataViewMainWindow::OnData( wxDataFormat format, wxCoord x, wxCoord y, +wxDragResult wxDataViewMainWindow::OnData( wxDataFormat format, wxCoord x, wxCoord y, wxDragResult def ) { int xx = x; @@ -1536,7 +1557,7 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent ) { wxDataViewTreeNode *node = GetTreeNodeByRow(row); indent = GetOwner()->GetIndent() * node->GetIndentLevel(); - indent = indent + m_lineHeight; + indent = indent + m_lineHeight; // try to use the m_lineHeight as the expander space if(!node->HasChildren()) @@ -1771,7 +1792,6 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) cell_rect.x = x_start; for (unsigned int i = col_start; i < col_last; i++) { - wxDataViewColumn *col = GetOwner()->GetColumnAt( i ); wxDataViewRenderer *cell = col->GetRenderer(); cell_rect.width = col->GetWidth(); @@ -1794,13 +1814,13 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) dataitem = node->GetItem(); - if ((i > 0) && model->IsContainer(dataitem) && + if ((i > 0) && model->IsContainer(dataitem) && !model->HasContainerColumns(dataitem)) continue; } else { - dataitem = wxDataViewItem( wxUIntToPtr(item) ); + dataitem = wxDataViewItem( wxUIntToPtr(item+1) ); } model->GetValue( value, dataitem, col->GetModelColumn()); @@ -1832,10 +1852,10 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // change the cell_rect.x to the appropriate pos int expander_x = indent + EXPANDER_MARGIN; - int expander_y = cell_rect.y + EXPANDER_MARGIN + (GetLineHeight(item) / 2) + int expander_y = cell_rect.y + EXPANDER_MARGIN + (GetLineHeight(item) / 2) - (expander_width/2) - EXPANDER_OFFSET; - indent = indent + m_lineHeight; + indent = indent + m_lineHeight; // try to use the m_lineHeight as the expander space dc.SetPen( m_penExpander ); @@ -1849,7 +1869,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) flag |= wxCONTROL_CURRENT; } if( node->IsOpen() ) - wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, + wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag|wxCONTROL_EXPANDED ); else wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag); @@ -1868,7 +1888,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // cannot be bigger than allocated space wxSize size = cell->GetSize(); - // Because of the tree structure indent, here we should minus the width + // Because of the tree structure indent, here we should minus the width // of the cell for drawing size.x = wxMin( size.x + 2*PADDING_RIGHTLEFT, cell_rect.width - indent ); // size.y = wxMin( size.y, cell_rect.height ); @@ -1931,42 +1951,10 @@ void wxDataViewMainWindow::OnRenameTimer() wxSafeYield(); } - int xpos = 0; - unsigned int cols = GetOwner()->GetColumnCount(); - unsigned int i; - for (i = 0; i < cols; i++) - { - wxDataViewColumn *c = GetOwner()->GetColumnAt( i ); - if (c->IsHidden()) - continue; // skip it! - - if (c == m_currentCol) - break; - xpos += c->GetWidth(); - } - - // we have to take an expander column into account and compute its indentation - // to get the editor at the correct x position where the actual text is - int indent = 0; - if (!IsVirtualList() && GetOwner()->GetExpanderColumn() == m_currentCol) - { - wxDataViewTreeNode* node = GetTreeNodeByRow(m_currentRow); - indent = GetOwner()->GetIndent() * node->GetIndentLevel(); - indent = indent + m_lineHeight; - - if(!node->HasChildren()) - delete node; - } - - wxRect labelRect( xpos + indent, - GetLineStart( m_currentRow ), - m_currentCol->GetWidth() - indent, - GetLineHeight( m_currentRow ) ); + wxDataViewItem item = GetItemByRow( m_currentRow ); - GetOwner()->CalcScrolledPosition( labelRect.x, labelRect.y, - &labelRect.x, &labelRect.y); + wxRect labelRect = GetItemRect(item, m_currentCol); - wxDataViewItem item = GetItemByRow( m_currentRow ); m_currentCol->GetRenderer()->StartEditing( item, labelRect ); } @@ -2040,7 +2028,7 @@ bool Walker( wxDataViewTreeNode * node, DoJob & func ) bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item) { - if (!m_root) + if (IsVirtualList()) { m_count++; UpdateDisplay(); @@ -2078,14 +2066,15 @@ bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxData static void DestroyTreeHelper( wxDataViewTreeNode * node); bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent, - const wxDataViewItem& item) + const wxDataViewItem& item) { - if (!m_root) + if (IsVirtualList()) { m_count--; if( m_currentRow > GetRowCount() ) m_currentRow = m_count - 1; + // TODO: why empty the entire selection? m_selection.Empty(); UpdateDisplay(); @@ -2096,7 +2085,7 @@ bool wxDataViewMainWindow::ItemDeleted(const wxDataViewItem& parent, wxDataViewTreeNode * node = FindNode(parent); wxCHECK_MSG( node != NULL, false, "item not found" ); - wxCHECK_MSG( node->GetChildren().Index( item.GetID() ) != wxNOT_FOUND, + wxCHECK_MSG( node->GetChildren().Index( item.GetID() ) != wxNOT_FOUND, false, "item not found" ); int sub = -1; @@ -2592,18 +2581,20 @@ int wxDataViewMainWindow::GetLineStart( unsigned int row ) const if (column->IsHidden()) continue; // skip it! - if ((col != 0) && model->IsContainer(item) && !model->HasContainerColumns(item)) + if ((col != 0) && + model->IsContainer(item) && + !model->HasContainerColumns(item)) continue; // skip it! - const wxDataViewRenderer *renderer = column->GetRenderer(); wxVariant value; model->GetValue( value, item, column->GetModelColumn() ); - wxDataViewRenderer *renderer2 = const_cast(renderer); - renderer2->SetValue( value ); + + wxDataViewRenderer *renderer = + const_cast(column->GetRenderer()); + renderer->SetValue( value ); height = wxMax( height, renderer->GetSize().y ); } - start += height; } @@ -2628,14 +2619,14 @@ int wxDataViewMainWindow::GetLineAt( unsigned int y ) const unsigned int yy = 0; for (;;) { - const wxDataViewTreeNode* node = GetTreeNodeByRow(row); - if (!node) - { - // not really correct... - return row + ((y-yy) / m_lineHeight); - } + const wxDataViewTreeNode* node = GetTreeNodeByRow(row); + if (!node) + { + // not really correct... + return row + ((y-yy) / m_lineHeight); + } - wxDataViewItem item = node->GetItem(); + wxDataViewItem item = node->GetItem(); if (node && !node->HasChildren()) { @@ -2644,31 +2635,34 @@ int wxDataViewMainWindow::GetLineAt( unsigned int y ) const wxDELETE(node); } - unsigned int cols = GetOwner()->GetColumnCount(); - unsigned int col; - int height = m_lineHeight; - for (col = 0; col < cols; col++) - { + unsigned int cols = GetOwner()->GetColumnCount(); + unsigned int col; + int height = m_lineHeight; + for (col = 0; col < cols; col++) + { const wxDataViewColumn *column = GetOwner()->GetColumn(col); if (column->IsHidden()) continue; // skip it! - if ((col != 0) && model->IsContainer(item) && !model->HasContainerColumns(item)) + if ((col != 0) && + model->IsContainer(item) && + !model->HasContainerColumns(item)) continue; // skip it! - const wxDataViewRenderer *renderer = column->GetRenderer(); wxVariant value; model->GetValue( value, item, column->GetModelColumn() ); - wxDataViewRenderer *renderer2 = const_cast(renderer); - renderer2->SetValue( value ); + + wxDataViewRenderer *renderer = + const_cast(column->GetRenderer()); + renderer->SetValue( value ); height = wxMax( height, renderer->GetSize().y ); - } + } - yy += height; - if (y < yy) - return row; + yy += height; + if (y < yy) + return row; - row++; + row++; } } @@ -2703,14 +2697,17 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const if (column->IsHidden()) continue; // skip it! - if ((col != 0) && model->IsContainer(item) && !model->HasContainerColumns(item)) + if ((col != 0) && + model->IsContainer(item) && + !model->HasContainerColumns(item)) continue; // skip it! - const wxDataViewRenderer *renderer = column->GetRenderer(); wxVariant value; model->GetValue( value, item, column->GetModelColumn() ); - wxDataViewRenderer *renderer2 = const_cast(renderer); - renderer2->SetValue( value ); + + wxDataViewRenderer *renderer = + const_cast(column->GetRenderer()); + renderer->SetValue( value ); height = wxMax( height, renderer->GetSize().y ); } @@ -2725,7 +2722,7 @@ int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const class RowToItemJob: public DoJob { public: - RowToItemJob( unsigned int row , int current ) + RowToItemJob( unsigned int row , int current ) { this->row = row; this->current = current; } virtual ~RowToItemJob() {} @@ -2745,9 +2742,9 @@ public: } else { - // If the current has no child node, we can find the desired item of the row + // If the current has no child node, we can find the desired item of the row // number directly. - // This if can speed up finding in some case, and will has a very good effect + // This if can speed up finding in some case, and will has a very good effect // when it comes to list view if( node->GetNodes().GetCount() == 0) { @@ -2781,15 +2778,17 @@ private: wxDataViewItem wxDataViewMainWindow::GetItemByRow(unsigned int row) const { - if (!m_root) + if (IsVirtualList()) { - return wxDataViewItem( wxUIntToPtr(row) ); + return wxDataViewItem( wxUIntToPtr(row+1) ); } else { RowToItemJob job( row, -2 ); Walker( m_root , job ); - return job.GetResult(); + wxDataViewItem res = job.GetResult(); +// wxPrintf( "row %d, item %d\n", row, (int) res.GetID() ); + return res; } } @@ -2823,9 +2822,9 @@ public: { parent = node; - // If the current node has no children, we can find the desired item of the + // If the current node has no children, we can find the desired item of the // row number directly. - // This if can speed up finding in some case, and will have a very good + // This if can speed up finding in some case, and will have a very good // effect for list views. if( node->GetNodes().GetCount() == 0) { @@ -2873,7 +2872,7 @@ wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row) co return job.GetResult(); } -wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, +wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, const wxDataViewItem & item ) { wxWindow *parent = GetParent(); @@ -2905,20 +2904,42 @@ bool wxDataViewMainWindow::IsExpanded( unsigned int row ) const return node->IsOpen(); } +bool wxDataViewMainWindow::HasChildren( unsigned int row ) const +{ + if (IsVirtualList()) + return false; + + wxDataViewTreeNode * node = GetTreeNodeByRow(row); + if (!node) + return false; + + if (!node->HasChildren()) + { + delete node; + return false; + } + + return true; +} -void wxDataViewMainWindow::OnExpanding( unsigned int row ) +void wxDataViewMainWindow::Expand( unsigned int row ) { if (IsVirtualList()) return; wxDataViewTreeNode * node = GetTreeNodeByRow(row); - if( node != NULL ) + if (!node) + return; + + if (!node->HasChildren()) { - if( node->HasChildren()) - { - if( !node->IsOpen()) + delete node; + return; + } + + if (!node->IsOpen()) { - wxDataViewEvent e = + wxDataViewEvent e = SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, node->GetItem()); // Check if the user prevent expanding @@ -2955,23 +2976,9 @@ void wxDataViewMainWindow::OnExpanding( unsigned int row ) // Send the expanded event SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED,node->GetItem()); } - else - { -#if 0 - // Why should we select the next row here??? - SelectRow( row, false ); - SelectRow( row + 1, true ); - ChangeCurrentRow( row + 1 ); - SendSelectionChangedEvent( GetItemByRow(row+1)); -#endif - } - } - else - delete node; - } } -void wxDataViewMainWindow::OnCollapsing(unsigned int row) +void wxDataViewMainWindow::Collapse(unsigned int row) { if (IsVirtualList()) return; @@ -2979,16 +2986,16 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row) wxDataViewTreeNode *node = GetTreeNodeByRow(row); if (!node) return; - - if( !node->HasChildren()) + + if (!node->HasChildren()) { delete node; return; } - if( node->HasChildren() && node->IsOpen() ) + if (node->IsOpen()) { - wxDataViewEvent e = + wxDataViewEvent e = SendExpanderEvent(wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING,node->GetItem()); if( e.GetSkipped() ) return; @@ -3023,7 +3030,7 @@ void wxDataViewMainWindow::OnCollapsing(unsigned int row) { // if there were no selected items below our node we still need to "fix" the // selection list to adjust for the changing of the row indices. - // We actually do the opposite of what we are doing in OnExpanding(). + // We actually do the opposite of what we are doing in Expand(). for(unsigned i=0; iGetItem()); } - else - { - node = node->GetParent(); - if( node != NULL ) - { - int parent = GetRowByItem( node->GetItem() ); - if( parent >= 0 ) - { - SelectRow( row, false); - SelectRow(parent , true ); - ChangeCurrentRow( parent ); - SendSelectionChangedEvent( node->GetItem() ); - } - } - } } wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item ) @@ -3120,7 +3112,7 @@ wxDataViewTreeNode * wxDataViewMainWindow::FindNode( const wxDataViewItem & item return NULL; } -void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, +void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column ) { wxDataViewColumn *col = NULL; @@ -3145,31 +3137,74 @@ void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item item = GetItemByRow( GetLineAt( y ) ); } -wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, +wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ) { + int xpos = 0; + int width = 0; + + unsigned int cols = GetOwner()->GetColumnCount(); + // If column is null the loop will compute the combined width of all columns. + // Otherwise, it will compute the x position of the column we are looking for. + for (unsigned int i = 0; i < cols; i++) + { + wxDataViewColumn* col = GetOwner()->GetColumnAt( i ); + + if (col == column) + break; + + if (col->IsHidden()) + continue; // skip it! + + xpos += col->GetWidth(); + width += col->GetWidth(); + } + + if(column != 0) + { + // If we have a column, we need can get its width directly. + if(column->IsHidden()) + width = 0; + else + width = column->GetWidth(); + + } + else + { + // If we have no column, we reset the x position back to zero. + xpos = 0; + } + + // we have to take an expander column into account and compute its indentation + // to get the correct x position where the actual text is + int indent = 0; int row = GetRowByItem(item); - int y = GetLineStart( row ); - int h = GetLineHeight( m_lineHeight ); - int x = 0; - wxDataViewColumn *col = NULL; - for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ ) + if (!IsVirtualList() && (column == 0 || GetOwner()->GetExpanderColumn() == column) ) { - col = GetOwner()->GetColumnAt( i ); - x += col->GetWidth(); - if( GetOwner()->GetColumnAt(i+1) == column ) - break; + wxDataViewTreeNode* node = GetTreeNodeByRow(row); + indent = GetOwner()->GetIndent() * node->GetIndentLevel(); + indent = indent + m_lineHeight; // use m_lineHeight as the width of the expander + + if(!node->HasChildren()) + delete node; } - int w = col->GetWidth(); - m_owner->CalcScrolledPosition( x, y, &x, &y ); - return wxRect(x, y, w, h); + + wxRect itemRect( xpos + indent, + GetLineStart( row ), + width - indent, + GetLineHeight( row ) ); + + GetOwner()->CalcScrolledPosition( itemRect.x, itemRect.y, + &itemRect.x, &itemRect.y ); + + return itemRect; } int wxDataViewMainWindow::RecalculateCount() { - if (!m_root) + if (IsVirtualList()) { - wxDataViewIndexListModel *list_model = + wxDataViewIndexListModel *list_model = (wxDataViewIndexListModel*) GetOwner()->GetModel(); #ifndef __WXMAC__ return list_model->GetLastIndex() + 1; @@ -3240,9 +3275,9 @@ int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) const if( model == NULL ) return -1; - if (!m_root) + if (IsVirtualList()) { - return wxPtrToUInt( item.GetID() ); + return wxPtrToUInt( item.GetID() ) -1; } else { @@ -3269,7 +3304,7 @@ int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) const } } -static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, +static void BuildTreeHelper( wxDataViewModel * model, wxDataViewItem & item, wxDataViewTreeNode * node) { if( !model->IsContainer( item ) ) @@ -3362,11 +3397,10 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) switch ( event.GetKeyCode() ) { case WXK_RETURN: - { - if (m_currentRow >= 0) { wxWindow *parent = GetParent(); - wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, parent->GetId()); + wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, + parent->GetId()); le.SetItem( GetItemByRow(m_currentRow) ); le.SetEventObject(parent); le.SetModel(GetOwner()->GetModel()); @@ -3374,7 +3408,7 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) parent->GetEventHandler()->ProcessEvent(le); } break; - } + case WXK_UP: if ( m_currentRow > 0 ) OnArrowChar( m_currentRow - 1, event ); @@ -3386,16 +3420,62 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) break; // Add the process for tree expanding/collapsing case WXK_LEFT: - OnCollapsing(m_currentRow); - break; - case WXK_RIGHT: - OnExpanding( m_currentRow); - break; + { + if (IsVirtualList()) + break; + + wxDataViewTreeNode* node = GetTreeNodeByRow(m_currentRow); + if (!node) + break; + + if (node->HasChildren() && node->IsOpen()) + { + Collapse(m_currentRow); + } + else // if the node is already closed we move the selection to its parent + { + wxDataViewTreeNode *parent_node = node->GetParent(); + + if(!node->HasChildren()) + delete node; + + if (parent_node) + { + int parent = GetRowByItem( parent_node->GetItem() ); + if ( parent >= 0 ) + { + unsigned int row = m_currentRow; + SelectRow( row, false); + SelectRow( parent, true ); + ChangeCurrentRow( parent ); + GetOwner()->EnsureVisible( parent, -1 ); + SendSelectionChangedEvent( parent_node->GetItem() ); + } + } + } + break; + } + case WXK_RIGHT: + { + if (!IsExpanded( m_currentRow )) + Expand( m_currentRow ); + else + { + unsigned int row = m_currentRow; + SelectRow( row, false ); + SelectRow( row + 1, true ); + ChangeCurrentRow( row + 1 ); + GetOwner()->EnsureVisible( row + 1, -1 ); + SendSelectionChangedEvent( GetItemByRow(row+1) ); + } + break; + } case WXK_END: + { if (!IsEmpty()) OnArrowChar( GetRowCount() - 1, event ); break; - + } case WXK_HOME: if (!IsEmpty()) OnArrowChar( 0, event ); @@ -3424,6 +3504,16 @@ void wxDataViewMainWindow::OnChar( wxKeyEvent &event ) } break; + case WXK_F2: + { + if(m_selection.size() == 1) + { + // TODO: we need to revise that when we have a concept for a 'current column' + GetOwner()->StartEditor(GetItemByRow(m_selection[0]), 0); + } + } + break; + default: event.Skip(); } @@ -3535,7 +3625,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) if (event.LeftIsDown()) { - m_owner->CalcUnscrolledPosition( m_dragStart.x, m_dragStart.y, + m_owner->CalcUnscrolledPosition( m_dragStart.x, m_dragStart.y, &m_dragStart.x, &m_dragStart.y ); unsigned int drag_item_row = GetLineAt( m_dragStart.y ); wxDataViewItem item = GetItemByRow( drag_item_row ); @@ -3630,7 +3720,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) ); } - // If the user click the expander, we do not do editing even if the column + // If the user click the expander, we do not do editing even if the column // with expander are editable if (m_lastOnSame && !ignore_other_columns) { @@ -3667,7 +3757,9 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) SelectRow(m_currentRow,true); SendSelectionChangedEvent(GetItemByRow( m_currentRow ) ); } - + } + else if (event.RightUp()) + { wxVariant value; model->GetValue( value, item, col->GetModelColumn() ); wxWindow *parent = GetParent(); @@ -3686,13 +3778,13 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) { wxDataViewTreeNode* node = GetTreeNodeByRow(current); - // hoverOverExpander being true tells us that our node must be + // hoverOverExpander being true tells us that our node must be // valid and have children. // So we don't need any extra checks. if( node->IsOpen() ) - OnCollapsing(current); + Collapse(current); else - OnExpanding(current); + Expand(current); } else if ((event.LeftDown() || simulateClick) && !hoverOverExpander) { @@ -3771,7 +3863,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event ) cell->SetValue( value ); wxRect cell_rect( xpos, GetLineStart( current ), col->GetWidth(), GetLineHeight( current ) ); - /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, + /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn()); } } @@ -4286,13 +4378,13 @@ void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataVie } -void wxDataViewCtrl::HitTest( const wxPoint & point, wxDataViewItem & item, +void wxDataViewCtrl::HitTest( const wxPoint & point, wxDataViewItem & item, wxDataViewColumn* &column ) const { m_clientArea->HitTest(point, item, column); } -wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem & item, +wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ) const { return m_clientArea->GetItemRect(item, column); @@ -4318,7 +4410,6 @@ void wxDataViewCtrl::Expand( const wxDataViewItem & item ) void wxDataViewCtrl::Collapse( const wxDataViewItem & item ) { int row = m_clientArea->GetRowByItem( item ); - wxPrintf( "row %d\n", row ); if (row != -1) m_clientArea->Collapse(row); } @@ -4331,8 +4422,17 @@ bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const return false; } -#endif - // !wxUSE_GENERICDATAVIEWCTRL +void wxDataViewCtrl::StartEditor( const wxDataViewItem & item, unsigned int column ) +{ + wxDataViewColumn* col = GetColumn( column ); + if (!col) + return; -#endif - // wxUSE_DATAVIEWCTRL + wxRect itemRect = GetItemRect(item, col); + wxDataViewRenderer* renderer = col->GetRenderer(); + renderer->StartEditing(item, itemRect); +} + +#endif // !wxUSE_GENERICDATAVIEWCTRL + +#endif // wxUSE_DATAVIEWCTRL