/*   EXTRAITS DE LA LICENCE
	Copyright CEA, contributeurs : Luc BILLARD et Damien
	CALISTE, laboratoire L_Sim, (2001-2006)
  
	Adresse mèl :
	BILLARD, non joignable par mèl ;
	CALISTE, damien P caliste AT cea 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 et Damien
	CALISTE, laboratoire L_Sim, (2001-2006)

	E-mail address:
	BILLARD, not reachable any more ;
	CALISTE, damien P caliste AT cea 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 "panelDataFile.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <gtk/gtk.h>

#include <gtk_main.h>
#include <visu_object.h>
#include <visu_tools.h>
#include <support.h>
#include <coreTools/toolShade.h>
#include <extraGtkFunctions/gtk_numericalEntryWidget.h>
#include <renderingBackend/visu_windowInterface.h>
#include <gtk_renderingWindowWidget.h>

subPanel *panelDataFile;
int nbColumns;
gboolean panelDataFileIsInitiated;
gboolean flagDataFileIsLoaded;

#define RED_DATA_LABEL   _("R")
#define GREEN_DATA_LABEL _("G")
#define BLUE_DATA_LABEL  _("B")
#define HUE_DATA_LABEL   _("H")
#define SAT_DATA_LABEL   _("S")
#define VAL_DATA_LABEL   _("V")

char* labelRGB[3];
char* labelHSV[3];

#define COLOR_PREVIEW_WIDTH  120
#define COLOR_PREVIEW_HEIGHT 15
#define COLOR_PREVIEW_BITS   8

#define COLOR_TRANSFORMATION_WIDTH  60
#define COLOR_TRANSFORMATION_HEIGHT 40

#define MIN_MAX_NO_DATA_FILE _("<span style=\"italic\">No data file loaded</span>")
#define DATA_FILE_EXTENSION "dat"
#define DATA_FILE_NO_FILE_MESSAGE _("No data file loaded, use the above Open button.")

void createInteriorDataFile();
void makeMinMaxLabels(VisuData *data);
void makeColumnSelection(VisuData *data);
void makeColorPreview(VisuData *data);
void makePreSetColorRange(GList *listOfShade);

/* Linkable widgets */
GtkWidget *containerDataFilePanel;
GtkWidget *vBoxDataFileOption;
GtkWidget *openDataFileButton;
GtkWidget *checkbuttonData;
GtkWidget *checkbuttonAutoLoad;
GtkWidget *statusbarDataFile;
guint statusDataFileContextId;
GtkWidget *expanderNormalize;
GtkWidget *radioNormalized;
GtkWidget *radioMinMax;
GtkWidget *entryDataMax;
GtkWidget *entryDataMin;
GtkWidget *spinbuttonDataChA[3];
GtkWidget *spinbuttonDataChB[3];
GtkWidget *comboboxDataCh[3];
GtkWidget *radiobuttonDataRGB;
GtkWidget *radiobuttonDataHSV;
GtkWidget *labelChannel[3];
GdkPixbuf *pixbufColorPreview;
GtkWidget *colorPreview;
GtkWidget *labelPreview;
GtkWidget *readMinMaxValues;
GtkWidget *comboPreSetColorRange;
GtkWidget *checkPreSetColorRange;
GtkWidget *checkHideMinValues;
GtkWidget *spinHideMinValues;
GtkWidget *entryHideMinValues;

GtkListStore *listStorePreSetColorRange;
enum
  {
    COLUMN_ICON, /* A pixmap to represent the color range */
    COLUMN_NAME,  /* The label shown */
    COLUMN_POINTER_TO_DATA,  /* Pointer to values that need to be applied. */
    N_COLUMNS
  };


/* Signals that need to be suspended */
gulong signalComboColumnId[3];
gulong signalSpinDataChA[3];
gulong signalSpinDataChB[3];
gulong signalRadioRGB;
gulong signalRadioHSV;
gulong signalAskForHide;
gulong signalSpinHide;

/* Callbacks */
void visuFileReset(GObject *obj, VisuData *dataObj, gpointer data);
void loadDataFile(GtkButton *button, gpointer data);
void useDataFileColor(GtkToggleButton *toggle, gpointer data);
gboolean checkDataFilesOnEnter(gpointer data);
void onScaleTypeChange(GtkToggleButton *toggle, gpointer data);
void onEntryMinMaxChangeValue(NumericalEntry *entry, double value, gpointer data);
void onSpinChAChangeValue(GtkSpinButton *spinbutton, gpointer user_data);
void onSpinChBChangeValue(GtkSpinButton *spinbutton, gpointer user_data);
void onComboColChange(GtkComboBox *combo, gpointer data);
void onColorTypeChange(GtkToggleButton *toggle, gpointer data);
void onColorPreSetChange(GtkToggleButton *toggle, gpointer data);
void onComboPreSetChange(GtkComboBox *combo, gpointer data);
void onSpinHideMinValuesChange(GtkSpinButton *spin, gpointer data);
void onEntryHideMinValuesChange(NumericalEntry *entry, double value, gpointer data);
void onCheckHideMinValuesChange(GtkToggleButton *toggle, gpointer data);
void onSpinHideMinValuesChange(GtkSpinButton *spinbutton, gpointer user_data);
static void onAskForHideNodes(VisuData *visuData, gboolean *redraw, gpointer data);

/* Local methods. */
void applyHideMinValues(VisuData *visuData, gboolean askRedraw);



subPanel* initPanelDataFile()
{
  char *cl = _("Colorize with data");
  char *tl = _("Data color");

  labelRGB[0] = RED_DATA_LABEL;
  labelRGB[1] = GREEN_DATA_LABEL;
  labelRGB[2] = BLUE_DATA_LABEL;
  labelHSV[0] = HUE_DATA_LABEL;
  labelHSV[1] = SAT_DATA_LABEL;
  labelHSV[2] = VAL_DATA_LABEL;

  /* We create the structure that store the color ranges */
  listStorePreSetColorRange = gtk_list_store_new (3,
						  GDK_TYPE_PIXBUF,
						  G_TYPE_STRING,
						  G_TYPE_POINTER);

/*   child = createInteriorDataFile(); */
  containerDataFilePanel = gtk_vbox_new (FALSE, 0);
  panelDataFile = createSubPanelWithIconFromStock(cl, tl, GTK_STOCK_SELECT_COLOR,
						  containerDataFilePanel,
						  checkDataFilesOnEnter ,
						  (onChangePanelFunc)0);
  if (!panelDataFile)
    return (subPanel*)0;
						 
  /* call the visu add routine */
  addSubPanel(panelDataFile);

  /* Local variables */
  panelDataFileIsInitiated = FALSE;
  flagDataFileIsLoaded = FALSE;

  return panelDataFile;
}

void createInteriorDataFile()
{
  GtkWidget *scrolledwindow1;
  GtkWidget *viewport1;
  GtkWidget *vbox;
  GtkWidget *vboxNormalize, *vboxTransformation, *vboxPostProcessing;
  GtkWidget *hbox3;
  GtkWidget *alignment6;
  GtkWidget *hbox9;
  GtkWidget *image3;
  GtkWidget *label19;
  GtkWidget *alignment2;
  GtkWidget *hbox8;
  GtkWidget *frame1;
  GtkWidget *label9;
  GtkWidget *hbox7;
  GSList *radioNormalized_group = NULL;
  GtkWidget *alignment3;
  GtkWidget *table2;
  GtkObject *spinbuttonDataMax_adj;
  GtkObject *spinbuttonDataMin_adj;
  GtkWidget *label7;
  GtkWidget *label8;
  GtkWidget *hbox6;
  GtkWidget *label22;
  GSList *radiobuttonDataRGB_group = NULL;
  GtkWidget *table3;
  GtkWidget *label;
  GtkWidget *label14;
  GtkWidget *label15;
  GtkWidget *label16;
  GtkWidget *label20;
  GtkWidget *label21;
  GtkObject *spinbuttonDataChA1_adj;
  GtkObject *spinbuttonDataChA2_adj;
  GtkObject *spinbuttonDataChA3_adj;
  GtkObject *spinbuttonDataChB1_adj;
  GtkObject *spinbuttonDataChB2_adj;
  GtkObject *spinbuttonDataChB3_adj;
  GtkWidget *alignment5;
  GtkWidget *expanderTransformation, *expanderPostProcessing;
  GtkWidget *hrule;
  GtkTooltips *tooltips;
  GtkCellRenderer *renderer;
  GtkWidget *hboxPreSetColorRange;
  int i;
  GList *list;
  RenderingWindow *window;

  DBG_fprintf(stderr, "Panel DataFile : creating subpanel.\n");

  tooltips = gtk_tooltips_new ();

  checkbuttonData = gtk_check_button_new ();
  gtk_widget_show (checkbuttonData);
  gtk_box_pack_start (GTK_BOX (containerDataFilePanel), checkbuttonData, FALSE, FALSE, 0);

  alignment6 = gtk_alignment_new (0.5, 0.5, 0, 0);
  gtk_widget_show (alignment6);
  gtk_container_add (GTK_CONTAINER (checkbuttonData), alignment6);

  hbox9 = gtk_hbox_new (FALSE, 2);
  gtk_widget_show (hbox9);
  gtk_container_add (GTK_CONTAINER (alignment6), hbox9);

  image3 = gtk_image_new_from_stock ("gtk-select-color", GTK_ICON_SIZE_BUTTON);
  gtk_widget_show (image3);
  gtk_box_pack_start (GTK_BOX (hbox9), image3, FALSE, FALSE, 0);

  label19 = gtk_label_new_with_mnemonic (_("Use color scheme"));
  gtk_widget_set_name(label19, "label_head");
  gtk_widget_show (label19);
  gtk_box_pack_start (GTK_BOX (hbox9), label19, FALSE, FALSE, 0);

  hbox3 = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(containerDataFilePanel), hbox3, FALSE, FALSE, 0);
  gtk_widget_show(hbox3);

  checkbuttonAutoLoad = gtk_check_button_new();
  gtk_box_pack_start(GTK_BOX(hbox3), checkbuttonAutoLoad, TRUE, TRUE, 10);
  gtk_tooltips_set_tip (tooltips, checkbuttonAutoLoad,
			_("Try to load a data file whenever a new V_Sim file is loaded."
			  " For example, if 'example.ascii' has just been opened, V_Sim"
			  " will look for 'example.dat' and will apply it."), NULL);
  gtk_widget_show(checkbuttonAutoLoad);

  label19 = gtk_label_new(_("Auto load data file"));
  gtk_widget_show(label19);
  gtk_container_add(GTK_CONTAINER(checkbuttonAutoLoad), label19);

  openDataFileButton = gtk_button_new_from_stock ("gtk-open");
  gtk_tooltips_set_tip(tooltips, openDataFileButton,
		       _("Choose a file to read the colorization data from."), NULL);
  gtk_box_pack_start(GTK_BOX(hbox3), openDataFileButton, FALSE, FALSE, 10);
  gtk_widget_show (openDataFileButton);
  

  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow1);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  gtk_box_pack_start (GTK_BOX (containerDataFilePanel), scrolledwindow1, TRUE, TRUE, 0);

  viewport1 = gtk_viewport_new (NULL, NULL);
  gtk_widget_show (viewport1);
  gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_widget_show (vbox);
  gtk_container_add (GTK_CONTAINER (viewport1), vbox);
  vBoxDataFileOption = vbox;

  /******************/
  /* Normalize part */
  /******************/
  hbox7 = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hbox7);
  gtk_box_pack_start(GTK_BOX(vbox), hbox7, FALSE, FALSE, 0);

  label = gtk_label_new(_("Normalize input: "));
  gtk_widget_set_name(label, "label_head");
  gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (hbox7), label, TRUE, TRUE, 0);

  radioNormalized = gtk_radio_button_new_with_mnemonic (NULL, _("auto"));
  gtk_widget_show (radioNormalized);
  gtk_box_pack_start (GTK_BOX (hbox7), radioNormalized, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radioNormalized), radioNormalized_group);
  radioNormalized_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radioNormalized));

  radioMinMax = gtk_radio_button_new_with_mnemonic (NULL, _("manual"));
  gtk_widget_show (radioMinMax);
  gtk_box_pack_start (GTK_BOX (hbox7), radioMinMax, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radioMinMax), radioNormalized_group);
  radioNormalized_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radioMinMax));

  expanderNormalize = gtk_expander_new(_("More informations"));
  gtk_widget_show(expanderNormalize);
  gtk_box_pack_start(GTK_BOX (vbox), expanderNormalize, FALSE, FALSE, 0);

  alignment3 = gtk_alignment_new(0.5, 0.5, 1, 1);
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment3), 0, 0, 15, 0);
  gtk_widget_show(alignment3);
  gtk_container_add(GTK_CONTAINER(expanderNormalize), alignment3);

  vboxNormalize = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vboxNormalize);
  gtk_container_add(GTK_CONTAINER(alignment3), vboxNormalize);

  label = gtk_label_new(_("<b>Input data bounds:</b>"));
  gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
  gtk_widget_show (label);
  gtk_box_pack_start(GTK_BOX(vboxNormalize), label, FALSE, FALSE, 0);

  alignment3 = gtk_alignment_new(0.5, 0.5, 0.8, 1);
  gtk_widget_show(alignment3);
  gtk_box_pack_start(GTK_BOX(vboxNormalize), alignment3, FALSE, FALSE, 0);

  table2 = gtk_table_new (1, 4, FALSE);
  gtk_widget_show (table2);
  gtk_container_add (GTK_CONTAINER (alignment3), table2);
  gtk_table_set_col_spacings (GTK_TABLE (table2), 3);

  entryDataMax = numericalEntry_new(1.);
  gtk_entry_set_width_chars(GTK_ENTRY(entryDataMax), 6);
  gtk_table_attach (GTK_TABLE (table2), entryDataMax, 3, 4, 0, 1,
                    GTK_FILL | GTK_EXPAND, (GtkAttachOptions)0, 0, 0);
  gtk_widget_set_sensitive(entryDataMax, FALSE);
  gtk_widget_show(entryDataMax);

  entryDataMin = numericalEntry_new(-1.);
  gtk_entry_set_width_chars(GTK_ENTRY(entryDataMin), 6);
  gtk_table_attach (GTK_TABLE (table2), entryDataMin, 1, 2, 0, 1,
                    GTK_FILL | GTK_EXPAND, (GtkAttachOptions)0, 0, 0);
  gtk_widget_set_sensitive(entryDataMin, FALSE);
  gtk_widget_show(entryDataMin);

  label7 = gtk_label_new (_("Min:"));
  gtk_widget_show (label7);
  gtk_table_attach (GTK_TABLE (table2), label7, 0, 1, 0, 1,
                    (GtkAttachOptions) (0),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (label7), 1, 0.5);

  label8 = gtk_label_new (_("Max:"));
  gtk_widget_show (label8);
  gtk_table_attach (GTK_TABLE (table2), label8, 2, 3, 0, 1,
                    (GtkAttachOptions) (0),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (label8), 1, 0.5);

  label = gtk_label_new(_("<b>Read min/max values:</b>"));
  gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
  gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5);
  gtk_widget_show(label);
  gtk_box_pack_start(GTK_BOX (vboxNormalize), label, FALSE, FALSE, 0);

  readMinMaxValues = gtk_alignment_new (0.5, 0.5, 0.8, 1);
  gtk_widget_show (readMinMaxValues);
  gtk_box_pack_start (GTK_BOX (vboxNormalize), readMinMaxValues, FALSE, FALSE, 0);

  label = gtk_label_new(MIN_MAX_NO_DATA_FILE);
  gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
  gtk_widget_show(label);
  gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
  gtk_container_add(GTK_CONTAINER(readMinMaxValues), label);


  /* Bar */
  alignment2 = gtk_alignment_new(0.5, 0.5, 0.3, 0);
  gtk_widget_show(alignment2);
  gtk_box_pack_start(GTK_BOX(vbox), alignment2, FALSE, FALSE, 8);
  hrule = gtk_hseparator_new();
  gtk_widget_show(hrule);
  gtk_container_add(GTK_CONTAINER(alignment2), hrule);

  /***********************/
  /* Transformation part */
  /***********************/
  label = gtk_label_new(_("Define the color scheme:"));
  gtk_widget_set_name(label, "label_head");
  gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
  gtk_widget_show (label);
  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);

  hboxPreSetColorRange = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hboxPreSetColorRange);
  gtk_box_pack_start(GTK_BOX(vbox), hboxPreSetColorRange, FALSE, FALSE, 0);

  checkPreSetColorRange = gtk_check_button_new();
  gtk_widget_show(checkPreSetColorRange);
  gtk_box_pack_start (GTK_BOX (hboxPreSetColorRange), checkPreSetColorRange, TRUE, TRUE, 0);
  
  label = gtk_label_new(_("Use preset:"));
  gtk_widget_show (label);
  gtk_container_add(GTK_CONTAINER(checkPreSetColorRange), label);

  comboPreSetColorRange = gtk_combo_box_new_with_model(GTK_TREE_MODEL(listStorePreSetColorRange));
  renderer = gtk_cell_renderer_pixbuf_new();
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(comboPreSetColorRange), renderer, FALSE);
  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(comboPreSetColorRange),
				renderer, "pixbuf", COLUMN_ICON);
  renderer = gtk_cell_renderer_text_new();
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(comboPreSetColorRange), renderer, FALSE);
  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(comboPreSetColorRange),
				renderer, "text", COLUMN_NAME);
  gtk_widget_show(comboPreSetColorRange);
  gtk_box_pack_start(GTK_BOX (hboxPreSetColorRange), comboPreSetColorRange, FALSE, FALSE, 0);

  expanderTransformation = gtk_expander_new(_("More informations"));
  gtk_expander_set_expanded(GTK_EXPANDER(expanderTransformation), FALSE);
  gtk_widget_show(expanderTransformation);
  gtk_box_pack_start(GTK_BOX (vbox), expanderTransformation, FALSE, FALSE, 0);

  alignment3 = gtk_alignment_new(0.5, 0.5, 1, 1);
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment3), 0, 0, 15, 0);
  gtk_widget_show(alignment3);
  gtk_container_add(GTK_CONTAINER(expanderTransformation), alignment3);

  vboxTransformation = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vboxTransformation);
  gtk_container_add(GTK_CONTAINER(alignment3), vboxTransformation);

  hbox6 = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hbox6);
  gtk_box_pack_start (GTK_BOX (vboxTransformation), hbox6, FALSE, FALSE, 0);

  label = gtk_label_new(_("<b>Colour space: </b>"));
  gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
  gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (hbox6), label, TRUE, TRUE, 0);

  radiobuttonDataRGB = gtk_radio_button_new_with_mnemonic (NULL, _("RGB"));
  gtk_widget_show (radiobuttonDataRGB);
  gtk_box_pack_start (GTK_BOX (hbox6), radiobuttonDataRGB, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobuttonDataRGB), radiobuttonDataRGB_group);
  radiobuttonDataRGB_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobuttonDataRGB));

  radiobuttonDataHSV = gtk_radio_button_new_with_mnemonic (NULL, _("HSV"));
  gtk_widget_show (radiobuttonDataHSV);
  gtk_box_pack_start (GTK_BOX (hbox6), radiobuttonDataHSV, FALSE, FALSE, 0);
  gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobuttonDataHSV), radiobuttonDataRGB_group);
  radiobuttonDataRGB_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobuttonDataHSV));

  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobuttonDataHSV), TRUE);

  table3 = gtk_table_new (3, 7, FALSE);
  gtk_widget_show (table3);
  gtk_box_pack_start (GTK_BOX (vboxTransformation), table3, FALSE, FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (table3), 3);
  gtk_table_set_row_spacings (GTK_TABLE (table3), 3);

  labelChannel[0] = gtk_label_new (_("R"));
  gtk_widget_show (labelChannel[0]);
  gtk_table_attach (GTK_TABLE (table3), labelChannel[0], 0, 1, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (labelChannel[0]), 0, 0.5);

  labelChannel[1] = gtk_label_new (_("G"));
  gtk_widget_show (labelChannel[1]);
  gtk_table_attach (GTK_TABLE (table3), labelChannel[1], 0, 1, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (labelChannel[1]), 0, 0.5);

  labelChannel[2] = gtk_label_new (_("B"));
  gtk_widget_show (labelChannel[2]);
  gtk_table_attach (GTK_TABLE (table3), labelChannel[2], 0, 1, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_misc_set_alignment (GTK_MISC (labelChannel[2]), 0, 0.5);

  label14 = gtk_label_new ("=");
  gtk_widget_show (label14);
  gtk_table_attach (GTK_TABLE (table3), label14, 1, 2, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  label14 = gtk_label_new ("=");
  gtk_widget_show (label14);
  gtk_table_attach (GTK_TABLE (table3), label14, 1, 2, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  label14 = gtk_label_new ("=");
  gtk_widget_show (label14);
  gtk_table_attach (GTK_TABLE (table3), label14, 1, 2, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  label15 = gtk_label_new ("+");
  gtk_widget_show (label15);
  gtk_table_attach (GTK_TABLE (table3), label15, 3, 4, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  label15 = gtk_label_new ("+");
  gtk_widget_show (label15);
  gtk_table_attach (GTK_TABLE (table3), label15, 3, 4, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  label15 = gtk_label_new ("+");
  gtk_widget_show (label15);
  gtk_table_attach (GTK_TABLE (table3), label15, 3, 4, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  label16 = gtk_label_new ("\303\227");
  gtk_widget_show (label16);
  gtk_table_attach (GTK_TABLE (table3), label16, 5, 6, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  label20 = gtk_label_new ("\303\227");
  gtk_widget_show (label20);
  gtk_table_attach (GTK_TABLE (table3), label20, 5, 6, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  label21 = gtk_label_new ("\303\227");
  gtk_widget_show (label21);
  gtk_table_attach (GTK_TABLE (table3), label21, 5, 6, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);

  spinbuttonDataChA1_adj = gtk_adjustment_new (1, -5, 5, 0.01, 0.1, 0.1);
  spinbuttonDataChA[0] = gtk_spin_button_new (GTK_ADJUSTMENT (spinbuttonDataChA1_adj), 0.001, 2);
  gtk_widget_show (spinbuttonDataChA[0]);
  gtk_table_attach (GTK_TABLE (table3), spinbuttonDataChA[0], 4, 5, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbuttonDataChA[0]), TRUE);

  spinbuttonDataChA2_adj = gtk_adjustment_new (1, -5, 5, 0.01, 0.1, 0.1);
  spinbuttonDataChA[1] = gtk_spin_button_new (GTK_ADJUSTMENT (spinbuttonDataChA2_adj), 0.001, 2);
  gtk_widget_show (spinbuttonDataChA[1]);
  gtk_table_attach (GTK_TABLE (table3), spinbuttonDataChA[1], 4, 5, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbuttonDataChA[1]), TRUE);

  spinbuttonDataChA3_adj = gtk_adjustment_new (1, -5, 5, 0.01, 0.1, 0.1);
  spinbuttonDataChA[2] = gtk_spin_button_new (GTK_ADJUSTMENT (spinbuttonDataChA3_adj), 0.001, 2);
  gtk_widget_show (spinbuttonDataChA[2]);
  gtk_table_attach (GTK_TABLE (table3), spinbuttonDataChA[2], 4, 5, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbuttonDataChA[2]), TRUE);

  spinbuttonDataChB1_adj = gtk_adjustment_new (0, -5, 5, 0.01, 0.1, 0.1);
  spinbuttonDataChB[0] = gtk_spin_button_new (GTK_ADJUSTMENT (spinbuttonDataChB1_adj), 0.001, 2);
  gtk_widget_show (spinbuttonDataChB[0]);
  gtk_table_attach (GTK_TABLE (table3), spinbuttonDataChB[0], 2, 3, 0, 1,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbuttonDataChB[0]), TRUE);

  spinbuttonDataChB2_adj = gtk_adjustment_new (0, -5, 5, 0.01, 0.1, 0.1);
  spinbuttonDataChB[1] = gtk_spin_button_new (GTK_ADJUSTMENT (spinbuttonDataChB2_adj), 0.001, 2);
  gtk_widget_show (spinbuttonDataChB[1]);
  gtk_table_attach (GTK_TABLE (table3), spinbuttonDataChB[1], 2, 3, 1, 2,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbuttonDataChB[1]), TRUE);

  spinbuttonDataChB3_adj = gtk_adjustment_new (0, -5, 5, 0.01, 0.1, 0.1);
  spinbuttonDataChB[2] = gtk_spin_button_new (GTK_ADJUSTMENT (spinbuttonDataChB3_adj), 0.001, 2);
  gtk_widget_show (spinbuttonDataChB[2]);
  gtk_table_attach (GTK_TABLE (table3), spinbuttonDataChB[2], 2, 3, 2, 3,
                    (GtkAttachOptions) (GTK_FILL),
                    (GtkAttachOptions) (0), 0, 0);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbuttonDataChB[2]), TRUE);

  for (i = 0; i < 3; i++)
    {
      comboboxDataCh[i] = gtk_combo_box_new_text ();
      gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxDataCh[i]), "1.");
      gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), 0);
      gtk_widget_show (comboboxDataCh[i]);
      gtk_table_attach (GTK_TABLE (table3), comboboxDataCh[i], 6, 7, i, i + 1,
			(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
			(GtkAttachOptions) (GTK_FILL), 0, 0);
    }

  hbox8 = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hbox8);
  gtk_box_pack_start(GTK_BOX(vbox), hbox8, FALSE, FALSE, 0);

  label = gtk_label_new(_("Color range preview: "));
  gtk_widget_show (label);
  gtk_box_pack_start (GTK_BOX (hbox8), label, FALSE, FALSE, 0);

  pixbufColorPreview = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE,
				      COLOR_PREVIEW_BITS,
				      COLOR_PREVIEW_WIDTH,
				      COLOR_PREVIEW_HEIGHT);
  colorPreview = create_pixmap (mainWindow, NULL);
  gtk_widget_set_size_request (colorPreview, COLOR_PREVIEW_WIDTH,
			       COLOR_PREVIEW_HEIGHT);
  gtk_box_pack_start (GTK_BOX (hbox8), colorPreview, TRUE, TRUE, 0);

  labelPreview = gtk_label_new(_("<span style=\"italic\">No preview available</span>"));
  gtk_label_set_use_markup(GTK_LABEL(labelPreview), TRUE);
  gtk_widget_show (labelPreview);
  gtk_box_pack_start (GTK_BOX (hbox8), labelPreview, TRUE, TRUE, 0);

  /* Bar */
  alignment2 = gtk_alignment_new(0.5, 0.5, 0.3, 0);
  gtk_widget_show(alignment2);
  gtk_box_pack_start(GTK_BOX(vbox), alignment2, FALSE, FALSE, 8);
  hrule = gtk_hseparator_new();
  gtk_widget_show(hrule);
  gtk_container_add(GTK_CONTAINER(alignment2), hrule);

  /***********************/
  /* Post treatment part */
  /***********************/
  expanderPostProcessing = gtk_expander_new(_("Post processing"));
  gtk_widget_set_name(gtk_expander_get_label_widget(GTK_EXPANDER(expanderPostProcessing)),
		      "label_head");
  gtk_expander_set_expanded(GTK_EXPANDER(expanderPostProcessing), TRUE);
  gtk_widget_show(expanderPostProcessing);
  gtk_box_pack_start(GTK_BOX(vbox), expanderPostProcessing, FALSE, FALSE, 0);

  vboxPostProcessing = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vboxPostProcessing);
  gtk_container_add(GTK_CONTAINER(expanderPostProcessing), vboxPostProcessing);

  hbox7 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox7);
  gtk_box_pack_start(GTK_BOX(vboxPostProcessing), hbox7, FALSE, FALSE, 0);

  checkHideMinValues = gtk_check_button_new();
  gtk_widget_show(checkHideMinValues);
  gtk_box_pack_start(GTK_BOX(hbox7), checkHideMinValues, FALSE, FALSE, 0);
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkHideMinValues), FALSE);
  
  label = gtk_label_new(_("Hide elements"));
  gtk_widget_show(label);
  gtk_container_add(GTK_CONTAINER(checkHideMinValues), label);

  label = gtk_label_new(_(" whose value from"));
  gtk_widget_show(label);
  gtk_box_pack_start(GTK_BOX(hbox7), label, FALSE, FALSE, 0);

  hbox7 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox7);
  gtk_box_pack_start(GTK_BOX(vboxPostProcessing), hbox7, FALSE, FALSE, 0);

  label = gtk_label_new(_("col. "));
  gtk_widget_show(label);
  gtk_misc_set_alignment(GTK_MISC(label), 1., 0.5);
  gtk_box_pack_start(GTK_BOX(hbox7), label, TRUE, TRUE, 0);

  spinHideMinValues = gtk_spin_button_new_with_range(1, 1, 1);
  gtk_widget_show(spinHideMinValues);
  gtk_box_pack_start(GTK_BOX(hbox7), spinHideMinValues, FALSE, FALSE, 0);

  label = gtk_label_new(_(" is lower than "));
  gtk_widget_show(label);
  gtk_box_pack_start(GTK_BOX(hbox7), label, FALSE, FALSE, 0);

  entryHideMinValues = numericalEntry_new(1.);
  gtk_entry_set_width_chars(GTK_ENTRY(entryHideMinValues), 10);
  gtk_widget_show(entryHideMinValues);
  gtk_box_pack_start(GTK_BOX(hbox7), entryHideMinValues, FALSE, FALSE, 0);


  /**************/
  /* Status bar */
  /**************/
  statusbarDataFile = gtk_statusbar_new ();
  gtk_widget_show (statusbarDataFile);
  gtk_box_pack_end (GTK_BOX (containerDataFilePanel), statusbarDataFile, FALSE, FALSE, 0);
  gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbarDataFile), FALSE);
  statusDataFileContextId = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbarDataFile),
							 _("Description of loaded data file."));
  gtk_statusbar_push(GTK_STATUSBAR(statusbarDataFile), statusDataFileContextId,
		     DATA_FILE_NO_FILE_MESSAGE);

  gtk_widget_set_sensitive(vBoxDataFileOption, FALSE);
  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window || !renderingWindowGet_visuData(window))
    gtk_widget_set_sensitive(openDataFileButton, FALSE);
  else
    {
      if (renderingWindowGet_visuData(window))
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbuttonData),
				     (gboolean)dataFileGet_used(renderingWindowGet_visuData(window)));
    }
  gtk_widget_show (containerDataFilePanel);

  /********************/
  /* Create callbacks */
  /********************/
  g_signal_connect(G_OBJECT(openDataFileButton), "clicked",
		   G_CALLBACK(loadDataFile), (gpointer)0);
  g_signal_connect(G_OBJECT(checkbuttonData), "toggled",
		   G_CALLBACK(useDataFileColor), (gpointer)0);

  g_signal_connect(G_OBJECT(visu), "dataReadyForRendering",
		   G_CALLBACK(visuFileReset), (gpointer)0);
  g_signal_connect(G_OBJECT(radioNormalized), "toggled",
		   G_CALLBACK(onScaleTypeChange), (gpointer)dataFile_normalize);
  g_signal_connect(G_OBJECT(radioMinMax), "toggled",
		   G_CALLBACK(onScaleTypeChange), (gpointer)dataFile_minMax);
  g_signal_connect(G_OBJECT(entryDataMin), "value-changed",
		   G_CALLBACK(onEntryMinMaxChangeValue), (gpointer)0);
  g_signal_connect(G_OBJECT(entryDataMax), "value-changed",
		   G_CALLBACK(onEntryMinMaxChangeValue), (gpointer)1);
  for (i = 0; i < 3; i++)
    {
      signalSpinDataChA[i] =
	g_signal_connect(G_OBJECT(spinbuttonDataChA[i]), "value-changed",
			 G_CALLBACK(onSpinChAChangeValue), GINT_TO_POINTER(i));
      signalSpinDataChB[i] =
	g_signal_connect(G_OBJECT(spinbuttonDataChB[i]), "value-changed",
			 G_CALLBACK(onSpinChBChangeValue), GINT_TO_POINTER(i));
      signalComboColumnId[i] =
	g_signal_connect(G_OBJECT(comboboxDataCh[i]), "changed",
			 G_CALLBACK(onComboColChange), GINT_TO_POINTER(i));
    }
  signalRadioRGB = g_signal_connect(G_OBJECT(radiobuttonDataRGB), "toggled",
				    G_CALLBACK(onColorTypeChange), (gpointer)dataFile_rgb);
  signalRadioHSV = g_signal_connect(G_OBJECT(radiobuttonDataHSV), "toggled",
				    G_CALLBACK(onColorTypeChange), (gpointer)dataFile_hsv);

  g_signal_connect(G_OBJECT(checkPreSetColorRange), "toggled",
		   G_CALLBACK(onColorPreSetChange), (gpointer)TRUE);
  g_signal_connect(G_OBJECT(comboPreSetColorRange), "changed",
		   G_CALLBACK(onComboPreSetChange), (gpointer)0);

  g_signal_connect(G_OBJECT(checkHideMinValues), "toggled",
		   G_CALLBACK(onCheckHideMinValuesChange), (gpointer)0);
  g_signal_connect(G_OBJECT(entryHideMinValues), "value-changed",
		   G_CALLBACK(onEntryHideMinValuesChange), (gpointer)0);
  signalSpinHide = g_signal_connect(G_OBJECT(spinHideMinValues), "value-changed",
				    G_CALLBACK(onSpinHideMinValuesChange), (gpointer)0);

  /***************************/
  /* Create still comboboxes */
  /***************************/
  list = dataFileBuild_presetShadeList();
  makePreSetColorRange(list);
  gtk_combo_box_set_active(GTK_COMBO_BOX(comboPreSetColorRange), 0);

  /* If there's a dataObj loaded, we missed the dataReadyForRendering signal,
     then we add the callback for NodeAskForShowHide manually. */
  if (renderingWindowGet_visuData(window))
    signalAskForHide = g_signal_connect(G_OBJECT(renderingWindowGet_visuData(window)),
					"NodeAskForShowHide",
					G_CALLBACK(onAskForHideNodes), (gpointer)0);

  DBG_fprintf(stderr, " | Creation OK.\n");
}

void makePreSetColorRange(GList *listOfShade)
{
  struct preSetColorRange_struct *values;
  GtkTreeIter iter;
  GdkPixbuf *pixbuf;
  gchar *iconPath;
  GList *tmpLst;
  Shade *shade;
  
  tmpLst = listOfShade;
  while (tmpLst)
    {
      shade = (Shade*)(tmpLst->data);
      pixbuf = gdk_pixbuf_new_from_file(shadeGet_pathToImage(shade), (GError**)0);
      gtk_list_store_append(listStorePreSetColorRange, &iter);
      gtk_list_store_set(listStorePreSetColorRange, &iter,
			 0, pixbuf,
			 1, shadeGet_label(shade),
			 2, shade,
			 -1);
      tmpLst = g_list_next(tmpLst);
    }
}
void makeMinMaxLabels(VisuData *data)
{
  char *file;
  GtkWidget *childMinMax;
  int nbColumns;
  int i;
  GtkWidget *table, *label;
  GString *labelStr;
  float minMax[2];

  if (!data)
    return;

  DBG_fprintf(stderr, "Panel dataFile : rebuilding min/max labels.\n");
  /* empty the child of the alignment */
  childMinMax = gtk_bin_get_child(GTK_BIN(readMinMaxValues));
  if (childMinMax)
    gtk_widget_destroy(childMinMax);

  nbColumns = dataFileGet_nbColumns(data);
  if (nbColumns > 0)
    {
      table = gtk_table_new(nbColumns + 1, 3, FALSE);
      gtk_widget_show(table);
      label = gtk_label_new(_("Column number"));
      gtk_widget_set_name(label, "label_head");
      gtk_widget_show(label);
      gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 2, 0);
      label = gtk_label_new(_("Min value"));
      gtk_widget_set_name(label, "label_head");
      gtk_widget_show(label);
      gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1, GTK_EXPAND, GTK_SHRINK, 2, 0);
      label = gtk_label_new(_("Max value"));
      gtk_widget_set_name(label, "label_head");
      gtk_widget_show(label);
      gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_EXPAND, GTK_SHRINK, 2, 0);

      labelStr = g_string_new("");
      for (i = 0; i < nbColumns; i++)
	{
	  g_string_printf(labelStr, _("Column %d"), i + 1);
	  label = gtk_label_new(labelStr->str);
	  gtk_widget_show(label);
	  gtk_table_attach(GTK_TABLE(table), label, 0, 1, i + 1, i + 2,
			   GTK_SHRINK, GTK_SHRINK, 2, 0);

	  if (dataFileGet_fileMinMaxFromColumn(data, minMax, i))
	    {
	      g_string_printf(labelStr, "%g", minMax[0]);
	      label = gtk_label_new(labelStr->str);
	      gtk_widget_show(label);
	      gtk_table_attach(GTK_TABLE(table), label, 1, 2, i + 1, i + 2,
			       GTK_SHRINK, GTK_SHRINK, 2, 0);

	      g_string_printf(labelStr, "%g", minMax[1]);
	      label = gtk_label_new(labelStr->str);
	      gtk_widget_show(label);
	      gtk_table_attach(GTK_TABLE(table), label, 2, 3, i + 1, i + 2,
			       GTK_SHRINK, GTK_SHRINK, 2, 0);
	    }
	  else
	    fprintf(stderr, "WARNING! Can't retrieve min/max values for column %d.\n", i);
	}
      g_string_free(labelStr, TRUE);

      gtk_container_add(GTK_CONTAINER(readMinMaxValues), table);
    }
  else
    {
      label = gtk_label_new(MIN_MAX_NO_DATA_FILE);
      gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
      gtk_widget_show(label);
      gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
      gtk_container_add(GTK_CONTAINER(readMinMaxValues), label);
    }
}
void makeColumnSelection(VisuData *data)
{
  int i, j;
  GString *label;
  int *selected;

  DBG_fprintf(stderr, "Panel dataFile : rebuilding comboboxes.\n");
  /* Suspend all combo signals during changes */
  for (i = 0; i < 3; i++)
    g_signal_handler_block(G_OBJECT(comboboxDataCh[i]), signalComboColumnId[i]);
  /* empty combobox */
  for (i = 0; i < 3; i++)
    {
      for (j = nbColumns; j > 0; j--)
	gtk_combo_box_remove_text(GTK_COMBO_BOX(comboboxDataCh[i]), j);
      gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), 0);
      DBG_fprintf(stderr, "Panel dataFile : Channel %d has selection %d.\n",
		  i, -1);
    }
  if (data)
    {
      nbColumns = dataFileGet_nbColumns(data);
      if (nbColumns > 0)
	{
	  label = g_string_new("");
	  for (j = 0; j < nbColumns; j++)
	    {
	      g_string_printf(label, _("Col. %d"), j + 1);
	      for (i = 0; i < 3; i++)
		gtk_combo_box_append_text(GTK_COMBO_BOX(comboboxDataCh[i]), label->str);
	    }
	  g_string_free(label, TRUE);
	  selected = dataFileGet_colUsed(data);
	  if (selected)
	    {
	      for (i = 0; i < 3; i++)
		{
		  DBG_fprintf(stderr, "Panel dataFile : Channel %d has selection %d.\n",
			      i, selected[i]);
		  gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), selected[i] + 1);
		}
	    }
	}
    }
  /* Activate all combo signals after changes */
  for (i = 0; i < 3; i++)
    g_signal_handler_unblock(G_OBJECT(comboboxDataCh[i]), signalComboColumnId[i]);
}

void makeColorPreview(VisuData *data)
{
  int *valCols;
  int i, j;
  gboolean different;
  int rowstride, x, y;
  guchar *pixels, *p;
  float rgbValues[COLOR_PREVIEW_WIDTH][3];
  float fromVal[3];
  int ind[3];

  if (!data)
    return;

  valCols = dataFileGet_colUsed(data);
  if (!valCols)
    return;

  for (i = 0; i < 3; i++)
    ind[i] = (valCols[i] != -1)?i:-1;
  different = (valCols[0] != -1 && valCols[1] != -1 && valCols[0] != valCols[1]) ||
    (valCols[1] != -1 && valCols[2] != -1 && valCols[1] != valCols[2]) ||
    (valCols[0] != -1 && valCols[2] != -1 && valCols[0] != valCols[2]) ||
    (valCols[0] == -1 && valCols[1] == -1 && valCols[2] == -1);
  if (different)
    {
      gtk_image_set_from_pixbuf(GTK_IMAGE(colorPreview), NULL);
      gtk_widget_hide(colorPreview);
      gtk_widget_show(labelPreview);
    }
  else
    {
      DBG_fprintf(stderr, "Panel dataFile : making color preview bitmap.\n");
      rowstride = gdk_pixbuf_get_rowstride(pixbufColorPreview);
      pixels = gdk_pixbuf_get_pixels(pixbufColorPreview);

      for (i = 0; i < COLOR_PREVIEW_WIDTH; i++)
	{
	  for (j = 0; j < 3; j++)
	    fromVal[j] = (ind[j] >= 0)?(float)i / (float)(COLOR_PREVIEW_WIDTH - 1):1.;
	  dataFileGet_valuesTransformedInRGB(data, rgbValues[i], fromVal);
/* 	  fprintf(stderr, "% d ----> %f %f %f -> %f %f %f\n",i, fromVal[0], fromVal[1], fromVal [2], rgbValues[i][0], rgbValues[i][1], rgbValues[i][2]); */
	}

      for (y = 0; y < COLOR_PREVIEW_HEIGHT; y++)
	for (x = 0; x < COLOR_PREVIEW_WIDTH; x++)
	  {
	    p = pixels + y * rowstride + x * 3;
	    p[0] = (guchar)(rgbValues[x][0] * 255);
	    p[1] = (guchar)(rgbValues[x][1] * 255);
	    p[2] = (guchar)(rgbValues[x][2] * 255);
	  }
      gtk_image_set_from_pixbuf(GTK_IMAGE(colorPreview), pixbufColorPreview);

      gtk_widget_hide(labelPreview);
      gtk_widget_show(colorPreview);
    }
}

void makeStatusBar(gchar* file, int nbColumns)
{
  gchar *fileUTF8;
  GString *message;

  /* Create the text of the status bar or empty it. */

  gtk_statusbar_pop(GTK_STATUSBAR(statusbarDataFile),
		    statusDataFileContextId);
  /* Create the text of the status bar or empty it. */
  if (file)
    {
      fileUTF8 = getStringInUTF8(file);
      message = g_string_new("");
      if (nbColumns > 0)
	{
	  if (g_utf8_strlen(fileUTF8, 24) > 23)
	    g_string_append_printf(message, _("(...)%s (%d col.)"),
				   g_utf8_offset_to_pointer(fileUTF8,
							    g_utf8_strlen(fileUTF8, -1) - 23),
				   nbColumns);
	  else
	    g_string_append_printf(message, _("%s (%d col.)"),
				   fileUTF8, nbColumns);
	}
      else
	{
	  if (g_utf8_strlen(fileUTF8, 16) > 15)
	    g_string_append_printf(message, _("(...)%s : no such file or not a data file."),
				   g_utf8_offset_to_pointer(fileUTF8,
							    g_utf8_strlen(fileUTF8, -1) - 15));
	  else
	    g_string_append_printf(message, _("%s : no such file or not a data file."),
				   fileUTF8);
	}
      gtk_statusbar_push(GTK_STATUSBAR(statusbarDataFile),
			 statusDataFileContextId,
			 message->str);
      g_string_free(message, TRUE);
      g_free(fileUTF8);
    }
  else
      gtk_statusbar_push(GTK_STATUSBAR(statusbarDataFile),
			 statusDataFileContextId,
			 DATA_FILE_NO_FILE_MESSAGE);
}
int panelDataFileLoad_file(VisuData *visuData, gchar *file)
{
  GString *message;
  int res, errors, nb;
  gchar *fileUTF8;
  gboolean somethingIsLoaded;

  DBG_fprintf(stderr, "Panel dataFile : loading a new file '%s'.\n", file);
  g_return_val_if_fail(visuData && file, 0);

  /* If panel has still not been loaded, we do it now. */
  if (!panelDataFileIsInitiated)
    {
      panelDataFileIsInitiated = TRUE;
      createInteriorDataFile();
    }

  message = g_string_new(_("Loading data file...\n"));
  somethingIsLoaded = dataFileSet_file(visuData, file, message, &errors);

  /* Raise the error dialog if necessary. */
  if (errors)
    raiseAlertDialogWithScrollView(message->str);
  g_string_free(message, TRUE);

  /* Create the panel. */
  makeMinMaxLabels(visuData);
  makeColumnSelection(visuData);
  makeColorPreview(visuData);
  if (somethingIsLoaded)
    {
      nb = dataFileGet_nbColumns(visuData);
      makeStatusBar(file, nb);
      flagDataFileIsLoaded = TRUE;
      /* The options for dataFile colorization become sensitive only
	 if one data file has been associated. */
      gtk_widget_set_sensitive(vBoxDataFileOption, TRUE);
      /* Force applying preset changes if toggle checked. */
      onColorPreSetChange(GTK_TOGGLE_BUTTON(checkPreSetColorRange), (gpointer)FALSE);
      /* Change the span of the spin button for hidding method. */
      g_signal_handler_block(G_OBJECT(spinHideMinValues), signalSpinHide);
      gtk_spin_button_set_range(GTK_SPIN_BUTTON(spinHideMinValues), 1., (double)nb);
      g_signal_handler_unblock(G_OBJECT(spinHideMinValues), signalSpinHide);
      /* Force applying hidding status if needed. */
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkHideMinValues)))
	applyHideMinValues(visuData, FALSE);
    }
  else
    {
      makeStatusBar((gchar*)0, 0);
      flagDataFileIsLoaded = FALSE;
      gtk_widget_set_sensitive(vBoxDataFileOption, FALSE);
    }

  return somethingIsLoaded;
}


/*************/
/* Callbacks */
/*************/
void visuFileReset(GObject *obj, VisuData *dataObj, gpointer data)
{
  char* file;
  gchar* fileCpy, *fileExtPosition;
  GString *dataFile;
  int res, i, nbColumns;
  float minVal, maxVal;
  int dataNormalize, colourScheme;
  int colUsed[3];
  float vectA[3], vectB[3];

  DBG_fprintf(stderr, "Panel dataFile : caught 'dataReadyForRendering' signal.\n");
  if (dataObj)
    {
      /* Add the listener to the 'NodeAskForShowHide' signal. */
      signalAskForHide = g_signal_connect(G_OBJECT(dataObj), "NodeAskForShowHide",
					  G_CALLBACK(onAskForHideNodes), (gpointer)0);

      /* A new file is loaded, no data are associated. */
      gtk_widget_set_sensitive(vBoxDataFileOption, FALSE);

      /* Store old values, may be useful if data file is autoloaded. */
      DBG_fprintf(stderr, "Panel dataFile : Saving current colour values.\n");
      for (i = 0; i < 3; i++)
	{
	  vectA[i] = (float)gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbuttonDataChA[i]));
	  vectB[i] = (float)gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinbuttonDataChB[i]));
	  colUsed[i] = gtk_combo_box_get_active(GTK_COMBO_BOX(comboboxDataCh[i])) - 1;
	}
      minVal = numericalEntryGet_value(NUMERICAL_ENTRY(entryDataMin));
      maxVal = numericalEntryGet_value(NUMERICAL_ENTRY(entryDataMax));
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioNormalized)))
	dataNormalize = dataFile_normalize;
      else
	dataNormalize = dataFile_minMax;
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobuttonDataHSV)))
	colourScheme = dataFile_hsv;
      else
	colourScheme = dataFile_rgb;
	  
      /* Check the autoload flag. */
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbuttonAutoLoad)))
	{
	  /* Compute the name of the data
	     file from the rendered filename. */
	  file = visuDataGet_file(dataObj, 0);
	  fileCpy = g_strdup(file);
	  fileExtPosition = g_strrstr(fileCpy, ".");
	  if (fileExtPosition)
	    *fileExtPosition = '\0';
	  dataFile = g_string_new("");
	  g_string_printf(dataFile, "%s.%s", fileCpy, DATA_FILE_EXTENSION);
	  DBG_fprintf(stderr, "Panel DataFile : try to load a new data file"
		      " ('%s') from the name of the rendered file.\n", dataFile->str);
	  res = panelDataFileLoad_file(dataObj, dataFile->str);
	  if (res && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange)))
	    {
	      DBG_fprintf(stderr, "Panel dataFile : restore colour values from previous.\n");
	      /* Reuse previous colUsed values. */
	      nbColumns = dataFileGet_nbColumns(dataObj);
	      for (i = 0; i < 3; i++)
		{
		  dataFileSet_vectA(dataObj, vectA[i], i);
		  dataFileSet_vectB(dataObj, vectB[i], i);
		  if (colUsed[i] < nbColumns)
		    {
		      dataFileSet_colUsed(dataObj, colUsed[i], i);
		      gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), colUsed[i] + 1);
		    }
		}
	      dataFileSet_min(dataObj, minVal);
	      dataFileSet_max(dataObj, maxVal);
	      dataFileSet_scaleType(dataObj, dataNormalize);
	      dataFileSet_colorType(dataObj, colourScheme);
	      makeMinMaxLabels(dataObj);
	      makeColumnSelection(dataObj);
	      makeColorPreview(dataObj);
	    }
	  /* If colorisation is disable, we set the flag. */
	  dataFileSet_used(dataObj,
			   gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbuttonData)));

	  g_string_free(dataFile, TRUE);
	  g_free(fileCpy);
	}
      else
	{
	  makeMinMaxLabels(dataObj);
	  makeColumnSelection(dataObj);
	  makeColorPreview(dataObj);
	  makeStatusBar((gchar*)0, 0);
	}
      gtk_widget_set_sensitive(openDataFileButton, TRUE);
    }
  else
    {
      makeMinMaxLabels(dataObj);
      makeColumnSelection(dataObj);
      makeColorPreview(dataObj);
      makeStatusBar((gchar*)0, 0);
      flagDataFileIsLoaded = FALSE;
/*       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbuttonData), FALSE); */
      gtk_widget_set_sensitive(vBoxDataFileOption, FALSE);
      gtk_widget_set_sensitive(openDataFileButton, FALSE);
    }
}
void loadDataFile(GtkButton *button, gpointer data)
{
  GtkWidget *file_selector;
  char *filename;
  char *directory;
  int res;
  RenderingWindow *window;
  VisuData *dataObj;
  gboolean ok;

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    {
      g_warning("Can't click here since no visuData is available.\n");
      return;
    }

  file_selector = gtk_file_chooser_dialog_new(_("Load data file"),
					      GTK_WINDOW(mainWindow),
					      GTK_FILE_CHOOSER_ACTION_OPEN,
					      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					      GTK_STOCK_OPEN, GTK_RESPONSE_OK,
					      NULL);
  directory = getLastOpenDirectory();
  if (directory)
    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(file_selector), directory);
  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(file_selector),
				       FALSE);


  gtk_widget_set_name(file_selector, "filesel");
  gtk_window_set_position(GTK_WINDOW(file_selector), GTK_WIN_POS_CENTER_ON_PARENT);
  gtk_window_set_modal (GTK_WINDOW (file_selector), TRUE);

  if (gtk_dialog_run (GTK_DIALOG (file_selector)) == GTK_RESPONSE_OK)
    {
      filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_selector));
      directory = (char*)gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER (file_selector));
      setLastOpenDirectory(directory);
      g_free(directory);
      gtk_widget_destroy (file_selector);
      res = panelDataFileLoad_file(dataObj, filename);
      /* Ask for a redraw */
      if (res)
	{
	  ok = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbuttonData));
	  dataFileSet_used(dataObj, ok);
	  if (ok)
	    dataFileReDraw(dataObj);
	}
      else
	{
	  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkHideMinValues)))
	    applyHideMinValues(dataObj, FALSE);
	  dataFileReDraw(dataObj);
	}
      g_free (filename);
    }
  else
    {
      directory = (char*)gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER (file_selector));
      setLastOpenDirectory(directory);
      g_free(directory);
      gtk_widget_destroy (file_selector);
    }
}
void useDataFileColor(GtkToggleButton *toggle, gpointer data)
{
  gboolean isOn;
  int res;
  RenderingWindow *window;
  VisuData *dataObj;

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    return;

  isOn = gtk_toggle_button_get_active(toggle);
  res = dataFileSet_used(dataObj, (gboolean)isOn);
  /* Force applying hidding status if needed. */
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkHideMinValues)))
    applyHideMinValues(dataObj, FALSE);
  if (res)
    dataFileReDraw(dataObj);
}
gboolean checkDataFilesOnEnter(gpointer data)
{
  float *val;
  int i, *selected;
  RenderingWindow *window;
  VisuData *dataObj;

  DBG_fprintf(stderr, "Panel dataFile : check values on enter.\n");

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return FALSE;

  dataObj = renderingWindowGet_visuData(window);

  if (!panelDataFileIsInitiated)
    {
      DBG_fprintf(stderr, "Panel dataFile : initialize interior.\n");
  
      panelDataFileIsInitiated = TRUE;
      createInteriorDataFile();
    }

  DBG_fprintf(stderr, "Panel dataFile : set values on enter.\n");

  if (dataObj && dataFileGet_used(dataObj))
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbuttonData), TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbuttonData), FALSE);

  /* If no visuData are loaded or if no data file has been associated,
     return. */
  if (!dataObj)
    return FALSE;

  gtk_widget_set_sensitive(openDataFileButton, TRUE);
  
  if (!dataFileGet_file(dataObj))
    return FALSE;

  /* Update the widgets of this panel. */
  makeStatusBar(dataFileGet_file(dataObj), dataFileGet_nbColumns(dataObj));

  switch (dataFileGet_scaleType(dataObj))
    {
    case dataFile_normalize:
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radioNormalized), TRUE);
      break;
    case dataFile_minMax:
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radioMinMax), TRUE);
      break;
    default:
      break;
    }

  numericalEntrySet_value(NUMERICAL_ENTRY(entryDataMin),
			  dataFileGet_min(dataObj));
  numericalEntrySet_value(NUMERICAL_ENTRY(entryDataMax),
			  dataFileGet_max(dataObj));
  val = dataFileGet_vectA(dataObj);
  if (val)
    for (i = 0; i < 3; i++)
      gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbuttonDataChA[i]), val[i]);
  val = dataFileGet_vectB(dataObj);
  if (val)
    for (i = 0; i < 3; i++)
      gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbuttonDataChB[i]), val[i]);

  selected = dataFileGet_colUsed(dataObj);
  if (selected)
    {
      for (i = 0; i < 3; i++)
	{
	  DBG_fprintf(stderr, "Panel dataFile : Channel %d has selection %d.\n",
		      i, selected[i]);
	  gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), selected[i] + 1);
	}
    }
  else
    for (i = 0; i < 3; i++)
      {
	DBG_fprintf(stderr, "Panel dataFile : Channel %d has selection %d.\n",
		    i, -1);
	gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), 0);
      }

  switch (dataFileGet_colorType(dataObj))
    {
    case dataFile_rgb:
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobuttonDataRGB), TRUE);
      for (i = 0; i < 3; i++)
	gtk_label_set_text(GTK_LABEL(labelChannel[i]), labelRGB[i]);
      break;
    case dataFile_hsv:
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobuttonDataHSV), TRUE);
      for (i = 0; i < 3; i++)
	gtk_label_set_text(GTK_LABEL(labelChannel[i]), labelHSV[i]);
      break;
    default:
      break;
    }

  return FALSE;
}
void onScaleTypeChange(GtkToggleButton *toggle, gpointer data)
{
  int scale, res;
  RenderingWindow *window;
  VisuData *dataObj;

  DBG_fprintf(stderr, "Panel dataFile : change on scale radio buttons.\n");

  if (!gtk_toggle_button_get_active(toggle))
    return;

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    {
      g_warning("Can't click here since no visuData is available.\n");
      return;
    }

  scale = GPOINTER_TO_INT(data);
  if (scale < dataFile_normalize || scale > dataFile_minMax)
    {
      fprintf(stderr, "WARNING! 'onScaleTypeChange' has been called with"
	      " a wrong data parameter (%d).\n", scale);
      return;
    }
  res = dataFileSet_scaleType(dataObj, scale);
  if (scale != dataFile_minMax)
    {
      gtk_widget_set_sensitive(entryDataMax, FALSE);
      gtk_widget_set_sensitive(entryDataMin, FALSE);
    }
  else
    {
      gtk_widget_set_sensitive(entryDataMax, TRUE);
      gtk_widget_set_sensitive(entryDataMin, TRUE);
      gtk_expander_set_expanded(GTK_EXPANDER(expanderNormalize), TRUE);
    }
  if (res)
    dataFileReDraw(dataObj);
}
void onEntryMinMaxChangeValue(NumericalEntry *entry, double value, gpointer data)
{
  int minMax, res;
  RenderingWindow *window;
  VisuData *dataObj;

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  DBG_fprintf(stderr, "Panel dataFile : change on min/max entries.\n");

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    {
      g_warning("Can't click here since no visuData is available.\n");
      return;
    }

  minMax = GPOINTER_TO_INT(data);
  g_return_if_fail(minMax == 0 || minMax == 1);
  DBG_fprintf(stderr, "Panel Data File : grep value from GtkEntry for"
	      " the minMax value (%d).\n", minMax);

  switch (minMax)
    {
    case 0:
      res = dataFileSet_min(dataObj, value);
      break;
    case 1:
      res = dataFileSet_max(dataObj, value);
      break;
    default:
      res = 0;
      break;
    }
  if (res)
    dataFileReDraw(dataObj);
}
void onSpinChAChangeValue(GtkSpinButton *spinbutton, gpointer user_data)
{
  int pos;
  int res;
  RenderingWindow *window;
  VisuData *dataObj;

  DBG_fprintf(stderr, "Panel dataFile : change on spin vectA.\n");
  /* Desable preset range since manual chance. */
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange), FALSE);

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    {
      g_warning("Can't click here since no visuData is available.\n");
      return;
    }

  pos = GPOINTER_TO_INT(user_data);
  if (pos < 0 || pos > 2)
    {
      fprintf(stderr, "WARNING! 'onSpinChAChangeValue' has been called with"
	      " a wrong data parameter (%d).\n", pos);
      return;
    }
  res = dataFileSet_vectA(dataObj, gtk_spin_button_get_value(spinbutton), pos);
  makeColorPreview(dataObj);
  if (res)
    dataFileReDraw(dataObj);
}
void onSpinChBChangeValue(GtkSpinButton *spinbutton, gpointer user_data)
{
  int pos;
  int res;
  RenderingWindow *window;
  VisuData *dataObj;

  DBG_fprintf(stderr, "Panel dataFile : change on spin vectB.\n");
  /* Desable preset range since manual chance. */
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange), FALSE);

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    {
      g_warning("Can't click here since no visuData is available.\n");
      return;
    }

  pos = GPOINTER_TO_INT(user_data);
  if (pos < 0 || pos > 2)
    {
      fprintf(stderr, "WARNING! 'onSpinChBChangeValue' has been called with"
	      " a wrong data parameter (%d).\n", pos);
      return;
    }
  res = dataFileSet_vectB(dataObj, gtk_spin_button_get_value(spinbutton), pos);
  makeColorPreview(dataObj);
  if (res)
    dataFileReDraw(dataObj);
}

void onComboColChange(GtkComboBox *combo, gpointer data)
{
  int pos;
  int res;
  RenderingWindow *window;
  VisuData *dataObj;

  DBG_fprintf(stderr, "Panel dataFile : change on combo column.\n");
  /* Desable preset range since manual chance. */
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange), FALSE);

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    {
      g_warning("Can't click here since no visuData is available.\n");
      return;
    }

  pos = GPOINTER_TO_INT(data);
  if (pos < 0 || pos > 2)
    {
      fprintf(stderr, "WARNING! 'onComboColChange' has been called with"
	      " a wrong data parameter (%d).\n", pos);
      return;
    }
  res = dataFileSet_colUsed(dataObj, gtk_combo_box_get_active(combo) - 1, pos);
  makeColorPreview(dataObj);
  if (res)
    dataFileReDraw(dataObj);
}
void onColorTypeChange(GtkToggleButton *toggle, gpointer data)
{
  int color, res, i;
  RenderingWindow *window;
  VisuData *dataObj;

  DBG_fprintf(stderr, "Panel dataFile : change on colour type radio buttons.\n");
  /* Desable preset range since manual chance. */
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange), FALSE);

  if (!gtk_toggle_button_get_active(toggle))
    return;

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);
  if (!dataObj)
    {
      g_warning("Can't click here since no visuData is available.\n");
      return;
    }

  color = GPOINTER_TO_INT(data);
  if (color < dataFile_rgb || color > dataFile_hsv)
    {
      fprintf(stderr, "WARNING! 'onColorTypeChange' has been called with"
	      " a wrong data parameter (%d).\n", color);
      return;
    }
  res = dataFileSet_colorType(dataObj, color);
  if (color == dataFile_rgb)
    for (i = 0; i < 3; i++)
      gtk_label_set_text(GTK_LABEL(labelChannel[i]), labelRGB[i]);
  else
    for (i = 0; i < 3; i++)
      gtk_label_set_text(GTK_LABEL(labelChannel[i]), labelHSV[i]);
  makeColorPreview(dataObj);
  if (res)
    dataFileReDraw(dataObj);
}
void onColorPreSetChange(GtkToggleButton *toggle, gpointer data)
{
  GtkTreeIter iter;
  gboolean selected, ok;
  Shade *values;
  float *vectA, *vectB;
  gboolean *vectX;
  int res, i;
  RenderingWindow *window;
  VisuData *dataObj;

  /* Nothing to do here since no data. */
  if (!flagDataFileIsLoaded)
    return;

  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange)))
    return;

  selected = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(comboPreSetColorRange), &iter);
  if (!selected)
    return;
  
  DBG_fprintf(stderr, "Panel dataFile : applying preset color range.\n");

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;

  dataObj = renderingWindowGet_visuData(window);

  gtk_tree_model_get(GTK_TREE_MODEL(listStorePreSetColorRange), &iter,
		     COLUMN_POINTER_TO_DATA, &values, -1);

  /* Suspend all combo signals during changes */
  g_signal_handler_block(G_OBJECT(radiobuttonDataRGB), signalRadioRGB);
  g_signal_handler_block(G_OBJECT(radiobuttonDataHSV), signalRadioHSV);
  for (i = 0; i < 3; i++)
    {
      g_signal_handler_block(G_OBJECT(comboboxDataCh[i]), signalComboColumnId[i]);
      g_signal_handler_block(G_OBJECT(spinbuttonDataChA[i]), signalSpinDataChA[i]);
      g_signal_handler_block(G_OBJECT(spinbuttonDataChB[i]), signalSpinDataChB[i]);
    }
  dataFileSet_shade(dataObj, values);
  switch (shadeGet_colorMode(values))
    {
    case shade_colorModeRGB:
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobuttonDataRGB), TRUE);
      for (i = 0; i < 3; i++)
	gtk_label_set_text(GTK_LABEL(labelChannel[i]), labelRGB[i]);
      break;
    case shade_colorModeHSV:
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobuttonDataHSV), TRUE);
      for (i = 0; i < 3; i++)
	gtk_label_set_text(GTK_LABEL(labelChannel[i]), labelHSV[i]);
      break;
    default:
      g_warning("Incorrect ShadeColorMode in call of 'onColorPreSetChange'.");
    }
  ok = shadeGet_colorTransformation(values, &vectA, &vectB, &vectX);
  if (ok)
    for (i = 0; i < 3; i++)
      {
	if (vectX[i])
	  gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), 1);
	else
	  gtk_combo_box_set_active(GTK_COMBO_BOX(comboboxDataCh[i]), 0);
	gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbuttonDataChA[i]), vectA[i]);
	gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinbuttonDataChB[i]), vectB[i]);
      }
  else
    g_warning("Can't get the color transformation parameters.");

  /* ReActivate all combo signals after changes */
  g_signal_handler_unblock(G_OBJECT(radiobuttonDataRGB), signalRadioRGB);
  g_signal_handler_unblock(G_OBJECT(radiobuttonDataHSV), signalRadioHSV);
  for (i = 0; i < 3; i++)
    {
      g_signal_handler_unblock(G_OBJECT(comboboxDataCh[i]), signalComboColumnId[i]);
      g_signal_handler_unblock(G_OBJECT(spinbuttonDataChA[i]), signalSpinDataChA[i]);
      g_signal_handler_unblock(G_OBJECT(spinbuttonDataChB[i]), signalSpinDataChB[i]);
    }

  makeColorPreview(dataObj);

  if ((gboolean)data && dataFileGet_used(dataObj))
    dataFileReDraw(dataObj);
}
void onComboPreSetChange(GtkComboBox *combo, gpointer data)
{
  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange)))
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkPreSetColorRange), TRUE);
  else
    onColorPreSetChange(GTK_TOGGLE_BUTTON(checkPreSetColorRange), (gpointer)TRUE);
}
void applyHideMinValues(VisuData *visuData, gboolean askRedraw)
{
  gboolean redraw;
  int col;
  double value;

  g_return_if_fail(visuData);

  /* Wants to change the rendered attributes of Nodes, must
     emit the NodeAskForShowHide signal. */
  DBG_fprintf(stderr, "Panel DataFile : emitting 'NodeAskForShowHide' signal.\n");
  g_signal_handler_block(G_OBJECT(visuData), signalAskForHide);
  visuDataEmit_askForShowHideNodes(visuData, &redraw);
  g_signal_handler_unblock(G_OBJECT(visuData), signalAskForHide);
  DBG_fprintf(stderr, " | returned redraw value %d.\n", redraw);

  /* Get the parameters for hiding mode. */
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkHideMinValues)) && 
      dataFileGet_used(visuData))
    col = (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinHideMinValues)) - 1;
  else
    col = -1;
  value = numericalEntryGet_value(NUMERICAL_ENTRY(entryHideMinValues));

  redraw = dataFileApply_hideOnMinValue(visuData, col, value) || redraw;

  if (redraw)
    {
      visuDataEmit_nodeRenderedChange(visuData);
      if (askRedraw)
	{
	  visuData_createAllNodes(visuData);
	  g_signal_emit (visu, VISU_GET_CLASS (visu)->OpenGLAskForReDraw_signal_id,
			 0 /* details */,
			 NULL);
	}
    }
}
void onCheckHideMinValuesChange(GtkToggleButton *toggle, gpointer data)
{
  RenderingWindow *window;

  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbuttonData)))
    return;

  DBG_fprintf(stderr, "Panel DataFile : toggle check"
	      " button to hide elements.\n");
  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;
  applyHideMinValues(renderingWindowGet_visuData(window), TRUE);
}
void onEntryHideMinValuesChange(NumericalEntry *entry, double value, gpointer data)
{
  RenderingWindow *window;

  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbuttonData)))
    return;

  DBG_fprintf(stderr, "Panel DataFile : change value on hide"
	      " min values entry : %f\n", value);
  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;
  applyHideMinValues(renderingWindowGet_visuData(window), TRUE);
}
void onSpinHideMinValuesChange(GtkSpinButton *spinbutton, gpointer user_data)
{
  RenderingWindow *window;

  if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbuttonData)))
    return;

  DBG_fprintf(stderr, "Panel DataFile : change value of spin column"
	      " for hide function : %f\n", gtk_spin_button_get_value(spinbutton));
  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  if (!window)
    return;
  applyHideMinValues(renderingWindowGet_visuData(window), TRUE);
}
static void onAskForHideNodes(VisuData *visuData, gboolean *redraw, gpointer data)
{
  int col;
  double val;

  /* No data, useless to stay here. */
  if (!flagDataFileIsLoaded)
    return;

  /* Not in used, can safely go out. */
  if (!dataFileGet_used(visuData))
    return;

  DBG_fprintf(stderr, "Panel DataFile : caught the 'NodeAskForShowHide' signal for"
	      " VisuData %p.\n", (gpointer)visuData);

  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkHideMinValues)))
    {
      col = (int)gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinHideMinValues)) - 1;
      val = numericalEntryGet_value(NUMERICAL_ENTRY(entryHideMinValues));
      *redraw = dataFileApply_hideOnMinValue(visuData, col, val) || *redraw;
    }
}
