]> git.street.me.uk Git - andy/viking.git/blobdiff - src/viktreeview.c
Add Terraserver
[andy/viking.git] / src / viktreeview.c
index b698d020d921794057ef092c3a633c7c4c856fab..0e5e81b5bea4c2533c49d14affcb45a8f476a6d4 100644 (file)
  *
  */
 
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <gtk/gtk.h>
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
 #include <string.h>
 
 #include "viking.h"
 #include <string.h>
 
 #include "viking.h"
@@ -67,8 +73,8 @@ static void treeview_init ( VikTreeview *vt );
 static void treeview_finalize ( GObject *gob );
 static void treeview_add_columns ( VikTreeview *vt );
 
 static void treeview_finalize ( GObject *gob );
 static void treeview_add_columns ( VikTreeview *vt );
 
-static gboolean vik_drag_data_received ( GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data );
-static gboolean vik_drag_data_delete ( GtkTreeDragSource *drag_source, GtkTreePath *path );
+static gboolean treeview_drag_data_received ( GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data );
+static gboolean treeview_drag_data_delete ( GtkTreeDragSource *drag_source, GtkTreePath *path );
 
 GType vik_treeview_get_type (void)
 {
 
 GType vik_treeview_get_type (void)
 {
@@ -172,9 +178,9 @@ gpointer vik_treeview_item_get_parent ( VikTreeview *vt, GtkTreeIter *iter )
   return rv;
 }
 
   return rv;
 }
 
-void vik_treeview_get_iter_from_path_str ( VikTreeview *vt, GtkTreeIter *iter, const gchar *path_str )
+gboolean vik_treeview_get_iter_from_path_str ( VikTreeview *vt, GtkTreeIter *iter, const gchar *path_str )
 {
 {
-  gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL(vt->model), iter, path_str );
+  return gtk_tree_model_get_iter_from_string ( GTK_TREE_MODEL(vt->model), iter, path_str );
 }
 
 static void treeview_add_columns ( VikTreeview *vt )
 }
 
 static void treeview_add_columns ( VikTreeview *vt )
@@ -183,6 +189,7 @@ static void treeview_add_columns ( VikTreeview *vt )
   GtkCellRenderer *renderer;
   GtkTreeViewColumn *column;
 
   GtkCellRenderer *renderer;
   GtkTreeViewColumn *column;
 
+  /* Layer column */
   renderer = gtk_cell_renderer_text_new ();
   g_signal_connect (renderer, "edited",
                    G_CALLBACK (treeview_edited_cb), vt);
   renderer = gtk_cell_renderer_text_new ();
   g_signal_connect (renderer, "edited",
                    G_CALLBACK (treeview_edited_cb), vt);
@@ -190,7 +197,7 @@ static void treeview_add_columns ( VikTreeview *vt )
   g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
 
   col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (vt),
   g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
 
   col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (vt),
-                                                           -1, "Layer Name",
+                                                           -1, _("Layer Name"),
                                                            renderer, "text",
                                                            NAME_COLUMN,
                                                            "editable", EDITABLE_COLUMN,
                                                            renderer, "text",
                                                            NAME_COLUMN,
                                                            "editable", EDITABLE_COLUMN,
@@ -198,36 +205,32 @@ static void treeview_add_columns ( VikTreeview *vt )
 
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (vt), col_offset - 1);
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
 
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (vt), col_offset - 1);
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
-                                  GTK_TREE_VIEW_COLUMN_FIXED);
-  gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 100);
-  gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
-  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (column), TRUE);
+                                   GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+  gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
 
 
+  /* Layer type */
   renderer = gtk_cell_renderer_pixbuf_new ();
 
   renderer = gtk_cell_renderer_pixbuf_new ();
 
-  g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
+  g_object_set (G_OBJECT (renderer), "xalign", 0.5, NULL);
 
   col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (vt),
 
   col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (vt),
-                                                           -1, "Type",
+                                                           -1, "",
                                                            renderer, "pixbuf",
                                                            ICON_COLUMN,
                                                            NULL);
 
                                                            renderer, "pixbuf",
                                                            ICON_COLUMN,
                                                            NULL);
 
-
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (vt), col_offset - 1);
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (vt), col_offset - 1);
-  gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 33);
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
-                                  GTK_TREE_VIEW_COLUMN_FIXED);
-  gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
-
+                                   GTK_TREE_VIEW_COLUMN_AUTOSIZE);
 
 
+  /* Layer visible */
   renderer = gtk_cell_renderer_toggle_new ();
   renderer = gtk_cell_renderer_toggle_new ();
-  g_object_set (G_OBJECT (renderer), "xalign", 0.0, NULL);
+  g_object_set (G_OBJECT (renderer), "xalign", 0.5, NULL);
 
   g_signal_connect (renderer, "toggled", G_CALLBACK (treeview_toggled_cb), vt);
 
   col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (vt),
 
   g_signal_connect (renderer, "toggled", G_CALLBACK (treeview_toggled_cb), vt);
 
   col_offset = gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (vt),
-                                                           -1, "Visible",
+                                                           -1, "",
                                                            renderer,
                                                            "active",
                                                            VISIBLE_COLUMN,
                                                            renderer,
                                                            "active",
                                                            VISIBLE_COLUMN,
@@ -238,13 +241,35 @@ static void treeview_add_columns ( VikTreeview *vt )
                                                            NULL);
 
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (vt), col_offset - 1);
                                                            NULL);
 
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (vt), col_offset - 1);
-  gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (column), 40);
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column),
-                                  GTK_TREE_VIEW_COLUMN_FIXED);
-  gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (column), TRUE);
+                                   GTK_TREE_VIEW_COLUMN_AUTOSIZE);
 
 }
 
 
 }
 
+static void select_cb(GtkTreeSelection *selection, gpointer data)
+{
+  VikTreeview *vt = data;
+  gint type;
+  GtkTreeIter iter, parent;
+  VikLayer *vl;
+  VikWindow * vw;
+
+  if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return;
+  type = vik_treeview_item_get_type( vt, &iter);
+
+  while ( type != VIK_TREEVIEW_TYPE_LAYER ) {
+    if ( ! vik_treeview_item_get_parent_iter ( vt, &iter, &parent ) )
+      return;
+    iter = parent;
+    type = vik_treeview_item_get_type (vt, &iter );
+  }
+
+  vl = VIK_LAYER( vik_treeview_item_get_pointer ( vt, &iter ) );
+
+  vw = VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vl));
+  vik_window_selected_layer(vw, vl);
+}
+
 void treeview_init ( VikTreeview *vt )
 {
   guint16 i;
 void treeview_init ( VikTreeview *vt )
 {
   guint16 i;
@@ -269,16 +294,18 @@ void treeview_init ( VikTreeview *vt )
     GtkTreeDragDestIface *idest;
 
     isrc = g_type_interface_peek (g_type_class_peek(G_OBJECT_TYPE(vt->model)), GTK_TYPE_TREE_DRAG_SOURCE);
     GtkTreeDragDestIface *idest;
 
     isrc = g_type_interface_peek (g_type_class_peek(G_OBJECT_TYPE(vt->model)), GTK_TYPE_TREE_DRAG_SOURCE);
-    isrc->drag_data_delete = vik_drag_data_delete;
+    isrc->drag_data_delete = treeview_drag_data_delete;
 
     idest = g_type_interface_peek (g_type_class_peek(G_OBJECT_TYPE(vt->model)), GTK_TYPE_TREE_DRAG_DEST);
 
     idest = g_type_interface_peek (g_type_class_peek(G_OBJECT_TYPE(vt->model)), GTK_TYPE_TREE_DRAG_DEST);
-    idest->drag_data_received = vik_drag_data_received;
+    idest->drag_data_received = treeview_drag_data_received;
   }      
 
   for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ )
     vt->layer_type_icons[i] = vik_layer_load_icon ( i ); /* if icon can't be loaded, it will be null and simply not be shown. */
 
   gtk_tree_view_set_reorderable (GTK_TREE_VIEW(vt), TRUE);
   }      
 
   for ( i = 0; i < VIK_LAYER_NUM_TYPES; i++ )
     vt->layer_type_icons[i] = vik_layer_load_icon ( i ); /* if icon can't be loaded, it will be null and simply not be shown. */
 
   gtk_tree_view_set_reorderable (GTK_TREE_VIEW(vt), TRUE);
+  g_signal_connect(gtk_tree_view_get_selection (GTK_TREE_VIEW (vt)), "changed",
+      G_CALLBACK(select_cb), vt);
 
 }
 
 
 }
 
@@ -388,7 +415,12 @@ void vik_treeview_insert_layer ( VikTreeview *vt, GtkTreeIter *parent_iter, GtkT
 {
   g_assert ( iter != NULL );
   g_assert ( icon_type < VIK_LAYER_NUM_TYPES );
 {
   g_assert ( iter != NULL );
   g_assert ( icon_type < VIK_LAYER_NUM_TYPES );
-  gtk_tree_store_insert_before ( GTK_TREE_STORE(vt->model), iter, parent_iter, sibling );
+  if (sibling) {
+    gtk_tree_store_insert_before ( GTK_TREE_STORE(vt->model), iter, parent_iter, sibling );
+  } else {
+    gtk_tree_store_append ( GTK_TREE_STORE(vt->model), iter, parent_iter );
+  }
+    
   gtk_tree_store_set ( GTK_TREE_STORE(vt->model), iter, NAME_COLUMN, name, VISIBLE_COLUMN, TRUE, 
     TYPE_COLUMN, VIK_TREEVIEW_TYPE_LAYER, ITEM_PARENT_COLUMN, parent, ITEM_POINTER_COLUMN, item, 
     ITEM_DATA_COLUMN, data, HAS_VISIBLE_COLUMN, TRUE, EDITABLE_COLUMN, TRUE,
   gtk_tree_store_set ( GTK_TREE_STORE(vt->model), iter, NAME_COLUMN, name, VISIBLE_COLUMN, TRUE, 
     TYPE_COLUMN, VIK_TREEVIEW_TYPE_LAYER, ITEM_PARENT_COLUMN, parent, ITEM_POINTER_COLUMN, item, 
     ITEM_DATA_COLUMN, data, HAS_VISIBLE_COLUMN, TRUE, EDITABLE_COLUMN, TRUE,
@@ -473,15 +505,15 @@ static void treeview_finalize ( GObject *gob )
   G_OBJECT_CLASS(parent_class)->finalize(gob);
 }
 
   G_OBJECT_CLASS(parent_class)->finalize(gob);
 }
 
-static gboolean vik_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data)
+static gboolean treeview_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData *selection_data)
 {
   GtkTreeModel *tree_model;
   GtkTreeStore *tree_store;
   GtkTreeModel *src_model = NULL;
   GtkTreePath *src_path = NULL, *dest_cp = NULL;
   gboolean retval = FALSE;
 {
   GtkTreeModel *tree_model;
   GtkTreeStore *tree_store;
   GtkTreeModel *src_model = NULL;
   GtkTreePath *src_path = NULL, *dest_cp = NULL;
   gboolean retval = FALSE;
-  GtkTreeIter src_iter, root_iter, dest_iter;
-  guint *i_src = NULL;
+  GtkTreeIter src_iter, root_iter, dest_iter, dest_parent;
+  gint *i_src = NULL;
   VikTreeview *vt;
   VikLayer *vl;
 
   VikTreeview *vt;
   VikLayer *vl;
 
@@ -505,6 +537,13 @@ static gboolean vik_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath
      *    and call the move method of that layer type. 
      *
      */
      *    and call the move method of that layer type. 
      *
      */
+    if (!gtk_tree_model_get_iter (src_model, &src_iter, src_path)) {
+      goto out;
+    }
+    if (!gtk_tree_path_compare(src_path, dest)) {
+      goto out;
+    }
+
     i_src = gtk_tree_path_get_indices (src_path);
     dest_cp = gtk_tree_path_copy (dest);
 
     i_src = gtk_tree_path_get_indices (src_path);
     dest_cp = gtk_tree_path_copy (dest);
 
@@ -512,68 +551,35 @@ static gboolean vik_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath
     TREEVIEW_GET(tree_model, &root_iter, ITEM_POINTER_COLUMN, &vl);
     vt = vl->vt;
 
     TREEVIEW_GET(tree_model, &root_iter, ITEM_POINTER_COLUMN, &vl);
     vt = vl->vt;
 
-    if (!gtk_tree_model_get_iter (src_model, &src_iter, src_path)) {
-      goto out;
-    }
 
 
-    switch(vik_treeview_item_get_type(vt, &src_iter)) {
-    case VIK_TREEVIEW_TYPE_LAYER: 
-      /* dest_cp is the future new path as envisioned by Gtk, and may not exist yet. 
-       * We are interested in the future parent, which must be an aggregate layer. 
-       * Therefore, we need to find the first ancestor who is an aggregate layer.
-       */
-      gtk_tree_path_up(dest_cp);
-      while (gtk_tree_model_get_iter (src_model, &dest_iter, dest_cp) &&
-            (vik_treeview_item_get_type(vt, &dest_iter) != VIK_TREEVIEW_TYPE_LAYER ||
-            !IS_VIK_AGGREGATE_LAYER(vik_treeview_item_get_pointer (vt, &dest_iter)))) {
-       gtk_tree_path_up(dest_cp);
-       fprintf(stderr, "up\n");
-      }
-      if (gtk_tree_model_get_iter (src_model, &dest_iter, dest_cp)) {
-       VikLayer *vl_src, *vl_dest;
-       vl_src = vik_treeview_item_get_pointer(vt, &src_iter);
-       vl_dest = vik_treeview_item_get_pointer(vt, &dest_iter);
-       printf("moving layer '%s' into layer '%s'\n", vl_src->name, vl_dest->name);
-
-       /* 
-        * FIXME: ..._layer_delete unrefs the given layer, causing it to be destroyed. 
-        * However, ..._add_layer doesn't increase the ref count, so regardless of order
-        * without the explicit g_object_ref this wouldn't work.  
-        */
-       g_object_ref(vl_src);
-       vik_aggregate_layer_delete(vik_treeview_item_get_parent(vt, &src_iter), &src_iter);
-       vik_aggregate_layer_add_layer(VIK_AGGREGATE_LAYER(vl_dest), vl_src);
-      }
-      break;
-    case VIK_TREEVIEW_TYPE_SUBLAYER: 
-      /* 
-       * If we're moving a sublayer, handle all known types separately.  For now that 
-       * is only TRW.  This might be done more elegantly through an interface.
-       */
-      if (IS_VIK_TRW_LAYER(vik_treeview_item_get_parent(vt, &src_iter))) {
-       VikTrwLayer *vtl_src, *vtl_dest;
+    if (gtk_tree_path_get_depth(dest_cp)>1) { /* can't be sibling of top layer */
+      VikLayer *vl_src, *vl_dest;
 
 
+      /* Find the first ancestor that is a full layer, and store in dest_parent. 
+       * In addition, put in dest_iter where Gtk wants us to insert the dragged object.
+       * (Note that this may end up being an invalid iter). 
+       */
+      do {
        gtk_tree_path_up(dest_cp);
        gtk_tree_path_up(dest_cp);
-       while (gtk_tree_path_get_depth(dest_cp)>0 && 
-              gtk_tree_model_get_iter (src_model, &dest_iter, dest_cp) &&
-              (vik_treeview_item_get_type(vt, &dest_iter) != VIK_TREEVIEW_TYPE_LAYER ||
-              !IS_VIK_TRW_LAYER(vik_treeview_item_get_pointer (vt, &dest_iter)))) {
-         gtk_tree_path_up(dest_cp);
-       }
-       vtl_src = vik_treeview_item_get_parent(vt, &src_iter);
-       vtl_dest = vik_treeview_item_get_pointer(vt, &dest_iter);
-       if (IS_VIK_TRW_LAYER(vtl_dest)) {
-         vik_trw_layer_move_iter(vtl_src, vtl_dest, &src_iter, &dest_iter);
-       }
-      }
-      break;
-
-    default:
-      printf("  Problem.\n");
+       dest_iter = dest_parent;
+       gtk_tree_model_get_iter (src_model, &dest_parent, dest_cp);
+      } while (gtk_tree_path_get_depth(dest_cp)>1 &&
+              vik_treeview_item_get_type(vt, &dest_parent) != VIK_TREEVIEW_TYPE_LAYER);
+
+      
+      g_assert ( vik_treeview_item_get_parent(vt, &src_iter) );
+      vl_src = vik_treeview_item_get_parent(vt, &src_iter);
+      vl_dest = vik_treeview_item_get_pointer(vt, &dest_parent);
+
+      /* TODO: might want to allow different types, and let the clients handle how they want */
+      if (vl_src->type == vl_dest->type && vik_layer_get_interface(vl_dest->type)->drag_drop_request) {
+       //      g_print("moving an item from layer '%s' into layer '%s'\n", vl_src->name, vl_dest->name);
+       vik_layer_get_interface(vl_dest->type)->drag_drop_request(vl_src, vl_dest, &src_iter, dest);
+      }    
     }
   }
     }
   }
- out:
 
 
+ out:
   if (dest_cp) 
     gtk_tree_path_free(dest_cp);
   if (src_path)
   if (dest_cp) 
     gtk_tree_path_free(dest_cp);
   if (src_path)
@@ -585,10 +591,10 @@ static gboolean vik_drag_data_received (GtkTreeDragDest *drag_dest, GtkTreePath
 /* 
  * This may not be necessary.
  */
 /* 
  * This may not be necessary.
  */
-static gboolean vik_drag_data_delete ( GtkTreeDragSource *drag_source, GtkTreePath *path )
+static gboolean treeview_drag_data_delete ( GtkTreeDragSource *drag_source, GtkTreePath *path )
 {
   gchar *s_dest = gtk_tree_path_to_string(path);
 {
   gchar *s_dest = gtk_tree_path_to_string(path);
-  printf("delete data from %s\n", s_dest);
+  g_print(_("delete data from %s\n"), s_dest);
   g_free(s_dest);
   return FALSE;
 }
   g_free(s_dest);
   return FALSE;
 }