[gimp/gimp-2-10] app: add "Swap compression" option to the preferences



commit d5e78f1899210f387edd0a628940fc4a10901020
Author: Ell <ell_se yahoo com>
Date:   Sun Sep 22 16:44:23 2019 +0300

    app: add "Swap compression" option to the preferences
    
    Add a new "Swap compression" option to the preferences, allowing
    explicit control over the tile-swap compression algorithm.
    Previously, control over swap compression was only possible through
    GEGL command-line options/environment variables.  Since the GEGL
    API to list all available compression algorithms is still private
    for now, we currently only list the three predefined compression
    levels -- "best performance" (the default), "balanced", and "best
    compression" -- and a "none" option, to disable compression
    altogether.  Selecting a custom compression algorithm is possible
    by entering its name manually.
    
    (cherry picked from commit 1664ecbf1dc1cd60f8f7e2f16ee6ef3dfa664d43)

 app/config/gimpgeglconfig.c            |  20 +++-
 app/config/gimpgeglconfig.h            |   1 +
 app/config/gimprc-blurbs.h             |   3 +
 app/dialogs/preferences-dialog-utils.c |  17 +++
 app/dialogs/preferences-dialog-utils.h |   6 +
 app/dialogs/preferences-dialog.c       |  10 +-
 app/gegl/gimp-gegl.c                   |  51 +++++---
 app/widgets/Makefile.am                |   2 +
 app/widgets/gimpcompressioncombobox.c  | 212 +++++++++++++++++++++++++++++++++
 app/widgets/gimpcompressioncombobox.h  |  55 +++++++++
 app/widgets/gimppropwidgets.c          | 102 ++++++++++++++++
 app/widgets/gimppropwidgets.h          |  31 ++---
 app/widgets/widgets-types.h            |   1 +
 13 files changed, 474 insertions(+), 37 deletions(-)
---
diff --git a/app/config/gimpgeglconfig.c b/app/config/gimpgeglconfig.c
index c876c939fc..1994c4477f 100644
--- a/app/config/gimpgeglconfig.c
+++ b/app/config/gimpgeglconfig.c
@@ -38,7 +38,9 @@
 #include "gimp-intl.h"
 
 
-#define GIMP_MAX_MEM_PROCESS (MIN (G_MAXSIZE, GIMP_MAX_MEMSIZE))
+#define GIMP_DEFAULT_SWAP_COMPRESSION "fast"
+
+#define GIMP_MAX_MEM_PROCESS          (MIN (G_MAXSIZE, GIMP_MAX_MEMSIZE))
 
 
 enum
@@ -46,6 +48,7 @@ enum
   PROP_0,
   PROP_TEMP_PATH,
   PROP_SWAP_PATH,
+  PROP_SWAP_COMPRESSION,
   PROP_NUM_PROCESSORS,
   PROP_TILE_CACHE_SIZE,
   PROP_USE_OPENCL,
@@ -105,6 +108,13 @@ gimp_gegl_config_class_init (GimpGeglConfigClass *klass)
                          GIMP_PARAM_STATIC_STRINGS |
                          GIMP_CONFIG_PARAM_RESTART);
 
+  GIMP_CONFIG_PROP_STRING (object_class, PROP_SWAP_COMPRESSION,
+                           "swap-compression",
+                           "Swap compression",
+                            SWAP_COMPRESSION_BLURB,
+                           GIMP_DEFAULT_SWAP_COMPRESSION,
+                           GIMP_PARAM_STATIC_STRINGS);
+
   n_threads = g_get_num_processors ();
 
   max_n_threads =
@@ -174,6 +184,7 @@ gimp_gegl_config_finalize (GObject *object)
 
   g_free (gegl_config->temp_path);
   g_free (gegl_config->swap_path);
+  g_free (gegl_config->swap_compression);
 
   gimp_debug_remove_instance (object);
 
@@ -198,6 +209,10 @@ gimp_gegl_config_set_property (GObject      *object,
       g_free (gegl_config->swap_path);
       gegl_config->swap_path = g_value_dup_string (value);
       break;
+    case PROP_SWAP_COMPRESSION:
+      g_free (gegl_config->swap_compression);
+      gegl_config->swap_compression = g_value_dup_string (value);
+      break;
     case PROP_NUM_PROCESSORS:
       gegl_config->num_processors = g_value_get_int (value);
       break;
@@ -234,6 +249,9 @@ gimp_gegl_config_get_property (GObject    *object,
     case PROP_SWAP_PATH:
       g_value_set_string (value, gegl_config->swap_path);
       break;
+    case PROP_SWAP_COMPRESSION:
+      g_value_set_string (value, gegl_config->swap_compression);
+      break;
     case PROP_NUM_PROCESSORS:
       g_value_set_int (value, gegl_config->num_processors);
       break;
diff --git a/app/config/gimpgeglconfig.h b/app/config/gimpgeglconfig.h
index 1f92d0b0e8..4ca948fe03 100644
--- a/app/config/gimpgeglconfig.h
+++ b/app/config/gimpgeglconfig.h
@@ -37,6 +37,7 @@ struct _GimpGeglConfig
 
   gchar    *temp_path;
   gchar    *swap_path;
+  gchar    *swap_compression;
   gint      num_processors;
   guint64   tile_cache_size;
   gboolean  use_opencl;
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index 402d69b641..f827bffbf6 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -456,6 +456,9 @@ _("Enable the Seamless Clone tool.")
 #define SPACE_BAR_ACTION_BLURB \
 _("What to do when the space bar is pressed in the image window.")
 
+#define SWAP_COMPRESSION_BLURB \
+_("The compression method used for tile data stored in the swap file.")
+
 #define SWAP_PATH_BLURB \
 _("Sets the swap file location. GIMP uses a tile based memory allocation " \
   "scheme. The swap file is used to quickly and easily swap tiles out to " \
diff --git a/app/dialogs/preferences-dialog-utils.c b/app/dialogs/preferences-dialog-utils.c
index 214ab94caa..1a1aaaa122 100644
--- a/app/dialogs/preferences-dialog-utils.c
+++ b/app/dialogs/preferences-dialog-utils.c
@@ -383,3 +383,20 @@ prefs_profile_combo_box_add (GObject      *config,
 
   return combo;
 }
+
+GtkWidget *
+prefs_compression_combo_box_add (GObject      *config,
+                                 const gchar  *property_name,
+                                 const gchar  *label,
+                                 GtkTable     *table,
+                                 gint          table_row,
+                                 GtkSizeGroup *group)
+{
+  GtkWidget *combo = gimp_prop_compression_combo_box_new (config,
+                                                          property_name);
+
+  if (combo)
+    prefs_widget_add_aligned (combo, label, table, table_row, FALSE, group);
+
+  return combo;
+}
diff --git a/app/dialogs/preferences-dialog-utils.h b/app/dialogs/preferences-dialog-utils.h
index 2e8fd687ff..46f2be9533 100644
--- a/app/dialogs/preferences-dialog-utils.h
+++ b/app/dialogs/preferences-dialog-utils.h
@@ -123,6 +123,12 @@ GtkWidget * prefs_profile_combo_box_add      (GObject      *config,
                                               GtkSizeGroup *group,
                                               GObject      *profile_path_config,
                                               const gchar  *profile_path_property_name);
+GtkWidget * prefs_compression_combo_box_add  (GObject      *config,
+                                              const gchar  *property_name,
+                                              const gchar  *label,
+                                              GtkTable     *table,
+                                              gint          table_row,
+                                              GtkSizeGroup *group);
 
 
 #endif /* __PREFERENCES_DIALOG_H__ */
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index fd25a955c0..db0bddd42a 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -1172,9 +1172,9 @@ prefs_dialog_new (Gimp       *gimp,
                            GTK_CONTAINER (vbox), FALSE);
 
 #ifdef ENABLE_MP
-  table = prefs_table_new (5, GTK_CONTAINER (vbox2));
+  table = prefs_table_new (6, GTK_CONTAINER (vbox2));
 #else
-  table = prefs_table_new (4, GTK_CONTAINER (vbox2));
+  table = prefs_table_new (5, GTK_CONTAINER (vbox2));
 #endif /* ENABLE_MP */
 
   prefs_spin_button_add (object, "undo-levels", 1.0, 5.0, 0,
@@ -1190,10 +1190,14 @@ prefs_dialog_new (Gimp       *gimp,
                            _("Maximum _new image size:"),
                            GTK_TABLE (table), 3, size_group);
 
+  prefs_compression_combo_box_add (object, "swap-compression",
+                                   _("S_wap compression:"),
+                                   GTK_TABLE (table), 4, size_group);
+
 #ifdef ENABLE_MP
   prefs_spin_button_add (object, "num-processors", 1.0, 4.0, 0,
                          _("Number of _threads to use:"),
-                         GTK_TABLE (table), 4, size_group);
+                         GTK_TABLE (table), 5, size_group);
 #endif /* ENABLE_MP */
 
   /*  Hardware Acceleration  */
diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c
index 6c7987b432..64046b607a 100644
--- a/app/gegl/gimp-gegl.c
+++ b/app/gegl/gimp-gegl.c
@@ -40,11 +40,12 @@
 #include <operation/gegl-operation.h>
 
 
-static void  gimp_gegl_notify_swap_path       (GimpGeglConfig *config);
-static void  gimp_gegl_notify_temp_path       (GimpGeglConfig *config);
-static void  gimp_gegl_notify_tile_cache_size (GimpGeglConfig *config);
-static void  gimp_gegl_notify_num_processors  (GimpGeglConfig *config);
-static void  gimp_gegl_notify_use_opencl      (GimpGeglConfig *config);
+static void  gimp_gegl_notify_temp_path        (GimpGeglConfig *config);
+static void  gimp_gegl_notify_swap_path        (GimpGeglConfig *config);
+static void  gimp_gegl_notify_swap_compression (GimpGeglConfig *config);
+static void  gimp_gegl_notify_tile_cache_size  (GimpGeglConfig *config);
+static void  gimp_gegl_notify_num_processors   (GimpGeglConfig *config);
+static void  gimp_gegl_notify_use_opencl       (GimpGeglConfig *config);
 
 
 /*  public functions  */
@@ -58,23 +59,27 @@ gimp_gegl_init (Gimp *gimp)
 
   config = GIMP_GEGL_CONFIG (gimp->config);
 
-  /* make sure swap and temp directories exist */
-  gimp_gegl_notify_swap_path (config);
+  /* make sure temp and swap directories exist */
   gimp_gegl_notify_temp_path (config);
+  gimp_gegl_notify_swap_path (config);
 
   g_object_set (gegl_config (),
-                "tile-cache-size", (guint64) config->tile_cache_size,
-                "threads",         config->num_processors,
-                "use-opencl",      config->use_opencl,
+                "swap-compression", config->swap_compression,
+                "tile-cache-size",  (guint64) config->tile_cache_size,
+                "threads",          config->num_processors,
+                "use-opencl",       config->use_opencl,
                 NULL);
 
   gimp_parallel_init (gimp);
 
+  g_signal_connect (config, "notify::temp-path",
+                    G_CALLBACK (gimp_gegl_notify_temp_path),
+                    NULL);
   g_signal_connect (config, "notify::swap-path",
                     G_CALLBACK (gimp_gegl_notify_swap_path),
                     NULL);
-  g_signal_connect (config, "notify::temp-path",
-                    G_CALLBACK (gimp_gegl_notify_temp_path),
+  g_signal_connect (config, "notify::swap-compression",
+                    G_CALLBACK (gimp_gegl_notify_swap_compression),
                     NULL);
   g_signal_connect (config, "notify::num-processors",
                     G_CALLBACK (gimp_gegl_notify_num_processors),
@@ -105,6 +110,17 @@ gimp_gegl_exit (Gimp *gimp)
 
 /*  private functions  */
 
+static void
+gimp_gegl_notify_temp_path (GimpGeglConfig *config)
+{
+  GFile *file = gimp_file_new_for_config_path (config->temp_path, NULL);
+
+  if (! g_file_query_exists (file, NULL))
+    g_file_make_directory_with_parents (file, NULL, NULL);
+
+  g_object_unref (file);
+}
+
 static void
 gimp_gegl_notify_swap_path (GimpGeglConfig *config)
 {
@@ -123,14 +139,11 @@ gimp_gegl_notify_swap_path (GimpGeglConfig *config)
 }
 
 static void
-gimp_gegl_notify_temp_path (GimpGeglConfig *config)
+gimp_gegl_notify_swap_compression (GimpGeglConfig *config)
 {
-  GFile *file = gimp_file_new_for_config_path (config->temp_path, NULL);
-
-  if (! g_file_query_exists (file, NULL))
-    g_file_make_directory_with_parents (file, NULL, NULL);
-
-  g_object_unref (file);
+  g_object_set (gegl_config (),
+                "swap-compression", config->swap_compression,
+                NULL);
 }
 
 static void
diff --git a/app/widgets/Makefile.am b/app/widgets/Makefile.am
index 2466635c8b..156fac32f3 100644
--- a/app/widgets/Makefile.am
+++ b/app/widgets/Makefile.am
@@ -94,6 +94,8 @@ libappwidgets_a_sources = \
        gimpcombotagentry.h             \
        gimpcomponenteditor.c           \
        gimpcomponenteditor.h           \
+       gimpcompressioncombobox.c       \
+       gimpcompressioncombobox.h       \
        gimpcontainerbox.c              \
        gimpcontainerbox.h              \
        gimpcontainercombobox.c         \
diff --git a/app/widgets/gimpcompressioncombobox.c b/app/widgets/gimpcompressioncombobox.c
new file mode 100644
index 0000000000..917237ebae
--- /dev/null
+++ b/app/widgets/gimpcompressioncombobox.c
@@ -0,0 +1,212 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcompressioncombobox.c
+ * Copyright (C) 2004, 2008  Sven Neumann <sven gimp org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "stdlib.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "widgets-types.h"
+
+#include "gimpcompressioncombobox.h"
+
+#include "gimp-intl.h"
+
+
+enum
+{
+  COLUMN_ID,
+  COLUMN_LABEL,
+  N_COLUMNS
+};
+
+
+/*  local function prototypes  */
+
+static void       gimp_compression_combo_box_constructed    (GObject      *object);
+
+static gboolean   gimp_compression_combo_box_separator_func (GtkTreeModel *model,
+                                                             GtkTreeIter  *iter,
+                                                             gpointer      data);
+
+
+G_DEFINE_TYPE (GimpCompressionComboBox, gimp_compression_combo_box,
+               GIMP_TYPE_STRING_COMBO_BOX)
+
+#define parent_class gimp_compression_combo_box_parent_class
+
+
+/*  private functions  */
+
+static void
+gimp_compression_combo_box_class_init (GimpCompressionComboBoxClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->constructed = gimp_compression_combo_box_constructed;
+}
+
+static void
+gimp_compression_combo_box_init (GimpCompressionComboBox *combo_box)
+{
+}
+
+static void
+gimp_compression_combo_box_constructed (GObject *object)
+{
+  GimpCompressionComboBox *combo_box = GIMP_COMPRESSION_COMBO_BOX (object);
+  GtkCellLayout           *layout;
+  GtkCellRenderer         *cell;
+  GtkListStore            *store;
+  GtkTreeIter              iter;
+
+  G_OBJECT_CLASS (parent_class)->constructed (object);
+
+  store = gtk_list_store_new (N_COLUMNS,
+                              G_TYPE_STRING,   /* ID    */
+                              G_TYPE_STRING);  /* LABEL */
+
+  gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (store));
+  g_object_unref (store);
+
+  gtk_combo_box_set_row_separator_func (
+    GTK_COMBO_BOX (combo_box),
+    gimp_compression_combo_box_separator_func,
+    NULL,
+    NULL);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set    (store, &iter,
+                         COLUMN_ID,    "none",
+                         COLUMN_LABEL, C_("compression", "None"),
+                         -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set    (store, &iter,
+                         COLUMN_ID,    NULL,
+                         COLUMN_LABEL, NULL,
+                         -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set    (store, &iter,
+                         COLUMN_ID,    "fast",
+                         COLUMN_LABEL, C_("compression", "Best performance"),
+                         -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set    (store, &iter,
+                         COLUMN_ID,    "balanced",
+                         COLUMN_LABEL, C_("compression", "Balanced"),
+                         -1);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set    (store, &iter,
+                         COLUMN_ID,    "best",
+                         COLUMN_LABEL, C_("compression", "Best compression"),
+                         -1);
+
+  gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (combo_box),
+                                       COLUMN_LABEL);
+
+  layout = GTK_CELL_LAYOUT (combo_box);
+
+  cell = gtk_cell_renderer_text_new ();
+
+  gtk_cell_layout_clear (layout);
+  gtk_cell_layout_pack_start (layout, cell, TRUE);
+  gtk_cell_layout_set_attributes (layout, cell,
+                                  "text", COLUMN_LABEL,
+                                  NULL);
+}
+
+static gboolean
+gimp_compression_combo_box_separator_func (GtkTreeModel *model,
+                                           GtkTreeIter  *iter,
+                                           gpointer      data)
+{
+  gchar    *value;
+  gboolean  result;
+
+  gtk_tree_model_get (model, iter, COLUMN_ID, &value, -1);
+
+  result = ! value;
+
+  g_free (value);
+
+  return result;
+}
+
+
+/*  public functions  */
+
+GtkWidget *
+gimp_compression_combo_box_new (void)
+{
+  return g_object_new (GIMP_TYPE_COMPRESSION_COMBO_BOX,
+                       "has-entry",    TRUE,
+                       "id-column",    COLUMN_ID,
+                       "label-column", COLUMN_LABEL,
+                       NULL);
+}
+
+void
+gimp_compression_combo_box_set_compression (GimpCompressionComboBox *combo_box,
+                                            const gchar             *compression)
+{
+  g_return_if_fail (GIMP_IS_COMPRESSION_COMBO_BOX (combo_box));
+  g_return_if_fail (compression != NULL);
+
+  if (! gimp_string_combo_box_set_active (GIMP_STRING_COMBO_BOX (combo_box),
+                                          compression))
+    {
+      GtkWidget *entry;
+
+      entry = gtk_bin_get_child (GTK_BIN (combo_box));
+
+      gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), -1);
+
+      gtk_entry_set_text (GTK_ENTRY (entry), compression);
+    }
+}
+
+gchar *
+gimp_compression_combo_box_get_compression (GimpCompressionComboBox *combo_box)
+{
+  gchar *result;
+
+  g_return_val_if_fail (GIMP_IS_COMPRESSION_COMBO_BOX (combo_box), NULL);
+
+  result = gimp_string_combo_box_get_active (GIMP_STRING_COMBO_BOX (combo_box));
+
+  if (! result)
+    {
+      GtkWidget *entry;
+
+      entry = gtk_bin_get_child (GTK_BIN (combo_box));
+
+      result = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+    }
+
+  return result;
+}
diff --git a/app/widgets/gimpcompressioncombobox.h b/app/widgets/gimpcompressioncombobox.h
new file mode 100644
index 0000000000..71ac4502e1
--- /dev/null
+++ b/app/widgets/gimpcompressioncombobox.h
@@ -0,0 +1,55 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpcompressioncombobox.h
+ * Copyright (C) 2019 Ell
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GIMP_COMPRESSION_COMBO_BOX_H__
+#define __GIMP_COMPRESSION_COMBO_BOX_H__
+
+
+#define GIMP_TYPE_COMPRESSION_COMBO_BOX            (gimp_compression_combo_box_get_type ())
+#define GIMP_COMPRESSION_COMBO_BOX(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
GIMP_TYPE_COMPRESSION_COMBO_BOX, GimpCompressionComboBox))
+#define GIMP_COMPRESSION_COMBO_BOX_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), 
GIMP_TYPE_COMPRESSION_COMBO_BOX, GimpCompressionComboBoxClass))
+#define GIMP_IS_COMPRESSION_COMBO_BOX(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
GIMP_TYPE_COMPRESSION_COMBO_BOX))
+#define GIMP_IS_COMPRESSION_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GIMP_TYPE_COMPRESSION_COMBO_BOX))
+#define GIMP_COMPRESSION_COMBO_BOX_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GIMP_TYPE_COMPRESSION_COMBO_BOX, GimpCompressionComboBoxClass))
+
+
+typedef struct _GimpCompressionComboBoxClass  GimpCompressionComboBoxClass;
+
+
+struct _GimpCompressionComboBox
+{
+  GimpStringComboBox  parent_instance;
+};
+
+struct _GimpCompressionComboBoxClass
+{
+  GimpStringComboBoxClass  parent_instance;
+};
+
+
+GType       gimp_compression_combo_box_get_type        (void) G_GNUC_CONST;
+
+GtkWidget * gimp_compression_combo_box_new             (void);
+
+void        gimp_compression_combo_box_set_compression (GimpCompressionComboBox *combo_box,
+                                                        const gchar             *compression);
+gchar     * gimp_compression_combo_box_get_compression (GimpCompressionComboBox *combo_box);
+
+#endif  /* __GIMP_COMPRESSION_COMBO_BOX_H__ */
diff --git a/app/widgets/gimppropwidgets.c b/app/widgets/gimppropwidgets.c
index aea3f6f4f8..c760a15456 100644
--- a/app/widgets/gimppropwidgets.c
+++ b/app/widgets/gimppropwidgets.c
@@ -40,6 +40,7 @@
 #include "core/gimpviewable.h"
 
 #include "gimpcolorpanel.h"
+#include "gimpcompressioncombobox.h"
 #include "gimpdial.h"
 #include "gimpdnd.h"
 #include "gimpiconpicker.h"
@@ -1856,6 +1857,107 @@ gimp_prop_profile_combo_notify (GObject                  *config,
 }
 
 
+/***************************/
+/*  compression combo box  */
+/***************************/
+
+static void   gimp_prop_compression_combo_box_callback (GtkWidget  *combo,
+                                                        GObject    *config);
+static void   gimp_prop_compression_combo_box_notify   (GObject    *config,
+                                                        GParamSpec *param_spec,
+                                                        GtkWidget  *combo);
+
+GtkWidget *
+gimp_prop_compression_combo_box_new (GObject     *config,
+                                     const gchar *property_name)
+{
+  GParamSpec *param_spec;
+  GtkWidget  *combo;
+  gchar      *value;
+
+  param_spec = check_param_spec_w (config, property_name,
+                                   G_TYPE_PARAM_STRING, G_STRFUNC);
+  if (! param_spec)
+    return NULL;
+
+  combo = gimp_compression_combo_box_new ();
+
+  g_object_get (config,
+                property_name, &value,
+                NULL);
+
+  gimp_compression_combo_box_set_compression (
+    GIMP_COMPRESSION_COMBO_BOX (combo), value);
+  g_free (value);
+
+  set_param_spec (G_OBJECT (combo), combo, param_spec);
+
+  g_signal_connect (combo, "changed",
+                    G_CALLBACK (gimp_prop_compression_combo_box_callback),
+                    config);
+
+  connect_notify (config, property_name,
+                  G_CALLBACK (gimp_prop_compression_combo_box_notify),
+                  combo);
+
+  return combo;
+}
+
+static void
+gimp_prop_compression_combo_box_callback (GtkWidget *combo,
+                                          GObject   *config)
+{
+  GParamSpec *param_spec;
+  gchar      *compression;
+
+  param_spec = get_param_spec (G_OBJECT (combo));
+  if (! param_spec)
+    return;
+
+  compression = gimp_compression_combo_box_get_compression (
+    GIMP_COMPRESSION_COMBO_BOX (combo));
+
+  g_signal_handlers_block_by_func (config,
+                                   gimp_prop_compression_combo_box_notify,
+                                   combo);
+
+  g_object_set (config,
+                param_spec->name, compression,
+                NULL);
+
+  g_signal_handlers_unblock_by_func (config,
+                                     gimp_prop_compression_combo_box_notify,
+                                     combo);
+
+  g_free (compression);
+}
+
+static void
+gimp_prop_compression_combo_box_notify (GObject    *config,
+                                        GParamSpec *param_spec,
+                                        GtkWidget  *combo)
+{
+  gchar *value;
+
+  g_object_get (config,
+                param_spec->name, &value,
+                NULL);
+
+  g_signal_handlers_block_by_func (combo,
+                                   gimp_prop_compression_combo_box_callback,
+                                   config);
+
+  gimp_compression_combo_box_set_compression (
+    GIMP_COMPRESSION_COMBO_BOX (combo), value);
+
+  g_signal_handlers_unblock_by_func (combo,
+                                     gimp_prop_compression_combo_box_callback,
+                                     config);
+
+  g_free (value);
+}
+
+
 /*****************/
 /*  icon picker  */
 /*****************/
diff --git a/app/widgets/gimppropwidgets.h b/app/widgets/gimppropwidgets.h
index 5f96f5d42d..ac2d5e154e 100644
--- a/app/widgets/gimppropwidgets.h
+++ b/app/widgets/gimppropwidgets.h
@@ -110,20 +110,23 @@ GtkWidget * gimp_prop_number_pair_entry_new (GObject     *config,
 
 /*  GParamString  */
 
-GtkWidget * gimp_prop_language_combo_box_new (GObject      *config,
-                                              const gchar  *property_name);
-GtkWidget * gimp_prop_language_entry_new     (GObject      *config,
-                                              const gchar  *property_name);
-
-GtkWidget * gimp_prop_profile_combo_box_new  (GObject      *config,
-                                              const gchar  *property_name,
-                                              GtkListStore *profile_store,
-                                              const gchar  *dialog_title,
-                                              GObject      *profile_path_config,
-                                              const gchar  *profile_path_property_name);
-
-GtkWidget * gimp_prop_icon_picker_new        (GimpViewable *viewable,
-                                              Gimp         *gimp);
+GtkWidget * gimp_prop_language_combo_box_new    (GObject      *config,
+                                                 const gchar  *property_name);
+GtkWidget * gimp_prop_language_entry_new        (GObject      *config,
+                                                 const gchar  *property_name);
+
+GtkWidget * gimp_prop_profile_combo_box_new     (GObject      *config,
+                                                 const gchar  *property_name,
+                                                 GtkListStore *profile_store,
+                                                 const gchar  *dialog_title,
+                                                 GObject      *profile_path_config,
+                                                 const gchar  *profile_path_property_name);
+
+GtkWidget * gimp_prop_compression_combo_box_new (GObject     *config,
+                                                 const gchar *property_name);
+
+GtkWidget * gimp_prop_icon_picker_new           (GimpViewable *viewable,
+                                                 Gimp         *gimp);
 
 
 /*  Utility functions  */
diff --git a/app/widgets/widgets-types.h b/app/widgets/widgets-types.h
index fba239800d..04631c70fe 100644
--- a/app/widgets/widgets-types.h
+++ b/app/widgets/widgets-types.h
@@ -177,6 +177,7 @@ typedef struct _GimpColorFrame               GimpColorFrame;
 typedef struct _GimpColorHistory             GimpColorHistory;
 typedef struct _GimpColorPanel               GimpColorPanel;
 typedef struct _GimpComboTagEntry            GimpComboTagEntry;
+typedef struct _GimpCompressionComboBox      GimpCompressionComboBox;
 typedef struct _GimpControllerEditor         GimpControllerEditor;
 typedef struct _GimpControllerList           GimpControllerList;
 typedef struct _GimpCurveView                GimpCurveView;


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