]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreeview.c
set the height correctly for fixed height when inserting a node, #138082
[~andy/gtk] / gtk / gtktreeview.c
index 271fc41b95a11b61c32851f5ec74d9ea31685e85..ed7503514b242b2aba49b72bf87186de587a1f90 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 
+#include <config.h>
 #include <string.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -1076,6 +1077,8 @@ gtk_tree_view_init (GtkTreeView *tree_view)
   tree_view->priv->search_column = -1;
   tree_view->priv->search_dialog_position_func = gtk_tree_view_search_position_func;
   tree_view->priv->search_equal_func = gtk_tree_view_search_equal_func;
+  tree_view->priv->init_hadjust_value = TRUE;    
+  tree_view->priv->width = 0;                    
 }
 
 \f
@@ -1583,10 +1586,12 @@ gtk_tree_view_update_size (GtkTreeView *tree_view)
   if (tree_view->priv->model == NULL)
     {
       tree_view->priv->width = 0;
+      tree_view->priv->prev_width = 0;                   
       tree_view->priv->height = 0;
       return;
     }
 
+  tree_view->priv->prev_width = tree_view->priv->width;  
   tree_view->priv->width = 0;
   /* keep this in sync with size_allocate below */
   for (list = tree_view->priv->columns, i = 0; list; list = list->next, i++)
@@ -1887,6 +1892,7 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
   GtkTreeView *tree_view;
   gboolean width_changed = FALSE;
   gboolean dy_changed = FALSE;
+  gint old_width = widget->allocation.width;           
 
   g_return_if_fail (GTK_IS_TREE_VIEW (widget));
 
@@ -1921,8 +1927,30 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
   tree_view->priv->hadjustment->lower = 0;
   tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->page_size, tree_view->priv->width);
 
-  if (tree_view->priv->hadjustment->value + allocation->width > tree_view->priv->width)
-    tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
+  if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)   
+     {
+      if (allocation->width < tree_view->priv->width)
+         {
+         if (tree_view->priv->init_hadjust_value)
+           {
+           tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
+           tree_view->priv->init_hadjust_value = FALSE;
+           }
+         else if(allocation->width != old_width)
+           tree_view->priv->hadjustment->value = CLAMP(tree_view->priv->hadjustment->value - allocation->width + old_width, 0, tree_view->priv->width - allocation->width);
+         else
+           tree_view->priv->hadjustment->value = CLAMP(tree_view->priv->width - (tree_view->priv->prev_width - tree_view->priv->hadjustment->value), 0, tree_view->priv->width - allocation->width);
+         }
+      else
+         {
+         tree_view->priv->hadjustment->value = 0;
+         tree_view->priv->init_hadjust_value = TRUE;
+         }
+     }
+  else
+     if (tree_view->priv->hadjustment->value + allocation->width > tree_view->priv->width)
+        tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
+
   gtk_adjustment_changed (tree_view->priv->hadjustment);
 
   tree_view->priv->vadjustment->page_size = allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view);
@@ -2327,7 +2355,7 @@ gtk_tree_view_button_press (GtkWidget      *widget,
              gtk_tree_view_column_get_sizing (column) != GTK_TREE_VIEW_COLUMN_AUTOSIZE)
            {
              _gtk_tree_view_column_autosize (tree_view, column);
-             break;
+             return TRUE;
            }
 
          if (gdk_pointer_grab (column->window, FALSE,
@@ -2355,10 +2383,10 @@ gtk_tree_view_button_press (GtkWidget      *widget,
 
          tree_view->priv->drag_pos = i;
          tree_view->priv->x_drag = column->button->allocation.x + (rtl ? 0 : column->button->allocation.width);
-         break;
+         return TRUE;
        }
     }
-  return TRUE;
+  return FALSE;
 }
 
 /* GtkWidget::button_release_event helper */
@@ -3138,6 +3166,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   gboolean allow_rules;
   gboolean has_special_cell;
   gboolean rtl;
+  gint n_visible_columns;
 
   g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
 
@@ -3200,6 +3229,16 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   gdk_drawable_get_size (tree_view->priv->bin_window,
                          &bin_window_width, NULL);
 
+
+  n_visible_columns = 0;
+  for (list = tree_view->priv->columns; list; list = list->next)
+    {
+      if (! GTK_TREE_VIEW_COLUMN (list->data)->visible)
+       continue;
+      n_visible_columns ++;
+    }
+
+  /* Find the last column */
   for (last_column = rtl ? g_list_first (tree_view->priv->columns) : g_list_last (tree_view->priv->columns);
        last_column &&
         !(GTK_TREE_VIEW_COLUMN (last_column->data)->visible) &&
@@ -3256,7 +3295,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
            }
 
           if (column->show_sort_indicator)
-            flags |= GTK_CELL_RENDERER_SORTED;
+           flags |= GTK_CELL_RENDERER_SORTED;
           else
             flags &= ~GTK_CELL_RENDERER_SORTED;
 
@@ -3292,7 +3331,8 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
            */
           if (allow_rules && tree_view->priv->has_rules)
             {
-              if (flags & GTK_CELL_RENDERER_SORTED)
+              if ((flags & GTK_CELL_RENDERER_SORTED) &&
+                 n_visible_columns >= 3)
                 {
                   if (parity)
                     detail = "cell_odd_ruled_sorted";
@@ -3309,7 +3349,8 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
             }
           else
             {
-              if (flags & GTK_CELL_RENDERER_SORTED)
+              if ((flags & GTK_CELL_RENDERER_SORTED) &&
+                 n_visible_columns >= 3)
                 {
                   if (parity)
                     detail = "cell_odd_sorted";
@@ -6624,6 +6665,7 @@ gtk_tree_view_row_inserted (GtkTreeModel *model,
   GtkRBNode *tmpnode = NULL;
   gint depth;
   gint i = 0;
+  gint height;
   gboolean free_path = FALSE;
 
   g_return_if_fail (path != NULL || iter != NULL);
@@ -6685,22 +6727,24 @@ gtk_tree_view_row_inserted (GtkTreeModel *model,
   if (tree == NULL)
     goto done;
 
+  if (tree_view->priv->fixed_height_mode
+      && tree_view->priv->fixed_height >= 0)
+    height = tree_view->priv->fixed_height;
+  else
+    height = 0;
+
   /* ref the node */
   gtk_tree_model_ref_node (tree_view->priv->model, iter);
   if (indices[depth - 1] == 0)
     {
       tmpnode = _gtk_rbtree_find_count (tree, 1);
-      _gtk_rbtree_insert_before (tree, tmpnode, 0, FALSE);
+      _gtk_rbtree_insert_before (tree, tmpnode, height, FALSE);
     }
   else
     {
       tmpnode = _gtk_rbtree_find_count (tree, indices[depth - 1]);
-      _gtk_rbtree_insert_after (tree, tmpnode, 0, FALSE);
-    }
-
-  if (tree_view->priv->fixed_height_mode
-      && tree_view->priv->fixed_height >= 0)
-    _gtk_rbtree_node_set_height (tree, tmpnode, tree_view->priv->fixed_height);
+      _gtk_rbtree_insert_after (tree, tmpnode, height, FALSE);
+    } 
 
  done:
   install_presize_handler (tree_view);
@@ -6891,8 +6935,12 @@ static void
 cancel_arrow_animation (GtkTreeView *tree_view)
 {
   if (tree_view->priv->expand_collapse_timeout)
-    while (do_expand_collapse (tree_view));
-  tree_view->priv->expand_collapse_timeout = 0;
+    {
+      while (do_expand_collapse (tree_view));
+
+      g_source_remove (tree_view->priv->expand_collapse_timeout);
+      tree_view->priv->expand_collapse_timeout = 0;
+    }
 }
 
 static void
@@ -8470,7 +8518,10 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
                       0);
       dy = tree_view->priv->dy - (int) tree_view->priv->vadjustment->value;
       if (dy && tree_view->priv->edited_column)
-        gtk_tree_view_stop_editing (tree_view, TRUE);
+       {
+         if (GTK_IS_WIDGET (tree_view->priv->edited_column->editable_widget))
+           GTK_WIDGET (tree_view->priv->edited_column->editable_widget)->allocation.y += dy;
+       }
       gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
 
       /* update our dy and top_row */
@@ -10291,10 +10342,10 @@ gtk_tree_view_get_reorderable (GtkTreeView *tree_view)
  * #GtkTreeStore and #GtkListStore support these.  If @reorderable is %TRUE, then
  * the user can reorder the model by dragging and dropping rows.  The
  * developer can listen to these changes by connecting to the model's
- * signals.
+ * row_inserted and row_deleted signals.
  *
  * This function does not give you any degree of control over the order -- any
- * reorderering is allowed.  If more control is needed, you should probably
+ * reordering is allowed.  If more control is needed, you should probably
  * handle drag and drop manually.
  **/
 void
@@ -10883,6 +10934,17 @@ unset_reorderable (GtkTreeView *tree_view)
     }
 }
 
+/**
+ * gtk_tree_view_enable_model_drag_source:
+ * @tree_view: a #GtkTreeView
+ * @start_button_mask: Mask of allowed buttons to start drag
+ * @targets: the table of targets that the drag will support
+ * @n_targets: the number of items in @targets
+ * @actions: the bitmask of possible actions for a drag from this
+ *    widget
+ * 
+ * Turns @tree_view into a drag source for automatic DND.
+ **/
 void
 gtk_tree_view_enable_model_drag_source (GtkTreeView              *tree_view,
                                        GdkModifierType           start_button_mask,
@@ -10894,6 +10956,12 @@ gtk_tree_view_enable_model_drag_source (GtkTreeView              *tree_view,
 
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
+  gtk_drag_source_set (GTK_WIDGET (tree_view),
+                      0,
+                      NULL,
+                      0,
+                      actions);
+
   di = ensure_info (tree_view);
   clear_source_info (di);
 
@@ -10906,6 +10974,16 @@ gtk_tree_view_enable_model_drag_source (GtkTreeView              *tree_view,
   unset_reorderable (tree_view);
 }
 
+/**
+ * gtk_tree_view_enable_model_drag_dest:
+ * @tree_view: a #GtkTreeView
+ * @targets: the table of targets that the drag will support
+ * @n_targets: the number of items in @targets
+ * @actions: the bitmask of possible actions for a drag from this
+ *    widget
+ * 
+ * Turns @tree_view into a drop destination for automatic DND.
+ **/
 void
 gtk_tree_view_enable_model_drag_dest (GtkTreeView              *tree_view,
                                      const GtkTargetEntry     *targets,
@@ -10933,6 +11011,12 @@ gtk_tree_view_enable_model_drag_dest (GtkTreeView              *tree_view,
   unset_reorderable (tree_view);
 }
 
+/**
+ * gtk_tree_view_unset_rows_drag_source:
+ * @tree_view: a #GtkTreeView
+ * 
+ * Undoes the effect of gtk_tree_view_enable_model_drag_source().
+ **/
 void
 gtk_tree_view_unset_rows_drag_source (GtkTreeView *tree_view)
 {
@@ -10946,6 +11030,7 @@ gtk_tree_view_unset_rows_drag_source (GtkTreeView *tree_view)
     {
       if (di->source_set)
         {
+          gtk_drag_source_unset (GTK_WIDGET (tree_view));
           clear_source_info (di);
           di->source_set = FALSE;
         }
@@ -10957,6 +11042,12 @@ gtk_tree_view_unset_rows_drag_source (GtkTreeView *tree_view)
   unset_reorderable (tree_view);
 }
 
+/**
+ * gtk_tree_view_unset_rows_drag_dest:
+ * @tree_view: a #GtkTreeView
+ * 
+ * Undoes the effect of gtk_tree_view_enable_model_drag_dest().
+ **/
 void
 gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view)
 {
@@ -10982,6 +11073,14 @@ gtk_tree_view_unset_rows_drag_dest (GtkTreeView *tree_view)
   unset_reorderable (tree_view);
 }
 
+/**
+ * gtk_tree_view_set_drag_dest_row:
+ * @tree_view: a #GtkTreeView
+ * @path: The path of the row to highlight, or %NULL.
+ * @pos: Specifies whether to drop before, after or into the row
+ * 
+ * Sets the row that is highlighted for feedback.
+ **/
 void
 gtk_tree_view_set_drag_dest_row (GtkTreeView            *tree_view,
                                  GtkTreePath            *path,
@@ -11052,6 +11151,14 @@ gtk_tree_view_set_drag_dest_row (GtkTreeView            *tree_view,
     }
 }
 
+/**
+ * gtk_tree_view_get_drag_dest_row:
+ * @tree_view: a #GtkTreeView
+ * @path: Return location for the path of the highlighted row, or %NULL.
+ * @pos: Return location for the drop position, or %NULL
+ * 
+ * Gets information about the row that is highlighted for feedback.
+ **/
 void
 gtk_tree_view_get_drag_dest_row (GtkTreeView              *tree_view,
                                  GtkTreePath             **path,
@@ -11076,6 +11183,18 @@ gtk_tree_view_get_drag_dest_row (GtkTreeView              *tree_view,
     *pos = tree_view->priv->drag_dest_pos;
 }
 
+/**
+ * gtk_tree_view_get_dest_row_at_pos:
+ * @tree_view: a #GtkTreeView
+ * @drag_x: the position to determine the destination row for
+ * @drag_y: the position to determine the destination row for
+ * @path: Return location for the path of the highlighted row, or %NULL.
+ * @pos: Return location for the drop position, or %NULL
+ * 
+ * Determines the destination row for a given position.
+ * 
+ * Return value: whether there is a row at the given postiion,
+ **/
 gboolean
 gtk_tree_view_get_dest_row_at_pos (GtkTreeView             *tree_view,
                                    gint                     drag_x,
@@ -11415,7 +11534,9 @@ gtk_tree_view_get_search_equal_func (GtkTreeView *tree_view)
  * @search_user_data: user data to pass to @search_equal_func, or %NULL
  * @search_destroy: Destroy notifier for @search_user_data, or %NULL
  *
- * Sets the compare function for the interactive search capabilities.
+ * Sets the compare function for the interactive search capabilities; note
+ * that somewhat like strcmp() returning 0 for equality
+ * #GtkTreeViewSearchEqualFunc returns %FALSE on matches.
  **/
 void
 gtk_tree_view_set_search_equal_func (GtkTreeView                *tree_view,
@@ -11659,13 +11780,13 @@ gtk_tree_view_search_equal_func (GtkTreeModel *model,
                                 gpointer      search_data)
 {
   gboolean retval = TRUE;
+  const gchar *str;
   gchar *normalized_string;
   gchar *normalized_key;
   gchar *case_normalized_string = NULL;
   gchar *case_normalized_key = NULL;
   GValue value = {0,};
   GValue transformed = {0,};
-  gint key_len;
 
   gtk_tree_model_get_value (model, iter, column, &value);
 
@@ -11674,12 +11795,19 @@ gtk_tree_view_search_equal_func (GtkTreeModel *model,
   if (!g_value_transform (&value, &transformed))
     {
       g_value_unset (&value);
-      return FALSE;
+      return TRUE;
     }
 
   g_value_unset (&value);
 
-  normalized_string = g_utf8_normalize (g_value_get_string (&transformed), -1, G_NORMALIZE_ALL);
+  str = g_value_get_string (&transformed);
+  if (!str)
+    {
+      g_value_unset (&transformed);
+      return TRUE;
+    }
+
+  normalized_string = g_utf8_normalize (str, -1, G_NORMALIZE_ALL);
   normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
 
   if (normalized_string && normalized_key)
@@ -11687,13 +11815,9 @@ gtk_tree_view_search_equal_func (GtkTreeModel *model,
       case_normalized_string = g_utf8_casefold (normalized_string, -1);
       case_normalized_key = g_utf8_casefold (normalized_key, -1);
 
-      key_len = strlen (case_normalized_key);
-
       if (strstr (case_normalized_string, case_normalized_key))
         retval = FALSE;
     }
-  else
-    retval = FALSE;
 
   g_value_unset (&transformed);
   g_free (normalized_key);