diff --git a/Common/Context.h b/Common/Context.h index 91738ca637b1ff884355211103352dc482db7e76..d8ccc0bacd0fc8d34442fb2a832956941e1fd826 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -64,6 +64,9 @@ class CTX { std::string meshStatReportFileName; // the home directory std::string homeDir; + // file history + int history_size; + std::string recent_files[5]; // create mesh statistics report (0: do nothing, 1: create, 2: append) int createAppendMeshStatReport; // save session/option file on exit? diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h index 55e38ad1eb7f4317e1784d296a0b059ecb0601ef..218d733ff6b2dcf0ce2ddb8c0912192cc7b27d61 100644 --- a/Common/DefaultOptions.h +++ b/Common/DefaultOptions.h @@ -60,6 +60,17 @@ StringXString GeneralOptions_String[] = { { F|S, "OptionsFileName" , opt_general_options_filename , ".gmsh-options" , "Option file created with `Tools->Options->Save'; automatically read on startup" }, + { F|S, "RecentFile1", opt_general_recent_file1 , "" , + "Most recent opened file"}, + { F|S, "RecentFile2", opt_general_recent_file2 , "" , + "2nd most recent opened file"}, + { F|S, "RecentFile3", opt_general_recent_file3 , "" , + "3rd most recent opened file"}, + { F|S, "RecentFile4", opt_general_recent_file4 , "" , + "4th most recent opened file"}, + { F|S, "RecentFile5", opt_general_recent_file5 , "" , + "5th most recent opened file"}, + { 0, "SessionFileName" , opt_general_session_filename , ".gmshrc" , "Option file into which session specific information is saved; automatically " "read on startup" }, @@ -598,6 +609,9 @@ StringXNumber GeneralOptions_Number[] = { { F|S, "GraphicsWidth" , opt_general_graphics_size0 , 600. , "Width (in pixels) of the graphic window" }, + { F|S, "HistorySize", opt_general_history_size , 0, + "Number of recently opened files in the menu"}, + { F|O, "InitialModule", opt_general_initial_context, 0. , "Module launched on startup (0=automatic, 1=geometry, 2=mesh, 3=solver, " "4=post-processing) " }, diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp index fdb7b72b35e8533da1cdc27271578e1e366aeeff..6bafd14c690dbb48999f60f0acb41edbac829ee8 100644 --- a/Common/OpenFile.cpp +++ b/Common/OpenFile.cpp @@ -18,6 +18,7 @@ #include "StringUtils.h" #include "GeomMeshMatcher.h" #include "LuaBindings.h" +#include "menuWindow.h" #if defined(HAVE_PARSER) #include "Parser.h" @@ -450,11 +451,18 @@ void OpenProject(std::string fileName) // temporary hack until we fill the current GModel on the fly during // parsing - ResetTemporaryBoundingBox(); + ResetTemporaryBoundingBox(); // merge the file - MergeFile(fileName); - + if(MergeFile(fileName)) { + for (int i=4; i > 0; i--) + CTX::instance()->recent_files[i] = CTX::instance()->recent_files[i-1]; + CTX::instance()->recent_files[0] = fileName; + if (CTX::instance()->history_size < 5) + CTX::instance()->history_size++; + FlGui::instance()->menu->fillRecentHistoryMenu(); + } + CTX::instance()->lock = 0; #if defined(HAVE_FLTK) diff --git a/Common/Options.cpp b/Common/Options.cpp index e707c1cce4df7ff67b381f08c0a6e6b46950efe3..e2a318bfed9d0cd13d60f8f01771e191de0aacf0 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -987,6 +987,41 @@ std::string opt_general_options_filename(OPT_ARGS_STR) return CTX::instance()->optionsFileName; } +std::string opt_general_recent_file1(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX::instance()->recent_files[0] = val; + return CTX::instance()->recent_files[0]; +} + +std::string opt_general_recent_file2(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX::instance()->recent_files[1] = val; + return CTX::instance()->recent_files[1]; +} + +std::string opt_general_recent_file3(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX::instance()->recent_files[2] = val; + return CTX::instance()->recent_files[2]; +} + +std::string opt_general_recent_file4(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX::instance()->recent_files[3] = val; + return CTX::instance()->recent_files[3]; +} + +std::string opt_general_recent_file5(OPT_ARGS_STR) +{ + if(action & GMSH_SET) + CTX::instance()->recent_files[4] = val; + return CTX::instance()->recent_files[4]; +} + std::string opt_general_editor(OPT_ARGS_STR) { if(action & GMSH_SET) @@ -2495,6 +2530,14 @@ double opt_general_message_auto_scroll(OPT_ARGS_NUM) return CTX::instance()->msgAutoScroll; } +double opt_general_history_size(OPT_ARGS_NUM) +{ + if(action & GMSH_SET) + if ((int)val >= 0 && (int)val < 6) + CTX::instance()->history_size = (int)val; + return CTX::instance()->history_size; +} + double opt_general_option_position0(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Common/Options.h b/Common/Options.h index 7fd5c9bf3c66a52bb28e5acf651ac0404fe2811c..7414368ff4f5b6d52a1c5c74ab266d730482f9a7 100644 --- a/Common/Options.h +++ b/Common/Options.h @@ -39,6 +39,11 @@ std::string opt_general_tmp_filename(OPT_ARGS_STR); std::string opt_general_error_filename(OPT_ARGS_STR); std::string opt_general_session_filename(OPT_ARGS_STR); std::string opt_general_options_filename(OPT_ARGS_STR); +std::string opt_general_recent_file1(OPT_ARGS_STR); +std::string opt_general_recent_file2(OPT_ARGS_STR); +std::string opt_general_recent_file3(OPT_ARGS_STR); +std::string opt_general_recent_file4(OPT_ARGS_STR); +std::string opt_general_recent_file5(OPT_ARGS_STR); std::string opt_general_editor(OPT_ARGS_STR); std::string opt_general_web_browser(OPT_ARGS_STR); std::string opt_general_gui_theme(OPT_ARGS_STR); @@ -243,6 +248,7 @@ double opt_general_message_position1(OPT_ARGS_NUM); double opt_general_message_size0(OPT_ARGS_NUM); double opt_general_message_size1(OPT_ARGS_NUM); double opt_general_message_auto_scroll(OPT_ARGS_NUM); +double opt_general_history_size(OPT_ARGS_NUM); double opt_general_option_position0(OPT_ARGS_NUM); double opt_general_option_position1(OPT_ARGS_NUM); double opt_general_plugin_position0(OPT_ARGS_NUM); diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp index de9c4529e476b048adcfa7546664cdb6963469e7..378fe0c4a0e9d92287b5cf2b4b7f3a7ea5e6b3bf 100644 --- a/Fltk/FlGui.cpp +++ b/Fltk/FlGui.cpp @@ -231,7 +231,7 @@ FlGui::FlGui(int argc, char **argv) gmsh32x32, 32, 32)); menu->win->icon ((const char*)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display), - gmsh32x32, 32, 32)); + gmsh32x32, 32, 32)); #endif // open graphic window first for correct non-modal behaviour on diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp index 9754e96a353646df0980b645745684947b927015..f148b3bd1e1996310402dc28bebea7924c5b4ede 100644 --- a/Fltk/menuWindow.cpp +++ b/Fltk/menuWindow.cpp @@ -141,6 +141,17 @@ static void file_merge_cb(Fl_Widget *w, void *data) FlGui::instance()->menu->setContext(menu_post, 0); } +void file_open_recent_cb(Fl_Widget *w, void *data) +{ + std::string str((const char*)data); + + int n = PView::list.size(); + OpenProject(str); + drawContext::global()->draw(); + if(n != (int)PView::list.size()) + FlGui::instance()->menu->setContext(menu_post, 0); +} + static void file_clear_cb(Fl_Widget *w, void *data) { ClearProject(); @@ -2218,6 +2229,13 @@ static Fl_Menu_Item bar_table[] = { {"&New...", FL_CTRL+'n', (Fl_Callback *)file_new_cb, 0}, {"&Open...", FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0}, {"M&erge...", FL_CTRL+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0}, + {"Open recent", 0, 0, 0, FL_SUBMENU}, + {"History1", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History2", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History3", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History4", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History5", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {0}, {"&Clear", 0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER}, {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, {"Start...", 0, (Fl_Callback *)file_remote_cb, (void*)"start"}, @@ -2271,6 +2289,13 @@ static Fl_Menu_Item sysbar_table[] = { {"Open...", FL_META+'o', (Fl_Callback *)file_open_cb, 0}, {"Merge...", FL_META+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0}, {"Clear", 0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER}, + {"Open recent", 0, 0, 0, FL_SUBMENU}, + {"History1", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History2", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History3", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History4", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {"History5", 0,(Fl_Callback *)file_open_recent_cb, 0, FL_MENU_INVISIBLE}, + {0}, {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU}, {"Start...", 0, (Fl_Callback *)file_remote_cb, (void*)"start"}, {"Merge...", 0, (Fl_Callback *)file_remote_cb, (void*)"merge"}, @@ -2598,6 +2623,10 @@ menuWindow::menuWindow() bar->menu(bar_table); bar->box(FL_UP_BOX); bar->global(); + + // create recent history menu + fillRecentHistoryMenu(); + Fl_Box *o = new Fl_Box(0, BH, width, BH + 6); o->box(FL_UP_BOX); y = BH + 3; @@ -2872,3 +2901,18 @@ void menuWindow::setContext(contextItem *menu_asked, int flag) else win->size(width, _MH + NB_BUTT_SCROLL * BH); } + +void menuWindow::fillRecentHistoryMenu() { + for (int i = 0; i < CTX::instance()->history_size; i++){ +#if defined(__APPLE__) + sysbar_table[i+5].text = (CTX::instance()->recent_files[i]).c_str(); + sysbar_table[i+5].callback_ = (Fl_Callback *)file_open_recent_cb; + sysbar_table[i+5].user_data_ = (void*)(CTX::instance()->recent_files[i]).c_str(); + sysbar_table[i+5].show(); +#endif + bar_table[i+5].text = (CTX::instance()->recent_files[i]).c_str(); + bar_table[i+5].callback_ = (Fl_Callback *)file_open_recent_cb; + bar_table[i+5].user_data_ = (void*)(CTX::instance()->recent_files[i]).c_str(); + bar_table[i+5].show(); + }; +} diff --git a/Fltk/menuWindow.h b/Fltk/menuWindow.h index c7a7bf056f9fb6eaddd266abb14d4aa8a7e71f54..6b8ca7efc899d66876722991eea063a08a8422dd 100644 --- a/Fltk/menuWindow.h +++ b/Fltk/menuWindow.h @@ -72,9 +72,11 @@ class menuWindow{ std::vector<popupButton*> popup; std::vector<popupButton*> popup2; std::vector<char*> label, label2; + public: menuWindow(); void setContext(contextItem *menu_asked, int flag); + void fillRecentHistoryMenu(); }; void file_quit_cb(Fl_Widget *w, void *data); @@ -88,5 +90,6 @@ void geometry_reload_cb(Fl_Widget *w, void *data); void mesh_1d_cb(Fl_Widget *w, void *data); void mesh_2d_cb(Fl_Widget *w, void *data); void mesh_3d_cb(Fl_Widget *w, void *data); +void file_open_recent_cb(Fl_Widget *w, void *data); #endif