**
** \legal
** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+** Copyright (c) 2007 Chris Moore
**
** This package is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
#include <fstream>
#include <iostream>
#include <locale>
+#include <cstring>
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#include "app.h"
#include "about.h"
+#include "splash.h"
#include "instance.h"
#include "canvasview.h"
#include "dialog_setup.h"
#include <gtkmm/filechooser.h>
#include <gtkmm/filechooserdialog.h>
+#include "general.h"
+
#endif
/* === U S I N G =========================================================== */
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;
std::list< etl::handle< studio::Module > > module_list_;
bool studio::App::use_colorspace_gamma=true;
+bool studio::App::single_threaded=false;
static int max_recent_files_=25;
int studio::App::get_max_recent_files() { return max_recent_files_; }
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;
/* === P R O C E D U R E S ================================================= */
-typedef unsigned char U8;
-typedef unsigned short U16;
-typedef unsigned long U32;
-
-typedef union {
- struct {
- U32 serial;
- U32 checksum;
- } element;
- U8 raw[8];
-} V_KeyUnwound;
-
-static inline U32 hash_U32(U32 i)
-{
- i=i*1664525+1013904223;
- i=i*1664525+1013904223;
- i=i*1664525+1013904223;
- return i;
-}
-
-#ifdef BIG_ENDIAN
-static const int endian_fix_table[8] = { 3, 2, 1, 0, 7, 6, 5, 4 } ;
-#define endian_fix(x) (endian_fix_table[x])
-#else
-#define endian_fix(x) (x)
-#endif
-
-int v_unwind_key(V_KeyUnwound* unwound, const char* key)
-{
- int i;
- unwound->element.serial=0;
- unwound->element.checksum=0;
-
- for(i=0;i<16;i++)
- {
- U8 data;
-
- switch(key[i])
- {
- case '0': data=0; break;
- case '1': data=1; break;
- case '2': data=2; break;
- case '3': data=3; break;
- case '4': data=4; break;
- case '5': data=5; break;
- case '6': data=6; break;
- case '7': data=7; break;
- case '8': data=8; break;
- case '9': data=9; break;
- case 'a': case 'A': data=10; break;
- case 'b': case 'B': data=11; break;
- case 'c': case 'C': data=12; break;
- case 'd': case 'D': data=13; break;
- case 'e': case 'E': data=14; break;
- case 'f': case 'F': data=15; break;
- default: return 0; break;
- }
- int bit=i*2;
- unwound->element.checksum|=(((U32)data&3)<<bit);
- unwound->element.serial|=(((U32)(data>>2)&3)<<bit);
- }
- return 1;
-}
-
-int v_key_check(const char* key, U32* serial, U32 appid)
-{
- V_KeyUnwound unwound_key;
- U32 appid_mask_a=hash_U32(appid);
- U32 appid_mask_b=hash_U32(appid_mask_a);
-
- if(!v_unwind_key(&unwound_key, key))
- {
- // Invalid characters in key
- return 0;
- }
-
-
- // Undo obfuscation pass
- {
- U32 next=hash_U32(unwound_key.raw[endian_fix(7)]);
- int i;
- for(i=0;i<7;i++)
- {
- next=hash_U32(next);
- unwound_key.raw[endian_fix(i)]^=(next>>24);
- }
- }
-
- unwound_key.element.serial^=appid_mask_a;
- unwound_key.element.checksum^=appid_mask_b;
-
- *serial=unwound_key.element.serial;
-
- return unwound_key.element.checksum==hash_U32(unwound_key.element.serial);
-}
-
-
-#ifdef _WIN32
-# ifdef LICENSE_KEY_REQUIRED
-int check_license(String basedir)
-# else
-int check_license(String /*basedir*/)
-# endif
-#else
-int check_license(String /*basedir*/)
-#endif
-{
-#ifdef LICENSE_KEY_REQUIRED
- String key;
- String license_file;
-
-#ifndef _WIN32
- license_file="/usr/local/etc/.synfiglicense";
-#else
- license_file=basedir+"\\etc\\.synfiglicense";
-#endif
-
- try {
- key=Glib::file_get_contents(license_file);
- } catch (Glib::FileError) { }
- U32 serial(0);
- if(!v_key_check(key.c_str(),&serial,0xdeadbeef))
- {
- while(!v_key_check(key.c_str(),&serial,0xdeadbeef))
- {
- key.clear();
-
- if(!App::dialog_entry(
- _("Synfig Studio Authentication"),
- _("Please enter your license key below. You will not\nbe able to use this software without a valid license key."),
- key
- ))
- throw String("No License");
- }
-
- FILE* file=fopen(license_file.c_str(),"w");
- if(file)
- {
- fprintf(file,"%s",key.c_str());
- fclose(file);
- }
- else
- synfig::error("Unable to save license key!");
- }
- synfig::info("License Authenticated -- Serial #%05d",serial);
- return serial;
-#else
- return 1;
-#endif
-}
-
/*
void
studio::UIManager::insert_action_group (const Glib::RefPtr<Gtk::ActionGroup>& action_group, int pos)
{
ui_manager->insert_action_group(group,0);
return;
- DEBUGPOINT();
std::list<Glib::RefPtr<Gtk::ActionGroup> > prev_groups(ui_manager->get_action_groups());
std::list<Glib::RefPtr<Gtk::ActionGroup> >::reverse_iterator iter;
- DEBUGPOINT();
for(iter=prev_groups.rbegin();iter!=prev_groups.rend();++iter)
{
- DEBUGPOINT();
if(*iter && (*iter)->get_name()!="menus")
{
synfig::info("Removing action group "+(*iter)->get_name());
ui_manager->remove_action_group(*iter);
}
}
- DEBUGPOINT();
ui_manager->insert_action_group(group,0);
- DEBUGPOINT();
for(;!prev_groups.empty();prev_groups.pop_front())
{
if(prev_groups.front() && prev_groups.front()!=group && prev_groups.front()->get_name()!="menus")
ui_manager->insert_action_group(prev_groups.front(),1);
}
- DEBUGPOINT();
}
*/
class Preferences : public synfigapp::Settings
value=strprintf("%s",Distance::system_name(App::distance_system).c_str());
return true;
}
+ if(key=="single_threaded")
+ {
+ value=strprintf("%i",(int)App::single_threaded);
+ return true;
+ }
if(key=="auto_recover_backup_interval")
{
value=strprintf("%i",App::auto_recover->get_timeout());
App::distance_system=Distance::ident_system(value);;
return true;
}
+ if(key=="single_threaded")
+ {
+ int i(atoi(value.c_str()));
+ App::single_threaded=i;
+ return true;
+ }
return synfigapp::Settings::set_value(key,value);
}
ret.push_back("distance_system");
ret.push_back("file_history.size");
ret.push_back("use_colorspace_gamma");
+ ret.push_back("single_threaded");
ret.push_back("auto_recover_backup_interval");
return ret;
}
Glib::RefPtr<Gtk::ActionGroup> actions_action_group = Gtk::ActionGroup::create();
- menus_action_group->add( Gtk::Action::create("menu-file", "_File") );
- menus_action_group->add( Gtk::Action::create("menu-edit", "_Edit") );
- menus_action_group->add( Gtk::Action::create("menu-view", "_View") );
- menus_action_group->add( Gtk::Action::create("menu-canvas", "_Canvas") );
- menus_action_group->add( Gtk::Action::create("menu-layer", "_Layer") );
- menus_action_group->add( Gtk::Action::create("menu-duck-mask", "Show/Hide Ducks") );
- menus_action_group->add( Gtk::Action::create("menu-preview-quality", "Preview Quality") );
- menus_action_group->add( Gtk::Action::create("menu-layer-new", "New Layer") );
- menus_action_group->add( Gtk::Action::create("menu-keyframe", "Keyframe") );
- menus_action_group->add( Gtk::Action::create("menu-group", "Group") );
- menus_action_group->add( Gtk::Action::create("menu-state", "State") );
- menus_action_group->add( Gtk::Action::create("menu-toolbox", "Toolbox") );
+ menus_action_group->add( Gtk::Action::create("menu-file", _("_File")) );
+ menus_action_group->add( Gtk::Action::create("menu-edit", _("_Edit")) );
+ menus_action_group->add( Gtk::Action::create("menu-view", _("_View")) );
+ menus_action_group->add( Gtk::Action::create("menu-canvas", _("_Canvas")) );
+ menus_action_group->add( Gtk::Action::create("menu-layer", _("_Layer")) );
+ menus_action_group->add( Gtk::Action::create("menu-duck-mask", _("Show/Hide Ducks")) );
+ menus_action_group->add( Gtk::Action::create("menu-preview-quality", _("Preview Quality")) );
+ menus_action_group->add( Gtk::Action::create("menu-lowres-pixel", _("Low-Res Pixel Size")) );
+ menus_action_group->add( Gtk::Action::create("menu-layer-new", _("New Layer")) );
+ menus_action_group->add( Gtk::Action::create("menu-keyframe", _("Keyframe")) );
+ menus_action_group->add( Gtk::Action::create("menu-group", _("Group")) );
+ menus_action_group->add( Gtk::Action::create("menu-state", _("State")) );
+ menus_action_group->add( Gtk::Action::create("menu-toolbox", _("Toolbox")) );
// Add the synfigapp actions...
synfigapp::Action::Book::iterator iter;
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("dialog-flipbook", _("Preview Dialog"));
DEFINE_ACTION("sound", _("Sound File"));
DEFINE_ACTION("options", _("Options"));
- DEFINE_ACTION("close", _("Close"));
+ DEFINE_ACTION("close", _("Close View"));
+ DEFINE_ACTION("close-document", _("Close Document"));
+ DEFINE_ACTION("quit", Gtk::Stock::QUIT);
DEFINE_ACTION("undo", Gtk::StockID("gtk-undo"));
DEFINE_ACTION("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("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"));
" </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='bleh04'/>"
" <menuitem action='options' />"
" <menuitem action='close' />"
+" <menuitem action='close-document' />"
+" <menuitem action='quit' />"
" </menu>"
" <menu action='menu-edit'>"
" <menuitem action='undo'/>"
" <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='pause'/>"
" <menuitem action='stop'/>"
" <menuitem action='dialog-flipbook'/>"
" <separator name='bleh09'/>"
ACCEL("<Actions>//time-zoom-in","+");
ACCEL("<Actions>//time-zoom-out","_");
*/
+ ACCEL2(Gtk::AccelKey('(',Gdk::CONTROL_MASK,"<Actions>//decrease-low-res-pixel-size"));
+ ACCEL2(Gtk::AccelKey(')',Gdk::CONTROL_MASK,"<Actions>//increase-low-res-pixel-size"));
+
ACCEL2(Gtk::AccelKey('(',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,"<Actions>//amount-dec"));
ACCEL2(Gtk::AccelKey(')',Gdk::MOD1_MASK|Gdk::CONTROL_MASK,"<Actions>//amount-inc"));
ACCEL2(Gtk::AccelKey(',',Gdk::CONTROL_MASK,"<Actions>//seek-prev-frame"));
ACCEL2(Gtk::AccelKey('>',Gdk::CONTROL_MASK,"<Actions>//seek-next-second"));
ACCEL2(Gtk::AccelKey('<',Gdk::CONTROL_MASK,"<Actions>//seek-prev-second"));
- ACCEL2(Gtk::AccelKey('o',Gdk::CONTROL_MASK,"<Actions>//toggle-onion-skin"));
+ ACCEL2(Gtk::AccelKey('o',Gdk::MOD1_MASK,"<Actions>//toggle-onion-skin"));
+ ACCEL("<Actions>//play", "<Control>p");
ACCEL("<Actions>//seek-begin","Home");
ACCEL("<Actions>//seek-end","End");
App::App(int *argc, char ***argv):
Gtk::Main(argc,argv),
- IconControler(etl::dirname((*argv)[0]))
+ IconController(etl::dirname((*argv)[0]))
{
app_base_path_=etl::dirname(etl::dirname((*argv)[0]));
- int serial_;
- serial_=check_license(app_base_path_);
-
ui_interface_=new GlobalUIInterface();
gdk_rgb_init();
- Glib::thread_init();
+ // don't call thread_init() if threads are already initialized
+ // on some machines bonobo_init() initialized threads before we get here
+ if (!g_thread_supported())
+ Glib::thread_init();
distance_system=Distance::SYSTEM_UNITS;
ipc=new IPC();
- try
+ if(!SYNFIG_CHECK_VERSION())
{
- if(!SYNFIG_CHECK_VERSION())
- {
cerr<<"FATAL: Synfig Version Mismatch"<<endl;
dialog_error_blocking("Synfig Studio",
"This copy of Synfig Studio was compiled against a\n"
"different version of libsynfig than what is currently\n"
"installed. Synfig Studio will now abort. Try downloading\n"
"the latest version from the Synfig website at\n"
- "http://www.synfig.com/ "
+ "http://synfig.org/Download"
);
throw 40;
- }
- }
- catch(synfig::SoftwareExpired)
- {
- cerr<<"FATAL: Software Expired"<<endl;
- dialog_error_blocking("Synfig Studio",
- "This copy of Synfig Studio has expired.\n"
- "Please erase this copy, or download and\n"
- "install the latest copy from the Synfig\n"
- "website at http://www.synfig.com/ ."
- );
- throw 39;
}
Glib::set_application_name(_("Synfig Studio"));
- About about_window;
- about_window.set_can_self_destruct(false);
- about_window.show();
+ Splash splash_screen;
+ splash_screen.set_can_self_destruct(false);
+ splash_screen.show();
shutdown_in_progress=false;
- SuperCallback synfig_init_cb(about_window.get_callback(),0,9000,10000);
- SuperCallback studio_init_cb(about_window.get_callback(),9000,10000,10000);
+ SuperCallback synfig_init_cb(splash_screen.get_callback(),0,9000,10000);
+ SuperCallback studio_init_cb(splash_screen.get_callback(),9000,10000,10000);
// Initialize the Synfig library
try { synfigapp_main=etl::smart_ptr<synfigapp::Main>(new synfigapp::Main(etl::dirname((*argv)[0]),&synfig_init_cb)); }
catch(...)
{
- get_ui_interface()->error("Failed to initialize synfig!");
+ get_ui_interface()->error(_("Failed to initialize synfig!"));
throw;
}
try
{
- studio_init_cb.task("Init UI Manager...");
+ studio_init_cb.task(_("Init UI Manager..."));
App::ui_manager_=studio::UIManager::create();
init_ui_manager();
- studio_init_cb.task("Init Dock Manager...");
+ studio_init_cb.task(_("Init Dock Manager..."));
dock_manager=new studio::DockManager();
- studio_init_cb.task("Init State Manager...");
+ studio_init_cb.task(_("Init State Manager..."));
state_manager=new StateManager();
- studio_init_cb.task("Init Toolbox...");
+ studio_init_cb.task(_("Init Toolbox..."));
toolbox=new studio::Toolbox();
- studio_init_cb.task("Init Tool Options...");
+ studio_init_cb.task(_("Init About Dialog..."));
+ about=new studio::About();
+
+ studio_init_cb.task(_("Init Tool Options..."));
dialog_tool_options=new studio::Dialog_ToolOptions();
dock_manager->register_dockable(*dialog_tool_options);
- studio_init_cb.task("Init History...");
+ studio_init_cb.task(_("Init History..."));
dock_history=new studio::Dock_History();
dock_manager->register_dockable(*dock_history);
- studio_init_cb.task("Init Canvases...");
+ studio_init_cb.task(_("Init Canvases..."));
dock_canvases=new studio::Dock_Canvases();
dock_manager->register_dockable(*dock_canvases);
- studio_init_cb.task("Init Keyframes...");
+ studio_init_cb.task(_("Init Keyframes..."));
dock_keyframes=new studio::Dock_Keyframes();
dock_manager->register_dockable(*dock_keyframes);
- studio_init_cb.task("Init Layers...");
+ studio_init_cb.task(_("Init Layers..."));
dock_layers=new studio::Dock_Layers();
dock_manager->register_dockable(*dock_layers);
- studio_init_cb.task("Init Params...");
+ studio_init_cb.task(_("Init Params..."));
dock_params=new studio::Dock_Params();
dock_manager->register_dockable(*dock_params);
- studio_init_cb.task("Init MetaData...");
+ studio_init_cb.task(_("Init MetaData..."));
dock_meta_data=new studio::Dock_MetaData();
dock_manager->register_dockable(*dock_meta_data);
- studio_init_cb.task("Init Children...");
+ studio_init_cb.task(_("Init Children..."));
dock_children=new studio::Dock_Children();
dock_manager->register_dockable(*dock_children);
- studio_init_cb.task("Init Info...");
+ studio_init_cb.task(_("Init Info..."));
dock_info = new studio::Dock_Info();
dock_manager->register_dockable(*dock_info);
- studio_init_cb.task("Init Navigator...");
+ studio_init_cb.task(_("Init Navigator..."));
dock_navigator = new studio::Dock_Navigator();
dock_manager->register_dockable(*dock_navigator);
- studio_init_cb.task("Init Timetrack...");
+ studio_init_cb.task(_("Init Timetrack..."));
dock_timetrack = new studio::Dock_Timetrack();
dock_manager->register_dockable(*dock_timetrack);
- studio_init_cb.task("Init Curve Editor...");
+ studio_init_cb.task(_("Init Curve Editor..."));
dock_curves = new studio::Dock_Curves();
dock_manager->register_dockable(*dock_curves);
- studio_init_cb.task("Init Layer Groups...");
+ studio_init_cb.task(_("Init Layer Groups..."));
dock_layer_groups = new studio::Dock_LayerGroups();
dock_manager->register_dockable(*dock_layer_groups);
- studio_init_cb.task("Init Color Dialog...");
+ studio_init_cb.task(_("Init Color Dialog..."));
dialog_color=new studio::Dialog_Color();
- studio_init_cb.task("Init Gradient Dialog...");
+ studio_init_cb.task(_("Init Gradient Dialog..."));
dialog_gradient=new studio::Dialog_Gradient();
- studio_init_cb.task("Init DeviceTracker...");
+ studio_init_cb.task(_("Init DeviceTracker..."));
device_tracker=new studio::DeviceTracker();
- studio_init_cb.task("Init Tools...");
+ studio_init_cb.task(_("Init Tools..."));
+
+ /* row 1 */
state_manager->add_state(&state_normal);
state_manager->add_state(&state_smooth_move);
state_manager->add_state(&state_scale);
state_manager->add_state(&state_rotate);
+ studio_init_cb.task(_("Init ModMirror...")); module_list_.push_back(new ModMirror()); module_list_.back()->start();
+ /* row 2 */
state_manager->add_state(&state_bline);
-
-
state_manager->add_state(&state_circle);
state_manager->add_state(&state_rectangle);
-
state_manager->add_state(&state_gradient);
- state_manager->add_state(&state_eyedrop);
- state_manager->add_state(&state_fill);
-
- state_manager->add_state(&state_zoom);
-
- // Enabled - it's useful to be able to work with polygons without tangent ducks getting in the way.
- // I know we can switch tangent ducks off, but why not allow this kind of layer as well?
- if(!getenv("SYNFIG_DISABLE_POLYGON")) state_manager->add_state(&state_polygon);
+ if(!getenv("SYNFIG_DISABLE_POLYGON")) state_manager->add_state(&state_polygon); // Enabled - for working without ducks
- // Enabled for now. Let's see whether they're good enough yet.
- if(!getenv("SYNFIG_DISABLE_DRAW" )) state_manager->add_state(&state_draw);
+ /* row 3 */
+ if(!getenv("SYNFIG_DISABLE_DRAW" )) state_manager->add_state(&state_draw); // Enabled for now. Let's see whether they're good enough yet.
if(!getenv("SYNFIG_DISABLE_SKETCH" )) state_manager->add_state(&state_sketch);
+ state_manager->add_state(&state_fill);
+ state_manager->add_state(&state_eyedrop);
+ state_manager->add_state(&state_zoom);
// Disabled by default - it doesn't work properly?
if(getenv("SYNFIG_ENABLE_WIDTH" )) state_manager->add_state(&state_width);
- studio_init_cb.task("Init ModPalette...");
+ studio_init_cb.task(_("Init ModPalette..."));
module_list_.push_back(new ModPalette()); module_list_.back()->start();
- studio_init_cb.task("Init ModMirror...");
- module_list_.push_back(new ModMirror()); module_list_.back()->start();
-
-
- studio_init_cb.task("Init Setup Dialog...");
+ studio_init_cb.task(_("Init Setup Dialog..."));
dialog_setup=new studio::Dialog_Setup();
- studio_init_cb.task("Init Input Dialog...");
+ 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::ptr_fun(studio::App::dialog_not_implemented) );
- studio_init_cb.task("Init auto recovery...");
+ studio_init_cb.task(_("Init auto recovery..."));
auto_recover=new AutoRecover();
studio_init_cb.amount_complete(9250,10000);
- studio_init_cb.task("Loading Settings...");
+ studio_init_cb.task(_("Loading Settings..."));
load_settings();
- studio_init_cb.task("Checking auto-recover...");
+ studio_init_cb.task(_("Checking auto-recover..."));
studio_init_cb.amount_complete(9900,10000);
if(auto_recover->recovery_needed())
{
- about_window.hide();
+ splash_screen.hide();
if(
get_ui_interface()->yes_no(
- "Auto Recovery",
- "Synfig Studio seems to have crashed\n"
+ _("Auto Recovery"),
+ _("Synfig Studio seems to have crashed\n"
"before you could save all your files.\n"
"Would you like to re-open those files\n"
- "and recover your unsaved changes?"
+ "and recover your unsaved changes?")
)==synfigapp::UIInterface::RESPONSE_YES
)
{
"idea to review them and save them now.")
);
}
- about_window.show();
+ splash_screen.show();
}
// Look for any files given on the command line,
// and load them if found.
+ bool opened_any = false;
for(;*argc>=1;(*argc)--)
if((*argv)[*argc] && (*argv)[*argc][0]!='-')
{
- studio_init_cb.task("Loading files...");
- about_window.hide();
+ studio_init_cb.task(_("Loading files..."));
+ splash_screen.hide();
open((*argv)[*argc]);
- about_window.show();
+ opened_any = true;
+ splash_screen.show();
}
- studio_init_cb.task("Done.");
+ // if no file was specified to be opened, create a new document to help new users get started more easily
+ if (!opened_any && !getenv("SYNFIG_DISABLE_AUTOMATIC_DOCUMENT_CREATION"))
+ new_instance();
+
+ studio_init_cb.task(_("Done."));
studio_init_cb.amount_complete(10000,10000);
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."));
selected_instance=0;
// Unload all of the modules
- for(;!module_list_.empty();module_list_.pop_back());
+ for(;!module_list_.empty();module_list_.pop_back())
+ ;
delete state_manager;
delete auto_recover;
+ delete about;
+
toolbox->hide();
// studio::App::iteration(false);
if(basename(filename)[0]=='.')
return;
- // If we aren't an absolute path, turn outselves into one
+ // If we aren't an absolute path, turn ourselves into one
if(!is_absolute_path(filename))
filename=absolute_path(filename);
//if(!synfigapp::Main::settings().load_from_file(filename))
{
gamma.set_gamma(1.0/2.2);
- synfigapp::Main::settings().set_value("dock.dialog.1.comp_selector","1");
- synfigapp::Main::settings().set_value("dock.dialog.1.contents","navigator - info pal_edit pal_browse - tool_options history canvases - layers groups");
- synfigapp::Main::settings().set_value("dock.dialog.1.contents_size","225 167 207");
- synfigapp::Main::settings().set_value("dock.dialog.1.pos","1057 32");
- synfigapp::Main::settings().set_value("dock.dialog.1.size","208 1174");
- synfigapp::Main::settings().set_value("dock.dialog.2.comp_selector","0");
- synfigapp::Main::settings().set_value("dock.dialog.2.contents","params children keyframes | timetrack curves meta_data");
- synfigapp::Main::settings().set_value("dock.dialog.2.contents_size","263");
- synfigapp::Main::settings().set_value("dock.dialog.2.pos","0 973");
- synfigapp::Main::settings().set_value("dock.dialog.2.size","1045 235");
- synfigapp::Main::settings().set_value("pref.distance_system","pt");
- synfigapp::Main::settings().set_value("pref.use_colorspace_gamma","1");
- synfigapp::Main::settings().set_value("window.toolbox.pos","4 4");
+ reset_initial_window_configuration();
}
}
setlocale(LC_NUMERIC,old_locale);
}
}
+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");
+ synfigapp::Main::settings().set_value("pref.single_threaded","0");
+ synfigapp::Main::settings().set_value("window.toolbox.pos","4 4");
+}
+
bool
App::shutdown_request(GdkEventAny*)
{
if(shutdown_in_progress)return;
- get_ui_interface()->task("Quit Request");
+ 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");
+ dialog_error_blocking(_("Cannot quit!"),_("Tasks are currently running.\nPlease cancel the current tasks and try again"));
return;
}
Gtk::Main::quit();
auto_recover->normal_shutdown();
- get_ui_interface()->task("Quit Request sent");
+ get_ui_interface()->task(_("Quit Request sent"));
}
void
#endif
bool
-App::dialog_open_file(const std::string &title, std::string &filename)
+App::dialog_open_file(const std::string &title, std::string &filename, std::string preference)
{
+ info("App::dialog_open_file('%s', '%s', '%s')", title.c_str(), filename.c_str(), preference.c_str());
+
#ifdef USE_WIN32_FILE_DIALOGS
static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
#else
synfig::String prev_path;
- if(!_preferences.get_value("curr_path",prev_path))
- 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);
+ 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 + ETL_DIRECTORY_SEPARATOR + filename);
- if(dialog->run()==GTK_RESPONSE_ACCEPT) {
- filename=dialog->get_filename();
+
+ 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;
+
/*
GtkWidget *ok;
if(val==1)
{
filename=gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection));
- _preferences.set_value("curr_path",dirname(filename));
+ _preferences.set_value(preference,dirname(filename));
}
else
{
}
bool
-App::dialog_save_file(const std::string &title, std::string &filename)
+App::dialog_save_file(const std::string &title, std::string &filename, std::string preference)
{
-#ifdef USE_WIN32_FILE_DIALOGS
+ info("App::dialog_save_file('%s', '%s', '%s')", title.c_str(), filename.c_str(), preference.c_str());
+
+#if USE_WIN32_FILE_DIALOGS
static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
if(GetSaveFileName(&ofn))
{
filename=szFilename;
+ _preferences.set_value(preference,dirname(filename));
return true;
}
return false;
#else
synfig::String prev_path;
- if(!_preferences.get_value("curr_path",prev_path))
+
+ if(!_preferences.get_value(preference, prev_path))
prev_path=".";
+
prev_path = absolute_path(prev_path);
- Gtk::FileChooserDialog *dialog=new Gtk::FileChooserDialog(title,Gtk::FILE_CHOOSER_ACTION_SAVE);
+ 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);
- if(!filename.empty())
- dialog->set_filename(prev_path + ETL_DIRECTORY_SEPARATOR + filename);
- if(dialog->run()==GTK_RESPONSE_ACCEPT) {
- filename=dialog->get_filename();
- delete dialog;
- return true;
- }
- delete dialog;
- return false;
-// return dialog_open_file(title, filename);
-#endif
-}
-bool
-App::dialog_saveas_file(const std::string &title, std::string &filename)
-{
-#if USE_WIN32_FILE_DIALOGS
- static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ;
-
- GdkWindow *gdkWinPtr=toolbox->get_window()->gobj();
- HINSTANCE hInstance=static_cast<HINSTANCE>(GetModuleHandle(NULL));
- HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
-
- ofn.lStructSize=sizeof(OPENFILENAME);
- ofn.hwndOwner = hWnd;
- ofn.hInstance = hInstance;
- ofn.lpstrFilter = szFilter;
-// ofn.lpstrCustomFilter=NULL;
-// ofn.nMaxCustFilter=0;
-// ofn.nFilterIndex=0;
-// ofn.lpstrFile=NULL;
- ofn.nMaxFile=MAX_PATH;
-// ofn.lpstrFileTitle=NULL;
-// ofn.lpstrInitialDir=NULL;
-// ofn.lpstrTitle=NULL;
- ofn.Flags=OFN_OVERWRITEPROMPT;
-// ofn.nFileOffset=0;
-// ofn.nFileExtension=0;
- ofn.lpstrDefExt=TEXT("sif");
-// ofn.lCustData = 0l;
- ofn.lpfnHook=NULL;
-// ofn.lpTemplateName=NULL;
-
- CHAR szFilename[MAX_PATH];
- CHAR szTitle[500];
- strcpy(szFilename,filename.c_str());
- strcpy(szTitle,title.c_str());
+ 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;
- ofn.lpstrFile=szFilename;
- ofn.lpstrFileTitle=szTitle;
+ // select the file if it exists
+ dialog->set_filename(full_path);
- if(GetSaveFileName(&ofn))
- {
- filename=szFilename;
- return true;
+ // 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));
}
- return false;
-#else
- synfig::String prev_path;
- if(!_preferences.get_value("curr_path",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);
- if(!filename.empty())
- dialog->set_filename(prev_path + ETL_DIRECTORY_SEPARATOR + filename);
- if(dialog->run()==GTK_RESPONSE_ACCEPT) {
- filename=dialog->get_filename();
+ if(dialog->run() == GTK_RESPONSE_ACCEPT) {
+ 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;
-// return dialog_open_file(title, filename);
#endif
}
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.");
+ 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();
}
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)
{
return false;
}
- _preferences.set_value("curr_path",dirname(as));
-
return true;
}
App::new_instance()
{
handle<synfig::Canvas> canvas=synfig::Canvas::create();
- canvas->set_name(strprintf("Untitled%d",Instance::get_count()));
+ canvas->set_name(strprintf("%s%d", DEFAULT_FILENAME_PREFIX, Instance::get_count()+1));
- String file_name(strprintf("untitled%d.sif",Instance::get_count()));
+ String file_name(strprintf("%s%d.sifz", DEFAULT_FILENAME_PREFIX, Instance::get_count()+1));
canvas->rend_desc().set_frame_rate(24.0);
canvas->rend_desc().set_time_start(0.0);
- canvas->rend_desc().set_time_end(00.0);
+ canvas->rend_desc().set_time_end(5.0);
canvas->rend_desc().set_x_res(DPI2DPM(72.0f));
canvas->rend_desc().set_y_res(DPI2DPM(72.0f));
canvas->rend_desc().set_tl(Vector(-4,2.25));
canvas->rend_desc().set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN);
canvas->set_file_name(file_name);
- Instance::create(canvas)->find_canvas_view(canvas)->canvas_properties.present();
+ handle<Instance> instance = Instance::create(canvas);
+
+ if (getenv("SYNFIG_ENABLE_NEW_CANVAS_EDIT_PROPERTIES"))
+ instance->find_canvas_view(canvas)->canvas_properties.present();
}
void
{
string filename="*.sif";
- while(dialog_open_file("Open", filename))
+ while(dialog_open_file("Open", filename, ANIMATION_DIR_PREFERENCE))
{
// If the filename still has wildcards, then we should
// continue looking for the file we want
}
etl::loose_handle<Instance>
-App::get_instance(Canvas::Handle canvas)
+App::get_instance(etl::handle<synfig::Canvas> canvas)
{
if(!canvas) return 0;
canvas=canvas->get_root();
void
App::dialog_about()
{
- (new class About())->show();
+ if(about)
+ about->show();
}
void