Make a ListIcon column editable

Linux specific forum
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Make a ListIcon column editable

Post by Oma »

Hello.

First of all: It works on my Xubuntu 13.10 (32-Bit) and Ubuntu 12.04, (64-Bit)

The last days i tried an improvement of my ListIcon-CellEdit to a more native version, still with problems.
Now i found your code and canceled my trials.
Congratulation and thank you for the short und fine solution!. This is VERY usefull.

To fulfill my needs for more than 1 editable column, i did a fusion with a small part of my trials and hope it makes it still more practicable.

What i've changed ...
- connect a 2. signal for 'editing-started' with a 2. callback
- in this callback i read the column of the current edited cell and save it in the ListIcon-Data like you did generally. So the column is flexible.
this callback also should be used for removing Keyboardshortcuts like #PB_Shortcut_Return, #PB_Shortcut_Escape, #PB_Shortcut_C | #PB_Shortcut_Control
during celledit if they are used for ListIcon-Lines or Buttons in the same window to avoid conflicts
- call the MakeColumnEditable() (my name: TV_ColumnSetEditable()) for each column i need
- the '_ColumEdited_Callback' also should be used to reactivate the removed Keyboardshortcuts

Please excuse my 'hijacking' of your code.

Code: Select all

EnableExplicit

ImportC "-gtk"
  g_object_set(object, property.p-UTF8, value, v=0)
  g_signal_connect(instance, signal.p-ascii, callback, vdata, destroy=0, flags=0) As "g_signal_connect_data"
  gtk_cell_layout_get_cells(col)
  g_type_check_instance_is_a(*instance.GTypeInstance, *type.GTypeClass)
EndImport


ProcedureC _ColumEditStart_Callback(Cell, Edit.s, Path.s, Gadget)
   Protected *TreePath, *TreeColumn, *ColumnList.GList
   Protected.i Column= -1
   gtk_tree_view_get_cursor_(GadgetID(Gadget), @*TreePath, @*TreeColumn);  pathes of cell just started to edit
   If *TreePath
      *ColumnList= gtk_tree_view_get_columns_(GadgetID(Gadget));       adress of column-List
      Column     = g_list_index_(*ColumnList, *TreeColumn);            index of edited column
   EndIf
   SetGadgetData(Gadget, Column);                                     Save current edited column in LIG-Data till next editstart
   If *TreePath : gtk_tree_path_free_(*TreePath) : EndIf
   g_list_free_(*ColumnList)
EndProcedure

ProcedureC _ColumEdited_Callback(Cell, Path.s, newTxt.s, Gadget)
   Protected  Row  = Val(Path)
   If GetGadgetData(Gadget)>- 1
      SetGadgetItemText(Gadget, row, PeekS(@newTxt, -1, #PB_UTF8), GetGadgetData(Gadget))
   EndIf
EndProcedure

Procedure MakeColumnEditable(ListIcon, Column)
  Protected col = gtk_tree_view_get_column_(GadgetID(ListIcon), Column)
  Protected aList = gtk_cell_layout_get_cells(col)
  Protected renderer
  Protected i
  For i = 0 To g_list_length_(aList) - 1
    renderer = g_list_nth_data_(alist, i)

    If g_type_check_instance_is_a(renderer, gtk_cell_renderer_text_get_type_())
      Break
    EndIf
  Next i
  g_list_free_(aList)
  SetGadgetData(ListIcon, -1)
  g_signal_connect(renderer, "editing-started", @_ColumEditStart_Callback(), ListIcon)
  g_signal_connect(renderer, "edited", @_ColumEdited_Callback(), ListIcon)
  g_object_set(renderer, "editable", 1)
EndProcedure


OpenWindow(1, 100, 100,400, 200, "ListIcon Editing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(1, 5, 5, 390, 190, "Edit1", 90)
gtk_tree_view_set_enable_search_(GadgetID(1), 0)
AddGadgetColumn(1, 1, "Fix2", 200)
AddGadgetColumn(1, 2, "Edit3", 200)
MakeColumnEditable(1, 0)
MakeColumnEditable(1, 2)

AddGadgetItem(1,0, "001" + #LF$ + "Edit 2-1" + #LF$ + "Edit 3-1")
AddGadgetItem(1,1, "002" + #LF$ + "Edit 2-2" + #LF$ + "Edit 3-2")
AddGadgetItem(1,2, "003" + #LF$ + "Edit 2-3" + #LF$ + "Edit 3-3")
;
Repeat
  Define Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

End
Charly
ps: 2 fixes done, see shardiks postings
Last edited by Oma on Sun Oct 19, 2014 9:43 am, edited 6 times in total.
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
empty
User
User
Posts: 27
Joined: Sat Apr 12, 2014 11:31 am

Re: Make a ListIcon column editable

Post by empty »

Nice addition. Thank you! :)
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Make a ListIcon column editable

Post by Shardik »

To further simplify the examples I would recommend to delete the overly complicated procedure WString(String$) in both code examples and change its call from

Code: Select all

SetGadgetItemText(Gadget, row, WString(newTxt), GetGadgetData(Gadget))
to

Code: Select all

SetGadgetItemText(Gadget, row, PeekS(@newTxt, -1, #PB_UTF8), GetGadgetData(Gadget))
empty
User
User
Posts: 27
Joined: Sat Apr 12, 2014 11:31 am

Re: Make a ListIcon column editable

Post by empty »

True, that's cleaner. I'll adapt it in my example.
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Make a ListIcon column editable

Post by Oma »

Thank you,

change of my posting is done!

Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Make a ListIcon column editable

Post by Shardik »

empty wrote:
Shardik wrote:- The cell renderers in the list returned from gtk_tree_view_column_get_cell_renderers() are in no particular order. So you can't simply use the 1st list entry because that may change and indeed I have already experienced this on different distributions in that I had to switch between list element 0 and 1...
GTK+ 2 Reference Manual wrote:gtk_tree_view_column_get_cell_renderers ()
...
Returns a newly-allocated GList of all the cell renderers in the column, in no particular order.
That doesn't matter in our case, because purebasic only uses on renderer to fill the ListIconGadget, so you can safely use the first one.
Unfortunately your explanation is wrong: as a proof you may simply try to edit column 0 in your example

Code: Select all

MakeColumnEditable(1, 0)
and you will receive the following error messages (on Ubuntu 14.04 x64 with KDE):
[WARNING] GLib-GObject (WARNING): /build/buildd/glib2.0-2.40.0/./gobject/gsignal.c:2464: signal 'edited' is invalid for instance '0x14fcb10' of type 'GtkCellRendererPixbuf'
[WARNING] GLib-GObject (WARNING): g_object_set_valist: object class 'GtkCellRendererPixbuf' has no property named 'editable'
The explanation is simple: in the cell renderer GList for column 0 the 1st cell renderer in my tests is always a GtkCellRendererPixbuf and the 2nd one is a GtkCellRendererText. In column 1 and higher the 1st cell renderer is always a GtkCellRendererText and the 2nd one a GtkCellRendererPixbuf. Therefore whenever you call MakeColumnEditable() for column 1 or higher your code is working but never for column 0... :wink:

The same holds true for Oma's code example...

So in order to take care for the hint in the GTK+ 2 reference manual (that the order of cell renderers is in no particular order) we have to check the type of each cell renderer in the GList. At first we have to add the following API function declaration to the ImportC section:

Code: Select all

  g_type_check_instance_is_a(*Instance.GTypeInstance, *Type.GTypeClass)
This is the modified procedure MakeColumnEditable() for empty's code example which correctly selects the text renderer:

Code: Select all

Procedure MakeColumnEditable(ListIcon, Column)
  Protected col = gtk_tree_view_get_column_(GadgetID(ListIcon), Column)
  Protected aList = gtk_cell_layout_get_cells(col)
  Protected renderer
  Protected i

  For i = 0 To g_list_length_(aList) - 1
    renderer = g_list_nth_data_(alist, i)

    If g_type_check_instance_is_a(renderer, gtk_cell_renderer_text_get_type_())
      Break
    EndIf
  Next i

  g_list_free_(aList)
  SetGadgetData(ListIcon, Column)
  g_signal_connect(renderer, "edited", @_MakeColumnEditable_Callback(), ListIcon)
  g_object_set(renderer, "editable", 1)
EndProcedure
And this is the corrected procedure MakeColumnEditable() for Oma's code example:

Code: Select all

Procedure MakeColumnEditable(ListIcon, Column)
  Protected col = gtk_tree_view_get_column_(GadgetID(ListIcon), Column)
  Protected aList = gtk_cell_layout_get_cells(col)
  Protected renderer
  Protected i

  For i = 0 To g_list_length_(aList) - 1
    renderer = g_list_nth_data_(alist, i)

    If g_type_check_instance_is_a(renderer, gtk_cell_renderer_text_get_type_())
      Break
    EndIf
  Next i

  g_list_free_(aList)
  SetGadgetData(ListIcon, -1)
  g_signal_connect(renderer, "editing-started", @_ColumEditStart_Callback(), ListIcon)
  g_signal_connect(renderer, "edited", @_ColumEdited_Callback(), ListIcon)
  g_object_set(renderer, "editable", 1)
EndProcedure
Now both posted code examples will allow to edit even column 0... 8)

The results were verified on these Linux distributions:
- andLinux/Kubuntu 9.04 x86 with KDE
- Fedora 20 x86 with Gnome 3
- Kubuntu 14.04 x86 with KDE
- Linux Mint 17 x86 with Cinnamon
- Lubuntu 14.04 x86 with LXDE
- OpenSuse 11.1 x86 with KDE (reported by Vera)
- OpenSuse 12.3 x86 with KDE
- OpenSuse 13.1 x86 with KDE
- Ubuntu 10.04 x86 with Gnome 2
- Ubuntu 14.04 x86 with Unity
- Ubuntu 14.04 x64 with KDE
- Xubuntu 14.04 x86 with Xfce
Last edited by Shardik on Mon Oct 20, 2014 2:05 pm, edited 2 times in total.
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Make a ListIcon column editable

Post by Oma »

Thank you again, shardik!

Yesterday i got doubts about this statement too as i tried a simple gtk-sorting on LIG-column-header-click.
No sorting happens, but the management works fine, except on column 0 i got a warning:

Code: Select all

[10:20:09] [WARNING] Gtk (WARNING): Attempting to sort on invalid type gpointer
I think the reason is the possible PB-pics, checkboxes, ... on column 0

I fixed my code above.

Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
User avatar
Vera
Addict
Addict
Posts: 858
Joined: Tue Aug 11, 2009 1:56 pm
Location: Essen (Germany)

Re: Make a ListIcon column editable

Post by Vera »

Hello shardik,

I too can confirm the effects you've described and might like to add to your verify list:
- Linux Suse 11.1 x86 with KDE

Using the updated versions and enabling MakeColumnEditable(1, 0) works out fine and stable in Oma's code.

But in empty's code it shows the effect, that the contents of column 0 is being copied into column 1 after submitting an edit or even a trial. And column 0 is reset to its preset content. a funny issue - just to tell

... and thanks for all the efforts you take and I try to grasp as much as I can :-)
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Make a ListIcon column editable

Post by Shardik »

Vera,

nice to see you posting again on this forum. I have missed your friendly and hearty postings for a long time... :wink:
And thank you for reporting about your tests.
Vera wrote:But in empty's code it shows the effect, that the contents of column 0 is being copied into column 1 after submitting an edit or even a trial. And column 0 is reset to its preset content. a funny issue - just to tell
Unfortunately I can't reproduce this misbehaviour although I tested with OpenSuse 12.3 x86 and 13.1 x86 (both with KDE). I don't have OpenSuse 11.1 x86 on my test machine anymore... Please also tell us your PB version. Did you do your tests with an older version of PB?
Vera wrote:... and thanks for all the efforts you take and I try to grasp as much as I can :-)
Thank you for your kind words!
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Make a ListIcon column editable

Post by Oma »

Hello Vera

Like shardik, i can't reproduce your problem, but you wrote:
and enabling MakeColumnEditable(1, 0) works out fine and stable in Oma's code
...in empty's code it shows the effect
Do you try code like this in emptys example?
MakeColumnEditable(1, 0)
MakeColumnEditable(1, 1)
...cause this doesn't work here. Only 1 certain column can be editable an so you only can use 1 MakeColumnEditable(x, x), otherwise you start editing in column 0 and finish it an column 1.

That's why i (Opa) did the extension. Here you have to call MakeColumnEditable(x, x) for every column you want to be editable.

I hope thats the (simple) reason for the misbehaviour.

Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
User avatar
Vera
Addict
Addict
Posts: 858
Joined: Tue Aug 11, 2009 1:56 pm
Location: Essen (Germany)

Re: Make a ListIcon column editable

Post by Vera »

Hi Shardik,

that's so nice to hear you've kept me in good memory :-)
... and enjoy my style of which I hope is more to come ... following straight forward :lol:

Trying to find out what could lead to my described effect I compared both codes, but disregarding Oma's additional procedure, and found a sign why it happens.

If you add a Debug GetGadgetData(Gadget) into the ProcedureC _MakeColumnEditable_Callback... you will find that Oma's code returns 0 / 1 / 2 depending on which column you edit. In empty's code it will always return '1' and therefore only apply changes in and to column 1, regardless which column has been edited.

Accordingly one can find the rather fixed SetGadgetData(ListIcon, Column) in empty's main procedure, where Oma's comand looks dynamic SetGadgetData(ListIcon, -1).
Strange that you don't get the same effects, but maybe you've missed to enable MakeColumnEditable(1, 0) ? - just in case.

At the moment I'm still with PB 4.50 (4.51), reconnecting to PB first before I'll move on, while already realising I'm excluding good stuff like post&bend-event, canvas, unicode and fixed&new PB-Linux constants. With a new harddrive to be installed on my fatally broken 'newer' PC I'll hope to set up PB there as well anew.



Hihi Opa,
thanks for confirming while I was still preparing this posting
and yes I'm quite aware about your beneficial enhancement :D

greets ~ Vera
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Make a ListIcon column editable

Post by Shardik »

Vera wrote:If you add a Debug GetGadgetData(Gadget) into the ProcedureC _MakeColumnEditable_Callback... you will find that Oma's code returns 0 / 1 / 2 depending on which column you edit. In empty's code it will always return '1' and therefore only apply changes in and to column 1, regardless which column has been edited.
I have done now my tests of empty's modified code even with PB 4.51 and it works like a charm:
An additional Debug GetGadgetData(1) at the end of procedure MakeColumnEditable(ListIcon, Column) always displays '0'...

But when changing SetGadgetData(ListIcon, Column) to SetGadgetData(ListIcon, 1), I am able to reproduce your described misbehaviour.

Sorry, instead of only posting the necessary changes I should have posted the complete modified example of empty. Please try the complete modified example of empty and report us whether the misbehaviour still exists:

Code: Select all

EnableExplicit


ImportC "-gtk"
  g_object_set(object, property.p-UTF8, value, v=0)
  gtk_cell_layout_get_cells(col)
  g_signal_connect(instance, signal.p-ascii, callback, vdata, destroy=0, flags=0) As "g_signal_connect_data"
  g_type_check_instance_is_a(*Instance.GTypeInstance, *Type.GTypeClass)
EndImport
 


ProcedureC _MakeColumnEditable_Callback(Cell, Path.s, newTxt.s, Gadget)
  Protected  Row  = Val(Path)
  SetGadgetItemText(Gadget, row, PeekS(@newTxt, -1, #PB_UTF8), GetGadgetData(Gadget))
EndProcedure

Procedure MakeColumnEditable(ListIcon, Column)
  Protected col = gtk_tree_view_get_column_(GadgetID(ListIcon), Column)
  Protected aList = gtk_cell_layout_get_cells(col)
  Protected renderer
  Protected i

  For i = 0 To g_list_length_(aList) - 1
    renderer = g_list_nth_data_(alist, i)

    If g_type_check_instance_is_a(renderer, gtk_cell_renderer_text_get_type_())
      Break
    EndIf
  Next i

  g_list_free_(aList)
  SetGadgetData(ListIcon, Column)
  g_signal_connect(renderer, "edited", @_MakeColumnEditable_Callback(), ListIcon)
  g_object_set(renderer, "editable", 1)
EndProcedure


OpenWindow(1, 100, 100,400, 200, "ListIcon Editing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ListIconGadget(1, 5, 5, 390, 190, "Column1", 90)
gtk_tree_view_set_enable_search_(GadgetID(1), 0)
AddGadgetColumn(1, 1, "Column2", 200)
MakeColumnEditable(1, 0)

AddGadgetItem(1,0, "001" + #LF$ + "Test 1")
AddGadgetItem(1,1, "002" + #LF$ + "Test 2")
AddGadgetItem(1,2, "003" + #LF$ + "Test 3")
;
Repeat
  Define Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

End
User avatar
Vera
Addict
Addict
Posts: 858
Joined: Tue Aug 11, 2009 1:56 pm
Location: Essen (Germany)

Re: Make a ListIcon column editable

Post by Vera »

Oh dear Shardik, you are far too clever and foresightful.

When testing both codes I ADDED MakeColumnEditable(1, 0) into each and used commenting out/on for a more comfortable crosschecking how it behaves when it is en-/ or disabled. (before and after applying your changes)

It did not occur to me that I mustn't add it into empty's code but would have had to exchange it with the existing MakeColumnEditable(1, 1), while only being focused on the gtk-warnings and the editability as such. ... And with both columns being editable I encountered that unwanted sideeffect.

I'm sorry I wasn't aware to have stated that explicitly and thus bringing you to unnecessary extra testing. :| And a posted example from my side could have solved that earlier.

Your complete modified example runs perfectly with only column 0 being editable :-)
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Make a ListIcon column editable

Post by Shardik »

Thank you, Vera, for reporting the problem you were able to solve.

I am glad it's now working for you... :wink:
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Make a ListIcon column editable

Post by Oma »

Hi!

I just noticed that (in Unicode mode) edited cells in lines > 9 finally will be set in wrong lines/items.
Please change the following Procedure (in original posting) to this version (for Ascii & Unicode) ...

Code: Select all

ProcedureC _ColumEdited_Callback(Cell, Path.s, newTxt.s, Gadget)
; 	  Protected  Row  = Val(Path)
	Protected  Row  = Val(PeekS(@Path, -1, #PB_UTF8))
   If GetGadgetData(Gadget)>- 1
      SetGadgetItemText(Gadget, row, PeekS(@newTxt, -1, #PB_UTF8), GetGadgetData(Gadget))
   EndIf
EndProcedure
Regards, Charly
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
Post Reply