//$Id: string-list-ops-priv.cc,v 1.6 2006/10/06 22:35:47 cactus Exp $ -*- c++ -*- /* Guikachu Copyright (C) 2001-2006 ÉRDI Gergõ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * 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 */ #include "string-list-ops-priv.h" #include // For g_assert using namespace Guikachu; using namespace Guikachu::StringListOps; AddOp::AddOp (const Glib::ustring &op_label, index_t index_, const std::string &item_) : OpBase (op_label), index (index_), item (item_) { } void AddOp::undo () { property_t &prop = get_prop (); value_t stringlist = prop; stringlist.erase (stringlist.begin () + index); prop = stringlist; } void AddOp::redo () { property_t &prop = get_prop (); value_t stringlist = prop; if (index >= stringlist.size ()) stringlist.push_back (item); else stringlist.insert (stringlist.begin () + index, item); prop = stringlist; } RemoveOp::RemoveOp (const Glib::ustring &op_label, index_t old_pos_, const std::string &old_item_) : OpBase (op_label), old_pos (old_pos_), old_item (old_item_) { } void RemoveOp::undo () { property_t &prop = get_prop (); value_t stringlist = prop; stringlist.insert (stringlist.begin () + old_pos, old_item); prop = stringlist; } void RemoveOp::redo () { property_t &prop = get_prop (); value_t stringlist = prop; stringlist.erase (stringlist.begin () + old_pos); prop = stringlist; } ChangeOp::ChangeOp (const Glib::ustring &op_label, index_t index_, const std::string &old_item_, const std::string &new_item_) : OpBase (op_label), index (index_), old_item (old_item_), new_item (new_item_) { } void ChangeOp::undo () { property_t &prop = get_prop (); value_t stringlist = prop; stringlist[index] = old_item; prop = stringlist; } void ChangeOp::redo () { property_t &prop = get_prop (); value_t stringlist = prop; stringlist[index] = new_item; prop = stringlist; } MoveOp::MoveOp (const Glib::ustring &op_label, index_t old_index, index_t new_index) : OpBase (op_label) { index_history.push_back (old_index); index_history.push_back (new_index); } MoveOp::MoveOp (const Glib::ustring &op_label, const index_list_t &index_history_head, const index_list_t &index_history_tail) : OpBase (op_label), index_history (index_history_head) { index_list_t::const_iterator tail_begin = index_history_tail.begin (); index_list_t::const_iterator tail_end = index_history_tail.end (); g_assert (index_history_tail.front () == index_history_head.back ()); index_history.insert (index_history.end (), ++tail_begin, tail_end); } void MoveOp::undo () { // Undo/redo may seem patently stupid and over-complicated, but // it's the only way to make cascading work property_t &prop = get_prop (); value_t items = prop; index_list_t::const_reverse_iterator rbegin = index_history.rbegin (); index_list_t::const_reverse_iterator rend = index_history.rend (); index_list_t::const_reverse_iterator curr, next; for (curr = rbegin, next = ++rbegin; next != rend; ++curr, ++next) std::iter_swap (items.begin () + *curr, items.begin () + *next); prop = items; } void MoveOp::redo () { property_t &prop = get_prop (); value_t items = prop; index_list_t::const_iterator begin = index_history.begin (); index_list_t::const_iterator end = index_history.end (); index_list_t::const_iterator curr, next; for (curr = begin, next = ++begin; next != end; ++curr, ++next) std::iter_swap (items.begin () + *curr, items.begin () + *next); prop = items; }