Hi Torsten. Thanks, once again, for the reply. On Thu, 2013-02-21 at 09:39 +0000, Torsten Schoenfeld wrote:
> On 21.02.2013 07:28, Dan Kasak wrote: > > Can't locate object method "EDITING_STARTED" via package > > "Gtk3::Ex::Datasheet::DBI::CellRendererText" at > > /usr/lib64/perl5/site_perl/5.12.4/Gtk3.pm line 228. > > I don't get this with my Gtk3 port of odot, so… no clue off-hand. Can > you provide a self-contained example program exhibiting this? Done. By the way ... perhaps an easier way of me getting this working is to look at your Gtk3 port of odot ;) > Some more comments on the code: > > > package Gtk3::Ex::Datasheet::DBI::CellEditableText; > > You might have to put empty implementations of the virtual functions of > Gtk3::CellEditable here: > > sub START_EDITING { > # do nothing > } > > sub EDITING_DONE { > # do nothing > } > > sub REMOVE_WIDGET { > # do nothing > } Also done. > > use Glib::Object::Subclass > > Gtk3::CellRendererText::, > > properties => [ > > Glib::ParamSpec->object( > > "editable-widget", > > "Editable widget", > > "The editable > > that's used for cell editing.", > > > > Gtk3::Ex::Datasheet::DBI::CellEditableText::, > > [ qw( readable > > writable ) ] > > ), > > Do you need this property? It was a hack in Odot, and I've now removed > it. If you don't need it, you can also consider moving the creation of > the editable from INIT_INSTANCE to START_EDITING. Hmmmm ... The only way I've seen a custom CellRendererText working is by implementing a CellEditableText, as per your previous example. Perhaps I don't need it? I didn't do it on purpose ... just pulled in example code and tweaked until it worked. > > # For some reason, the last item returned by the above call to > > # $parent->get_columns isn't a Gtk3::TreeViewColumn, and > > therefore > > # the $parent_set_cursor line fails. Avoid this. > > if ( ref $next_col eq 'Gtk3::TreeViewColumn' ) { > > $parent->set_cursor ( $path, $next_col, 1 ) > > if $next_col; > > } > > That shouldn't happen. What is the last item if it's not a column? This is a comment from WAY back in Gtk2 land. When everything is working again ... I'll re-test. > > sub GET_SIZE { > > > > my ( $self, $widget, $cell_area ) = @_; > > > > return $self->SUPER::GET_SIZE ( $widget, $cell_area ); > > > > } > > If you simply chain up, you can also just not provide any implementation > at all. The effect will be the same, but it will be faster as it avoids > the roundtrip marshalling of the arguments from C to Perl back to C. > (And GET_SIZE will be called a lot.) Ah. Noted. I think I must have had more functionality in there at one point, and removed it, not realising I could remove the whole thing. > > #$editable->modify_font( Gtk2::Pango::FontDescription->from_string( > > "Arial " . $cell->get( "font" ) ) ); > > $editable->modify_font( Pango::FontDescription->from_string( "Arial > > " . $cell->get( "font" ) ) ); > > Do you really want to hard-code a particular font here, completely > ignoring the user's preference? If you want to modify the font size, > use the Gtk3::CellRendererText's "size" property (which you inherit in > your cell renderer). Yeah :) To be honest ... this was to make things work properly on Windows. At the time I was writing it ... 1/2 the users were on Windows 2000, and for some reason that escapes me now, this was required. I'm free of these users now, by the way ;) --- Example code that demonstrates a number of issues I'm facing. Now I don't get the error as before, but I get a segfault instead, when clicking inside a cell to edit :( cell_renderer.pl: --- use strict; use Gtk3 -init; use Glib qw / TRUE FALSE /; my $builder = Gtk3::Builder->new(); $builder->add_objects_from_file( "cell_renderer.ui", "window1" ); my $treeview = $builder->get_object( "treeview1" ); my $model = Gtk3::ListStore->new( [ "Glib::Int" , "Glib::String" ] ); my $renderer_one = Gtk3::Ex::Datasheet::DBI::CellRendererText->new; $renderer_one->set( editable => TRUE ); my $column_one = Gtk3::TreeViewColumn->new_with_attributes( "Column 1", $renderer_one, 'text' => 0 ); $treeview->append_column( $column_one ); my $renderer_two = Gtk3::Ex::Datasheet::DBI::CellRendererText->new; $renderer_two->set( editable => TRUE ); my $column_two = Gtk3::TreeViewColumn->new_with_attributes( "Column 2", $renderer_two, 'text' => 1 ); $treeview->append_column( $column_two ); $model->set( $model->append , 0, "text 1" , 1, "text 2" ); $builder->get_object( "treeview1" )->set_model( $model ); $builder->get_object( "window1" )->show; Gtk3->main; ####################################################################################### # Custom CellRendererText ####################################################################################### package Gtk3::Ex::Datasheet::DBI::CellEditableText; # Copied and pasted from Odot use strict; use warnings; use Glib qw(TRUE FALSE); use Glib::Object::Subclass Gtk3::TextView::, interfaces => [ Gtk3::CellEditable:: ] , properties => [ Glib::ParamSpec->boolean( "editing-canceled", "Editing canceled", "Whether editing has been canceled.", FALSE, [ qw( readable writable ) ] ) ]; sub START_EDITING { # do nothing } sub EDITING_DONE { # do nothing } sub REMOVE_WIDGET { # do nothing } sub set_text { my ( $editable, $text ) = @_; $text = "" unless ( defined( $text ) ); $editable->get_buffer()->set_text( $text, length( $text ) ); } sub get_text { my ( $editable ) = @_; my $buffer = $editable->get_buffer(); return $buffer->get_text( $buffer->get_bounds(), TRUE ); } sub select_all { my ( $editable ) = @_; my $buffer = $editable->get_buffer(); my ( $start, $end ) = $buffer->get_bounds(); $buffer->move_mark_by_name( insert => $start ); $buffer->move_mark_by_name( selection_bound => $end ); } 1; package Gtk3::Ex::Datasheet::DBI::CellRendererText; # Originally from Odot, with bits and pieces from the CellRendererSpinButton example, # and even some of my own stuff worked in :) use constant x_padding => 2; use constant y_padding => 3; use strict; use warnings; use Glib qw(TRUE FALSE); use Glib::Object::Subclass Gtk3::CellRendererText::, properties => [ Glib::ParamSpec->object( "editable-widget", "Editable widget", "The editable that's used for cell editing.", Gtk3::Ex::Datasheet::DBI::CellEditableText::, [ qw( readable writable ) ] ), Glib::ParamSpec->boolean( "number", "Number", "Should I apply number formatting to the data?", 0, [ qw( readable writable ) ] ), Glib::ParamSpec->string( "decimals", "Decimals", "How many decimal places should be displayed?", -1, [ qw( readable writable ) ] ), Glib::ParamSpec->boolean( "currency", "Currency", "Should I prepend a dollar sign to the data?", 0, [ qw( readable writable ) ] ) ]; sub EDITING_STARTED { # do nothing } sub START_EDITING { my ( $cell, $event, $view, $path, $background_area, $cell_area, $flags ) = @_; if ( $event ) { return unless ( $event->button == 1 ); } ### my $editable = Gtk3::Ex::Datasheet::DBI::CellEditableText->new(); $editable->set( border_width => $cell->get( "ypad" ) ); $editable->signal_connect( key_press_event => sub { my ( $editable, $event ) = @_; if ( $event->keyval == $Gtk3::Gdk::KEY_Return || $event->keyval == $Gtk3::Gdk::KEY_KP_Enter and not $event-> state & qw(control-mask) ) { # Grab parent my $parent = $editable->get_parent; $editable->{ _editing_canceled } = FALSE; $editable->editing_done(); $editable->remove_widget(); my ( $path, $focus_column ) = $parent->get_cursor; my @cols = $parent->get_columns; my $next_col = undef; foreach my $i (0..$#cols) { if ( $cols[$i] == $focus_column ) { if ( $event->state >= 'shift-mask' ) { # go backwards $next_col = $cols[$i-1] if $i > 0; } else { # Go forwards # First check whether the next column is read_only while ( $i-1 < $#cols ) { $i++; if ( ! $cols[$i]->{definition}->{read_only} ) { last; } } $next_col = $cols[$i]; } last; } } # For some reason, the last item returned by the above call to # $parent->get_columns isn't a Gtk3::TreeViewColumn, and therefore # the $parent_set_cursor line fails. Avoid this. if ( ref $next_col eq 'Gtk3::TreeViewColumn' ) { $parent->set_cursor ( $path, $next_col, 1 ) if $next_col; } return TRUE; } return FALSE; }); $editable -> signal_connect( editing_done => sub { my ( $editable ) = @_; my $canceled = $editable->get( 'editing-canceled' ); # or $editable -> { _editing_canceled } if you store it directly $cell->stop_editing( $canceled ); unless ( $canceled ) { $cell->signal_emit( edited => $path, $editable->get_text() ); } }); $cell->set( editable_widget => $editable ); ### #$editable->modify_font( Pango::FontDescription->from_string( "Arial " . $cell->get( "font" ) ) ); $editable->{ _editing_canceled } = FALSE; $editable->{ _path } = $path; $editable->set( height_request => $cell_area->{height} ); $editable->set_text( $cell->get( "text" ) ); $editable->select_all(); $editable->show(); $editable -> signal_connect_after( 'focus-out-event' => sub { my ( $event_box, $event ) = @_; $cell->signal_emit( edited => $editable->{ _path }, $editable->get_text ); return $event; } ); return $editable; } sub get_layout { my ( $cell, $widget ) = @_; return $widget->create_pango_layout( "" ); } 1; --- cell_renderer.ui: --- <?xml version="1.0" encoding="UTF-8"?> <interface> <!-- interface-requires gtk+ 3.0 --> <object class="GtkWindow" id="window1"> <property name="can_focus">False</property> <child> <object class="GtkBox" id="box1"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> <child> <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="label" translatable="yes">label</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <object class="GtkScrolledWindow" id="scrolledwindow1"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="shadow_type">in</property> <child> <object class="GtkTreeView" id="treeview1"> <property name="visible">True</property> <property name="can_focus">True</property> <child internal-child="selection"> <object class="GtkTreeSelection" id="treeview-selection2"/> </child> </object> </child> </object> <packing> <property name="expand">True</property> <property name="fill">True</property> <property name="position">1</property> </packing> </child> <child> <object class="GtkButton" id="button1"> <property name="label" translatable="yes">button</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">2</property> </packing> </child> </object> </child> </object> </interface>
_______________________________________________ gtk-perl-list mailing list gtk-perl-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-perl-list