示例#1
0
文件: debug.c 项目: BYC/geany-plugins
/* 
 * text has been dragged into the watch tree view
 */
static void on_watch_dragged_callback(GtkWidget *wgt, GdkDragContext *context, int x, int y,
	GtkSelectionData *seldata, guint info, guint _time,
    gpointer userdata)
{
	/* string that is dragged */
	gchar *expression = (gchar*)seldata->data;
	GtkTreePath *path = NULL;
	GtkTreeViewDropPosition pos;
	GtkTreePath *empty_path;
	GtkTreeIter newvar;

	/* lookup for where the text has been dropped */
	gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(wtree), x, y, &path, &pos);

	/* if dropped into last row - insert before it */
	empty_path = wtree_empty_path();
	if (!gtk_tree_path_compare(empty_path, path))
		pos = GTK_TREE_VIEW_DROP_BEFORE;
	gtk_tree_path_free(empty_path);
	
	/* if dropped into children area - insert before parent */
	if (gtk_tree_path_get_depth(path) > 1)
	{
		while (gtk_tree_path_get_depth(path) > 1)
			gtk_tree_path_up(path);
		pos = GTK_TREE_VIEW_DROP_BEFORE;
	}
	
	/* insert new row */
	if (path)
	{
		GtkTreeIter sibling;
		gtk_tree_model_get_iter(wmodel, &sibling, path);
		
		if (GTK_TREE_VIEW_DROP_BEFORE == pos || GTK_TREE_VIEW_DROP_INTO_OR_BEFORE == pos)
			gtk_tree_store_insert_before(wstore, &newvar, NULL, &sibling);
		else
			gtk_tree_store_insert_after(wstore, &newvar, NULL, &sibling);
	}
	else
	{
		GtkTreeIter empty;

		wtree_empty_row(&empty);
		gtk_tree_store_insert_before(wstore, &newvar, NULL, &empty);
	}
	
	/* if debugger is active (in stopped condition) - add to run-time watch list
	 *  if not - just set new expession in the tree view */ 
	if (DBS_STOPPED == debug_state)
	{
		variable *var = active_module->add_watch(expression);
		change_watch(GTK_TREE_VIEW(wtree), &newvar, var);
	}
	else
		variable_set_name_only(wstore, &newvar, expression);

	config_set_debug_changed();
}
示例#2
0
G_MODULE_EXPORT void
on_add_sibling_activate(GtkMenuItem *menuitem, gpointer user_data)
{
	INFO *info;
	EDITOR *e = (EDITOR *)user_data;
	GtkWidget *tree = GTK_WIDGET(e->treeview);
	gint test;
	GS_DIALOG *d;
	GtkTreeIter sibling;

	info = _get_info(tree);

	d = gui_new_dialog();
#ifdef HAVE_GTK_310
	d->stock_icon = "dialog-question";
#else
	d->stock_icon = GTK_STOCK_DIALOG_QUESTION;
#endif
	d->title = _("Prayer List/Journal Item");
	d->label_top = _("New name");
	d->label1 = _("Name: ");
	d->text1 = g_strdup(info->local_name);
	d->ok = TRUE;
	d->cancel = TRUE;

	test = gui_gs_dialog(d);
	if (test == GS_OK) {
		unsigned long l_offset = main_treekey_append_sibling(info->book,
								     d->text1,
								     info->offset);
		if (l_offset) {
			char *buf = g_strdup_printf("%ld", l_offset);
			gtk_tree_store_insert_after(GTK_TREE_STORE(info->model),
						    &sibling, NULL,
						    &info->iter);
			gtk_tree_store_set(GTK_TREE_STORE(info->model),
					   &sibling, COL_OPEN_PIXBUF,
					   pixbufs->pixbuf_helpdoc,
					   COL_CLOSED_PIXBUF, NULL,
					   COL_CAPTION, d->text1,
					   COL_MODULE, info->book,
					   COL_OFFSET, buf, -1);
			if (e->key)
				g_free(e->key);
			e->key = g_strdup(buf);
			editor_load_book(e);
			g_free(buf);
		}
	}
	g_free(info->book);
	g_free(info->local_name);
	g_free(info->offset);
	g_free(info);
	g_free(d->text1);
	g_free(d);
}
示例#3
0
/**
 * bmark_get_iter_at_tree_position:
 *
 * determine bookmark's location in the tree and  insert - result GtkTreeIter is stored in m->iter 
 */
static void bmark_get_iter_at_tree_position(Tbfwin * bfwin, Tbmark * m) {
	GtkTreeIter *parent;
	gpointer ptr;
	DEBUG_MSG("bmark_get_iter_at_tree_position, started for filepath=%s\n",m->filepath);
	if (!bfwin->bmark_files) {
		DEBUG_MSG("bmark_get_iter_at_tree_position, creating hashtable for bfwin=%p\n",bfwin);
		bfwin->bmark_files = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
	}
	ptr = g_hash_table_lookup(bfwin->bmark_files, m->filepath);
	if (ptr == NULL) {			/* closed document or bookmarks never set */
		gchar *title = NULL;
		parent = g_new0(GtkTreeIter, 1);
		gtk_tree_store_append(bfwin->bookmarkstore, parent, NULL);
		switch (main_v->props.bookmarks_filename_mode) {
		case BM_FMODE_FULL:
			g_strdup(m->filepath);
			break;
		case BM_FMODE_HOME:	/* todo */
			if (bfwin->project != NULL && bfwin->project->basedir && strlen(bfwin->project->basedir)) {
				gint baselen = strlen(bfwin->project->basedir);
				if (strncmp(m->filepath, bfwin->project->basedir, baselen)==0) {
					title = g_strdup(m->filepath + baselen);
				}
			}
			break;
/*		case BM_FMODE_FILE:
			title = g_path_get_basename(m->filepath);
			break;*/
		}
		if (title == NULL) {
			title = g_path_get_basename(m->filepath);
		}
		gtk_tree_store_set(bfwin->bookmarkstore, parent, NAME_COLUMN, title, PTR_COLUMN, m->doc, -1);
		g_free (title);
		  
		if (m->doc != NULL) {
			DEBUG_MSG("bmark_get_iter_at_tree_position, setting parent iter %p for doc%p\n",parent,m->doc);
			m->doc->bmark_parent = parent;
		}
		DEBUG_MSG("bmark_get_iter_at_tree_position, appending parent %p in hashtable for filepath=%s\n",parent, m->filepath);
		/* the hash table frees the key, but not the value, on destroy */
		g_hash_table_insert(bfwin->bmark_files, g_strdup(m->filepath), parent);
	} else
		parent = (GtkTreeIter *) ptr;

	{
		Tbmark *bef = bmark_find_bookmark_before_offset(bfwin, m->offset, parent);
		if (bef == NULL) {
			gtk_tree_store_prepend(bfwin->bookmarkstore, &m->iter, parent);
			return;
		} else {
			gtk_tree_store_insert_after(GTK_TREE_STORE(bfwin->bookmarkstore),&m->iter,parent,&bef->iter);
			return;
		}
	}
}
示例#4
0
/******************************************************************************
* gtk_TreeStoreInsertAfter(tree, parent_path_string/NULL, sibling_path_string/NULL, ncol, val, ....)-->path_string
******************************************************************************/
int
clip_GTK_TREESTOREINSERTAFTER(ClipMachine * ClipMachineMemory)
{

   C_object *cstree = _fetch_co_arg(ClipMachineMemory);

   gchar    *parent = _clip_parc(ClipMachineMemory, 2);

   gchar    *sibling = _clip_parc(ClipMachineMemory, 3);

   GtkTreeIter iter;

   GtkTreeIter parentiter;

   GtkTreeIter siblingiter;

   GtkTreePath *path;

   gchar    *path_string;

   CHECKARG2(1, MAP_type_of_ClipVarType, NUMERIC_type_of_ClipVarType);
   CHECKCOBJ(cstree, GTK_IS_TREE_STORE(cstree->object));
   CHECKOPT(2, CHARACTER_type_of_ClipVarType);
   CHECKOPT(3, CHARACTER_type_of_ClipVarType);

   if (parent)
      gtk_tree_model_get_iter(GTK_TREE_MODEL(GTK_TREE_STORE(cstree->object)),
			      &parentiter, gtk_tree_path_new_from_string(parent));

   if (sibling)
      gtk_tree_model_get_iter(GTK_TREE_MODEL(GTK_TREE_STORE(cstree->object)),
			      &siblingiter, gtk_tree_path_new_from_string(sibling));

   gtk_tree_store_insert_after(GTK_TREE_STORE(cstree->object), &iter,
			       (parent ? &parentiter : NULL), (sibling ? &siblingiter : NULL));

   __tree_store_set(ClipMachineMemory, &iter, 4);

   path = gtk_tree_model_get_path(GTK_TREE_MODEL(GTK_TREE_STORE(cstree->object)), &iter);

   path_string = gtk_tree_path_to_string(path);

   _clip_retc(ClipMachineMemory, path_string);

   g_free(path_string);

   return 0;
 err:
   return 1;
}
static VALUE
rg_insert_after(VALUE self, VALUE parent, VALUE sibling)
{ 
    VALUE ret;
    GtkTreeIter iter;
    GtkTreeStore* model = _SELF(self);
    gtk_tree_store_insert_after(model, &iter, 
                                NIL_P(parent) ? NULL : RVAL2GTKTREEITER(parent), 
                                NIL_P(sibling) ? NULL : RVAL2GTKTREEITER(sibling));
    iter.user_data3 = model;

    ret = GTKTREEITER2RVAL(&iter);
    G_CHILD_ADD(self, ret);
    return ret;
}
示例#6
0
gTreeRow* gTree::addRow(char *key, char *after, bool before)
{
	GtkTreeIter iter;
	GtkTreeIter *piter;
	gTreeRow *row,*aft = NULL;
	char *buf;

	if (!key)
		return NULL;
	
	if (g_hash_table_lookup (datakey,(gconstpointer)key)) return NULL;
	
	if (after)
	{
		aft=(gTreeRow*)g_hash_table_lookup (datakey,(gconstpointer)after);
		if (!aft) return NULL;	
	}
	
	piter = NULL;
	
	//fprintf(stderr, "[0]: %d %d\n", columnResizable(0), gtk_tree_view_column_get_sizing(gt_tree_view_find_column(GTK_TREE_VIEW(widget), 0)));
	
	if (aft) 
	{
		if (before)
			gtk_tree_store_insert_before(store, &iter, piter, aft->dataiter);
		else
			gtk_tree_store_insert_after(store, &iter, piter, aft->dataiter);
	}
	else
		gtk_tree_store_append (store, &iter, piter);
	
	buf = g_strdup(key); // Will be freed by ~gTreeRow()
	
	row = new gTreeRow(this, buf, gtk_tree_iter_copy(&iter));
	
	g_hash_table_insert(datakey, (gpointer)buf, (gpointer)row);
	gtk_tree_store_set(store, &iter, 1, buf, -1);
	
	//fprintf(stderr, "[0]: -> %d %d\n", columnResizable(0), gtk_tree_view_column_get_sizing(gt_tree_view_find_column(GTK_TREE_VIEW(widget), 0)));

	return row;
}
示例#7
0
static GtkTreeModel*
gwy_grain_value_tree_model_new(gboolean show_id)
{
    GrainValueStorePrivate *priv;
    GwyInventory *inventory;
    GtkTreeStore *store;
    GtkTreeIter siter, iter;
    GwyGrainValue *gvalue;
    GwyGrainValueGroup group, lastgroup;
    guint i, j, n;

    if (!priv_quark)
        priv_quark = g_quark_from_static_string("gwy-grain-value-chooser-data");

    priv = g_new0(GrainValueStorePrivate, 1);
    store = gtk_tree_store_new(3,
                               GWY_TYPE_GRAIN_VALUE,
                               GWY_TYPE_GRAIN_VALUE_GROUP,
                               G_TYPE_BOOLEAN);
    g_object_set_qdata_full(G_OBJECT(store), priv_quark, priv, g_free);

    inventory = gwy_grain_values();
    n = gwy_inventory_get_n_items(inventory);
    lastgroup = -1;
    for (i = j = 0; i < n; i++) {
        gvalue = gwy_inventory_get_nth_item(inventory, i);
        group = gwy_grain_value_get_group(gvalue);
        if (!show_id && group == GWY_GRAIN_VALUE_GROUP_ID)
            continue;

        if (group != lastgroup) {
            gtk_tree_store_insert_after(store, &siter, NULL,
                                        lastgroup != (GwyGrainValueGroup)-1
                                        ? &siter
                                        : NULL);
            gtk_tree_store_set(store, &siter,
                               GWY_GRAIN_VALUE_STORE_COLUMN_GROUP, group,
                               -1);
            if (group == GWY_GRAIN_VALUE_GROUP_USER) {
                priv->user_group_iter = siter;
                priv->user_start_pos = i;
            }
            lastgroup = group;
            j = 0;
        }
        gtk_tree_store_insert_after(store, &iter, &siter, j ? &iter : NULL);
        gtk_tree_store_set(store, &iter,
                           GWY_GRAIN_VALUE_STORE_COLUMN_ITEM, gvalue,
                           GWY_GRAIN_VALUE_STORE_COLUMN_GROUP, group,
                           -1);
        j++;
    }

    /* Ensure User branch is present, even if empty */
    if (lastgroup != GWY_GRAIN_VALUE_GROUP_USER) {
        group = GWY_GRAIN_VALUE_GROUP_USER;
        gtk_tree_store_insert_after(store, &siter, NULL, i ? &siter : NULL);
        gtk_tree_store_set(store, &siter,
                           GWY_GRAIN_VALUE_STORE_COLUMN_GROUP, group,
                           -1);
        priv->user_group_iter = siter;
        priv->user_start_pos = i;
    }

    g_signal_connect(inventory, "item-updated",
                     G_CALLBACK(inventory_item_updated), store);
    g_signal_connect(inventory, "item-inserted",
                     G_CALLBACK(inventory_item_inserted), store);
    g_signal_connect(inventory, "item-deleted",
                     G_CALLBACK(inventory_item_deleted), store);
    g_object_weak_ref(G_OBJECT(store), grain_value_store_finalized, inventory);

    return GTK_TREE_MODEL(store);
}
static void
contact_list_store_add_contact (EmpathyContactListStore *store,
				EmpathyContact          *contact)
{
	EmpathyContactListStorePriv *priv;
	GtkTreeIter                 iter;
	GList                      *groups = NULL, *l;

	priv = GET_PRIV (store);
	
	if (EMP_STR_EMPTY (empathy_contact_get_name (contact)) ||
	    (!priv->show_offline && !empathy_contact_is_online (contact))) {
		return;
	}

	if (priv->show_groups) {
		groups = empathy_contact_list_get_groups (priv->list, contact);
	}

	/* If no groups just add it at the top level. */
	if (!groups) {
		gtk_tree_store_append (GTK_TREE_STORE (store), &iter, NULL);
		gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
				    EMPATHY_CONTACT_LIST_STORE_COL_NAME, empathy_contact_get_name (contact),
				    EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, contact,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_AUDIO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_AUDIO,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_VIDEO,
				    -1);
	}

	/* Else add to each group. */
	for (l = groups; l; l = l->next) {
		GtkTreeIter iter_group;

		contact_list_store_get_group (store, l->data, &iter_group, NULL, NULL);

		gtk_tree_store_insert_after (GTK_TREE_STORE (store), &iter,
					     &iter_group, NULL);
		gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
				    EMPATHY_CONTACT_LIST_STORE_COL_NAME, empathy_contact_get_name (contact),
				    EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, contact,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_AUDIO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_AUDIO,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_VIDEO,
				    -1);
		g_free (l->data);
	}
	g_list_free (groups);

	contact_list_store_contact_update (store, contact);

}
示例#9
0
G_MODULE_EXPORT void 
queue_drag_cb(
    GtkTreeView *dstwidget, 
    GdkDragContext *dc, 
    gint x, gint y, 
    GtkSelectionData *selection_data, 
    guint info, guint t, 
    signal_user_data_t *ud)
{
    GtkTreePath *path = NULL;
    //GtkTreeModel *model;
    GtkTreeViewDropPosition pos;
    GtkTreeIter dstiter, srciter;
    gint *indices, row;
    GValue *js;
    
    GtkTreeModel *dstmodel = gtk_tree_view_get_model(dstwidget);
            
    g_debug("queue_drag_cb ()");
    // This doesn't work here for some reason...
    // gtk_tree_view_get_drag_dest_row(dstwidget, &path, &pos);
    gtk_tree_view_get_dest_row_at_pos (dstwidget, x, y, &path, &pos);
    // This little hack is needed because attempting to drop after
    // the last item gives us no path or pos.
    if (path == NULL)
    {
        gint n_children;

        n_children = gtk_tree_model_iter_n_children(dstmodel, NULL);
        if (n_children)
        {
            pos = GTK_TREE_VIEW_DROP_AFTER;
            path = gtk_tree_path_new_from_indices(n_children-1, -1);
        }
        else
        {
            pos = GTK_TREE_VIEW_DROP_BEFORE;
            path = gtk_tree_path_new_from_indices(0, -1);
        }
    }
    if (path)
    {
        if (gtk_tree_path_get_depth(path) > 1)
            gtk_tree_path_up(path);
        if (gtk_tree_model_get_iter (dstmodel, &dstiter, path))
        {
            GtkTreeIter iter;
            GtkTreeView *srcwidget;
            GtkTreeModel *srcmodel;
            GtkTreeSelection *select;
            GtkTreePath *srcpath = NULL;
            GtkTreePath *dstpath = NULL;

            srcwidget = GTK_TREE_VIEW(gtk_drag_get_source_widget(dc));
            //srcmodel = gtk_tree_view_get_model(srcwidget);
            select = gtk_tree_view_get_selection (srcwidget);
            gtk_tree_selection_get_selected (select, &srcmodel, &srciter);

            srcpath = gtk_tree_model_get_path (srcmodel, &srciter);
            indices = gtk_tree_path_get_indices(srcpath);
            row = indices[0];
            gtk_tree_path_free(srcpath);
            js = ghb_array_get_nth(ud->queue, row);

            switch (pos)
            {
                case GTK_TREE_VIEW_DROP_BEFORE:
                case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
                    gtk_tree_store_insert_before (GTK_TREE_STORE (dstmodel), 
                                                    &iter, NULL, &dstiter);
                    break;

                case GTK_TREE_VIEW_DROP_AFTER:
                case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
                    gtk_tree_store_insert_after (GTK_TREE_STORE (dstmodel), 
                                                    &iter, NULL, &dstiter);
                    break;

                default:
                    break;
            }
            // Reset job to pending
            ghb_settings_set_int(js, "job_status", GHB_QUEUE_PENDING);
            add_to_queue_list(ud, js, &iter);

            dstpath = gtk_tree_model_get_path (dstmodel, &iter);
            indices = gtk_tree_path_get_indices(dstpath);
            row = indices[0];
            gtk_tree_path_free(dstpath);
            ghb_array_insert(ud->queue, row, js);

            srcpath = gtk_tree_model_get_path (srcmodel, &srciter);
            indices = gtk_tree_path_get_indices(srcpath);
            row = indices[0];
            gtk_tree_path_free(srcpath);
            ghb_array_remove(ud->queue, row);
            gtk_tree_store_remove (GTK_TREE_STORE (srcmodel), &srciter);
            ghb_save_queue(ud->queue);
        }
        gtk_tree_path_free(path);
    }
}
示例#10
0
static void bar_pane_keywords_edit_ok_cb(GenericDialog *gd, gpointer data)
{
	ConfDialogData *cdd = data;
	PaneKeywordsData *pkd = cdd->pkd;
	GtkTreeModel *model;

	GtkTreeModel *keyword_tree;
	GtkTreeIter kw_iter;

	gboolean have_dest = FALSE;

	GList *keywords;

	model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview));
	keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));

        if (cdd->click_tpath)
		{
		GtkTreeIter iter;
		if (gtk_tree_model_get_iter(model, &iter, cdd->click_tpath))
			{
			gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &kw_iter, &iter);
			have_dest = TRUE;
			}
		}

	if (cdd->edit_existing && !have_dest) return;

	keywords = keyword_list_pull(cdd->edit_widget);

	if (cdd->edit_existing)
		{
		if (keywords && keywords->data && /* there should be one keyword */
		    !keyword_exists(keyword_tree, NULL, &kw_iter, keywords->data, TRUE, NULL))
			{
			keyword_set(GTK_TREE_STORE(keyword_tree), &kw_iter, keywords->data, cdd->is_keyword);
			}
		}
	else
		{
		GList *work = keywords;
		gboolean append_to = FALSE;

		while (work)
			{
			GtkTreeIter add;
			if (keyword_exists(keyword_tree, NULL, (have_dest || append_to) ? &kw_iter : NULL, work->data, FALSE, NULL))
				{
				work = work->next;
				continue;
				}
			if (have_dest)
				{
				gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &add, &kw_iter);
				}
			else if (append_to)
				{
				gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &kw_iter);
				}
			else
				{
				gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &add, NULL);
				append_to = TRUE;
				kw_iter = add;
				}
			keyword_set(GTK_TREE_STORE(keyword_tree), &add, work->data, cdd->is_keyword);
			work = work->next;
			}
		}
	string_list_free(keywords);
}
示例#11
0
static void bar_pane_keywords_dnd_receive(GtkWidget *tree_view, GdkDragContext *context,
					  gint x, gint y,
					  GtkSelectionData *selection_data, guint info,
					  guint time, gpointer data)
{
	PaneKeywordsData *pkd = data;
	GtkTreePath *tpath = NULL;
        GtkTreeViewDropPosition pos;
	GtkTreeModel *model;

	GtkTreeModel *keyword_tree;
	gboolean src_valid = FALSE;
	GList *new_keywords = NULL;
	GList *work;

	/* iterators for keyword_tree */
	GtkTreeIter src_kw_iter;
	GtkTreeIter dest_kw_iter;
	GtkTreeIter new_kw_iter;

	g_signal_stop_emission_by_name(tree_view, "drag_data_received");

	model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view));
	keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));

	gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y, &tpath, &pos);
	gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), NULL, pos);

	switch (info)
		{
		case TARGET_APP_KEYWORD_PATH:
			{
			GList *path = *(gpointer *)gtk_selection_data_get_data(selection_data);
			src_valid = keyword_tree_get_iter(keyword_tree, &src_kw_iter, path);
			string_list_free(path);
			break;
			}
		default:
			new_keywords = string_to_keywords_list((gchar *)gtk_selection_data_get_data(selection_data));
			break;
		}

	if (tpath)
		{
		GtkTreeIter dest_iter;
                gtk_tree_model_get_iter(model, &dest_iter, tpath);
		gtk_tree_path_free(tpath);
		gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &dest_kw_iter, &dest_iter);

		if (src_valid && gtk_tree_store_is_ancestor(GTK_TREE_STORE(keyword_tree), &src_kw_iter, &dest_kw_iter))
			{
			/* can't move to it's own child */
			return;
			}

		if (src_valid && keyword_compare(keyword_tree, &src_kw_iter, &dest_kw_iter) == 0)
			{
			/* can't move to itself */
			return;
			}

		if ((pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) &&
		    !gtk_tree_model_iter_has_child(keyword_tree, &dest_kw_iter))
			{
			/* the node has no children, all keywords can be added */
			gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &dest_kw_iter);
			}
		else
			{
			if (src_valid && !bar_pane_keywords_dnd_can_move(keyword_tree, &src_kw_iter, &dest_kw_iter))
				{
				/* the keyword can't be moved if the same name already exist */
				return;
				}
			if (new_keywords && !bar_pane_keywords_dnd_skip_existing(keyword_tree, &dest_kw_iter, &new_keywords))
				{
				/* the keywords can't be added if the same name already exist */
				return;
				}

			switch (pos)
				{
				case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
				case GTK_TREE_VIEW_DROP_BEFORE:
					gtk_tree_store_insert_before(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter);
					break;
				case GTK_TREE_VIEW_DROP_INTO_OR_AFTER:
				case GTK_TREE_VIEW_DROP_AFTER:
					gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter);
					break;
				}
			}

		}
	else
		{
		if (src_valid && !bar_pane_keywords_dnd_can_move(keyword_tree, &src_kw_iter, NULL))
			{
			/* the keyword can't be moved if the same name already exist */
			return;
			}
		if (new_keywords && !bar_pane_keywords_dnd_skip_existing(keyword_tree, NULL, &new_keywords))
			{
			/* the keywords can't be added if the same name already exist */
			return;
			}
		gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL);
		}


	if (src_valid)
		{
		keyword_move_recursive(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &src_kw_iter);
		}

	work = new_keywords;
	while (work)
		{
		gchar *keyword = work->data;
		keyword_set(GTK_TREE_STORE(keyword_tree), &new_kw_iter, keyword, TRUE);
		work = work->next;

		if (work)
			{
			GtkTreeIter add;
			gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &add, NULL, &new_kw_iter);
			new_kw_iter = add;
			}
		}
	string_list_free(new_keywords);
	bar_keyword_tree_sync(pkd);
}
示例#12
0
文件: testtreeview.c 项目: Pfiver/gtk
static void
treestore_torture_recurse (GtkTreeStore *store,
                           GtkTreeIter  *root,
                           gint          depth)
{
  GtkTreeModel *model;
  gint i;
  GtkTreeIter iter;  
  
  model = GTK_TREE_MODEL (store);    

  if (depth > 2)
    return;

  ++depth;

  gtk_tree_store_append (store, &iter, root);
  
  gtk_tree_model_iter_children (model, &iter, root);
  
  i = 0;
  while (i < 100)
    {
      gtk_tree_store_append (store, &iter, root);
      ++i;
    }

  while (gtk_tree_model_iter_children (model, &iter, root))
    gtk_tree_store_remove (store, &iter);

  gtk_tree_store_append (store, &iter, root);

  /* inserts before last node in tree */
  i = 0;
  while (i < 100)
    {
      gtk_tree_store_insert_before (store, &iter, root, &iter);
      ++i;
    }

  /* inserts after the node before the last node */
  i = 0;
  while (i < 100)
    {
      gtk_tree_store_insert_after (store, &iter, root, &iter);
      ++i;
    }

  /* inserts after the last node */
  gtk_tree_store_append (store, &iter, root);
    
  i = 0;
  while (i < 100)
    {
      gtk_tree_store_insert_after (store, &iter, root, &iter);
      ++i;
    }

  /* remove everything again */
  while (gtk_tree_model_iter_children (model, &iter, root))
    gtk_tree_store_remove (store, &iter);


    /* Prepends */
  gtk_tree_store_prepend (store, &iter, root);
    
  i = 0;
  while (i < 100)
    {
      gtk_tree_store_prepend (store, &iter, root);
      ++i;
    }

  /* remove everything again */
  while (gtk_tree_model_iter_children (model, &iter, root))
    gtk_tree_store_remove (store, &iter);

  gtk_tree_store_append (store, &iter, root);
  gtk_tree_store_append (store, &iter, root);
  gtk_tree_store_append (store, &iter, root);
  gtk_tree_store_append (store, &iter, root);

  while (gtk_tree_model_iter_children (model, &iter, root))
    {
      treestore_torture_recurse (store, &iter, depth);
      gtk_tree_store_remove (store, &iter);
    }
}
示例#13
0
static void tree_buttons_add_button(int button, GtkTreeIter *iter_after, GtkTreeStore *store)
{
	GtkTreeIter iter, iter_parent;
	int evtype_val, switch_type_val;
	gchar 	*rawcode, 
			*delay, 
			*enabled,
			*force_release,
			*evtype,
			*switch_type,
			*switch_name,
			*keycode, 
			*mod1,
			*mod2,
			*mod3,
			*uid,
			*name,
			*command;
	
	rawcode = g_strdup_printf("0x%08x", buttons_get_rawcode(button));
	delay = g_strdup_printf("%d", buttons_get_delay(button));
	enabled = g_strdup_printf("%d", buttons_get_enabled(button));
	force_release = g_strdup_printf("%d", buttons_get_force_release(button));
	evtype_val = buttons_get_evtype(button);
	switch_type_val = buttons_get_switch_type(button);
	//evtype = g_strdup_printf("%d", buttons_get_evtype(button));
	uid = g_strdup_printf("%d", buttons_get_uid(button));
	
	if (buttons_get_keycode(button) != NULL)
		keycode = g_strndup(buttons_get_keycode(button), 16);
	else
		keycode = g_strdup("NONE");
	if (buttons_get_mod1(button) != NULL)
		mod1 = g_strndup(buttons_get_mod1(button), 16);
	else
		mod1 = g_strdup("NONE");
	if (buttons_get_mod2(button) != NULL)
		mod2 = g_strndup(buttons_get_mod2(button), 16);
	else
		mod2 = g_strdup("NONE");
	if (buttons_get_mod3(button) != NULL)
		mod3 = g_strndup(buttons_get_mod3(button), 16);
	else
		mod3 = g_strdup("NONE");
	if (buttons_get_switch_name(button) != NULL)
		switch_name = g_strndup(buttons_get_switch_name(button), 16);
	else
		switch_name = g_strdup("NONE");
	if (buttons_get_name(button) != NULL)
		name = g_strndup(buttons_get_name(button), 16);
	else
		name = g_strdup(" ");
	if (buttons_get_command(button) != NULL)
		command = g_strndup(buttons_get_command(button), 16);
	else
		command = g_strdup(" ");
	if (evtype_val == EVTYPE_KEY)
		evtype = strdup(EVTYPE_KEY_STR);
	else if (evtype_val == EVTYPE_CONFIG)
		evtype = strdup(EVTYPE_CONFIG_STR);
	else if (evtype_val == EVTYPE_COMMAND)
		evtype = strdup(EVTYPE_COMMAND_STR);
	else
		evtype = strdup(TEXT_ERROR);
	
	if (switch_type_val == CONFIG_SWITCH_NONE)
		switch_type = strdup("NONE");
	else if (switch_type_val == CONFIG_SWITCH_NEXT)
		switch_type = strdup(CONFIG_SWITCH_NEXT_STR);
	else if (switch_type_val == CONFIG_SWITCH_PREV)
		switch_type = strdup(CONFIG_SWITCH_PREV_STR);
	else if (switch_type_val == CONFIG_SWITCH_TO)
		switch_type = strdup(CONFIG_SWITCH_TO_STR);
	else
		switch_type = strdup(TEXT_ERROR);
			
	//gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter_parent);
	if (iter_after == NULL)
	{
		gtk_tree_store_append(store, &iter_parent, NULL);	
	}
	else
	{
		gtk_tree_store_insert_after(store, &iter_parent, NULL, iter_after);
	}
	
	gtk_tree_store_set(	store, &iter_parent,
						COL_NAME, 		name,
						COL_PROPERTY,	" ",
						-1);
	
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
						COL_NAME,		"RC",
						COL_PROPERTY,	rawcode);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. Enabled can be
	 * either true or false. In this case, it means whether the program should
	 * ignore a certain mouse button or do something when it is being pressed.*/
						COL_NAME,		_("Enabled"),
						COL_PROPERTY,	enabled);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. Evtype is already
	 * abbreviated from the words "Event type". This refers to the type of
	 * event that should be sent by the program when it recognizes it must do
	 * something. */
						COL_NAME,		_("Evtype"),
						COL_PROPERTY,	evtype);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. Delay refers to a
	 * certain time interval during which the program should wait. */
						COL_NAME,		_("Delay"),
						COL_PROPERTY,	delay);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
						COL_NAME,		_("Release"),
						COL_PROPERTY,	force_release);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. This word is used
	 * elsewhere in the program. The keycode is a keyboard or button
	 * name. Example: KEY_PAGEUP for a "Page Up" key. */
						COL_NAME,		_("Keycode"),
						COL_PROPERTY,	keycode);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. Modifier refers
	 * to a keyboard modifier key. Examples: Shift, Ctrl, Alt. Make sure to
	 * include the number at the end.*/
						COL_NAME,		_("Modifier1"),
						COL_PROPERTY,	mod1);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. Modifier refers
	 * to a keyboard modifier key. Examples: Shift, Ctrl, Alt. Make sure to
	 * include the number at the end.*/
						COL_NAME,		_("Modifier2"),
						COL_PROPERTY,	mod2);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. Modifier refers
	 * to a keyboard modifier key. Examples: Shift, Ctrl, Alt. Make sure to
	 * include the number at the end.*/
						COL_NAME,		_("Modifier3"),
						COL_PROPERTY,	mod3);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
						COL_NAME,		_("Switch type"),
						COL_PROPERTY,	switch_type);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
						COL_NAME,		CONFIG_SWITCH_TO_STR,
						COL_PROPERTY,	switch_name);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. The UID refers
	 * to User Identification, a number referring to a user in a 
	 * Linux system. Do not try to translate UID unless it is explicitly
	 * used differently by Linux in your language. */
						COL_NAME,		_("UID"),
						COL_PROPERTY,	uid);
	gtk_tree_store_append(store, &iter, &iter_parent);
	gtk_tree_store_set(	store, &iter,
	/* TRANSLATORS: Make this short. Abbreviate if necessary. Command refers
	 * to a shell command that can be executed. */
						COL_NAME,		_("Command"),
						COL_PROPERTY,	command);
	
	
	g_free(rawcode);
	g_free(delay);
	g_free(enabled);
	g_free(force_release);
	g_free(evtype);
	g_free(keycode);
	g_free(mod1);
	g_free(mod2);
	g_free(mod3);
	g_free(uid);
	g_free(name);
	g_free(command);
	g_free(switch_type);
	g_free(switch_name);
}
示例#14
0
void
accel_edited (GtkCellRendererAccel * accel,
              gchar * path_string,
              guint accel_key,
              GdkModifierType accel_mods,
              guint hardware_keycode, GladeEPropAccel * eprop_accel)
{
  gboolean key_was_set;
  GtkTreeIter iter, parent_iter, new_iter;
  gchar *accel_text;
  GladePropertyClass *pclass;
  GladeWidgetAdaptor *adaptor;
  gboolean is_action;

  pclass = glade_editor_property_get_pclass (GLADE_EDITOR_PROPERTY (eprop_accel));
  adaptor = glade_property_class_get_adaptor (pclass);

  if (!gtk_tree_model_get_iter_from_string (eprop_accel->model,
                                            &iter, path_string))
    return;

  is_action = (glade_widget_adaptor_get_object_type (adaptor) == GTK_TYPE_ACTION ||
               g_type_is_a (glade_widget_adaptor_get_object_type (adaptor), GTK_TYPE_ACTION));

  gtk_tree_model_get (eprop_accel->model, &iter,
                      ACCEL_COLUMN_KEY_ENTERED, &key_was_set, -1);

  accel_text = gtk_accelerator_name (accel_key, accel_mods);

  gtk_tree_store_set
      (GTK_TREE_STORE (eprop_accel->model), &iter,
       ACCEL_COLUMN_KEY_ENTERED, TRUE,
       ACCEL_COLUMN_STYLE, PANGO_STYLE_NORMAL,
       ACCEL_COLUMN_FOREGROUND, "Black",
       ACCEL_COLUMN_TEXT, accel_text,
       ACCEL_COLUMN_KEYCODE, accel_key, ACCEL_COLUMN_MODIFIERS, accel_mods, -1);

  g_free (accel_text);

  /* Append a new one if needed
   */
  if (is_action == FALSE && key_was_set == FALSE &&
      gtk_tree_model_iter_parent (eprop_accel->model, &parent_iter, &iter))
    {
      gchar *signal, *real_signal;

      gtk_tree_model_get (eprop_accel->model, &iter,
                          ACCEL_COLUMN_SIGNAL, &signal,
                          ACCEL_COLUMN_REAL_SIGNAL, &real_signal, -1);

      /* Append a new empty slot at the end */
      gtk_tree_store_insert_after (GTK_TREE_STORE (eprop_accel->model),
                                   &new_iter, &parent_iter, &iter);
      gtk_tree_store_set (GTK_TREE_STORE (eprop_accel->model), &new_iter,
                          ACCEL_COLUMN_SIGNAL, signal,
                          ACCEL_COLUMN_REAL_SIGNAL, real_signal,
                          ACCEL_COLUMN_TEXT, _("<choose a key>"),
                          ACCEL_COLUMN_WEIGHT, PANGO_WEIGHT_NORMAL,
                          ACCEL_COLUMN_STYLE, PANGO_STYLE_ITALIC,
                          ACCEL_COLUMN_FOREGROUND, "Grey",
                          ACCEL_COLUMN_VISIBLE, TRUE,
                          ACCEL_COLUMN_KEYCODE, 0,
                          ACCEL_COLUMN_MODIFIERS, 0,
                          ACCEL_COLUMN_KEY_ENTERED, FALSE, -1);
      g_free (signal);
      g_free (real_signal);
    }
}
示例#15
0
static void
contact_list_store_add_contact (EmpathyContactListStore *store,
				EmpathyContact          *contact)
{
	EmpathyContactListStorePriv *priv;
	GtkTreeIter                 iter;
	GList                      *groups = NULL, *l;
	TpConnection               *connection;
	EmpathyContactListFlags     flags = 0;

	priv = GET_PRIV (store);

	if (EMP_STR_EMPTY (empathy_contact_get_name (contact)) ||
	    (!priv->show_offline && !empathy_contact_is_online (contact))) {
		return;
	}

	if (priv->show_groups) {
		groups = empathy_contact_list_get_groups (priv->list, contact);
	}

	connection = empathy_contact_get_connection (contact);
	if (EMPATHY_IS_CONTACT_MANAGER (priv->list)) {
		flags = empathy_contact_manager_get_flags_for_connection (
			EMPATHY_CONTACT_MANAGER (priv->list), connection);
	}
	/* If no groups just add it at the top level. */
	if (!groups) {
		GtkTreeModel *model = GTK_TREE_MODEL (store);

		if (gtk_tree_model_get_iter_first (model, &iter)) do {
			EmpathyContact *c;

			gtk_tree_model_get (model, &iter,
				EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, &c,
				-1);

			if (c == contact) {
				g_object_unref (c);
				return;
			}
			if (c != NULL)
				g_object_unref (c);
		} while (gtk_tree_model_iter_next (model, &iter));

		gtk_tree_store_append (GTK_TREE_STORE (store), &iter, NULL);
		gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
				    EMPATHY_CONTACT_LIST_STORE_COL_NAME, empathy_contact_get_name (contact),
				    EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, contact,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_AUDIO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_AUDIO,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_VIDEO,
				    EMPATHY_CONTACT_LIST_STORE_COL_FLAGS, flags,
				    -1);
	}

	/* Else add to each group. */
	for (l = groups; l; l = l->next) {
		GtkTreeIter iter_group;

		contact_list_store_get_group (store, l->data, &iter_group, NULL, NULL);

		gtk_tree_store_insert_after (GTK_TREE_STORE (store), &iter,
					     &iter_group, NULL);
		gtk_tree_store_set (GTK_TREE_STORE (store), &iter,
				    EMPATHY_CONTACT_LIST_STORE_COL_NAME, empathy_contact_get_name (contact),
				    EMPATHY_CONTACT_LIST_STORE_COL_CONTACT, contact,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_GROUP, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_IS_SEPARATOR, FALSE,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_AUDIO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_AUDIO,
				    EMPATHY_CONTACT_LIST_STORE_COL_CAN_VIDEO_CALL,
				      empathy_contact_get_capabilities (contact) &
				        EMPATHY_CAPABILITIES_VIDEO,
				    EMPATHY_CONTACT_LIST_STORE_COL_FLAGS, flags,
				    -1);
		g_free (l->data);
	}
	g_list_free (groups);

	contact_list_store_contact_update (store, contact);

}
示例#16
0
/**
@brief paste tree rows into @a treeview

Row(s) are inserted after the 1st selected row in @a treeview,
as child(ren) if the path depth is appropriate
It is assumed here that the buffer hash has pastable data

@param rowscopied list of copied value-arrays
@param treeview the treeview to be processed

@return
*/
void e2_tree_paste (GList *rowscopied, GtkTreeView *treeview)
{
	GtkTreeSelection *sel = gtk_tree_view_get_selection (treeview);
	if (gtk_tree_selection_count_selected_rows (sel) > 0)
	{
		//get source-view path for the 1st buffered item, the
		//root of the copied branch (or one of several roots)
		GArray *value_array = rowscopied->data;
		GValue *value = &g_array_index (value_array, GValue, 0);
//		gchar *pathstring = g_value_dup_string (value);
//		GtkTreePath *path = gtk_tree_path_new_from_string (pathstring);
		GtkTreePath *rootpath = (GtkTreePath *) g_value_get_pointer (value);
		gint copyrootdepth = gtk_tree_path_get_depth (rootpath);
//		gtk_tree_path_free (path);
		//store for references (hence iters) needed to preserve relations
		//among pasted rows
		GHashTable *ref_hash = NULL;
		GtkTreeRowReference *ref;

		GtkTreeModel *model;
		GList *selpaths = gtk_tree_selection_get_selected_rows (sel, &model);
		gint columns = gtk_tree_model_get_n_columns (model);
		GList *tmp;
		GtkTreeIter local1;
		GtkTreeIter local2;
		GtkTreeIter *iter = &local1;
		GtkTreeIter *parent = &local2;

		//find a selected item where it's valid to paste
		for (tmp = selpaths; tmp != NULL; tmp = tmp->next)
		{
			if (gtk_tree_model_get_iter (model, iter, (GtkTreePath *) tmp->data))
			{
				gint thisdepth = gtk_tree_path_get_depth (tmp->data);
				if (thisdepth == copyrootdepth)
				{	//the selected row is a valid sibling of the buffered row(s)
					//paste the root of the copied branch
					printd (DEBUG, "pasting branch root, at depth %d", thisdepth);
/*					if (gtk_tree_model_iter_parent (model, parent, iter))
					{	//pasted row (iter) will be _pre_pended to parent's children
						gtk_tree_store_insert_after (GTK_TREE_STORE (model), iter, parent, NULL);
					}
					else //parent is the root node
					{ */
					//pasted row (iter) will be inserted after selected row
						gtk_tree_store_insert_after (GTK_TREE_STORE (model), parent, NULL, iter);
						iter = parent;
//					}
					break;
				}
				else if (thisdepth == copyrootdepth - 1)
				{	//the selected item is a parent of the buffered row(s)
					//pasted row (iter) will be appended to parent's children
					printd (DEBUG, "pasting branch root, at depth %d", thisdepth);
					gtk_tree_store_insert_before (GTK_TREE_STORE (model), parent, iter, NULL);
					iter = parent;
					break;
				}
			}
			//keep looking ...
		}
		if (tmp != NULL)
		{	//found a place where it's ok to paste
			//populate the newly-added "root" iter
			gint i;
			for (i = 0; i < columns; i++)
			{
				value = &g_array_index (value_array, GValue, i+1);
				gtk_tree_store_set_value (GTK_TREE_STORE (model), iter, i, value);
			}

			//remember how to find the parent of each pasted iter
			//the hash key (a path from the source treeview) is used
			//determine parent/child relations between pasted rows
			ref_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
				g_free, (GDestroyNotify) gtk_tree_row_reference_free);
//			ref_hash = g_hash_table_new_full (g_direct_hash,
//				(GEqualFunc) _e2_tree_path_compare,
//				NULL,	//we don't want to damage the buffered paths
//				(GDestroyNotify) gtk_tree_row_reference_free);
			GtkTreePath *path = gtk_tree_model_get_path (model, iter);
			ref = gtk_tree_row_reference_new (model, path);
			gtk_tree_path_free (path);
//			g_hash_table_insert (ref_hash, pathstring, ref);
			gchar *rootstring = gtk_tree_path_to_string (rootpath);
			g_hash_table_insert (ref_hash, rootstring, ref);

			//now the rest of the list, if any
			//there may be descendant(s) and/or sibling(s) of the initial item
			GtkTreePath *src_path;
			gchar *ppstring;
			GList *tmp2 = rowscopied;
			while ((tmp2 = tmp2->next) != NULL)
			{
				value_array = tmp2->data;
				//get source-view path and find where it should sit in the new tree
				value = &g_array_index (value_array, GValue, 0);
//				pathstring = g_value_dup_string (value);
				src_path = (GtkTreePath *) g_value_get_pointer (value);
				path = gtk_tree_path_copy (src_path);
				//get former parent path string, by truncating the last segment
//				gchar *s = g_strrstr (pathstring, ":");
//				if (s != NULL)
//				{
//					*s = '\0';
				if (gtk_tree_path_up (path))
				{
					//try to find an already-pasted parent iter
					ppstring = gtk_tree_path_to_string (path);
					if (ppstring != NULL)
					{	//we're not at the root node now
						ref = g_hash_table_lookup (ref_hash, ppstring);
						gtk_tree_path_free (path);
						g_free (ppstring);
					}
					else
						ref = NULL;
					if (ref != NULL)
					{
						path = gtk_tree_row_reference_get_path (ref);
						gtk_tree_model_get_iter (model, parent, path);
						gtk_tree_path_free (path);
						//append row (iter) to parent's children
						gtk_tree_store_insert_before (
							GTK_TREE_STORE (model), iter, parent, NULL);
					}
					else
					{	//this is probably a sibling
						ref = g_hash_table_lookup (ref_hash, rootstring);
						path = gtk_tree_row_reference_get_path (ref);
						gtk_tree_model_get_iter (model, parent, path);
						gtk_tree_path_free (path);
						//append row (iter) to as a sibling
						gtk_tree_store_insert_after (
							GTK_TREE_STORE (model), iter, NULL, parent);
					}
				}
				else
				{
					//CHECKME probably can't be at a root already
					printd (DEBUG, "root node problem");
					continue;
				}
				//populate row
				for (i = 0; i < columns; i++)
				{
					value = &g_array_index (value_array, GValue, i+1);
					gtk_tree_store_set_value (GTK_TREE_STORE (model), iter, i, value);
				}
//				g_free (pathstring);
				//remember newly-added iter in case it's a parent
				path = gtk_tree_model_get_path (model, iter);
				ref = gtk_tree_row_reference_new (model, path);
				gtk_tree_path_free (path);
				ppstring = gtk_tree_path_to_string (src_path);
//				g_hash_table_insert (ref_hash, g_value_dup_string (value), ref);
				g_hash_table_insert (ref_hash, ppstring, ref);
			}
			//no change to (single row) selection, as all new rows are after
			if (ref_hash != NULL)
				g_hash_table_destroy (ref_hash);
		}
		g_list_foreach (selpaths, (GFunc) gtk_tree_path_free, NULL);
		g_list_free (selpaths);
	}
}