/*   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 <gtk/gtk.h>

#include "gtk_stippleComboBoxWidget.h"
#include <visu_tools.h>

/**
 * SECTION:gtk_stippleComboBoxWidget
 * @short_description: Defines a specialised #GtkComboBox to choose
 * patterns for lines.
 * @see_also: #VisuUiShadeCombobox
 *
 * <para>This widget looks like a #GtkComboBox and it displays a list
 * of preset patterns for line. These patterns are defined by a
 * guint16 value that is given to OpenGL for line stipple.</para>
 * <para>This widget can emit a #VisuUiStippleCombobox::stipple-selected
 * signal that is a wrapper around the #GtkComboBox::changed signal,
 * but it is emitted only when a stipple is selected and this stipple
 * is passed to the call back.</para>
 *
 * Since: 3.4
 */

enum {
  STIPPLE_SELECTED_SIGNAL,
  LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };

enum
  {
    PROP_0,
    VALUE_PROP,
    N_PROP
  };
static GParamSpec *properties[N_PROP];

/* This enum is used to access the column of the GtkListStore
   that contains the informations of stroed shades. */
enum
  {
    /* This has a pointer to an image to represent the stipple. */
    COLUMN_STIPPLE_PIXBUF,
    /* This is a pointer to a label that describes the stipple. */
    COLUMN_STIPPLE_LABEL,
    /* This is the value of the stipple. */
    COLUMN_STIPPLE_VALUE,

    N_COLUMN_STIPPLE
  };

/* Store a tree model to remember stipples. */
#define STIPPLE_BOX_WIDTH  32
#define STIPPLE_BOX_HEIGHT 3
#define STIPPLE_BOX_BITS   8

static void visu_ui_stipple_combobox_dispose (GObject *obj);
static void visu_ui_stipple_combobox_finalize(GObject *obj);
static void visu_ui_stipple_combobox_get_property(GObject* obj, guint property_id,
                                                  GValue *value, GParamSpec *pspec);
static void visu_ui_stipple_combobox_set_property(GObject* obj, guint property_id,
                                                  const GValue *value, GParamSpec *pspec);


/**
 * VisuUiStippleCombobox:
 *
 * Private structure to store informations of a #VisuUiStippleCombobox object.
 *
 * Since: 3.4
 */
struct _VisuUiStippleCombobox
{
  GtkComboBox comboStipple;
  guint16 previousStipple;

  /* Memory gestion. */
  gboolean dispose_has_run;
};
/**
 * VisuUiStippleComboboxClass
 *
 * Private structure to store informations of a #VisuUiStippleComboboxClass object.
 *
 * Since: 3.4
 */
struct _VisuUiStippleComboboxClass
{
  GtkComboBoxClass parent_class;

  void (*stippleComboBox) (VisuUiStippleCombobox *stippleCombo);

  /* This listStore contains all the stipples
     known by widgets of this class. It is used
     as TreeModel for the combobox in the widget. */
  GtkListStore *listStoredStipples;

  gulong stippleAddedSignalId;
};

/* Built-in stipple values. */
static guint16 builtInStipples[] = {65535, 43690, 52428, 61680, 65280,
				    58596, 57568, 49344, 65340, 0};

/* Local callbacks. */
static void visu_ui_stipple_combobox_changed(VisuUiStippleCombobox *stippleComboBox,
				    gpointer data _U_);

/* Local methods. */
static void addStippleToModel(GtkTreeIter *iter, VisuUiStippleComboboxClass* klass,
			      guint16 value);
static void buildWidgets(VisuUiStippleCombobox *stippleComboBox);

/**
 * visu_ui_stipple_combobox_get_type
 *
 * #GType are unique numbers to identify objects.
 *
 * Returns: the #GType associated with #VisuUiStippleCombobox objects.
 *
 * Since: 3.4
 */
G_DEFINE_TYPE(VisuUiStippleCombobox, visu_ui_stipple_combobox, GTK_TYPE_COMBO_BOX)

static void visu_ui_stipple_combobox_class_init(VisuUiStippleComboboxClass *klass)
{
  GtkTreeIter iter;
  int i;
  
  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: creating the class of the widget.\n");
  DBG_fprintf(stderr, "                     - adding new signals ;\n");
  /**
   * VisuUiStippleCombobox::stipple-selected:
   * @combo: the #VisuUiStippleCombobox that emits the signal ;
   * @stipple: the value of the newly selected line patter.
   *
   * This signal is emitted when a new valid line pattern is selected.
   *
   * Since: 3.4
   */
  signals[STIPPLE_SELECTED_SIGNAL] =
    g_signal_new ("stipple-selected",
		  G_TYPE_FROM_CLASS (klass),
		  G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (VisuUiStippleComboboxClass, stippleComboBox),
		  NULL, 
		  NULL,                
		  g_cclosure_marshal_VOID__UINT,
		  G_TYPE_NONE, 1, G_TYPE_UINT);

  DBG_fprintf(stderr, "                     - initializing the listStore of stipples.\n");
  /* Init the listStore of stipples. */
  klass->listStoredStipples = gtk_list_store_new(N_COLUMN_STIPPLE,
						 GDK_TYPE_PIXBUF,
						 G_TYPE_STRING,
						 G_TYPE_UINT);
  for (i = 0; builtInStipples[i]; i++)
    addStippleToModel(&iter, klass, builtInStipples[i]);
  
  /* Connect freeing methods. */
  G_OBJECT_CLASS(klass)->dispose = visu_ui_stipple_combobox_dispose;
  G_OBJECT_CLASS(klass)->finalize = visu_ui_stipple_combobox_finalize;
  G_OBJECT_CLASS(klass)->set_property = visu_ui_stipple_combobox_set_property;
  G_OBJECT_CLASS(klass)->get_property = visu_ui_stipple_combobox_get_property;

  /**
   * VisuUiStippleCombobox::value:
   *
   * Store the current stipple.
   *
   * Since: 3.8
   */
  properties[VALUE_PROP] = g_param_spec_uint("value", "stipple value",
                                             "stipple pattern for OpenGL",
                                             0, 65535, (guint)builtInStipples[0],
                                             G_PARAM_READWRITE);
  g_object_class_install_property(G_OBJECT_CLASS(klass), VALUE_PROP,
				  properties[VALUE_PROP]);
}

static void visu_ui_stipple_combobox_dispose(GObject *obj)
{
  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: dispose object %p.\n", (gpointer)obj);

  if (VISU_UI_STIPPLE_COMBOBOX(obj)->dispose_has_run)
    return;

  VISU_UI_STIPPLE_COMBOBOX(obj)->dispose_has_run = TRUE;
  /* Chain up to the parent class */
  DBG_fprintf(stderr, " | chain to parent\n");
  G_OBJECT_CLASS(visu_ui_stipple_combobox_parent_class)->dispose(obj);
  DBG_fprintf(stderr, " | disposing ... OK.\n");
}
static void visu_ui_stipple_combobox_finalize(GObject *obj)
{
  g_return_if_fail(obj);

  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: finalize object %p.\n", (gpointer)obj);

  /* Chain up to the parent class */
  G_OBJECT_CLASS(visu_ui_stipple_combobox_parent_class)->finalize(obj);

  DBG_fprintf(stderr, " | freeing ... OK.\n");
}
static void visu_ui_stipple_combobox_get_property(GObject* obj, guint property_id,
                                                  GValue *value, GParamSpec *pspec)
{
  guint16 stipple;
  VisuUiStippleCombobox *self = VISU_UI_STIPPLE_COMBOBOX(obj);

  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: get property '%s' -> ",
	      g_param_spec_get_name(pspec));
  switch (property_id)
    {
    case VALUE_PROP:
      stipple = visu_ui_stipple_combobox_getSelection(self);
      g_value_set_uint(value, (guint)stipple);
      DBG_fprintf(stderr, "%d.\n", stipple);
      break;
    default:
      /* We don't have any other property... */
      G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
      break;
    }
}
static void visu_ui_stipple_combobox_set_property(GObject* obj, guint property_id,
                                                  const GValue *value, GParamSpec *pspec)
{
  guint16 stipple;
  VisuUiStippleCombobox *self = VISU_UI_STIPPLE_COMBOBOX(obj);

  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: set property '%s' -> ",
	      g_param_spec_get_name(pspec));
  switch (property_id)
    {
    case VALUE_PROP:
      stipple = (guint16)g_value_get_uint(value);
      visu_ui_stipple_combobox_set(self, stipple);
      DBG_fprintf(stderr, "%d.\n", stipple);
      break;
    default:
      /* We don't have any other property... */
      G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
      break;
    }
}

static void visu_ui_stipple_combobox_init(VisuUiStippleCombobox *stippleComboBox)
{
  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: initializing new object (%p).\n",
	      (gpointer)stippleComboBox);

  stippleComboBox->previousStipple = (guint16)0;
  stippleComboBox->dispose_has_run = FALSE;
}

static void buildWidgets(VisuUiStippleCombobox *stippleComboBox)
{
  GObjectClass *klass;
  GtkCellRenderer *renderer;

  klass = G_OBJECT_GET_CLASS(stippleComboBox);
  gtk_combo_box_set_model(GTK_COMBO_BOX(stippleComboBox),
			  GTK_TREE_MODEL(VISU_UI_STIPPLE_COMBOBOX_CLASS(klass)->listStoredStipples));

  renderer = gtk_cell_renderer_pixbuf_new();
  gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stippleComboBox), renderer, FALSE);
  gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(stippleComboBox), renderer,
				"pixbuf", COLUMN_STIPPLE_PIXBUF);
/*   renderer = gtk_cell_renderer_text_new(); */
/*   gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(stippleComboBox), renderer, FALSE); */
/*   gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(stippleComboBox), renderer, */
/* 				"markup", COLUMN_STIPPLE_LABEL); */

  gtk_combo_box_set_active(GTK_COMBO_BOX(stippleComboBox), 0);
  g_signal_connect(G_OBJECT(stippleComboBox), "changed",
		   G_CALLBACK(visu_ui_stipple_combobox_changed), (gpointer)0);
}

/**
 * visu_ui_stipple_combobox_new :
 *
 * A #VisuUiStippleCombobox widget is like a #GtkComboBox widget, but it is already filled
 * with predefined line patterns (call stipple). Using this widget is
 * a convienient way to share stipples between all part of V_Sim and
 * to give a consistent look of all stipple selection.
 *
 * Returns: (transfer full): a newly created #VisuUiStippleCombobox widget.
 *
 * Since: 3.4
 */
GtkWidget* visu_ui_stipple_combobox_new()
{
  VisuUiStippleCombobox *stippleComboBox;

  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: creating new object.\n");

  stippleComboBox = VISU_UI_STIPPLE_COMBOBOX(g_object_new(VISU_TYPE_UI_STIPPLE_COMBOBOX, NULL));

  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: build widgets.\n");
  buildWidgets(stippleComboBox);

  return GTK_WIDGET(stippleComboBox);
}

static void visu_ui_stipple_combobox_changed(VisuUiStippleCombobox *stippleComboBox,
                                             gpointer data _U_)
{
  int selected;
  guint16 stipple;

  selected = gtk_combo_box_get_active(GTK_COMBO_BOX(stippleComboBox));
  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: internal combobox changed signal -> %d.\n", selected);
  if (selected < 0)
    {
      stippleComboBox->previousStipple = (guint16)0;
/*       DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox : emitting 'stipple-selected' signal.\n"); */
/*       g_signal_emit(G_OBJECT(stippleComboBox), */
/* 		    signals[STIPPLE_SELECTED_SIGNAL], 0, (gpointer)0, NULL); */
      return;
    }

  stipple = visu_ui_stipple_combobox_getSelection(stippleComboBox);
  if (stipple && stipple != stippleComboBox->previousStipple)
    {
      stippleComboBox->previousStipple = stipple;
      DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: emitting 'stipple-selected'"
		  " signal for value %d.\n", stipple);
      g_object_notify_by_pspec(G_OBJECT(stippleComboBox), properties[VALUE_PROP]);
      g_signal_emit(G_OBJECT(stippleComboBox),
		    signals[STIPPLE_SELECTED_SIGNAL],
                    0, (guint)stipple, NULL);
    }
  else
    DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: aborting 'stipple-selected' signal.\n");
}
/**
 * visu_ui_stipple_combobox_class_buildStamp:
 * @stipple: a pattern value.
 *
 * This method is used to create pixbuf representing stipples.A new
 * pixbuf is created.
 *
 * Returns: (transfer full): a pixbuf pointer.
 *
 * Since: 3.4
 */
GdkPixbuf* visu_ui_stipple_combobox_class_buildStamp(guint16 stipple)
{
  GdkPixbuf *pixbufStippleBox;
  int rowstride, x, y;
  guchar *pixels, *p;
  guint16 coul;

  pixbufStippleBox = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE,
				    STIPPLE_BOX_BITS,
				    STIPPLE_BOX_WIDTH,
				    STIPPLE_BOX_HEIGHT);
  rowstride = gdk_pixbuf_get_rowstride(pixbufStippleBox);
  pixels = gdk_pixbuf_get_pixels(pixbufStippleBox);
  for (x = 0; x < STIPPLE_BOX_WIDTH; x++)
    {
      coul = stipple & (1 << ((x+3)%16));
      for (y = 0; y < STIPPLE_BOX_HEIGHT; y++)
	{
	  p    = pixels + y * rowstride + x * 4;
	  p[0] = 0;
	  p[1] = 0;
	  p[2] = 0;
	  p[3] = (coul)?255:0;
	}
    }
  return pixbufStippleBox;
}

void addStippleToModel(GtkTreeIter *iter, VisuUiStippleComboboxClass* klass, guint16 stipple)
{
  GdkPixbuf *pix;
  gchar *label;

  g_return_if_fail(iter && klass && stipple);

  label = g_markup_printf_escaped("<span size=\"smaller\"><i>(%d)</i></span>",
				  stipple);
  pix = visu_ui_stipple_combobox_class_buildStamp(stipple);
  gtk_list_store_append(klass->listStoredStipples, iter);
  gtk_list_store_set(klass->listStoredStipples, iter,
		     COLUMN_STIPPLE_PIXBUF, pix,
		     COLUMN_STIPPLE_LABEL,  label,
		     COLUMN_STIPPLE_VALUE,  (guint)stipple,
		     -1);
  g_object_unref(pix);
  g_free(label);
  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: appending a new stipple '%d'.\n",
	      stipple);
}
/**
 * visu_ui_stipple_combobox_setSelection:
 * @stippleComboBox: a #VisuUiStippleCombobox widget ;
 * @stipple: a pattern value.
 *
 * Use this method to set the ComboBox on the given stipple. This emits a 'stipple-channel'
 * signal if the stipple is changed, which means, a previous stipple has been modified,
 * or a new stipple is selected.
 *
 * Returns: TRUE if the @stipple already exists in the model.
 *
 * Since: 3.4
 */
gboolean visu_ui_stipple_combobox_setSelection(VisuUiStippleCombobox* stippleComboBox,
					       guint16 stipple)
{
  GtkTreeIter iter;
  gboolean validIter;
  GObjectClass *klass;
  GtkListStore *model;
  guint tmpStipple;

  g_return_val_if_fail(stipple && VISU_IS_UI_STIPPLE_COMBOBOX(stippleComboBox), FALSE);

  DBG_fprintf(stderr, "Gtk VisuUiStippleCombobox: select a new stipple %d.\n", stipple);
  klass = G_OBJECT_GET_CLASS(stippleComboBox);
  model = GTK_LIST_STORE(VISU_UI_STIPPLE_COMBOBOX_CLASS(klass)->listStoredStipples);
  validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
  while (validIter)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
			 COLUMN_STIPPLE_VALUE, &tmpStipple,
			 -1);
      if ((guint16)(tmpStipple) == stipple)
	{
	  gtk_combo_box_set_active_iter(GTK_COMBO_BOX(stippleComboBox), &iter);
	  return TRUE;
	}
      validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
    }
  return FALSE;
}
GdkPixbuf* stippleComboBoxGet_selectedPixbuf(VisuUiStippleCombobox *stippleComboBox)
{
  gboolean validIter;
  GtkTreeIter iter;
  GdkPixbuf *pixbuf;
  GObjectClass *klass;

  g_return_val_if_fail(VISU_IS_UI_STIPPLE_COMBOBOX(stippleComboBox), (GdkPixbuf*)0);

  validIter = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(stippleComboBox), &iter);
  if (!validIter)
    return (GdkPixbuf*)0;

  pixbuf = (GdkPixbuf*)0;
  klass = G_OBJECT_GET_CLASS(stippleComboBox);
  gtk_tree_model_get(GTK_TREE_MODEL(VISU_UI_STIPPLE_COMBOBOX_CLASS(klass)->listStoredStipples), &iter,
		     COLUMN_STIPPLE_PIXBUF, &pixbuf,
		     -1);
  return pixbuf;
}
/**
 * visu_ui_stipple_combobox_getSelection:
 * @stippleComboBox: a #VisuUiStippleCombobox widget.
 *
 * The user can access to the selected stipple pattern using this method.
 *
 * Returns: a pattern value (or 65535).
 *
 * Since: 3.4
 */
guint16 visu_ui_stipple_combobox_getSelection(VisuUiStippleCombobox *stippleComboBox)
{
  gboolean validIter;
  GtkTreeIter iter;
  guint stipple;
  GObjectClass *klass;

  g_return_val_if_fail(VISU_IS_UI_STIPPLE_COMBOBOX(stippleComboBox), (guint16)0);

  validIter = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(stippleComboBox), &iter);
  if (!validIter)
    return (guint16)0;

  klass = G_OBJECT_GET_CLASS(stippleComboBox);
  gtk_tree_model_get(GTK_TREE_MODEL(VISU_UI_STIPPLE_COMBOBOX_CLASS(klass)->listStoredStipples), &iter,
		     COLUMN_STIPPLE_VALUE, &stipple,
		     -1);
  return (guint16)stipple;
}
/**
 * visu_ui_stipple_combobox_getStamp:
 * @stippleComboBox: a #VisuUiStippleCombobox widget ;
 * @stipple: a pattern value.
 *
 * The @stippleComboBox has little pixbufs to represent the stipple. User methods can
 * use these pixbufs but should considered them read-only.
 *
 * Returns: (transfer none): a pixbuf pointer corresponding to the
 * little image shown on the @stippleComboBox.
 *
 * Since: 3.4
 */
GdkPixbuf* visu_ui_stipple_combobox_getStamp(VisuUiStippleCombobox *stippleComboBox, guint16 stipple)
{
  GtkTreeIter iter;
  gboolean validIter;
  GdkPixbuf *pixbuf;
  guint cl;
  GtkListStore *model;

  g_return_val_if_fail(VISU_IS_UI_STIPPLE_COMBOBOX(stippleComboBox) && stipple, (GdkPixbuf*)0);

  model = VISU_UI_STIPPLE_COMBOBOX_CLASS(G_OBJECT_GET_CLASS(stippleComboBox))->listStoredStipples;
  validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
  while (validIter)
    {
      pixbuf = (GdkPixbuf*)0;
      gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
			 COLUMN_STIPPLE_PIXBUF, &pixbuf,
			 COLUMN_STIPPLE_VALUE, &cl,
			 -1);
      if (stipple == (guint16)cl)
	return pixbuf;
      validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
    }
  return (GdkPixbuf*)0;
}
/**
 * visu_ui_stipple_combobox_add:
 * @stippleComboBox: a #VisuUiStippleCombobox widget ;
 * @stipple: a pattern value.
 *
 * Create an entry in the ComboBox for the given @stipple pattern if
 * it does not already exist.
 *
 * Since: 3.4
 */
void visu_ui_stipple_combobox_add(VisuUiStippleCombobox *stippleComboBox, guint16 stipple)
{
  GtkTreeIter iter;
  gboolean validIter;
  GObjectClass *klass;
  GtkListStore *model;
  guint tmpStipple;

  g_return_if_fail(VISU_IS_UI_STIPPLE_COMBOBOX(stippleComboBox));

  /* We test if the stipple already exist or not. */
  klass = G_OBJECT_GET_CLASS(stippleComboBox);
  model = GTK_LIST_STORE(VISU_UI_STIPPLE_COMBOBOX_CLASS(klass)->listStoredStipples);
  validIter = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
  while (validIter)
    {
      gtk_tree_model_get(GTK_TREE_MODEL(model), &iter,
			 COLUMN_STIPPLE_VALUE, &tmpStipple,
			 -1);
      if ((guint16)(tmpStipple) == stipple)
	return ;
      validIter = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
    }
  addStippleToModel(&iter, VISU_UI_STIPPLE_COMBOBOX_CLASS(klass), stipple);
}
/**
 * visu_ui_stipple_combobox_set:
 * @stippleComboBox: a #VisuUiStippleCombobox object.
 * @stipple: a stipple value.
 *
 * Select the given stipple, if not exists in the model, add it. See
 * visu_ui_stipple_combobox_setSelection() for a set method that do
 * not add.
 *
 * Since: 3.8
 **/
void visu_ui_stipple_combobox_set(VisuUiStippleCombobox *stippleComboBox, guint16 stipple)
{
  if (!visu_ui_stipple_combobox_setSelection(stippleComboBox, stipple))
    {
      visu_ui_stipple_combobox_add(stippleComboBox, stipple);
      visu_ui_stipple_combobox_setSelection(stippleComboBox, stipple);
    }
}
