#include "wx/gtk/dcclient.h"
#include "wx/gtk/private/gdkconv.h"
+#include "wx/gtk/private/list.h"
using namespace wxGTKImpl;
class wxGtkDataViewModelNotifier;
wxDECLARE_NO_COPY_CLASS(wxGtkTreePath);
};
+// ----------------------------------------------------------------------------
+// wxGtkTreePathList: self-destroying list of GtkTreePath objects.
+// ----------------------------------------------------------------------------
+
+class wxGtkTreePathList : public wxGtkList
+{
+public:
+ // Ctor takes ownership of the list.
+ explicit wxGtkTreePathList(GList* list)
+ : wxGtkList(list)
+ {
+ }
+
+ ~wxGtkTreePathList()
+ {
+ // Delete the list contents, wxGtkList will delete the list itself.
+ g_list_foreach(m_list, (GFunc)gtk_tree_path_free, NULL);
+ }
+};
+
// ----------------------------------------------------------------------------
// wxGtkTreeSelectionLock: prevent selection from changing during the
// lifetime of this object
static
int LINKAGEMODE wxGtkTreeModelChildCmp( void** id1, void** id2 )
{
- int ret = gs_internal->GetDataViewModel()->Compare( *id1, *id2,
+ int ret = gs_internal->GetDataViewModel()->Compare( wxDataViewItem(*id1), wxDataViewItem(*id2),
gs_internal->GetSortColumn(), (gs_internal->GetSortOrder() == GTK_SORT_ASCENDING) );
return ret;
return ret;
}
-void wxDataViewRenderer::GtkUpdateAlignment()
+void wxDataViewRenderer::GtkApplyAlignment(GtkCellRenderer *renderer)
{
int align = m_alignment;
GValue gvalue = { 0, };
g_value_init( &gvalue, G_TYPE_FLOAT );
g_value_set_float( &gvalue, xalign );
- g_object_set_property( G_OBJECT(m_renderer), "xalign", &gvalue );
+ g_object_set_property( G_OBJECT(renderer), "xalign", &gvalue );
g_value_unset( &gvalue );
// vertical alignment:
GValue gvalue2 = { 0, };
g_value_init( &gvalue2, G_TYPE_FLOAT );
g_value_set_float( &gvalue2, yalign );
- g_object_set_property( G_OBJECT(m_renderer), "yalign", &gvalue2 );
+ g_object_set_property( G_OBJECT(renderer), "yalign", &gvalue2 );
g_value_unset( &gvalue2 );
}
Init(mode, align);
}
+void wxDataViewCustomRenderer::GtkInitTextRenderer()
+{
+ m_text_renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
+ g_object_ref_sink(m_text_renderer);
+
+ GtkApplyAlignment(GTK_CELL_RENDERER(m_text_renderer));
+}
+
GtkCellRendererText *wxDataViewCustomRenderer::GtkGetTextRenderer() const
{
if ( !m_text_renderer )
{
// we create it on demand so need to do it even from a const function
- const_cast<wxDataViewCustomRenderer *>(this)->
- m_text_renderer = GTK_CELL_RENDERER_TEXT(gtk_cell_renderer_text_new());
- g_object_ref_sink(m_text_renderer);
+ const_cast<wxDataViewCustomRenderer *>(this)->GtkInitTextRenderer();
}
return m_text_renderer;
{
m_renderer = (GtkCellRenderer*) gtk_cell_renderer_progress_new();
- GValue gvalue = { 0, };
- g_value_init( &gvalue, G_TYPE_STRING );
-
- g_value_set_string( &gvalue, wxGTK_CONV_FONT( m_label, GetOwner()->GetOwner()->GetFont() ) );
- g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue );
- g_value_unset( &gvalue );
-
SetMode(mode);
SetAlignment(align);
+
+#if !wxUSE_UNICODE
+ // We can't initialize the renderer just yet because we don't have the
+ // pointer to the column that uses this renderer yet and so attempt to
+ // dereference GetOwner() to get the font that is used as a source of
+ // encoding in multibyte-to-Unicode conversion in GTKSetLabel() in
+ // non-Unicode builds would crash. So simply remember to do it later.
+ if ( !m_label.empty() )
+ m_needsToSetLabel = true;
+ else
+#endif // !wxUSE_UNICODE
+ GTKSetLabel();
}
else
#endif
{
}
+void wxDataViewProgressRenderer::GTKSetLabel()
+{
+ GValue gvalue = { 0, };
+ g_value_init( &gvalue, G_TYPE_STRING );
+
+ // Take care to not use GetOwner() here if the label is empty, we can be
+ // called from ctor when GetOwner() is still NULL in this case.
+ g_value_set_string( &gvalue,
+ m_label.empty() ? ""
+ : wxGTK_CONV_FONT(m_label,
+ GetOwner()->GetOwner()->GetFont())
+ );
+ g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue );
+ g_value_unset( &gvalue );
+
+#if !wxUSE_UNICODE
+ m_needsToSetLabel = false;
+#endif // !wxUSE_UNICODE
+}
+
bool wxDataViewProgressRenderer::SetValue( const wxVariant &value )
{
#ifdef __WXGTK26__
if (!gtk_check_version(2,6,0))
{
+#if !wxUSE_UNICODE
+ if ( m_needsToSetLabel )
+ GTKSetLabel();
+#endif // !wxUSE_UNICODE
+
gint tmp = (long) value;
GValue gvalue = { 0, };
g_value_init( &gvalue, G_TYPE_INT );
static
int LINKAGEMODE wxGtkTreeModelChildPtrCmp( void*** data1, void*** data2 )
{
- return gs_internal->GetDataViewModel()->Compare( **data1, **data2,
+ return gs_internal->GetDataViewModel()->Compare( wxDataViewItem(**data1), wxDataViewItem(**data2),
gs_internal->GetSortColumn(), (gs_internal->GetSortOrder() == GTK_SORT_ASCENDING) );
}
GtkTreePath *path )
{
delete m_dragDataObject;
+ m_dragDataObject = NULL;
wxDataViewItem item(GetOwner()->GTKPathToItem(path));
if ( !item )
{
GtkTreeViewColumn *gtk_column = GTK_TREE_VIEW_COLUMN(column->GetGtkHandle());
- GList *list = gtk_tree_view_get_columns( GTK_TREE_VIEW(m_treeview) );
+ wxGtkList list(gtk_tree_view_get_columns(GTK_TREE_VIEW(m_treeview)));
- gint pos = g_list_index( list, (gconstpointer) gtk_column );
-
- g_list_free( list );
-
- return pos;
+ return g_list_index( list, (gconstpointer) gtk_column );
}
wxDataViewColumn *wxDataViewCtrl::GetSortingColumn() const
if (HasFlag(wxDV_MULTIPLE))
{
GtkTreeModel *model;
- GList *list = gtk_tree_selection_get_selected_rows( selection, &model );
+ wxGtkTreePathList list(gtk_tree_selection_get_selected_rows(selection, &model));
int count = 0;
- while (list)
+ for ( GList* current = list; current; current = g_list_next(current) )
{
GtkTreePath *path = (GtkTreePath*) list->data;
sel.Add(GTKPathToItem(path));
-
- list = g_list_next( list );
count++;
}
- // delete list
- g_list_foreach( list, (GFunc) gtk_tree_path_free, NULL );
- g_list_free( list );
-
return count;
}
else