static void cb_append_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state) { WorkbookSheetState *old_state; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); GtkTreeIter iter; Sheet *sheet, *old_sheet; workbook_signals_block (state); old_state = workbook_sheet_state_new (wb); old_sheet = workbook_sheet_by_index (wb, 0); workbook_sheet_add (wb, -1, gnm_sheet_get_max_cols (old_sheet), gnm_sheet_get_max_rows (old_sheet)); cmd_reorganize_sheets (wbc, old_state, NULL); update_undo (state, wbc); workbook_signals_unblock (state); sheet = workbook_sheet_by_index (wb, workbook_sheet_count (wb) - 1); g_signal_handler_block (state->model, state->model_row_insertion_listener); gtk_list_store_append (state->model, &iter); g_signal_handler_unblock (state->model, state->model_row_insertion_listener); set_sheet_info_at_iter (state, &iter, sheet); cb_selection_changed (NULL, state); }
static void dialog_sheet_order_changed (SheetManager *state) { WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); WorkbookSheetState *old_state; GtkTreeIter this_iter; gint n = 0, changes = 0; workbook_signals_block (state); old_state = workbook_sheet_state_new (wb); while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state->model), &this_iter, NULL, n)) { Sheet *this_sheet; gtk_tree_model_get (GTK_TREE_MODEL (state->model), &this_iter, SHEET_POINTER, &this_sheet, -1); if (this_sheet->index_in_wb != n) { changes++; workbook_sheet_move (this_sheet, n - this_sheet->index_in_wb); } n++; } if (changes > 0) { cmd_reorganize_sheets (wbc, old_state, NULL); update_undo (state, wbc); } else workbook_sheet_state_free (old_state); workbook_signals_unblock (state); }
static void cb_color_changed_back (G_GNUC_UNUSED GOComboColor *go_combo_color, GOColor color, G_GNUC_UNUSED gboolean custom, G_GNUC_UNUSED gboolean by_user, G_GNUC_UNUSED gboolean is_default, SheetManager *state) { GList *selected_rows, *l; GtkTreeSelection *selection = gtk_tree_view_get_selection (state->sheet_list); WorkbookSheetState *old_state; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); GdkRGBA gdk_color; GdkRGBA *p_gdk_color; GnmColor *gnm_color; g_return_if_fail (selection != NULL); selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL); p_gdk_color = (color == 0) ? NULL : go_color_to_gdk_rgba (color, &gdk_color); gnm_color = (color == 0) ? NULL : gnm_color_new_gdk (&gdk_color); old_state = workbook_sheet_state_new (wb); for (l = selected_rows; l != NULL; l = l->next) { Sheet *this_sheet; GtkTreeIter sel_iter; GtkTreePath *path = l->data; gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model), &sel_iter, path); gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter, SHEET_POINTER, &this_sheet, -1); if (color_equal (p_gdk_color, this_sheet->tab_color)) continue; gtk_list_store_set (state->model, &sel_iter, BACKGROUND_COLOUR, p_gdk_color, -1); g_object_set (this_sheet, "tab-background", gnm_color, NULL); } style_color_unref (gnm_color); cmd_reorganize_sheets (wbc, old_state, NULL); update_undo (state, wbc); g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free); }
static void cb_duplicate_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state) { GtkTreeIter sel_iter, iter; GtkTreeSelection *selection = gtk_tree_view_get_selection (state->sheet_list); GList *selected_rows; WorkbookSheetState *old_state; int index; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); Sheet *new_sheet, *this_sheet; g_return_if_fail (selection != NULL); g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1); selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL); gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model), &sel_iter, (GtkTreePath *) selected_rows->data); g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free); gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter, SHEET_POINTER, &this_sheet, -1); workbook_signals_block (state); old_state = workbook_sheet_state_new (wb); index = this_sheet->index_in_wb; new_sheet = sheet_dup (this_sheet); workbook_sheet_attach_at_pos (wb, new_sheet, index + 1); g_signal_emit_by_name (G_OBJECT (wb), "sheet_added", 0); cmd_reorganize_sheets (wbc, old_state, NULL); update_undo (state, wbc); workbook_signals_unblock (state); g_signal_handler_block (state->model, state->model_row_insertion_listener); gtk_list_store_insert_after (state->model, &iter, &sel_iter); g_signal_handler_unblock (state->model, state->model_row_insertion_listener); set_sheet_info_at_iter (state, &iter, new_sheet); g_object_unref (new_sheet); cb_selection_changed (NULL, state); }
static void cb_toggled_lock (G_GNUC_UNUSED GtkCellRendererToggle *cell, gchar *path_string, gpointer data) { SheetManager *state = data; GtkTreeModel *model = GTK_TREE_MODEL (state->model); GtkTreeIter iter; GtkTreePath *path = gtk_tree_path_new_from_string (path_string); gboolean is_locked = TRUE; Sheet *this_sheet = NULL; WorkbookSheetState *old_state = NULL; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); if (gtk_tree_model_get_iter (model, &iter, path)) { gtk_tree_model_get (model, &iter, SHEET_LOCKED, &is_locked, SHEET_POINTER, &this_sheet, -1); if (is_locked) { gtk_list_store_set (GTK_LIST_STORE (model), &iter, SHEET_LOCKED, FALSE, SHEET_LOCK_IMAGE, state->image_padlock_no, -1); } else { gtk_list_store_set (GTK_LIST_STORE (model), &iter, SHEET_LOCKED, TRUE, SHEET_LOCK_IMAGE, state->image_padlock, -1); } } else { g_warning ("Did not get a valid iterator"); gtk_tree_path_free (path); return; } gtk_tree_path_free (path); old_state = workbook_sheet_state_new (wb); g_object_set (this_sheet, "protected", !is_locked, NULL); cmd_reorganize_sheets (wbc, old_state, this_sheet); update_undo (state, wbc); }
static void cb_delete_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state) { GtkTreeSelection *selection = gtk_tree_view_get_selection (state->sheet_list); GList *selected_rows, *l; WorkbookSheetState *old_state; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); g_return_if_fail (selection != NULL); selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL); for (l = selected_rows; l != NULL; l = l->next) l->data = gtk_tree_row_reference_new (GTK_TREE_MODEL (state->model), (GtkTreePath *) l->data); workbook_signals_block (state); old_state = workbook_sheet_state_new (wb); for (l = selected_rows; l != NULL; l = l->next) { GtkTreeRowReference *ref = l->data; if (gtk_tree_row_reference_valid (ref)) { GtkTreePath *path = gtk_tree_row_reference_get_path (ref); GtkTreeIter sel_iter; Sheet *sheet; gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model), &sel_iter, path); gtk_tree_path_free (path); gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter, SHEET_POINTER, &sheet, -1); gtk_list_store_remove (state->model, &sel_iter); workbook_sheet_delete (sheet); } } cmd_reorganize_sheets (wbc, old_state, NULL); update_undo (state, wbc); workbook_signals_unblock (state); populate_sheet_list (state); cb_name_edited (NULL, NULL, NULL, state); g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_row_reference_free); }
static void cb_add_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state) { GtkTreeIter sel_iter, iter; GtkTreeSelection *selection = gtk_tree_view_get_selection (state->sheet_list); GList *selected_rows; int index = -1; WorkbookSheetState *old_state; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); Sheet *sheet, *old_sheet = NULL; g_return_if_fail (selection != NULL); g_return_if_fail (gtk_tree_selection_count_selected_rows (selection) == 1); selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL); gtk_tree_model_get_iter (GTK_TREE_MODEL (state->model), &sel_iter, (GtkTreePath *) selected_rows->data); g_list_free_full (selected_rows, (GDestroyNotify) gtk_tree_path_free); gtk_tree_model_get (GTK_TREE_MODEL (state->model), &sel_iter, SHEET_POINTER, &old_sheet, -1); index = old_sheet->index_in_wb; workbook_signals_block (state); old_state = workbook_sheet_state_new (wb); workbook_sheet_add (wb, index, gnm_sheet_get_max_cols (old_sheet), gnm_sheet_get_max_rows (old_sheet)); cmd_reorganize_sheets (wbc, old_state, NULL); update_undo (state, wbc); workbook_signals_unblock (state); g_signal_handler_block (state->model, state->model_row_insertion_listener); sheet = workbook_sheet_by_index (wb, index); gtk_list_store_insert_before (state->model, &iter, &sel_iter); g_signal_handler_unblock (state->model, state->model_row_insertion_listener); set_sheet_info_at_iter (state, &iter, sheet); cb_selection_changed (NULL, state); }
static void sort_asc_desc (SheetManager *state, gboolean asc) { WorkbookSheetState *old_state; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); GSList *l = NULL, *l_tmp; gint n = 0; gtk_tree_model_foreach (GTK_TREE_MODEL (state->model), gtmff_asc, &l); if (!asc) l = g_slist_reverse (l); workbook_signals_block (state); old_state = workbook_sheet_state_new (wb); for (l_tmp = l; l_tmp != NULL; l_tmp = l_tmp->next) { gtmff_sort_t *ptr = l_tmp->data; GtkTreeIter iter; Sheet *sheet; gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state->model), &iter, NULL, ptr->i); g_free (ptr->key); g_free (ptr); l_tmp->data = NULL; gtk_tree_model_get (GTK_TREE_MODEL (state->model), &iter, SHEET_POINTER, &sheet, -1); workbook_sheet_move (sheet, n - sheet->index_in_wb); n++; } g_slist_free (l); /* Now we change the list store */ dialog_sheet_order_update_sheet_order (state); cmd_reorganize_sheets (wbc, old_state, NULL); update_undo (state, wbc); workbook_signals_unblock (state); }
static void cb_apply_names_clicked (G_GNUC_UNUSED GtkWidget *ignore, SheetManager *state) { WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); WorkbookSheetState *old_state; GtkTreeIter this_iter; gint n = 0; /* Stop listening to changes in the sheet order. */ workbook_signals_block (state); old_state = workbook_sheet_state_new (wb); while (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (state->model), &this_iter, NULL, n)) { Sheet *this_sheet; char *new_name; gtk_tree_model_get (GTK_TREE_MODEL (state->model), &this_iter, SHEET_POINTER, &this_sheet, SHEET_NEW_NAME, &new_name, -1); if (*new_name) { g_object_set (this_sheet, "name", new_name, NULL); gtk_list_store_set (state->model, &this_iter, SHEET_NAME, new_name, SHEET_NEW_NAME, "", -1); } g_free (new_name); n++; } cmd_reorganize_sheets (wbc, old_state, NULL); gtk_label_set_text (GTK_LABEL (state->warning), ""); update_undo (state, wbc); workbook_signals_unblock (state); }
static void cb_toggled_direction (G_GNUC_UNUSED GtkCellRendererToggle *cell, gchar *path_string, SheetManager *state) { GtkTreeModel *model = GTK_TREE_MODEL (state->model); GtkTreePath *path = gtk_tree_path_new_from_string (path_string); GtkTreeIter iter; gboolean is_rtl = TRUE; Sheet *this_sheet = NULL; WorkbookSheetState *old_state = NULL; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); if (gtk_tree_model_get_iter (model, &iter, path)) { gtk_tree_model_get (model, &iter, SHEET_DIRECTION, &is_rtl, SHEET_POINTER, &this_sheet, -1); gtk_list_store_set (GTK_LIST_STORE (model), &iter, SHEET_DIRECTION, !is_rtl, SHEET_DIRECTION_IMAGE, is_rtl ? state->image_ltr : state->image_rtl, -1); } else { g_warning ("Did not get a valid iterator"); gtk_tree_path_free (path); return; } gtk_tree_path_free (path); old_state = workbook_sheet_state_new (wb); g_object_set (this_sheet, "text-is-rtl", !is_rtl, NULL); cmd_reorganize_sheets (wbc, old_state, this_sheet); update_undo (state, wbc); }
static GnmSolverResult * run_solver (SolverState *state, GnmSolverParameters *param) { GError *err = NULL; gboolean ok; GnmSheetRange sr; GOUndo *undo = NULL; GnmSolver *sol = NULL; GnmValue const *vinput; GtkWindow *top = GTK_WINDOW (gtk_widget_get_toplevel (state->dialog)); GnmSolverResult *res = NULL; state->ref_count++; sol = gnm_solver_factory_functional (param->options.algorithm, state->wbcg) ? gnm_solver_factory_create (param->options.algorithm, param) : NULL; if (!sol) { go_gtk_notice_dialog (top, GTK_MESSAGE_ERROR, _("The chosen solver is not functional.")); goto fail; } gtk_notebook_set_current_page (GTK_NOTEBOOK (state->notebook), -1); state->run.solver = sol; vinput = gnm_solver_param_get_input (param); gnm_sheet_range_from_value (&sr, vinput); if (!sr.sheet) sr.sheet = param->sheet; undo = clipboard_copy_range_undo (sr.sheet, &sr.range); g_signal_connect_swapped (G_OBJECT (sol), "notify::status", G_CALLBACK (cb_notify_status), state); g_signal_connect_swapped (G_OBJECT (sol), "notify::reason", G_CALLBACK (cb_notify_status), state); cb_notify_status (state); g_signal_connect_swapped (G_OBJECT (sol), "notify::result", G_CALLBACK (cb_notify_result), state); cb_notify_result (state); state->run.timer_source = g_timeout_add_seconds (1, (GSourceFunc)cb_timer_tick, state); cb_timer_tick (state); /* ---------------------------------------- */ ok = gnm_solver_start (sol, GNM_WBC (state->wbcg), &err); if (ok) { state->run.in_main++; go_cmd_context_set_sensitive (GO_CMD_CONTEXT (state->wbcg), FALSE); gtk_main (); go_cmd_context_set_sensitive (GO_CMD_CONTEXT (state->wbcg), TRUE); state->run.in_main--; ok = gnm_solver_has_solution (sol); } else if (err) { gnm_solver_set_reason (sol, err->message); } g_clear_error (&err); remove_objective_value_source (state); remove_timer_source (state); /* ---------------------------------------- */ if (ok) { GOUndo *redo; gnm_solver_store_result (sol); redo = clipboard_copy_range_undo (sr.sheet, &sr.range); if (param->options.program_report || param->options.sensitivity_report) { Workbook *wb = param->sheet->workbook; GOUndo *undo_report, *redo_report; undo_report = go_undo_binary_new (wb, workbook_sheet_state_new (wb), (GOUndoBinaryFunc)workbook_sheet_state_restore, NULL, (GFreeFunc)workbook_sheet_state_free); undo = go_undo_combine (undo, undo_report); create_report (sol, state); redo_report = go_undo_binary_new (wb, workbook_sheet_state_new (wb), (GOUndoBinaryFunc)workbook_sheet_state_restore, NULL, (GFreeFunc)workbook_sheet_state_free); redo = go_undo_combine (redo, redo_report); } cmd_generic (GNM_WBC (state->wbcg), _("Running solver"), undo, redo); res = g_object_ref (sol->result); undo = redo = NULL; } fail: if (undo) g_object_unref (undo); if (state->run.solver) { g_object_unref (state->run.solver); state->run.solver = NULL; } unref_state (state); return res; }
static void cb_toggled_visible (G_GNUC_UNUSED GtkCellRendererToggle *cell, gchar *path_string, gpointer data) { SheetManager *state = data; GtkTreeModel *model = GTK_TREE_MODEL (state->model); GtkTreeIter iter; GtkTreePath *path = gtk_tree_path_new_from_string (path_string); gboolean is_visible; Sheet *this_sheet; WorkbookSheetState *old_state; WorkbookControl *wbc = GNM_WBC (state->wbcg); Workbook *wb = wb_control_get_workbook (wbc); int cnt; if (!gtk_tree_model_get_iter (model, &iter, path)) { g_warning ("Did not get a valid iterator"); gtk_tree_path_free (path); return; } gtk_tree_model_get (model, &iter, SHEET_VISIBLE, &is_visible, SHEET_POINTER, &this_sheet, -1); if (is_visible) { cnt = sheet_order_cnt_visible (state); if (cnt <= 1) { go_gtk_notice_dialog (GTK_WINDOW (state->dialog), GTK_MESSAGE_ERROR, _("At least one sheet must remain visible!")); gtk_tree_path_free (path); return; } gtk_list_store_set (GTK_LIST_STORE (model), &iter, SHEET_VISIBLE, FALSE, SHEET_VISIBLE_IMAGE, NULL, -1); } else { gtk_list_store_set (GTK_LIST_STORE (model), &iter, SHEET_VISIBLE, TRUE, SHEET_VISIBLE_IMAGE, state->image_visible, -1); } gtk_tree_path_free (path); old_state = workbook_sheet_state_new (wb); g_object_set (this_sheet, "visibility", !is_visible ? GNM_SHEET_VISIBILITY_VISIBLE : GNM_SHEET_VISIBILITY_HIDDEN, NULL); cmd_reorganize_sheets (wbc, old_state, this_sheet); update_undo (state, wbc); if (is_visible) populate_sheet_list (state); }