]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkclist.c
Merges from gtk-1-2
[~andy/gtk] / gtk / gtkclist.c
index d6a72419541be0e6e2fc6efcf8d1b84e7c402977..34396b6295c06faefbe95dd69f4f175df58eec63 100644 (file)
@@ -32,7 +32,6 @@
 #include "gtkclist.h"
 #include "gtkbindings.h"
 #include "gtkdnd.h"
-#include "gdkx.h"
 #include <gdk/gdkkeysyms.h>
 
 /* length of button_actions array */
@@ -123,6 +122,12 @@ LIST_WIDTH (GtkCList * clist)
   return 0;
 }
 
+/* returns the GList item for the nth row */
+#define        ROW_ELEMENT(clist, row) (((row) == (clist)->rows - 1) ? \
+                                (clist)->row_list_end : \
+                                g_list_nth ((clist)->row_list, (row)))
+
+
 #define GTK_CLIST_CLASS_FW(_widget_) GTK_CLIST_CLASS (((GtkObject*) (_widget_))->klass)
 
 /* redraw the list if it's not frozen */
@@ -134,8 +139,7 @@ LIST_WIDTH (GtkCList * clist)
 
 
 /* Signals */
-enum
-{
+enum {
   SELECT_ROW,
   UNSELECT_ROW,
   ROW_MOVE,
@@ -155,8 +159,7 @@ enum
   LAST_SIGNAL
 };
 
-enum
-{
+enum {
   SYNC_REMOVE,
   SYNC_INSERT
 };
@@ -169,7 +172,8 @@ enum {
   ARG_ROW_HEIGHT,
   ARG_TITLES_ACTIVE,
   ARG_REORDERABLE,
-  ARG_USE_DRAG_ICONS
+  ARG_USE_DRAG_ICONS,
+  ARG_SORT_TYPE
 };
 
 /* GtkCList Methods */
@@ -452,6 +456,7 @@ static void drag_dest_cell            (GtkCList         *clist,
                                       GtkCListDestInfo *dest_info);
 
 
+
 static GtkContainerClass *parent_class = NULL;
 static guint clist_signals[LAST_SIGNAL] = {0};
 
@@ -524,7 +529,10 @@ gtk_clist_class_init (GtkCListClass *klass)
                           GTK_TYPE_BOOL,
                           GTK_ARG_READWRITE,
                           ARG_USE_DRAG_ICONS);
-  
+  gtk_object_add_arg_type ("GtkCList::sort_type",
+                          GTK_TYPE_SORT_TYPE,
+                          GTK_ARG_READWRITE,
+                          ARG_SORT_TYPE);  
   object_class->set_arg = gtk_clist_set_arg;
   object_class->get_arg = gtk_clist_get_arg;
   object_class->destroy = gtk_clist_destroy;
@@ -853,7 +861,8 @@ gtk_clist_set_arg (GtkObject      *object,
     case ARG_USE_DRAG_ICONS:
       gtk_clist_set_use_drag_icons (clist, GTK_VALUE_BOOL (*arg));
       break;
-    default:
+    case ARG_SORT_TYPE:
+      gtk_clist_set_sort_type (clist, GTK_VALUE_ENUM (*arg));
       break;
     }
 }
@@ -899,6 +908,9 @@ gtk_clist_get_arg (GtkObject      *object,
     case ARG_USE_DRAG_ICONS:
       GTK_VALUE_BOOL (*arg) = GTK_CLIST_USE_DRAG_ICONS (clist);
       break;
+    case ARG_SORT_TYPE:
+      GTK_VALUE_ENUM (*arg) = clist->sort_type;
+      break;
     default:
       arg->type = GTK_TYPE_INVALID;
       break;
@@ -1297,8 +1309,6 @@ void
 gtk_clist_column_title_active (GtkCList *clist,
                               gint      column)
 {
-  GtkObject *object;
-
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
@@ -2170,7 +2180,7 @@ gtk_clist_get_cell_type (GtkCList *clist,
   if (column < 0 || column >= clist->columns)
     return -1;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   return clist_row->cell[column].type;
 }
@@ -2191,7 +2201,7 @@ gtk_clist_set_text (GtkCList    *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   /* if text is null, then the cell is empty */
   GTK_CLIST_CLASS_FW (clist)->set_cell_contents
@@ -2221,7 +2231,7 @@ gtk_clist_get_text (GtkCList  *clist,
   if (column < 0 || column >= clist->columns)
     return 0;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].type != GTK_CELL_TEXT)
     return 0;
@@ -2249,7 +2259,7 @@ gtk_clist_set_pixmap (GtkCList  *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
   
   gdk_pixmap_ref (pixmap);
   
@@ -2283,7 +2293,7 @@ gtk_clist_get_pixmap (GtkCList   *clist,
   if (column < 0 || column >= clist->columns)
     return 0;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].type != GTK_CELL_PIXMAP)
     return 0;
@@ -2317,7 +2327,7 @@ gtk_clist_set_pixtext (GtkCList    *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
   
   gdk_pixmap_ref (pixmap);
   if (mask) gdk_pixmap_ref (mask);
@@ -2351,7 +2361,7 @@ gtk_clist_get_pixtext (GtkCList   *clist,
   if (column < 0 || column >= clist->columns)
     return 0;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].type != GTK_CELL_PIXTEXT)
     return 0;
@@ -2387,7 +2397,7 @@ gtk_clist_set_shift (GtkCList *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist->column[column].auto_resize &&
       !GTK_CLIST_AUTO_RESIZE_BLOCKED(clist))
@@ -2725,7 +2735,7 @@ real_remove_row (GtkCList *clist,
   was_selected = 0;
 
   /* get the row we're going to delete */
-  list = g_list_nth (clist->row_list, row);
+  list = ROW_ELEMENT (clist, row);
   g_assert (list != NULL);
   clist_row = list->data;
 
@@ -2737,8 +2747,7 @@ real_remove_row (GtkCList *clist,
     gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW],
                     row, -1, NULL);
 
-  /* reset the row end pointer if we're removing at the
-   * end of the list */
+  /* reset the row end pointer if we're removing at the end of the list */
   clist->rows--;
   if (clist->row_list == list)
     clist->row_list = g_list_next (list);
@@ -2853,7 +2862,7 @@ real_row_move (GtkCList *clist,
   gtk_clist_freeze (clist);
 
   /* unlink source row */
-  clist_row = g_list_nth_data (clist->row_list, source_row);
+  clist_row = ROW_ELEMENT (clist, source_row)->data;
   if (source_row == clist->rows - 1)
     clist->row_list_end = clist->row_list_end->prev;
   clist->row_list = g_list_remove (clist->row_list, clist_row);
@@ -3010,7 +3019,11 @@ gtk_clist_set_row_data_full (GtkCList         *clist,
   if (row < 0 || row > (clist->rows - 1))
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
+
+  if (clist_row->destroy)
+    clist_row->destroy (clist_row->data);
+  
   clist_row->data = data;
   clist_row->destroy = destroy;
 }
@@ -3027,7 +3040,7 @@ gtk_clist_get_row_data (GtkCList *clist,
   if (row < 0 || row > (clist->rows - 1))
     return NULL;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
   return clist_row->data;
 }
 
@@ -3136,7 +3149,7 @@ gtk_clist_set_foreground (GtkCList *clist,
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (color)
     {
@@ -3166,7 +3179,7 @@ gtk_clist_set_background (GtkCList *clist,
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (color)
     {
@@ -3207,7 +3220,7 @@ gtk_clist_set_cell_style (GtkCList *clist,
   if (column < 0 || column >= clist->columns)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->cell[column].style == style)
     return;
@@ -3259,7 +3272,7 @@ gtk_clist_get_cell_style (GtkCList *clist,
   if (row < 0 || row >= clist->rows || column < 0 || column >= clist->columns)
     return NULL;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   return clist_row->cell[column].style;
 }
@@ -3280,7 +3293,7 @@ gtk_clist_set_row_style (GtkCList *clist,
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->style == style)
     return;
@@ -3342,7 +3355,7 @@ gtk_clist_get_row_style (GtkCList *clist,
   if (row < 0 || row >= clist->rows)
     return NULL;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   return clist_row->style;
 }
@@ -3369,7 +3382,7 @@ gtk_clist_set_selectable (GtkCList *clist,
   if (row < 0 || row >= clist->rows)
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (selectable == clist_row->selectable)
     return;
@@ -3400,7 +3413,7 @@ gtk_clist_get_selectable (GtkCList *clist,
   if (row < 0 || row >= clist->rows)
     return FALSE;
 
-  return GTK_CLIST_ROW (g_list_nth (clist->row_list, row))->selectable;
+  return GTK_CLIST_ROW (ROW_ELEMENT (clist, row))->selectable;
 }
 
 void
@@ -3507,7 +3520,7 @@ toggle_row (GtkCList *clist,
     case GTK_SELECTION_EXTENDED:
     case GTK_SELECTION_MULTIPLE:
     case GTK_SELECTION_SINGLE:
-      clist_row = g_list_nth (clist->row_list, row)->data;
+      clist_row = ROW_ELEMENT (clist, row)->data;
 
       if (!clist_row)
        return;
@@ -3531,7 +3544,7 @@ fake_toggle_row (GtkCList *clist,
 {
   GList *work;
 
-  work = g_list_nth (clist->row_list, row);
+  work = ROW_ELEMENT (clist, row);
 
   if (!work || !GTK_CLIST_ROW (work)->selectable)
     return;
@@ -3656,7 +3669,7 @@ real_select_row (GtkCList *clist,
       break;
     }
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->state != GTK_STATE_NORMAL || !clist_row->selectable)
     return;
@@ -3691,7 +3704,7 @@ real_unselect_row (GtkCList *clist,
   if (row < 0 || row > (clist->rows - 1))
     return;
 
-  clist_row = (g_list_nth (clist->row_list, row))->data;
+  clist_row = ROW_ELEMENT (clist, row)->data;
 
   if (clist_row->state == GTK_STATE_SELECTED)
     {
@@ -3813,7 +3826,7 @@ fake_unselect_all (GtkCList *clist,
   GList *work;
   gint i;
 
-  if (row >= 0 && (work = g_list_nth (clist->row_list, row)))
+  if (row >= 0 && (work = ROW_ELEMENT (clist, row)))
     {
       if (GTK_CLIST_ROW (work)->state == GTK_STATE_NORMAL &&
          GTK_CLIST_ROW (work)->selectable)
@@ -3830,7 +3843,7 @@ fake_unselect_all (GtkCList *clist,
   clist->undo_selection = clist->selection;
   clist->selection = NULL;
   clist->selection_end = NULL;
-  
+
   for (list = clist->undo_selection; list; list = list->next)
     {
       if ((i = GPOINTER_TO_INT (list->data)) == row ||
@@ -3857,8 +3870,7 @@ real_undo_selection (GtkCList *clist)
       clist->selection_mode != GTK_SELECTION_EXTENDED)
     return;
 
-  if (clist->anchor >= 0)
-    GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+  GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
 
   if (!(clist->undo_selection || clist->undo_unselection))
     {
@@ -3872,7 +3884,7 @@ real_undo_selection (GtkCList *clist)
 
   for (work = clist->undo_unselection; work; work = work->next)
     {
-      g_print ("unselect %d\n",GPOINTER_TO_INT (work->data));
+      /* g_print ("unselect %d\n",GPOINTER_TO_INT (work->data)); */
       gtk_signal_emit (GTK_OBJECT (clist), clist_signals[UNSELECT_ROW], 
                       GPOINTER_TO_INT (work->data), -1, NULL);
     }
@@ -3940,7 +3952,10 @@ resync_selection (GtkCList *clist,
   GList *list;
   GtkCListRow *clist_row;
 
-  if (clist->anchor < 0)
+  if (clist->selection_mode != GTK_SELECTION_EXTENDED)
+    return;
+
+  if (clist->anchor < 0 || clist->drag_pos < 0)
     return;
 
   gtk_clist_freeze (clist);
@@ -4218,10 +4233,9 @@ end_selection (GtkCList *clist)
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
 
-  if ((gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_FOCUS(clist)) ||
-      clist->anchor == -1)
+  if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_FOCUS(clist))
     return;
-  
+
   GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
 }
 
@@ -4278,8 +4292,7 @@ sync_selection (GtkCList *clist,
        clist->focus_row = clist->rows - 1;
     }
 
-  if (clist->selection_mode == GTK_SELECTION_BROWSE && clist->anchor != -1)
-    GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+  GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
 
   g_list_free (clist->undo_selection);
   g_list_free (clist->undo_unselection);
@@ -4512,7 +4525,8 @@ gtk_clist_realize (GtkWidget *widget)
   /* We'll use this gc to do scrolling as well */
   gdk_gc_set_exposures (clist->fg_gc, TRUE);
 
-  values.foreground = widget->style->white;
+  values.foreground = (widget->style->white.pixel==0 ?
+                      widget->style->black:widget->style->white);
   values.function = GDK_XOR;
   values.subwindow_mode = GDK_INCLUDE_INFERIORS;
   clist->xor_gc = gdk_gc_new_with_values (widget->window,
@@ -4683,9 +4697,7 @@ gtk_clist_unmap (GtkWidget *widget)
        {
          remove_grab (clist);
 
-         if (clist->anchor != -1 &&
-             clist->selection_mode == GTK_SELECTION_EXTENDED)
-           GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, NULL);
+         GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, NULL);
 
          clist->click_cell.row = -1;
          clist->click_cell.column = -1;
@@ -4756,7 +4768,7 @@ gtk_clist_draw (GtkWidget    *widget,
                       (2 * widget->style->klass->ythickness) +
                       clist->column_title_area.height);
 
-      gdk_window_clear_area (clist->clist_window, 0, 0, -1, -1);
+      gdk_window_clear_area (clist->clist_window, 0, 0, 0, 0);
       draw_rows (clist, NULL);
 
       for (i = 0; i < clist->columns; i++)
@@ -4985,9 +4997,12 @@ gtk_clist_button_press (GtkWidget      *widget,
                case GTK_SELECTION_SINGLE:
                case GTK_SELECTION_MULTIPLE:
                  if (event->type != GDK_BUTTON_PRESS)
-                   gtk_signal_emit (GTK_OBJECT (clist),
-                                    clist_signals[SELECT_ROW],
-                                    row, column, event);
+                   {
+                     gtk_signal_emit (GTK_OBJECT (clist),
+                                      clist_signals[SELECT_ROW],
+                                      row, column, event);
+                     clist->anchor = -1;
+                   }
                  else
                    clist->anchor = row;
                  break;
@@ -5657,7 +5672,7 @@ draw_row (GtkCList     *clist,
   /* if the function is passed the pointer to the row instead of null,
    * it avoids this expensive lookup */
   if (!clist_row)
-    clist_row = (g_list_nth (clist->row_list, row))->data;
+    clist_row = ROW_ELEMENT (clist, row)->data;
 
   /* rectangle of the entire row */
   row_rectangle.x = 0;
@@ -5671,7 +5686,7 @@ draw_row (GtkCList     *clist,
   cell_rectangle.width = row_rectangle.width;
   cell_rectangle.height = CELL_SPACING;
 
-  /* rectangle used to clip drawing operations, it's y and height
+  /* rectangle used to clip drawing operations, its y and height
    * positions only need to be set once, so we set them once here. 
    * the x and width are set withing the drawing loop below once per
    * column */
@@ -5702,7 +5717,7 @@ draw_row (GtkCList     *clist,
                            intersect_rectangle.width,
                            intersect_rectangle.height);
 
-      /* the last row has to clear it's bottom cell spacing too */
+      /* the last row has to clear its bottom cell spacing too */
       if (clist_row == clist->row_list_end->data)
        {
          cell_rectangle.y += clist->row_height + CELL_SPACING;
@@ -5733,7 +5748,7 @@ draw_row (GtkCList     *clist,
                          cell_rectangle.width,
                          cell_rectangle.height);
 
-      /* the last row has to clear it's bottom cell spacing too */
+      /* the last row has to clear its bottom cell spacing too */
       if (clist_row == clist->row_list_end->data)
        {
          cell_rectangle.y += clist->row_height + CELL_SPACING;
@@ -5934,7 +5949,7 @@ draw_rows (GtkCList     *clist,
   if (clist->rows == first_row)
     first_row--;
 
-  list = g_list_nth (clist->row_list, first_row);
+  list = ROW_ELEMENT (clist, first_row);
   i = first_row;
   while (list)
     {
@@ -5949,8 +5964,8 @@ draw_rows (GtkCList     *clist,
     }
 
   if (!area)
-    gdk_window_clear_area (clist->clist_window,
-                          0, ROW_TOP_YPIXEL (clist, i), -1, -1);
+    gdk_window_clear_area (clist->clist_window, 0,
+                          ROW_TOP_YPIXEL (clist, i), 0, 0);
 }
 
 static void                          
@@ -6050,7 +6065,8 @@ adjust_adjustments (GtkCList *clist,
       clist->vadjustment->lower = 0;
       clist->vadjustment->upper = LIST_HEIGHT (clist);
 
-      if (clist->clist_window_height - clist->voffset > LIST_HEIGHT (clist))
+      if (clist->clist_window_height - clist->voffset > LIST_HEIGHT (clist) ||
+         (clist->voffset + (gint)clist->vadjustment->value) != 0)
        {
          clist->vadjustment->value = MAX (0, (LIST_HEIGHT (clist) -
                                               clist->clist_window_height));
@@ -6068,7 +6084,8 @@ adjust_adjustments (GtkCList *clist,
       clist->hadjustment->lower = 0;
       clist->hadjustment->upper = LIST_WIDTH (clist);
 
-      if (clist->clist_window_width - clist->hoffset > LIST_WIDTH (clist))
+      if (clist->clist_window_width - clist->hoffset > LIST_WIDTH (clist) ||
+         (clist->hoffset + (gint)clist->hadjustment->value) != 0)
        {
          clist->hadjustment->value = MAX (0, (LIST_WIDTH (clist) -
                                               clist->clist_window_width));
@@ -6676,8 +6693,7 @@ gtk_clist_focus_out (GtkWidget     *widget,
   
   clist = GTK_CLIST (widget);
 
-  if (clist->anchor != -1 && clist->selection_mode == GTK_SELECTION_EXTENDED)
-    GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, (GdkEvent *) event);
+  GTK_CLIST_CLASS_FW (widget)->resync_selection (clist, (GdkEvent *) event);
 
   return FALSE;
 }
@@ -7863,7 +7879,7 @@ gtk_clist_set_button_actions (GtkCList *clist,
   g_return_if_fail (clist != NULL);
   g_return_if_fail (GTK_IS_CLIST (clist));
   
-  if (button <= MAX_BUTTON)
+  if (button < MAX_BUTTON)
     {
       if (gdk_pointer_is_grabbed () || GTK_WIDGET_HAS_GRAB (clist))
        {
@@ -7871,9 +7887,7 @@ gtk_clist_set_button_actions (GtkCList *clist,
          clist->drag_button = 0;
        }
 
-      if (clist->anchor >= 0 &&
-         clist->selection_mode == GTK_SELECTION_EXTENDED)
-       GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
+      GTK_CLIST_CLASS_FW (clist)->resync_selection (clist, NULL);
 
       clist->button_actions[button] = button_actions;
     }