GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Fri Jul 25, 2014 5:17 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: gtktreeview multiple selection - update
PostPosted: Wed Jun 19, 2013 10:02 am 
Offline
Familiar Face

Joined: Mon Oct 29, 2012 1:30 pm
Posts: 16
good morning

in a previous post i asked infos about how gtk manages multiple selection in gtktreeview model
in that post i notified that, using "cursor-changed" signal (and also some other, as i discovered later) the selected row number detected by "gtk_tree_selection_count_selected_rows" function is not the right value

after some test i discovered that using "cursor-changed" signal handler its answer referred to the situation before my selection changing
if i check selected rows using another way, i.e. i ask to count for selected rows when i push a button, "gtk_tree_selection_count_selected_rows" function works well

in my opinion "cursor-changed" signal call its handler before gtk engine update the treeview

to solve this "problem" i thougt to do 2 possible things:
1- use a timer to check periodically selected rows (not so good for me)
2- build a customer signal to be emitted in "cursor-changed" signal handler, and use this new signal to call one function to manage selected rows. in this way i hope gtk engine will update treeview before call my new function

I hope I explained myself

what do you think about? have you a better suggestion?

thanks and regards

EDIT:
i'm using gtk 2, not 3 (because i'm using it also on windows os, and gtk 3 is not yet ported on windows)


Top
 Profile  
 
 Post subject: Re: gtktreeview multiple selection - update
PostPosted: Fri Jun 21, 2013 6:29 am 
Offline
Familiar Face

Joined: Mon Oct 29, 2012 1:30 pm
Posts: 16
to demonstrate hte behaviour i described before i include a part of my program who use multiselection treeview

here is c code
Code:
/***********/
/* INCLUDE */
/***********/
#include <stdlib.h>
#include <gtk/gtk.h>
#include <string.h>
#include <glib.h>
#include <glib/gstdio.h>

/**********/
/* DEFINE */
/**********/
#define D_VERSION   "01.01 (02-Feb-2013)"
#define D_MAX_LEN_MSG   200

/*********/
/* MACRO */
/*********/
/* errori */
enum {
   E_RES_OK = 0,
   E_ERR_GTK_BUILDER,
   E_ERR_RIPRISTINO
};

/************/
/* COSTANTI */
/************/

/***********/
/* TYPEDEF */
/***********/

/*************/
/* VARIABILI */
/*************/
/* Risorse visuali */
GtkTreeView *V_MainTreeview = NULL;
GtkListStore *V_MainListstore = NULL;

GtkEntry *V_TotalEntryUnchecked = NULL;
GtkEntry *V_TotalEntryVerified = NULL;
GtkEntry *V_TotalEntryApproved = NULL;

/*************/
/* PROTOTYPE */
/*************/
void F_Update_Totals (gint val);
void F_Display_Records (void);
gint F_Get_Index_Single_Selection (void);

/* Uscita */
G_MODULE_EXPORT void on_main_destroy (GtkWidget *object/*, gpointer user_data*/);

/* Azioni sulla lista */
G_MODULE_EXPORT void on_main_treeview_cursor_changed (GtkTreeView *tree_view/*, gpointer user_data*/);
G_MODULE_EXPORT void on_main_treeview_selection_notify_event (GtkWidget *widget,
                                                GdkEvent *event/*, gpointer user_data*/);
G_MODULE_EXPORT void on_main_treeview_row_activated (GtkTreeView *treeview,
                                          GtkTreePath *arg1,
                                          GtkTreeViewColumn *arg2/*, gpointer user_data*/);

/************/
/* FUNZIONI */
/************/
/* main */
int main (int argc, char *argv[]) {
   GtkBuilder *builder;
   GtkWidget *window;
//   GtkTreeSelection *select;

   /* Inizializza gtk */
   gtk_init (&argc, &argv);

   /* Carica il frame principale */
   builder = gtk_builder_new ();

   if (!gtk_builder_add_from_file (builder, "main.glade", NULL)) {
      /* Errore in lettura file */
      g_warning ("Errore apertura file \"main.glade\"");
      return (E_ERR_GTK_BUILDER);
   }
//   gtk_builder_add_from_string (uistr,strlen(uistr),"main", NULL);

   /* Visualizza il frame principale e associa la struttura dati */
   window = GTK_WIDGET (gtk_builder_get_object (builder, "main"));
   gtk_builder_connect_signals (builder, NULL);
   V_MainTreeview = (GtkTreeView *)gtk_builder_get_object (builder, "main_treeview");
   V_MainListstore = (GtkListStore *)gtk_builder_get_object (builder, "main_liststore");

   V_TotalEntryUnchecked = (GtkEntry *)gtk_builder_get_object (builder, "main_entry_unchecked");
   V_TotalEntryVerified = (GtkEntry *)gtk_builder_get_object (builder, "main_entry_verified");
   V_TotalEntryApproved = (GtkEntry *)gtk_builder_get_object (builder, "main_entry_approved");

   /* Imposta la selezione multipla */
   gtk_tree_selection_set_mode (
      gtk_tree_view_get_selection (GTK_TREE_VIEW (V_MainTreeview)),
      GTK_SELECTION_MULTIPLE);

F_Display_Records ();

   /* Libera le risorse */
   g_object_unref (G_OBJECT (builder));

   gtk_widget_show (window);
   gtk_main ();

   return 0;
}

/* Visualizza messagebox di informazione (Ok) */
void F_Show_Message_Ok (guint Type, gchararray Title,
                  gchararray Message) {
   GtkWidget *dialog;

   /* Prepara ildialogo modale del tipo richiesto */
   dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, Type, GTK_BUTTONS_OK, Message);

   /* Imposta la label e la posizione del dialogo */
   gtk_window_set_title (GTK_WINDOW (dialog), Title);
   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);

   /* Visualizza il dialogo */
   gtk_dialog_run (GTK_DIALOG (dialog));

   /* Chiude */
   gtk_widget_destroy (dialog);
}

/* Visualizza messagebox di informazione (Ok) */
gint F_Show_Message_YesNo (gchararray Title,
                  gchararray Message) {
   GtkWidget *dialog;
   gint Exit;

   /* Prepara ildialogo modale del tipo richiesto */
   dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, Message);

   /* Imposta la label e la posizione del dialogo */
   gtk_window_set_title (GTK_WINDOW (dialog), Title);
   gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);

   /* Visualizza il dialogo */
   Exit = gtk_dialog_run (GTK_DIALOG (dialog));

   /* Chiude */
   gtk_widget_destroy (dialog);
   return (Exit);
}

/********************/
/* FUNZIONI INTERNE */
/********************/
/* Aggiorna i valori dei totali */
void F_Update_Totals (gint val) {
   gchar Message[D_MAX_LEN_MSG];

sprintf (Message, "%d", val);
   /* Visualizza il totale incorso  */
   gtk_entry_set_text (V_TotalEntryUnchecked, Message);
}

/* Riempie la lista "V_MainTreeview" con i record precedentemente caricati */
void F_Display_Records (void) {
   gint Index, Ind2;
   gboolean FlagTotal;
   GtkTreeIter Iter;
   gchar Message[D_MAX_LEN_MSG];
   glong *pMovimenti;

   /* Svuota la lista */
   gtk_list_store_clear (V_MainListstore);

/* Aggiunge una riga */

/* Memorizza indice */
gtk_list_store_append (V_MainListstore, &Iter);
gtk_list_store_set (V_MainListstore, &Iter, 0, "AAA", 1, "pippo", 2, "blue", -1);
gtk_list_store_append (V_MainListstore, &Iter);
gtk_list_store_set (V_MainListstore, &Iter, 0, "BBB", 1, "pluto", 2, "yellow", -1);
gtk_list_store_append (V_MainListstore, &Iter);
gtk_list_store_set (V_MainListstore, &Iter, 0, "CCC", 1, "qui", 2, "green", -1);
gtk_list_store_append (V_MainListstore, &Iter);
gtk_list_store_set (V_MainListstore, &Iter, 0, "DDD", 1, "quo", 2, "white", -1);
gtk_list_store_append (V_MainListstore, &Iter);
gtk_list_store_set (V_MainListstore, &Iter, 0, "EEE", 1, "qua", 2, "red", -1);
}

/* Ottiene l' indice dell' elemento selezionato (selezione singola) */
gint F_Get_Index_Single_Selection (void) {
   GtkTreeSelection *selection;
   GtkTreeModel *model;
   GtkTreeIter iter;
   gint Index;

   /* Recupera l' indice della riga selezionata */
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(V_MainTreeview));

   return (gtk_tree_selection_count_selected_rows (selection));
}

/* Distruttore / Handler di chiusura */
G_MODULE_EXPORT void on_main_destroy (GtkWidget *object/*, gpointer user_data*/) {
   /* Controlla se ci sono modifiche in corso */
   /* Esce dal programma */
   gtk_main_quit ();
}

/* Modifica la selezione della tree_view */
/* Al momento lavora con la selezione singola */
G_MODULE_EXPORT void on_main_treeview_cursor_changed (GtkTreeView *tree_view/*, gpointer user_data*/) {
//   GList *rows_list;
   gint Index;
   gboolean Global;

   /* Recupera l' indice della riga selezionata */
   Index = F_Get_Index_Single_Selection ();
F_Update_Totals (Index);
}

G_MODULE_EXPORT void on_main_treeview_selection_notify_event (GtkWidget *widget,
                                                GdkEvent *event/*, gpointer user_data*/) {
   F_Show_Message_Ok (GTK_MESSAGE_INFO, "Information", "on_main_treeview_selection_notify_event");
}

/* Attivazione (doppio click) di un' operazione */
G_MODULE_EXPORT void on_main_treeview_row_activated (GtkTreeView *treeview,
                                          GtkTreePath *arg1,
                                          GtkTreeViewColumn *arg2/*, gpointer user_data*/) {
   /* Chiama la funzione "on_main_toolbutton_edit_clicked" se il button e' abilitato */
   /* a quanto pare la versione gtk per windows non e' stata aggiornata e devo usare una via diversa */
//   if (gtk_widget_get_sensitive ((GtkWidget *)gtk_toolbar_get_nth_item (V_MainToolbar, E_EDIT))) {
}

and here is glade code (i use glade to build visual interface) (save it as "main.glade" file)
Code:
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.16"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkImage" id="image1">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="stock">gtk-open</property>
  </object>
  <object class="GtkImage" id="image2">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="stock">gtk-save</property>
  </object>
  <object class="GtkImage" id="image3">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="xalign">0.43999999761581421</property>
    <property name="stock">gtk-quit</property>
  </object>
  <object class="GtkImage" id="image4">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="stock">gtk-delete</property>
  </object>
  <object class="GtkImage" id="image5">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="stock">gtk-edit</property>
  </object>
  <object class="GtkImage" id="image8">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="stock">gtk-about</property>
  </object>
  <object class="GtkWindow" id="main">
    <property name="width_request">700</property>
    <property name="height_request">600</property>
    <property name="can_focus">False</property>
    <property name="window_position">center</property>
    <signal name="destroy" handler="on_main_destroy" swapped="no"/>
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkHBox" id="hbox1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="homogeneous">True</property>
            <child>
              <object class="GtkTable" id="table1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="n_columns">2</property>
                <property name="homogeneous">True</property>
                <child>
                  <object class="GtkLabel" id="main_label_unchecked">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="label" translatable="yes">selected</property>
                  </object>
                  <packing>
                    <property name="x_options">GTK_FILL</property>
                    <property name="y_options">GTK_FILL</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkEntry" id="main_entry_unchecked">
                    <property name="width_request">80</property>
                    <property name="visible">True</property>
                    <property name="can_focus">True</property>
                    <property name="editable">False</property>
                    <property name="invisible_char">‚óŹ</property>
                    <property name="xalign">1</property>
                    <property name="primary_icon_activatable">False</property>
                    <property name="secondary_icon_activatable">False</property>
                    <property name="primary_icon_sensitive">True</property>
                    <property name="secondary_icon_sensitive">True</property>
                  </object>
                  <packing>
                    <property name="left_attach">1</property>
                    <property name="right_attach">2</property>
                    <property name="x_options">GTK_FILL</property>
                    <property name="y_options">GTK_FILL</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="padding">5</property>
                <property name="position">0</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkScrolledWindow" id="main_scrolledwindow">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="hscrollbar_policy">automatic</property>
            <property name="vscrollbar_policy">automatic</property>
            <child>
              <object class="GtkTreeView" id="main_treeview">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="model">main_liststore</property>
                <signal name="cursor-changed" handler="on_main_treeview_cursor_changed" swapped="no"/>
                <signal name="row-activated" handler="on_main_treeview_row_activated" swapped="no"/>
                <signal name="selection-notify-event" handler="on_main_treeview_selection_notify_event" swapped="no"/>
                <child>
                  <object class="GtkTreeViewColumn" id="main_treeviewcolumn_dataop">
                    <property name="sizing">autosize</property>
                    <property name="title">data op</property>
                    <property name="expand">True</property>
                    <property name="alignment">0.5</property>
                    <signal name="clicked" handler="on_main_treeviewcolumn_dataop_clicked" swapped="no"/>
                    <child>
                      <object class="GtkCellRendererText" id="dataop_text">
                        <property name="alignment">center</property>
                      </object>
                      <attributes>
                        <attribute name="background">11</attribute>
                        <attribute name="foreground">10</attribute>
                        <attribute name="text">0</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="main_treeviewcolumn_datareg">
                    <property name="sizing">autosize</property>
                    <property name="title">data reg</property>
                    <property name="expand">True</property>
                    <property name="alignment">0.5</property>
                    <child>
                      <object class="GtkCellRendererText" id="datareg_text">
                        <property name="alignment">center</property>
                      </object>
                      <attributes>
                        <attribute name="background">11</attribute>
                        <attribute name="foreground">10</attribute>
                        <attribute name="text">1</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkTreeViewColumn" id="main_treeviewcolumn_dataval">
                    <property name="sizing">autosize</property>
                    <property name="title">data val</property>
                    <property name="expand">True</property>
                    <property name="alignment">0.5</property>
                    <child>
                      <object class="GtkCellRendererText" id="dataval_text">
                        <property name="alignment">center</property>
                      </object>
                      <attributes>
                        <attribute name="background">11</attribute>
                        <attribute name="foreground">10</attribute>
                        <attribute name="text">2</attribute>
                      </attributes>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
  <object class="GtkListStore" id="main_liststore">
    <columns>
      <!-- column-name data_operazione -->
      <column type="gchararray"/>
      <!-- column-name data_registrazione -->
      <column type="gchararray"/>
      <!-- column-name data_valuta -->
      <column type="gchararray"/>
    </columns>
  </object>
</interface>

now you can check single e multiple selection using mouse, ctrl key and shift key
in the upper edit box you can read the number of selecting rows obtained from gtk_tree_selection_count_selected_rows function when it is called from "cursor changed" signal handler

in this way should more easy to understand my problem
regards


Top
 Profile  
 
 Post subject: Re: gtktreeview multiple selection - update
PostPosted: Thu Jun 27, 2013 3:30 pm 
Offline
Familiar Face

Joined: Mon Oct 29, 2012 1:30 pm
Posts: 16
nobody notices such a behaviour?

is there anyone who use gtktreeview with multiple selection?


Top
 Profile  
 
 Post subject: Re: gtktreeview multiple selection - update
PostPosted: Thu Jun 27, 2013 7:18 pm 
Offline
Never Seen the Sunlight

Joined: Mon Apr 28, 2008 5:52 am
Posts: 733
Location: UK
Hello,

You are using the incorrect signal to find out when the tree view selection has changed. The signal you need is "changed" in the helper class GtkTreeSelection.

This tutorial shows how to use the signal correctly.
http://zetcode.com/tutorials/gtktutorial/gtktreeview/

and the documentation at
https://developer.gnome.org/gtk2/stable/GtkTreeSelection.html

_________________
E.


Top
 Profile  
 
 Post subject: Re: gtktreeview multiple selection - update
PostPosted: Fri Jun 28, 2013 6:18 am 
Offline
Familiar Face

Joined: Mon Oct 29, 2012 1:30 pm
Posts: 16
hi errol

thank you about your answer

i'm quite sure to try also with gtktreeselection change signal and i obtained the same result. in any case it's possible i wrong something, so i will do it again then i will refer

thanks again


Top
 Profile  
 
 Post subject: Re: gtktreeview multiple selection - update
PostPosted: Fri Jun 28, 2013 7:16 am 
Offline
Familiar Face

Joined: Mon Oct 29, 2012 1:30 pm
Posts: 16
hi errol, you are right!!!

i verified your suggestion and it works. great!

i made my previous test using another handler, but chosen in glade signals manager, not doing adding code directly. my fault

you resolved my problem. thank you very much


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group