X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/47583ac10327986031e89c13b75238fc6f66381c..0738b901b17340f09766524b8d9d79e9ed1268e7:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index fead2fd22f..a35bbbd9f8 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -1553,10 +1553,18 @@ wxDataViewRenderer::wxDataViewRenderer( const wxString &varianttype, wxDataViewC { m_renderer = NULL; + // we haven't changed them yet + m_usingDefaultAttrs = true; + // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor, // after the m_renderer pointer has been initialized } +void wxDataViewRenderer::GtkPackIntoColumn(GtkTreeViewColumn *column) +{ + gtk_tree_view_column_pack_end( column, m_renderer, TRUE /* expand */); +} + void wxDataViewRenderer::GtkInitHandlers() { if (!gtk_check_version(2,6,0)) @@ -1683,37 +1691,76 @@ int wxDataViewRenderer::GetAlignment() const return m_alignment; } -// --------------------------------------------------------- -// wxDataViewTextRenderer -// --------------------------------------------------------- +void wxDataViewRenderer::EnableEllipsize(wxEllipsizeMode mode) +{ + if ( gtk_check_version(2, 6, 0) != NULL ) + return; -extern "C" { -static void wxGtkTextRendererEditedCallback( GtkCellRendererText *renderer, - gchar *arg1, gchar *arg2, gpointer user_data ); + // we use the same values in wxEllipsizeMode as PangoEllipsizeMode so we + // can just cast between them + GValue gvalue = { 0, }; + g_value_init( &gvalue, PANGO_TYPE_ELLIPSIZE_MODE ); + g_value_set_enum( &gvalue, static_cast(mode) ); + g_object_set_property( G_OBJECT(m_renderer), "ellipsize", &gvalue ); + g_value_unset( &gvalue ); } -static void wxGtkTextRendererEditedCallback( GtkCellRendererText *WXUNUSED(renderer), - gchar *arg1, gchar *arg2, gpointer user_data ) +wxEllipsizeMode wxDataViewRenderer::GetEllipsizeMode() const { - wxDataViewRenderer *cell = (wxDataViewRenderer*) user_data; + if ( gtk_check_version(2, 6, 0) != NULL ) + return wxELLIPSIZE_NONE; - wxString tmp = wxGTK_CONV_BACK_FONT(arg2, cell->GetOwner()->GetOwner()->GetFont()); - wxVariant value = tmp; - if (!cell->Validate( value )) - return; + GValue gvalue = { 0, }; + g_value_init( &gvalue, PANGO_TYPE_ELLIPSIZE_MODE ); + g_object_get_property( G_OBJECT(m_renderer), "ellipsize", &gvalue ); + wxEllipsizeMode + mode = static_cast(g_value_get_enum( &gvalue )); + g_value_unset( &gvalue ); - wxDataViewModel *model = cell->GetOwner()->GetOwner()->GetModel(); + return mode; +} + +void +wxDataViewRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str) +{ + wxVariant value(str); + if (!Validate( value )) + return; - GtkTreePath *path = gtk_tree_path_new_from_string( arg1 ); + GtkTreePath *path = gtk_tree_path_new_from_string( itempath ); GtkTreeIter iter; - cell->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, path ); + GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, path ); wxDataViewItem item( (void*) iter.user_data );; gtk_tree_path_free( path ); - unsigned int model_col = cell->GetOwner()->GetModelColumn(); + GtkOnCellChanged(value, item, GetOwner()->GetModelColumn()); +} + +void +wxDataViewRenderer::GtkOnCellChanged(const wxVariant& value, + const wxDataViewItem& item, + unsigned col) +{ + wxDataViewModel *model = GetOwner()->GetOwner()->GetModel(); + model->ChangeValue( value, item, col ); +} + +// --------------------------------------------------------- +// wxDataViewTextRenderer +// --------------------------------------------------------- + +extern "C" +{ + +static void wxGtkTextRendererEditedCallback( GtkCellRendererText *WXUNUSED(renderer), + gchar *arg1, gchar *arg2, gpointer user_data ) +{ + wxDataViewRenderer *cell = (wxDataViewRenderer*) user_data; + + cell->GtkOnTextEdited(arg1, wxGTK_CONV_BACK_FONT( + arg2, cell->GetOwner()->GetOwner()->GetFont())); +} - model->SetValue( value, item, model_col ); - model->ValueChanged( item, model_col ); } IMPLEMENT_CLASS(wxDataViewTextRenderer, wxDataViewRenderer) @@ -1743,29 +1790,25 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxD SetAlignment(align); } -bool wxDataViewTextRenderer::SetValue( const wxVariant &value ) +bool wxDataViewTextRenderer::SetTextValue(const wxString& str) { - wxString tmp = value; - GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_STRING ); - g_value_set_string( &gvalue, wxGTK_CONV_FONT( tmp, GetOwner()->GetOwner()->GetFont() ) ); + g_value_set_string( &gvalue, wxGTK_CONV_FONT( str, GetOwner()->GetOwner()->GetFont() ) ); g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue ); g_value_unset( &gvalue ); return true; } -bool wxDataViewTextRenderer::GetValue( wxVariant &value ) const +bool wxDataViewTextRenderer::GetTextValue(wxString& str) const { GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_STRING ); g_object_get_property( G_OBJECT(m_renderer), "text", &gvalue ); - wxString tmp = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast(this)->GetOwner()->GetOwner()->GetFont() ); + str = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast(this)->GetOwner()->GetOwner()->GetFont() ); g_value_unset( &gvalue ); - value = tmp; - return true; } @@ -1794,13 +1837,28 @@ void wxDataViewTextRenderer::SetAlignment( int align ) // wxDataViewBitmapRenderer // --------------------------------------------------------- +namespace +{ + +// set "pixbuf" property on the given renderer +void SetPixbufProp(GtkCellRenderer *renderer, GdkPixbuf *pixbuf) +{ + GValue gvalue = { 0, }; + g_value_init( &gvalue, G_TYPE_OBJECT ); + g_value_set_object( &gvalue, pixbuf ); + g_object_set_property( G_OBJECT(renderer), "pixbuf", &gvalue ); + g_value_unset( &gvalue ); +} + +} // anonymous namespace + IMPLEMENT_CLASS(wxDataViewBitmapRenderer, wxDataViewRenderer) wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : wxDataViewRenderer( varianttype, mode, align ) { - m_renderer = (GtkCellRenderer*) gtk_cell_renderer_pixbuf_new(); + m_renderer = gtk_cell_renderer_pixbuf_new(); SetMode(mode); SetAlignment(align); @@ -1813,38 +1871,23 @@ bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value ) wxBitmap bitmap; bitmap << value; - // This may create a Pixbuf representation in the - // wxBitmap object (and it will stay there) - GdkPixbuf *pixbuf = bitmap.GetPixbuf(); - - GValue gvalue = { 0, }; - g_value_init( &gvalue, G_TYPE_OBJECT ); - g_value_set_object( &gvalue, pixbuf ); - g_object_set_property( G_OBJECT(m_renderer), "pixbuf", &gvalue ); - g_value_unset( &gvalue ); - - return true; + // GetPixbuf() may create a Pixbuf representation in the wxBitmap + // object (and it will stay there and remain owned by wxBitmap) + SetPixbufProp(m_renderer, bitmap.GetPixbuf()); } - - if (value.GetType() == wxT("wxIcon")) + else if (value.GetType() == wxT("wxIcon")) { - wxIcon bitmap; - bitmap << value; - - // This may create a Pixbuf representation in the - // wxBitmap object (and it will stay there) - GdkPixbuf *pixbuf = bitmap.GetPixbuf(); + wxIcon icon; + icon << value; - GValue gvalue = { 0, }; - g_value_init( &gvalue, G_TYPE_OBJECT ); - g_value_set_object( &gvalue, pixbuf ); - g_object_set_property( G_OBJECT(m_renderer), "pixbuf", &gvalue ); - g_value_unset( &gvalue ); - - return true; + SetPixbufProp(m_renderer, icon.GetPixbuf()); + } + else + { + return false; } - return false; + return true; } bool wxDataViewBitmapRenderer::GetValue( wxVariant &WXUNUSED(value) ) const @@ -1889,8 +1932,7 @@ static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle *renderer, unsigned int model_col = cell->GetOwner()->GetModelColumn(); - model->SetValue( value, item, model_col ); - model->ValueChanged( item, model_col ); + model->ChangeValue( value, item, model_col ); } IMPLEMENT_CLASS(wxDataViewToggleRenderer, wxDataViewRenderer) @@ -2327,10 +2369,7 @@ END_EVENT_TABLE() void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event ) { - wxDateTime date = event.GetDate(); - wxVariant value = date; - m_model->SetValue( value, m_item, m_col ); - m_model->ValueChanged( m_item, m_col ); + m_model->ChangeValue( event.GetDate(), m_item, m_col ); DismissAndNotify(); } @@ -2396,67 +2435,63 @@ bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewModel *m IMPLEMENT_CLASS(wxDataViewIconTextRenderer, wxDataViewCustomRenderer) -wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( - const wxString &varianttype, wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) +wxDataViewIconTextRenderer::wxDataViewIconTextRenderer + ( + const wxString &varianttype, + wxDataViewCellMode mode, + int align + ) + : wxDataViewTextRenderer(varianttype, mode, align) { - SetMode(mode); - SetAlignment(align); + m_rendererIcon = gtk_cell_renderer_pixbuf_new(); } wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() { } -bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) +void wxDataViewIconTextRenderer::GtkPackIntoColumn(GtkTreeViewColumn *column) { - m_value << value; - return true; -} + // add the icon renderer first + gtk_tree_view_column_pack_start(column, m_rendererIcon, FALSE /* !expand */); -bool wxDataViewIconTextRenderer::GetValue( wxVariant &WXUNUSED(value) ) const -{ - return false; + // add the text renderer too + wxDataViewRenderer::GtkPackIntoColumn(column); } -bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state ) +bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) { - const wxIcon &icon = m_value.GetIcon(); - int offset = 0; - if (icon.IsOk()) - { - int yoffset = wxMax( 0, (cell.height - icon.GetHeight()) / 2 ); - dc->DrawIcon( icon, cell.x, cell.y + yoffset ); - offset = icon.GetWidth() + 4; - } + m_value << value; - RenderText( m_value.GetText(), offset, cell, dc, state ); + SetTextValue(m_value.GetText()); + SetPixbufProp(m_rendererIcon, m_value.GetIcon().GetPixbuf()); return true; } -wxSize wxDataViewIconTextRenderer::GetSize() const +bool wxDataViewIconTextRenderer::GetValue(wxVariant& value) const { - wxSize size; - if (m_value.GetIcon().IsOk()) - size.x = 4 + m_value.GetIcon().GetWidth(); - wxCoord x,y,d; - GetView()->GetTextExtent( m_value.GetText(), &x, &y, &d ); - size.x += x; - size.y = y+d; - return size; -} + wxString str; + if ( !GetTextValue(str) ) + return false; -wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl( - wxWindow *WXUNUSED(parent), wxRect WXUNUSED(labelRect), const wxVariant &WXUNUSED(value) ) -{ - return NULL; + // user doesn't have any way to edit the icon so leave it unchanged + value << wxDataViewIconText(str, m_value.GetIcon()); + + return true; } -bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( - wxControl* WXUNUSED(editor), wxVariant &WXUNUSED(value) ) +void +wxDataViewIconTextRenderer::GtkOnCellChanged(const wxVariant& value, + const wxDataViewItem& item, + unsigned col) { - return false; + // we receive just the text part of our value as it's the only one which + // can be edited, but we need the full wxDataViewIconText value for the + // model + wxVariant valueIconText; + valueIconText << wxDataViewIconText(value.GetString(), m_value.GetIcon()); + wxDataViewTextRenderer::GtkOnCellChanged(valueIconText, item, col); } // --------------------------------------------------------- @@ -2550,62 +2585,76 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *WXUNUSED(column), cell->SetValue( value ); + + // deal with attributes wxDataViewItemAttr attr; - if (wx_model->GetAttr( item, cell->GetOwner()->GetModelColumn(), attr )) + if ( !wx_model->GetAttr( item, cell->GetOwner()->GetModelColumn(), attr ) + && cell->GtkIsUsingDefaultAttrs() ) { - if (attr.HasColour()) - { - const GdkColor * const gcol = attr.GetColour().GetColor(); + // no custom attributes specified and we're already using the default + // ones -- nothing to do + return; + } - GValue gvalue = { 0, }; - g_value_init( &gvalue, GDK_TYPE_COLOR ); - g_value_set_boxed( &gvalue, gcol ); - g_object_set_property( G_OBJECT(renderer), "foreground_gdk", &gvalue ); - g_value_unset( &gvalue ); - } - else - { - GValue gvalue = { 0, }; - g_value_init( &gvalue, G_TYPE_BOOLEAN ); - g_value_set_boolean( &gvalue, FALSE ); - g_object_set_property( G_OBJECT(renderer), "foreground-set", &gvalue ); - g_value_unset( &gvalue ); - } + bool usingDefaultAttrs = true; + if (attr.HasColour()) + { + const GdkColor * const gcol = attr.GetColour().GetColor(); - if (attr.GetItalic()) - { - GValue gvalue = { 0, }; - g_value_init( &gvalue, PANGO_TYPE_STYLE ); - g_value_set_enum( &gvalue, PANGO_STYLE_ITALIC ); - g_object_set_property( G_OBJECT(renderer), "style", &gvalue ); - g_value_unset( &gvalue ); - } - else - { - GValue gvalue = { 0, }; - g_value_init( &gvalue, G_TYPE_BOOLEAN ); - g_value_set_boolean( &gvalue, FALSE ); - g_object_set_property( G_OBJECT(renderer), "style-set", &gvalue ); - g_value_unset( &gvalue ); - } + GValue gvalue = { 0, }; + g_value_init( &gvalue, GDK_TYPE_COLOR ); + g_value_set_boxed( &gvalue, gcol ); + g_object_set_property( G_OBJECT(renderer), "foreground_gdk", &gvalue ); + g_value_unset( &gvalue ); + usingDefaultAttrs = false; + } + else + { + GValue gvalue = { 0, }; + g_value_init( &gvalue, G_TYPE_BOOLEAN ); + g_value_set_boolean( &gvalue, FALSE ); + g_object_set_property( G_OBJECT(renderer), "foreground-set", &gvalue ); + g_value_unset( &gvalue ); + } - if (attr.GetBold()) - { - GValue gvalue = { 0, }; - g_value_init( &gvalue, PANGO_TYPE_WEIGHT ); - g_value_set_enum( &gvalue, PANGO_WEIGHT_BOLD ); - g_object_set_property( G_OBJECT(renderer), "weight", &gvalue ); - g_value_unset( &gvalue ); - } - else - { - GValue gvalue = { 0, }; - g_value_init( &gvalue, G_TYPE_BOOLEAN ); - g_value_set_boolean( &gvalue, FALSE ); - g_object_set_property( G_OBJECT(renderer), "weight-set", &gvalue ); - g_value_unset( &gvalue ); - } + if (attr.GetItalic()) + { + GValue gvalue = { 0, }; + g_value_init( &gvalue, PANGO_TYPE_STYLE ); + g_value_set_enum( &gvalue, PANGO_STYLE_ITALIC ); + g_object_set_property( G_OBJECT(renderer), "style", &gvalue ); + g_value_unset( &gvalue ); + + usingDefaultAttrs = false; + } + else + { + GValue gvalue = { 0, }; + g_value_init( &gvalue, G_TYPE_BOOLEAN ); + g_value_set_boolean( &gvalue, FALSE ); + g_object_set_property( G_OBJECT(renderer), "style-set", &gvalue ); + g_value_unset( &gvalue ); + } + + + if (attr.GetBold()) + { + GValue gvalue = { 0, }; + g_value_init( &gvalue, PANGO_TYPE_WEIGHT ); + g_value_set_enum( &gvalue, PANGO_WEIGHT_BOLD ); + g_object_set_property( G_OBJECT(renderer), "weight", &gvalue ); + g_value_unset( &gvalue ); + + usingDefaultAttrs = false; + } + else + { + GValue gvalue = { 0, }; + g_value_init( &gvalue, G_TYPE_BOOLEAN ); + g_value_set_boolean( &gvalue, FALSE ); + g_object_set_property( G_OBJECT(renderer), "weight-set", &gvalue ); + g_value_unset( &gvalue ); } #if 0 @@ -2630,6 +2679,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *WXUNUSED(column), } #endif + cell->GtkSetUsingDefaultAttrs(usingDefaultAttrs); } } // extern "C" @@ -2661,7 +2711,6 @@ void wxDataViewColumn::Init(wxAlignment align, int flags, int width) { m_isConnected = false; - GtkCellRenderer *renderer = (GtkCellRenderer *) GetRenderer()->GetGtkHandle(); GtkTreeViewColumn *column = gtk_tree_view_column_new(); m_column = (GtkWidget*) column; @@ -2680,10 +2729,13 @@ void wxDataViewColumn::Init(wxAlignment align, int flags, int width) gtk_box_pack_end( GTK_BOX(box), GTK_WIDGET(m_label), FALSE, FALSE, 1 ); gtk_tree_view_column_set_widget( column, box ); - gtk_tree_view_column_pack_end( column, renderer, TRUE ); + wxDataViewRenderer * const colRenderer = GetRenderer(); + GtkCellRenderer * const cellRenderer = colRenderer->GetGtkHandle(); + + colRenderer->GtkPackIntoColumn(column); - gtk_tree_view_column_set_cell_data_func( column, renderer, - wxGtkTreeCellDataFunc, (gpointer) GetRenderer(), NULL ); + gtk_tree_view_column_set_cell_data_func( column, cellRenderer, + wxGtkTreeCellDataFunc, (gpointer) colRenderer, NULL ); } void wxDataViewColumn::OnInternalIdle() @@ -4059,8 +4111,6 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator ) { - Init(); - if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator )) { @@ -4164,13 +4214,10 @@ void wxDataViewCtrl::OnInternalIdle() bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) { - if (GetModel()) + if ( m_internal ) { delete m_internal; m_internal = NULL; - - delete m_notifier; - m_notifier = NULL; } if (!wxDataViewCtrlBase::AssociateModel( model ))