**
** \legal
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
-** Copyright (c) 2007 Chris Moore
+** Copyright (c) 2007, 2008 Chris Moore
**
** This package is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
using namespace etl;
using namespace std;
-namespace synfig { extern Canvas::Handle open_canvas(const String &filename); };
+namespace synfig { extern Canvas::Handle open_canvas(const String &filename, String &errors, String &warnings); };
/* === M A C R O S ========================================================= */
Canvas::~Canvas()
{
- bool keep_going = true;
-
// we were having a crash where pastecanvas layers were still
// refering to a canvas after it had been destroyed; this code
// will stop the pastecanvas layers from refering to the canvas
// before the canvas is destroyed
// the set_sub_canvas(0) ends up deleting the parent-child link,
- // which modifies the set we're iterating through, invalidating
- // the set iterator. the outer while loop makes sure that we
- // recreate the set iterator each time the set itself is modified
- while (keep_going)
+ // which deletes the current element from the set we're iterating
+ // through, so we have to make sure we've incremented the iterator
+ // before we mess with the pastecanvas
+ std::set<Node*>::iterator iter = parent_set.begin();
+ while (iter != parent_set.end())
{
- keep_going = false; // only keep going if we find a pastecanvas parent to clear
- for (std::set<Node*>::iterator iter = parent_set.begin(); iter != parent_set.end(); iter++)
- {
- Layer_PasteCanvas* paste_canvas = dynamic_cast<Layer_PasteCanvas*>(*iter);
- if(paste_canvas)
- {
- paste_canvas->set_sub_canvas(0);
- keep_going = true;
- break; // out of the for loop to the while loop
- }
- else
- warning("destroyed canvas has a parent that is not a pastecanvas - please report if repeatable");
- }
+ Layer_PasteCanvas* paste_canvas = dynamic_cast<Layer_PasteCanvas*>(*iter);
+ iter++;
+ if(paste_canvas)
+ paste_canvas->set_sub_canvas(0);
+ else
+ warning("destroyed canvas has a parent that is not a pastecanvas - please report if repeatable");
}
//if(is_inline() && parent_) assert(0);
return id;
}
-
ValueNode::Handle
Canvas::find_value_node(const String &id)
{
//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
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
x->set_id("");
}
-
-etl::handle<Canvas>
-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;
// 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('#'));
external_canvas=externals_[file_name];
else
{
+ String errors;
if(is_absolute_path(file_name))
- external_canvas=open_canvas(file_name);
+ external_canvas=open_canvas(file_name, errors, warnings);
else
- external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name);
+ external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+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
// 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
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<const Canvas*>(this)->find_canvas(id)
+ const_cast<const Canvas*>(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);
+ if(is_inline() && parent_)
+ return parent_->find_canvas(id, warnings);
if(id.empty())
return this;
// 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('#'));
external_canvas=externals_[file_name];
else
{
+ String errors, warnings;
if(is_absolute_path(file_name))
- external_canvas=open_canvas(file_name);
+ external_canvas=open_canvas(file_name, errors, warnings);
else
- external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name);
+ external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+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
// 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));
+ if(id[0]==':')
+ 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
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
Canvas::create()
{
x->set_canvas(this);
-
add_child(x.get());
-
LooseHandle correct_canvas(this);
//while(correct_canvas->is_inline())correct_canvas=correct_canvas->parent();
Layer::LooseHandle loose_layer(x);
&Canvas::remove_group_pair),
loose_layer))));
-
if(!x->get_group().empty())
add_group_pair(x->get_group(),x);
-
changed();
}
// it was failing to ascertain the absolute pathname of the imported image, since it needs the pathname
// of the canvas to get that, which is stored in the parent canvas
canvas->parent_=parent();
+ canvas->rend_desc() = rend_desc();
//canvas->set_inline(parent());
}
try
{
- find_canvas(id);
+ String warnings;
+ find_canvas(id, warnings);
throw Exception::IDAlreadyExists(id);
}
catch(Exception::IDNotFound)
return dirname(file_name_);
}
-
String
Canvas::get_meta_data(const String& key)const
{