Logo Search packages:      
Sourcecode: v-sim version File versions  Download package

panelSurfaces.c

/*   EXTRAITS DE LA LICENCE
      Copyright CEA, contributeurs : Luc BILLARD, Damien
      CALISTE, Olivier D'Astier, laboratoire L_Sim, (2001-2005)
  
      Adresses mèl :
      BILLARD, non joignable par mèl ;
      CALISTE, damien P caliste AT cea P fr.
      D'ASTIER, dastier AT iie P cnam P fr.

      Ce logiciel est un programme informatique servant à visualiser des
      structures atomiques dans un rendu pseudo-3D. 

      Ce logiciel est régi par la licence CeCILL soumise au droit français et
      respectant les principes de diffusion des logiciels libres. Vous pouvez
      utiliser, modifier et/ou redistribuer ce programme sous les conditions
      de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA 
      sur le site "http://www.cecill.info".

      Le fait que vous puissiez accéder à cet en-tête signifie que vous avez 
      pris connaissance de la licence CeCILL, et que vous en avez accepté les
      termes (cf. le fichier Documentation/licence.fr.txt fourni avec ce logiciel).
*/

/*   LICENCE SUM UP
      Copyright CEA, contributors : Luc BILLARD and Damien
      CALISTE and Olivier D'Astier, laboratoire L_Sim, (2001-2005)

      E-mail addresses :
      BILLARD, not reachable any more ;
      CALISTE, damien P caliste AT cea P fr.
      D'ASTIER, dastier AT iie P cnam P fr.

      This software is a computer program whose purpose is to visualize atomic
      configurations in 3D.

      This software is governed by the CeCILL  license under French law and
      abiding by the rules of distribution of free software.  You can  use, 
      modify and/ or redistribute the software under the terms of the CeCILL
      license as circulated by CEA, CNRS and INRIA at the following URL
      "http://www.cecill.info". 

      The fact that you are presently reading this means that you have had
      knowledge of the CeCILL license and that you accept its terms. You can
      find a copy of this licence shipped with this software at Documentation/licence.en.txt.
*/
#include "panelSurfaces.h"
#include "panelSurfacesTools.h"

#include <visu_object.h>
#include <support.h>
#include <gtk_main.h>
#include <opengl.h>
#include <visu_extension.h>
#include <openGLFunctions/objectList.h>

#include <extraFunctions/surfaces.h>
#include <extraFunctions/scalarFields.h>
#include <extraFunctions/pot2surf.h>
#include <extraGtkFunctions/gtk_toolPanelWidget.h>
#include <extraGtkFunctions/gtk_colorComboBoxWidget.h>

/* Global variables. */
static int identifier_isosurfaces;
static GtkWidget *isosurfaces_gtk_vbox;
static OpenGLExtension *extension_isosurfaces;
static GtkTreeStore *isosurfaces_data_list;
static GtkListStore *fields_data_list;
static GtkWidget *isosurfaces_tree_model;
static SurfacesOrder *surfaceOrder;
static gulong moveSignal;

enum
  {
    SURFACE_TYPE_FILE_DENPOT, /* The entry is a potential or a density file. */
    SURFACE_TYPE_FILE_SURF,   /* The entry is a surfaces file. */
    SURFACE_TYPE_SURF         /* The entry is a surface. */
  };

enum
  {
    NUMBER_COLUMN,
    SHOW_COLUMN,
    USE_SHOW_COLUMN,
    NAME_COLUMN,
    EDIT_NAME_COLUMN,
    COLOR_NAME_COLUMN,
    TYPE_COLUMN,
    POTENTIAL_COLUMN,
    USE_POTENTIAL_COLUMN,
    EDIT_POTENTIAL_COLUMN,
    COLOR_POTENTIAL_COLUMN,
    PIXBUF_COLUMN,
    DATA_SURF_COLUMN,
    DATA_FIELD_COLUMN,
    FILENAME_COLUMN,
    N_COLUMNS
  };

gboolean gtk_tree_model_iter_previous(GtkTreeModel *tree_model, GtkTreeIter *iter);

void isosurfaces_rebuild_gl_list_in_order(VisuData *dataObj, OpenGLView *view, gpointer data);
void isosurfaces_rebuild_gl_list(VisuData *dataObj);
static gboolean getSelectedRow(GtkTreeIter *iter);
static void isosurfaces_update_data_list(Surfaces *surf, GtkTreeIter *iter);
static void showHideSurfaces(GtkTreeIter *iter, gboolean recurse, gpointer value);
void isosurfaces_rebuild_gl_list_and_redraw();
static gboolean isosurfaces_rebuild_gl_list_in_order_and_redraw(gpointer data);
static void changeSurfaceColor(GtkTreeIter *iter, gboolean recurse, gpointer color);
static gboolean panel_isosurfaces_add(GtkTreeIter *iter, gboolean setValue,
                              float value, gchar *name);
static gboolean panel_isosurfaces_remove(GtkTreeIter *iter);
static void isosurfaces_remove_field(GtkListStore *list, ScalarField *field);
static void handleAutoReorder(GtkToggleButton *toggle, VisuData *dataObj);
static void isosurfaces_open_file_chooser();
static void changeTreeViewElement(const gchar *nameRef, int columnId, gpointer value);

/* Callbacks. */
static void onTreeSelectionChanged(GtkTreeSelection *tree, gpointer data);
static void onAddButtonClicked(GtkButton *button, gpointer data);
static void onRemoveButtonClicked(GtkButton *button, gpointer data);
static void onReorderToggled(GtkToggleButton *toggle, gpointer data);
static void onNameEdited(GtkCellRendererText *cellrenderertext,
                   gchar *path, gchar *text, gpointer user_data);
static void onPotentialValueEdited(GtkCellRendererText *cellrenderertext,
                           gchar *path, gchar *text, gpointer user_data);
static void onDataReady(GObject *visu, VisuData *dataObj, gpointer data);
static void onShowHideAllButton(GtkButton *button, gpointer visibility);
static void onRangesChanged(ColorComboBox *colorComboBox, guint valId, gpointer data);
static void onObserveMovement(VisuData *dataObj, gboolean start, gpointer data);
static void onEditPropertiesClicked(GtkButton *button, gpointer data);
static void onRowClicked(GtkTreeView *tree_view, GtkTreePath *path,
                         GtkTreeViewColumn *column, gpointer user_data);
static gboolean onTreeViewClicked(GtkWidget *widget, GdkEventButton *event, gpointer user_data);

/* Global widgets. */
static GtkWidget *useButton;
static GtkWidget *edit_window;
static GtkWidget *edit_combo_color;
static GtkWidget *auto_reorder;
static GtkWidget *buttonAddSurface;
static GtkWidget *buttonRemoveSurface;
static GtkWidget *buttonEdit;
static GtkWidget *buttonEditAll;
static GtkWidget *buttonOpen;
static GtkWidget *buttonConvert;

/* Global flags. */
static gboolean reverse_order = FALSE;
static gboolean autoload_file = FALSE;

/* New types. */
typedef void (*ChangesMethod)(GtkTreeIter *iter, gboolean recurse, gpointer data);



/* Get the iter of the selected row. */
static gboolean getSelectedRow(GtkTreeIter *iter)
{
  GtkTreeModel *model;
  GtkTreeSelection* tree_selection = 
    gtk_tree_view_get_selection(GTK_TREE_VIEW(isosurfaces_tree_model));

  if (!gtk_tree_selection_get_selected(tree_selection, &model, iter))
    return FALSE;

  return TRUE;
}

/* Call @method on iter depending on selection.
   - If there is no selection, changes are applied on all surfaces.
   - If selection is on a file, changes are applied on all surfaces on that file.
   - If selection is on a surface, changes are applied on all surfaces
     of the same file.
   */
static void applyChanges(ChangesMethod method, gpointer value)
{
  gboolean valid;
  int type;
  gboolean validParent, validChild;
  GtkTreeIter iter, parent, child;
  
  DBG_fprintf(stderr, "Panel Isosurfaces : run in the treeview to apply changes.\n");
  valid = getSelectedRow(&iter);
  if (!valid)
    {
      DBG_fprintf(stderr, " | run on all row without recurse.\n");
      /* Nothing is selected, we call the changing method on all surfaces. */
      validParent = gtk_tree_model_get_iter_first
        (GTK_TREE_MODEL(isosurfaces_data_list), &parent);
      while (validParent)
        {
          DBG_fprintf(stderr, "Panel Isosurfaces : find one parent.\n");
          validChild = gtk_tree_model_iter_children(GTK_TREE_MODEL(isosurfaces_data_list),
                                                    &child, &parent);
          while (validChild)
            {
              DBG_fprintf(stderr, "Panel Isosurfaces : find one child.\n");
              method(&child, FALSE, value);
              validChild = gtk_tree_model_iter_next
                (GTK_TREE_MODEL(isosurfaces_data_list), &child);
            }
          validParent = gtk_tree_model_iter_next
            (GTK_TREE_MODEL(isosurfaces_data_list), &parent);
        }
    }
  else
    {
      DBG_fprintf(stderr, " | run on all row of the current file.\n");
      /* Something is selected, we try to find the parent file. */
      gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iter,
                         TYPE_COLUMN, &type, -1);
      if (type == SURFACE_TYPE_SURF)
        {
          valid = gtk_tree_model_iter_parent(GTK_TREE_MODEL(isosurfaces_data_list),
                                             &parent, &iter);
          g_return_if_fail(valid);
        }
      else
        parent = iter;
      /* We change the visibility of all child of parent. */
      valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(isosurfaces_data_list),
                                           &iter, &parent);
      while (valid)
        {
          DBG_fprintf(stderr, "Panel Isosurfaces : find one child.\n");
          method(&iter, TRUE, value);
          valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
        }
    }

}

/* Change one element in the tree (visibility, pixbuf color...) for
   all surfaces whose resource's name is @nameRef. */
static void changeTreeViewElement(const gchar *nameRef, int columnId, gpointer value)
{
  gchar *name;
  gboolean validParent, validChild;
  GtkTreeIter parent, child;

  g_return_if_fail(nameRef);
  /* Update the treestore, for all surfaces with the same name. */
  validParent = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(isosurfaces_data_list), &parent);
  while (validParent)
    {
      validChild = gtk_tree_model_iter_children(GTK_TREE_MODEL(isosurfaces_data_list),
                                                &child, &parent);
      while (validChild)
        {
          gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                       &child, NAME_COLUMN, &name, -1);
          if (!strcmp(name, nameRef))
            gtk_tree_store_set(isosurfaces_data_list, &child,
                               columnId, value, -1);
          validChild = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &child);
        }
      validParent = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &parent);
    }
}

/***********************/
/* Visibility Handling */
/***********************/
/* Change the visibility of one surface (given by its iter).
   The visibility is in value (using GPOINTER_TO_INT) and
   recurse is a flag to tell if changes must be propagated to
   all elements with the same name or not. */
static void showHideSurfaces(GtkTreeIter *iter, gboolean recurse, gpointer value)
{
  int surf_number;
  Surfaces *surfaces;
  SurfaceResource *res;
  int type;
  gchar *name;

  g_return_if_fail(iter);
  
  /* Grep surface informations. */
  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                 iter, NUMBER_COLUMN, &surf_number,
                 DATA_SURF_COLUMN, &surfaces,
                 NAME_COLUMN, &name,
                 TYPE_COLUMN, &type, -1);
  if (type != SURFACE_TYPE_SURF)
    return;

  /* Update the treestore, for all surfaces with the same name. */
  if (recurse)
    changeTreeViewElement(name, SHOW_COLUMN, value);
  else
    gtk_tree_store_set(isosurfaces_data_list, iter,
                       SHOW_COLUMN, value, -1);

  /* Update the surface properties. */
  res = isosurfacesGet_surfaceResource(surfaces, surf_number);
  DBG_fprintf(stderr, "Panel Isosurfaces : set visible property of"
            " surface %d to %d.\n", surf_number, GPOINTER_TO_INT(value));
  res->rendered = (gboolean)GPOINTER_TO_INT(value);
}

/* Callback for the "Draw" check box. 
   If the selected surface were drawn, hides it and uncheck the button.
   If it was hidden, shows it and check the button. */
void isosurfaces_tree_show_hide(GtkCellRendererToggle *cell_renderer, 
                        gchar *string_path, gpointer user_data)
{
  GtkTreePath* path = gtk_tree_path_new_from_string(string_path);
  GtkTreeIter iter;
  gboolean valid;

  valid = gtk_tree_model_get_iter(GTK_TREE_MODEL(isosurfaces_data_list), &iter, path);
  gtk_tree_path_free(path);
  if(!valid)
    return;

  /* We change the visibility of the surface (both resource and check box). */
  showHideSurfaces(&iter, TRUE,
                   GINT_TO_POINTER(!gtk_cell_renderer_toggle_get_active(cell_renderer)));

  isosurfaces_rebuild_gl_list_and_redraw();
}

gboolean panelIsosurfacesShow_all(gboolean show)
{
  applyChanges(showHideSurfaces, GINT_TO_POINTER(show));
  return TRUE;
}

void onShowHideAllButton(GtkButton *button, gpointer visibility)
{
  gboolean reorder;

  reorder = panelIsosurfacesShow_all(GPOINTER_TO_INT(visibility));
  if (reorder)
    isosurfaces_rebuild_gl_list_and_redraw();
}


/******************************/
/* Colour & material Handling */
/******************************/
/* Changes the colour for a specific surface identified by its iter.
   If recurse is TRUE, changes are also applied on surfaces with
   the same name. */
void changeSurfaceColor(GtkTreeIter *iter, gboolean recurse, gpointer colorComboBox)
{
  GdkPixbuf *pixbuf;
  int id, i;
  SurfaceResource *res;
  Surfaces *surfaces;
  gchar *name;
  Color *color;
  float *rgba;
  float *material;

  g_return_if_fail(iter);
  
  /* Grep surface informations. */
  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), iter,
                 DATA_SURF_COLUMN, &surfaces,
                 NAME_COLUMN, &name,
                 NUMBER_COLUMN, &id, -1);

  /* We get a color from the values of the ranges. */
  material = colorComboBoxGet_material(COLOR_COMBOX(colorComboBox));
  rgba = colorComboBoxGet_color(COLOR_COMBOX(colorComboBox));
  color = colorNew_floatRGBA(rgba);
  
  /* Change the pixbuf for all surfaces with the name @name. */
  pixbuf = colorComboBoxBuild_colorStamp(color, TRUE);
  if (recurse)
    changeTreeViewElement(name, PIXBUF_COLUMN, (gpointer)pixbuf);
  else
    gtk_tree_store_set(isosurfaces_data_list, iter,
                       PIXBUF_COLUMN, (gpointer)pixbuf, -1);
  g_object_unref(pixbuf);

  /* Change the color & material. */
  res = isosurfacesGet_surfaceResource(surfaces, id);
  for (i = 0; i < 4; i++)
    res->color->rgba[i] = color->rgba[i];
  for (i = 0; i < nb_material; i++)
      res->material[i] = material[i];

  g_free(material);
  g_free(rgba);
  g_free(color);
}

/* Callback for when the combo color is changed in the edit panel */
void isosurfaces_combo_selection_changed(ColorComboBox *combo, Color *color, gpointer data)
{
  GtkTreeIter iter;
  gboolean valid;

  DBG_fprintf(stderr, "Panel Isosurfaces : caught the 'color-selected' signal.\n");

  if (GPOINTER_TO_INT(data))
    {
      valid = getSelectedRow(&iter);
      g_return_if_fail(valid);
      /* We only change the selected surface. */
      changeSurfaceColor(&iter, TRUE, (gpointer)combo);
    }
  else
    /* We change all surfaces depending on the selected one. */
    applyChanges(changeSurfaceColor, (gpointer)combo);

  isosurfaces_rebuild_gl_list_and_redraw();
}

static void onRangesChanged(ColorComboBox *colorComboBox, guint valId, gpointer data)
{
  gboolean valid;
  GtkTreeIter iter;

  DBG_fprintf(stderr, "Panel Isosurfaces : caught the "
                      "'[material:color]-value-changed' signal.\n");

  if (GPOINTER_TO_INT(data))
    {
      valid = getSelectedRow(&iter);
      g_return_if_fail(valid);
      /* We only change the selected surface. */
      changeSurfaceColor(&iter, TRUE, (gpointer)colorComboBox);
    }
  else
    /* We change all surfaces depending on the selected one. */
    applyChanges(changeSurfaceColor, (gpointer)colorComboBox);

  isosurfaces_rebuild_gl_list_and_redraw();
}

void panelIsosurfacesEdit_surfaceProperties(gboolean flag)
{
  GtkWidget *edit_vbox, *hbox, *label, *expand;
  GtkWidget *close_button;
  int current_surface_selected, type;
  GtkTreeIter iter;
  gboolean valid;
  SurfaceResource *res;
  Surfaces *surfaces;
  float material[5];

  res = (SurfaceResource*)0;
  valid = getSelectedRow(&iter);
  if(valid)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iter,
                   DATA_SURF_COLUMN, &surfaces,
                   TYPE_COLUMN, &type,
                   NUMBER_COLUMN, &current_surface_selected, -1);
      if (type != SURFACE_TYPE_SURF)
       return;

      res = isosurfacesGet_surfaceResource(surfaces, current_surface_selected);
      g_return_if_fail(res);
    }
  
  if (!IS_COLOR_COMBOX(edit_combo_color) || !GTK_IS_WINDOW(edit_window))
    {
      edit_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title(GTK_WINDOW(edit_window), "Edit surface properties");
      gtk_window_set_modal(GTK_WINDOW(edit_window), FALSE);
      gtk_window_set_transient_for(GTK_WINDOW(edit_window), GTK_WINDOW(mainWindow));
      gtk_window_set_default_size(GTK_WINDOW(edit_window), 320, -1);
      gtk_window_set_type_hint(GTK_WINDOW(edit_window), GDK_WINDOW_TYPE_HINT_UTILITY);
      gtk_window_set_skip_pager_hint(GTK_WINDOW(edit_window), TRUE);
      gtk_container_set_border_width(GTK_CONTAINER(edit_window), 3);

      edit_vbox = gtk_vbox_new(FALSE, 2);
      gtk_container_add(GTK_CONTAINER(edit_window), edit_vbox);

      if (flag)
      label = gtk_label_new(res->surfnom);
      else
      label = gtk_label_new(_("All surfaces"));
      gtk_widget_set_name(label, "label_head_2");
      gtk_box_pack_start(GTK_BOX(edit_vbox), label, FALSE, FALSE, 2);

      hbox = gtk_hbox_new(FALSE, 0);
      gtk_box_pack_start(GTK_BOX(edit_vbox), hbox, FALSE, FALSE, 0);

      label = gtk_label_new(_("Color: "));
      gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);

      edit_combo_color = colorComboBox_newWithRanges(TRUE);
      colorComboBoxSet_expanded(COLOR_COMBOX(edit_combo_color), TRUE);
      gtk_box_pack_start(GTK_BOX(hbox), edit_combo_color, TRUE, TRUE, 2);

      expand = colorComboBoxGet_rangesWidgets(COLOR_COMBOX(edit_combo_color));
      gtk_box_pack_start(GTK_BOX(edit_vbox), expand, FALSE, FALSE, 0);

      close_button = gtk_button_new_with_label(_("Close"));
      gtk_box_pack_start(GTK_BOX(edit_vbox), close_button, FALSE, FALSE, 0);

      /* Set the callbacks. */
      g_signal_connect_swapped(close_button, "clicked",
                         G_CALLBACK(gtk_widget_destroy), edit_window);
      g_signal_connect(G_OBJECT(edit_combo_color), "color-selected",
                   G_CALLBACK(isosurfaces_combo_selection_changed),
                   GINT_TO_POINTER(flag));
      g_signal_connect(G_OBJECT(edit_combo_color), "material-value-changed",
                   G_CALLBACK(onRangesChanged), GINT_TO_POINTER(flag));
      g_signal_connect(G_OBJECT(edit_combo_color), "color-value-changed",
                   G_CALLBACK(onRangesChanged), GINT_TO_POINTER(flag));

      gtk_widget_show_all(edit_window);
    }
  else
    gdk_window_raise(GDK_WINDOW(edit_window->window));

  /* Set the default values but don't raise any change signal. */
  if (res)
    {
      colorComboBoxSet_color(COLOR_COMBOX(edit_combo_color), res->color->rgba, FALSE);
      colorComboBoxSet_material(COLOR_COMBOX(edit_combo_color), res->material, FALSE);
    }
  else
    {
      material[0] = 0.2f;
      material[1] = 1.0f;
      material[2] = 0.5f;
      material[3] = 0.5f;
      material[4] = 0.0f;
      colorComboBoxSet_material(COLOR_COMBOX(edit_combo_color), material, FALSE);
    }
 
}

static void onEditPropertiesClicked(GtkButton *button, gpointer data)
{
  DBG_fprintf(stderr, "Panel Isosurfaces : clicked on properties"
                      " button (%d).\n", GPOINTER_TO_INT(data));
  panelIsosurfacesEdit_surfaceProperties((gboolean)GPOINTER_TO_INT(data));
}

static void onRowClicked(GtkTreeView *tree_view, GtkTreePath *path,
                         GtkTreeViewColumn *column, gpointer user_data)
{
  DBG_fprintf(stderr, "Panel Isosurfaces : clicked on tree view row"
                      " '%s'.\n", gtk_tree_path_to_string(path));
  panelIsosurfacesEdit_surfaceProperties(TRUE);
}




/* See header for more info */
static void isosurfaces_open_file_chooser()
{
  char *file_choosed;
  gchar *directory = getLastOpenDirectory();
  GtkWidget* file_chooser = 
    gtk_file_chooser_dialog_new("Open .surf file",
                        GTK_WINDOW(mainWindow),
                        GTK_FILE_CHOOSER_ACTION_OPEN,
                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                        NULL);
  GtkTooltips *tooltips = gtk_tooltips_new ();
  GtkWidget *fit_to_box = gtk_check_button_new_with_label (_("Fit surfaces to box"));
  GList *scalarMethods;
  GList *allFilters, *allMethods, *tmpLst;
  char *type[] = {"*.surf", (char*)0};
  char *descr = _("Isosurfaces files");
  FileFormat *fmt;
  gboolean invalid, redraw;

  if (directory)
    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_chooser), directory);

  gtk_tooltips_set_tip(tooltips, fit_to_box, 
                   _("Makes surfaces fit to the current loaded bounding box"), NULL);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fit_to_box), TRUE);
  gtk_box_pack_start(GTK_BOX(GTK_DIALOG(file_chooser)->vbox), fit_to_box, FALSE, FALSE, 0);
  gtk_widget_show(fit_to_box);

  fmt = fileFormatNew(descr, type);
  scalarMethods = scalarFieldGet_allLoadMethods();
  allMethods = (GList*)0;
  allMethods = g_list_append(allMethods, fmt);
  while(scalarMethods)
    {
      allMethods = g_list_append(allMethods, ((ScalarFieldLoadStruct*)scalarMethods->data)->fmt);
      scalarMethods = g_list_next(scalarMethods);
    }
  allFilters = gtkMainCreate_fileChooserFilter(allMethods, file_chooser);

  redraw = FALSE;
  invalid = TRUE;
  while(invalid)
    {
      switch(gtk_dialog_run (GTK_DIALOG (file_chooser)))
      {
      case GTK_RESPONSE_ACCEPT:
        file_choosed = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_chooser));
        if(panelIsosurfacesLoad_file(file_choosed, 
                               gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fit_to_box)),
                               toolPanelGet_visuData(TOOL_PANEL(panelSurfaces)),
                               (OptionTable*)0) == 0)
          {
            redraw = TRUE;
            invalid = FALSE;
          }
        break;
      default:
        invalid = FALSE;
      }
    }
  directory = 
    (char*)gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER (file_chooser));
  setLastOpenDirectory(directory);
  /* Free everything. */
  DBG_fprintf(stderr, "Gtk Main : free load dialog.\n");
  g_free(directory);
  gtk_widget_destroy(file_chooser);
  tmpLst = allFilters;
  while(tmpLst)
    {
      g_free(tmpLst->data);
      tmpLst = g_list_next(tmpLst);
    }
  g_list_free(allFilters);
  g_list_free(allMethods);

  if (redraw)
    g_idle_add(isosurfaces_rebuild_gl_list_in_order_and_redraw, (gpointer)0);
}

/* See header for more info */
int panelIsosurfacesLoad_file(const char* file_name, gboolean fit_to_box,
                        VisuData *data, OptionTable *table)
{
  GError *error;
  Surfaces *surf;
  GtkTreeIter iter, iter2;
  gchar *name, *label;
  gboolean valid;
  gchar *filename;
  int type;
  GList *list, *tmplst;
  ScalarField *field;
  double minmax[2];

  g_return_val_if_fail(file_name, 1);
  g_return_val_if_fail(isosurfaces_data_list, 2);

  surf = (Surfaces*)0;
  list = (GList*)0;
  field = (ScalarField*)0;
  error = (GError*)0;
  valid = isosurfacesLoad_file(file_name, &surf, &error);
  if (!valid)
    {
      /* Not a surfaces file. */
      if (error)
        g_error_free(error);
      error = (GError*)0;
      valid = scalarFieldLoad_fromFile(file_name, &list, &error, table);
      if (error)
      {
        raiseAlertDialog(error->message);
        g_error_free(error);
        tmplst = list;
        while (tmplst)
          {
            scalarFieldFree((ScalarField*)tmplst->data);
            tmplst = g_list_next(tmplst);
          }
        g_list_free(list);
        return 3;
      }
      if (!valid)
      /* Not a density/potential file. */
      return 3;
      type = SURFACE_TYPE_FILE_DENPOT;
    }
  else
    {
      if (error)
      {
        raiseAlertDialog(error->message);
        g_error_free(error);
        isosurfacesFree(surf);
        return 3;
      }
      list = g_list_append(list, (gpointer)surf);
      type = SURFACE_TYPE_FILE_SURF;
    }

  if (fit_to_box)
    {
      tmplst = list;
      while (tmplst)
      {
        if (type == SURFACE_TYPE_FILE_SURF)
          isoSurfacesSet_fitToBox(data, (Surfaces*)tmplst->data);
        else
          scalarFieldSet_fitToBox(data, (ScalarField*)tmplst->data);
        tmplst = g_list_next(tmplst);
      }
    }

  /* Before adding it to the tree, we may remove all identic
     already existing file. */
  DBG_fprintf(stderr, "Panel Surfaces : may remove an existing entry.\n");
  valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(isosurfaces_data_list),
                              &iter);
  while (valid)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                   &iter, FILENAME_COLUMN, &filename, -1);
      iter2 = iter;
      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list),
                               &iter);
      if (!strcmp(filename, file_name))
      panel_isosurfaces_remove(&iter2);
    }

  /* We create a root element for the file. */
  DBG_fprintf(stderr, "Panel Surfaces : add a new root entry '%s'.\n", file_name);
  name = g_path_get_basename(file_name);
  tmplst = list;
  while(tmplst)
    {
      if (type == SURFACE_TYPE_FILE_SURF)
      {
        label = g_strdup_printf(_("<b>%s</b>\n  <span size=\"smaller\"><i>"
                            "Surfaces file</i></span>"), name);
        surf = (Surfaces*)tmplst->data;
        field = (ScalarField*)0;
      }
      else
      {
        scalarFieldGet_minMax((ScalarField*)tmplst->data, minmax);
        label = g_strdup_printf(_("<b>%s</b>\n  <span size=\"smaller\"><i>"
                            "Den./pot. file (min|max)\n  %g | %g</i></span>"),
                          name, minmax[0], minmax[1]);
        surf = (Surfaces*)0;
        field = (ScalarField*)tmplst->data;
        gtk_list_store_append(fields_data_list, &iter);
        gtk_list_store_set(fields_data_list, &iter,
                       COLUMN_FIELD_LABEL, label,
                       COLUMN_FIELD_POINTER, field,
                       -1);
      }
      gtk_tree_store_append(isosurfaces_data_list, &iter, (GtkTreeIter*)0);
      gtk_tree_store_set(isosurfaces_data_list, &iter,
                   NUMBER_COLUMN, -1,
                   USE_SHOW_COLUMN, FALSE,
                   NAME_COLUMN, label,
                   TYPE_COLUMN, type,
                   USE_POTENTIAL_COLUMN, FALSE,
                   FILENAME_COLUMN, file_name,
                   DATA_SURF_COLUMN, surf,
                   DATA_FIELD_COLUMN, field,
                   -1);
      g_free(label);
      tmplst = g_list_next(tmplst);
    }
  g_free(name);
  g_list_free(list);

  if (type == SURFACE_TYPE_FILE_SURF)
    isosurfaces_update_data_list(surf, &iter);

  return 0;
}

/* refresh tree view info according to loaded surfaces by surfaces.c 
   refresh gl display */
static void isosurfaces_update_data_list(Surfaces *surf, GtkTreeIter *iter)
{
  int i, n, type, *ids, pos;
  SurfaceResource *res;
  const gchar *current_surface;
  GdkPixbuf *pixbuf;
  float *potentialData;
  GtkTreeIter childIter;
  gboolean valid;
  GtkTreePath *path;

  g_return_if_fail(isosurfaces_data_list);
  
  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), iter,
                 TYPE_COLUMN, &type, -1);

  /* We remove all children from the given iter. */
  DBG_fprintf(stderr, "Isosurfaces : remove children from the iter.\n");
  valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(isosurfaces_data_list),
                               &childIter, iter);
  while (valid)
    {
      gtk_tree_store_remove(isosurfaces_data_list, &childIter);
      valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(isosurfaces_data_list),
                                 &childIter, iter);
    }

  ids = isosurfacesGet_surfaceSortedById(surf);
  n = isosurfacesGet_nbSurfaces(surf);
  DBG_fprintf(stderr, "Isosurfaces : append %d children to the iter.\n", n);
  potentialData = isosurfacesGet_floatProperty(surf, ISOSURFACES_PROPERTY_POTENTIAL);
  for(i = 0; i < n; i++)
    {
      current_surface = isosurfacesGet_surfaceName(surf, ids[i]);
      DBG_fprintf(stderr, " | surface '%s' %d.\n", current_surface, ids[i]);
      res = isosurfacesGet_surfaceResource(surf, ids[i]);
      pixbuf = colorComboBoxBuild_colorStamp(res->color, TRUE);
      pos = isosurfacesGet_surfacePosition(surf, ids[i]);
      gtk_tree_store_append(isosurfaces_data_list, &childIter, iter);
      gtk_tree_store_set(isosurfaces_data_list, &childIter,
                   NUMBER_COLUMN, ids[i],
                   SHOW_COLUMN, res->rendered,
                   USE_SHOW_COLUMN, TRUE,
                   NAME_COLUMN, current_surface,
                   EDIT_NAME_COLUMN, TRUE,
                   COLOR_NAME_COLUMN, "blue",
                   TYPE_COLUMN, SURFACE_TYPE_SURF,
                   POTENTIAL_COLUMN, potentialData[pos],
                   EDIT_POTENTIAL_COLUMN, (type == SURFACE_TYPE_FILE_DENPOT),
                   USE_POTENTIAL_COLUMN, TRUE,
                   DATA_SURF_COLUMN, surf,
                   PIXBUF_COLUMN, pixbuf, -1);
                  /* We count down the ref on the pixbuf, since one was added when
                     created and one was added when insering into the tree_model.
                     But we want only one ref count. */
      g_object_unref(pixbuf);
      if (type == SURFACE_TYPE_FILE_DENPOT)
      gtk_tree_store_set(isosurfaces_data_list, &childIter,
                     COLOR_POTENTIAL_COLUMN, "blue", -1);
    }
  g_free(ids);

  DBG_fprintf(stderr, "Isosurfaces : select first child.\n");
  path = gtk_tree_model_get_path(GTK_TREE_MODEL(isosurfaces_data_list), iter);
  gtk_tree_view_expand_row(GTK_TREE_VIEW(isosurfaces_tree_model), path, TRUE);
  gtk_tree_path_free(path);
  valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(isosurfaces_data_list),
                               &childIter, iter);
  if (valid)
    gtk_tree_selection_select_iter
      (gtk_tree_view_get_selection(GTK_TREE_VIEW(isosurfaces_tree_model)), &childIter);

}

/* See header file for more info */
gboolean isosurfaces_show_next()
{
  GtkTreeIter iter;
  GtkTreeSelection* selected_surf;

  selected_surf = gtk_tree_view_get_selection(GTK_TREE_VIEW(isosurfaces_tree_model));

  if(!gtk_tree_selection_get_selected(selected_surf, NULL, &iter))
    return FALSE;

  if(reverse_order == FALSE)
    {
      if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &iter))
      {
        reverse_order = TRUE;
        if (!gtk_tree_model_iter_previous(GTK_TREE_MODEL(isosurfaces_data_list), &iter))
          return FALSE;
      }
    }
  else
    {
      if (!gtk_tree_model_iter_previous(GTK_TREE_MODEL(isosurfaces_data_list), &iter))
      {
        reverse_order = FALSE;
        if (!gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &iter))
          return FALSE;
      }
    }

  /* Set the selection to the new row. */
  gtk_tree_selection_select_iter(selected_surf, &iter);

  /* Set all surfaces, set show to FALSE. */
  panelIsosurfacesShow_all(FALSE);
  /* For the selected surface, set show to TRUE. */
  showHideSurfaces(&iter, FALSE, GINT_TO_POINTER(TRUE));

  isosurfaces_rebuild_gl_list_and_redraw();

  return TRUE;
}

/* Callback for the "play" button. Registers the above function to be called at a specified time
   interval. */
void isosurfaces_play(GtkWidget *play_stop, GtkWidget *time_interval)
{
  static int event_id = 0;

  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(play_stop)) == TRUE)
    {
      event_id = g_timeout_add(gtk_spin_button_get_value(GTK_SPIN_BUTTON(time_interval)),
                         isosurfaces_show_next, NULL);
      gtk_button_set_label(GTK_BUTTON(play_stop), " Stop ");
    }
  else
    {
      g_source_remove(event_id);
      gtk_button_set_label(GTK_BUTTON(play_stop), " Play ");
    }      
}


/* Sets up the model/view architecture used to store the surfaces info. */
void isosurfaces_make_tree_view()
{
  GtkCellRenderer *cell_show = gtk_cell_renderer_toggle_new();
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column = NULL;

  isosurfaces_data_list =
    gtk_tree_store_new (N_COLUMNS, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
                  G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT,
                  G_TYPE_FLOAT, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING,
                  GDK_TYPE_PIXBUF, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING);
  isosurfaces_tree_model = 
    gtk_tree_view_new_with_model (GTK_TREE_MODEL (isosurfaces_data_list));

  g_signal_connect(cell_show, "toggled", G_CALLBACK(isosurfaces_tree_show_hide), NULL);

  renderer = gtk_cell_renderer_text_new();
  column = gtk_tree_view_column_new_with_attributes(_("File / label"), renderer,
                                        "markup", NAME_COLUMN,
                                        "foreground", COLOR_NAME_COLUMN,
                                        "editable", EDIT_NAME_COLUMN, NULL);
  g_signal_connect(G_OBJECT(renderer), "edited",
               G_CALLBACK(onNameEdited), (gpointer)0);
  gtk_tree_view_column_set_expand(column, TRUE);
  gtk_tree_view_column_set_alignment(column, 0);
  gtk_tree_view_column_set_resizable(column, TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (isosurfaces_tree_model), column);

  column = gtk_tree_view_column_new_with_attributes("", cell_show,
                                        "active", SHOW_COLUMN,
                                        "visible", USE_SHOW_COLUMN, NULL);
  gtk_tree_view_column_set_expand(column, FALSE);
  gtk_tree_view_column_set_alignment(column, 0.5);
  gtk_tree_view_append_column (GTK_TREE_VIEW (isosurfaces_tree_model), column);

  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes(_("Value"), renderer,
                                        "text", POTENTIAL_COLUMN,
                                        "editable", EDIT_POTENTIAL_COLUMN,
                                        "foreground", COLOR_POTENTIAL_COLUMN,
                                        "visible", USE_POTENTIAL_COLUMN, NULL);
  g_signal_connect(G_OBJECT(renderer), "edited",
               G_CALLBACK(onPotentialValueEdited), (gpointer)0);
  gtk_tree_view_append_column(GTK_TREE_VIEW(isosurfaces_tree_model), column);

  renderer = gtk_cell_renderer_pixbuf_new ();
  column = gtk_tree_view_column_new_with_attributes(_("Color"), renderer,
                                        "pixbuf", PIXBUF_COLUMN,
                                        NULL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(isosurfaces_tree_model), column);

  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (isosurfaces_tree_model), TRUE);  

  g_signal_connect_swapped(G_OBJECT(isosurfaces_tree_model), "row_activated",   
                           G_CALLBACK(onRowClicked), (gpointer)0);

  g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(isosurfaces_tree_model)),
               "changed", G_CALLBACK(onTreeSelectionChanged), (gpointer)0);
  g_signal_connect(G_OBJECT(isosurfaces_tree_model), "button-release-event",
               G_CALLBACK(onTreeViewClicked), (gpointer)0);
}

/* Callback for time interval value spin button.
   Changes the frequency used to play the surfaces. */
void isosurfaces_change_time_interval(GtkWidget *spin_button, GtkWidget *play_stop)
{
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_stop), FALSE);
}

gboolean panelIsosurfacesSet_used(VisuData *dataObj, gboolean used)
{
  if(used == extension_isosurfaces->used)
    return FALSE;

  extension_isosurfaces->used = used;
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useButton), used);

  if (!dataObj)
    return FALSE;
  
  if (used)
    isosurfaces_rebuild_gl_list(dataObj);

  return TRUE;
}

/* Callback for the check button "use isosurfaces".
   Enables/disables the drawing of isosurfaces by V_Sim's core. */
void isosurfaces_switch_use(GtkToggleButton *togglebutton, gpointer user_data)
{
  gboolean redraw;

  redraw = panelIsosurfacesSet_used(toolPanelGet_visuData(TOOL_PANEL(panelSurfaces)),
                            gtk_toggle_button_get_active(togglebutton));
  
  if(redraw)
    g_signal_emit(visu, VISU_GET_CLASS (visu)->OpenGLAskForReDraw_signal_id, 0, NULL);
}

/* void isosurfaces_auto_reorder_polys(GtkWidget *button, GtkWidget *reorder_button) */
/* { */
/*   gtk_widget_set_sensitive(reorder_button, */
/*                   !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))); */
/* } */
void panelIsosurfacesAdd_withValue(gchar *filename, float value, gchar *name)
{
  GtkTreeIter iter;
  gboolean valid, found;
  gchar *file;

  g_return_if_fail(filename);

  DBG_fprintf(stderr, "Panel Isosurfaces : add a new surface (%f) for '%s'.\n", value, filename);
  valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
  /* We look for the iter with the given file. */
  found = FALSE;
  while (valid && !found)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                   &iter, FILENAME_COLUMN, &file, -1);
      found = (!strcmp(file, filename));
      if (!found)
      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
    }
  if (valid && found)
    panel_isosurfaces_add(&iter, TRUE, value, name);
  else
    g_warning("Cannot find the given scalar field '%s'.", filename);
}
static gboolean panel_isosurfaces_add(GtkTreeIter *iter, gboolean setValue,
                              float value, gchar *name)
{
  double mimax[2];
  Surfaces *surf;
  int type, nb;
  gboolean valid;
  ScalarField *field;

  g_return_val_if_fail(iter, FALSE);

  surf = (Surfaces*)0;
  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                 iter, TYPE_COLUMN, &type,
                 DATA_SURF_COLUMN, &surf,
                 DATA_FIELD_COLUMN, &field, -1);

  g_return_val_if_fail(type == SURFACE_TYPE_FILE_DENPOT && field, FALSE);

  nb = isosurfacesGet_newId(surf);
  if (setValue)
    valid = pot2surfCreate(&surf, field, value, nb, name);
  else
    {
      scalarFieldGet_minMax(field, mimax);
      valid = pot2surfCreate(&surf, field, (mimax[0] + mimax[1]) / 2., nb, name);
    }

  gtk_tree_store_set(isosurfaces_data_list, iter,
                 DATA_SURF_COLUMN, surf, -1);

  if (valid)
    isosurfaces_update_data_list(surf, iter);

  return valid;
}
static void isosurfaces_remove_field(GtkListStore *list, ScalarField *field)
{
  gboolean valid;
  GtkTreeIter iter;
  ScalarField *tmpField;

  valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list), &iter);
  while (valid)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(list), &iter,
                   COLUMN_FIELD_POINTER, &tmpField, -1);
      if (tmpField == field)
      {
        gtk_list_store_remove(list, &iter);
        return;
      }
      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(list), &iter);
    }
}
static gboolean panel_isosurfaces_remove(GtkTreeIter *iter)
{
  int type, idSurf;
  Surfaces *surf;
  ScalarField *field;
  gboolean rebuild, empty;
  GtkTreeIter iterFather;

  g_return_val_if_fail(iter, FALSE);

  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                 iter, TYPE_COLUMN, &type,
                 DATA_SURF_COLUMN, &surf,
                 DATA_FIELD_COLUMN, &field,
                 NUMBER_COLUMN, &idSurf, -1);
  
  rebuild = FALSE;
  switch (type)
    {
    case SURFACE_TYPE_FILE_DENPOT:
    case SURFACE_TYPE_FILE_SURF:
      /* We remove the entry from the tree. */
      gtk_tree_store_remove(isosurfaces_data_list, iter);
      if (field)
      isosurfaces_remove_field(fields_data_list, field);
      /* We free the memory used by these surfaces. */
      if (surf)
      isosurfacesFree(surf);
      if (field)
      scalarFieldFree(field);
      /* We need to rebuild the order list. */
      rebuild = TRUE;
      break;
    case SURFACE_TYPE_SURF:
      /* We change the surface list. */
      empty = isosurfacesRemove(surf, idSurf);
      if (empty)
      {
        gtk_tree_model_iter_parent(GTK_TREE_MODEL(isosurfaces_data_list),
                             &iterFather, iter);
        gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                       &iterFather, TYPE_COLUMN, &type, -1);
        if (type == SURFACE_TYPE_FILE_SURF)
          gtk_tree_store_remove(isosurfaces_data_list, &iterFather);
        else
          {
            gtk_tree_store_set(isosurfaces_data_list, &iterFather,
                         DATA_SURF_COLUMN, (Surfaces*)0, -1);
            /* We remove the entry from the tree. */
            gtk_tree_store_remove(isosurfaces_data_list, iter);
          }
        isosurfacesFree(surf);
      }
      else
      {
        /* We remove the entry from the tree. */
        gtk_tree_store_remove(isosurfaces_data_list, iter);
      }
      /* We need to rebuild the order list. */
      rebuild = TRUE;
      break;
    default:
      g_warning("Wrong type for the selected entry.");
    }
  return rebuild;
}


/* Creates the main panel. */
void isosurfaces_create_gtk_interface(ToolPanel *toolPanel)
{
  GtkTooltips *tooltips = gtk_tooltips_new ();
  GtkWidget *top_hbox = gtk_hbox_new (FALSE, 0);
  GtkWidget *h_box3 = gtk_hbox_new (FALSE, 0);
  GtkWidget *show_all = gtk_button_new();
  GtkWidget *show_none = gtk_button_new();
  GtkWidget *play_stop =
    gtk_toggle_button_new_with_label(_("Play"));
  GtkWidget *time_interval = 
    gtk_spin_button_new_with_range  (50, 2000, 10);
  GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
/*   GtkWidget *reorder_button = gtk_button_new_with_label("Re-order"); */
  GtkWidget *image_surfs = create_pixmap(mainWindow, "stock-isosurfaces.png");
  GtkWidget *image_color_i = create_pixmap(mainWindow, "stock_effects-object-colorize_20_.png");
  GtkWidget *image_color = create_pixmap(mainWindow, "stock_effects-object-colorize_20.png");
  GtkWidget *image_show = create_pixmap(mainWindow, "stock-select-all_20.png");
  GtkWidget *image_hide = create_pixmap(mainWindow, "stock-unselect-all_20.png");
  GtkWidget *label_title = gtk_label_new(_("Use isosurfaces"));
  GtkWidget *hbox = gtk_hbox_new(FALSE, 5);
  GtkWidget *tree_vbox = gtk_vbox_new(FALSE, 0);
  GtkWidget *tree_hbox = gtk_hbox_new(FALSE, 0);
  GtkWidget *image, *align, *wd, *vbox;

  vbox = gtk_vbox_new(FALSE, 0);

  useButton = gtk_check_button_new();
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useButton), extension_isosurfaces->used);
  gtk_box_pack_start(GTK_BOX(vbox), useButton, FALSE, FALSE, 0);

  buttonEdit = gtk_button_new();
  gtk_widget_set_sensitive(buttonEdit, FALSE);
  buttonEditAll = gtk_button_new();
  gtk_widget_set_sensitive(buttonEditAll, FALSE);

  gtk_container_add(GTK_CONTAINER(buttonEdit), image_color);
  gtk_container_add(GTK_CONTAINER(buttonEditAll), image_color_i);
  gtk_container_add(GTK_CONTAINER(show_all), image_show);
  gtk_container_add(GTK_CONTAINER(show_none), image_hide);

  /* The line about loading files. */
  gtk_box_pack_start(GTK_BOX(vbox), top_hbox, FALSE, FALSE, 0);
  align = gtk_alignment_new(0., 0.5, 1., 0.);
  gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, 10, 0);
  gtk_box_pack_start(GTK_BOX(top_hbox), align, TRUE, TRUE, 2);
  wd = gtk_check_button_new_with_label(_("Auto load data file"));
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wd), autoload_file);
  gtk_tooltips_set_tip (tooltips, wd,
                  _("Try to load a data file whenever a new V_Sim file is loaded."
                    " If the new file contains a scalar field, it is loaded, otherwise"
                    " a surface file is tested using a .surf extension on the file name."), NULL);
  g_signal_connect(G_OBJECT(visu), "dataReadyForRendering",
                       G_CALLBACK(onDataReady), (gpointer)wd);
  gtk_container_add(GTK_CONTAINER(align), wd);
  buttonOpen = gtk_button_new();
  buttonConvert = gtk_button_new_with_label(_("Convert"));
  gtk_tooltips_set_tip (tooltips, buttonOpen, _("Load a surface file or a potential/density file."), NULL);
  gtk_box_pack_end(GTK_BOX(top_hbox), buttonOpen, FALSE, FALSE, 2);
  image = gtk_image_new_from_stock(GTK_STOCK_OPEN, GTK_ICON_SIZE_BUTTON);
  gtk_container_add(GTK_CONTAINER( buttonOpen), image);
  gtk_tooltips_set_tip (tooltips, buttonConvert, _("Several built-in tools to create .surf files."), NULL);
  gtk_box_pack_end(GTK_BOX(top_hbox), buttonConvert, FALSE, FALSE, 2);
  

  isosurfaces_make_tree_view ();

  isosurfaces_gtk_vbox = gtk_vbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(vbox), isosurfaces_gtk_vbox, TRUE, TRUE, 0);

  auto_reorder = gtk_check_button_new_with_label(_("Reorder on the fly"));
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_reorder), TRUE);

  gtk_widget_set_name(label_title, "label_head");
  gtk_box_pack_start(GTK_BOX(hbox), image_surfs, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(hbox), label_title, FALSE, FALSE, 0);
  gtk_container_add(GTK_CONTAINER(useButton), hbox);

/*   gtk_widget_set_sensitive(reorder_button, FALSE); */

  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(play_stop), FALSE);

  g_signal_connect(G_OBJECT(auto_reorder), "toggled",
               G_CALLBACK(onReorderToggled), (gpointer)0);
/*   g_signal_connect(G_OBJECT(reorder_button), "clicked", */
/*             G_CALLBACK(isosurfaces_rebuild_gl_list_in_order_and_redraw), NULL); */
  g_signal_connect(G_OBJECT(buttonOpen), "clicked",
               G_CALLBACK(isosurfaces_open_file_chooser), NULL);
  g_signal_connect(G_OBJECT(buttonConvert), "clicked",
               G_CALLBACK(isosurfaces_convert_interface), NULL);
  g_signal_connect(G_OBJECT(buttonEdit), "clicked",
               G_CALLBACK(onEditPropertiesClicked), GINT_TO_POINTER(1));
  g_signal_connect(G_OBJECT(buttonEditAll), "clicked",
               G_CALLBACK(onEditPropertiesClicked), GINT_TO_POINTER(0));
  g_signal_connect(G_OBJECT(show_all), "clicked",
               G_CALLBACK(onShowHideAllButton), GINT_TO_POINTER(1));
  g_signal_connect(G_OBJECT(show_none), "clicked",
               G_CALLBACK(onShowHideAllButton), GINT_TO_POINTER(0));
  g_signal_connect(G_OBJECT(play_stop), "toggled",
               G_CALLBACK(isosurfaces_play), time_interval);
  g_signal_connect(G_OBJECT(time_interval), "value_changed",
               G_CALLBACK(isosurfaces_change_time_interval), play_stop);
  g_signal_connect(G_OBJECT(useButton), "toggled",
               G_CALLBACK(isosurfaces_switch_use), NULL);

  /* The main viewport. */
  gtk_box_pack_start(GTK_BOX(isosurfaces_gtk_vbox), tree_hbox, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(tree_hbox), scrolled_window, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), 
                         GTK_POLICY_AUTOMATIC, 
                         GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
  gtk_container_add (GTK_CONTAINER (scrolled_window), isosurfaces_tree_model);
  gtk_box_pack_start(GTK_BOX(tree_hbox), tree_vbox, FALSE, FALSE, 2);
  gtk_tooltips_set_tip (tooltips, buttonEdit, _("Change selected surface's color and material properties"), NULL);
  gtk_box_pack_start(GTK_BOX(tree_vbox), buttonEdit, FALSE, FALSE, 2);
  gtk_tooltips_set_tip (tooltips, buttonEditAll, _("Change ALL surfaces' color and material properties"), NULL);
  gtk_box_pack_start(GTK_BOX(tree_vbox), buttonEditAll, FALSE, FALSE, 2);

  align = gtk_alignment_new(0.5, 1., 0., 0.);
  gtk_box_pack_start(GTK_BOX(tree_vbox), align, TRUE, TRUE, 2);
  buttonAddSurface = gtk_button_new();
  gtk_widget_set_sensitive(buttonAddSurface, FALSE);
  gtk_tooltips_set_tip(tooltips, buttonAddSurface,
                   _("Add a new surface."), NULL);
  g_signal_connect(G_OBJECT(buttonAddSurface), "clicked",
               G_CALLBACK(onAddButtonClicked), NULL);
  gtk_container_add(GTK_CONTAINER(align), buttonAddSurface);
  image = gtk_image_new_from_stock ("gtk-add", GTK_ICON_SIZE_BUTTON);
  gtk_container_add(GTK_CONTAINER(buttonAddSurface), image);

  align = gtk_alignment_new(0.5, 0., 0., 0.);
  gtk_box_pack_start(GTK_BOX(tree_vbox), align, TRUE, TRUE, 2);
  buttonRemoveSurface = gtk_button_new ();
  gtk_widget_set_sensitive(buttonRemoveSurface, FALSE);
  gtk_tooltips_set_tip(tooltips, buttonRemoveSurface,
                   _("Remove selected surface or file."), NULL);
  g_signal_connect(G_OBJECT(buttonRemoveSurface), "clicked",
               G_CALLBACK(onRemoveButtonClicked), NULL);
  gtk_container_add(GTK_CONTAINER(align), buttonRemoveSurface);
  image = gtk_image_new_from_stock ("gtk-remove", GTK_ICON_SIZE_BUTTON);
  gtk_container_add (GTK_CONTAINER(buttonRemoveSurface), image);

  gtk_tooltips_set_tip (tooltips, show_all, _("Shows all surfaces"), NULL);
  gtk_box_pack_end(GTK_BOX(tree_vbox), show_all, FALSE, FALSE, 2);
  gtk_tooltips_set_tip (tooltips, show_none, _("Hides all surfaces"), NULL);
  gtk_box_pack_end(GTK_BOX(tree_vbox), show_none, FALSE, FALSE, 2);
 
  gtk_box_pack_start(GTK_BOX(isosurfaces_gtk_vbox), h_box3, FALSE, FALSE, 0);
  gtk_tooltips_set_tip (tooltips, play_stop, _("Starts/stops showing isosurfaces at specified rate"), NULL);
  gtk_box_pack_start(GTK_BOX(h_box3), play_stop, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(h_box3), gtk_label_new(_("@")), FALSE, FALSE, 0);
  gtk_tooltips_set_tip (tooltips, time_interval, _("Selects rate to show isosurfaces"), NULL);
  gtk_box_pack_start(GTK_BOX(h_box3), time_interval, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(h_box3), gtk_label_new(_("ms")), FALSE, FALSE, 0);
  gtk_tooltips_set_tip (tooltips, auto_reorder, _("Automatically re-orders surfaces in back to front order whenever camera is modified (can be slow but get rid of transparency problems)"), NULL);
  gtk_box_pack_end(GTK_BOX(h_box3), auto_reorder, FALSE, FALSE, 0);
/*   gtk_tooltips_set_tip (tooltips, reorder_button, _("Re-orders surfaces in back to front order (deals with transparency problems for current point of view)"), NULL); */
/*   gtk_box_pack_end(GTK_BOX(h_box3), reorder_button, FALSE, FALSE, 0); */

  gtk_widget_show_all(vbox);

  gtk_container_add(GTK_CONTAINER(toolPanel), vbox);
}

static Surfaces** getAllSurfacesList()
{
  int n;
  gboolean valid;
  GtkTreeIter iter;
  Surfaces **surfaces;

  n = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(isosurfaces_data_list),
                             (GtkTreeIter*)0);
  surfaces = g_malloc(sizeof(Surfaces*) * (n + 1));
  n = 0;
  valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
  while (valid)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list),
                   &iter, DATA_SURF_COLUMN, surfaces + n, -1);
      /* In case the surface n is NULL, we don't count it. */
      if (surfaces[n])
      n += 1;
      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
    }
  surfaces[n] = (Surfaces*)0;
  DBG_fprintf(stderr, "Panel Isosurfaces : get list of all surfaces (%d).\n", n);
  return surfaces;
}

/* Reorders the polygons according to camera position and redraw isosurfaces. 
   this is because we're using alpha and for alpha to work properly, it is needed to
   draw polygons from back to front. */
void isosurfaces_rebuild_gl_list_in_order(VisuData *dataObj, OpenGLView *view, gpointer data)
{
  Surfaces **surfaces;

  if (!dataObj)
    return;

  if(extension_isosurfaces->used == TRUE)
    {
      if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_reorder)) ||
       GPOINTER_TO_INT(data))
      {
        surfaces = getAllSurfacesList();
        isosurfacesOrder_polygons(surfaceOrder, surfaces);
        isosurfacesDraw_surfaces(identifier_isosurfaces, view, surfaces, surfaceOrder);
        g_free(surfaces);
      }
    }
}

static gboolean isosurfaces_rebuild_gl_list_in_order_and_redraw(gpointer data)
{
  VisuData *dataObj;
  
  dataObj = toolPanelGet_visuData(TOOL_PANEL(panelSurfaces));
  g_return_val_if_fail(dataObj, FALSE);
  isosurfaces_rebuild_gl_list_in_order(dataObj, visuDataGet_openGLView(dataObj),
                               GINT_TO_POINTER(TRUE));
  if(extension_isosurfaces->used == TRUE)
    g_signal_emit(visu, VISU_GET_CLASS (visu)->OpenGLAskForReDraw_signal_id, 0, NULL);

  return FALSE;
}


/* Rebuilds the gl list associated to isosurfaces */
void isosurfaces_rebuild_gl_list(VisuData *dataObj)
{  
  Surfaces **list;

  if(extension_isosurfaces->used == TRUE)
    {
      list = getAllSurfacesList();
      isosurfacesDraw_surfaces(identifier_isosurfaces, visuDataGet_openGLView(dataObj),
                         list, surfaceOrder);
      g_free(list);
    }
}

/* Same as isosurfaces_rebuild_gl_list() but also asks the core for a redraw. */
void isosurfaces_rebuild_gl_list_and_redraw()
{  
  VisuData *dataObj;

  dataObj = toolPanelGet_visuData(TOOL_PANEL(panelSurfaces));
  g_return_if_fail(dataObj);
  isosurfaces_rebuild_gl_list(dataObj);
  if(extension_isosurfaces->used == TRUE)
    g_signal_emit(visu, VISU_GET_CLASS (visu)->OpenGLAskForReDraw_signal_id, 0, NULL);
}

/* Callback to set the interface insensitive whenever a file hasn't been loaded. */
void isosurfaces_set_interface_sensitive(gpointer *useless,
                               VisuData *dataObj, gpointer data)
{
  DBG_fprintf(stderr, "Panel Surfaces : caught 'dataReadyForRendering' signal,"
            " setting sensitivity.\n");
  if (dataObj)
    {
      gtk_widget_set_sensitive(isosurfaces_gtk_vbox, TRUE);
      gtk_widget_set_sensitive(buttonOpen, TRUE);
      gtk_widget_set_sensitive(buttonConvert, TRUE);
      g_signal_connect(G_OBJECT(dataObj), "OpenGLObserveMovement",
                   G_CALLBACK(onObserveMovement), NULL);
      handleAutoReorder(GTK_TOGGLE_BUTTON(auto_reorder), dataObj);
    }
  else
    {
      gtk_widget_set_sensitive(isosurfaces_gtk_vbox, FALSE);
      gtk_widget_set_sensitive(buttonOpen, FALSE);
      gtk_widget_set_sensitive(buttonConvert, FALSE);
    }
}

static void onTreeSelectionChanged(GtkTreeSelection *tree, gpointer data)
{
  gboolean res;
  GtkTreeModel *model;
  GtkTreeIter iter;
  int type;
  gboolean empty;

  DBG_fprintf(stderr, "Panel Surfaces : catch 'changed' signal from "
            " the gtkTreeSelection.\n");

  res = gtk_tree_selection_get_selected(tree, &model, &iter);
  if (res)
    gtk_tree_model_get(model, &iter, TYPE_COLUMN, &type, -1);
  else
    type = -1;
    
  empty = !gtk_tree_model_get_iter_first(GTK_TREE_MODEL(isosurfaces_data_list), &iter);

  gtk_widget_set_sensitive(buttonRemoveSurface, (type >= 0));
  gtk_widget_set_sensitive(buttonAddSurface, (type == SURFACE_TYPE_FILE_DENPOT));
  gtk_widget_set_sensitive(buttonEditAll, !empty);
  gtk_widget_set_sensitive(buttonEdit, (type == SURFACE_TYPE_SURF));
}

static void onAddButtonClicked(GtkButton *button, gpointer data)
{
  gboolean rebuild, valid;
  GtkTreeIter iter;

  valid = getSelectedRow(&iter);
  g_return_if_fail(valid);

  rebuild = panel_isosurfaces_add(&iter, FALSE, 0., (gchar*)0);
  if (rebuild)
    g_idle_add(isosurfaces_rebuild_gl_list_in_order_and_redraw, (gpointer)0);
}
static void onRemoveButtonClicked(GtkButton *button, gpointer data)
{
  gboolean rebuild, valid;
  GtkTreeIter iter;

  valid = getSelectedRow(&iter);
  g_return_if_fail(valid);

  rebuild = panel_isosurfaces_remove(&iter);
  if (rebuild)
    g_idle_add(isosurfaces_rebuild_gl_list_in_order_and_redraw, (gpointer)0);
}
static void onNameEdited(GtkCellRendererText *cellrenderertext,
                   gchar *path, gchar *text, gpointer user_data)
{
  GtkTreeIter iter;
  gboolean status, new;
  int type, surfId;
  Surfaces *surf;
  SurfaceResource *res, *res_old;
  GdkPixbuf *pixbuf;

  status = gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(isosurfaces_data_list),
                                     &iter, path);
  g_return_if_fail(status);

  /* We get the Surfaces of the edited object. */
  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iter,
                 DATA_SURF_COLUMN, &surf,
                 NUMBER_COLUMN, &surfId,
                 TYPE_COLUMN, &type, -1);
  g_return_if_fail(type == SURFACE_TYPE_SURF);
  g_return_if_fail(surf);

  /* Save previous resource. */
  res_old = isosurfacesGet_surfaceResource(surf, surfId);

  /* We change the resource of the edited surface. */
  res = isosurfacesGet_resourceFromName(text, &new);
  isosurfacesSet_surfaceResource(surf, surfId, res);
  
  /* If the resource is new, we copy the value of previous
     resource into the new. */
  if (new)
    isosurfacesCopy_resource(res, res_old);
  else
    {
      /* We need to change the visibility and color of the
       surface since the new resource is different from old one. */
      pixbuf = colorComboBoxBuild_colorStamp(res->color, TRUE);
      gtk_tree_store_set(isosurfaces_data_list, &iter,
                   PIXBUF_COLUMN, (gpointer)pixbuf, -1);
      g_object_unref(pixbuf);
      gtk_tree_store_set(isosurfaces_data_list, &iter,
                   SHOW_COLUMN, res->rendered, -1);
      /* Since properties have changed, we need to redraw. */
      isosurfaces_rebuild_gl_list_and_redraw();
    }
  gtk_tree_store_set(isosurfaces_data_list, &iter,
                 NAME_COLUMN, text, -1);
  DBG_fprintf(stderr, "Panel Isosurfaces : set surface resource to '%s'.\n",
                  surf->resources[isosurfacesGet_surfacePosition(surf, surfId)]->surfnom);
}
static void onPotentialValueEdited(GtkCellRendererText *cellrenderertext,
                           gchar *path, gchar *text, gpointer user_data)
{
  GtkTreeIter iterFather;
  GtkTreeIter iter;
  float new_value = atof(text);
  Surfaces *surf;
  ScalarField *field;
  int type, idSurf;
  double minmax[2];
  gboolean status, empty;
  gchar *name;

  status = gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(isosurfaces_data_list),
                                     &iter, path);
  g_return_if_fail(status);

  gtk_tree_model_iter_parent(GTK_TREE_MODEL(isosurfaces_data_list),
                       &iterFather, &iter);
  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iterFather,
                 DATA_FIELD_COLUMN, &field,
                 DATA_SURF_COLUMN, &surf,
                 TYPE_COLUMN, &type, -1);
  g_return_if_fail(type == SURFACE_TYPE_FILE_DENPOT);
  g_return_if_fail(surf && field);

  scalarFieldGet_minMax(field, minmax);
  g_return_if_fail(new_value >= minmax[0] && new_value <= minmax[1]);

  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iter,
                 NAME_COLUMN, &name,
                 NUMBER_COLUMN, &idSurf, -1);
  DBG_fprintf(stderr, "Panel Isosurfaces : remove surface with id %d ('%s').\n",
            idSurf, surf->resources[isosurfacesGet_surfacePosition(surf, idSurf)]->surfnom);

  /* We remove the surface. */
  empty = isosurfacesRemove(surf, idSurf);
  if (empty)
    {
      isosurfacesFree(surf);
      surf = (Surfaces*)0;
    }
  
  /* We add the new surface. */
  DBG_fprintf(stderr, "Panel Isosurfaces : create surface with id %d.\n", idSurf);
  status = pot2surfCreate(&surf, field, new_value, idSurf, name);

  /* We readd the surf pointer if this one has changed. */
  gtk_tree_store_set(isosurfaces_data_list, &iterFather,
                 DATA_SURF_COLUMN, surf, -1);

  isosurfaces_update_data_list(surf, &iterFather);

  g_idle_add(isosurfaces_rebuild_gl_list_in_order_and_redraw, (gpointer)0);
}

static void onObserveMovement(VisuData *dataObj, gboolean start, gpointer data)
{
  if (!start && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_reorder)))
    isosurfaces_rebuild_gl_list_in_order_and_redraw((gpointer)0);
}
static void handleAutoReorder(GtkToggleButton *toggle, VisuData *dataObj)
{
  if (gtk_toggle_button_get_active(toggle))
    moveSignal = g_signal_connect(G_OBJECT(dataObj), "OpenGLThetaPhiOmega",
                          G_CALLBACK(isosurfaces_rebuild_gl_list_in_order), NULL);
  else
    g_signal_handler_disconnect(G_OBJECT(dataObj), moveSignal);
}
static void onReorderToggled(GtkToggleButton *toggle, gpointer data)
{
  VisuData *dataObj;

  dataObj = toolPanelGet_visuData(TOOL_PANEL(panelSurfaces));
  g_return_if_fail(dataObj);

  handleAutoReorder(toggle, dataObj);
}

static void onDataReady(GObject *visu, VisuData *dataObj, gpointer data)
{
  GtkTreeIter iter, iterChild;
  gboolean valid, rebuild, *flag;
  int type, res, i;
  Surfaces *surf;
  ScalarField *field;
  gchar *file, *fileCpy, *fileExtPosition;
  GString *dataFile;
  float isoValues[256];
  int nIsoValues;
  double minmax[2];
  
  DBG_fprintf(stderr, "Panel Surfaces : caught the 'dataReadyForRendering' signal.\n");
  /* Store all isovalues into isoValues array. */
  nIsoValues = 0;
  /* Remove all scalar-fields. */
  rebuild = FALSE;
  valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
  while (valid)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iter,
                         DATA_FIELD_COLUMN, &field,
                         DATA_SURF_COLUMN, &surf,
                         TYPE_COLUMN, &type, -1);
      g_return_if_fail(type == SURFACE_TYPE_FILE_DENPOT || type == SURFACE_TYPE_FILE_SURF);

      DBG_fprintf(stderr, " | remove a non persistent scalar field.\n");
      if (surf)
      isosurfacesFree(surf);
      if (field)
      {
        /* We clear the field. */
        scalarFieldFree(field);
        /* We get all iso values associated and still stored in the tree. */
        valid = gtk_tree_model_iter_children(GTK_TREE_MODEL(isosurfaces_data_list),
                                     &iterChild, &iter);
        while (valid)
          {
            gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iterChild,
                         POTENTIAL_COLUMN, isoValues + nIsoValues, -1);
            nIsoValues = MIN(255, nIsoValues + 1);
            valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list),
                                     &iterChild);
          }
      }
      rebuild = TRUE;
      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
    }
  gtk_tree_store_clear(GTK_TREE_STORE(isosurfaces_data_list));
  gtk_list_store_clear(GTK_LIST_STORE(fields_data_list));
  
  /* If the flag of autoload is not checked or no data is available, we return. */
  if (!dataObj || !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data)))
    {
      /* If rebuild is TRUE, we rebuild the list to empty. */
      if (rebuild)
        {
          DBG_fprintf(stderr, "Panel Surfaces : reorder and build the list.\n");
          isosurfaces_rebuild_gl_list_in_order(dataObj, visuDataGet_openGLView(dataObj),
                                     GINT_TO_POINTER(TRUE));
        }
      return;
    }
  
  /* Read if the new file has the SCALAR_FIELD_DEFINED_IN_STRUCT_FILE flag. */
  flag = (gboolean*)visuDataGet_property(dataObj, SCALAR_FIELD_DEFINED_IN_STRUCT_FILE);
  file = visuDataGet_file(dataObj, 0, (FileFormat**)0);
  fileCpy = g_strdup(file);
  if (!flag)
    {
      /* We try to find a surf file with the right name. */
      fileExtPosition = g_strrstr(fileCpy, ".");
      if (fileExtPosition)
      *fileExtPosition = '\0';
      dataFile = g_string_new("");
      g_string_printf(dataFile, "%s.%s", fileCpy, "surf");
      g_free(fileCpy);
      DBG_fprintf(stderr, "Panel Surfaces : try to load a new surface file"
              " ('%s') from the name of the rendered file.\n", dataFile->str);
      fileCpy = dataFile->str;
      g_string_free(dataFile, FALSE);
      if (!g_file_test(fileCpy, G_FILE_TEST_EXISTS))
      {
          g_free(fileCpy);
        fileCpy = (gchar*)0;
          DBG_fprintf(stderr, " | file doesn't exist.\n");
        }
    }
  if (fileCpy)
    {
      res = panelIsosurfacesLoad_file(fileCpy, TRUE, dataObj, (OptionTable*)0);
      if (!res)
        rebuild = TRUE;
      g_free(fileCpy);
      /* We create the surfaces for the values readed from
       isoValues. */
      valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(isosurfaces_data_list), &iter);
      if (valid)
      {
        gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iter,
                       DATA_FIELD_COLUMN, &field,
                       TYPE_COLUMN, &type, -1);
        if (type == SURFACE_TYPE_FILE_DENPOT)
          {
            scalarFieldGet_minMax(field, minmax);
            for (i = 0; i < nIsoValues; i++)
            if (isoValues[i] > minmax[0] && isoValues[i] < minmax[1])
              panel_isosurfaces_add(&iter, TRUE, isoValues[i], (gchar*)0);
          }
      }
    }
    
  /* If rebuild is TRUE, we reorder. */
  if (rebuild)
    {
      DBG_fprintf(stderr, "Panel Surfaces : reorder and build the list.\n");
      isosurfaces_rebuild_gl_list_in_order(dataObj, visuDataGet_openGLView(dataObj),
                                 GINT_TO_POINTER(TRUE));
    }
}

static gboolean onPopupClicked(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  gtk_widget_destroy(widget);
  return FALSE;
}
static gboolean onTreeViewClicked(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
  gboolean valid;
  GtkTreePath *path;
  GtkTreeIter iter;
  int type, row;
  ScalarField *field;
  GtkWidget *win, *vbox, *wd, *table, *align;
  gchar *name, *markup, *comment;
  gint x, y;
  GList *options, *tmplst;

  if (event->button != 3)
    return FALSE;

  DBG_fprintf(stderr, "Panel Surfaces : right clic detected.\n");

  valid = gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), (gint)event->x,
                              (gint)event->y, &path, (GtkTreeViewColumn**)0,
                                        (gint*)0, (gint*)0);
  if (!valid)
    return FALSE;

  valid = gtk_tree_model_get_iter(GTK_TREE_MODEL(isosurfaces_data_list), &iter, path);
  gtk_tree_path_free(path);
  if (!valid)
    return FALSE;

  gtk_tree_model_get(GTK_TREE_MODEL(isosurfaces_data_list), &iter,
                 DATA_FIELD_COLUMN, &field,
                 TYPE_COLUMN, &type, -1);
  if (type != SURFACE_TYPE_FILE_DENPOT)
    return FALSE;

  g_return_val_if_fail(field, FALSE);

  /* Ok, now, we have the scalar field.
     We create a popup window with info. */
  win = gtk_window_new(GTK_WINDOW_POPUP);
  gtk_widget_set_events(win, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK);
  gtk_grab_add(win);
  gdk_display_get_pointer(gdk_screen_get_display(gtk_widget_get_screen(widget)),
                    (GdkScreen**)0, &x, &y, NULL);

  gtk_window_move(GTK_WINDOW(win), x, y);
  g_signal_connect(G_OBJECT(win), "button-press-event",
               G_CALLBACK(onPopupClicked), (gpointer)0);
  gtk_container_set_border_width(GTK_CONTAINER(win), 20);
  vbox = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(win), vbox);

  /* Print the File name. */
  name = g_path_get_basename(scalarFieldGet_filename(field));
  markup = g_markup_printf_escaped("<span size=\"larger\"><b>%s</b></span>", name);
  g_free(name);
  wd = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(wd), 0., 0.5);
  gtk_label_set_markup(GTK_LABEL(wd), markup);
  g_free(markup);
  gtk_box_pack_start(GTK_BOX(vbox), wd, FALSE, FALSE, 0);

  /* Print a list of all interesting characteristics of the file. */
  align = gtk_alignment_new(0., 0.5, 1., 1.);
  gtk_alignment_set_padding(GTK_ALIGNMENT(align), 15, 0, 15, 0);
  gtk_box_pack_start(GTK_BOX(vbox), align, FALSE, FALSE, 0);
  options = scalarFieldGet_allOptions(field);
  table = gtk_table_new(1 + g_list_length(options), 2, FALSE);
  gtk_container_add(GTK_CONTAINER(align), table);

  wd = gtk_label_new("");
  gtk_misc_set_alignment(GTK_MISC(wd), 1., 0.5);
  gtk_label_set_markup(GTK_LABEL(wd), _("<span style=\"italic\">Comment:</span>"));
  gtk_table_attach(GTK_TABLE(table), wd, 0, 1, 0, 1, GTK_FILL, GTK_SHRINK, 5, 0);

  comment = scalarFieldGet_commentary(field);
  if (comment)
    wd = gtk_label_new(comment);
  else
    wd = gtk_label_new(_("None"));
  gtk_misc_set_alignment(GTK_MISC(wd), 0., 0.5);
  gtk_table_attach(GTK_TABLE(table), wd, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 5, 0);
  
  row = 1;
  tmplst = options;
  while(tmplst)
    {
      wd = gtk_label_new("");
      gtk_misc_set_alignment(GTK_MISC(wd), 1., 0.5);
      markup = g_markup_printf_escaped("<span style=\"italic\">%s:</span>",
                                       toolOptionsGet_name((Option*)tmplst->data));
      gtk_label_set_markup(GTK_LABEL(wd), markup);
      g_free(markup);
      gtk_table_attach(GTK_TABLE(table), wd, 0, 1, row, row + 1, GTK_FILL, GTK_SHRINK, 5, 0);

      wd = gtk_label_new("");
      gtk_misc_set_alignment(GTK_MISC(wd), 0., 0.5);
      markup = toolOptionsGet_valueAndLabel((Option*)tmplst->data);
      gtk_label_set_markup(GTK_LABEL(wd), markup);
      g_free(markup);
      gtk_table_attach(GTK_TABLE(table), wd, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 5, 0);
      
      row += 1;
      tmplst = g_list_next(tmplst);
    }
  g_list_free(options);

  gtk_widget_show_all(win);

  return FALSE;
}

GtkListStore* panelIsosurfacesGet_listStore()
{
  return fields_data_list;
}


ToolPanel* initPanelSurfaces()
{
  /* Long description */
  char *cl = _("Drawing iso-surfaces");
  /* Short description */
  char *tl = _("Isosurfaces");

  panelSurfaces = toolPanelNew_withIconFromPath("Panel_surfaces", cl, tl, "stock-isosurfaces.png");
  toolPanelSet_dockable(TOOL_PANEL(panelSurfaces), TRUE);

  /* Register the extension as an opengl one */
  identifier_isosurfaces = openGLObjectList_new(1);
  extension_isosurfaces = 
    OpenGLExtension_new(tl, cl, identifier_isosurfaces, 
                  isosurfaces_rebuild_gl_list);
  extension_isosurfaces->used = 0;
/*   OpenGLExtensionSet_priority(extension_isosurfaces, OPENGL_EXTENSION_PRIORITY_NORMAL);  */
  OpenGLExtensionSet_sensitiveToRenderingMode(extension_isosurfaces, TRUE);
  OpenGLExtensionSet_saveOpenGLState(extension_isosurfaces, TRUE);
  OpenGLExtensionRegister(extension_isosurfaces);

  surfaceOrder = isosurfacesOrder_new();
  fields_data_list =  gtk_list_store_new(NB_COLUMN_FIELD,
                               G_TYPE_STRING,
                               G_TYPE_POINTER);

  /* Create the widgets. */
  isosurfaces_create_gtk_interface(TOOL_PANEL(panelSurfaces));
  gtk_widget_set_sensitive(isosurfaces_gtk_vbox, FALSE);
  gtk_widget_set_sensitive(buttonOpen, FALSE);
  gtk_widget_set_sensitive(buttonConvert, FALSE);
  /* Add the signal for the vBoxPlanes. */
  g_signal_connect(G_OBJECT(visu), "dataReadyForRendering",
               G_CALLBACK(isosurfaces_set_interface_sensitive), (gpointer)0);

  if(!panelSurfaces)
    return NULL;

  return TOOL_PANEL(panelSurfaces);
}
 


Generated by  Doxygen 1.6.0   Back to index