From 125a16a9d559a759df6a6b71cc9ef17a9b730e7b Mon Sep 17 00:00:00 2001
From: Christophe Geuzaine <cgeuzaine@ulg.ac.be>
Date: Fri, 25 Jul 2014 11:35:00 +0000
Subject: [PATCH] - ParseString can now run in the current model directory
 (useful when parsing things with relative filenames) - New View.Time option
 to select the timestep according to the time value

---
 Common/CreateFile.cpp   |  2 +-
 Common/DefaultOptions.h |  3 +++
 Common/OpenFile.cpp     | 10 ++++++++--
 Common/OpenFile.h       |  2 +-
 Common/Options.cpp      | 25 +++++++++++++++++++++++++
 Common/Options.h        |  1 +
 Common/onelabUtils.cpp  |  4 ++--
 Fltk/onelabGroup.cpp    |  2 +-
 Fltk/openglWindow.cpp   |  7 ++++++-
 Parser/Gmsh.y           |  2 +-
 10 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index d4a2a2de91..030a87725f 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -222,7 +222,7 @@ void change_print_parameter(int frame)
   double v = first + frame * step * CTX::instance()->post.animStep;
   Msg::Info("Setting Print.Parameter = %g", v);
   opt_print_parameter(0, GMSH_SET | GMSH_GUI, v);
-  ParseString(CTX::instance()->print.parameterCommand);
+  ParseString(CTX::instance()->print.parameterCommand, true);
 }
 
 void CreateOutputFile(const std::string &fileName, int format,
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index f1bbd1370e..c8b5352b7c 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -1523,6 +1523,9 @@ StringXNumber ViewOptions_Number[] = {
     "Tensor Visualization Type" },
   { F,   "TimeStep" , opt_view_timestep , 0. ,
     "Current time step displayed" },
+  { F,   "Time" , opt_view_time , -1. ,
+    "Current time displayed (if positive, sets the time step corresponding "
+    "the given time value)" },
   { F,   "TransformXX" , opt_view_transform00 , 1. ,
     "Element (1,1) of the 3x3 coordinate transformation matrix" },
   { F,   "TransformXY" , opt_view_transform01 , 0. ,
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 80c25cd60c..37b3ef8c72 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -250,15 +250,21 @@ static bool doSystemUncompress(std::string fileName, std::string noExt)
   return false;
 }
 
-void ParseString(const std::string &str)
+void ParseString(const std::string &str, bool inCurrentModelDir)
 {
   if(str.empty()) return;
-  std::string fileName = CTX::instance()->homeDir + CTX::instance()->tmpFileName;
+  std::string fileName;
+  if(inCurrentModelDir)
+    fileName = FixRelativePath(GModel::current()->getFileName(),
+                               CTX::instance()->tmpFileName);
+  else
+    fileName = CTX::instance()->homeDir + CTX::instance()->tmpFileName;
   FILE *fp = Fopen(fileName.c_str(), "w");
   if(fp){
     fprintf(fp, "%s\n", str.c_str());
     fclose(fp);
     GModel::readGEO(fileName);
+    UnlinkFile(fileName);
   }
 }
 
diff --git a/Common/OpenFile.h b/Common/OpenFile.h
index 0812c73782..469dd2b3b2 100644
--- a/Common/OpenFile.h
+++ b/Common/OpenFile.h
@@ -9,7 +9,7 @@
 #include <string>
 
 int ParseFile(const std::string &fileName, bool close, bool warnIfMissing=false);
-void ParseString(const std::string &str);
+void ParseString(const std::string &str, bool inCurrentModelDir=false);
 void OpenProject(const std::string &filename, bool setWindowTitle=true);
 void OpenProjectMacFinder(const char *fileName);
 int MergeFile(const std::string &fileName, bool warnIfMissing=false,
diff --git a/Common/Options.cpp b/Common/Options.cpp
index f791414b20..51c3359ac6 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -6464,6 +6464,31 @@ double opt_view_timestep(OPT_ARGS_NUM)
 #endif
 }
 
+double opt_view_time(OPT_ARGS_NUM)
+{
+#if defined(HAVE_POST)
+  GET_VIEW(0.);
+  if(action & GMSH_SET) {
+    if(val >= 0.){
+      // if negative (the default), don't do anything so that we do not compete
+      // with timestep
+      int step = 0;
+      for(int i = 0; i < data->getNumTimeSteps(); i++){
+        double time = data->getTime(i);
+        if(fabs(time - val) < 1.e-15){
+          step = i;
+          break;
+        }
+      }
+      opt_view_timestep(num, action, step);
+    }
+  }
+  return opt->currentTime;
+#else
+  return 0.;
+#endif
+}
+
 double opt_view_min(OPT_ARGS_NUM)
 {
 #if defined(HAVE_POST)
diff --git a/Common/Options.h b/Common/Options.h
index 1848f9554b..7cb7468d34 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -535,6 +535,7 @@ double opt_post_graph_point_y(OPT_ARGS_NUM);
 double opt_view_nb_timestep(OPT_ARGS_NUM);
 double opt_view_nb_non_empty_timestep(OPT_ARGS_NUM);
 double opt_view_timestep(OPT_ARGS_NUM);
+double opt_view_time(OPT_ARGS_NUM);
 double opt_view_min(OPT_ARGS_NUM);
 double opt_view_max(OPT_ARGS_NUM);
 double opt_view_custom_min(OPT_ARGS_NUM);
diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp
index 9b9d6e72b1..803ea54a20 100644
--- a/Common/onelabUtils.cpp
+++ b/Common/onelabUtils.cpp
@@ -267,8 +267,8 @@ namespace onelabUtils {
     }
     if(x.size() && y.size()){
       if(x.size() != y.size())
-        Msg::Warning("X-Y data series have different length (%d != %d)",
-                     (int)x.size(), (int)y.size());
+        Msg::Info("X-Y data series have different length (%d != %d)",
+                  (int)x.size(), (int)y.size());
       if(view){
         view->getData()->setXY(x, y);
         view->getData()->setName(yName);
diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index 71bc0b7ac2..9a46781690 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -356,7 +356,7 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
     drawContext::global()->draw();
     break;
   case GmshSocket::GMSH_PARSE_STRING:
-    ParseString(message);
+    ParseString(message, true);
     drawContext::global()->draw();
     break;
   case GmshSocket::GMSH_SPEED_TEST:
diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index 80e22c0c71..00de31de12 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -357,7 +357,7 @@ int openglWindow::handle(int event)
         CTX::instance()->post.graphPointX = points[0].x();
         CTX::instance()->post.graphPointY = points[0].y();
         if(CTX::instance()->post.graphPointCommand.size())
-          ParseString(CTX::instance()->post.graphPointCommand);
+          ParseString(CTX::instance()->post.graphPointCommand, true);
       }
       else{ // popup quick access menu
         status_options_cb(0, (void*)"quick_access");
@@ -651,6 +651,11 @@ int openglWindow::handle(int event)
           char tmp[256];
           sprintf(tmp, "(%g,%g)", points[0].x(), points[0].y());
           text += tmp;
+          if(CTX::instance()->post.graphPointCommand.size()){
+            text += std::string("\nDouble-click to parse `");
+            text += CTX::instance()->post.graphPointCommand;
+            text += std::string("'");
+          }
         }
         if(CTX::instance()->tooltips)
           drawTooltip(text);
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index e557d106d5..6d81fd30b7 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -133,7 +133,7 @@ struct doubleXstring{
 %token tLayers tScaleLast tHole tAlias tAliasWithOptions tCopyOptions
 %token tQuadTriAddVerts tQuadTriNoNewVerts tQuadTriSngl tQuadTriDbl
 %token tRecombLaterals tTransfQuadTri
-%token tText2D tText3D tInterpolationScheme  tTime tCombine
+%token tText2D tText3D tInterpolationScheme tTime tCombine
 %token tBSpline tBezier tNurbs tNurbsOrder tNurbsKnots
 %token tColor tColorTable tFor tIn tEndFor tIf tEndIf tExit tAbort
 %token tField tReturn tCall tFunction tShow tHide tGetValue tGetEnv tGetString
-- 
GitLab