--- /dev/null
- "http://synfig.org/Download"
+/* === 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"
- if (!try_open_url("http://synfig.org/Documentation"))
++ "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);
+ if(!getenv("SYNFIG_DISABLE_WIDTH" )) state_manager->add_state(&state_width); // Enabled since 0.61.09
+
+ /* new objects */
+ 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
+ state_manager->add_state(&state_text);
+ 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.
+
+ /* other */
+ state_manager->add_state(&state_fill);
+ state_manager->add_state(&state_eyedrop);
+ state_manager->add_state(&state_zoom);
+ if(!getenv("SYNFIG_DISABLE_SKETCH" )) state_manager->add_state(&state_sketch);
+
+ 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);
+
+ 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);
+}
+
+#define SCALE_FACTOR (1280)
+//! set the \a instance's canvas(es) position and size to be those specified in the first entry of recent_files_window_size
+void
+App::set_recent_file_window_size(etl::handle<Instance> instance)
+{
+ int screen_w(Gdk::screen_width());
+ int screen_h(Gdk::screen_height());
+
+ const std::string &canvas_window_size = *recent_files_window_size.begin();
+
+ if(canvas_window_size.empty())
+ return;
+
+ synfig::String::size_type current=0;
+ bool seen_root(false), shown_non_root(false);
+
+ while(current != synfig::String::npos)
+ {
+ // find end of first field (canvas) or return
+ synfig::String::size_type separator = canvas_window_size.find_first_of(' ', current);
+ if(separator == synfig::String::npos) break;
+
+ // find the canvas
+ synfig::Canvas::Handle canvas;
+ try {
+ String warnings;
+ canvas = instance->get_canvas()->find_canvas(String(canvas_window_size, current, separator-current), warnings);
+ }
+ catch(Exception::IDNotFound) {
+ // can't find the canvas; skip to the next canvas or return
+ separator = canvas_window_size.find_first_of('\t', current);
+ if(separator == synfig::String::npos) return;
+ current = separator+1;
+ continue;
+ }
+
+ if (canvas->is_root())
+ seen_root = true;
+ else
+ shown_non_root = true;
+
+ // check that we have the tab character the ends this canvas' data or return
+ current = separator+1;
+ separator = canvas_window_size.find_first_of('\t', current);
+ if(separator == synfig::String::npos) return;
+
+ int x,y,w,h;
+ if(!strscanf(String(canvas_window_size, current, separator-current),"%d %d %d %d",&x, &y, &w, &h))
+ {
+ current = separator+1;
+ continue;
+ }
+
+ if (x > SCALE_FACTOR) x = SCALE_FACTOR - 150; if (x < 0) x = 0;
+ if (y > SCALE_FACTOR) y = SCALE_FACTOR - 150; if (y < 0) y = 0;
+ x=x*screen_w/SCALE_FACTOR;
+ y=y*screen_h/SCALE_FACTOR;
+ if(getenv("SYNFIG_WINDOW_POSITION_X_OFFSET"))
+ x += atoi(getenv("SYNFIG_WINDOW_POSITION_X_OFFSET"));
+ if(getenv("SYNFIG_WINDOW_POSITION_Y_OFFSET"))
+ y += atoi(getenv("SYNFIG_WINDOW_POSITION_Y_OFFSET"));
+
+ if (w > SCALE_FACTOR) w = 150; if (w < 0) w = 0;
+ if (h > SCALE_FACTOR) h = 150; if (h < 0) h = 0;
+
+ CanvasView::Handle canvasview = instance->find_canvas_view(canvas);
+ canvasview->move(x,y);
+ canvasview->resize(w*screen_w/SCALE_FACTOR,h*screen_h/SCALE_FACTOR);
+ canvasview->present();
+
+ current = separator+1;
+ }
+
+ if (shown_non_root && !seen_root)
+ instance->find_canvas_view(instance->get_canvas())->hide();
+}
+
+void
+App::add_recent_file(const etl::handle<Instance> instance)
+{
+ int screen_w(Gdk::screen_width());
+ int screen_h(Gdk::screen_height());
+
+ std::string canvas_window_size;
+
+ const Instance::CanvasViewList& cview_list = instance->canvas_view_list();
+ Instance::CanvasViewList::const_iterator iter;
+
+ for(iter=cview_list.begin();iter!=cview_list.end();iter++)
+ {
+ if( !((*iter)->is_visible()) )
+ continue;
+
+ etl::handle<synfig::Canvas> canvas = (*iter)->get_canvas();
+ int x_pos, y_pos, x_size, y_size;
+ (*iter)->get_position(x_pos,y_pos);
+ (*iter)->get_size(x_size,y_size);
+
+ canvas_window_size += strprintf("%s %d %d %d %d\t",
+ canvas->get_relative_id(canvas->get_root()).c_str(),
+ x_pos*SCALE_FACTOR/screen_w, y_pos*SCALE_FACTOR/screen_h,
+ x_size*SCALE_FACTOR/screen_w, y_size*SCALE_FACTOR/screen_h);
+ }
+
+ add_recent_file(absolute_path(instance->get_file_name()), canvas_window_size);
+}
+#undef SCALE_FACTOR
+
+void
+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()
+{
+ synfigapp::Main::settings().set_value("dock.dialog.1.comp_selector","1");
+ synfigapp::Main::settings().set_value("dock.dialog.1.contents","navigator - info pal_edit pal_browse - tool_options history canvases - layers groups");
+ synfigapp::Main::settings().set_value("dock.dialog.1.contents_size","225 167 207");
+ synfigapp::Main::settings().set_value("dock.dialog.1.pos","1057 32");
+ synfigapp::Main::settings().set_value("dock.dialog.1.size","208 1174");
+ synfigapp::Main::settings().set_value("dock.dialog.2.comp_selector","0");
+ synfigapp::Main::settings().set_value("dock.dialog.2.contents","params children keyframes | timetrack curves meta_data");
+ synfigapp::Main::settings().set_value("dock.dialog.2.contents_size","263");
+ synfigapp::Main::settings().set_value("dock.dialog.2.pos","0 973");
+ synfigapp::Main::settings().set_value("dock.dialog.2.size","1045 235");
+ synfigapp::Main::settings().set_value("pref.distance_system","pt");
+ synfigapp::Main::settings().set_value("pref.use_colorspace_gamma","1");
+#ifdef SINGLE_THREADED
+ synfigapp::Main::settings().set_value("pref.single_threaded","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);
+ synfigapp::Main::settings().set_value("window.toolbox.pos","4 4");
+}
+
+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_00, "0.62.00", strprintf("0.62.00 (%s)", _("current")))
+ .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()
+{
- dialog.set_secondary_text(_("Documentation for Synfig Studio is available on the website:\n\nhttp://www.synfig.org/Documentation"));
++ 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_;
+}
--- /dev/null
- set_website("http://www.synfig.org/");
+/* === 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-2008\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("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("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("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("Robert B. Quattlebaum Jr. (darco)");
+
+ 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);
+}
--- /dev/null
- "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.",
- "libxvidcore MPEG-4 part 2.",
- "MJPEG (Motion JPEG).",
- "raw MPEG-1 video.",
- "raw MPEG-2 video.",
- "MPEG-4 part 2.",
- "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.",
+/* === 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 ========================================================= */
+
+/* === 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[] =
+{
+ "flv", "h263p", "huffyuv", "libtheora", "libx264", "libxvid",
+ "mjpeg", "mpeg1video", "mpeg2video", "mpeg4", "msmpeg4",
+ "msmpeg4v1", "msmpeg4v2", "wmv1", "wmv2", 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[] =
+{
- set_title("TargetParam Dialog");
++ _("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."),
++ _("libxvidcore MPEG-4 part 2."),
++ _("MJPEG (Motion JPEG)."),
++ _("raw MPEG-1 video."),
++ _("raw MPEG-2 video."),
++ _("MPEG-4 part 2."),
++ _("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."),
+ 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 ================================================= */
+
+Dialog_TargetParam::Dialog_TargetParam(synfig::TargetParam &tparam)
+{
++ set_title(_("TargetParam Dialog"));
+ set_tparam(tparam);
+ // Available Video Codecs Combo Box Text.
+ vcodec = Gtk::manage(new Gtk::ComboBoxText());
+ Gtk::Label* label(manage(new Gtk::Label(_("Available Video Codecs:"))));
+ label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
+ get_vbox()->pack_start(*label, true, true, 0);
+ for (int i = 0; allowed_video_codecs[i] != NULL &&
+ allowed_video_codecs_description[i] != NULL; i++)
+ vcodec->append_text(allowed_video_codecs_description[i]);
+ 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]);
+
+ get_vbox()->pack_start(*vcodec, true, true, 0);
+
+ //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()
+{
+ 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];
+ tparam_.bitrate=bitrate->get_value();
+ hide();
+}
+
+void
+Dialog_TargetParam::on_cancel()
+{
+ hide();
+}
+
+Dialog_TargetParam::~Dialog_TargetParam()
+{
+}
+
--- /dev/null
- else if(layer.find("gradient")!=String::npos)
- return Gtk::StockID("synfig-gradient");
+/* === 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,_("Normal 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);
+}
--- /dev/null
- Gtk::Button *render_button(manage(new class Gtk::Button(Gtk::StockID("Render"))));
+/* === 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),
+ tparam("libxvid",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));
+
+ Gtk::Button *tparam_button(manage(new class Gtk::Button(Gtk::StockID(_("Parameters...")))));
+ tparam_button->show();
+ 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;
+}
+
+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(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();
+}
--- /dev/null
- etl::handle<CanvasView> canvas_view_;
+/* === 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:
- etl::handle<CanvasView> canvas_view_;
++ 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
+{
- const etl::handle<CanvasView>& get_canvas_view()const{return canvas_view_;}
++ CanvasView* canvas_view_;
+
+ synfigapp::Settings& settings;
+
+ sigc::connection keypress_connect;
+ sigc::connection keyrelease_connect;
+
+ etl::handle<DuckDrag_Combo> duck_dragger_;
+
+ Gtk::Table options_table;
+
+ Gtk::CheckButton checkbutton_rotate;
+ Gtk::CheckButton checkbutton_scale;
+ Gtk::CheckButton checkbutton_constrain;
+
+public:
+
+ 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(); }
+
+ 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(); }
+
+ 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(); }
+
+ 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 load_settings();
+ void save_settings();
+
+ bool key_pressed(GdkEventKey *event);
+ bool key_released(GdkEventKey *event);
+
+ 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_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_LAYER_CLICKED,&StateNormal_Context::event_layer_click));
+
+}
+
+StateNormal::~StateNormal()
+{
+}
+
+void
+StateNormal_Context::load_settings()
+{
+ 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::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");
+}
+
+StateNormal_Context::StateNormal_Context(CanvasView* canvas_view):
+ canvas_view_(canvas_view),
+ 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)"))
+{
+ duck_dragger_->canvas_view_=get_canvas_view();
+
+ // Set up the tool options dialog
+ 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));
+
+
+ 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_);
+
+ 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);
+
+ //these will segfault
+// get_work_area()->set_cursor(Gdk::CROSSHAIR);
+// get_work_area()->reset_cursor();
+
+ App::toolbox->refresh();
+
+ 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
+}
+
+void
+StateNormal_Context::refresh_tool_options()
+{
+ App::dialog_tool_options->clear();
+ App::dialog_tool_options->set_widget(options_table);
+ App::dialog_tool_options->set_local_name(_("Normal Tool"));
+ App::dialog_tool_options->set_name("normal");
+}
+
+
+
+StateNormal_Context::~StateNormal_Context()
+{
+ save_settings();
+
+ 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_Combo::DuckDrag_Combo():
+ scale(false),
+ rotate(false),
+ constrain(false) // Lock aspect for scale; smooth move for translate
+{
+}
+
+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
+ {
+ //vect[0]=vect[1]=vect.mag()*0.707106781;
+ Real 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_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;
+}
+
+
--- /dev/null
- /* TRANSLATORS: Help menu entry */ WIKI(_("Synfig Wiki"), /* TRANSLATORS: a wiki page */ _("/Main_Page") );
- /* TRANSLATORS: Help menu entry */ WIKI(_("Tutorials"), /* TRANSLATORS: a wiki page */ _("/Tutorials") );
+/* === 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::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(_("Get Support"), /* TRANSLATORS: a wiki page */ _("/Contact") );
- /* TRANSLATORS: Help menu entry */ WIKI(_("Keyboard Shortcuts"), /* TRANSLATORS: a wiki page */ _("/Keyboard_Shortcuts") );
- /* TRANSLATORS: Help menu entry */ WIKI(_("Mouse Shortcuts"), /* TRANSLATORS: a wiki page */ _("/Mouse_Shortcuts") );
- /* TRANSLATORS: Help menu entry */ WIKI(_("All Pages"), "/Special:Allpages" );
-
++ /* 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_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);
+
+ 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->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::SHRINK, Gtk::SHRINK, 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
+ )
+ )
+ );
+}