]> git.street.me.uk Git - andy/viking.git/blobdiff - src/viklayerspanel.c
Fix drawing of copied MBTiles map layers.
[andy/viking.git] / src / viklayerspanel.c
index a6b0f543ec647ee53829672b7fab2709dc1a92a8..96b0cbf7e289314ce24638cc2ced6db84fe195c4 100644 (file)
 #include <string.h>
 
 #include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
 
 enum {
   VLP_UPDATE_SIGNAL,
+  VLP_DELETE_LAYER_SIGNAL,
   VLP_LAST_SIGNAL
 };
 
-static void layers_panel_class_init ( VikLayersPanelClass *klass );
-static void layers_panel_init ( VikLayersPanel *vlp );
-
 static guint layers_panel_signals[VLP_LAST_SIGNAL] = { 0 };
 
 static GObjectClass *parent_class;
@@ -49,56 +48,30 @@ struct _VikLayersPanel {
 
   VikTreeview *vt;
   VikViewport *vvp; /* reference */
-
-  GtkItemFactory *popup_factory;
 };
 
-static GtkItemFactoryEntry base_entries[] = {
- { N_("/C_ut"), NULL, (GtkItemFactoryCallback) vik_layers_panel_cut_selected, -1, "<StockItem>", GTK_STOCK_CUT },
- { N_("/_Copy"), NULL, (GtkItemFactoryCallback) vik_layers_panel_copy_selected, -1, "<StockItem>", GTK_STOCK_COPY },
- { N_("/_Paste"), NULL, (GtkItemFactoryCallback) vik_layers_panel_paste_selected, -1, "<StockItem>", GTK_STOCK_PASTE },
- { N_("/_Delete"), NULL, (GtkItemFactoryCallback) vik_layers_panel_delete_selected, -1, "<StockItem>", GTK_STOCK_DELETE },
- { N_("/New Layer"), NULL, NULL, -1, "<Branch>" },
+static GtkActionEntry entries[] = {
+  { "Cut",    GTK_STOCK_CUT,    N_("C_ut"),       NULL, NULL, (GCallback) vik_layers_panel_cut_selected },
+  { "Copy",   GTK_STOCK_COPY,   N_("_Copy"),      NULL, NULL, (GCallback) vik_layers_panel_copy_selected },
+  { "Paste",  GTK_STOCK_PASTE,  N_("_Paste"),     NULL, NULL, (GCallback) vik_layers_panel_paste_selected },
+  { "Delete", GTK_STOCK_DELETE, N_("_Delete"),    NULL, NULL, (GCallback) vik_layers_panel_delete_selected },
 };
 
-#define NUM_BASE_ENTRIES (sizeof(base_entries)/sizeof(base_entries[0]))
-
 static void layers_item_toggled (VikLayersPanel *vlp, GtkTreeIter *iter);
 static void layers_item_edited (VikLayersPanel *vlp, GtkTreeIter *iter, const gchar *new_text);
 static void menu_popup_cb (VikLayersPanel *vlp);
 static void layers_popup_cb (VikLayersPanel *vlp);
 static void layers_popup ( VikLayersPanel *vlp, GtkTreeIter *iter, gint mouse_button );
 static gboolean layers_button_press_cb (VikLayersPanel *vlp, GdkEventButton *event);
+static gboolean layers_key_press_cb (VikLayersPanel *vlp, GdkEventKey *event);
 static void layers_move_item ( VikLayersPanel *vlp, gboolean up );
 static void layers_move_item_up ( VikLayersPanel *vlp );
 static void layers_move_item_down ( VikLayersPanel *vlp );
 static void layers_panel_finalize ( GObject *gob );
 
-GType vik_layers_panel_get_type()
-{
-  static GType vlp_type = 0;
-
-  if (!vlp_type)
-  {
-    static const GTypeInfo vlp_info = 
-    {
-      sizeof (VikLayersPanelClass),
-      NULL, /* base_init */
-      NULL, /* base_finalize */
-      (GClassInitFunc) layers_panel_class_init,
-      NULL, /* class_finalize */
-      NULL, /* class_data */
-      sizeof (VikLayersPanel),
-      0,
-      (GInstanceInitFunc) layers_panel_init,
-    };
-    vlp_type = g_type_register_static ( GTK_TYPE_VBOX, "VikLayersPanel", &vlp_info, 0 );
-  }
-
-  return vlp_type;
-}
+G_DEFINE_TYPE (VikLayersPanel, vik_layers_panel, GTK_TYPE_VBOX)
 
-static void layers_panel_class_init ( VikLayersPanelClass *klass )
+static void vik_layers_panel_class_init ( VikLayersPanelClass *klass )
 {
   GObjectClass *object_class;
 
@@ -109,6 +82,7 @@ static void layers_panel_class_init ( VikLayersPanelClass *klass )
   parent_class = g_type_class_peek_parent (klass);
 
   layers_panel_signals[VLP_UPDATE_SIGNAL] = g_signal_new ( "update", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikLayersPanelClass, update), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+  layers_panel_signals[VLP_DELETE_LAYER_SIGNAL] = g_signal_new ( "delete_layer", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (VikLayersPanelClass, update), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
 }
 
 VikLayersPanel *vik_layers_panel_new ()
@@ -127,7 +101,65 @@ VikViewport *vik_layers_panel_get_viewport ( VikLayersPanel *vlp )
   return vlp->vvp;
 }
 
-static void layers_panel_init ( VikLayersPanel *vlp )
+static gboolean layers_panel_new_layer ( gpointer lpnl[2] )
+{
+  return vik_layers_panel_new_layer ( lpnl[0], GPOINTER_TO_INT(lpnl[1]) );
+}
+
+/**
+ * Create menu popup on demand
+ * @full: offer cut/copy options as well - not just the new layer options
+ */
+static GtkWidget* layers_panel_create_popup ( VikLayersPanel *vlp, gboolean full )
+{
+  GtkWidget *menu = gtk_menu_new ();
+  GtkWidget *menuitem;
+  guint ii;
+
+  if ( full ) {
+    for ( ii = 0; ii < G_N_ELEMENTS(entries); ii++ ) {
+      if ( entries[ii].stock_id ) {
+        menuitem = gtk_image_menu_item_new_with_mnemonic ( entries[ii].label );
+        gtk_image_menu_item_set_image ( (GtkImageMenuItem*)menuitem, gtk_image_new_from_stock (entries[ii].stock_id, GTK_ICON_SIZE_MENU) );
+      }
+      else
+        menuitem = gtk_menu_item_new_with_mnemonic ( entries[ii].label );
+
+      g_signal_connect_swapped ( G_OBJECT(menuitem), "activate", G_CALLBACK(entries[ii].callback), vlp );
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+      gtk_widget_show ( menuitem );
+    }
+  }
+
+  GtkWidget *submenu = gtk_menu_new();
+  menuitem = gtk_menu_item_new_with_mnemonic ( _("New Layer") );
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+  gtk_widget_show ( menuitem );
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu );
+
+  // Static: so memory accessible yet not continually allocated
+  static gpointer lpnl[VIK_LAYER_NUM_TYPES][2];
+
+  for ( ii = 0; ii < VIK_LAYER_NUM_TYPES; ii++ ) {
+    if ( vik_layer_get_interface(ii)->icon ) {
+      menuitem = gtk_image_menu_item_new_with_mnemonic ( vik_layer_get_interface(ii)->name );
+      gtk_image_menu_item_set_image ( (GtkImageMenuItem*)menuitem, gtk_image_new_from_pixbuf ( vik_layer_load_icon (ii) ) );
+    }
+    else
+      menuitem = gtk_menu_item_new_with_mnemonic ( vik_layer_get_interface(ii)->name );
+
+    lpnl[ii][0] = vlp;
+    lpnl[ii][1] = GINT_TO_POINTER(ii);
+
+    g_signal_connect_swapped ( G_OBJECT(menuitem), "activate", G_CALLBACK(layers_panel_new_layer), lpnl[ii] );
+    gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
+    gtk_widget_show ( menuitem );
+  }
+
+  return menu;
+}
+
+static void vik_layers_panel_init ( VikLayersPanel *vlp )
 {
   GtkWidget *hbox;
   GtkWidget *addbutton, *addimage;
@@ -138,8 +170,6 @@ static void layers_panel_init ( VikLayersPanel *vlp )
   GtkWidget *copybutton, *copyimage;
   GtkWidget *pastebutton, *pasteimage;
   GtkWidget *scrolledwindow;
-  GtkItemFactoryEntry entry;
-  guint i, tmp;
 
   vlp->vvp = NULL;
 
@@ -150,13 +180,14 @@ static void layers_panel_init ( VikLayersPanel *vlp )
   vik_layer_rename ( VIK_LAYER(vlp->toplayer), _("Top Layer"));
   g_signal_connect_swapped ( G_OBJECT(vlp->toplayer), "update", G_CALLBACK(vik_layers_panel_emit_update), vlp );
 
-  vik_treeview_add_layer ( vlp->vt, NULL, &(vlp->toplayer_iter), VIK_LAYER(vlp->toplayer)->name, NULL, vlp->toplayer, VIK_LAYER_AGGREGATE, VIK_LAYER_AGGREGATE );
+  vik_treeview_add_layer ( vlp->vt, NULL, &(vlp->toplayer_iter), VIK_LAYER(vlp->toplayer)->name, NULL, TRUE, vlp->toplayer, VIK_LAYER_AGGREGATE, VIK_LAYER_AGGREGATE );
   vik_layer_realize ( VIK_LAYER(vlp->toplayer), vlp->vt, &(vlp->toplayer_iter) );
 
   g_signal_connect_swapped ( vlp->vt, "popup_menu", G_CALLBACK(menu_popup_cb), vlp);
   g_signal_connect_swapped ( vlp->vt, "button_press_event", G_CALLBACK(layers_button_press_cb), vlp);
   g_signal_connect_swapped ( vlp->vt, "item_toggled", G_CALLBACK(layers_item_toggled), vlp);
   g_signal_connect_swapped ( vlp->vt, "item_edited", G_CALLBACK(layers_item_edited), vlp);
+  g_signal_connect_swapped ( vlp->vt, "key_press_event", G_CALLBACK(layers_key_press_cb), vlp);
 
   /* Add button */
   addimage = gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_SMALL_TOOLBAR );
@@ -204,7 +235,7 @@ static void layers_panel_init ( VikLayersPanel *vlp )
   pasteimage = gtk_image_new_from_stock ( GTK_STOCK_PASTE, GTK_ICON_SIZE_SMALL_TOOLBAR );
   pastebutton = gtk_button_new ( );
   gtk_container_add ( GTK_CONTAINER(pastebutton),pasteimage );
-  gtk_widget_set_tooltip_text ( GTK_WIDGET(pastebutton), _("Paste layer below selected layer"));
+  gtk_widget_set_tooltip_text ( GTK_WIDGET(pastebutton), _("Paste layer into selected container layer or otherwise above selected layer"));
   gtk_box_pack_start ( GTK_BOX(hbox), pastebutton, TRUE, TRUE, 0 );
   g_signal_connect_swapped ( G_OBJECT(pastebutton), "clicked", G_CALLBACK(vik_layers_panel_paste_selected), vlp );
 
@@ -214,37 +245,30 @@ static void layers_panel_init ( VikLayersPanel *vlp )
   
   gtk_box_pack_start ( GTK_BOX(vlp), scrolledwindow, TRUE, TRUE, 0 );
   gtk_box_pack_start ( GTK_BOX(vlp), hbox, FALSE, FALSE, 0 );
+}
 
-  vlp->popup_factory = gtk_item_factory_new ( GTK_TYPE_MENU, "<main>", NULL );
-  gtk_item_factory_create_items ( vlp->popup_factory, NUM_BASE_ENTRIES, base_entries, vlp );
-  for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ )
-  {
-    /* TODO: FIXME: if name has a '/' in it it will get all messed up. why not have an itemfactory field with
-                    name, icon, shortcut, etc.? */
-    /* Note: we use a temporary label in order to share translation with other codde */
-    gchar *label = g_strdup_printf(_("New %s Layer"), vik_layer_get_interface(i)->name );
-    entry.path = g_strdup_printf("%s/%s", base_entries[NUM_BASE_ENTRIES-1].path, label );
-    g_free ( label );
-    entry.accelerator = NULL;
-    entry.callback = (GtkItemFactoryCallback) vik_layers_panel_new_layer;
-    entry.callback_action = i;
-    if ( vik_layer_get_interface(i)->icon )
-    {
-      entry.item_type = "<ImageItem>";
-      entry.extra_data = gdk_pixdata_serialize ( vik_layer_get_interface(i)->icon, &tmp );
-    }
-    else
-      entry.item_type = "<Item>";
-
-    gtk_item_factory_create_item ( vlp->popup_factory, &entry, vlp, 1 );
-    g_free ( (gpointer) entry.extra_data );
-    g_free ( entry.path );
-  }
+/**
+ * Invoke the actual drawing via signal method
+ */
+static gboolean idle_draw_panel ( VikLayersPanel *vlp )
+{
+  g_signal_emit ( G_OBJECT(vlp), layers_panel_signals[VLP_UPDATE_SIGNAL], 0 );
+  return FALSE; // Nothing else to do
 }
 
 void vik_layers_panel_emit_update ( VikLayersPanel *vlp )
 {
-  g_signal_emit ( G_OBJECT(vlp), layers_panel_signals[VLP_UPDATE_SIGNAL], 0 );
+  GThread *thread = vik_window_get_thread (VIK_WINDOW(VIK_GTK_WINDOW_FROM_WIDGET(vlp)));
+  if ( !thread )
+    // Do nothing
+    return;
+
+  // Only ever draw when there is time to do so
+  if ( g_thread_self() != thread )
+    // Drawing requested from another (background) thread, so handle via the gdk thread method
+    gdk_threads_add_idle ( (GSourceFunc) idle_draw_panel, vlp );
+  else
+    g_idle_add ( (GSourceFunc) idle_draw_panel, vlp );
 }
 
 static void layers_item_toggled (VikLayersPanel *vlp, GtkTreeIter *iter)
@@ -276,6 +300,14 @@ static void layers_item_toggled (VikLayersPanel *vlp, GtkTreeIter *iter)
 
 static void layers_item_edited (VikLayersPanel *vlp, GtkTreeIter *iter, const gchar *new_text)
 {
+  if ( !new_text )
+    return;
+
+  if ( new_text[0] == '\0' ) {
+    a_dialog_error_msg ( GTK_WINDOW(VIK_WINDOW_FROM_WIDGET(vlp)), _("New name can not be blank.") );
+    return;
+  }
+
   if ( vik_treeview_item_get_type ( vlp->vt, iter ) == VIK_TREEVIEW_TYPE_LAYER )
   {
     VikLayer *l;
@@ -301,7 +333,7 @@ static gboolean layers_button_press_cb ( VikLayersPanel *vlp, GdkEventButton *ev
 {
   if (event->button == 3)
   {
-    GtkTreeIter iter;
+    static GtkTreeIter iter;
     if ( vik_treeview_get_iter_at_pos ( vlp->vt, &iter, event->x, event->y ) )
     {
       layers_popup ( vlp, &iter, 3 );
@@ -314,6 +346,16 @@ static gboolean layers_button_press_cb ( VikLayersPanel *vlp, GdkEventButton *ev
   return FALSE;
 }
 
+static gboolean layers_key_press_cb ( VikLayersPanel *vlp, GdkEventKey *event )
+{
+  // Accept all forms of delete keys
+  if (event->keyval == GDK_Delete || event->keyval == GDK_KP_Delete || event->keyval == GDK_BackSpace) {
+    vik_layers_panel_delete_selected (vlp);
+    return TRUE;
+ }
+ return FALSE;
+}
+
 static void layers_popup ( VikLayersPanel *vlp, GtkTreeIter *iter, gint mouse_button )
 {
   GtkMenu *menu = NULL;
@@ -326,7 +368,7 @@ static void layers_popup ( VikLayersPanel *vlp, GtkTreeIter *iter, gint mouse_bu
       VikLayer *layer = VIK_LAYER(vik_treeview_item_get_pointer ( vlp->vt, iter ));
 
       if ( layer->type == VIK_LAYER_AGGREGATE )
-        menu = GTK_MENU(gtk_item_factory_get_widget ( vlp->popup_factory, "<main>" ));
+        menu = GTK_MENU ( layers_panel_create_popup ( vlp, TRUE ) );
       else
       {
         GtkWidget *del, *prop;
@@ -368,9 +410,8 @@ static void layers_popup ( VikLayersPanel *vlp, GtkTreeIter *iter, gint mouse_bu
          gtk_menu_shell_append (GTK_MENU_SHELL (menu), del);
          gtk_widget_show ( del );
        }
-
-        vik_layer_add_menu_items ( layer, menu, vlp );
-      } 
+      }
+      vik_layer_add_menu_items ( layer, menu, vlp );
     }
     else
     {
@@ -384,7 +425,9 @@ static void layers_popup ( VikLayersPanel *vlp, GtkTreeIter *iter, gint mouse_bu
     }
   }
   else
-    menu = GTK_MENU(gtk_item_factory_get_widget ( vlp->popup_factory, base_entries[NUM_BASE_ENTRIES-1].path ));
+  {
+    menu = GTK_MENU ( layers_panel_create_popup ( vlp, FALSE ) );
+  }
   gtk_menu_popup ( menu, NULL, NULL, NULL, NULL, mouse_button, gtk_get_current_event_time() );
 }
 
@@ -399,20 +442,31 @@ static void layers_popup_cb ( VikLayersPanel *vlp )
   layers_popup ( vlp, NULL, 0 );
 }
 
-gboolean vik_layers_panel_new_layer ( VikLayersPanel *vlp, gint type )
+/**
+ * vik_layers_panel_new_layer:
+ * @type: type of the new layer
+ * 
+ * Create a new layer and add to panel.
+ */
+gboolean vik_layers_panel_new_layer ( VikLayersPanel *vlp, VikLayerTypeEnum type )
 {
   VikLayer *l;
   g_assert ( vlp->vvp );
-  l = vik_layer_create ( type, vlp->vvp, VIK_GTK_WINDOW_FROM_WIDGET(vlp), TRUE );
+  l = vik_layer_create ( type, vlp->vvp, TRUE );
   if ( l )
   {
     vik_layers_panel_add_layer ( vlp, l );
-    vik_layers_panel_emit_update ( vlp );
     return TRUE;
   }
   return FALSE;
 }
 
+/**
+ * vik_layers_panel_add_layer:
+ * @l: existing layer
+ * 
+ * Add an existing layer to panel.
+ */
 void vik_layers_panel_add_layer ( VikLayersPanel *vlp, VikLayer *l )
 {
   GtkTreeIter iter;
@@ -422,7 +476,7 @@ void vik_layers_panel_add_layer ( VikLayersPanel *vlp, VikLayer *l )
   vik_layer_change_coord_mode ( l, vik_viewport_get_coord_mode(vlp->vvp) );
 
   if ( ! vik_treeview_get_selected_iter ( vlp->vt, &iter ) )
-    vik_aggregate_layer_add_layer ( vlp->toplayer, l );
+    vik_aggregate_layer_add_layer ( vlp->toplayer, l, TRUE );
   else
   {
     VikAggregateLayer *addtoagg;
@@ -458,8 +512,10 @@ void vik_layers_panel_add_layer ( VikLayersPanel *vlp, VikLayer *l )
     if ( replace_iter )
       vik_aggregate_layer_insert_layer ( addtoagg, l, replace_iter );
     else
-      vik_aggregate_layer_add_layer ( addtoagg, l );
+      vik_aggregate_layer_add_layer ( addtoagg, l, TRUE );
   }
+
+  vik_layers_panel_emit_update ( vlp );
 }
 
 static void layers_move_item ( VikLayersPanel *vlp, gboolean up )
@@ -508,12 +564,6 @@ void vik_layers_panel_draw_all ( VikLayersPanel *vlp )
     vik_aggregate_layer_draw ( vlp->toplayer, vlp->vvp );
 }
 
-void vik_layers_panel_draw_all_using_viewport ( VikLayersPanel *vlp, VikViewport *vvp )
-{
-  if ( vlp->vvp && VIK_LAYER(vlp->toplayer)->visible )
-    vik_aggregate_layer_draw ( vlp->toplayer, vvp );
-}
-
 void vik_layers_panel_cut_selected ( VikLayersPanel *vlp )
 {
   gint type;
@@ -537,8 +587,11 @@ void vik_layers_panel_cut_selected ( VikLayersPanel *vlp )
       a_clipboard_copy_selected ( vlp );
 
       if (IS_VIK_AGGREGATE_LAYER(parent)) {
-       if ( vik_aggregate_layer_delete ( parent, &iter ) )
-         vik_layers_panel_emit_update ( vlp );
+
+        g_signal_emit ( G_OBJECT(vlp), layers_panel_signals[VLP_DELETE_LAYER_SIGNAL], 0 );
+
+        if ( vik_aggregate_layer_delete ( parent, &iter ) )
+          vik_layers_panel_emit_update ( vlp );
       }
     }
     else
@@ -563,13 +616,13 @@ void vik_layers_panel_copy_selected ( VikLayersPanel *vlp )
   a_clipboard_copy_selected ( vlp );
 }
 
-void vik_layers_panel_paste_selected ( VikLayersPanel *vlp )
+gboolean vik_layers_panel_paste_selected ( VikLayersPanel *vlp )
 {
   GtkTreeIter iter;
   if ( ! vik_treeview_get_selected_iter ( vlp->vt, &iter ) )
     /* Nothing to do */
-    return;
-  a_clipboard_paste ( vlp );
+    return FALSE;
+  return a_clipboard_paste ( vlp );
 }
 
 void vik_layers_panel_delete_selected ( VikLayersPanel *vlp )
@@ -599,6 +652,9 @@ void vik_layers_panel_delete_selected ( VikLayersPanel *vlp )
         vik_viewport_set_trigger ( vlp->vvp, NULL );
 
       if (IS_VIK_AGGREGATE_LAYER(parent)) {
+
+        g_signal_emit ( G_OBJECT(vlp), layers_panel_signals[VLP_DELETE_LAYER_SIGNAL], 0 );
+
         if ( vik_aggregate_layer_delete ( parent, &iter ) )
          vik_layers_panel_emit_update ( vlp );
       }
@@ -662,7 +718,7 @@ gboolean vik_layers_panel_tool ( VikLayersPanel *vlp, guint16 layer_type, VikToo
 }
 #endif
 
-VikLayer *vik_layers_panel_get_layer_of_type ( VikLayersPanel *vlp, gint type )
+VikLayer *vik_layers_panel_get_layer_of_type ( VikLayersPanel *vlp, VikLayerTypeEnum type )
 {
   VikLayer *rv = vik_layers_panel_get_selected ( vlp );
   if ( rv == NULL || rv->type != type )
@@ -688,8 +744,10 @@ VikAggregateLayer *vik_layers_panel_get_top_layer ( VikLayersPanel *vlp )
 
 void vik_layers_panel_clear ( VikLayersPanel *vlp )
 {
-  if ( (! vik_aggregate_layer_is_empty(vlp->toplayer)) && a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("Are you sure you wish to delete all layers?"), NULL ) )
+  if ( (! vik_aggregate_layer_is_empty(vlp->toplayer)) && a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_WIDGET(vlp), _("Are you sure you wish to delete all layers?"), NULL ) ) {
+    g_signal_emit ( G_OBJECT(vlp), layers_panel_signals[VLP_DELETE_LAYER_SIGNAL], 0 );
     vik_aggregate_layer_clear ( vlp->toplayer ); /* simply deletes all layers */
+  }
 }
 
 void vik_layers_panel_change_coord_mode ( VikLayersPanel *vlp, VikCoordMode mode )
@@ -701,7 +759,6 @@ static void layers_panel_finalize ( GObject *gob )
 {
   VikLayersPanel *vlp = VIK_LAYERS_PANEL ( gob );
   g_object_unref ( VIK_LAYER(vlp->toplayer) );
-  g_object_unref ( G_OBJECT(vlp->popup_factory) );
   G_OBJECT_CLASS(parent_class)->finalize(gob);
 }