GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Tue Sep 02, 2014 6:57 pm

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Move up/down in list and update changes in file.
PostPosted: Thu Nov 22, 2012 9:28 pm 
Offline
Familiar Face

Joined: Thu Nov 22, 2012 3:46 pm
Posts: 22
I want to write an application that stores some presets in a registry.
To manipulate entries in this list I use a GtkTreeView:



Code:
   |     NAME             |  FREQUENCY  |
   --------------------------------------------------------
       Rock FM                   87.50
       One FM                    92.20
       unnamed         101.40

   --------------------------------------------------------


To add or remove entries I managed to write code that works fine, update changes in list view and save changes in app registry:

Code:
   typedef struct Settings settings;
    typedef struct Preset preset;

    struct Settings
    {
       GList *presets;
    };

    struct Preset
    {
       gchar* title;
       gfloat freq;
    };



*Store the presets*

Code:
   gint i, count;
    gchar *buffer;
    preset *ps;

    count = g_list_length(settings.presets);
    gconf_client_set_int(client, "/apps/presets/presets", count, NULL);
    for (i = 0; i < count; i++)
    {
           ps = g_list_nth_data(settings.presets, i);
           buffer = g_strdup_printf("/apps/presets/%d/name", i);
           gconf_client_set_string(client, buffer, ps->title, NULL);
           g_free(buffer);
           buffer = g_strdup_printf("/apps/presets/%d/freqency", i);
           gconf_client_set_float(client, buffer, ps->freq, NULL);
           g_free(buffer);
    }      
    gconf_client_set_int(client, "/apps/presets/last", mom_ps, NULL);

*Load the presets*

Code:
   gint i, count;
   gchar *buffer;
   preset *ps;
   GConfClient *client = NULL;
   double freq;
   
   settings.presets = NULL;

   count = gconf_client_get_int(client, "/apps/presets/presets", NULL);
   for (i=0; i < count; i++)
   {
      ps = malloc(sizeof(preset));
      buffer = g_strdup_printf("apps/presets/%d/name", i);
      ps->title = gconf_client_get_string(client, buffer, NULL);
      g_free(buffer);
      if (!ps->title)
         ps->title = g_strdup(_("unnamed"));
      buffer = g_strdup_printf("/apps/presets/%d/freqency", i);
      freq = gconf_client_get_float(client, buffer, NULL);
      if ((freq < FREQ_MIN) || (freq > FREQ_MAX))
         ps->freq = FREQ_MIN;
      else
         ps->freq = freq;
      g_free(buffer);
      settings.presets = g_list_append(settings.presets, (gpointer)ps);   
   }


*delete button*

Code:
    static void delete_button_clicked_cb(GtkWidget *widget, gpointer data)
    {
       GtkTreePath *path = NULL;
       GtkTreeViewColumn *focus_column = NULL;
       GtkTreeIter iter;
       preset *ps;
       int *row;
       GList* menuitems;
       GtkWidget *menuitem;
   
       gtk_tree_view_get_cursor(GTK_TREE_VIEW(list_view), &path, &focus_column);
   
       if (!path) return;

       row = gtk_tree_path_get_indices(path);
       g_assert(row);
       g_assert(*row < g_list_length(settings.presets));

       ps = g_list_nth_data(settings.presets, *row);
       g_assert(ps);   
       settings.presets = g_list_remove(settings.presets, (gpointer)ps);
       g_free(ps->title);
       g_free(ps);
   
       gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
       gtk_list_store_remove(list_store, &iter);

       if (main_visible) {
          gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
          if (--mom_ps < 0) mom_ps = 0;
          if (!g_list_length(settings.presets)) mom_ps = -1;
          preset_combo_set_item(mom_ps);

          menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
          g_assert(*row < g_list_length(menuitems));
          menuitem = g_list_nth_data(menuitems, *row);
          gtk_widget_destroy(menuitem);
       }
   
       gtk_tree_path_prev(path);
       gtk_tree_view_set_cursor(GTK_TREE_VIEW(list_view), path, NULL, FALSE);
       gtk_tree_path_free(path);   
    }


To reorder items in the list I want code for moving up and down a line and update the list view and registry of the app. My code moves up/down in the list
preview but doesn't update the registry because I don't know how to use the function "g_list_remove", "g_list_insert", ... for this part of code .

Code:
   *button up/down*

    void up_button_clicked_cb(GtkWidget * widget, gpointer data)
   {
      GtkTreeIter curr_iter, prev_iter;
      GtkTreePath *curr_path, *prev_path;

      selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
      gtk_tree_selection_get_selected(selection, NULL, &curr_iter);
      curr_path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &curr_iter);

      prev_path = curr_path;
      gtk_tree_path_prev(prev_path);

      if (gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &prev_iter, prev_path)) {
            gtk_list_store_swap(GTK_LIST_STORE(GTK_TREE_MODEL(list_store)), &curr_iter, &prev_iter);
      }
   }

   static void down_button_clicked_cb(GtkWidget * widget, gpointer data)
   {
      GtkTreeIter curr_iter, next_iter;
      GtkTreePath *curr_path, *next_path;

      selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
      gtk_tree_selection_get_selected(selection, NULL, &curr_iter);
      curr = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &curr_iter);

      next_path = curr_path;
      gtk_tree_path_next(next);

      if (gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &next_iter, next_path)) {
            gtk_list_store_swap(GTK_LIST_STORE(GTK_TREE_MODEL(list_store)), &curr_iter, &next_iter);
      }
   }


Any help would be welcome. Thanks in advance.


Attachments:
File comment: Application UI
App.png
App.png [ 4.02 KiB | Viewed 407 times ]
File comment: Preset interface
Presets.png
Presets.png [ 7.79 KiB | Viewed 407 times ]
Top
 Profile  
 
 Post subject: Re: Move up/down in list and update changes in file.
PostPosted: Fri Nov 23, 2012 8:55 am 
Offline
Never Seen the Sunlight

Joined: Thu Mar 24, 2011 2:10 pm
Posts: 328
Location: Sydney, Australia
I have done something similar, though a bit more basic as it is just text strings in a table (https://github.com/pchilds/Harmonic/blob/master/src/batc.c - quite a long file but all the relevant code is in the beginning).
In my case I put the label widgets in a doubly linked list and rearranging was only a simple matter of swapping the text strings of the labels (no need to manipulate the list).
Remember the GList structure contains pointers to the current item, the next item and the previous item. If you want to swap items j and j+1 you don't have to do any messy inserting and removing, you can simply adjust the pointers to change the ordering.
Code:
iter1=g_list_nth(list, j);
iter0=iter1->prev;
iter2=iter1->next;
iter3=iter2->next;
iter0->next=iter2;
iter1->prev=iter2;
iter1->next=iter3;
iter2->prev=iter0;
iter2->next=iter1;
iter3->prev=iter1;

It's a bit messy, but that's the sort of thing that goes on internally in a lot of the glib functions.
By the way, only use the doubly linked list if you have reason to search from either direction. It's a bit more inefficient due to the extra pointer both in terms of memory and having to mess around with extra code at times like this.

Also for deleting as you are row specific rather than contents specific, I would generally lean more towards g_list_remove_link (instead of g_list_remove) and then taking care of freeing the node.


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

All times are UTC


Who is online

Users browsing this forum: Google [Bot], newguy and 4 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