source: synfigstudio/trunk/fuentes/src/synfigapp/action.cpp @ 481

Last change on this file since 481 was 481, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 17.2 KB
Line 
1/* === S Y N F I G ========================================================= */
2/*!     \file action.cpp
3**      \brief Template File
4**
5**      $Id$
6**
7**      \legal
8**      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9**      Copyright (c) 2008 Chris Moore
10**
11**      This package is free software; you can redistribute it and/or
12**      modify it under the terms of the GNU General Public License as
13**      published by the Free Software Foundation; either version 2 of
14**      the License, or (at your option) any later version.
15**
16**      This package is distributed in the hope that it will be useful,
17**      but WITHOUT ANY WARRANTY; without even the implied warranty of
18**      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19**      General Public License for more details.
20**      \endlegal
21*/
22/* ========================================================================= */
23
24/* === H E A D E R S ======================================================= */
25
26#ifdef USING_PCH
27#       include "pch.h"
28#else
29#ifdef HAVE_CONFIG_H
30#       include <config.h>
31#endif
32
33#include "action.h"
34#include "instance.h"
35
36
37#include "actions/layerremove.h"
38#include "actions/layermove.h"
39#include "actions/layerraise.h"
40#include "actions/layerlower.h"
41#include "actions/layeradd.h"
42#include "actions/layeraddframe.h"
43#include "actions/layeractivate.h"
44#include "actions/layercopy.h"
45#include "actions/layerfit.h"
46#include "actions/layermakebline.h"
47#include "actions/layerparamset.h"
48#include "actions/layerparamsetstatic.h"
49#include "actions/layerparamunsetstatic.h"
50#include "actions/layerparamconnect.h"
51#include "actions/layerparamdisconnect.h"
52#include "actions/layerencapsulate.h"
53#include "actions/layerencapsulateswitch.h"
54#include "actions/layerduplicate.h"
55#include "actions/layersetdesc.h"
56#include "actions/layersetexcludefromrendering.h"
57#include "actions/layerzdepthrangeset.h"
58#include "actions/layerembed.h"
59#include "actions/layerextract.h"
60#include "actions/layerresetpose.h"
61
62#include "actions/valuenodeconstset.h"
63#include "actions/valuenodeconstsetstatic.h"
64#include "actions/valuenodeconstunsetstatic.h"
65#include "actions/valuenodeadd.h"
66#include "actions/valuenodereplace.h"
67#include "actions/valuenodelinkconnect.h"
68#include "actions/valuenodelinkdisconnect.h"
69#include "actions/valuenodedynamiclistinsert.h"
70#include "actions/valuenodedynamiclistremove.h"
71#include "actions/valuenodedynamiclistinsertsmart.h"
72#include "actions/valuenodedynamiclistremovesmart.h"
73#include "actions/valuenodedynamiclistloop.h"
74#include "actions/valuenodedynamiclistunloop.h"
75#include "actions/valuenodedynamiclistrotateorder.h"
76#include "actions/valuenodestaticlistinsert.h"
77#include "actions/valuenodestaticlistremove.h"
78#include "actions/valuenodestaticlistinsertsmart.h"
79#include "actions/valuenodestaticlistremovesmart.h"
80#include "actions/valuenodestaticlistloop.h"
81#include "actions/valuenodestaticlistunloop.h"
82#include "actions/valuenodestaticlistrotateorder.h"
83#include "actions/valuenoderename.h"
84#include "actions/valuenoderemove.h"
85
86#include "actions/valuedescset.h"
87#include "actions/valuedescsetinterpolation.h"
88#include "actions/valuedescexport.h"
89#include "actions/valuedescconvert.h"
90#include "actions/valuedescconnect.h"
91#include "actions/valuedescdisconnect.h"
92#include "actions/valuedesclink.h"
93#include "actions/valuedescblinelink.h"
94#include "actions/valuedescremovesmart.h"
95#include "actions/valuedescbonelink.h"
96#include "actions/valuedescskeletonlink.h"
97#include "actions/valuedesccreatechildbone.h"
98#include "actions/valuedescresetpose.h"
99
100#include "actions/waypointadd.h"
101#include "actions/waypointset.h"
102#include "actions/waypointsetsmart.h"
103#include "actions/waypointremove.h"
104#include "actions/waypointconnect.h"
105#include "actions/waypointdisconnect.h"
106// #include "actions/waypointsimpleadd.h"
107
108#include "actions/activepointadd.h"
109#include "actions/activepointset.h"
110#include "actions/activepointsetsmart.h"
111#include "actions/activepointsetoff.h"
112#include "actions/activepointseton.h"
113#include "actions/activepointremove.h"
114// #include "actions/activepointsimpleadd.h"
115
116#include "actions/keyframeadd.h"
117#include "actions/keyframeset.h"
118#include "actions/keyframeremove.h"
119#include "actions/keyframetoggl.h"
120#include "actions/keyframeduplicate.h"
121#include "actions/keyframewaypointset.h"
122#include "actions/keyframesetdelta.h"
123
124#include "actions/timepointsmove.h"
125#include "actions/timepointscopy.h"
126#include "actions/timepointsdelete.h"
127
128#include "actions/canvasdescriptionset.h"
129#include "actions/canvasidset.h"
130#include "actions/canvasmetadataerase.h"
131#include "actions/canvasmetadataset.h"
132#include "actions/canvasnameset.h"
133#include "actions/canvasrenddescset.h"
134#include "actions/canvasadd.h"
135#include "actions/canvasremove.h"
136
137#include "actions/editmodeset.h"
138
139#include "actions/blinepointtangentmerge.h"
140#include "actions/blinepointtangentsplit.h"
141
142#include "actions/gradientset.h"
143#include "actions/colorset.h"
144
145#include "actions/groupaddlayers.h"
146#include "actions/groupremovelayers.h"
147#include "actions/groupremove.h"
148#include "actions/grouprename.h"
149
150#include "canvasinterface.h"
151
152#include "general.h"
153
154#endif
155
156using namespace std;
157using namespace etl;
158using namespace synfig;
159using namespace synfigapp;
160using namespace Action;
161
162/* === P R O C E D U R E S ================================================= */
163
164/* === S T A T I C S ======================================================= */
165
166synfigapp::Action::Book *book_;
167
168/* === M E T H O D S ======================================================= */
169
170#define ADD_ACTION(x) { BookEntry &be(book()[x::name__]); \
171        be.name=x::name__; \
172        be.local_name=dgettext("synfigstudio",x::local_name__); \
173        be.version=x::version__; \
174        be.task=x::task__; \
175        be.priority=x::priority__; \
176        be.category=x::category__; \
177        be.factory=x::create; \
178        be.get_param_vocab=x::get_param_vocab; \
179        be.is_candidate=x::is_candidate; \
180        }
181
182
183Action::Main::Main()
184{
185        book_=new synfigapp::Action::Book();
186
187        ADD_ACTION(Action::LayerRemove);
188        ADD_ACTION(Action::LayerMove);
189        ADD_ACTION(Action::LayerRaise);
190        ADD_ACTION(Action::LayerLower);
191        ADD_ACTION(Action::LayerAdd);
192        ADD_ACTION(Action::LayerActivate);
193        ADD_ACTION(Action::LayerFit);
194        ADD_ACTION(Action::LayerMakeOutline);
195        ADD_ACTION(Action::LayerMakeAdvancedOutline);
196        ADD_ACTION(Action::LayerMakeRegion);
197        ADD_ACTION(Action::LayerParamSet);
198        ADD_ACTION(Action::LayerParamSetStatic);
199        ADD_ACTION(Action::LayerParamUnSetStatic);
200        ADD_ACTION(Action::LayerParamConnect);
201        ADD_ACTION(Action::LayerParamDisconnect);
202        ADD_ACTION(Action::LayerEncapsulate);
203        ADD_ACTION(Action::LayerEncapsulateSwitch);
204        ADD_ACTION(Action::LayerDuplicate);
205        ADD_ACTION(Action::LayerSetDesc);
206        ADD_ACTION(Action::LayerZDepthRangeSet);
207        ADD_ACTION(Action::LayerEmbed);
208        ADD_ACTION(Action::LayerExtract);
209        ADD_ACTION(Action::LayerSetExcludeFromRenderingOn);
210        ADD_ACTION(Action::LayerSetExcludeFromRenderingOff);
211        ADD_ACTION(Action::LayerAddFrame);
212        ADD_ACTION(Action::LayerCopy);
213        ADD_ACTION(Action::LayerResetPose);
214
215        ADD_ACTION(Action::ValueNodeConstSet);
216        ADD_ACTION(Action::ValueNodeConstSetStatic);
217        ADD_ACTION(Action::ValueNodeConstUnSetStatic);
218        ADD_ACTION(Action::ValueNodeAdd);
219        ADD_ACTION(Action::ValueNodeReplace);
220        ADD_ACTION(Action::ValueNodeLinkConnect);
221        ADD_ACTION(Action::ValueNodeLinkDisconnect);
222        ADD_ACTION(Action::ValueNodeDynamicListInsert);
223        ADD_ACTION(Action::ValueNodeDynamicListRemove);
224        ADD_ACTION(Action::ValueNodeDynamicListInsertSmart);
225        ADD_ACTION(Action::ValueNodeDynamicListInsertSmartKeepShape);
226        ADD_ACTION(Action::ValueNodeDynamicListRemoveSmart);
227        ADD_ACTION(Action::ValueNodeDynamicListLoop);
228        ADD_ACTION(Action::ValueNodeDynamicListUnLoop);
229        ADD_ACTION(Action::ValueNodeDynamicListRotateOrder);
230        ADD_ACTION(Action::ValueNodeStaticListInsert);
231        ADD_ACTION(Action::ValueNodeStaticListRemove);
232        ADD_ACTION(Action::ValueNodeStaticListInsertSmart);
233        ADD_ACTION(Action::ValueNodeStaticListRemoveSmart);
234        ADD_ACTION(Action::ValueNodeStaticListLoop);
235        ADD_ACTION(Action::ValueNodeStaticListUnLoop);
236        ADD_ACTION(Action::ValueNodeStaticListRotateOrder);
237        ADD_ACTION(Action::ValueNodeRename);
238        ADD_ACTION(Action::ValueNodeRemove);
239
240        ADD_ACTION(Action::ValueDescSet);
241        ADD_ACTION(Action::ValueDescSetInterpolation);
242        ADD_ACTION(Action::ValueDescExport);
243        ADD_ACTION(Action::ValueDescConvert);
244        ADD_ACTION(Action::ValueDescConnect);
245        ADD_ACTION(Action::ValueDescDisconnect);
246        ADD_ACTION(Action::ValueDescLink);
247        ADD_ACTION(Action::ValueDescLinkOpposite);
248        ADD_ACTION(Action::ValueDescBLineLink);
249        ADD_ACTION(Action::ValueDescRemoveSmart);
250        ADD_ACTION(Action::ValueDescBoneLink);
251        ADD_ACTION(Action::ValueDescSkeletonLink);
252        ADD_ACTION(Action::ValueDescCreateChildBone);
253        ADD_ACTION(Action::ValueDescResetPose);
254
255        ADD_ACTION(Action::WaypointAdd);
256        ADD_ACTION(Action::WaypointSet);
257        ADD_ACTION(Action::WaypointSetSmart);
258        ADD_ACTION(Action::WaypointRemove);
259        ADD_ACTION(Action::WaypointConnect);
260        ADD_ACTION(Action::WaypointDisconnect);
261//      ADD_ACTION(Action::WaypointSimpleAdd);
262
263        ADD_ACTION(Action::ActivepointAdd);
264        ADD_ACTION(Action::ActivepointSet);
265        ADD_ACTION(Action::ActivepointSetSmart);
266        ADD_ACTION(Action::ActivepointSetOn);
267        ADD_ACTION(Action::ActivepointSetOff);
268        ADD_ACTION(Action::ActivepointRemove);
269//      ADD_ACTION(Action::ActivepointSimpleAdd);
270
271        ADD_ACTION(Action::KeyframeAdd);
272        ADD_ACTION(Action::KeyframeSet);
273        ADD_ACTION(Action::KeyframeRemove);
274        ADD_ACTION(Action::KeyframeToggl);
275        ADD_ACTION(Action::KeyframeDuplicate);
276        ADD_ACTION(Action::KeyframeWaypointSet);
277        ADD_ACTION(Action::KeyframeSetDelta);
278
279        ADD_ACTION(Action::CanvasDescriptionSet);
280        ADD_ACTION(Action::CanvasIdSet);
281        ADD_ACTION(Action::CanvasNameSet)
282        ADD_ACTION(Action::CanvasMetadataErase);;
283        ADD_ACTION(Action::CanvasMetadataSet);
284        ADD_ACTION(Action::CanvasRendDescSet);
285        ADD_ACTION(Action::CanvasAdd);
286        ADD_ACTION(Action::CanvasRemove);
287
288        ADD_ACTION(Action::EditModeSet);
289
290        ADD_ACTION(Action::BLinePointTangentMerge);
291        ADD_ACTION(Action::BLinePointTangentMergeRadius);
292        ADD_ACTION(Action::BLinePointTangentMergeAngle);
293        ADD_ACTION(Action::BLinePointTangentSplit);
294        ADD_ACTION(Action::BLinePointTangentSplitRadius);
295        ADD_ACTION(Action::BLinePointTangentSplitAngle);
296
297        ADD_ACTION(Action::GradientSet);
298        ADD_ACTION(Action::ColorSetFromOC);
299        ADD_ACTION(Action::ColorSetFromFC);
300
301        ADD_ACTION(Action::TimepointsMove);
302        ADD_ACTION(Action::TimepointsCopy);
303        ADD_ACTION(Action::TimepointsDelete);
304
305        ADD_ACTION(Action::GroupAddLayers);
306        ADD_ACTION(Action::GroupRemoveLayers);
307        ADD_ACTION(Action::GroupRemove);
308        ADD_ACTION(Action::GroupRename);
309}
310
311Action::Main::~Main()
312{
313        delete book_;
314}
315
316
317Action::Book& Action::book() { return *book_; }
318
319
320Action::Handle
321Action::create(const synfig::String &name)
322{
323        if(!book().count(name))
324                return 0; //! \todo perhaps we should throw something instead?
325        return book()[name].factory();
326}
327
328
329Action::CandidateList
330Action::compile_candidate_list(const ParamList& param_list, Category category)
331{
332        Action::CandidateList ret;
333
334        Book::const_iterator iter;
335
336        //synfig::info("param_list.size()=%d",param_list.size());
337
338        for(iter=book().begin();iter!=book().end();++iter)
339        {
340                if((iter->second.category&category))
341                {
342                        if(iter->second.is_candidate(param_list))
343                        {
344                                //synfig::info("Action \"%s\" is in",iter->second.name.c_str());
345                                ret.push_back(iter->second);
346                        }
347                        else
348                        {
349                                //synfig::info("Action \"%s\" is not a candidate",iter->second.name.c_str());
350                        }
351                }
352                else
353                {
354                        //synfig::info("Action \"%s\" has unsuitable category",iter->second.name.c_str());
355                }
356        }
357
358        return ret;
359}
360
361Action::CandidateList::iterator
362Action::CandidateList::find(const synfig::String& x)
363{
364        iterator iter;
365        for(iter=begin();iter!=end();++iter)
366                if(iter->name==x)
367                        break;
368        return iter;
369}
370
371void
372Action::Base::set_param_list(const ParamList &param_list)
373{
374        ParamList::const_iterator iter;
375
376        for(iter=param_list.begin();iter!=param_list.end();++iter)
377                set_param(iter->first,iter->second);
378}
379
380synfig::String
381Action::Base::get_layer_descriptions(const std::list<synfig::Layer::Handle> layers, synfig::String singular_prefix, synfig::String plural_prefix)
382{
383        String ret;
384        bool first = true;
385
386        if (plural_prefix.empty())
387                plural_prefix = singular_prefix;
388
389        if (layers.empty())
390                return plural_prefix;
391
392        if (layers.size() == 1)
393                ret = singular_prefix;
394        else
395                ret = plural_prefix;
396
397        if (!ret.empty())
398                ret.push_back(' ');
399
400        for(std::list<synfig::Layer::Handle>::const_iterator iter=layers.begin(); iter!=layers.end(); ++iter)
401        {
402                if (first)
403                        first = false;
404                else
405                        ret += ", ";
406
407                ret += strprintf("'%s'", (*iter)->get_non_empty_description().c_str());
408        }
409
410        return ret;
411}
412
413synfig::String
414Action::Base::get_layer_descriptions(const std::list<std::pair<synfig::Layer::Handle,int> > layers, synfig::String singular_prefix, synfig::String plural_prefix)
415{
416        String ret;
417        bool first = true;
418
419        if (plural_prefix.empty())
420                plural_prefix = singular_prefix;
421
422        if (layers.empty())
423                return plural_prefix;
424
425        if (layers.size() == 1)
426                ret = singular_prefix;
427        else
428                ret = plural_prefix;
429
430        if (!ret.empty())
431                ret.push_back(' ');
432
433        for(std::list<std::pair<synfig::Layer::Handle,int> >::const_iterator iter=layers.begin(); iter!=layers.end(); ++iter)
434        {
435                if (first)
436                        first = false;
437                else
438                        ret += ", ";
439
440                ret += strprintf("'%s'", iter->first->get_non_empty_description().c_str());
441        }
442
443        return ret;
444}
445
446void
447Super::perform()
448{
449        set_dirty(false);
450
451        prepare();
452
453        ActionList::const_iterator iter;
454        for(iter=action_list_.begin();iter!=action_list_.end();++iter)
455        {
456                if (getenv("SYNFIG_DEBUG_ACTIONS"))
457                        synfig::info("%s:%d action: '%s'", __FILE__, __LINE__, (*iter)->get_name().c_str());
458
459                try
460                {
461                        try
462                        {
463                                (*iter)->perform();
464                                CanvasSpecific* canvas_specific(dynamic_cast<CanvasSpecific*>(iter->get()));
465                                if(canvas_specific && canvas_specific->is_dirty())
466                                        set_dirty(true);
467                        }
468                        catch(...)
469                        {
470                                if(iter!=action_list_.begin())
471                                {
472                                        for(--iter;iter!=action_list_.begin();--iter)
473                                                (*iter)->undo();
474                                        (*iter)->undo();
475                                }
476                                throw;
477                        }
478                }
479                catch(Error x)
480                {
481                        //synfig::info("%s:%d caught exception", __FILE__, __LINE__);
482                        throw Error(x.get_type(),((*iter)->get_local_name()+": "+x.get_desc()).c_str());
483                }
484                //synfig::info("%s:%d finished action: '%s'", __FILE__, __LINE__, (*iter)->get_name().c_str());
485        }
486}
487
488void
489Super::undo()
490{
491        set_dirty(false);
492
493        ActionList::const_reverse_iterator iter;
494        for(iter=const_cast<const ActionList &>(action_list_).rbegin();iter!=const_cast<const ActionList &>(action_list_).rend();++iter)
495        {
496                try {
497                        (*iter)->undo();
498                        CanvasSpecific* canvas_specific(dynamic_cast<CanvasSpecific*>(iter->get()));
499                        if(canvas_specific && canvas_specific->is_dirty())
500                                set_dirty(true);
501                }
502                catch(...)
503                {
504                        if(iter!=const_cast<const ActionList &>(action_list_).rbegin())
505                        {
506                                for(--iter;iter!=const_cast<const ActionList &>(action_list_).rbegin();--iter)
507                                        (*iter)->perform();
508                                (*iter)->perform();
509                        }
510                        throw;
511                }
512        }
513}
514
515void
516Super::add_action(etl::handle<Undoable> action)
517{
518        action_list_.push_back(action);
519        CanvasSpecific *specific_action=dynamic_cast<CanvasSpecific *>(action.get());
520        if(specific_action && !get_canvas())
521                set_canvas(specific_action->get_canvas());
522}
523
524void
525Super::add_action_front(etl::handle<Undoable> action)
526{
527        action_list_.push_front(action);
528        CanvasSpecific *specific_action=dynamic_cast<CanvasSpecific *>(action.get());
529        if(specific_action && !get_canvas())
530                set_canvas(specific_action->get_canvas());
531}
532
533
534Group::Group(const synfig::String &str):
535        name_(str),
536        ready_(true)
537{
538}
539
540Group::~Group()
541{
542}
543
544
545
546
547Action::ParamVocab
548Action::CanvasSpecific::get_param_vocab()
549{
550        ParamVocab ret;
551
552        ret.push_back(ParamDesc("canvas",Param::TYPE_CANVAS)
553                .set_local_name(_("Canvas"))
554                .set_desc(_("Selected Canvas"))
555        );
556
557        ret.push_back(ParamDesc("canvas_interface",Param::TYPE_CANVASINTERFACE)
558                .set_local_name(_("Canvas Interface"))
559                .set_desc(_("Canvas Interface"))
560                .set_optional(true)
561        );
562
563
564        return ret;
565}
566
567bool
568CanvasSpecific::set_param(const synfig::String& name, const Param &param)
569{
570        if(name=="canvas" && param.get_type()==Param::TYPE_CANVAS)
571        {
572                if(!param.get_canvas())
573                        return false;
574                set_canvas(param.get_canvas());
575
576                return true;
577        }
578        if(name=="canvas_interface" && param.get_type()==Param::TYPE_CANVASINTERFACE)
579        {
580                if(!param.get_canvas_interface())
581                        return false;
582                set_canvas_interface(param.get_canvas_interface());
583                if(!get_canvas())
584                        set_canvas(get_canvas_interface()->get_canvas());
585
586                return true;
587        }
588        if(name=="edit_mode" && param.get_type()==Param::TYPE_EDITMODE)
589        {
590                set_edit_mode(param.get_edit_mode());
591
592                return true;
593        }
594
595        return false;
596}
597
598bool
599CanvasSpecific::is_ready()const
600{
601        if(!get_canvas())
602                return false;
603        return true;
604}
605
606EditMode
607CanvasSpecific::get_edit_mode()const
608{
609        if(mode_!=MODE_UNDEFINED)
610                return mode_;
611
612        if(get_canvas_interface())
613                return get_canvas_interface()->get_mode();
614
615        return MODE_NORMAL;
616}
617
618//DOO static int undoable_count = 0;
619
620Undoable::Undoable():
621        active_(true)
622{
623        //DOO printf("%s:%d Undoable::Undoable() (we have %d)\n", __FILE__, __LINE__, ++undoable_count);
624}
625
626#ifdef _DEBUG
627Undoable::~Undoable() {
628        //DOO printf("%s:%d Undoable::~Undoable() (we now have %d)\n", __FILE__, __LINE__, --undoable_count);
629}
630
631void
632Undoable::ref()const
633{
634        if (getenv("SYNFIG_DEBUG_ACTION_REFCOUNT"))
635                printf("%s:%d %lx   ref undoable %*s -> %2d\n", __FILE__, __LINE__, uintptr_t(this), (count()*2), "", count()+1);
636
637        Base::ref();
638}
639
640bool
641Undoable::unref()const
642{
643        if (getenv("SYNFIG_DEBUG_ACTION_REFCOUNT"))
644                printf("%s:%d %lx unref undoable %*s%2d <-\n", __FILE__, __LINE__, uintptr_t(this), ((count()-1)*2), "", count()-1);
645
646        return Base::unref();
647}
648#endif
Note: See TracBrowser for help on using the repository browser.