/** * undo_redo: * @w: not used * @data: not used * * executes a redo request on the current document **/ void undo_redo(UndoMain *undostruct) { UndoInfo *redoinfo; GtkTextView *textview; GtkTextBuffer *buffer; GtkTextIter iter, start_iter, end_iter; GtkTextMark *mark; cm_return_if_fail(undostruct != NULL); if (undostruct->redo == NULL) return; redoinfo = (UndoInfo *)undostruct->redo->data; cm_return_if_fail (redoinfo != NULL); undostruct->undo = g_list_prepend(undostruct->undo, redoinfo); undostruct->redo = g_list_remove(undostruct->redo, redoinfo); textview = undostruct->textview; buffer = gtk_text_view_get_buffer(textview); undo_block(undostruct); /* Check if there is a selection active */ mark = gtk_text_buffer_get_insert(buffer); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(buffer, &iter); /* Move the view to the right position. */ gtk_adjustment_set_value(gtk_text_view_get_vadjustment(textview), redoinfo->window_position); switch (redoinfo->action) { case UNDO_ACTION_INSERT: gtk_text_buffer_get_iter_at_offset(buffer, &iter, redoinfo->start_pos); gtk_text_buffer_insert(buffer, &iter, redoinfo->text, -1); break; case UNDO_ACTION_DELETE: gtk_text_buffer_get_iter_at_offset(buffer, &start_iter, redoinfo->start_pos); gtk_text_buffer_get_iter_at_offset(buffer, &end_iter, redoinfo->end_pos); gtk_text_buffer_delete(buffer, &start_iter, &end_iter); break; case UNDO_ACTION_REPLACE_DELETE: gtk_text_buffer_get_iter_at_offset(buffer, &start_iter, redoinfo->start_pos); gtk_text_buffer_get_iter_at_offset(buffer, &end_iter, redoinfo->end_pos); gtk_text_buffer_delete(buffer, &start_iter, &end_iter); debug_print("UNDO_ACTION_REPLACE %s\n", redoinfo->text); /* "pull" another data structure from the list */ redoinfo = (UndoInfo *)undostruct->redo->data; cm_return_if_fail(redoinfo != NULL); undostruct->undo = g_list_prepend(undostruct->undo, redoinfo); undostruct->redo = g_list_remove(undostruct->redo, redoinfo); cm_return_if_fail(redoinfo->action == UNDO_ACTION_REPLACE_INSERT); gtk_text_buffer_insert(buffer, &start_iter, redoinfo->text, -1); break; case UNDO_ACTION_REPLACE_INSERT: /* This is needed only if we redo from a middle-click button */ gtk_text_buffer_get_iter_at_offset(buffer, &iter, redoinfo->start_pos); gtk_text_buffer_insert(buffer, &iter, redoinfo->text, -1); break; default: g_assert_not_reached(); break; } undostruct->change_state_func(undostruct, UNDO_STATE_TRUE, UNDO_STATE_UNCHANGED, undostruct->change_state_data); if (undostruct->redo == NULL) undostruct->change_state_func(undostruct, UNDO_STATE_UNCHANGED, UNDO_STATE_FALSE, undostruct->change_state_data); undo_unblock(undostruct); }
/** * undo_redo: * @w: not used * @data: not used * * executes a redo request on the current document **/ void undo_redo(UndoMain *undostruct) { UndoInfo *redoinfo; GtkTextView *textview; GtkTextBuffer *buffer; GtkTextIter iter, start_iter, end_iter; GtkTextMark *mark; g_return_if_fail(undostruct != NULL); if (undostruct->redo == NULL) return; redoinfo = (UndoInfo *)undostruct->redo->data; g_return_if_fail (redoinfo != NULL); undostruct->undo = g_list_prepend(undostruct->undo, redoinfo); undostruct->redo = g_list_remove(undostruct->redo, redoinfo); textview = undostruct->textview; buffer = gtk_text_view_get_buffer(textview); undo_block(undostruct); /* Check if there is a selection active */ mark = gtk_text_buffer_get_insert(buffer); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(buffer, &iter); /* Move the view to the right position. */ gtk_adjustment_set_value(textview->vadjustment, redoinfo->window_position); switch (redoinfo->action) { case UNDO_ACTION_INSERT: gtk_text_buffer_get_iter_at_offset (buffer, &iter, redoinfo->start_pos); gtk_text_buffer_insert(buffer, &iter, redoinfo->text, -1); debug_print("redo: UNDO_ACTION_DELETE: %d: %s\n", redoinfo->start_pos, redoinfo->text); break; case UNDO_ACTION_DELETE: gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, redoinfo->start_pos); gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, redoinfo->end_pos); gtk_text_buffer_delete(buffer, &start_iter, &end_iter); debug_print("redo: UNDO_ACTION_INSERT: %d: delete %d chars\n", redoinfo->start_pos, redoinfo->end_pos - redoinfo->start_pos); break; case UNDO_ACTION_REPLACE_DELETE: gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, redoinfo->start_pos); gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, redoinfo->end_pos); gtk_text_buffer_delete(buffer, &start_iter, &end_iter); debug_print("redo: UNDO_ACTION_REPLACE: %d: %s\n", redoinfo->start_pos, redoinfo->text); /* "pull" another data structure from the list */ redoinfo = (UndoInfo *)undostruct->redo->data; g_return_if_fail(redoinfo != NULL); undostruct->undo = g_list_prepend(undostruct->undo, redoinfo); undostruct->redo = g_list_remove(undostruct->redo, redoinfo); g_return_if_fail(redoinfo->action == UNDO_ACTION_REPLACE_INSERT); gtk_text_buffer_insert(buffer, &start_iter, redoinfo->text, -1); debug_print("redo: UNDO_ACTION_REPLACE: %d: %s\n", redoinfo->start_pos, redoinfo->text); break; case UNDO_ACTION_REPLACE_INSERT: g_warning("redo: this should not happen: UNDO_REPLACE_INSERT"); break; default: g_assert_not_reached(); break; } gtk_widget_queue_draw(GTK_WIDGET(textview)); undostruct->change_state_func(undostruct, UNDO_STATE_TRUE, UNDO_STATE_UNCHANGED, undostruct->change_state_data); if (undostruct->redo == NULL) undostruct->change_state_func(undostruct, UNDO_STATE_UNCHANGED, UNDO_STATE_FALSE, undostruct->change_state_data); undo_unblock(undostruct); }
/** * undo_undo: * @w: not used * @data: not used * * Executes an undo request on the current document **/ void undo_undo(UndoMain *undostruct) { UndoInfo *undoinfo; GtkTextView *textview; GtkTextBuffer *buffer; GtkTextIter iter, start_iter, end_iter; GtkTextMark *mark; cm_return_if_fail(undostruct != NULL); if (undostruct->undo == NULL) return; /* The undo data we need is always at the top op the stack. So, therefore, the first one */ undoinfo = (UndoInfo *)undostruct->undo->data; cm_return_if_fail(undoinfo != NULL); undoinfo->mergeable = FALSE; undostruct->redo = g_list_prepend(undostruct->redo, undoinfo); undostruct->undo = g_list_remove(undostruct->undo, undoinfo); textview = undostruct->textview; buffer = gtk_text_view_get_buffer(textview); undo_block(undostruct); /* Check if there is a selection active */ mark = gtk_text_buffer_get_insert(buffer); gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark); gtk_text_buffer_place_cursor(buffer, &iter); /* Move the view (scrollbars) to the correct position */ gtk_adjustment_set_value (GTK_ADJUSTMENT(gtk_text_view_get_vadjustment(textview)), undoinfo->window_position); switch (undoinfo->action) { case UNDO_ACTION_DELETE: gtk_text_buffer_get_iter_at_offset(buffer, &iter, undoinfo->start_pos); gtk_text_buffer_insert(buffer, &iter, undoinfo->text, -1); break; case UNDO_ACTION_INSERT: gtk_text_buffer_get_iter_at_offset(buffer, &start_iter, undoinfo->start_pos); gtk_text_buffer_get_iter_at_offset(buffer, &end_iter, undoinfo->end_pos); gtk_text_buffer_delete(buffer, &start_iter, &end_iter); break; case UNDO_ACTION_REPLACE_INSERT: gtk_text_buffer_get_iter_at_offset(buffer, &start_iter, undoinfo->start_pos); gtk_text_buffer_get_iter_at_offset(buffer, &end_iter, undoinfo->end_pos); gtk_text_buffer_delete(buffer, &start_iter, &end_iter); /* "pull" another data structure from the list */ if (undostruct->undo){ undoinfo = (UndoInfo *)undostruct->undo->data; undostruct->redo = g_list_prepend(undostruct->redo, undoinfo); undostruct->undo = g_list_remove(undostruct->undo, undoinfo); cm_return_if_fail(undoinfo != NULL); cm_return_if_fail(undoinfo->action == UNDO_ACTION_REPLACE_DELETE); gtk_text_buffer_insert(buffer, &start_iter, undoinfo->text, -1); } break; case UNDO_ACTION_REPLACE_DELETE: g_warning("This should not happen. UNDO_REPLACE_DELETE"); break; default: g_assert_not_reached(); break; } undostruct->change_state_func(undostruct, UNDO_STATE_UNCHANGED, UNDO_STATE_TRUE, undostruct->change_state_data); if (undostruct->undo == NULL) undostruct->change_state_func(undostruct, UNDO_STATE_FALSE, UNDO_STATE_UNCHANGED, undostruct->change_state_data); undo_unblock(undostruct); }