From 6a057fa6de6453c3f1c2349d87c91e69e9c08522 Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Sat, 10 Jan 2009 08:47:20 +0000
Subject: [PATCH] Added "File->Save Options" to automatically save options for
 the current project (same name + appended ".opt")

OpenProject will detect the ".opt" and will load the options
automatically if available.

Adapted from an original idea and patch from <jiri.hnidek@tul.cz>.

Thanks Jiri!
---
 Common/GmshMessage.cpp |  4 +---
 Common/OpenFile.cpp    | 15 +++++++++++----
 Common/Options.cpp     | 24 ++++++++++++++----------
 Fltk/fileDialogs.cpp   |  3 +++
 Fltk/menuWindow.cpp    | 10 ++++++++++
 Fltk/optionWindow.cpp  | 10 ++++------
 6 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index 86ab9206e3..0e2284b6a8 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -94,11 +94,9 @@ void Msg::Exit(int level)
   // if we exit cleanly (level==0) and we are in full GUI mode, save
   // the persistent info to disk
   if(GUI::available() && !_commRank) {
-    if(CTX.session_save) {
-      GUI::instance()->storeCurrentWindowsInfo();
+    if(CTX.session_save)
       Print_Options(0, GMSH_SESSIONRC, 0, 0, 
                     (CTX.home_dir + CTX.session_filename).c_str());
-    }
     if(CTX.options_save)
       Print_Options(0, GMSH_OPTIONSRC, 1, 0, 
                     (CTX.home_dir + CTX.options_filename).c_str());
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index b93f5dd12f..b39aef576f 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -406,15 +406,16 @@ void OpenProject(std::string fileName)
 
   if(GModel::current()->empty()){
     // if the current model is empty, make sure it's reaaally
-    // cleaned-up, and reuse it
+    // cleaned-up, and reuse it (don't clear the parser variables: if
+    // the model is empty we probably just launched gmsh, and we don't
+    // want to delete variables set e.g. using the -string command
+    // line option)
     GModel::current()->destroy();
     GModel::current()->getGEOInternals()->destroy();
   }
   else{
     // if the current model is not empty make it invisible, clear the
-    // parser variables (if it's empty it probably means we just
-    // launched gmsh, and we don't want to delete variables set
-    // e.g. using the -string command line option) and add a new model
+    // parser variables and add a new model
     GModel::current()->setVisibility(0);
 #if !defined(HAVE_NO_PARSER)
     gmsh_yysymbols.clear();
@@ -426,8 +427,14 @@ void OpenProject(std::string fileName)
   // temporary hack until we fill the current GModel on the fly during
   // parsing
   ResetTemporaryBoundingBox();
+
+  // merge the file
   MergeFile(fileName);
 
+  // merge the associated option file if there is one
+  if(!StatFile(fileName + ".opt"))
+    MergeFile(fileName + ".opt");
+
   CTX.threads_lock = 0;
 
 #if defined(HAVE_FLTK)
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 5ceff5bca8..8d64440fcb 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -615,18 +615,23 @@ static void Print_ColorTable(int num, int diff, const char *prefix, FILE *file)
 //used in field options, sorry if it's already implemented somewhere else...
 static void Sanitize_String_Texi(std::string &s)
 {
-  int i=-1;
-  while ((i=s.find('\n',i+1))>=0){
-    s.insert(i,"@*");
-    i+=2;
+  int i = -1;
+  while ((i = s.find('\n', i + 1)) >= 0){
+    s.insert(i, "@*");
+    i += 2;
   }
-  i=-1;
-  while ((i=s.find_first_of("{}",i+1))>=0)
-    s.insert(i++,"@");
+  i = -1;
+  while ((i = s.find_first_of("{}", i + 1)) >= 0)
+    s.insert(i++, "@");
 }
 
 void Print_Options(int num, int level, int diff, int help, const char *filename)
 {
+#if defined(HAVE_FLTK)
+  if(GUI::available())
+    GUI::instance()->storeCurrentWindowsInfo();
+#endif
+
   FILE *file;
 
   if(filename) {
@@ -656,7 +661,7 @@ void Print_Options(int num, int level, int diff, int help, const char *filename)
     fprintf(file, "// This file contains configuration options (preferences) that\n");
     fprintf(file, "// are loaded each time Gmsh is launched. You can create this\n");
     fprintf(file, "// file by hand, or let Gmsh generate it for you (with\n");
-    fprintf(file, "// 'Tools->Options->Save as defaults'). This file can also be\n");
+    fprintf(file, "// 'File->Save Default Options'). This file can also be\n");
     fprintf(file, "// automatically saved every time you quit Gmsh if the option\n");
     fprintf(file, "// 'General.SaveOptions' is set.\n");
     fprintf(file, "//\n");
@@ -738,14 +743,13 @@ void Print_Options(int num, int level, int diff, int help, const char *filename)
 
 void Print_OptionsDoc()
 {
-  FILE *file;
   const char *warn =
     "@c\n"
     "@c This file is generated automatically by running \"gmsh -doc\".\n"
     "@c Do not edit by hand!\n"
     "@c\n\n";
   
-  file = fopen("opt_general.texi", "w");
+  FILE *file = fopen("opt_general.texi", "w");
   if(!file) {
     Msg::Error("Unable to open file 'opt_general.texi'");
     return;
diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp
index 6b0815f5b5..b12b1af413 100644
--- a/Fltk/fileDialogs.cpp
+++ b/Fltk/fileDialogs.cpp
@@ -19,6 +19,7 @@
 #include <FL/Fl_Round_Button.H>
 #include <FL/Fl_Choice.H>
 #include "GmshConfig.h"
+#include "GmshMessage.h"
 #include "GmshDefines.h"
 #include "GUI.h"
 #include "CreateFile.h"
@@ -527,7 +528,9 @@ int options_dialog(const char *name)
       Fl_Widget* o = Fl::readqueue();
       if (!o) break;
       if (o == dialog->ok) {
+        Msg::StatusBar(2, true, "Writing '%s'", name);
         Print_Options(0, GMSH_FULLRC, dialog->b[0]->value(), dialog->b[1]->value(), name);
+        Msg::StatusBar(2, true, "Wrote '%s'", name);
         dialog->window->hide();
         return 1;
       }
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
index 92a9094223..ce7e31a32a 100644
--- a/Fltk/menuWindow.cpp
+++ b/Fltk/menuWindow.cpp
@@ -318,6 +318,14 @@ static void file_save_as_cb(Fl_Widget *w, void *data)
 #undef TT
 #undef NN
 
+static void file_options_save_cb(Fl_Widget *w, void *data)
+{
+  std::string fileName = GModel::current()->getFileName() + ".opt";
+  Msg::StatusBar(2, true, "Writing '%s'", fileName.c_str());
+  Print_Options(0, GMSH_FULLRC, 1, 0, fileName.c_str());
+  Msg::StatusBar(2, true, "Wrote '%s'", fileName.c_str());
+}
+
 static void file_rename_cb(Fl_Widget *w, void *data)
 {
  test:
@@ -2145,6 +2153,7 @@ static Fl_Menu_Item bar_table[] = {
     {"&Rename...",  FL_CTRL+'r', (Fl_Callback *)file_rename_cb, 0},
     {"Save &As...", FL_CTRL+'s', (Fl_Callback *)file_save_as_cb, 0},
     {"Sa&ve Mesh",  FL_CTRL+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0},
+    {"Save Options", 0, (Fl_Callback *)file_options_save_cb, 0},
     {"Save Default Options", 0, (Fl_Callback *)options_save_cb, 0, FL_MENU_DIVIDER},
     {"&Quit",       FL_CTRL+'q', (Fl_Callback *)file_quit_cb, 0},
     {0},
@@ -2188,6 +2197,7 @@ static Fl_Menu_Item sysbar_table[] = {
     {"Rename...",  FL_META+'r', (Fl_Callback *)file_rename_cb, 0},
     {"Save As...", FL_META+'s', (Fl_Callback *)file_save_as_cb, 0},
     {"Save Mesh",  FL_META+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0},
+    {"Save Options", 0, (Fl_Callback *)file_options_save_cb, 0},
     {"Save Default Options", 0, (Fl_Callback *)options_save_cb, 0},
     {0},
   {"Tools", 0, 0, 0, FL_SUBMENU},
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 6d7c56ac94..b5a7423855 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -143,12 +143,10 @@ static void options_browser_cb(Fl_Widget *w, void *data)
 
 void options_save_cb(Fl_Widget *w, void *data)
 {
-  Msg::StatusBar(2, true, "Writing '%s'",
-                 (CTX.home_dir + CTX.options_filename).c_str());
-  Print_Options(0, GMSH_OPTIONSRC, 1, 1, 
-                (CTX.home_dir + CTX.options_filename).c_str());
-  Msg::StatusBar(2, true, "Wrote '%s'",
-                 (CTX.home_dir + CTX.options_filename).c_str());
+  std::string fileName = CTX.home_dir + CTX.options_filename;
+  Msg::StatusBar(2, true, "Writing '%s'", fileName.c_str());
+  Print_Options(0, GMSH_OPTIONSRC, 1, 1, fileName.c_str());
+  Msg::StatusBar(2, true, "Wrote '%s'", fileName.c_str());
 }
 
 static void options_restore_defaults_cb(Fl_Widget *w, void *data)
-- 
GitLab