Remove .gitignore do nothing is ignored.
[synfig.git] / synfig-studio / trunk / src / gtkmm / app.cpp
index 0292ff4..24e2bcf 100644 (file)
@@ -2,10 +2,13 @@
 /*!    \file app.cpp
 **     \brief writeme
 **
 /*!    \file app.cpp
 **     \brief writeme
 **
-**     $Id: app.cpp,v 1.11 2005/03/24 21:47:28 darco Exp $
+**     $Id$
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 **
 **     \legal
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**     Copyright (c) 2007, 2008 Chris Moore
+**     Copyright (c) 2008 Gerald Young
+**  Copyright (c) 2008 Carlos López
 **
 **     This package is free software; you can redistribute it and/or
 **     modify it under the terms of the GNU General Public License as
 **
 **     This package is free software; you can redistribute it and/or
 **     modify it under the terms of the GNU General Public License as
 #      include <config.h>
 #endif
 
 #      include <config.h>
 #endif
 
+#ifdef WIN32
+#define WINVER 0x0500
+#include <windows.h>
+#endif
+
 #include <fstream>
 #include <iostream>
 #include <locale>
 #include <fstream>
 #include <iostream>
 #include <locale>
+#include <cstring>
 
 #ifdef HAVE_SYS_ERRNO_H
 #include <sys/errno.h>
 
 #ifdef HAVE_SYS_ERRNO_H
 #include <sys/errno.h>
 #include <gtkmm/inputdialog.h>
 #include <gtkmm/accelmap.h>
 #include <gtkmm/uimanager.h>
 #include <gtkmm/inputdialog.h>
 #include <gtkmm/accelmap.h>
 #include <gtkmm/uimanager.h>
+#include <gtkmm/textview.h>
 
 #include <gtk/gtk.h>
 
 
 #include <gtk/gtk.h>
 
+#include <gdkmm/general.h>
+
 #include <synfig/loadcanvas.h>
 #include <synfig/loadcanvas.h>
+#include <synfig/savecanvas.h>
 
 #include "app.h"
 #include "about.h"
 
 #include "app.h"
 #include "about.h"
+#include "splash.h"
 #include "instance.h"
 #include "canvasview.h"
 #include "dialog_setup.h"
 #include "instance.h"
 #include "canvasview.h"
 #include "dialog_setup.h"
 #include "state_rectangle.h"
 #include "state_smoothmove.h"
 #include "state_scale.h"
 #include "state_rectangle.h"
 #include "state_smoothmove.h"
 #include "state_scale.h"
+#include "state_star.h"
+#include "state_text.h"
 #include "state_width.h"
 #include "state_rotate.h"
 #include "state_zoom.h"
 
 #include "devicetracker.h"
 #include "dialog_tooloptions.h"
 #include "state_width.h"
 #include "state_rotate.h"
 #include "state_zoom.h"
 
 #include "devicetracker.h"
 #include "dialog_tooloptions.h"
+#include "widget_enum.h"
 
 #include "autorecover.h"
 
 
 #include "autorecover.h"
 
 #include <fmod.h>
 #endif
 
 #include <fmod.h>
 #endif
 
-#ifdef WIN32
-#define _WIN32_WINNT 0x0500
-#include <windows.h>
-#endif
 #include <gtkmm/accelmap.h>
 #include <gtkmm/filechooser.h>
 #include <gtkmm/filechooserdialog.h>
 
 #include <gtkmm/accelmap.h>
 #include <gtkmm/filechooser.h>
 #include <gtkmm/filechooserdialog.h>
 
+#include "general.h"
+
 #endif
 
 /* === U S I N G =========================================================== */
 #endif
 
 /* === U S I N G =========================================================== */
@@ -136,8 +151,10 @@ using namespace studio;
 #ifndef SYNFIG_USER_APP_DIR
 #ifdef __APPLE__
 #define SYNFIG_USER_APP_DIR    "Library/Synfig"
 #ifndef SYNFIG_USER_APP_DIR
 #ifdef __APPLE__
 #define SYNFIG_USER_APP_DIR    "Library/Synfig"
-#else
+#elif defined(_WIN32)
 #define SYNFIG_USER_APP_DIR    "Synfig"
 #define SYNFIG_USER_APP_DIR    "Synfig"
+#else
+#define SYNFIG_USER_APP_DIR    ".synfig"
 #endif
 #endif
 
 #endif
 #endif
 
@@ -194,6 +211,8 @@ App::signal_instance_deleted() { return signal_instance_deleted_; }
 static std::list<std::string> recent_files;
 const std::list<std::string>& App::get_recent_files() { return recent_files; }
 
 static std::list<std::string> recent_files;
 const std::list<std::string>& App::get_recent_files() { return recent_files; }
 
+static std::list<std::string> recent_files_window_size;
+
 int    App::Busy::count;
 bool App::shutdown_in_progress;
 
 int    App::Busy::count;
 bool App::shutdown_in_progress;
 
@@ -216,6 +235,8 @@ const etl::handle<synfigapp::UIInterface>& App::get_ui_interface() { return ui_i
 etl::handle<Instance> App::selected_instance;
 etl::handle<CanvasView> App::selected_canvas_view;
 
 etl::handle<Instance> App::selected_instance;
 etl::handle<CanvasView> App::selected_canvas_view;
 
+studio::About *studio::App::about=NULL;
+
 studio::Toolbox *studio::App::toolbox=NULL;
 
 studio::AutoRecover *studio::App::auto_recover=NULL;
 studio::Toolbox *studio::App::toolbox=NULL;
 
 studio::AutoRecover *studio::App::auto_recover=NULL;
@@ -250,6 +271,22 @@ studio::Dock_Curves* dock_curves;
 std::list< etl::handle< studio::Module > > module_list_;
 
 bool studio::App::use_colorspace_gamma=true;
 std::list< etl::handle< studio::Module > > module_list_;
 
 bool studio::App::use_colorspace_gamma=true;
+#ifdef SINGLE_THREADED
+bool studio::App::single_threaded=false;
+#endif
+bool studio::App::restrict_radius_ducks=false;
+bool studio::App::resize_imported_images=false;
+String studio::App::custom_filename_prefix(DEFAULT_FILENAME_PREFIX);
+int studio::App::preferred_x_size=480;
+int studio::App::preferred_y_size=270;
+String studio::App::predefined_size(DEFAULT_PREDEFINED_SIZE);
+String studio::App::predefined_fps(DEFAULT_PREDEFINED_FPS);
+float studio::App::preferred_fps=24.0;
+#ifdef USE_OPEN_FOR_URLS
+String studio::App::browser_command("open"); // MacOS only
+#else
+String studio::App::browser_command("xdg-open"); // Linux XDG standard
+#endif
 
 static int max_recent_files_=25;
 int studio::App::get_max_recent_files() { return max_recent_files_; }
 
 static int max_recent_files_=25;
 int studio::App::get_max_recent_files() { return max_recent_files_; }
@@ -258,6 +295,25 @@ void studio::App::set_max_recent_files(int x) { max_recent_files_=x; }
 static synfig::String app_base_path_;
 
 namespace studio {
 static synfig::String app_base_path_;
 
 namespace studio {
+
+bool
+really_delete_widget(Gtk::Widget *widget)
+{
+       // synfig::info("really delete %p", (void*)widget);
+       delete widget;
+       return false;
+}
+
+// nasty workaround - when we've finished with a popup menu, we want to delete it
+// attaching to the signal_hide() signal gets us here before the action on the menu has run,
+// so schedule the real delete to happen in 50ms, giving the action a chance to run
+void
+delete_widget(Gtk::Widget *widget)
+{
+       // synfig::info("delete %p", (void*)widget);
+       Glib::signal_timeout().connect(sigc::bind(sigc::ptr_fun(&really_delete_widget), widget), 50);
+}
+
 }; // END of namespace studio
 studio::StateManager* state_manager;
 
 }; // END of namespace studio
 studio::StateManager* state_manager;
 
@@ -268,6 +324,34 @@ class GlobalUIInterface : public synfigapp::UIInterface
 {
 public:
 
 {
 public:
 
+       virtual Response confirmation(const std::string &title,
+                       const std::string &primaryText,
+                       const std::string &secondaryText,
+                       const std::string &confirmPhrase,
+                       const std::string &cancelPhrase,
+                       Response defaultResponse)
+       {
+               Gtk::MessageDialog dialog(
+                       primaryText,            // Message
+                       false,                  // Markup
+                       Gtk::MESSAGE_WARNING,   // Type
+                       Gtk::BUTTONS_NONE,      // Buttons
+                       true                    // Modal
+               );
+
+               if (! title.empty())
+                       dialog.set_title(title);
+               if (! secondaryText.empty())
+                       dialog.set_secondary_text(secondaryText);
+
+               dialog.add_button(cancelPhrase, RESPONSE_CANCEL);
+               dialog.add_button(confirmPhrase, RESPONSE_OK);
+               dialog.set_default_response(defaultResponse);
+
+               dialog.show_all();
+               return (Response) dialog.run();
+       }
+
        virtual Response yes_no(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)
        {
                Gtk::Dialog dialog(
        virtual Response yes_no(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)
        {
                Gtk::Dialog dialog(
@@ -277,11 +361,11 @@ public:
                );
                Gtk::Label label(message);
                label.show();
                );
                Gtk::Label label(message);
                label.show();
-               
+
                dialog.get_vbox()->pack_start(label);
                dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
                dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
                dialog.get_vbox()->pack_start(label);
                dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
                dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
-               
+
                dialog.set_default_response(dflt);
                dialog.show();
                return (Response)dialog.run();
                dialog.set_default_response(dflt);
                dialog.show();
                return (Response)dialog.run();
@@ -295,12 +379,12 @@ public:
                );
                Gtk::Label label(message);
                label.show();
                );
                Gtk::Label label(message);
                label.show();
-               
+
                dialog.get_vbox()->pack_start(label);
                dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
                dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
                dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
                dialog.get_vbox()->pack_start(label);
                dialog.add_button(Gtk::StockID("gtk-yes"),RESPONSE_YES);
                dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
                dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
-               
+
                dialog.set_default_response(dflt);
                dialog.show();
                return (Response)dialog.run();
                dialog.set_default_response(dflt);
                dialog.show();
                return (Response)dialog.run();
@@ -314,11 +398,11 @@ public:
                );
                Gtk::Label label(message);
                label.show();
                );
                Gtk::Label label(message);
                label.show();
-               
+
                dialog.get_vbox()->pack_start(label);
                dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK);
                dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
                dialog.get_vbox()->pack_start(label);
                dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK);
                dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
-               
+
                dialog.set_default_response(dflt);
                dialog.show();
                return (Response)dialog.run();
                dialog.set_default_response(dflt);
                dialog.show();
                return (Response)dialog.run();
@@ -334,17 +418,8 @@ public:
 
        virtual bool
        error(const std::string &err)
 
        virtual bool
        error(const std::string &err)
-       {               
-               Gtk::Dialog dialog(
-                       "Error",                // Title
-                       true,           // Modal
-                       true            // use_separator
-               );
-               Gtk::Label label(err);
-               label.show();
-               
-               dialog.get_vbox()->pack_start(label);
-               dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK);
+       {
+               Gtk::MessageDialog dialog(err, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
                dialog.show();
                dialog.run();
                return true;
                dialog.show();
                dialog.run();
                return true;
@@ -359,7 +434,7 @@ public:
        }
 
        virtual bool
        }
 
        virtual bool
-       amount_complete(int current, int total)
+       amount_complete(int /*current*/, int /*total*/)
        {
                while(studio::App::events_pending())studio::App::iteration(false);
                return true;
        {
                while(studio::App::events_pending())studio::App::iteration(false);
                return true;
@@ -368,149 +443,6 @@ public:
 
 /* === P R O C E D U R E S ================================================= */
 
 
 /* === P R O C E D U R E S ================================================= */
 
-typedef unsigned char U8;
-typedef unsigned short U16;
-typedef unsigned long U32;
-
-typedef union {
-       struct {
-               U32 serial;
-               U32 checksum;
-       } element;
-       U8      raw[8];
-} V_KeyUnwound;
-
-static inline U32 hash_U32(U32 i)
-{
-       i=i*1664525+1013904223;
-       i=i*1664525+1013904223;
-       i=i*1664525+1013904223;
-       return i;
-}
-
-#ifdef BIG_ENDIAN
-static const int endian_fix_table[8] = { 3, 2, 1, 0, 7, 6, 5, 4 } ;
-#define endian_fix(x) (endian_fix_table[x])
-#else
-#define endian_fix(x) (x)
-#endif
-
-int v_unwind_key(V_KeyUnwound* unwound, const char* key)
-{
-       int i;
-       unwound->element.serial=0;
-       unwound->element.checksum=0;
-       
-       for(i=0;i<16;i++)
-       {
-               U8 data;
-               
-               switch(key[i])
-               {
-                       case '0': data=0; break;
-                       case '1': data=1; break;
-                       case '2': data=2; break;
-                       case '3': data=3; break;
-                       case '4': data=4; break;
-                       case '5': data=5; break;
-                       case '6': data=6; break;
-                       case '7': data=7; break;
-                       case '8': data=8; break;
-                       case '9': data=9; break;
-                       case 'a': case 'A':  data=10; break;
-                       case 'b': case 'B':  data=11; break;
-                       case 'c': case 'C':  data=12; break;
-                       case 'd': case 'D':  data=13; break;
-                       case 'e': case 'E':  data=14; break;
-                       case 'f': case 'F':  data=15; break;
-                       default: return 0; break;
-               }
-               int bit=i*2;
-               unwound->element.checksum|=(((U32)data&3)<<bit);
-               unwound->element.serial|=(((U32)(data>>2)&3)<<bit);
-       }
-       return 1;
-}
-
-int v_key_check(const char* key, U32* serial, U32 appid)
-{
-       V_KeyUnwound unwound_key;
-       U32 appid_mask_a=hash_U32(appid);
-       U32 appid_mask_b=hash_U32(appid_mask_a);
-       
-       if(!v_unwind_key(&unwound_key, key))
-       {
-               // Invalid characters in key
-               return 0;
-       }
-       
-
-       // Undo obfuscation pass
-       {
-               U32 next=hash_U32(unwound_key.raw[endian_fix(7)]);
-               int i;
-               for(i=0;i<7;i++)
-               {
-                       next=hash_U32(next);
-                       unwound_key.raw[endian_fix(i)]^=(next>>24);
-               }
-       }
-       
-       unwound_key.element.serial^=appid_mask_a;
-       unwound_key.element.checksum^=appid_mask_b;
-
-       *serial=unwound_key.element.serial;
-       
-       return unwound_key.element.checksum==hash_U32(unwound_key.element.serial);
-}
-
-
-int check_license(String basedir)
-{
-#ifdef LICENSE_KEY_REQUIRED
-       String key;
-       String license_file;
-
-#ifndef _WIN32
-       license_file="/usr/local/etc/.synfiglicense";
-#else
-       license_file=basedir+"\\etc\\.synfiglicense";
-#endif         
-       
-       try {
-               key=Glib::file_get_contents(license_file);
-       } catch (Glib::FileError) { }
-       U32 serial(0);
-       if(!v_key_check(key.c_str(),&serial,0xdeadbeef))
-       {
-               while(!v_key_check(key.c_str(),&serial,0xdeadbeef))
-               {
-                       key.clear();
-                       
-                       if(!App::dialog_entry(
-                               _("Synfig Studio Authentication"),
-                               _("Please enter your license key below. You will not\nbe able to use this software without a valid license key."),
-                               key
-                       ))
-                               throw String("No License");
-               }
-               
-               FILE* file=fopen(license_file.c_str(),"w");
-               if(file)
-               {
-                       fprintf(file,"%s",key.c_str());
-                       fclose(file);
-               }
-               else
-                       synfig::error("Unable to save license key!");
-       }
-       synfig::info("License Authenticated -- Serial #%05d",serial);
-       return serial;
-#else
-       return 1;
-#endif 
-}
-
 /*
 void
 studio::UIManager::insert_action_group (const Glib::RefPtr<Gtk::ActionGroup>& action_group, int pos)
 /*
 void
 studio::UIManager::insert_action_group (const Glib::RefPtr<Gtk::ActionGroup>& action_group, int pos)
@@ -538,30 +470,24 @@ studio::add_action_group_to_top(Glib::RefPtr<studio::UIManager> ui_manager, Glib
 {
        ui_manager->insert_action_group(group,0);
        return;
 {
        ui_manager->insert_action_group(group,0);
        return;
-       DEBUGPOINT();
        std::list<Glib::RefPtr<Gtk::ActionGroup> > prev_groups(ui_manager->get_action_groups());
        std::list<Glib::RefPtr<Gtk::ActionGroup> >::reverse_iterator iter;
        std::list<Glib::RefPtr<Gtk::ActionGroup> > prev_groups(ui_manager->get_action_groups());
        std::list<Glib::RefPtr<Gtk::ActionGroup> >::reverse_iterator iter;
-       
-       DEBUGPOINT();
+
        for(iter=prev_groups.rbegin();iter!=prev_groups.rend();++iter)
        {
        for(iter=prev_groups.rbegin();iter!=prev_groups.rend();++iter)
        {
-               DEBUGPOINT();
                if(*iter && (*iter)->get_name()!="menus")
                {
                        synfig::info("Removing action group "+(*iter)->get_name());
                        ui_manager->remove_action_group(*iter);
                }
        }
                if(*iter && (*iter)->get_name()!="menus")
                {
                        synfig::info("Removing action group "+(*iter)->get_name());
                        ui_manager->remove_action_group(*iter);
                }
        }
-       DEBUGPOINT();
        ui_manager->insert_action_group(group,0);
        ui_manager->insert_action_group(group,0);
-       
-       DEBUGPOINT();
+
        for(;!prev_groups.empty();prev_groups.pop_front())
        {
                if(prev_groups.front() && prev_groups.front()!=group && prev_groups.front()->get_name()!="menus")
                        ui_manager->insert_action_group(prev_groups.front(),1);
        }
        for(;!prev_groups.empty();prev_groups.pop_front())
        {
                if(prev_groups.front() && prev_groups.front()!=group && prev_groups.front()->get_name()!="menus")
                        ui_manager->insert_action_group(prev_groups.front(),1);
        }
-       DEBUGPOINT();
 }
 */
 class Preferences : public synfigapp::Settings
 }
 */
 class Preferences : public synfigapp::Settings
@@ -599,21 +525,73 @@ public:
                        value=strprintf("%s",Distance::system_name(App::distance_system).c_str());
                        return true;
                }
                        value=strprintf("%s",Distance::system_name(App::distance_system).c_str());
                        return true;
                }
+#ifdef SINGLE_THREADED
+               if(key=="single_threaded")
+               {
+                       value=strprintf("%i",(int)App::single_threaded);
+                       return true;
+               }
+#endif
                if(key=="auto_recover_backup_interval")
                {
                        value=strprintf("%i",App::auto_recover->get_timeout());
                        return true;
                }
                if(key=="auto_recover_backup_interval")
                {
                        value=strprintf("%i",App::auto_recover->get_timeout());
                        return true;
                }
-               
+               if(key=="restrict_radius_ducks")
+               {
+                       value=strprintf("%i",(int)App::restrict_radius_ducks);
+                       return true;
+               }
+               if(key=="resize_imported_images")
+               {
+                       value=strprintf("%i",(int)App::resize_imported_images);
+                       return true;
+               }
+               if(key=="browser_command")
+               {
+                       value=App::browser_command;
+                       return true;
+               }
+               if(key=="custom_filename_prefix")
+               {
+                       value=App::custom_filename_prefix;
+                       return true;
+               }
+               if(key=="preferred_x_size")
+               {
+                       value=strprintf("%i",App::preferred_x_size);
+                       return true;
+               }
+               if(key=="preferred_y_size")
+               {
+                       value=strprintf("%i",App::preferred_y_size);
+                       return true;
+               }
+               if(key=="predefined_size")
+               {
+                       value=strprintf("%s",App::predefined_size.c_str());
+                       return true;
+               }
+               if(key=="preferred_fps")
+               {
+                       value=strprintf("%f",App::preferred_fps);
+                       return true;
+               }
+               if(key=="predefined_fps")
+               {
+                       value=strprintf("%s",App::predefined_fps.c_str());
+                       return true;
+               }
+
                return synfigapp::Settings::get_value(key,value);
        }
                return synfigapp::Settings::get_value(key,value);
        }
-       
+
        virtual bool set_value(const synfig::String& key,const synfig::String& value)
        {
                if(key=="gamma")
                {
                        float r,g,b,blk;
        virtual bool set_value(const synfig::String& key,const synfig::String& value)
        {
                if(key=="gamma")
                {
                        float r,g,b,blk;
-                       
+
                        strscanf(value,"%f %f %f %f",
                                &r,
                                &g,
                        strscanf(value,"%f %f %f %f",
                                &r,
                                &g,
@@ -622,7 +600,7 @@ public:
                        );
 
                        App::gamma.set_all(r,g,b,blk);
                        );
 
                        App::gamma.set_all(r,g,b,blk);
-                       
+
                        return true;
                }
                if(key=="time_format")
                        return true;
                }
                if(key=="time_format")
@@ -654,10 +632,68 @@ public:
                        App::distance_system=Distance::ident_system(value);;
                        return true;
                }
                        App::distance_system=Distance::ident_system(value);;
                        return true;
                }
-               
+#ifdef SINGLE_THREADED
+               if(key=="single_threaded")
+               {
+                       int i(atoi(value.c_str()));
+                       App::single_threaded=i;
+                       return true;
+               }
+#endif
+               if(key=="restrict_radius_ducks")
+               {
+                       int i(atoi(value.c_str()));
+                       App::restrict_radius_ducks=i;
+                       return true;
+               }
+               if(key=="resize_imported_images")
+               {
+                       int i(atoi(value.c_str()));
+                       App::resize_imported_images=i;
+                       return true;
+               }
+               if(key=="browser_command")
+               {
+                       App::browser_command=value;
+                       return true;
+               }
+               if(key=="custom_filename_prefix")
+               {
+                       App::custom_filename_prefix=value;
+                       return true;
+               }
+               if(key=="preferred_x_size")
+               {
+                       int i(atoi(value.c_str()));
+                       App::preferred_x_size=i;
+                       return true;
+               }
+               if(key=="preferred_y_size")
+               {
+                       int i(atoi(value.c_str()));
+                       App::preferred_y_size=i;
+                       return true;
+               }
+               if(key=="predefined_size")
+               {
+                       App::predefined_size=value;
+                       return true;
+               }
+               if(key=="preferred_fps")
+               {
+                       float i(atof(value.c_str()));
+                       App::preferred_fps=i;
+                       return true;
+               }
+               if(key=="predefined_fps")
+               {
+                       App::predefined_fps=value;
+                       return true;
+               }
+
                return synfigapp::Settings::set_value(key,value);
        }
                return synfigapp::Settings::set_value(key,value);
        }
-       
+
        virtual KeyList get_key_list()const
        {
                KeyList ret(synfigapp::Settings::get_key_list());
        virtual KeyList get_key_list()const
        {
                KeyList ret(synfigapp::Settings::get_key_list());
@@ -666,7 +702,19 @@ public:
                ret.push_back("distance_system");
                ret.push_back("file_history.size");
                ret.push_back("use_colorspace_gamma");
                ret.push_back("distance_system");
                ret.push_back("file_history.size");
                ret.push_back("use_colorspace_gamma");
+#ifdef SINGLE_THREADED
+               ret.push_back("single_threaded");
+#endif
                ret.push_back("auto_recover_backup_interval");
                ret.push_back("auto_recover_backup_interval");
+               ret.push_back("restrict_radius_ducks");
+               ret.push_back("resize_imported_images");
+               ret.push_back("browser_command");
+               ret.push_back("custom_filename_prefix");
+               ret.push_back("preferred_x_size");
+               ret.push_back("preferred_y_size");
+               ret.push_back("predefined_size");
+               ret.push_back("preferred_fps");
+               ret.push_back("predefined_fps");
                return ret;
        }
 };
                return ret;
        }
 };
@@ -681,19 +729,20 @@ init_ui_manager()
        Glib::RefPtr<Gtk::ActionGroup> toolbox_action_group = Gtk::ActionGroup::create("toolbox");
 
        Glib::RefPtr<Gtk::ActionGroup> actions_action_group = Gtk::ActionGroup::create();
        Glib::RefPtr<Gtk::ActionGroup> toolbox_action_group = Gtk::ActionGroup::create("toolbox");
 
        Glib::RefPtr<Gtk::ActionGroup> actions_action_group = Gtk::ActionGroup::create();
-       
-       menus_action_group->add( Gtk::Action::create("menu-file", "_File") );
-       menus_action_group->add( Gtk::Action::create("menu-edit", "_Edit") );
-       menus_action_group->add( Gtk::Action::create("menu-view", "_View") );
-       menus_action_group->add( Gtk::Action::create("menu-canvas", "_Canvas") );
-       menus_action_group->add( Gtk::Action::create("menu-layer", "_Layer") );
-       menus_action_group->add( Gtk::Action::create("menu-duck-mask", "Show/Hide Ducks") );
-       menus_action_group->add( Gtk::Action::create("menu-preview-quality", "Preview Quality") );
-       menus_action_group->add( Gtk::Action::create("menu-layer-new", "New Layer") );
-       menus_action_group->add( Gtk::Action::create("menu-keyframe", "Keyframe") );
-       menus_action_group->add( Gtk::Action::create("menu-group", "Group") );
-       menus_action_group->add( Gtk::Action::create("menu-state", "State") );
-       menus_action_group->add( Gtk::Action::create("menu-toolbox", "Toolbox") );
+
+       menus_action_group->add( Gtk::Action::create("menu-file", _("_File")) );
+       menus_action_group->add( Gtk::Action::create("menu-edit", _("_Edit")) );
+       menus_action_group->add( Gtk::Action::create("menu-view", _("_View")) );
+       menus_action_group->add( Gtk::Action::create("menu-canvas", _("_Canvas")) );
+       menus_action_group->add( Gtk::Action::create("menu-layer", _("_Layer")) );
+       menus_action_group->add( Gtk::Action::create("menu-duck-mask", _("Show/Hide Ducks")) );
+       menus_action_group->add( Gtk::Action::create("menu-preview-quality", _("Preview Quality")) );
+       menus_action_group->add( Gtk::Action::create("menu-lowres-pixel", _("Low-Res Pixel Size")) );
+       menus_action_group->add( Gtk::Action::create("menu-layer-new", _("New Layer")) );
+       menus_action_group->add( Gtk::Action::create("menu-keyframe", _("Keyframe")) );
+       menus_action_group->add( Gtk::Action::create("menu-group", _("Group")) );
+       menus_action_group->add( Gtk::Action::create("menu-state", _("Tool")) );
+       menus_action_group->add( Gtk::Action::create("menu-toolbox", _("Toolbox")) );
 
        // Add the synfigapp actions...
        synfigapp::Action::Book::iterator iter;
 
        // Add the synfigapp actions...
        synfigapp::Action::Book::iterator iter;
@@ -705,13 +754,14 @@ init_ui_manager()
                        iter->second.local_name,iter->second.local_name
                ));
        }
                        iter->second.local_name,iter->second.local_name
                ));
        }
-       
+
 #define DEFINE_ACTION(x,stock) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); }
 #define DEFINE_ACTION2(x,stock,label) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock,label,label) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); }
 #define DEFINE_ACTION_SIG(group,x,stock,sig) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ group->add(action,sig); }
 
        DEFINE_ACTION2("keyframe-properties", Gtk::StockID("gtk-properties"), _("Keyframe Properties"));
        DEFINE_ACTION("about", Gtk::StockID("synfig-about"));
 #define DEFINE_ACTION(x,stock) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); }
 #define DEFINE_ACTION2(x,stock,label) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock,label,label) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); }
 #define DEFINE_ACTION_SIG(group,x,stock,sig) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ group->add(action,sig); }
 
        DEFINE_ACTION2("keyframe-properties", Gtk::StockID("gtk-properties"), _("Keyframe Properties"));
        DEFINE_ACTION("about", Gtk::StockID("synfig-about"));
+       DEFINE_ACTION("new", Gtk::Stock::NEW);
        DEFINE_ACTION("open", Gtk::Stock::OPEN);
        DEFINE_ACTION("save", Gtk::Stock::SAVE);
        DEFINE_ACTION("save-as", Gtk::Stock::SAVE_AS);
        DEFINE_ACTION("open", Gtk::Stock::OPEN);
        DEFINE_ACTION("save", Gtk::Stock::SAVE);
        DEFINE_ACTION("save-as", Gtk::Stock::SAVE_AS);
@@ -726,7 +776,9 @@ init_ui_manager()
        DEFINE_ACTION("dialog-flipbook", _("Preview Dialog"));
        DEFINE_ACTION("sound", _("Sound File"));
        DEFINE_ACTION("options", _("Options"));
        DEFINE_ACTION("dialog-flipbook", _("Preview Dialog"));
        DEFINE_ACTION("sound", _("Sound File"));
        DEFINE_ACTION("options", _("Options"));
-       DEFINE_ACTION("close", _("Close"));
+       DEFINE_ACTION("close", _("Close View"));
+       DEFINE_ACTION("close-document", _("Close Document"));
+       DEFINE_ACTION("quit", Gtk::Stock::QUIT);
 
 
        DEFINE_ACTION("undo", Gtk::StockID("gtk-undo"));
 
 
        DEFINE_ACTION("undo", Gtk::StockID("gtk-undo"));
@@ -735,6 +787,8 @@ init_ui_manager()
        DEFINE_ACTION("copy", Gtk::StockID("gtk-copy"));
        DEFINE_ACTION("paste", Gtk::StockID("gtk-paste"));
        DEFINE_ACTION("select-all-ducks", _("Select All Ducks"));
        DEFINE_ACTION("copy", Gtk::StockID("gtk-copy"));
        DEFINE_ACTION("paste", Gtk::StockID("gtk-paste"));
        DEFINE_ACTION("select-all-ducks", _("Select All Ducks"));
+       DEFINE_ACTION("unselect-all-ducks", _("Unselect All Ducks"));
+       DEFINE_ACTION("select-all-layers", _("Select All Layers"));
        DEFINE_ACTION("unselect-all-layers", _("Unselect All Layers"));
        DEFINE_ACTION("properties", _("Properties"));
 
        DEFINE_ACTION("unselect-all-layers", _("Unselect All Layers"));
        DEFINE_ACTION("properties", _("Properties"));
 
@@ -755,13 +809,17 @@ init_ui_manager()
        DEFINE_ACTION("quality-08", _("Use Quality Level 8"));
        DEFINE_ACTION("quality-09", _("Use Quality Level 9"));
        DEFINE_ACTION("quality-10", _("Use Quality Level 10"));
        DEFINE_ACTION("quality-08", _("Use Quality Level 8"));
        DEFINE_ACTION("quality-09", _("Use Quality Level 9"));
        DEFINE_ACTION("quality-10", _("Use Quality Level 10"));
+       for(list<int>::iterator iter = CanvasView::get_pixel_sizes().begin(); iter != CanvasView::get_pixel_sizes().end(); iter++)
+               DEFINE_ACTION(strprintf("lowres-pixel-%d", *iter), strprintf(_("Set Low-Res pixel size to %d"), *iter));
        DEFINE_ACTION("play", _("Play"));
        DEFINE_ACTION("play", _("Play"));
-       DEFINE_ACTION("pause", _("Pause"));
+       // DEFINE_ACTION("pause", _("Pause"));
        DEFINE_ACTION("stop", _("Stop"));
        DEFINE_ACTION("toggle-grid-show", _("Toggle Grid Show"));
        DEFINE_ACTION("toggle-grid-snap", _("Toggle Grid Snap"));
        DEFINE_ACTION("toggle-guide-show", _("Toggle Guide Show"));
        DEFINE_ACTION("toggle-low-res", _("Toggle Low-Res"));
        DEFINE_ACTION("stop", _("Stop"));
        DEFINE_ACTION("toggle-grid-show", _("Toggle Grid Show"));
        DEFINE_ACTION("toggle-grid-snap", _("Toggle Grid Snap"));
        DEFINE_ACTION("toggle-guide-show", _("Toggle Guide Show"));
        DEFINE_ACTION("toggle-low-res", _("Toggle Low-Res"));
+       DEFINE_ACTION("decrease-low-res-pixel-size", _("Decrease Low-Res Pixel Size"));
+       DEFINE_ACTION("increase-low-res-pixel-size", _("Increase Low-Res Pixel Size"));
        DEFINE_ACTION("toggle-onion-skin", _("Toggle Onion Skin"));
        DEFINE_ACTION("canvas-zoom-in", Gtk::StockID("gtk-zoom-in"));
        DEFINE_ACTION("canvas-zoom-out", Gtk::StockID("gtk-zoom-out"));
        DEFINE_ACTION("toggle-onion-skin", _("Toggle Onion Skin"));
        DEFINE_ACTION("canvas-zoom-in", Gtk::StockID("gtk-zoom-in"));
        DEFINE_ACTION("canvas-zoom-out", Gtk::StockID("gtk-zoom-out"));
@@ -791,11 +849,11 @@ init_ui_manager()
 // Set up synfigapp actions
        /*{
                synfigapp::Action::Book::iterator iter;
 // Set up synfigapp actions
        /*{
                synfigapp::Action::Book::iterator iter;
-       
+
                for(iter=synfigapp::Action::book().begin();iter!=synfigapp::Action::book().end();++iter)
                {
                        Gtk::StockID stock_id;
                for(iter=synfigapp::Action::book().begin();iter!=synfigapp::Action::book().end();++iter)
                {
                        Gtk::StockID stock_id;
-                       
+
                        if(!(iter->second.category&synfigapp::Action::CATEGORY_HIDDEN))
                        {
                                //Gtk::Image* image(manage(new Gtk::Image()));
                        if(!(iter->second.category&synfigapp::Action::CATEGORY_HIDDEN))
                        {
                                //Gtk::Image* image(manage(new Gtk::Image()));
@@ -809,7 +867,7 @@ init_ui_manager()
                                //else if(iter->second.task=="duplicate")       stock_id=Gtk::Stock::COPY;
                                else if(iter->second.task=="remove")    stock_id=Gtk::Stock::DELETE;
                                else                                                                    stock_id=Gtk::StockID("synfig-"+iter->second.task);
                                //else if(iter->second.task=="duplicate")       stock_id=Gtk::Stock::COPY;
                                else if(iter->second.task=="remove")    stock_id=Gtk::Stock::DELETE;
                                else                                                                    stock_id=Gtk::StockID("synfig-"+iter->second.task);
-       
+
                                actions_action_group->add(Gtk::Action::create(
                                        "action-"+iter->second.name,
                                        stock_id,
                                actions_action_group->add(Gtk::Action::create(
                                        "action-"+iter->second.name,
                                        stock_id,
@@ -829,6 +887,8 @@ init_ui_manager()
 "      </popup>"
 "      <popup name='menu-main' action='menu-main'>"
 "      <menu action='menu-file'>"
 "      </popup>"
 "      <popup name='menu-main' action='menu-main'>"
 "      <menu action='menu-file'>"
+"              <menuitem action='new' />"
+"              <menuitem action='open' />"
 "              <menuitem action='save' />"
 "              <menuitem action='save-as' />"
 "              <menuitem action='revert' />"
 "              <menuitem action='save' />"
 "              <menuitem action='save-as' />"
 "              <menuitem action='revert' />"
@@ -846,6 +906,8 @@ init_ui_manager()
 "              <separator name='bleh04'/>"
 "              <menuitem action='options' />"
 "              <menuitem action='close' />"
 "              <separator name='bleh04'/>"
 "              <menuitem action='options' />"
 "              <menuitem action='close' />"
+"              <menuitem action='close-document' />"
+"              <menuitem action='quit' />"
 "      </menu>"
 "      <menu action='menu-edit'>"
 "              <menuitem action='undo'/>"
 "      </menu>"
 "      <menu action='menu-edit'>"
 "              <menuitem action='undo'/>"
@@ -855,8 +917,10 @@ init_ui_manager()
 "              <menuitem action='copy'/>"
 "              <menuitem action='paste'/>"
 "              <separator name='bleh06'/>"
 "              <menuitem action='copy'/>"
 "              <menuitem action='paste'/>"
 "              <separator name='bleh06'/>"
-"              <menuitem action='select-all-ducks'/>"
+"              <menuitem action='select-all-layers'/>"
 "              <menuitem action='unselect-all-layers'/>"
 "              <menuitem action='unselect-all-layers'/>"
+"              <menuitem action='select-all-ducks'/>"
+"              <menuitem action='unselect-all-ducks'/>"
 "              <separator name='bleh07'/>"
 "              <menuitem action='properties'/>"
 "      </menu>"
 "              <separator name='bleh07'/>"
 "              <menuitem action='properties'/>"
 "      </menu>"
@@ -882,9 +946,20 @@ init_ui_manager()
 "                      <menuitem action='quality-09' />"
 "                      <menuitem action='quality-10' />"
 "              </menu>"
 "                      <menuitem action='quality-09' />"
 "                      <menuitem action='quality-10' />"
 "              </menu>"
+"              <menu action='menu-lowres-pixel'>"
+"              <menuitem action='decrease-low-res-pixel-size'/>"
+"              <menuitem action='increase-low-res-pixel-size'/>"
+"              <separator name='pixel-size-separator'/>"
+;
+
+       for(list<int>::iterator iter = CanvasView::get_pixel_sizes().begin(); iter != CanvasView::get_pixel_sizes().end(); iter++)
+               ui_info += strprintf("                  <menuitem action='lowres-pixel-%d' />", *iter);
+
+       ui_info +=
+"              </menu>"
 "              <separator name='bleh08'/>"
 "              <menuitem action='play'/>"
 "              <separator name='bleh08'/>"
 "              <menuitem action='play'/>"
-"              <menuitem action='pause'/>"
+//"            <menuitem action='pause'/>"
 "              <menuitem action='stop'/>"
 "              <menuitem action='dialog-flipbook'/>"
 "              <separator name='bleh09'/>"
 "              <menuitem action='stop'/>"
 "              <menuitem action='dialog-flipbook'/>"
 "              <separator name='bleh09'/>"
@@ -913,8 +988,6 @@ init_ui_manager()
 "      </menu>"
 "      <menu action='menu-canvas'>"
 "              <menuitem action='canvas-new'/>"
 "      </menu>"
 "      <menu action='menu-canvas'>"
 "              <menuitem action='canvas-new'/>"
-       "       <menuitem action='amount-inc'/>"
-       "       <menuitem action='amount-dec'/>"
 "      </menu>"
 "      <menu name='menu-state' action='menu-state'>"
 "      </menu>"
 "      </menu>"
 "      <menu name='menu-state' action='menu-state'>"
 "      </menu>"
@@ -927,6 +1000,8 @@ init_ui_manager()
 //"            <menuitem action='paste'/>"
 //"            <separator name='bleh06'/>"
 "              <menu action='menu-layer-new'></menu>"
 //"            <menuitem action='paste'/>"
 //"            <separator name='bleh06'/>"
 "              <menu action='menu-layer-new'></menu>"
+"              <menuitem action='amount-inc'/>"
+"              <menuitem action='amount-dec'/>"
 "      </menu>"
 "      <menu action='menu-keyframe'>"
 "              <menuitem action='keyframe-properties'/>"
 "      </menu>"
 "      <menu action='menu-keyframe'>"
 "              <menuitem action='keyframe-properties'/>"
@@ -971,77 +1046,93 @@ init_ui_manager()
        }
 
        // Add default keyboard accelerators
        }
 
        // Add default keyboard accelerators
-#define ACCEL(path,accel)      { Gtk::AccelKey accel_key(accel,path); Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(),accel_key.get_mod()); }
-#define ACCEL2(accel)  { Gtk::AccelKey accel_key(accel); Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(),accel_key.get_mod()); }
-       ACCEL("<Actions>//select-all-ducks","<Control>a");
-       ACCEL("<Actions>//unselect-all-layers","<Control>d");
-       ACCEL("<Actions>//render","F9");
-       ACCEL("<Actions>//preview","F11");
-       ACCEL("<Actions>//properties","F8");
-       ACCEL("<Actions>//options","F12");
-       ACCEL("<Actions>//import","<control>i");
-       ACCEL2(Gtk::AccelKey(GDK_Escape,static_cast<Gdk::ModifierType>(0),"<Actions>//stop"));
-       ACCEL("<Actions>//toggle-grid-show","<Control>g");
-       ACCEL("<Actions>//toggle-grid-snap","<Control>l");
-       ACCEL2(Gtk::AccelKey('`',Gdk::CONTROL_MASK,"<Actions>//toggle-low-res"));
-       ACCEL("<Actions>//mask-position-ducks", "<Mod1>1");
-       ACCEL("<Actions>//mask-vertex-ducks", "<Mod1>2");
-       ACCEL("<Actions>//mask-tangent-ducks", "<Mod1>3");
-       ACCEL("<Actions>//mask-radius-ducks", "<Mod1>4");
-       ACCEL("<Actions>//mask-width-ducks", "<Mod1>5");
-       ACCEL("<Actions>//mask-angle-ducks", "<Mod1>6");
-
-
-       ACCEL2(Gtk::AccelKey(GDK_Page_Up,Gdk::SHIFT_MASK,"<Actions>//action-layer_raise"));
-       ACCEL2(Gtk::AccelKey(GDK_Page_Down,Gdk::SHIFT_MASK,"<Actions>//action-layer_lower"));
-
-       ACCEL("<Actions>//quality-01","<Control>1");
-       ACCEL("<Actions>//quality-02","<Control>2");
-       ACCEL("<Actions>//quality-03","<Control>3");
-       ACCEL("<Actions>//quality-04","<Control>4");
-       ACCEL("<Actions>//quality-05","<Control>5");
-       ACCEL("<Actions>//quality-06","<Control>6");
-       ACCEL("<Actions>//quality-07","<Control>7");
-       ACCEL("<Actions>//quality-08","<Control>8");
-       ACCEL("<Actions>//quality-09","<Control>9");
-       ACCEL("<Actions>//quality-10","<Control>0");
-       ACCEL("<Actions>//undo","<Control>z");
-       ACCEL("<Actions>//redo","<Control>r");
-       ACCEL("<Actions>//action-layer_remove","Delete");
-
-/*     ACCEL2(Gtk::AccelKey(']',static_cast<Gdk::ModifierType>(0),"<Actions>//jump-next-keyframe"));
-       ACCEL2(Gtk::AccelKey('[',static_cast<Gdk::ModifierType>(0),"<Actions>//jump-prev-keyframe"));
-       ACCEL2(Gtk::AccelKey('=',static_cast<Gdk::ModifierType>(0),"<Actions>//canvas-zoom-in"));
-       ACCEL2(Gtk::AccelKey('-',static_cast<Gdk::ModifierType>(0),"<Actions>//canvas-zoom-out"));
-       ACCEL("<Actions>//time-zoom-in","+");
-       ACCEL("<Actions>//time-zoom-out","_");
-*/
-       ACCEL2(Gtk::AccelKey('(',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,"<Actions>//amount-dec"));
-       ACCEL2(Gtk::AccelKey(')',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,"<Actions>//amount-inc"));
-
-       ACCEL2(Gtk::AccelKey(']',Gdk::CONTROL_MASK,"<Actions>//jump-next-keyframe"));
-       ACCEL2(Gtk::AccelKey('[',Gdk::CONTROL_MASK,"<Actions>//jump-prev-keyframe"));
-       ACCEL2(Gtk::AccelKey('=',Gdk::CONTROL_MASK,"<Actions>//canvas-zoom-in"));
-       ACCEL2(Gtk::AccelKey('-',Gdk::CONTROL_MASK,"<Actions>//canvas-zoom-out"));
-       ACCEL2(Gtk::AccelKey('+',Gdk::CONTROL_MASK,"<Actions>//time-zoom-in"));
-       ACCEL2(Gtk::AccelKey('_',Gdk::CONTROL_MASK,"<Actions>//time-zoom-out"));
-       ACCEL2(Gtk::AccelKey('.',Gdk::CONTROL_MASK,"<Actions>//seek-next-frame"));
-       ACCEL2(Gtk::AccelKey(',',Gdk::CONTROL_MASK,"<Actions>//seek-prev-frame"));
-       ACCEL2(Gtk::AccelKey('>',Gdk::CONTROL_MASK,"<Actions>//seek-next-second"));
-       ACCEL2(Gtk::AccelKey('<',Gdk::CONTROL_MASK,"<Actions>//seek-prev-second"));
-       ACCEL2(Gtk::AccelKey('o',Gdk::CONTROL_MASK,"<Actions>//toggle-onion-skin"));
-       ACCEL("<Actions>//seek-begin","Home");
-       ACCEL("<Actions>//seek-end","End");
-       ACCEL("<Actions>//state-normal","<Mod1>a");
-       ACCEL("<Actions>//state-rotate","<Mod1>s");
-       ACCEL("<Actions>//state-scale","<Mod1>d");
-       ACCEL("<Actions>//state-bline","<Mod1>b");
-       ACCEL("<Actions>//state-fill","<Mod1>f");
-       ACCEL("<Actions>//state-eyedrop","<Mod1>e");
-       ACCEL("<Actions>//state-gradient","<Mod1>g");
-       ACCEL("<Actions>//state-zoom","<Mod1>z");
-       ACCEL("<Actions>//canvas-zoom-fit","<Control><Shift>z");
-       
+#define ACCEL(accel,path)                                              \
+       {                                                                                       \
+               Gtk::AccelKey accel_key(accel,path);    \
+               Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(), accel_key.get_mod());       \
+       }
+
+#define ACCEL2(accel)                                                  \
+       {                                                                                       \
+               Gtk::AccelKey accel_key(accel);                 \
+               Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(), accel_key.get_mod());       \
+       }
+
+       // the toolbox
+       ACCEL("<Mod1>a",                                                                                                        "<Actions>//state-normal"                                       );
+       ACCEL("<Mod1>v",                                                                                                        "<Actions>//state-smooth_move"                          );
+       ACCEL("<Mod1>s",                                                                                                        "<Actions>//state-scale"                                        );
+       ACCEL("<Mod1>t",                                                                                                        "<Actions>//state-rotate"                                       );
+       ACCEL("<Mod1>m",                                                                                                        "<Actions>//state-mirror"                                       );
+       ACCEL("<Mod1>c",                                                                                                        "<Actions>//state-circle"                                       );
+       ACCEL("<Mod1>r",                                                                                                        "<Actions>//state-rectangle"                            );
+       ACCEL("<Mod1>q",                                                                                                        "<Actions>//state-star"                                         );
+       ACCEL("<Mod1>g",                                                                                                        "<Actions>//state-gradient"                                     );
+       ACCEL("<Mod1>p",                                                                                                        "<Actions>//state-polygon"                                      );
+       ACCEL("<Mod1>b",                                                                                                        "<Actions>//state-bline"                                        );
+       ACCEL("<Mod1>x",                                                                                                        "<Actions>//state-text"                                         );
+       ACCEL("<Mod1>f",                                                                                                        "<Actions>//state-fill"                                         );
+       ACCEL("<Mod1>e",                                                                                                        "<Actions>//state-eyedrop"                                      );
+       ACCEL("<Mod1>z",                                                                                                        "<Actions>//state-zoom"                                         );
+       ACCEL("<Mod1>d",                                                                                                        "<Actions>//state-draw"                                         );
+       ACCEL("<Mod1>k",                                                                                                        "<Actions>//state-sketch"                                       );
+       ACCEL("<Mod1>w",                                                                                                        "<Actions>//state-width"                                        );
+
+       // everything else
+       ACCEL("<Control>a",                                                                                                     "<Actions>//select-all-ducks"                           );
+       ACCEL("<Control>d",                                                                                                     "<Actions>//unselect-all-ducks"                         );
+       ACCEL("<Control><Shift>a",                                                                                      "<Actions>//select-all-layers"                          );
+       ACCEL("<Control><Shift>d",                                                                                      "<Actions>//unselect-all-layers"                        );
+       ACCEL("F9",                                                                                                                     "<Actions>//render"                                                     );
+       ACCEL("F11",                                                                                                            "<Actions>//preview"                                            );
+       ACCEL("F8",                                                                                                                     "<Actions>//properties"                                         );
+       ACCEL("F12",                                                                                                            "<Actions>//options"                                            );
+       ACCEL("<control>i",                                                                                                     "<Actions>//import"                                                     );
+       ACCEL2(Gtk::AccelKey(GDK_Escape,static_cast<Gdk::ModifierType>(0),      "<Actions>//stop"                                                       ));
+       ACCEL("<Control>g",                                                                                                     "<Actions>//toggle-grid-show"                           );
+       ACCEL("<Control>l",                                                                                                     "<Actions>//toggle-grid-snap"                           );
+       ACCEL2(Gtk::AccelKey('`',Gdk::CONTROL_MASK,                                                     "<Actions>//toggle-low-res"                                     ));
+       ACCEL("<Mod1>1",                                                                                                        "<Actions>//mask-position-ducks"                        );
+       ACCEL("<Mod1>2",                                                                                                        "<Actions>//mask-vertex-ducks"                          );
+       ACCEL("<Mod1>3",                                                                                                        "<Actions>//mask-tangent-ducks"                         );
+       ACCEL("<Mod1>4",                                                                                                        "<Actions>//mask-radius-ducks"                          );
+       ACCEL("<Mod1>5",                                                                                                        "<Actions>//mask-width-ducks"                           );
+       ACCEL("<Mod1>6",                                                                                                        "<Actions>//mask-angle-ducks"                           );
+       ACCEL2(Gtk::AccelKey(GDK_Page_Up,Gdk::SHIFT_MASK,                                       "<Actions>//action-LayerRaise"                          ));
+       ACCEL2(Gtk::AccelKey(GDK_Page_Down,Gdk::SHIFT_MASK,                                     "<Actions>//action-LayerLower"                          ));
+       ACCEL("<Control>1",                                                                                                     "<Actions>//quality-01"                                         );
+       ACCEL("<Control>2",                                                                                                     "<Actions>//quality-02"                                         );
+       ACCEL("<Control>3",                                                                                                     "<Actions>//quality-03"                                         );
+       ACCEL("<Control>4",                                                                                                     "<Actions>//quality-04"                                         );
+       ACCEL("<Control>5",                                                                                                     "<Actions>//quality-05"                                         );
+       ACCEL("<Control>6",                                                                                                     "<Actions>//quality-06"                                         );
+       ACCEL("<Control>7",                                                                                                     "<Actions>//quality-07"                                         );
+       ACCEL("<Control>8",                                                                                                     "<Actions>//quality-08"                                         );
+       ACCEL("<Control>9",                                                                                                     "<Actions>//quality-09"                                         );
+       ACCEL("<Control>0",                                                                                                     "<Actions>//quality-10"                                         );
+       ACCEL("<Control>z",                                                                                                     "<Actions>//undo"                                                       );
+       ACCEL("<Control>r",                                                                                                     "<Actions>//redo"                                                       );
+       ACCEL2(Gtk::AccelKey(GDK_Delete,Gdk::CONTROL_MASK,                                      "<Actions>//action-LayerRemove"                         ));
+       ACCEL2(Gtk::AccelKey('(',Gdk::CONTROL_MASK,                                                     "<Actions>//decrease-low-res-pixel-size"        ));
+       ACCEL2(Gtk::AccelKey(')',Gdk::CONTROL_MASK,                                                     "<Actions>//increase-low-res-pixel-size"        ));
+       ACCEL2(Gtk::AccelKey('(',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,                      "<Actions>//amount-dec"                                         ));
+       ACCEL2(Gtk::AccelKey(')',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,                      "<Actions>//amount-inc"                                         ));
+       ACCEL2(Gtk::AccelKey(']',Gdk::CONTROL_MASK,                                                     "<Actions>//jump-next-keyframe"                         ));
+       ACCEL2(Gtk::AccelKey('[',Gdk::CONTROL_MASK,                                                     "<Actions>//jump-prev-keyframe"                         ));
+       ACCEL2(Gtk::AccelKey('=',Gdk::CONTROL_MASK,                                                     "<Actions>//canvas-zoom-in"                                     ));
+       ACCEL2(Gtk::AccelKey('-',Gdk::CONTROL_MASK,                                                     "<Actions>//canvas-zoom-out"                            ));
+       ACCEL2(Gtk::AccelKey('+',Gdk::CONTROL_MASK,                                                     "<Actions>//time-zoom-in"                                       ));
+       ACCEL2(Gtk::AccelKey('_',Gdk::CONTROL_MASK,                                                     "<Actions>//time-zoom-out"                                      ));
+       ACCEL2(Gtk::AccelKey('.',Gdk::CONTROL_MASK,                                                     "<Actions>//seek-next-frame"                            ));
+       ACCEL2(Gtk::AccelKey(',',Gdk::CONTROL_MASK,                                                     "<Actions>//seek-prev-frame"                            ));
+       ACCEL2(Gtk::AccelKey('>',Gdk::CONTROL_MASK,                                                     "<Actions>//seek-next-second"                           ));
+       ACCEL2(Gtk::AccelKey('<',Gdk::CONTROL_MASK,                                                     "<Actions>//seek-prev-second"                           ));
+       ACCEL("<Mod1>o",                                                                                                        "<Actions>//toggle-onion-skin"                          );
+       ACCEL("<Control><Shift>z",                                                                                      "<Actions>//canvas-zoom-fit"                            );
+       ACCEL("<Control>p",                                                                                                     "<Actions>//play"                                                       );
+       ACCEL("Home",                                                                                                           "<Actions>//seek-begin"                                         );
+       ACCEL("End",                                                                                                            "<Actions>//seek-end"                                           );
+
 #undef ACCEL
 }
 
 #undef ACCEL
 }
 
@@ -1053,22 +1144,22 @@ init_ui_manager()
 
 App::App(int *argc, char ***argv):
        Gtk::Main(argc,argv),
 
 App::App(int *argc, char ***argv):
        Gtk::Main(argc,argv),
-       IconControler(etl::dirname((*argv)[0]))
+       IconController(etl::dirname((*argv)[0]))
 {
        app_base_path_=etl::dirname(etl::dirname((*argv)[0]));
 {
        app_base_path_=etl::dirname(etl::dirname((*argv)[0]));
-       
-       int serial_;
-       serial_=check_license(app_base_path_);
-       
-       
+
+
        ui_interface_=new GlobalUIInterface();
 
        gdk_rgb_init();
 
        ui_interface_=new GlobalUIInterface();
 
        gdk_rgb_init();
 
-       Glib::thread_init();
+       // don't call thread_init() if threads are already initialized
+       // on some machines bonobo_init() initialized threads before we get here
+       if (!g_thread_supported())
+               Glib::thread_init();
 
        distance_system=Distance::SYSTEM_UNITS;
 
        distance_system=Distance::SYSTEM_UNITS;
-               
+
        if(mkdir(get_user_app_directory().c_str(),ACCESSPERMS)<0)
        {
                if(errno!=EEXIST)
        if(mkdir(get_user_app_directory().c_str(),ACCESSPERMS)<0)
        {
                if(errno!=EEXIST)
@@ -1078,231 +1169,233 @@ App::App(int *argc, char ***argv):
        {
                synfig::info("Created directory \"%s\"",get_user_app_directory().c_str());
        }
        {
                synfig::info("Created directory \"%s\"",get_user_app_directory().c_str());
        }
-       
-       
+
+
        ipc=new IPC();
        ipc=new IPC();
-       
-       try
+
+       if(!SYNFIG_CHECK_VERSION())
        {
        {
-               if(!SYNFIG_CHECK_VERSION())
-               {
                cerr<<"FATAL: Synfig Version Mismatch"<<endl;
                cerr<<"FATAL: Synfig Version Mismatch"<<endl;
-               dialog_error_blocking("SYNFIG Studio",
-                       "This copy of SYNFIG Studio was compiled against a\n"
+               dialog_error_blocking("Synfig Studio",
+                       "This copy of Synfig Studio was compiled against a\n"
                        "different version of libsynfig than what is currently\n"
                        "installed. Synfig Studio will now abort. Try downloading\n"
                        "different version of libsynfig than what is currently\n"
                        "installed. Synfig Studio will now abort. Try downloading\n"
-                       "the latest version from the SYNFIG Development Website at\n"
-                       "http://dev.synfig.com/ "
+                       "the latest version from the Synfig website at\n"
+                       "http://synfig.org/Download"
                );
                throw 40;
                );
                throw 40;
-               }
        }
        }
-       catch(synfig::SoftwareExpired)
-       {
-               cerr<<"FATAL: Software Expired"<<endl;
-               dialog_error_blocking("SYNFIG Studio",
-                       "This copy of SYNFIG Studio has expired.\n"
-                       "Please erase this copy, or download and\n"
-                       "install the latest copy from the SYNFIG\n"
-                       "Development Website at http://dev.synfig.com/ ."
-               );
-               throw 39;
-       }
-       Glib::set_application_name(_("SYNFIG Studio"));
-       
-       About about_window;
-       about_window.set_can_self_destruct(false);
-       about_window.show();
+       Glib::set_application_name(_("Synfig Studio"));
+
+       Splash splash_screen;
+       splash_screen.show();
 
        shutdown_in_progress=false;
 
        shutdown_in_progress=false;
-       SuperCallback synfig_init_cb(about_window.get_callback(),0,9000,10000);
-       SuperCallback studio_init_cb(about_window.get_callback(),9000,10000,10000);
-       
+       SuperCallback synfig_init_cb(splash_screen.get_callback(),0,9000,10000);
+       SuperCallback studio_init_cb(splash_screen.get_callback(),9000,10000,10000);
+
        // Initialize the Synfig library
        try { synfigapp_main=etl::smart_ptr<synfigapp::Main>(new synfigapp::Main(etl::dirname((*argv)[0]),&synfig_init_cb)); }
        // Initialize the Synfig library
        try { synfigapp_main=etl::smart_ptr<synfigapp::Main>(new synfigapp::Main(etl::dirname((*argv)[0]),&synfig_init_cb)); }
+       catch(std::runtime_error x)
+       {
+               get_ui_interface()->error(strprintf("%s\n\n%s", _("Failed to initialize synfig!"), x.what()));
+               throw;
+       }
        catch(...)
        {
        catch(...)
        {
-               get_ui_interface()->error("Failed to initialize synfig!");
+               get_ui_interface()->error(_("Failed to initialize synfig!"));
                throw;
        }
 
        // add the preferences to the settings
        synfigapp::Main::settings().add_domain(&_preferences,"pref");
                throw;
        }
 
        // add the preferences to the settings
        synfigapp::Main::settings().add_domain(&_preferences,"pref");
-       
+
        try
        {
        try
        {
-               studio_init_cb.task("Init UI Manager...");
+               studio_init_cb.task(_("Init UI Manager..."));
                App::ui_manager_=studio::UIManager::create();
                init_ui_manager();
                App::ui_manager_=studio::UIManager::create();
                init_ui_manager();
-               
-               studio_init_cb.task("Init Dock Manager...");
+
+               studio_init_cb.task(_("Init Dock Manager..."));
                dock_manager=new studio::DockManager();
 
                dock_manager=new studio::DockManager();
 
-               studio_init_cb.task("Init State Manager...");
+               studio_init_cb.task(_("Init State Manager..."));
                state_manager=new StateManager();
 
                state_manager=new StateManager();
 
-               studio_init_cb.task("Init Toolbox...");
+               studio_init_cb.task(_("Init Toolbox..."));
                toolbox=new studio::Toolbox();
 
                toolbox=new studio::Toolbox();
 
-               studio_init_cb.task("Init Tool Options...");
+               studio_init_cb.task(_("Init About Dialog..."));
+               about=new studio::About();
+
+               studio_init_cb.task(_("Init Tool Options..."));
                dialog_tool_options=new studio::Dialog_ToolOptions();
                dock_manager->register_dockable(*dialog_tool_options);
 
                dialog_tool_options=new studio::Dialog_ToolOptions();
                dock_manager->register_dockable(*dialog_tool_options);
 
-               studio_init_cb.task("Init History...");
+               studio_init_cb.task(_("Init History..."));
                dock_history=new studio::Dock_History();
                dock_manager->register_dockable(*dock_history);
 
                dock_history=new studio::Dock_History();
                dock_manager->register_dockable(*dock_history);
 
-               studio_init_cb.task("Init Canvases...");
+               studio_init_cb.task(_("Init Canvases..."));
                dock_canvases=new studio::Dock_Canvases();
                dock_manager->register_dockable(*dock_canvases);
 
                dock_canvases=new studio::Dock_Canvases();
                dock_manager->register_dockable(*dock_canvases);
 
-               studio_init_cb.task("Init Keyframes...");
+               studio_init_cb.task(_("Init Keyframes..."));
                dock_keyframes=new studio::Dock_Keyframes();
                dock_manager->register_dockable(*dock_keyframes);
 
                dock_keyframes=new studio::Dock_Keyframes();
                dock_manager->register_dockable(*dock_keyframes);
 
-               studio_init_cb.task("Init Layers...");
+               studio_init_cb.task(_("Init Layers..."));
                dock_layers=new studio::Dock_Layers();
                dock_manager->register_dockable(*dock_layers);
 
                dock_layers=new studio::Dock_Layers();
                dock_manager->register_dockable(*dock_layers);
 
-               studio_init_cb.task("Init Params...");
+               studio_init_cb.task(_("Init Params..."));
                dock_params=new studio::Dock_Params();
                dock_manager->register_dockable(*dock_params);
 
                dock_params=new studio::Dock_Params();
                dock_manager->register_dockable(*dock_params);
 
-               studio_init_cb.task("Init MetaData...");
+               studio_init_cb.task(_("Init MetaData..."));
                dock_meta_data=new studio::Dock_MetaData();
                dock_manager->register_dockable(*dock_meta_data);
 
                dock_meta_data=new studio::Dock_MetaData();
                dock_manager->register_dockable(*dock_meta_data);
 
-               studio_init_cb.task("Init Children...");
+               studio_init_cb.task(_("Init Children..."));
                dock_children=new studio::Dock_Children();
                dock_manager->register_dockable(*dock_children);
                dock_children=new studio::Dock_Children();
                dock_manager->register_dockable(*dock_children);
-               
-               studio_init_cb.task("Init Info...");
+
+               studio_init_cb.task(_("Init Info..."));
                dock_info = new studio::Dock_Info();
                dock_manager->register_dockable(*dock_info);
                dock_info = new studio::Dock_Info();
                dock_manager->register_dockable(*dock_info);
-               
-               studio_init_cb.task("Init Navigator...");
+
+               studio_init_cb.task(_("Init Navigator..."));
                dock_navigator = new studio::Dock_Navigator();
                dock_manager->register_dockable(*dock_navigator);
 
                dock_navigator = new studio::Dock_Navigator();
                dock_manager->register_dockable(*dock_navigator);
 
-               studio_init_cb.task("Init Timetrack...");
+               studio_init_cb.task(_("Init Timetrack..."));
                dock_timetrack = new studio::Dock_Timetrack();
                dock_manager->register_dockable(*dock_timetrack);
 
                dock_timetrack = new studio::Dock_Timetrack();
                dock_manager->register_dockable(*dock_timetrack);
 
-               studio_init_cb.task("Init Curve Editor...");
+               studio_init_cb.task(_("Init Curve Editor..."));
                dock_curves = new studio::Dock_Curves();
                dock_manager->register_dockable(*dock_curves);
 
                dock_curves = new studio::Dock_Curves();
                dock_manager->register_dockable(*dock_curves);
 
-               studio_init_cb.task("Init Layer Groups...");
+               studio_init_cb.task(_("Init Layer Groups..."));
                dock_layer_groups = new studio::Dock_LayerGroups();
                dock_manager->register_dockable(*dock_layer_groups);
                dock_layer_groups = new studio::Dock_LayerGroups();
                dock_manager->register_dockable(*dock_layer_groups);
-               
-               
-               studio_init_cb.task("Init Color Dialog...");
+
+
+               studio_init_cb.task(_("Init Color Dialog..."));
                dialog_color=new studio::Dialog_Color();
 
                dialog_color=new studio::Dialog_Color();
 
-               studio_init_cb.task("Init Gradient Dialog...");
+               studio_init_cb.task(_("Init Gradient Dialog..."));
                dialog_gradient=new studio::Dialog_Gradient();
 
                dialog_gradient=new studio::Dialog_Gradient();
 
-               studio_init_cb.task("Init DeviceTracker...");
+               studio_init_cb.task(_("Init DeviceTracker..."));
                device_tracker=new studio::DeviceTracker();
 
                device_tracker=new studio::DeviceTracker();
 
-               studio_init_cb.task("Init Tools...");
+               studio_init_cb.task(_("Init Tools..."));
+
+               /* row 1 */
                state_manager->add_state(&state_normal);
                state_manager->add_state(&state_smooth_move);
                state_manager->add_state(&state_scale);
                state_manager->add_state(&state_rotate);
                state_manager->add_state(&state_normal);
                state_manager->add_state(&state_smooth_move);
                state_manager->add_state(&state_scale);
                state_manager->add_state(&state_rotate);
+               studio_init_cb.task(_("Init ModMirror...")); module_list_.push_back(new ModMirror()); module_list_.back()->start();
 
 
-               state_manager->add_state(&state_bline);
-               
-               
+               /* row 2 */
                state_manager->add_state(&state_circle);
                state_manager->add_state(&state_rectangle);
                state_manager->add_state(&state_circle);
                state_manager->add_state(&state_rectangle);
-
+               state_manager->add_state(&state_star);
                state_manager->add_state(&state_gradient);
                state_manager->add_state(&state_gradient);
-               state_manager->add_state(&state_eyedrop);
+               if(!getenv("SYNFIG_DISABLE_POLYGON")) state_manager->add_state(&state_polygon); // Enabled - for working without ducks
+
+               /* row 3 */
+               state_manager->add_state(&state_bline);
+               state_manager->add_state(&state_text);
                state_manager->add_state(&state_fill);
                state_manager->add_state(&state_fill);
-               
+               state_manager->add_state(&state_eyedrop);
                state_manager->add_state(&state_zoom);
 
                state_manager->add_state(&state_zoom);
 
-               if(false) {
-                       // Disabled this tool because it should be
-                       // considered deprecated. Use the bline tool instead.
-                       state_manager->add_state(&state_polygon);
-       
-                       // These tools are disabled for now,
-                       // because they tend to confuse users.
-                       state_manager->add_state(&state_draw);
-                       state_manager->add_state(&state_sketch);
-                       state_manager->add_state(&state_width);
-               }
+               if(!getenv("SYNFIG_DISABLE_DRAW"   )) state_manager->add_state(&state_draw); // Enabled for now.  Let's see whether they're good enough yet.
+               if(!getenv("SYNFIG_DISABLE_SKETCH" )) state_manager->add_state(&state_sketch);
+               if(!getenv("SYNFIG_DISABLE_WIDTH"  )) state_manager->add_state(&state_width); // Enabled since 0.61.09
 
 
-               studio_init_cb.task("Init ModPalette...");
+               studio_init_cb.task(_("Init ModPalette..."));
                module_list_.push_back(new ModPalette()); module_list_.back()->start();
 
                module_list_.push_back(new ModPalette()); module_list_.back()->start();
 
-               studio_init_cb.task("Init ModMirror...");
-               module_list_.push_back(new ModMirror()); module_list_.back()->start();
-
-
-               studio_init_cb.task("Init Setup Dialog...");
+               studio_init_cb.task(_("Init Setup Dialog..."));
                dialog_setup=new studio::Dialog_Setup();
                dialog_setup=new studio::Dialog_Setup();
-               
-               studio_init_cb.task("Init Input Dialog...");
+
+               studio_init_cb.task(_("Init Input Dialog..."));
                dialog_input=new Gtk::InputDialog();
                dialog_input=new Gtk::InputDialog();
+               dialog_input->get_close_button()->signal_clicked().connect( sigc::mem_fun( *dialog_input, &Gtk::InputDialog::hide ) );
+               dialog_input->get_save_button()->signal_clicked().connect( sigc::mem_fun( *device_tracker, &DeviceTracker::save_preferences) );
 
 
-               studio_init_cb.task("Init auto recovery...");
+               studio_init_cb.task(_("Init auto recovery..."));
                auto_recover=new AutoRecover();
 
                studio_init_cb.amount_complete(9250,10000);
                auto_recover=new AutoRecover();
 
                studio_init_cb.amount_complete(9250,10000);
-               studio_init_cb.task("Loading Settings...");
+               studio_init_cb.task(_("Loading Settings..."));
                load_settings();
                load_settings();
-               studio_init_cb.task("Checking auto-recover...");
-       
+               device_tracker->load_preferences();
+
+               studio_init_cb.task(_("Checking auto-recover..."));
+
                studio_init_cb.amount_complete(9900,10000);
                studio_init_cb.amount_complete(9900,10000);
-       
+
+               bool opened_any = false;
                if(auto_recover->recovery_needed())
                {
                if(auto_recover->recovery_needed())
                {
-                       about_window.hide();
-                       if(
-                               get_ui_interface()->yes_no(
-                                       "Auto Recovery",
-                                       "SYNFIG Studio seems to have crashed\n"
-                                       "before you could save all your files.\n"
-                                       "Would you like to re-open those files\n"
-                                       "and recover your unsaved changes?"
-                               )==synfigapp::UIInterface::RESPONSE_YES
-                       )
+                       splash_screen.hide();
+                       if (get_ui_interface()->confirmation("Crash Recovery",
+                                       _("Auto recovery file found"),
+                                       _("Synfig Studio seems to have crashed\n"
+                                         "before you could save all your files.\n"
+                                         "Recover unsaved changes?"),
+                                       _("Recover"), _("Ignore"))
+                               == synfigapp::UIInterface::RESPONSE_OK)
                        {
                        {
-                               if(!auto_recover->recover())
-                               {
-                                       get_ui_interface()->error(_("Unable to fully recover from previous crash"));
-                               }
+                               int number_recovered;
+                               if(!auto_recover->recover(number_recovered))
+                                       if (number_recovered)
+                                               get_ui_interface()->error(_("Unable to fully recover from previous crash"));
+                                       else
+                                               get_ui_interface()->error(_("Unable to recover from previous crash"));
                                else
                                else
-                               get_ui_interface()->error(
-                                       _("SYNFIG Studio has attempted to recover\n"
-                                       "from a previous crash. The files that it has\n"
-                                       "recovered are NOT YET SAVED. It would be a good\n"
-                                       "idea to review them and save them now.")
-                               );
+                                       get_ui_interface()->error(
+                                               _("Synfig Studio has attempted to recover\n"
+                                                 "from a previous crash. The files that it has\n"
+                                                 "recovered are NOT YET SAVED. It would be a good\n"
+                                                 "idea to review them and save them now."));
+
+                               if (number_recovered)
+                                       opened_any = true;
                        }
                        }
-                       about_window.show();
+                       splash_screen.show();
                }
                }
-               
+
                // Look for any files given on the command line,
                // and load them if found.
                for(;*argc>=1;(*argc)--)
                        if((*argv)[*argc] && (*argv)[*argc][0]!='-')
                        {
                // Look for any files given on the command line,
                // and load them if found.
                for(;*argc>=1;(*argc)--)
                        if((*argv)[*argc] && (*argv)[*argc][0]!='-')
                        {
-                               studio_init_cb.task("Loading files...");
-                               about_window.hide();
+                               studio_init_cb.task(_("Loading files..."));
+                               splash_screen.hide();
                                open((*argv)[*argc]);
                                open((*argv)[*argc]);
-                               about_window.show();
+                               opened_any = true;
+                               splash_screen.show();
                        }
                        }
-               
-               studio_init_cb.task("Done.");
+
+               // if no file was specified to be opened, create a new document to help new users get started more easily
+               if (!opened_any && !getenv("SYNFIG_DISABLE_AUTOMATIC_DOCUMENT_CREATION"))
+                       new_instance();
+
+               studio_init_cb.task(_("Done."));
                studio_init_cb.amount_complete(10000,10000);
                studio_init_cb.amount_complete(10000,10000);
-       
+
                toolbox->present();
        }
                toolbox->present();
        }
+       catch(String x)
+       {
+               get_ui_interface()->error(_("Unknown exception caught when constructing App.\nThis software may be unstable.") + String("\n\n") + x);
+       }
        catch(...)
        {
                get_ui_interface()->error(_("Unknown exception caught when constructing App.\nThis software may be unstable."));
        catch(...)
        {
                get_ui_interface()->error(_("Unknown exception caught when constructing App.\nThis software may be unstable."));
@@ -1318,27 +1411,30 @@ App::~App()
        save_settings();
 
        synfigapp::Main::settings().remove_domain("pref");
        save_settings();
 
        synfigapp::Main::settings().remove_domain("pref");
-       
+
        selected_instance=0;
 
        // Unload all of the modules
        selected_instance=0;
 
        // Unload all of the modules
-       for(;!module_list_.empty();module_list_.pop_back());
-       
+       for(;!module_list_.empty();module_list_.pop_back())
+               ;
+
        delete state_manager;
 
        delete ipc;
        delete state_manager;
 
        delete ipc;
-       
+
        delete auto_recover;
 
        delete auto_recover;
 
+       delete about;
+
        toolbox->hide();
 
        toolbox->hide();
 
-//     studio::App::iteration(false); 
-       
+//     studio::App::iteration(false);
+
        delete toolbox;
        delete toolbox;
-       
-//     studio::App::iteration(false); 
 
 
-//     studio::App::iteration(false); 
+//     studio::App::iteration(false);
+
+//     studio::App::iteration(false);
 
        delete dialog_setup;
 
 
        delete dialog_setup;
 
@@ -1358,7 +1454,12 @@ App::~App()
 String
 App::get_user_app_directory()
 {
 String
 App::get_user_app_directory()
 {
+//! \todo do we need locale_from_utf8() on non-Windows boxes too?  (bug #1837445)
+#ifdef WIN32
+       return Glib::locale_from_utf8(Glib::build_filename(Glib::get_home_dir(),SYNFIG_USER_APP_DIR));
+#else
        return Glib::build_filename(Glib::get_home_dir(),SYNFIG_USER_APP_DIR);
        return Glib::build_filename(Glib::get_home_dir(),SYNFIG_USER_APP_DIR);
+#endif
 }
 
 synfig::String
 }
 
 synfig::String
@@ -1367,44 +1468,164 @@ App::get_config_file(const synfig::String& file)
        return Glib::build_filename(get_user_app_directory(),file);
 }
 
        return Glib::build_filename(get_user_app_directory(),file);
 }
 
+#define SCALE_FACTOR   (1280)
+//! set the \a instance's canvas(es) position and size to be those specified in the first entry of recent_files_window_size
+void
+App::set_recent_file_window_size(etl::handle<Instance> instance)
+{
+       int screen_w(Gdk::screen_width());
+       int screen_h(Gdk::screen_height());
+
+       const std::string &canvas_window_size = *recent_files_window_size.begin();
+
+       if(canvas_window_size.empty())
+               return;
+
+       synfig::String::size_type current=0;
+       bool seen_root(false), shown_non_root(false);
+
+       while(current != synfig::String::npos)
+       {
+               // find end of first field (canvas) or return
+               synfig::String::size_type separator = canvas_window_size.find_first_of(' ', current);
+               if(separator == synfig::String::npos) break;
+
+               // find the canvas
+               synfig::Canvas::Handle canvas;
+               try {
+                       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
+                       separator = canvas_window_size.find_first_of('\t', current);
+                       if(separator == synfig::String::npos) return;
+                       current = separator+1;
+                       continue;
+               }
+
+               if (canvas->is_root())
+                       seen_root = true;
+               else
+                       shown_non_root = true;
+
+               // check that we have the tab character the ends this canvas' data or return
+               current = separator+1;
+               separator = canvas_window_size.find_first_of('\t', current);
+               if(separator == synfig::String::npos) return;
+
+               int x,y,w,h;
+               if(!strscanf(String(canvas_window_size, current, separator-current),"%d %d %d %d",&x, &y, &w, &h))
+               {
+                       current = separator+1;
+                       continue;
+               }
+
+               if (x > SCALE_FACTOR) x = SCALE_FACTOR - 150; if (x < 0) x = 0;
+               if (y > SCALE_FACTOR) y = SCALE_FACTOR - 150; if (y < 0) y = 0;
+               x=x*screen_w/SCALE_FACTOR;
+               y=y*screen_h/SCALE_FACTOR;
+               if(getenv("SYNFIG_WINDOW_POSITION_X_OFFSET"))
+                       x += atoi(getenv("SYNFIG_WINDOW_POSITION_X_OFFSET"));
+               if(getenv("SYNFIG_WINDOW_POSITION_Y_OFFSET"))
+                       y += atoi(getenv("SYNFIG_WINDOW_POSITION_Y_OFFSET"));
+
+               if (w > SCALE_FACTOR) w = 150; if (w < 0) w = 0;
+               if (h > SCALE_FACTOR) h = 150; if (h < 0) h = 0;
+
+               CanvasView::Handle canvasview = instance->find_canvas_view(canvas);
+               canvasview->move(x,y);
+               canvasview->resize(w*screen_w/SCALE_FACTOR,h*screen_h/SCALE_FACTOR);
+               canvasview->present();
+
+               current = separator+1;
+       }
+
+       if (shown_non_root && !seen_root)
+               instance->find_canvas_view(instance->get_canvas())->hide();
+}
+
+void
+App::add_recent_file(const etl::handle<Instance> instance)
+{
+       int screen_w(Gdk::screen_width());
+       int screen_h(Gdk::screen_height());
+
+       std::string canvas_window_size;
+
+       const Instance::CanvasViewList& cview_list = instance->canvas_view_list();
+       Instance::CanvasViewList::const_iterator iter;
+
+       for(iter=cview_list.begin();iter!=cview_list.end();iter++)
+       {
+               if( !((*iter)->is_visible()) )
+                       continue;
+
+               etl::handle<synfig::Canvas> canvas = (*iter)->get_canvas();
+               int x_pos, y_pos, x_size, y_size;
+               (*iter)->get_position(x_pos,y_pos);
+               (*iter)->get_size(x_size,y_size);
+
+               canvas_window_size += strprintf("%s %d %d %d %d\t",
+                                                                               canvas->get_relative_id(canvas->get_root()).c_str(),
+                                                                               x_pos*SCALE_FACTOR/screen_w,  y_pos*SCALE_FACTOR/screen_h,
+                                                                               x_size*SCALE_FACTOR/screen_w, y_size*SCALE_FACTOR/screen_h);
+       }
+
+       add_recent_file(absolute_path(instance->get_file_name()), canvas_window_size);
+}
+#undef SCALE_FACTOR
+
 void
 void
-App::add_recent_file(const std::string &file_name)
+App::add_recent_file(const std::string &file_name, const std::string &window_size)
 {
        std::string filename(file_name);
 
        assert(!filename.empty());
 {
        std::string filename(file_name);
 
        assert(!filename.empty());
-       
+
        if(filename.empty())
                return;
        if(filename.empty())
                return;
-       
+
        // Toss out any "hidden" files
        if(basename(filename)[0]=='.')
                return;
        // Toss out any "hidden" files
        if(basename(filename)[0]=='.')
                return;
-               
-       // If we aren't an absolute path, turn outselves into one
+
+       // If we aren't an absolute path, turn ourselves into one
        if(!is_absolute_path(filename))
                filename=absolute_path(filename);
        if(!is_absolute_path(filename))
                filename=absolute_path(filename);
-       
+
+       std::string old_window_size;
+
        list<string>::iterator iter;
        list<string>::iterator iter;
+       list<string>::iterator iter_wsize;
        // Check to see if the file is already on the list.
        // If it is, then remove it from the list
        // Check to see if the file is already on the list.
        // If it is, then remove it from the list
-       for(iter=recent_files.begin();iter!=recent_files.end();iter++)
+       for(iter=recent_files.begin(), iter_wsize=recent_files_window_size.begin();iter!=recent_files.end();iter++, iter_wsize++)
                if(*iter==filename)
                {
                        recent_files.erase(iter);
                if(*iter==filename)
                {
                        recent_files.erase(iter);
+                       old_window_size = *iter_wsize;
+                       recent_files_window_size.erase(iter_wsize);
                        break;
                }
 
                        break;
                }
 
-       
+
        // Push the filename to the front of the list
        recent_files.push_front(filename);
        // Push the filename to the front of the list
        recent_files.push_front(filename);
-               
+       if(window_size.empty())
+               recent_files_window_size.push_front(old_window_size);
+       else
+               recent_files_window_size.push_front(window_size);
+
        // Clean out the files at the end of the list.
        while(recent_files.size()>(unsigned)get_max_recent_files())
        // Clean out the files at the end of the list.
        while(recent_files.size()>(unsigned)get_max_recent_files())
+       {
                recent_files.pop_back();
                recent_files.pop_back();
-       
+               recent_files_window_size.pop_back();
+       }
+
        signal_recent_files_changed_();
        signal_recent_files_changed_();
-       
+
        return;
 }
 
        return;
 }
 
@@ -1439,22 +1660,38 @@ App::save_settings()
                        std::string filename=get_config_file("recentfiles");
 
                        std::ofstream file(filename.c_str());
                        std::string filename=get_config_file("recentfiles");
 
                        std::ofstream file(filename.c_str());
-               
+
                        if(!file)
                        {
                                synfig::warning("Unable to save %s",filename.c_str());
                                break;
                        }
                        if(!file)
                        {
                                synfig::warning("Unable to save %s",filename.c_str());
                                break;
                        }
-               
+
                        list<string>::reverse_iterator iter;
                        list<string>::reverse_iterator iter;
-       
+
                        for(iter=recent_files.rbegin();iter!=recent_files.rend();iter++)
                                file<<*iter<<endl;
                }while(0);
                        for(iter=recent_files.rbegin();iter!=recent_files.rend();iter++)
                                file<<*iter<<endl;
                }while(0);
+               do{
+                       std::string filename=get_config_file("recentfiles")+std::string("_window_size");
+
+                       std::ofstream file(filename.c_str());
 
 
+                       if(!file)
+                       {
+                               synfig::warning("Unable to save %s",filename.c_str());
+                               break;
+                       }
+
+                       list<string>::reverse_iterator iter;
+
+                       for(iter=recent_files_window_size.rbegin();iter!=recent_files_window_size.rend();iter++)
+                               file<<*iter<<endl;
+
+               }while(0);
                std::string filename=get_config_file("settings");
                synfigapp::Main::settings().save_to_file(filename);
                std::string filename=get_config_file("settings");
                synfigapp::Main::settings().save_to_file(filename);
-       setlocale(LC_NUMERIC,old_locale);       
+       setlocale(LC_NUMERIC,old_locale);
        }
        catch(...)
        {
        }
        catch(...)
        {
@@ -1475,41 +1712,57 @@ App::load_settings()
                        Gtk::AccelMap::load(filename);
                }
                {
                        Gtk::AccelMap::load(filename);
                }
                {
+                       bool window_size_broken = false;
+
                        std::string filename=get_config_file("recentfiles");
                        std::string filename=get_config_file("recentfiles");
+                       std::string filename_window_size=filename+std::string("_window_size");
 
                        std::ifstream file(filename.c_str());
 
                        std::ifstream file(filename.c_str());
-       
+                       std::ifstream file_window_size(filename_window_size.c_str());
+
+                       if(!file_window_size)
+                               window_size_broken = true;
+
                        while(file)
                        {
                                std::string recent_file;
                        while(file)
                        {
                                std::string recent_file;
+                               std::string recent_file_window_size;
                                getline(file,recent_file);
                                getline(file,recent_file);
+                               if(!window_size_broken)
+                                       getline(file_window_size,recent_file_window_size);
                                if(!recent_file.empty())
                                if(!recent_file.empty())
-                                       add_recent_file(recent_file);
+                               {
+                                       if(!window_size_broken && !file_window_size)
+                                               window_size_broken = true;
+                                       if (std::ifstream(recent_file.c_str()))
+                                       {
+                                               if(!window_size_broken)
+                                                       add_recent_file(recent_file,recent_file_window_size);
+                                               else
+                                                       add_recent_file(recent_file);
+                                       }
+                               }
+                       }
+                       if(!window_size_broken && file_window_size)
+                               window_size_broken = true;
+
+                       if(window_size_broken)
+                       {
+                               recent_files_window_size.clear();
+                               recent_files_window_size.resize(recent_files.size());
                        }
                }
                std::string filename=get_config_file("settings");
                if(!synfigapp::Main::settings().load_from_file(filename))
                {
                        }
                }
                std::string filename=get_config_file("settings");
                if(!synfigapp::Main::settings().load_from_file(filename))
                {
-                       //std::string filename=Glib::build_filename(Glib::get_home_dir(),".synfigrc");
+                       //std::string filename=Glib::locale_from_utf8(Glib::build_filename(Glib::get_home_dir(),".synfigrc"));
                        //if(!synfigapp::Main::settings().load_from_file(filename))
                        {
                                gamma.set_gamma(1.0/2.2);
                        //if(!synfigapp::Main::settings().load_from_file(filename))
                        {
                                gamma.set_gamma(1.0/2.2);
-                               synfigapp::Main::settings().set_value("dock.dialog.1.comp_selector","1");
-                               synfigapp::Main::settings().set_value("dock.dialog.1.contents","navigator - info pal_edit pal_browse - tool_options history canvases - layers groups");
-                               synfigapp::Main::settings().set_value("dock.dialog.1.contents_size","225 167 207");
-                               synfigapp::Main::settings().set_value("dock.dialog.1.pos","1057 32");
-                               synfigapp::Main::settings().set_value("dock.dialog.1.size","208 1174");
-                               synfigapp::Main::settings().set_value("dock.dialog.2.comp_selector","0");
-                               synfigapp::Main::settings().set_value("dock.dialog.2.contents","params children keyframes | timetrack curves meta_data");
-                               synfigapp::Main::settings().set_value("dock.dialog.2.contents_size","263");
-                               synfigapp::Main::settings().set_value("dock.dialog.2.pos","0 973");
-                               synfigapp::Main::settings().set_value("dock.dialog.2.size","1045 235");
-                               synfigapp::Main::settings().set_value("pref.distance_system","pt");
-                               synfigapp::Main::settings().set_value("pref.use_colorspace_gamma","1");
-                               synfigapp::Main::settings().set_value("window.toolbox.pos","4 4");
+                               reset_initial_window_configuration();
                        }
                }
                        }
                }
-       setlocale(LC_NUMERIC,old_locale);       
+       setlocale(LC_NUMERIC,old_locale);
        }
        catch(...)
        {
        }
        catch(...)
        {
@@ -1517,6 +1770,35 @@ App::load_settings()
        }
 }
 
        }
 }
 
+void
+App::reset_initial_window_configuration()
+{
+       synfigapp::Main::settings().set_value("dock.dialog.1.comp_selector","1");
+       synfigapp::Main::settings().set_value("dock.dialog.1.contents","navigator - info pal_edit pal_browse - tool_options history canvases - layers groups");
+       synfigapp::Main::settings().set_value("dock.dialog.1.contents_size","225 167 207");
+       synfigapp::Main::settings().set_value("dock.dialog.1.pos","1057 32");
+       synfigapp::Main::settings().set_value("dock.dialog.1.size","208 1174");
+       synfigapp::Main::settings().set_value("dock.dialog.2.comp_selector","0");
+       synfigapp::Main::settings().set_value("dock.dialog.2.contents","params children keyframes | timetrack curves meta_data");
+       synfigapp::Main::settings().set_value("dock.dialog.2.contents_size","263");
+       synfigapp::Main::settings().set_value("dock.dialog.2.pos","0 973");
+       synfigapp::Main::settings().set_value("dock.dialog.2.size","1045 235");
+       synfigapp::Main::settings().set_value("pref.distance_system","pt");
+       synfigapp::Main::settings().set_value("pref.use_colorspace_gamma","1");
+#ifdef SINGLE_THREADED
+       synfigapp::Main::settings().set_value("pref.single_threaded","0");
+#endif
+       synfigapp::Main::settings().set_value("pref.restrict_radius_ducks","0");
+       synfigapp::Main::settings().set_value("pref.resize_imported_images","0");
+       synfigapp::Main::settings().set_value("pref.custom_filename_prefix",DEFAULT_FILENAME_PREFIX);
+       synfigapp::Main::settings().set_value("pref.preferred_x_size","480");
+       synfigapp::Main::settings().set_value("pref.preferred_y_size","270");
+       synfigapp::Main::settings().set_value("pref.predefined_size",DEFAULT_PREDEFINED_SIZE);
+       synfigapp::Main::settings().set_value("pref.preferred_fps","24.0");
+       synfigapp::Main::settings().set_value("pref.predefined_fps",DEFAULT_PREDEFINED_FPS);
+       synfigapp::Main::settings().set_value("window.toolbox.pos","4 4");
+}
+
 bool
 App::shutdown_request(GdkEventAny*)
 {
 bool
 App::shutdown_request(GdkEventAny*)
 {
@@ -1529,12 +1811,12 @@ void
 App::quit()
 {
        if(shutdown_in_progress)return;
 App::quit()
 {
        if(shutdown_in_progress)return;
-               
-       
-       get_ui_interface()->task("Quit Request");
+
+
+       get_ui_interface()->task(_("Quit Request"));
        if(Busy::count)
        {
        if(Busy::count)
        {
-               dialog_error_blocking("Cannot quit!","Tasks are currently running.\nPlease cancel the current tasks and try again");
+               dialog_error_blocking(_("Cannot quit!"),_("Tasks are currently running.\nPlease cancel the current tasks and try again"));
                return;
        }
 
                return;
        }
 
@@ -1587,22 +1869,22 @@ App::quit()
                                        return;
                        }
                }
                                        return;
                        }
                }
-*/             
-               
+*/
+
                // This next line causes things to crash for some reason
                // This next line causes things to crash for some reason
-               //(*iter)->close(); 
+               //(*iter)->close();
        }
        }
-       
+
        shutdown_in_progress=true;
 
        instance_list.clear();
 
        while(studio::App::events_pending())studio::App::iteration(false);
        shutdown_in_progress=true;
 
        instance_list.clear();
 
        while(studio::App::events_pending())studio::App::iteration(false);
-               
+
        Gtk::Main::quit();
        auto_recover->normal_shutdown();
 
        Gtk::Main::quit();
        auto_recover->normal_shutdown();
 
-       get_ui_interface()->task("Quit Request sent");
+       get_ui_interface()->task(_("Quit Request sent"));
 }
 
 void
 }
 
 void
@@ -1612,8 +1894,8 @@ App::show_setup()
        dialog_setup->show();
 }
 
        dialog_setup->show();
 }
 
-gint Signal_Open_Ok(GtkWidget *widget, int *val){*val=1;return 0;}
-gint Signal_Open_Cancel(GtkWidget *widget, int *val){*val=2;return 0;}
+gint Signal_Open_Ok(GtkWidget */*widget*/, int *val){*val=1;return 0;}
+gint Signal_Open_Cancel(GtkWidget */*widget*/, int *val){*val=2;return 0;}
 
 //#ifdef WIN32
 //#define USE_WIN32_FILE_DIALOGS 1
 
 //#ifdef WIN32
 //#define USE_WIN32_FILE_DIALOGS 1
@@ -1626,17 +1908,19 @@ static OPENFILENAME ofn={};
 #ifdef WIN32
 #include <gdk/gdkwin32.h>
 #endif
 #ifdef WIN32
 #include <gdk/gdkwin32.h>
 #endif
-       
+
 bool
 bool
-App::dialog_open_file(const std::string &title, std::string &filename)
+App::dialog_open_file(const std::string &title, std::string &filename, std::string preference)
 {
 {
+       // info("App::dialog_open_file('%s', '%s', '%s')", title.c_str(), filename.c_str(), preference.c_str());
+
 #ifdef USE_WIN32_FILE_DIALOGS
        static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
 
        GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
        HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
        HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
 #ifdef USE_WIN32_FILE_DIALOGS
        static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
 
        GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
        HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
        HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
-       
+
        ofn.lStructSize=sizeof(OPENFILENAME);
        ofn.hwndOwner = hWnd;
        ofn.hInstance = hInstance;
        ofn.lStructSize=sizeof(OPENFILENAME);
        ofn.hwndOwner = hWnd;
        ofn.hInstance = hInstance;
@@ -1656,53 +1940,67 @@ App::dialog_open_file(const std::string &title, std::string &filename)
 //     ofn.lCustData = 0l;
        ofn.lpfnHook=NULL;
 //     ofn.lpTemplateName=NULL;
 //     ofn.lCustData = 0l;
        ofn.lpfnHook=NULL;
 //     ofn.lpTemplateName=NULL;
-       
+
        CHAR szFilename[MAX_PATH];
        CHAR szTitle[500];
        strcpy(szFilename,filename.c_str());
        strcpy(szTitle,title.c_str());
        CHAR szFilename[MAX_PATH];
        CHAR szTitle[500];
        strcpy(szFilename,filename.c_str());
        strcpy(szTitle,title.c_str());
-       
+
        ofn.lpstrFile=szFilename;
        ofn.lpstrFileTitle=szTitle;
        ofn.lpstrFile=szFilename;
        ofn.lpstrFileTitle=szTitle;
-       
+
        if(GetOpenFileName(&ofn))
        {
                filename=szFilename;
                return true;
        }
        return false;
        if(GetOpenFileName(&ofn))
        {
                filename=szFilename;
                return true;
        }
        return false;
-       
+
 #else
        synfig::String prev_path;
 #else
        synfig::String prev_path;
-       if(!_preferences.get_value("curr_path",prev_path))
-               prev_path=".";
-       
-    Gtk::FileChooserDialog *dialog=new Gtk::FileChooserDialog(title,Gtk::FILE_CHOOSER_ACTION_OPEN);
+
+       if(!_preferences.get_value(preference, prev_path))
+               prev_path = ".";
+
+       prev_path = absolute_path(prev_path);
+
+    Gtk::FileChooserDialog *dialog = new Gtk::FileChooserDialog(title, Gtk::FILE_CHOOSER_ACTION_OPEN);
+
     dialog->set_current_folder(prev_path);
     dialog->set_current_folder(prev_path);
-    dialog->add_button(Gtk::StockID("gtk-ok"),GTK_RESPONSE_ACCEPT);
-    dialog->add_button(Gtk::StockID("gtk-cancel"),GTK_RESPONSE_CANCEL);
-    if(!filename.empty())
-        dialog->set_filename(filename);
-    if(dialog->run()==GTK_RESPONSE_ACCEPT) {
-        filename=dialog->get_filename();
+    dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+    dialog->add_button(Gtk::Stock::OPEN,   Gtk::RESPONSE_ACCEPT);
+
+    if (filename.empty())
+               dialog->set_filename(prev_path);
+       else if (is_absolute_path(filename))
+               dialog->set_filename(filename);
+       else
+               dialog->set_filename(prev_path + ETL_DIRECTORY_SEPARATOR + filename);
+
+    if(dialog->run() == GTK_RESPONSE_ACCEPT) {
+        filename = dialog->get_filename();
+               // info("Saving preference %s = '%s' in App::dialog_open_file()", preference.c_str(), dirname(filename).c_str());
+               _preferences.set_value(preference, dirname(filename));
         delete dialog;
         return true;
     }
         delete dialog;
         return true;
     }
+
     delete dialog;
     return false;
     delete dialog;
     return false;
+
     /*
     /*
-    
+
        GtkWidget *ok;
        GtkWidget *cancel;
        int val=0;
        GtkWidget *ok;
        GtkWidget *cancel;
        int val=0;
-       
+
        GtkWidget *fileselection;
        fileselection = gtk_file_selection_new(title.c_str());
 
        GtkWidget *fileselection;
        fileselection = gtk_file_selection_new(title.c_str());
 
-       
+
        if(basename(filename)==filename)
        {
        if(basename(filename)==filename)
        {
-               gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),(prev_path+ETL_DIRECTORY_SEPERATOR).c_str());         
+               gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),(prev_path+ETL_DIRECTORY_SEPARATOR).c_str());
        }
        else
                gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),dirname(filename).c_str());
        }
        else
                gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),dirname(filename).c_str());
@@ -1712,19 +2010,19 @@ App::dialog_open_file(const std::string &title, std::string &filename)
        ok=GTK_FILE_SELECTION(fileselection)->ok_button;
        cancel=GTK_FILE_SELECTION(fileselection)->cancel_button;
 
        ok=GTK_FILE_SELECTION(fileselection)->ok_button;
        cancel=GTK_FILE_SELECTION(fileselection)->cancel_button;
 
-       gtk_signal_connect(GTK_OBJECT(ok),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Ok),&val);              
-       gtk_signal_connect(GTK_OBJECT(cancel),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Cancel),&val);              
+       gtk_signal_connect(GTK_OBJECT(ok),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Ok),&val);
+       gtk_signal_connect(GTK_OBJECT(cancel),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Cancel),&val);
 
        gtk_widget_show(fileselection);
 
        while(!val)
 
        gtk_widget_show(fileselection);
 
        while(!val)
-               iteration();            
-       
-       
+               iteration();
+
+
        if(val==1)
        {
                filename=gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection));
        if(val==1)
        {
                filename=gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection));
-               _preferences.set_value("curr_path",dirname(filename));
+               _preferences.set_value(preference,dirname(filename));
        }
        else
        {
        }
        else
        {
@@ -1738,15 +2036,17 @@ App::dialog_open_file(const std::string &title, std::string &filename)
 }
 
 bool
 }
 
 bool
-App::dialog_save_file(const std::string &title, std::string &filename)
+App::dialog_save_file(const std::string &title, std::string &filename, std::string preference)
 {
 {
-#ifdef USE_WIN32_FILE_DIALOGS
+       // info("App::dialog_save_file('%s', '%s', '%s')", title.c_str(), filename.c_str(), preference.c_str());
+
+#if USE_WIN32_FILE_DIALOGS
        static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
        static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
-       
+
        GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
        HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
        HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
        GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
        HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
        HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
-       
+
        ofn.lStructSize=sizeof(OPENFILENAME);
        ofn.hwndOwner = hWnd;
        ofn.hInstance = hInstance;
        ofn.lStructSize=sizeof(OPENFILENAME);
        ofn.hwndOwner = hWnd;
        ofn.hInstance = hInstance;
@@ -1766,122 +2066,94 @@ App::dialog_save_file(const std::string &title, std::string &filename)
 //     ofn.lCustData = 0l;
        ofn.lpfnHook=NULL;
 //     ofn.lpTemplateName=NULL;
 //     ofn.lCustData = 0l;
        ofn.lpfnHook=NULL;
 //     ofn.lpTemplateName=NULL;
-       
+
        CHAR szFilename[MAX_PATH];
        CHAR szTitle[500];
        strcpy(szFilename,filename.c_str());
        strcpy(szTitle,title.c_str());
        CHAR szFilename[MAX_PATH];
        CHAR szTitle[500];
        strcpy(szFilename,filename.c_str());
        strcpy(szTitle,title.c_str());
-       
+
        ofn.lpstrFile=szFilename;
        ofn.lpstrFileTitle=szTitle;
        ofn.lpstrFile=szFilename;
        ofn.lpstrFileTitle=szTitle;
-       
+
        if(GetSaveFileName(&ofn))
        {
                filename=szFilename;
        if(GetSaveFileName(&ofn))
        {
                filename=szFilename;
+               _preferences.set_value(preference,dirname(filename));
                return true;
        }
        return false;
 #else
        synfig::String prev_path;
                return true;
        }
        return false;
 #else
        synfig::String prev_path;
-       if(!_preferences.get_value("curr_path",prev_path))
+
+       if(!_preferences.get_value(preference, prev_path))
                prev_path=".";
                prev_path=".";
-       
-    Gtk::FileChooserDialog *dialog=new Gtk::FileChooserDialog(title,Gtk::FILE_CHOOSER_ACTION_SAVE);
+
+       prev_path = absolute_path(prev_path);
+
+    Gtk::FileChooserDialog *dialog = new Gtk::FileChooserDialog(title, Gtk::FILE_CHOOSER_ACTION_SAVE);
+
     dialog->set_current_folder(prev_path);
     dialog->set_current_folder(prev_path);
-    dialog->add_button(Gtk::StockID("gtk-ok"),GTK_RESPONSE_ACCEPT);
-    dialog->add_button(Gtk::StockID("gtk-cancel"),GTK_RESPONSE_CANCEL);
-    if(!filename.empty())
-        dialog->set_filename(filename);
-    if(dialog->run()==GTK_RESPONSE_ACCEPT) {
-        filename=dialog->get_filename();
-        delete dialog;
-        return true;
-    }
-    delete dialog;
-    return false;
-//     return dialog_open_file(title, filename);
-#endif
-}
+    dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+    dialog->add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_ACCEPT);
 
 
-bool
-App::dialog_saveas_file(const std::string &title, std::string &filename)
-{
-#if USE_WIN32_FILE_DIALOGS
-       static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
-       
-       GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
-       HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
-       HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
-       
-       ofn.lStructSize=sizeof(OPENFILENAME);
-       ofn.hwndOwner = hWnd;
-       ofn.hInstance = hInstance;
-       ofn.lpstrFilter = szFilter;
-//     ofn.lpstrCustomFilter=NULL;
-//     ofn.nMaxCustFilter=0;
-//     ofn.nFilterIndex=0;
-//     ofn.lpstrFile=NULL;
-       ofn.nMaxFile=MAX_PATH;
-//     ofn.lpstrFileTitle=NULL;
-//     ofn.lpstrInitialDir=NULL;
-//     ofn.lpstrTitle=NULL;
-       ofn.Flags=OFN_OVERWRITEPROMPT;
-//     ofn.nFileOffset=0;
-//     ofn.nFileExtension=0;
-       ofn.lpstrDefExt=TEXT("sif");
-//     ofn.lCustData = 0l;
-       ofn.lpfnHook=NULL;
-//     ofn.lpTemplateName=NULL;
-       
-       CHAR szFilename[MAX_PATH];
-       CHAR szTitle[500];
-       strcpy(szFilename,filename.c_str());
-       strcpy(szTitle,title.c_str());
-       
-       ofn.lpstrFile=szFilename;
-       ofn.lpstrFileTitle=szTitle;
-       
-       if(GetSaveFileName(&ofn))
+       Widget_Enum *file_type_enum = 0;
+       if (preference == ANIMATION_DIR_PREFERENCE)
        {
        {
-               filename=szFilename;
-               return true;
+               file_type_enum = manage(new Widget_Enum());
+               file_type_enum->set_param_desc(ParamDesc().set_hint("enum")
+                                                                          .add_enum_value(synfig::RELEASE_VERSION_0_61_09, "0.61.09", strprintf("0.61.09 (%s)", _("current")))
+                                                                          .add_enum_value(synfig::RELEASE_VERSION_0_61_08, "0.61.08", "0.61.08")
+                                                                          .add_enum_value(synfig::RELEASE_VERSION_0_61_07, "0.61.07", "0.61.07")
+                                                                          .add_enum_value(synfig::RELEASE_VERSION_0_61_06, "0.61.06", strprintf("0.61.06 %s", _("and older"))));
+               file_type_enum->set_value(RELEASE_VERSION_END-1); // default to the most recent version
+
+               Gtk::HBox *hbox = manage(new Gtk::HBox);
+               hbox->pack_start(*manage(new Gtk::Label(_("File Format Version: "))),Gtk::PACK_SHRINK,0);
+               hbox->pack_start(*file_type_enum,Gtk::PACK_EXPAND_WIDGET,0);
+               hbox->show_all();
+
+               dialog->set_extra_widget(*hbox);
        }
        }
-       return false;
-#else
-       synfig::String prev_path;
-       if(!_preferences.get_value("curr_path",prev_path))
-               prev_path=".";
-       
-    Gtk::FileChooserDialog *dialog=new Gtk::FileChooserDialog(title,Gtk::FILE_CHOOSER_ACTION_SAVE);
-    dialog->set_current_folder(prev_path);
-    dialog->add_button(Gtk::StockID("gtk-ok"),GTK_RESPONSE_ACCEPT);
-    dialog->add_button(Gtk::StockID("gtk-cancel"),GTK_RESPONSE_CANCEL);
-    if(!filename.empty())
-        dialog->set_filename(filename);
-    if(dialog->run()==GTK_RESPONSE_ACCEPT) {
-        filename=dialog->get_filename();
+
+    if (filename.empty())
+               dialog->set_filename(prev_path);
+    else
+       {
+               std::string full_path;
+               if (is_absolute_path(filename))
+                       full_path = filename;
+               else
+                       full_path = prev_path + ETL_DIRECTORY_SEPARATOR + filename;
+
+               // select the file if it exists
+               dialog->set_filename(full_path);
+
+               // if the file doesn't exist, put its name into the filename box
+               struct stat s;
+               if(stat(full_path.c_str(),&s) == -1 && errno == ENOENT)
+                       dialog->set_current_name(basename(filename));
+       }
+
+    if(dialog->run() == GTK_RESPONSE_ACCEPT) {
+               if (preference == ANIMATION_DIR_PREFERENCE)
+                       set_file_version(synfig::ReleaseVersion(file_type_enum->get_value()));
+        filename = dialog->get_filename();
+               // info("Saving preference %s = '%s' in App::dialog_save_file()", preference.c_str(), dirname(filename).c_str());
+               _preferences.set_value(preference, dirname(filename));
         delete dialog;
         return true;
     }
         delete dialog;
         return true;
     }
+
     delete dialog;
     return false;
     delete dialog;
     return false;
-//     return dialog_open_file(title, filename);
 #endif
 }
 
 void
 App::dialog_error_blocking(const std::string &title, const std::string &message)
 {
 #endif
 }
 
 void
 App::dialog_error_blocking(const std::string &title, const std::string &message)
 {
-       Gtk::Dialog dialog(
-               title,          // Title
-               true,           // Modal
-               true            // use_separator
-       );
-       Gtk::Label label(message);
-       label.show();
-       
-       dialog.get_vbox()->pack_start(label);
-       dialog.add_button(Gtk::StockID("gtk-ok"),1);
+       Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
+       dialog.set_title(title);
        dialog.show();
        dialog.run();
 }
        dialog.show();
        dialog.run();
 }
@@ -1889,16 +2161,8 @@ App::dialog_error_blocking(const std::string &title, const std::string &message)
 void
 App::dialog_warning_blocking(const std::string &title, const std::string &message)
 {
 void
 App::dialog_warning_blocking(const std::string &title, const std::string &message)
 {
-       Gtk::Dialog dialog(
-               title,          // Title
-               true,           // Modal
-               true            // use_separator
-       );
-       Gtk::Label label(message);
-       label.show();
-
-       dialog.get_vbox()->pack_start(label);
-       dialog.add_button(Gtk::StockID("gtk-ok"),1);
+       Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true);
+       dialog.set_title(title);
        dialog.show();
        dialog.run();
 }
        dialog.show();
        dialog.run();
 }
@@ -1913,7 +2177,7 @@ App::dialog_yes_no(const std::string &title, const std::string &message)
        );
        Gtk::Label label(message);
        label.show();
        );
        Gtk::Label label(message);
        label.show();
-       
+
        dialog.get_vbox()->pack_start(label);
        dialog.add_button(Gtk::StockID("gtk-yes"),1);
        dialog.add_button(Gtk::StockID("gtk-no"),0);
        dialog.get_vbox()->pack_start(label);
        dialog.add_button(Gtk::StockID("gtk-yes"),1);
        dialog.add_button(Gtk::StockID("gtk-no"),0);
@@ -1943,9 +2207,109 @@ App::dialog_yes_no_cancel(const std::string &title, const std::string &message)
 void
 App::dialog_not_implemented()
 {
 void
 App::dialog_not_implemented()
 {
-       Gtk::MessageDialog dialog("Feature not available", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
-       dialog.set_secondary_text("Sorry, this feature has not yet been implemented.");
-       dialog.run(); 
+       Gtk::MessageDialog dialog(_("Feature not available"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
+       dialog.set_secondary_text(_("Sorry, this feature has not yet been implemented."));
+       dialog.run();
+}
+
+static bool
+try_open_url(const std::string &url)
+{
+#ifdef WIN32
+       return ShellExecute(GetDesktopWindow(), "open", url.c_str(), NULL, NULL, SW_SHOW);
+#else // !WIN32
+       std::vector<std::string> command_line;
+       std::vector<std::string> browsers;
+       browsers.reserve(23);
+
+       // Browser wrapper scripts
+#ifdef USE_OPEN_FOR_URLS
+       browsers.push_back("open");              // Apple MacOS X wrapper, on Linux it opens a virtual console
+#endif
+       browsers.push_back("xdg-open");          // XDG wrapper
+       browsers.push_back("sensible-browser");  // Debian wrapper
+       browsers.push_back("gnome-open");        // GNOME wrapper
+       browsers.push_back("kfmclient");         // KDE wrapper
+       browsers.push_back("exo-open");          // XFCE wrapper
+
+       // Alternatives system
+       browsers.push_back("gnome-www-browser"); // Debian GNOME alternative
+       browsers.push_back("x-www-browser");     // Debian GUI alternative
+
+       // Individual browsers
+       browsers.push_back("firefox");
+       browsers.push_back("epiphany-browser");
+       browsers.push_back("epiphany");
+       browsers.push_back("konqueror");
+       browsers.push_back("iceweasel");
+       browsers.push_back("mozilla");
+       browsers.push_back("netscape");
+       browsers.push_back("icecat");
+       browsers.push_back("galeon");
+       browsers.push_back("midori");
+       browsers.push_back("safari");
+       browsers.push_back("opera");
+       browsers.push_back("amaya");
+       browsers.push_back("netsurf");
+       browsers.push_back("dillo");
+
+       // Try the user-specified browser first
+       command_line.push_back(App::browser_command);
+       if( command_line[0] == "kfmclient" ) command_line.push_back("openURL");
+       command_line.push_back(url);
+
+       try { Glib::spawn_async(".", command_line, Glib::SPAWN_SEARCH_PATH); return true; }
+       catch( Glib::SpawnError& exception ){
+
+               while ( !browsers.empty() )
+               {
+                       // Skip the browser if we already tried it
+                       if( browsers[0] == App::browser_command )
+                               continue;
+
+                       // Construct the command line
+                       command_line.clear();
+                       command_line.push_back(browsers[0]);
+                       if( command_line[0] == "kfmclient" ) command_line.push_back("openURL");
+                       command_line.push_back(url);
+
+                       // Remove the browser from the list
+                       browsers.erase(browsers.begin());
+
+                       // Try to spawn the browser
+                       try { Glib::spawn_async(".", command_line, Glib::SPAWN_SEARCH_PATH); }
+                       // Failed, move on to the next one
+                       catch(Glib::SpawnError& exception){ continue; }
+                       return true; // No exception means we succeeded!
+               }
+       }
+
+       return false;
+#endif // !WIN32
+}
+
+void
+App::dialog_help()
+{
+       if (!try_open_url("http://synfig.org/Documentation"))
+       {
+               Gtk::MessageDialog dialog(_("Documentation"), false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, true);
+               dialog.set_secondary_text(_("Documentation for Synfig Studio is available on the website:\n\nhttp://www.synfig.org/Documentation"));
+               dialog.set_title(_("Help"));
+               dialog.run();
+       }
+}
+
+void
+App::open_url(const std::string &url)
+{
+       if(!try_open_url(url))
+       {
+               Gtk::MessageDialog dialog(_("No browser was found. Please load this website manually:"), false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
+               dialog.set_secondary_text(url);
+               dialog.set_title(_("No browser found"));
+               dialog.run();
+       }
 }
 
 bool
 }
 
 bool
@@ -1954,8 +2318,8 @@ App::dialog_entry(const std::string &title, const std::string &message,std::stri
        Gtk::Dialog dialog(
                title,          // Title
                true,           // Modal
        Gtk::Dialog dialog(
                title,          // Title
                true,           // Modal
-               true            // use_separator
-       );
+               true);          // use_separator
+
        Gtk::Label label(message);
        label.show();
        dialog.get_vbox()->pack_start(label);
        Gtk::Label label(message);
        label.show();
        dialog.get_vbox()->pack_start(label);
@@ -1964,11 +2328,13 @@ App::dialog_entry(const std::string &title, const std::string &message,std::stri
        entry.set_text(text);
        entry.show();
        entry.set_activates_default(true);
        entry.set_text(text);
        entry.show();
        entry.set_activates_default(true);
+
        dialog.get_vbox()->pack_start(entry);
 
        dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK);
        dialog.add_button(Gtk::StockID("gtk-cancel"),Gtk::RESPONSE_CANCEL);
        dialog.set_default_response(Gtk::RESPONSE_OK);
        dialog.get_vbox()->pack_start(entry);
 
        dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK);
        dialog.add_button(Gtk::StockID("gtk-cancel"),Gtk::RESPONSE_CANCEL);
        dialog.set_default_response(Gtk::RESPONSE_OK);
+
        entry.signal_activate().connect(sigc::bind(sigc::mem_fun(dialog,&Gtk::Dialog::response),Gtk::RESPONSE_OK));
        dialog.show();
 
        entry.signal_activate().connect(sigc::bind(sigc::mem_fun(dialog,&Gtk::Dialog::response),Gtk::RESPONSE_OK));
        dialog.show();
 
@@ -1980,8 +2346,39 @@ App::dialog_entry(const std::string &title, const std::string &message,std::stri
        return true;
 }
 
        return true;
 }
 
+bool
+App::dialog_paragraph(const std::string &title, const std::string &message,std::string &text)
+{
+       Gtk::Dialog dialog(
+               title,          // Title
+               true,           // Modal
+               true);          // use_separator
+
+       Gtk::Label label(message);
+       label.show();
+       dialog.get_vbox()->pack_start(label);
+
+       Glib::RefPtr<Gtk::TextBuffer> text_buffer(Gtk::TextBuffer::create());
+       text_buffer->set_text(text);
+       Gtk::TextView text_view(text_buffer);
+       text_view.show();
+
+       dialog.get_vbox()->pack_start(text_view);
+
+       dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK);
+       dialog.add_button(Gtk::StockID("gtk-cancel"),Gtk::RESPONSE_CANCEL);
+       dialog.set_default_response(Gtk::RESPONSE_OK);
+
+       //text_entry.signal_activate().connect(sigc::bind(sigc::mem_fun(dialog,&Gtk::Dialog::response),Gtk::RESPONSE_OK));
+       dialog.show();
+
+       if(dialog.run()!=Gtk::RESPONSE_OK)
+               return false;
 
 
+       text=text_buffer->get_text();
 
 
+       return true;
+}
 
 bool
 App::open(std::string filename)
 
 bool
 App::open(std::string filename)
@@ -1989,53 +2386,73 @@ App::open(std::string filename)
        return open_as(filename,filename);
 }
 
        return open_as(filename,filename);
 }
 
+// this is called from autorecover.cpp:
+//   App::open_as(get_shadow_file_name(filename),filename)
+// other than that, 'filename' and 'as' are the same
 bool
 App::open_as(std::string filename,std::string as)
 {
 #ifdef WIN32
     char long_name[1024];
     if(GetLongPathName(as.c_str(),long_name,sizeof(long_name)));
 bool
 App::open_as(std::string filename,std::string as)
 {
 #ifdef WIN32
     char long_name[1024];
     if(GetLongPathName(as.c_str(),long_name,sizeof(long_name)));
-    as=long_name;
+       // when called from autorecover.cpp, filename doesn't exist, and so long_name is empty
+       // don't use it if that's the case
+       if (long_name[0] != '\0')
+               as=long_name;
 #endif
 
        try
        {
                OneMoment one_moment;
 #endif
 
        try
        {
                OneMoment one_moment;
-       
-               etl::handle<synfig::Canvas> canvas(open_canvas_as(filename,as));
+               String errors, warnings;
+
+               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 && get_instance(canvas))
                {
                        get_instance(canvas)->find_canvas_view(canvas)->present();
-                       throw (String)strprintf(_("\"%s\" appears to already be open!"),filename.c_str());              
+                       info("%s is already open", filename.c_str());
+                       // throw (String)strprintf(_("\"%s\" appears to already be open!"),filename.c_str());
+               }
+               else
+               {
+                       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);
+
+                       handle<Instance> instance(Instance::create(canvas));
+
+                       if(!instance)
+                               throw (String)strprintf(_("Unable to create instance for \"%s\""),filename.c_str());
+
+                       set_recent_file_window_size(instance);
+
+                       one_moment.hide();
+
+                       if(instance->is_updated() && App::dialog_yes_no(_("CVS Update"), _("There appears to be a newer version of this file available on the CVS repository.\nWould you like to update now? (It would probably be a good idea)")))
+                               instance->dialog_cvs_update();
                }
                }
-               if(!canvas)
-                       throw (String)strprintf(_("Unable to open file \"%s\""),filename.c_str());
-
-               add_recent_file(as);
-               
-               handle<Instance> instance(Instance::create(canvas));
-
-               if(!instance)
-                       throw (String)strprintf(_("Unable to create instance for \"%s\""),filename.c_str());
-               
-               one_moment.hide();
-               
-               if(instance->is_updated() && App::dialog_yes_no(_("CVS Update"), _("There appears to be a newer version of this file available on the CVS repository.\nWould you like to update now? (It would probably be a good idea)")))
-                       instance->dialog_cvs_update();
        }
        catch(String x)
        {
                dialog_error_blocking(_("Error"), x);
                return false;
        }
        }
        catch(String x)
        {
                dialog_error_blocking(_("Error"), x);
                return false;
        }
+       catch(runtime_error x)
+       {
+               dialog_error_blocking(_("Error"), x.what());
+               return false;
+       }
        catch(...)
        {
                dialog_error_blocking(_("Error"), _("Uncaught error on file open (BUG)"));
                return false;
        }
 
        catch(...)
        {
                dialog_error_blocking(_("Error"), _("Uncaught error on file open (BUG)"));
                return false;
        }
 
-       _preferences.set_value("curr_path",dirname(as));
-       
        return true;
 }
 
        return true;
 }
 
@@ -2044,32 +2461,39 @@ void
 App::new_instance()
 {
        handle<synfig::Canvas> canvas=synfig::Canvas::create();
 App::new_instance()
 {
        handle<synfig::Canvas> canvas=synfig::Canvas::create();
-       canvas->set_name(strprintf("Untitled%d",Instance::get_count()));
 
 
-       String file_name(strprintf("untitled%d.sif",Instance::get_count()));
-       
-       canvas->rend_desc().set_frame_rate(24.0);
+       String file_name(strprintf("%s%d", App::custom_filename_prefix.c_str(), Instance::get_count()+1));
+       canvas->set_name(file_name);
+       file_name += ".sifz";
+
+       canvas->rend_desc().set_frame_rate(preferred_fps);
        canvas->rend_desc().set_time_start(0.0);
        canvas->rend_desc().set_time_start(0.0);
-       canvas->rend_desc().set_time_end(00.0);
+       canvas->rend_desc().set_time_end(5.0);
        canvas->rend_desc().set_x_res(DPI2DPM(72.0f));
        canvas->rend_desc().set_y_res(DPI2DPM(72.0f));
        canvas->rend_desc().set_x_res(DPI2DPM(72.0f));
        canvas->rend_desc().set_y_res(DPI2DPM(72.0f));
-       canvas->rend_desc().set_tl(Vector(-4,2.25));
-       canvas->rend_desc().set_br(Vector(4,-2.25));
-       canvas->rend_desc().set_w(480);
-       canvas->rend_desc().set_h(270);
+       // The top left and botton right positions are expressed in units
+       // Original convention is that 1 unit = 60 pixels
+       canvas->rend_desc().set_tl(Vector(-(preferred_x_size/60.0)/2.0,(preferred_y_size/60.0)/2.0));
+       canvas->rend_desc().set_br(Vector((preferred_x_size/60.0)/2.0,-(preferred_y_size/60.0)/2.0));
+       canvas->rend_desc().set_w(preferred_x_size);
+       canvas->rend_desc().set_h(preferred_y_size);
        canvas->rend_desc().set_antialias(1);
        canvas->rend_desc().set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
        canvas->set_file_name(file_name);
        canvas->rend_desc().set_antialias(1);
        canvas->rend_desc().set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
        canvas->set_file_name(file_name);
-       
-       Instance::create(canvas)->find_canvas_view(canvas)->canvas_properties.present();
+
+       handle<Instance> instance = Instance::create(canvas);
+
+       if (getenv("SYNFIG_ENABLE_NEW_CANVAS_EDIT_PROPERTIES"))
+               instance->find_canvas_view(canvas)->canvas_properties.present();
 }
 
 void
 }
 
 void
-App::dialog_open()
+App::dialog_open(string filename)
 {
 {
-       string filename="*.sif";
+       if (filename.empty())
+               filename="*.sif";
 
 
-       while(dialog_open_file("Open", filename))
+       while(dialog_open_file("Open", filename, ANIMATION_DIR_PREFERENCE))
        {
                // If the filename still has wildcards, then we should
                // continue looking for the file we want
        {
                // If the filename still has wildcards, then we should
                // continue looking for the file we want
@@ -2133,7 +2557,7 @@ App::set_selected_canvas_view(etl::loose_handle<CanvasView> canvas_view)
 }
 
 etl::loose_handle<Instance>
 }
 
 etl::loose_handle<Instance>
-App::get_instance(Canvas::Handle canvas)
+App::get_instance(etl::handle<synfig::Canvas> canvas)
 {
        if(!canvas) return 0;
        canvas=canvas->get_root();
 {
        if(!canvas) return 0;
        canvas=canvas->get_root();
@@ -2150,7 +2574,8 @@ App::get_instance(Canvas::Handle canvas)
 void
 App::dialog_about()
 {
 void
 App::dialog_about()
 {
-       (new class About())->show();
+       if(about)
+               about->show();
 }
 
 void
 }
 
 void