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

panelBrowser.c

/*   EXTRAITS DE LA LICENCE
      Copyright CEA, contributeurs : Luc BILLARD et Damien
      CALISTE, laboratoire L_Sim, (2001-2005)
  
      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-2005)

      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 "panelBrowser.h"

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

#include <gtk/gtk.h>

#include <visu_object.h>
#include <visu_tools.h>
#include <visu_rendering.h>
#include <visu_basic.h>
#include <support.h>
#include <gtk_main.h>
#include <extraGtkFunctions/gtk_dumpDialogWidget.h>
#include <extraGtkFunctions/gtk_toolPanelWidget.h>
#include <gtk_openGLWidget.h>
#include <renderingBackend/visu_windowInterface.h>
#include <gtk_renderingWindowWidget.h>

static GtkWidget *panelBrowser;
GtkListStore *listStoreFiles;
GtkTreeModel *listStoreFilesFilter;
enum
  {
    COLUMN_BOOLEAN, /* Rendered or not. */
    COLUMN_NAME,  /* File name in locale of the file system. */
    COLUMN_NAME_UTF8,  /* File name in UTF8 (to view it it GTK). */
    COLUMN_DATA,  /* File info (size). */
    COLUMN_ACTIVE, /* A boolean to set if this file is active or not. */
    COLUMN_FILE_KIND, /* An integer that correspond to the file type. */
    N_COLUMNS
  };
GtkWidget *fileTree;
gboolean listLoaded;
GtkWidget *progressbar;
GtkWidget *vBoxWaiting;
GtkWidget *labelWaiting;
GtkWidget *scrolledwindow1;
GtkWidget *labelDirectory;
gboolean flagWorkInProgress;
gboolean flagBarIsShown;
gchar *currentBrowseredDirectory;

GtkWidget *entryFilterBrowser;
enum
  {
    PANEL_BROWSER_COLUMN_FILTER_LABEL,
    PANEL_BROWSER_COLUMN_FILTER_ID,
    PANEL_BROWSER_N_COLUMN_FILTER
  };
GtkListStore *panelBrowserListFilter;
GtkWidget *panelBrowserComboFilter;
gint currentComboFilterValue;

GtkWidget *imagePlay;
GtkWidget *imageStop;
GtkWidget *spinDelay;
guint isPlayingCallbackId;

GtkWidget *buttonPrevious;
GtkWidget *buttonNext;
GtkWidget *buttonSelectAll;
GtkWidget *buttonUnselectAll;
GtkWidget *buttonDirectory;
GtkWidget *buttonPlayStop;
GtkWidget *radioGoAround, *radioGoOnce, *radioGoAndBack;
static int currentBrowseDirection;
static GtkTreePath *startBrowsePath;

GtkWidget *buttonDumpAll;
/* GtkProgressBar *progressBarDump; */


GtkWidget *createInteriorBrowser();
void createCallBacksBrowser();
static void panelBrowserBrowse_directory(gchar* dir);
gboolean showProgressBar(gpointer data);
gboolean browserLoad(gchar *filename);

gboolean gtk_tree_model_get_iter_last(GtkTreeModel *model, GtkTreeIter *last, GtkTreePath **path);
void panelBrowserSet_labelCurrentDir();

/* Callbacks */
gboolean treeViewClicked(GtkWidget *widget, GdkEventButton *event,
                   gpointer user_data);
void treeViewActivated(GtkTreeView *treeview, GtkTreePath *path,
                   GtkTreeViewColumn *col, gpointer user_data);
void navigateClicked(GtkButton *button, gpointer data);
void checkFiles(GtkButton *button, gpointer data);
void clearListFiles(GObject *obj, gpointer data);
static void onDirectoryClicked(GtkButton *button, gpointer data);
void playStopClicked(GtkButton *button, gpointer data);
void stopPlayStop(gpointer data);
void onSpinDelayChangeValue(GtkSpinButton *spinbutton,
                      GtkScrollType scroll,
                      gpointer user_data);
void onDumpButtonClicked(GtkButton *button, gpointer user_data);
void filterBrowserChanged(GtkEditable *entry, gpointer user_data);
void abortDumpAll(GtkButton *button, gpointer data);
void updateDumpAllProgressBar(gpointer data);
void onRenderingChangedUpdateFilters(GObject *obj, gpointer data);
gboolean panelBrowserIsIterVisible(GtkTreeModel *model, GtkTreeIter *iter, gpointer data);
void onComboFilterChanged(GtkComboBox *combo, gpointer data);
void onFileLoaded(GObject *obj, VisuData *dataObj, gpointer data);
static void onRefreshDir(GtkButton *button, gpointer data);
static void onBrowserEnter(ToolPanel *toolPanel, gpointer data);
static void refreshCurrentFileList();
gboolean checkFile(GtkTreeModel *model, GtkTreePath *path,
               GtkTreeIter *iter, gpointer data);


gboolean navigateInFiles(GtkTreePath *path, GtkTreeIter *iterSelected);


ToolPanel* panelBrowser_init()
{
  char *cl = _("Browser");
  char *tl = _("Browser");
  GtkCellRenderer *renderer;
  GtkTreeViewColumn *column;

  /* Create the list that store the filters. */
  panelBrowserListFilter = gtk_list_store_new(PANEL_BROWSER_N_COLUMN_FILTER,
                                    G_TYPE_STRING,
                                    G_TYPE_INT);


  panelBrowser = toolPanelNew_withIconFromStock("Panel_browser", cl, tl, GTK_STOCK_INDEX);
  if (!panelBrowser)
    return (ToolPanel*)0;
  gtk_container_add(GTK_CONTAINER(panelBrowser), createInteriorBrowser());
  toolPanelSet_dockable(TOOL_PANEL(panelBrowser), TRUE);
                                     
  /* Create the tree structure. */
  listStoreFiles = gtk_list_store_new (N_COLUMNS,
                               G_TYPE_BOOLEAN,
                               G_TYPE_STRING,
                               G_TYPE_STRING,
                               G_TYPE_STRING,
                               G_TYPE_BOOLEAN,
                               G_TYPE_INT);
  /* Use the COLUMN_ACTIVE as a flag to hide or not the rows that 
     don't match the filter value. */
  listStoreFilesFilter = gtk_tree_model_filter_new(GTK_TREE_MODEL(listStoreFiles), NULL);
  gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(listStoreFilesFilter),
                               panelBrowserIsIterVisible, (gpointer)0,
                               (GtkDestroyNotify)0);
/*   gtk_tree_model_filter_set_visible_column(GTK_TREE_MODEL_FILTER(listStoreFilesFilter), COLUMN_ACTIVE); */

  /* Add a new row to the model */
  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(listStoreFiles),
                               COLUMN_NAME_UTF8, GTK_SORT_ASCENDING);

  renderer = gtk_cell_renderer_toggle_new ();
  column = gtk_tree_view_column_new_with_attributes ("Render",
                                         renderer,
                                         "active", COLUMN_BOOLEAN,
                                         NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (fileTree), column);
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Filename",
                                         renderer,
                                         "text", COLUMN_NAME_UTF8,
                                         NULL);
  gtk_tree_view_append_column (GTK_TREE_VIEW (fileTree), column);
/*   renderer = gtk_cell_renderer_text_new (); */
/*   column = gtk_tree_view_column_new_with_attributes ("Data", */
/*                                       renderer, */
/*                                       "text", COLUMN_DATA, */
/*                                       NULL); */
/*   gtk_tree_view_append_column (GTK_TREE_VIEW (fileTree), column); */

  gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(fileTree)),
                        GTK_SELECTION_BROWSE);

  /* Initialise the values. */
  currentBrowseredDirectory = (gchar*)0;
  listLoaded = FALSE;
  isPlayingCallbackId = 0;
  currentBrowseDirection = BROWSER_NEXT;

  /* Create the callbacks of all the sensitive widgets. */
  createCallBacksBrowser();
  g_signal_connect(G_OBJECT(panelBrowser), "page-entered",
               G_CALLBACK(onBrowserEnter), (gpointer)0);

  return TOOL_PANEL(panelBrowser);
}

GtkWidget *createInteriorBrowser()
{
  GtkWidget *vbox1;

  /* include from glade */
  GtkWidget *image2;
  GtkWidget *image3;
  GtkWidget *image1;
  GtkWidget *hbox2;
  GtkWidget *label4;
  GtkObject *spinDelay_adj;
  GtkWidget *label1;
  GtkWidget *hbox3;
  GtkWidget *alignment1;
  GtkWidget *hbox4;
  GtkWidget *hbox5;
  GtkWidget *image4;
  GtkWidget *label3;
  GtkWidget *refreshDirButton;
  GtkTooltips *tooltips;

  GtkWidget *label5;
  GtkWidget *label;
  GtkWidget *hbox, *vbox;
  GtkWidget *hrule;

  GtkCellRenderer *renderer;

  GSList *radiobuttonCycle_group;

  vbox1 = gtk_vbox_new(FALSE, 0);
  gtk_widget_show(vbox1);

  tooltips = gtk_tooltips_new ();

  hbox = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox);
  gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
  /* This is a label in the browser panel to introduce the
     entry that allows to enter a filter for files shown. */
  label = gtk_label_new(_("Filter: "));
  gtk_widget_show(label);
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
  entryFilterBrowser = gtk_entry_new();
  gtk_entry_set_editable(GTK_ENTRY(entryFilterBrowser), TRUE);
  gtk_entry_set_text(GTK_ENTRY(entryFilterBrowser), "*");
  gtk_widget_show(entryFilterBrowser);
  gtk_box_pack_start(GTK_BOX(hbox), entryFilterBrowser, TRUE, TRUE, 0);
  panelBrowserComboFilter = gtk_combo_box_new_with_model(GTK_TREE_MODEL(panelBrowserListFilter));
  renderer = gtk_cell_renderer_text_new();
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(panelBrowserComboFilter), renderer, FALSE);
  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(panelBrowserComboFilter), renderer,
                        "text", PANEL_BROWSER_COLUMN_FILTER_LABEL);
  gtk_widget_show(panelBrowserComboFilter);
  gtk_box_pack_start(GTK_BOX(hbox), panelBrowserComboFilter, FALSE, FALSE, 2);

  /*******************/
  /* File lists part */
  /*******************/
  hbox = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox);
  gtk_box_pack_start(GTK_BOX(vbox1), hbox, TRUE, TRUE, 0);
  
  vbox = gtk_vbox_new (FALSE, 0);
  gtk_widget_show(vbox);
  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 2);

  buttonDirectory = gtk_button_new ();
  gtk_widget_show (buttonDirectory);
  gtk_box_pack_start (GTK_BOX (vbox), buttonDirectory, FALSE, FALSE, 2);
  gtk_tooltips_set_tip (tooltips, buttonDirectory, _("Choose a different directory."), NULL);

  image3 = gtk_image_new_from_stock ("gtk-open", GTK_ICON_SIZE_BUTTON);
  gtk_widget_show (image3);
  gtk_container_add (GTK_CONTAINER (buttonDirectory), image3);

  refreshDirButton = gtk_button_new ();
  gtk_tooltips_set_tip (tooltips, refreshDirButton, _("Rescan current directory."), NULL);
  gtk_widget_show (refreshDirButton);
  gtk_box_pack_start(GTK_BOX(vbox), refreshDirButton, FALSE, FALSE, 2);
  image3 = create_pixmap (mainWindow, "stock-refresh-dir_20.png");
  gtk_widget_show(image3);
  gtk_container_add(GTK_CONTAINER(refreshDirButton), image3);
  g_signal_connect(G_OBJECT(refreshDirButton), "clicked",
               G_CALLBACK(onRefreshDir), (gpointer)0);

#if GTK_MINOR_VERSION > 5
  label = gtk_label_new(_("Directory tools:"));
  gtk_label_set_angle(GTK_LABEL(label), 90.);
  gtk_widget_show(label);
  gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 5);
#endif

  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_show (scrolledwindow1);
  gtk_box_pack_start (GTK_BOX (hbox), scrolledwindow1, TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_ETCHED_IN);

  fileTree = gtk_tree_view_new ();
  gtk_tooltips_set_tip (tooltips, fileTree, _("Double clic on a selected file to render it."), NULL);
  gtk_widget_show (fileTree);
  gtk_container_add (GTK_CONTAINER (scrolledwindow1), fileTree);
  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fileTree), FALSE);

  vBoxWaiting = gtk_vbox_new (FALSE, 0);
/*   gtk_widget_show (vBoxWaiting); */
  gtk_box_pack_start (GTK_BOX (vbox1), vBoxWaiting, TRUE, TRUE, 0);

  label5 = gtk_label_new (_("Please wait, parsing the directory ..."));
  gtk_widget_show (label5);
  gtk_box_pack_start (GTK_BOX (vBoxWaiting), label5, TRUE, TRUE, 0);
  gtk_misc_set_alignment (GTK_MISC (label5), 0.5, 1);

  progressbar = gtk_progress_bar_new ();
  gtk_widget_show (progressbar);
  gtk_box_pack_start (GTK_BOX (vBoxWaiting), progressbar, TRUE, FALSE, 0);

  labelWaiting = gtk_label_new (_("0 files"));
  gtk_widget_show (labelWaiting);
  gtk_box_pack_start (GTK_BOX (vBoxWaiting), labelWaiting, TRUE, TRUE, 0);
  gtk_misc_set_alignment (GTK_MISC (labelWaiting), 0.5, 0);

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_widget_show(vbox);
  gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 2);

  buttonSelectAll = gtk_button_new();
  gtk_tooltips_set_tip(tooltips, buttonSelectAll, _("Select all files."), NULL);
  gtk_widget_show (buttonSelectAll);
  gtk_box_pack_start (GTK_BOX (vbox), buttonSelectAll, FALSE, FALSE, 1);
  image2 = create_pixmap (mainWindow, "stock-select-all_20.png");
  gtk_widget_show (image2);
  gtk_container_add (GTK_CONTAINER (buttonSelectAll), image2);

  buttonUnselectAll = gtk_button_new();
  gtk_tooltips_set_tip(tooltips, buttonUnselectAll, _("Unselect all files."), NULL);
  gtk_widget_show (buttonUnselectAll);
  gtk_box_pack_start(GTK_BOX(vbox), buttonUnselectAll, FALSE, FALSE, 1);
  image2 = create_pixmap (mainWindow, "stock-unselect-all_20.png");
  gtk_widget_show (image2);
  gtk_container_add(GTK_CONTAINER(buttonUnselectAll), image2);

  buttonNext = gtk_button_new ();
  gtk_widget_show (buttonNext);
  gtk_box_pack_end (GTK_BOX (vbox), buttonNext, FALSE, FALSE, 1);
  gtk_tooltips_set_tip (tooltips, buttonNext, _("Render the next selected file."), NULL);

  image1 = gtk_image_new_from_stock ("gtk-go-down", GTK_ICON_SIZE_BUTTON);
  gtk_widget_show (image1);
  gtk_container_add (GTK_CONTAINER (buttonNext), image1);

  buttonPrevious = gtk_button_new ();
  gtk_widget_show (buttonPrevious);
  gtk_box_pack_end (GTK_BOX (vbox), buttonPrevious, FALSE, FALSE, 1);
  gtk_tooltips_set_tip (tooltips, buttonPrevious, _("Render the previous selected file."), NULL);

  image2 = gtk_image_new_from_stock ("gtk-go-up", GTK_ICON_SIZE_BUTTON);
  gtk_widget_show (image2);
  gtk_container_add (GTK_CONTAINER (buttonPrevious), image2);

  hbox = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox);
  gtk_box_pack_start(GTK_BOX(vbox1), hbox, FALSE, FALSE, 0);
  
  label = gtk_label_new(_("<span size=\"smaller\">Current dir.: </span>"));
  gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
  gtk_widget_show(label);
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
  
  labelDirectory = gtk_label_new("");
  gtk_label_set_use_markup(GTK_LABEL(labelDirectory), TRUE);
  gtk_misc_set_alignment(GTK_MISC(labelDirectory), 0., 0.5);
#if GTK_MINOR_VERSION > 5
  gtk_label_set_ellipsize(GTK_LABEL(labelDirectory), PANGO_ELLIPSIZE_START);
#endif
  gtk_widget_show(labelDirectory);
  gtk_box_pack_start(GTK_BOX(hbox), labelDirectory, TRUE, TRUE, 0);
  panelBrowserSet_labelCurrentDir();

  /***************/
  /* Action part */
  /***************/
  alignment1 = gtk_alignment_new(0.5, 0.5, 0.3, 0);
  gtk_widget_show(alignment1);
  gtk_box_pack_start(GTK_BOX(vbox1), alignment1, FALSE, FALSE, 2);

  hrule = gtk_hseparator_new();
  gtk_widget_show(hrule);
  gtk_container_add(GTK_CONTAINER(alignment1), hrule);

  hbox2 = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hbox2);
  gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, TRUE, 1);

  alignment1 = gtk_alignment_new(0.5, 0.5, 1.0, 0.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(alignment1), 0, 0, 0, 5);
  gtk_widget_show(alignment1);
  gtk_box_pack_start(GTK_BOX(hbox2), alignment1, FALSE, FALSE, 0);

  hbox5 = gtk_hbox_new(FALSE, 0);
  gtk_widget_show(hbox5);
  gtk_container_add(GTK_CONTAINER(alignment1), hbox5);
  
  radioGoAround = gtk_radio_button_new(NULL);
  gtk_radio_button_set_group(GTK_RADIO_BUTTON(radioGoAround), (GSList*)0);
  radiobuttonCycle_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioGoAround));
  gtk_widget_show(radioGoAround);
  gtk_box_pack_start(GTK_BOX(hbox5), radioGoAround, FALSE, FALSE, 0);
  image1 = create_pixmap(mainWindow, "stock-go-around.png");
  gtk_widget_show (image1);
  gtk_container_add(GTK_CONTAINER(radioGoAround), image1);

  radioGoOnce = gtk_radio_button_new(NULL);
  gtk_radio_button_set_group(GTK_RADIO_BUTTON(radioGoOnce), radiobuttonCycle_group);
  radiobuttonCycle_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioGoOnce));
  gtk_widget_show(radioGoOnce);
  gtk_box_pack_start(GTK_BOX(hbox5), radioGoOnce, FALSE, FALSE, 0);
  image1 = create_pixmap(mainWindow, "stock-go-once.png");
  gtk_widget_show (image1);
  gtk_container_add(GTK_CONTAINER(radioGoOnce), image1);

  radioGoAndBack = gtk_radio_button_new(NULL);
  gtk_radio_button_set_group(GTK_RADIO_BUTTON(radioGoAndBack), radiobuttonCycle_group);
  radiobuttonCycle_group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radioGoAndBack));
  gtk_widget_show(radioGoAndBack);
  gtk_box_pack_start(GTK_BOX(hbox5), radioGoAndBack, FALSE, FALSE, 0);
  image1 = create_pixmap(mainWindow, "stock-go-and-back.png");
  gtk_widget_show (image1);
  gtk_container_add(GTK_CONTAINER(radioGoAndBack), image1);

  label4 = gtk_label_new (_("Play at "));
  gtk_widget_show (label4);
  gtk_box_pack_start (GTK_BOX (hbox2), label4, TRUE, TRUE, 0);
  gtk_misc_set_alignment (GTK_MISC (label4), 1, 0.5);

  spinDelay_adj = gtk_adjustment_new (500, 10, 10000, 25, 100, 100);
  spinDelay = gtk_spin_button_new (GTK_ADJUSTMENT (spinDelay_adj), 1, 0);
  gtk_widget_show (spinDelay);
  gtk_box_pack_start (GTK_BOX (hbox2), spinDelay, FALSE, TRUE, 0);
  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinDelay), TRUE);

  /* Units: milliseconds */
  label1 = gtk_label_new (_(" ms"));
  gtk_widget_show (label1);
  gtk_box_pack_start (GTK_BOX (hbox2), label1, TRUE, TRUE, 0);
  gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5);

  buttonPlayStop = gtk_button_new ();
  gtk_tooltips_set_tip (tooltips, buttonPlayStop, _("Cycle through the selected files at the given rate."), NULL);
  gtk_widget_show (buttonPlayStop);
  gtk_box_pack_start (GTK_BOX (hbox2), buttonPlayStop, FALSE, FALSE, 5);

  hbox5 = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hbox5);
  gtk_container_add (GTK_CONTAINER (buttonPlayStop), hbox5);

  imagePlay = create_pixmap (mainWindow, "stock_media-play.png");
  gtk_widget_show (imagePlay);
  gtk_box_pack_start (GTK_BOX (hbox5), imagePlay, TRUE, TRUE, 0);

  imageStop = create_pixmap (mainWindow, "stock_media-stop.png");
  gtk_box_pack_start (GTK_BOX (hbox5), imageStop, TRUE, TRUE, 0);

  hbox3 = gtk_hbox_new (FALSE, 0);
  gtk_widget_show (hbox3);
  gtk_box_pack_start (GTK_BOX (vbox1), hbox3, FALSE, TRUE, 1);

  buttonDumpAll = gtk_button_new ();
  gtk_widget_show (buttonDumpAll);
  gtk_box_pack_start (GTK_BOX (hbox3), buttonDumpAll, TRUE, FALSE, 0);
  gtk_tooltips_set_tip (tooltips, buttonDumpAll, _("Export the rendering of all selected files in other formats."), NULL);

  alignment1 = gtk_alignment_new (0.5, 0.5, 0, 0);
  gtk_widget_show (alignment1);
  gtk_container_add (GTK_CONTAINER (buttonDumpAll), alignment1);

  hbox4 = gtk_hbox_new (FALSE, 2);
  gtk_widget_show (hbox4);
  gtk_container_add (GTK_CONTAINER (alignment1), hbox4);

  image4 = gtk_image_new_from_stock ("gtk-save-as", GTK_ICON_SIZE_BUTTON);
  gtk_widget_show (image4);
  gtk_box_pack_start (GTK_BOX (hbox4), image4, FALSE, FALSE, 0);

  label3 = gtk_label_new_with_mnemonic (_("Export all selected files"));
  gtk_widget_show (label3);
  gtk_box_pack_start (GTK_BOX (hbox4), label3, FALSE, FALSE, 0);

  return vbox1;
}

void createCallBacksBrowser()
{
  g_signal_connect(G_OBJECT(fileTree), "button-release-event",
               G_CALLBACK(treeViewClicked), (gpointer)0);
  g_signal_connect(G_OBJECT(fileTree), "row-activated",
               G_CALLBACK(treeViewActivated), (gpointer)0);
  g_signal_connect(G_OBJECT(buttonPrevious), "clicked",
               G_CALLBACK(navigateClicked), (gpointer)BROWSER_PREVIOUS);
  g_signal_connect(G_OBJECT(buttonNext), "clicked",
               G_CALLBACK(navigateClicked), (gpointer)BROWSER_NEXT);
  g_signal_connect(G_OBJECT(buttonSelectAll), "clicked",
               G_CALLBACK(checkFiles), (gpointer)1);
  g_signal_connect(G_OBJECT(buttonUnselectAll), "clicked",
               G_CALLBACK(checkFiles), (gpointer)0);
  g_signal_connect(G_OBJECT(buttonDirectory), "clicked",
               G_CALLBACK(onDirectoryClicked), (gpointer)0);
  g_signal_connect(G_OBJECT(buttonPlayStop), "clicked",
               G_CALLBACK(playStopClicked), (gpointer)0);
  g_signal_connect(G_OBJECT(spinDelay), "value-changed",
               G_CALLBACK(onSpinDelayChangeValue), (gpointer)0);
  g_signal_connect(G_OBJECT(buttonDumpAll), "clicked",
               G_CALLBACK(onDumpButtonClicked), (gpointer)0);
  g_signal_connect(G_OBJECT(visu), "renderingChanged",
               G_CALLBACK(clearListFiles), (gpointer)0);
  g_signal_connect(G_OBJECT(visu), "renderingChanged",
               G_CALLBACK(onRenderingChangedUpdateFilters), (gpointer)0);
  g_signal_connect(G_OBJECT(entryFilterBrowser), "changed",
               G_CALLBACK(filterBrowserChanged), (gpointer)0);
  g_signal_connect(G_OBJECT(panelBrowserComboFilter), "changed",
               G_CALLBACK(onComboFilterChanged), (gpointer)0);
  g_signal_connect(G_OBJECT(visu), "dataReadyForRendering",
               G_CALLBACK(onFileLoaded), (gpointer)0);
}

/*************/
/* Callbacks */
/*************/

void filterBrowserChanged(GtkEditable *entry, gpointer user_data)
{
  GPatternSpec *pattern;
  gboolean valid;
  GtkTreeIter iter;
  gboolean match;
  gchar *fileUTF8;

/*   fprintf(stderr, "'%s'\n", gtk_entry_get_text(GTK_ENTRY(entry))); */

  pattern = g_pattern_spec_new(gtk_entry_get_text(GTK_ENTRY(entry)));

  valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoreFiles), &iter);
  while (valid)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(listStoreFiles), &iter,
                   COLUMN_NAME_UTF8, &fileUTF8, -1);
      match = g_pattern_match_string(pattern, fileUTF8);
      gtk_list_store_set(listStoreFiles, &iter,
                   COLUMN_ACTIVE, match, -1);
      valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(listStoreFiles), &iter);
    }
  gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(listStoreFilesFilter));
}

gboolean treeViewClicked(GtkWidget *widget, GdkEventButton *event,
                   gpointer user_data)
{
  GtkTreePath *currentPath;
  GtkTreeIter iter, iterList;
  GtkTreeViewColumn *col;
  gboolean res;
  gboolean checked;

  if (event->button == 1)
    {
      res = gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW (fileTree),
                                event->x, event->y, &currentPath,
                                &col, NULL, NULL);

      if (!res)
      return FALSE;
      if (col == gtk_tree_view_get_column(GTK_TREE_VIEW(fileTree), COLUMN_BOOLEAN))
      {
        gtk_tree_model_get_iter(GTK_TREE_MODEL(listStoreFilesFilter), &iter, currentPath);
        gtk_tree_model_get(GTK_TREE_MODEL(listStoreFilesFilter), &iter,
                       COLUMN_BOOLEAN, &checked, -1);
        gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(listStoreFilesFilter),
                                             &iterList, &iter);
        gtk_list_store_set(listStoreFiles, &iterList,
                       COLUMN_BOOLEAN, !checked, -1);
      }
      gtk_tree_path_free(currentPath);
    }

  return FALSE;
}

void treeViewActivated(GtkTreeView *treeview, GtkTreePath *path,
                   GtkTreeViewColumn *col, gpointer user_data)
{
  GtkTreeIter iter, childIter;
  gboolean checked;
  gchar* filename, *utf8;

  gtk_tree_model_get_iter(GTK_TREE_MODEL(listStoreFilesFilter), &iter, path);
  gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(listStoreFilesFilter),
                                       &childIter, &iter);
  gtk_tree_model_get(GTK_TREE_MODEL(listStoreFiles), &childIter,
                 COLUMN_NAME, &filename,
                 COLUMN_NAME_UTF8, &utf8,
                 COLUMN_BOOLEAN, &checked, -1);
  if (!checked)
    gtk_list_store_set(GTK_LIST_STORE(listStoreFiles), &childIter,
                   COLUMN_BOOLEAN, TRUE, -1);

  DBG_fprintf(stderr, "Panel Browser : double clic asks for loading (%s).\n", filename);
  browserLoad(filename);
}
void navigateClicked(GtkButton *button, gpointer data)
{
  GtkTreeIter iter;
  GtkTreePath *path;
  gboolean res;

  res = panelBrowserGet_nextSelected(&path, &iter, GPOINTER_TO_INT(data));
  if (!res)
    return;

  res = navigateInFiles(path, &iter);
  gtk_tree_path_free(path);
}
void checkFiles(GtkButton *button, gpointer data)
{
  gtk_tree_model_foreach(GTK_TREE_MODEL(listStoreFilesFilter), checkFile, data);
}
void clearListFiles(GObject *obj, gpointer data)
{
  gtk_list_store_clear(listStoreFiles);
  listLoaded = FALSE;
  if (currentBrowseredDirectory)
    g_free(currentBrowseredDirectory);
  currentBrowseredDirectory = (gchar*)0;
}
void onRenderingChangedUpdateFilters(GObject *obj, gpointer data)
{
  int nb, i;
  GtkTreeIter iter;
  RenderingMethod *method;

  DBG_fprintf(stderr, "Panel Browser : catch the 'renderingChanged' signal,"
            " recreating filters...\n");
  gtk_list_store_clear(panelBrowserListFilter);
  method = getRenderingMethodInUse();
  if (!method)
    return;
  nb = renderingMethodGet_nbFileType(method);
  if (nb == 1)
    gtk_widget_set_sensitive(panelBrowserComboFilter, FALSE);
  else
    gtk_widget_set_sensitive(panelBrowserComboFilter, TRUE);
  for (i = 0; i < nb; i++)
    {
      gtk_list_store_append(panelBrowserListFilter, &iter);
      gtk_list_store_set(panelBrowserListFilter, &iter,
                   PANEL_BROWSER_COLUMN_FILTER_LABEL,
                   renderingMethodGet_fileTypeName(method, i),
                   PANEL_BROWSER_COLUMN_FILTER_ID, i,
                   -1);
    }
  gtk_combo_box_set_active(GTK_COMBO_BOX(panelBrowserComboFilter), 0);
  currentComboFilterValue = 0;
}
void onFileLoaded(GObject *obj, VisuData *dataObj, gpointer data)
{
  DBG_fprintf(stderr, "Panel Browser: caught 'dataReadyForRendering' signal'.\n");
  refreshCurrentFileList();
}
static void onRefreshDir(GtkButton *button, gpointer data)
{
  panelBrowserBrowse_directory((gchar*)0);
}
gboolean playSelectedFiles(gpointer data)
{
  GtkTreeIter iter;
  gboolean res;
  GtkTreePath *path;

  g_return_val_if_fail(startBrowsePath, FALSE);

  res = panelBrowserGet_nextSelected(&path, &iter, currentBrowseDirection);
  if (!res)
    return FALSE;

  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioGoAround)))
    {
      res = navigateInFiles(path, &iter);
      gtk_tree_path_free(path);
      return res;
    }

  res = TRUE;
  if (!gtk_tree_path_compare(path, startBrowsePath))
    {
      DBG_fprintf(stderr, "Panel Browser : On round is done, applyng policy.\n");
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioGoAndBack)))
      {
        if (currentBrowseDirection == BROWSER_PREVIOUS)
          {
            res = navigateInFiles(path, &iter);
            gtk_tree_path_free(path);
            currentBrowseDirection = BROWSER_NEXT;
          }
        else
          {
            gtk_tree_path_free(path);
            currentBrowseDirection = BROWSER_PREVIOUS;
            res = panelBrowserGet_nextSelected(&path, &iter, currentBrowseDirection);
            if (res)
            {
              res = navigateInFiles(path, &iter);
              gtk_tree_path_free(path);
            }
          }
      }
      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radioGoOnce)))
      {
        res = FALSE;
        navigateInFiles(path, &iter);
        gtk_tree_path_free(path);
      }
    }
  else
    {
      res = navigateInFiles(path, &iter);
      gtk_tree_path_free(path);
    }

  return res;
}

void playStopClicked(GtkButton *button, gpointer data)
{
  GtkTreeIter startIter;
  gboolean res;

  if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(panelBrowserListFilter), &startIter))
    return;
  if (!isPlayingCallbackId)
    {
      res = panelBrowserGet_currentSelected(&startBrowsePath, &startIter);
      if (!res)
      {
        res = panelBrowserGet_nextSelected(&startBrowsePath, &startIter, BROWSER_NEXT);
        if (!res)
          return;
        else
          navigateInFiles(startBrowsePath, &startIter);
      }

      /* Launch play */
      gtk_widget_hide(imagePlay);
      gtk_widget_show(imageStop);

      currentBrowseDirection = BROWSER_NEXT;
      isPlayingCallbackId =
      g_timeout_add_full(G_PRIORITY_DEFAULT + 30,
                     (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(spinDelay)),
                     playSelectedFiles, (gpointer)0,
                     stopPlayStop);
    }
  else
    {
      /* Stop play */
      g_source_remove(isPlayingCallbackId);
    }
}
void stopPlayStop(gpointer data)
{
  isPlayingCallbackId = 0;
  gtk_widget_hide(imageStop);
  gtk_widget_show(imagePlay);
  g_return_if_fail(startBrowsePath);
  gtk_tree_path_free(startBrowsePath);
}
void onSpinDelayChangeValue(GtkSpinButton *spinbutton,
                      GtkScrollType scroll,
                      gpointer user_data)
{
  GtkTreePath *startPath;

  if (isPlayingCallbackId != 0)
    {
      startPath = gtk_tree_path_copy(startBrowsePath);
      /* Stop playing at this rate */
      g_source_remove(isPlayingCallbackId);
      startBrowsePath = startPath;
      /* Flush the remove callback */
      visuWaitFunction();
      /* Relaunch playing */
      gtk_widget_hide(imagePlay);
      gtk_widget_show(imageStop);
      isPlayingCallbackId =
      g_timeout_add_full(G_PRIORITY_DEFAULT + 30,
                     (guint)gtk_spin_button_get_value(spinbutton),
                     playSelectedFiles, (gpointer)0,
                     stopPlayStop);
    }
}
void onDumpButtonClicked(GtkButton *button, gpointer user_data)
{
  GtkWidget *dump;
  GtkProgressBar *progressBarDump;
  char *filename;
  DumpType *format;
  int res;
  GString *buffer;
  GtkButton *abort;
  char *chr, *chr2;
  int goodPattern;
  int flagAbort;
  int i;
  GString *fileNumbered;
  GtkTreeIter iter;
  gboolean valid, checked, errors;
  GtkTreePath *currentPath;

  dump = dumpDialog_new(toolPanelGet_visuData(TOOL_PANEL(panelBrowser)));
  if (gtk_dialog_run(GTK_DIALOG(dump)) != GTK_RESPONSE_ACCEPT)
    {
      gtk_widget_destroy(dump);
      return;
    }

  filename = dumpDialogGet_fileName(DUMP_DIALOG(dump));
  format = dumpDialogGet_dumpType(DUMP_DIALOG(dump));
  if (!format || !filename)
    {
      fprintf(stderr, "INTERNAL ERROR! The dump dialog doesn't"
            " return the desired format nor the chosen name.\n");
      exit(1);
    }

  DBG_fprintf(stderr, "Panel Browser : dump all returns this filename"
            " pattern '%s' (format : %s)\n", filename, format->fileType->description);
  if (format->writeFunc)
    {
      res = 0;
      buffer = g_string_new(_("Dumping all selected files to images,"));
      g_string_append_printf(buffer, _(" format '%s'.\n\n"), format->fileType->description);
      /* Verify the name is regular */
      if (g_pattern_match_simple("*%0?d*", filename))
      {
        chr = strchr(filename, '%');
        if ((int)*(chr + 2) <= '0' || (int)*(chr + 2) > '9')
          {
            goodPattern = 0;
            g_string_append_printf(buffer, _("Error! The numbering pattern is"
                                     " wrong.\n"));
          }
        else
          {
            chr2 = strchr(chr + 1, '%');
            if (chr2)
            {
              goodPattern = 0;
              g_string_append_printf(buffer, _("Error! Only one '%%' character"
                                       " is allowed in the file name.\n"));
            }
            else
            goodPattern = 1;
          }
      }
      else
      {
        goodPattern = 0;
        g_string_append_printf(buffer, _("Error! Missing pattern in the filename.\n"));
      }
      if (!goodPattern)
      {
        g_string_append_printf(buffer, _("\nHelp : you must specify '%%0xd' in"
                                 " the filename, with 'x' is a number [|1;9|]."
                                 " This allows V_Sim to number the dumped"
                                 " files.\n\n For example, with a pattern like this"
                                 " : 'toto%%02d.pdf', dumped files will be named"
                                 " : toto00.pdf, toto01.pdf..."));
      }
      if (goodPattern)
      {
        abort = dumpDialogGet_cancelButton(DUMP_DIALOG(dump));
        progressBarDump = dumpDialogGet_progressBar(DUMP_DIALOG(dump));

        g_signal_connect (G_OBJECT(abort), "clicked",
                      G_CALLBACK(abortDump), (gpointer)&flagAbort);
        g_signal_connect (G_OBJECT(abort), "clicked",
                      G_CALLBACK(abortDumpAll), (gpointer)progressBarDump);

        gtk_progress_bar_set_fraction(progressBarDump, 0.);
        fileNumbered = g_string_new("");
        i = 0;
        flagAbort = 0;

        valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoreFilesFilter), &iter);
        errors = FALSE;
        while (valid && !errors && !flagAbort)
          {
            checked = FALSE;
            gtk_tree_model_get(GTK_TREE_MODEL(listStoreFilesFilter), &iter,
                         COLUMN_BOOLEAN, &checked, -1);
            if (checked)
            {
              g_string_append_printf(buffer, _("Write to file %d ..."), i);

              currentPath = gtk_tree_model_get_path(GTK_TREE_MODEL(listStoreFilesFilter), &iter);
              res = navigateInFiles(currentPath, &iter);
              gtk_tree_path_free(currentPath);
      
              if (!res)
                {
                  g_string_append_printf(buffer, _(" error\n"));
                  errors = TRUE;
                }
              else
                {
                  g_string_printf(fileNumbered, filename, i);
                  DBG_fprintf(stderr, "Panel browser : write '%s'\n",
                          fileNumbered->str);

                  gtk_progress_bar_set_text(progressBarDump,
                                    _("Waiting for generating image in memory..."));
                  visuWaitFunction();

                  res = (int)visuRenderingWindowDump
                  (RENDERING_WINDOW(currentRenderingWindow),
                   format, buffer, fileNumbered->str,
                   dumpDialogGet_widthValue(DUMP_DIALOG(dump)),
                   dumpDialogGet_heightValue(DUMP_DIALOG(dump)),
                   updateDumpAllProgressBar, (gpointer)progressBarDump); 
                  if (!res)
                  {
                    g_string_append_printf(buffer, _(" error\n"));
                    errors = TRUE;
                  }
                  else
                  g_string_append_printf(buffer, _(" OK\n"));
                }
              i++;
            }
            valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(listStoreFilesFilter), &iter);
          }
        g_string_free(fileNumbered, TRUE);
      }
      if (!goodPattern || errors)
      raiseAlertDialog(buffer->str);
      g_string_free(buffer, TRUE);
    }
  gtk_widget_destroy(dump);
  /* We replace the the last browsed directory to the current directory. */
  setLastOpenDirectory(currentBrowseredDirectory);
}
void updateDumpAllProgressBar(gpointer data)
{
  gdouble val;
  gdouble percentage;
  gdouble nEle;

  g_return_if_fail(GTK_PROGRESS_BAR(data));

  nEle = (gdouble)gtk_tree_model_iter_n_children(GTK_TREE_MODEL(listStoreFilesFilter), NULL);
  val = gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(data));
  if (((int)(val * nEle)) % 100 == 0)
    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(data), "");

  percentage = val + 0.01 / nEle;
  if (percentage > 1.0)
    percentage = 1.0;
  if (percentage < 0.)
    percentage = 0.;
  gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data), percentage);
  visuWaitFunction();
}
void abortDumpAll(GtkButton *button, gpointer data)
{
  gtk_progress_bar_set_text(GTK_PROGRESS_BAR(data),
                      _("Abortion request, please wait..."));
}





/******************/
/* Public methods */
/******************/

gboolean panelBrowserGet_currentSelected(GtkTreePath **path, GtkTreeIter *iterSelected)
{
  GtkTreeSelection *selection;
  gboolean res;
  GtkTreeModel *model;

  g_return_val_if_fail(path && iterSelected, FALSE);

  if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoreFilesFilter), iterSelected))
    return FALSE;

  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(fileTree));
  res = gtk_tree_selection_get_selected(selection, &model, iterSelected);

  if (res)
    *path = gtk_tree_model_get_path(model, iterSelected);
  return res;
}

gboolean panelBrowserGet_nextSelected(GtkTreePath **path, GtkTreeIter *iterSelected, int direction)
{
  GtkTreeSelection *selection;
  GtkTreePath *currentPath, *firstPath;
  GtkTreeIter iter;
  gboolean res, checked;
  GtkTreeModel *model;
  int loopComplete;

  g_return_val_if_fail(path && iterSelected &&
                   (direction == BROWSER_NEXT || direction == BROWSER_PREVIOUS), FALSE);

  *path = (GtkTreePath*)0;

  if (!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoreFilesFilter), &iter))
    return FALSE;

  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(fileTree));
  res = gtk_tree_selection_get_selected(selection, &model, &iter);

  /* Cas où rien n'est sélectionné */
  if (!res)
    {
      if (direction == BROWSER_NEXT)
      res = gtk_tree_model_get_iter_last(GTK_TREE_MODEL(listStoreFilesFilter),
                                 &iter, (GtkTreePath**)0);
      else if (GPOINTER_TO_INT(direction) == BROWSER_PREVIOUS)
      res = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoreFilesFilter), &iter);
    }
  g_return_val_if_fail(res, FALSE);

  currentPath = gtk_tree_model_get_path(GTK_TREE_MODEL(listStoreFilesFilter), &iter);
  firstPath = gtk_tree_path_copy(currentPath);
  do
    {
      if (direction == BROWSER_NEXT)
      {
        /* Avance d'un pas dans la liste */
        gtk_tree_path_next(currentPath);
        /* Recupère l'itération avancée d'un pas */
        res = gtk_tree_model_get_iter(GTK_TREE_MODEL(listStoreFilesFilter),
                              &iter, currentPath);
        /* Si cette iteration n'existe pas on revient au début. */
        if (!res)
          {
            gtk_tree_model_get_iter_first(GTK_TREE_MODEL(listStoreFilesFilter),
                                  &iter);
            gtk_tree_path_free(currentPath);
            currentPath =
            gtk_tree_model_get_path(GTK_TREE_MODEL(listStoreFilesFilter), &iter);
          }
      }
      else if (direction == BROWSER_PREVIOUS)
      {
        /* Recule d'un pas dans la liste */
        res = gtk_tree_path_prev(currentPath);
        /* Recupère l'itération reculée d'un pas */
        res = res && gtk_tree_model_get_iter(GTK_TREE_MODEL(listStoreFilesFilter),
                              &iter, currentPath);
        /* Si ce path n'existe pas ou 
           si cette iteration n'existe pas on va à la fin. */
        if (!res)
          {
            gtk_tree_path_free(currentPath);
            res = gtk_tree_model_get_iter_last(GTK_TREE_MODEL(listStoreFilesFilter),
                                     &iter, &currentPath);
            if (!res)
            {
              g_warning("Panel browser : impossible to find"
                      " the end of the list.\n");
              gtk_tree_path_free(currentPath);
              gtk_tree_path_free(firstPath);
              return FALSE;
            }
          }
      }

      /* Récupère les données pour l'itération avancée d'un pas. */
      checked = FALSE;
      gtk_tree_model_get(GTK_TREE_MODEL(listStoreFilesFilter), &iter,
                   COLUMN_BOOLEAN, &checked, -1);
/*       fprintf(stderr, "%d '%s'\n", nbSteps, filename); */
      loopComplete = !gtk_tree_path_compare(firstPath, currentPath);
    }
  while ( !checked && !loopComplete);
  gtk_tree_path_free(firstPath);
  if (!loopComplete)
    {
      *path = currentPath;
      *iterSelected = iter;
      return TRUE;
    }
  else
    {
      gtk_tree_path_free(currentPath);
      return FALSE;
    }
}

gboolean navigateInFiles(GtkTreePath *path, GtkTreeIter *iterSelected)
{
  GtkTreeSelection *selection;
  gboolean res;
  gchar *filename;

  g_return_val_if_fail(path && iterSelected, FALSE);

  /* Rend l'iter sélectionné */
  selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(fileTree));
  gtk_tree_selection_select_iter(selection, iterSelected);
  gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(fileTree), path, NULL, FALSE, 0., 0.);
      
  /* Load the new selected file */
  gtk_tree_model_get(GTK_TREE_MODEL(listStoreFilesFilter), iterSelected,
                 COLUMN_NAME, &filename, -1);
  res = browserLoad(filename);
  return res;
}

gboolean browserLoad(gchar *filename)
{
  gchar *pathToFile;
  GError *error;
  VisuData *data, *prevData;
  RenderingMethod *method;
  int kind, nbKind;
  gboolean changeElement, res;
  VisuData *dataObj;
  RenderingWindow *window;

  window = RENDERING_WINDOW(visuRenderingWindowGet_current());
  g_return_val_if_fail(window, FALSE);

  dataObj = toolPanelGet_visuData(TOOL_PANEL(panelBrowser));
  if (dataObj)
    data = visuDataNew_withOpenGLView(visuDataGet_openGLView(dataObj));
  else
    data = visuDataNew();
  g_return_val_if_fail(data, FALSE);

  method = getRenderingMethodInUse();
  if (!method)
    {
      fprintf(stderr, "INTERNAL ERROR! Can't load file '%s' since no"
            " rendering method is specififed.\n", filename);
      return FALSE;
    }
  pathToFile = g_build_filename(currentBrowseredDirectory, filename, NULL);
  visuDataAdd_file(data, pathToFile, currentComboFilterValue, (FileFormat*)0);
  g_free(pathToFile);
  nbKind = renderingMethodGet_nbFileType(method);
  dataObj = toolPanelGet_visuData(TOOL_PANEL(panelBrowser));
  if (nbKind > 1 && !dataObj)
    {
      raiseAlertDialog(_("Can't load this file through the browser because it"
                   " requires to read several files. You should use the 'Open'"
                   " button on the main panel and then use the browser to vary"
                   " one kind of file at a time."));
      g_object_unref(data);
      return FALSE;

    }
  for (kind = 0; kind < nbKind; kind++)
    if (kind != currentComboFilterValue)
      visuDataAdd_file(data, visuDataGet_file(dataObj, kind, (FileFormat**)0),
                   kind, (FileFormat*)0);

  prevData = dataObj;

  error = (GError*)0;
  res = visuBasicLoad_dataFromFile(data, (FileFormat*)0, &error);
  if (!res)
    {
      raiseAlertDialog(error->message);
      dataObj = (VisuData*)0;
    }
  else
    dataObj = data;

  if (prevData && dataObj)
    {
      changeElement = visuData_compareElements(prevData, dataObj);
      visuDataSet_changeElementFlag(dataObj, changeElement);
      /* Useless unref since, attaching dataObj to the window on
       next line will unref the previous VisuData object attached. */
/*       g_object_unref(G_OBJECT(prevData)); */
    }
  renderingWindowSet_visuData(window, dataObj);
  if (dataObj)
    {
      visuData_createAllNodes(dataObj);
      g_signal_emit (visu, VISU_GET_CLASS (visu)->OpenGLAskForReDraw_signal_id,
                 0 , NULL);
    }

  if (error)
    g_error_free(error);

  if (dataObj)
    return TRUE;
  else
    return FALSE;
}

gboolean checkFile(GtkTreeModel *model, GtkTreePath *path,
               GtkTreeIter *iter, gpointer data)
{
  gboolean filterOk;
  GtkTreeIter iterList;
  GtkListStore *list;

  /* If we check the row, the checkbutton is on only
     if the name is in accordance with the filter. */
  gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(listStoreFilesFilter),
                                       &iterList, iter);
  list = GTK_LIST_STORE(gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(listStoreFilesFilter)));
  if (GPOINTER_TO_INT(data))
    {
      gtk_tree_model_get(GTK_TREE_MODEL(model), iter, COLUMN_ACTIVE,
                   &filterOk, -1);
      
      if (filterOk)
      gtk_list_store_set(list, &iterList, COLUMN_BOOLEAN,
                     TRUE, -1);
      else
      gtk_list_store_set(list, &iterList, COLUMN_BOOLEAN,
                     FALSE, -1);
    }
  else
    {
      gtk_list_store_set(list, &iterList, COLUMN_BOOLEAN,
                   FALSE, -1);
    }
  return FALSE;
}

static void panelBrowserBrowse_directory(gchar* dir)
{
  GDir *gdir;
  const gchar *fileFromDir;
  gchar *fileUTF8, *file;
  GtkTreeIter iter;
  gsize lu, ecrit;
  GPatternSpec ***pattern;
  int *nbPattern, i;
  RenderingMethod* method;
  gboolean passed;
  char nbFilesLabel[36];
  GList *tmpLst, *tmpLst2;
  int nbFiles;
  gint nbKind, kind;

  if (!dir)
    dir = currentBrowseredDirectory;
  else
    {
      /* Set the new directory current. */
      if (currentBrowseredDirectory)
      g_free(currentBrowseredDirectory);
      currentBrowseredDirectory = g_strdup(dir);
      DBG_fprintf(stderr, "Panel Browser: set currentBrowseredDirectory to '%s'.\n",
              currentBrowseredDirectory);
    }

  g_return_if_fail(dir);

  DBG_fprintf(stderr, "Panel browser : scanning directory '%s'.\n", dir);
  gdir = g_dir_open(dir, 0, NULL);
  if (!gdir)
    {
      raiseAlertDialog(_("The specified directory is unreadable."));
      return;
    }
  DBG_fprintf(stderr, "Panel browser : cleaning of the list.\n");
  gtk_list_store_clear(listStoreFiles);
  listLoaded = FALSE;
  
  method = getRenderingMethodInUse();
  if (!method)
    return;

  nbKind = renderingMethodGet_nbFileType(method);
  pattern = malloc(sizeof(GPatternSpec**) * nbKind);
  nbPattern = malloc(sizeof(int) * nbKind);
  if (!pattern || !nbPattern)
    {
      allocationProblems();
      exit(1);
    }
  for( kind = 0; kind < nbKind; kind++)
    {
      nbPattern[kind] = 0;
      tmpLst = renderingMethodGet_fileType(method, kind);
      while (tmpLst)
      {
        nbPattern[kind] += g_list_length(((FileFormat*)tmpLst->data)->fileType);
        tmpLst = g_list_next(tmpLst);
      }
      if (nbPattern[kind])
      {
        pattern[kind] = malloc(sizeof(GPatternSpec*) * nbPattern[kind]);
        if (!pattern[kind])
          {
            allocationProblems();
            exit(1);
          }
        i = 0;
        tmpLst = renderingMethodGet_fileType(method, kind);
        while (tmpLst)
          {
            tmpLst2 = ((FileFormat*)tmpLst->data)->fileType;
            while (tmpLst2)
            {
              pattern[kind][i] = g_pattern_spec_new((char*)tmpLst2->data);
              tmpLst2 = g_list_next(tmpLst2);
              i++;
            }
            tmpLst = g_list_next(tmpLst);
          }
      }
      else
      {
        g_warning("WARNING! The present rendering method has no"
                " pattern for prefered file of kind %d, assuming '*'.\n", kind);
        pattern[kind] = malloc(sizeof(GPatternSpec*));
        if (!pattern[kind])
          {
            allocationProblems();
            exit(1);
          }
        nbPattern[kind] = 1;
        pattern[kind][0] = g_pattern_spec_new((char*)"*");
      }
    }

  /* Add a timeout to show the progress bar if the scan is too long. */
  flagWorkInProgress = TRUE;
  flagBarIsShown = FALSE;
  g_timeout_add(150, showProgressBar, (gpointer)0);
    
  gtk_tree_view_set_model(GTK_TREE_VIEW(fileTree),
                    (GtkTreeModel*)0);
  nbFiles = 0;
  fileFromDir = g_dir_read_name(gdir);
  while (fileFromDir)
    {
      passed = FALSE;
      file = g_strdup(fileFromDir);
      DBG_fprintf(stderr, "Panel Browser: read file '%s'\n", file);
      if (!getFileSystemInUTF8())
      {
        fileUTF8 = g_filename_to_utf8(fileFromDir, -1, &lu, &ecrit, NULL);
        if (!fileUTF8)
          g_warning("INTERNAL ERROR! Impossible to convert this file"
                  " name (%s) to UTF8.\n", fileFromDir);
      }
      else
      fileUTF8 = g_strdup(file);

      if(fileUTF8)
      {
        for (kind = 0; kind < nbKind && !passed; kind++)
          {
            for (i = 0; i < nbPattern[kind] && !passed; i++)
            passed = passed || g_pattern_match_string(pattern[kind][i], fileUTF8);
            if (passed)
            {
              DBG_fprintf(stderr, "Panel Browser: file added.\n");
              gtk_list_store_append(listStoreFiles, &iter);
              gtk_list_store_set(listStoreFiles, &iter,
                             COLUMN_BOOLEAN, FALSE,
                             COLUMN_NAME, file,
                             COLUMN_NAME_UTF8, fileUTF8,
                             COLUMN_DATA, "??",
                             COLUMN_ACTIVE, TRUE,
                             COLUMN_FILE_KIND, kind,
                              -1);
              nbFiles ++;
            }
          }
      }
      if (flagBarIsShown && nbFiles%10 == 0)
      {
        gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressbar));
        sprintf(nbFilesLabel, _("%d files."), nbFiles);
        gtk_label_set_text(GTK_LABEL(labelWaiting), nbFilesLabel);
      }
      visuWaitFunction();
      fileFromDir = g_dir_read_name(gdir);
    }
  flagWorkInProgress = FALSE;
  g_dir_close(gdir);

  panelBrowserSet_labelCurrentDir();

  listLoaded = TRUE;
  for (kind = 0; kind < nbKind; kind++)
    {
      for (i = 0; i < nbPattern[kind]; i++)
      g_pattern_spec_free(pattern[kind][i]);
      free(pattern[kind]);
    }
  free(pattern);
  free(nbPattern);
  gtk_tree_view_set_model(GTK_TREE_VIEW(fileTree),
                    GTK_TREE_MODEL(listStoreFilesFilter));
  if (flagBarIsShown)
    {
      gtk_widget_show(scrolledwindow1);
      gtk_widget_hide(vBoxWaiting);
      flagBarIsShown = FALSE;
    }
  gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(listStoreFilesFilter));
}

static void onBrowserEnter(ToolPanel *toolPanel, gpointer data)
{
  refreshCurrentFileList();
}

static void refreshCurrentFileList()
{
  /* This method treats the case of refreshing the list of files for:
     - an enter action in the panel, we check if nothing has been browsed
       or if the current browsed dir is different than current dir.
     - a new file is loaded, we check that the load action didn't change the
       current dir.
  */
  DBG_fprintf(stderr, "Panel Browser: compare dirs '%s' '%s'.\n", 
            currentBrowseredDirectory, getLastOpenDirectory());
  if (currentBrowseredDirectory &&
      !strcmp(currentBrowseredDirectory, getLastOpenDirectory()))
    return;

  DBG_fprintf(stderr, "Panel Browser: refreshing file list...\n");
  panelBrowserBrowse_directory(getLastOpenDirectory());
}

static void onDirectoryClicked(GtkButton *button, gpointer data)
{
  char *filename;

  filename = getSelectedDirectory();

  if (!filename)
    return;

  panelBrowserBrowse_directory(filename);  
  g_free(filename);
}

gboolean showProgressBar(gpointer data)
{
  if (flagWorkInProgress)
    {
      gtk_widget_hide(scrolledwindow1);
      gtk_widget_show(vBoxWaiting);
      DBG_fprintf(stderr, "Panel Browser : scanning is too slow, showing progress bar.\n");
      flagBarIsShown = TRUE;
    }
  return FALSE;
}


/***************************/
/* Miscellaneous functions */
/***************************/

gboolean gtk_tree_model_get_iter_last(GtkTreeModel *model, GtkTreeIter *last, GtkTreePath **path)
{
  gboolean valid;
  GtkTreeIter iter;

  if (!model || !last)
    {
      fprintf(stderr, "WARNING! 'gtk_tree_model_get_iter_last' has been called with a"
            " null model or a null last argument.\n");
      return FALSE;
    }

  valid = gtk_tree_model_get_iter_first(model, &iter);
  if (valid)
    *last = iter;
  else
    return FALSE;
  while (valid)
    {
      *last = iter;
      valid = gtk_tree_model_iter_next(model, &iter);
    }

  if (path)
    {
      if (last)
      *path = gtk_tree_model_get_path(model, last);
      else
      *path = (GtkTreePath*)0;
    }
  
  return TRUE;
}

gboolean panelBrowserIsIterVisible(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
  gboolean passUserFilter;
  gint kind;
  
  gtk_tree_model_get(model, iter,
                 COLUMN_FILE_KIND, &kind,
                 COLUMN_ACTIVE, &passUserFilter,
                 -1);
  return (passUserFilter && (kind == currentComboFilterValue));
}

void onComboFilterChanged(GtkComboBox *combo, gpointer data)
{
  GtkTreeIter comboIter;
  gboolean validIter;

  validIter = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(panelBrowserComboFilter), &comboIter);
  if (!validIter)
    return;

  gtk_tree_model_get(GTK_TREE_MODEL(panelBrowserListFilter), &comboIter,
                 PANEL_BROWSER_COLUMN_FILTER_ID, &currentComboFilterValue,
                 -1);
  gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(listStoreFilesFilter));
}

void panelBrowserSet_labelCurrentDir()
{
  gchar *directoryUTF8, *markup;

  if (!currentBrowseredDirectory)
    return;

  directoryUTF8 = getStringInUTF8(currentBrowseredDirectory);
  markup = g_markup_printf_escaped(_("<span style=\"italic\" size=\"smaller\">%s</span>"),
                           directoryUTF8);
  g_free(directoryUTF8);
  gtk_label_set_markup(GTK_LABEL(labelDirectory), markup);
  g_free(markup);
}

Generated by  Doxygen 1.6.0   Back to index