Merge branch 'master' into nikitakit_restructure
authorNikita Kitaev <nikitakit@gmail.com>
Mon, 31 May 2010 04:18:19 +0000 (21:18 -0700)
committerNikita Kitaev <nikitakit@gmail.com>
Mon, 31 May 2010 04:18:19 +0000 (21:18 -0700)
17 files changed:
1  2 
synfig-studio/configure.ac
synfig-studio/src/gui/app.cpp
synfig-studio/src/gui/app.h
synfig-studio/src/gui/asyncrenderer.cpp
synfig-studio/src/gui/dialogs/about.cpp
synfig-studio/src/gui/dialogs/dialog_targetparam.cpp
synfig-studio/src/gui/dialogs/dialog_targetparam.h
synfig-studio/src/gui/docks/dockmanager.cpp
synfig-studio/src/gui/docks/dockmanager.h
synfig-studio/src/gui/duck.cpp
synfig-studio/src/gui/iconcontroller.cpp
synfig-studio/src/gui/render.cpp
synfig-studio/src/gui/render.h
synfig-studio/src/gui/splash.cpp
synfig-studio/src/gui/states/state_mirror.cpp
synfig-studio/src/gui/states/state_normal.cpp
synfig-studio/src/gui/toolbox.cpp

Simple merge
index c1a8ba3,0000000..b50b120
mode 100644,000000..100644
--- /dev/null
@@@ -1,2514 -1,0 +1,2585 @@@
-               if(!getenv("SYNFIG_DISABLE_WIDTH"  )) state_manager->add_state(&state_width); // Enabled since 0.61.09
 +/* === S Y N F I G ========================================================= */
 +/*!   \file app.cpp
 +**    \brief writeme
 +**
 +**    $Id$
 +**
 +**    \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
 +**    Copyright (c) 2009 Nikita Kitaev
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#ifdef WIN32
 +#define WINVER 0x0500
 +#include <windows.h>
 +#endif
 +
 +#include <fstream>
 +#include <iostream>
 +#include <locale>
 +#include <cstring>
 +
 +#ifdef HAVE_SYS_ERRNO_H
 +#include <sys/errno.h>
 +#endif
 +#include <gtkmm/fileselection.h>
 +#include <gtkmm/dialog.h>
 +#include <gtkmm/messagedialog.h>
 +#include <gtkmm/label.h>
 +#include <gtkmm/stock.h>
 +#include <gtkmm/stockitem.h>
 +#include <gtkmm/iconsource.h>
 +#include <gtkmm/inputdialog.h>
 +#include <gtkmm/accelmap.h>
 +#include <gtkmm/uimanager.h>
 +#include <gtkmm/textview.h>
 +
 +#include <gtk/gtk.h>
 +
 +#include <gdkmm/general.h>
 +
 +#include <synfig/loadcanvas.h>
 +#include <synfig/savecanvas.h>
 +
 +#include "app.h"
 +#include "dialogs/about.h"
 +#include "splash.h"
 +#include "instance.h"
 +#include "canvasview.h"
 +#include "dialogs/dialog_setup.h"
 +#include "dialogs/dialog_gradient.h"
 +#include "dialogs/dialog_color.h"
 +#include "toolbox.h"
 +#include "onemoment.h"
 +
 +#include "docks/dockmanager.h"
 +
 +#include "states/state_eyedrop.h"
 +#include "states/state_normal.h"
 +#include "states/state_mirror.h"
 +#include "states/state_draw.h"
 +#include "states/state_fill.h"
 +#include "states/state_bline.h"
 +#include "states/state_polygon.h"
 +#include "states/state_sketch.h"
 +#include "states/state_gradient.h"
 +#include "states/state_circle.h"
 +#include "states/state_rectangle.h"
 +#include "states/state_smoothmove.h"
 +#include "states/state_scale.h"
 +#include "states/state_star.h"
 +#include "states/state_text.h"
 +#include "states/state_width.h"
 +#include "states/state_rotate.h"
 +#include "states/state_zoom.h"
 +
 +#include "devicetracker.h"
 +#include "docks/dialog_tooloptions.h"
 +#include "widgets/widget_enum.h"
 +
 +#include "autorecover.h"
 +
 +#include <synfigapp/settings.h>
 +#include "docks/dock_history.h"
 +#include "docks/dock_canvases.h"
 +#include "docks/dock_keyframes.h"
 +#include "docks/dock_layers.h"
 +#include "docks/dock_params.h"
 +#include "docks/dock_metadata.h"
 +#include "docks/dock_children.h"
 +#include "docks/dock_info.h"
 +#include "docks/dock_navigator.h"
 +#include "docks/dock_layergroups.h"
 +#include "docks/dock_timetrack.h"
 +#include "docks/dock_curves.h"
 +
 +#include "modules/module.h"
 +#include "modules/mod_palette/mod_palette.h"
 +
 +#include <sys/stat.h>
 +
 +#include "ipc.h"
 +
 +#include "statemanager.h"
 +
 +#ifdef WITH_FMOD
 +#include <fmod.h>
 +#endif
 +
 +#include <gtkmm/accelmap.h>
 +#include <gtkmm/filechooser.h>
 +#include <gtkmm/filechooserdialog.h>
 +
 +#include "general.h"
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +#ifndef SYNFIG_USER_APP_DIR
 +#ifdef __APPLE__
 +#define SYNFIG_USER_APP_DIR   "Library/Synfig"
 +#elif defined(_WIN32)
 +#define SYNFIG_USER_APP_DIR   "Synfig"
 +#else
 +#define SYNFIG_USER_APP_DIR   ".synfig"
 +#endif
 +#endif
 +
 +#ifndef DPM2DPI
 +#define DPM2DPI(x)    (float(x)/39.3700787402f)
 +#define DPI2DPM(x)    (float(x)*39.3700787402f)
 +#endif
 +
 +#ifdef WIN32
 +#     ifdef IMAGE_DIR
 +#             undef IMAGE_DIR
 +#             define IMAGE_DIR "share\\pixmaps"
 +#     endif
 +#endif
 +
 +#ifndef IMAGE_DIR
 +#     define IMAGE_DIR "/usr/local/share/pixmaps"
 +#endif
 +
 +#ifndef IMAGE_EXT
 +#     define IMAGE_EXT        "tif"
 +#endif
 +
 +#include <synfigapp/main.h>
 +
 +/* === S I G N A L S ======================================================= */
 +
 +static sigc::signal<void> signal_present_all_;
 +sigc::signal<void>&
 +App::signal_present_all() { return signal_present_all_; }
 +
 +static sigc::signal<void> signal_recent_files_changed_;
 +sigc::signal<void>&
 +App::signal_recent_files_changed() { return signal_recent_files_changed_; }
 +
 +static sigc::signal<void,etl::loose_handle<CanvasView> > signal_canvas_view_focus_;
 +sigc::signal<void,etl::loose_handle<CanvasView> >&
 +App::signal_canvas_view_focus() { return signal_canvas_view_focus_; }
 +
 +static sigc::signal<void,etl::handle<Instance> > signal_instance_selected_;
 +sigc::signal<void,etl::handle<Instance> >&
 +App::signal_instance_selected() { return signal_instance_selected_; }
 +
 +static sigc::signal<void,etl::handle<Instance> > signal_instance_created_;
 +sigc::signal<void,etl::handle<Instance> >&
 +App::signal_instance_created() { return signal_instance_created_; }
 +
 +static sigc::signal<void,etl::handle<Instance> > signal_instance_deleted_;
 +sigc::signal<void,etl::handle<Instance> >&
 +App::signal_instance_deleted() { return signal_instance_deleted_; }
 +
 +/* === G L O B A L S ======================================================= */
 +
 +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;
 +
 +synfig::Gamma App::gamma;
 +
 +Glib::RefPtr<studio::UIManager>       App::ui_manager_;
 +
 +synfig::Distance::System App::distance_system;
 +
 +studio::Dialog_Setup* App::dialog_setup;
 +
 +etl::handle< studio::ModPalette > mod_palette_;
 +//studio::Dialog_Palette* App::dialog_palette;
 +
 +std::list<etl::handle<Instance> > App::instance_list;
 +
 +static etl::handle<synfigapp::UIInterface> ui_interface_;
 +const etl::handle<synfigapp::UIInterface>& App::get_ui_interface() { return ui_interface_; }
 +
 +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::IPC *ipc=NULL;
 +
 +studio::DockManager* studio::App::dock_manager=0;
 +
 +studio::DeviceTracker* studio::App::device_tracker=0;
 +
 +studio::Dialog_Gradient* studio::App::dialog_gradient;
 +
 +studio::Dialog_Color* studio::App::dialog_color;
 +
 +Gtk::InputDialog* studio::App::dialog_input;
 +
 +studio::Dialog_ToolOptions* studio::App::dialog_tool_options;
 +
 +studio::Dock_History* dock_history;
 +studio::Dock_Canvases* dock_canvases;
 +studio::Dock_Keyframes* dock_keyframes;
 +studio::Dock_Layers* dock_layers;
 +studio::Dock_Params* dock_params;
 +studio::Dock_MetaData* dock_meta_data;
 +studio::Dock_Children* dock_children;
 +studio::Dock_Info* dock_info;
 +studio::Dock_LayerGroups* dock_layer_groups;
 +studio::Dock_Navigator* dock_navigator;
 +studio::Dock_Timetrack* dock_timetrack;
 +studio::Dock_Curves* dock_curves;
 +
 +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_; }
 +void studio::App::set_max_recent_files(int x) { max_recent_files_=x; }
 +
 +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;
 +
 +
 +
 +
 +class GlobalUIInterface : public synfigapp::UIInterface
 +{
 +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(
 +                      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-yes"),RESPONSE_YES);
 +              dialog.add_button(Gtk::StockID("gtk-no"),RESPONSE_NO);
 +
 +              dialog.set_default_response(dflt);
 +              dialog.show();
 +              return (Response)dialog.run();
 +      }
 +      virtual Response yes_no_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_YES)
 +      {
 +              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-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();
 +      }
 +      virtual Response ok_cancel(const std::string &title, const std::string &message,Response dflt=RESPONSE_OK)
 +      {
 +              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"),RESPONSE_OK);
 +              dialog.add_button(Gtk::StockID("gtk-cancel"),RESPONSE_CANCEL);
 +
 +              dialog.set_default_response(dflt);
 +              dialog.show();
 +              return (Response)dialog.run();
 +      }
 +
 +      virtual bool
 +      task(const std::string &task)
 +      {
 +              std::cerr<<task<<std::endl;
 +              while(studio::App::events_pending())studio::App::iteration(false);
 +              return true;
 +      }
 +
 +      virtual bool
 +      error(const std::string &err)
 +      {
 +              Gtk::MessageDialog dialog(err, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
 +              dialog.show();
 +              dialog.run();
 +              return true;
 +      }
 +
 +      virtual bool
 +      warning(const std::string &err)
 +      {
 +              std::cerr<<"warning: "<<err<<std::endl;
 +              while(studio::App::events_pending())studio::App::iteration(false);
 +              return true;
 +      }
 +
 +      virtual bool
 +      amount_complete(int /*current*/, int /*total*/)
 +      {
 +              while(studio::App::events_pending())studio::App::iteration(false);
 +              return true;
 +      }
 +};
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +/*
 +void
 +studio::UIManager::insert_action_group (const Glib::RefPtr<Gtk::ActionGroup>& action_group, int pos)
 +{
 +      action_group_list.push_back(action_group);
 +      Gtk::UIManager::insert_action_group(action_group, pos);
 +}
 +
 +void
 +studio::UIManager::remove_action_group (const Glib::RefPtr<Gtk::ActionGroup>& action_group)
 +{
 +      std::list<Glib::RefPtr<Gtk::ActionGroup> >::iterator iter;
 +      for(iter=action_group_list.begin();iter!=action_group_list.end();++iter)
 +              if(*iter==action_group)
 +              {
 +                      action_group_list.erase(iter);
 +                      Gtk::UIManager::remove_action_group(action_group);
 +                      return;
 +              }
 +      synfig::error("Unable to find action group");
 +}
 +
 +void
 +studio::add_action_group_to_top(Glib::RefPtr<studio::UIManager> ui_manager, Glib::RefPtr<Gtk::ActionGroup> group)
 +{
 +      ui_manager->insert_action_group(group,0);
 +      return;
 +      std::list<Glib::RefPtr<Gtk::ActionGroup> > prev_groups(ui_manager->get_action_groups());
 +      std::list<Glib::RefPtr<Gtk::ActionGroup> >::reverse_iterator iter;
 +
 +      for(iter=prev_groups.rbegin();iter!=prev_groups.rend();++iter)
 +      {
 +              if(*iter && (*iter)->get_name()!="menus")
 +              {
 +                      synfig::info("Removing action group "+(*iter)->get_name());
 +                      ui_manager->remove_action_group(*iter);
 +              }
 +      }
 +      ui_manager->insert_action_group(group,0);
 +
 +      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);
 +      }
 +}
 +*/
 +class Preferences : public synfigapp::Settings
 +{
 +public:
 +      virtual bool get_value(const synfig::String& key, synfig::String& value)const
 +      {
 +              if(key=="gamma")
 +              {
 +                      value=strprintf("%f %f %f %f",
 +                              App::gamma.get_gamma_r(),
 +                              App::gamma.get_gamma_g(),
 +                              App::gamma.get_gamma_b(),
 +                              App::gamma.get_black_level()
 +                      );
 +                      return true;
 +              }
 +              if(key=="time_format")
 +              {
 +                      value=strprintf("%i",App::get_time_format());
 +                      return true;
 +              }
 +              if(key=="file_history.size")
 +              {
 +                      value=strprintf("%i",App::get_max_recent_files());
 +                      return true;
 +              }
 +              if(key=="use_colorspace_gamma")
 +              {
 +                      value=strprintf("%i",(int)App::use_colorspace_gamma);
 +                      return true;
 +              }
 +              if(key=="distance_system")
 +              {
 +                      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=="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);
 +      }
 +
 +      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,
 +                              &b,
 +                              &blk
 +                      );
 +
 +                      App::gamma.set_all(r,g,b,blk);
 +
 +                      return true;
 +              }
 +              if(key=="time_format")
 +              {
 +                      int i(atoi(value.c_str()));
 +                      App::set_time_format(static_cast<synfig::Time::Format>(i));
 +                      return true;
 +              }
 +              if(key=="auto_recover_backup_interval")
 +              {
 +                      int i(atoi(value.c_str()));
 +                      App::auto_recover->set_timeout(i);
 +                      return true;
 +              }
 +              if(key=="file_history.size")
 +              {
 +                      int i(atoi(value.c_str()));
 +                      App::set_max_recent_files(i);
 +                      return true;
 +              }
 +              if(key=="use_colorspace_gamma")
 +              {
 +                      int i(atoi(value.c_str()));
 +                      App::use_colorspace_gamma=i;
 +                      return true;
 +              }
 +              if(key=="distance_system")
 +              {
 +                      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);
 +      }
 +
 +      virtual KeyList get_key_list()const
 +      {
 +              KeyList ret(synfigapp::Settings::get_key_list());
 +              ret.push_back("gamma");
 +              ret.push_back("time_format");
 +              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("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;
 +      }
 +};
 +
 +static ::Preferences _preferences;
 +
 +void
 +init_ui_manager()
 +{
 +      Glib::RefPtr<Gtk::ActionGroup> menus_action_group = Gtk::ActionGroup::create("menus");
 +
 +      Glib::RefPtr<Gtk::ActionGroup> toolbox_action_group = Gtk::ActionGroup::create("toolbox");
 +
 +      Glib::RefPtr<Gtk::ActionGroup> actions_action_group = Gtk::ActionGroup::create("actions");
 +
 +      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;
 +      for(iter=synfigapp::Action::book().begin();iter!=synfigapp::Action::book().end();++iter)
 +      {
 +              actions_action_group->add(Gtk::Action::create(
 +                      "action-"+iter->second.name,
 +                      get_action_stock_id(iter->second),
 +                      iter->second.local_name,iter->second.local_name
 +              ));
 +      }
 +
 +#define DEFINE_ACTION(x,stock) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); actions_action_group->add(action); }
 +#define DEFINE_ACTION2(x,stock,label) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock,label,label) ); actions_action_group->add(action); }
 +#define DEFINE_ACTION_SIG(group,x,stock,sig) { Glib::RefPtr<Gtk::Action> action( Gtk::Action::create(x, stock) ); 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("revert", Gtk::Stock::REVERT_TO_SAVED);
 +      DEFINE_ACTION("cvs-add", Gtk::StockID("synfig-cvs_add"));
 +      DEFINE_ACTION("cvs-update", Gtk::StockID("synfig-cvs_update"));
 +      DEFINE_ACTION("cvs-commit", Gtk::StockID("synfig-cvs_commit"));
 +      DEFINE_ACTION("cvs-revert", Gtk::StockID("synfig-cvs_revert"));
 +      DEFINE_ACTION("import", _("Import"));
 +      DEFINE_ACTION("render", _("Render"));
 +      DEFINE_ACTION("preview", _("Preview"));
 +      DEFINE_ACTION("dialog-flipbook", _("Preview Dialog"));
 +      DEFINE_ACTION("sound", _("Sound File"));
 +      DEFINE_ACTION("options", _("Options"));
 +      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("redo", Gtk::StockID("gtk-redo"));
 +      DEFINE_ACTION("cut", Gtk::StockID("gtk-cut"));
 +      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("mask-position-ducks", _("Show Position Ducks"));
 +      DEFINE_ACTION("mask-vertex-ducks", _("Show Vertex Ducks"));
 +      DEFINE_ACTION("mask-tangent-ducks", _("Show Tangent Ducks"));
 +      DEFINE_ACTION("mask-radius-ducks", _("Show Radius Ducks"));
 +      DEFINE_ACTION("mask-width-ducks", _("Show Width Ducks"));
 +      DEFINE_ACTION("mask-angle-ducks", _("Show Angle Ducks"));
 +      DEFINE_ACTION("quality-00", _("Use Parametric Renderer"));
 +      DEFINE_ACTION("quality-01", _("Use Quality Level 1"));
 +      DEFINE_ACTION("quality-02", _("Use Quality Level 2"));
 +      DEFINE_ACTION("quality-03", _("Use Quality Level 3"));
 +      DEFINE_ACTION("quality-04", _("Use Quality Level 4"));
 +      DEFINE_ACTION("quality-05", _("Use Quality Level 5"));
 +      DEFINE_ACTION("quality-06", _("Use Quality Level 6"));
 +      DEFINE_ACTION("quality-07", _("Use Quality Level 7"));
 +      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("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("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("canvas-zoom-fit", Gtk::StockID("gtk-zoom-fit"));
 +      DEFINE_ACTION("canvas-zoom-100", Gtk::StockID("gtk-zoom-100"));
 +      DEFINE_ACTION("time-zoom-in", Gtk::StockID("gtk-zoom-in"));
 +      DEFINE_ACTION("time-zoom-out", Gtk::StockID("gtk-zoom-out"));
 +      DEFINE_ACTION("jump-next-keyframe", _("Jump to Next Keyframe"));
 +      DEFINE_ACTION("jump-prev-keyframe", _("Jump to Prev Keyframe"));
 +      DEFINE_ACTION("seek-next-frame", _("Next Frame"));
 +      DEFINE_ACTION("seek-prev-frame", _("Prev Frame"));
 +      DEFINE_ACTION("seek-next-second", _("Seek Forward"));
 +      DEFINE_ACTION("seek-prev-second", _("Seek Backward"));
 +      DEFINE_ACTION("seek-begin", _("Seek to Begin"));
 +      DEFINE_ACTION("seek-end", _("Seek to End"));
 +
 +      DEFINE_ACTION("action-group_add", _("Add group"));
 +
 +      DEFINE_ACTION("canvas-new", _("New Canvas"));
 +
 +      DEFINE_ACTION("amount-inc", _("Increase Amount"));
 +      DEFINE_ACTION("amount-dec", _("Decrease Amount"));
 +
 +#undef DEFINE_ACTION
 +#undef DEFINE_ACTION_2
 +#undef DEFINE_ACTION_SIG
 +
 +    Glib::ustring ui_info =
 +"<ui>"
 +"     <popup name='menu-toolbox' action='menu-toolbox'>"
 +"     <menu action='menu-file'>"
 +"     </menu>"
 +"     </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' />"
 +"             <separator name='bleh01'/>"
 +"             <menuitem action='cvs-add' />"
 +"             <menuitem action='cvs-update' />"
 +"             <menuitem action='cvs-commit' />"
 +"             <menuitem action='cvs-revert' />"
 +"             <separator name='bleh02'/>"
 +"             <menuitem action='import' />"
 +"             <separator name='bleh03'/>"
 +"             <menuitem action='render' />"
 +"             <menuitem action='preview' />"
 +"             <menuitem action='sound' />"
 +"             <separator name='bleh04'/>"
 +"             <menuitem action='options' />"
 +"             <menuitem action='close' />"
 +"             <menuitem action='close-document' />"
 +"             <menuitem action='quit' />"
 +"     </menu>"
 +"     <menu action='menu-edit'>"
 +"             <menuitem action='undo'/>"
 +"             <menuitem action='redo'/>"
 +"             <separator name='bleh05'/>"
 +"             <menuitem action='cut'/>"
 +"             <menuitem action='copy'/>"
 +"             <menuitem action='paste'/>"
 +"             <separator name='bleh06'/>"
 +"             <menuitem action='select-all-layers'/>"
 +"             <menuitem action='unselect-all-layers'/>"
 +"             <menuitem action='select-all-ducks'/>"
 +"             <menuitem action='unselect-all-ducks'/>"
 +"             <separator name='bleh07'/>"
 +"             <menuitem action='properties'/>"
 +"     </menu>"
 +"     <menu action='menu-view'>"
 +"             <menu action='menu-duck-mask'>"
 +"                     <menuitem action='mask-position-ducks' />"
 +"                     <menuitem action='mask-vertex-ducks' />"
 +"                     <menuitem action='mask-tangent-ducks' />"
 +"                     <menuitem action='mask-radius-ducks' />"
 +"                     <menuitem action='mask-width-ducks' />"
 +"                     <menuitem action='mask-angle-ducks' />"
 +"             </menu>"
 +"             <menu action='menu-preview-quality'>"
 +"                     <menuitem action='quality-00' />"
 +"                     <menuitem action='quality-01' />"
 +"                     <menuitem action='quality-02' />"
 +"                     <menuitem action='quality-03' />"
 +"                     <menuitem action='quality-04' />"
 +"                     <menuitem action='quality-05' />"
 +"                     <menuitem action='quality-06' />"
 +"                     <menuitem action='quality-07' />"
 +"                     <menuitem action='quality-08' />"
 +"                     <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'/>"
 +//"           <menuitem action='pause'/>"
 +"             <menuitem action='stop'/>"
 +"             <menuitem action='dialog-flipbook'/>"
 +"             <separator name='bleh09'/>"
 +"             <menuitem action='toggle-grid-show'/>"
 +"             <menuitem action='toggle-grid-snap'/>"
 +"             <menuitem action='toggle-guide-show'/>"
 +"             <menuitem action='toggle-low-res'/>"
 +"             <menuitem action='toggle-onion-skin'/>"
 +"             <separator name='bleh10'/>"
 +"             <menuitem action='canvas-zoom-in'/>"
 +"             <menuitem action='canvas-zoom-out'/>"
 +"             <menuitem action='canvas-zoom-fit'/>"
 +"             <menuitem action='canvas-zoom-100'/>"
 +"             <separator name='bleh11'/>"
 +"             <menuitem action='time-zoom-in'/>"
 +"             <menuitem action='time-zoom-out'/>"
 +"             <separator name='bleh12'/>"
 +"             <menuitem action='jump-next-keyframe'/>"
 +"             <menuitem action='jump-prev-keyframe'/>"
 +"             <menuitem action='seek-next-frame'/>"
 +"             <menuitem action='seek-prev-frame'/>"
 +"             <menuitem action='seek-next-second'/>"
 +"             <menuitem action='seek-prev-second'/>"
 +"             <menuitem action='seek-begin'/>"
 +"             <menuitem action='seek-end'/>"
 +"     </menu>"
 +"     <menu action='menu-canvas'>"
 +"             <menuitem action='canvas-new'/>"
 +"     </menu>"
 +"     <menu name='menu-state' action='menu-state'>"
 +"     </menu>"
 +"     <menu action='menu-group'>"
 +"             <menuitem action='action-group_add'/>"
 +"     </menu>"
 +"     <menu action='menu-layer'>"
 +//"           <menuitem action='cut'/>"
 +//"           <menuitem action='copy'/>"
 +//"           <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>"
 +"     </popup>"
 +
 +"</ui>"
 +;
 +/*            "<ui>"
 +        "  <menubar name='MenuBar'>"
 +        "    <menu action='MenuFile'>"
 +        "      <menuitem action='New'/>"
 +        "      <menuitem action='Open'/>"
 +        "      <separator/>"
 +        "      <menuitem action='Quit'/>"
 +        "    </menu>"
 +        "    <menu action='MenuEdit'>"
 +        "      <menuitem action='Cut'/>"
 +        "      <menuitem action='Copy'/>"
 +        "      <menuitem action='Paste'/>"
 +        "    </menu>"
 +        "  </menubar>"
 +        "  <toolbar  name='ToolBar'>"
 +        "    <toolitem action='Open'/>"
 +        "    <toolitem action='Quit'/>"
 +        "  </toolbar>"
 +        "</ui>";
 +*/
 +      try
 +      {
 +              actions_action_group->set_sensitive(false);
 +              App::ui_manager()->set_add_tearoffs(true);
 +              App::ui_manager()->insert_action_group(menus_action_group,1);
 +              App::ui_manager()->insert_action_group(actions_action_group,1);
 +              App::ui_manager()->add_ui_from_string(ui_info);
 +
 +              //App::ui_manager()->get_accel_group()->unlock();
 +      }
 +      catch(const Glib::Error& ex)
 +      {
 +              synfig::error("building menus and toolbars failed: " + ex.what());
 +      }
 +
 +      // Add default keyboard accelerators
 +#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>/action_group_state_manager/state-normal"                                     );
 +      ACCEL("<Mod1>v",                                                                                                        "<Actions>/action_group_state_manager/state-smooth_move"                                );
 +      ACCEL("<Mod1>s",                                                                                                        "<Actions>/action_group_state_manager/state-scale"                                      );
 +      ACCEL("<Mod1>t",                                                                                                        "<Actions>/action_group_state_manager/state-rotate"                                     );
 +      ACCEL("<Mod1>m",                                                                                                        "<Actions>/action_group_state_manager/state-mirror"                                     );
 +      ACCEL("<Mod1>c",                                                                                                        "<Actions>/action_group_state_manager/state-circle"                                     );
 +      ACCEL("<Mod1>r",                                                                                                        "<Actions>/action_group_state_manager/state-rectangle"                          );
 +      ACCEL("<Mod1>q",                                                                                                        "<Actions>/action_group_state_manager/state-star"                                               );
 +      ACCEL("<Mod1>g",                                                                                                        "<Actions>/action_group_state_manager/state-gradient"                                   );
 +      ACCEL("<Mod1>p",                                                                                                        "<Actions>/action_group_state_manager/state-polygon"                                    );
 +      ACCEL("<Mod1>b",                                                                                                        "<Actions>/action_group_state_manager/state-bline"                                      );
 +      ACCEL("<Mod1>x",                                                                                                        "<Actions>/action_group_state_manager/state-text"                                               );
 +      ACCEL("<Mod1>f",                                                                                                        "<Actions>/action_group_state_manager/state-fill"                                               );
 +      ACCEL("<Mod1>e",                                                                                                        "<Actions>/action_group_state_manager/state-eyedrop"                                    );
 +      ACCEL("<Mod1>z",                                                                                                        "<Actions>/action_group_state_manager/state-zoom"                                               );
 +      ACCEL("<Mod1>d",                                                                                                        "<Actions>/action_group_state_manager/state-draw"                                               );
 +      ACCEL("<Mod1>k",                                                                                                        "<Actions>/action_group_state_manager/state-sketch"                                     );
 +      ACCEL("<Mod1>w",                                                                                                        "<Actions>/action_group_state_manager/state-width"                                      );
 +
 +      // everything else
 +      ACCEL("<Control>a",                                                                                                     "<Actions>/canvasview/select-all-ducks"                         );
 +      ACCEL("<Control>d",                                                                                                     "<Actions>/canvasview/unselect-all-ducks"                               );
 +      ACCEL("<Control><Shift>a",                                                                                      "<Actions>/canvasview/select-all-layers"                                );
 +      ACCEL("<Control><Shift>d",                                                                                      "<Actions>/canvasview/unselect-all-layers"                      );
 +      ACCEL("F9",                                                                                                                     "<Actions>/canvasview/render"                                                   );
 +      ACCEL("F11",                                                                                                            "<Actions>/canvasview/preview"                                          );
 +      ACCEL("F8",                                                                                                                     "<Actions>/canvasview/properties"                                               );
 +      ACCEL("F12",                                                                                                            "<Actions>/canvasview/options"                                          );
 +      ACCEL("<control>i",                                                                                                     "<Actions>/canvasview/import"                                                   );
 +      ACCEL2(Gtk::AccelKey(GDK_Escape,static_cast<Gdk::ModifierType>(0),      "<Actions>/canvasview/stop"                                                     ));
 +      ACCEL("<Control>g",                                                                                                     "<Actions>/canvasview/toggle-grid-show"                         );
 +      ACCEL("<Control>l",                                                                                                     "<Actions>/canvasview/toggle-grid-snap"                         );
 +      ACCEL2(Gtk::AccelKey('`',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/toggle-low-res"                                   ));
 +      ACCEL("<Mod1>1",                                                                                                        "<Actions>/canvasview/mask-position-ducks"                      );
 +      ACCEL("<Mod1>2",                                                                                                        "<Actions>/canvasview/mask-vertex-ducks"                                );
 +      ACCEL("<Mod1>3",                                                                                                        "<Actions>/canvasview/mask-tangent-ducks"                               );
 +      ACCEL("<Mod1>4",                                                                                                        "<Actions>/canvasview/mask-radius-ducks"                                );
 +      ACCEL("<Mod1>5",                                                                                                        "<Actions>/canvasview/mask-width-ducks"                         );
 +      ACCEL("<Mod1>6",                                                                                                        "<Actions>/canvasview/mask-angle-ducks"                         );
 +      ACCEL2(Gtk::AccelKey(GDK_Page_Up,Gdk::SHIFT_MASK,                                       "<Actions>/action_group_layer_action_manager/action-LayerRaise"                         ));
 +      ACCEL2(Gtk::AccelKey(GDK_Page_Down,Gdk::SHIFT_MASK,                                     "<Actions>/action_group_layer_action_manager/action-LayerLower"                         ));
 +      ACCEL("<Control>1",                                                                                                     "<Actions>/canvasview/quality-01"                                               );
 +      ACCEL("<Control>2",                                                                                                     "<Actions>/canvasview/quality-02"                                               );
 +      ACCEL("<Control>3",                                                                                                     "<Actions>/canvasview/quality-03"                                               );
 +      ACCEL("<Control>4",                                                                                                     "<Actions>/canvasview/quality-04"                                               );
 +      ACCEL("<Control>5",                                                                                                     "<Actions>/canvasview/quality-05"                                               );
 +      ACCEL("<Control>6",                                                                                                     "<Actions>/canvasview/quality-06"                                               );
 +      ACCEL("<Control>7",                                                                                                     "<Actions>/canvasview/quality-07"                                               );
 +      ACCEL("<Control>8",                                                                                                     "<Actions>/canvasview/quality-08"                                               );
 +      ACCEL("<Control>9",                                                                                                     "<Actions>/canvasview/quality-09"                                               );
 +      ACCEL("<Control>0",                                                                                                     "<Actions>/canvasview/quality-10"                                               );
 +      ACCEL("<Control>z",                                                                                                     "<Actions>/action_group_dock_history/undo"                                                      );
 +      ACCEL("<Control>r",                                                                                                     "<Actions>/action_group_dock_history/redo"                                                      );
 +      ACCEL2(Gtk::AccelKey(GDK_Delete,Gdk::CONTROL_MASK,                                      "<Actions>/action_group_layer_action_manager/action-LayerRemove"                                ));
 +      ACCEL2(Gtk::AccelKey('(',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/decrease-low-res-pixel-size"      ));
 +      ACCEL2(Gtk::AccelKey(')',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/increase-low-res-pixel-size"      ));
 +      ACCEL2(Gtk::AccelKey('(',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,                      "<Actions>/action_group_layer_action_manager/amount-dec"                                                ));
 +      ACCEL2(Gtk::AccelKey(')',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,                      "<Actions>/action_group_layer_action_manager/amount-inc"                                                ));
 +      ACCEL2(Gtk::AccelKey(']',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/jump-next-keyframe"                               ));
 +      ACCEL2(Gtk::AccelKey('[',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/jump-prev-keyframe"                               ));
 +      ACCEL2(Gtk::AccelKey('=',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/canvas-zoom-in"                                   ));
 +      ACCEL2(Gtk::AccelKey('-',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/canvas-zoom-out"                          ));
 +      ACCEL2(Gtk::AccelKey('+',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/time-zoom-in"                                     ));
 +      ACCEL2(Gtk::AccelKey('_',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/time-zoom-out"                                    ));
 +      ACCEL2(Gtk::AccelKey('.',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/seek-next-frame"                          ));
 +      ACCEL2(Gtk::AccelKey(',',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/seek-prev-frame"                          ));
 +      ACCEL2(Gtk::AccelKey('>',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/seek-next-second"                         ));
 +      ACCEL2(Gtk::AccelKey('<',Gdk::CONTROL_MASK,                                                     "<Actions>/canvasview/seek-prev-second"                         ));
 +      ACCEL("<Mod1>o",                                                                                                        "<Actions>/canvasview/toggle-onion-skin"                                );
 +      ACCEL("<Control><Shift>z",                                                                                      "<Actions>/canvasview/canvas-zoom-fit"                          );
 +      ACCEL("<Control>p",                                                                                                     "<Actions>/canvasview/play"                                                     );
 +      ACCEL("Home",                                                                                                           "<Actions>/canvasview/seek-begin"                                               );
 +      ACCEL("End",                                                                                                            "<Actions>/canvasview/seek-end"                                         );
 +
 +#undef ACCEL
 +#undef ACCEL2
 +}
 +
 +#ifdef _WIN32
 +#define mkdir(x,y) mkdir(x)
 +#endif
 +
 +/* === M E T H O D S ======================================================= */
 +
 +App::App(int *argc, char ***argv):
 +      Gtk::Main(argc,argv),
 +      IconController(etl::dirname((*argv)[0]))
 +{
 +      app_base_path_=etl::dirname(etl::dirname((*argv)[0]));
 +
 +
 +      ui_interface_=new GlobalUIInterface();
 +
 +      gdk_rgb_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;
 +
 +      if(mkdir(get_user_app_directory().c_str(),ACCESSPERMS)<0)
 +      {
 +              if(errno!=EEXIST)
 +                      synfig::error("UNABLE TO CREATE \"%s\"",get_user_app_directory().c_str());
 +      }
 +      else
 +      {
 +              synfig::info("Created directory \"%s\"",get_user_app_directory().c_str());
 +      }
 +
 +
 +      ipc=new IPC();
 +
 +      if(!SYNFIG_CHECK_VERSION())
 +      {
 +              cerr<<"FATAL: Synfig Version Mismatch"<<endl;
 +              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"
 +                      "the latest version from the Synfig website at\n"
 +                      "http://synfig.org/en/current-release"
 +              );
 +              throw 40;
 +      }
 +      Glib::set_application_name(_("Synfig Studio"));
 +
 +      Splash splash_screen;
 +      splash_screen.show();
 +
 +      shutdown_in_progress=false;
 +      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)); }
 +      catch(std::runtime_error x)
 +      {
 +              get_ui_interface()->error(strprintf("%s\n\n%s", _("Failed to initialize synfig!"), x.what()));
 +              throw;
 +      }
 +      catch(...)
 +      {
 +              get_ui_interface()->error(_("Failed to initialize synfig!"));
 +              throw;
 +      }
 +
 +      // add the preferences to the settings
 +      synfigapp::Main::settings().add_domain(&_preferences,"pref");
 +
 +      try
 +      {
 +              studio_init_cb.task(_("Init UI Manager..."));
 +              App::ui_manager_=studio::UIManager::create();
 +              init_ui_manager();
 +
 +              studio_init_cb.task(_("Init Dock Manager..."));
 +              dock_manager=new studio::DockManager();
 +
 +              studio_init_cb.task(_("Init State Manager..."));
 +              state_manager=new StateManager();
 +
 +              studio_init_cb.task(_("Init Toolbox..."));
 +              toolbox=new studio::Toolbox();
 +
 +              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);
 +
 +              studio_init_cb.task(_("Init History..."));
 +              dock_history=new studio::Dock_History();
 +              dock_manager->register_dockable(*dock_history);
 +
 +              studio_init_cb.task(_("Init Canvases..."));
 +              dock_canvases=new studio::Dock_Canvases();
 +              dock_manager->register_dockable(*dock_canvases);
 +
 +              studio_init_cb.task(_("Init Keyframes..."));
 +              dock_keyframes=new studio::Dock_Keyframes();
 +              dock_manager->register_dockable(*dock_keyframes);
 +
 +              studio_init_cb.task(_("Init Layers..."));
 +              dock_layers=new studio::Dock_Layers();
 +              dock_manager->register_dockable(*dock_layers);
 +
 +              studio_init_cb.task(_("Init Params..."));
 +              dock_params=new studio::Dock_Params();
 +              dock_manager->register_dockable(*dock_params);
 +
 +              studio_init_cb.task(_("Init MetaData..."));
 +              dock_meta_data=new studio::Dock_MetaData();
 +              dock_manager->register_dockable(*dock_meta_data);
 +
 +              studio_init_cb.task(_("Init Children..."));
 +              dock_children=new studio::Dock_Children();
 +              dock_manager->register_dockable(*dock_children);
 +
 +              studio_init_cb.task(_("Init Info..."));
 +              dock_info = new studio::Dock_Info();
 +              dock_manager->register_dockable(*dock_info);
 +
 +              studio_init_cb.task(_("Init Navigator..."));
 +              dock_navigator = new studio::Dock_Navigator();
 +              dock_manager->register_dockable(*dock_navigator);
 +
 +              studio_init_cb.task(_("Init Timetrack..."));
 +              dock_timetrack = new studio::Dock_Timetrack();
 +              dock_manager->register_dockable(*dock_timetrack);
 +
 +              studio_init_cb.task(_("Init Curve Editor..."));
 +              dock_curves = new studio::Dock_Curves();
 +              dock_manager->register_dockable(*dock_curves);
 +
 +              studio_init_cb.task(_("Init Layer Groups..."));
 +              dock_layer_groups = new studio::Dock_LayerGroups();
 +              dock_manager->register_dockable(*dock_layer_groups);
 +
 +
 +              studio_init_cb.task(_("Init Color Dialog..."));
 +              dialog_color=new studio::Dialog_Color();
 +
 +              studio_init_cb.task(_("Init Gradient Dialog..."));
 +              dialog_gradient=new studio::Dialog_Gradient();
 +
 +              studio_init_cb.task(_("Init DeviceTracker..."));
 +              device_tracker=new studio::DeviceTracker();
 +
 +              studio_init_cb.task(_("Init Tools..."));
 +
 +              /* editing tools */
 +              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_mirror);
-               /* new objects */
 +
-               state_manager->add_state(&state_text);
++              /* geometry */
 +              state_manager->add_state(&state_circle);
 +              state_manager->add_state(&state_rectangle);
 +              state_manager->add_state(&state_star);
 +              state_manager->add_state(&state_gradient);
 +              if(!getenv("SYNFIG_DISABLE_POLYGON")) state_manager->add_state(&state_polygon); // Enabled - for working without ducks
-               /* other */
++
++              /* bline tools */
 +              state_manager->add_state(&state_bline);
 +              if(!getenv("SYNFIG_DISABLE_DRAW"   )) state_manager->add_state(&state_draw); // Enabled for now.  Let's see whether they're good enough yet.
-               state_manager->add_state(&state_zoom);
++              if(!getenv("SYNFIG_DISABLE_WIDTH"  )) state_manager->add_state(&state_width); // Enabled since 0.61.09
 +              state_manager->add_state(&state_fill);
 +              state_manager->add_state(&state_eyedrop);
- #define SCALE_FACTOR  (1280)
++
++              /* other */
++              state_manager->add_state(&state_text);
 +              if(!getenv("SYNFIG_DISABLE_SKETCH" )) state_manager->add_state(&state_sketch);
++              state_manager->add_state(&state_zoom);
 +
 +              studio_init_cb.task(_("Init ModPalette..."));
 +              module_list_.push_back(new ModPalette()); module_list_.back()->start();
 +
 +              studio_init_cb.task(_("Init Setup Dialog..."));
 +              dialog_setup=new studio::Dialog_Setup();
 +
 +              studio_init_cb.task(_("Init Input Dialog..."));
 +              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..."));
 +              auto_recover=new AutoRecover();
 +
 +              studio_init_cb.amount_complete(9250,10000);
 +              studio_init_cb.task(_("Loading Settings..."));
 +              load_settings();
 +              device_tracker->load_preferences();
 +
 +              studio_init_cb.task(_("Checking auto-recover..."));
 +
 +              studio_init_cb.amount_complete(9900,10000);
 +
 +              bool opened_any = false;
 +              if(auto_recover->recovery_needed())
 +              {
 +                      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)
 +                      {
 +                              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
 +                                      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;
 +                      }
 +                      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]!='-')
 +                      {
 +                              studio_init_cb.task(_("Loading files..."));
 +                              splash_screen.hide();
 +                              open((*argv)[*argc]);
 +                              opened_any = true;
 +                              splash_screen.show();
 +                      }
 +
 +              // 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);
 +
++              // To avoid problems with some window managers and gtk >= 2.18
++              // we should show dock dialogs after the settings load.
++              // If dock dialogs are shown before the settings are loaded,
++              // the windows manager can act over it.
++              // See discussions here:
++              // * http://synfig.org/forums/viewtopic.php?f=1&t=1131&st=0&sk=t&sd=a&start=30
++              // * http://synfig.org/forums/viewtopic.php?f=15&t=1062
++              dock_manager->show_all_dock_dialogs();
++
 +              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."));
 +      }
 +}
 +
 +StateManager* App::get_state_manager() { return state_manager; }
 +
 +App::~App()
 +{
 +      shutdown_in_progress=true;
 +
 +      save_settings();
 +
 +      synfigapp::Main::settings().remove_domain("pref");
 +
 +      selected_instance=0;
 +
 +      // Unload all of the modules
 +      for(;!module_list_.empty();module_list_.pop_back())
 +              ;
 +
 +      delete state_manager;
 +
 +      delete ipc;
 +
 +      delete auto_recover;
 +
 +      delete about;
 +
 +      toolbox->hide();
 +
 +      delete toolbox;
 +
 +      delete dialog_setup;
 +
 +      delete dialog_gradient;
 +
 +      delete dialog_color;
 +
 +      delete dialog_input;
 +
 +      delete dock_manager;
 +
 +      instance_list.clear();
 +}
 +
 +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);
 +#endif
 +}
 +
 +synfig::String
 +App::get_config_file(const synfig::String& file)
 +{
 +      return Glib::build_filename(get_user_app_directory(),file);
 +}
 +
-       int screen_w(Gdk::screen_width());
-       int screen_h(Gdk::screen_height());
 +//! 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)
 +{
-               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;
 +
 +      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;
 +              }
-               canvasview->resize(w*screen_w/SCALE_FACTOR,h*screen_h/SCALE_FACTOR);
 +              CanvasView::Handle canvasview = instance->find_canvas_view(canvas);
 +              canvasview->move(x,y);
-       int screen_w(Gdk::screen_width());
-       int screen_h(Gdk::screen_height());
++              canvasview->resize(w,h);
 +              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)
 +{
-                                                                               x_pos*SCALE_FACTOR/screen_w,  y_pos*SCALE_FACTOR/screen_h,
-                                                                               x_size*SCALE_FACTOR/screen_w, y_size*SCALE_FACTOR/screen_h);
 +
 +      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(),
- #undef SCALE_FACTOR
++                                                                              x_pos,  y_pos,
++                                                                              x_size, y_size);
 +      }
 +
 +      add_recent_file(absolute_path(instance->get_file_name()), canvas_window_size);
 +}
-       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");
 +
 +void
 +App::add_recent_file(const std::string &file_name, const std::string &window_size)
 +{
 +      std::string filename(file_name);
 +
 +      assert(!filename.empty());
 +
 +      if(filename.empty())
 +              return;
 +
 +      // Toss out any "hidden" files
 +      if(basename(filename)[0]=='.')
 +              return;
 +
 +      // If we aren't an absolute path, turn ourselves into one
 +      if(!is_absolute_path(filename))
 +              filename=absolute_path(filename);
 +
 +      std::string old_window_size;
 +
 +      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
 +      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);
 +                      old_window_size = *iter_wsize;
 +                      recent_files_window_size.erase(iter_wsize);
 +                      break;
 +              }
 +
 +
 +      // 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())
 +      {
 +              recent_files.pop_back();
 +              recent_files_window_size.pop_back();
 +      }
 +
 +      signal_recent_files_changed_();
 +
 +      return;
 +}
 +
 +static Time::Format _App_time_format(Time::FORMAT_NORMAL);
 +
 +Time::Format
 +App::get_time_format()
 +{
 +      return _App_time_format;
 +}
 +
 +void
 +App::set_time_format(synfig::Time::Format x)
 +{
 +      _App_time_format=x;
 +}
 +
 +
 +void
 +App::save_settings()
 +{
 +      char * old_locale;
 +      try
 +      {
 +      old_locale=strdup(setlocale(LC_NUMERIC, NULL));
 +      setlocale(LC_NUMERIC, "C");
 +              {
 +                      std::string filename=get_config_file("accelrc");
 +                      Gtk::AccelMap::save(filename);
 +              }
 +              do{
 +                      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;
 +                      }
 +
 +                      list<string>::reverse_iterator iter;
 +
 +                      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);
 +      setlocale(LC_NUMERIC,old_locale);
 +      }
 +      catch(...)
 +      {
 +              synfig::warning("Caught exception when attempting to save settings.");
 +      }
 +}
 +
 +void
 +App::load_settings()
 +{
 +      char  * old_locale;
 +      try
 +      {
 +      old_locale=strdup(setlocale(LC_NUMERIC, NULL));
 +      setlocale(LC_NUMERIC, "C");
 +              {
 +                      std::string filename=get_config_file("accelrc");
 +                      Gtk::AccelMap::load(filename);
 +              }
 +              {
 +                      bool window_size_broken = false;
 +
 +                      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_window_size(filename_window_size.c_str());
 +
 +                      if(!file_window_size)
 +                              window_size_broken = true;
 +
 +                      while(file)
 +                      {
 +                              std::string recent_file;
 +                              std::string recent_file_window_size;
 +                              getline(file,recent_file);
 +                              if(!window_size_broken)
 +                                      getline(file_window_size,recent_file_window_size);
 +                              if(!recent_file.empty())
 +                              {
 +                                      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=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);
 +                              reset_initial_window_configuration();
 +                      }
 +              }
 +      setlocale(LC_NUMERIC,old_locale);
 +      }
 +      catch(...)
 +      {
 +              synfig::warning("Caught exception when attempting to load settings.");
 +      }
 +}
 +
 +void
 +App::reset_initial_window_configuration()
 +{
++      Glib::RefPtr<Gdk::Display> display(Gdk::Display::get_default());
++      Glib::RefPtr<const Gdk::Screen> screen(display->get_default_screen());
++      Gdk::Rectangle rect;
++      // A proper way to obtain the primary monitor is to use the
++      // Gdk::Screen::get_primary_monitor () const member. But as it
++      // was introduced in gtkmm 2.20 I assume that the monitor 0 is the
++      // primary one.
++      screen->get_monitor_geometry(0,rect);
++#define hpanel_width 79.0f
++#define hpanel_height 25.0f
++#define vpanel_width 20.0f
++#define vpanel_height 100.0f
++#define vdock 20.0f
++#define hdock 20.0f
++
++/* percentages referred to width or height of the screen
++ *---------------------------------------------------------------------*
++ *    t   |                                                |
++ *    o   |                                                |
++ *    o   |                                                |vdock%
++ *    l   |                                                |
++ *    b   |                                                |------------
++ *    o   |                                                |
++ *    x   |                                                |vdock%
++ * --------                                                |
++ *                                                         |
++ *                                                         |------------
++ *                                                         |
++ *                                                         |vdock%
++ *                                                         |
++ *                                                         |
++ *-----hdock%----------------------------------------------|------------
++ *             |                                           |
++ *             |                                           |vdock%
++ *             |                                           |
++ *             |                                           |
++ * --------------------------------------------------------------------*
++*/
++// Vertical Panel
++      int v_xpos=rect.get_x() + rect.get_width()*(1.0-vpanel_width/100.0);
++      int v_xsize=rect.get_width()*vpanel_width/100.0;
++      int v_ypos=rect.get_y();
++      int v_ysize=rect.get_height()*vpanel_height/100.0;
++      std::string v_pos(strprintf("%d %d", v_xpos, v_ypos));
++      std::string v_size(strprintf("%d %d", v_xsize, v_ysize));
++// Horizontal Panel
++      int h_xpos=rect.get_x();
++      int h_xsize=rect.get_width()*hpanel_width/100.0;
++      int h_ypos=rect.get_y()+ rect.get_height()*(1.0-hpanel_height/100.0);;
++      int h_ysize=rect.get_height()*hpanel_height/100.0;
++      std::string h_pos(strprintf("%d %d", h_xpos, h_ypos));
++      std::string h_size(strprintf("%d %d", h_xsize, h_ysize));
++      int v_dock1 = rect.get_height()*vdock*0.8/100.0;
++      int v_dock2 = rect.get_height()*vdock*0.6/100.0;
++      int v_dock3 = rect.get_height()*vdock*1.1/100.0;
++      int h_dock = rect.get_width()*hdock/100.0;
++//Contents size
++      std::string v_contents(strprintf("%d %d %d", v_dock1, v_dock2, v_dock3));
++      std::string h_contents(strprintf("%d", h_dock));
++// Tool Box position
++      std::string tbox_pos(strprintf("%d %d", rect.get_x(), rect.get_y()));
++/*
++      synfig::info("tool box pos: %s", tbox_pos.c_str());
++      synfig::info("v_contents sizes: %s", v_contents.c_str());
++      synfig::info("v_pos: %s", v_pos.c_str());
++      synfig::info("v_sizes: %s", v_size.c_str());
++      synfig::info("h_contents sizes: %s", h_contents.c_str());
++      synfig::info("h_pos: %s", h_pos.c_str());
++      synfig::info("h_sizes: %s", h_size.c_str());
++*/
 +      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.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("dock.dialog.1.contents_size",v_contents);
++      synfigapp::Main::settings().set_value("dock.dialog.1.size",v_size);
++      synfigapp::Main::settings().set_value("dock.dialog.1.pos",v_pos);
 +      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("window.toolbox.pos","4 4");
++      synfigapp::Main::settings().set_value("dock.dialog.2.contents_size",h_contents);
++      synfigapp::Main::settings().set_value("dock.dialog.2.size",h_size);
++      synfigapp::Main::settings().set_value("dock.dialog.2.pos",h_pos);
++      synfigapp::Main::settings().set_value("window.toolbox.pos",tbox_pos);
++
++      dock_manager->show_all_dock_dialogs();
++}
++
++void
++App::reset_initial_preferences()
++{
 +      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","1");
 +#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);
-                                                                          .add_enum_value(synfig::RELEASE_VERSION_0_62_00, "0.62.00", strprintf("0.62.00 (%s)", _("current")))
++
 +}
 +
 +bool
 +App::shutdown_request(GdkEventAny*)
 +{
 +      quit();
 +      return true;
 +      //return !shutdown_in_progress;
 +}
 +
 +void
 +App::quit()
 +{
 +      if(shutdown_in_progress)return;
 +
 +
 +      get_ui_interface()->task(_("Quit Request"));
 +      if(Busy::count)
 +      {
 +              dialog_error_blocking(_("Cannot quit!"),_("Tasks are currently running.\nPlease cancel the current tasks and try again"));
 +              return;
 +      }
 +
 +      std::list<etl::handle<Instance> >::iterator iter;
 +      for(iter=instance_list.begin();!instance_list.empty();iter=instance_list.begin())
 +      {
 +              if(!(*iter)->safe_close())
 +                      return;
 +
 +/*
 +              if((*iter)->synfigapp::Instance::get_action_count())
 +              {
 +                      handle<synfigapp::UIInterface> uim;
 +                      uim=(*iter)->find_canvas_view((*iter)->get_canvas())->get_ui_interface();
 +                      assert(uim);
 +                      string str=strprintf(_("Would you like to save your changes to %s?"),(*iter)->get_file_name().c_str() );
 +                      switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,synfigapp::UIInterface::RESPONSE_YES))
 +                      {
 +                              case synfigapp::UIInterface::RESPONSE_NO:
 +                                      break;
 +                              case synfigapp::UIInterface::RESPONSE_YES:
 +                                      (*iter)->save();
 +                                      break;
 +                              case synfigapp::UIInterface::RESPONSE_CANCEL:
 +                                      return;
 +                              default:
 +                                      assert(0);
 +                                      return;
 +                      }
 +              }
 +
 +
 +              if((*iter)->synfigapp::Instance::is_modified())
 +              {
 +                      handle<synfigapp::UIInterface> uim;
 +                      uim=(*iter)->find_canvas_view((*iter)->get_canvas())->get_ui_interface();
 +                      assert(uim);
 +                      string str=strprintf(_("%s has changes not yet on the CVS repository.\nWould you like to commit these changes?"),(*iter)->get_file_name().c_str() );
 +                      switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,synfigapp::UIInterface::RESPONSE_YES))
 +                      {
 +                              case synfigapp::UIInterface::RESPONSE_NO:
 +                                      break;
 +                              case synfigapp::UIInterface::RESPONSE_YES:
 +                                      (*iter)->dialog_cvs_commit();
 +                                      break;
 +                              case synfigapp::UIInterface::RESPONSE_CANCEL:
 +                                      return;
 +                              default:
 +                                      assert(0);
 +                                      return;
 +                      }
 +              }
 +*/
 +
 +              // This next line causes things to crash for some reason
 +              //(*iter)->close();
 +      }
 +
 +      shutdown_in_progress=true;
 +
 +      instance_list.clear();
 +
 +      while(studio::App::events_pending())studio::App::iteration(false);
 +
 +      Gtk::Main::quit();
 +      auto_recover->normal_shutdown();
 +
 +      get_ui_interface()->task(_("Quit Request sent"));
 +}
 +
 +void
 +App::show_setup()
 +{
 +      dialog_setup->refresh();
 +      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;}
 +
 +//#ifdef WIN32
 +//#define USE_WIN32_FILE_DIALOGS 1
 +//#endif
 +
 +#ifdef USE_WIN32_FILE_DIALOGS
 +static OPENFILENAME ofn={};
 +#endif
 +
 +#ifdef WIN32
 +#include <gdk/gdkwin32.h>
 +#endif
 +
 +bool
 +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));
 +
 +      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_HIDEREADONLY;
 +//    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(GetOpenFileName(&ofn))
 +      {
 +              filename=szFilename;
 +              return true;
 +      }
 +      return false;
 +
 +#else   // not USE_WIN32_FILE_DIALOGS
 +      synfig::String prev_path;
 +
 +      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->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 false;
 +#endif   // not USE_WIN32_FILE_DIALOGS
 +}
 +
 +bool
 +App::dialog_save_file(const std::string &title, std::string &filename, std::string preference)
 +{
 +      // 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") ;
 +
 +      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))
 +      {
 +              filename=szFilename;
 +              _preferences.set_value(preference,dirname(filename));
 +              return true;
 +      }
 +      return false;
 +#else
 +      synfig::String prev_path;
 +
 +      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_SAVE);
 +
 +    dialog->set_current_folder(prev_path);
 +    dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
 +    dialog->add_button(Gtk::Stock::SAVE,   Gtk::RESPONSE_ACCEPT);
 +
 +      Widget_Enum *file_type_enum = 0;
 +      if (preference == ANIMATION_DIR_PREFERENCE)
 +      {
 +              file_type_enum = manage(new Widget_Enum());
 +              file_type_enum->set_param_desc(ParamDesc().set_hint("enum")
++                                                                         .add_enum_value(synfig::RELEASE_VERSION_0_62_01, "0.62.01", strprintf("0.62.01 (%s)", _("current")))
++                                                                         .add_enum_value(synfig::RELEASE_VERSION_0_62_00, "0.62.00", "0.61.00")
 +                                                                         .add_enum_value(synfig::RELEASE_VERSION_0_61_09, "0.61.09", "0.61.09")
 +                                                                         .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);
 +      }
 +
 +    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 false;
 +#endif
 +}
 +
 +void
 +App::dialog_error_blocking(const std::string &title, const std::string &message)
 +{
 +      Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true);
 +      dialog.set_title(title);
 +      dialog.show();
 +      dialog.run();
 +}
 +
 +void
 +App::dialog_warning_blocking(const std::string &title, const std::string &message)
 +{
 +      Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true);
 +      dialog.set_title(title);
 +      dialog.show();
 +      dialog.run();
 +}
 +
 +bool
 +App::dialog_yes_no(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-yes"),1);
 +      dialog.add_button(Gtk::StockID("gtk-no"),0);
 +      dialog.show();
 +      return dialog.run();
 +}
 +
 +int
 +App::dialog_yes_no_cancel(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-yes"),1);
 +      dialog.add_button(Gtk::StockID("gtk-no"),0);
 +      dialog.add_button(Gtk::StockID("gtk-cancel"),2);
 +      dialog.show();
 +      return dialog.run();
 +}
 +
 +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();
 +}
 +
 +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/wiki/Category:Manual"))
 +      {
 +              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://synfig.org/wiki/Category:Manual"));
 +              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
 +App::dialog_entry(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);
 +
 +      Gtk::Entry entry;
 +      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);
 +
 +      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=entry.get_text();
 +
 +      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)
 +{
 +      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)));
 +      // 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;
 +              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();
 +                      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();
 +              }
 +      }
 +      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;
 +      }
 +
 +      return true;
 +}
 +
 +
 +void
 +App::new_instance()
 +{
 +      handle<synfig::Canvas> canvas=synfig::Canvas::create();
 +
 +      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_end(5.0);
 +      canvas->rend_desc().set_x_res(DPI2DPM(72.0f));
 +      canvas->rend_desc().set_y_res(DPI2DPM(72.0f));
 +      // 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);
 +
 +      handle<Instance> instance = Instance::create(canvas);
 +
 +      if (getenv("SYNFIG_ENABLE_NEW_CANVAS_EDIT_PROPERTIES"))
 +              instance->find_canvas_view(canvas)->canvas_properties.present();
 +}
 +
 +void
 +App::dialog_open(string filename)
 +{
 +      if (filename.empty())
 +              filename="*.sif";
 +
 +      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(find(filename.begin(),filename.end(),'*')!=filename.end())
 +                      continue;
 +
 +              if(open(filename))
 +                      break;
 +
 +              get_ui_interface()->error(_("Unable to open file"));
 +      }
 +}
 +
 +void
 +App::set_selected_instance(etl::loose_handle<Instance> instance)
 +{
 +/*    if(get_selected_instance()==instance)
 +      {
 +              selected_instance=instance;
 +              signal_instance_selected()(instance);
 +              return;
 +      }
 +      else
 +      {
 +*/
 +              selected_instance=instance;
 +              if(get_selected_canvas_view() && get_selected_canvas_view()->get_instance()!=instance)
 +              {
 +                      if(instance)
 +                      {
 +                              instance->focus(instance->get_canvas());
 +                      }
 +                      else
 +                              set_selected_canvas_view(0);
 +              }
 +              signal_instance_selected()(instance);
 +}
 +
 +void
 +App::set_selected_canvas_view(etl::loose_handle<CanvasView> canvas_view)
 +{
 +      selected_canvas_view=canvas_view;
 +      signal_canvas_view_focus()(selected_canvas_view);
 +      if(canvas_view)
 +      {
 +              selected_instance=canvas_view->get_instance();
 +              signal_instance_selected()(canvas_view->get_instance());
 +      }
 +/*
 +      if(get_selected_canvas_view()==canvas_view)
 +      {
 +              signal_canvas_view_focus()(selected_canvas_view);
 +              signal_instance_selected()(canvas_view->get_instance());
 +              return;
 +      }
 +      selected_canvas_view=canvas_view;
 +      if(canvas_view && canvas_view->get_instance() != get_selected_instance())
 +              set_selected_instance(canvas_view->get_instance());
 +      signal_canvas_view_focus()(selected_canvas_view);
 +*/
 +}
 +
 +etl::loose_handle<Instance>
 +App::get_instance(etl::handle<synfig::Canvas> canvas)
 +{
 +      if(!canvas) return 0;
 +      canvas=canvas->get_root();
 +
 +      std::list<etl::handle<Instance> >::iterator iter;
 +      for(iter=instance_list.begin();iter!=instance_list.end();++iter)
 +      {
 +              if((*iter)->get_canvas()==canvas)
 +                      return *iter;
 +      }
 +      return 0;
 +}
 +
 +void
 +App::dialog_about()
 +{
 +      if(about)
 +              about->show();
 +}
 +
 +void
 +studio::App::undo()
 +{
 +      if(selected_instance)
 +              selected_instance->undo();
 +}
 +
 +void
 +studio::App::redo()
 +{
 +      if(selected_instance)
 +              selected_instance->redo();
 +}
 +
 +synfig::String
 +studio::App::get_base_path()
 +{
 +      return app_base_path_;
 +}
index f9960d3,0000000..06b60d3
mode 100644,000000..100644
--- /dev/null
@@@ -1,363 -1,0 +1,364 @@@
 +/* === S Y N F I G ========================================================= */
 +/*!   \file app.h
 +**    \brief writeme
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007, 2008 Chris Moore
 +**  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
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === S T A R T =========================================================== */
 +
 +#ifndef __SYNFIG_STUDIO_APP_H
 +#define __SYNFIG_STUDIO_APP_H
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#include <sigc++/bind.h>
 +
 +#include <gtkmm/main.h>
 +#include <string>
 +#include <list>
 +
 +#include <ETL/smart_ptr>
 +
 +#include <synfig/distance.h>
 +#include <synfig/string.h>
 +#include <synfig/time.h>
 +
 +#include <gtkmm/uimanager.h>
 +
 +#include <synfigapp/instance.h>
 +#include "iconcontroller.h"
 +
 +/* === M A C R O S ========================================================= */
 +
 +#define MISC_DIR_PREFERENCE                   "misc_dir"
 +#define ANIMATION_DIR_PREFERENCE      "animation_dir"
 +#define IMAGE_DIR_PREFERENCE          "image_dir"
 +#define SKETCH_DIR_PREFERENCE         "sketch_dir"
 +#define RENDER_DIR_PREFERENCE         "render_dir"
 +
 +/* === T Y P E D E F S ===================================================== */
 +
 +/* === C L A S S E S & S T R U C T S ======================================= */
 +
 +namespace Gtk
 +{
 +      class InputDialog;
 +      class UIManager;
 +      class ActionGroup;
 +};
 +
 +namespace synfigapp
 +{
 +      class UIInterface;
 +      class Main;
 +};
 +
 +class Preferences;
 +
 +namespace studio {
 +
 +typedef Gtk::UIManager UIManager;
 +
 +class About;
 +class Toolbox;
 +class Instance;
 +class CanvasView;
 +class Dialog_Setup;
 +class Dialog_Gradient;
 +class Dialog_Color;
 +class Dialog_ToolOptions;
 +class DeviceTracker;
 +class AutoRecover;
 +
 +class DockManager;
 +
 +class Dock_History;
 +class Dock_Canvases;
 +
 +class Dock_Keyframes;
 +class Dock_Params;
 +class Dock_Layers;
 +class Dock_MetaData;
 +class Dock_Children;
 +class Dock_Info;
 +class Dock_Navigator;
 +class Dock_LayerGroups;
 +class IPC;
 +
 +class Module;
 +
 +class StateManager;
 +class IconController;
 +
 +class App : public Gtk::Main, private IconController
 +{
 +      friend class Preferences;
 +      friend class Dialog_Setup;
 +
 +      /*
 + -- ** -- P U B L I C   T Y P E S ---------------------------------------------
 +      */
 +
 +public:
 +
 +      struct Busy
 +      {
 +              static int count;
 +              Busy(){count++;}
 +              ~Busy(){count--;}
 +      };
 +
 +
 +      /*
 + -- ** -- P R I V A T E   D A T A ---------------------------------------------
 +      */
 +
 +private:
 +      //static etl::handle<synfigapp::UIInterface> ui_interface_;
 +      //static int max_recent_files;
 +
 +/*      //declated as globals in app.cpp
 +      static Dock_Keyframes *dock_keyframes;
 +      static Dock_Layers *dock_layers;
 +      static Dock_Params *dock_params;
 +      static Dock_MetaData *dock_meta_data;
 +      static Dock_Children *dock_children;
 +      static Dock_Info *dock_info;
 +      static Dock_Navigator *dock_navigator;
 +      static Dock_History *dock_history;
 +      static Dock_Canvases *dock_canvases;
 +      static Dock_LayerGroups *dock_layer_groups;
 +
 +      static IPC *ipc;
 +*/
 +
 +      etl::smart_ptr<synfigapp::Main> synfigapp_main;
 +
 +
 +      static etl::handle<Instance> selected_instance;
 +      static etl::handle<CanvasView> selected_canvas_view;
 +
 +      static Glib::RefPtr<UIManager>  ui_manager_;
 +
 +//    static std::list< etl::handle< Module > > module_list_;
 +
 +      /*
 + -- ** -- P U B L I C   D A T A -----------------------------------------------
 +      */
 +
 +public:
 +      static Gtk::InputDialog* dialog_input;
 +
 +      static DeviceTracker*   device_tracker;
 +      static AutoRecover*     auto_recover;
 +      static DockManager* dock_manager;
 +
 +      static DockManager* get_dock_manager() { return dock_manager; }
 +
 +      static Dialog_Setup* dialog_setup;
 +      static Dialog_Gradient* dialog_gradient;
 +      static Dialog_Color* dialog_color;
 +//    static Dialog_Palette* dialog_palette;
 +      static Dialog_ToolOptions *dialog_tool_options;
 +
 +      static synfig::Distance::System distance_system;
 +
 +      static synfig::Gamma gamma;
 +
 +      static About *about;
 +      static Toolbox *toolbox;
 +
 +      static std::list<etl::handle<Instance> > instance_list;
 +
 +      static bool shutdown_in_progress;
 +
 +      static bool use_colorspace_gamma;
 +
 +#ifdef SINGLE_THREADED
 +      static bool single_threaded;
 +#endif
 +
 +      static bool restrict_radius_ducks;
 +      static bool resize_imported_images;
 +
 +      static synfig::String browser_command;
 +      static synfig::String custom_filename_prefix;
 +      static int preferred_x_size;
 +      static int preferred_y_size;
 +      static synfig::String predefined_size;
 +      static synfig::String predefined_fps;
 +      static float preferred_fps;
 +      /*
 + -- ** -- S I G N A L S -------------------------------------------------------
 +      */
 +/*      //declated as globals in app.cpp
 +      static sigc::signal<
 +              void,
 +              etl::loose_handle<CanvasView>
 +      > signal_canvas_view_focus_;
 +      static sigc::signal<
 +              void,
 +              etl::handle<Instance>
 +      > signal_instance_selected_;
 +      static sigc::signal<
 +              void,
 +              etl::handle<Instance>
 +      > signal_instance_created_;
 +      static sigc::signal<
 +              void,
 +              etl::handle<Instance>
 +      > signal_instance_deleted_;
 +      static sigc::signal<void> signal_recent_files_changed_;
 +      static sigc::signal<void> signal_present_all_;
 +*/
 +public:
 +
 +      static sigc::signal<void> &signal_present_all();
 +
 +      static sigc::signal<void> &signal_recent_files_changed();
 +
 +      static sigc::signal<
 +              void,
 +              etl::loose_handle<CanvasView>
 +      >& signal_canvas_view_focus();
 +
 +      static sigc::signal<
 +              void,
 +              etl::handle<Instance>
 +      > &signal_instance_selected();
 +
 +      static sigc::signal<
 +              void,
 +              etl::handle<Instance>
 +      > &signal_instance_created();
 +
 +      static sigc::signal<
 +              void,
 +              etl::handle<Instance>
 +      > &signal_instance_deleted();
 +
 +      /*
 + -- ** -- P R I V A T E   M E T H O D S ---------------------------------------
 +      */
 +
 +private:
 +      static void add_recent_file(const std::string &filename, const std::string &window_size = std::string());
 +
 +      /*
 + -- ** -- P U B L I C   M E T H O D S -----------------------------------------
 +      */
 +
 +public:
 +
 +      App(int *argc, char ***argv);
 +      virtual ~App();
 +
 +      /*
 + -- ** -- S T A T I C   P U B L I C   M E T H O D S ---------------------------
 +      */
 +
 +public:
 +
 +      static StateManager* get_state_manager();
 +
 +      static Glib::RefPtr<UIManager>& ui_manager() { return ui_manager_; }
 +
 +      static void set_recent_file_window_size(etl::handle<Instance> instance);
 +      static void add_recent_file(const etl::handle<Instance> instance);
 +
 +      static synfig::String get_base_path();
 +      static void save_settings();
 +      static void load_settings();
 +      static void reset_initial_window_configuration();
++      static void reset_initial_preferences();
 +
 +      static const std::list<std::string>& get_recent_files();
 +
 +      static const etl::handle<synfigapp::UIInterface>& get_ui_interface();
 +
 +
 +      static void set_selected_instance(etl::loose_handle<Instance> instance);
 +      static void set_selected_canvas_view(etl::loose_handle<CanvasView>);
 +
 +      static etl::loose_handle<Instance> get_instance(etl::handle<synfig::Canvas> canvas);
 +
 +      static etl::loose_handle<Instance> get_selected_instance() { return selected_instance; }
 +      static etl::loose_handle<CanvasView> get_selected_canvas_view() { return selected_canvas_view; }
 +
 +      static bool open(std::string filename);
 +
 +      static bool open_as(std::string filename,std::string as);
 +
 +      static void new_instance();
 +
 +      static void dialog_open(std::string filename = "");
 +
 +      static void dialog_about();
 +
 +      static void quit();
 +
 +      static void show_setup();
 +
 +      static void undo();
 +      static void redo();
 +
 +      static int get_max_recent_files();
 +      static void set_max_recent_files(int x);
 +
 +
 +      static synfig::Time::Format get_time_format();
 +      static void set_time_format(synfig::Time::Format x);
 +
 +      static bool shutdown_request(GdkEventAny*bleh=NULL);
 +
 +//    static bool dialog_file(const std::string &title, std::string &filename);
 +
 +      static bool dialog_open_file(const std::string &title, std::string &filename, std::string preference);
 +      static bool dialog_save_file(const std::string &title, std::string &filename, std::string preference);
 +
 +      static void dialog_error_blocking(const std::string &title, const std::string &message);
 +
 +      static void dialog_warning_blocking(const std::string &title, const std::string &message);
 +
 +      static bool dialog_entry(const std::string &title, const std::string &message,std::string &text);
 +      static bool dialog_paragraph(const std::string &title, const std::string &message,std::string &text);
 +
 +      static bool dialog_yes_no(const std::string &title, const std::string &message);
 +
 +      static int dialog_yes_no_cancel(const std::string &title, const std::string &message);
 +
 +      static void dialog_not_implemented();
 +
 +      static void dialog_help();
 +
 +      static void open_url(const std::string &url);
 +
 +      static synfig::String get_user_app_directory();
 +      static synfig::String get_config_file(const synfig::String& file);
 +}; // END of class App
 +
 +      void delete_widget(Gtk::Widget *widget);
 +
 +}; // END namespace studio
 +
 +/* === E N D =============================================================== */
 +
 +#endif
index 72a286c,0000000..4ec1537
mode 100644,000000..100644
--- /dev/null
@@@ -1,541 -1,0 +1,541 @@@
-                       synfig::info("%s:%d rendering in the same thread", __FILE__, __LINE__);
 +/* === S Y N F I G ========================================================= */
 +/*!   \file asyncrenderer.cpp
 +**    \brief Template File
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007 Chris Moore
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include "asyncrenderer.h"
 +#include "app.h"
 +#include <glibmm/thread.h>
 +#include <glibmm/dispatcher.h>
 +
 +#ifdef HAVE_UNISTD_H
 +#include <unistd.h>
 +#endif
 +
 +#ifdef HAVE_SYS_TYPES_H
 +#include <sys/types.h>
 +#endif
 +
 +#ifdef HAVE_SYS_WAIT_H
 +#include <sys/wait.h>
 +#endif
 +
 +#ifdef HAVE_SIGNAL_H
 +#include <signal.h>
 +#endif
 +
 +#include <synfig/general.h>
 +#include <ETL/clock>
 +
 +#include "general.h"
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +
 +#define BOREDOM_TIMEOUT               50
 +
 +#define REJOIN_ON_STOP        1
 +
 +// The Glib::Dispatcher class is broken as of Glibmm 2.4.5.
 +// Defining this macro enables the workaround.
 +#define GLIB_DISPATCHER_BROKEN 1
 +
 +/* === C L A S S E S ======================================================= */
 +
 +class AsyncTarget_Tile : public synfig::Target_Tile
 +{
 +public:
 +      etl::handle<synfig::Target_Tile> warm_target;
 +
 +      struct tile_t
 +      {
 +              Surface surface;
 +              int x,y;
 +              tile_t(const Surface& surface,int x, int y):
 +                      surface(surface),
 +                      x(x),y(y)
 +              {
 +              }
 +      };
 +      std::list<tile_t> tile_queue;
 +      Glib::Mutex mutex;
 +
 +#ifndef GLIB_DISPATCHER_BROKEN
 +      Glib::Dispatcher tile_ready_signal;
 +#endif
 +      Glib::Cond cond_tile_queue_empty;
 +      bool alive_flag;
 +
 +      sigc::connection ready_connection;
 +
 +public:
 +      AsyncTarget_Tile(etl::handle<synfig::Target_Tile> warm_target):
 +              warm_target(warm_target)
 +      {
 +              set_avoid_time_sync(warm_target->get_avoid_time_sync());
 +              set_tile_w(warm_target->get_tile_w());
 +              set_tile_h(warm_target->get_tile_h());
 +              set_canvas(warm_target->get_canvas());
 +              set_quality(warm_target->get_quality());
 +              set_remove_alpha(warm_target->get_remove_alpha());
 +              set_threads(warm_target->get_threads());
 +              set_clipping(warm_target->get_clipping());
 +              set_rend_desc(&warm_target->rend_desc());
 +              alive_flag=true;
 +#ifndef GLIB_DISPATCHER_BROKEN
 +              ready_connection=tile_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Tile::tile_ready));
 +#endif
 +      }
 +
 +      ~AsyncTarget_Tile()
 +      {
 +              ready_connection.disconnect();
 +      }
 +      void set_dead()
 +      {
 +              Glib::Mutex::Lock lock(mutex);
 +              alive_flag=false;
 +      }
 +
 +      virtual int total_tiles()const
 +      {
 +              return warm_target->total_tiles();
 +      }
 +
 +      virtual int next_tile(int& x, int& y)
 +      {
 +              if(!alive_flag)
 +                      return 0;
 +
 +              return warm_target->next_tile(x,y);
 +      }
 +
 +      virtual int next_frame(Time& time)
 +      {
 +              if(!alive_flag)
 +                      return 0;
 +              return warm_target->next_frame(time);
 +      }
 +
 +      virtual bool start_frame(synfig::ProgressCallback *cb=0)
 +      {
 +              if(!alive_flag)
 +                      return false;
 +              return warm_target->start_frame(cb);
 +      }
 +
 +      virtual bool add_tile(const synfig::Surface &surface, int gx, int gy)
 +      {
 +              assert(surface);
 +              if(!alive_flag)
 +                      return false;
 +              Glib::Mutex::Lock lock(mutex);
 +              tile_queue.push_back(tile_t(surface,gx,gy));
 +              if(tile_queue.size()==1)
 +              {
 +#ifdef GLIB_DISPATCHER_BROKEN
 +              ready_connection=Glib::signal_timeout().connect(
 +                      sigc::bind_return(
 +                              sigc::mem_fun(*this,&AsyncTarget_Tile::tile_ready),
 +                              false
 +                      )
 +                      ,0
 +              );
 +#else
 +              tile_ready_signal();
 +#endif
 +              }
 +
 +              return alive_flag;
 +      }
 +
 +      void tile_ready()
 +      {
 +              Glib::Mutex::Lock lock(mutex);
 +              if(!alive_flag)
 +              {
 +                      tile_queue.clear();
 +                      cond_tile_queue_empty.signal();
 +                      return;
 +              }
 +              while(!tile_queue.empty() && alive_flag)
 +              {
 +                      tile_t& tile(tile_queue.front());
 +
 +                      if (getenv("SYNFIG_SHOW_TILE_OUTLINES"))
 +                      {
 +                              Color red(1,0,0);
 +                              tile.surface.fill(red, 0, 0, 1, tile.surface.get_h());
 +                              tile.surface.fill(red, 0, 0, tile.surface.get_w(), 1);
 +                      }
 +
 +                      alive_flag=warm_target->add_tile(tile.surface,tile.x,tile.y);
 +
 +                      tile_queue.pop_front();
 +              }
 +              cond_tile_queue_empty.signal();
 +      }
 +
 +      virtual void end_frame()
 +      {
 +#ifdef SINGLE_THREADED
 +              if (!single_threaded())
 +              {
 +#endif
 +                      while(alive_flag)
 +                      {
 +                              Glib::Mutex::Lock lock(mutex);
 +                              if(!tile_queue.empty() && alive_flag)
 +                              {
 +                                      if(cond_tile_queue_empty.timed_wait(mutex,Glib::TimeVal(0,BOREDOM_TIMEOUT)))
 +                                              break;
 +                              }
 +                              else
 +                                      break;
 +                      }
 +#ifdef SINGLE_THREADED
 +              }
 +#endif
 +              Glib::Mutex::Lock lock(mutex);
 +              if(!alive_flag)
 +                      return;
 +              return warm_target->end_frame();
 +      }
 +};
 +
 +
 +
 +class AsyncTarget_Scanline : public synfig::Target_Scanline
 +{
 +public:
 +      etl::handle<synfig::Target_Scanline> warm_target;
 +
 +      int scanline_;
 +      Surface surface;
 +
 +      Glib::Mutex mutex;
 +
 +#ifndef GLIB_DISPATCHER_BROKEN
 +      Glib::Dispatcher frame_ready_signal;
 +#endif
 +      Glib::Cond cond_frame_queue_empty;
 +      bool alive_flag;
 +      bool ready_next;
 +      sigc::connection ready_connection;
 +
 +
 +public:
 +      AsyncTarget_Scanline(etl::handle<synfig::Target_Scanline> warm_target):
 +              warm_target(warm_target)
 +      {
 +              set_avoid_time_sync(warm_target->get_avoid_time_sync());
 +              set_canvas(warm_target->get_canvas());
 +              set_quality(warm_target->get_quality());
 +              set_remove_alpha(warm_target->get_remove_alpha());
 +              set_threads(warm_target->get_threads());
 +              set_rend_desc(&warm_target->rend_desc());
 +              alive_flag=true;
 +#ifndef GLIB_DISPATCHER_BROKEN
 +              ready_connection=frame_ready_signal.connect(sigc::mem_fun(*this,&AsyncTarget_Scanline::frame_ready));
 +#endif
 +              surface.set_wh(warm_target->rend_desc().get_w(),warm_target->rend_desc().get_h());
 +      }
 +
 +      ~AsyncTarget_Scanline()
 +      {
 +              ready_connection.disconnect();
 +      }
 +
 +      virtual int next_frame(Time& time)
 +      {
 +              if(!alive_flag)
 +                      return 0;
 +              return warm_target->next_frame(time);
 +
 +      }
 +
 +      void set_dead()
 +      {
 +              Glib::Mutex::Lock lock(mutex);
 +              alive_flag=false;
 +      }
 +
 +      virtual bool start_frame(synfig::ProgressCallback */*cb*/=0)
 +      {
 +              return alive_flag;
 +      }
 +
 +      virtual void end_frame()
 +      {
 +              {
 +                      Glib::Mutex::Lock lock(mutex);
 +
 +                      if(!alive_flag)
 +                              return;
 +                      ready_next=false;
 +
 +#ifdef GLIB_DISPATCHER_BROKEN
 +              ready_connection=Glib::signal_timeout().connect(
 +                      sigc::bind_return(
 +                              sigc::mem_fun(*this,&AsyncTarget_Scanline::frame_ready),
 +                              false
 +                      )
 +                      ,0
 +              );
 +#else
 +                      frame_ready_signal();
 +#endif
 +              }
 +
 +#ifdef SINGLE_THREADED
 +              if (single_threaded())
 +                      signal_progress()();
 +              else
 +#endif
 +                      while(alive_flag && !ready_next)
 +                      {
 +                              Glib::Mutex::Lock lock(mutex);
 +                              if(cond_frame_queue_empty.timed_wait(mutex,Glib::TimeVal(0,BOREDOM_TIMEOUT)))
 +                                      break;
 +                      }
 +      }
 +
 +
 +      virtual Color * start_scanline(int scanline)
 +      {
 +              Glib::Mutex::Lock lock(mutex);
 +
 +              return surface[scanline];
 +      }
 +
 +      virtual bool end_scanline()
 +      {
 +              return alive_flag;
 +      }
 +
 +      void frame_ready()
 +      {
 +              Glib::Mutex::Lock lock(mutex);
 +              if(alive_flag)
 +                      alive_flag=warm_target->add_frame(&surface);
 +#ifdef SINGLE_THREADED
 +              if (!single_threaded())
 +#endif
 +                      cond_frame_queue_empty.signal();
 +              ready_next=true;
 +      }
 +};
 +
 +/* === G L O B A L S ======================================================= */
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +/* === M E T H O D S ======================================================= */
 +
 +AsyncRenderer::AsyncRenderer(etl::handle<synfig::Target> target_,synfig::ProgressCallback *cb):
 +      error(false),
 +      success(false),
 +      cb(cb)
 +#ifdef SINGLE_THREADED
 +      , updating(false)
 +#endif
 +{
 +      render_thread=0;
 +      if(etl::handle<synfig::Target_Tile>::cast_dynamic(target_))
 +      {
 +              etl::handle<AsyncTarget_Tile> wrap_target(
 +                      new AsyncTarget_Tile(etl::handle<synfig::Target_Tile>::cast_dynamic(target_))
 +              );
 +
 +              signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Tile::set_dead));
 +
 +              target=wrap_target;
 +      }
 +      else if(etl::handle<synfig::Target_Scanline>::cast_dynamic(target_))
 +      {
 +              etl::handle<AsyncTarget_Scanline> wrap_target(
 +                      new AsyncTarget_Scanline(
 +                              etl::handle<synfig::Target_Scanline>::cast_dynamic(target_)
 +                      )
 +              );
 +
 +              signal_stop_.connect(sigc::mem_fun(*wrap_target,&AsyncTarget_Scanline::set_dead));
 +
 +              target=wrap_target;
 +      }
 +}
 +
 +AsyncRenderer::~AsyncRenderer()
 +{
 +      stop();
 +}
 +
 +void
 +AsyncRenderer::stop()
 +{
 +      if(target)
 +      {
 +              Glib::Mutex::Lock lock(mutex);
 +              done_connection.disconnect();
 +
 +              if(render_thread)
 +              {
 +                      signal_stop_();
 +
 +#if REJOIN_ON_STOP
 +#ifdef SINGLE_THREADED
 +                      if (!single_threaded())
 +#endif
 +                              render_thread->join();
 +#endif
 +
 +                      // Make sure all the dispatch crap is cleared out
 +                      //Glib::MainContext::get_default()->iteration(false);
 +
 +                      if(success)
 +                              signal_success_();
 +
 +                      signal_finished_();
 +
 +                      target=0;
 +                      render_thread=0;
 +              }
 +      }
 +}
 +
 +void
 +AsyncRenderer::pause()
 +{
 +}
 +
 +void
 +AsyncRenderer::resume()
 +{
 +}
 +
 +void
 +AsyncRenderer::start()
 +{
 +      done_connection=Glib::signal_timeout().connect(
 +              sigc::bind_return(
 +                      mem_fun(*this,&AsyncRenderer::start_),
 +                      false
 +              )
 +              ,50
 +      );
 +}
 +
 +#ifdef SINGLE_THREADED
 +void
 +AsyncRenderer::rendering_progress()
 +{
 +      updating = true;
 +      while(studio::App::events_pending()) studio::App::iteration(false);
 +      updating = false;
 +}
 +#endif
 +
 +void
 +AsyncRenderer::start_()
 +{
 +      error=false;success=false;
 +      if(target)
 +      {
 +#ifndef GLIB_DISPATCHER_BROKEN
 +              done_connection=signal_done_.connect(mem_fun(*this,&AsyncRenderer::stop));
 +#endif
 +
 +#ifdef SINGLE_THREADED
 +              if (single_threaded())
 +              {
++                      //synfig::info("%s:%d rendering in the same thread", __FILE__, __LINE__);
 +                      target->signal_progress().connect(sigc::mem_fun(this,&AsyncRenderer::rendering_progress));
 +                      render_thread = (Glib::Thread*)1;
 +                      render_target();
 +              }
 +              else
 +#endif
 +              {
 +                      render_thread=Glib::Thread::create(
 +                              sigc::mem_fun(*this,&AsyncRenderer::render_target),
 +#if REJOIN_ON_STOP
 +                              true
 +#else
 +                              false
 +#endif
 +                              );
 +                      assert(render_thread);
 +              }
 +      }
 +      else
 +      {
 +              stop();
 +      }
 +}
 +
 +void
 +AsyncRenderer::render_target()
 +{
 +      etl::handle<Target> target(AsyncRenderer::target);
 +
 +      if(target && target->render())
 +      {
 +              success=true;
 +      }
 +      else
 +      {
 +              error=true;
 +#ifndef REJOIN_ON_STOP
 +              return;
 +#endif
 +      }
 +
 +      if(mutex.trylock())
 +      {
 +#ifdef GLIB_DISPATCHER_BROKEN
 +              done_connection=Glib::signal_timeout().connect(
 +                      sigc::bind_return(
 +                              mem_fun(*this,&AsyncRenderer::stop),
 +                              false
 +                      )
 +                      ,0
 +              );
 +#else
 +              signal_done_.emit();
 +#endif
 +              mutex.unlock();
 +      }
 +}
index dc005ff,0000000..ef8404d
mode 100644,000000..100644
--- /dev/null
@@@ -1,248 -1,0 +1,254 @@@
-       set_copyright(_("Copyright 2001-2008\nRobert B. Quattlebaum Jr.,\nAdrian Bentley and Synfig contributors"));
 +/* === S Y N F I G ========================================================= */
 +/*!   \file about.cpp
 +**    \brief About dialog implementation
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2008 Paul Wise
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include <vector>
 +
 +#include <gtk/gtk.h>
 +
 +#include <gtkmm/aboutdialog.h>
 +
 +#include <ETL/stringf>
 +
 +#include <synfig/general.h>
 +
 +// This is generated at make time from .svn or .git/svn or autorevision.conf
 +#include <autorevision.h>
 +
 +#include "about.h"
 +#include "app.h"
 +
 +#include "general.h"
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +#ifndef VERSION
 +#define VERSION       "unknown"
 +#define PACKAGE       "synfigstudio"
 +#endif
 +
 +#ifdef WIN32
 +#     ifdef IMAGE_DIR
 +#             undef IMAGE_DIR
 +#             define IMAGE_DIR "share\\pixmaps"
 +#     endif
 +#endif
 +
 +#ifndef IMAGE_DIR
 +#     define IMAGE_DIR "/usr/local/share/pixmaps"
 +#endif
 +
 +#ifndef IMAGE_EXT
 +#     define IMAGE_EXT        "png"
 +#endif
 +
 +#define stringify_(x) #x
 +#define stringify(x) stringify_(x)
 +
 +/* === G L O B A L S ======================================================= */
 +
 +extern const guint gtk_major_version;
 +extern const guint gtk_minor_version;
 +extern const guint gtk_micro_version;
 +extern const guint gtk_binary_age;
 +extern const guint gtk_interface_age;
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +/* === M E T H O D S ======================================================= */
 +
 +About::About()
 +{
 +
 +#ifdef HAVE_GTK_ABOUTDIALOG_SET_PROGRAM_NAME
 +      set_program_name(PACKAGE_NAME);
 +#else
 +      set_name(PACKAGE_NAME);
 +#endif
 +      set_version(VERSION);
 +      set_comments(_("2D vector animation studio"));
 +
 +      set_url_hook(sigc::mem_fun(*this, &About::on_link_clicked));
 +      set_website("http://synfig.org/");
 +      set_website_label(_("Visit the Synfig website"));
 +
++      set_copyright(_("Copyright 2001-2010\nRobert B. Quattlebaum Jr.,\nAdrian Bentley and Synfig contributors"));
 +      Glib::ustring license =
 +              "This program is free software; you can redistribute it and/or modify "
 +              "it under the terms of the GNU General Public License as published by "
 +              "the Free Software Foundation; either version 2 of the License, or "
 +              "(at your option) any later version.\n\n"
 +
 +              "This program is distributed in the hope that it will be useful, "
 +              "but WITHOUT ANY WARRANTY; without even the implied warranty of "
 +              "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
 +              "GNU General Public License for more details.\n\n"
 +
 +              "You should have received a copy of the GNU General Public License along "
 +              "with this program; if not, write to the Free Software Foundation, Inc., "
 +              "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or visit: http://www.gnu.org/";
 +      set_license(license);
 +#ifdef HAVE_GTK_ABOUTDIALOG_SET_WRAP_LICENSE
 +      set_wrap_license(true);
 +#endif
 +
 +      std::vector<Glib::ustring> authors;
 +      authors.push_back(_("Original developers:"));
 +      authors.push_back("");
 +      authors.push_back("Robert B. Quattlebaum Jr (darco)");
 +      authors.push_back("Adrian Bentley");
 +      authors.push_back("");
 +      authors.push_back(_("Contributors:"));
 +      authors.push_back("");
 +      authors.push_back("Adrian Winchell (SnapSilverlight)");
 +      authors.push_back("Andreas Jochens");
++      authors.push_back("Brendon Higgins");
 +      authors.push_back("Carlos López González (genete)");
 +      authors.push_back("Carlos A. Sosa Navarro");
 +      authors.push_back("Chris Moore (dooglus)");
 +      authors.push_back("Chris Norman (pixelgeek)");
 +      authors.push_back("Cyril Brulebois (KiBi)");
 +      authors.push_back("Daniel Fort");
 +      authors.push_back("Daniel Hornung (rubikcube)");
 +      authors.push_back("David Roden (Bombe)");
 +      authors.push_back("Dmitriy Pomerantsev (Atrus)");
 +      authors.push_back("Douglas Lau");
 +      authors.push_back("Gerald Young (Yoyobuae)");
 +      authors.push_back("Gerco Ballintijn");
 +      authors.push_back("IL'dar AKHmetgaleev (AkhIL)");
 +      authors.push_back("Konstantin Dmitriev (zelgadis)");
 +      authors.push_back("Luka Pravica");
++      authors.push_back("Nikita Kitaev (nikitakit)");
 +      authors.push_back("Martin Michlmayr (tbm)");
 +      authors.push_back("Miguel Gea Milvaques (xerakko)");
 +      authors.push_back("Paul Wise (pabs)");
 +      authors.push_back("Ralf Corsepius");
 +      authors.push_back("Ray Frederikson");
 +      authors.push_back("Timo Paulssen (timonator)");
 +      authors.push_back("Yue Shi Lai");
 +      set_authors(authors);
 +
 +      std::vector<Glib::ustring> artists;
 +      artists.push_back("Aurore D (rore)");
++      artists.push_back("Bertrand Grégoire (berteh)");
 +      artists.push_back("Carlos López González (genete)");
 +      artists.push_back("Chris Norman (pixelgeek)");
 +      artists.push_back("Daniel Hornung (rubikcube)");
 +      artists.push_back("David Rylander (rylleman)");
 +      artists.push_back("Franco Iacomella (Yaco)");
 +      artists.push_back("Gerald Young (Yoyobuae)");
 +      artists.push_back("Henrique Lopes Barone");
++      artists.push_back("Konstantin Dmitriev (zelgadis)");
++      artists.push_back("Madeleine Crubellier (mad0)");
 +      artists.push_back("Robert B. Quattlebaum Jr. (darco)");
++      artists.push_back("Thimotee Guiet (satrip)");
 +
 +      set_artists(artists);
 +
 +      // TRANSLATORS: change this to your name, separate multiple names with \n
 +      set_translator_credits(_("translator-credits"));
 +
 +      std::string imagepath;
 +#ifdef WIN32
 +      imagepath=App::get_base_path()+ETL_DIRECTORY_SEPARATOR+IMAGE_DIR;
 +#else
 +      imagepath=IMAGE_DIR;
 +#endif
 +      char* synfig_root=getenv("SYNFIG_ROOT");
 +      if(synfig_root) {
 +              imagepath=synfig_root;
 +              imagepath+=ETL_DIRECTORY_SEPARATOR;
 +              imagepath+="share";
 +              imagepath+=ETL_DIRECTORY_SEPARATOR;
 +              imagepath+="pixmaps";
 +      }
 +      imagepath+=ETL_DIRECTORY_SEPARATOR;
 +
 +      Gtk::Image *Logo = manage(new class Gtk::Image());
 +      Logo->set(imagepath+"synfig_icon."IMAGE_EXT);
 +      set_logo(Logo->get_pixbuf());
 +
 +#ifdef SHOW_EXTRA_INFO
 +
 +      string extra_info = get_comments() + "\n";
 +
 +      #ifdef DEVEL_VERSION
 +              extra_info += strprintf(_("\nDevelopment version:\n%s\n"),DEVEL_VERSION);
 +      #endif
 +
 +      extra_info += "\n";
 +
 +      extra_info += strprintf(_("Built on %s" /* at %s */ "\n"), __DATE__ /* , __TIME__ */ );
 +
 +      extra_info += "\n";
 +
 +      extra_info += strprintf(_("Built with:\n"), ETL_VERSION);
 +      extra_info += strprintf(_("ETL %s\n"), ETL_VERSION);
 +      extra_info += strprintf(_("Synfig API %s\n"), stringify(SYNFIG_VERSION));
 +      extra_info += strprintf(_("Synfig library %d\n"), SYNFIG_LIBRARY_VERSION);
 +      extra_info += strprintf(_("GTK+ %d.%d.%d\n"), GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION);
 +      #ifdef __GNUC__
 +              extra_info += strprintf(_("GNU G++ %d.%d.%d\n"),__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__);
 +      #endif
 +
 +      extra_info += "\n";
 +
 +      extra_info += strprintf(_("Using:\n"), synfig::get_version());
 +      extra_info += strprintf(_("Synfig %s\n"), synfig::get_version());
 +      extra_info += strprintf(_("GTK+ %d.%d.%d"),gtk_major_version,gtk_minor_version,gtk_micro_version);
 +
 +      #ifdef _DEBUG
 +              extra_info += "\n\nDEBUG BUILD";
 +      #endif
 +
 +      set_comments(extra_info);
 +
 +#endif
 +
 +      // Hide the dialog when you click close
 +      signal_response().connect(sigc::mem_fun(*this, &About::close));
 +}
 +
 +void About::close(int){
 +      hide();
 +}
 +
 +void About::on_link_clicked(Gtk::AboutDialog&, const Glib::ustring &url)
 +{
 +      App::open_url(url);
 +}
index 03bb696,0000000..7c8250e
mode 100644,000000..100644
--- /dev/null
@@@ -1,150 -1,0 +1,182 @@@
-       "flv", "h263p", "huffyuv", "libtheora", "libx264", "libxvid",
 +/* === S Y N F I G ========================================================= */
 +/*!   \file dialog_targetparam.cpp
 +**    \brief Implementation for the TargetParam Dialog
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2010 Carlos López González
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include "dialogs/dialog_targetparam.h"
 +
 +#include "general.h"
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
++#define CUSTOM_VCODEC_DESCRIPTION _("Custom Video Codec")
++#define CUSTOM_VCODEC _("write your video codec here")
++
 +/* === G L O B A L S ======================================================= */
 +//! Allowed video codecs
 +/*! \warning This variable is linked to allowed_video_codecs_description,
 + *  if you change this you must change the other acordingly.
 + *  \warning These codecs are linked to the filename extensions for
 + *  mod_ffmpeg. If you change this you must change the others acordingly.
 + */
 +const char* allowed_video_codecs[] =
 +{
-       "msmpeg4v1", "msmpeg4v2", "wmv1", "wmv2", NULL
++      "flv", "h263p", "huffyuv", "libtheora", "libx264",
 +      "mjpeg", "mpeg1video", "mpeg2video", "mpeg4", "msmpeg4",
-       _("libxvidcore MPEG-4 part 2."),
++      "msmpeg4v1", "msmpeg4v2", "wmv1", "wmv2", CUSTOM_VCODEC, NULL
 +};
 +
 +//! Allowed video codecs description.
 +/*! \warning This variable is linked to allowed_video_codecs,
 + *  if you change this you must change the other acordingly.
 + */
 +const char* allowed_video_codecs_description[] =
 +{
 +      _("Flash Video (FLV) / Sorenson Spark / Sorenson H.263."),
 +      _("H.263+ / H.263-1998 / H.263 version 2."),
 +      _("Huffyuv / HuffYUV."),
 +      _("libtheora Theora."),
 +      _("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10."),
-       _("MPEG-4 part 2."),
 +      _("MJPEG (Motion JPEG)."),
 +      _("raw MPEG-1 video."),
 +      _("raw MPEG-2 video."),
- Dialog_TargetParam::Dialog_TargetParam(synfig::TargetParam &tparam)
++      _("MPEG-4 part 2. (XviD/DivX)"),
 +      _("MPEG-4 part 2 Microsoft variant version 3."),
 +      _("MPEG-4 part 2 Microsoft variant version 1."),
 +      _("MPEG-4 part 2 Microsoft variant version 2."),
 +      _("Windows Media Video 7."),
 +      _("Windows Media Video 8."),
++      CUSTOM_VCODEC_DESCRIPTION,
 +      NULL
 +};
 +/* === P R O C E D U R E S ================================================= */
 +
 +/* === M E T H O D S ======================================================= */
 +
 +/* === E N T R Y P O I N T ================================================= */
 +
-       set_title(_("TargetParam Dialog"));
++Dialog_TargetParam::Dialog_TargetParam(Gtk::Window &parent, synfig::TargetParam &tparam):
++      Gtk::Dialog(_("Target Parameters"), parent, false, true)
 +{
-       vcodec = Gtk::manage(new Gtk::ComboBoxText());
 +      set_tparam(tparam);
++      // Custom Video Codec Entry
++      Gtk::Label* custom_label(manage(new Gtk::Label(std::string(CUSTOM_VCODEC_DESCRIPTION)+":")));
++      custom_label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
++      customvcodec=Gtk::manage(new Gtk::Entry());
 +      // Available Video Codecs Combo Box Text.
-       get_vbox()->pack_start(*label, true, true, 0);
 +      Gtk::Label* label(manage(new Gtk::Label(_("Available Video Codecs:"))));
 +      label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
-       get_vbox()->pack_start(*vcodec, true, true, 0);
++      vcodec = Gtk::manage(new Gtk::ComboBoxText());
++      // Appends the codec descriptions to the Combo Box
 +      for (int i = 0; allowed_video_codecs[i] != NULL &&
 +                                      allowed_video_codecs_description[i] != NULL; i++)
 +              vcodec->append_text(allowed_video_codecs_description[i]);
++      //Adds the Combo Box and the Custom Video Codec entry to the vertical box
++      get_vbox()->pack_start(*label, true, true, 0);
++      get_vbox()->pack_start(*vcodec, true, true, 0);
++      get_vbox()->pack_start(*custom_label, true, true, 0);
++      get_vbox()->pack_start(*customvcodec, true, true, 0);
++
++      // Connect the signal change to the handler
++      vcodec->signal_changed().connect(sigc::mem_fun(*this, &Dialog_TargetParam::on_vcodec_change));
++      // By defaut, set the active text to the Custom Video Codec
++      vcodec->set_active_text(CUSTOM_VCODEC_DESCRIPTION);
++      customvcodec->set_text(CUSTOM_VCODEC);
++      //Compare the passed vcodec to the available and set it active if found
 +      for (int i = 0; allowed_video_codecs[i] != NULL &&
 +                                      allowed_video_codecs_description[i] != NULL; i++)
 +              if(!get_tparam().video_codec.compare(allowed_video_codecs[i]))
++              {
 +                      vcodec->set_active_text(allowed_video_codecs_description[i]);
-       std::string codecnamed = vcodec->get_active_text();
-       for (int i = 0; allowed_video_codecs[i] != NULL &&
-                                       allowed_video_codecs_description[i] != NULL; i++)
-               if(!codecnamed.compare(allowed_video_codecs_description[i]))
-                       tparam_.video_codec=allowed_video_codecs[i];
++                      customvcodec->set_text(allowed_video_codecs[i]);
++              }
 +
 +      //Bitrate Spin Button
 +      Gtk::Adjustment* bradj(manage(new class Gtk::Adjustment(double(tparam.bitrate), 10.0,1000.0)));
 +      bitrate = Gtk::manage(new class Gtk::SpinButton(*bradj));
 +      Gtk::Label* label2(manage(new Gtk::Label(_("Video Bit Rate:"))));
 +      label2->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
 +      get_vbox()->pack_start(*label2, true, true, 0);
 +      get_vbox()->pack_start(*bitrate,true, true, 0);
 +
 +      get_vbox()->show_all();
 +
 +      ok_button = manage(new class Gtk::Button(Gtk::StockID("gtk-ok")));
 +      ok_button->show();
 +      add_action_widget(*ok_button,Gtk::RESPONSE_OK);
 +      ok_button->signal_clicked().connect(sigc::mem_fun(*this,&Dialog_TargetParam::on_ok));
 +
 +      cancel_button = manage(new class Gtk::Button(Gtk::StockID("gtk-cancel")));
 +      cancel_button->show();
 +      add_action_widget(*cancel_button,Gtk::RESPONSE_CANCEL);
 +      cancel_button->signal_clicked().connect(sigc::mem_fun(*this,&Dialog_TargetParam::on_cancel));
 +
 +}
 +
 +void
 +Dialog_TargetParam::on_ok()
 +{
++      tparam_.video_codec=customvcodec->get_text().c_str();
 +      tparam_.bitrate=bitrate->get_value();
 +      hide();
 +}
 +
 +void
 +Dialog_TargetParam::on_cancel()
 +{
 +      hide();
 +}
 +
++void
++Dialog_TargetParam::on_vcodec_change()
++{
++      std::string codecnamed = vcodec->get_active_text();
++      customvcodec->set_sensitive(false);
++      for (int i = 0; allowed_video_codecs[i] != NULL &&
++                                      allowed_video_codecs_description[i] != NULL; i++)
++              if(!codecnamed.compare(allowed_video_codecs_description[i]))
++              {
++                      if(!codecnamed.compare(CUSTOM_VCODEC_DESCRIPTION))
++                              customvcodec->set_sensitive(true);
++                      else
++                              customvcodec->set_text(allowed_video_codecs[i]);
++              }
++}
++
 +Dialog_TargetParam::~Dialog_TargetParam()
 +{
 +}
 +
index 5575c20,0000000..8eb0c52
mode 100644,000000..100644
--- /dev/null
@@@ -1,71 -1,0 +1,73 @@@
-       Dialog_TargetParam(synfig::TargetParam &tparam);
 +/* === S Y N F I G ========================================================= */
 +/*!   \file dialogs/dialog_targetparam.h
 +**    \brief Targetparam Dialog Header
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2010 Carlos López González
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === S T A R T =========================================================== */
 +
 +#ifndef __SYNFIG_STUDIO_DIALOG_TARGETPARAM_H
 +#define __SYNFIG_STUDIO_DIALOG_TARGETPARAM_H
 +
 +/* === H E A D E R S ======================================================= */
 +#include <gtkmm/dialog.h>
 +#include <gtkmm/button.h>
 +#include <gtkmm/comboboxtext.h>
 +#include <gtkmm/spinbutton.h>
 +
 +#include <synfig/targetparam.h>
 +
 +/* === M A C R O S ========================================================= */
 +
 +/* === T Y P E D E F S ===================================================== */
 +
 +/* === C L A S S E S & S T R U C T S ======================================= */
 +
 +namespace studio {
 +
 +class Dialog_TargetParam : public Gtk::Dialog
 +{
 +      synfig::TargetParam tparam_;
 +      Gtk::Button *ok_button;
 +      Gtk::Button *cancel_button;
 +      Gtk::SpinButton *bitrate;
 +      Gtk::ComboBoxText *vcodec;
++      Gtk::Entry *customvcodec;
 +
 +      void on_ok();
 +      void on_cancel();
++      void on_vcodec_change();
 +
 +public:
++      Dialog_TargetParam(Gtk::Window &parent, synfig::TargetParam &tparam);
 +      ~Dialog_TargetParam();
 +
 +      synfig::TargetParam get_tparam() const { return tparam_; }
 +      void set_tparam(const synfig::TargetParam &tp) {tparam_=tp; }
 +
 +};
 +
 +}; // END of namespace studio
 +
 +/* === E N D =============================================================== */
 +
 +#endif
 +
 +
 +
index a6c2ad6,0000000..b3fe3ea
mode 100644,000000..100644
--- /dev/null
@@@ -1,328 -1,0 +1,313 @@@
- #define SCALE_FACTOR  (1280)
 +/* === S Y N F I G ========================================================= */
 +/*!   \file dockmanager.cpp
 +**    \brief Template File
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007, 2008 Chris Moore
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include "docks/dockmanager.h"
 +#include <stdexcept>
 +#include "docks/dockable.h"
 +#include "docks/dockdialog.h"
 +#include <synfigapp/settings.h>
 +#include <synfigapp/main.h>
 +#include <gdkmm/general.h>
 +
 +#include "general.h"
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +class studio::DockSettings : public synfigapp::Settings
 +{
 +      DockManager* dock_manager;
 +
 +public:
 +      DockSettings(DockManager* dock_manager):dock_manager(dock_manager)
 +      {
 +              synfigapp::Main::settings().add_domain(this,"dock");
 +      }
 +
 +      virtual ~DockSettings()
 +      {
 +              synfigapp::Main::settings().remove_domain("dock");
 +      }
-               int screen_w(Gdk::screen_width());
-               int screen_h(Gdk::screen_height());
 +      virtual bool get_value(const synfig::String& key_, synfig::String& value)const
 +      {
-                                       value+=strprintf("%d ",(*iter)*SCALE_FACTOR/screen_h);
 +
 +              if(key_.size()>6 && String(key_.begin(),key_.begin()+6)=="dialog")try
 +              {
 +                      synfig::String key(key_.begin()+7,key_.end());
 +                      synfig::String::size_type separator=key.find_first_of('.');
 +                      int id(atoi(synfig::String(key.begin(),key.begin()+separator).c_str()));
 +                      key=synfig::String(key.begin()+separator+1,key.end());
 +
 +                      DockDialog& dock_dialog(dock_manager->find_dock_dialog(id));
 +
 +                      if(key=="contents_size")
 +                      {
 +                              dock_dialog.rebuild_sizes();
 +                              vector<int>::const_iterator iter(dock_dialog.get_dock_book_sizes().begin());
 +                              vector<int>::const_iterator end(dock_dialog.get_dock_book_sizes().end());
 +                              value.clear();
 +                              for(;iter!=end;++iter)
-                               value=strprintf("%d %d",x*SCALE_FACTOR/screen_w,y*SCALE_FACTOR/screen_h);
++                                      value+=strprintf("%d ",*iter);
 +                              return true;
 +                      }
 +                      if(key=="pos")
 +                      {
 +                              int x,y; dock_dialog.get_position(x,y);
-                               value=strprintf("%d %d",x*SCALE_FACTOR/screen_w,y*SCALE_FACTOR/screen_h);
++                              value=strprintf("%d %d",x,y);
 +                              return true;
 +                      }
 +                      if(key=="size")
 +                      {
 +                              int x,y; dock_dialog.get_size(x,y);
-               int screen_w(Gdk::screen_width());
-               int screen_h(Gdk::screen_height());
++                              value=strprintf("%d %d",x,y);
 +                              return true;
 +                      }
 +                      if(key=="contents")
 +                      {
 +                              value=dock_dialog.get_contents();
 +                              return true;
 +                      }
 +                      if(key=="comp_selector")
 +                      {
 +                              value=dock_dialog.get_composition_selector()?"1":"0";
 +                              return true;
 +                      }
 +              }catch (...) { return false; }
 +              return synfigapp::Settings::get_value(key_,value);
 +      }
 +
 +      virtual bool set_value(const synfig::String& key_,const synfig::String& value)
 +      {
-                                       if (size > SCALE_FACTOR) size = SCALE_FACTOR - 150;
-                                       if (size < 0) size = 0;
-                                       size=size*screen_h/SCALE_FACTOR;
-                                       // prevent errors like this, by allowing space for at least the dockable's icon:
-                                       // ** CRITICAL **: clearlooks_style_draw_box_gap: assertion `height >= -1' failed
-                                       if (size < height + 9) size = height + 9;
 +
 +              if(key_.size()>6 && String(key_.begin(),key_.begin()+6)=="dialog")
 +              {
 +                      synfig::String key(key_.begin()+7,key_.end());
 +                      synfig::String::size_type separator=key.find_first_of('.');
 +                      int id(atoi(synfig::String(key.begin(),key.begin()+separator).c_str()));
 +                      key=synfig::String(key.begin()+separator+1,key.end());
 +
 +                      DockDialog& dock_dialog(dock_manager->find_dock_dialog(id));
 +
 +                      if(key=="contents_size")
 +                      {
 +                              try {
 +                              int width, height;
 +                              Gtk::IconSize::lookup(Gtk::IconSize(4),width,height);
 +                              vector<int> data;
 +                              String::size_type n=0;
 +                              String value_(value);
 +                              while(value_.size() && value_.size()>n){
 +                                      value_=String(value_.begin()+n,value_.end());
 +                                      int size;
 +                                      if(!strscanf(value_,"%d",&size))
 +                                              break;
-                               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"));
 +
 +                                      data.push_back(size);
 +
 +                                      n=value_.find(" ");
 +                                      if(n==String::npos)
 +                                              break;
 +                                      n++;
 +                              }
 +                              dock_dialog.set_dock_book_sizes(data);
 +                              }
 +                              catch(...)
 +                              {
 +                                      synfig::error("Exception caught!!!");
 +                                      return false;
 +                              }
 +                              return true;
 +                      }
 +                      if(key=="pos")
 +                      {
 +                              int x,y;
 +                              if(!strscanf(value,"%d %d",&x, &y))
 +                                      return false;
-                               if (x > SCALE_FACTOR) x = 150; if (x < 0) x = 0;
-                               if (y > SCALE_FACTOR) y = 150; if (y < 0) y = 0;
-                               x=x*screen_w/SCALE_FACTOR;
-                               y=y*screen_h/SCALE_FACTOR;
++                              //synfig::info("dock_manager. move to: %d, %d", x,y);
 +                              dock_dialog.move(x,y);
 +                              return true;
 +                      }
 +                      if(key=="size")
 +                      {
 +                              int x,y;
 +                              if(!strscanf(value,"%d %d",&x, &y))
 +                                      return false;
-       dock_dialog->show();
++                              //synfig::info("dock_manager. size to: %d, %d", x,y);
 +                              dock_dialog.set_default_size(x,y);
 +                              dock_dialog.resize(x,y);
 +                              return true;
 +                      }
 +                      if(key=="contents")
 +                      {
 +                              dock_dialog.set_contents(value);
 +                              return true;
 +                      }
 +                      if(key=="comp_selector")
 +                      {
 +                              if(value.empty() || value[0]=='0')
 +                                      dock_dialog.set_composition_selector(false);
 +                              else
 +                                      dock_dialog.set_composition_selector(true);
 +                              return true;
 +                      }
 +              }
 +              return synfigapp::Settings::set_value(key_,value);
 +      }
 +
 +      virtual KeyList get_key_list()const
 +      {
 +              synfigapp::Settings::KeyList ret(synfigapp::Settings::get_key_list());
 +
 +              std::list<DockDialog*>::const_iterator iter;
 +              for(iter=dock_manager->dock_dialog_list_.begin();iter!=dock_manager->dock_dialog_list_.end();++iter)
 +              {
 +                      ret.push_back(strprintf("dialog.%d.contents",(*iter)->get_id()));
 +                      ret.push_back(strprintf("dialog.%d.comp_selector",(*iter)->get_id()));
 +                      ret.push_back(strprintf("dialog.%d.pos",(*iter)->get_id()));
 +                      ret.push_back(strprintf("dialog.%d.size",(*iter)->get_id()));
 +                      ret.push_back(strprintf("dialog.%d.contents_size",(*iter)->get_id()));
 +              }
 +              return ret;
 +      }
 +};
 +
 +/* === M E T H O D S ======================================================= */
 +
 +DockManager::DockManager():
 +      dock_settings(new DockSettings(this))
 +{
 +}
 +
 +DockManager::~DockManager()
 +{
 +      while(!dock_dialog_list_.empty())
 +      {
 +              dock_dialog_list_.back()->close();
 +      }
 +      while(!dockable_list_.empty())
 +      {
 +              Dockable* dockable(dockable_list_.back());
 +              // synfig::info("DockManager::~DockManager(): Deleting dockable \"%s\"",dockable->get_name().c_str());
 +              dockable_list_.pop_back();
 +              delete dockable;
 +      }
 +}
 +
 +void
 +DockManager::register_dockable(Dockable& x)
 +{
 +      dockable_list_.push_back(&x);
 +      // synfig::info("DockManager::register_dockable(): Registered dockable \"%s\"",dockable_list_.back()->get_name().c_str());
 +      signal_dockable_registered()(&x);
 +}
 +
 +bool
 +DockManager::unregister_dockable(Dockable& x)
 +{
 +      std::list<Dockable*>::iterator iter;
 +      for(iter=dockable_list_.begin();iter!=dockable_list_.end();++iter)
 +      {
 +              if(&x==*iter)
 +              {
 +                      x.detach();
 +                      dockable_list_.erase(iter);
 +                      synfig::info("DockManager::unregister_dockable(): \"%s\" has been Unregistered",x.get_name().c_str());
 +                      return true;
 +              }
 +      }
 +      return false;
 +}
 +
 +Dockable&
 +DockManager::find_dockable(const synfig::String& x)
 +{
 +      std::list<Dockable*>::iterator iter;
 +      for(iter=dockable_list_.begin();iter!=dockable_list_.end();++iter)
 +              if((*iter)->get_name()==x)
 +                      return **iter;
 +
 +      throw std::runtime_error("DockManager::find_dockable(): not found");
 +}
 +
 +void
 +DockManager::present(synfig::String x)
 +{
 +      try
 +      {
 +              find_dockable(x).present();
 +      }
 +      catch(...)
 +      {
 +      }
 +}
 +
 +DockDialog&
 +DockManager::find_dock_dialog(int id)
 +{
 +      std::list<DockDialog*>::iterator iter;
 +      for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter)
 +              if((*iter)->get_id()==id)
 +                      return **iter;
 +
 +      DockDialog* dock_dialog(new DockDialog());
 +      dock_dialog->set_id(id);
 +      return *dock_dialog;
 +}
 +
 +const DockDialog&
 +DockManager::find_dock_dialog(int id)const
 +{
 +      std::list<DockDialog*>::const_iterator iter;
 +      for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter)
 +              if((*iter)->get_id()==id)
 +                      return **iter;
 +
 +      throw std::runtime_error("DockManager::find_dock_dialog(int id)const: not found");
 +}
++
++void
++DockManager::show_all_dock_dialogs()
++{
++      std::list<DockDialog*>::iterator iter;
++      for(iter=dock_dialog_list_.begin();iter!=dock_dialog_list_.end();++iter)
++              (*iter)->present();
++}
index 0949bcc,0000000..e92e06c
mode 100644,000000..100644
--- /dev/null
@@@ -1,82 -1,0 +1,83 @@@
 +/* === S Y N F I G ========================================================= */
 +/*!   \file docks/dockmanager.h
 +**    \brief Template Header
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === S T A R T =========================================================== */
 +
 +#ifndef __SYNFIG_DOCKMANAGER_H
 +#define __SYNFIG_DOCKMANAGER_H
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#include <vector>
 +#include <list>
 +#include <synfig/string.h>
 +#include <sigc++/signal.h>
 +#include <sigc++/object.h>
 +#include <ETL/smart_ptr>
 +
 +/* === M A C R O S ========================================================= */
 +
 +/* === T Y P E D E F S ===================================================== */
 +
 +/* === C L A S S E S & S T R U C T S ======================================= */
 +
 +namespace studio {
 +
 +class Dockable;
 +class DockDialog;
 +class DockSettings;
 +
 +class DockManager : public sigc::trackable
 +{
 +      friend class Dockable;
 +      friend class DockDialog;
 +      friend class DockSettings;
 +
 +      std::list<Dockable*> dockable_list_;
 +      std::list<DockDialog*> dock_dialog_list_;
 +
 +      sigc::signal<void,Dockable*> signal_dockable_registered_;
 +
 +      etl::smart_ptr<DockSettings> dock_settings;
 +
 +public:
 +      DockManager();
 +      ~DockManager();
 +
 +      DockDialog& find_dock_dialog(int id);
 +      const DockDialog& find_dock_dialog(int id)const;
 +
 +      sigc::signal<void,Dockable*>& signal_dockable_registered() { return signal_dockable_registered_; }
 +
 +      void register_dockable(Dockable& x);
 +      bool unregister_dockable(Dockable& x);
 +      Dockable& find_dockable(const synfig::String& x);
 +      void present(synfig::String x);
++      void show_all_dock_dialogs();
 +
 +}; // END of class DockManager
 +
 +}; // END of namespace studio
 +
 +/* === E N D =============================================================== */
 +
 +#endif
index 14ea8d0,0000000..da571f6
mode 100644,000000..100644
--- /dev/null
@@@ -1,300 -1,0 +1,300 @@@
-               int old_halves = round_to_int(Angle::deg(rotations).get()/180);
 +/* === S Y N F I G ========================================================= */
 +/*!   \file duck.cpp
 +**    \brief Template File
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007, 2008 Chris Moore
 +**    Copyright (c) 2009 Nikita Kitaev
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include "duck.h"
 +#include <ETL/misc>
 +
 +#include <synfig/valuenode_bline.h>
 +#include <synfig/valuenode_blinecalctangent.h>
 +#include <synfig/valuenode_blinecalcvertex.h>
 +#include <synfig/valuenode_blinecalcwidth.h>
 +#include <synfig/valuenode_composite.h>
 +
 +#include "general.h"
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +/* === G L O B A L S ======================================================= */
 +
 +int studio::Duck::duck_count(0);
 +
 +struct _DuckCounter
 +{
 +      static int counter;
 +      ~_DuckCounter()
 +      {
 +              if(counter)
 +                      synfig::error("%d ducks not yet deleted!",counter);
 +      }
 +} _duck_counter;
 +
 +int _DuckCounter::counter(0);
 +
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +/* === M E T H O D S ======================================================= */
 +
 +Duck::Duck():
 +      rotations(synfig::Angle::deg(0)),
 +      origin(0,0),
 +      scalar(1),
 +      editable(false),
 +      radius_(false),
 +      tangent_(false),
 +      hover_(false),
 +      ignore_(false)
 +{ duck_count++; _DuckCounter::counter++; }
 +
 +Duck::Duck(const synfig::Point &point):
 +      type_(TYPE_NONE),
 +      point(point),
 +      rotations(synfig::Angle::deg(0)),
 +      origin(0,0),
 +      scalar(1),
 +      guid_(0),
 +      editable(false),
 +      radius_(false),
 +      tangent_(false),
 +      hover_(false),
 +      ignore_(false)
 +{ duck_count++; _DuckCounter::counter++;}
 +
 +Duck::Duck(const synfig::Point &point,const synfig::Point &origin):
 +      point(point),
 +      rotations(synfig::Angle::deg(0)),
 +      origin(origin),
 +      scalar(1),
 +      guid_(0),
 +      editable(false),
 +      radius_(true),
 +      tangent_(false),
 +      hover_(false),
 +      ignore_(false)
 +{ duck_count++; _DuckCounter::counter++;}
 +
 +Duck::~Duck() { duck_count--; _DuckCounter::counter--;}
 +
 +synfig::GUID
 +Duck::get_data_guid()const
 +{
 +      if(value_desc_.is_value_node())
 +              return value_desc_.get_value_node()->get_guid();
 +      return synfig::GUID::hasher(get_name());
 +}
 +
 +void
 +Duck::set_name(const synfig::String &x)
 +{
 +      name=x;
 +      if(guid_==synfig::GUID::zero())
 +      {
 +              guid_=synfig::GUID::hasher(name);
 +      }
 +}
 +
 +
 +bool
 +Duck::operator==(const Duck &rhs)const
 +{
 +      if(this==&rhs)
 +              return true;
 +      return
 +              name==rhs.name &&
 +              scalar==rhs.scalar &&
 +              type_==rhs.type_ &&
 +              transform_stack_.size()==rhs.transform_stack_.size();
 +              //true;
 +              //(origin_duck?*origin_duck==*rhs.origin_duck:origin==rhs.origin) &&
 +              //(shared_point?*shared_point==*rhs.shared_point:point==rhs.point) ;
 +}
 +
 +synfig::Point
 +Duck::get_trans_point()const
 +{
 +      return transform_stack_.perform(get_sub_trans_point());
 +}
 +
 +void
 +Duck::set_trans_point(const synfig::Point &x)
 +{
 +      set_sub_trans_point(transform_stack_.unperform(x));
 +}
 +
 +void
 +Duck::set_trans_point(const synfig::Point &x, const synfig::Time &time)
 +{
 +      set_sub_trans_point(transform_stack_.unperform(x), time);
 +}
 +
 +//! Sets the origin point.
 +void
 +Duck::set_origin(const synfig::Point &x)
 +{
 +      origin=x; origin_duck=0;
 +}
 +
 +//! Sets the origin point as another duck
 +void
 +Duck::set_origin(const etl::handle<Duck> &x)
 +{
 +      origin_duck=x;
 +}
 +
 +//! Retrieves the origin location
 +synfig::Point
 +Duck::get_origin()const
 +{
 +      return origin_duck?origin_duck->get_point():origin;
 +}
 +
 +//! Retrieves the origin duck
 +const etl::handle<Duck> &
 +Duck::get_origin_duck() const
 +{
 +      return origin_duck;
 +}
 +
 +//! Retrieves the origin location
 +synfig::Point
 +Duck::get_trans_origin()const
 +{
 +      return transform_stack_.perform(get_sub_trans_origin());
 +}
 +
 +synfig::Point
 +Duck::get_sub_trans_point()const
 +{
 +      return get_point()*get_scalar()+get_sub_trans_origin();
 +}
 +
 +void
 +Duck::set_sub_trans_point(const synfig::Point &x, const synfig::Time &time)
 +{
 +      if (get_type() == Duck::TYPE_TANGENT ||
 +              get_type() == Duck::TYPE_ANGLE)
 +      {
 +              Angle old_angle = get_point().angle();
 +              set_point((x-get_sub_trans_origin())/get_scalar());
 +              Angle change = get_point().angle() - old_angle;
 +              while (change < Angle::deg(-180)) change += Angle::deg(360);
 +              while (change > Angle::deg(180)) change -= Angle::deg(360);
-               int new_halves = round_to_int(Angle::deg(rotations).get()/180);
-               if (old_halves != new_halves &&
++              //int old_halves = round_to_int(Angle::deg(rotations).get()/180);
 +              rotations += change;
-                       synfig::info("rotation: %.2f turns", new_halves/2.0);
++              //int new_halves = round_to_int(Angle::deg(rotations).get()/180);
++              /*if (old_halves != new_halves &&
 +                      (new_halves > 1 || new_halves < -1 ||
 +                       old_halves > 1 || old_halves < -1))
-               int old_halves = round_to_int(Angle::deg(rotations).get()/180);
++                      synfig::info("rotation: %.2f turns", new_halves/2.0)*/;
 +      } else if(get_type() == Duck::TYPE_VERTEX || get_type() == Duck::TYPE_POSITION)
 +      {
 +              set_point((x-get_sub_trans_origin())/get_scalar());
 +
 +              ValueNode_BLineCalcVertex::Handle bline_vertex;
 +              ValueNode_Composite::Handle composite;
 +
 +              if ((bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(get_value_desc().get_value_node())) ||
 +                      ((composite = ValueNode_Composite::Handle::cast_dynamic(get_value_desc().get_value_node())) &&
 +                       composite->get_type() == ValueBase::TYPE_BLINEPOINT &&
 +                       (bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(composite->get_link("point")))))
 +              {
 +                      synfig::Point closest_point = get_point();
 +                      synfig::Real radius = 0.0;
 +                      ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline")));
 +                      synfig::find_closest_point(
 +                              (*bline)(time),
 +                              get_point(),
 +                              radius,
 +                              bline->get_loop(),
 +                              &closest_point);
 +                      set_point(closest_point);
 +              }
 +      }
 +      else set_point((x-get_sub_trans_origin())/get_scalar());
 +}
 +
 +void
 +Duck::set_sub_trans_point(const synfig::Point &x)
 +{
 +      if (get_type() == Duck::TYPE_TANGENT ||
 +              get_type() == Duck::TYPE_ANGLE)
 +      {
 +              Angle old_angle = get_point().angle();
 +              set_point((x-get_sub_trans_origin())/get_scalar());
 +              Angle change = get_point().angle() - old_angle;
 +              while (change < Angle::deg(-180)) change += Angle::deg(360);
 +              while (change > Angle::deg(180)) change -= Angle::deg(360);
-               int new_halves = round_to_int(Angle::deg(rotations).get()/180);
-               if (old_halves != new_halves &&
++              //int old_halves = round_to_int(Angle::deg(rotations).get()/180);
 +              rotations += change;
-                       synfig::info("rotation: %.2f turns", new_halves/2.0);
++              //int new_halves = round_to_int(Angle::deg(rotations).get()/180);
++              /*if (old_halves != new_halves &&
 +                      (new_halves > 1 || new_halves < -1 ||
 +                       old_halves > 1 || old_halves < -1))
++                      synfig::info("rotation: %.2f turns", new_halves/2.0);*/
 +      }
 +      else set_point((x-get_sub_trans_origin())/get_scalar());
 +}
 +
 +synfig::Point
 +Duck::get_sub_trans_origin()const
 +{
 +      return origin_duck?origin_duck->get_sub_trans_point():origin;
 +}
 +
 +#ifdef _DEBUG
 +synfig::String
 +Duck::type_name(Type id)
 +{
 +      String ret;
 +
 +      if (id & TYPE_POSITION) { if (!ret.empty()) ret += ", "; ret += "position"; }
 +      if (id & TYPE_TANGENT ) { if (!ret.empty()) ret += ", "; ret += "tangent" ; }
 +      if (id & TYPE_RADIUS  ) { if (!ret.empty()) ret += ", "; ret += "radius"  ; }
 +      if (id & TYPE_WIDTH       ) { if (!ret.empty()) ret += ", "; ret += "width"   ; }
 +      if (id & TYPE_ANGLE       ) { if (!ret.empty()) ret += ", "; ret += "angle"   ; }
 +      if (id & TYPE_VERTEX  ) { if (!ret.empty()) ret += ", "; ret += "vertex"  ; }
 +
 +      if (ret.empty())
 +              ret = "none";
 +
 +      return ret;
 +}
 +#endif        // _DEBUG
index 87e7edb,0000000..5b5a8d1
mode 100644,000000..100644
--- /dev/null
@@@ -1,548 -1,0 +1,548 @@@
-       INIT_STOCK_ICON(normal,"normal_icon."IMAGE_EXT,_("Normal Tool"));
 +/* === S Y N F I G ========================================================= */
 +/*!   \file iconcontroller.cpp
 +**    \brief Template File
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007, 2008 Chris Moore
 +**  Copyright (c) 2008 Paul Wise
 +**  Copyright (c) 2009 Gerco Ballintijn
 +**    Copyright (c) 2009 Carlos López
 +**    Copyright (c) 2009 Nikita Kitaev
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include "iconcontroller.h"
 +#include <synfig/valuenode_const.h>
 +#include <gtkmm/button.h>
 +#include <gtkmm/window.h>
 +#include <synfigapp/action.h>
 +
 +#include "general.h"
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace etl;
 +using namespace std;
 +using namespace studio;
 +using namespace synfig;
 +
 +/* === M A C R O S ========================================================= */
 +
 +#ifdef WIN32
 +#     ifdef IMAGE_DIR
 +#             undef IMAGE_DIR
 +#             define IMAGE_DIR "share\\pixmaps"
 +#     endif
 +#endif
 +
 +#ifndef IMAGE_DIR
 +#     define IMAGE_DIR "/usr/local/share/pixmaps"
 +#endif
 +
 +
 +#ifndef IMAGE_EXT
 +#     define IMAGE_EXT        "png"
 +#endif
 +
 +/* === M E T H O D S ======================================================= */
 +
 +static Glib::RefPtr<Gdk::Pixbuf> _tree_pixbuf_table_value_type[(int)synfig::ValueBase::TYPE_END];
 +
 +#ifdef WIN32
 +IconController::IconController(const synfig::String& basepath)
 +#else
 +IconController::IconController(const synfig::String& /*basepath*/)
 +#endif
 +{
 +      Gtk::IconSource icon_source;
 +      icon_source.set_direction_wildcarded();
 +      icon_source.set_state_wildcarded();
 +      icon_source.set_size_wildcarded();
 +      icon_factory=Gtk::IconFactory::create();
 +
 +      std::string path_to_icons;
 +#ifdef WIN32
 +      path_to_icons=basepath+ETL_DIRECTORY_SEPARATOR+".."+ETL_DIRECTORY_SEPARATOR+IMAGE_DIR;
 +#else
 +      path_to_icons=IMAGE_DIR;
 +#endif
 +
 +      char* synfig_root=getenv("SYNFIG_ROOT");
 +      if(synfig_root) {
 +              path_to_icons=synfig_root;
 +              path_to_icons+=ETL_DIRECTORY_SEPARATOR;
 +              path_to_icons+="share";
 +              path_to_icons+=ETL_DIRECTORY_SEPARATOR;
 +              path_to_icons+="pixmaps";
 +              path_to_icons+=ETL_DIRECTORY_SEPARATOR;
 +              path_to_icons+="synfigstudio";
 +      }
 +      path_to_icons+=ETL_DIRECTORY_SEPARATOR;
 +
 +      try{
 +      Gtk::Window::set_default_icon_from_file(path_to_icons+"synfig_icon."+IMAGE_EXT);
 +      } catch(...)
 +      {
 +              synfig::warning("Unable to open "+path_to_icons+"synfig_icon."+IMAGE_EXT);
 +      }
 +
 +#define INIT_STOCK_ICON(name,iconfile,desc){                                                  \
 +      Gtk::StockItem stockitem(Gtk::StockID("synfig-" #name),desc); \
 +      Gtk::Stock::add(stockitem);                                                             \
 +      Gtk::IconSet icon_set;                                                                  \
 +      icon_source.set_filename(path_to_icons+iconfile);                                                       \
 +      icon_set.add_source(icon_source);                                               \
 +      icon_factory->add(stockitem.get_stock_id(),icon_set); \
 +      }
 +
 +#define INIT_STOCK_ICON_CLONE(name,stockid,desc){                                                     \
 +      Gtk::StockItem stockitem(Gtk::StockID("synfig-" #name),desc); \
 +      Gtk::Stock::add(stockitem);                                                             \
 +      Gtk::IconSet icon_set;                                                                  \
 +      if(Gtk::Stock::lookup(stockitem.get_stock_id(),icon_set))       \
 +      icon_factory->add(stockitem.get_stock_id(),icon_set); \
 +      }
 +
 +#define INIT_STOCK_ITEM(name,desc)                                                    \
 +      stock_##name=Gtk::StockItem(Gtk::StockID("synfig-" #name),desc);                        \
 +      Gtk::Stock::add(stock_##name);
 +
 +      INIT_STOCK_ICON(bool,"bool_icon."IMAGE_EXT,_("Bool"));
 +      INIT_STOCK_ICON(integer,"integer_icon."IMAGE_EXT,_("Integer"));
 +      INIT_STOCK_ICON(angle,"angle_icon."IMAGE_EXT,_("Angle"));
 +      INIT_STOCK_ICON(time,"time_icon."IMAGE_EXT,_("Time"));
 +      INIT_STOCK_ICON(real,"real_icon."IMAGE_EXT,_("Real"));
 +      INIT_STOCK_ICON(vector,"vector_icon."IMAGE_EXT,_("Vector"));
 +      INIT_STOCK_ICON(color,"color_icon."IMAGE_EXT,_("Color"));
 +      INIT_STOCK_ICON(segment,"segment_icon."IMAGE_EXT,_("Segment"));
 +      INIT_STOCK_ICON(blinepoint,"blinepoint_icon."IMAGE_EXT,_("BLine Point"));
 +      INIT_STOCK_ICON(list,"list_icon."IMAGE_EXT,_("Rename"));
 +      INIT_STOCK_ICON(canvas,"canvas_icon."IMAGE_EXT,_("Canvas"));
 +      INIT_STOCK_ICON(string,"string_icon."IMAGE_EXT,_("Rename"));
 +
 +      INIT_STOCK_ICON(reset_colors,"reset_colors_icon."IMAGE_EXT,_("Reset Colors"));
 +      INIT_STOCK_ICON(swap_colors,"swap_colors_icon."IMAGE_EXT,_("Swap Colors"));
 +      INIT_STOCK_ICON(value_node,"valuenode_icon."IMAGE_EXT,_("ValueNode"));
 +      INIT_STOCK_ICON(about,"about_icon."IMAGE_EXT,_("About"));
 +      INIT_STOCK_ICON(rename,"rename_icon."IMAGE_EXT,_("Rename"));
 +      INIT_STOCK_ICON(canvas_pointer,"canvas_pointer_icon."IMAGE_EXT,_("Rename"));
 +      INIT_STOCK_ICON(canvas_new,"canvas_icon."IMAGE_EXT,_("New Canvas"));
 +      INIT_STOCK_ICON(saveall,"saveall_icon."IMAGE_EXT,_("Save All"));
 +
 +      INIT_STOCK_ICON(layer,"layer_icon."IMAGE_EXT,_("Layer"));
 +      INIT_STOCK_ICON(layer_pastecanvas,"pastecanvas_icon."IMAGE_EXT,_("Paste Canvas"));
 +      INIT_STOCK_ICON(layer_duplicate,"layer_duplicate_icon."IMAGE_EXT,_("Duplicate Layer"));
 +      INIT_STOCK_ICON(layer_gradient_lineal,"gradient_icon."IMAGE_EXT,_("Lineal Gradient Layer"));
 +      INIT_STOCK_ICON(layer_gradient_radial,"layer_gradient_radial_icon."IMAGE_EXT,_("Radial Gradient Layer"));
 +      INIT_STOCK_ICON(layer_gradient_spiral,"layer_gradient_spiral_icon."IMAGE_EXT,_("Spiral Gradient Layer"));
 +      INIT_STOCK_ICON(layer_gradient_curve,"layer_gradient_curve_icon."IMAGE_EXT,_("Curve Gradient Layer"));
 +      INIT_STOCK_ICON(layer_gradient_conical,"layer_gradient_conical_icon."IMAGE_EXT,_("Conical Gradient Layer"));
 +      INIT_STOCK_ICON(layer_gradient_noise,"layer_gradient_noise_icon."IMAGE_EXT,_("Noise Gradient Layer"));
 +      INIT_STOCK_ICON(layer_checkerboard,"layer_checkerboard_icon."IMAGE_EXT,_("Checker Board Layer"));
 +      INIT_STOCK_ICON(layer_blur,"layer_blur_icon."IMAGE_EXT,_("Blur Layer"));
 +      INIT_STOCK_ICON(layer_blur_motion,"layer_blur_motion_icon."IMAGE_EXT,_("Motion Blur Layer"));
 +      INIT_STOCK_ICON(layer_blur_radial,"layer_blur_radial_icon."IMAGE_EXT,_("Radial Blur Layer"));
 +      INIT_STOCK_ICON(layer_distortion_curvewarp,"layer_distortion_curvewarp_icon."IMAGE_EXT,_("Curve Warp Layer"));
 +      INIT_STOCK_ICON(layer_distortion_insideout,"layer_distortion_insideout_icon."IMAGE_EXT,_("Inside Out Layer"));
 +      INIT_STOCK_ICON(layer_distortion_noise,"layer_distortion_noise_icon."IMAGE_EXT,_("Noise Distort Layer"));
 +      INIT_STOCK_ICON(layer_distortion_spherize,"layer_distortion_spherize_icon."IMAGE_EXT,_("Spherize Layer"));
 +      INIT_STOCK_ICON(layer_distortion_stretch,"layer_distortion_stretch_icon."IMAGE_EXT,_("Stretch Layer"));
 +      INIT_STOCK_ICON(layer_distortion_twirl,"layer_distortion_twirl_icon."IMAGE_EXT,_("Twirl Layer"));
 +      INIT_STOCK_ICON(layer_distortion_warp,"layer_distortion_warp_icon."IMAGE_EXT,_("Warp Layer"));
 +      INIT_STOCK_ICON(layer_filter_clamp,"layer_filter_clamp_icon."IMAGE_EXT,_("Clamp Layer"));
 +      INIT_STOCK_ICON(layer_filter_colorcorrect,"layer_filter_colorcorrect_icon."IMAGE_EXT,_("Color Correct Layer"));
 +      INIT_STOCK_ICON(layer_filter_halftone2,"layer_filter_halftone2_icon."IMAGE_EXT,_("Half Tone 2 Layer"));
 +      INIT_STOCK_ICON(layer_filter_halftone3,"layer_filter_halftone3_icon."IMAGE_EXT,_("Half Tone 3 Layer"));
 +      INIT_STOCK_ICON(layer_filter_luma,"layer_filter_luma_icon."IMAGE_EXT,_("Luma Layer"));
 +      INIT_STOCK_ICON(layer_fractal_mandelbrot,"layer_fractal_mandelbrot_icon."IMAGE_EXT,_("Mandelbrot Set Layer"));
 +      INIT_STOCK_ICON(layer_fractal_julia,"layer_fractal_julia_icon."IMAGE_EXT,_("Julia Set Layer"));
 +      INIT_STOCK_ICON(layer_stylize_bevel,"layer_stylize_bevel_icon."IMAGE_EXT,_("Bevel Layer"));
 +      INIT_STOCK_ICON(layer_stylize_shade,"layer_stylize_shade_icon."IMAGE_EXT,_("Shade Layer"));
 +      INIT_STOCK_ICON(layer_example_metaballs,"layer_example_metaballs_icon."IMAGE_EXT,_("Metaballs Layer"));
 +      INIT_STOCK_ICON(layer_other_XOR,"layer_other_XOR_icon."IMAGE_EXT,_("XOR Pattern Layer"));
 +      INIT_STOCK_ICON(layer_other_supersample,"layer_other_supersample_icon."IMAGE_EXT,_("Super Sample Layer"));
 +      INIT_STOCK_ICON(layer_other_timeloop,"layer_other_timeloop_icon."IMAGE_EXT,_("Time Loop Layer"));
 +      INIT_STOCK_ICON(layer_transform_translate,"layer_transform_translate_icon."IMAGE_EXT,_("Translate Layer"));
 +
 +      INIT_STOCK_ICON(plant,"plant_icon."IMAGE_EXT,"");
 +
 +      INIT_STOCK_ICON(group,"group_icon."IMAGE_EXT,_("Group"));
 +      INIT_STOCK_ICON(grid_enable,"grid_enable_icon."IMAGE_EXT,_("Show Grid"));
 +      INIT_STOCK_ICON(grid_disable,"grid_disable_icon."IMAGE_EXT,_("Hide Grid"));
 +      INIT_STOCK_ICON(grid_snap_enable,"grid_snap_enable_icon."IMAGE_EXT,_("Enable Grid Snap"));
 +      INIT_STOCK_ICON(grid_snap_disable,"grid_snap_disable_icon."IMAGE_EXT,_("Disable Grid Snap"));
 +      INIT_STOCK_ICON(duplicate,"duplicate_icon."IMAGE_EXT,_("Duplicate"));
 +      INIT_STOCK_ICON(encapsulate,"encapsulate_icon."IMAGE_EXT,_("Encapsulate"));
 +      INIT_STOCK_ICON(select_all_child_layers,"select_all_child_layers_icon."IMAGE_EXT,_("Select All Child Layers"));
 +
 +      INIT_STOCK_ICON(clear_undo,"clear_undo_icon."IMAGE_EXT,_("Clear Undo Stack"));
 +      INIT_STOCK_ICON(clear_redo,"clear_redo_icon."IMAGE_EXT,_("Clear Redo Stack"));
 +
 +      INIT_STOCK_ICON(children,"children_icon."IMAGE_EXT,_("Children"));
 +      INIT_STOCK_ICON(curves,"curves_icon."IMAGE_EXT,_("Curves"));
 +      INIT_STOCK_ICON(keyframes,"keyframe_icon."IMAGE_EXT,_("Keyframes"));
 +      INIT_STOCK_ICON(meta_data,"meta_data_icon."IMAGE_EXT,_("MetaData"));
 +      INIT_STOCK_ICON(navigator,"navigator_icon."IMAGE_EXT,_("Navigator"));
 +      INIT_STOCK_ICON(timetrack,"time_track_icon."IMAGE_EXT,_("Time Track"));
 +
 +      INIT_STOCK_ICON(keyframe_lock_all,"keyframe_lock_all."IMAGE_EXT,_("All Keyframes Locked"));
 +      INIT_STOCK_ICON(keyframe_lock_past,"keyframe_lock_past."IMAGE_EXT,_("Past Keyframes Locked"));
 +      INIT_STOCK_ICON(keyframe_lock_future,"keyframe_lock_future."IMAGE_EXT,_("Future Keyframes Locked"));
 +      INIT_STOCK_ICON(keyframe_lock_none,"keyframe_lock_none."IMAGE_EXT,_("No Keyframes Locked"));
 +
 +      INIT_STOCK_ICON(set_outline_color,"set_outline_color."IMAGE_EXT,_("Set as Outline"));
 +      INIT_STOCK_ICON(set_fill_color,"set_fill_color."IMAGE_EXT,_("Set as Fill"));
 +
 +      INIT_STOCK_ICON(seek_begin,"seek_begin."IMAGE_EXT,_("Seek to Begin"));
 +      INIT_STOCK_ICON(seek_prev_frame,"seek_prev_frame."IMAGE_EXT,_("Previous Frame"));
 +      INIT_STOCK_ICON(seek_next_frame,"seek_next_frame."IMAGE_EXT,_("Next Frame"));
 +      INIT_STOCK_ICON(seek_end,"seek_end."IMAGE_EXT,_("Seek to End"));
 +      INIT_STOCK_ICON(add_to_group,"action_add_to_group_icon."IMAGE_EXT,_("Add Layer to Group"));
 +      INIT_STOCK_ICON(remove_from_group,"action_remove_from_group_icon."IMAGE_EXT,_("Remove Layer from Group"));
 +      INIT_STOCK_ICON(set_desc,"action_set_layer_description_icon."IMAGE_EXT,_("Set Layer Description"));
 +      INIT_STOCK_ICON(export,"action_export_icon."IMAGE_EXT,_("Export Value Node"));
 +      INIT_STOCK_ICON(unexport,"action_unexport_icon."IMAGE_EXT,_("Unexport Value Node"));
 +
 +      INIT_STOCK_ICON(toggle_duck_position,"duck_position_icon."IMAGE_EXT,_("Toggle position ducks"));
 +      INIT_STOCK_ICON(toggle_duck_vertex,"duck_vertex_icon."IMAGE_EXT,_("Toggle vertex ducks"));
 +      INIT_STOCK_ICON(toggle_duck_tangent,"duck_tangent_icon."IMAGE_EXT,_("Toggle tangent ducks"));
 +      INIT_STOCK_ICON(toggle_duck_radius,"duck_radius_icon."IMAGE_EXT,_("Toggle radius ducks"));
 +      INIT_STOCK_ICON(toggle_duck_width,"duck_width_icon."IMAGE_EXT,_("Toggle width ducks"));
 +      INIT_STOCK_ICON(toggle_duck_angle,"duck_angle_icon."IMAGE_EXT,_("Toggle angle ducks"));
 +
 +      INIT_STOCK_ICON(toggle_show_grid,"show_grid_icon."IMAGE_EXT,_("Toggle show grid"));
 +      INIT_STOCK_ICON(toggle_snap_grid,"snap_grid_icon."IMAGE_EXT,_("Toggle snap grid"));
 +
 +      INIT_STOCK_ICON(toggle_onion_skin,"onion_skin_icon."IMAGE_EXT,_("Toggle onion skin"));
 +
 +      INIT_STOCK_ICON(increase_resolution,"incr_resolution_icon."IMAGE_EXT,_("Increase resolution"));
 +      INIT_STOCK_ICON(decrease_resolution,"decr_resolution_icon."IMAGE_EXT,_("Decrease resolution"));
 +
 +      INIT_STOCK_ICON(preview_options,"preview_options_icon."IMAGE_EXT,_("Preview Options Dialog"));
 +      INIT_STOCK_ICON(render_options,"render_options_icon."IMAGE_EXT,_("Render Options Dialog"));
 +
 +      INIT_STOCK_ICON_CLONE(cvs_add,"gtk-add",_("CVS Add"));
 +      INIT_STOCK_ICON_CLONE(cvs_update,"gtk-open",_("CVS Update"));
 +      INIT_STOCK_ICON_CLONE(cvs_commit,"gtk-save",_("CVS Commit"));
 +      INIT_STOCK_ICON_CLONE(cvs_revert,"gtk-revert",_("CVS Revert"));
 +
 +      // Tools
++      INIT_STOCK_ICON(normal,"normal_icon."IMAGE_EXT,_("Transform Tool"));
 +      INIT_STOCK_ICON(transform,"transform_icon."IMAGE_EXT,_("Transform Tool"));
 +      INIT_STOCK_ICON(polygon,"polyline_icon."IMAGE_EXT,_("Polygon Tool"));
 +      INIT_STOCK_ICON(bline,"bline_icon."IMAGE_EXT,_("BLine Tool"));
 +      INIT_STOCK_ICON(eyedrop,"eyedrop_icon."IMAGE_EXT,_("Eyedrop Tool"));
 +      INIT_STOCK_ICON(fill,"fill_icon."IMAGE_EXT,_("Fill Tool"));
 +      INIT_STOCK_ICON(draw,"draw_icon."IMAGE_EXT,_("Draw Tool"));
 +      INIT_STOCK_ICON(sketch,"sketch_icon."IMAGE_EXT,_("Sketch Tool"));
 +      INIT_STOCK_ICON(circle,"circle_icon."IMAGE_EXT,_("Circle Tool"));
 +      INIT_STOCK_ICON(rectangle,"rectangle_icon."IMAGE_EXT,_("Rectangle Tool"));
 +      INIT_STOCK_ICON(smooth_move,"smooth_move_icon."IMAGE_EXT,_("SmoothMove Tool"));
 +      INIT_STOCK_ICON(rotate,"rotate_icon."IMAGE_EXT,"Rotate Tool");
 +      INIT_STOCK_ICON(width,"width_icon."IMAGE_EXT,_("Width Tool"));
 +      INIT_STOCK_ICON(scale,"scale_icon."IMAGE_EXT,"Scale Tool");
 +      INIT_STOCK_ICON(zoom,"zoom_icon."IMAGE_EXT,_("Zoom Tool"));
 +      INIT_STOCK_ICON(info,"info_icon."IMAGE_EXT,_("Info Tool"));
 +      INIT_STOCK_ICON(mirror,"mirror_icon."IMAGE_EXT,_("Mirror Tool"));
 +      INIT_STOCK_ICON(text,"text_icon."IMAGE_EXT,"Text Tool");
 +      INIT_STOCK_ICON(gradient,"gradient_icon."IMAGE_EXT,_("Gradient Tool"));
 +      INIT_STOCK_ICON(star,"star_icon."IMAGE_EXT,_("Star Tool"));
 +
 +#undef INIT_STOCK_ICON
 +#undef INIT_STOCK_ICON
 +
 +      icon_factory->add_default();
 +
 +      Gtk::IconSize::register_new("synfig-small_icon",12,12);
 +      Gtk::IconSize::register_new("synfig-small_icon_16x16",16,16);
 +
 +      for(int i(0);i<(int)ValueBase::TYPE_END;i++)
 +              _tree_pixbuf_table_value_type[i]=Gtk::Button().render_icon(value_icon(ValueBase::Type(i)),Gtk::ICON_SIZE_SMALL_TOOLBAR);
 +
 +}
 +
 +IconController::~IconController()
 +{
 +      for(int i(0);i<(int)ValueBase::TYPE_END;i++)
 +              _tree_pixbuf_table_value_type[i]=Glib::RefPtr<Gdk::Pixbuf>();
 +
 +      icon_factory->remove_default();
 +}
 +
 +Gdk::Cursor
 +IconController::get_normal_cursor()
 +{
 +      return Gdk::Cursor(Gdk::TOP_LEFT_ARROW);
 +}
 +
 +Gdk::Cursor
 +IconController::get_tool_cursor(const Glib::ustring& name,const Glib::RefPtr<Gdk::Window>& window)
 +{
 +      //this function is never called
 +      //it is commented out in WorkArea::refresh_cursor()
 +      assert(0);
 +      // \todo Do we still need it?
 +
 +      Glib::RefPtr<Gdk::Pixmap> pixmap;
 +      pixmap=Gdk::Pixmap::create(window, 64, 64, 8);
 +      pixmap->set_colormap(window->get_colormap());
 +      //pixmap->set_colormap(Gdk::Colormap::create(pixmap->get_visual(),false));
 +      Glib::RefPtr<Gdk::Pixbuf> pixbuf;
 +      pixbuf=Gtk::Button().render_icon(Gtk::StockID("synfig-"+name),Gtk::ICON_SIZE_SMALL_TOOLBAR);
 +
 +      pixbuf->render_to_drawable_alpha(
 +              pixmap,
 +              0,0,    // SOURCE X,Y
 +              0,0,    // DEST X Y
 +              -1,-1,  // WIDTH HEIGHT
 +              Gdk::PIXBUF_ALPHA_FULL, // (ignored)
 +              64,             //int alpha_threshold,
 +              Gdk::RGB_DITHER_MAX,            //RgbDither dither,
 +              2,2     //int x_dither, int y_dither
 +      );
 +/*
 +      pixmap->draw_pixbuf(
 +              Glib::RefPtr<const Gdk::GC>(0), // GC
 +              pixbuf,
 +              0, 0, // Source X,Y
 +              0, 0, // Dest X,Y
 +              -1, -1, // Width, Height
 +              Gdk::RGB_DITHER_MAX, // Dither
 +              0,0 // Dither X,Y
 +      );
 +*/
 +
 +      Gdk::Color FG("#000000");
 +      Gdk::Color BG("#FF00FF");
 +
 +      return Gdk::Cursor(pixmap, pixmap, FG, BG, 0, 0);
 +}
 +
 +Gtk::StockID
 +studio::value_icon(synfig::ValueBase::Type type)
 +{
 +              switch(type)
 +              {
 +              case ValueBase::TYPE_BOOL:
 +                      return Gtk::StockID("synfig-bool");
 +                      break;
 +              case ValueBase::TYPE_INTEGER:
 +                      return Gtk::StockID("synfig-integer");
 +                      break;
 +              case ValueBase::TYPE_ANGLE:
 +                      return Gtk::StockID("synfig-angle");
 +                      break;
 +              case ValueBase::TYPE_TIME:
 +                      return Gtk::StockID("synfig-time");
 +                      break;
 +              case ValueBase::TYPE_REAL:
 +                      return Gtk::StockID("synfig-real");
 +                      break;
 +              case ValueBase::TYPE_VECTOR:
 +                      return Gtk::StockID("synfig-vector");
 +                      break;
 +              case ValueBase::TYPE_COLOR:
 +                      return Gtk::StockID("synfig-color");
 +                      break;
 +              case ValueBase::TYPE_SEGMENT:
 +                      return Gtk::StockID("synfig-segment");
 +                      break;
 +              case ValueBase::TYPE_BLINEPOINT:
 +                      return Gtk::StockID("synfig-blinepoint");
 +                      break;
 +              case ValueBase::TYPE_LIST:
 +                      return Gtk::StockID("synfig-list");
 +                      break;
 +              case ValueBase::TYPE_CANVAS:
 +                      return Gtk::StockID("synfig-canvas_pointer");
 +                      break;
 +              case ValueBase::TYPE_STRING:
 +                      return Gtk::StockID("synfig-string");
 +                      break;
 +              case ValueBase::TYPE_GRADIENT:
 +                      return Gtk::StockID("synfig-gradient");
 +                      break;
 +              case ValueBase::TYPE_NIL:
 +              default:
 +                      return Gtk::StockID("synfig-unknown");
 +                      break;
 +              }
 +}
 +
 +Gtk::StockID
 +studio::valuenode_icon(etl::handle<synfig::ValueNode> value_node)
 +{
 +      if(handle<ValueNode_Const>::cast_dynamic(value_node))
 +      {
 +              return value_icon(value_node->get_type());
 +      }
 +      else
 +      {
 +              return Gtk::StockID("synfig-value_node");
 +      }
 +}
 +
 +Glib::RefPtr<Gdk::Pixbuf>
 +studio::get_tree_pixbuf(synfig::ValueBase::Type type)
 +{
 +      //return Gtk::Button().render_icon(value_icon(type),Gtk::ICON_SIZE_SMALL_TOOLBAR);
 +      return _tree_pixbuf_table_value_type[int(type)];
 +}
 +
 +#ifdef WIN32
 +#define TEMPORARY_DELETE_MACRO DELETE
 +#undef DELETE
 +#endif
 +
 +Gtk::StockID
 +studio::get_action_stock_id(const synfigapp::Action::BookEntry& action)
 +{
 +      Gtk::StockID stock_id;
 +      if(action.task=="add")                          stock_id=Gtk::Stock::ADD;
 +      else if(action.task=="connect")         stock_id=Gtk::Stock::CONNECT;
 +      else if(action.task=="disconnect")      stock_id=Gtk::Stock::DISCONNECT;
 +      else if(action.task=="insert")          stock_id=Gtk::Stock::ADD;
 +      else if(action.task=="lower")           stock_id=Gtk::Stock::GO_DOWN;
 +      else if(action.task=="move_bottom")     stock_id=Gtk::Stock::GOTO_BOTTOM;
 +      else if(action.task=="move_top")        stock_id=Gtk::Stock::GOTO_TOP;
 +      else if(action.task=="raise")           stock_id=Gtk::Stock::GO_UP;
 +      else if(action.task=="remove")          stock_id=Gtk::Stock::DELETE;
 +      else if(action.task=="set_off")         stock_id=Gtk::Stock::NO;
 +      else if(action.task=="set_on")          stock_id=Gtk::Stock::YES;
 +      else                                                            stock_id=Gtk::StockID("synfig-"+
 +                                                                                                                        action.task);
 +      return stock_id;
 +}
 +
 +#ifdef WIN32
 +#define DELETE TEMPORARY_DELETE_MACRO
 +#undef TEMPORARY_DELETE_MACRO
 +#endif
 +
 +Gtk::StockID
 +studio::layer_icon(const synfig::String &layer)
 +{
 +      if(layer=="PasteCanvas" || layer=="pastecanvas" || layer=="paste_canvas")
 +              return Gtk::StockID("synfig-layer_pastecanvas");
 +      else if(layer=="rotate")
 +              return Gtk::StockID("synfig-rotate");
 +      else if(layer=="zoom")
 +              return Gtk::StockID("synfig-zoom");
 +      else if(layer=="region")
 +              return Gtk::StockID("synfig-bline");
 +      else if(layer=="polygon")
 +              return Gtk::StockID("synfig-polygon");
 +      else if(layer=="outline")
 +              return Gtk::StockID("synfig-width");
 +      else if(layer=="circle")
 +              return Gtk::StockID("synfig-circle");
 +      else if(layer=="rectangle")
 +              return Gtk::StockID("synfig-rectangle");
 +      else if(layer=="star")
 +              return Gtk::StockID("synfig-star");
 +      else if(layer=="plant")
 +              return Gtk::StockID("synfig-plant");
 +      else if(layer=="text")
 +              return Gtk::StockID("synfig-text");
 +      else if(layer=="checker_board")
 +              return Gtk::StockID("synfig-layer_checkerboard");
 +      else if(layer=="duplicate")
 +              return Gtk::StockID("synfig-layer_duplicate");
 +      else if(layer=="linear_gradient")
 +              return Gtk::StockID("synfig-layer_gradient_lineal");
 +      else if(layer=="radial_gradient")
 +              return Gtk::StockID("synfig-layer_gradient_radial");
 +      else if(layer=="spiral_gradient")
 +              return Gtk::StockID("synfig-layer_gradient_spiral");
 +      else if(layer=="curve_gradient")
 +              return Gtk::StockID("synfig-layer_gradient_curve");
 +      else if(layer=="conical_gradient")
 +              return Gtk::StockID("synfig-layer_gradient_conical");
 +      else if(layer=="noise")
 +              return Gtk::StockID("synfig-layer_gradient_noise");
 +      else if(layer=="blur")
 +              return Gtk::StockID("synfig-layer_blur");
 +      else if(layer=="radial_blur")
 +              return Gtk::StockID("synfig-layer_blur_radial");
 +      else if(layer=="MotionBlur") // in the future should be "motion_blur"
 +              return Gtk::StockID("synfig-layer_blur_motion");
 +      else if(layer=="curve_warp")
 +              return Gtk::StockID("synfig-layer_distortion_curvewarp");
 +      else if(layer=="inside_out")
 +              return Gtk::StockID("synfig-layer_distortion_insideout");
 +      else if(layer=="noise_distort")
 +              return Gtk::StockID("synfig-layer_distortion_noise");
 +      else if(layer=="spherize")
 +              return Gtk::StockID("synfig-layer_distortion_spherize");
 +      else if(layer=="stretch")
 +              return Gtk::StockID("synfig-layer_distortion_stretch");
 +      else if(layer=="twirl")
 +              return Gtk::StockID("synfig-layer_distortion_twirl");
 +      else if(layer=="warp")
 +              return Gtk::StockID("synfig-layer_distortion_warp");
 +      else if(layer=="clamp")
 +              return Gtk::StockID("synfig-layer_filter_clamp");
 +      else if(layer=="colorcorrect")
 +              return Gtk::StockID("synfig-layer_filter_colorcorrect");
 +      else if(layer=="halftone2")
 +              return Gtk::StockID("synfig-layer_filter_halftone2");
 +      else if(layer=="halftone3")
 +              return Gtk::StockID("synfig-layer_filter_halftone3");
 +      else if(layer=="lumakey")
 +              return Gtk::StockID("synfig-layer_filter_luma");
 +      else if(layer=="mandelbrot")
 +              return Gtk::StockID("synfig-layer_fractal_mandelbrot");
 +      else if(layer=="julia")
 +              return Gtk::StockID("synfig-layer_fractal_julia");
 +      else if(layer=="bevel")
 +              return Gtk::StockID("synfig-layer_stylize_bevel");
 +      else if(layer=="shade")
 +              return Gtk::StockID("synfig-layer_stylize_shade");
 +      else if(layer=="metaballs")
 +              return Gtk::StockID("synfig-layer_example_metaballs");
 +      else if(layer=="simple_circle")
 +              return Gtk::StockID("synfig-circle");
 +      else if(layer=="filled_rectangle")
 +              return Gtk::StockID("synfig-rectangle");
 +      else if(layer=="xor_pattern")
 +              return Gtk::StockID("synfig-layer_other_XOR");
 +      else if(layer=="super_sample")
 +              return Gtk::StockID("synfig-layer_other_supersample");
 +      else if(layer=="timeloop")
 +              return Gtk::StockID("synfig-layer_other_timeloop");
 +      else if(layer=="translate")
 +              return Gtk::StockID("synfig-layer_transform_translate");
 +      else
 +              return Gtk::StockID("synfig-layer");
 +}
 +
 +Glib::RefPtr<Gdk::Pixbuf>
 +studio::get_tree_pixbuf_layer(const synfig::String &layer)
 +{
 +      return Gtk::Button().render_icon(layer_icon(layer),Gtk::ICON_SIZE_SMALL_TOOLBAR);
 +}
index 870a356,0000000..a94a94c
mode 100644,000000..100644
--- /dev/null
@@@ -1,380 -1,0 +1,382 @@@
-       tparam("libxvid",200)
 +/* === S Y N F I G ========================================================= */
 +/*!   \file gtkmm/render.cpp
 +**    \brief Template File
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007, 2008 Chris Moore
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include "render.h"
 +#include "app.h"
 +#include <gtkmm/frame.h>
 +#include <gtkmm/alignment.h>
 +#include <synfig/target_scanline.h>
 +#include <synfig/canvas.h>
 +#include "asyncrenderer.h"
 +#include "dialogs/dialog_targetparam.h"
 +
 +#include "general.h"
 +
 +#include <fstream>
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +/* === G L O B A L S ======================================================= */
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +/* === M E T H O D S ======================================================= */
 +
 +RenderSettings::RenderSettings(Gtk::Window& parent, etl::handle<synfigapp::CanvasInterface> canvas_interface):
 +      Gtk::Dialog(_("Render Settings"),parent,false,true),
 +      canvas_interface_(canvas_interface),
 +      adjustment_quality(3,0,9),
 +      entry_quality(adjustment_quality,1,0),
 +      adjustment_antialias(1,1,31),
 +      entry_antialias(adjustment_antialias,1,0),
 +      toggle_single_frame(_("Use _current frame"), true),
-       Gtk::Button *tparam_button(manage(new class Gtk::Button(Gtk::StockID(_("Parameters...")))));
++      tparam("mpeg4",200)
 +{
 +      widget_rend_desc.show();
 +      widget_rend_desc.signal_changed().connect(sigc::mem_fun(*this,&studio::RenderSettings::on_rend_desc_changed));
 +      widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
 +
 +      canvas_interface->signal_rend_desc_changed().connect(sigc::mem_fun(*this,&RenderSettings::on_rend_desc_changed));
 +
 +      menu_target=manage(new class Gtk::Menu());
 +
 +      menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Auto"),
 +                      sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),String())
 +              ));
 +
 +      synfig::Target::Book::iterator iter;
 +      synfig::Target::Book book(synfig::Target::book());
 +
 +      for(iter=book.begin();iter!=book.end();iter++)
 +      {
 +              menu_target->items().push_back(Gtk::Menu_Helpers::MenuElem(iter->first,
 +                      sigc::bind(sigc::mem_fun(*this,&RenderSettings::set_target),iter->first)
 +              ));
 +      }
 +      optionmenu_target.set_menu(*menu_target);
 +
 +      optionmenu_target.set_history(0);
 +
 +      Gtk::Alignment *dialogPadding = manage(new Gtk::Alignment(0, 0, 1, 1));
 +      dialogPadding->set_padding(12, 12, 12, 12);
 +      get_vbox()->pack_start(*dialogPadding, false, false, 0);
 +
 +      Gtk::VBox *dialogBox = manage(new Gtk::VBox(false, 12));
 +      dialogPadding->add(*dialogBox);
 +
 +      Gtk::Button *choose_button(manage(new class Gtk::Button(Gtk::StockID(_("Choose...")))));
 +      choose_button->show();
 +      choose_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_choose_pressed));
 +
-       Dialog_TargetParam *dialogtp = new Dialog_TargetParam(tparam);
++      tparam_button=manage(new class Gtk::Button(Gtk::StockID(_("Parameters..."))));
 +      tparam_button->show();
++      tparam_button->set_sensitive(false);
 +      tparam_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_targetparam_pressed));
 +
 +      Gtk::Frame *target_frame=manage(new Gtk::Frame(_("Target")));
 +      target_frame->set_shadow_type(Gtk::SHADOW_NONE);
 +      ((Gtk::Label *) target_frame->get_label_widget())->set_markup(_("<b>Target</b>"));
 +      dialogBox->pack_start(*target_frame);
 +      Gtk::Alignment *targetPadding = manage(new Gtk::Alignment(0, 0, 1, 1));
 +      targetPadding->set_padding(6, 0, 24, 0);
 +      target_frame->add(*targetPadding);
 +
 +      Gtk::Table *target_table = manage(new Gtk::Table(2, 3, false));
 +      target_table->set_row_spacings(6);
 +      target_table->set_col_spacings(12);
 +      targetPadding->add(*target_table);
 +
 +      Gtk::Label *filenameLabel = manage(new Gtk::Label(_("_Filename"), true));
 +      filenameLabel->set_alignment(0, 0.5);
 +      filenameLabel->set_mnemonic_widget(entry_filename);
 +      target_table->attach(*filenameLabel, 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +      target_table->attach(entry_filename, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +      target_table->attach(*choose_button, 2, 3, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +
 +      Gtk::Label *targetLabel = manage(new Gtk::Label(_("_Target"), true));
 +      targetLabel->set_alignment(0, 0.5);
 +      targetLabel->set_mnemonic_widget(optionmenu_target);
 +      target_table->attach(*targetLabel, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +      target_table->attach(optionmenu_target, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +      target_table->attach(*tparam_button, 2, 3, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +
 +      toggle_single_frame.signal_toggled().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_single_frame_toggle));
 +
 +      Gtk::Frame *settings_frame=manage(new Gtk::Frame(_("Settings")));
 +      settings_frame->set_shadow_type(Gtk::SHADOW_NONE);
 +      ((Gtk::Label *) settings_frame->get_label_widget())->set_markup(_("<b>Settings</b>"));
 +      dialogBox->pack_start(*settings_frame);
 +
 +      Gtk::Alignment *settingsPadding = manage(new Gtk::Alignment(0, 0, 1, 1));
 +      settingsPadding->set_padding(6, 0, 24, 0);
 +      settings_frame->add(*settingsPadding);
 +
 +      Gtk::Table *settings_table=manage(new Gtk::Table(2,2,false));
 +      settings_table->set_row_spacings(6);
 +      settings_table->set_col_spacings(12);
 +      settingsPadding->add(*settings_table);
 +
 +      Gtk::Label *qualityLabel = manage(new Gtk::Label(_("_Quality"), true));
 +      qualityLabel->set_alignment(0, 0.5);
 +      qualityLabel->set_mnemonic_widget(entry_quality);
 +      settings_table->attach(*qualityLabel, 0, 1, 0, 1, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +      settings_table->attach(entry_quality, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +
 +      Gtk::Label *antiAliasLabel = manage(new Gtk::Label(_("_Anti-Aliasing"), true));
 +      antiAliasLabel->set_alignment(0, 0.5);
 +      antiAliasLabel->set_mnemonic_widget(entry_antialias);
 +      settings_table->attach(*antiAliasLabel, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +      settings_table->attach(entry_antialias, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +
 +      toggle_single_frame.set_alignment(0, 0.5);
 +      settings_table->attach(toggle_single_frame, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK|Gtk::FILL, 0, 0);
 +
 +      dialogBox->pack_start(widget_rend_desc);
 +
 +
 +      Gtk::Button *render_button(manage(new class Gtk::Button(Gtk::StockID(_("Render")))));
 +      render_button->show();
 +      add_action_widget(*render_button,1);
 +      render_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_render_pressed));
 +
 +      Gtk::Button *cancel_button(manage(new class Gtk::Button(Gtk::StockID("gtk-cancel"))));
 +      cancel_button->show();
 +      add_action_widget(*cancel_button,0);
 +      cancel_button->signal_clicked().connect(sigc::mem_fun(*this, &studio::RenderSettings::on_cancel_pressed));
 +
 +      //set_default_response(1);
 +
 +      set_title(_("Render Settings")+String(" - ")+canvas_interface_->get_canvas()->get_name());
 +
 +      toggle_single_frame.set_active(false);
 +      widget_rend_desc.enable_time_section();
 +
 +      set_entry_filename();
 +
 +      get_vbox()->show_all();
 +}
 +
 +RenderSettings::~RenderSettings()
 +{
 +}
 +
 +void
 +RenderSettings::set_entry_filename()
 +{
 +      String filename(filename_sans_extension(canvas_interface_->get_canvas()->get_file_name()));
 +
 +      // if this isn't the root canvas, append (<canvasname>) to the filename
 +      etl::handle<synfig::Canvas> canvas = canvas_interface_->get_canvas();
 +      if (!canvas->is_root())
 +      {
 +              if(canvas->get_name().empty())
 +                      filename+=" ("+canvas->get_id()+')';
 +              else
 +                      filename+=" ("+canvas->get_name()+')';
 +      }
 +
 +      filename += ".png";
 +
 +      try
 +      {
 +              entry_filename.set_text((filename));
 +      }
 +      catch(...)
 +      {
 +              synfig::warning("Averted crash!");
 +              entry_filename.set_text("output.png");
 +      }
 +}
 +
 +void
 +RenderSettings::on_rend_desc_changed()
 +{
 +      widget_rend_desc.set_rend_desc(canvas_interface_->get_canvas()->rend_desc());
 +}
 +
 +void
 +RenderSettings::set_target(synfig::String name)
 +{
 +      target_name=name;
++      tparam_button->set_sensitive(target_name.compare("ffmpeg")?false:true);
 +}
 +
 +void
 +RenderSettings::on_choose_pressed()
 +{
 +      String filename=entry_filename.get_text();
 +      if(App::dialog_save_file("Save Render As", filename, RENDER_DIR_PREFERENCE))
 +              entry_filename.set_text(filename);
 +}
 +
 +void
 +RenderSettings::on_targetparam_pressed()
 +{
++      Dialog_TargetParam *dialogtp = new Dialog_TargetParam(*this, tparam);
 +      if(dialogtp->run()==Gtk::RESPONSE_OK)
 +              tparam=dialogtp->get_tparam();
 +
 +      delete dialogtp;
 +}
 +
 +void
 +RenderSettings::on_render_pressed()
 +{
 +      String filename=entry_filename.get_text();
 +      synfig::String calculated_target_name(target_name);
 +
 +      if(filename.empty())
 +      {
 +              canvas_interface_->get_ui_interface()->error(_("You must supply a filename!"));
 +              return;
 +      }
 +
 +      // If the target type is not yet defined,
 +      // try to figure it out from the outfile.
 +      if(calculated_target_name.empty())
 +      {
 +              try
 +              {
 +                      String ext(filename_extension(filename));
 +                      if (ext.size()) ext=ext.substr(1); // skip initial '.'
 +                      synfig::info("render target filename: '%s'; extension: '%s'", filename.c_str(), ext.c_str());
 +                      if(Target::ext_book().count(ext))
 +                      {
 +                              calculated_target_name=Target::ext_book()[ext];
 +                              synfig::info("'%s' is a known extension - using target '%s'", ext.c_str(), calculated_target_name.c_str());
 +                      }
 +                      else
 +                      {
 +                              calculated_target_name=ext;
 +                              synfig::info("unknown extension");
 +                      }
 +              }
 +              catch(std::runtime_error x)
 +              {
 +                      canvas_interface_->get_ui_interface()->error(_("Unable to determine proper target from filename."));
 +                      return;
 +              }
 +      }
 +
 +      if(filename.empty() && calculated_target_name!="null")
 +      {
 +              canvas_interface_->get_ui_interface()->error(_("A filename is required for this target"));
 +              return;
 +      }
 +
 +      Target::Handle target=Target::create(calculated_target_name,filename, tparam);
 +      if(!target)
 +      {
 +              canvas_interface_->get_ui_interface()->error(_("Unable to create target for ")+filename);
 +              return;
 +      }
 +      // This is the only way I've found to avoid send a non writable
 +      // filename path to the renderer.
 +      fstream filetest (filename.c_str(), fstream::out);
 +      if (filetest.fail())
 +      {
 +              canvas_interface_->get_ui_interface()->error(_("Unable to create file for ")+filename);
 +              return;
 +      }
 +
 +      hide();
 +
 +      target->set_canvas(canvas_interface_->get_canvas());
 +      RendDesc rend_desc(widget_rend_desc.get_rend_desc());
 +      rend_desc.set_antialias((int)adjustment_antialias.get_value());
 +
 +      // If we are to only render the current frame
 +      if(toggle_single_frame.get_active())
 +              rend_desc.set_time(canvas_interface_->get_time());
 +
 +      target->set_rend_desc(&rend_desc);
 +      target->set_quality((int)adjustment_quality.get_value());
 +      if( !target->init() ){
 +              canvas_interface_->get_ui_interface()->error(_("Target initialization failure"));
 +              return;
 +      }
 +
 +      canvas_interface_->get_ui_interface()->task(_("Rendering ")+filename);
 +
 +      if(async_renderer)
 +      {
 +              async_renderer->stop();
 +              async_renderer.detach();
 +      }
 +      async_renderer=new AsyncRenderer(target);
 +      async_renderer->signal_finished().connect( sigc::mem_fun(*this,&RenderSettings::on_finished));
 +      async_renderer->start();
 +      /*
 +      if(!target->render(canvas_interface_->get_ui_interface().get()))
 +      {
 +              canvas_interface_->get_ui_interface()->error(_("Render Failure"));
 +              canvas_interface_->get_ui_interface()->amount_complete(0,10000);
 +              return;
 +      }
 +
 +      // Success!
 +      canvas_interface_->get_ui_interface()->task(filename+_(" rendered successfully"));
 +      canvas_interface_->get_ui_interface()->amount_complete(0,10000);
 +      */
 +      return;
 +}
 +
 +void
 +RenderSettings::on_finished()
 +{
 +      canvas_interface_->get_ui_interface()->task(_("File rendered successfully"));
 +      canvas_interface_->get_ui_interface()->amount_complete(0,10000);
 +}
 +
 +void
 +RenderSettings::on_cancel_pressed()
 +{
 +      hide();
 +}
 +
 +void
 +RenderSettings::on_single_frame_toggle()
 +{
 +      if(toggle_single_frame.get_active())
 +              widget_rend_desc.disable_time_section();
 +      else
 +              widget_rend_desc.enable_time_section();
 +}
index 729251b,0000000..ac26cbc
mode 100644,000000..100644
--- /dev/null
@@@ -1,108 -1,0 +1,109 @@@
 +/* === S Y N F I G ========================================================= */
 +/*!   \file gtkmm/render.h
 +**    \brief Template Header
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007 Chris Moore
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === S T A R T =========================================================== */
 +
 +#ifndef __SYNFIG_STUDIO_GTKMM_RENDER_H
 +#define __SYNFIG_STUDIO_GTKMM_RENDER_H
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#include <gtkmm/dialog.h>
 +#include <gtkmm/tooltips.h>
 +#include <gtkmm/table.h>
 +#include <gtkmm/entry.h>
 +#include <gtkmm/adjustment.h>
 +#include <gtkmm/spinbutton.h>
 +#include <gtkmm/checkbutton.h>
 +#include <gtkmm/tooltips.h>
 +#include <gtkmm/optionmenu.h>
 +
 +#include <synfig/string.h>
 +#include <synfig/targetparam.h>
 +
 +#include <synfigapp/canvasinterface.h>
 +
 +#include "renddesc.h"
 +
 +/* === M A C R O S ========================================================= */
 +
 +/* === T Y P E D E F S ===================================================== */
 +
 +/* === C L A S S E S & S T R U C T S ======================================= */
 +
 +namespace studio
 +{
 +class AsyncRenderer;
 +
 +class RenderSettings : public Gtk::Dialog
 +{
 +      Gtk::Tooltips tooltips;
 +
 +      etl::handle<synfigapp::CanvasInterface> canvas_interface_;
 +      Widget_RendDesc widget_rend_desc;
 +
 +      Gtk::Entry entry_filename;
 +
 +      Gtk::Adjustment adjustment_quality;
 +      Gtk::SpinButton entry_quality;
 +
 +      Gtk::Adjustment adjustment_antialias;
 +      Gtk::SpinButton entry_antialias;
 +
 +      Gtk::CheckButton toggle_single_frame;
 +
 +      Gtk::OptionMenu optionmenu_target;
 +      Gtk::Menu *menu_target;
++      Gtk::Button *tparam_button;
 +
 +      synfig::String target_name;
 +
 +      void set_target(synfig::String name);
 +
 +      etl::handle<AsyncRenderer> async_renderer;
 +
 +      synfig::TargetParam tparam;
 +
 +public:
 +      RenderSettings(Gtk::Window& parent,etl::handle<synfigapp::CanvasInterface> canvas_interface);
 +      ~RenderSettings();
 +      void set_entry_filename();
 +
 +private:
 +
 +      void on_rend_desc_changed();
 +      void on_single_frame_toggle();
 +      void on_choose_pressed();
 +      void on_render_pressed();
 +      void on_cancel_pressed();
 +      void on_targetparam_pressed();
 +
 +      void on_finished();
 +}; // END of class RenderSettings
 +
 +}; // END of namespace studio
 +
 +
 +/* === E N D =============================================================== */
 +
 +#endif
index fe87f01,0000000..d952fd1
mode 100644,000000..100644
--- /dev/null
@@@ -1,252 -1,0 +1,258 @@@
-       splash_image->set(imagepath+"splash_screen."IMAGE_EXT);
 +/* === S Y N F I G ========================================================= */
 +/*!   \file splash.cpp
 +**    \brief writeme
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007 Chris Moore
 +**    Copyright (c) 2008 Paul Wise
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +**
 +** === N O T E S ===========================================================
 +**
 +** ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include <iostream>
 +#include <string>
 +
 +#include <ETL/stringf>
 +
 +#include <gtkmm/image.h>
 +#include <gtkmm/label.h>
 +#include <gtkmm/frame.h>
 +#include <gtkmm/fixed.h>
 +
 +#include <synfig/general.h>
 +
 +#include "splash.h"
 +#include "app.h"
 +
 +#include "general.h"
 +
 +#endif
 +
 +using namespace std;
 +using namespace etl;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +#ifndef VERSION
 +#define VERSION       "unknown"
 +#define PACKAGE       "synfigstudio"
 +#endif
 +
 +#ifdef WIN32
 +#     ifdef IMAGE_DIR
 +#             undef IMAGE_DIR
 +#             define IMAGE_DIR "share\\pixmaps"
 +#     endif
 +#endif
 +
 +#ifndef IMAGE_DIR
 +#     define IMAGE_DIR "/usr/local/share/pixmaps"
 +#endif
 +
 +#ifndef IMAGE_EXT
 +#     define IMAGE_EXT        "png"
 +#endif
 +
 +/* === G L O B A L S ======================================================= */
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +class studio::SplashProgress : public synfig::ProgressCallback
 +{
 +      Splash &splash;
 +
 +public:
 +
 +      SplashProgress(Splash &splash):splash(splash) { }
 +
 +      virtual bool task(const std::string &task)
 +      {
 +              if(splash.tasklabel)
 +              {
 +                      splash.tasklabel->set_label(task);
 +                      splash.tasklabel->show();
 +              }
 +              else
 +              {
 +                      cerr<<task<<endl;
 +              }
 +
 +              while(studio::App::events_pending())studio::App::iteration(false);
 +              return true;
 +      }
 +
 +      virtual bool error(const std::string &task)
 +      {
 +              if(splash.tasklabel)
 +              {
 +                      splash.tasklabel->set_label(_("ERROR:")+task);
 +                      splash.tasklabel->show();
 +              }
 +              else
 +              {
 +                      cerr<<task<<endl;
 +              }
 +
 +              while(studio::App::events_pending())studio::App::iteration(false);
 +              return true;
 +      }
 +
 +      virtual bool warning(const std::string &task)
 +      {
 +              if(splash.tasklabel)
 +              {
 +                      splash.tasklabel->set_label(_("WARNING:")+task);
 +                      splash.tasklabel->show();
 +              }
 +              else
 +              {
 +                      cerr<<task<<endl;
 +              }
 +
 +              while(studio::App::events_pending())studio::App::iteration(false);
 +              return true;
 +      }
 +
 +      virtual bool amount_complete(int current, int total)
 +      {
 +              if(splash.progressbar)
 +              {
 +                      splash.progressbar->set_fraction((float)current/(float)total);
 +                      splash.progressbar->show();
 +              }
 +              else
 +                      cerr<<current<<'/'<<total<<endl;
 +
 +              while(studio::App::events_pending())studio::App::iteration(false);
 +              return true;
 +      }
 +}; // END of class SplashProgress
 +
 +/* === M E T H O D S ======================================================= */
 +
 +Splash::Splash():
 +      Gtk::Window(getenv("SYNFIG_DISABLE_POPUP_WINDOWS") ? Gtk::WINDOW_TOPLEVEL : Gtk::WINDOW_POPUP)
 +{
 +      std::string imagepath;
 +#ifdef WIN32
 +      imagepath=App::get_base_path()+ETL_DIRECTORY_SEPARATOR+IMAGE_DIR;
 +#else
 +      imagepath=IMAGE_DIR;
 +#endif
 +      char* synfig_root=getenv("SYNFIG_ROOT");
 +      if(synfig_root) {
 +              imagepath=synfig_root;
 +              imagepath+=ETL_DIRECTORY_SEPARATOR;
 +              imagepath+="share";
 +              imagepath+=ETL_DIRECTORY_SEPARATOR;
 +              imagepath+="pixmaps";
 +              imagepath+=ETL_DIRECTORY_SEPARATOR;
 +              imagepath+="synfigstudio";
 +      }
 +      imagepath+=ETL_DIRECTORY_SEPARATOR;
 +
 +      // Create the splash image
 +      Gtk::Image* splash_image = manage(new class Gtk::Image());
++      srand(time(NULL));
++      const float ran = rand()/float(RAND_MAX);
++      int number = 1;
++      if(ran >0.499999)
++              number = 2;
++      //synfig::info("%s", strprintf("%d",number).c_str());
++      splash_image->set(imagepath+"splash_screen"+strprintf("%d",number)+"."IMAGE_EXT);
 +      splash_image->set_alignment(0.5,0.5);
 +      splash_image->set_padding(0,0);
 +
 +      // Get the image size
 +      int image_w = 350; int image_h = 0;
 +      Glib::RefPtr<Gdk::Pixbuf> pixbuf = splash_image->get_pixbuf();
 +      if( pixbuf ){
 +              image_w = pixbuf->get_width();
 +              image_h = pixbuf->get_height();
 +      }
 +
 +      // Create the progress bar
 +      progressbar = manage(new class Gtk::ProgressBar());
 +      progressbar->set_size_request(image_w,24);
 +
 +      // Create the current task label
 +      tasklabel = manage(new class Gtk::Label());
 +      tasklabel->set_size_request(image_w,24);
 +      tasklabel->set_use_underline(false);
 +
 +      // Create the Gtk::Fixed container and put all of the widgets into it
 +      Gtk::Fixed* fixed = manage(new class Gtk::Fixed());
 +      if( pixbuf ) fixed->put(*splash_image, 0, 0);
 +      fixed->put(*progressbar, 0, image_h+24);
 +      fixed->put(*tasklabel, 0, image_h);
 +
 +      // Create shadow around the outside of the window
 +      Gtk::Frame* frame = manage(new class Gtk::Frame());
 +      frame->set_shadow_type(Gtk::SHADOW_OUT);
 +      frame->add(*fixed);
 +
 +      // Set up the parameters for this pop-up window
 +      set_title("Synfig Studio "VERSION);
 +      set_modal(false);
 +      property_window_position().set_value(Gtk::WIN_POS_CENTER);
 +      set_resizable(false);
 +      set_type_hint(Gdk::WINDOW_TYPE_HINT_SPLASHSCREEN);
 +      set_auto_startup_notification(false);
 +      try {
 +              set_icon_from_file(imagepath+"synfig_icon."+IMAGE_EXT);
 +      } catch(...) {
 +              synfig::warning("Unable to open "+imagepath+"synfig_icon."+IMAGE_EXT);
 +      }
 +      add(*frame);
 +
 +      // show everything off
 +      if( pixbuf ) splash_image->show();
 +      fixed->show();
 +      frame->show();
 +
 +      // Once the splash is shown, we want startup stuff to continue as normal
 +      signal_map().connect(sigc::mem_fun(*this, &Splash::enable_startup_notification));
 +
 +      cb=new SplashProgress(*this);
 +}
 +
 +Splash::~Splash()
 +{
 +      delete cb;
 +}
 +
 +synfig::ProgressCallback *
 +Splash::get_callback()
 +{
 +      return cb;
 +}
 +
 +void
 +Splash::enable_startup_notification(){
 +      set_auto_startup_notification(true);
 +}
index 2b1eb0a,0000000..3f7786b
mode 100644,000000..100644
--- /dev/null
@@@ -1,336 -1,0 +1,354 @@@
-       synfigapp::Settings& settings;
-       sigc::connection keypress_connect;
-       sigc::connection keyrelease_connect;
 +/* === S Y N F I G ========================================================= */
 +/*!   \file state_mirror.cpp
 +**    \brief Template File
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2009 Nikita Kitaev
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include <gtkmm/dialog.h>
 +#include <gtkmm/entry.h>
 +
 +#include <synfig/valuenode_dynamiclist.h>
 +#include <synfigapp/action_system.h>
 +
 +#include "state_mirror.h"
 +#include "state_normal.h"
 +#include "canvasview.h"
 +#include "workarea.h"
 +#include "app.h"
 +
 +#include <synfigapp/action.h>
 +#include "event_mouse.h"
 +#include "event_layerclick.h"
 +#include "toolbox.h"
 +#include "docks/dialog_tooloptions.h"
 +#include <gtkmm/optionmenu.h>
 +#include "duck.h"
 +#include <synfigapp/main.h>
 +
 +#include "general.h"
 +
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +enum Axis {
 +      AXIS_X,
 +      AXIS_Y
 +} ;
 +
 +/* === G L O B A L S ======================================================= */
 +
 +StateMirror studio::state_mirror;
 +
 +/* === C L A S S E S & S T R U C T S ======================================= */
 +
 +class DuckDrag_Mirror : public DuckDrag_Base
 +{
 +      synfig::Vector center;
 +
 +      std::vector<synfig::Vector> positions;
 +
 +public:
 +      Axis axis;
 +
 +      DuckDrag_Mirror();
 +      void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin);
 +      bool end_duck_drag(Duckmatic* duckmatic);
 +      void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector);
 +};
 +
 +class studio::StateMirror_Context : public sigc::trackable
 +{
 +      etl::handle<CanvasView> canvas_view_;
 +      CanvasView::IsWorking is_working;
 +
-       void load_settings();
-       void save_settings();
 +      etl::handle<DuckDrag_Mirror> duck_dragger_;
 +
 +      Gtk::Table options_table;
 +
++
++      sigc::connection keypress_connect;
++      sigc::connection keyrelease_connect;
++      bool shift_is_pressed;
 +      Gtk::RadioButton::Group radiobutton_group;
 +      Gtk::RadioButton radiobutton_axis_x;
 +      Gtk::RadioButton radiobutton_axis_y;
 +
 +public:
 +
 +      Axis get_axis()const { return radiobutton_axis_x.get_active()?AXIS_X:AXIS_Y; }
 +      void set_axis(Axis a)
 +      {
 +              if(a==AXIS_X)
 +                      radiobutton_axis_x.set_active(true);
 +              else
 +                      radiobutton_axis_y.set_active(true);
 +
 +              duck_dragger_->axis=get_axis();
 +      }
 +
 +      void update_axes()
 +      {
 +              duck_dragger_->axis=get_axis();
 +              get_work_area()->set_cursor(get_axis() == AXIS_X?Gdk::SB_H_DOUBLE_ARROW:Gdk::SB_V_DOUBLE_ARROW);
 +      }
 +
++
++
++
 +      Smach::event_result event_stop_handler(const Smach::event& x);
 +      Smach::event_result event_refresh_tool_options(const Smach::event& x);
++      Smach::event_result event_mouse_motion_handler(const Smach::event& x);
 +
 +      void refresh_tool_options();
 +
 +      StateMirror_Context(CanvasView* canvas_view);
 +
 +      ~StateMirror_Context();
 +
 +      const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
 +      etl::handle<synfigapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
 +      synfig::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
 +      WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
 +
-       bool key_event(GdkEventKey *event);
++      bool key_press_event(GdkEventKey *event);
++      bool key_release_event(GdkEventKey *event);
++
 +
- void
- StateMirror_Context::load_settings()
- {
-       String value;
-       settings.get_value("mirror.axis",value);
-       set_axis((Axis)atoi(value.c_str()));
- }
- void
- StateMirror_Context::save_settings()
- {
-       settings.set_value("mirror.lock_aspect",strprintf("%d",(int)get_axis()));
- }
 +};    // END of class StateMirror_Context
 +
 +/* === M E T H O D S ======================================================= */
 +
 +StateMirror::StateMirror():
 +      Smach::state<StateMirror_Context>("mirror")
 +{
 +      insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateMirror_Context::event_refresh_tool_options));
 +      insert(event_def(EVENT_STOP,&StateMirror_Context::event_stop_handler));
++      insert(event_def(EVENT_WORKAREA_MOUSE_MOTION,           &StateMirror_Context::event_mouse_motion_handler));
++      insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,      &StateMirror_Context::event_mouse_motion_handler));
 +}
 +
 +StateMirror::~StateMirror()
 +{
 +}
 +
-       settings(synfigapp::Main::get_selected_input_device()->settings()),
 +StateMirror_Context::StateMirror_Context(CanvasView* canvas_view):
 +      canvas_view_(canvas_view),
 +      is_working(*canvas_view),
-       keypress_connect=get_work_area()->signal_key_press_event().connect(sigc::mem_fun(*this,&StateMirror_Context::key_event),false);
-       keyrelease_connect=get_work_area()->signal_key_release_event().connect(sigc::mem_fun(*this,&StateMirror_Context::key_event),false);
 +      duck_dragger_(new DuckDrag_Mirror()),
 +      radiobutton_axis_x(radiobutton_group,_("Horizontal")),
 +      radiobutton_axis_y(radiobutton_group,_("Vertical"))
 +{
 +      // Set up the tool options dialog
 +      options_table.attach(*manage(new Gtk::Label(_("Mirror Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
 +      options_table.attach(radiobutton_axis_x, 0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
 +      options_table.attach(radiobutton_axis_y, 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
 +      options_table.attach(*manage(new Gtk::Label(_("(Shift key toggles axis)"))), 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
 +
 +      radiobutton_axis_x.signal_toggled().connect(sigc::mem_fun(*this,&StateMirror_Context::update_axes));
 +      radiobutton_axis_y.signal_toggled().connect(sigc::mem_fun(*this,&StateMirror_Context::update_axes));
++      shift_is_pressed=false;
++      keypress_connect=get_work_area()->signal_key_press_event().connect(sigc::mem_fun(*this,&StateMirror_Context::key_press_event),false);
++      keyrelease_connect=get_work_area()->signal_key_release_event().connect(sigc::mem_fun(*this,&StateMirror_Context::key_release_event),false);
 +
 +      options_table.show_all();
 +      refresh_tool_options();
 +      App::dialog_tool_options->present();
 +
 +      get_work_area()->set_allow_layer_clicks(true);
 +      get_work_area()->set_duck_dragger(duck_dragger_);
 +
-       set_axis(AXIS_X);
-       load_settings();
 +      get_work_area()->set_cursor(Gdk::SB_H_DOUBLE_ARROW);
 +//    get_work_area()->reset_cursor();
 +
 +      App::toolbox->refresh();
 +
- StateMirror_Context::key_event(GdkEventKey *event)
++      set_axis(AXIS_Y);
 +}
 +
 +bool
-               get_work_area()->set_cursor(get_axis() == AXIS_X?Gdk::SB_H_DOUBLE_ARROW:Gdk::SB_V_DOUBLE_ARROW);
++StateMirror_Context::key_press_event(GdkEventKey *event)
 +{
 +      if (event->keyval==GDK_Shift_L || event->keyval==GDK_Shift_R )
 +      {
++              if (shift_is_pressed) return false;
++              shift_is_pressed=true;
 +              set_axis(get_axis()==AXIS_X ? AXIS_Y:AXIS_X);
- StateMirror_Context::~StateMirror_Context()
++              update_axes();
++      }
++
++      return false; //Pass on the event to other handlers, just in case
++}
++
++bool
++StateMirror_Context::key_release_event(GdkEventKey *event)
++{
++      if (event->keyval==GDK_Shift_L || event->keyval==GDK_Shift_R )
++      {
++              if (!shift_is_pressed) return false;
++              shift_is_pressed = false;
++              set_axis(get_axis()==AXIS_X ? AXIS_Y:AXIS_X);
++              update_axes();
 +      }
 +
 +      return false; //Pass on the event to other handlers, just in case
 +}
 +
 +void
 +StateMirror_Context::refresh_tool_options()
 +{
 +      App::dialog_tool_options->clear();
 +      App::dialog_tool_options->set_widget(options_table);
 +      App::dialog_tool_options->set_local_name(_("Mirror Tool"));
 +      App::dialog_tool_options->set_name("mirror");
 +}
 +
 +Smach::event_result
 +StateMirror_Context::event_refresh_tool_options(const Smach::event& /*x*/)
 +{
 +      refresh_tool_options();
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +Smach::event_result
 +StateMirror_Context::event_stop_handler(const Smach::event& /*x*/)
 +{
 +      throw &state_normal;
 +      return Smach::RESULT_OK;
 +}
 +
-       save_settings();
++Smach::event_result
++StateMirror_Context::event_mouse_motion_handler(const Smach::event& x)
 +{
++      // synfig::info("STATE NORMAL: Received mouse button down Event");
++
++      const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
++      bool shift_state = event.modifier&GDK_SHIFT_MASK;
++      if (shift_state != shift_is_pressed)
++      {
++              shift_is_pressed = !shift_is_pressed;
++              set_axis(get_axis()==AXIS_X ? AXIS_Y:AXIS_X);
++      }
 +
++      return Smach::RESULT_OK;
++}
++
++StateMirror_Context::~StateMirror_Context()
++{
 +      get_work_area()->clear_duck_dragger();
 +      get_work_area()->reset_cursor();
 +
 +      keypress_connect.disconnect();
 +      keyrelease_connect.disconnect();
 +
 +      App::dialog_tool_options->clear();
 +
 +      App::toolbox->refresh();
 +}
 +
 +DuckDrag_Mirror::DuckDrag_Mirror():
 +      axis(AXIS_X)
 +{
 +}
 +
 +#ifndef EPSILON
 +#define EPSILON       0.0000001
 +#endif
 +
 +void
 +DuckDrag_Mirror::begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& /*offset*/)
 +{
 +      const DuckList selected_ducks(duckmatic->get_selected_ducks());
 +      DuckList::const_iterator iter;
 +
 +      positions.clear();
 +      int i;
 +      for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +      {
 +              Point p((*iter)->get_trans_point());
 +              positions.push_back(p);
 +      }
 +
 +}
 +
 +void
 +DuckDrag_Mirror::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector)
 +{
 +      center=vector;
 +      int i;
 +
 +      const DuckList selected_ducks(duckmatic->get_selected_ducks());
 +      DuckList::const_iterator iter;
 +
 +      Time time(duckmatic->get_time());
 +
 +      // do the Vertex and Position ducks first
 +      for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              if ((*iter)->get_type() == Duck::TYPE_VERTEX ||
 +                      (*iter)->get_type() == Duck::TYPE_POSITION)
 +              {
 +                      Vector p(positions[i]);
 +
 +                      if              (axis==AXIS_X) p[0] = -(p[0]-center[0]) + center[0];
 +                      else if (axis==AXIS_Y) p[1] = -(p[1]-center[1]) + center[1];
 +
 +                      (*iter)->set_trans_point(p);
 +              }
 +
 +      // then do the other ducks
 +      for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              if ((*iter)->get_type() != Duck::TYPE_VERTEX &&
 +                      (*iter)->get_type() != Duck::TYPE_POSITION)
 +              {
 +                      // we don't need to mirror radius ducks - they're one-dimensional
 +                      if ((*iter)->is_radius())
 +                              continue;
 +
 +                      Vector p(positions[i]);
 +
 +                      if              (axis==AXIS_X) p[0] = -(p[0]-center[0]) + center[0];
 +                      else if (axis==AXIS_Y) p[1] = -(p[1]-center[1]) + center[1];
 +
 +                      (*iter)->set_trans_point(p);
 +              }
 +}
 +
 +bool
 +DuckDrag_Mirror::end_duck_drag(Duckmatic* duckmatic)
 +{
 +      duckmatic->signal_edited_selected_ducks();
 +      return true;
 +}
index 723ca90,0000000..f71af5b
mode 100644,000000..100644
--- /dev/null
@@@ -1,824 -1,0 +1,767 @@@
-       synfigapp::Settings& settings;
-       sigc::connection keypress_connect;
-       sigc::connection keyrelease_connect;
 +/* === S Y N F I G ========================================================= */
 +/*!   \file state_normal.cpp
 +**    \brief Template File
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007, 2008 Chris Moore
 +**    Copyright (c) 2009 Nikita Kitaev
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +*/
 +/* ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include <gtkmm/dialog.h>
 +#include <gtkmm/entry.h>
 +
 +#include <synfig/valuenode_animated.h>
 +#include <synfig/valuenode_blinecalcvertex.h>
 +#include <synfig/valuenode_composite.h>
 +#include <synfig/valuenode_const.h>
 +#include <synfig/valuenode_dynamiclist.h>
 +#include <synfigapp/action_system.h>
 +
 +#include "state_normal.h"
 +#include "canvasview.h"
 +#include "workarea.h"
 +#include "app.h"
 +
 +#include <synfigapp/action.h>
 +#include "event_mouse.h"
 +#include "event_layerclick.h"
 +#include "toolbox.h"
 +#include "docks/dialog_tooloptions.h"
 +#include <gtkmm/optionmenu.h>
 +#include "duck.h"
 +#include <synfig/angle.h>
 +#include <synfigapp/main.h>
 +
 +#include "general.h"
 +#endif
 +
 +/* === U S I N G =========================================================== */
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +
 +/* === M A C R O S ========================================================= */
 +
 +#ifndef EPSILON
 +#define EPSILON       0.0000001
 +#endif
 +
 +/* === G L O B A L S ======================================================= */
 +
 +StateNormal studio::state_normal;
 +
 +/* === C L A S S E S & S T R U C T S ======================================= */
 +
 +class DuckDrag_Combo : public DuckDrag_Base
 +{
 +      synfig::Vector last_move;
 +      synfig::Vector drag_offset;
 +      synfig::Vector center;
 +      synfig::Vector snap;
 +
 +      synfig::Angle original_angle;
 +      synfig::Real original_mag;
 +
 +      std::vector<synfig::Vector> last_;
 +      std::vector<synfig::Vector> positions;
 +
 +
 +      bool bad_drag;
 +      bool move_only;
 +
 +public:
 +      CanvasView* canvas_view_;
 +      bool scale;
 +      bool rotate;
 +      bool constrain;
 +      DuckDrag_Combo();
 +      void begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& begin);
 +      bool end_duck_drag(Duckmatic* duckmatic);
 +      void duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector);
 +
 +      etl::handle<synfigapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
 +};
 +
 +
 +class studio::StateNormal_Context : public sigc::trackable
 +{
 +      CanvasView* canvas_view_;
 +
-       Gtk::CheckButton checkbutton_rotate;
-       Gtk::CheckButton checkbutton_scale;
-       Gtk::CheckButton checkbutton_constrain;
 +      etl::handle<DuckDrag_Combo> duck_dragger_;
 +
 +      Gtk::Table options_table;
 +
-       bool get_rotate_flag()const { return checkbutton_rotate.get_active(); }
-       void set_rotate_flag(bool x) { checkbutton_rotate.set_active(x); refresh_rotate_flag(); }
-       void refresh_rotate_flag() { if(duck_dragger_)duck_dragger_->rotate=get_rotate_flag(); }
 +public:
 +
-       bool get_scale_flag()const { return checkbutton_scale.get_active(); }
-       void set_scale_flag(bool x) { checkbutton_scale.set_active(x); refresh_scale_flag(); }
-       void refresh_scale_flag() { if(duck_dragger_)duck_dragger_->scale=get_scale_flag(); }
++      void refresh_cursor();
++
++      bool get_rotate_flag()const { if(duck_dragger_) return duck_dragger_->rotate; else return false; }
++      void set_rotate_flag(bool x) { if(duck_dragger_ && x!=duck_dragger_->rotate)
++                                             {duck_dragger_->rotate=x; refresh_cursor();} }
 +
-       bool get_constrain_flag()const { return checkbutton_constrain.get_active(); }
-       void set_constrain_flag(bool x) { checkbutton_constrain.set_active(x); refresh_constrain_flag(); }
-       void refresh_constrain_flag() { if(duck_dragger_)duck_dragger_->constrain=get_constrain_flag(); }
++      bool get_scale_flag()const { if(duck_dragger_) return duck_dragger_->scale; else return false; }
++      void set_scale_flag(bool x) { if(duck_dragger_ && x!=duck_dragger_->scale)
++                                            {duck_dragger_->scale=x; refresh_cursor();} }
 +
-       void load_settings();
-       void save_settings();
-       bool key_pressed(GdkEventKey *event);
-       bool key_released(GdkEventKey *event);
++      bool get_constrain_flag()const { if(duck_dragger_) return duck_dragger_->constrain; else return false; }
++      void set_constrain_flag(bool x) { if(duck_dragger_ && x!=duck_dragger_->constrain)
++                                                {duck_dragger_->constrain=x; refresh_cursor();} }
 +
 +      StateNormal_Context(CanvasView* canvas_view);
 +
 +      ~StateNormal_Context();
 +
 +      CanvasView* get_canvas_view()const{return canvas_view_;}
 +      etl::handle<synfigapp::CanvasInterface> get_canvas_interface()const{return canvas_view_->canvas_interface();}
 +      synfig::Canvas::Handle get_canvas()const{return canvas_view_->get_canvas();}
 +      WorkArea * get_work_area()const{return canvas_view_->get_work_area();}
 +
- void
- StateNormal_Context::load_settings()
 +      Smach::event_result event_stop_handler(const Smach::event& x);
 +      Smach::event_result event_refresh_handler(const Smach::event& x);
 +      Smach::event_result event_refresh_ducks_handler(const Smach::event& x);
 +      Smach::event_result event_undo_handler(const Smach::event& x);
 +      Smach::event_result event_redo_handler(const Smach::event& x);
 +      Smach::event_result event_mouse_button_down_handler(const Smach::event& x);
 +      Smach::event_result event_multiple_ducks_clicked_handler(const Smach::event& x);
++      Smach::event_result event_mouse_motion_handler(const Smach::event& x);
 +      Smach::event_result event_refresh_tool_options(const Smach::event& x);
 +      void refresh_tool_options();
 +      Smach::event_result event_layer_click(const Smach::event& x);
 +
 +
 +};    // END of class StateNormal_Context
 +
 +/* === M E T H O D S ======================================================= */
 +
 +StateNormal::StateNormal():
 +      Smach::state<StateNormal_Context>("normal")
 +{
 +      insert(event_def(EVENT_STOP,&StateNormal_Context::event_stop_handler));
 +      insert(event_def(EVENT_REFRESH,&StateNormal_Context::event_refresh_handler));
 +      insert(event_def(EVENT_REFRESH_DUCKS,&StateNormal_Context::event_refresh_ducks_handler));
 +      insert(event_def(EVENT_UNDO,&StateNormal_Context::event_undo_handler));
 +      insert(event_def(EVENT_REDO,&StateNormal_Context::event_redo_handler));
 +      insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DOWN,&StateNormal_Context::event_mouse_button_down_handler));
 +      insert(event_def(EVENT_WORKAREA_MULTIPLE_DUCKS_CLICKED,&StateNormal_Context::event_multiple_ducks_clicked_handler));
 +      insert(event_def(EVENT_REFRESH_TOOL_OPTIONS,&StateNormal_Context::event_refresh_tool_options));
++      insert(event_def(EVENT_WORKAREA_MOUSE_MOTION,           &StateNormal_Context::event_mouse_motion_handler));
++      insert(event_def(EVENT_WORKAREA_MOUSE_BUTTON_DRAG,      &StateNormal_Context::event_mouse_motion_handler));
 +      insert(event_def(EVENT_WORKAREA_LAYER_CLICKED,&StateNormal_Context::event_layer_click));
 +
 +}
 +
 +StateNormal::~StateNormal()
 +{
 +}
 +
-       String value;
-       if(settings.get_value("normal.rotate",value) && value=="1")
-               set_rotate_flag(true);
-       else
-               set_rotate_flag(false);
-       if(settings.get_value("normal.scale",value) && value=="1")
-               set_scale_flag(true);
-       else
-               set_scale_flag(false);
-       if(settings.get_value("normal.constrain",value) && value=="1")
-               set_constrain_flag(true);
-       else
-               set_constrain_flag(false);
++void StateNormal_Context::refresh_cursor()
 +{
- }
++      // Check the current state and return when applicable
++      synfig::String sname;
++      sname=get_canvas_view()->get_smach().get_state_name();
++      if (sname!="normal")
++                      return;
++
++      // Change the cursor based on key flags
++      if(get_rotate_flag() && !get_scale_flag())
++      {
++              get_work_area()->set_cursor(Gdk::EXCHANGE);
++              return;
++      }
++      if(!get_rotate_flag() && get_scale_flag())
++      {
++              get_work_area()->set_cursor(Gdk::SIZING);
++              return;
++      }
++      if(get_rotate_flag() && get_scale_flag())
++      {
++              get_work_area()->set_cursor(Gdk::CROSSHAIR);
++              return;
++      }
 +
- void
- StateNormal_Context::save_settings()
- {
-       settings.set_value("normal.rotate",get_rotate_flag()?"1":"0");
-       settings.set_value("normal.scale",get_scale_flag()?"1":"0");
-       settings.set_value("normal.constrain",get_constrain_flag()?"1":"0");
++      // Default cursor for Transform tool
++      get_work_area()->set_cursor(Gdk::ARROW);
 +
-       settings(synfigapp::Main::get_selected_input_device()->settings()),
-       duck_dragger_(new DuckDrag_Combo()),
-       checkbutton_rotate(_("Rotate (Ctrl)")),
-       checkbutton_scale(_("Scale (Alt)")),
-       checkbutton_constrain(_("Constrain (Shift)"))
 +}
 +
 +StateNormal_Context::StateNormal_Context(CanvasView* canvas_view):
 +      canvas_view_(canvas_view),
-       options_table.attach(*manage(new Gtk::Label(_("Normal Tool"))), 0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
-       options_table.attach(checkbutton_rotate,                                                        0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
-       options_table.attach(checkbutton_scale,                                                 0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
-       options_table.attach(checkbutton_constrain,                                                     0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
-       checkbutton_rotate.signal_toggled().connect(sigc::mem_fun(*this,&StateNormal_Context::refresh_rotate_flag));
-       checkbutton_scale.signal_toggled().connect(sigc::mem_fun(*this,&StateNormal_Context::refresh_scale_flag));
-       checkbutton_constrain.signal_toggled().connect(sigc::mem_fun(*this,&StateNormal_Context::refresh_constrain_flag));
++      duck_dragger_(new DuckDrag_Combo())
 +{
 +      duck_dragger_->canvas_view_=get_canvas_view();
 +
 +      // Set up the tool options dialog
-       keypress_connect=get_work_area()->signal_key_press_event().connect(sigc::mem_fun(*this,&StateNormal_Context::key_pressed),false);
-       keyrelease_connect=get_work_area()->signal_key_release_event().connect(sigc::mem_fun(*this,&StateNormal_Context::key_released),false);
++      options_table.attach(*manage(new Gtk::Label(_("Transform Tool"))),      0, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
++      options_table.attach(*manage(new Gtk::Label(_("Ctrl to rotate"), Gtk::ALIGN_LEFT)),     0, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
++      options_table.attach(*manage(new Gtk::Label(_("Alt to scale"), Gtk::ALIGN_LEFT)),       0, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
++      options_table.attach(*manage(new Gtk::Label(_("Shift to constrain"), Gtk::ALIGN_LEFT)), 0, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL, 0, 0);
 +
 +      options_table.show_all();
 +      refresh_tool_options();
 +      //App::dialog_tool_options->set_widget(options_table);
 +      //App::dialog_tool_options->present();
 +
 +      get_work_area()->set_allow_layer_clicks(true);
 +      get_work_area()->set_duck_dragger(duck_dragger_);
 +
-       load_settings();
-       refresh_scale_flag();
- }
- bool
- StateNormal_Context::key_pressed(GdkEventKey *event)
- {
-       switch(event->keyval)
-       {
-               case GDK_Control_L:
-               case GDK_Control_R:
-                       set_rotate_flag(true);
-                       break;
-               case GDK_Alt_L:
-               case GDK_Alt_R:
-                       set_scale_flag(true);
-                       break;
-               case GDK_Shift_L:
-               case GDK_Shift_R:
-                       set_constrain_flag(true);
-                       break;
-               default:
-                       break;
-       }
-       return false; //Pass on the event to other handlers, just in case
- }
- bool
- StateNormal_Context::key_released(GdkEventKey *event)
- {
-       switch(event->keyval)
-       {
-               case GDK_Control_L:
-               case GDK_Control_R:
-                       set_rotate_flag(false);
-                       break;
-               case GDK_Alt_L:
-               case GDK_Alt_R:
-                       set_scale_flag(false);
-                       break;
-               case GDK_Shift_L:
-               case GDK_Shift_R:
-                       set_constrain_flag(false);
-                       break;
-               default:
-                       break;
-       }
-       return false; //Pass on the event to other handlers
 +      //these will segfault
 +//    get_work_area()->set_cursor(Gdk::CROSSHAIR);
 +//    get_work_area()->reset_cursor();
 +
 +      App::toolbox->refresh();
-       App::dialog_tool_options->set_local_name(_("Normal Tool"));
 +}
 +
 +void
 +StateNormal_Context::refresh_tool_options()
 +{
 +      App::dialog_tool_options->clear();
 +      App::dialog_tool_options->set_widget(options_table);
-       save_settings();
++      App::dialog_tool_options->set_local_name(_("Transform Tool"));
 +      App::dialog_tool_options->set_name("normal");
 +}
 +
 +
 +
 +StateNormal_Context::~StateNormal_Context()
 +{
-       keypress_connect.disconnect();
-       keyrelease_connect.disconnect();
 +      get_work_area()->clear_duck_dragger();
 +      get_work_area()->reset_cursor();
 +
-       constrain(false) // Lock aspect for scale; smooth move for translate
 +      App::dialog_tool_options->clear();
 +
 +      App::toolbox->refresh();
 +}
 +
 +DuckDrag_Combo::DuckDrag_Combo():
 +      scale(false),
 +      rotate(false),
-                       //vect[0]=vect[1]=vect.mag()*0.707106781;
-                       Real amount(vect.mag()/(drag_offset-center).mag());
++      constrain(false) // Lock aspect for scale
 +{
 +}
 +
 +void
 +DuckDrag_Combo::begin_duck_drag(Duckmatic* duckmatic, const synfig::Vector& offset)
 +{
 +      last_move=Vector(1,1);
 +
 +      const DuckList selected_ducks(duckmatic->get_selected_ducks());
 +      DuckList::const_iterator iter;
 +
 +      bad_drag=false;
 +
 +              drag_offset=duckmatic->find_duck(offset)->get_trans_point();
 +
 +              //snap=drag_offset-duckmatic->snap_point_to_grid(drag_offset);
 +              //snap=offset-drag_offset_;
 +              snap=Vector(0,0);
 +
 +      // Calculate center
 +      Point vmin(100000000,100000000);
 +      Point vmax(-100000000,-100000000);
 +      //std::set<etl::handle<Duck> >::iterator iter;
 +      positions.clear();
 +      int i;
 +      for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +      {
 +              Point p((*iter)->get_trans_point());
 +              vmin[0]=min(vmin[0],p[0]);
 +              vmin[1]=min(vmin[1],p[1]);
 +              vmax[0]=max(vmax[0],p[0]);
 +              vmax[1]=max(vmax[1],p[1]);
 +              positions.push_back(p);
 +      }
 +      center=(vmin+vmax)*0.5;
 +      if((vmin-vmax).mag()<=EPSILON)
 +              move_only=true;
 +      else
 +              move_only=false;
 +
 +
 +      synfig::Vector vect(offset-center);
 +      original_angle=Angle::tan(vect[1],vect[0]);
 +      original_mag=vect.mag();
 +}
 +
 +
 +void
 +DuckDrag_Combo::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector)
 +{
 +      if (!duckmatic) return;
 +
 +      if(bad_drag)
 +              return;
 +
 +      //Override axis lock set in workarea when holding down the shift key
 +      if (!move_only && (scale || rotate))
 +              duckmatic->set_axis_lock(false);
 +
 +      synfig::Vector vect;
 +      if (move_only || (!scale && !rotate))
 +              vect= duckmatic->snap_point_to_grid(vector)-drag_offset+snap;
 +      else
 +              vect= duckmatic->snap_point_to_grid(vector)-center+snap;
 +
 +      last_move=vect;
 +
 +      const DuckList selected_ducks(duckmatic->get_selected_ducks());
 +      DuckList::const_iterator iter;
 +
 +      Time time(duckmatic->get_time());
 +
 +      int i;
 +      if( move_only || (!scale && !rotate) )
 +      {
 +              for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              {
 +                      if((*iter)->get_type()==Duck::TYPE_VERTEX || (*iter)->get_type()==Duck::TYPE_POSITION)
 +                              (*iter)->set_trans_point(positions[i]+vect, time);
 +              }
 +              for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              {
 +                      if((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION)
 +                              (*iter)->set_trans_point(positions[i]+vect, time);
 +              }
 +      }
 +
 +      if (rotate)
 +      {
 +              Angle::deg angle(Angle::tan(vect[1],vect[0]));
 +              angle=original_angle-angle;
 +              if (constrain)
 +              {
 +                      float degrees = angle.get()/15;
 +                      angle= Angle::deg (degrees>0?std::floor(degrees)*15:std::ceil(degrees)*15);
 +              }
 +              Real mag(vect.mag()/original_mag);
 +              Real sine(Angle::sin(angle).get());
 +              Real cosine(Angle::cos(angle).get());
 +
 +              for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              {
 +                      if((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION)continue;
 +
 +                      Vector x(positions[i]-center),p;
 +
 +                      p[0]=cosine*x[0]+sine*x[1];
 +                      p[1]=-sine*x[0]+cosine*x[1];
 +                      if(scale)p*=mag;
 +                      p+=center;
 +                      (*iter)->set_trans_point(p, time);
 +              }
 +              for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              {
 +                      if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
 +
 +                      Vector x(positions[i]-center),p;
 +
 +                      p[0]=cosine*x[0]+sine*x[1];
 +                      p[1]=-sine*x[0]+cosine*x[1];
 +                      if(scale)p*=mag;
 +                      p+=center;
 +                      (*iter)->set_trans_point(p, time);
 +              }
 +      } else if (scale)
 +      {
 +              if(!constrain)
 +              {
 +                      if(abs(drag_offset[0]-center[0])>EPSILON)
 +                              vect[0]/=drag_offset[0]-center[0];
 +                      else
 +                              vect[0]=1;
 +                      if(abs(drag_offset[1]-center[1])>EPSILON)
 +                              vect[1]/=drag_offset[1]-center[1];
 +                      else
 +                              vect[1]=1;
 +                      }
 +              else
 +              {
++                      Real amount;
++                      if((drag_offset-center).mag() < EPSILON)
++                              amount = 1;
++                      else
++                              amount = vect.mag()/(drag_offset-center).mag();
++
 +                      vect[0]=vect[1]=amount;
 +              }
 +
 +              if(vect[0]<EPSILON && vect[0]>-EPSILON)
 +                      vect[0]=1;
 +              if(vect[1]<EPSILON && vect[1]>-EPSILON)
 +                      vect[1]=1;
 +
 +              for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              {
 +                      if(((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
 +
 +                      Vector p(positions[i]-center);
 +
 +                      p[0]*=vect[0];
 +                      p[1]*=vect[1];
 +                      p+=center;
 +                      (*iter)->set_trans_point(p, time);
 +              }
 +              for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++)
 +              {
 +                      if(!((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION))continue;
 +
 +                      Vector p(positions[i]-center);
 +
 +                      p[0]*=vect[0];
 +                      p[1]*=vect[1];
 +                      p+=center;
 +                      (*iter)->set_trans_point(p, time);
 +              }
++
 +      }
 +
 +      // then patch up the tangents for the vertices we've moved
 +      duckmatic->update_ducks();
 +
 +      last_move=vect;
 +}
 +
 +bool
 +DuckDrag_Combo::end_duck_drag(Duckmatic* duckmatic)
 +{
 +      if(bad_drag)return false;
 +
 +      //synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Rotate Ducks"));
 +
 +      if((last_move-Vector(1,1)).mag()>0.0001)
 +      {
 +              duckmatic->signal_edited_selected_ducks();
 +              return true;
 +      }
 +      else
 +      {
 +              duckmatic->signal_user_click_selected_ducks(0);
 +              return false;
 +      }
 +}
 +
 +Smach::event_result
 +StateNormal_Context::event_refresh_tool_options(const Smach::event& /*x*/)
 +{
 +      refresh_tool_options();
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +Smach::event_result
 +StateNormal_Context::event_stop_handler(const Smach::event& /*x*/)
 +{
 +      // synfig::info("STATE NORMAL: Received Stop Event");
 +      canvas_view_->stop();
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +Smach::event_result
 +StateNormal_Context::event_refresh_handler(const Smach::event& /*x*/)
 +{
 +      // synfig::info("STATE NORMAL: Received Refresh Event");
 +      canvas_view_->rebuild_tables();
 +      canvas_view_->work_area->queue_render_preview();
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +Smach::event_result
 +StateNormal_Context::event_refresh_ducks_handler(const Smach::event& /*x*/)
 +{
 +      // synfig::info("STATE NORMAL: Received Refresh Ducks");
 +      canvas_view_->queue_rebuild_ducks();
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +Smach::event_result
 +StateNormal_Context::event_undo_handler(const Smach::event& /*x*/)
 +{
 +      // synfig::info("STATE NORMAL: Received Undo Event");
 +      canvas_view_->get_instance()->undo();
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +Smach::event_result
 +StateNormal_Context::event_redo_handler(const Smach::event& /*x*/)
 +{
 +      // synfig::info("STATE NORMAL: Received Redo Event");
 +      canvas_view_->get_instance()->redo();
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +Smach::event_result
 +StateNormal_Context::event_mouse_button_down_handler(const Smach::event& x)
 +{
 +      // synfig::info("STATE NORMAL: Received mouse button down Event");
 +
 +      const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
 +
 +      switch(event.button)
 +      {
 +      case BUTTON_RIGHT:
 +              canvas_view_->popup_main_menu();
 +              return Smach::RESULT_ACCEPT;
 +      default:
 +              return Smach::RESULT_OK;
 +      }
 +}
 +
 +Smach::event_result
++StateNormal_Context::event_mouse_motion_handler(const Smach::event& x)
++{
++      // synfig::info("STATE NORMAL: Received mouse button down Event");
++
++      const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
++
++      set_rotate_flag(event.modifier&GDK_CONTROL_MASK);
++      set_scale_flag(event.modifier&GDK_MOD1_MASK);
++      set_constrain_flag(event.modifier&GDK_SHIFT_MASK);
++
++      return Smach::RESULT_OK;
++}
++
++Smach::event_result
 +StateNormal_Context::event_layer_click(const Smach::event& x)
 +{
 +      const EventLayerClick& event(*reinterpret_cast<const EventLayerClick*>(&x));
 +
 +      if(event.layer)
 +      {
 +              // synfig::info("STATE NORMAL: Received layer click Event, \"%s\"",event.layer->get_name().c_str());
 +      }
 +      else
 +      {
 +              // synfig::info("STATE NORMAL: Received layer click Event with an empty layer.");
 +      }
 +
 +      switch(event.button)
 +      {
 +      case BUTTON_LEFT:
 +              if(!(event.modifier&Gdk::CONTROL_MASK))
 +                      canvas_view_->get_selection_manager()->clear_selected_layers();
 +              if(event.layer)
 +              {
 +                      std::list<Layer::Handle> layer_list(canvas_view_->get_selection_manager()->get_selected_layers());
 +                      std::set<Layer::Handle> layers(layer_list.begin(),layer_list.end());
 +                      if(layers.count(event.layer))
 +                      {
 +                              layers.erase(event.layer);
 +                              layer_list=std::list<Layer::Handle>(layers.begin(),layers.end());
 +                              canvas_view_->get_selection_manager()->clear_selected_layers();
 +                              canvas_view_->get_selection_manager()->set_selected_layers(layer_list);
 +                      }
 +                      else
 +                      {
 +                              canvas_view_->get_selection_manager()->set_selected_layer(event.layer);
 +                      }
 +              }
 +              return Smach::RESULT_ACCEPT;
 +      case BUTTON_RIGHT:
 +              canvas_view_->popup_layer_menu(event.layer);
 +              return Smach::RESULT_ACCEPT;
 +      default:
 +              return Smach::RESULT_OK;
 +      }
 +}
 +
 +/*
 +void
 +StateNormal_Context::edit_several_waypoints(std::list<synfigapp::ValueDesc> value_desc_list)
 +{
 +      Gtk::Dialog dialog(
 +              "Edit Multiple Waypoints",              // Title
 +              true,           // Modal
 +              true            // use_separator
 +      );
 +
 +      Widget_WaypointModel widget_waypoint_model;
 +      widget_waypoint_model.show();
 +
 +      dialog.get_vbox()->pack_start(widget_waypoint_model);
 +
 +
 +      dialog.add_button(Gtk::StockID("gtk-apply"),1);
 +      dialog.add_button(Gtk::StockID("gtk-cancel"),0);
 +      dialog.show();
 +
 +      if(dialog.run()==0)
 +              return;
 +      synfigapp::Action::PassiveGrouper group(get_canvas_interface()->get_instance().get(),_("Set Waypoints"));
 +
 +      std::list<synfigapp::ValueDesc>::iterator iter;
 +      for(iter=value_desc_list.begin();iter!=value_desc_list.end();++iter)
 +      {
 +              synfigapp::ValueDesc value_desc(*iter);
 +
 +              if(!value_desc.is_valid())
 +                      continue;
 +
 +              ValueNode_Animated::Handle value_node;
 +
 +              // If this value isn't a ValueNode_Animated, but
 +              // it is somewhat constant, then go ahead and convert
 +              // it to a ValueNode_Animated.
 +              if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node()))
 +              {
 +                      ValueBase value;
 +                      if(value_desc.is_value_node())
 +                              value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value();
 +                      else
 +                              value=value_desc.get_value();
 +
 +                      value_node=ValueNode_Animated::create(value,get_canvas()->get_time());
 +
 +                      synfigapp::Action::Handle action;
 +
 +                      if(!value_desc.is_value_node())
 +                      {
 +                              action=synfigapp::Action::create("ValueDescConnect");
 +                              action->set_param("dest",value_desc);
 +                              action->set_param("src",ValueNode::Handle(value_node));
 +                      }
 +                      else
 +                      {
 +                              action=synfigapp::Action::create("ValueNodeReplace");
 +                              action->set_param("dest",value_desc.get_value_node());
 +                              action->set_param("src",ValueNode::Handle(value_node));
 +                      }
 +
 +                      action->set_param("canvas",get_canvas());
 +                      action->set_param("canvas_interface",get_canvas_interface());
 +
 +
 +                      if(!get_canvas_interface()->get_instance()->perform_action(action))
 +                      {
 +                              get_canvas_view()->get_ui_interface()->error(_("Unable to convert to animated waypoint"));
 +                              group.cancel();
 +                              return;
 +                      }
 +              }
 +              else
 +              {
 +                      if(value_desc.is_value_node())
 +                              value_node=ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node());
 +              }
 +
 +
 +              if(value_node)
 +              {
 +
 +                      synfigapp::Action::Handle action(synfigapp::Action::create("WaypointSetSmart"));
 +
 +                      if(!action)
 +                      {
 +                              get_canvas_view()->get_ui_interface()->error(_("Unable to find WaypointSetSmart action"));
 +                              group.cancel();
 +                              return;
 +                      }
 +
 +
 +                      action->set_param("canvas",get_canvas());
 +                      action->set_param("canvas_interface",get_canvas_interface());
 +                      action->set_param("value_node",ValueNode::Handle(value_node));
 +                      action->set_param("time",get_canvas()->get_time());
 +                      action->set_param("model",widget_waypoint_model.get_waypoint_model());
 +
 +                      if(!get_canvas_interface()->get_instance()->perform_action(action))
 +                      {
 +                              get_canvas_view()->get_ui_interface()->error(_("Unable to set a specific waypoint"));
 +                              group.cancel();
 +                              return;
 +                      }
 +              }
 +              else
 +              {
 +                      //get_canvas_view()->get_ui_interface()->error(_("Unable to animate a specific valuedesc"));
 +                      //group.cancel();
 +                      //return;
 +              }
 +
 +      }
 +}
 +*/
 +
 +Smach::event_result
 +StateNormal_Context::event_multiple_ducks_clicked_handler(const Smach::event& /*x*/)
 +{
 +      // synfig::info("STATE NORMAL: Received multiple duck click event");
 +
 +      //const EventMouse& event(*reinterpret_cast<const EventMouse*>(&x));
 +
 +      std::list<synfigapp::ValueDesc> value_desc_list;
 +
 +      // Create a list of value_descs associated with selection
 +      const DuckList selected_ducks(get_work_area()->get_selected_ducks());
 +      DuckList::const_iterator iter;
 +      for(iter=selected_ducks.begin();iter!=selected_ducks.end();++iter)
 +      {
 +              synfigapp::ValueDesc value_desc((*iter)->get_value_desc());
 +
 +              if(!value_desc.is_valid())
 +                      continue;
 +
 +              if(value_desc.get_value_type()==ValueBase::TYPE_BLINEPOINT && value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
 +              {
 +                      value_desc_list.push_back(
 +                              synfigapp::ValueDesc(
 +                                      ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())
 +                                      ,ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())
 +                                                               ->get_link_index_from_name("point")
 +                              )
 +                      );
 +              }
 +              else
 +                      value_desc_list.push_back(value_desc);
 +      }
 +
 +      Gtk::Menu *menu=manage(new Gtk::Menu());
 +      menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu));
 +
 +      canvas_view_->get_instance()->make_param_menu(menu,canvas_view_->get_canvas(),value_desc_list);
 +
 +      /*
 +      synfigapp::Action::ParamList param_list;
 +      param_list=get_canvas_interface()->generate_param_list(value_desc_list);
 +
 +      canvas_view_->add_actions_to_menu(menu, param_list,synfigapp::Action::CATEGORY_VALUEDESC|synfigapp::Action::CATEGORY_VALUENODE);
 +
 +      menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Edit Waypoints"),
 +              sigc::bind(
 +                      sigc::mem_fun(
 +                              *this,
 +                              &studio::StateNormal_Context::edit_several_waypoints
 +                      ),
 +                      value_desc_list
 +              )
 +      ));
 +      */
 +      menu->popup(3,gtk_get_current_event_time());
 +
 +      return Smach::RESULT_ACCEPT;
 +}
 +
 +
index 12a56a2,0000000..45d735a
mode 100644,000000..100644
--- /dev/null
@@@ -1,649 -1,0 +1,651 @@@
-       file_buttons->attach(*button_new,      0,1, 0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_open,     1,2, 0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_save,     2,3, 0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_saveas,   3,4, 0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_save_all, 4,5, 0,1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
 +/* === S Y N F I G ========================================================= */
 +/*!   \file toolbox.cpp
 +**    \brief writeme
 +**
 +**    $Id$
 +**
 +**    \legal
 +**    Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 +**    Copyright (c) 2007, 2008 Chris Moore
 +**  Copyright (c) 2008 Paul Wise
 +**    Copyright (c) 2009 Nikita Kitaev
 +**
 +**    This package is free software; you can redistribute it and/or
 +**    modify it under the terms of the GNU General Public License as
 +**    published by the Free Software Foundation; either version 2 of
 +**    the License, or (at your option) any later version.
 +**
 +**    This package is distributed in the hope that it will be useful,
 +**    but WITHOUT ANY WARRANTY; without even the implied warranty of
 +**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 +**    General Public License for more details.
 +**    \endlegal
 +**
 +** === N O T E S ===========================================================
 +**
 +** ========================================================================= */
 +
 +/* === H E A D E R S ======================================================= */
 +
 +#ifdef USING_PCH
 +#     include "pch.h"
 +#else
 +#ifdef HAVE_CONFIG_H
 +#     include <config.h>
 +#endif
 +
 +#include <gtk/gtk.h>
 +#include <gtkmm/uimanager.h>
 +
 +#include <gtkmm/ruler.h>
 +#include <gtkmm/arrow.h>
 +#include <gtkmm/image.h>
 +#include <gdkmm/pixbufloader.h>
 +#include <gtkmm/viewport.h>
 +#include <gtkmm/adjustment.h>
 +#include <gtkmm/scrolledwindow.h>
 +#include <gtkmm/table.h>
 +#include <gtkmm/statusbar.h>
 +#include <gtkmm/menubar.h>
 +#include <gtkmm/menu.h>
 +#include <gtkmm/button.h>
 +#include <gtkmm/toolbar.h>
 +#include <gtkmm/box.h>
 +#include <gtkmm/image.h>
 +#include <gtkmm/stock.h>
 +#include <gtkmm/handlebox.h>
 +
 +#include <gtkmm/inputdialog.h>
 +
 +#include <sigc++/signal.h>
 +#include <sigc++/hide.h>
 +#include <sigc++/slot.h>
 +#include <sigc++/retype_return.h>
 +#include <sigc++/retype.h>
 +
 +#include <sstream>
 +
 +#include "toolbox.h"
 +#include "instance.h"
 +#include "app.h"
 +#include "canvasview.h"
 +#include "dialogs/dialog_gradient.h"
 +#include "dialogs/dialog_color.h"
 +#include "docks/dialog_tooloptions.h"
 +#include "dialogs/dialog_preview.h"
 +#include "docks/dockable.h"
 +#include "docks/dockmanager.h"
 +#include "docks/dockdialog.h"
 +
 +#include "widgets/widget_defaults.h"
 +
 +#include <synfigapp/main.h>
 +
 +#include "general.h"
 +
 +#endif
 +
 +using namespace std;
 +using namespace etl;
 +using namespace synfig;
 +using namespace studio;
 +using namespace sigc;
 +
 +/* === M A C R O S ========================================================= */
 +
 +#define GRAB_HINT_DATA(y,default)     { \
 +              String x; \
 +              if(synfigapp::Main::settings().get_value(String("pref.")+y+"_hints",x)) \
 +              { \
 +                      set_type_hint((Gdk::WindowTypeHint)atoi(x.c_str()));    \
 +              } else {\
 +                      set_type_hint(default); \
 +              } \
 +      }
 +
 +/* === G L O B A L S ======================================================= */
 +
 +/* === P R O C E D U R E S ================================================= */
 +
 +/* === M E T H O D S ======================================================= */
 +
 +#define TOGGLE_TOOLBOX_BUTTON(button,stockid,tooltip) \
 +      button = manage(new class Gtk::ToggleButton()); \
 +      icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::IconSize(4)));    \
 +      button->add(*icon);     \
 +      tooltips.set_tip(*button,tooltip);      \
 +      icon->show();   \
 +      button->show()
 +
 +#define TOOLBOX_BUTTON(button,stockid,tooltip)        \
 +      button = manage(new class Gtk::Button());       \
 +      icon=manage(new Gtk::Image(Gtk::StockID(stockid),Gtk::IconSize(4)));    \
 +      button->add(*icon);     \
 +      tooltips.set_tip(*button,tooltip);      \
 +      icon->show();   \
 +      button->show()
 +
 +#define ADD_TOOLBOX_BUTTON(button,stockid,tooltip)    Gtk::Button *TOOLBOX_BUTTON(button,stockid,tooltip)
 +
 +void
 +save_selected_instance()
 +{
 +      if(!studio::App::get_selected_instance())
 +      {
 +              App::dialog_error_blocking(_("Cannot save"),_("Nothing to save"));
 +              return;
 +      }
 +
 +      studio::App::get_selected_instance()->save();
 +}
 +
 +void
 +save_as_selected_instance()
 +{
 +      if(!studio::App::get_selected_instance())
 +      {
 +              App::dialog_error_blocking(_("Cannot save as"),_("Nothing to save"));
 +              return;
 +      }
 +
 +      studio::App::get_selected_instance()->dialog_save_as();
 +}
 +
 +void
 +save_all()
 +{
 +      std::list<etl::handle<Instance> >::iterator iter;
 +      for(iter=App::instance_list.begin();iter!=App::instance_list.end();iter++)
 +              (*iter)->save();
 +}
 +
 +void
 +close_selected_instance()
 +{
 +      etl::handle<studio::Instance> instance=studio::App::get_selected_instance();
 +
 +      if(!instance)
 +      {
 +              App::dialog_error_blocking(_("Cannot close"),_("Nothing to close"));
 +              return;
 +      }
 +
 +      instance->safe_close();
 +
 +      //assert(instance.unique());
 +}
 +
 +
 +static void
 +show_dialog_input()
 +{
 +      App::dialog_input->present();
 +}
 +
 +void _create_stock_dialog1()
 +{
 +      DockDialog* dock_dialog(new DockDialog);
 +      dock_dialog->set_contents("canvases history");
 +      dock_dialog->set_composition_selector(true);
 +      dock_dialog->present();
 +}
 +void _create_stock_dialog2()
 +{
 +      DockDialog* dock_dialog(new DockDialog);
 +      dock_dialog->set_contents("layers children keyframes | params");
 +      dock_dialog->present();
 +}
 +
 +Toolbox::Toolbox():
 +      Gtk::Window(Gtk::WINDOW_TOPLEVEL),
 +      dialog_settings(this,"toolbox")
 +{
 +      GRAB_HINT_DATA(
 +              "toolbox",
 +//#ifdef __APPLE__
 +              Gdk::WINDOW_TYPE_HINT_NORMAL
 +//#else
 +//            Gdk::WINDOW_TYPE_HINT_UTILITY
 +//#endif
 +      );
 +      set_keep_above(false);
 +      set_role("toolbox");
 +
 +
 +
 +      recent_files_menu= manage(new class Gtk::Menu());
 +
 +      Gtk::Menu       *filemenu       =manage(new class Gtk::Menu());
 +
 +      dock_dialogs=manage(new class Gtk::Menu());
 +
 +      dock_dialogs->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Vertical Dock: Canvases, History"),sigc::ptr_fun(_create_stock_dialog1)));
 +      dock_dialogs->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Horizontal Dock: Layers, Children, Params"),sigc::ptr_fun(_create_stock_dialog2)));
 +      dock_dialogs->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
 +      dock_dialogs->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Reset Windows to Original Layout"),sigc::ptr_fun(App::reset_initial_window_configuration)));
 +      dock_dialogs->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
 +
 +
 +      filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::NEW,
 +              sigc::ptr_fun(&studio::App::new_instance)));
 +      filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::OPEN,
 +              sigc::bind(sigc::ptr_fun(&studio::App::dialog_open), "")));
 +
 +      filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Open Recent"),*recent_files_menu));
 +
 +      filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("synfig-saveall"),
 +              sigc::ptr_fun(save_all)));
 +      filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::CLOSE,
 +              sigc::ptr_fun(close_selected_instance)));
 +      filemenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
 +      filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Panels"),*dock_dialogs));
 +
 +      filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Input Devices..."),
 +              sigc::ptr_fun(&show_dialog_input)));
 +      filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Setup..."),
 +              sigc::ptr_fun(&studio::App::show_setup)));
++      filemenu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("Reset to default Setup values"),
++              sigc::ptr_fun(&studio::App::reset_initial_preferences)));
 +
 +      filemenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
 +      filemenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID(Gtk::Stock::QUIT),
 +              sigc::ptr_fun(studio::App::quit)));
 +
 +#define WIKI(title,page)                                                                                      \
 +      helpmenu->items().push_back(Gtk::Menu_Helpers::MenuElem(title,  \
 +              sigc::bind(sigc::ptr_fun(&studio::App::open_url),String("http://synfig.org/wiki")+page)))
 +
 +#define SITE(title,page)                                                                                      \
 +      helpmenu->items().push_back(Gtk::Menu_Helpers::MenuElem(title,  \
 +              sigc::bind(sigc::ptr_fun(&studio::App::open_url),String("http://synfig.org")+page)))
 +
 +      Gtk::Menu       *helpmenu = manage(new class Gtk::Menu());
 +      helpmenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::Stock::HELP, sigc::ptr_fun(studio::App::dialog_help)));
 +      helpmenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
 +
 +      /* TRANSLATORS: Help menu entry */ WIKI(_("Tutorials"),                                 /* TRANSLATORS: a wiki page */ _("/Category:Tutorials")                         );
 +      /* TRANSLATORS: Help menu entry */ WIKI(_("Reference"),                                 /* TRANSLATORS: a wiki page */ _("/Category:Reference")                         );
 +      /* TRANSLATORS: Help menu entry */ WIKI(_("Frequently Asked Questions"),/* TRANSLATORS: a wiki page */ _("/FAQ")                                        );
 +      helpmenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
 +      /* TRANSLATORS: Help menu entry */ SITE(_("Get Support"),                               /* TRANSLATORS: a website page */ _("/en/support")                      );
 +      helpmenu->items().push_back(Gtk::Menu_Helpers::SeparatorElem());
 +      helpmenu->items().push_back(Gtk::Menu_Helpers::StockMenuElem(Gtk::StockID("synfig-about"),
 +              sigc::ptr_fun(studio::App::dialog_about)));
 +
 +      Gtk::MenuBar *menubar1 = manage(new class Gtk::MenuBar());
 +      menubar1->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_File"),*filemenu));
 +      menubar1->items().push_back(Gtk::Menu_Helpers::MenuElem(_("_Help"),*helpmenu));
 +
 +
 +      menubar1->show();
 +
 +      Gtk::Image *icon;
 +
 +      ADD_TOOLBOX_BUTTON(button_new,"gtk-new",_("New..."));
 +      ADD_TOOLBOX_BUTTON(button_open,"gtk-open",_("Open..."));
 +      ADD_TOOLBOX_BUTTON(button_save,"gtk-save",_("Save"));
 +      ADD_TOOLBOX_BUTTON(button_saveas,"gtk-save-as",_("Save As..."));
 +      ADD_TOOLBOX_BUTTON(button_save_all,"synfig-saveall",_("Save All"));
 +      TOOLBOX_BUTTON(button_undo,"gtk-undo",_("Undo"));
 +      TOOLBOX_BUTTON(button_redo,"gtk-redo",_("Redo"));
 +      ADD_TOOLBOX_BUTTON(button_setup,"gtk-properties",_("Setup"));
 +      ADD_TOOLBOX_BUTTON(button_about,"synfig-about",_("About Synfig Studio"));
 +      ADD_TOOLBOX_BUTTON(button_help,"gtk-help",_("Help"));
 +
 +      button_setup->signal_clicked().connect(sigc::ptr_fun(studio::App::show_setup));
 +      button_about->signal_clicked().connect(sigc::ptr_fun(studio::App::dialog_about));
 +      button_help->signal_clicked().connect(sigc::ptr_fun(studio::App::dialog_help));
 +      button_new->signal_clicked().connect(sigc::ptr_fun(studio::App::new_instance));
 +      button_open->signal_clicked().connect(sigc::bind(sigc::ptr_fun(studio::App::dialog_open), ""));
 +      button_save->signal_clicked().connect(sigc::ptr_fun(save_selected_instance));
 +      button_saveas->signal_clicked().connect(sigc::ptr_fun(save_as_selected_instance));
 +      button_save_all->signal_clicked().connect(sigc::ptr_fun(save_all));
 +      button_undo->signal_clicked().connect(sigc::ptr_fun(studio::App::undo));
 +      button_redo->signal_clicked().connect(sigc::ptr_fun(studio::App::redo));
 +
 +      // Create the file button cluster
 +      Gtk::Table *file_buttons=manage(new class Gtk::Table());
 +
-       file_buttons->attach(*button_undo,     0,1, 1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_redo,     1,2, 1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_setup,    2,3, 1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_about,    3,4, 1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
-       file_buttons->attach(*button_help,     4,5, 1,2, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
++      file_buttons->attach(*button_new,      0,1, 0,1, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_open,     1,2, 0,1, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_save,     2,3, 0,1, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_saveas,   3,4, 0,1, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_save_all, 4,5, 0,1, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
 +
-       tool_table->attach(*button,col,col+1,row,row+1, Gtk::SHRINK, Gtk::SHRINK, 0, 0);
++      file_buttons->attach(*button_undo,     0,1, 1,2, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_redo,     1,2, 1,2, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_setup,    2,3, 1,2, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_about,    3,4, 1,2, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
++      file_buttons->attach(*button_help,     4,5, 1,2, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
 +
 +      file_buttons->show();
 +
 +      tool_table=manage(new class Gtk::Table());
 +      tool_table->show();
 +      Gtk::HandleBox* handle_tools(manage(new Gtk::HandleBox()));
 +      handle_tools->add(*tool_table);
 +      handle_tools->show();
 +      handle_tools->set_handle_position(Gtk::POS_TOP);
 +      handle_tools->set_snap_edge(Gtk::POS_TOP);
 +
 +      Widget_Defaults* widget_defaults(manage(new Widget_Defaults()));
 +      widget_defaults->show();
 +      Gtk::HandleBox* handle_defaults(manage(new Gtk::HandleBox()));
 +      handle_defaults->add(*widget_defaults);
 +      handle_defaults->show();
 +      handle_defaults->set_handle_position(Gtk::POS_TOP);
 +      handle_defaults->set_snap_edge(Gtk::POS_TOP);
 +
 +      // Create the toplevel table
 +      Gtk::Table *table1 = manage(new class Gtk::Table(1, 2, false));
 +      table1->set_row_spacings(0);
 +      table1->set_col_spacings(0);
 +      table1->attach(*menubar1,        0,1, 0,1, Gtk::FILL|Gtk::EXPAND, Gtk::SHRINK, 0, 0);
 +      table1->attach(*file_buttons,    0,1, 1,2, Gtk::FILL|Gtk::EXPAND,Gtk::EXPAND|Gtk::FILL, 0, 0);
 +      table1->attach(*handle_tools,    0,1, 2,3, Gtk::FILL|Gtk::EXPAND,Gtk::EXPAND|Gtk::FILL, 0, 0);
 +      table1->attach(*handle_defaults, 0,1, 3,4, Gtk::FILL|Gtk::EXPAND,Gtk::EXPAND|Gtk::FILL, 0, 0);
 +      table1->show_all();
 +
 +
 +
 +      // Set the parameters for this window
 +      add(*table1);
 +      set_title(_("Synfig Studio"));
 +      set_modal(false);
 +      property_window_position().set_value(Gtk::WIN_POS_NONE);
 +      signal_delete_event().connect(sigc::ptr_fun(App::shutdown_request));
 +      set_resizable(false);
 +
 +
 +
 +      App::signal_instance_selected().connect(
 +              sigc::hide(
 +                      sigc::mem_fun(*this,&studio::Toolbox::update_undo_redo)
 +              )
 +      );
 +
 +      App::signal_recent_files_changed().connect(
 +                      sigc::mem_fun(*this,&studio::Toolbox::on_recent_files_changed)
 +      );
 +
 +      button_undo->set_sensitive(false);
 +      button_redo->set_sensitive(false);
 +
 +      std::list<Gtk::TargetEntry> listTargets;
 +      listTargets.push_back( Gtk::TargetEntry("text/plain") );
 +      listTargets.push_back( Gtk::TargetEntry("image") );
 +//    listTargets.push_back( Gtk::TargetEntry("image/x-sif") );
 +
 +      drag_dest_set(listTargets);
 +      signal_drag_data_received().connect( sigc::mem_fun(*this, &studio::Toolbox::on_drop_drag_data_received) );
 +
 +      App::dock_manager->signal_dockable_registered().connect(sigc::mem_fun(*this,&Toolbox::dockable_registered));
 +
 +      changing_state_=false;
 +
 +
 +      add_accel_group(App::ui_manager()->get_accel_group());
 +
 +      App::signal_present_all().connect(sigc::mem_fun0(*this,&Toolbox::present));
 +}
 +
 +Toolbox::~Toolbox()
 +{
 +      hide();
 +      //studio::App::cb.task(_("Toolbox: I was nailed!"));
 +      //studio::App::quit();
 +
 +      if(studio::App::toolbox==this)
 +              studio::App::toolbox=NULL;
 +
 +}
 +
 +void
 +Toolbox::set_active_state(const synfig::String& statename)
 +{
 +      std::map<synfig::String,Gtk::ToggleButton *>::iterator iter;
 +
 +      changing_state_=true;
 +
 +      synfigapp::Main::set_state(statename);
 +
 +      try
 +      {
 +
 +              for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
 +              {
 +                      if(iter->first==statename)
 +                      {
 +                              if(!iter->second->get_active())
 +                                      iter->second->set_active(true);
 +                      }
 +                      else
 +                      {
 +                              if(iter->second->get_active())
 +                                      iter->second->set_active(false);
 +                      }
 +              }
 +      }
 +      catch(...)
 +      {
 +              changing_state_=false;
 +              throw;
 +      }
 +      changing_state_=false;
 +}
 +
 +void
 +Toolbox::change_state(const synfig::String& statename)
 +{
 +      etl::handle<studio::CanvasView> canvas_view(studio::App::get_selected_canvas_view());
 +      if(canvas_view)
 +      {
 +              if(statename==canvas_view->get_smach().get_state_name())
 +              {
 +                      return;
 +              }
 +
 +              if(state_button_map.count(statename))
 +              {
 +                      state_button_map[statename]->clicked();
 +              }
 +              else
 +              {
 +                      synfig::error("Unknown state \"%s\"",statename.c_str());
 +              }
 +      }
 +}
 +
 +void
 +Toolbox::change_state_(const Smach::state_base *state)
 +{
 +      if(changing_state_)
 +              return;
 +      changing_state_=true;
 +
 +      try
 +      {
 +              etl::handle<studio::CanvasView> canvas_view(studio::App::get_selected_canvas_view());
 +              if(canvas_view)
 +                              canvas_view->get_smach().enter(state);
 +              else
 +                      refresh();
 +      }
 +      catch(...)
 +      {
 +              changing_state_=false;
 +              throw;
 +      }
 +
 +      changing_state_=false;
 +}
 +
 +void
 +Toolbox::add_state(const Smach::state_base *state)
 +{
 +      Gtk::Image *icon;
 +
 +      assert(state);
 +
 +      String name=state->get_name();
 +
 +      Gtk::StockItem stock_item;
 +      Gtk::Stock::lookup(Gtk::StockID("synfig-"+name),stock_item);
 +
 +      Gtk::ToggleButton* button;
 +      button=manage(new class Gtk::ToggleButton());
 +
 +      icon=manage(new Gtk::Image(stock_item.get_stock_id(),Gtk::IconSize(4)));
 +      button->add(*icon);
 +      tooltips.set_tip(*button,stock_item.get_label());
 +      icon->show();
 +      button->show();
 +
 +      int row=state_button_map.size()/5;
 +      int col=state_button_map.size()%5;
 +
++      tool_table->attach(*button,col,col+1,row,row+1, Gtk::EXPAND, Gtk::EXPAND, 0, 0);
 +
 +      state_button_map[name]=button;
 +
 +      button->signal_clicked().connect(
 +              sigc::bind(
 +                      sigc::mem_fun(*this,&studio::Toolbox::change_state_),
 +                      state
 +              )
 +      );
 +
 +      refresh();
 +}
 +
 +
 +void
 +Toolbox::update_undo_redo()
 +{
 +      etl::handle<Instance> instance=App::get_selected_instance();
 +      if(instance)
 +      {
 +              button_undo->set_sensitive(instance->get_undo_status());
 +              button_redo->set_sensitive(instance->get_redo_status());
 +      }
 +
 +      // This should probably go elsewhere, but it should
 +      // work fine here with no troubles.
 +      // These next several lines just adjust the tool buttons
 +      // so that they are only clickable when they should be.
 +      if(instance && App::get_selected_canvas_view())
 +      {
 +              std::map<synfig::String,Gtk::ToggleButton *>::iterator iter;
 +
 +              for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
 +                      iter->second->set_sensitive(true);
 +      }
 +      else
 +      {
 +              std::map<synfig::String,Gtk::ToggleButton *>::iterator iter;
 +
 +              for(iter=state_button_map.begin();iter!=state_button_map.end();++iter)
 +                      iter->second->set_sensitive(false);
 +      }
 +
 +      etl::handle<CanvasView> canvas_view=App::get_selected_canvas_view();
 +      if(canvas_view && canvas_view->get_smach().get_state_name())
 +      {
 +              set_active_state(canvas_view->get_smach().get_state_name());
 +      }
 +      else
 +              set_active_state("none");
 +
 +}
 +
 +void
 +Toolbox::on_recent_files_changed()
 +{
 +      while(recent_files_menu->get_children().size())
 +              recent_files_menu->remove(**recent_files_menu->get_children().begin());
 +
 +      list<string>::const_iterator iter;
 +      for(iter=App::get_recent_files().begin();iter!=App::get_recent_files().end();iter++)
 +      {
 +              string raw = basename(*iter), quoted;
 +              size_t pos = 0, last_pos = 0;
 +
 +              // replace _ in filenames by __ or it won't show up in the menu
 +              for (pos = last_pos = 0; (pos = raw.find('_', pos)) != string::npos; last_pos = pos)
 +                      quoted += raw.substr(last_pos, ++pos - last_pos) + '_';
 +              quoted += raw.substr(last_pos);
 +
 +              recent_files_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(quoted,
 +                      sigc::hide_return(sigc::bind(sigc::ptr_fun(&App::open),*iter))
 +              ));
 +      }
 +
 +      // HACK
 +      show();
 +}
 +
 +void
 +Toolbox::on_drop_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int /*x*/, int /*y*/, const Gtk::SelectionData& selection_data_, guint /*info*/, guint time)
 +{
 +      // We will make this true once we have a solid drop
 +      bool success(false);
 +
 +      if ((selection_data_.get_length() >= 0) && (selection_data_.get_format() == 8))
 +      {
 +              synfig::String selection_data((gchar *)(selection_data_.get_data()));
 +
 +              // For some reason, GTK hands us a list of URLs separated
 +              // by not only Carriage-Returns, but also Line-Feeds.
 +              // Line-Feeds will mess us up. Remove all the line-feeds.
 +              while(selection_data.find_first_of('\r')!=synfig::String::npos)
 +                      selection_data.erase(selection_data.begin()+selection_data.find_first_of('\r'));
 +
 +              std::stringstream stream(selection_data);
 +
 +              while(stream)
 +              {
 +                      synfig::String filename,URI;
 +                      getline(stream,filename);
 +
 +                      // If we don't have a filename, move on.
 +                      if(filename.empty())
 +                              continue;
 +
 +                      // Make sure this URL is of the "file://" type.
 +                      URI=String(filename.begin(),filename.begin()+sizeof("file://")-1);
 +                      if(URI!="file://")
 +                      {
 +                              synfig::warning("Unknown URI (%s) in \"%s\"",URI.c_str(),filename.c_str());
 +                              continue;
 +                      }
 +
 +                      // Strip the "file://" part from the filename
 +                      filename=synfig::String(filename.begin()+sizeof("file://")-1,filename.end());
 +
 +                      synfig::info("Attempting to open "+filename);
 +                      if(App::open(filename))
 +                              success=true;
 +                      else
 +                              synfig::error("Drop failed: Unable to open "+filename);
 +              }
 +      }
 +      else
 +              synfig::error("Drop failed: bad selection data");
 +
 +      // Finish the drag
 +      context->drag_finish(success, false, time);
 +}
 +
 +void
 +Toolbox::dockable_registered(Dockable* x)
 +{
 +      dock_dialogs->items().push_back(
 +              Gtk::Menu_Helpers::MenuElem(
 +                      x->get_local_name(),
 +                      sigc::mem_fun(
 +                              *x,
 +                              &Dockable::present
 +                      )
 +              )
 +      );
 +}