<commit_before>/*
 * Seahorse
 *
 * Copyright (C) 2005 <NAME>
 *
 * 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 2 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, write to the
 * Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "seahorse-set.h"
#include "seahorse-marshal.h"

enum {
    PROP_0,
    PROP_PREDICATE
};

enum {
    ADDED,
    REMOVED,
    CHANGED,
    SET_CHANGED,
    LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

struct _SeahorseSetPrivate {
    GHashTable *objects;
    SeahorseObjectPredicate *pred;
};

G_DEFINE_TYPE (SeahorseSet, seahorse_set, G_TYPE_OBJECT);

/* -----------------------------------------------------------------------------
 * INTERNAL 
 */

static gboolean
remove_update (SeahorseObject *sobj, gpointer unused, SeahorseSet *skset)
{
    g_signal_emit (skset, signals[REMOVED], 0, sobj);
    g_signal_emit (skset, signals[SET_CHANGED], 0);
    return TRUE;
}

static void
remove_object  (SeahorseObject *sobj, SeahorseSet *skset)
{
    g_hash_table_remove (skset->pv->objects, sobj);
    remove_update (sobj, NULL, skset);
}

static gboolean
maybe_add_object (SeahorseSet *skset, SeahorseObject *sobj)
{
    if (seahorse_object_get_context (sobj) != SCTX_APP ())
        return FALSE;

    if (g_hash_table_lookup (skset->pv->objects, sobj))
        return FALSE;
    
    if (!skset->pv->pred || !seahorse_object_predicate_match (skset->pv->pred, sobj))
        return FALSE;
    
    g_hash_table_replace (skset->pv->objects, sobj, GINT_TO_POINTER (TRUE));
    g_signal_emit (skset, signals[ADDED], 0, sobj);
    g_signal_emit (skset, signals[SET_CHANGED], 0);
    return TRUE;
}

static gboolean
maybe_remove_object (SeahorseSet *skset, SeahorseObject *sobj)
{
    if (!g_hash_table_lookup (skset->pv->objects, sobj))
        return FALSE;
    
    if (skset->pv->pred && seahorse_object_predicate_match (skset->pv->pred, sobj))
        return FALSE;
    
    remove_object (sobj, skset);
    return TRUE;
}

static void
object_added (SeahorseContext *sctx, SeahorseObject *sobj, SeahorseSet *skset)
{
    g_assert (SEAHORSE_IS_OBJECT (sobj));
    g_assert (SEAHORSE_IS_SET (skset));

    maybe_add_object (skset, sobj);
}

static void 
object_removed (SeahorseContext *sctx, SeahorseObject *sobj, SeahorseSet *skset)
{
    g_assert (SEAHORSE_IS_OBJECT (sobj));
    g_assert (SEAHORSE_IS_SET (skset));

    if (g_hash_table_lookup (skset->pv->objects, sobj))
        remove_object (sobj, skset);
}

static void
object_changed (SeahorseContext *sctx, SeahorseObject *sobj, SeahorseSet *skset)
{
    g_assert (SEAHORSE_IS_OBJECT (sobj));
    g_assert (SEAHORSE_IS_SET (skset));

    if (g_hash_table_lookup (skset->pv->objects, sobj)) {

        /* See if needs to be removed, otherwise emit signal */
        if (!maybe_remove_object (skset, sobj))
            g_signal_emit (skset, signals[CHANGED], 0, sobj);

    /* Not in our set yet */
    } else 
        maybe_add_object (skset, sobj);
}

static void
objects_to_list (SeahorseObject *sobj, gpointer *c, GList **l)
{
    *l = g_list_append (*l, sobj);
}

static void
objects_to_hash (SeahorseObject *sobj, gpointer *c, GHashTable *ht)
{
    g_hash_table_replace (ht, sobj, NULL);
}

/* -----------------------------------------------------------------------------
 * OBJECT 
 */

static void
seahorse_set_dispose (GObject *gobject)
{
	SeahorseSet *skset = SEAHORSE_SET (gobject);

	g_signal_handlers_disconnect_by_func (SCTX_APP (), object_added, skset);
	g_signal_handlers_disconnect_by_func (SCTX_APP (), object_removed, skset);
	g_signal_handlers_disconnect_by_func (SCTX_APP (), object_changed, skset);

	/* Release all our pointers and stuff */
	g_hash_table_foreach_remove (skset->pv->objects, (GHRFunc)remove_update, skset);
	skset->pv->pred = NULL;

	G_OBJECT_CLASS (seahorse_set_parent_class)->dispose (gobject);
}

static void
seahorse_set_finalize (GObject *gobject)
{
    SeahorseSet *skset = SEAHORSE_SET (gobject);

    g_hash_table_destroy (skset->pv->objects);
    g_assert (skset->pv->pred == NULL);
    g_free (skset->pv);
    
	G_OBJECT_CLASS (seahorse_set_parent_class)->finalize (gobject);
}

static void
seahorse_set_set_property (GObject *object, guint prop_id, const GValue *value, 
                              GParamSpec *pspec)
{
	SeahorseSet *skset = SEAHORSE_SET (object);
	
    switch (prop_id) {
    case PROP_PREDICATE:<commit_msg>Don't fire events when disposing of SeahorseSet<commit_after>/*
 * Seahorse
 *
 * Copyright (C) 2005 <NAME>
 *
 * 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 2 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, write to the
 * Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "seahorse-set.h"
#include "seahorse-marshal.h"

enum {
    PROP_0,
    PROP_PREDICATE
};

enum {
    ADDED,
    REMOVED,
    CHANGED,
    SET_CHANGED,
    LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

struct _SeahorseSetPrivate {
    GHashTable *objects;
    SeahorseObjectPredicate *pred;
};

G_DEFINE_TYPE (SeahorseSet, seahorse_set, G_TYPE_OBJECT);

/* -----------------------------------------------------------------------------
 * INTERNAL 
 */

static gboolean
remove_update (SeahorseObject *sobj, gpointer unused, SeahorseSet *skset)
{
    g_signal_emit (skset, signals[REMOVED], 0, sobj);
    g_signal_emit (skset, signals[SET_CHANGED], 0);
    return TRUE;
}

static void
remove_object  (SeahorseObject *sobj, SeahorseSet *skset)
{
    g_hash_table_remove (skset->pv->objects, sobj);
    remove_update (sobj, NULL, skset);
}

static gboolean
maybe_add_object (SeahorseSet *skset, SeahorseObject *sobj)
{
    if (seahorse_object_get_context (sobj) != SCTX_APP ())
        return FALSE;

    if (g_hash_table_lookup (skset->pv->objects, sobj))
        return FALSE;
    
    if (!skset->pv->pred || !seahorse_object_predicate_match (skset->pv->pred, sobj))
        return FALSE;
    
    g_hash_table_replace (skset->pv->objects, sobj, GINT_TO_POINTER (TRUE));
    g_signal_emit (skset, signals[ADDED], 0, sobj);
    g_signal_emit (skset, signals[SET_CHANGED], 0);
    return TRUE;
}

static gboolean
maybe_remove_object (SeahorseSet *skset, SeahorseObject *sobj)
{
    if (!g_hash_table_lookup (skset->pv->objects, sobj))
        return FALSE;
    
    if (skset->pv->pred && seahorse_object_predicate_match (skset->pv->pred, sobj))
        return FALSE;
    
    remove_object (sobj, skset);
    return TRUE;
}

static void
object_added (SeahorseContext *sctx, SeahorseObject *sobj, SeahorseSet *skset)
{
    g_assert (SEAHORSE_IS_OBJECT (sobj));
    g_assert (SEAHORSE_IS_SET (skset));

    maybe_add_object (skset, sobj);
}

static void 
object_removed (SeahorseContext *sctx, SeahorseObject *sobj, SeahorseSet *skset)
{
    g_assert (SEAHORSE_IS_OBJECT (sobj));
    g_assert (SEAHORSE_IS_SET (skset));

    if (g_hash_table_lookup (skset->pv->objects, sobj))
        remove_object (sobj, skset);
}

static void
object_changed (SeahorseContext *sctx, SeahorseObject *sobj, SeahorseSet *skset)
{
    g_assert (SEAHORSE_IS_OBJECT (sobj));
    g_assert (SEAHORSE_IS_SET (skset));

    if (g_hash_table_lookup (skset->pv->objects, sobj)) {

        /* See if needs to be removed, otherwise emit signal */
        if (!maybe_remove_object (skset, sobj))
            g_signal_emit (skset, signals[CHANGED], 0, sobj);

    /* Not in our set yet */
    } else 
        maybe_add_object (skset, sobj);
}

static void
objects_to_list (SeahorseObject *sobj, gpointer *c, GList **l)
{
    *l = g_list_append (*l, sobj);
}

static void
objects_to_hash (SeahorseObject *sobj, gpointer *c, GHashTable *ht)
{
    g_hash_table_replace (ht, sobj, NULL);
}

/* -----------------------------------------------------------------------------
 * OBJECT 
 */

static void
seahorse_set_dispose (GObject *gobject)
{
	SeahorseSet *skset = SEAHORSE_SET (gobject);

	g_signal_handlers_disconnect_by_func (SCTX_APP (), object_added, skset);
	g_signal_handlers_disconnect_by_func (SCTX_APP (), object_removed, skset);
	g_signal_handlers_disconnect_by_func (SCTX_APP (), object_changed, skset);

	g_hash_table_remove_all (skset->pv->objects);
	skset->pv->pred = NULL;

	G_OBJECT_CLASS (seahorse_set_parent_class)->dispose (gobject);
}

static void
seahorse_set_finalize (GObject *gobject)
{
    SeahorseSet *skset = SEAHORSE_SET (gobject);

    g_hash_table_destroy (skset->pv->objects);
    g_assert (skset->pv->pred == NULL);
    g_free (skset->pv);
    
	G_OBJECT_CLASS (seahorse_set_parent_class)->finalize (gobject);
}

static void
seahorse_set_set_property (GObject *object, guint prop_id, const GValue *value, 
                              GParamSpec *pspec)
{
	SeahorseSet *skset = SEAHORSE_SET (object);
	
    switch (prop_id) {
    case PROP_PREDICATE:
{'fraction_non_alphanumeric': 0.13469553725729388, 'fraction_numerical': 0.005286164481040968, 'mean_word_length': 3.4435411020776874, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2981501', 'n_tokens_mistral': 3506, 'n_tokens_neox': 3473, 'n_words': 869}