invalid storage - GtkTreeModel falsch?



  • Hallo

    Ich habe mit ANSI C die passwd in einer dynamischen Liste eingelesen. Jetzt möchte ich die Liste über das GTK in einem Fenster darstellen. Meine ursprüngliche Liste habe ich zu einem Gtk_List_Store umgearbeitet. Als Basis für den TreeView habe ich das Script aus der Gtk-Demo genommen. Aber Error! Als GTK-Neuling weiß ich nicht wirklich, was mir der Compiler sagen möchten. Die Fehler treten im Funktionskopf der fixed_toggled und der add_columns auf. Wäre schön, wenn jemand einen Plan hat und mir die entscheidenden Hinweise geben kann. (error 3 steht auch noch an) Die Meldungen befinden sich unter dem Code.

    Besten Dank!
    mfg Caterpillar

    #include <gtk/gtk.h>
    #include <glib.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define BUF 150
    #define NAME 36
    #define PASSWD 36
    #define GECOS 48
    #define HOME 36
    #define SHELL 36
    #define PWD_INDEX 7
    
    #define FILEPATH "/home/caterpillar/passwd"
    #define TMPFILE "/home/caterpillar/passwd_tmp"
    
    FILE *data_uidgid;
    FILE *tmp_file;
    int pwd_record;
    char *line[BUF];
    
    struct{
    	gchar name[NAME];
    	gchar passwd[PASSWD];
    	gint uid;
    	gint gid;
    	gchar gecos[GECOS];
    	gchar home [HOME];
    	gchar shell [SHELL];
    	gboolean usb_flag;
    }passwd_list;
    
    void open_passwd();
    void open_tmp();
    void write_tmpfile();
    void fill_list();
    
    void open_passwd(){
    	/* passwd oeffnen */
    	data_uidgid = fopen(FILEPATH, "r");
    	if(data_uidgid != NULL){
    		printf("\npasswd " FILEPATH " angelegt!\n");
    	}else{
    		printf("Datei konnte nicht geoffnet " FILEPATH " werden!\n");
    	}
    }
    
    void open_tmp(){
    	/* temopraere Datei anlegen, und oeffnen */
    	tmp_file = fopen(TMPFILE, "r+");
    	if(tmp_file != NULL){
    		printf("TMP-Datei " TMPFILE " angelegt!\n");
    	}else{
    		printf("Datei konnte nicht geoffnet " TMPFILE " werden!\n");
    	}
    }
    
    void write_tmpfile(){
    	gint c;
    	pwd_record = 1;
    
    	while((c = fgetc(data_uidgid)) != EOF){
    		if(c == ':'||c == '\n'){ // Werte untereinanderschreiben
    			fputc('\n', tmp_file);
    			pwd_record++;
    			continue;
    		}
    		fputc(c, tmp_file);
    	}
    }
    /* ENDE DYNAMISCHE LISTE */
    
    static GtkWidget *window=NULL;
    
    enum{
        COLUMN_FLAG,
        COLUMN_NAME,
        COLUMN_PASSWORT,
        COLUMN_UID,
        COLUMN_GID,
        COLUMN_GECOS,
        COLUMN_HOME,
        COLUMN_SHELL
    };
    
    /* Create GTK-Tree-Model */
    static GtkTreeModel *create_model(void){
    
      gint i = 0;
      GtkListStore *store;
      GtkTreeIter iter;
    
      /* create list store */
      store = gtk_list_store_new(G_TYPE_BOOLEAN,
                                G_TYPE_STRING,
                                G_TYPE_STRING,
                                G_TYPE_UINT,
                                G_TYPE_UINT,
                                G_TYPE_STRING,
                                G_TYPE_STRING,
                                G_TYPE_STRING);
    
      /* add data to the list store */
      while(fgets(line, BUF, tmp_file)){
          i++;
          switch(i){
              case 1: strcpy(passwd_list.name, line);
              break;
              case 2: strcpy(passwd_list.passwd, line);
              break;
              case 3: passwd_list.uid = atoi(line);
              break;
              case 4: passwd_list.gid = atoi(line);
              break;
              case 5: strcpy(passwd_list.gecos, line);
              break;
              case 6: strcpy(passwd_list.home, line);
              break;
              case 7: strcpy(passwd_list.shell, line);
              break;
              default: printf("Fehler!");
          }
          if(i == 7){
          gtk_list_store_append(store, &iter);
          gtk_list_store_set(store, &iter,
                                COLUMN_FLAG, passwd_list.usb_flag,
                                COLUMN_NAME, passwd_list.name,
                                COLUMN_PASSWORT, passwd_list.passwd,
                                COLUMN_UID, passwd_list.uid,
                                COLUMN_GID, passwd_list.gid,
                                COLUMN_GECOS, passwd_list.gecos,
                                COLUMN_HOME, passwd_list.home,
                                COLUMN_SHELL, passwd_list.shell, -1);
                                i = 1;
          }
      return GTK_TREE_MODEL(store);
    }
    
    static void fixed_toggled(GtkCellRendererToggle *cell, gchar *path_str, gpointer passwd_list){
      GtkTreeModel *model = (GtkTreeModel *)passwd_list;
      GtkTreeIter  iter;
      GtkTreePath *path = gtk_tree_path_new_from_string(path_str);
      gboolean usb_flag;
    
      /* get toggled iter */
      gtk_tree_model_get_iter(model, &iter, path);
      gtk_tree_model_get(model, &iter, COLUMN_FLAG, &usb_flag, -1);
    
      /* do something with the value */
      usb_flag ^= 1;
    
      /* set new value */
      gtk_list_store_set(GTK_LIST_STORE(model), &iter, COLUMN_FLAG, usb_flag, -1);
    
      /* clean up */
      gtk_tree_path_free(path);
    }
    
    static void add_columns(GtkTreeView *treeview){
      GtkCellRenderer *renderer;
      GtkTreeViewColumn *column;
      GtkTreeModel *model = gtk_tree_view_get_model(treeview);
    
      /* Spalte fuer usb_flag */
      renderer = gtk_cell_renderer_toggle_new();
      g_signal_connect(renderer, "toggled", G_CALLBACK(fixed_toggled), model);
      column = gtk_tree_view_column_new_with_attributes("Status", renderer, "active", COLUMN_FLAG, NULL);
    
      gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column), GTK_TREE_VIEW_COLUMN_FIXED);
      gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 50);
      gtk_tree_view_append_column(treeview, column);
    
      /* Spalte fuer Name */
      renderer = gtk_cell_renderer_text_new();
      column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", COLUMN_NAME, NULL);
      gtk_tree_view_column_set_sort_column_id(column, COLUMN_NAME);
      gtk_tree_view_append_column(treeview, column);
    
      /* Spalte fuer Passwort */
      renderer = gtk_cell_renderer_text_new();
      column = gtk_tree_view_column_new_with_attributes("Passwort", renderer, "text", COLUMN_PASSWORT, NULL);
      gtk_tree_view_column_set_sort_column_id(column, COLUMN_PASSWORT);
      gtk_tree_view_append_column(treeview, column);
    
      /* Spalte fuer UID */
      renderer = gtk_cell_renderer_text_new();
      column = gtk_tree_view_column_new_with_attributes("UID", renderer, "text", COLUMN_UID, NULL);
      gtk_tree_view_column_set_sort_column_id(column, COLUMN_UID);
      gtk_tree_view_append_column(treeview, column);
    
      /* Spalte fuer GID */
      renderer = gtk_cell_renderer_text_new();
      column = gtk_tree_view_column_new_with_attributes("GID", renderer, "text", COLUMN_GID, NULL);
      gtk_tree_view_column_set_sort_column_id(column, COLUMN_GID);
      gtk_tree_view_append_column(treeview, column);
    
      /* Spalte fuer Gecos */
      renderer = gtk_cell_renderer_text_new();
      column = gtk_tree_view_column_new_with_attributes("Gecos", renderer, "text", COLUMN_GECOS, NULL);
      gtk_tree_view_column_set_sort_column_id(column, COLUMN_GECOS);
      gtk_tree_view_append_column(treeview, column);
    
      /* Spalte fuer Home */
      renderer = gtk_cell_renderer_text_new();
      column = gtk_tree_view_column_new_with_attributes("Home", renderer, "text", COLUMN_HOME, NULL);
      gtk_tree_view_column_set_sort_column_id(column, COLUMN_HOME);
      gtk_tree_view_append_column(treeview, column);
    
      /* Spalte fuer Shell*/
      renderer = gtk_cell_renderer_text_new();
      column = gtk_tree_view_column_new_with_attributes("Shell", renderer, "text", COLUMN_SHELL, NULL);
      gtk_tree_view_column_set_sort_column_id(column, COLUMN_SHELL);
      gtk_tree_view_append_column(treeview, column);
    }
    
    GtkWidget *do_list_store(GtkWidget *do_widget){
      if (!window){
          GtkWidget *vbox;
          GtkWidget *label;
          GtkWidget *sw;
          GtkTreeModel *model;
          GtkWidget *treeview;
    
          /* create window, etc */
          window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    
          /*
          gtk_window_set_screen (GTK_WINDOW (window),
    			     gtk_widget_get_screen (do_widget));
          */
    
          gtk_window_set_title(GTK_WINDOW (window), "GtkListStore demo");
          g_signal_connect(window, "destroy", G_CALLBACK(gtk_widget_destroyed), &window);
          gtk_container_set_border_width(GTK_CONTAINER(window), 8);
    
          vbox = gtk_vbox_new(FALSE, 8);
          gtk_container_add(GTK_CONTAINER(window), vbox);
    
          label = gtk_label_new("User-Liste aus passwd");
          gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
    
          sw = gtk_scrolled_window_new(NULL, NULL);
          gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_ETCHED_IN);
          gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
          gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
    
          /* create tree model */
          model = create_model();
    
          /* create tree view */
          treeview = gtk_tree_view_new_with_model(model);
          gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
          gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview), COLUMN_NAME);
    
          g_object_unref(model);
    
          gtk_container_add(GTK_CONTAINER(sw), treeview);
    
          /* add columns to the tree view */
          add_columns(GTK_TREE_VIEW(treeview));
    
          /* finish & show */
          gtk_window_set_default_size(GTK_WINDOW(window), 280, 250);
      }
    
      if(!GTK_WIDGET_VISIBLE(window))
        gtk_widget_show_all(window);
      else{
          gtk_widget_destroy(window);
          window = NULL;
      }
      return window;
    }
    
    int main(int argc, char **argv){
        open_passwd();
    	open_tmp();
    	write_tmpfile();
    	fclose(data_uidgid);
    	rewind(tmp_file);
        gtk_init(&argc, &argv);
        do_list_store(window);
        gtk_main();
        return 0;
    }
    
    /home/caterpillar/Tree/main.c:143: error: invalid storage class for function ‘fixed_toggled’
    /home/caterpillar/Tree/main.c:164: error: invalid storage class for function ‘add_columns’
    /home/caterpillar/Tree/main.c:283: warning: ‘main’ is normally a non-static function
    /home/caterpillar/Tree/main.c:293: error: expected declaration or statement at end of input
    /home/caterpillar/Tree/main.c:293: warning: control reaches end of non-void function
    Process terminated with status 1 (0 minutes, 1 seconds)
    3 errors, 10 warnings
    


  • Den dritten Fehler habe ich jetzt gefunden. Es war die abschließende Funktionsklammer der Funktion create_model(). Sie fehlte. Der Compiler läuft jetzt auch ohne Error durch. Das Fenster wird angezeigt, aber leider ohne Inhalt.

    Anstelle dessen, bekomme ich von der Codeblocks-Console die Fehlermeldung:
    (Tree:5040)Glib-GObject-CRITICAL **: g_object_unref: assertation 'G_IS_OBJECT (object)' failed

    Es fehlt ein Objekt. Aber welches? In dem Konstrukt TReeModel oder beim TreeView?

    Schön, wenn hier noch jemand einen Plan hätte.

    Gruß Caterpillar



  • Hallo

    Es ist ein Denk-Fehler beim Aufbau der ListStore. Ich muss den ListStore ganz anders aufbauen.

    Meine Frage hat sich damit erledigt.

    Gruß Caterpillar


Anmelden zum Antworten