X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fapp.cpp;h=504d0a061c12c1c759386f5b7ed6313a9e3d071a;hb=63e709f66d50c124cc0ece2325f4773ac4ae7b20;hp=49cce745ea2748be50bea1e31ebadaaaf98e4242;hpb=c2fd06582a447241e51ad52527f7d82624ff375b;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/app.cpp b/synfig-studio/trunk/src/gtkmm/app.cpp index 49cce74..504d0a0 100644 --- a/synfig-studio/trunk/src/gtkmm/app.cpp +++ b/synfig-studio/trunk/src/gtkmm/app.cpp @@ -1,20 +1,22 @@ -/* === S I N F G =========================================================== */ +/* === S Y N F I G ========================================================= */ /*! \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 @@ -43,7 +50,7 @@ #include -#include +#include #include "app.h" #include "about.h" @@ -79,7 +86,7 @@ #include "autorecover.h" -#include +#include #include "dock_history.h" #include "dock_canvases.h" #include "dock_keyframes.h" @@ -109,9 +116,14 @@ #endif #ifdef WIN32 +#define _WIN32_WINNT 0x0500 #include #endif #include +#include +#include + +#include "general.h" #endif @@ -119,11 +131,21 @@ using namespace std; using namespace etl; -using namespace sinfg; +using namespace synfig; using namespace studio; /* === M A C R O S ========================================================= */ +#ifndef SYNFIG_USER_APP_DIR +#ifdef __APPLE__ +#define SYNFIG_USER_APP_DIR "Library/Synfig" +#elif defined(_WIN32) +#define SYNFIG_USER_APP_DIR "Synfig" +#else +#define SYNFIG_USER_APP_DIR ".synfig" +#endif +#endif + #ifndef DPM2DPI #define DPM2DPI(x) (float(x)/39.3700787402f) #define DPI2DPM(x) (float(x)*39.3700787402f) @@ -144,7 +166,7 @@ using namespace studio; # define IMAGE_EXT "tif" #endif -#include +#include /* === S I G N A L S ======================================================= */ @@ -180,11 +202,11 @@ const std::list& App::get_recent_files() { return recent_files; } int App::Busy::count; bool App::shutdown_in_progress; -sinfg::Gamma App::gamma; +synfig::Gamma App::gamma; Glib::RefPtr App::ui_manager_; -sinfg::Distance::System App::distance_system; +synfig::Distance::System App::distance_system; studio::Dialog_Setup* App::dialog_setup; @@ -193,8 +215,8 @@ etl::handle< studio::ModPalette > mod_palette_; std::list > App::instance_list; -static etl::handle ui_interface_; -const etl::handle& App::get_ui_interface() { return ui_interface_; } +static etl::handle ui_interface_; +const etl::handle& App::get_ui_interface() { return ui_interface_; } etl::handle App::selected_instance; etl::handle App::selected_canvas_view; @@ -233,21 +255,41 @@ 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_; } void studio::App::set_max_recent_files(int x) { max_recent_files_=x; } -static sinfg::String app_base_path_; +static synfig::String app_base_path_; namespace studio { + +bool +really_delete_widget(Gtk::Widget *widget) +{ + synfig::info("really delete %p", (void*)widget); + delete widget; + return false; +} + +// nasty workaround - when we've finished with a popup menu, we want to delete it +// attaching to the signal_hide() signal gets us here before the action on the menu has run, +// so schedule the real delete to happen in 50ms, giving the action a chance to run +void +delete_widget(Gtk::Widget *widget) +{ + synfig::info("delete %p", (void*)widget); + Glib::signal_timeout().connect(sigc::bind(sigc::ptr_fun(&really_delete_widget), widget), 50); +} + }; // END of namespace studio studio::StateManager* state_manager; -class GlobalUIInterface : public sinfgapp::UIInterface +class GlobalUIInterface : public synfigapp::UIInterface { public: @@ -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; @@ -351,145 +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) -{ - 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 - sinfg::error("Unable to save license key!"); - } - sinfg::info("License Authenticated -- Serial #%05d",serial); - return serial; -} - /* void studio::UIManager::insert_action_group (const Glib::RefPtr& action_group, int pos) @@ -509,7 +403,7 @@ studio::UIManager::remove_action_group (const Glib::RefPtr& ac Gtk::UIManager::remove_action_group(action_group); return; } - sinfg::error("Unable to find action group"); + synfig::error("Unable to find action group"); } void @@ -517,36 +411,30 @@ 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") { - sinfg::info("Removing action group "+(*iter)->get_name()); + 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 sinfgapp::Settings +class Preferences : public synfigapp::Settings { public: - virtual bool get_value(const sinfg::String& key, sinfg::String& value)const + virtual bool get_value(const synfig::String& key, synfig::String& value)const { if(key=="gamma") { @@ -578,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 sinfgapp::Settings::get_value(key,value); + + return synfigapp::Settings::get_value(key,value); } - - virtual bool set_value(const sinfg::String& key,const sinfg::String& 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, @@ -601,13 +494,13 @@ public: ); App::gamma.set_all(r,g,b,blk); - + return true; } if(key=="time_format") { int i(atoi(value.c_str())); - App::set_time_format(static_cast(i)); + App::set_time_format(static_cast(i)); return true; } if(key=="auto_recover_backup_interval") @@ -633,24 +526,31 @@ public: App::distance_system=Distance::ident_system(value);; return true; } - - return sinfgapp::Settings::set_value(key,value); + 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(sinfgapp::Settings::get_key_list()); + KeyList ret(synfigapp::Settings::get_key_list()); ret.push_back("gamma"); ret.push_back("time_format"); ret.push_back("distance_system"); ret.push_back("file_history.size"); ret.push_back("use_colorspace_gamma"); + ret.push_back("single_threaded"); ret.push_back("auto_recover_backup_interval"); return ret; } }; -static Preferences _preferences; +static ::Preferences _preferences; void init_ui_manager() @@ -660,23 +560,23 @@ 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") ); - - // Add the sinfgapp actions... - sinfgapp::Action::Book::iterator iter; - for(iter=sinfgapp::Action::book().begin();iter!=sinfgapp::Action::book().end();++iter) + + 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; + for(iter=synfigapp::Action::book().begin();iter!=synfigapp::Action::book().end();++iter) { actions_action_group->add(Gtk::Action::create( "action-"+iter->second.name, @@ -684,28 +584,29 @@ 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); } DEFINE_ACTION2("keyframe-properties", Gtk::StockID("gtk-properties"), _("Keyframe Properties")); - DEFINE_ACTION("about", Gtk::StockID("sinfg-about")); + DEFINE_ACTION("about", Gtk::StockID("synfig-about")); DEFINE_ACTION("open", Gtk::Stock::OPEN); DEFINE_ACTION("save", Gtk::Stock::SAVE); DEFINE_ACTION("save-as", Gtk::Stock::SAVE_AS); DEFINE_ACTION("revert", Gtk::Stock::REVERT_TO_SAVED); - DEFINE_ACTION("cvs-add", Gtk::StockID("sinfg-cvs_add")); - DEFINE_ACTION("cvs-update", Gtk::StockID("sinfg-cvs_update")); - DEFINE_ACTION("cvs-commit", Gtk::StockID("sinfg-cvs_commit")); - DEFINE_ACTION("cvs-revert", Gtk::StockID("sinfg-cvs_revert")); + DEFINE_ACTION("cvs-add", Gtk::StockID("synfig-cvs_add")); + DEFINE_ACTION("cvs-update", Gtk::StockID("synfig-cvs_update")); + DEFINE_ACTION("cvs-commit", Gtk::StockID("synfig-cvs_commit")); + DEFINE_ACTION("cvs-revert", Gtk::StockID("synfig-cvs_revert")); DEFINE_ACTION("import", _("Import")); DEFINE_ACTION("render", _("Render")); DEFINE_ACTION("preview", _("Preview")); DEFINE_ACTION("dialog-flipbook", _("Preview Dialog")); DEFINE_ACTION("sound", _("Sound File")); DEFINE_ACTION("options", _("Options")); - DEFINE_ACTION("close", _("Close")); + DEFINE_ACTION("close", _("Close View")); + DEFINE_ACTION("close-document", _("Close Document")); DEFINE_ACTION("undo", Gtk::StockID("gtk-undo")); @@ -717,12 +618,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")); @@ -735,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")); @@ -767,15 +668,15 @@ init_ui_manager() #undef DEFINE_ACTION -// Set up sinfgapp actions +// Set up synfigapp actions /*{ - sinfgapp::Action::Book::iterator iter; - - for(iter=sinfgapp::Action::book().begin();iter!=sinfgapp::Action::book().end();++iter) + 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&sinfgapp::Action::CATEGORY_HIDDEN)) + + if(!(iter->second.category&synfigapp::Action::CATEGORY_HIDDEN)) { //Gtk::Image* image(manage(new Gtk::Image())); if(iter->second.task=="raise") stock_id=Gtk::Stock::GO_UP; @@ -787,8 +688,8 @@ init_ui_manager() else if(iter->second.task=="set_off") stock_id=Gtk::Stock::NO; //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("sinfg-"+iter->second.task); - + else stock_id=Gtk::StockID("synfig-"+iter->second.task); + actions_action_group->add(Gtk::Action::create( "action-"+iter->second.name, stock_id, @@ -825,6 +726,7 @@ init_ui_manager() " " " " " " +" " " " " " " " @@ -863,7 +765,7 @@ init_ui_manager() " " " " " " -" " +//" " " " " " " " @@ -892,8 +794,6 @@ init_ui_manager() " " " " " " - " " - " " " " " " " " @@ -906,6 +806,8 @@ init_ui_manager() //" " //" " " " +" " +" " " " " " " " @@ -946,12 +848,22 @@ init_ui_manager() } catch(const Glib::Error& ex) { - sinfg::error("building menus and toolbars failed: " + ex.what()); + synfig::error("building menus and toolbars failed: " + ex.what()); } // 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"); @@ -970,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")); @@ -1009,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 } @@ -1032,215 +957,210 @@ 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) - sinfg::error("UNABLE TO CREATE \"%s\"",get_user_app_directory().c_str()); + synfig::error("UNABLE TO CREATE \"%s\"",get_user_app_directory().c_str()); } else { - sinfg::info("Created directory \"%s\"",get_user_app_directory().c_str()); + synfig::info("Created directory \"%s\"",get_user_app_directory().c_str()); } - - + + ipc=new IPC(); - - try + + if(!SYNFIG_CHECK_VERSION()) { - if(!SINFG_CHECK_VERSION()) - { - cerr<<"FATAL: Sinfg Version Mismatch"<(new sinfgapp::Main(etl::dirname((*argv)[0]),&sinfg_init_cb)); } + + // Initialize the Synfig library + try { synfigapp_main=etl::smart_ptr(new synfigapp::Main(etl::dirname((*argv)[0]),&synfig_init_cb)); } catch(...) { - get_ui_interface()->error("Failed to initialize sinfg!"); + get_ui_interface()->error(_("Failed to initialize synfig!")); throw; } // add the preferences to the settings - sinfgapp::Main::settings().add_domain(&_preferences,"pref"); - + 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", - "SINFG 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?" - )==sinfgapp::UIInterface::RESPONSE_YES + "and recover your unsaved changes?") + )==synfigapp::UIInterface::RESPONSE_YES ) { if(!auto_recover->recover()) @@ -1249,7 +1169,7 @@ App::App(int *argc, char ***argv): } else get_ui_interface()->error( - _("SINFG 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.") @@ -1257,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.")); @@ -1288,28 +1212,28 @@ App::~App() save_settings(); - sinfgapp::Main::settings().remove_domain("pref"); - + 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; @@ -1329,11 +1253,11 @@ App::~App() String App::get_user_app_directory() { - return Glib::build_filename(Glib::get_home_dir(),"sinfg"); + return Glib::build_filename(Glib::get_home_dir(),SYNFIG_USER_APP_DIR); } -sinfg::String -App::get_config_file(const sinfg::String& file) +synfig::String +App::get_config_file(const synfig::String& file) { return Glib::build_filename(get_user_app_directory(),file); } @@ -1344,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 @@ -1366,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; } @@ -1388,7 +1312,7 @@ App::get_time_format() } void -App::set_time_format(sinfg::Time::Format x) +App::set_time_format(synfig::Time::Format x) { _App_time_format=x; } @@ -1397,8 +1321,11 @@ App::set_time_format(sinfg::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); @@ -1407,33 +1334,37 @@ App::save_settings() std::string filename=get_config_file("recentfiles"); std::ofstream file(filename.c_str()); - + if(!file) { - sinfg::warning("Unable to save %s",filename.c_str()); + 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; } @@ -1509,20 +1447,20 @@ App::quit() return; /* - if((*iter)->sinfgapp::Instance::get_action_count()) + if((*iter)->synfigapp::Instance::get_action_count()) { - handle uim; + handle uim; uim=(*iter)->find_canvas_view((*iter)->get_canvas())->get_ui_interface(); assert(uim); string str=strprintf(_("Would you like to save your changes to %s?"),(*iter)->get_file_name().c_str() ); - switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,sinfgapp::UIInterface::RESPONSE_YES)) + switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,synfigapp::UIInterface::RESPONSE_YES)) { - case sinfgapp::UIInterface::RESPONSE_NO: + case synfigapp::UIInterface::RESPONSE_NO: break; - case sinfgapp::UIInterface::RESPONSE_YES: + case synfigapp::UIInterface::RESPONSE_YES: (*iter)->save(); break; - case sinfgapp::UIInterface::RESPONSE_CANCEL: + case synfigapp::UIInterface::RESPONSE_CANCEL: return; default: assert(0); @@ -1531,42 +1469,42 @@ App::quit() } - if((*iter)->sinfgapp::Instance::is_modified()) + if((*iter)->synfigapp::Instance::is_modified()) { - handle uim; + handle uim; uim=(*iter)->find_canvas_view((*iter)->get_canvas())->get_ui_interface(); assert(uim); string str=strprintf(_("%s has changes not yet on the CVS repository.\nWould you like to commit these changes?"),(*iter)->get_file_name().c_str() ); - switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,sinfgapp::UIInterface::RESPONSE_YES)) + switch(uim->yes_no_cancel((*iter)->get_canvas()->get_name(),str,synfigapp::UIInterface::RESPONSE_YES)) { - case sinfgapp::UIInterface::RESPONSE_NO: + case synfigapp::UIInterface::RESPONSE_NO: break; - case sinfgapp::UIInterface::RESPONSE_YES: + case synfigapp::UIInterface::RESPONSE_YES: (*iter)->dialog_cvs_commit(); break; - case sinfgapp::UIInterface::RESPONSE_CANCEL: + case synfigapp::UIInterface::RESPONSE_CANCEL: return; default: assert(0); 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 @@ -1576,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 @@ -1590,7 +1528,7 @@ static OPENFILENAME ofn={}; #ifdef WIN32 #include #endif - + bool App::dialog_open_file(const std::string &title, std::string &filename) { @@ -1600,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; @@ -1620,38 +1558,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 - sinfg::String prev_path; + 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()); @@ -1661,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)); @@ -1682,19 +1639,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; @@ -1714,88 +1672,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(); } @@ -1803,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(); } @@ -1827,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); @@ -1857,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(); } @@ -1912,31 +1829,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)); + + 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(); } @@ -1952,7 +1878,7 @@ App::open_as(std::string filename,std::string as) } _preferences.set_value("curr_path",dirname(as)); - + return true; } @@ -1960,11 +1886,11 @@ App::open_as(std::string filename,std::string as) void App::new_instance() { - handle canvas=sinfg::Canvas::create(); - canvas->set_name(strprintf("Untitled%d",Instance::get_count())); + handle canvas=synfig::Canvas::create(); + 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); @@ -1977,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 @@ -2050,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(); @@ -2084,7 +2013,7 @@ studio::App::redo() selected_instance->redo(); } -sinfg::String +synfig::String studio::App::get_base_path() { return app_base_path_;