bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item );
bool ItemChanged( const wxDataViewItem &item );
- bool ValueChanged( const wxDataViewItem &item, unsigned int col );
+ bool ValueChanged( const wxDataViewItem &item, unsigned int model_column );
bool Cleared();
bool BeforeReset();
bool AfterReset();
int GetIndexOf( const wxDataViewItem &parent, const wxDataViewItem &item );
virtual void OnInternalIdle();
-
+
protected:
void InitTree();
void ScheduleRefresh();
-
+
wxGtkTreeModelNode *FindNode( const wxDataViewItem &item );
wxGtkTreeModelNode *FindNode( GtkTreeIter *iter );
wxGtkTreeModelNode *FindParentNode( const wxDataViewItem &item );
GtkTargetEntry m_dropTargetTargetEntry;
wxCharBuffer m_dropTargetTargetEntryTarget;
wxDataObject *m_dropDataObject;
-
+
wxGtkDataViewModelNotifier *m_notifier;
-
+
bool m_dirty;
};
virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
virtual bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item );
virtual bool ItemChanged( const wxDataViewItem &item );
- virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col );
+ virtual bool ValueChanged( const wxDataViewItem &item, unsigned int model_column );
virtual bool Cleared();
virtual void Resort();
virtual bool BeforeReset();
virtual bool AfterReset();
-
+
void UpdateLastCount();
private:
bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem &item )
{
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
-
+
GtkTreeIter iter;
iter.stamp = wxgtk_model->stamp;
iter.user_data = (gpointer) item.GetID();
return true;
}
-bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsigned int model_col )
+bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsigned int model_column )
{
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
wxDataViewCtrl *ctrl = m_internal->GetOwner();
-
+
// This adds GTK+'s missing MVC logic for ValueChanged
unsigned int index;
for (index = 0; index < ctrl->GetColumnCount(); index++)
{
wxDataViewColumn *column = ctrl->GetColumn( index );
- if (column->GetModelColumn() == model_col)
+ if (column->GetModelColumn() == model_column)
{
GtkTreeView *widget = GTK_TREE_VIEW(ctrl->GtkGetTreeView());
GtkTreeViewColumn *gcolumn = GTK_TREE_VIEW_COLUMN(column->GetGtkHandle());
gtk_widget_queue_draw_area( GTK_WIDGET(widget),
cell_area.x - xdiff, ydiff + cell_area.y, cell_area.width, cell_area.height );
- m_internal->ValueChanged( item, model_col );
+ m_internal->ValueChanged( item, model_column );
return true;
}
{
GtkWidget *treeview = m_internal->GetOwner()->GtkGetTreeView();
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
-
- m_internal->Cleared();
-
+
+ m_internal->Cleared();
+
gtk_tree_view_set_model( GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(wxgtk_model) );
-
+
return true;
}
bool wxGtkDataViewModelNotifier::Cleared()
{
GtkWxTreeModel *wxgtk_model = m_internal->GetGtkModel();
-
+
// There is no call to tell the model that everything
// has been deleted so call row_deleted() for every
// child of root...
int count = m_internal->iter_n_children( NULL ); // number of children of root
-
+
GtkTreePath *path = gtk_tree_path_new_first(); // points to root
int i;
for (i = 0; i < count; i++)
gtk_tree_model_row_deleted( GTK_TREE_MODEL(wxgtk_model), path );
-
+
gtk_tree_path_free( path );
-
+
m_internal->Cleared();
return true;
wxDataViewRendererBase( varianttype, mode, align )
{
m_renderer = NULL;
+ m_mode = mode;
// we haven't changed them yet
m_usingDefaultAttrs = true;
wxDataViewChoiceRenderer( choices, mode, alignment )
{
}
-
+
void wxDataViewChoiceByIndexRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str)
{
wxVariant value( (long) GetChoices().Index( str ) );
wxVariant string_value = GetChoice( value.GetLong() );
return wxDataViewChoiceRenderer::SetValue( string_value );
}
-
+
bool wxDataViewChoiceByIndexRenderer::GetValue( wxVariant &value ) const
{
wxVariant string_value;
if (!wxDataViewChoiceRenderer::GetValue( string_value ))
return false;
-
+
value = (long) GetChoices().Index( string_value.GetString() );
return true;
}
cell->SetValue( value );
+ // deal with disabled items
+ bool enabled = wx_model->IsEnabled( item, cell->GetOwner()->GetModelColumn() );
+
+ // a) this sets the appearance to disabled grey
+ GValue gvalue = { 0, };
+ g_value_init( &gvalue, G_TYPE_BOOLEAN );
+ g_value_set_boolean( &gvalue, enabled );
+ g_object_set_property( G_OBJECT(renderer), "sensitive", &gvalue );
+ g_value_unset( &gvalue );
+
+ // b) this actually disables the control/renderer
+ if (enabled)
+ cell->SetMode( cell->GtkGetMode() );
+ else
+ cell->SetMode( wxDATAVIEW_CELL_INERT );
+
// deal with attributes: if the renderer doesn't support them at all, we
// don't even need to query the model for them
}
// else: no custom attributes specified and we're already using the default
// ones -- nothing to do
+
}
} // extern "C"
{
if (m_isConnected)
return;
-
+
if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview))
{
GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(m_column);
G_CALLBACK (gtk_dataview_header_button_press_callback), this);
// otherwise the event will be blocked by GTK+
- gtk_tree_view_column_set_clickable( column, TRUE );
-
+ gtk_tree_view_column_set_clickable( column, TRUE );
+
m_isConnected = true;
}
}
void wxDataViewColumn::SetWidth( int width )
{
- if (width < 0)
+ if ( width == wxCOL_WIDTH_AUTOSIZE )
{
-#if 1
- gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column), GTK_TREE_VIEW_COLUMN_FIXED );
-
- // TODO find a better calculation
- gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column), wxDVC_DEFAULT_WIDTH );
-#else
- // this is unpractical for large numbers of items and disables
- // user resizing, which is totally unexpected
+ // NB: this disables user resizing
gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE );
-#endif
}
else
{
- gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column), GTK_TREE_VIEW_COLUMN_FIXED );
+ if ( width == wxCOL_WIDTH_DEFAULT )
+ {
+ // TODO find a better calculation
+ width = wxDVC_DEFAULT_WIDTH;
+ }
+ gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column), GTK_TREE_VIEW_COLUMN_FIXED );
gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column), width );
}
}
{
m_owner = owner;
m_wx_model = wx_model;
-
+
m_gtk_model = NULL;
m_root = NULL;
m_sort_order = GTK_SORT_ASCENDING;
m_dropDataObject = NULL;
m_dirty = false;
-
+
m_gtk_model = wxgtk_tree_model_new();
m_gtk_model->internal = this;
if (!m_wx_model->IsVirtualListModel())
InitTree();
-
+
gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->GtkGetTreeView()), GTK_TREE_MODEL(m_gtk_model) );
}
{
m_wx_model->RemoveNotifier( m_notifier );
- // remove the model from the GtkTreeView before it gets destroyed
+ // remove the model from the GtkTreeView before it gets destroyed
gtk_tree_view_set_model( GTK_TREE_VIEW( m_owner->GtkGetTreeView() ), NULL );
g_object_unref( m_gtk_model );
{
wxDataViewItemArray children;
unsigned int count = m_wx_model->GetChildren( node->GetItem(), children );
-
+
unsigned int pos;
for (pos = 0; pos < count; pos++)
{
event.SetEventObject( m_owner );
event.SetItem( item );
event.SetModel( m_wx_model );
+ gint x, y;
+ gtk_widget_get_pointer(m_owner->GtkGetTreeView(), &x, &y);
+ event.SetPosition(x, y);
if (!m_owner->HandleWindowEvent( event ))
return FALSE;
delete m_root;
m_root = NULL;
}
-
+
InitTree();
-
+
ScheduleRefresh();
-
+
return true;
}
{
if (!m_wx_model->IsVirtualListModel())
m_root->Resort();
-
+
ScheduleRefresh();
}
}
ScheduleRefresh();
-
+
return true;
}
}
ScheduleRefresh();
-
+
return true;
}
return true;
}
-bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem &item, unsigned int col )
+bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem &item, unsigned int view_column )
{
wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, m_owner->GetId() );
event.SetEventObject( m_owner );
event.SetModel( m_owner->GetModel() );
- event.SetColumn( col );
- event.SetDataViewColumn( GetOwner()->GetColumn(col) );
+ event.SetColumn( view_column );
+ event.SetDataViewColumn( GetOwner()->GetColumn(view_column) );
event.SetItem( item );
m_owner->HandleWindowEvent( event );
while (node)
{
int pos = node->GetChildren().Index( id );
-
+
gtk_tree_path_prepend_index( retval, pos );
id = node->GetItem().GetID();
void wxDataViewCtrl::OnInternalIdle()
{
wxWindow::OnInternalIdle();
-
+
m_internal->OnInternalIdle();
unsigned int cols = GetColumnCount();
wxDataViewColumn *col = GetColumn( i );
col->OnInternalIdle();
}
-
+
if (m_ensureVisibleDefered.IsOk())
{
ExpandAncestors(m_ensureVisibleDefered);
gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(m_treeview), path, NULL, false, 0.0, 0.0 );
}
-void wxDataViewCtrl::HitTest(const wxPoint& WXUNUSED(point),
+void wxDataViewCtrl::HitTest(const wxPoint& point,
wxDataViewItem& item,
wxDataViewColumn *& column) const
{
- item = wxDataViewItem(0);
- column = NULL;
+ // gtk_tree_view_get_dest_row_at_pos() is the right one. But it does not tell the column.
+ // gtk_tree_view_get_path_at_pos() is the wrong function. It doesn't mind the header but returns column.
+ // See http://mail.gnome.org/archives/gtkmm-list/2005-January/msg00080.html
+ // So we have to use both of them.
+ // Friedrich Haase 2010-9-20
+ wxGtkTreePath path, pathScratch;
+ GtkTreeViewColumn* GtkColumn = NULL;
+ GtkTreeViewDropPosition pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER;
+ gint cell_x = 0;
+ gint cell_y = 0;
+
+ // cannot directly call GtkGetTreeView(), HitTest is const and so is this pointer
+ wxDataViewCtrl* ctrl = (wxDataViewCtrl*)this; // ugly workaround, ctrl is NOT const
+ GtkTreeView* treeView = GTK_TREE_VIEW(ctrl->GtkGetTreeView());
+
+ // is there possibly a better suited function to get the column?
+ gtk_tree_view_get_path_at_pos( // and this is the wrong call but it delivers the column
+ treeView,
+ (int) point.x, (int) point.y,
+ pathScratch.ByRef(),
+ &GtkColumn, // here we get the GtkColumn
+ &cell_x,
+ &cell_y );
+
+ if ( GtkColumn != NULL )
+ {
+ // we got GTK column
+ // the right call now which takes the header into account
+ gtk_tree_view_get_dest_row_at_pos( treeView, (int) point.x, (int) point.y, path.ByRef(), &pos);
+
+ if (path)
+ item = wxDataViewItem(GTKPathToItem(path));
+ // else we got a GTK column but the position is not over an item, e.g. below last item
+ for ( unsigned int i=0, cols=GetColumnCount(); i<cols; ++i ) // search the wx column
+ {
+ wxDataViewColumn* col = GetColumn(i);
+ if ( GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()) == GtkColumn )
+ {
+ column = col; // here we get the wx column
+ break;
+ }
+ }
+ }
+ // else no column and thus no item, both null
}
wxRect