Revision: 2203
http://synfig.svn.sourceforge.net/synfig/?rev=2203&view=rev
Author: dooglus
Date: 2008-11-17 00:38:20 +0000 (Mon, 17 Nov 2008)
Log Message:
-----------
When loading .sif files, show any warnings in the GUI. When loading .sif files
with circular references to themselves, show a warning, and avoid crashing.
The circular reference is shortcutted to allow loading. (Fixes
https://bugs.launchpad.net/ubuntu/+source/synfig/+bug/195447 )
Modified Paths:
--------------
synfig-core/trunk/src/synfig/canvas.cpp
synfig-core/trunk/src/synfig/canvas.h
synfig-core/trunk/src/synfig/loadcanvas.cpp
synfig-core/trunk/src/synfig/loadcanvas.h
synfig-core/trunk/src/tool/main.cpp
synfig-studio/trunk/src/gtkmm/app.cpp
synfig-studio/trunk/src/gtkmm/widget_canvaschooser.cpp
synfig-studio/trunk/src/synfigapp/canvasinterface.cpp
Modified: synfig-core/trunk/src/synfig/canvas.cpp
===================================================================
--- synfig-core/trunk/src/synfig/canvas.cpp 2008-11-17 00:37:38 UTC (rev
2202)
+++ synfig-core/trunk/src/synfig/canvas.cpp 2008-11-17 00:38:20 UTC (rev
2203)
@@ -47,7 +47,7 @@
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 ========================================================= */
@@ -399,7 +399,8 @@
//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 +422,8 @@
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 +508,11 @@
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;
@@ -522,7 +524,7 @@
// 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('#'));
@@ -539,16 +541,16 @@
{
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
@@ -571,7 +573,7 @@
// 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 +581,25 @@
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;
@@ -609,7 +611,7 @@
// 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('#'));
@@ -624,18 +626,18 @@
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
@@ -656,7 +658,7 @@
// 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 +666,9 @@
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
@@ -914,7 +916,8 @@
try
{
- find_canvas(id);
+ String warnings;
+ find_canvas(id, warnings);
throw Exception::IDAlreadyExists(id);
}
catch(Exception::IDNotFound)
Modified: synfig-core/trunk/src/synfig/canvas.h
===================================================================
--- synfig-core/trunk/src/synfig/canvas.h 2008-11-17 00:37:38 UTC (rev
2202)
+++ synfig-core/trunk/src/synfig/canvas.h 2008-11-17 00:38:20 UTC (rev
2203)
@@ -469,19 +469,19 @@
** 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 &);
Modified: synfig-core/trunk/src/synfig/loadcanvas.cpp
===================================================================
--- synfig-core/trunk/src/synfig/loadcanvas.cpp 2008-11-17 00:37:38 UTC (rev
2202)
+++ synfig-core/trunk/src/synfig/loadcanvas.cpp 2008-11-17 00:38:20 UTC (rev
2203)
@@ -39,6 +39,7 @@
#include <stdexcept>
#include <iostream>
+#include "layer_pastecanvas.h"
#include "loadcanvas.h"
#include "valuenode.h"
#include "valuenode_subtract.h"
@@ -92,6 +93,8 @@
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);
@@ -121,20 +124,45 @@
}
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)
{
+ 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())
{
errors = parser.get_errors_text();
@@ -161,10 +189,13 @@
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"));
}
@@ -908,7 +939,11 @@
// <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());
}
@@ -1718,7 +1753,11 @@
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
@@ -1830,7 +1869,9 @@
{
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(...)
{
Modified: synfig-core/trunk/src/synfig/loadcanvas.h
===================================================================
--- synfig-core/trunk/src/synfig/loadcanvas.h 2008-11-17 00:37:38 UTC (rev
2202)
+++ synfig-core/trunk/src/synfig/loadcanvas.h 2008-11-17 00:38:20 UTC (rev
2203)
@@ -74,6 +74,7 @@
String path;
String errors_text;
+ String warnings_text;
GUID guid_;
@@ -116,10 +117,13 @@
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
@@ -168,8 +172,8 @@
//! 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();
Modified: synfig-core/trunk/src/tool/main.cpp
===================================================================
--- synfig-core/trunk/src/tool/main.cpp 2008-11-17 00:37:38 UTC (rev 2202)
+++ synfig-core/trunk/src/tool/main.cpp 2008-11-17 00:38:20 UTC (rev 2203)
@@ -1174,8 +1174,8 @@
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)
{
@@ -1199,7 +1199,8 @@
{
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)
{
@@ -1235,8 +1236,8 @@
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;
Modified: synfig-studio/trunk/src/gtkmm/app.cpp
===================================================================
--- synfig-studio/trunk/src/gtkmm/app.cpp 2008-11-17 00:37:38 UTC (rev
2202)
+++ synfig-studio/trunk/src/gtkmm/app.cpp 2008-11-17 00:38:20 UTC (rev
2203)
@@ -1450,7 +1450,8 @@
// 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
@@ -2358,9 +2359,9 @@
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();
@@ -2372,6 +2373,9 @@
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);
Modified: synfig-studio/trunk/src/gtkmm/widget_canvaschooser.cpp
===================================================================
--- synfig-studio/trunk/src/gtkmm/widget_canvaschooser.cpp 2008-11-17
00:37:38 UTC (rev 2202)
+++ synfig-studio/trunk/src/gtkmm/widget_canvaschooser.cpp 2008-11-17
00:38:20 UTC (rev 2203)
@@ -150,7 +150,8 @@
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)
Modified: synfig-studio/trunk/src/synfigapp/canvasinterface.cpp
===================================================================
--- synfig-studio/trunk/src/synfigapp/canvasinterface.cpp 2008-11-17
00:37:38 UTC (rev 2202)
+++ synfig-studio/trunk/src/synfigapp/canvasinterface.cpp 2008-11-17
00:38:20 UTC (rev 2203)
@@ -579,8 +579,8 @@
// 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;
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Synfig-devl mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synfig-devl