+
+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;
+ GtkTreeIter src_iter, root_iter, dest_iter, dest_parent;
+ gint *i_src = NULL;
+ VikTreeview *vt;
+ VikLayer *vl;
+
+ g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
+
+ tree_model = GTK_TREE_MODEL (drag_dest);
+ tree_store = GTK_TREE_STORE (drag_dest);
+
+ if (gtk_tree_get_row_drag_data (selection_data, &src_model, &src_path) && src_model == tree_model) {
+ /*
+ * Copy src_path to dest. There are two subcases here, depending on what
+ * is being dragged.
+ *
+ * 1. src_path is a layer. In this case, interpret the drop
+ * as a request to move the layer to a different aggregate layer.
+ * If the destination is not an aggregate layer, use the first
+ * ancestor that is.
+ *
+ * 2. src_path is a sublayer. In this case, find ancestors of
+ * both source and destination nodes who are full layers,
+ * 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);
+
+ gtk_tree_model_get_iter_first(tree_model, &root_iter);
+ TREEVIEW_GET(tree_model, &root_iter, ITEM_POINTER_COLUMN, &vl);
+ vt = vl->vt;
+
+
+ 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);
+ 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:
+ if (dest_cp)
+ gtk_tree_path_free(dest_cp);
+ if (src_path)
+ gtk_tree_path_free (src_path);
+
+ return retval;
+}
+
+/*
+ * This may not be necessary.
+ */
+static gboolean treeview_drag_data_delete ( GtkTreeDragSource *drag_source, GtkTreePath *path )
+{
+ gchar *s_dest = gtk_tree_path_to_string(path);
+ g_print("delete data from %s\n", s_dest);
+ g_free(s_dest);
+ return FALSE;
+}
+