libgimpmodule: Convert ModuleDB to GListModel

This commit converts `GimpModuleDB` into a `GListModel`. This allows us
to drop quite a bit of custom code to have an adaptive list of modules
by just becoming a `GListModel` implementation.

Next to that, this commit also rewrites `GimpModule` to use the `notify`
signal for its 2 new properties: "auto-load" and "on-disk", rather than
trying to define a custom signal for that. This in turn allows us to use
basic methods like `g_object_bind_property()`.

Finally, the module manager dialog now uses `GtkListBox`, which can
easily bind to that new `GListModel` infrastructure.
This commit is contained in:
Niels De Graef 2023-05-20 22:37:33 +02:00
parent e5820261ec
commit a4c3eacc02
6 changed files with 256 additions and 495 deletions

View file

@ -150,25 +150,6 @@ gimp_modules_load (Gimp *gimp)
gimp_module_db_load (gimp->module_db, gimp->config->module_path);
}
static void
add_to_inhibit_string (gpointer data,
gpointer user_data)
{
GimpModule *module = data;
GString *str = user_data;
if (! gimp_module_get_auto_load (module))
{
GFile *file = gimp_module_get_file (module);
gchar *path = g_file_get_path (file);
g_string_append_c (str, G_SEARCHPATH_SEPARATOR);
g_string_append (str, path);
g_free (path);
}
}
void
gimp_modules_unload (Gimp *gimp)
{
@ -178,13 +159,31 @@ gimp_modules_unload (Gimp *gimp)
{
GimpConfigWriter *writer;
GString *str;
GListModel *modules = G_LIST_MODEL (gimp->module_db);
guint i;
const gchar *p;
GFile *file;
GError *error = NULL;
str = g_string_new (NULL);
g_list_foreach (gimp_module_db_get_modules (gimp->module_db),
add_to_inhibit_string, str);
for (i = 0; i < g_list_model_get_n_items (modules); i++)
{
GimpModule *module;
module = g_list_model_get_item (modules, i);
if (! gimp_module_get_auto_load (module))
{
GFile *file = gimp_module_get_file (module);
gchar *path = g_file_get_path (file);
g_string_append_c (str, G_SEARCHPATH_SEPARATOR);
g_string_append (str, path);
g_free (path);
}
g_clear_object (&module);
}
if (str->len > 0)
p = str->str + 1;
else

View file

@ -42,14 +42,6 @@
#define RESPONSE_REFRESH 1
enum
{
COLUMN_NAME,
COLUMN_ENABLED,
COLUMN_MODULE,
N_COLUMNS
};
enum
{
INFO_AUTHOR,
@ -68,6 +60,7 @@ struct _ModuleDialog
GimpModule *selected;
GtkListStore *list;
GtkWidget *listbox;
GtkWidget *hint;
GtkWidget *grid;
@ -79,29 +72,20 @@ struct _ModuleDialog
/* local function prototypes */
static void dialog_response (GtkWidget *widget,
gint response_id,
ModuleDialog *private);
static void dialog_destroy_callback (GtkWidget *widget,
ModuleDialog *private);
static void dialog_select_callback (GtkTreeSelection *sel,
ModuleDialog *private);
static void dialog_enabled_toggled (GtkCellRendererToggle *celltoggle,
const gchar *path_string,
ModuleDialog *private);
static void make_list_item (gpointer data,
gpointer user_data);
static void dialog_info_add (GimpModuleDB *db,
GimpModule *module,
ModuleDialog *private);
static void dialog_info_remove (GimpModuleDB *db,
GimpModule *module,
ModuleDialog *private);
static void dialog_info_update (GimpModuleDB *db,
GimpModule *module,
ModuleDialog *private);
static void dialog_info_init (ModuleDialog *private,
GtkWidget *grid);
static GtkWidget * create_widget_for_module (gpointer item,
gpointer user_data);
static void dialog_response (GtkWidget *widget,
gint response_id,
ModuleDialog *private);
static void dialog_destroy_callback (GtkWidget *widget,
ModuleDialog *private);
static void dialog_select_callback (GtkListBox *listbox,
GtkListBoxRow *row,
ModuleDialog *private);
static void dialog_enabled_toggled (GtkToggleButton *checkbox,
ModuleDialog *private);
static void dialog_info_init (ModuleDialog *private,
GtkWidget *grid);
/* public functions */
@ -113,12 +97,7 @@ module_dialog_new (Gimp *gimp)
GtkWidget *dialog;
GtkWidget *vbox;
GtkWidget *sw;
GtkWidget *view;
GtkWidget *image;
GtkTreeSelection *sel;
GtkTreeIter iter;
GtkTreeViewColumn *col;
GtkCellRenderer *rend;
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
@ -167,38 +146,20 @@ module_dialog_new (Gimp *gimp)
gtk_widget_set_size_request (sw, 124, 100);
gtk_widget_show (sw);
private->list = gtk_list_store_new (N_COLUMNS,
G_TYPE_STRING,
G_TYPE_BOOLEAN,
GIMP_TYPE_MODULE);
view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (private->list));
g_object_unref (private->list);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
g_list_foreach (gimp_module_db_get_modules (gimp->module_db),
make_list_item, private);
rend = gtk_cell_renderer_toggle_new ();
g_signal_connect (rend, "toggled",
G_CALLBACK (dialog_enabled_toggled),
private->listbox = gtk_list_box_new ();
gtk_list_box_set_selection_mode (GTK_LIST_BOX (private->listbox),
GTK_SELECTION_BROWSE);
gtk_list_box_bind_model (GTK_LIST_BOX (private->listbox),
G_LIST_MODEL (gimp->module_db),
create_widget_for_module,
private,
NULL);
g_signal_connect (private->listbox, "row-selected",
G_CALLBACK (dialog_select_callback),
private);
col = gtk_tree_view_column_new ();
gtk_tree_view_column_pack_start (col, rend, FALSE);
gtk_tree_view_column_add_attribute (col, rend, "active", COLUMN_ENABLED);
gtk_tree_view_append_column (GTK_TREE_VIEW (view), col);
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 1,
_("Module"),
gtk_cell_renderer_text_new (),
"text", COLUMN_NAME,
NULL);
gtk_container_add (GTK_CONTAINER (sw), view);
gtk_widget_show (view);
gtk_container_add (GTK_CONTAINER (sw), private->listbox);
gtk_widget_show (private->listbox);
private->grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (private->grid), 6);
@ -221,30 +182,6 @@ module_dialog_new (Gimp *gimp)
dialog_info_init (private, private->grid);
dialog_info_update (gimp->module_db, private->selected, private);
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
g_signal_connect (sel, "changed",
G_CALLBACK (dialog_select_callback),
private);
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (private->list), &iter))
gtk_tree_selection_select_iter (sel, &iter);
/* hook the GimpModuleDB signals so we can refresh the display
* appropriately.
*/
g_signal_connect (gimp->module_db, "add",
G_CALLBACK (dialog_info_add),
private);
g_signal_connect (gimp->module_db, "remove",
G_CALLBACK (dialog_info_remove),
private);
g_signal_connect (gimp->module_db, "module-modified",
G_CALLBACK (dialog_info_update),
private);
g_signal_connect (dialog, "destroy",
G_CALLBACK (dialog_destroy_callback),
private);
@ -255,6 +192,46 @@ module_dialog_new (Gimp *gimp)
/* private functions */
static GtkWidget *
create_widget_for_module (gpointer item,
gpointer user_data)
{
GimpModule *module = GIMP_MODULE (item);
ModuleDialog *private = user_data;
const GimpModuleInfo *info = gimp_module_get_info (module);
GFile *file = gimp_module_get_file (module);
GtkWidget *row;
GtkWidget *grid;
GtkWidget *label;
GtkWidget *checkbox;
row = gtk_list_box_row_new ();
g_object_set_data (G_OBJECT (row), "module", module);
gtk_widget_show (row);
grid = gtk_grid_new ();
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
g_object_set (grid, "margin", 3, NULL);
gtk_container_add (GTK_CONTAINER (row), grid);
gtk_widget_show (grid);
checkbox = gtk_check_button_new ();
g_object_bind_property (module, "auto-load", checkbox, "active",
G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
g_signal_connect (checkbox, "toggled",
G_CALLBACK (dialog_enabled_toggled),
private);
gtk_widget_show (checkbox);
gtk_grid_attach (GTK_GRID (grid), checkbox, 0, 0, 1, 1);
label = gtk_label_new (info ? gettext (info->purpose) :
gimp_file_get_utf8_name (file));
gtk_widget_show (label);
gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
return row;
}
static void
dialog_response (GtkWidget *widget,
gint response_id,
@ -270,201 +247,36 @@ static void
dialog_destroy_callback (GtkWidget *widget,
ModuleDialog *private)
{
g_signal_handlers_disconnect_by_func (private->gimp->module_db,
dialog_info_add,
private);
g_signal_handlers_disconnect_by_func (private->gimp->module_db,
dialog_info_remove,
private);
g_signal_handlers_disconnect_by_func (private->gimp->module_db,
dialog_info_update,
private);
g_slice_free (ModuleDialog, private);
}
static void
dialog_select_callback (GtkTreeSelection *sel,
ModuleDialog *private)
dialog_select_callback (GtkListBox *listbox,
GtkListBoxRow *row,
ModuleDialog *private)
{
GtkTreeIter iter;
if (gtk_tree_selection_get_selected (sel, NULL, &iter))
{
GimpModule *module;
gtk_tree_model_get (GTK_TREE_MODEL (private->list), &iter,
COLUMN_MODULE, &module, -1);
if (module)
g_object_unref (module);
if (private->selected == module)
return;
private->selected = module;
dialog_info_update (private->gimp->module_db, private->selected, private);
}
}
static void
dialog_enabled_toggled (GtkCellRendererToggle *celltoggle,
const gchar *path_string,
ModuleDialog *private)
{
GtkTreePath *path;
GtkTreeIter iter;
GimpModule *module = NULL;
path = gtk_tree_path_new_from_string (path_string);
if (! gtk_tree_model_get_iter (GTK_TREE_MODEL (private->list), &iter, path))
{
g_warning ("%s: bad tree path?", G_STRFUNC);
return;
}
gtk_tree_path_free (path);
gtk_tree_model_get (GTK_TREE_MODEL (private->list), &iter,
COLUMN_MODULE, &module,
-1);
if (module)
{
gimp_module_set_auto_load (module, ! gimp_module_get_auto_load (module));
g_object_unref (module);
private->gimp->write_modulerc = TRUE;
gtk_widget_show (private->hint);
}
}
static void
dialog_list_item_update (ModuleDialog *private,
GtkTreeIter *iter,
GimpModule *module)
{
const GimpModuleInfo *info = gimp_module_get_info (module);
GFile *file = gimp_module_get_file (module);
gtk_list_store_set (private->list, iter,
COLUMN_NAME, (info ?
gettext (info->purpose) :
gimp_file_get_utf8_name (file)),
COLUMN_ENABLED, gimp_module_get_auto_load (module),
COLUMN_MODULE, module,
-1);
}
static void
make_list_item (gpointer data,
gpointer user_data)
{
GimpModule *module = data;
ModuleDialog *private = user_data;
GtkTreeIter iter;
if (! private->selected)
private->selected = module;
gtk_list_store_append (private->list, &iter);
dialog_list_item_update (private, &iter, module);
}
static void
dialog_info_add (GimpModuleDB *db,
GimpModule *module,
ModuleDialog *private)
{
make_list_item (module, private);
}
static void
dialog_info_remove (GimpModuleDB *db,
GimpModule *module,
ModuleDialog *private)
{
GtkTreeIter iter;
/* FIXME: Use gtk_list_store_foreach_remove when it becomes available */
if (! gtk_tree_model_get_iter_first (GTK_TREE_MODEL (private->list), &iter))
return;
do
{
GimpModule *this;
gtk_tree_model_get (GTK_TREE_MODEL (private->list), &iter,
COLUMN_MODULE, &this,
-1);
if (this)
g_object_unref (this);
if (this == module)
{
gtk_list_store_remove (private->list, &iter);
return;
}
}
while (gtk_tree_model_iter_next (GTK_TREE_MODEL (private->list), &iter));
g_warning ("%s: Tried to remove a module not in the dialog's list.",
G_STRFUNC);
}
static void
dialog_info_update (GimpModuleDB *db,
GimpModule *module,
ModuleDialog *private)
{
GtkTreeModel *model = GTK_TREE_MODEL (private->list);
guint i;
GimpModule *module;
const gchar *location;
const GimpModuleInfo *info;
GtkTreeIter iter;
const gchar *text[N_INFOS] = { NULL, };
const gchar *location = NULL;
gboolean iter_valid;
gint i;
gboolean show_error;
for (iter_valid = gtk_tree_model_get_iter_first (model, &iter);
iter_valid;
iter_valid = gtk_tree_model_iter_next (model, &iter))
{
GimpModule *this;
gtk_tree_model_get (model, &iter,
COLUMN_MODULE, &this,
-1);
if (this)
g_object_unref (this);
if (this == module)
break;
}
if (iter_valid)
dialog_list_item_update (private, &iter, module);
/* only update the info if we're actually showing it */
if (module != private->selected)
return;
if (! module)
if (row == NULL)
{
for (i = 0; i < N_INFOS; i++)
gtk_label_set_text (GTK_LABEL (private->label[i]), NULL);
gtk_label_set_text (GTK_LABEL (private->error_label), NULL);
gtk_widget_hide (private->error_box);
return;
}
module = g_object_get_data (G_OBJECT (row), "module");
if (private->selected == module)
return;
private->selected = module;
if (gimp_module_is_on_disk (module))
location = gimp_file_get_utf8_name (gimp_module_get_file (module));
@ -497,6 +309,14 @@ dialog_info_update (GimpModuleDB *db,
gtk_widget_set_visible (private->error_box, show_error);
}
static void
dialog_enabled_toggled (GtkToggleButton *checkbox,
ModuleDialog *private)
{
private->gimp->write_modulerc = TRUE;
gtk_widget_show (private->hint);
}
static void
dialog_info_init (ModuleDialog *private,
GtkWidget *grid)

View file

@ -49,10 +49,12 @@
enum
{
MODIFIED,
LAST_SIGNAL
PROP_0,
PROP_AUTO_LOAD,
PROP_ON_DISK,
N_PROPS
};
static GParamSpec *obj_props[N_PROPS] = { NULL, };
struct _GimpModulePrivate
{
@ -73,16 +75,23 @@ struct _GimpModulePrivate
};
static void gimp_module_finalize (GObject *object);
static void gimp_module_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_module_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_module_finalize (GObject *object);
static gboolean gimp_module_load (GTypeModule *module);
static void gimp_module_unload (GTypeModule *module);
static gboolean gimp_module_load (GTypeModule *module);
static void gimp_module_unload (GTypeModule *module);
static gboolean gimp_module_open (GimpModule *module);
static gboolean gimp_module_close (GimpModule *module);
static void gimp_module_set_last_error (GimpModule *module,
const gchar *error_str);
static void gimp_module_modified (GimpModule *module);
static gboolean gimp_module_open (GimpModule *module);
static gboolean gimp_module_close (GimpModule *module);
static void gimp_module_set_last_error (GimpModule *module,
const gchar *error_str);
static GimpModuleInfo * gimp_module_info_new (guint32 abi_version,
const gchar *purpose,
@ -98,8 +107,6 @@ G_DEFINE_TYPE_WITH_PRIVATE (GimpModule, gimp_module, G_TYPE_TYPE_MODULE)
#define parent_class gimp_module_parent_class
static guint module_signals[LAST_SIGNAL];
static void
gimp_module_class_init (GimpModuleClass *klass)
@ -107,20 +114,18 @@ gimp_module_class_init (GimpModuleClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
module_signals[MODIFIED] =
g_signal_new ("modified",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpModuleClass, modified),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
object_class->set_property = gimp_module_set_property;
object_class->get_property = gimp_module_get_property;
object_class->finalize = gimp_module_finalize;
obj_props[PROP_AUTO_LOAD] = g_param_spec_boolean ("auto-load", "auto-load", "auto-load",
FALSE, GIMP_PARAM_READWRITE);
obj_props[PROP_ON_DISK] = g_param_spec_boolean ("on-disk", "on-disk", "on-disk",
FALSE, GIMP_PARAM_READABLE);
g_object_class_install_properties (object_class, N_PROPS, obj_props);
module_class->load = gimp_module_load;
module_class->unload = gimp_module_unload;
klass->modified = NULL;
}
static void
@ -131,6 +136,50 @@ gimp_module_init (GimpModule *module)
module->priv->state = GIMP_MODULE_STATE_ERROR;
}
static void
gimp_module_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpModule *module = GIMP_MODULE (object);
switch (property_id)
{
case PROP_AUTO_LOAD:
gimp_module_set_auto_load (module, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_module_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpModule *module = GIMP_MODULE (object);
switch (property_id)
{
case PROP_AUTO_LOAD:
g_value_set_boolean (value, gimp_module_get_auto_load (module));
break;
case PROP_ON_DISK:
g_value_set_boolean (value, gimp_module_is_on_disk (module));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_module_finalize (GObject *object)
{
@ -286,7 +335,7 @@ gimp_module_get_file (GimpModule *module)
* @module: A #GimpModule
* @auto_load: Pass %FALSE to exclude this module from auto-loading
*
* Sets the @auto_load property if the module. Emits "modified".
* Sets the @auto_load property of the module
*
* Since: 3.0
**/
@ -298,9 +347,9 @@ gimp_module_set_auto_load (GimpModule *module,
if (auto_load != module->priv->auto_load)
{
module->priv->auto_load = auto_load ? TRUE : FALSE;
module->priv->auto_load = auto_load;
gimp_module_modified (module);
g_object_notify_by_pspec (G_OBJECT (module), obj_props[PROP_AUTO_LOAD]);
}
}
@ -345,7 +394,7 @@ gimp_module_is_on_disk (GimpModule *module)
G_FILE_TYPE_REGULAR);
if (module->priv->on_disk != old_on_disk)
gimp_module_modified (module);
g_object_notify_by_pspec (G_OBJECT (module), obj_props[PROP_ON_DISK]);
return module->priv->on_disk;
}
@ -554,14 +603,6 @@ gimp_module_set_last_error (GimpModule *module,
module->priv->last_error = g_strdup (error_str);
}
static void
gimp_module_modified (GimpModule *module)
{
g_return_if_fail (GIMP_IS_MODULE (module));
g_signal_emit (module, module_signals[MODIFIED], 0);
}
/* GimpModuleInfo functions */

View file

@ -1,6 +1,5 @@
EXPORTS
gimp_module_db_get_load_inhibit
gimp_module_db_get_modules
gimp_module_db_get_type
gimp_module_db_get_verbose
gimp_module_db_load

View file

@ -43,21 +43,14 @@
**/
enum
struct _GimpModuleDB
{
ADD,
REMOVE,
MODULE_MODIFIED,
LAST_SIGNAL
};
GObject parent_instance;
GPtrArray *modules;
struct _GimpModuleDBPrivate
{
GList *modules;
gchar *load_inhibit;
gboolean verbose;
gchar *load_inhibit;
gboolean verbose;
};
@ -74,84 +67,75 @@ static GimpModule * gimp_module_db_module_find_by_file (GimpModuleDB *db,
static void gimp_module_db_module_dump_func (gpointer data,
gpointer user_data);
static void gimp_module_db_module_modified (GimpModule *module,
GimpModuleDB *db);
static void gimp_module_db_list_model_iface_init (GListModelInterface *iface);
G_DEFINE_TYPE_WITH_PRIVATE (GimpModuleDB, gimp_module_db, G_TYPE_OBJECT)
G_DEFINE_TYPE_WITH_CODE (GimpModuleDB, gimp_module_db, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
gimp_module_db_list_model_iface_init))
#define parent_class gimp_module_db_parent_class
static guint db_signals[LAST_SIGNAL] = { 0 };
static void
gimp_module_db_class_init (GimpModuleDBClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
db_signals[ADD] =
g_signal_new ("add",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpModuleDBClass, add),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
GIMP_TYPE_MODULE);
db_signals[REMOVE] =
g_signal_new ("remove",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpModuleDBClass, remove),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
GIMP_TYPE_MODULE);
db_signals[MODULE_MODIFIED] =
g_signal_new ("module-modified",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpModuleDBClass, module_modified),
NULL, NULL, NULL,
G_TYPE_NONE, 1,
GIMP_TYPE_MODULE);
object_class->finalize = gimp_module_db_finalize;
klass->add = NULL;
klass->remove = NULL;
}
static void
gimp_module_db_init (GimpModuleDB *db)
{
db->priv = gimp_module_db_get_instance_private (db);
db->priv->modules = NULL;
db->priv->load_inhibit = NULL;
db->priv->verbose = FALSE;
db->modules = g_ptr_array_new ();
db->load_inhibit = NULL;
db->verbose = FALSE;
}
static void
gimp_module_db_finalize (GObject *object)
{
GimpModuleDB *db = GIMP_MODULE_DB (object);
GList *list;
for (list = db->priv->modules; list; list = g_list_next (list))
{
g_signal_handlers_disconnect_by_func (list->data,
gimp_module_db_module_modified,
object);
}
g_clear_pointer (&db->priv->modules, g_list_free);
g_clear_pointer (&db->priv->load_inhibit, g_free);
g_clear_pointer (&db->modules, g_ptr_array_unref);
g_clear_pointer (&db->load_inhibit, g_free);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static GType
gimp_module_db_get_item_type (GListModel *list)
{
return GIMP_TYPE_MODULE;
}
static guint
gimp_module_db_get_n_items (GListModel *list)
{
GimpModuleDB *self = GIMP_MODULE_DB (list);
return self->modules->len;
}
static void *
gimp_module_db_get_item (GListModel *list,
guint index)
{
GimpModuleDB *self = GIMP_MODULE_DB (list);
if (index >= self->modules->len)
return NULL;
return g_object_ref (g_ptr_array_index (self->modules, index));
}
static void
gimp_module_db_list_model_iface_init (GListModelInterface *iface)
{
iface->get_item_type = gimp_module_db_get_item_type;
iface->get_n_items = gimp_module_db_get_n_items;
iface->get_item = gimp_module_db_get_item;
}
/**
* gimp_module_db_new:
* @verbose: Pass %TRUE to enable debugging output.
@ -168,31 +152,11 @@ gimp_module_db_new (gboolean verbose)
db = g_object_new (GIMP_TYPE_MODULE_DB, NULL);
db->priv->verbose = verbose ? TRUE : FALSE;
db->verbose = verbose ? TRUE : FALSE;
return db;
}
/**
* gimp_module_db_get_modules:
* @db: A #GimpModuleDB.
*
* Returns a #GList of the modules kept by @db. The list must not be
* modified or freed.
*
* Returns: (element-type GimpModule) (transfer none): a #GList
* of #GimpModule instances.
*
* Since: 3.0
**/
GList *
gimp_module_db_get_modules (GimpModuleDB *db)
{
g_return_val_if_fail (GIMP_IS_MODULE_DB (db), NULL);
return db->priv->modules;
}
/**
* gimp_module_db_set_verbose:
* @db: A #GimpModuleDB.
@ -208,7 +172,7 @@ gimp_module_db_set_verbose (GimpModuleDB *db,
{
g_return_if_fail (GIMP_IS_MODULE_DB (db));
db->priv->verbose = verbose ? TRUE : FALSE;
db->verbose = verbose ? TRUE : FALSE;
}
/**
@ -226,7 +190,7 @@ gimp_module_db_get_verbose (GimpModuleDB *db)
{
g_return_val_if_fail (GIMP_IS_MODULE_DB (db), FALSE);
return db->priv->verbose;
return db->verbose;
}
static gboolean
@ -286,22 +250,21 @@ void
gimp_module_db_set_load_inhibit (GimpModuleDB *db,
const gchar *load_inhibit)
{
GList *list;
guint i;
g_return_if_fail (GIMP_IS_MODULE_DB (db));
if (db->priv->load_inhibit)
g_free (db->priv->load_inhibit);
g_free (db->load_inhibit);
db->priv->load_inhibit = g_strdup (load_inhibit);
db->load_inhibit = g_strdup (load_inhibit);
for (list = db->priv->modules; list; list = g_list_next (list))
for (i = 0; i < db->modules->len; i++)
{
GimpModule *module = list->data;
GimpModule *module = g_ptr_array_index (db->modules, i);
gboolean inhibit;
inhibit =is_in_inhibit_list (gimp_module_get_file (module),
load_inhibit);
inhibit = is_in_inhibit_list (gimp_module_get_file (module),
load_inhibit);
gimp_module_set_auto_load (module, ! inhibit);
}
@ -321,7 +284,7 @@ gimp_module_db_get_load_inhibit (GimpModuleDB *db)
{
g_return_val_if_fail (GIMP_IS_MODULE_DB (db), NULL);
return db->priv->load_inhibit;
return db->load_inhibit;
}
/**
@ -357,7 +320,7 @@ gimp_module_db_load (GimpModuleDB *db,
}
if (FALSE)
g_list_foreach (db->priv->modules, gimp_module_db_module_dump_func, NULL);
g_ptr_array_foreach (db->modules, gimp_module_db_module_dump_func, NULL);
}
/**
@ -377,29 +340,21 @@ void
gimp_module_db_refresh (GimpModuleDB *db,
const gchar *module_path)
{
GList *list;
guint i;
g_return_if_fail (GIMP_IS_MODULE_DB (db));
g_return_if_fail (module_path != NULL);
list = db->priv->modules;
while (list)
for (i = 0; i < db->modules->len; i++)
{
GimpModule *module = list->data;
list = g_list_next (list);
GimpModule *module = g_ptr_array_index (db->modules, i);
if (! gimp_module_is_on_disk (module) &&
! gimp_module_is_loaded (module))
{
g_signal_handlers_disconnect_by_func (module,
gimp_module_db_module_modified,
db);
db->priv->modules = g_list_remove (db->priv->modules, module);
g_signal_emit (db, db_signals[REMOVE], 0, module);
g_ptr_array_remove_index (db->modules, i);
g_list_model_items_changed (G_LIST_MODEL (db), i, 1, 0);
i--;
}
}
@ -459,30 +414,25 @@ gimp_module_db_load_module (GimpModuleDB *db,
if (gimp_module_db_module_find_by_file (db, file))
return;
load_inhibit = is_in_inhibit_list (file, db->priv->load_inhibit);
load_inhibit = is_in_inhibit_list (file, db->load_inhibit);
module = gimp_module_new (file,
! load_inhibit,
db->priv->verbose);
db->verbose);
g_signal_connect (module, "modified",
G_CALLBACK (gimp_module_db_module_modified),
db);
db->priv->modules = g_list_append (db->priv->modules, module);
g_signal_emit (db, db_signals[ADD], 0, module);
g_ptr_array_add (db->modules, module);
g_list_model_items_changed (G_LIST_MODEL (db), db->modules->len - 1, 0, 1);
}
static GimpModule *
gimp_module_db_module_find_by_file (GimpModuleDB *db,
GFile *file)
{
GList *list;
guint i;
for (list = db->priv->modules; list; list = g_list_next (list))
for (i = 0; i < db->modules->len; i++)
{
GimpModule *module = list->data;
GimpModule *module = g_ptr_array_index (db->modules, i);
if (g_file_equal (file, gimp_module_get_file (module)))
return module;
@ -532,10 +482,3 @@ gimp_module_db_module_dump_func (gpointer data,
info->date ? info->date : "NONE");
}
}
static void
gimp_module_db_module_modified (GimpModule *module,
GimpModuleDB *db)
{
g_signal_emit (db, db_signals[MODULE_MODIFIED], 0, module);
}

View file

@ -25,53 +25,12 @@
G_BEGIN_DECLS
#define GIMP_TYPE_MODULE_DB (gimp_module_db_get_type ())
#define GIMP_MODULE_DB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_MODULE_DB, GimpModuleDB))
#define GIMP_MODULE_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_MODULE_DB, GimpModuleDBClass))
#define GIMP_IS_MODULE_DB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_MODULE_DB))
#define GIMP_IS_MODULE_DB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_MODULE_DB))
#define GIMP_MODULE_DB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_MODULE_DB, GimpModuleDBClass))
G_DECLARE_FINAL_TYPE (GimpModuleDB, gimp_module_db, GIMP, MODULE_DB, GObject)
typedef struct _GimpModuleDBPrivate GimpModuleDBPrivate;
typedef struct _GimpModuleDBClass GimpModuleDBClass;
struct _GimpModuleDB
{
GObject parent_instance;
GimpModuleDBPrivate *priv;
};
struct _GimpModuleDBClass
{
GObjectClass parent_class;
void (* add) (GimpModuleDB *db,
GimpModule *module);
void (* remove) (GimpModuleDB *db,
GimpModule *module);
void (* module_modified) (GimpModuleDB *db,
GimpModule *module);
/* Padding for future expansion */
void (* _gimp_reserved1) (void);
void (* _gimp_reserved2) (void);
void (* _gimp_reserved3) (void);
void (* _gimp_reserved4) (void);
void (* _gimp_reserved5) (void);
void (* _gimp_reserved6) (void);
void (* _gimp_reserved7) (void);
void (* _gimp_reserved8) (void);
};
GType gimp_module_db_get_type (void) G_GNUC_CONST;
GimpModuleDB * gimp_module_db_new (gboolean verbose);
GList * gimp_module_db_get_modules (GimpModuleDB *db);
void gimp_module_db_set_verbose (GimpModuleDB *db,
gboolean verbose);
gboolean gimp_module_db_get_verbose (GimpModuleDB *db);