/*! \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
#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
std::list< etl::handle< studio::Module > > module_list_;
bool studio::App::use_colorspace_gamma=true;
+bool studio::App::single_threaded=true;
static int max_recent_files_=25;
int studio::App::get_max_recent_files() { return max_recent_files_; }
}
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;
}
+#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;
value=strprintf("%s",Distance::system_name(App::distance_system).c_str());
return true;
}
+ if(key=="single_threaded")
+ {
+ value=strprintf("%i",(int)App::single_threaded);
+ return true;
+ }
if(key=="auto_recover_backup_interval")
{
value=strprintf("%i",App::auto_recover->get_timeout());
App::distance_system=Distance::ident_system(value);;
return true;
}
+ if(key=="single_threaded")
+ {
+ int i(atoi(value.c_str()));
+ App::single_threaded=i;
+ return true;
+ }
return synfigapp::Settings::set_value(key,value);
}
ret.push_back("distance_system");
ret.push_back("file_history.size");
ret.push_back("use_colorspace_gamma");
+ ret.push_back("single_threaded");
ret.push_back("auto_recover_backup_interval");
return ret;
}
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"));
" </menu>"
" <separator name='bleh08'/>"
" <menuitem action='play'/>"
-" <menuitem action='pause'/>"
+//" <menuitem action='pause'/>"
" <menuitem action='stop'/>"
" <menuitem action='dialog-flipbook'/>"
" <separator name='bleh09'/>"
" </menu>"
" <menu action='menu-canvas'>"
" <menuitem action='canvas-new'/>"
- " <menuitem action='amount-inc'/>"
- " <menuitem action='amount-dec'/>"
" </menu>"
" <menu name='menu-state' action='menu-state'>"
" </menu>"
//" <menuitem action='paste'/>"
//" <separator name='bleh06'/>"
" <menu action='menu-layer-new'></menu>"
+" <menuitem action='amount-inc'/>"
+" <menuitem action='amount-dec'/>"
" </menu>"
" <menu action='menu-keyframe'>"
" <menuitem action='keyframe-properties'/>"
}
// 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("<Actions>//select-all-ducks","<Control>a");
ACCEL("<Actions>//unselect-all-layers","<Control>d");
ACCEL("<Actions>//render","F9");
ACCEL("<Actions>//mask-width-ducks", "<Mod1>5");
ACCEL("<Actions>//mask-angle-ducks", "<Mod1>6");
-
ACCEL2(Gtk::AccelKey(GDK_Page_Up,Gdk::SHIFT_MASK,"<Actions>//action-layer_raise"));
ACCEL2(Gtk::AccelKey(GDK_Page_Down,Gdk::SHIFT_MASK,"<Actions>//action-layer_lower"));
ACCEL2(Gtk::AccelKey('>',Gdk::CONTROL_MASK,"<Actions>//seek-next-second"));
ACCEL2(Gtk::AccelKey('<',Gdk::CONTROL_MASK,"<Actions>//seek-prev-second"));
ACCEL2(Gtk::AccelKey('o',Gdk::CONTROL_MASK,"<Actions>//toggle-onion-skin"));
+ ACCEL("<Actions>//play", "<Control>p");
ACCEL("<Actions>//seek-begin","Home");
ACCEL("<Actions>//seek-end","End");
- ACCEL("<Actions>//state-normal","<Mod1>a");
- ACCEL("<Actions>//state-rotate","<Mod1>s");
- ACCEL("<Actions>//state-scale","<Mod1>d");
- ACCEL("<Actions>//state-bline","<Mod1>b");
- ACCEL("<Actions>//state-fill","<Mod1>f");
- ACCEL("<Actions>//state-eyedrop","<Mod1>e");
- ACCEL("<Actions>//state-gradient","<Mod1>g");
- ACCEL("<Actions>//state-zoom","<Mod1>z");
+
+ ACCEL("<Actions>//state-normal", "<Mod1>a");
+ ACCEL("<Actions>//state-smooth_move", "<Mod1>v");
+ ACCEL("<Actions>//state-scale", "<Mod1>d");
+ ACCEL("<Actions>//state-rotate", "<Mod1>s");
+
+ ACCEL("<Actions>//state-bline", "<Mod1>b");
+ ACCEL("<Actions>//state-circle", "<Mod1>c");
+ ACCEL("<Actions>//state-rectangle", "<Mod1>r");
+ ACCEL("<Actions>//state-gradient", "<Mod1>g");
+
+ ACCEL("<Actions>//state-eyedrop", "<Mod1>e");
+ ACCEL("<Actions>//state-fill", "<Mod1>f");
+ ACCEL("<Actions>//state-zoom", "<Mod1>z");
+ ACCEL("<Actions>//state-polygon", "<Mod1>p");
+
+ ACCEL("<Actions>//state-draw", "<Mod1>w");
+ ACCEL("<Actions>//state-sketch", "<Mod1>k");
+ ACCEL("<Actions>//state-width", "<Mod1>t");
+ ACCEL("<Actions>//state-mirror", "<Mod1>m");
+
ACCEL("<Actions>//canvas-zoom-fit","<Control><Shift>z");
#undef ACCEL
if(!SYNFIG_CHECK_VERSION())
{
cerr<<"FATAL: Synfig Version Mismatch"<<endl;
- dialog_error_blocking("SYNFIG Studio",
- "This copy of SYNFIG Studio was compiled against a\n"
+ dialog_error_blocking("Synfig Studio",
+ "This copy of Synfig Studio was compiled against a\n"
"different version of libsynfig than what is currently\n"
"installed. Synfig Studio will now abort. Try downloading\n"
- "the latest version from the SYNFIG Development Website at\n"
- "http://dev.synfig.com/ "
+ "the latest version from the Synfig website at\n"
+ "http://www.synfig.com/ "
);
throw 40;
}
catch(synfig::SoftwareExpired)
{
cerr<<"FATAL: Software Expired"<<endl;
- dialog_error_blocking("SYNFIG Studio",
- "This copy of SYNFIG Studio has expired.\n"
+ dialog_error_blocking("Synfig Studio",
+ "This copy of Synfig Studio has expired.\n"
"Please erase this copy, or download and\n"
- "install the latest copy from the SYNFIG\n"
- "Development Website at http://dev.synfig.com/ ."
+ "install the latest copy from the Synfig\n"
+ "website at http://www.synfig.com/ ."
);
throw 39;
}
- Glib::set_application_name(_("SYNFIG Studio"));
+ Glib::set_application_name(_("Synfig Studio"));
About about_window;
about_window.set_can_self_destruct(false);
state_manager->add_state(&state_zoom);
- // Disabled this tool because it should be
- // considered deprecated. Use the bline tool instead.
- if(getenv("SYNFIG_ENABLE_POLYGON")) state_manager->add_state(&state_polygon);
+ // 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);
- // These tools are disabled by default for now,
- // because they tend to confuse users.
- if(getenv("SYNFIG_ENABLE_DRAW" )) state_manager->add_state(&state_draw);
- if(getenv("SYNFIG_ENABLE_SKETCH")) state_manager->add_state(&state_sketch);
- if(getenv("SYNFIG_ENABLE_WIDTH" )) state_manager->add_state(&state_width);
+ // 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 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...");
auto_recover=new AutoRecover();
if(
get_ui_interface()->yes_no(
"Auto Recovery",
- "SYNFIG Studio seems to have crashed\n"
+ "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?"
}
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.")
//if(!synfigapp::Main::settings().load_from_file(filename))
{
gamma.set_gamma(1.0/2.2);
- synfigapp::Main::settings().set_value("dock.dialog.1.comp_selector","1");
- synfigapp::Main::settings().set_value("dock.dialog.1.contents","navigator - info pal_edit pal_browse - tool_options history canvases - layers groups");
- synfigapp::Main::settings().set_value("dock.dialog.1.contents_size","225 167 207");
- synfigapp::Main::settings().set_value("dock.dialog.1.pos","1057 32");
- synfigapp::Main::settings().set_value("dock.dialog.1.size","208 1174");
- synfigapp::Main::settings().set_value("dock.dialog.2.comp_selector","0");
- synfigapp::Main::settings().set_value("dock.dialog.2.contents","params children keyframes | timetrack curves meta_data");
- synfigapp::Main::settings().set_value("dock.dialog.2.contents_size","263");
- synfigapp::Main::settings().set_value("dock.dialog.2.pos","0 973");
- synfigapp::Main::settings().set_value("dock.dialog.2.size","1045 235");
- synfigapp::Main::settings().set_value("pref.distance_system","pt");
- synfigapp::Main::settings().set_value("pref.use_colorspace_gamma","1");
- synfigapp::Main::settings().set_value("window.toolbox.pos","4 4");
+ reset_initial_window_configuration();
}
}
setlocale(LC_NUMERIC,old_locale);
}
}
+void
+App::reset_initial_window_configuration()
+{
+ synfigapp::Main::settings().set_value("dock.dialog.1.comp_selector","1");
+ synfigapp::Main::settings().set_value("dock.dialog.1.contents","navigator - info pal_edit pal_browse - tool_options history canvases - layers groups");
+ synfigapp::Main::settings().set_value("dock.dialog.1.contents_size","225 167 207");
+ synfigapp::Main::settings().set_value("dock.dialog.1.pos","1057 32");
+ synfigapp::Main::settings().set_value("dock.dialog.1.size","208 1174");
+ synfigapp::Main::settings().set_value("dock.dialog.2.comp_selector","0");
+ synfigapp::Main::settings().set_value("dock.dialog.2.contents","params children keyframes | timetrack curves meta_data");
+ synfigapp::Main::settings().set_value("dock.dialog.2.contents_size","263");
+ synfigapp::Main::settings().set_value("dock.dialog.2.pos","0 973");
+ synfigapp::Main::settings().set_value("dock.dialog.2.size","1045 235");
+ synfigapp::Main::settings().set_value("pref.distance_system","pt");
+ synfigapp::Main::settings().set_value("pref.use_colorspace_gamma","1");
+ synfigapp::Main::settings().set_value("pref.single_threaded","0");
+ synfigapp::Main::settings().set_value("window.toolbox.pos","4 4");
+}
+
bool
App::shutdown_request(GdkEventAny*)
{
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
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;
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());
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();
if(GetSaveFileName(&ofn))
{
filename=szFilename;
+ _preferences.set_value("curr_path",dirname(filename));
return true;
}
return false;
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<HINSTANCE>(GetModuleHandle(NULL));
- HWND hWnd=static_cast<HWND>(GDK_WINDOW_HWND(gdkWinPtr));
-
- ofn.lStructSize=sizeof(OPENFILENAME);
- ofn.hwndOwner = hWnd;
- ofn.hInstance = hInstance;
- ofn.lpstrFilter = szFilter;
-// ofn.lpstrCustomFilter=NULL;
-// ofn.nMaxCustFilter=0;
-// ofn.nFilterIndex=0;
-// ofn.lpstrFile=NULL;
- ofn.nMaxFile=MAX_PATH;
-// ofn.lpstrFileTitle=NULL;
-// ofn.lpstrInitialDir=NULL;
-// ofn.lpstrTitle=NULL;
- ofn.Flags=OFN_OVERWRITEPROMPT;
-// ofn.nFileOffset=0;
-// ofn.nFileExtension=0;
- ofn.lpstrDefExt=TEXT("sif");
-// ofn.lCustData = 0l;
- ofn.lpfnHook=NULL;
-// ofn.lpTemplateName=NULL;
-
- CHAR szFilename[MAX_PATH];
- CHAR szTitle[500];
- strcpy(szFilename,filename.c_str());
- strcpy(szTitle,title.c_str());
-
- ofn.lpstrFile=szFilename;
- ofn.lpstrFileTitle=szTitle;
-
- if(GetSaveFileName(&ofn))
{
- filename=szFilename;
- 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;
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)
{
App::new_instance()
{
handle<synfig::Canvas> canvas=synfig::Canvas::create();
- canvas->set_name(strprintf("Untitled%d",Instance::get_count()));
+ canvas->set_name(strprintf("%s%d", DEFAULT_FILENAME_PREFIX, Instance::get_count()+1));
- String file_name(strprintf("untitled%d.sif",Instance::get_count()));
+ String file_name(strprintf("%s%d.sifz", DEFAULT_FILENAME_PREFIX, Instance::get_count()+1));
canvas->rend_desc().set_frame_rate(24.0);
canvas->rend_desc().set_time_start(0.0);