/*================================================================== * SwamiUndoFuncs.c - Swami item type undo functions * * Swami * Copyright (C) 1999-2003 Josh Green * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green * Swami homepage: http://swami.sourceforge.net *==================================================================*/ #include #include #include "SwamiUndoFuncs.h" #include "SwamiObject.h" #include "i18n.h" static void item_new_restore (SwamiObject *swami, const SwamiUndoItem *doitem); static void item_new_restate (SwamiObject *swami, const SwamiUndoItem *doitem, SwamiUndoItem *newitem); static void item_new_free (SwamiObject *swami, SwamiUndoItem *doitem); static gpointer item_new_save_state (IPItem *sfitem); static void item_remove_restore (SwamiObject *swami, const SwamiUndoItem *doitem); static void item_remove_restate (SwamiObject *swami, const SwamiUndoItem *doitem, SwamiUndoItem *newitem); static void item_remove_free (SwamiObject *swami, SwamiUndoItem *doitem); static gpointer item_remove_save_state (IPItem *sfitem); static void property_change_restore (SwamiObject *swami, const SwamiUndoItem *doitem); static void property_change_restate (SwamiObject *swami, const SwamiUndoItem *doitem, SwamiUndoItem *newitem); static void property_change_free (SwamiObject *swami, SwamiUndoItem *doitem); static gpointer property_change_save_state (SwamiObject *swami, IPItem *sfitem, const char *property_name); SwamiUndoTypeInfo swami_undo_type_info [] = { { NULL, NULL, NULL}, /* SWAMI_UNDO_NONE */ { N_("New sound font item"), item_new_restore, item_new_restate, item_new_free }, { N_("Remove sound font item"), item_remove_restore, item_remove_restate, item_remove_free }, { N_("Sound font item property change"), property_change_restore, property_change_restate, property_change_free }, }; /* ------------------------------------------------ */ /* created item save state (state of non-existence) */ /* ------------------------------------------------ */ void swami_undo_save_item_new (SwamiObject *swami, IPItem *sfitem) { gpointer st; g_return_if_fail (swami != NULL); g_return_if_fail (sfitem != NULL); SWAMI_UNDO_ENTER (swami); st = item_new_save_state (sfitem); swami_undo_item_add (swami, SWAMI_UNDO_ITEM_NEW, st); } static void item_new_restore (SwamiObject *swami, const SwamiUndoItem *doitem) { /* unlink item (the original state) */ instp_item_unlink (INSTP_ITEM (doitem->state)); } /* save redo state (SF item itself) */ static void item_new_restate (SwamiObject *swami, const SwamiUndoItem *doitem, SwamiUndoItem *newitem) { newitem->type = SWAMI_UNDO_ITEM_REMOVE; newitem->state = item_remove_save_state (INSTP_ITEM (doitem->state)); } static void item_new_free (SwamiObject *swami, SwamiUndoItem *doitem) { instp_item_unref (INSTP_ITEM (doitem->state)); /* release undo reference */ } static gpointer item_new_save_state (IPItem *sfitem) { /* add a reference to the item (undo now referencing it) */ instp_item_ref (sfitem); return (sfitem); /* return item pointer as state data */ } /* ------------------------------------- */ /* item remove undo type (save the item) */ /* ------------------------------------- */ typedef struct _ItemRemoveState { IPItem *sfitem; IPItem *parent; IPItem *next; } ItemRemoveState; void swami_undo_save_item_remove (SwamiObject *swami, IPItem *sfitem) { gpointer st; g_return_if_fail (swami != NULL); g_return_if_fail (sfitem != NULL); SWAMI_UNDO_ENTER (swami); st = item_remove_save_state (sfitem); swami_undo_item_add (swami, SWAMI_UNDO_ITEM_REMOVE, st); } static void item_remove_restore (SwamiObject *swami, const SwamiUndoItem *doitem) { ItemRemoveState *st = doitem->state; /* insert item (restore original state) */ instp_item_insert_before (st->parent, st->sfitem, st->next); } static void item_remove_restate (SwamiObject *swami, const SwamiUndoItem *doitem, SwamiUndoItem *newitem) { ItemRemoveState *st = doitem->state; newitem->type = SWAMI_UNDO_ITEM_NEW; newitem->state = item_new_save_state (st->sfitem); } static void item_remove_free (SwamiObject *swami, SwamiUndoItem *doitem) { ItemRemoveState *st = doitem->state; instp_item_unref (st->sfitem); instp_item_unref (st->parent); if (st->next) instp_item_unref (st->next); g_free (st); } /* save sound font item (reference it and save link pointers) */ static gpointer item_remove_save_state (IPItem *sfitem) { ItemRemoveState *st; st = g_malloc (sizeof (ItemRemoveState)); st->sfitem = sfitem; st->parent = sfitem->parent; st->next = sfitem->next; /* increment item references for undo state */ instp_item_ref (sfitem); instp_item_ref (sfitem->parent); if (sfitem->next) instp_item_ref (sfitem->next); return (st); } /* ------------------------------------- */ /* item property change */ /* ------------------------------------- */ typedef struct _PropertyChangeState { IPItem *sfitem; char *property_name; GValue *value; } PropertyChangeState; void swami_undo_save_property_change (SwamiObject *swami, IPItem *sfitem, const char *property_name) { PropertyChangeState *st; g_return_if_fail (swami != NULL); g_return_if_fail (sfitem != NULL); g_return_if_fail (property_name != NULL); SWAMI_UNDO_ENTER (swami); st = property_change_save_state (swami, sfitem, property_name); swami_undo_item_add (swami, SWAMI_UNDO_PROPERTY_CHANGE, st); } static void property_change_restore (SwamiObject *swami, const SwamiUndoItem *doitem) { PropertyChangeState *st; st = doitem->state; swami_item_set_property (swami, st->sfitem, st->property_name, st->value); } static void property_change_restate (SwamiObject *swami, const SwamiUndoItem *doitem, SwamiUndoItem *newitem) { PropertyChangeState *st; st = doitem->state; newitem->type = doitem->type; /* just copy the type */ newitem->state = property_change_save_state (swami, st->sfitem, st->property_name); } static void property_change_free (SwamiObject *swami, SwamiUndoItem *doitem) { PropertyChangeState *st; st = doitem->state; instp_item_unref (st->sfitem); /* release undo reference on item */ if (st->value) { g_value_unset (st->value); g_free (st->value); } g_free (st->property_name); g_free (st); } static gpointer property_change_save_state (SwamiObject *swami, IPItem *sfitem, const char *property_name) { PropertyChangeState *st; GValue v; st = g_malloc (sizeof (PropertyChangeState)); st->sfitem = sfitem; instp_item_ref (sfitem); /* add undo reference on item */ st->property_name = g_strdup (property_name); g_value_init (&v, G_TYPE_STRING); if (swami_item_get_property (swami, sfitem, property_name, &v)) { st->value = g_malloc (sizeof (GValue)); g_value_init (st->value, G_VALUE_TYPE (&v)); g_value_copy (&v, st->value); } else st->value = NULL; return (st); }