Blame gtk/gtktreeselection.c

Packit Service fb6fa5
/* gtktreeselection.h
Packit Service fb6fa5
 * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Library General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Library General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Library General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
#include "gtktreeselection.h"
Packit Service fb6fa5
#include "gtktreeprivate.h"
Packit Service fb6fa5
#include "gtkrbtree.h"
Packit Service fb6fa5
#include "gtkmarshalers.h"
Packit Service fb6fa5
#include "gtkintl.h"
Packit Service fb6fa5
#include "gtkalias.h"
Packit Service fb6fa5
Packit Service fb6fa5
static void gtk_tree_selection_finalize          (GObject               *object);
Packit Service fb6fa5
static gint gtk_tree_selection_real_select_all   (GtkTreeSelection      *selection);
Packit Service fb6fa5
static gint gtk_tree_selection_real_unselect_all (GtkTreeSelection      *selection);
Packit Service fb6fa5
static gint gtk_tree_selection_real_select_node  (GtkTreeSelection      *selection,
Packit Service fb6fa5
						  GtkRBTree             *tree,
Packit Service fb6fa5
						  GtkRBNode             *node,
Packit Service fb6fa5
						  gboolean               select);
Packit Service fb6fa5
Packit Service fb6fa5
enum
Packit Service fb6fa5
{
Packit Service fb6fa5
  CHANGED,
Packit Service fb6fa5
  LAST_SIGNAL
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
static guint tree_selection_signals [LAST_SIGNAL] = { 0 };
Packit Service fb6fa5
Packit Service fb6fa5
G_DEFINE_TYPE (GtkTreeSelection, gtk_tree_selection, G_TYPE_OBJECT)
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_tree_selection_class_init (GtkTreeSelectionClass *class)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GObjectClass *object_class;
Packit Service fb6fa5
Packit Service fb6fa5
  object_class = (GObjectClass*) class;
Packit Service fb6fa5
Packit Service fb6fa5
  object_class->finalize = gtk_tree_selection_finalize;
Packit Service fb6fa5
  class->changed = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  tree_selection_signals[CHANGED] =
Packit Service fb6fa5
    g_signal_new (I_("changed"),
Packit Service fb6fa5
		  G_OBJECT_CLASS_TYPE (object_class),
Packit Service fb6fa5
		  G_SIGNAL_RUN_FIRST,
Packit Service fb6fa5
		  G_STRUCT_OFFSET (GtkTreeSelectionClass, changed),
Packit Service fb6fa5
		  NULL, NULL,
Packit Service fb6fa5
		  _gtk_marshal_VOID__VOID,
Packit Service fb6fa5
		  G_TYPE_NONE, 0);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_tree_selection_init (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  selection->type = GTK_SELECTION_SINGLE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_tree_selection_finalize (GObject *object)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreeSelection *selection = GTK_TREE_SELECTION (object);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->destroy)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GDestroyNotify d = selection->destroy;
Packit Service fb6fa5
Packit Service fb6fa5
      selection->destroy = NULL;
Packit Service fb6fa5
      d (selection->user_data);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /* chain parent_class' handler */
Packit Service fb6fa5
  G_OBJECT_CLASS (gtk_tree_selection_parent_class)->finalize (object);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * _gtk_tree_selection_new:
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Creates a new #GtkTreeSelection object.  This function should not be invoked,
Packit Service fb6fa5
 * as each #GtkTreeView will create its own #GtkTreeSelection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: A newly created #GtkTreeSelection object.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkTreeSelection*
Packit Service fb6fa5
_gtk_tree_selection_new (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreeSelection *selection;
Packit Service fb6fa5
Packit Service fb6fa5
  selection = g_object_new (GTK_TYPE_TREE_SELECTION, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * _gtk_tree_selection_new_with_tree_view:
Packit Service fb6fa5
 * @tree_view: The #GtkTreeView.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Creates a new #GtkTreeSelection object.  This function should not be invoked,
Packit Service fb6fa5
 * as each #GtkTreeView will create its own #GtkTreeSelection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: A newly created #GtkTreeSelection object.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkTreeSelection*
Packit Service fb6fa5
_gtk_tree_selection_new_with_tree_view (GtkTreeView *tree_view)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreeSelection *selection;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  selection = _gtk_tree_selection_new ();
Packit Service fb6fa5
  _gtk_tree_selection_set_tree_view (selection, tree_view);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * _gtk_tree_selection_set_tree_view:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @tree_view: The #GtkTreeView.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Sets the #GtkTreeView of @selection.  This function should not be invoked, as
Packit Service fb6fa5
 * it is used internally by #GtkTreeView.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
_gtk_tree_selection_set_tree_view (GtkTreeSelection *selection,
Packit Service fb6fa5
                                   GtkTreeView      *tree_view)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  if (tree_view != NULL)
Packit Service fb6fa5
    g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
Packit Service fb6fa5
Packit Service fb6fa5
  selection->tree_view = tree_view;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_set_mode:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @type: The selection mode
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Sets the selection mode of the @selection.  If the previous type was
Packit Service fb6fa5
 * #GTK_SELECTION_MULTIPLE, then the anchor is kept selected, if it was
Packit Service fb6fa5
 * previously selected.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_set_mode (GtkTreeSelection *selection,
Packit Service fb6fa5
			     GtkSelectionMode  type)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreeSelectionFunc tmp_func;
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == type)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (type == GTK_SELECTION_NONE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* We do this so that we unconditionally unset all rows
Packit Service fb6fa5
       */
Packit Service fb6fa5
      tmp_func = selection->user_func;
Packit Service fb6fa5
      selection->user_func = NULL;
Packit Service fb6fa5
      gtk_tree_selection_unselect_all (selection);
Packit Service fb6fa5
      selection->user_func = tmp_func;
Packit Service fb6fa5
Packit Service fb6fa5
      gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
      selection->tree_view->priv->anchor = NULL;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (type == GTK_SELECTION_SINGLE ||
Packit Service fb6fa5
	   type == GTK_SELECTION_BROWSE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkRBTree *tree = NULL;
Packit Service fb6fa5
      GtkRBNode *node = NULL;
Packit Service fb6fa5
      gint selected = FALSE;
Packit Service fb6fa5
      GtkTreePath *anchor_path = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
      if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
	{
Packit Service fb6fa5
          anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
          if (anchor_path)
Packit Service fb6fa5
            {
Packit Service fb6fa5
              _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
                                        anchor_path,
Packit Service fb6fa5
                                        &tree,
Packit Service fb6fa5
                                        &node);
Packit Service fb6fa5
Packit Service fb6fa5
              if (node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
                selected = TRUE;
Packit Service fb6fa5
            }
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      /* We do this so that we unconditionally unset all rows
Packit Service fb6fa5
       */
Packit Service fb6fa5
      tmp_func = selection->user_func;
Packit Service fb6fa5
      selection->user_func = NULL;
Packit Service fb6fa5
      gtk_tree_selection_unselect_all (selection);
Packit Service fb6fa5
      selection->user_func = tmp_func;
Packit Service fb6fa5
Packit Service fb6fa5
      if (node && selected)
Packit Service fb6fa5
	_gtk_tree_selection_internal_select_node (selection,
Packit Service fb6fa5
						  node,
Packit Service fb6fa5
						  tree,
Packit Service fb6fa5
						  anchor_path,
Packit Service fb6fa5
                                                  0,
Packit Service fb6fa5
						  FALSE);
Packit Service fb6fa5
      if (anchor_path)
Packit Service fb6fa5
	gtk_tree_path_free (anchor_path);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  selection->type = type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_get_mode:
Packit Service fb6fa5
 * @selection: a #GtkTreeSelection
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Gets the selection mode for @selection. See
Packit Service fb6fa5
 * gtk_tree_selection_set_mode().
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: the current selection mode
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkSelectionMode
Packit Service fb6fa5
gtk_tree_selection_get_mode (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), GTK_SELECTION_SINGLE);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection->type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_set_select_function:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @func: The selection function.
Packit Service fb6fa5
 * @data: The selection function's data.
Packit Service fb6fa5
 * @destroy: The destroy function for user data.  May be NULL.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Sets the selection function.  If set, this function is called before any node
Packit Service fb6fa5
 * is selected or unselected, giving some control over which nodes are selected.
Packit Service fb6fa5
 * The select function should return %TRUE if the state of the node may be toggled,
Packit Service fb6fa5
 * and %FALSE if the state of the node should be left unchanged.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_set_select_function (GtkTreeSelection     *selection,
Packit Service fb6fa5
					GtkTreeSelectionFunc  func,
Packit Service fb6fa5
					gpointer              data,
Packit Service fb6fa5
					GDestroyNotify        destroy)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (func != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->destroy)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GDestroyNotify d = selection->destroy;
Packit Service fb6fa5
Packit Service fb6fa5
      selection->destroy = NULL;
Packit Service fb6fa5
      d (selection->user_data);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  selection->user_func = func;
Packit Service fb6fa5
  selection->user_data = data;
Packit Service fb6fa5
  selection->destroy = destroy;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_get_select_function: (skip)
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns the current selection function.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: The function.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.14
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkTreeSelectionFunc
Packit Service fb6fa5
gtk_tree_selection_get_select_function (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection->user_func;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_get_user_data: (skip)
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns the user data for the selection function.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: The user data.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gpointer
Packit Service fb6fa5
gtk_tree_selection_get_user_data (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection->user_data;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_get_tree_view:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Returns the tree view associated with @selection.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: (transfer none): A #GtkTreeView
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GtkTreeView *
Packit Service fb6fa5
gtk_tree_selection_get_tree_view (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return selection->tree_view;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_get_selected:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @model: (out) (allow-none) (transfer none): A pointer to set to the #GtkTreeModel, or NULL.
Packit Service fb6fa5
 * @iter: (out) (allow-none): The #GtkTreeIter, or NULL.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Sets @iter to the currently selected node if @selection is set to
Packit Service fb6fa5
 * #GTK_SELECTION_SINGLE or #GTK_SELECTION_BROWSE.  @iter may be NULL if you
Packit Service fb6fa5
 * just want to test if @selection has any selected nodes.  @model is filled
Packit Service fb6fa5
 * with the current model as a convenience.  This function will not work if you
Packit Service fb6fa5
 * use @selection is #GTK_SELECTION_MULTIPLE.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: TRUE, if there is a selected node.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_tree_selection_get_selected (GtkTreeSelection  *selection,
Packit Service fb6fa5
				 GtkTreeModel     **model,
Packit Service fb6fa5
				 GtkTreeIter       *iter)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkRBTree *tree;
Packit Service fb6fa5
  GtkRBNode *node;
Packit Service fb6fa5
  GtkTreePath *anchor_path;
Packit Service fb6fa5
  gboolean retval;
Packit Service fb6fa5
  gboolean found_node;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection->type != GTK_SELECTION_MULTIPLE, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection->tree_view != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  /* Clear the iter */
Packit Service fb6fa5
  if (iter)
Packit Service fb6fa5
    memset (iter, 0, sizeof (GtkTreeIter));
Packit Service fb6fa5
Packit Service fb6fa5
  if (model)
Packit Service fb6fa5
    *model = selection->tree_view->priv->model;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->anchor == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
  if (anchor_path == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  retval = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  found_node = !_gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
                                          anchor_path,
Packit Service fb6fa5
                                          &tree,
Packit Service fb6fa5
                                          &node);
Packit Service fb6fa5
Packit Service fb6fa5
  if (found_node && GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* we only want to return the anchor if it exists in the rbtree and
Packit Service fb6fa5
       * is selected.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      if (iter == NULL)
Packit Service fb6fa5
	retval = TRUE;
Packit Service fb6fa5
      else
Packit Service fb6fa5
        retval = gtk_tree_model_get_iter (selection->tree_view->priv->model,
Packit Service fb6fa5
                                          iter,
Packit Service fb6fa5
                                          anchor_path);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* We don't want to return the anchor if it isn't actually selected.
Packit Service fb6fa5
       */
Packit Service fb6fa5
      retval = FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  gtk_tree_path_free (anchor_path);
Packit Service fb6fa5
Packit Service fb6fa5
  return retval;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_get_selected_rows:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @model: (out) (allow-none) (transfer none): A pointer to set to the #GtkTreeModel, or %NULL.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Creates a list of path of all selected rows. Additionally, if you are
Packit Service fb6fa5
 * planning on modifying the model after calling this function, you may
Packit Service fb6fa5
 * want to convert the returned list into a list of #GtkTreeRowReferences.
Packit Service fb6fa5
 * To do this, you can use gtk_tree_row_reference_new().
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * To free the return value, use:
Packit Service fb6fa5
 * |[
Packit Service fb6fa5
 * g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
Packit Service fb6fa5
 * g_list_free (list);
Packit Service fb6fa5
 * ]|
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: (element-type GtkTreePath) (transfer full): A #GList containing a #GtkTreePath for each selected row.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.2
Packit Service fb6fa5
 **/
Packit Service fb6fa5
GList *
Packit Service fb6fa5
gtk_tree_selection_get_selected_rows (GtkTreeSelection   *selection,
Packit Service fb6fa5
                                      GtkTreeModel      **model)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GList *list = NULL;
Packit Service fb6fa5
  GtkRBTree *tree = NULL;
Packit Service fb6fa5
  GtkRBNode *node = NULL;
Packit Service fb6fa5
  GtkTreePath *path;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), NULL);
Packit Service fb6fa5
  g_return_val_if_fail (selection->tree_view != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (model)
Packit Service fb6fa5
    *model = selection->tree_view->priv->model;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->tree == NULL ||
Packit Service fb6fa5
      selection->tree_view->priv->tree->root == NULL)
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == GTK_SELECTION_NONE)
Packit Service fb6fa5
    return NULL;
Packit Service fb6fa5
  else if (selection->type != GTK_SELECTION_MULTIPLE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkTreeIter iter;
Packit Service fb6fa5
Packit Service fb6fa5
      if (gtk_tree_selection_get_selected (selection, NULL, &iter))
Packit Service fb6fa5
        {
Packit Service fb6fa5
	  GtkTreePath *path;
Packit Service fb6fa5
Packit Service fb6fa5
	  path = gtk_tree_model_get_path (selection->tree_view->priv->model, &iter);
Packit Service fb6fa5
	  list = g_list_append (list, path);
Packit Service fb6fa5
Packit Service fb6fa5
	  return list;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      return NULL;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  tree = selection->tree_view->priv->tree;
Packit Service fb6fa5
  node = selection->tree_view->priv->tree->root;
Packit Service fb6fa5
Packit Service fb6fa5
  while (node->left != tree->nil)
Packit Service fb6fa5
    node = node->left;
Packit Service fb6fa5
  path = gtk_tree_path_new_first ();
Packit Service fb6fa5
Packit Service fb6fa5
  do
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
	list = g_list_prepend (list, gtk_tree_path_copy (path));
Packit Service fb6fa5
Packit Service fb6fa5
      if (node->children)
Packit Service fb6fa5
        {
Packit Service fb6fa5
	  tree = node->children;
Packit Service fb6fa5
	  node = tree->root;
Packit Service fb6fa5
Packit Service fb6fa5
	  while (node->left != tree->nil)
Packit Service fb6fa5
	    node = node->left;
Packit Service fb6fa5
Packit Service fb6fa5
	  gtk_tree_path_append_index (path, 0);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
        {
Packit Service fb6fa5
	  gboolean done = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
	  do
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      node = _gtk_rbtree_next (tree, node);
Packit Service fb6fa5
	      if (node != NULL)
Packit Service fb6fa5
	        {
Packit Service fb6fa5
		  done = TRUE;
Packit Service fb6fa5
		  gtk_tree_path_next (path);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	      else
Packit Service fb6fa5
	        {
Packit Service fb6fa5
		  node = tree->parent_node;
Packit Service fb6fa5
		  tree = tree->parent_tree;
Packit Service fb6fa5
Packit Service fb6fa5
		  if (!tree)
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      gtk_tree_path_free (path);
Packit Service fb6fa5
Packit Service fb6fa5
		      goto done; 
Packit Service fb6fa5
		    }
Packit Service fb6fa5
Packit Service fb6fa5
		  gtk_tree_path_up (path);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  while (!done);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  while (TRUE);
Packit Service fb6fa5
Packit Service fb6fa5
  gtk_tree_path_free (path);
Packit Service fb6fa5
Packit Service fb6fa5
 done:
Packit Service fb6fa5
  return g_list_reverse (list);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gtk_tree_selection_count_selected_rows_helper (GtkRBTree *tree,
Packit Service fb6fa5
					       GtkRBNode *node,
Packit Service fb6fa5
					       gpointer   data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint *count = (gint *)data;
Packit Service fb6fa5
Packit Service fb6fa5
  if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
    (*count)++;
Packit Service fb6fa5
Packit Service fb6fa5
  if (node->children)
Packit Service fb6fa5
    _gtk_rbtree_traverse (node->children, node->children->root,
Packit Service fb6fa5
			  G_PRE_ORDER,
Packit Service fb6fa5
			  gtk_tree_selection_count_selected_rows_helper, data);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_count_selected_rows:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Returns the number of rows that have been selected in @tree.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Return value: The number of rows selected.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Since: 2.2
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gint
Packit Service fb6fa5
gtk_tree_selection_count_selected_rows (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint count = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), 0);
Packit Service fb6fa5
  g_return_val_if_fail (selection->tree_view != NULL, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->tree == NULL ||
Packit Service fb6fa5
      selection->tree_view->priv->tree->root == NULL)
Packit Service fb6fa5
    return 0;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == GTK_SELECTION_SINGLE ||
Packit Service fb6fa5
      selection->type == GTK_SELECTION_BROWSE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (gtk_tree_selection_get_selected (selection, NULL, NULL))
Packit Service fb6fa5
	return 1;
Packit Service fb6fa5
      else
Packit Service fb6fa5
	return 0;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  _gtk_rbtree_traverse (selection->tree_view->priv->tree,
Packit Service fb6fa5
                        selection->tree_view->priv->tree->root,
Packit Service fb6fa5
			G_PRE_ORDER,
Packit Service fb6fa5
			gtk_tree_selection_count_selected_rows_helper,
Packit Service fb6fa5
			&count);
Packit Service fb6fa5
Packit Service fb6fa5
  return count;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* gtk_tree_selection_selected_foreach helper */
Packit Service fb6fa5
static void
Packit Service fb6fa5
model_changed (gpointer data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gboolean *stop = (gboolean *)data;
Packit Service fb6fa5
Packit Service fb6fa5
  *stop = TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_selected_foreach:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @func: (scope call): The function to call for each selected node.
Packit Service fb6fa5
 * @data: user data to pass to the function.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Calls a function for each selected node. Note that you cannot modify
Packit Service fb6fa5
 * the tree or selection from within this function. As a result,
Packit Service fb6fa5
 * gtk_tree_selection_get_selected_rows() might be more useful.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_selected_foreach (GtkTreeSelection            *selection,
Packit Service fb6fa5
				     GtkTreeSelectionForeachFunc  func,
Packit Service fb6fa5
				     gpointer                     data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreePath *path;
Packit Service fb6fa5
  GtkRBTree *tree;
Packit Service fb6fa5
  GtkRBNode *node;
Packit Service fb6fa5
  GtkTreeIter iter;
Packit Service fb6fa5
  GtkTreeModel *model;
Packit Service fb6fa5
Packit Service fb6fa5
  gulong inserted_id, deleted_id, reordered_id, changed_id;
Packit Service fb6fa5
  gboolean stop = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (func == NULL ||
Packit Service fb6fa5
      selection->tree_view->priv->tree == NULL ||
Packit Service fb6fa5
      selection->tree_view->priv->tree->root == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == GTK_SELECTION_SINGLE ||
Packit Service fb6fa5
      selection->type == GTK_SELECTION_BROWSE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (gtk_tree_row_reference_valid (selection->tree_view->priv->anchor))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
Packit Service fb6fa5
	  gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path);
Packit Service fb6fa5
	  (* func) (selection->tree_view->priv->model, path, &iter, data);
Packit Service fb6fa5
	  gtk_tree_path_free (path);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      return;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  tree = selection->tree_view->priv->tree;
Packit Service fb6fa5
  node = selection->tree_view->priv->tree->root;
Packit Service fb6fa5
  
Packit Service fb6fa5
  while (node->left != tree->nil)
Packit Service fb6fa5
    node = node->left;
Packit Service fb6fa5
Packit Service fb6fa5
  model = selection->tree_view->priv->model;
Packit Service fb6fa5
  g_object_ref (model);
Packit Service fb6fa5
Packit Service fb6fa5
  /* connect to signals to monitor changes in treemodel */
Packit Service fb6fa5
  inserted_id = g_signal_connect_swapped (model, "row-inserted",
Packit Service fb6fa5
					  G_CALLBACK (model_changed),
Packit Service fb6fa5
				          &stop);
Packit Service fb6fa5
  deleted_id = g_signal_connect_swapped (model, "row-deleted",
Packit Service fb6fa5
					 G_CALLBACK (model_changed),
Packit Service fb6fa5
				         &stop);
Packit Service fb6fa5
  reordered_id = g_signal_connect_swapped (model, "rows-reordered",
Packit Service fb6fa5
					   G_CALLBACK (model_changed),
Packit Service fb6fa5
				           &stop);
Packit Service fb6fa5
  changed_id = g_signal_connect_swapped (selection->tree_view, "notify::model",
Packit Service fb6fa5
					 G_CALLBACK (model_changed), 
Packit Service fb6fa5
					 &stop);
Packit Service fb6fa5
Packit Service fb6fa5
  /* find the node internally */
Packit Service fb6fa5
  path = gtk_tree_path_new_first ();
Packit Service fb6fa5
Packit Service fb6fa5
  do
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
        {
Packit Service fb6fa5
          gtk_tree_model_get_iter (model, &iter, path);
Packit Service fb6fa5
	  (* func) (model, path, &iter, data);
Packit Service fb6fa5
        }
Packit Service fb6fa5
Packit Service fb6fa5
      if (stop)
Packit Service fb6fa5
	goto out;
Packit Service fb6fa5
Packit Service fb6fa5
      if (node->children)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  tree = node->children;
Packit Service fb6fa5
	  node = tree->root;
Packit Service fb6fa5
Packit Service fb6fa5
	  while (node->left != tree->nil)
Packit Service fb6fa5
	    node = node->left;
Packit Service fb6fa5
Packit Service fb6fa5
	  gtk_tree_path_append_index (path, 0);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gboolean done = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
	  do
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      node = _gtk_rbtree_next (tree, node);
Packit Service fb6fa5
	      if (node != NULL)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  done = TRUE;
Packit Service fb6fa5
		  gtk_tree_path_next (path);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	      else
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  node = tree->parent_node;
Packit Service fb6fa5
		  tree = tree->parent_tree;
Packit Service fb6fa5
Packit Service fb6fa5
		  if (tree == NULL)
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      /* we've run out of tree */
Packit Service fb6fa5
		      /* We're done with this function */
Packit Service fb6fa5
Packit Service fb6fa5
		      goto out;
Packit Service fb6fa5
		    }
Packit Service fb6fa5
Packit Service fb6fa5
		  gtk_tree_path_up (path);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  while (!done);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  while (TRUE);
Packit Service fb6fa5
Packit Service fb6fa5
out:
Packit Service fb6fa5
  if (path)
Packit Service fb6fa5
    gtk_tree_path_free (path);
Packit Service fb6fa5
Packit Service fb6fa5
  g_signal_handler_disconnect (model, inserted_id);
Packit Service fb6fa5
  g_signal_handler_disconnect (model, deleted_id);
Packit Service fb6fa5
  g_signal_handler_disconnect (model, reordered_id);
Packit Service fb6fa5
  g_signal_handler_disconnect (selection->tree_view, changed_id);
Packit Service fb6fa5
  g_object_unref (model);
Packit Service fb6fa5
Packit Service fb6fa5
  /* check if we have to spew a scary message */
Packit Service fb6fa5
  if (stop)
Packit Service fb6fa5
    g_warning ("The model has been modified from within gtk_tree_selection_selected_foreach.\n"
Packit Service fb6fa5
	       "This function is for observing the selections of the tree only.  If\n"
Packit Service fb6fa5
	       "you are trying to get all selected items from the tree, try using\n"
Packit Service fb6fa5
	       "gtk_tree_selection_get_selected_rows instead.\n");
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_select_path:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @path: The #GtkTreePath to be selected.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Select the row at @path.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_select_path (GtkTreeSelection *selection,
Packit Service fb6fa5
				GtkTreePath      *path)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkRBNode *node;
Packit Service fb6fa5
  GtkRBTree *tree;
Packit Service fb6fa5
  gboolean ret;
Packit Service fb6fa5
  GtkTreeSelectMode mode = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
  g_return_if_fail (path != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  ret = _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				  path,
Packit Service fb6fa5
				  &tree,
Packit Service fb6fa5
				  &node);
Packit Service fb6fa5
Packit Service fb6fa5
  if (node == NULL || GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) ||
Packit Service fb6fa5
      ret == TRUE)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == GTK_SELECTION_MULTIPLE)
Packit Service fb6fa5
    mode = GTK_TREE_SELECT_MODE_TOGGLE;
Packit Service fb6fa5
Packit Service fb6fa5
  _gtk_tree_selection_internal_select_node (selection,
Packit Service fb6fa5
					    node,
Packit Service fb6fa5
					    tree,
Packit Service fb6fa5
					    path,
Packit Service fb6fa5
                                            mode,
Packit Service fb6fa5
					    FALSE);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_unselect_path:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @path: The #GtkTreePath to be unselected.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Unselects the row at @path.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_unselect_path (GtkTreeSelection *selection,
Packit Service fb6fa5
				  GtkTreePath      *path)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkRBNode *node;
Packit Service fb6fa5
  GtkRBTree *tree;
Packit Service fb6fa5
  gboolean ret;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
  g_return_if_fail (path != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  ret = _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				  path,
Packit Service fb6fa5
				  &tree,
Packit Service fb6fa5
				  &node);
Packit Service fb6fa5
Packit Service fb6fa5
  if (node == NULL || !GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) ||
Packit Service fb6fa5
      ret == TRUE)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  _gtk_tree_selection_internal_select_node (selection,
Packit Service fb6fa5
					    node,
Packit Service fb6fa5
					    tree,
Packit Service fb6fa5
					    path,
Packit Service fb6fa5
                                            GTK_TREE_SELECT_MODE_TOGGLE,
Packit Service fb6fa5
					    TRUE);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_select_iter:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @iter: The #GtkTreeIter to be selected.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Selects the specified iterator.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_select_iter (GtkTreeSelection *selection,
Packit Service fb6fa5
				GtkTreeIter      *iter)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreePath *path;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view->priv->model != NULL);
Packit Service fb6fa5
  g_return_if_fail (iter != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  path = gtk_tree_model_get_path (selection->tree_view->priv->model,
Packit Service fb6fa5
				  iter);
Packit Service fb6fa5
Packit Service fb6fa5
  if (path == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  gtk_tree_selection_select_path (selection, path);
Packit Service fb6fa5
  gtk_tree_path_free (path);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_unselect_iter:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @iter: The #GtkTreeIter to be unselected.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Unselects the specified iterator.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_unselect_iter (GtkTreeSelection *selection,
Packit Service fb6fa5
				  GtkTreeIter      *iter)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreePath *path;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view->priv->model != NULL);
Packit Service fb6fa5
  g_return_if_fail (iter != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  path = gtk_tree_model_get_path (selection->tree_view->priv->model,
Packit Service fb6fa5
				  iter);
Packit Service fb6fa5
Packit Service fb6fa5
  if (path == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  gtk_tree_selection_unselect_path (selection, path);
Packit Service fb6fa5
  gtk_tree_path_free (path);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_path_is_selected:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @path: A #GtkTreePath to check selection on.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Returns %TRUE if the row pointed to by @path is currently selected.  If @path
Packit Service fb6fa5
 * does not point to a valid location, %FALSE is returned
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE if @path is selected.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_tree_selection_path_is_selected (GtkTreeSelection *selection,
Packit Service fb6fa5
				     GtkTreePath      *path)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkRBNode *node;
Packit Service fb6fa5
  GtkRBTree *tree;
Packit Service fb6fa5
  gboolean ret;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (path != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection->tree_view != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->model == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  ret = _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				  path,
Packit Service fb6fa5
				  &tree,
Packit Service fb6fa5
				  &node);
Packit Service fb6fa5
Packit Service fb6fa5
  if ((node == NULL) || !GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) ||
Packit Service fb6fa5
      ret == TRUE)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_iter_is_selected:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection
Packit Service fb6fa5
 * @iter: A valid #GtkTreeIter
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Returns %TRUE if the row at @iter is currently selected.
Packit Service fb6fa5
 * 
Packit Service fb6fa5
 * Return value: %TRUE, if @iter is selected
Packit Service fb6fa5
 **/
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gtk_tree_selection_iter_is_selected (GtkTreeSelection *selection,
Packit Service fb6fa5
				     GtkTreeIter      *iter)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreePath *path;
Packit Service fb6fa5
  gboolean retval;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GTK_IS_TREE_SELECTION (selection), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (iter != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection->tree_view != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (selection->tree_view->priv->model != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  path = gtk_tree_model_get_path (selection->tree_view->priv->model, iter);
Packit Service fb6fa5
  if (path == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  retval = gtk_tree_selection_path_is_selected (selection, path);
Packit Service fb6fa5
  gtk_tree_path_free (path);
Packit Service fb6fa5
Packit Service fb6fa5
  return retval;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/* Wish I was in python, right now... */
Packit Service fb6fa5
struct _TempTuple {
Packit Service fb6fa5
  GtkTreeSelection *selection;
Packit Service fb6fa5
  gint dirty;
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
select_all_helper (GtkRBTree  *tree,
Packit Service fb6fa5
		   GtkRBNode  *node,
Packit Service fb6fa5
		   gpointer    data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  struct _TempTuple *tuple = data;
Packit Service fb6fa5
Packit Service fb6fa5
  if (node->children)
Packit Service fb6fa5
    _gtk_rbtree_traverse (node->children,
Packit Service fb6fa5
			  node->children->root,
Packit Service fb6fa5
			  G_PRE_ORDER,
Packit Service fb6fa5
			  select_all_helper,
Packit Service fb6fa5
			  data);
Packit Service fb6fa5
  if (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tuple->dirty = gtk_tree_selection_real_select_node (tuple->selection, tree, node, TRUE) || tuple->dirty;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/* We have a real_{un,}select_all function that doesn't emit the signal, so we
Packit Service fb6fa5
 * can use it in other places without fear of the signal being emitted.
Packit Service fb6fa5
 */
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gtk_tree_selection_real_select_all (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  struct _TempTuple *tuple;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->tree == NULL)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Mark all nodes selected */
Packit Service fb6fa5
  tuple = g_new (struct _TempTuple, 1);
Packit Service fb6fa5
  tuple->selection = selection;
Packit Service fb6fa5
  tuple->dirty = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  _gtk_rbtree_traverse (selection->tree_view->priv->tree,
Packit Service fb6fa5
			selection->tree_view->priv->tree->root,
Packit Service fb6fa5
			G_PRE_ORDER,
Packit Service fb6fa5
			select_all_helper,
Packit Service fb6fa5
			tuple);
Packit Service fb6fa5
  if (tuple->dirty)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      g_free (tuple);
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  g_free (tuple);
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_select_all:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Selects all the nodes. @selection must be set to #GTK_SELECTION_MULTIPLE
Packit Service fb6fa5
 * mode.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_select_all (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->tree == NULL || selection->tree_view->priv->model == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (selection->type == GTK_SELECTION_MULTIPLE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_tree_selection_real_select_all (selection))
Packit Service fb6fa5
    g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
unselect_all_helper (GtkRBTree  *tree,
Packit Service fb6fa5
		     GtkRBNode  *node,
Packit Service fb6fa5
		     gpointer    data)
Packit Service fb6fa5
{
Packit Service fb6fa5
  struct _TempTuple *tuple = data;
Packit Service fb6fa5
Packit Service fb6fa5
  if (node->children)
Packit Service fb6fa5
    _gtk_rbtree_traverse (node->children,
Packit Service fb6fa5
			  node->children->root,
Packit Service fb6fa5
			  G_PRE_ORDER,
Packit Service fb6fa5
			  unselect_all_helper,
Packit Service fb6fa5
			  data);
Packit Service fb6fa5
  if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tuple->dirty = gtk_tree_selection_real_select_node (tuple->selection, tree, node, FALSE) || tuple->dirty;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
gtk_tree_selection_real_unselect_all (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  struct _TempTuple *tuple;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == GTK_SELECTION_SINGLE ||
Packit Service fb6fa5
      selection->type == GTK_SELECTION_BROWSE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      GtkRBTree *tree = NULL;
Packit Service fb6fa5
      GtkRBNode *node = NULL;
Packit Service fb6fa5
      GtkTreePath *anchor_path;
Packit Service fb6fa5
Packit Service fb6fa5
      if (selection->tree_view->priv->anchor == NULL)
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
      if (anchor_path == NULL)
Packit Service fb6fa5
        return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
                                anchor_path,
Packit Service fb6fa5
				&tree,
Packit Service fb6fa5
				&node);
Packit Service fb6fa5
Packit Service fb6fa5
      gtk_tree_path_free (anchor_path);
Packit Service fb6fa5
Packit Service fb6fa5
      if (tree == NULL)
Packit Service fb6fa5
        return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (gtk_tree_selection_real_select_node (selection, tree, node, FALSE))
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
	      selection->tree_view->priv->anchor = NULL;
Packit Service fb6fa5
	      return TRUE;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      tuple = g_new (struct _TempTuple, 1);
Packit Service fb6fa5
      tuple->selection = selection;
Packit Service fb6fa5
      tuple->dirty = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      _gtk_rbtree_traverse (selection->tree_view->priv->tree,
Packit Service fb6fa5
                            selection->tree_view->priv->tree->root,
Packit Service fb6fa5
                            G_PRE_ORDER,
Packit Service fb6fa5
                            unselect_all_helper,
Packit Service fb6fa5
                            tuple);
Packit Service fb6fa5
Packit Service fb6fa5
      if (tuple->dirty)
Packit Service fb6fa5
        {
Packit Service fb6fa5
          g_free (tuple);
Packit Service fb6fa5
          return TRUE;
Packit Service fb6fa5
        }
Packit Service fb6fa5
      g_free (tuple);
Packit Service fb6fa5
      return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_unselect_all:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Unselects all the nodes.
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_unselect_all (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->tree == NULL || selection->tree_view->priv->model == NULL)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (gtk_tree_selection_real_unselect_all (selection))
Packit Service fb6fa5
    g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
enum
Packit Service fb6fa5
{
Packit Service fb6fa5
  RANGE_SELECT,
Packit Service fb6fa5
  RANGE_UNSELECT
Packit Service fb6fa5
};
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gtk_tree_selection_real_modify_range (GtkTreeSelection *selection,
Packit Service fb6fa5
                                      gint              mode,
Packit Service fb6fa5
				      GtkTreePath      *start_path,
Packit Service fb6fa5
				      GtkTreePath      *end_path)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkRBNode *start_node, *end_node;
Packit Service fb6fa5
  GtkRBTree *start_tree, *end_tree;
Packit Service fb6fa5
  GtkTreePath *anchor_path = NULL;
Packit Service fb6fa5
  gboolean dirty = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  switch (gtk_tree_path_compare (start_path, end_path))
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case 1:
Packit Service fb6fa5
      _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				end_path,
Packit Service fb6fa5
				&start_tree,
Packit Service fb6fa5
				&start_node);
Packit Service fb6fa5
      _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				start_path,
Packit Service fb6fa5
				&end_tree,
Packit Service fb6fa5
				&end_node);
Packit Service fb6fa5
      anchor_path = start_path;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    case 0:
Packit Service fb6fa5
      _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				start_path,
Packit Service fb6fa5
				&start_tree,
Packit Service fb6fa5
				&start_node);
Packit Service fb6fa5
      end_tree = start_tree;
Packit Service fb6fa5
      end_node = start_node;
Packit Service fb6fa5
      anchor_path = start_path;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    case -1:
Packit Service fb6fa5
      _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				start_path,
Packit Service fb6fa5
				&start_tree,
Packit Service fb6fa5
				&start_node);
Packit Service fb6fa5
      _gtk_tree_view_find_node (selection->tree_view,
Packit Service fb6fa5
				end_path,
Packit Service fb6fa5
				&end_tree,
Packit Service fb6fa5
				&end_node);
Packit Service fb6fa5
      anchor_path = start_path;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (start_node != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (end_node != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  if (anchor_path)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
	gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
      selection->tree_view->priv->anchor =
Packit Service fb6fa5
	gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view),
Packit Service fb6fa5
	                                  selection->tree_view->priv->model,
Packit Service fb6fa5
					  anchor_path);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  do
Packit Service fb6fa5
    {
Packit Service fb6fa5
      dirty |= gtk_tree_selection_real_select_node (selection, start_tree, start_node, (mode == RANGE_SELECT)?TRUE:FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
      if (start_node == end_node)
Packit Service fb6fa5
	break;
Packit Service fb6fa5
Packit Service fb6fa5
      if (start_node->children)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  start_tree = start_node->children;
Packit Service fb6fa5
	  start_node = start_tree->root;
Packit Service fb6fa5
	  while (start_node->left != start_tree->nil)
Packit Service fb6fa5
	    start_node = start_node->left;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  _gtk_rbtree_next_full (start_tree, start_node, &start_tree, &start_node);
Packit Service fb6fa5
	  if (start_tree == NULL)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      /* we just ran out of tree.  That means someone passed in bogus values.
Packit Service fb6fa5
	       */
Packit Service fb6fa5
	      return dirty;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  while (TRUE);
Packit Service fb6fa5
Packit Service fb6fa5
  return dirty;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_select_range:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @start_path: The initial node of the range.
Packit Service fb6fa5
 * @end_path: The final node of the range.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Selects a range of nodes, determined by @start_path and @end_path inclusive.
Packit Service fb6fa5
 * @selection must be set to #GTK_SELECTION_MULTIPLE mode. 
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_select_range (GtkTreeSelection *selection,
Packit Service fb6fa5
				 GtkTreePath      *start_path,
Packit Service fb6fa5
				 GtkTreePath      *end_path)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
  g_return_if_fail (selection->type == GTK_SELECTION_MULTIPLE);
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view->priv->model != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_tree_selection_real_modify_range (selection, RANGE_SELECT, start_path, end_path))
Packit Service fb6fa5
    g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/**
Packit Service fb6fa5
 * gtk_tree_selection_unselect_range:
Packit Service fb6fa5
 * @selection: A #GtkTreeSelection.
Packit Service fb6fa5
 * @start_path: The initial node of the range.
Packit Service fb6fa5
 * @end_path: The initial node of the range.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Unselects a range of nodes, determined by @start_path and @end_path
Packit Service fb6fa5
 * inclusive.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * Since: 2.2
Packit Service fb6fa5
 **/
Packit Service fb6fa5
void
Packit Service fb6fa5
gtk_tree_selection_unselect_range (GtkTreeSelection *selection,
Packit Service fb6fa5
                                   GtkTreePath      *start_path,
Packit Service fb6fa5
				   GtkTreePath      *end_path)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view != NULL);
Packit Service fb6fa5
  g_return_if_fail (selection->tree_view->priv->model != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (gtk_tree_selection_real_modify_range (selection, RANGE_UNSELECT, start_path, end_path))
Packit Service fb6fa5
    g_signal_emit (selection, tree_selection_signals[CHANGED], 0);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
_gtk_tree_selection_row_is_selectable (GtkTreeSelection *selection,
Packit Service fb6fa5
				       GtkRBNode        *node,
Packit Service fb6fa5
				       GtkTreePath      *path)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GtkTreeIter iter;
Packit Service fb6fa5
  gboolean sensitive = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!gtk_tree_model_get_iter (selection->tree_view->priv->model, &iter, path))
Packit Service fb6fa5
    sensitive = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!sensitive && selection->tree_view->priv->row_separator_func)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* never allow separators to be selected */
Packit Service fb6fa5
      if ((* selection->tree_view->priv->row_separator_func) (selection->tree_view->priv->model,
Packit Service fb6fa5
							      &iter,
Packit Service fb6fa5
							      selection->tree_view->priv->row_separator_data))
Packit Service fb6fa5
	return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->user_func)
Packit Service fb6fa5
    return (*selection->user_func) (selection, selection->tree_view->priv->model, path,
Packit Service fb6fa5
				    GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED),
Packit Service fb6fa5
				    selection->user_data);
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
/* Called internally by gtktreeview.c It handles actually selecting the tree.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * docs about the 'override_browse_mode', we set this flag when we want to
Packit Service fb6fa5
 * unset select the node and override the select browse mode behaviour (that is
Packit Service fb6fa5
 * 'one node should *always* be selected').
Packit Service fb6fa5
 */
Packit Service fb6fa5
void
Packit Service fb6fa5
_gtk_tree_selection_internal_select_node (GtkTreeSelection *selection,
Packit Service fb6fa5
					  GtkRBNode        *node,
Packit Service fb6fa5
					  GtkRBTree        *tree,
Packit Service fb6fa5
					  GtkTreePath      *path,
Packit Service fb6fa5
                                          GtkTreeSelectMode mode,
Packit Service fb6fa5
					  gboolean          override_browse_mode)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gint flags;
Packit Service fb6fa5
  gint dirty = FALSE;
Packit Service fb6fa5
  GtkTreePath *anchor_path = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == GTK_SELECTION_NONE)
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
    anchor_path = gtk_tree_row_reference_get_path (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
  if (selection->type == GTK_SELECTION_SINGLE ||
Packit Service fb6fa5
      selection->type == GTK_SELECTION_BROWSE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* just unselect */
Packit Service fb6fa5
      if (selection->type == GTK_SELECTION_BROWSE && override_browse_mode)
Packit Service fb6fa5
        {
Packit Service fb6fa5
	  dirty = gtk_tree_selection_real_unselect_all (selection);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      /* Did we try to select the same node again? */
Packit Service fb6fa5
      else if (selection->type == GTK_SELECTION_SINGLE &&
Packit Service fb6fa5
	       anchor_path && gtk_tree_path_compare (path, anchor_path) == 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if ((mode & GTK_TREE_SELECT_MODE_TOGGLE) == GTK_TREE_SELECT_MODE_TOGGLE)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      dirty = gtk_tree_selection_real_unselect_all (selection);
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (anchor_path)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      /* We only want to select the new node if we can unselect the old one,
Packit Service fb6fa5
	       * and we can select the new one. */
Packit Service fb6fa5
	      dirty = _gtk_tree_selection_row_is_selectable (selection, node, path);
Packit Service fb6fa5
Packit Service fb6fa5
	      /* if dirty is FALSE, we weren't able to select the new one, otherwise, we try to
Packit Service fb6fa5
	       * unselect the new one
Packit Service fb6fa5
	       */
Packit Service fb6fa5
	      if (dirty)
Packit Service fb6fa5
		dirty = gtk_tree_selection_real_unselect_all (selection);
Packit Service fb6fa5
Packit Service fb6fa5
	      /* if dirty is TRUE at this point, we successfully unselected the
Packit Service fb6fa5
	       * old one, and can then select the new one */
Packit Service fb6fa5
	      if (dirty)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
                    {
Packit Service fb6fa5
                      gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
                      selection->tree_view->priv->anchor = NULL;
Packit Service fb6fa5
                    }
Packit Service fb6fa5
Packit Service fb6fa5
		  if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      selection->tree_view->priv->anchor =
Packit Service fb6fa5
			gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      if (gtk_tree_selection_real_select_node (selection, tree, node, TRUE))
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  dirty = TRUE;
Packit Service fb6fa5
		  if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
		    gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
		  selection->tree_view->priv->anchor =
Packit Service fb6fa5
		    gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else if (selection->type == GTK_SELECTION_MULTIPLE)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if ((mode & GTK_TREE_SELECT_MODE_EXTEND) == GTK_TREE_SELECT_MODE_EXTEND
Packit Service fb6fa5
          && (anchor_path == NULL))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
	    gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
	  selection->tree_view->priv->anchor =
Packit Service fb6fa5
	    gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
Packit Service fb6fa5
	  dirty = gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else if ((mode & (GTK_TREE_SELECT_MODE_EXTEND | GTK_TREE_SELECT_MODE_TOGGLE)) == (GTK_TREE_SELECT_MODE_EXTEND | GTK_TREE_SELECT_MODE_TOGGLE))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  gtk_tree_selection_select_range (selection,
Packit Service fb6fa5
					   anchor_path,
Packit Service fb6fa5
					   path);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else if ((mode & GTK_TREE_SELECT_MODE_TOGGLE) == GTK_TREE_SELECT_MODE_TOGGLE)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  flags = node->flags;
Packit Service fb6fa5
	  if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
	    gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
	  selection->tree_view->priv->anchor =
Packit Service fb6fa5
	    gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
Packit Service fb6fa5
Packit Service fb6fa5
	  if ((flags & GTK_RBNODE_IS_SELECTED) == GTK_RBNODE_IS_SELECTED)
Packit Service fb6fa5
	    dirty |= gtk_tree_selection_real_select_node (selection, tree, node, FALSE);
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else if ((mode & GTK_TREE_SELECT_MODE_EXTEND) == GTK_TREE_SELECT_MODE_EXTEND)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  dirty = gtk_tree_selection_real_unselect_all (selection);
Packit Service fb6fa5
	  dirty |= gtk_tree_selection_real_modify_range (selection,
Packit Service fb6fa5
                                                         RANGE_SELECT,
Packit Service fb6fa5
							 anchor_path,
Packit Service fb6fa5
							 path);
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  dirty = gtk_tree_selection_real_unselect_all (selection);
Packit Service fb6fa5
Packit Service fb6fa5
	  if (selection->tree_view->priv->anchor)
Packit Service fb6fa5
	    gtk_tree_row_reference_free (selection->tree_view->priv->anchor);
Packit Service fb6fa5
Packit Service fb6fa5
	  selection->tree_view->priv->anchor =
Packit Service fb6fa5
	    gtk_tree_row_reference_new_proxy (G_OBJECT (selection->tree_view), selection->tree_view->priv->model, path);
Packit Service fb6fa5
Packit Service fb6fa5
	  dirty |= gtk_tree_selection_real_select_node (selection, tree, node, TRUE);
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (anchor_path)
Packit Service fb6fa5
    gtk_tree_path_free (anchor_path);
Packit Service fb6fa5
Packit Service fb6fa5
  if (dirty)
Packit Service fb6fa5
    g_signal_emit (selection, tree_selection_signals[CHANGED], 0);  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
void 
Packit Service fb6fa5
_gtk_tree_selection_emit_changed (GtkTreeSelection *selection)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_signal_emit (selection, tree_selection_signals[CHANGED], 0);  
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* NOTE: Any {un,}selection ever done _MUST_ be done through this function!
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gtk_tree_selection_real_select_node (GtkTreeSelection *selection,
Packit Service fb6fa5
				     GtkRBTree        *tree,
Packit Service fb6fa5
				     GtkRBNode        *node,
Packit Service fb6fa5
				     gboolean          select)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gboolean toggle = FALSE;
Packit Service fb6fa5
  GtkTreePath *path = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  select = !! select;
Packit Service fb6fa5
Packit Service fb6fa5
  if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) != select)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      path = _gtk_tree_view_find_path (selection->tree_view, tree, node);
Packit Service fb6fa5
      toggle = _gtk_tree_selection_row_is_selectable (selection, node, path);
Packit Service fb6fa5
      gtk_tree_path_free (path);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (toggle)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      node->flags ^= GTK_RBNODE_IS_SELECTED;
Packit Service fb6fa5
Packit Service fb6fa5
      _gtk_tree_view_queue_draw_node (selection->tree_view, tree, node, NULL);
Packit Service fb6fa5
      
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
#define __GTK_TREE_SELECTION_C__
Packit Service fb6fa5
#include "gtkaliasdef.c"