From faf88978402b01afb9dfc2bf7538e4ddfb464f66 Mon Sep 17 00:00:00 2001
From: Francois Henrotte <francois.henrotte@ulg.ac.be>
Date: Tue, 2 Oct 2012 07:57:28 +0000
Subject: [PATCH] loop index stored in onelab::number

---
 Common/onelab.h        | 12 +++++++++++-
 Common/onelabUtils.cpp | 36 ++++++++++++++++++++++++------------
 Fltk/onelabWindow.cpp  |  6 +++++-
 3 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/Common/onelab.h b/Common/onelab.h
index 113ee67761..5700dfb54f 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -268,17 +268,21 @@ namespace onelab{
   class number : public parameter{
   private:
     double _value, _min, _max, _step;
+    // when in a loop, indicates current index in the vector _choices
+    // is -1 when not in a loop
+    int _index;
     std::vector<double> _choices;
     std::map<double, std::string> _valueLabels;
   public:
     number(const std::string &name="", double value=0.,
            const std::string &label="", const std::string &help="")
       : parameter(name, label, help), _value(value),
-        _min(-maxNumber()), _max(maxNumber()), _step(0.) {}
+      _min(-maxNumber()), _max(maxNumber()), _step(0.), _index(0) {}
     void setValue(double value){ _value = value; }
     void setMin(double min){ _min = min; }
     void setMax(double max){ _max = max; }
     void setStep(double step){ _step = step; }
+    void setIndex(int index){ _index = index; }
     void setChoices(const std::vector<double> &choices){ _choices = choices; }
     void setChoiceLabels(const std::vector<std::string> &labels)
     {
@@ -299,6 +303,7 @@ namespace onelab{
     double getMin() const { return _min; }
     double getMax() const { return _max; }
     double getStep() const { return _step; }
+    int getIndex() const { return _index; }
     const std::vector<double> &getChoices() const { return _choices; }
     const std::map<double, std::string> &getValueLabels() const
     {
@@ -325,6 +330,7 @@ namespace onelab{
       setMin(p.getMin());
       setMax(p.getMax());
       setStep(p.getStep());
+      setIndex(p.getIndex());
       setChoices(p.getChoices());
       setValueLabels(p.getValueLabels());
     }
@@ -333,6 +339,7 @@ namespace onelab{
       std::ostringstream sstream;
       sstream << parameter::toChar() << _value << charSep()
               << _min << charSep() << _max << charSep() << _step << charSep()
+	      << _index << charSep()
               << _choices.size() << charSep();
       for(unsigned int i = 0; i < _choices.size(); i++)
         sstream << _choices[i] << charSep();
@@ -352,6 +359,7 @@ namespace onelab{
       setMin(atof(getNextToken(msg, pos).c_str()));
       setMax(atof(getNextToken(msg, pos).c_str()));
       setStep(atof(getNextToken(msg, pos).c_str()));
+      setIndex(atoi(getNextToken(msg, pos).c_str()));
       _choices.resize(atoi(getNextToken(msg, pos).c_str()));
       for(unsigned int i = 0; i < _choices.size(); i++)
         _choices[i] = atof(getNextToken(msg, pos).c_str());
@@ -402,6 +410,8 @@ namespace onelab{
         setChanged(true);
       }
       setChoices(p.getChoices());
+      if(getName().find("/Action") != std::string::npos)
+	setChanged(false);
     }
     std::string toChar() const
     {
diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp
index 6eacf624ff..7e7f40be2d 100644
--- a/Common/onelabUtils.cpp
+++ b/Common/onelabUtils.cpp
@@ -100,8 +100,10 @@ namespace onelabUtils {
     std::vector<onelab::number> numbers;
     onelab::server::instance()->get(numbers);
     for(unsigned int i = 0; i < numbers.size(); i++){
+
       if(numbers[i].getAttribute("Loop") == level){
         if(numbers[i].getChoices().size() > 1){
+	  numbers[i].setIndex(0);
           numbers[i].setValue(numbers[i].getChoices()[0]);
           onelab::server::instance()->set(numbers[i]);
           changed = true;
@@ -139,21 +141,31 @@ namespace onelabUtils {
         loop = true;
 
         if(numbers[i].getChoices().size() > 1){
+	  int j=numbers[i].getIndex();
+	  if((j>=0) && (j < numbers[i].getChoices().size())){
+	    numbers[i].setValue(numbers[i].getChoices()[j]);
+	    numbers[i].setIndex(j+1);
+	    onelab::server::instance()->set(numbers[i]);
+            Msg::Info("Recomputing with %dth choice %s=%g", j,
+		      numbers[i].getName().c_str(), numbers[i].getValue());
+	    recompute = true;
+	  }
+
           // FIXME should store loopVariable attribute in the parameter
           // -- the following test will loop forever if 2 values are
           // identical in the list of choices
-          std::vector<double> choices(numbers[i].getChoices());
-          for(unsigned int j = 0; j < choices.size() - 1; j++){
-            if(numbers[i].getValue() == choices[j]){
-              numbers[i].setValue(choices[j + 1]);
-              onelab::server::instance()->set(numbers[i]);
-              Msg::Info("Recomputing with new choice %s=%g",
-                        numbers[i].getName().c_str(), numbers[i].getValue());
-              recompute = true;
-              break;
-            }
-          }
-        }
+          // std::vector<double> choices(numbers[i].getChoices());
+          // for(unsigned int j = 0; j < choices.size() - 1; j++){
+          //   if(numbers[i].getValue() == choices[j]){
+          //     numbers[i].setValue(choices[j + 1]);
+          //     onelab::server::instance()->set(numbers[i]);
+          //     Msg::Info("Recomputing with new choice %s=%g",
+          //               numbers[i].getName().c_str(), numbers[i].getValue());
+          //     recompute = true;
+          //     break;
+          //   }
+	  // }
+	}
         else if(numbers[i].getStep() > 0){
           if(numbers[i].getMax() != onelab::parameter::maxNumber() &&
              numbers[i].getValue() < numbers[i].getMax()){
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabWindow.cpp
index 2835ba2a34..90c767b2b0 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabWindow.cpp
@@ -530,9 +530,13 @@ void onelab_cb(Fl_Widget *w, void *data)
       o.setVisible(false);
       onelab::server::instance()->set(o);
       c->run();
-      if(action == "compute")
+      if(action == "compute"){
         FlGui::instance()->onelab->checkForErrors(c->getName());
+	if(metamodel)
+	  onelab::server::instance()->setChanged(false,c->getName());
+      }
       if(FlGui::instance()->onelab->stop()) break;
+
     }
 
     // update geometry which might have been changed by the metamodel
-- 
GitLab