diff --git a/Common/Context.h b/Common/Context.h index fe5a1ca3cebb9b4f58ff094d42d437d97d6cbda5..a4f2afafdef381065136cc0bcee2528bc2788fc5 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -63,6 +63,7 @@ public : char *display; // forced display host:0.0 under X11 int terminal; // show we print to the terminal console? char *editor; // text editor command (with included '%s') + char *web_browser; // web browser command (with included '%s') char home_dir[256]; // the home directory char *scheme; // FLTK GUI theme int tooltips; // show tootips in GUI? diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index e96841469a69d0833a76efd20c73436cde4a10b3..c0565aac3baef6126c263afd9bae63c97154db20 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -53,18 +53,31 @@ StringXString GeneralOptions_String[] = { { 0, "SessionFileName" , opt_general_session_filename , ".gmshrc" , "Option file into which session specific information is saved; automatically read on startup" }, + { F|S, "Scheme" , opt_general_scheme , "" , + "FLTK graphical user interface scheme (try e.g. plastic)" }, + { F|O, "TextEditor" , opt_general_editor , #if defined(WIN32) - { F|O, "TextEditor" , opt_general_editor , "notepad.exe %s" , + "notepad.exe %s" , +#elif defined(__APPLE__) + "open -e %s" , #else - { F|O, "TextEditor" , opt_general_editor , "emacs %s &" , + "emacs %s &" , #endif "System command to launch a text editor (OS-dependent)" }, - { F|S, "Scheme" , opt_general_scheme , "" , - "FLTK graphical user interface scheme (try e.g. plastic)" }, { F|S, "TmpFileName" , opt_general_tmp_filename , ".gmsh-tmp" , "Temporary file used by the geometry module" }, + { F|O, "WebBrowser" , opt_general_web_browser , +#if defined(WIN32) + "explorer.exe %s" , +#elif defined(__APPLE__) + "open %s" , +#else + "mozilla %s &" , +#endif + "System command to launch a web browser (OS-dependent)" }, + { 0, NULL , NULL , NULL , NULL } } ; @@ -559,10 +572,11 @@ StringXNumber GeneralOptions_Number[] = { { F|S, "SystemMenuBar" , opt_general_system_menu_bar , 1. , "Use the system menu bar on Mac OS X?" }, + { F|O, "Terminal" , opt_general_terminal , #if defined(HAVE_FLTK) - { F|O, "Terminal" , opt_general_terminal , 0. , + 0. , #else - { F|O, "Terminal" , opt_general_terminal , 1. , + 1. , #endif "Should information be printed on the terminal (if available)?" }, { F|O, "Tooltips" , opt_general_tooltips , 1. , @@ -796,10 +810,11 @@ StringXNumber SolverOptions_Number[] = { "Connect solver 0 to the Gmsh server" }, { F|O, "MergeViews0" , opt_solver_merge_views0 , 1. , "Automatically merge any post-processing view created by solver 0" }, + { F|O, "PopupMessages0" , opt_solver_popup_messages0 , #if defined(WIN32) - { F|O, "PopupMessages0" , opt_solver_popup_messages0 , 0. , // we already have the transient dos window + 0. , // we already have the transient dos window #else - { F|O, "PopupMessages0" , opt_solver_popup_messages0 , 1. , + 1. , #endif "Automatically display messages produced by solver 0" }, diff --git a/Common/Options.cpp b/Common/Options.cpp index f26b5b474a7cfc9335149a98bee4653e81b872b1..047b1593ca0308deefb9a51bb5317abba091a5b5 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -1,4 +1,4 @@ -// $Id: Options.cpp,v 1.124 2003-12-02 22:57:41 geuzaine Exp $ +// $Id: Options.cpp,v 1.125 2003-12-03 04:14:17 geuzaine Exp $ // // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle // @@ -776,6 +776,13 @@ char *opt_general_editor(OPT_ARGS_STR) return CTX.editor; } +char *opt_general_web_browser(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX.web_browser = val; + return CTX.web_browser; +} + char *opt_general_scheme(OPT_ARGS_STR) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index 1b9caae0fadcf831650f6eaab53fa6ecda045096..c7e6c56317138f7f1c2b3d95316c119fc541ddbb 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -43,6 +43,7 @@ char * opt_general_error_filename(OPT_ARGS_STR); char * opt_general_session_filename(OPT_ARGS_STR); char * opt_general_options_filename(OPT_ARGS_STR); char * opt_general_editor(OPT_ARGS_STR); +char * opt_general_web_browser(OPT_ARGS_STR); char * opt_general_scheme(OPT_ARGS_STR); char * opt_mesh_triangle_options(OPT_ARGS_STR); char * opt_solver_name(OPT_ARGS_STR); diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp index b4cb0e76a7c735df3ec91a15ecf1efcaf2887719..b3f7610498c40fb231bcc59738a788c25ee12153 100644 --- a/Fltk/Callbacks.cpp +++ b/Fltk/Callbacks.cpp @@ -1,4 +1,4 @@ -// $Id: Callbacks.cpp,v 1.190 2003-12-01 21:51:19 geuzaine Exp $ +// $Id: Callbacks.cpp,v 1.191 2003-12-03 04:14:17 geuzaine Exp $ // // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle // @@ -20,6 +20,7 @@ // Please report all bugs and problems to "gmsh@geuz.org". #include <sys/types.h> +#include <sys/stat.h> #include <signal.h> #include <map> #include "Gmsh.h" @@ -57,8 +58,8 @@ extern Context_T CTX; static char *fn = NULL; -int file_chooser(int multi, const char *message, const char *pat, - int patindex) +int file_chooser(int multi, int create, const char *message, + const char *pat, int patindex) { fn = fl_file_chooser(message, pat, NULL); if(fn) @@ -84,8 +85,8 @@ int file_chooser_get_filter() static Fl_File_Chooser *fc = NULL; -int file_chooser(int multi, const char *message, const char *pat, - int patindex) +int file_chooser(int multi, int create, const char *message, + const char *pat, int patindex) { static char oldfilter[1024]; @@ -93,7 +94,7 @@ int file_chooser(int multi, const char *message, const char *pat, Fl_File_Chooser::all_files_label = "All files (*)"; if(!fc) { - fc = new Fl_File_Chooser(".", pat, Fl_File_Chooser::CREATE, message); + fc = new Fl_File_Chooser(".", pat, Fl_File_Chooser::SINGLE, message); strncpy(oldfilter, pat, 1024); } @@ -107,8 +108,10 @@ int file_chooser(int multi, const char *message, const char *pat, if(multi) fc->type(Fl_File_Chooser::MULTI); - else + else if(create) fc->type(Fl_File_Chooser::CREATE); + else + fc->type(Fl_File_Chooser::SINGLE); fc->show(); @@ -361,10 +364,37 @@ void status_cancel_cb(CALLBACK_ARGS) // File Menu +void file_new_cb(CALLBACK_ARGS) +{ + test: + if(file_chooser(0, 1, "New file", "*", 0)) { + char *name = file_chooser_get_name(1); + struct stat buf; + if(!stat(name, &buf)) + if(fl_ask("%s already exists.\nDo you want to erase it?", name)) + goto save; + else + goto test; + save: + unlink(name); + // create a zero length file so that it actually exists (and stupid + // Mac/Windows editors accept to deal with it) + FILE *fp = fopen(name, "w"); + if(!fp){ + Msg(GERROR, "Unable to open file '%s'", name); + return; + } + fprintf(fp, ""); + fclose(fp); + OpenProblem(name); + Draw(); + } +} + void file_open_cb(CALLBACK_ARGS) { int n = List_Nbr(CTX.post.list); - if(file_chooser(0, "Open file", "*", 0)) { + if(file_chooser(0, 0, "Open file", "*", 0)) { OpenProblem(file_chooser_get_name(1)); Draw(); } @@ -375,7 +405,7 @@ void file_open_cb(CALLBACK_ARGS) void file_merge_cb(CALLBACK_ARGS) { int n = List_Nbr(CTX.post.list); - int f = file_chooser(1, "Merge file(s)", "*", 0); + int f = file_chooser(1, 0, "Merge file(s)", "*", 0); if(f) { for(int i = 1; i <= f; i++) MergeProblem(file_chooser_get_name(i)); @@ -568,9 +598,6 @@ typedef struct{ void (*func) (char *name); } patXfunc; -#include <sys/types.h> -#include <sys/stat.h> - void file_save_as_cb(CALLBACK_ARGS) { int i, nbformats; @@ -628,7 +655,7 @@ void file_save_as_cb(CALLBACK_ARGS) test: - if(file_chooser(0, "Save file as", pat, patindex)) { + if(file_chooser(0, 1, "Save file as", pat, patindex)) { char *name = file_chooser_get_name(1); @@ -655,133 +682,133 @@ test: void file_save_as_auto_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save file by extension", "*", 0)) + if(file_chooser(0, 1, "Save file by extension", "*", 0)) _save_auto(file_chooser_get_name(1)); } void file_save_as_geo_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save GEO file", "*", 0)) + if(file_chooser(0, 1, "Save GEO file", "*", 0)) _save_geo(file_chooser_get_name(1)); } void file_save_as_geo_options_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save option file", "*", 0)) + if(file_chooser(0, 1, "Save option file", "*", 0)) _save_geo_options(file_chooser_get_name(1)); } void file_save_as_msh_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save MSH file", "*", 0)) + if(file_chooser(0, 1, "Save MSH file", "*", 0)) _save_msh(file_chooser_get_name(1)); } void file_save_as_msh_all_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save MSH file (no physicals)", "*", 0)) + if(file_chooser(0, 1, "Save MSH file (no physicals)", "*", 0)) _save_msh_all(file_chooser_get_name(1)); } void file_save_as_unv_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save UNV file", "*", 0)) + if(file_chooser(0, 1, "Save UNV file", "*", 0)) _save_unv(file_chooser_get_name(1)); } void file_save_as_gref_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save GREF file", "*", 0)) + if(file_chooser(0, 1, "Save GREF file", "*", 0)) _save_gref(file_chooser_get_name(1)); } void file_save_as_vrml_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save VRML file", "*", 0)) + if(file_chooser(0, 1, "Save VRML file", "*", 0)) _save_vrml(file_chooser_get_name(1)); } void file_save_as_ps_simple_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save PS file", "*", 0)) + if(file_chooser(0, 1, "Save PS file", "*", 0)) _save_ps_simple(file_chooser_get_name(1)); } void file_save_as_ps_accurate_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save PS file", "*", 0)) + if(file_chooser(0, 1, "Save PS file", "*", 0)) _save_ps_accurate(file_chooser_get_name(1)); } void file_save_as_pstex_simple_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save LaTeX file (PS part)", "*", 0)) + if(file_chooser(0, 1, "Save LaTeX file (PS part)", "*", 0)) _save_pstex_simple(file_chooser_get_name(1)); } void file_save_as_pstex_accurate_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save LaTeX file (PS part)", "*", 0)) + if(file_chooser(0, 1, "Save LaTeX file (PS part)", "*", 0)) _save_ps_accurate(file_chooser_get_name(1)); } void file_save_as_jpegtex_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save LaTeX file (JPEG part)", "*", 0)) + if(file_chooser(0, 1, "Save LaTeX file (JPEG part)", "*", 0)) _save_jpegtex(file_chooser_get_name(1)); } void file_save_as_pngtex_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save LaTeX file (PNG part)", "*", 0)) + if(file_chooser(0, 1, "Save LaTeX file (PNG part)", "*", 0)) _save_pngtex(file_chooser_get_name(1)); } void file_save_as_tex_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save LaTeX file (TeX part)", "*", 0)) + if(file_chooser(0, 1, "Save LaTeX file (TeX part)", "*", 0)) _save_tex(file_chooser_get_name(1)); } void file_save_as_jpeg_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save JPEG file", "*", 0)) + if(file_chooser(0, 1, "Save JPEG file", "*", 0)) _save_jpeg(file_chooser_get_name(1)); } void file_save_as_png_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save PNG file", "*", 0)) + if(file_chooser(0, 1, "Save PNG file", "*", 0)) _save_png(file_chooser_get_name(1)); } void file_save_as_gif_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save GIF file", "*", 0)) + if(file_chooser(0, 1, "Save GIF file", "*", 0)) _save_gif(file_chooser_get_name(1)); } void file_save_as_gif_dithered_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save GIF file", "*", 0)) + if(file_chooser(0, 1, "Save GIF file", "*", 0)) _save_gif_dithered(file_chooser_get_name(1)); } void file_save_as_gif_transparent_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save GIF file", "*", 0)) + if(file_chooser(0, 1, "Save GIF file", "*", 0)) _save_gif_transparent(file_chooser_get_name(1)); } void file_save_as_ppm_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save PPM file", "*", 0)) + if(file_chooser(0, 1, "Save PPM file", "*", 0)) _save_ppm(file_chooser_get_name(1)); } void file_save_as_yuv_cb(CALLBACK_ARGS) { - if(file_chooser(0, "Save YUV file", "*", 0)) + if(file_chooser(0, 1, "Save YUV file", "*", 0)) _save_yuv(file_chooser_get_name(1)); } @@ -1140,7 +1167,7 @@ void message_clear_cb(CALLBACK_ARGS) void message_save_cb(CALLBACK_ARGS) { test: - if(file_chooser(0, "Save messages", "*", 0)) { + if(file_chooser(0, 1, "Save messages", "*", 0)) { char *name = file_chooser_get_name(1); if(CTX.confirm_overwrite) { struct stat buf; @@ -1468,6 +1495,14 @@ void help_about_cb(CALLBACK_ARGS) WID->create_about_window(); } +void help_online_cb(CALLBACK_ARGS) +{ + char cmd[1000]; + sprintf(cmd, CTX.web_browser, "http://www.geuz.org/gmsh/doc/texinfo/"); + Msg(INFO, "Starting web browser '%s'", cmd); + SystemCall(cmd); +} + // Module Menu void mod_geometry_cb(CALLBACK_ARGS) @@ -2557,7 +2592,10 @@ void solver_file_open_cb(CALLBACK_ARGS) char tmp[256]; int num = (int)data; sprintf(tmp, "*%s", SINFO[num].extension); - if(file_chooser(0, "Open problem definition file", tmp, 0)) { + + // We allow to create the .pro file... Or should we add a "New file" + // button? + if(file_chooser(0, 1, "Open problem definition file", tmp, 0)) { WID->solver[num].input[0]->value(file_chooser_get_name(1)); if(SINFO[num].nboptions) { sprintf(tmp, "%s \"%s\"", SINFO[num].option_command, @@ -2577,7 +2615,7 @@ void solver_file_edit_cb(CALLBACK_ARGS) void solver_choose_mesh_cb(CALLBACK_ARGS) { int num = (int)data; - if(file_chooser(0, "Open mesh file", "*.msh", 0)) + if(file_chooser(0, 0, "Open mesh file", "*.msh", 0)) WID->solver[num].input[1]->value(file_chooser_get_name(1)); } int nbs(char *str) @@ -2647,7 +2685,7 @@ void solver_kill_cb(CALLBACK_ARGS) void solver_choose_executable_cb(CALLBACK_ARGS) { int num = (int)data; - if(file_chooser(0, "Choose executable", + if(file_chooser(0, 0, "Choose executable", #if defined(WIN32) "*.exe" #else @@ -2718,14 +2756,11 @@ void view_reload_cb(CALLBACK_ARGS) Post_View *v = (Post_View *) List_Pointer(CTX.post.list, (long int)data); strcpy(filename, v->FileName); - // Hum... We should use the appropriate function to test this, but I - // don't know it (stat?) - FILE *fp = fopen(filename, "r"); - if(!fp){ - Msg(GERROR, "Unable to open file '%s'", filename); + struct stat buf; + if(stat(filename, &buf)){ + Msg(GERROR, "File '%s' does not exist", filename); return; } - fclose(fp); CopyViewOptions(v, &tmp); FreeView(v); @@ -2795,7 +2830,7 @@ void view_remove_cb(CALLBACK_ARGS) void view_save_ascii_cb(CALLBACK_ARGS) { test: - if(file_chooser(0, "Save view in ASCII format", "*", 0)) { + if(file_chooser(0, 1, "Save view in ASCII format", "*", 0)) { char *name = file_chooser_get_name(1); if(CTX.confirm_overwrite) { struct stat buf; @@ -2814,7 +2849,7 @@ test: void view_save_binary_cb(CALLBACK_ARGS) { test: - if(file_chooser(0, "Save view in binary format", "*", 0)) { + if(file_chooser(0, 1, "Save view in binary format", "*", 0)) { char *name = file_chooser_get_name(1); if(CTX.confirm_overwrite) { struct stat buf; diff --git a/Fltk/Callbacks.h b/Fltk/Callbacks.h index 4f56b0db1a74bb4a35a6c85606d50dc3265c25eb..027a69d43caf47369917ab26f08ec53059f1a926 100644 --- a/Fltk/Callbacks.h +++ b/Fltk/Callbacks.h @@ -43,6 +43,7 @@ void status_cancel_cb(CALLBACK_ARGS) ; // File Menu +void file_new_cb(CALLBACK_ARGS) ; void file_open_cb(CALLBACK_ARGS) ; void file_merge_cb(CALLBACK_ARGS) ; void file_save_as_cb(CALLBACK_ARGS) ; @@ -146,6 +147,7 @@ void visibility_ok_cb(CALLBACK_ARGS) ; void help_short_cb(CALLBACK_ARGS) ; void help_command_line_cb(CALLBACK_ARGS) ; +void help_online_cb(CALLBACK_ARGS) ; void help_license_cb(CALLBACK_ARGS) ; void help_about_cb(CALLBACK_ARGS) ; diff --git a/Fltk/GUI.cpp b/Fltk/GUI.cpp index 564a5bd446e987ba1c07fbf05b9af6672d3b06ae..20ddf7064e1add4edf212d6191da63a50d1549bc 100644 --- a/Fltk/GUI.cpp +++ b/Fltk/GUI.cpp @@ -1,4 +1,4 @@ -// $Id: GUI.cpp,v 1.260 2003-12-03 00:54:11 geuzaine Exp $ +// $Id: GUI.cpp,v 1.261 2003-12-03 04:14:18 geuzaine Exp $ // // Copyright (C) 1997-2003 C. Geuzaine, J.-F. Remacle // @@ -82,13 +82,14 @@ extern Context_T CTX; // Don't define shortcuts for FL_CTRL+'n', FL_CTRL+'p', FL_CTRL+'f', FL_CTRL+'b' // these are used by fltk for widget navigation (in the same way as the 4 arrow keys) -// We can not use the 'g', 'm' 's' and 'p' mnemonics since they are +// We shouldn't use the 'g', 'm' 's' and 'p' mnemonics since they are // already defined as global shortcuts (geometry, mesh, solver, post). Fl_Menu_Item m_menubar_table[] = { {"&File", 0, 0, 0, FL_SUBMENU}, + {"&New...", 0, (Fl_Callback *)file_new_cb, 0}, {"&Open...", FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0}, - {"M&erge...", FL_CTRL+'m', (Fl_Callback *)file_merge_cb, 0}, + {"M&erge...", FL_CTRL+'m', (Fl_Callback *)file_merge_cb, 0, FL_MENU_DIVIDER}, {"Sa&ve mesh", FL_CTRL+'s', (Fl_Callback *)mesh_save_cb, 0}, #if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 0) {"Save &as", 0, 0, 0, FL_MENU_DIVIDER|FL_SUBMENU}, @@ -144,6 +145,7 @@ Fl_Menu_Item m_menubar_table[] = { {"&Current options...", 0, (Fl_Callback *)status_xyz1p_cb, (void*)4}, {"S&hortcuts...", 0, (Fl_Callback *)help_short_cb, 0}, {"C&ommand line options...", 0, (Fl_Callback *)help_command_line_cb, 0, FL_MENU_DIVIDER}, + {"On&line Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER}, {"&About...", 0, (Fl_Callback *)help_about_cb, 0}, {0}, {0} @@ -156,6 +158,7 @@ Fl_Menu_Item m_menubar_table[] = { Fl_Menu_Item m_sys_menubar_table[] = { {"File", 0, 0, 0, FL_SUBMENU}, + {"New...", 0, (Fl_Callback *)file_new_cb, 0}, {"Open...", FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0}, {"Merge...", FL_CTRL+'m', (Fl_Callback *)file_merge_cb, 0, FL_MENU_DIVIDER}, {"Save Mesh", FL_CTRL+'s', (Fl_Callback *)mesh_save_cb, 0}, @@ -171,6 +174,7 @@ Fl_Menu_Item m_sys_menubar_table[] = { {"Current Options...", 0, (Fl_Callback *)status_xyz1p_cb, (void*)4}, {"Shortcuts...", 0, (Fl_Callback *)help_short_cb, 0}, {"Command Line Options...", 0, (Fl_Callback *)help_command_line_cb, 0, FL_MENU_DIVIDER}, + {"Online Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER}, {"About Gmsh...", 0, (Fl_Callback *)help_about_cb, 0}, {0}, {0} diff --git a/doc/VERSIONS b/doc/VERSIONS index e93d4fb7d52f380581c48416cafe0b9c14b10fb2..2831bf7b7fb163bda3da1268e158b017b1bab00a 100644 --- a/doc/VERSIONS +++ b/doc/VERSIONS @@ -1,8 +1,9 @@ -$Id: VERSIONS,v 1.170 2003-12-01 23:15:33 geuzaine Exp $ +$Id: VERSIONS,v 1.171 2003-12-03 04:14:18 geuzaine Exp $ New since 1.49: small changes to the visibility browser + made visibility scriptable (new Show/Hide commands); fixed (rare) crash -when deleting views; +when deleting views; split File->Open into File->Open/File->New to +behave like most other programs; New in 1.49: made Merge, Save and Print behave like Include (i.e., open files in the same directory as the main project file if the path