X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fapp.cpp;h=eeb3ed35e051d77b8e01a1b6fac12a916ec3d0b2;hb=c2813b4d63804cac9b4067146a9e6eca717cb3e4;hp=277cc80397285872c35f129a380e4b5e25eb7f46;hpb=67567152a10173ae01e29eeda32267160c3c96c4;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/app.cpp b/synfig-studio/trunk/src/gtkmm/app.cpp index 277cc80..eeb3ed3 100644 --- a/synfig-studio/trunk/src/gtkmm/app.cpp +++ b/synfig-studio/trunk/src/gtkmm/app.cpp @@ -2,19 +2,21 @@ /*! \file app.cpp ** \brief writeme ** -** $Id: app.cpp,v 1.11 2005/03/24 21:47:28 darco Exp $ +** $Id$ ** ** \legal -** Copyright (c) 2002 Robert B. Quattlebaum Jr. +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007 Chris Moore ** -** This software and associated documentation -** are CONFIDENTIAL and PROPRIETARY property of -** the above-mentioned copyright holder. +** 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. ** -** You may not copy, print, publish, or in any -** other way distribute this software without -** a prior written agreement with -** the copyright holder. +** 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 */ /* ========================================================================= */ @@ -30,9 +32,14 @@ #include #include +#include +#ifdef HAVE_SYS_ERRNO_H +#include +#endif #include #include +#include #include #include #include @@ -109,9 +116,14 @@ #endif #ifdef WIN32 +#define _WIN32_WINNT 0x0500 #include #endif #include +#include +#include + +#include "general.h" #endif @@ -124,6 +136,16 @@ 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) @@ -233,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_; } @@ -241,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; @@ -260,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(); @@ -278,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(); @@ -297,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(); @@ -317,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; @@ -342,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; @@ -383,11 +416,11 @@ 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; @@ -420,13 +453,13 @@ 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 { @@ -438,17 +471,25 @@ int v_key_check(const char* key, U32* serial, U32 appid) 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; @@ -458,8 +499,8 @@ int check_license(String basedir) license_file="/usr/local/etc/.synfiglicense"; #else license_file=basedir+"\\etc\\.synfiglicense"; -#endif - +#endif + try { key=Glib::file_get_contents(license_file); } catch (Glib::FileError) { } @@ -469,7 +510,7 @@ int check_license(String basedir) 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."), @@ -477,7 +518,7 @@ int check_license(String basedir) )) throw String("No License"); } - + FILE* file=fopen(license_file.c_str(),"w"); if(file) { @@ -491,7 +532,7 @@ int check_license(String basedir) return serial; #else return 1; -#endif +#endif } /* @@ -524,7 +565,7 @@ studio::add_action_group_to_top(Glib::RefPtr ui_manager, Glib 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) { @@ -537,7 +578,7 @@ studio::add_action_group_to_top(Glib::RefPtr ui_manager, Glib } DEBUGPOINT(); ui_manager->insert_action_group(group,0); - + DEBUGPOINT(); for(;!prev_groups.empty();prev_groups.pop_front()) { @@ -582,21 +623,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, @@ -605,7 +651,7 @@ public: ); App::gamma.set_all(r,g,b,blk); - + return true; } if(key=="time_format") @@ -637,10 +683,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()); @@ -649,12 +701,13 @@ 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; } }; -static Preferences _preferences; +static ::Preferences _preferences; void init_ui_manager() @@ -664,19 +717,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", "Mask 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; @@ -688,7 +741,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); } @@ -709,7 +762,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")); @@ -721,12 +775,12 @@ init_ui_manager() DEFINE_ACTION("unselect-all-layers", _("Unselect All Layers")); DEFINE_ACTION("properties", _("Properties")); - DEFINE_ACTION("mask-position-ducks", _("Mask Position Ducks")); - DEFINE_ACTION("mask-vertex-ducks", _("Mask Vertex Ducks")); - DEFINE_ACTION("mask-tangent-ducks", _("Mask Tangent Ducks")); - DEFINE_ACTION("mask-radius-ducks", _("Mask Radius Ducks")); - DEFINE_ACTION("mask-width-ducks", _("Mask Width Ducks")); - DEFINE_ACTION("mask-angle-ducks", _("Mask Angle Ducks")); + 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")); @@ -739,7 +793,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")); @@ -774,11 +828,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())); @@ -792,7 +846,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, @@ -829,6 +883,7 @@ init_ui_manager() " " " " " " +" " " " " " " " @@ -867,7 +922,7 @@ init_ui_manager() " " " " " " -" " +//" " " " " " " " @@ -896,8 +951,6 @@ init_ui_manager() " " " " " " - " " - " " " " " " " " @@ -910,6 +963,8 @@ init_ui_manager() //" " //" " " " +" " +" " " " " " " " @@ -954,8 +1009,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"); @@ -974,7 +1039,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")); @@ -1013,18 +1077,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 } @@ -1036,22 +1114,25 @@ 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) @@ -1061,21 +1142,21 @@ 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()) { 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_polygon); + + state_manager->add_state(&state_circle); state_manager->add_state(&state_rectangle); - state_manager->add_state(&state_draw); - state_manager->add_state(&state_sketch); - + state_manager->add_state(&state_gradient); state_manager->add_state(&state_eyedrop); state_manager->add_state(&state_fill); - - state_manager->add_state(&state_width); - state_manager->add_state(&state_gradient); - + state_manager->add_state(&state_zoom); - studio_init_cb.task("Init ModPalette..."); + // 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...")); 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 ) { @@ -1253,7 +1343,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.") @@ -1261,21 +1351,21 @@ 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(...) @@ -1293,27 +1383,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; @@ -1333,11 +1423,7 @@ App::~App() String App::get_user_app_directory() { -#ifdef __APPLE__ - return Glib::build_filename(Glib::get_home_dir(),"Library/Synfig"); -#else - return Glib::build_filename(Glib::get_home_dir(),"Synfig"); -#endif + return Glib::build_filename(Glib::get_home_dir(),SYNFIG_USER_APP_DIR); } synfig::String @@ -1352,18 +1438,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 @@ -1374,16 +1460,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; } @@ -1405,8 +1491,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); @@ -1415,21 +1504,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; } @@ -1559,22 +1659,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 @@ -1584,8 +1684,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 @@ -1598,7 +1698,7 @@ static OPENFILENAME ofn={}; #ifdef WIN32 #include #endif - + bool App::dialog_open_file(const std::string &title, std::string &filename) { @@ -1608,7 +1708,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; @@ -1628,38 +1728,57 @@ 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::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog->add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT); + if(!filename.empty()) + 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; + return true; + } + 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()); @@ -1669,15 +1788,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)); @@ -1690,19 +1809,20 @@ App::dialog_open_file(const std::string &title, std::string &filename) } gtk_widget_destroy(fileselection); return true; + */ #endif } 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; @@ -1722,88 +1842,64 @@ 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; #else - return dialog_open_file(title, filename); -#endif -} + synfig::String prev_path; + if(!_preferences.get_value("curr_path",prev_path)) + prev_path="."; + prev_path = absolute_path(prev_path); -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)) + 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()) { - 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 - return dialog_open_file(title, filename); + if(dialog->run()==GTK_RESPONSE_ACCEPT) { + filename=dialog->get_filename(); + delete dialog; + _preferences.set_value("curr_path",dirname(filename)); + return true; + } + delete dialog; + return false; +// return dialog_open_file(title, filename); #endif } void App::dialog_error_blocking(const std::string &title, const std::string &message) { - Gtk::Dialog dialog( - title, // Title - true, // Modal - true // use_separator - ); - Gtk::Label label(message); - label.show(); - - dialog.get_vbox()->pack_start(label); - dialog.add_button(Gtk::StockID("gtk-ok"),1); + Gtk::MessageDialog dialog(message, false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE, true); + dialog.set_title(title); dialog.show(); dialog.run(); } @@ -1811,16 +1907,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(); } @@ -1835,7 +1923,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); @@ -1865,17 +1953,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(); } @@ -1920,31 +1999,40 @@ 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))); + as=long_name; +#endif + 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(); } @@ -1960,7 +2048,7 @@ App::open_as(std::string filename,std::string as) } _preferences.set_value("curr_path",dirname(as)); - + return true; } @@ -1969,10 +2057,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); @@ -1985,8 +2073,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 @@ -2058,7 +2149,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();