Re: gtk_widget_show_all [or "much ado about foreach and forall]



>>>>> "J" == J A M Molenaar <Klem.Prod@net.HCC.nl> writes:

 J> Sascha Ziemann wrote:
 >>  Sascha Ziemann <szi@aibon.ping.de> writes:
 >> 
 >> | gtk_widget_show_all does not show tree items.  Is that intended?
 >> 
 >> sorry: it shows items but doesn't show subtrees.

 J> Yes, I had the same problem a while ago... It had something to do
 J> with a TRUE value that had to be FALSE or visa versa... If you
 J> can't figure it out give a sample of the code you have written


hmm...this kind of made me curious, since I couldn't find anything in
the header files[1] like a flag to modify this kind of behavior...and
since the only alternative to examining this was getting some real
work done, I decided to track the show_all stuff...

--<code from gtkwidget.c>----------------------------------------------

void
gtk_widget_show_all (GtkWidget *widget)
{
  GtkWidgetClass *class;

  g_return_if_fail (widget != NULL);
  g_return_if_fail (GTK_IS_WIDGET (widget));

  class = GTK_WIDGET_CLASS (GTK_OBJECT (widget)->klass);

  if (class->show_all)
    class->show_all (widget);
}

--</code>--------------------------------------------------------------

Now, show all is a virtual function:

in GtkWidgetClass:

  void (* show_all)            (GtkWidget      *widget);

initialized in class_init:

  klass->show_all = gtk_widget_show;

so it couldn't be here I should look.  Now there aren't any show_all
in gtktree, nor in gtktreeitem, so I thought I'd look in the parent
class, the container [2].  Here I found the initialisation

  widget_class->show_all = gtk_container_show_all;

where

--<code from gtkcontainer.c>--------------------------------------------
static void
gtk_container_show_all (GtkWidget *widget)
{
  g_return_if_fail (widget != NULL);
  g_return_if_fail (GTK_IS_CONTAINER (widget));

  gtk_container_foreach (GTK_CONTAINER (widget),
			 (GtkCallback) gtk_widget_show_all,
			 NULL);
  gtk_widget_show (widget);
}
--</code>--------------------------------------------------------------

so it would seem it was foreach I should track down.  OK, I could do
that...

gtk_container_foreach got the class, and called the forall virtual
function of the approriate class:

--<code from gtkcontainer.c:gtk_container_foreach>---------------------
  class = GTK_CONTAINER_CLASS (GTK_OBJECT (container)->klass);

  if (class->forall)
    class->forall (container, FALSE, callback, callback_data);
--</code>--------------------------------------------------------------

Now, the class in our case must be the tree, so I turned to gtktree.c
and gtktreeitem, the two containers which should be affected by this...

Initialised to:

  container_class->forall = gtk_tree_forall;
and
  container_class->forall = gtk_tree_item_forall;

where

--<code from gtktree.c>------------------------------------------------
static void
gtk_tree_forall (GtkContainer *container,
		 gboolean      include_internals,
		 GtkCallback   callback,
		 gpointer      callback_data)
{
  GtkTree *tree;
  GtkWidget *child;
  GList *children;
  
  
  g_return_if_fail (container != NULL);
  g_return_if_fail (GTK_IS_TREE (container));
  g_return_if_fail (callback != NULL);
  
  tree = GTK_TREE (container);
  children = tree->children;
  
  while (children)
    {
      child = children->data;
      children = children->next;
      
      (* callback) (child, callback_data);
    }
}
--</code>--------------------------------------------------------------

and

--<code from gtktreeitem.c>--------------------------------------------
static void
gtk_tree_item_forall (GtkContainer *container,
		      gboolean      include_internals,
		      GtkCallback   callback,
		      gpointer      callback_data)
{
  GtkBin *bin;
  GtkTreeItem *tree_item;

  g_return_if_fail (container != NULL);
  g_return_if_fail (GTK_IS_TREE_ITEM (container));
  g_return_if_fail (callback != NULL);

  bin = GTK_BIN (container);
  tree_item = GTK_TREE_ITEM (container);

  if (bin->child)
    (* callback) (bin->child, callback_data);
  if (include_internals && tree_item->subtree)
    (* callback) (tree_item->subtree, callback_data);
}
--</code>--------------------------------------------------------------

Hmm...it would seem the include_internals was FALSE in the call, where
we wanted it to be TRUE

  if (include_internals && tree_item->subtree)
    (* callback) (tree_item->subtree, callback_data);


Now, the only difference between container_foreach and
container_forall seems to be the lines

 if (class->forall)
    class->forall (container, TRUE, callback, callback_data);
and
 if (class->forall)
    class->forall (container, FALSE, callback, callback_data);

so changing the call in gtk_container_show_all to gtk_container_forall
instead of gtk_container_foreach seems to solve the problem...so I
tried it, and it did. What other consequences this could have I dare
not say, though I can't really see how it could affect anything...

...of course, it doesn't really help me to fix it here, in my
local installation...

So, to quote the original poster: "Is that intended?"

	/mailund

-- 
[1] gtkwidget, gtktree.h, and gtktreeitem.h that is...it could be
somewhere else...

[2] A pretty obvious place to look when I think about it...



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