Example #1
0
/* 
 * 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();
}
Example #2
0
orcaData orcaGtkIter::ex_insert(orcaVM* vm, int n)/*{{{*/
{
	if (n < 1) vm->need_param();

	GtkTreeIter iter;

	if (m_type == GUI_LIST) 
		gtk_list_store_insert_before(GTK_LIST_STORE(m_gp->store), &iter, &m_iter);
	else {
		GtkTreeIter parent;
		GtkTreeIter* pp = NULL;
		if (gtk_tree_model_iter_parent(m_gp->store, &parent, &m_iter))
			pp = &parent;

		gtk_tree_store_insert_before(GTK_TREE_STORE(m_gp->store), &iter, pp, &m_iter);
	}

	orcaList* lp = castobj<orcaList>(vm->get_param(0));
	if (lp == NULL) {
		throw orcaException(vm, "orca.type", "list type is required");
	}

	set_list_to_store(lp, m_gp->store, &iter, m_type);
	return NIL;
}
Example #3
0
void update_room_list(void)
{
	GtkTreeStore *store;
	int i;
	const int numrooms = ggzcore_server_get_num_rooms(ggz_gtk.server);

	/* Retrieve the player list widget. */
	store = GTK_TREE_STORE(ggz_lookup_widget(room_list, "room_list_store"));

	clear_room_list();

	gtk_tree_store_append(store, &other_iter, NULL);
	gtk_tree_store_set(store, &other_iter,
			   ROOM_COLUMN_PTR, NULL,
			   ROOM_COLUMN_NAME, _("Other Rooms"),
			   ROOM_COLUMN_PLAYERS, 0, -1);

	room_iter = ggz_realloc(room_iter, numrooms * sizeof(*room_iter));
	for (i = 0; i < numrooms; i++) {
		GGZRoom *room = ggzcore_server_get_nth_room(ggz_gtk.server, i);
		GGZGameType *gt = ggzcore_room_get_gametype(room);
		GtkTreeIter *iter = &room_iter[i];

		if (gt && !can_launch_gametype(gt)) {
			gtk_tree_store_append(store, iter, &other_iter);
		} else {
			gtk_tree_store_insert_before(store, iter,
						     NULL, &other_iter);
		}

		update_iter_room(store, iter, room);
	}
}
Example #4
0
void 
gbf_project_model_move_target_shortcut (GbfProjectModel *model,
		     GtkTreeIter     *iter,
    		     GbfTreeData     *shortcut,
		     GtkTreePath     *before_path)
{
	AnjutaProjectNode *node;
	GtkTreeIter sibling;
	GtkTreePath *root_path;
	GtkTreePath *src_path;
	AnjutaProjectNode *parent;
	
	if (!shortcut)
		return;

	root_path = gbf_project_model_get_project_root (model);
	
	/* check before_path */
	if (!before_path ||
	    gtk_tree_path_get_depth (before_path) > 1)
	{
		/* Missing destination path, use root path */
		before_path = root_path;
	}
	else if (gtk_tree_path_compare (before_path, root_path) > 0)
	{
		/* Destination path outside shortcut are, remove shortcut */
		gbf_project_model_remove (model, iter);
		gtk_tree_path_free (root_path);
		
		return;
	}
		
	/* get the tree iter for the row before which to insert the shortcut */
	if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &sibling, before_path)) {
		gtk_tree_path_free (root_path);
		return;
	}

	src_path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), iter);
	if (gtk_tree_path_compare (src_path, before_path) != 0)
	{
		gtk_tree_store_remove (GTK_TREE_STORE (model), iter);			
		gtk_tree_store_insert_before (GTK_TREE_STORE (model), iter, NULL, &sibling);
		gtk_tree_store_set (GTK_TREE_STORE (model), iter, 
				    GBF_PROJECT_MODEL_COLUMN_DATA, shortcut,
				    -1);

		/* add sources */
		parent = gbf_tree_data_get_node (shortcut->shortcut);
		for (node = anjuta_project_node_first_child (parent); node; node = anjuta_project_node_next_sibling (node))
			gbf_project_model_add_node (model, node, iter);

	}

	gtk_tree_path_free (src_path);
	gtk_tree_path_free (root_path);

}
Example #5
0
/*
 * add new watche to the tree view
 */
void wtree_add_watch(gchar *watch)
{
	GtkTreeIter newvar;
	GtkTreeIter empty = wtree_empty_row();
	gtk_tree_store_insert_before(store, &newvar, NULL, &empty);

	variable_set_name_only(store, &newvar, watch);
}
Example #6
0
void
cdda_record_addlist_iter(GtkTreeIter iter_record, playlist_t * pl, GtkTreeIter * dest, int album_mode) {

        GtkTreeIter iter_track;
	GtkTreeIter list_iter;
	GtkTreeIter * plist_iter;
	
	int i;
	float record_duration = 0.0f;
	playlist_data_t * pldata = NULL;

	if (gtk_tree_model_iter_n_children(GTK_TREE_MODEL(music_store), &iter_record) == 0) {
		return;
	}

	if (album_mode) {

		char list_str[MAXLEN];
		cdda_drive_t * drive;

		if ((pldata = playlist_data_new()) == NULL) {
			return;
		}

		gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_DATA, &drive, -1);

		snprintf(list_str, MAXLEN-1, "%s: %s", drive->disc.artist_name, drive->disc.record_name);

		pldata->artist = strdup(drive->disc.artist_name);
		pldata->album = strdup(drive->disc.record_name);

		gtk_tree_store_insert_before(pl->store, &list_iter, NULL, dest);
		gtk_tree_store_set(pl->store, &list_iter,
				   PL_COL_NAME, list_str,
				   PL_COL_VADJ, "",
				   PL_COL_DURA, "00:00",
				   PL_COL_COLO, pl_color_inactive,
				   PL_COL_FONT, PANGO_WEIGHT_NORMAL,
				   PL_COL_DATA, pldata, -1);

		plist_iter = &list_iter;
		dest = NULL;
	} else {
		plist_iter = NULL;
	}

	i = 0;
	while (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(music_store), &iter_track, &iter_record, i++)) {
		record_duration += cdda_track_addlist_iter(iter_track, pl, plist_iter, dest);
	}

	if (album_mode) {
		char duration_str[MAXLEN];
		pldata->duration = record_duration;
		time2time(record_duration, duration_str);
		gtk_tree_store_set(pl->store, &list_iter, PL_COL_DURA, duration_str, -1);
	}
}
Example #7
0
/*
 * add new breakpoint to the tree view
 * arguments:
 * 		bp - breakpoint to add
 */
void bptree_add_breakpoint(breakpoint* bp)
{
	GtkTreeIter file_iter, iter, child, *sibling = NULL;
	GtkTreeRowReference *file_reference = (GtkTreeRowReference*)g_hash_table_lookup(files, bp->file);

	if (!file_reference)
	{
		GtkTreePath *file_path;

		gtk_tree_store_prepend (store, &file_iter, NULL);
		gtk_tree_store_set (store, &file_iter,
						FILEPATH, bp->file,
						ENABLED, TRUE,
						-1);

		file_path = gtk_tree_model_get_path(model, &file_iter);
		file_reference = gtk_tree_row_reference_new(model, file_path);
		gtk_tree_path_free(file_path);

		g_hash_table_insert(files, (gpointer)g_strdup(bp->file),(gpointer)file_reference);
	}
	else
	{
		GtkTreePath *path = gtk_tree_row_reference_get_path(file_reference);
		gtk_tree_model_get_iter(model, &file_iter, path);
		gtk_tree_path_free(path);
	}
	
	/* lookup where to insert new row */
	if(gtk_tree_model_iter_children(model, &child, &file_iter))
	{
		do
		{
			int line;
			gtk_tree_model_get (
				model,
				&child,
				LINE, &line,
				-1);
			if (line > bp->line)
			{
				sibling = &child;
				break;
			}
		}
		while(gtk_tree_model_iter_next(model, &child));
	}
	
	gtk_tree_store_insert_before(store, &iter, &file_iter, sibling);
	bp->iter = iter;
	
	bptree_update_breakpoint(bp);
}
static VALUE
rg_insert_before(VALUE self, VALUE parent, VALUE sibling)
{
    VALUE ret;
    GtkTreeIter iter;
    GtkTreeStore* model = _SELF(self);
    gtk_tree_store_insert_before(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;
}
Example #9
0
/******************************************************************************
* gtk_TreeStoreInsertBefore(tree, parent_path_string/NULL, sibling_path_string/NULL, ncol, val, ....)-->path_string
******************************************************************************/
int
clip_GTK_TREESTOREINSERTBEFORE(ClipMachine * ClipMachineMemory)
{

   C_object *cstree = _fetch_co_arg(ClipMachineMemory);

   gchar    *parent = _clip_parc(ClipMachineMemory, 2);

   gchar    *sibling = _clip_parc(ClipMachineMemory, 3);

   GtkTreeIter iter;

   GtkTreeIter siblingiter;

   GtkTreeIter parentiter;

   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_before(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;
}
Example #10
0
static void
tagAdd(
        const tReaderManager    *pManager,
        GtkTreeIter             *pTagListIter,
        int                     readerNumber,
        int                     tagNumber
    )
{
    char                numberString[20];
    const char          *tagTypeName;
    GtkTreeIter         tagIter, tagTypeIter, tagDataIter, dataCharIter, dataHexIter;

    sprintf( numberString, "Tag %d", tagNumber );

    gtk_tree_store_insert_before( store, &tagIter, pTagListIter, NULL );
    gtk_tree_store_set( store, &tagIter,
                        OBJECT_COLUMN, numberString,
                        DESCRIPTION_COLUMN, pManager->readers[readerNumber].tagList.pTags[tagNumber].uid, -1);

    TAG_TYPE_NAME_FROM_ENUM( pManager->readers[readerNumber].tagList.pTags[tagNumber].tagType, tagTypeName );
    gtk_tree_store_append( store, &tagTypeIter, &tagIter );
    gtk_tree_store_set( store, &tagTypeIter,
                        OBJECT_COLUMN, "TagType",
                        DESCRIPTION_COLUMN, tagTypeName, -1);

    /* if we have tag contents then show them */
    if ( pManager->readers[readerNumber].tagList.pTags[tagNumber].contents.dataSize > 0 )
    {
        sprintf( numberString, "%d Bytes", pManager->readers[readerNumber].tagList.pTags[tagNumber].contents.dataSize );
        gtk_tree_store_append( store, &tagDataIter, &tagIter );
        gtk_tree_store_set( store, &tagDataIter,
                            OBJECT_COLUMN, "Contents",
                            DESCRIPTION_COLUMN, numberString, -1);

        gtk_tree_store_append( store, &dataCharIter, &tagDataIter );
        gtk_tree_store_set( store, &dataCharIter,
                            OBJECT_COLUMN, "ASCII",
                            DESCRIPTION_COLUMN, pManager->readers[readerNumber].tagList.pTags[tagNumber].contents.pData, -1);

        gtk_tree_store_append( store, &dataHexIter, &tagDataIter );
        gtk_tree_store_set( store, &dataHexIter,
                            OBJECT_COLUMN, "Hex",
                            DESCRIPTION_COLUMN, pManager->readers[readerNumber].tagList.pTags[tagNumber].contents.extensionHook, -1);

    }

}
Example #11
0
/*
 *	add frame to the tree view
 */
void stree_add(frame *f)
{
	GtkTreeRowReference *reference = (GtkTreeRowReference*)g_hash_table_lookup(threads, (gpointer)current_thread_id);
	GtkTreeIter thread_iter;
	gtk_tree_model_get_iter(model, &thread_iter, gtk_tree_row_reference_get_path(reference));

	GtkTreeIter frame_iter;
	gtk_tree_store_insert_before(store, &frame_iter, &thread_iter, 0);

	gtk_tree_store_set (store, &frame_iter,
                    S_ADRESS, f->address,
                    S_FUNCTION, f->function,
                    S_FILEPATH, f->file,
                    S_LINE, f->line,
                    S_HAVE_SOURCE, f->have_source,
                    -1);
}
Example #12
0
/* 
 * mouse button has been pressed while being in watch(autos) tree view
 */
static gboolean on_watch_button_pressed_callback(GtkWidget *treeview, GdkEventButton *event, gpointer userdata)
{
    if (event->type == GDK_2BUTTON_PRESS  &&  event->button == 1)
	{
		GtkTreePath *path = NULL;
		if (gtk_tree_view_get_path_at_pos(
			GTK_TREE_VIEW(treeview),
		    (int)event->x, (int)event->y, &path, NULL, NULL, NULL))
		{
			gchar *expression = NULL;
			GtkTreeIter iter;
			GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
			gtk_tree_model_get_iter (model, &iter, path);

			gtk_tree_model_get(model, &iter,
				W_EXPRESSION, &expression,
			    -1);

			if (strlen(expression))
			{
				GtkTreeIter newvar, 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();
			}

			g_free(expression);
		}
	}
	
	return FALSE;
}
Example #13
0
static void
update_days_and_lines_for_log (LogviewLoglist *loglist,
                               GtkTreeIter *log, GSList *days)
{
  gboolean res;
  GtkTreeIter iter, dummy;
  GSList *l;
  int i;
  char date[200];
  Day *day;

  /* if we have some days, we can't remove all the items immediately, otherwise,
   * if the row is expanded, it will be collapsed because there are no items,
   * so we create a dummy entry, remove all the others and then remove the
   * dummy one.
   */
  res = gtk_tree_model_iter_children (GTK_TREE_MODEL (loglist->priv->model),
                                      &iter, log);
  if (res) {
    gtk_tree_store_insert_before (loglist->priv->model, &dummy, log, &iter);
    gtk_tree_store_set (loglist->priv->model, &dummy,
                        LOG_NAME, "", -1);
    do {
      gtk_tree_store_remove (loglist->priv->model, &iter);
    } while (gtk_tree_store_iter_is_valid (loglist->priv->model, &iter));
  }

  for (i = 1, l = days; l; l = l->next) {
    /* now insert all the days */
    day = l->data;

    g_date_strftime (date, 200, "%A, %e %b", day->date);

    gtk_tree_store_insert (GTK_TREE_STORE (loglist->priv->model),
                           &iter, log, i);
    gtk_tree_store_set (GTK_TREE_STORE (loglist->priv->model),
                        &iter, LOG_NAME, date, LOG_DAY, day, -1);
    i++;
  }

  if (res) {
    gtk_tree_store_remove (loglist->priv->model, &dummy);
  }
}
Example #14
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;
}
Example #15
0
static void
chanview_insert_sorted (chanview *cv, GtkTreeIter *add_iter, GtkTreeIter *parent, void *ud)
{
	GtkTreeIter iter;
	chan *ch;

	if (cv->sorted && gtk_tree_model_iter_children (GTK_TREE_MODEL (cv->store), &iter, parent))
	{
		do
		{
			gtk_tree_model_get (GTK_TREE_MODEL (cv->store), &iter, COL_CHAN, &ch, -1);
			if (ch->tag == 0 && cv->cb_compare (ch->userdata, ud) > 0)
			{
				gtk_tree_store_insert_before (cv->store, add_iter, parent, &iter);
				return;
			}
		}
		while (gtk_tree_model_iter_next (GTK_TREE_MODEL (cv->store), &iter));
	}

	gtk_tree_store_append (cv->store, add_iter, parent);
}
Example #16
0
/*
 * Update the tree by adding/removing entries
 * Does not change other nodes
 */
static void update_tree(struct menu *src, GtkTreeIter * dst)
{
	struct menu *child1;
	GtkTreeIter iter, tmp;
	GtkTreeIter *child2 = &iter;
	gboolean valid;
	GtkTreeIter *sibling;
	struct symbol *sym;
	struct property *prop;
	struct menu *menu1, *menu2;

	if (src == &rootmenu)
		indent = 1;

	valid = gtk_tree_model_iter_children(model2, child2, dst);
	for (child1 = src->list; child1; child1 = child1->next) {

		prop = child1->prompt;
		sym = child1->sym;

	      reparse:
		menu1 = child1;
		if (valid)
			gtk_tree_model_get(model2, child2, COL_MENU,
					   &menu2, -1);
		else
			menu2 = NULL;	// force adding of a first child

#ifdef DEBUG
		printf("%*c%s | %s\n", indent, ' ',
		       menu1 ? menu_get_prompt(menu1) : "nil",
		       menu2 ? menu_get_prompt(menu2) : "nil");
#endif

		if (!menu_is_visible(child1) && !show_all) {	// remove node
			if (gtktree_iter_find_node(dst, menu1) != NULL) {
				memcpy(&tmp, child2, sizeof(GtkTreeIter));
				valid = gtk_tree_model_iter_next(model2,
								 child2);
				gtk_tree_store_remove(tree2, &tmp);
				if (!valid)
					return;	// next parent 
				else
					goto reparse;	// next child
			} else
				continue;
		}

		if (menu1 != menu2) {
			if (gtktree_iter_find_node(dst, menu1) == NULL) {	// add node
				if (!valid && !menu2)
					sibling = NULL;
				else
					sibling = child2;
				gtk_tree_store_insert_before(tree2,
							     child2,
							     dst, sibling);
				set_node(child2, menu1, fill_row(menu1));
				if (menu2 == NULL)
					valid = TRUE;
			} else {	// remove node
				memcpy(&tmp, child2, sizeof(GtkTreeIter));
				valid = gtk_tree_model_iter_next(model2,
								 child2);
				gtk_tree_store_remove(tree2, &tmp);
				if (!valid)
					return;	// next parent 
				else
					goto reparse;	// next child
			}
		} else if (sym && (sym->flags & SYMBOL_CHANGED)) {
			set_node(child2, menu1, fill_row(menu1));
		}

		indent++;
		update_tree(child1, child2);
		indent--;

		valid = gtk_tree_model_iter_next(model2, child2);
	}
}
Example #17
0
/* returns the duration of the track */
float
cdda_track_addlist_iter(GtkTreeIter iter_track, playlist_t * pl, GtkTreeIter * parent, GtkTreeIter * dest) {

	GtkTreeIter dest_parent;
        GtkTreeIter iter_record;
	GtkTreeIter list_iter;

	cdda_track_t * data;
	cdda_drive_t * drive;

        char * track_name;
	char list_str[MAXLEN];
	char duration_str[MAXLEN];

	playlist_data_t * pldata = NULL;


	gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_track,
			   MS_COL_NAME, &track_name,
			   MS_COL_DATA, &data, -1);

	gtk_tree_model_iter_parent(GTK_TREE_MODEL(music_store), &iter_record, &iter_track);
	gtk_tree_model_get(GTK_TREE_MODEL(music_store), &iter_record, MS_COL_DATA, &drive, -1);

	if (parent != NULL ||
	    (dest != NULL && gtk_tree_model_iter_parent(GTK_TREE_MODEL(pl->store), &dest_parent, dest))) {
		GtkTreeIter * piter = (parent != NULL) ? parent : &dest_parent;
		playlist_data_t * pdata;

		gtk_tree_model_get(GTK_TREE_MODEL(pl->store), piter, PL_COL_DATA, &pdata, -1);
		if (pdata->artist && pdata->album &&
		    !strcmp(pdata->artist, drive->disc.artist_name) && !strcmp(pdata->album, drive->disc.record_name)) {
			strcpy(list_str, track_name);
		} else {
			make_title_string(list_str, options.title_format, drive->disc.artist_name,
					  drive->disc.record_name, track_name);
		}
	} else {
		make_title_string(list_str, options.title_format, drive->disc.artist_name,
				  drive->disc.record_name, track_name);
	}

	time2time(data->duration, duration_str);

	if ((pldata = playlist_data_new()) == NULL) {
		return 0;
	}

	pldata->artist = strdup(drive->disc.artist_name);
	pldata->album = strdup(drive->disc.record_name);
	pldata->title = strdup(track_name);
	pldata->file = strdup(data->path);

	pldata->duration = data->duration;

	/* either parent or dest should be set, but not both */
	gtk_tree_store_insert_before(pl->store, &list_iter, parent, dest);
	
	gtk_tree_store_set(pl->store, &list_iter,
			   PL_COL_NAME, list_str,
			   PL_COL_VADJ, "",
			   PL_COL_DURA, duration_str,
			   PL_COL_COLO, pl_color_inactive,
			   PL_COL_FONT, PANGO_WEIGHT_NORMAL,
			   PL_COL_DATA, pldata, -1);

	g_free(track_name);

	return data->duration;
}
Example #18
0
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);
    }
}
Example #19
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);
    }
}
Example #20
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);
}
Example #21
0
void 
gbf_project_model_add_target_shortcut (GbfProjectModel *model,
                     GtkTreeIter     *shortcut,
		     GbfTreeData     *target,
		     GtkTreePath     *before_path,
                     gboolean	     *expanded)
{
	AnjutaProjectNode *node;
	GtkTreeIter iter, sibling;
	GtkTreePath *root_path;
	GbfTreeData *data;
	AnjutaProjectNode *parent;
	gboolean valid = FALSE;
	
	if (!target)
		return;

	if (expanded != NULL) *expanded = FALSE;

	root_path = gbf_project_model_get_project_root (model);
	if ((before_path == NULL) && (target->type != GBF_TREE_NODE_SHORTCUT))
	{
		/* Check is a proxy node is not already existing. It is used to
		 * save the shortcut order */

		for (valid = gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter, NULL);
			valid;
			valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter))
		{
			GbfTreeData *data;

			/* Look for current node */
			gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
				GBF_PROJECT_MODEL_COLUMN_DATA, &data,
				-1);

			if (((data->type == GBF_TREE_NODE_UNKNOWN) || (data->type == GBF_TREE_NODE_SHORTCUT)) && (g_strcmp0 (target->name, data->name) == 0))
			{
				/* Find already existing node and replace it */
				if (expanded != NULL) *expanded = data->expanded;
				gbf_tree_data_free (data);
				
				data = gbf_tree_data_new_shortcut (target);
				gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
				    GBF_PROJECT_MODEL_COLUMN_DATA, data,
				    -1);
				break;
			}
		}
	}
	if (!valid)
	{
		/* check before_path */
		if ((before_path == NULL) ||
		    gtk_tree_path_get_depth (before_path) > 1 ||
		    gtk_tree_path_compare (before_path, root_path) > 0)
		{
			before_path = root_path;
		}
		
		/* get the tree iter for the row before which to insert the shortcut */
		if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &sibling, before_path)) {
			gtk_tree_path_free (root_path);
			return;
		}

		if (target->type != GBF_TREE_NODE_SHORTCUT)
		{
			data = gbf_tree_data_new_shortcut (target);
		}
		else
		{
			data = target;
		}
		gtk_tree_store_insert_before (GTK_TREE_STORE (model), &iter, NULL, &sibling);
		gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 
				    GBF_PROJECT_MODEL_COLUMN_DATA, data,
				    -1);
	}
	
	/* add sources */
	parent = gbf_tree_data_get_node (target);
	for (node = anjuta_project_node_first_child (parent); node; node = anjuta_project_node_next_sibling (node))
		gbf_project_model_add_node (model, node, &iter);

	gtk_tree_path_free (root_path);

	if (shortcut) *shortcut = iter;
}
Example #22
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);
	}
}
Example #23
0
/* 
 * watch expression has been changed
 */
static void on_watch_changed(GtkCellRendererText *renderer, gchar *path, gchar *new_text, gpointer user_data)
{
	/* get iterator to the changed row */
	GtkTreeIter  iter;
	GtkTreePath *tree_path = gtk_tree_path_new_from_string (path);
	gtk_tree_model_get_iter (
		 gtk_tree_view_get_model(GTK_TREE_VIEW(wtree)),
		 &iter,
		 tree_path);
	
	/* get oldvalue */
	gchar* oldvalue;
	gtk_tree_model_get (
		wmodel,
		&iter,
		W_NAME, &oldvalue,
       -1);
	gchar *internal = NULL;
		gtk_tree_model_get (
		wmodel,
		&iter,
		W_INTERNAL, &internal,
		-1);

	/* check if it is empty row */
	GtkTreePath *empty_path = wtree_empty_path();
	gboolean is_empty_row = !gtk_tree_path_compare (tree_path, empty_path);
	gtk_tree_path_free(empty_path);

   	gchar *striped = g_strstrip(g_strdup(new_text));
	if (!strlen(striped) &&
		!is_empty_row &&
		dialogs_show_question(_("Delete variable?")))
	{
		/* if new value is empty string on non-empty row
		 * offer to delete watch */
		gtk_tree_store_remove(wstore, &iter);
		if (DBS_STOPPED == debug_state)
			active_module->remove_watch(internal);

		config_set_debug_changed();
	}
	else if (strcmp(oldvalue, striped))
    {
		/* new value is non empty */

		/* insert new row if changing was the last empty row */
		GtkTreeIter newiter;
		if (is_empty_row)
			gtk_tree_store_insert_before(wstore, &newiter, NULL, &iter);
		
		/* set expression */
		variable_set_name_only(wstore, is_empty_row ? &newiter : &iter, striped);

		/* if debug is active - remove old watch and add new one */
		if (DBS_STOPPED == debug_state)
		{
			active_module->remove_watch(internal);
			variable *newvar = active_module->add_watch(striped);
			change_watch(GTK_TREE_VIEW(wtree), is_empty_row ? &newiter : &iter, newvar);
		}
		
		/* if new watch has been added - set selection to the new created row */
		if (is_empty_row)
		{
			GtkTreePath *_path = gtk_tree_model_get_path(wmodel, &newiter);
			GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(wtree));
			gtk_tree_selection_unselect_all(selection);
			gtk_tree_selection_select_path(selection, _path);
			gtk_tree_path_free(_path);
		}

		config_set_debug_changed();
	}
	
	/* free resources */
	gtk_tree_path_free(tree_path);
	g_free(oldvalue);
	g_free(internal);
	g_free(striped);
}
static void sort_method_ext_blist_sort(
	PurpleBlistNode *node, PurpleBuddyList *blist,
	GtkTreeIter group, GtkTreeIter *cur, GtkTreeIter *ret
) {
	GtkTreeIter tmp_iter;
	PidginBuddyList *gtkblist;

	gtkblist = PIDGIN_BLIST(purple_get_blist());
	

	if(!PURPLE_BLIST_NODE_IS_CONTACT(node) && !PURPLE_BLIST_NODE_IS_CHAT(node)) {
		sort_method_none(node, blist, group, cur, ret);
		return;	
	}

	/* Get first child of group. Insert immediately if group is empty. */
	if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(gtkblist->treemodel), &tmp_iter, &group)) {
		gtk_tree_store_insert(gtkblist->treemodel, ret, &group, 0);
		return;
	}

	/* Go trough all children */
	do {
		GValue val;
		PurpleBlistNode *n;
		gint cmp1, cmp2, cmp3;

		/* Retrieve a BlistNode from a TreeModelNode */
		val.g_type=0;
		gtk_tree_model_get_value(GTK_TREE_MODEL(gtkblist->treemodel), &tmp_iter, NODE_COLUMN, &val);
		n = g_value_get_pointer(&val);

		/* Comparing... */
		cmp1 = compare(
			purple_prefs_get_int(PLUGIN_PREFS_PREFIX "/sort1"),
			purple_prefs_get_bool(PLUGIN_PREFS_PREFIX "/sort1_reverse"),
			node, n
		);
		cmp2 = compare(
			purple_prefs_get_int(PLUGIN_PREFS_PREFIX "/sort2"),
			purple_prefs_get_bool(PLUGIN_PREFS_PREFIX "/sort2_reverse"),
			node, n
		);
		cmp3 = compare(
			purple_prefs_get_int(PLUGIN_PREFS_PREFIX "/sort3"),
			purple_prefs_get_bool(PLUGIN_PREFS_PREFIX "/sort3_reverse"),
			node, n
		);

		/* Insert node before the current? */
		/* TODO: refactor */
		if(cmp1 < 0 ||
			(cmp1 == 0 &&
				(cmp2 < 0 ||
					(cmp2 == 0 &&
						(cmp3 < 0 ||
							(cmp3 == 0 && node < n)))))) {
			if(cur == NULL) {
				gtk_tree_store_insert_before(gtkblist->treemodel, ret, &group, &tmp_iter);
			} else {
				gtk_tree_store_move_before(gtkblist->treemodel, cur, &tmp_iter);
				*ret = *cur;
			}
			return;
		}

		g_value_unset(&val);

		/* Get next node */
	} while(gtk_tree_model_iter_next(GTK_TREE_MODEL(gtkblist->treemodel), &tmp_iter));

	/* Insert at the end */
	if(cur == NULL) {
		gtk_tree_store_append(gtkblist->treemodel, ret, &group);
	} else {
		gtk_tree_store_move_before(gtkblist->treemodel, cur, NULL);
		*ret = *cur;
	}
	return;
	
}