]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreeselection.c
filechooser: Use _gtk_file_has_native_path() throughout when testing for local_only
[~andy/gtk] / gtk / gtktreeselection.c
index 1ec2000a17956246180910899d7add4bf87bd45e..10c9cd717a6908cf686251f22bd0ee58fb1e49d4 100644 (file)
@@ -12,9 +12,7 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 #include "config.h"
@@ -24,6 +22,8 @@
 #include "gtkrbtree.h"
 #include "gtkmarshalers.h"
 #include "gtkintl.h"
+#include "gtktypebuiltins.h"
+#include "a11y/gtktreeviewaccessibleprivate.h"
 
 
 /**
@@ -54,7 +54,7 @@
  *
  * One of the important things to remember when monitoring the selection of
  * a view is that the #GtkTreeSelection::changed signal is mostly a hint.
- * That is,it may only emit one signal when a range of rows is selected.
+ * That is, it may only emit one signal when a range of rows is selected.
  * Additionally, it may on occasion emit a #GtkTreeSelection::changed signal
  * when nothing has happened (mostly as a result of programmers calling
  * select_row on an already selected row).
@@ -76,6 +76,21 @@ static gint gtk_tree_selection_real_select_node  (GtkTreeSelection      *selecti
                                                  GtkRBTree             *tree,
                                                  GtkRBNode             *node,
                                                  gboolean               select);
+static void gtk_tree_selection_set_property      (GObject               *object,
+                                                  guint                  prop_id,
+                                                  const GValue          *value,
+                                                  GParamSpec            *pspec);
+static void gtk_tree_selection_get_property      (GObject               *object,
+                                                  guint                  prop_id,
+                                                  GValue                *value,
+                                                  GParamSpec            *pspec);
+
+enum
+{
+  PROP_0,
+  PROP_MODE,
+  N_PROPERTIES
+};
 
 enum
 {
@@ -83,6 +98,7 @@ enum
   LAST_SIGNAL
 };
 
+static GParamSpec *properties[N_PROPERTIES];
 static guint tree_selection_signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (GtkTreeSelection, gtk_tree_selection, G_TYPE_OBJECT)
@@ -95,8 +111,33 @@ gtk_tree_selection_class_init (GtkTreeSelectionClass *class)
   object_class = (GObjectClass*) class;
 
   object_class->finalize = gtk_tree_selection_finalize;
+  object_class->set_property = gtk_tree_selection_set_property;
+  object_class->get_property = gtk_tree_selection_get_property;
   class->changed = NULL;
 
+  /* Properties */
+  
+  /**
+   * GtkTreeSelection:mode:
+   *
+   * Selection mode.
+   * See gtk_tree_selection_set_mode() for more information on this property.
+   *
+   * Since: 3.2
+   */
+  properties[PROP_MODE] = g_param_spec_enum ("mode",
+                                             P_("Mode"),
+                                             P_("Selection mode"),
+                                             GTK_TYPE_SELECTION_MODE,
+                                             GTK_SELECTION_SINGLE,
+                                             G_PARAM_READWRITE |
+                                             G_PARAM_STATIC_STRINGS);
+
+  /* Install all properties */
+  g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+  
+  /* Signals */
+  
   /**
    * GtkTreeSelection::changed:
    * @treeselection: the object which received the signal.
@@ -144,6 +185,44 @@ gtk_tree_selection_finalize (GObject *object)
   G_OBJECT_CLASS (gtk_tree_selection_parent_class)->finalize (object);
 }
 
+static void
+gtk_tree_selection_set_property (GObject *object,
+                                 guint prop_id,
+                                 const GValue *value,
+                                 GParamSpec *pspec)
+{
+  g_return_if_fail (GTK_IS_TREE_SELECTION (object));
+
+  switch (prop_id)
+    {
+      case PROP_MODE:
+        gtk_tree_selection_set_mode (GTK_TREE_SELECTION (object), g_value_get_enum (value));
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+gtk_tree_selection_get_property (GObject *object,
+                                 guint prop_id,
+                                 GValue *value,
+                                 GParamSpec *pspec)
+{
+  g_return_if_fail (GTK_IS_TREE_SELECTION (object));
+
+  switch (prop_id)
+    {
+      case PROP_MODE:
+        g_value_set_enum (value, gtk_tree_selection_get_mode (GTK_TREE_SELECTION (object)));
+        break;
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
 /**
  * _gtk_tree_selection_new:
  *
@@ -281,6 +360,8 @@ gtk_tree_selection_set_mode (GtkTreeSelection *selection,
     }
 
   priv->type = type;
+  
+  g_object_notify_by_pspec (G_OBJECT (selection), properties[PROP_MODE]);
 }
 
 /**
@@ -472,8 +553,7 @@ gtk_tree_selection_get_selected (GtkTreeSelection  *selection,
  *
  * To free the return value, use:
  * |[
- * g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
- * g_list_free (list);
+ * g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free);
  * ]|
  *
  * Return value: (element-type GtkTreePath) (transfer full): A #GList containing a #GtkTreePath for each selected row.
@@ -523,10 +603,7 @@ gtk_tree_selection_get_selected_rows (GtkTreeSelection   *selection,
       return NULL;
     }
 
-  node = tree->root;
-
-  while (node->left != tree->nil)
-    node = node->left;
+  node = _gtk_rbtree_first (tree);
   path = gtk_tree_path_new_first ();
 
   do
@@ -537,10 +614,7 @@ gtk_tree_selection_get_selected_rows (GtkTreeSelection   *selection,
       if (node->children)
         {
          tree = node->children;
-         node = tree->root;
-
-         while (node->left != tree->nil)
-           node = node->left;
+          node = _gtk_rbtree_first (tree);
 
          gtk_tree_path_append_index (path, 0);
        }
@@ -704,10 +778,7 @@ gtk_tree_selection_selected_foreach (GtkTreeSelection            *selection,
       return;
     }
 
-  node = tree->root;
-  
-  while (node->left != tree->nil)
-    node = node->left;
+  node = _gtk_rbtree_first (tree);
 
   g_object_ref (model);
 
@@ -742,10 +813,7 @@ gtk_tree_selection_selected_foreach (GtkTreeSelection            *selection,
       if (node->children)
        {
          tree = node->children;
-         node = tree->root;
-
-         while (node->left != tree->nil)
-           node = node->left;
+          node = _gtk_rbtree_first (tree);
 
          gtk_tree_path_append_index (path, 0);
        }
@@ -1295,9 +1363,7 @@ gtk_tree_selection_real_modify_range (GtkTreeSelection *selection,
       if (start_node->children)
        {
          start_tree = start_node->children;
-         start_node = start_tree->root;
-         while (start_node->left != start_tree->nil)
-           start_node = start_node->left;
+          start_node = _gtk_rbtree_first (start_tree);
        }
       else
        {
@@ -1562,14 +1628,23 @@ gtk_tree_selection_real_select_node (GtkTreeSelection *selection,
 
   if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED) != select)
     {
-      path = _gtk_tree_view_find_path (priv->tree_view, tree, node);
+      path = _gtk_tree_path_new_from_rbtree (tree, node);
       toggle = _gtk_tree_selection_row_is_selectable (selection, node, path);
       gtk_tree_path_free (path);
     }
 
   if (toggle)
     {
-      node->flags ^= GTK_RBNODE_IS_SELECTED;
+      if (!GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
+        {
+          GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SELECTED);
+          _gtk_tree_view_accessible_add_state (priv->tree_view, tree, node, GTK_CELL_RENDERER_SELECTED);
+        }
+      else
+        {
+          GTK_RBNODE_UNSET_FLAG (node, GTK_RBNODE_IS_SELECTED);
+          _gtk_tree_view_accessible_remove_state (priv->tree_view, tree, node, GTK_CELL_RENDERER_SELECTED);
+        }
 
       _gtk_tree_view_queue_draw_node (priv->tree_view, tree, node, NULL);