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

Reply via email to