Commit 22202ad3 authored by Pierre Wieser's avatar Pierre Wieser

Fix various memory leaks

parent 044cb32d
......@@ -16,7 +16,7 @@
Fix equality check if a profile is modified.
* src/common/na-object-api.h (na_object_dump_norec,
na_object_dump_tree, na_object_rewind_origin): New functions.
na_object_dump_tree, na_object_reset_origin): New functions.
na_object_insert_item(): Add a sibling pointer.
* src/common/na-object.c:
......@@ -38,11 +38,20 @@
* src/common/na-pivot.c:
* src/common/na-pivot.h (na_pivot_get_item): New function.
na_pivot_remove_item(): The removed object may have been already
deleted.
* src/nact/nact-application.c (appli_initialize_application):
Allocate a fake NAObjectAction to initialize NAIDuplicable
interface.
* src/nact/nact-assistant-import.c:
Actually imports the actions into the tree store before
confirming the operation was done.
* src/nact/nact-clipboard.c:
* src/nact/nact-clipboard.h: Make it a convenience class.
* nact/nact-iactions-list.c:
* nact/nact-iactions-list.h (nact_iactions_list_get_item):
New function.
......@@ -53,6 +62,7 @@
* src/nact/nact-main-window.c (nact_main_window_action_exists):
Restore the function, searching in NAPivot and in tree store.
instance_dispose(): Clear the clipboard.
* src/nact/nact-tree-model.c:
Now inserts the new row before a given sibling object.
......
......@@ -129,7 +129,6 @@ interface_base_init( NAIDuplicableInterface *klass )
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
klass->private = g_new0( NAIDuplicableInterfacePrivate, 1 );
klass->private->consumers = NULL;
/**
......@@ -179,7 +178,6 @@ interface_base_init( NAIDuplicableInterface *klass )
G_TYPE_POINTER );
st_interface = klass;
st_initialized = TRUE;
}
}
......
......@@ -50,7 +50,6 @@ G_BEGIN_DECLS
#define na_object_dump_tree( tree ) na_object_object_dump_tree( tree )
#define na_object_get_clipboard_id( object ) na_object_object_get_clipboard_id( NA_OBJECT( object ))
#define na_object_ref( object ) na_object_object_ref( NA_OBJECT( object ))
#define na_object_rewind_origin( target, source ) na_object_object_rewind_origin( NA_OBJECT( target ), NA_OBJECT( source ))
/* NAIDuplicable
*/
......@@ -61,6 +60,7 @@ G_BEGIN_DECLS
#define na_object_get_origin( object ) na_object_iduplicable_get_origin( NA_OBJECT( object ))
#define na_object_set_origin( object, origin ) na_object_iduplicable_set_origin( NA_OBJECT( object ), NA_OBJECT( origin ))
#define na_object_reset_origin( object, origin ) na_object_object_reset_origin( NA_OBJECT( object ), NA_OBJECT( origin ))
/* NAObjectId
*/
......
......@@ -64,7 +64,7 @@ void na_object_object_dump_norec( const NAObject *object );
void na_object_object_dump_tree( GList *tree );
gchar *na_object_object_get_clipboard_id( const NAObject *object );
NAObject *na_object_object_ref( const NAObject *object );
void na_object_object_rewind_origin( NAObject *target, const NAObject *source );
void na_object_object_reset_origin( NAObject *object, const NAObject *origin );
GList *na_object_get_hierarchy( const NAObject *object );
void na_object_free_hierarchy( GList *hierarchy );
......
......@@ -715,7 +715,6 @@ na_object_item_append_item( NAObjectItem *item, const NAObject *object )
g_return_if_fail( NA_IS_OBJECT( object ));
if( !g_list_find( item->private->items, ( gpointer ) object )){
/*item->private->items = g_list_append( item->private->items, g_object_ref(( gpointer ) object ));*/
item->private->items = g_list_append( item->private->items, ( gpointer ) object );
}
}
......@@ -743,10 +742,8 @@ na_object_item_insert_item( NAObjectItem *item, const NAObject *object, const NA
if( !g_list_find( item->private->items, ( gpointer ) object )){
before_list = g_list_find( item->private->items, ( gconstpointer ) before );
if( before_list ){
/*item->private->items = g_list_insert_before( item->private->items, before_list, g_object_ref(( gpointer ) object ));*/
item->private->items = g_list_insert_before( item->private->items, before_list, ( gpointer ) object );
} else {
/*item->private->items = g_list_prepend( item->private->items, g_object_ref(( gpointer ) object ));*/
item->private->items = g_list_prepend( item->private->items, ( gpointer ) object );
}
}
......@@ -770,7 +767,6 @@ na_object_item_remove_item( NAObjectItem *item, const NAObject *object )
if( g_list_find( item->private->items, ( gconstpointer ) object )){
item->private->items = g_list_remove( item->private->items, ( gconstpointer ) object );
/*g_object_unref(( gpointer ) object );*/
}
}
......
......@@ -529,39 +529,42 @@ na_object_object_ref( const NAObject *object )
}
/**
* na_object_object_rewind_origin:
* @target: must be a duplication of @source.
* @source: a #NAObject-derived object.
* na_object_object_reset_origin:
* @object: a #NAObject-derived object.
* @origin: must be a duplication of @object.
*
* Recursively rewind origin between @source to @target, so that
* @target appear as the origin of @source.
* Recursively reset origin of @object and its childs to @origin and
* its childs), so that @origin appear as the actual origin of @object.
*
* The origin of @target itself is set to NULL.
* The origin of @origin itself is set to NULL.
*
* This only works if @target has just been duplicated from @source,
* This only works if @origin has just been duplicated from @object,
* and thus we do not have to check if childs lists are equal.
*/
void
na_object_object_rewind_origin( NAObject *target, const NAObject *source )
na_object_object_reset_origin( NAObject *object, const NAObject *origin )
{
GList *childs, *ic;
NAObject *origin;
GList *origin_childs, *iorig;
GList *object_childs, *iobj;
NAObject *orig_object;
g_return_if_fail( NA_IS_OBJECT( target ));
g_return_if_fail( !target->private->dispose_has_run );
g_return_if_fail( NA_IS_OBJECT( source ));
g_return_if_fail( !source->private->dispose_has_run );
g_return_if_fail( NA_IS_OBJECT( origin ));
g_return_if_fail( !origin->private->dispose_has_run );
g_return_if_fail( NA_IS_OBJECT( object ));
g_return_if_fail( !object->private->dispose_has_run );
childs = v_get_childs( target );
for( ic = childs ; ic ; ic = ic->next ){
origin = na_object_get_origin( ic->data );
na_object_rewind_origin( ic->data, origin );
origin_childs = v_get_childs( origin );
object_childs = v_get_childs( object );
for( iorig = origin_childs, iobj = object_childs ; iorig && iobj ; iorig = iorig->next, iobj = iobj->next ){
orig_object = na_object_get_origin( iorig->data );
g_return_if_fail( orig_object == iobj->data );
na_object_reset_origin( iobj->data, iorig->data );
}
origin = na_object_get_origin( target );
g_return_if_fail( origin == source );
na_iduplicable_set_origin( NA_IDUPLICABLE( source ), NA_IDUPLICABLE( target ));
na_iduplicable_set_origin( NA_IDUPLICABLE( target ), NULL );
orig_object = na_object_get_origin( origin );
g_return_if_fail( orig_object == object );
na_iduplicable_set_origin( NA_IDUPLICABLE( object ), NA_IDUPLICABLE( origin ));
na_iduplicable_set_origin( NA_IDUPLICABLE( origin ), NULL );
}
/**
......
......@@ -492,6 +492,9 @@ na_pivot_get_item( const NAPivot *pivot, const gchar *uuid )
* Removes a #NAObjectItem from the hierarchical tree.
*
* Note that #NAPivot also g_object_unref() the removed #NAObjectItem.
*
* Last, note that the @item may have been already deleted, when its
* parents has itself been removed from @pivot.
*/
void
na_pivot_remove_item( NAPivot *pivot, NAObject *item )
......@@ -502,10 +505,12 @@ na_pivot_remove_item( NAPivot *pivot, NAObject *item )
g_return_if_fail( NA_IS_PIVOT( pivot ));
g_return_if_fail( !pivot->private->dispose_has_run );
g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
pivot->private->tree = g_list_remove( pivot->private->tree, ( gconstpointer ) item );
g_object_unref( item );
if( NA_IS_OBJECT( item )){
g_object_unref( item );
}
}
/**
......
......@@ -34,7 +34,7 @@
/**
* SECTION: base_dialog
* @short_description: #BaseDialog class definition.
* @include: base/base-dialog.h
* @include: nact/base-dialog.h
*
* This class is derived from BaseWindow class, and serves as a base
* class for all Nautilus Actions dialogs.
......
......@@ -36,6 +36,7 @@
#include <gtk/gtk.h>
#include <common/na-about.h>
#include <common/na-iduplicable.h>
#include <common/na-ipivot-consumer.h>
#include "nact-application.h"
......@@ -323,15 +324,27 @@ appli_initialize_unique_app( BaseApplication *application )
* NAPivot notification messages
*
* At last, let the base class do its work, i.e. creating the main window.
*
* When the pivot will be empty, NAIDuplicable signals must yet be
* recorded in the system. Done here because :
* - I don't want do this in NAPivot which is also used by the plugin,
* - this is the last place where I'm pretty sure NAObject has not yet
* been registered.
* So we allocate a new NAObject-derived object to be sure the interface
* is correctly initialized.
*/
static gboolean
appli_initialize_application( BaseApplication *application )
{
static const gchar *thisfn = "nact_application_appli_initialize_application";
gboolean ok;
NAObjectAction *fake;
g_debug( "%s: application=%p", thisfn, ( void * ) application );
fake = na_object_action_new();
g_object_unref( fake );
NACT_APPLICATION( application )->private->pivot = na_pivot_new( NULL );
/* call parent class */
......
......@@ -44,6 +44,19 @@
#include "nact-clipboard.h"
/* private class data
*/
struct NactClipboardClassPrivate {
void *empty; /* so that gcc -pedantic is happy */
};
/* private instance data
*/
struct NactClipboardPrivate {
gboolean dispose_has_run;
GtkClipboard *primary;
};
#define NACT_CLIPBOARD_ATOM gdk_atom_intern( "_NACT_CLIPBOARD", FALSE )
#define NACT_CLIPBOARD_NACT_ATOM gdk_atom_intern( "ClipboardNautilusActions", FALSE )
......@@ -74,6 +87,14 @@ typedef struct {
}
NactClipboardData;
static GObjectClass *st_parent_class = NULL;
static GType register_type( void );
static void class_init( NactClipboardClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_dispose( GObject *application );
static void instance_finalize( GObject *application );
static GtkClipboard *get_nact_clipboard( void );
static GtkClipboard *get_primary_clipboard( void );
static void add_item_to_clipboard0( NAObject *object, gboolean copy_data, gboolean only_profiles, GList **copied );
......@@ -84,6 +105,132 @@ static void get_from_clipboard_callback( GtkClipboard *clipboard, GtkSe
static void clear_clipboard_callback( GtkClipboard *clipboard, NactClipboardData *data );
static void renumber_items( GList *items );
GType
nact_clipboard_get_type( void )
{
static GType type = 0;
if( !type ){
type = register_type();
}
return( type );
}
static GType
register_type( void )
{
static const gchar *thisfn = "nact_clipboard_register_type";
GType type;
static GTypeInfo info = {
sizeof( NactClipboardClass ),
( GBaseInitFunc ) NULL,
( GBaseFinalizeFunc ) NULL,
( GClassInitFunc ) class_init,
NULL,
NULL,
sizeof( NactClipboard ),
0,
( GInstanceInitFunc ) instance_init
};
g_debug( "%s", thisfn );
type = g_type_register_static( G_TYPE_OBJECT, "NactClipboard", &info, 0 );
return( type );
}
static void
class_init( NactClipboardClass *klass )
{
static const gchar *thisfn = "nact_clipboard_class_init";
GObjectClass *object_class;
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
st_parent_class = g_type_class_peek_parent( klass );
object_class = G_OBJECT_CLASS( klass );
object_class->dispose = instance_dispose;
object_class->finalize = instance_finalize;
klass->private = g_new0( NactClipboardClassPrivate, 1 );
}
static void
instance_init( GTypeInstance *instance, gpointer klass )
{
static const gchar *thisfn = "nact_clipboard_instance_init";
NactClipboard *self;
g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
g_assert( NACT_IS_CLIPBOARD( instance ));
self = NACT_CLIPBOARD( instance );
self->private = g_new0( NactClipboardPrivate, 1 );
self->private->dispose_has_run = FALSE;
self->private->primary = get_primary_clipboard();
}
static void
instance_dispose( GObject *window )
{
static const gchar *thisfn = "nact_clipboard_instance_dispose";
NactClipboard *self;
g_debug( "%s: window=%p", thisfn, ( void * ) window );
g_assert( NACT_IS_CLIPBOARD( window ));
self = NACT_CLIPBOARD( window );
if( !self->private->dispose_has_run ){
self->private->dispose_has_run = TRUE;
gtk_clipboard_clear( self->private->primary );
/* chain up to the parent class */
if( G_OBJECT_CLASS( st_parent_class )->dispose ){
G_OBJECT_CLASS( st_parent_class )->dispose( window );
}
}
}
static void
instance_finalize( GObject *window )
{
static const gchar *thisfn = "nact_clipboard_instance_finalize";
NactClipboard *self;
g_debug( "%s: window=%p", thisfn, ( void * ) window );
g_assert( NACT_IS_CLIPBOARD( window ));
self = NACT_CLIPBOARD( window );
g_free( self->private );
/* chain call to parent class */
if( G_OBJECT_CLASS( st_parent_class )->finalize ){
G_OBJECT_CLASS( st_parent_class )->finalize( window );
}
}
/**
* nact_clipboard_new:
*
* Returns: a new #NactClipboard object.
*/
NactClipboard *
nact_clipboard_new( void )
{
NactClipboard *clipboard;
clipboard = g_object_new( NACT_CLIPBOARD_TYPE, NULL );
return( clipboard );
}
/**
* nact_clipboard_get_data_for_intern_use:
*
......@@ -325,7 +472,7 @@ get_nact_clipboard( void )
GtkClipboard *clipboard;
display = gdk_display_get_default();
clipboard = gtk_clipboard_get_for_display( display, GDK_SELECTION_PRIMARY );
clipboard = gtk_clipboard_get_for_display( display, NACT_CLIPBOARD_ATOM );
return( clipboard );
}
......@@ -337,7 +484,7 @@ get_primary_clipboard( void )
GtkClipboard *clipboard;
display = gdk_display_get_default();
clipboard = gtk_clipboard_get_for_display( display, NACT_CLIPBOARD_ATOM );
clipboard = gtk_clipboard_get_for_display( display, GDK_SELECTION_PRIMARY );
return( clipboard );
}
......
......@@ -31,20 +31,57 @@
#ifndef __NACT_CLIPBOARD_H__
#define __NACT_CLIPBOARD_H__
#include <glib.h>
/*
* SECTION: nact_clipboard.
* @short_description: #NactClipboard class definition.
* @include: nact/nact-clipboard.h
*
* This is just a convenience class to extract clipboard functions
* from main window code. There is a unique object which manages all
* clipboard buffers.
*/
#include <glib-object.h>
G_BEGIN_DECLS
void nact_clipboard_get_data_for_intern_use( GList *selected_items, gboolean copy_data );
char *nact_clipboard_get_data_for_extern_use( GList *selected_items );
#define NACT_CLIPBOARD_TYPE ( nact_clipboard_get_type())
#define NACT_CLIPBOARD( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_CLIPBOARD_TYPE, NactClipboard ))
#define NACT_CLIPBOARD_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, NACT_CLIPBOARD_TYPE, NactClipboardClass ))
#define NACT_IS_CLIPBOARD( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_CLIPBOARD_TYPE ))
#define NACT_IS_CLIPBOARD_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_CLIPBOARD_TYPE ))
#define NACT_CLIPBOARD_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_CLIPBOARD_TYPE, NactClipboardClass ))
typedef struct NactClipboardPrivate NactClipboardPrivate;
typedef struct {
GObject parent;
NactClipboardPrivate *private;
}
NactClipboard;
typedef struct NactClipboardClassPrivate NactClipboardClassPrivate;
typedef struct {
GObjectClass parent;
NactClipboardClassPrivate *private;
}
NactClipboardClass;
GType nact_clipboard_get_type( void );
NactClipboard *nact_clipboard_new( void );
void nact_clipboard_get_data_for_intern_use( GList *selected_items, gboolean copy_data );
char *nact_clipboard_get_data_for_extern_use( GList *selected_items );
void nact_clipboard_primary_set( GList *items, gboolean renumber_items );
GList *nact_clipboard_primary_get( void );
void nact_clipboard_primary_counts( guint *actions, guint *profiles, guint *menus );
void nact_clipboard_primary_set( GList *items, gboolean renumber_items );
GList *nact_clipboard_primary_get( void );
void nact_clipboard_primary_counts( guint *actions, guint *profiles, guint *menus );
void nact_clipboard_free_items( GSList *items );
void nact_clipboard_free_items( GSList *items );
void nact_clipboard_export_items( const gchar *uri, GList *items );
void nact_clipboard_export_items( const gchar *uri, GList *items );
G_END_DECLS
......
......@@ -448,7 +448,7 @@ save_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *item )
}
dup_pivot = NA_OBJECT_ITEM( na_object_duplicate( item ));
na_object_rewind_origin( dup_pivot, item );
na_object_reset_origin( item, dup_pivot );
na_pivot_add_item( pivot, NA_OBJECT( dup_pivot ));
na_object_check_edition_status( item );
......
......@@ -45,6 +45,7 @@
#include "base-iprefs.h"
#include "nact-application.h"
#include "nact-clipboard.h"
#include "nact-iactions-list.h"
#include "nact-iaction-tab.h"
#include "nact-icommand-tab.h"
......@@ -89,6 +90,11 @@ struct NactMainWindowPrivate {
* (because an action cannot have zero profile).
*/
NAObjectProfile *edited_profile;
/**
* The convenience clipboard object.
*/
NactClipboard *clipboard;
};
/* action properties
......@@ -485,6 +491,8 @@ instance_dispose( GObject *window )
self->private->dispose_has_run = TRUE;
g_object_unref( self->private->clipboard );
pane = base_window_get_widget( BASE_WINDOW( window ), "MainPaned" );
pos = gtk_paned_get_position( GTK_PANED( pane ));
base_iprefs_set_int( BASE_WINDOW( window ), "main-paned", pos );
......@@ -716,6 +724,8 @@ on_base_initial_load_toplevel( NactMainWindow *window, gpointer user_data )
g_debug( "%s: window=%p, user_data=%p", thisfn, ( void * ) window, ( void * ) user_data );
g_assert( NACT_IS_MAIN_WINDOW( window ));
window->private->clipboard = nact_clipboard_new();
pos = base_iprefs_get_int( BASE_WINDOW( window ), "main-paned" );
if( pos ){
pane = base_window_get_widget( BASE_WINDOW( window ), "MainPaned" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment