Nearly fix 1800783. Don't freeze dynamic parameters of PasteCanvas layers if there...
[synfig.git] / synfig-core / trunk / src / synfig / canvas.cpp
index 6875155..2464c42 100644 (file)
@@ -2,7 +2,7 @@
 /*!    \file canvas.cpp
 **     \brief Canvas Class Member Definitions
 **
-**     $Id: canvas.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
+**     $Id$
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
@@ -510,7 +510,7 @@ Canvas::surefind_canvas(const String &id)
                if(id[0]=='#')
                        return surefind_canvas(String(id,1));
 
-               //! \todo This needs alot more optimization
+               //! \todo This needs a lot more optimization
                String file_name(id,0,id.find_first_of('#'));
                String external_id(id,id.find_first_of('#')+1);
 
@@ -526,7 +526,7 @@ Canvas::surefind_canvas(const String &id)
                        if(is_absolute_path(file_name))
                                external_canvas=open_canvas(file_name);
                        else
-                               external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPERATOR+file_name);
+                               external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name);
 
                        if(!external_canvas)
                                throw Exception::FileNotFound(file_name);
@@ -553,7 +553,7 @@ Canvas::surefind_canvas(const String &id)
                return new_child_canvas(id);
        }
 
-       // If the first character is the seperator, then
+       // If the first character is the separator, then
        // this references the root canvas.
        if(id[0]==':')
                return get_root()->surefind_canvas(string(id,1));
@@ -595,7 +595,7 @@ Canvas::find_canvas(const String &id)const
                if(id[0]=='#')
                        return find_canvas(String(id,1));
 
-               //! \todo This needs alot more optimization
+               //! \todo This needs a lot more optimization
                String file_name(id,0,id.find_first_of('#'));
                String external_id(id,id.find_first_of('#')+1);
 
@@ -611,7 +611,7 @@ Canvas::find_canvas(const String &id)const
                        if(is_absolute_path(file_name))
                                external_canvas=open_canvas(file_name);
                        else
-                               external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPERATOR+file_name);
+                               external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name);
 
                        if(!external_canvas)
                                throw Exception::FileNotFound(file_name);
@@ -636,7 +636,7 @@ Canvas::find_canvas(const String &id)const
                throw Exception::IDNotFound("Child Canvas in Parent Canvas: (child)"+id);
        }
 
-       // If the first character is the seperator, then
+       // If the first character is the separator, then
        // this references the root canvas.
        if(id.find_first_of(':')==0)
                return get_root()->find_canvas(string(id,1));
@@ -700,24 +700,22 @@ Canvas::insert(iterator iter,etl::handle<Layer> x)
        //while(correct_canvas->is_inline())correct_canvas=correct_canvas->parent();
        Layer::LooseHandle loose_layer(x);
 
-       x->signal_added_to_group().connect(
-               sigc::bind(
-                       sigc::mem_fun(
-                               *correct_canvas,
-                               &Canvas::add_group_pair
-                       ),
-                       loose_layer
-               )
-       );
-       x->signal_removed_from_group().connect(
-               sigc::bind(
-                       sigc::mem_fun(
-                               *correct_canvas,
-                               &Canvas::remove_group_pair
-                       ),
-                       loose_layer
-               )
-       );
+       add_connection(loose_layer,
+                                  sigc::connection::connection(
+                                          x->signal_added_to_group().connect(
+                                                  sigc::bind(
+                                                          sigc::mem_fun(
+                                                                  *correct_canvas,
+                                                                  &Canvas::add_group_pair),
+                                                          loose_layer))));
+       add_connection(loose_layer,
+                                  sigc::connection::connection(
+                                          x->signal_removed_from_group().connect(
+                                                  sigc::bind(
+                                                          sigc::mem_fun(
+                                                                  *correct_canvas,
+                                                                  &Canvas::remove_group_pair),
+                                                          loose_layer))));
 
 
        if(!x->get_group().empty())
@@ -749,8 +747,10 @@ Canvas::erase(Canvas::iterator iter)
        // is using these signals, so I'll just
        // leave these next two lines like they
        // are for now - darco 07-30-2004
-       (*iter)->signal_added_to_group().clear();
-       (*iter)->signal_removed_from_group().clear();
+
+       // so don't wipe them out entirely
+       // - dooglus 09-21-2007
+       disconnect_connections(*iter);
 
        if(!op_flag_)remove_child(iter->get());
 
@@ -1013,7 +1013,7 @@ Canvas::get_meta_data_keys()const
 }
 
 void
-synfig::optimize_layers(Context context, Canvas::Handle op_canvas)
+synfig::optimize_layers(Context context, Canvas::Handle op_canvas, bool seen_motion_blur)
 {
        Context iter;
 
@@ -1035,11 +1035,16 @@ synfig::optimize_layers(Context context, Canvas::Handle op_canvas)
                if(value.get_type()==ValueBase::TYPE_REAL && value.get(Real())==0)
                        continue;
 
+               if(layer->get_name()=="MotionBlur")
+                       seen_motion_blur = true;
+
                Layer_PasteCanvas* paste_canvas(static_cast<Layer_PasteCanvas*>(layer.get()));
                if(layer->get_name()=="PasteCanvas" && paste_canvas->get_time_offset()==0)
                {
                        Canvas::Handle sub_canvas(Canvas::create_inline(op_canvas));
-                       optimize_layers(paste_canvas->get_sub_canvas()->get_context(),sub_canvas);
+                       Canvas::Handle paste_sub_canvas = paste_canvas->get_sub_canvas();
+                       if(paste_sub_canvas)
+                               optimize_layers(paste_sub_canvas->get_context(),sub_canvas,seen_motion_blur);
 //#define SYNFIG_OPTIMIZE_PASTE_CANVAS 1
 
 #ifdef SYNFIG_OPTIMIZE_PASTE_CANVAS
@@ -1075,12 +1080,18 @@ synfig::optimize_layers(Context context, Canvas::Handle op_canvas)
                        }catch(int) { }
 #endif
                        Layer::Handle new_layer(Layer::create("PasteCanvas"));
-                       dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_do_not_muck_with_time(true);
+                       dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_muck_with_time(false);
+                       if (seen_motion_blur)
+                       {
+                               Layer::DynamicParamList dynamic_param_list(paste_canvas->dynamic_param_list());
+                               for(Layer::DynamicParamList::const_iterator iter(dynamic_param_list.begin()); iter != dynamic_param_list.end(); ++iter)
+                                       new_layer->connect_dynamic_param(iter->first, iter->second);
+                       }
                        Layer::ParamList param_list(paste_canvas->get_param_list());
                        //param_list.erase("canvas");
                        new_layer->set_param_list(param_list);
                        dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_sub_canvas(sub_canvas);
-                       dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_do_not_muck_with_time(false);
+                       dynamic_cast<Layer_PasteCanvas*>(new_layer.get())->set_muck_with_time(true);
                        layer=new_layer;
                }
 
@@ -1177,6 +1188,21 @@ Canvas::remove_group_pair(String group, etl::handle<Layer> layer)
 }
 
 void
+Canvas::add_connection(Layer::LooseHandle layer, sigc::connection connection)
+{
+       connections_[layer].push_back(connection);
+}
+
+void
+Canvas::disconnect_connections(Layer::LooseHandle layer)
+{
+       std::vector<sigc::connection>::iterator iter;
+       for(iter=connections_[layer].begin();iter!=connections_[layer].end();++iter)
+               iter->disconnect();
+       connections_[layer].clear();
+}
+
+void
 Canvas::rename_group(const String&old_name,const String&new_name)
 {
        if(is_inline() && parent_)