/* * Copyright (c) 2015 Tricoire Sebastien 3dsman@free.fr * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * */ #include "actions/OE_actionsStitchs.h" #include "actions/OE_actionsLineStitchs.h" #include "actions/OE_actionsBirailStitchs.h" #include "actions/OE_actionsFillStitchs.h" #include "stitchs/OE_linkstitch.h" #include "OE_document.h" #include ///////// actionNewStitch /////////////// OE_actionNewStitch::OE_actionNewStitch(OE_document* doc, OE_stitchs* stitch) : OE_actions(doc), actionStitch(nullptr), linkStitch(nullptr) { if (document) { if (document->stitchs.size() > 0) { OE_stitchs* tmpstitch = document->stitchs.back(); linkStitch = new OE_linkstitch(tmpstitch, stitch); document->addStitch(linkStitch); } actionStitch = stitch; document->addStitch( actionStitch); } } OE_actionNewStitch::~OE_actionNewStitch() { if (!active) { if (linkStitch) { delete linkStitch; } } } void OE_actionNewStitch::undo() { if (active) { if (linkStitch) { document->removeStitch(linkStitch); } if (actionStitch) { document->removeStitch(actionStitch); } active = false; } } void OE_actionNewStitch::redo() { if (!active) { if (linkStitch) { document->addStitch(linkStitch); } if (actionStitch) { document->addStitch(actionStitch); } active = true; } } ///////// actionDelStitch /////////////// /// \brief OE_actionDelStitch::OE_actionDelStitch /// \param stitch /// OE_actionDelStitch::OE_actionDelStitch(OE_document* doc, OE_stitchs* stitch) : OE_actions(doc), actionStitch(nullptr), linkStitchBefore(nullptr), linkStitchAfter(nullptr), nextStitch(nullptr), selNextLinkStitchBefore(nullptr), selNextLinkStitchAfter(nullptr), selNextStitch(nullptr), newLinkStitch(nullptr), linkStitchBeforeSelected(false),linkStitchAfterSelected(false), selected(false) { if (document) { actionStitch = stitch; std::list::iterator it = find (document->stitchs.begin(), document->stitchs.end(), actionStitch); if (it != document->stitchs.end()) { // if this is not the first stich if (it != document->stitchs.begin()) { //get the previous one, store the linkstitch and remove it from the list it--; linkStitchBefore = dynamic_cast(*it); if (linkStitchBefore) { it = document->stitchs.erase(it); } else { it++; } } //remove the actionStitch from the list it = document->stitchs.erase(it); nextStitch = *it; //if there is other stitches after the actionStitch get the next one, store it in linkStitchAfter and remove it from the list if (it != document->stitchs.end()) { linkStitchAfter = dynamic_cast(*it); if (linkStitchAfter) { it = document->stitchs.erase(it); nextStitch = *it; } //linkStitchAfter = *it; //it = document->stitchs.erase(it); } } if (linkStitchBefore && linkStitchAfter) { newLinkStitch = new OE_linkstitch(linkStitchBefore->getStitchStart(), linkStitchAfter->getStitchEnd()); document->stitchs.insert(it, newLinkStitch); } it = find(document->selectedStitchs.begin(), document->selectedStitchs.end(), actionStitch); if (it != document->selectedStitchs.end()) { selected = true; it = document->selectedStitchs.erase(it); if (it != document->stitchs.end()) { selNextStitch = *it; } } if (linkStitchBefore) { it = find (document->selectedStitchs.begin(), document->selectedStitchs.end(), linkStitchBefore); if (it != document->selectedStitchs.end()) { linkStitchBeforeSelected = true; it = document->selectedStitchs.erase(it); if (it != document->stitchs.end()) { selNextLinkStitchBefore = *it; } } } if (linkStitchAfter) { it = find (document->selectedStitchs.begin(), document->selectedStitchs.end(), linkStitchAfter); if (it != document->selectedStitchs.end()) { linkStitchAfterSelected = true; it = document->selectedStitchs.erase(it); if (it != document->stitchs.end()) { selNextLinkStitchAfter = *it; } } } } } OE_actionDelStitch::~OE_actionDelStitch() { if (active) { if (linkStitchBefore) { delete linkStitchBefore; } if (linkStitchAfter) { delete linkStitchAfter; } if (actionStitch) { delete actionStitch; } } else if (newLinkStitch) { delete newLinkStitch; } } void OE_actionDelStitch::undo() { if (actionStitch && active) { if (newLinkStitch) { document->stitchs.remove(newLinkStitch); } std::list::iterator it = document->stitchs.end(); if (nextStitch) { it = find (document->stitchs.begin(), document->stitchs.end(), nextStitch); } if (linkStitchAfter) { it = document->stitchs.insert(it, linkStitchAfter); } it = document->stitchs.insert(it, actionStitch); if (linkStitchBefore) { it = document->stitchs.insert(it, linkStitchBefore); } if (linkStitchAfterSelected) { it = document->selectedStitchs.end(); if (selNextLinkStitchAfter) { it = find (document->selectedStitchs.begin(), document->selectedStitchs.end(), selNextLinkStitchAfter); } document->selectedStitchs.insert(it, linkStitchAfter); } if (linkStitchBeforeSelected) { it = document->selectedStitchs.end(); if (selNextLinkStitchBefore) { it = find (document->selectedStitchs.begin(), document->selectedStitchs.end(), selNextLinkStitchBefore); } document->selectedStitchs.insert(it, linkStitchBefore); } if (selected) { it = document->selectedStitchs.end(); if (selNextStitch) { it = find (document->selectedStitchs.begin(), document->selectedStitchs.end(), selNextStitch); } document->selectedStitchs.insert(it, actionStitch); } } active = false; } void OE_actionDelStitch::redo() { if (actionStitch && !active) { if (selected) { document->selectedStitchs.remove(actionStitch); } if (linkStitchBeforeSelected) { document->selectedStitchs.remove(linkStitchBefore); } if (linkStitchAfterSelected) { document->selectedStitchs.remove(linkStitchAfter); } if(linkStitchBefore) { document->stitchs.remove(linkStitchBefore); } document->stitchs.remove(actionStitch); if(linkStitchAfter) { document->stitchs.remove(linkStitchAfter); } if (newLinkStitch) { std::list::iterator it = find (document->stitchs.begin(), document->stitchs.end(), nextStitch); it = document->stitchs.insert(it, newLinkStitch); } } active = true; } ///////// OE_actionSetStitchMaxLen /////////////// /// \brief OE_actionSetStitchMaxLen::OE_actionSetStitchMaxLen /// \param stitch /// \param maxLen /// OE_actionSetStitchMaxLen::OE_actionSetStitchMaxLen(OE_document* doc, OE_stitchs* stitch, float maxLen) : OE_actions(doc), actionStitch(nullptr) { if (document && stitch) { actionStitch = stitch; oldMaxLen = actionStitch->getMaxLen(); actionStitch->setMaxLen(maxLen); } } OE_actionSetStitchMaxLen::~OE_actionSetStitchMaxLen() { } void OE_actionSetStitchMaxLen::undo() { if (active) { float tmpMaxLen = actionStitch->getMaxLen(); actionStitch->setMaxLen(oldMaxLen); oldMaxLen = tmpMaxLen; active = false; } } void OE_actionSetStitchMaxLen::redo() { if (!active) { float tmpMaxLen = actionStitch->getMaxLen(); actionStitch->setMaxLen(oldMaxLen); oldMaxLen = tmpMaxLen; active = true; } } ///////// actionSetStitchThread /////////////// OE_actionSetStitchThread::OE_actionSetStitchThread(OE_document* doc, OE_stitchs* stitch, OE_thread* thread) : OE_actions(doc), actionStitch(nullptr), oldThread(nullptr) { if (document && stitch) { actionStitch = stitch; oldThread = actionStitch->getThread(); actionStitch->setThread(thread); } } OE_actionSetStitchThread::~OE_actionSetStitchThread() { } void OE_actionSetStitchThread::undo() { if (active) { OE_thread * tmpThread = actionStitch->getThread(); actionStitch->setThread(oldThread); oldThread = tmpThread; active = false; } } void OE_actionSetStitchThread::redo() { if (!active) { OE_thread * tmpThread = actionStitch->getThread(); actionStitch->setThread(oldThread); oldThread = tmpThread; active = true; } } ///////// actionScaleSelectedStitchLen /////////////// OE_actionScaleSelectedStitchLen::OE_actionScaleSelectedStitchLen(OE_document* doc, float scale) : OE_actions(doc) { if (document) { actionScaleSelectedLineStitchLen = new OE_actionScaleSelectedLineStitchLen(document, scale); actionScaleSelectedBirailStitchLen = new OE_actionScaleSelectedBirailStitchLen(document, scale); actionScaleSelectedFillStitchLen = new OE_actionScaleSelectedFillStitchLen(document, scale); } } OE_actionScaleSelectedStitchLen::~OE_actionScaleSelectedStitchLen() { if(actionScaleSelectedLineStitchLen) { delete actionScaleSelectedLineStitchLen; } if(actionScaleSelectedBirailStitchLen) { delete actionScaleSelectedBirailStitchLen; } if(actionScaleSelectedFillStitchLen) { delete actionScaleSelectedFillStitchLen; } } void OE_actionScaleSelectedStitchLen::undo() { if (active) { actionScaleSelectedLineStitchLen->undo(); actionScaleSelectedBirailStitchLen->undo(); actionScaleSelectedFillStitchLen->undo(); active = false; } } void OE_actionScaleSelectedStitchLen::redo() { if (!active) { actionScaleSelectedLineStitchLen->redo(); actionScaleSelectedBirailStitchLen->redo(); actionScaleSelectedFillStitchLen->redo(); active = true; } } ///////// actionScaleSelectedStitchWidth /////////////// OE_actionScaleSelectedStitchWidth::OE_actionScaleSelectedStitchWidth(OE_document* doc, float scale) : OE_actions(doc) { if (document) { actionScaleSelectedLineStitchWidth = new OE_actionScaleSelectedLineStitchWidth(document, scale); actionScaleSelectedFillStitchWidth = new OE_actionScaleSelectedFillStitchWidth(document, scale); } } OE_actionScaleSelectedStitchWidth::~OE_actionScaleSelectedStitchWidth() { if (!active) { if (actionScaleSelectedLineStitchWidth) { delete actionScaleSelectedLineStitchWidth; } if(actionScaleSelectedFillStitchWidth) { delete actionScaleSelectedFillStitchWidth; } } } void OE_actionScaleSelectedStitchWidth::undo() { if (active) { actionScaleSelectedLineStitchWidth->undo(); actionScaleSelectedFillStitchWidth->undo(); active = false; } } void OE_actionScaleSelectedStitchWidth::redo() { if (!active) { actionScaleSelectedLineStitchWidth->redo(); actionScaleSelectedFillStitchWidth->redo(); active = true; } } ///////// OE_actionSetSelectedStitchPattern /////////////// OE_actionSetSelectedStitchPattern::OE_actionSetSelectedStitchPattern(OE_document* doc, OE_pattern* pattern) : OE_actions(doc) { if (document) { actionSetSelectedLineStitchPattern = new OE_actionSetSelectedLineStitchPattern(document, pattern); actionSetSelectedFillStitchPattern = new OE_actionSetSelectedFillStitchPattern(document, pattern); } } OE_actionSetSelectedStitchPattern::~OE_actionSetSelectedStitchPattern() { if (!active) { if (actionSetSelectedLineStitchPattern) { delete actionSetSelectedLineStitchPattern; } if(actionSetSelectedFillStitchPattern) { delete actionSetSelectedFillStitchPattern; } } } void OE_actionSetSelectedStitchPattern::undo() { if (active) { actionSetSelectedLineStitchPattern->undo(); actionSetSelectedFillStitchPattern->undo(); active = false; } } void OE_actionSetSelectedStitchPattern::redo() { if (!active) { actionSetSelectedLineStitchPattern->redo(); actionSetSelectedFillStitchPattern->redo(); active = true; } } ///////// OE_actionShiftSelectedStitches /////////////// OE_actionMoveInListSelectedStitches::OE_actionMoveInListSelectedStitches(OE_document* doc, int posInsertion) : OE_actions(doc) { if (document) { actionStitches = document->stitchs; std::list tmpBeforeStitchList; std::list tmpAfterStitchList; std::list tmpSelectedStitchList; bool selected = false; int curIndex = 0; // to always get good insertion point (just after a linkstitches) posInsertion += posInsertion & 1; //loop on every stitches, split before and after insertion and make a lists with selected ones for (std::list::iterator stitchIt=document->stitchs.begin(); stitchIt!=document->stitchs.end(); ++stitchIt) { curIndex++; OE_linkstitch* linkStitch = dynamic_cast(*stitchIt); if (!linkStitch) { //check if the stitch is selected auto it = std::find(document->selectedStitchs.begin(), document->selectedStitchs.end(), *stitchIt); if(it != document->selectedStitchs.end()) { //if we start a new selected block if (selected == false) startNewBlock(tmpSelectedStitchList, *stitchIt); selected = true; } else { //if we start a new unselected block if (selected == true) { if (curIndex <= posInsertion) startNewBlock(tmpBeforeStitchList, *stitchIt); else startNewBlock(tmpAfterStitchList, *stitchIt); } selected = false; } } //add the stitch to the corresponding list if (selected) tmpSelectedStitchList.push_back(*stitchIt); else { if (curIndex <= posInsertion) //if we're before the insertion point tmpBeforeStitchList.push_back(*stitchIt); else tmpAfterStitchList.push_back(*stitchIt); } } //remove last linkstitch in each lists if needed OE_linkstitch* linkStitch = dynamic_cast(tmpBeforeStitchList.back()); if (linkStitch) { document->selectedStitchs.remove(linkStitch); oldLinkStitches.push_back(linkStitch); tmpBeforeStitchList.pop_back(); } linkStitch = dynamic_cast(tmpAfterStitchList.back()); if (linkStitch) { document->selectedStitchs.remove(linkStitch); oldLinkStitches.push_back(linkStitch); tmpAfterStitchList.pop_back(); } linkStitch = dynamic_cast(tmpSelectedStitchList.back()); if (linkStitch) { document->selectedStitchs.remove(linkStitch); oldLinkStitches.push_back(linkStitch); tmpSelectedStitchList.pop_back(); } //concatenate the lists if (tmpSelectedStitchList.size()>0) { if (tmpBeforeStitchList.size()>0) { OE_linkstitch* link = new OE_linkstitch(tmpBeforeStitchList.back(),tmpSelectedStitchList.front()); newLinkStitches.push_back(link); tmpBeforeStitchList.push_back(link); } tmpBeforeStitchList.insert(tmpBeforeStitchList.end(),tmpSelectedStitchList.begin(),tmpSelectedStitchList.end()); if (tmpAfterStitchList.size()>0) { OE_linkstitch* link = new OE_linkstitch(tmpBeforeStitchList.back(),tmpAfterStitchList.front()); newLinkStitches.push_back(link); tmpBeforeStitchList.push_back(link); tmpBeforeStitchList.insert(tmpBeforeStitchList.end(),tmpAfterStitchList.begin(),tmpAfterStitchList.end()); } //then replace stitchlist in the document document->stitchs = tmpBeforeStitchList; } } } void OE_actionMoveInListSelectedStitches::startNewBlock(std::list &list, OE_stitchs* stitch) { if (list.size()!=0) { //remove previous linkstitch OE_linkstitch* linkStitch = dynamic_cast(list.back()); document->selectedStitchs.remove(linkStitch); oldLinkStitches.push_back(linkStitch); list.pop_back(); //and make a new one OE_linkstitch* link = new OE_linkstitch(list.back(),stitch); newLinkStitches.push_back(link); list.push_back(link); } } OE_actionMoveInListSelectedStitches::~OE_actionMoveInListSelectedStitches() { if (active) { for(auto&& stitch : oldLinkStitches) { delete stitch; } }else { for(auto&& stitch : newLinkStitches) { delete stitch; } } } void OE_actionMoveInListSelectedStitches::undo() { if (active) { document->stitchs = switchVal(document->stitchs, &actionStitches); active = false; } } void OE_actionMoveInListSelectedStitches::redo() { if (!active) { document->stitchs = switchVal(document->stitchs, &actionStitches); active = true; } }