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 ========================================================= */
//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('#'));
{
String errors;
if(is_absolute_path(file_name))
- external_canvas=open_canvas(file_name, errors);
+ external_canvas=open_canvas(file_name, errors, warnings);
else
- external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name, errors);
+ external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name, errors, warnings);
if(!external_canvas)
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);
+ 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;
+ String errors, warnings;
if(is_absolute_path(file_name))
- external_canvas=open_canvas(file_name, errors);
+ external_canvas=open_canvas(file_name, errors, warnings);
else
- external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name, errors);
+ external_canvas=open_canvas(get_file_path()+ETL_DIRECTORY_SEPARATOR+file_name, errors, warnings);
if(!external_canvas)
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()->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
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
try
{
- find_canvas(id);
+ String warnings;
+ find_canvas(id, warnings);
throw Exception::IDAlreadyExists(id);
}
catch(Exception::IDNotFound)
** If not found, it creates a new Canvas and returns it
** If an error occurs, it returns an empty handle
*/
- Handle surefind_canvas(const String &id);
+ Handle surefind_canvas(const String &id,String &warnings);
//! Finds a child Canvas in the Canvas with the given \a id
/*! \return If found, returns a handle to the child Canvas.
** Otherwise, returns an empty handle.
*/
- Handle find_canvas(const String &id);
+ Handle find_canvas(const String &id, String &warnings);
//! Finds a child Canvas in the Canvas with the given \a id
/*! \return If found, returns a handle to the child Canvas.
** Otherwise, returns an empty handle.
*/
- ConstHandle find_canvas(const String &id)const;
+ ConstHandle find_canvas(const String &id, String &warnings)const;
//! Sets the file path for the Canvas
//void set_file_path(const String &);
#include <stdexcept>
#include <iostream>
+#include "layer_pastecanvas.h"
#include "loadcanvas.h"
#include "valuenode.h"
#include "valuenode_subtract.h"
inline bool is_whitespace(char x) { return ((x)=='\n' || (x)=='\t' || (x)==' '); }
+std::set<String> CanvasParser::loading_;
+
/* === P R O C E D U R E S ================================================= */
static std::map<String, Canvas::LooseHandle>* open_canvas_map_(0);
}
Canvas::Handle
-synfig::open_canvas(const String &filename,String &errors)
+synfig::open_canvas(const String &filename,String &errors,String &warnings)
{
- return open_canvas_as(filename, filename, errors);
+ return open_canvas_as(filename, filename, errors, warnings);
}
Canvas::Handle
-synfig::open_canvas_as(const String &filename,const String &as,String &errors)
+synfig::open_canvas_as(const String &filename,const String &as,String &errors,String &warnings)
{
- CanvasParser parser;
+ if (CanvasParser::loading_.count(filename))
+ {
+ String warning(strprintf(_("cannot load '%s' recursively"), filename.c_str()));
+ synfig::warning(warning);
+ warnings = " * " + warning + "\n";
+ Canvas::Handle canvas(Canvas::create());
+ canvas->set_file_name(filename);
+ Layer::Handle paste(Layer_PasteCanvas::create());
+ canvas->push_back(paste);
+ paste->set_description(warning);
+ return canvas;
+ }
+ Canvas::Handle canvas;
+ CanvasParser parser;
parser.set_allow_errors(true);
- Canvas::Handle canvas=parser.parse_from_file_as(filename,as,errors);
+ try
+ {
+ CanvasParser::loading_.insert(filename);
+ canvas=parser.parse_from_file_as(filename,as,errors);
+ }
+ catch (...)
+ {
+ CanvasParser::loading_.erase(filename);
+ throw;
+ }
+ CanvasParser::loading_.erase(filename);
+
+ warnings = parser.get_warnings_text();
if(parser.error_count())
{
void
CanvasParser::warning(xmlpp::Node *element, const String &text)
{
- string str=strprintf("%s:<%s>:%d: warning: ",filename.c_str(),element->get_name().c_str(),element->get_line())+text;
- //synfig::warning(str);
- cerr<<str<<endl;
+ string str=strprintf("%s:<%s>:%d: ",filename.c_str(),element->get_name().c_str(),element->get_line())+text;
+
+ synfig::warning(str);
+ // cerr<<str<<endl;
+
total_warnings_++;
+ warnings_text += " * " + str + "\n";
if(total_warnings_>=max_warnings_)
fatal_error(element, _("Too many warnings"));
}
// <waypoint time="0s" use="mycanvas"/>
// </animated>
if (type==ValueBase::TYPE_CANVAS)
- waypoint_value_node=ValueNode_Const::create(canvas->surefind_canvas(child->get_attribute("use")->get_value()));
+ {
+ String warnings;
+ waypoint_value_node=ValueNode_Const::create(canvas->surefind_canvas(child->get_attribute("use")->get_value(), warnings));
+ warnings_text += warnings;
+ }
else
waypoint_value_node=canvas->surefind_value_node(child->get_attribute("use")->get_value());
}
error(child,_("Empty use=\"\" value in <param>"));
else if(layer->get_param(param_name).get_type()==ValueBase::TYPE_CANVAS)
{
- if(!layer->set_param(param_name,canvas->surefind_canvas(str)))
+ String warnings;
+ Canvas::Handle c(canvas->surefind_canvas(str, warnings));
+ warnings_text += warnings;
+ if(!c) error((*iter),strprintf(_("Failed to load subcanvas '%s'"), str.c_str()));
+ if(!layer->set_param(param_name,c))
error((*iter),_("Layer rejected canvas link"));
}
else
{
try
{
- canvas=parent->find_canvas(element->get_attribute("id")->get_value());
+ String warnings;
+ canvas=parent->find_canvas(element->get_attribute("id")->get_value(), warnings);
+ warnings_text += warnings;
}
catch(...)
{
String path;
String errors_text;
+ String warnings_text;
GUID guid_;
const synfig::String& get_path()const { return path; }
const synfig::String& get_errors_text()const { return errors_text; }
+ const synfig::String& get_warnings_text()const { return warnings_text; }
//! \todo writeme
Canvas::Handle parse_from_file_as(const String &filename,const String &as,String &errors);
+ static std::set<String> loading_;
+
private:
// Error/Warning handling functions
//! Loads a canvas from \a filename
/*! \return The Canvas's handle on success, an empty handle on failure */
-extern Canvas::Handle open_canvas(const String &filename,String &errors);
-extern Canvas::Handle open_canvas_as(const String &filename,const String &as,String &errors);
+extern Canvas::Handle open_canvas(const String &filename,String &errors,String &warnings);
+extern Canvas::Handle open_canvas_as(const String &filename,const String &as,String &errors,String &warnings);
std::map<synfig::String, etl::loose_handle<Canvas> >& get_open_canvas_map();
return ret;
// Open the composition
- String errors;
- job_list.front().root=open_canvas(job_list.front().filename, errors);
+ String errors, warnings;
+ job_list.front().root=open_canvas(job_list.front().filename, errors, warnings);
if(!job_list.front().root)
{
{
try
{
- job_list.front().canvas=job_list.front().root->find_canvas(canvasid);
+ String warnings;
+ job_list.front().canvas=job_list.front().root->find_canvas(canvasid, warnings);
}
catch(Exception::IDNotFound)
{
extract_append(imageargs,composite_file);
if(!composite_file.empty())
{
- String errors;
- Canvas::Handle composite(open_canvas(composite_file, errors));
+ String errors, warnings;
+ Canvas::Handle composite(open_canvas(composite_file, errors, warnings));
if(!composite)
{
cerr<<_("Unable to append '")<<composite_file<<"'."<<endl;
// find the canvas
synfig::Canvas::Handle canvas;
try {
- canvas = instance->get_canvas()->find_canvas(String(canvas_window_size, current, separator-current));
+ String warnings;
+ canvas = instance->get_canvas()->find_canvas(String(canvas_window_size, current, separator-current), warnings);
}
catch(Exception::IDNotFound) {
// can't find the canvas; skip to the next canvas or return
try
{
OneMoment one_moment;
- String errors;
+ String errors, warnings;
- etl::handle<synfig::Canvas> canvas(open_canvas_as(filename,as,errors));
+ etl::handle<synfig::Canvas> canvas(open_canvas_as(filename,as,errors,warnings));
if(canvas && get_instance(canvas))
{
get_instance(canvas)->find_canvas_view(canvas)->present();
if(!canvas)
throw (String)strprintf(_("Unable to load \"%s\":\n\n"),filename.c_str()) + errors;
+ if (warnings != "")
+ dialog_warning_blocking(_("Warnings"), strprintf("%s:\n\n%s", _("Warnings"), warnings.c_str()));
+
if (as.find(custom_filename_prefix.c_str()) != 0)
add_recent_file(as);
Canvas::Handle new_canvas;
try
{
- new_canvas=parent_canvas->find_canvas(canvas_name);
+ String warnings;
+ new_canvas=parent_canvas->find_canvas(canvas_name, warnings);
set_value_(new_canvas);
}
catch(std::runtime_error x)
// If this is a SIF file, then we need to do things slightly differently
if(ext=="sif" || ext=="sifz")try
{
- String errors;
- Canvas::Handle outside_canvas(synfig::open_canvas(filename, errors));
+ String errors, warnings;
+ Canvas::Handle outside_canvas(synfig::open_canvas(filename, errors, warnings));
if(!outside_canvas)
throw String(_("Unable to open this composition")) + ":\n\n" + errors;