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_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); }
/* Copy text from the cutbuffer into the current filestruct. */ void do_uncut_text(void) { assert(openfile->current != NULL && openfile->current->data != NULL); /* If the cutbuffer is empty, get out. */ if (cutbuffer == NULL) return; add_undo(PASTE); /* Add a copy of the text in the cutbuffer to the current filestruct * at the current cursor position. */ copy_from_filestruct(cutbuffer); update_undo(PASTE); /* Set the current place we want to where the text from the * cutbuffer ends. */ openfile->placewewant = xplustabs(); /* Mark the file as modified. */ set_modified(); /* Update the screen. */ edit_refresh_needed = TRUE; #ifndef DISABLE_COLOR reset_multis(openfile->current, FALSE); #endif #ifdef DEBUG dump_filestruct_reverse(); #endif }
/* Move text from the current filestruct into the cutbuffer. */ void do_cut_text_void(void) { #ifndef NANO_TINY add_undo(CUT); #endif do_cut_text(FALSE, FALSE); #ifndef NANO_TINY update_undo(CUT); #endif }
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); }
/* Move text from the current linestruct into the cutbuffer. If * copy_text is TRUE, copy the text back into the linestruct afterward. * If cut_till_eof is TRUE, move all text from the current cursor * position to the end of the file into the cutbuffer. */ void do_cut_text( #ifndef NANO_TINY bool copy_text, bool cut_till_eof, bool undoing #else void #endif ) { #ifndef NANO_TINY linestruct *cb_save = NULL; /* The current end of the cutbuffer, before we add text to * it. */ size_t cb_save_len = 0; /* The length of the string at the current end of the cutbuffer, * before we add text to it. */ bool old_no_newlines = ISSET(NO_NEWLINES); #endif assert(openfile->current != NULL && openfile->current->data != NULL); /* If keep_cutbuffer is FALSE and the cutbuffer isn't empty, blow * away the text in the cutbuffer. */ if (!keep_cutbuffer && cutbuffer != NULL) { free_filestruct(cutbuffer); cutbuffer = NULL; #ifdef DEBUG fprintf(stderr, "Blew away cutbuffer =)\n"); #endif } #ifndef NANO_TINY if (copy_text) { if (cutbuffer != NULL) { /* If the cutbuffer isn't empty, save where it currently * ends. This is where we'll add the new text. */ cb_save = cutbottom; cb_save_len = strlen(cutbottom->data); } /* Set NO_NEWLINES to TRUE, so that we don't disturb the last * line of the file when moving text to the cutbuffer. */ SET(NO_NEWLINES); } #endif /* Set keep_cutbuffer to TRUE, so that the text we're going to move * into the cutbuffer will be added to the text already in the * cutbuffer instead of replacing it. */ keep_cutbuffer = TRUE; #ifndef NANO_TINY if (cut_till_eof) { /* If cut_till_eof is TRUE, move all text up to the end of the * file into the cutbuffer. */ cut_to_eof(); } else if (openfile->mark_set) { /* If the mark is on, move the marked text to the cutbuffer, and * turn the mark off. */ cut_marked(); openfile->mark_set = FALSE; } else if (ISSET(CUT_TO_END)) /* If the CUT_TO_END flag is set, move all text up to the end of * the line into the cutbuffer. */ cut_to_eol(); else #endif /* Move the entire line into the cutbuffer. */ cut_line(); #ifndef NANO_TINY if (copy_text) { /* Copy the text in the cutbuffer, starting at its saved end if * there is one, back into the linestruct. This effectively * uncuts the text we just cut without marking the file as * modified. */ if (cutbuffer != NULL) { if (cb_save != NULL) { cb_save->data += cb_save_len; copy_from_filestruct(cb_save); cb_save->data -= cb_save_len; } else copy_from_filestruct(cutbuffer); /* Set the current place we want to where the text from the * cutbuffer ends. */ openfile->placewewant = xplustabs(); } /* Set NO_NEWLINES back to what it was before, since we're done * disturbing the text. */ if (!old_no_newlines) UNSET(NO_NEWLINES); } else if (!undoing) update_undo(cut_till_eof ? CUT_EOF : CUT); /* Leave the text in the cutbuffer, and mark the file as * modified. */ if (!copy_text) #endif /* !NANO_TINY */ set_modified(); /* Update the screen. */ edit_refresh_needed = TRUE; #ifndef DISABLE_COLOR reset_multis(openfile->current, FALSE); #endif #ifdef DEBUG dump_filestruct(cutbuffer); #endif }
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); }
/* Cut from the current cursor position to the end of the file. */ void do_cut_till_eof(void) { add_undo(CUT_EOF); do_cut_text(FALSE, TRUE); update_undo(CUT_EOF); }