Index: ChangeLog =================================================================== RCS file: /cvs/gnome/gnumeric/ChangeLog,v retrieving revision 1.2426 diff -u -3 -p -r1.2426 ChangeLog --- ChangeLog 23 Sep 2002 19:50:47 -0000 1.2426 +++ ChangeLog 23 Sep 2002 20:40:53 -0000 @@ -1,3 +1,11 @@ +2002-09-23 Lutz Müller + + * src/dialogs/dialog-sheet-order.c: Be aware of changes in the + sheet order. + * src/workbook.[c,h]: Provide a "sheet_order_changed" signal. + * src/workbook-control-gui.c: Remove debugging messages. Hide the + arrow if we leave a label. + 2002-09-23 Jody Goldberg * src/expr.c (gnm_expr_eval) : handle empties when implicit Index: src/workbook.c =================================================================== RCS file: /cvs/gnome/gnumeric/src/workbook.c,v retrieving revision 1.560 diff -u -3 -p -r1.560 workbook.c --- src/workbook.c 17 Sep 2002 16:43:20 -0000 1.560 +++ src/workbook.c 23 Sep 2002 20:40:54 -0000 @@ -48,6 +48,7 @@ static GObjectClass *workbook_parent_cla enum { SUMMARY_CHANGED, FILENAME_CHANGED, + SHEET_ORDER_CHANGED, LAST_SIGNAL }; @@ -359,7 +360,16 @@ workbook_class_init (GObjectClass *objec (GSignalAccumulator) NULL, NULL, gnm__VOID__VOID, G_TYPE_NONE, - 0, G_TYPE_NONE); + 0, G_TYPE_NONE); + + signals [SHEET_ORDER_CHANGED] = g_signal_new ("sheet_order_changed", + WORKBOOK_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (WorkbookClass, sheet_order_changed), + (GSignalAccumulator) NULL, NULL, + gnm__VOID__VOID, + G_TYPE_NONE, + 0, G_TYPE_NONE); } /** @@ -1127,6 +1137,7 @@ workbook_sheet_reorganize (WorkbookContr GSList *the_back; GSList *the_lock; Workbook *wb = wb_control_workbook (wbc); + gboolean order_changed = FALSE; /* We need to verify validity of the new names */ the_names = new_names; @@ -1294,6 +1305,8 @@ workbook_sheet_reorganize (WorkbookContr int max_pos = MAX (old_pos, new_pos); int min_pos = MIN (old_pos, new_pos); + order_changed = TRUE; + g_ptr_array_remove_index (wb->sheets, old_pos); g_ptr_array_insert (wb->sheets, sheet, new_pos); for (; max_pos >= min_pos ; max_pos--) { @@ -1310,6 +1323,9 @@ workbook_sheet_reorganize (WorkbookContr } this_sheet = this_sheet->next; } + if (order_changed) + g_signal_emit (G_OBJECT (wb), signals [SHEET_ORDER_CHANGED], 0); + return FALSE; } Index: src/workbook.h =================================================================== RCS file: /cvs/gnome/gnumeric/src/workbook.h,v retrieving revision 1.110 diff -u -3 -p -r1.110 workbook.h --- src/workbook.h 17 Sep 2002 16:43:21 -0000 1.110 +++ src/workbook.h 23 Sep 2002 20:40:54 -0000 @@ -49,8 +49,9 @@ struct _Workbook { typedef struct { GObjectClass base; - void (*summary_changed) (Workbook *wb); - void (*filename_changed) (Workbook *wb); + void (*summary_changed) (Workbook *wb); + void (*filename_changed) (Workbook *wb); + void (*sheet_order_changed) (Workbook *wb); } WorkbookClass; GType workbook_get_type (void); Index: src/workbook-control-gui.c =================================================================== RCS file: /cvs/gnome/gnumeric/src/workbook-control-gui.c,v retrieving revision 1.341 diff -u -3 -p -r1.341 workbook-control-gui.c --- src/workbook-control-gui.c 23 Sep 2002 16:15:58 -0000 1.341 +++ src/workbook-control-gui.c 23 Sep 2002 20:40:56 -0000 @@ -796,8 +796,6 @@ cb_sheet_label_drag_begin (GtkWidget *wi g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg)); - g_message ("cb_sheet_label_drag_begin"); - /* Create the arrow. */ arrow = gtk_window_new (GTK_WINDOW_POPUP); gtk_widget_realize (arrow); @@ -828,6 +826,18 @@ cb_sheet_label_drag_end (GtkWidget *widg g_object_set_data (G_OBJECT (widget), "arrow", NULL); } +static void +cb_sheet_label_drag_leave (GtkWidget *widget, GdkDragContext *context, + guint time, WorkbookControlGUI *wbcg) +{ + GtkWidget *w_source, *arrow; + + /* Hide the arrow. */ + w_source = gtk_drag_get_source_widget (context); + arrow = g_object_get_data (G_OBJECT (w_source), "arrow"); + gtk_widget_hide (arrow); +} + static gboolean cb_sheet_label_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, WorkbookControlGUI *wbcg) @@ -837,17 +847,17 @@ cb_sheet_label_drag_motion (GtkWidget *w g_return_val_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg), FALSE); - g_message ("cb_sheet_label_drag_motion"); - /* Make sure we are really hovering over another label. */ w_source = gtk_drag_get_source_widget (context); n_source = gtk_notebook_page_num_by_label (wbcg->notebook, w_source); n_dest = gtk_notebook_page_num_by_label (wbcg->notebook, widget); - if (n_source == n_dest) + arrow = g_object_get_data (G_OBJECT (w_source), "arrow"); + if (n_source == n_dest) { + gtk_widget_hide (arrow); return (FALSE); + } /* Move the arrow to the correct position and show it. */ - arrow = g_object_get_data (G_OBJECT (w_source), "arrow"); window = gtk_widget_get_ancestor (widget, GTK_TYPE_WINDOW); gtk_window_get_position (GTK_WINDOW (window), &root_x, &root_y); pos_x = root_x + widget->allocation.x; @@ -920,6 +930,8 @@ wbcg_sheet_add (WorkbookControl *wbc, Sh G_CALLBACK (cb_sheet_label_drag_begin), wbcg); g_signal_connect (G_OBJECT (scg->label), "drag_end", G_CALLBACK (cb_sheet_label_drag_end), wbcg); + g_signal_connect (G_OBJECT (scg->label), "drag_leave", + G_CALLBACK (cb_sheet_label_drag_leave), wbcg); g_signal_connect (G_OBJECT (scg->label), "drag_data_get", G_CALLBACK (cb_sheet_label_drag_data_get), wbcg); g_signal_connect (G_OBJECT (scg->label), "drag_data_received", Index: src/dialogs/dialog-sheet-order.c =================================================================== RCS file: /cvs/gnome/gnumeric/src/dialogs/dialog-sheet-order.c,v retrieving revision 1.37 diff -u -3 -p -r1.37 dialog-sheet-order.c --- src/dialogs/dialog-sheet-order.c 18 Aug 2002 15:48:55 -0000 1.37 +++ src/dialogs/dialog-sheet-order.c 23 Sep 2002 20:40:57 -0000 @@ -67,6 +67,8 @@ typedef struct { gboolean initial_colors_set; GSList *old_order; + + gulong sheet_order_changed_listener; } SheetManager; enum { @@ -676,6 +678,12 @@ cb_ok_clicked (GtkWidget *ignore, SheetM static void cb_sheet_order_destroy (GtkWidget *ignored, SheetManager *state) { + Workbook *wb = wb_control_workbook (WORKBOOK_CONTROL (state->wbcg)); + + /* Stop to listen to changes in the sheet order. */ + g_signal_handler_disconnect (G_OBJECT (wb), + state->sheet_order_changed_listener); + wbcg_edit_detach_guru (state->wbcg); g_object_unref (G_OBJECT (state->gui)); state->gui = NULL; @@ -691,6 +699,144 @@ cb_sheet_order_destroy (GtkWidget *ignor g_free (state); } +static void +dialog_sheet_order_update_sheet_order (SheetManager *state) +{ + gchar *name, *new_name; + gboolean is_deleted; + gboolean is_editable; + gboolean is_locked; + GdkColor *back, *fore; + GtkTreeIter iter; + Workbook *wb = wb_control_workbook (WORKBOOK_CONTROL (state->wbcg)); + gint i, j, n_sheets, n_children; + GtkTreeModel *model = GTK_TREE_MODEL (state->model); + Sheet *sheet_wb, *sheet_model; + GtkTreeSelection *sel = gtk_tree_view_get_selection (state->sheet_list); + gboolean selected; + + n_sheets = workbook_sheet_count (wb); + n_children = gtk_tree_model_iter_n_children (model, NULL); + g_return_if_fail (n_sheets == n_children); + + for (i = 0; i < n_sheets; i++) { + sheet_wb = workbook_sheet_by_index (wb, i); + for (j = i; j < n_children; j++) { + if (!gtk_tree_model_iter_nth_child (model, &iter, + NULL, j)) + break; + gtk_tree_model_get (model, &iter, SHEET_POINTER, + &sheet_model, -1); + if (sheet_model == sheet_wb) + break; + } + if (j == i) + continue; + + if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, j)) + break; + selected = gtk_tree_selection_iter_is_selected (sel, &iter); + gtk_tree_model_get (model, &iter, + SHEET_LOCKED, &is_locked, + SHEET_NAME, &name, + SHEET_NEW_NAME, &new_name, + IS_EDITABLE_COLUMN, &is_editable, + SHEET_POINTER, &sheet_model, + IS_DELETED, &is_deleted, + BACKGROUND_COLOUR_POINTER, &back, + FOREGROUND_COLOUR_POINTER, &fore, + -1); + gtk_list_store_remove (state->model, &iter); + gtk_list_store_insert (state->model, &iter, i); + gtk_list_store_set (state->model, &iter, + SHEET_LOCKED, is_locked, + SHEET_LOCK_IMAGE, is_locked ? + state->image_padlock : state->image_padlock_no, + SHEET_NAME, name, + SHEET_NEW_NAME, new_name, + IS_EDITABLE_COLUMN, is_editable, + SHEET_POINTER, sheet_model, + IS_DELETED, is_deleted, + BACKGROUND_COLOUR_POINTER, back, + FOREGROUND_COLOUR_POINTER, fore, + -1); + if (back) + gdk_color_free (back); + if (fore) + gdk_color_free (fore); + g_free (name); + g_free (new_name); + if (selected) + gtk_tree_selection_select_iter (sel, &iter); + } + + g_slist_free (state->old_order); + state->old_order = NULL; + for (i = 0; i < n_sheets; i++) + state->old_order = g_slist_append (state->old_order, + workbook_sheet_by_index (wb, i)); + + cb_selection_changed (NULL, state); +} + +static void +cb_sheet_order_changed (Workbook *wb, SheetManager *state) +{ + GtkTreeIter iter; + GtkTreeModel *model = GTK_TREE_MODEL (state->model); + guint i, n = 0; + Sheet *sheet; + + /* + * First question: Has the user already changed the order via + * the dialog? If no, we assume that the user wants to see the + * sheet order change reflected in the dialog. + */ + n = g_slist_length (state->old_order); + for (i = 0; i < n; i++) { + if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, i)) + break; + gtk_tree_model_get (model, &iter, SHEET_POINTER, &sheet, -1); + if (sheet != g_slist_nth_data (state->old_order, i)) + break; + } + if (n == i) { + dialog_sheet_order_update_sheet_order (state); + return; + } + + /* + * The user has already changed the order via the dialog. + * Let's check if the new sheet order is already reflected + * in the dialog. If yes, things are easy. + */ + n = workbook_sheet_count (wb); + for (i = 0; i < n; i++) { + if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, i)) + break; + gtk_tree_model_get (model, &iter, SHEET_POINTER, &sheet, -1); + if (sheet != workbook_sheet_by_index (wb, i)) + break; + } + if (i == n) { + g_slist_free (state->old_order); + state->old_order = NULL; + for (i = 0; i < n; i++) + state->old_order = g_slist_append (state->old_order, + workbook_sheet_by_index (wb, i)); + return; + } + + /* + * The order in the dialog and the new sheet order are totally + * different. Ask the user what to do. + */ + if (gnumeric_dialog_question_yes_no (state->wbcg, + _("The sheet order has changed. Do you want to " + "update the list?"), TRUE)) + dialog_sheet_order_update_sheet_order (state); +} + void dialog_sheet_order (WorkbookControlGUI *wbcg) { @@ -698,6 +844,7 @@ dialog_sheet_order (WorkbookControlGUI * GladeXML *gui; GtkTable *table; ColorGroup *cg; + Workbook *wb; g_return_if_fail (wbcg != NULL); @@ -727,6 +874,12 @@ dialog_sheet_order (WorkbookControlGUI * "Gnumeric_PadlockNo", GTK_ICON_SIZE_LARGE_TOOLBAR, "Gnumeric-Sheet-Manger"); + + /* Listen for changes in the sheet order. */ + wb = wb_control_workbook (WORKBOOK_CONTROL (wbcg)); + state->sheet_order_changed_listener = g_signal_connect (G_OBJECT (wb), + "sheet_order_changed", G_CALLBACK (cb_sheet_order_changed), + state); gtk_button_stock_alignment_set (GTK_BUTTON (state->up_btn), 0., .5, 0., 0.); gtk_button_stock_alignment_set (GTK_BUTTON (state->down_btn), 0., .5, 0., 0.);