X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-core%2Ftrunk%2Fsrc%2Fsynfig%2Fcanvas.cpp;h=2bbb743366aed661dfc3dde7956999c420edee08;hb=9459638ad6797b8139f1e9f0715c96076dbf0890;hp=b02053c203676a6416afe8cd01601593a538a733;hpb=ab420f25e2dec25227844d356de45a82a2369fd3;p=synfig.git diff --git a/synfig-core/trunk/src/synfig/canvas.cpp b/synfig-core/trunk/src/synfig/canvas.cpp index b02053c..2bbb743 100644 --- a/synfig-core/trunk/src/synfig/canvas.cpp +++ b/synfig-core/trunk/src/synfig/canvas.cpp @@ -39,6 +39,7 @@ #include "time.h" #include "context.h" #include "layer_pastecanvas.h" +#include "loadcanvas.h" #include #endif @@ -47,10 +48,12 @@ using namespace synfig; using namespace etl; using namespace std; -namespace synfig { extern Canvas::Handle open_canvas(const String &filename, String &errors); }; +namespace synfig { extern Canvas::Handle open_canvas(const String &filename, String &errors, String &warnings); }; /* === M A C R O S ========================================================= */ +#define ALLOW_CLONE_NON_INLINE_CANVASES + struct _CanvasCounter { static int counter; @@ -399,7 +402,8 @@ Canvas::find_value_node(const String &id)const //synfig::warning("constfind:value_node_id: "+value_node_id); //synfig::warning("constfind:canvas_id: "+canvas_id); - return find_canvas(canvas_id)->value_node_list_.find(value_node_id); + String warnings; + return find_canvas(canvas_id, warnings)->value_node_list_.find(value_node_id); } ValueNode::Handle @@ -421,7 +425,8 @@ Canvas::surefind_value_node(const String &id) if(canvas_id.empty()) canvas_id=':'; - return surefind_canvas(canvas_id)->value_node_list_.surefind(value_node_id); + String warnings; + return surefind_canvas(canvas_id,warnings)->value_node_list_.surefind(value_node_id); } void @@ -506,11 +511,11 @@ Canvas::remove_value_node(ValueNode::Handle x) x->set_id(""); } -etl::handle -Canvas::surefind_canvas(const String &id) +Canvas::Handle +Canvas::surefind_canvas(const String &id, String &warnings) { if(is_inline() && parent_) - return parent_->surefind_canvas(id); + return parent_->surefind_canvas(id,warnings); if(id.empty()) return this; @@ -522,7 +527,7 @@ Canvas::surefind_canvas(const String &id) // If '#' is the first character, remove it // and attempt to parse the ID again. if(id[0]=='#') - return surefind_canvas(String(id,1)); + return surefind_canvas(String(id,1),warnings); //! \todo This needs a lot more optimization String file_name(id,0,id.find_first_of('#')); @@ -532,23 +537,22 @@ Canvas::surefind_canvas(const String &id) Canvas::Handle external_canvas; + if(!is_absolute_path(file_name)) + file_name = get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name; + // If the composition is already open, then use it. if(externals_.count(file_name)) external_canvas=externals_[file_name]; else { String errors; - if(is_absolute_path(file_name)) - external_canvas=open_canvas(file_name, errors); - else - external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name, errors); - + external_canvas=open_canvas(file_name, errors, warnings); if(!external_canvas) - throw Exception::FileNotFound(file_name); + throw runtime_error(errors); externals_[file_name]=external_canvas; } - return Handle::cast_const(external_canvas.constant()->find_canvas(external_id)); + return Handle::cast_const(external_canvas.constant()->find_canvas(external_id, warnings)); } // If we do not have any resolution, then we assume that the @@ -571,7 +575,7 @@ Canvas::surefind_canvas(const String &id) // If the first character is the separator, then // this references the root canvas. if(id[0]==':') - return get_root()->surefind_canvas(string(id,1)); + return get_root()->surefind_canvas(string(id,1),warnings); // Now we know that the requested Canvas is in a child // of this canvas. We have to find that canvas and @@ -579,25 +583,25 @@ Canvas::surefind_canvas(const String &id) String canvas_name=string(id,0,id.find_first_of(':')); - Canvas::Handle child_canvas=surefind_canvas(canvas_name); + Canvas::Handle child_canvas=surefind_canvas(canvas_name,warnings); - return child_canvas->surefind_canvas(string(id,id.find_first_of(':')+1)); + return child_canvas->surefind_canvas(string(id,id.find_first_of(':')+1),warnings); } Canvas::Handle -Canvas::find_canvas(const String &id) +Canvas::find_canvas(const String &id, String &warnings) { return Canvas::Handle::cast_const( - const_cast(this)->find_canvas(id) + const_cast(this)->find_canvas(id, warnings) ); } Canvas::ConstHandle -Canvas::find_canvas(const String &id)const +Canvas::find_canvas(const String &id, String &warnings)const { if(is_inline() && parent_) - return parent_->find_canvas(id); + return parent_->find_canvas(id, warnings); if(id.empty()) return this; @@ -609,7 +613,7 @@ Canvas::find_canvas(const String &id)const // If '#' is the first character, remove it // and attempt to parse the ID again. if(id[0]=='#') - return find_canvas(String(id,1)); + return find_canvas(String(id,1), warnings); //! \todo This needs a lot more optimization String file_name(id,0,id.find_first_of('#')); @@ -619,23 +623,22 @@ Canvas::find_canvas(const String &id)const Canvas::Handle external_canvas; + if(!is_absolute_path(file_name)) + file_name = get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name; + // If the composition is already open, then use it. if(externals_.count(file_name)) external_canvas=externals_[file_name]; else { - String errors; - if(is_absolute_path(file_name)) - external_canvas=open_canvas(file_name, errors); - else - external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name, errors); - + String errors, warnings; + external_canvas=open_canvas(file_name, errors, warnings); if(!external_canvas) - throw Exception::FileNotFound(file_name); + throw runtime_error(errors); externals_[file_name]=external_canvas; } - return Handle::cast_const(external_canvas.constant()->find_canvas(external_id)); + return Handle::cast_const(external_canvas.constant()->find_canvas(external_id, warnings)); } // If we do not have any resolution, then we assume that the @@ -656,7 +659,7 @@ Canvas::find_canvas(const String &id)const // If the first character is the separator, then // this references the root canvas. if(id[0]==':') - return get_root()->find_canvas(string(id,1)); + return get_root()->find_canvas(string(id,1), warnings); // Now we know that the requested Canvas is in a child // of this canvas. We have to find that canvas and @@ -664,9 +667,9 @@ Canvas::find_canvas(const String &id)const String canvas_name=string(id,0,id.find_first_of(':')); - Canvas::ConstHandle child_canvas=find_canvas(canvas_name); + Canvas::ConstHandle child_canvas=find_canvas(canvas_name, warnings); - return child_canvas->find_canvas(string(id,id.find_first_of(':')+1)); + return child_canvas->find_canvas(string(id,id.find_first_of(':')+1), warnings); } Canvas::Handle @@ -778,7 +781,9 @@ Canvas::clone(const GUID& deriv_guid)const { name=get_id()+"_CLONE"; +#ifndef ALLOW_CLONE_NON_INLINE_CANVASES throw runtime_error("Cloning of non-inline canvases is not yet supported"); +#endif // ALLOW_CLONE_NON_INLINE_CANVASES } Handle canvas(new Canvas(name)); @@ -914,7 +919,8 @@ Canvas::add_child_canvas(Canvas::Handle child_canvas, const synfig::String& id) try { - find_canvas(id); + String warnings; + find_canvas(id, warnings); throw Exception::IDAlreadyExists(id); } catch(Exception::IDNotFound) @@ -953,8 +959,24 @@ Canvas::set_file_name(const String &file_name) parent()->set_file_name(file_name); else { + String old_name(file_name_); file_name_=file_name; - signal_file_name_changed_(); + + // when a canvas is made, its name is "" + // then, before it's saved or even edited, it gets a name like "Synfig Animation 23", in the local language + // we don't want to register the canvas' filename in the canvas map until it gets a real filename + if (old_name != "") + { + file_name_=file_name; + std::map >::iterator iter; + for(iter=get_open_canvas_map().begin();iter!=get_open_canvas_map().end();++iter) + if(iter->second==this) + break; + if (iter == get_open_canvas_map().end()) + CanvasParser::register_canvas_in_map(this, file_name); + else + signal_file_name_changed_(); + } } } @@ -962,7 +984,7 @@ sigc::signal& Canvas::signal_file_name_changed() { if(parent()) - return signal_file_name_changed(); + return parent()->signal_file_name_changed(); else return signal_file_name_changed_; } @@ -1212,7 +1234,8 @@ synfig::optimize_layers(Time time, Context context, Canvas::Handle op_canvas, bo !composite->reads_context()) { Canvas::Handle sub_canvas(Canvas::create_inline(op_canvas)); - sub_canvas->push_back(composite = composite->clone()); + // don't use clone() because it re-randomizes the seeds of any random valuenodes + sub_canvas->push_back(composite = composite->simple_clone()); layer = Layer::create("PasteCanvas"); composite->set_description(strprintf("Wrapped clone of '%s'", composite->get_non_empty_description().c_str())); layer->set_description(strprintf("PasteCanvas wrapper for '%s'", composite->get_non_empty_description().c_str())); @@ -1360,3 +1383,26 @@ Canvas::rename_group(const String&old_name,const String&new_name) (*iter)->add_to_group(new_name); } } + +void +Canvas::register_external_canvas(String file_name, Handle canvas) +{ + if(!is_absolute_path(file_name)) file_name = get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name; + externals_[file_name] = canvas; +} + +#ifdef _DEBUG +void +Canvas::show_externals(String file, int line, String text) const +{ + printf(" .----- (externals for %lx '%s')\n | %s:%d %s\n", ulong(this), get_name().c_str(), file.c_str(), line, text.c_str()); + std::map::iterator iter; + for (iter = externals_.begin(); iter != externals_.end(); iter++) + { + synfig::String first(iter->first); + etl::loose_handle second(iter->second); + printf(" | %40s : %lx (%d)\n", first.c_str(), ulong(&*second), second->count()); + } + printf(" `-----\n\n"); +} +#endif // _DEBUG