[chronojump] DB 1.75, 1.76. ForceSensor elastic code



commit 11d94c92049ec478bf4b1bf1a78707c58b1c2eda
Author: Xavier de Blas <xaviblas gmail com>
Date:   Wed Oct 23 18:55:42 2019 +0200

    DB 1.75, 1.76. ForceSensor elastic code

 glade/app1.glade                       |  78 +++---
 glade/force_sensor_elastic_bands.glade | 438 +++++++++++++++++++++++++++++++++
 po/POTFILES.in                         |   2 +
 src/Makefile.am                        |   4 +-
 src/constants.cs                       |   1 +
 src/forceSensor.cs                     | 156 +++++++++++-
 src/gui/forceSensor.cs                 |  90 ++++++-
 src/gui/forceSensorElasticBands.cs     | 423 +++++++++++++++++++++++++++++++
 src/sqlite/forceSensor.cs              | 191 +++++++++++++-
 src/sqlite/main.cs                     |  31 ++-
 10 files changed, 1363 insertions(+), 51 deletions(-)
---
diff --git a/glade/app1.glade b/glade/app1.glade
index 83cb3df8..a7666c01 100644
--- a/glade/app1.glade
+++ b/glade/app1.glade
@@ -6661,7 +6661,7 @@ EncoderInertialCapture</property>
                                                             <widget class="GtkHBox" id="hbox298">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
-                                                            <property name="spacing">8</property>
+                                                            <property name="spacing">4</property>
                                                             <child>
                                                             <widget class="GtkButton" 
id="button_force_sensor_exercise_edit">
                                                             <property name="visible">True</property>
@@ -9216,10 +9216,10 @@ EncoderInertialCapture</property>
                                                             <property name="can_focus">False</property>
                                                             <property name="spacing">20</property>
                                                             <child>
-                                                            <widget class="GtkComboBox" 
id="combo_force_sensor_capture_options">
-                                                            <property name="visible">True</property>
-                                                            <property name="can_focus">False</property>
-                                                            <property name="items" translatable="yes"/>
+                                                            <widget class="GtkButton" 
id="button_force_sensor_stiffness">
+                                                            <property name="can_focus">True</property>
+                                                            <property name="receives_default">True</property>
+                                                            <signal name="clicked" 
handler="on_button_force_sensor_stiffness_clicked" swapped="no"/>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
@@ -9228,27 +9228,22 @@ EncoderInertialCapture</property>
                                                             </packing>
                                                             </child>
                                                             <child>
-                                                            <widget class="GtkHBox" 
id="hbox_force_sensor_laterality">
-                                                            <property name="visible">True</property>
-                                                            <property name="can_focus">False</property>
-                                                            <property name="spacing">12</property>
-                                                            <child>
-                                                            <widget class="GtkLabel" id="label382">
+                                                            <widget class="GtkComboBox" 
id="combo_force_sensor_capture_options">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
-                                                            <property name="label" 
translatable="yes">Laterality</property>
+                                                            <property name="items" translatable="yes"/>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
                                                             <property name="fill">False</property>
-                                                            <property name="position">0</property>
+                                                            <property name="position">1</property>
                                                             </packing>
                                                             </child>
                                                             <child>
-                                                            <widget class="GtkHBox" id="hbox302">
+                                                            <widget class="GtkHBox" 
id="hbox_force_sensor_laterality">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
-                                                            <property name="spacing">8</property>
+                                                            <property name="spacing">6</property>
                                                             <child>
                                                             <widget class="GtkRadioButton" 
id="radio_force_sensor_laterality_both">
                                                             <property name="visible">True</property>
@@ -9386,16 +9381,9 @@ EncoderInertialCapture</property>
                                                             </child>
                                                             </widget>
                                                             <packing>
-                                                            <property name="expand">True</property>
-                                                            <property name="fill">True</property>
-                                                            <property name="position">1</property>
-                                                            </packing>
-                                                            </child>
-                                                            </widget>
-                                                            <packing>
                                                             <property name="expand">False</property>
                                                             <property name="fill">False</property>
-                                                            <property name="position">1</property>
+                                                            <property name="position">2</property>
                                                             </packing>
                                                             </child>
                                                             <child>
@@ -9449,7 +9437,7 @@ EncoderInertialCapture</property>
                                                             <packing>
                                                             <property name="expand">True</property>
                                                             <property name="fill">True</property>
-                                                            <property name="position">2</property>
+                                                            <property name="position">3</property>
                                                             </packing>
                                                             </child>
                                                             </widget>
@@ -22015,6 +22003,15 @@ Concentric</property>
                                                             <child>
                                                             <placeholder/>
                                                             </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
@@ -23963,6 +23960,18 @@ Concentric</property>
                                                             <property name="can_focus">False</property>
                                                             <property name="spacing">6</property>
                                                             <child>
+                                                            <widget class="GtkLabel" 
id="label_video_encoder_tests_will_be_filmed">
+                                                            <property name="can_focus">False</property>
+                                                            <property name="label" translatable="yes">Tests 
will be filmed</property>
+                                                            </widget>
+                                                            <packing>
+                                                            <property name="expand">False</property>
+                                                            <property name="fill">False</property>
+                                                            <property name="pack_type">end</property>
+                                                            <property name="position">0</property>
+                                                            </packing>
+                                                            </child>
+                                                            <child>
                                                             <widget class="GtkHBox" 
id="hbox_video_encoder_capturing">
                                                             <property name="can_focus">False</property>
                                                             <property name="spacing">4</property>
@@ -23999,18 +24008,6 @@ Concentric</property>
                                                             </packing>
                                                             </child>
                                                             <child>
-                                                            <widget class="GtkLabel" 
id="label_video_encoder_tests_will_be_filmed">
-                                                            <property name="can_focus">False</property>
-                                                            <property name="label" translatable="yes">Tests 
will be filmed</property>
-                                                            </widget>
-                                                            <packing>
-                                                            <property name="expand">False</property>
-                                                            <property name="fill">False</property>
-                                                            <property name="pack_type">end</property>
-                                                            <property name="position">0</property>
-                                                            </packing>
-                                                            </child>
-                                                            <child>
                                                             <widget class="GtkHBox" 
id="hbox_video_encoder_no_capturing">
                                                             <property name="visible">True</property>
                                                             <property name="can_focus">False</property>
@@ -30972,6 +30969,15 @@ then click this button.</property>
                                                             <child>
                                                             <placeholder/>
                                                             </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
+                                                            <child>
+                                                            <placeholder/>
+                                                            </child>
                                                             </widget>
                                                             <packing>
                                                             <property name="expand">False</property>
diff --git a/glade/force_sensor_elastic_bands.glade b/glade/force_sensor_elastic_bands.glade
new file mode 100644
index 00000000..d2271ac0
--- /dev/null
+++ b/glade/force_sensor_elastic_bands.glade
@@ -0,0 +1,438 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<glade-interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <!-- interface-naming-policy toplevel-contextual -->
+  <widget class="GtkWindow" id="force_sensor_elastic_bands">
+    <property name="width_request">550</property>
+    <property name="can_focus">False</property>
+    <property name="border_width">10</property>
+    <property name="title" translatable="yes">Chronojump</property>
+    <property name="modal">True</property>
+    <property name="type_hint">dialog</property>
+    <signal name="delete_event" handler="on_delete_event" swapped="no"/>
+    <child>
+      <widget class="GtkVBox" id="vbox_win">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="spacing">8</property>
+        <child>
+          <widget class="GtkLabel" id="label_header">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkVBox" id="vbox_bands">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">4</property>
+            <child>
+              <widget class="GtkScrolledWindow" id="scrolled_window_treeview">
+                <property name="height_request">150</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <widget class="GtkTreeView" id="treeview">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="headers_clickable">False</property>
+                  </widget>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">12</property>
+                <child>
+                  <widget class="GtkHBox" id="hbox3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="label1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Total stiffness:</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label_total_stiffness_value">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="xalign">0</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">N/m</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkHBox" id="hbox5">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">20</property>
+                    <child>
+                      <widget class="GtkButton" id="button_add_show">
+                        <property name="label" translatable="yes">Add new fixation</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <signal name="clicked" handler="on_button_add_show_clicked" swapped="no"/>
+                      </widget>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkButton" id="button_delete">
+                        <property name="label">Delete selected</property>
+                        <property name="visible">True</property>
+                        <property name="sensitive">False</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <signal name="clicked" handler="on_button_delete_clicked" swapped="no"/>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="pack_type">end</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkFrame" id="frame_add_edit">
+            <property name="visible">True</property>
+            <property name="sensitive">False</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0.30000001192092896</property>
+            <property name="shadow_type">out</property>
+            <child>
+              <widget class="GtkVBox" id="vbox1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="border_width">10</property>
+                <child>
+                  <widget class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">20</property>
+                    <child>
+                      <widget class="GtkTable" id="table_add_edit">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="border_width">10</property>
+                        <property name="n_rows">4</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">12</property>
+                        <property name="row_spacing">8</property>
+                        <child>
+                          <widget class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Brand</property>
+                          </widget>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label_entry2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label">Color</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label_entry1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label">Stiffness</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkHBox" id="hbox4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <widget class="GtkSpinButton" id="spin_stiffness">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">●</property>
+                                <property name="activates_default">True</property>
+                                <property name="primary_icon_activatable">False</property>
+                                <property name="secondary_icon_activatable">False</property>
+                                <property name="primary_icon_sensitive">True</property>
+                                <property name="secondary_icon_sensitive">True</property>
+                                <property name="adjustment">0 0 9999999 0.10000000000000001 10 0</property>
+                                <property name="climb_rate">1</property>
+                                <property name="digits">3</property>
+                                <property name="numeric">True</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <widget class="GtkLabel" id="label3">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label">N/m</property>
+                              </widget>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="entry_color">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">●</property>
+                            <property name="invisible_char_set">True</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                            <property name="primary_icon_sensitive">True</property>
+                            <property name="secondary_icon_sensitive">True</property>
+                            <signal name="changed" handler="on_entries_changed" swapped="no"/>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="entry_brand">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">●</property>
+                            <property name="invisible_char_set">True</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                            <property name="primary_icon_sensitive">True</property>
+                            <property name="secondary_icon_sensitive">True</property>
+                            <signal name="changed" handler="on_entries_changed" swapped="no"/>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="entry_comments">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">●</property>
+                            <property name="invisible_char_set">True</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                            <property name="primary_icon_sensitive">True</property>
+                            <property name="secondary_icon_sensitive">True</property>
+                            <signal name="changed" handler="on_entries_changed" swapped="no"/>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label_entry4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label">Comments</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <widget class="GtkVButtonBox" id="vbuttonbox1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="layout_style">spread</property>
+                        <child>
+                          <widget class="GtkButton" id="button_save">
+                            <property name="label">gtk-save</property>
+                            <property name="visible">True</property>
+                            <property name="sensitive">False</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="use_stock">True</property>
+                            <signal name="clicked" handler="on_button_save_clicked" swapped="no"/>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkLabel" id="label_edit_or_add">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </widget>
+              <packing>
+                <property name="type">label_item</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <widget class="GtkAlignment" id="alignment2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="top_padding">12</property>
+            <child>
+              <widget class="GtkHButtonBox" id="hbuttonbox1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <widget class="GtkButton" id="button_close">
+                    <property name="label">gtk-close</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="can_default">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="use_stock">True</property>
+                    <signal name="clicked" handler="on_button_close_clicked" swapped="no"/>
+                    <accelerator key="Escape" signal="clicked"/>
+                  </widget>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </widget>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 628e8366..a04af51e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -18,6 +18,7 @@ glade/error_window.glade
 glade/evaluator_window.glade
 glade/event_graph_configure.glade
 glade/execute_auto.glade
+glade/force_sensor_elastic_bands.glade
 glade/force_sensor_exercise.glade
 glade/generic_window.glade
 glade/jumps_runs_more.glade
@@ -71,6 +72,7 @@ src/gui/event.cs
 src/gui/eventExecute.cs
 src/gui/executeAuto.cs
 src/gui/forceSensorAnalyze.cs
+src/gui/forceSensorElasticBands.cs
 src/gui/forceSensorExercise.cs
 src/gui/forceSensor.cs
 src/gui/genericWindow.cs
diff --git a/src/Makefile.am b/src/Makefile.am
index d4928c1c..ff577e21 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,8 +25,9 @@ SOURCES = \
        gui/executeAuto.cs\
        gui/exhibition.cs\
        gui/forceSensor.cs\
-       gui/forceSensorExercise.cs\
        gui/forceSensorAnalyze.cs\
+       gui/forceSensorElasticBands.cs\
+       gui/forceSensorExercise.cs\
        gui/guiTests.cs\
        gui/jump.cs\
        gui/jumpsProfile.cs\
@@ -251,6 +252,7 @@ RESOURCES = \
        ../glade/event_graph_configure.glade \
        ../glade/execute_auto.glade \
        ../glade/generic_window.glade \
+       ../glade/force_sensor_elastic_bands.glade \
        ../glade/force_sensor_exercise.glade \
        ../glade/jump_type_add.glade \
        ../glade/jumps_runs_more.glade \
diff --git a/src/constants.cs b/src/constants.cs
index 27392413..995ef96e 100644
--- a/src/constants.cs
+++ b/src/constants.cs
@@ -159,6 +159,7 @@ public class Constants
        public const string TriggerTable = "trigger";
        public const string ForceSensorTable = "forceSensor";
        public const string ForceSensorExerciseTable = "forceSensorExercise";
+       public const string ForceSensorElasticBandTable = "forceSensorElasticBand";
        public const string ForceRFDTable = "forceRFD";
        public const string RunEncoderTable = "runEncoder";
        public const string RunEncoderExerciseTable = "runEncoderExercise";
diff --git a/src/forceSensor.cs b/src/forceSensor.cs
index f5ea56df..3297fd27 100644
--- a/src/forceSensor.cs
+++ b/src/forceSensor.cs
@@ -63,6 +63,8 @@ public class ForceSensor
        private string dateTime;
        private string comments;
        private string videoURL;
+       private double stiffness; //on not elastic capture will be -1 (just check if it is negative because 
it's a double and sometimes -1.0 comparisons don't work)
+       private string stiffnessString;
 
        private string exerciseName;
 
@@ -74,7 +76,8 @@ public class ForceSensor
 
        //constructor
        public ForceSensor(int uniqueID, int personID, int sessionID, int exerciseID, CaptureOptions 
captureOption, int angle,
-                       string laterality, string filename, string url, string dateTime, string comments, 
string videoURL, string exerciseName)
+                       string laterality, string filename, string url, string dateTime, string comments, 
string videoURL,
+                       double stiffness, string stiffnessString, string exerciseName)
        {
                this.uniqueID = uniqueID;
                this.personID = personID;
@@ -88,6 +91,8 @@ public class ForceSensor
                this.dateTime = dateTime;
                this.comments = comments;
                this.videoURL = videoURL;
+               this.stiffness = stiffness;
+               this.stiffnessString = stiffnessString;
 
                this.exerciseName = exerciseName;
        }
@@ -107,7 +112,7 @@ public class ForceSensor
                return
                        "(" + uniqueIDStr + ", " + personID + ", " + sessionID + ", " + exerciseID + ", \"" + 
captureOption.ToString() + "\", " +
                        angle + ", \"" + laterality + "\", \"" + filename + "\", \"" + url + "\", \"" + 
dateTime + "\", \"" +
-                       comments + "\", \"" + videoURL + "\")";
+                       comments + "\", \"" + videoURL + "\", " + Util.ConvertToPoint(stiffness) + ", \"" + 
stiffnessString + "\")";
        }
 
        public void UpdateSQL(bool dbconOpened)
@@ -129,6 +134,8 @@ public class ForceSensor
                        "\", dateTime = \"" + dateTime +
                        "\", comments = \"" + comments +
                        "\", videoURL = \"" + Util.MakeURLrelative(videoURL) +
+                       "\", stiffness = " + Util.ConvertToPoint(stiffness) +
+                       ", stiffnessString = \"" + stiffnessString +
                        "\" WHERE uniqueID = " + uniqueID;
        }
 
@@ -137,6 +144,7 @@ public class ForceSensor
                SqliteForceSensor.UpdateComments (dbconOpened, uniqueID, comments); //SQL not opened
        }
 
+       //for load window
        public string [] ToStringArray (int count)
        {
                int all = 8;
@@ -252,6 +260,16 @@ public class ForceSensor
                get { return videoURL; }
                set { videoURL = value; }
        }
+       public double Stiffness
+       {
+               get { return stiffness; }
+               //set { stiffness = value; }
+       }
+       public string StiffnessString
+       {
+               get { return stiffnessString; }
+               set { stiffnessString = value; }
+       }
        public string ExerciseName
        {
                get { return exerciseName; }
@@ -280,11 +298,18 @@ public class ForceSensorExercise
 
        public ForceSensorExercise()
        {
+               //default values
+               this.forceResultant = false;
+               this.elastic = false;
        }
 
        public ForceSensorExercise(string name)
        {
                this.name = name;
+
+               //default values
+               this.forceResultant = false;
+               this.elastic = false;
        }
 
        public ForceSensorExercise(int uniqueID, string name, int percentBodyWeight, string resistance, int 
angleDefault,
@@ -392,6 +417,133 @@ public class ForceSensorExercise
        {
                get { return elastic; }
        }
+
+       public bool ComputeAsElastic
+       {
+               get { return forceResultant && elastic; }
+       }
+}
+
+public class ForceSensorElasticBand
+{
+       private int uniqueID;
+       private bool active;
+       private string brand;
+       private string color;
+       private double stiffness;
+       private string comments;
+
+
+       // constructors ----
+
+       public ForceSensorElasticBand()
+       {
+               uniqueID = -1; //undefined
+       }
+
+       public ForceSensorElasticBand(int uniqueID, bool active, string brand, string color, double 
stiffness, string comments)
+       {
+               this.uniqueID = uniqueID;
+               this.active = active;
+               this.brand = brand;
+               this.color = color;
+               this.stiffness = stiffness;
+               this.comments = comments;
+       }
+
+       // public methods ----
+
+       /*
+       public void UpdateActive (bool active)
+       {
+               this.active = active;
+       }
+       */
+
+       public void Update(string brand, string color, double stiffness, string comments)
+       {
+               this.brand = brand;
+               this.color = color;
+               this.stiffness = stiffness;
+               this.comments = comments;
+       }
+
+       public string ToSQLInsertString()
+       {
+               string uniqueIDStr = "NULL";
+               if(uniqueID != -1)
+                       uniqueIDStr = uniqueID.ToString();
+
+               LogB.Information("stiffness is: " + stiffness.ToString());
+               return
+                       uniqueIDStr + ", " + Util.BoolToInt(active).ToString() +
+                       ", \"" + brand + "\", \"" + color + "\", " +
+                       Util.ConvertToPoint(stiffness) + ", \"" + comments + "\"";
+       }
+
+       public string [] ToStringArray ()
+       {
+               int all = 6;
+               string [] str = new String [all];
+               int i=0;
+               str[i++] = uniqueID.ToString();
+               str[i++] = active.ToString();
+               str[i++] = brand;
+               str[i++] = color;
+               str[i++] = stiffness.ToString();
+               str[i++] = comments;
+
+               return str;
+       }
+
+       //public static methods ----
+
+       //with one SqliteForceSensorElasticBand.SelectAll call, we can use then this two methods
+       public static double GetStiffnessOfActiveBands (List<ForceSensorElasticBand> list_fseb)
+       {
+               double sum = 0;
+               foreach(ForceSensorElasticBand fseb in list_fseb)
+                       sum += fseb.Stiffness;
+
+               return sum;
+       }
+       public static string GetIDsOfActiveBands (List<ForceSensorElasticBand> list_fseb)
+       {
+               string str = "";
+               string sep = "";
+               foreach(ForceSensorElasticBand fseb in list_fseb)
+               {
+                       str += sep + fseb.UniqueID.ToString();
+                       sep = ";";
+               }
+
+               return str;
+       }
+
+       public int UniqueID
+       {
+               get { return uniqueID; }
+       }
+       public bool Active
+       {
+               get { return active; }
+       }
+       public string Brand
+       {
+               get { return brand; }
+       }
+       public string Color
+       {
+               get { return color; }
+       }
+       public double Stiffness
+       {
+               get { return stiffness; }
+       }
+       public string Comments
+       {
+               get { return comments; }
+       }
 }
 
 /*
diff --git a/src/gui/forceSensor.cs b/src/gui/forceSensor.cs
index 2bce43b4..9dc73b3a 100644
--- a/src/gui/forceSensor.cs
+++ b/src/gui/forceSensor.cs
@@ -70,6 +70,7 @@ public partial class ChronoJumpWindow
        [Widget] Gtk.HBox hbox_force_capture_buttons;
        [Widget] Gtk.HBox hbox_combo_force_sensor_exercise;
        [Widget] Gtk.ComboBox combo_force_sensor_exercise;
+       [Widget] Gtk.Button button_force_sensor_stiffness;
        [Widget] Gtk.ComboBox combo_force_sensor_capture_options;
        [Widget] Gtk.RadioButton radio_force_sensor_laterality_both;
        [Widget] Gtk.RadioButton radio_force_sensor_laterality_l;
@@ -97,6 +98,7 @@ public partial class ChronoJumpWindow
        [Widget] Gtk.SpinButton spin_force_sensor_capture_feedback_range;
 
        ForceSensorExerciseWindow forceSensorExerciseWin;
+       ForceSensorElasticBandsWindow forceSensorElasticBandsWin;
 
        Gdk.Pixmap force_capture_pixmap = null;
 
@@ -354,11 +356,27 @@ public partial class ChronoJumpWindow
        //buttons: tare, calibrate, check version and capture (via on_button_execute_test_cicked) come here
        private void on_buttons_force_sensor_clicked(object o, EventArgs args)
        {
-               if(UtilGtk.ComboGetActive(combo_force_sensor_exercise) == "")
+               if (o == (object) button_execute_test)
                {
-                       new DialogMessage(Constants.MessageTypes.WARNING, Catalog.GetString("Need to 
create/select an exercise."));
-                       return;
+                       if(UtilGtk.ComboGetActive(combo_force_sensor_exercise) == "")
+                       {
+                               new DialogMessage(Constants.MessageTypes.WARNING, Catalog.GetString("Need to 
create/select an exercise."));
+                               return;
+                       }
+
+                       assignCurrentForceSensorExercise();
+
+                       if(currentForceSensorExercise.ComputeAsElastic)
+                       {
+                               List<ForceSensorElasticBand> list_fseb = 
SqliteForceSensorElasticBand.SelectAll(false, true); //not opened, onlyActive
+                               if(ForceSensorElasticBand.GetStiffnessOfActiveBands(list_fseb) == 0)
+                               {
+                                       new DialogMessage(Constants.MessageTypes.WARNING, 
Catalog.GetString("Need to configure fixture to know stiffness of this elastic exercise."));
+                                       return;
+                               }
+                       }
                }
+
                if(chronopicRegister.NumConnectedOfType(ChronopicRegisterPort.Types.ARDUINO_FORCE) == 0)
                {
                        event_execute_label_message.Text = forceSensorNotConnectedString;
@@ -390,7 +408,7 @@ public partial class ChronoJumpWindow
                        sensitiveLastTestButtons(false);
 
                        textview_force_sensor_capture_comment.Buffer.Text = "";
-                       assignCurrentForceSensorExercise();
+
                        if(currentForceSensorExercise.TareBeforeCapture)
                        {
                                forceSensorOtherMode = forceSensorOtherModeEnum.TARE_AND_CAPTURE_PRE;
@@ -1038,6 +1056,15 @@ LogB.Information(" fs C ");
                                {
                                        event_execute_label_message.Text = "Saved.";
 
+                                       double stiffness = -1;
+                                       string stiffnessString = "";
+                                       if(currentForceSensorExercise.ComputeAsElastic)
+                                       {
+                                               List<ForceSensorElasticBand> list_fseb = 
SqliteForceSensorElasticBand.SelectAll(false, true); //not opened, onlyActive
+                                               stiffness = 
ForceSensorElasticBand.GetStiffnessOfActiveBands(list_fseb);
+                                               stiffnessString = 
ForceSensorElasticBand.GetIDsOfActiveBands(list_fseb);
+                                       }
+
                                        currentForceSensor = new ForceSensor(-1, currentPerson.UniqueID, 
currentSession.UniqueID,
                                                        currentForceSensorExercise.UniqueID, 
getForceSensorCaptureOptions(),
                                                        ForceSensor.AngleUndefined, getLaterality(false),
@@ -1046,6 +1073,7 @@ LogB.Information(" fs C ");
                                                        UtilDate.ToFile(forceSensorTimeStartCapture),
                                                        "", //on capture cannot store comment (comment has to 
be written after),
                                                        "", //videoURL
+                                                       stiffness, stiffnessString,
                                                        currentForceSensorExercise.Name);
 
                                        currentForceSensor.UniqueID = currentForceSensor.InsertSQL(false);
@@ -2209,9 +2237,34 @@ LogB.Information(" fs R ");
                combo_force_sensor_exercise = ComboBox.NewText ();
                fillForceSensorExerciseCombo("");
 
-//             combo_force_sensor_exercise.Changed += new EventHandler 
(on_combo_force_sensor_exercise_changed);
+               combo_force_sensor_exercise.Changed += new EventHandler 
(on_combo_force_sensor_exercise_changed);
                hbox_combo_force_sensor_exercise.PackStart(combo_force_sensor_exercise, true, true, 0);
                hbox_combo_force_sensor_exercise.ShowAll();
+
+               //needed because the += EventHandler does not work on first fill of the combo
+               on_combo_force_sensor_exercise_changed (new object (), new EventArgs ());
+       }
+
+       private void on_combo_force_sensor_exercise_changed (object o, EventArgs args)
+       {
+               ForceSensorExercise fse = (ForceSensorExercise) SqliteForceSensorExercise.Select (
+                                false, getExerciseIDFromAnyCombo(
+                                       combo_force_sensor_exercise, forceSensorComboExercisesString, false), 
false )[0];
+
+               if(fse.ComputeAsElastic)
+               {
+                       List<ForceSensorElasticBand> list_fseb = 
SqliteForceSensorElasticBand.SelectAll(false, true); //not opened, onlyActive
+                       double stiffness = ForceSensorElasticBand.GetStiffnessOfActiveBands(list_fseb);
+
+                       if(stiffness == 0)
+                               button_force_sensor_stiffness.Label = Catalog.GetString("Configure fixation");
+                       else
+                               button_force_sensor_stiffness.Label = Catalog.GetString("Stiffness:") + " " + 
stiffness.ToString() + " N/m";
+                       button_force_sensor_stiffness.Visible = true;
+               } else {
+                       button_force_sensor_stiffness.Label = "0";
+                       button_force_sensor_stiffness.Visible = false;
+               }
        }
 
        private void fillForceSensorExerciseCombo(string name)
@@ -2341,6 +2394,33 @@ LogB.Information(" fs R ");
 
        // -------------------------------- end of exercise stuff --------------------
 
+       // -------------------------------- elastic band stuff -----------------------
+
+       /*
+       private string getForceSensorStiffnessString()
+       {
+               return "";
+       }
+       */
+
+       private void on_button_force_sensor_stiffness_clicked (object o, EventArgs args)
+       {
+               forceSensorElasticBandsWin = ForceSensorElasticBandsWindow.Show(
+                               Catalog.GetString("Elastic band selection"), "Elastic bands and other 
fixtures");
+               forceSensorElasticBandsWin.FakeButton_stiffness_changed.Clicked -= new 
EventHandler(on_elastic_bands_win_stiffness_changed);
+               forceSensorElasticBandsWin.FakeButton_stiffness_changed.Clicked += new 
EventHandler(on_elastic_bands_win_stiffness_changed);
+       }
+
+       private void on_elastic_bands_win_stiffness_changed(object o, EventArgs args)
+       {
+               button_force_sensor_stiffness.Label = Catalog.GetString("Stiffness:") + " " +
+                       forceSensorElasticBandsWin.TotalStiffness + " N/m";
+       }
+
+
+       // -------------------------------- end of elastic band stuff ----------------
+
+
        // -------------------------------- options, laterality and comment stuff -------------
 
        //note: Standard capture, Absolute values, Inverted values are:
diff --git a/src/gui/forceSensorElasticBands.cs b/src/gui/forceSensorElasticBands.cs
new file mode 100644
index 00000000..d18dc8a7
--- /dev/null
+++ b/src/gui/forceSensorElasticBands.cs
@@ -0,0 +1,423 @@
+/*
+ * This file is part of ChronoJump
+ *
+ * ChronoJump is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or   
+ *    (at your option) any later version.
+ *    
+ * ChronoJump is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ *    GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright (C) 2004-2019   Xavier de Blas <xaviblas gmail com> 
+ */
+
+using System;
+using Gdk;
+using Gtk;
+using Glade;
+using GLib; //for Value
+using System.Collections.Generic; //List<T>
+using Mono.Unix;
+
+public class ForceSensorElasticBandsWindow
+{
+       [Widget] Gtk.Window force_sensor_elastic_bands;
+       [Widget] Gtk.Label label_header;
+       //[Widget] Gtk.VBox vbox_bands;
+       //[Widget] Gtk.ScrolledWindow scrolled_window_treeview;
+       [Widget] Gtk.TreeView treeview;
+       [Widget] Gtk.Button button_save;
+       [Widget] Gtk.Button button_delete;
+       [Widget] Gtk.Button button_close;
+       [Widget] Gtk.Label label_total_stiffness_value;
+       [Widget] Gtk.Frame frame_add_edit;
+       [Widget] Gtk.Label label_edit_or_add;
+       [Widget] Gtk.Entry entry_brand;
+       [Widget] Gtk.Entry entry_color;
+       [Widget] Gtk.Entry entry_comments;
+       [Widget] Gtk.SpinButton spin_stiffness;
+
+       [Widget] Gtk.Button fakeButton_stiffness_changed;
+
+       static ForceSensorElasticBandsWindow ForceSensorElasticBandsWindowBox;
+       
+       private TreeStore store;
+
+       //used to read data, see if it's ok, and print an error message.
+       //if all is ok, destroy it with HideAndNull()
+       //public bool HideOnAccept;
+       
+       //used when we don't need to read data, 
+       //and we want to ensure next window will be created at needed size
+       //public bool DestroyOnAccept;
+       public int TreeviewSelectedUniqueID;
+
+       public int uniqueID;                    //used on encoder & forceSensor edit exercise
+       private int stiffnessColumn;
+
+       private enum modes { EDITING, ADDING } 
+       private modes currentMode;
+
+       public ForceSensorElasticBandsWindow ()
+       {
+               Glade.XML gladeXML;
+               gladeXML = Glade.XML.FromAssembly (Util.GetGladePath() + "force_sensor_elastic_bands.glade", 
"force_sensor_elastic_bands", "chronojump");
+               gladeXML.Autoconnect(this);
+       
+               //HideOnAccept = true;
+               //DestroyOnAccept = false;
+               fakeButton_stiffness_changed = new Gtk.Button();
+       }
+
+       //for an array of widgets
+       static public ForceSensorElasticBandsWindow Show (string title, string textHeader)
+       {
+               if (ForceSensorElasticBandsWindowBox == null) {
+                       ForceSensorElasticBandsWindowBox = new ForceSensorElasticBandsWindow();
+               } else {
+                       ForceSensorElasticBandsWindowBox.setTitle(title);
+                       ForceSensorElasticBandsWindowBox.label_header.Text = textHeader;
+               }
+
+               ForceSensorElasticBandsWindowBox.initializeGui(title, textHeader);
+               ForceSensorElasticBandsWindowBox.frame_add_edit.Sensitive = false;
+               ForceSensorElasticBandsWindowBox.force_sensor_elastic_bands.Show ();
+               
+               return ForceSensorElasticBandsWindowBox;
+       }
+
+       private void setTitle(string title)
+       {
+               if(title != "")
+                       force_sensor_elastic_bands.Title = "Chronojump - " + title;
+       }
+
+       private void initializeGui(string title, string textHeader)
+       {
+               setTitle(title);
+               label_header.Text = textHeader;
+
+               //put an icon to window
+               UtilGtk.IconWindow(force_sensor_elastic_bands);
+       
+               setTreeview();
+       }
+
+       private ForceSensorElasticBand getSelectedForceSensorElasticBand()
+       {
+               ForceSensorElasticBand fseb = new ForceSensorElasticBand();
+
+               TreeIter iter = new TreeIter();
+               TreeModel myModel = treeview.Model;
+               if (treeview.Selection.GetSelected (out myModel, out iter))
+               {
+                       fseb = getForceSensorElasticBand(iter);
+               }
+
+               return fseb;
+       }
+                       
+       private ForceSensorElasticBand getForceSensorElasticBand(TreeIter iter)
+       {
+               return new ForceSensorElasticBand(
+                               Convert.ToInt32(store.GetValue (iter, 0)),
+                               (bool) store.GetValue (iter, 1),
+                               store.GetValue (iter, 2).ToString(), //brand
+                               store.GetValue (iter, 3).ToString(), //color
+                               Convert.ToDouble(store.GetValue (iter, stiffnessColumn)),
+                               store.GetValue (iter, 5).ToString() //comments
+                               );
+       }
+
+       private void empty_frame()
+       {
+               entry_brand.Text = "";
+               entry_color.Text = "";
+               entry_comments.Text = "";
+               spin_stiffness.Value = 0;
+       }
+       private void fill_frame(ForceSensorElasticBand fseb)
+       {
+               entry_brand.Text = fseb.Brand;
+               entry_color.Text = fseb.Color;
+               entry_comments.Text = fseb.Comments;
+               spin_stiffness.Value = fseb.Stiffness;
+       }
+
+       //data is an ArrayList of strings[], each string [] is a row, each of its strings is a column
+       private void setTreeview() 
+       {
+               string [] columnsString = new string [] {
+                       //Catalog.GetString("ID"),
+                       "ID",
+                       Catalog.GetString("Selected"),  //checkboxes
+                       Catalog.GetString("Brand"), Catalog.GetString("Color"),
+                               Catalog.GetString("Stiffness"), Catalog.GetString("Comments") 
+               };
+               stiffnessColumn = 4;
+
+               store = getStore(columnsString.Length); 
+               treeview.Model = store;
+               prepareHeaders(columnsString);
+               treeview.HeadersClickable = false;
+               fillTreeview();
+
+               /*
+               LogB.Debug("aaaaaaaaaaaaaaaa1");        
+               foreach (string [] line in data) {
+                       store.AppendValues (line);
+                       //Log.WriteLine(Util.StringArrayToString(line,"\n"));
+               }
+               LogB.Debug("aaaaaaaaaaaaaaaa2");        
+               */
+               treeview.CursorChanged += on_treeview_cursor_changed;
+       }
+
+       private void fillTreeview()
+       {
+               List<ForceSensorElasticBand> list_fseb = SqliteForceSensorElasticBand.SelectAll(false, false);
+               foreach (ForceSensorElasticBand fseb in list_fseb) {
+                       store.AppendValues (fseb.ToStringArray());
+               }
+
+               markActiveRows(list_fseb);
+               stiffnessTotalUpdate();
+       }
+
+       private void markActiveRows(List<ForceSensorElasticBand> list_fseb) 
+       {
+               int count = 0;
+               Gtk.TreeIter iter;
+               bool okIter = store.GetIterFirst(out iter);
+               if(okIter) {
+                       do {
+                               foreach(ForceSensorElasticBand fseb in list_fseb)
+                                       if(fseb.Active && fseb.UniqueID == Convert.ToInt32(store.GetValue 
(iter, 0)))
+                                               store.SetValue (iter, 1, true);
+                       } while ( store.IterNext(ref iter) );
+               }
+       }
+       
+       private TreeStore getStore (int columns)
+       {
+               //prepares the TreeStore for required columns
+               Type [] types = new Type [columns];
+
+               for (int i=0; i < columns; i++) {
+                       if(i == 1)
+                               types[1] = typeof (bool);
+                       else
+                               types[i] = typeof (string);
+               }
+               TreeStore myStore = new TreeStore(types);
+               return myStore;
+       }
+       
+       private void prepareHeaders(string [] columnsString)
+       {
+               treeview = UtilGtk.RemoveColumns(treeview);
+               treeview.HeadersVisible=true;
+               int i=0;
+               bool visible = false;
+               foreach(string myCol in columnsString) {
+                       if(i == 1)
+                               createCheckboxes(treeview, columnsString[1]);
+                       else
+                               UtilGtk.CreateCols(treeview, store, myCol, i, visible);
+//                     if(i == 1)      //first columns: ID, is hidden
+//                             store.SetSortFunc (0, UtilGtk.IdColumnCompare);
+                       visible = true;
+                       i++;
+               }
+       }
+       
+       private void on_treeview_cursor_changed (object o, EventArgs args) 
+       {
+               TreeIter iter = new TreeIter();
+               TreeModel myModel = treeview.Model;
+               if (treeview.Selection.GetSelected (out myModel, out iter))
+               {
+                       currentMode = modes.EDITING;
+                       button_delete.Sensitive = true;
+                       label_edit_or_add.Text = Catalog.GetString("Edit selected fixation");
+                       ForceSensorElasticBand fseb = getSelectedForceSensorElasticBand();
+                       fill_frame(fseb);
+                       frame_add_edit.Sensitive = true;
+               }
+       }
+
+       private void on_button_add_show_clicked (object o, EventArgs args)
+       {
+               currentMode = modes.ADDING;
+               empty_frame(); //empty all
+               label_edit_or_add.Text = Catalog.GetString("Add fixation");
+               frame_add_edit.Sensitive = true;
+       }
+       private void on_button_save_clicked (object o, EventArgs args)
+       {
+               //1) insert on SQL
+               if(currentMode == modes.ADDING)
+               {
+                       //create fseb from frame_add_edit
+                       ForceSensorElasticBand fseb = new ForceSensorElasticBand(-1, false, entry_brand.Text, 
entry_color.Text, spin_stiffness.Value, entry_comments.Text);
+
+                       //insert on SQL
+                       SqliteForceSensorElasticBand.Insert(false, fseb);
+
+                       //unsensitivize frame_add_edit
+                       frame_add_edit.Sensitive = false;
+               }
+               else //(currentMode == modes.EDITING)
+               {
+                       //get selected just to know uniqueID and if it is active
+                       ForceSensorElasticBand fseb = getSelectedForceSensorElasticBand();
+
+                       //change the params on frame_add_edit
+                       fseb.Update(entry_brand.Text, entry_color.Text, spin_stiffness.Value, 
entry_comments.Text);
+
+                       //update SQL
+                       SqliteForceSensorElasticBand.Update(false, fseb);
+               }
+               
+               //vbox_bands.Sensitive = true;
+
+               //2) regenerate treeview
+               UtilGtk.RemoveColumns(treeview);
+               setTreeview();
+       }
+
+       private void on_button_delete_clicked (object o, EventArgs args)
+       {
+               //1) get selected just to know uniqueID and if it is active
+               ForceSensorElasticBand fseb = getSelectedForceSensorElasticBand();
+
+               //2) delete on SQL
+               SqliteForceSensorElasticBand.Delete(false, fseb.UniqueID);
+
+               //3) regenerate treeview
+               UtilGtk.RemoveColumns(treeview);
+               setTreeview();
+
+               //4) fix the rest of the gui
+               empty_frame(); //empty all
+               frame_add_edit.Sensitive = false;
+               button_delete.Sensitive = false;
+       }
+
+       private void createCheckboxes(TreeView tv, string headerName) 
+       {
+               CellRendererToggle crt = new CellRendererToggle();
+               crt.Visible = true;
+               crt.Activatable = true;
+               crt.Active = true;
+               crt.Toggled += ItemToggled;
+
+               TreeViewColumn column = new TreeViewColumn (headerName, crt, "active", 1);
+               column.Clickable = true;
+               tv.AppendColumn (column);
+               
+       }
+
+       private void ItemToggled(object o, ToggledArgs args)
+       {
+               int column = 1;
+               TreeIter iter;
+               if (store.GetIter (out iter, new TreePath(args.Path))) 
+               {
+                       //Log.WriteLine(args.Path);
+                       bool val = (bool) store.GetValue (iter, column);
+                       //Log.WriteLine (string.Format("toggled {0} with value {1}", args.Path, !val));
+
+                       store.SetValue (iter, column, !val);
+
+                       ForceSensorElasticBand fseb = getForceSensorElasticBand(iter);
+                       SqliteForceSensorElasticBand.Update(false, fseb);
+               }
+
+               stiffnessTotalUpdate();
+       }
+
+       private void stiffnessTotalUpdate()
+       {
+               double sum = 0;
+               Gtk.TreeIter iter;
+               bool okIter = store.GetIterFirst(out iter);
+               if(okIter) {
+                       do {
+                               if((bool) store.GetValue (iter, 1))
+                                       sum += Convert.ToDouble(store.GetValue (iter, stiffnessColumn));
+                       } while ( store.IterNext(ref iter) );
+               }
+               label_total_stiffness_value.Text = sum.ToString();
+               fakeButton_stiffness_changed.Click();
+       }
+
+       private void on_entries_changed (object o, EventArgs args)
+       {
+               Gtk.Entry entry = o as Gtk.Entry;
+               if (o == null)
+                       return;
+
+               entry.Text = Util.MakeValidSQL(entry.Text);
+
+               button_save.Sensitive = ( entry_brand.Text != "" || entry_color.Text != "" || 
entry_comments.Text != "" );
+       }
+
+       private void on_button_close_clicked (object o, EventArgs args)
+       {
+               ForceSensorElasticBandsWindowBox.force_sensor_elastic_bands.Hide();
+               ForceSensorElasticBandsWindowBox = null;
+       }
+
+       private void on_delete_event (object o, DeleteEventArgs args)
+       {
+               LogB.Information("calling on_delete_event");
+
+               //args.RetVal = true;
+                       
+               ForceSensorElasticBandsWindowBox.force_sensor_elastic_bands.Hide();
+               ForceSensorElasticBandsWindowBox = null;
+       }
+
+
+       /*      
+       //when ! HideOnAccept, use this to close window
+       //also is better to call it always tat is closed clicking on accept (after data has been readed)
+       public void HideAndNull()
+       {
+               //this check is extra safety if there are extra EventHandlers opened with +=
+               if(ForceSensorElasticBandsWindowBox.force_sensor_elastic_bands != null)
+                       ForceSensorElasticBandsWindowBox.force_sensor_elastic_bands.Hide();
+
+               ForceSensorElasticBandsWindowBox = null;
+       }
+       */
+
+       /*      
+       public Button Button_accept {
+               set { button_accept = value; }
+               get { return button_accept; }
+       }
+       */
+
+       public string TotalStiffness
+       {
+               get { return label_total_stiffness_value.Text; }
+       }
+
+       public Button FakeButton_stiffness_changed
+       {
+               get { return fakeButton_stiffness_changed; }
+       }
+
+       ~ForceSensorElasticBandsWindow() {}
+       
+}
+
diff --git a/src/sqlite/forceSensor.cs b/src/sqlite/forceSensor.cs
index ce7aa563..90f22024 100644
--- a/src/sqlite/forceSensor.cs
+++ b/src/sqlite/forceSensor.cs
@@ -55,7 +55,9 @@ class SqliteForceSensor : Sqlite
                        "url TEXT, " +          //URL of data files. stored as relative
                        "datetime TEXT, " +     //2019-07-11_15-01-44
                        "comments TEXT, " +
-                       "videoURL TEXT)";       //URL of video of signals. stored as relative
+                       "videoURL TEXT, " +     //URL of video of signals. stored as relative
+                       "stiffness FLOAT DEFAULT -1, " +        //this is the important, next one is needed 
for recalculate, but note that some bands can have changed or being deleted
+                       "stiffnessString TEXT)"; //uniqueID of ElasticBand separated by ';' or empty if 
exerciseID ! elastic
                LogB.SQL(dbcmd.CommandText.ToString());
                dbcmd.ExecuteNonQuery();
        }
@@ -66,10 +68,10 @@ class SqliteForceSensor : Sqlite
 
                LogB.Information("goint to insert: " + insertString);
                dbcmd.CommandText = "INSERT INTO " + table +
-                               " (uniqueID, personID, sessionID, exerciseID, captureOption, angle, 
laterality, filename, url, dateTime, comments, videoURL)" +
+                               " (uniqueID, personID, sessionID, exerciseID, captureOption, angle, 
laterality, filename, url, dateTime, comments, videoURL, stiffness, stiffnessString)" +
                                " VALUES " + insertString;
                LogB.SQL(dbcmd.CommandText.ToString());
-               dbcmd.ExecuteNonQuery(); //TODO uncomment this again
+               dbcmd.ExecuteNonQuery();
 
                string myString = @"select last_insert_rowid()";
                dbcmd.CommandText = myString;
@@ -176,7 +178,10 @@ class SqliteForceSensor : Sqlite
                                        reader[9].ToString(),                   //datetime
                                        reader[10].ToString(),                  //comments
                                        reader[11].ToString(),                  //videoURL
-                                       reader[12].ToString()                   //exerciseName
+                                       Convert.ToDouble(Util.ChangeDecimalSeparator(
+                                                       reader[12].ToString())), //stiffness
+                                       reader[13].ToString(),                  //stiffnessString
+                                       reader[14].ToString()                   //exerciseName
                                        );
                        array.Add(fs);
                }
@@ -395,7 +400,9 @@ class SqliteForceSensor : Sqlite
                                                ForceSensor.AngleUndefined, lat,
                                                myFilename,
                                                
Util.MakeURLrelative(Util.GetForceSensorSessionDir(Convert.ToInt32(session.Name))),
-                                               parsedDate, fslt.Comment, "", exerciseName);
+                                               parsedDate, fslt.Comment,
+                                               "", -1, "", //videoURL, stiffness, stiffnessString
+                                               exerciseName);
                                forceSensor.InsertSQL(true);
                        }
                }
@@ -594,6 +601,180 @@ class SqliteForceSensorExercise : Sqlite
        }
 }
 
+class SqliteForceSensorElasticBand : Sqlite
+{
+       private static string table = Constants.ForceSensorElasticBandTable;
+
+       public SqliteForceSensorElasticBand() {
+       }
+
+       ~SqliteForceSensorElasticBand() {}
+
+       /*
+        * create and initialize tables
+        */
+
+       /*
+        * note we use AUTOINCREMENT here
+        * because rubber bands can be deleted
+        * and deleting them will not delete the forceSensor table rows
+        * but if we add a new rubber band, we want that it has a different ID than previously deleted.
+        * This is different from the rest of the sofware because:
+        * on the rest of the software, we care to delete the rows on related tables
+        *
+        * Note AUTOINCREMENT should only be used on special situations:
+        * https://www.sqlitetutorial.net/sqlite-autoincrement/
+        */
+       protected internal static void createTable()
+       {
+               dbcmd.CommandText =
+                       "CREATE TABLE " + table + " ( " +
+                       "uniqueID INTEGER PRIMARY KEY AUTOINCREMENT, " +
+                       "active INT, " +        //bool
+                       "brand TEXT, " +
+                       "color TEXT, " +
+                       "stiffness FLOAT, " +
+                       "comments TEXT)";
+               LogB.SQL(dbcmd.CommandText.ToString());
+               dbcmd.ExecuteNonQuery();
+       }
+
+       public static int Insert (bool dbconOpened, ForceSensorElasticBand eb)
+       {
+               if(! dbconOpened)
+                       Sqlite.Open();
+
+               dbcmd.CommandText = "INSERT INTO " + table +
+                               " (uniqueID, active, brand, color, stiffness, comments)" +
+                               " VALUES (" + eb.ToSQLInsertString() + ")";
+               LogB.SQL(dbcmd.CommandText.ToString());
+               dbcmd.ExecuteNonQuery();
+
+               string myString = @"select last_insert_rowid()";
+               dbcmd.CommandText = myString;
+               int myLast = Convert.ToInt32(dbcmd.ExecuteScalar()); // Need to type-cast since 
`ExecuteScalar` returns an object.
+
+               if(! dbconOpened)
+                       Sqlite.Close();
+
+               return myLast;
+       }
+
+       public static void Update (bool dbconOpened, ForceSensorElasticBand eb)
+       {
+               if(! dbconOpened)
+                       Sqlite.Open();
+
+               dbcmd.CommandText = "UPDATE " + table + " SET " +
+                       " active = " + Util.BoolToInt(eb.Active).ToString() +
+                       ", brand = \"" + eb.Brand +
+                       "\", color = \"" + eb.Color +
+                       "\", stiffness = " + Util.ConvertToPoint(eb.Stiffness) +
+                       ", comments = \"" + eb.Comments +
+                       "\" WHERE uniqueID = " + eb.UniqueID;
+
+               LogB.SQL(dbcmd.CommandText.ToString());
+               dbcmd.ExecuteNonQuery();
+
+               if(! dbconOpened)
+                       Sqlite.Close();
+       }
+
+       public static void Delete (bool dbconOpened, int uniqueID)
+       {
+               openIfNeeded(dbconOpened);
+
+               dbcmd.CommandText = "DELETE FROM " + table + " WHERE uniqueID = " + uniqueID;
+
+               LogB.SQL(dbcmd.CommandText.ToString());
+               dbcmd.ExecuteNonQuery();
+
+               closeIfNeeded(dbconOpened);
+       }
+
+       public static List<ForceSensorElasticBand> SelectAll (bool dbconOpened, bool onlyActive)
+       {
+               openIfNeeded(dbconOpened);
+
+               dbcmd.CommandText = "SELECT * FROM " + table;
+               if(onlyActive)
+                       dbcmd.CommandText += " WHERE active = 1";
+
+               LogB.SQL(dbcmd.CommandText.ToString());
+
+               dbcmd.ExecuteNonQuery();
+
+               SqliteDataReader reader = dbcmd.ExecuteReader();
+
+               List<ForceSensorElasticBand> list_fseb = new List<ForceSensorElasticBand>();
+
+               while(reader.Read()) {
+                       ForceSensorElasticBand fseb = new ForceSensorElasticBand (
+                                       Convert.ToInt32(reader[0].ToString()),  //uniqueID
+                                       Util.IntToBool(Convert.ToInt32(reader[1])),     //active
+                                       reader[2].ToString(),                   //brand
+                                       reader[3].ToString(),                   //color
+                                       Convert.ToDouble(Util.ChangeDecimalSeparator(reader[4].ToString())),
+                                       reader[5].ToString()                    //comments
+                                       );
+                       list_fseb.Add(fseb);
+               }
+
+               reader.Close();
+               closeIfNeeded(dbconOpened);
+
+               return list_fseb;
+       }
+
+       //stiffnessString is a parameter of forceSensor table
+       public static double GetStiffnessOfACapture (bool dbconOpened, string stiffnessString)
+       {
+               //return 0 if empty
+               if(stiffnessString == "")
+                       return 0;
+
+               //return 0 if there is only one value and is not a integer
+               string [] strFull = stiffnessString.Split(new char[] {';'});
+               if(strFull.Length == 1) //there is just one value (there are no ';')
+                       if(! Util.IsNumber(strFull[0], false))
+                               return 0;
+
+               //return 0 if there is any of the values is not an integer
+               foreach(string s in strFull)
+                       if(! Util.IsNumber(s, false))
+                               return 0;
+
+               return getStiffnessOfACaptureDo (dbconOpened, strFull);
+       }
+       private static double getStiffnessOfACaptureDo (bool dbconOpened, string [] stiffnessStrArray)
+       {
+               openIfNeeded(dbconOpened);
+
+               /*
+                * instead of doing a select for each of the members of stiffnessArray (slow),
+                * do a select of all and the filter what is not on the array
+                */
+
+               dbcmd.CommandText = "SELECT uniqueID, stiffness FROM " + table;
+               LogB.SQL(dbcmd.CommandText.ToString());
+               dbcmd.ExecuteNonQuery();
+
+               SqliteDataReader reader = dbcmd.ExecuteReader();
+
+               double sum = 0;
+               while(reader.Read())
+               {
+                       string id = reader[0].ToString();
+                       if(Util.FoundInStringArray(stiffnessStrArray, id))
+                               sum += Convert.ToDouble(Util.ChangeDecimalSeparator(reader[1].ToString()));
+               }
+
+               reader.Close();
+               closeIfNeeded(dbconOpened);
+
+               return sum;
+       }
+}
 
 class SqliteForceSensorRFD : Sqlite
 {
diff --git a/src/sqlite/main.cs b/src/sqlite/main.cs
index abad8252..21b2b75d 100644
--- a/src/sqlite/main.cs
+++ b/src/sqlite/main.cs
@@ -129,7 +129,7 @@ class Sqlite
        /*
         * Important, change this if there's any update to database
         */
-       static string lastChronojumpDatabaseVersion = "1.74";
+       static string lastChronojumpDatabaseVersion = "1.76";
 
        public Sqlite() {
        }
@@ -2507,6 +2507,30 @@ class Sqlite
 
                                currentVersion = updateVersion("1.74");
                        }
+                       if(currentVersion == "1.74")
+                       {
+                               LogB.SQL("Created table ForceSensorElasticBand");
+
+                               SqliteForceSensorElasticBand.createTable();
+
+                               currentVersion = updateVersion("1.75");
+                       }
+                       if(currentVersion == "1.75")
+                       {
+                               LogB.SQL("Doing alter table forceSensor adding stiffness/stiffnessString");
+                               try {
+                                       //sqlite does not have drop column
+                                       executeSQL("ALTER TABLE " + Constants.ForceSensorTable + " ADD COLUMN 
stiffness FLOAT DEFAULT -1;");
+                                       executeSQL("ALTER TABLE " + Constants.ForceSensorTable + " ADD COLUMN 
stiffnessString TEXT;");
+
+                               } catch {
+                                       LogB.SQL("Catched. forceSensor stiffness/stiffnessString already 
exists.");
+
+                               }
+                               LogB.SQL("Done!");
+
+                               currentVersion = updateVersion("1.76");
+                       }
 
 
                        // --- add more updates here
@@ -2685,6 +2709,7 @@ class Sqlite
                SqliteForceSensorExercise.createTable();
                SqliteForceSensorRFD.createTable();
                SqliteForceSensorRFD.InsertDefaultValues(true);
+               SqliteForceSensorElasticBand.createTable();
 
                //runEncoder
                SqliteRunEncoder.createTable();
@@ -2700,7 +2725,9 @@ class Sqlite
                SqliteJson.createTableUploadExhibitionTestTemp ();
 
                //changes [from - to - desc]
-               //1.73 - 1.74 Converted DB to 1.74 ALTER TABLE Constants.ForceSensorExerciseTable ADD COLUMN 
forceResultant, clastic INT
+               //1.75 - 1.76 Converted DB to 1.76 ALTER TABLE " + Constants.ForceSensorTable + " ADD COLUMN 
(stiffness float, stiffnessString string)
+               //1.74 - 1.75 Converted DB to 1.75 Created table ForceSensorElasticBand
+               //1.73 - 1.74 Converted DB to 1.74 ALTER TABLE Constants.ForceSensorExerciseTable ADD COLUMN 
forceResultant, elastic
                //1.72 - 1.73 Converted DB to 1.73 Inserted into preferences: jumpsDjGraphHeights
                //1.71 - 1.72 Converted DB to 1.72 Inserted into preferences: forceSensorCaptureWidthSeconds, 
forceSensorCaptureScroll
                //1.70 - 1.71 Converted DB to 1.71 Imported run encoder text files into SQL


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]