X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fapp.cpp;h=504d0a061c12c1c759386f5b7ed6313a9e3d071a;hb=63e709f66d50c124cc0ece2325f4773ac4ae7b20;hp=53f3581a2cc208dc26b647b5076bcfcbb0238e00;hpb=c17ff8c0593a678801a38e3dc400ace6bc57a4bb;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/app.cpp b/synfig-studio/trunk/src/gtkmm/app.cpp index 53f3581..504d0a0 100644 --- a/synfig-studio/trunk/src/gtkmm/app.cpp +++ b/synfig-studio/trunk/src/gtkmm/app.cpp @@ -2,10 +2,11 @@ /*! \file app.cpp ** \brief writeme ** -** $Id: app.cpp,v 1.11 2005/03/24 21:47:28 darco Exp $ +** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** 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 @@ -31,12 +32,14 @@ #include #include +#include #ifdef HAVE_SYS_ERRNO_H #include #endif #include #include +#include #include #include #include @@ -120,6 +123,8 @@ #include #include +#include "general.h" + #endif /* === U S I N G =========================================================== */ @@ -134,8 +139,10 @@ using namespace studio; #ifndef SYNFIG_USER_APP_DIR #ifdef __APPLE__ #define SYNFIG_USER_APP_DIR "Library/Synfig" -#else +#elif defined(_WIN32) #define SYNFIG_USER_APP_DIR "Synfig" +#else +#define SYNFIG_USER_APP_DIR ".synfig" #endif #endif @@ -248,6 +255,7 @@ studio::Dock_Curves* dock_curves; 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_; } @@ -256,6 +264,25 @@ 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; @@ -275,11 +302,11 @@ public: ); 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(); @@ -293,12 +320,12 @@ public: ); 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(); @@ -312,11 +339,11 @@ public: ); 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(); @@ -332,17 +359,8 @@ public: virtual bool error(const std::string &err) - { - Gtk::Dialog dialog( - "Error", // Title - true, // Modal - true // use_separator - ); - Gtk::Label label(err); - label.show(); - - dialog.get_vbox()->pack_start(label); - dialog.add_button(Gtk::StockID("gtk-ok"),RESPONSE_OK); + { + Gtk::MessageDialog dialog(err, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true); dialog.show(); dialog.run(); return true; @@ -357,7 +375,7 @@ public: } virtual bool - amount_complete(int current, int total) + amount_complete(int /*current*/, int /*total*/) { while(studio::App::events_pending())studio::App::iteration(false); return true; @@ -366,149 +384,6 @@ public: /* === 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)<element.serial|=(((U32)(data>>2)&3)<>24); - } - } - - unwound_key.element.serial^=appid_mask_a; - unwound_key.element.checksum^=appid_mask_b; - - *serial=unwound_key.element.serial; - - return unwound_key.element.checksum==hash_U32(unwound_key.element.serial); -} - - -int check_license(String basedir) -{ -#ifdef LICENSE_KEY_REQUIRED - String key; - String license_file; - -#ifndef _WIN32 - license_file="/usr/local/etc/.synfiglicense"; -#else - license_file=basedir+"\\etc\\.synfiglicense"; -#endif - - try { - key=Glib::file_get_contents(license_file); - } catch (Glib::FileError) { } - U32 serial(0); - if(!v_key_check(key.c_str(),&serial,0xdeadbeef)) - { - while(!v_key_check(key.c_str(),&serial,0xdeadbeef)) - { - key.clear(); - - if(!App::dialog_entry( - _("Synfig Studio Authentication"), - _("Please enter your license key below. You will not\nbe able to use this software without a valid license key."), - key - )) - throw String("No License"); - } - - FILE* file=fopen(license_file.c_str(),"w"); - if(file) - { - fprintf(file,"%s",key.c_str()); - fclose(file); - } - else - synfig::error("Unable to save license key!"); - } - synfig::info("License Authenticated -- Serial #%05d",serial); - return serial; -#else - return 1; -#endif -} - /* void studio::UIManager::insert_action_group (const Glib::RefPtr& action_group, int pos) @@ -536,30 +411,24 @@ studio::add_action_group_to_top(Glib::RefPtr ui_manager, Glib { ui_manager->insert_action_group(group,0); return; - DEBUGPOINT(); std::list > prev_groups(ui_manager->get_action_groups()); std::list >::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 @@ -597,21 +466,26 @@ public: 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()); 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, @@ -620,7 +494,7 @@ public: ); App::gamma.set_all(r,g,b,blk); - + return true; } if(key=="time_format") @@ -652,10 +526,16 @@ public: 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); } - + virtual KeyList get_key_list()const { KeyList ret(synfigapp::Settings::get_key_list()); @@ -664,6 +544,7 @@ public: 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; } @@ -679,19 +560,19 @@ init_ui_manager() Glib::RefPtr toolbox_action_group = Gtk::ActionGroup::create("toolbox"); Glib::RefPtr 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-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; @@ -703,7 +584,7 @@ init_ui_manager() iter->second.local_name,iter->second.local_name )); } - + #define DEFINE_ACTION(x,stock) { Glib::RefPtr action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); } #define DEFINE_ACTION2(x,stock,label) { Glib::RefPtr action( Gtk::Action::create(x, stock,label,label) ); /*action->set_sensitive(false);*/ actions_action_group->add(action); } #define DEFINE_ACTION_SIG(group,x,stock,sig) { Glib::RefPtr action( Gtk::Action::create(x, stock) ); /*action->set_sensitive(false);*/ group->add(action,sig); } @@ -724,7 +605,8 @@ init_ui_manager() 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("undo", Gtk::StockID("gtk-undo")); @@ -754,7 +636,7 @@ init_ui_manager() DEFINE_ACTION("quality-09", _("Use Quality Level 9")); DEFINE_ACTION("quality-10", _("Use Quality Level 10")); 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")); @@ -789,11 +671,11 @@ init_ui_manager() // Set up synfigapp actions /*{ synfigapp::Action::Book::iterator iter; - + for(iter=synfigapp::Action::book().begin();iter!=synfigapp::Action::book().end();++iter) { Gtk::StockID stock_id; - + if(!(iter->second.category&synfigapp::Action::CATEGORY_HIDDEN)) { //Gtk::Image* image(manage(new Gtk::Image())); @@ -807,7 +689,7 @@ init_ui_manager() //else if(iter->second.task=="duplicate") stock_id=Gtk::Stock::COPY; else if(iter->second.task=="remove") stock_id=Gtk::Stock::DELETE; else stock_id=Gtk::StockID("synfig-"+iter->second.task); - + actions_action_group->add(Gtk::Action::create( "action-"+iter->second.name, stock_id, @@ -844,6 +726,7 @@ init_ui_manager() " " " " " " +" " " " " " " " @@ -882,7 +765,7 @@ init_ui_manager() " " " " " " -" " +//" " " " " " " " @@ -911,8 +794,6 @@ init_ui_manager() " " " " " " - " " - " " " " " " " " @@ -925,6 +806,8 @@ init_ui_manager() //" " //" " " " +" " +" " " " " " " " @@ -969,8 +852,18 @@ init_ui_manager() } // Add default keyboard accelerators -#define ACCEL(path,accel) { Gtk::AccelKey accel_key(accel,path); Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(),accel_key.get_mod()); } -#define ACCEL2(accel) { Gtk::AccelKey accel_key(accel); Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(),accel_key.get_mod()); } +#define ACCEL(path,accel) \ + { \ + Gtk::AccelKey accel_key(accel,path); \ + Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(), accel_key.get_mod()); \ + } + +#define ACCEL2(accel) \ + { \ + Gtk::AccelKey accel_key(accel); \ + Gtk::AccelMap::add_entry(accel_key.get_path(), accel_key.get_key(), accel_key.get_mod()); \ + } + ACCEL("//select-all-ducks","a"); ACCEL("//unselect-all-layers","d"); ACCEL("//render","F9"); @@ -989,7 +882,6 @@ init_ui_manager() ACCEL("//mask-width-ducks", "5"); ACCEL("//mask-angle-ducks", "6"); - ACCEL2(Gtk::AccelKey(GDK_Page_Up,Gdk::SHIFT_MASK,"//action-layer_raise")); ACCEL2(Gtk::AccelKey(GDK_Page_Down,Gdk::SHIFT_MASK,"//action-layer_lower")); @@ -1028,18 +920,32 @@ init_ui_manager() ACCEL2(Gtk::AccelKey('>',Gdk::CONTROL_MASK,"//seek-next-second")); ACCEL2(Gtk::AccelKey('<',Gdk::CONTROL_MASK,"//seek-prev-second")); ACCEL2(Gtk::AccelKey('o',Gdk::CONTROL_MASK,"//toggle-onion-skin")); + ACCEL("//play", "p"); ACCEL("//seek-begin","Home"); ACCEL("//seek-end","End"); - ACCEL("//state-normal","a"); - ACCEL("//state-rotate","s"); - ACCEL("//state-scale","d"); - ACCEL("//state-bline","b"); - ACCEL("//state-fill","f"); - ACCEL("//state-eyedrop","e"); - ACCEL("//state-gradient","g"); - ACCEL("//state-zoom","z"); + + ACCEL("//state-normal", "a"); + ACCEL("//state-smooth_move", "v"); + ACCEL("//state-scale", "d"); + ACCEL("//state-rotate", "s"); + + ACCEL("//state-bline", "b"); + ACCEL("//state-circle", "c"); + ACCEL("//state-rectangle", "r"); + ACCEL("//state-gradient", "g"); + + ACCEL("//state-eyedrop", "e"); + ACCEL("//state-fill", "f"); + ACCEL("//state-zoom", "z"); + ACCEL("//state-polygon", "p"); + + ACCEL("//state-draw", "w"); + ACCEL("//state-sketch", "k"); + ACCEL("//state-width", "t"); + ACCEL("//state-mirror", "m"); + ACCEL("//canvas-zoom-fit","z"); - + #undef ACCEL } @@ -1051,22 +957,22 @@ init_ui_manager() 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; - + if(mkdir(get_user_app_directory().c_str(),ACCESSPERMS)<0) { if(errno!=EEXIST) @@ -1076,38 +982,24 @@ App::App(int *argc, char ***argv): { synfig::info("Created directory \"%s\"",get_user_app_directory().c_str()); } - - + + ipc=new IPC(); - - try + + if(!SYNFIG_CHECK_VERSION()) { - if(!SYNFIG_CHECK_VERSION()) - { cerr<<"FATAL: Synfig Version Mismatch"<(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; } // add the preferences to the settings synfigapp::Main::settings().add_domain(&_preferences,"pref"); - + 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 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...")); 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_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); - if(false) { - // Disabled this tool because it should be - // considered deprecated. Use the bline tool instead. - state_manager->add_state(&state_polygon); - - // These tools are disabled for now, - // because they tend to confuse users. - state_manager->add_state(&state_draw); - state_manager->add_state(&state_sketch); - state_manager->add_state(&state_width); - } + // 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); + + // Enabled for now. Let's see whether they're good enough yet. + if(!getenv("SYNFIG_DISABLE_DRAW" )) state_manager->add_state(&state_draw); + if(!getenv("SYNFIG_DISABLE_SKETCH" )) state_manager->add_state(&state_sketch); + + // 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..."); + 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(); 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 ) { @@ -1276,7 +1169,7 @@ App::App(int *argc, char ***argv): } else get_ui_interface()->error( - _("SYNFIG Studio has attempted to recover\n" + _("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.") @@ -1284,23 +1177,27 @@ App::App(int *argc, char ***argv): } about_window.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..."); + studio_init_cb.task(_("Loading files...")); about_window.hide(); open((*argv)[*argc]); about_window.show(); } - - studio_init_cb.task("Done."); + + 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.")); @@ -1316,27 +1213,27 @@ App::~App() 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; toolbox->hide(); -// studio::App::iteration(false); - +// studio::App::iteration(false); + delete toolbox; - -// studio::App::iteration(false); -// studio::App::iteration(false); +// studio::App::iteration(false); + +// studio::App::iteration(false); delete dialog_setup; @@ -1371,18 +1268,18 @@ App::add_recent_file(const std::string &file_name) 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 outselves into one + + // If we aren't an absolute path, turn ourselves into one if(!is_absolute_path(filename)) filename=absolute_path(filename); - + list::iterator iter; // Check to see if the file is already on the list. // If it is, then remove it from the list @@ -1393,16 +1290,16 @@ App::add_recent_file(const std::string &file_name) break; } - + // Push the filename to the front of the list recent_files.push_front(filename); - + // Clean out the files at the end of the list. while(recent_files.size()>(unsigned)get_max_recent_files()) recent_files.pop_back(); - + signal_recent_files_changed_(); - + return; } @@ -1424,8 +1321,11 @@ App::set_time_format(synfig::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); @@ -1434,21 +1334,22 @@ App::save_settings() 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::reverse_iterator iter; - + for(iter=recent_files.rbegin();iter!=recent_files.rend();iter++) file<<*iter<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; } @@ -1578,22 +1489,22 @@ App::quit() return; } } -*/ - +*/ + // This next line causes things to crash for some reason - //(*iter)->close(); + //(*iter)->close(); } - + shutdown_in_progress=true; instance_list.clear(); while(studio::App::events_pending())studio::App::iteration(false); - + Gtk::Main::quit(); auto_recover->normal_shutdown(); - get_ui_interface()->task("Quit Request sent"); + get_ui_interface()->task(_("Quit Request sent")); } void @@ -1603,8 +1514,8 @@ App::show_setup() dialog_setup->show(); } -gint Signal_Open_Ok(GtkWidget *widget, int *val){*val=1;return 0;} -gint Signal_Open_Cancel(GtkWidget *widget, int *val){*val=2;return 0;} +gint Signal_Open_Ok(GtkWidget */*widget*/, int *val){*val=1;return 0;} +gint Signal_Open_Cancel(GtkWidget */*widget*/, int *val){*val=2;return 0;} //#ifdef WIN32 //#define USE_WIN32_FILE_DIALOGS 1 @@ -1617,7 +1528,7 @@ static OPENFILENAME ofn={}; #ifdef WIN32 #include #endif - + bool App::dialog_open_file(const std::string &title, std::string &filename) { @@ -1627,7 +1538,7 @@ App::dialog_open_file(const std::string &title, std::string &filename) GdkWindow *gdkWinPtr=toolbox->get_window()->gobj(); HINSTANCE hInstance=static_cast(GetModuleHandle(NULL)); HWND hWnd=static_cast(GDK_WINDOW_HWND(gdkWinPtr)); - + ofn.lStructSize=sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.hInstance = hInstance; @@ -1647,33 +1558,37 @@ App::dialog_open_file(const std::string &title, std::string &filename) // 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 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_OPEN); dialog->set_current_folder(prev_path); - dialog->add_button(Gtk::StockID("gtk-ok"),GTK_RESPONSE_ACCEPT); - dialog->add_button(Gtk::StockID("gtk-cancel"),GTK_RESPONSE_CANCEL); + dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT); if(!filename.empty()) - dialog->set_filename(filename); + 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(); delete dialog; @@ -1682,18 +1597,18 @@ App::dialog_open_file(const std::string &title, std::string &filename) delete dialog; return false; /* - + GtkWidget *ok; GtkWidget *cancel; int val=0; - + GtkWidget *fileselection; fileselection = gtk_file_selection_new(title.c_str()); - + if(basename(filename)==filename) { - gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),(prev_path+ETL_DIRECTORY_SEPERATOR).c_str()); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),(prev_path+ETL_DIRECTORY_SEPARATOR).c_str()); } else gtk_file_selection_set_filename(GTK_FILE_SELECTION(fileselection),dirname(filename).c_str()); @@ -1703,15 +1618,15 @@ App::dialog_open_file(const std::string &title, std::string &filename) ok=GTK_FILE_SELECTION(fileselection)->ok_button; cancel=GTK_FILE_SELECTION(fileselection)->cancel_button; - gtk_signal_connect(GTK_OBJECT(ok),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Ok),&val); - gtk_signal_connect(GTK_OBJECT(cancel),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Cancel),&val); + gtk_signal_connect(GTK_OBJECT(ok),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Ok),&val); + gtk_signal_connect(GTK_OBJECT(cancel),"clicked",GTK_SIGNAL_FUNC(Signal_Open_Cancel),&val); gtk_widget_show(fileselection); while(!val) - iteration(); - - + iteration(); + + if(val==1) { filename=gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection)); @@ -1731,13 +1646,13 @@ App::dialog_open_file(const std::string &title, std::string &filename) bool App::dialog_save_file(const std::string &title, std::string &filename) { -#ifdef USE_WIN32_FILE_DIALOGS +#if USE_WIN32_FILE_DIALOGS static TCHAR szFilter[] = TEXT ("All Files (*.*)\0*.*\0\0") ; - + GdkWindow *gdkWinPtr=toolbox->get_window()->gobj(); HINSTANCE hInstance=static_cast(GetModuleHandle(NULL)); HWND hWnd=static_cast(GDK_WINDOW_HWND(gdkWinPtr)); - + ofn.lStructSize=sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.hInstance = hInstance; @@ -1757,18 +1672,19 @@ App::dialog_save_file(const std::string &title, std::string &filename) // 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("curr_path",dirname(filename)); return true; } return false; @@ -1776,82 +1692,31 @@ App::dialog_save_file(const std::string &title, std::string &filename) 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::StockID("gtk-ok"),GTK_RESPONSE_ACCEPT); - dialog->add_button(Gtk::StockID("gtk-cancel"),GTK_RESPONSE_CANCEL); + dialog->add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog->add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); if(!filename.empty()) - dialog->set_filename(filename); - if(dialog->run()==GTK_RESPONSE_ACCEPT) { - filename=dialog->get_filename(); - delete dialog; - return true; - } - delete dialog; - return false; -// return dialog_open_file(title, filename); -#endif -} - -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(GetModuleHandle(NULL)); - HWND hWnd=static_cast(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; - return true; + 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)); } - return false; -#else - synfig::String prev_path; - if(!_preferences.get_value("curr_path",prev_path)) - prev_path="."; - - Gtk::FileChooserDialog *dialog=new Gtk::FileChooserDialog(title,Gtk::FILE_CHOOSER_ACTION_SAVE); - dialog->set_current_folder(prev_path); - dialog->add_button(Gtk::StockID("gtk-ok"),GTK_RESPONSE_ACCEPT); - dialog->add_button(Gtk::StockID("gtk-cancel"),GTK_RESPONSE_CANCEL); - if(!filename.empty()) - dialog->set_filename(filename); if(dialog->run()==GTK_RESPONSE_ACCEPT) { filename=dialog->get_filename(); delete dialog; + _preferences.set_value("curr_path",dirname(filename)); return true; } delete dialog; @@ -1863,16 +1728,8 @@ App::dialog_saveas_file(const std::string &title, std::string &filename) void App::dialog_error_blocking(const std::string &title, const std::string &message) { - Gtk::Dialog dialog( - title, // Title - true, // Modal - true // use_separator - ); - Gtk::Label label(message); - label.show(); - - dialog.get_vbox()->pack_start(label); - dialog.add_button(Gtk::StockID("gtk-ok"),1); + Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true); + dialog.set_title(title); dialog.show(); dialog.run(); } @@ -1880,16 +1737,8 @@ App::dialog_error_blocking(const std::string &title, const std::string &message) void App::dialog_warning_blocking(const std::string &title, const std::string &message) { - Gtk::Dialog dialog( - title, // Title - true, // Modal - true // use_separator - ); - Gtk::Label label(message); - label.show(); - - dialog.get_vbox()->pack_start(label); - dialog.add_button(Gtk::StockID("gtk-ok"),1); + Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_CLOSE, true); + dialog.set_title(title); dialog.show(); dialog.run(); } @@ -1904,7 +1753,7 @@ App::dialog_yes_no(const std::string &title, const std::string &message) ); 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); @@ -1934,17 +1783,8 @@ App::dialog_yes_no_cancel(const std::string &title, const std::string &message) void App::dialog_not_implemented() { - Gtk::Dialog dialog( - "Feature not available", // Title - true, // Modal - true // use_separator - ); - Gtk::Label label("Sorry, this feature has not yet been implemented."); - label.show(); - - dialog.get_vbox()->pack_start(label); - dialog.add_button(Gtk::StockID("gtk-ok"),Gtk::RESPONSE_OK); - dialog.show(); + 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(); } @@ -1989,6 +1829,9 @@ 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) { @@ -2001,25 +1844,25 @@ App::open_as(std::string filename,std::string as) try { OneMoment one_moment; - + etl::handle canvas(open_canvas_as(filename,as)); if(canvas && get_instance(canvas)) { get_instance(canvas)->find_canvas_view(canvas)->present(); - throw (String)strprintf(_("\"%s\" appears to already be open!"),filename.c_str()); + throw (String)strprintf(_("\"%s\" appears to already be open!"),filename.c_str()); } if(!canvas) throw (String)strprintf(_("Unable to open file \"%s\""),filename.c_str()); add_recent_file(as); - + handle instance(Instance::create(canvas)); if(!instance) throw (String)strprintf(_("Unable to create instance for \"%s\""),filename.c_str()); - + one_moment.hide(); - + if(instance->is_updated() && App::dialog_yes_no(_("CVS Update"), _("There appears to be a newer version of this file available on the CVS repository.\nWould you like to update now? (It would probably be a good idea)"))) instance->dialog_cvs_update(); } @@ -2035,7 +1878,7 @@ App::open_as(std::string filename,std::string as) } _preferences.set_value("curr_path",dirname(as)); - + return true; } @@ -2044,10 +1887,10 @@ void App::new_instance() { handle 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("%s%d.sifz", DEFAULT_FILENAME_PREFIX, Instance::get_count()+1)); - String file_name(strprintf("untitled%d.sif",Instance::get_count())); - canvas->rend_desc().set_frame_rate(24.0); canvas->rend_desc().set_time_start(0.0); canvas->rend_desc().set_time_end(00.0); @@ -2060,8 +1903,11 @@ App::new_instance() canvas->rend_desc().set_antialias(1); canvas->rend_desc().set_flags(RendDesc::PX_ASPECT|RendDesc::IM_SPAN); canvas->set_file_name(file_name); - - Instance::create(canvas)->find_canvas_view(canvas)->canvas_properties.present(); + + handle instance = Instance::create(canvas); + + if (!getenv("SYNFIG_DISABLE_NEW_CANVAS_EDIT_PROPERTIES")) + instance->find_canvas_view(canvas)->canvas_properties.present(); } void @@ -2133,7 +1979,7 @@ App::set_selected_canvas_view(etl::loose_handle canvas_view) } etl::loose_handle -App::get_instance(Canvas::Handle canvas) +App::get_instance(etl::handle canvas) { if(!canvas) return 0; canvas=canvas->get_root();