GtkTreeView bug?



I'm trying to create a new FileModel for the treeview but have found some
problems.
I don't know if i'm doing wrong or if GtkTreeView is buggy:

But if I am removing all elements I'm getting a lots of warnings like:

"gtkfileview (pid:23372): Gtk-CRITICAL **: file gtktreeview.c: line 2788
(gtk_tree_view_bin_expose): assertion `has_next' failed.
There is a disparity between the internal view of the GtkTreeView,
and the GtkTreeModel.  This generally means that the model has changed
without letting the view know.  Any display from now on is likely to
be incorrect."

the problems happens after call to erase_directory_list (and yes the
"deleted" signal is emited):

struct GtkFileData
{
	gchar *filename;
	struct stat st;
	GdkPixbuf *icon;
};

void
erase_directory_list(GtkTreeModel *model)
{
  g_return_if_fail (GTK_IS_FILE_MODEL(model));

  g_list_foreach(model->directory_list, _gtk_file_model_remove_filedata,
model);
  g_list_free(model->directory_list);
  model->directory_list=NULL;
}

void
_gtk_file_model_append_filedata (GtkFileModel *model, GtkFileData
*filedata)
{
  GtkTreeIter iter;
  GtkTreePath *path;
  g_return_if_fail (GTK_IS_FILE_MODEL(model));

   model->directory_list = g_list_append(model->directory_list, filedata);
    model->length++;

    iter.stamp = model->stamp;
   iter.user_data = g_list_last(model->directory_list);
    
   path = gtk_tree_path_new ();
   gtk_tree_path_append_index (path, model->length - 1);
   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, &iter);
   gtk_tree_path_free (path);
}

void
_gtk_file_model_remove_filedata (GtkFileData *filedata, GtkFileModel*
model)
{
  GtkTreeIter iter;
  g_return_if_fail (GTK_IS_FILE_MODEL(model));

  if(!gtk_tree_model_get_iter_root (GTK_TREE_MODEL (model), &iter))
    g_assert("this is weird no root iter???????\n");
  
  do
  {  
    if (((GList*)iter.user_data)->data == filedata)
    {
      GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (model),
&iter);
      model->length --;
      model->stamp ++;
      g_free (filedata);
	/* this should be called to make sure tree_view is notified about
the change */
      gtk_tree_model_deleted (GTK_TREE_MODEL (model), path);
      gtk_tree_path_free (path);
      break ;
    }    
  } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter));

}

static void
gtk_file_model_get_value (GtkTreeModel *tree_model,
			  GtkTreeIter  *iter,
			  gint          column,
			  GValue       *value)
{
  GtkFileModel *model;
  GtkFileData *filedata;
  char buf[32];

  g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
  g_return_if_fail (column < FILE_MODEL_MAX_COLUMNS);
  g_return_if_fail (GTK_FILE_MODEL (tree_model)->stamp == iter->stamp);

  model = GTK_FILE_MODEL (tree_model);
  filedata = ((GList*) (iter->user_data))->data;

  g_value_init (value, model->columns[column]);
  if (filedata)
  {
    switch (column)    {
       case 0: /* column 0 holds the filedata structure */
        g_value_set_pointer (value, filedata);
       break;
      case 1: /* column 1 holds color values */
        if (!filedata->st.st_mtime) /* probadly a broken symlink */
          g_value_set_string (value, "gray");
        else if (S_ISDIR(filedata->st.st_mode)) /* file is a directory */
          g_value_set_string (value, "blue");
        else /* file is normal file */
          g_value_set_string (value, NULL);
      break;
      case 2:
          g_value_set_pointer (value, filedata->icon);
      break;
      case 3:
          g_value_set_string (value, filedata->filename);
      break;
      case 4:
          g_snprintf(buf, 32, "%d", (int)filedata->st.st_size);
          g_value_set_string (value, buf);
      break;
      case 5: 
		/* localtime/ctime coredumps on my system GLIBC-2.2 bug????
*/
	  /* g_snprintf(buf, 32, "%s", ctime(filedata->st.st_mtime)); */
          g_snprintf(buf, 32, "%d", (int)filedata->st.st_mtime);
          g_value_set_string (value, buf);
      break;
      case 6:
          g_snprintf(buf, 32, "TODO %X", filedata->st.st_mode);
          g_value_set_string (value, buf);
      break;
    }
  }    
  else
    g_warning ("No filedata???\n");
}

static gboolean
gtk_file_model_get_iter (GtkTreeModel *tree_model,
			 GtkTreeIter  *iter,
			 GtkTreePath  *path)
{
  GList *list;
  guint i;
  GtkFileModel *model = GTK_FILE_MODEL (tree_model);

  g_return_val_if_fail (GTK_IS_FILE_MODEL (tree_model), FALSE);
  g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);

  i = gtk_tree_path_get_indices (path)[0];

  if (!model->directory_list || i > model->length)
    return FALSE;

  list = g_list_nth (model->directory_list, i);

  /* If this fails, list_store->length has gotten mangled. */
  g_assert (list);

  iter->stamp = model->stamp;
  iter->user_data = list;
  return TRUE;
}


Greets

M.H.




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]