Esempio n. 1
0
void print_tree_view_list_init_tree_view_data ( GtkTreeView *tree_view )
{
    GList *list;
    GList *list_tmp;
    gint col_width = 0;
    gint i = 0;

    devel_debug (NULL);

    /* get the number of columns */
    list = gtk_tree_view_get_columns ( tree_view );
    nbre_cols = g_list_length ( list );

    tree_view_cols_width = g_malloc0 ( nbre_cols * sizeof ( gint ) );
    alignment = g_malloc0 ( nbre_cols * sizeof ( gint ) );

    list_tmp = list;
    while ( list_tmp )
    {
        GtkTreeViewColumn *col;

        col = list_tmp -> data;
        col_width += gtk_tree_view_column_get_width ( col );

        list_tmp  = list_tmp -> next;
    }

    list_tmp = list;
    while ( list_tmp )
    {
        GtkTreeViewColumn *col;
        gfloat number;

        col = ( GtkTreeViewColumn * ) list_tmp -> data;
        tree_view_cols_width[i] = ( gtk_tree_view_column_get_width ( col ) * 100 ) / col_width + 1;

        number = gtk_tree_view_column_get_alignment ( col );
        if ( number == 0.0 )
            alignment[i] = PANGO_ALIGN_LEFT;
        else if ( number == 1.0 )
            alignment[i] = PANGO_ALIGN_RIGHT;
        else
            alignment[i] = PANGO_ALIGN_CENTER;

        list_tmp  = list_tmp -> next;
        i++;
    }

    g_list_free ( list );
}
Esempio n. 2
0
static gboolean do_motion_event(GtkWidget *tv, GdkEventMotion *e,
				GObject *cel)
{
	GObject *siglist;
	gint x;
	gint offset;
	GArray *data;
	guint nsamples;
	GtkTreeViewColumn *col;
	gint width;
	gdouble scale, *rscale;
	GtkAdjustment *adj;

	x = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tv), "motion-x"));
	g_object_set_data(G_OBJECT(tv), "motion-x", GINT_TO_POINTER((gint)e->x));
	adj = g_object_get_data(G_OBJECT(tv), "hadj");

	siglist = G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(tv)));
	data = g_object_get_data(siglist, "sampledata");
	rscale = g_object_get_data(siglist, "rscale");
	nsamples = (data->len / g_array_get_element_size(data)) - 1;
	col = g_object_get_data(G_OBJECT(tv), "signalcol");
	width = gtk_tree_view_column_get_width(col);

	g_object_get(cel, "offset", &offset, "scale", &scale, NULL);
	offset += x - e->x;
	if (offset < 0)
		offset = 0;
	if (offset > nsamples * *rscale - width)
		offset = nsamples * *rscale - width;

	gtk_adjustment_set_value(adj, offset);

	return TRUE;
}
Esempio n. 3
0
void library_view_destroy(library_view_t* view)
{
  // first store the column widths
  playlist_column_enum e;
  for(e = PLAYLIST_MODEL_COL_NR; e < PLAYLIST_MODEL_N_COLUMNS; ++e) {
    char path [500];
    sprintf(path, "library.column.%s.width", column_id(e));
    int w = gtk_tree_view_column_get_width(view->cols[e]);
    log_debug3("%s = %d", path, w);
    el_config_set_int(btb_config(view->btb), path, w);
    g_object_unref(view->cols[e]);
  }
  mc_free(view->cols);
  
  if (view->run_timeout) {
    log_error("timeout has not been stopped before destroying!");
    library_view_stop_info_updater(view);
  }
  
  playlist_model_destroy(view->playlist_model);
  string_model_destroy(view->genre_model);
  string_model_destroy(view->artist_model);
  string_model_destroy(view->album_model);
  playlists_model_destroy(view->playlists_model);
  
  if (view->current_lyric_track_id != NULL) { 
    mc_free(view->current_lyric_track_id);
  }
  
  mc_free(view);
}
Esempio n. 4
0
static gboolean
bidding_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode,
		GtkTooltip *tooltip, window_board_t *bidding_store)
{
	if (keyboard_mode) {
		printf ("FIXME: keyboard usage\n");
		return FALSE;
	}
	GtkTreeIter iter;
	gboolean ret = gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget),
			&x, &y, keyboard_mode, NULL, NULL, &iter);
	if (!ret) {
		gtk_tooltip_set_text (tooltip, NULL);
		// TODO: don't show anything at all, or something interesting
		// y<0 -> headings
		return TRUE;
	}

	int i;
	int width = 0;
	for (i = 0; i < 4; i++) {
		width += gtk_tree_view_column_get_width (win->bidding_column[i]);
		// TODO: cache this, or use gtk_tree_view_get_path_at_pos
		if (x < width)
			break;
	}
	assert (i < 4);

	gchar *alert;
	gtk_tree_model_get (GTK_TREE_MODEL (win->bidding_store), &iter, 2 * i + 1, &alert, -1);
	gtk_tooltip_set_markup (tooltip, !alert || *alert ? alert : _("(no explanation)"));
	return TRUE;
}
Esempio n. 5
0
void trace_view_data_func(GtkTreeViewColumn *column, GtkCellRenderer *renderer,
			  GtkTreeModel *model, GtkTreeIter *iter,
			  gpointer data)
{
	long col_num = (long)data;
	int str_len, label_len;
	gchar *text, *str;
	int new_w, x_pad;
	GValue val = {0};
	GtkWidget *view;

	PangoFontDescription *pfd;
	PangoLayout *playout;

	/* Put the text in the renderer. */
	gtk_tree_model_get_value(model, iter, col_num, &val);
	g_object_set_property(G_OBJECT(renderer), "text", &val);

	g_object_get(G_OBJECT(renderer),
			"text", &text,
			"font-desc", &pfd,
			NULL);

	if (!text)
		goto out;

	/* Make sure there is enough room to render the column label. */
	str = text;
	str_len = strlen(str);
	label_len = strlen(col_labels[col_num]);
	if (label_len > str_len) {
		str = col_labels[col_num];
		str_len = label_len;
	}

	/* Don't bother with pango unless we have more chars than the max. */
	if (str_len > col_chars[col_num]) {
		col_chars[col_num] = str_len;

		view = GTK_WIDGET(gtk_tree_view_column_get_tree_view(column));
		playout = gtk_widget_create_pango_layout(GTK_WIDGET(view), str);
		pango_layout_set_font_description(playout, pfd);
		pango_layout_get_pixel_size(playout, &new_w, NULL);
		gtk_cell_renderer_get_padding(renderer, &x_pad, NULL);
		/* +10 to avoid another adjustment for one char */
		new_w += 2*x_pad + 10;
		g_object_unref(playout);

		if (new_w > gtk_tree_view_column_get_width(column))
			gtk_tree_view_column_set_fixed_width(column, new_w);
	}

	g_free(text);
 out:
	pango_font_description_free(pfd);
	g_value_unset(&val);
}
Esempio n. 6
0
/**
 * gpk_log_treeview_size_allocate_cb:
 **/
static void
gpk_log_treeview_size_allocate_cb (GtkWidget *widget, GtkAllocation *allocation, GtkCellRenderer *cell)
{
	GtkTreeViewColumn *column;
	gint width;

	column = gtk_tree_view_get_column (GTK_TREE_VIEW(widget), 2);
	width = gtk_tree_view_column_get_width (column);
	g_object_set (cell, "wrap-width", width - 10, NULL);
}
Esempio n. 7
0
gint
gnc_reconcile_view_get_column_width (GNCReconcileView *view, gint column)
{
    GNCQueryView      *qview = GNC_QUERY_VIEW (view);
    GtkTreeViewColumn *col;

    //allow for pointer model column at column 0
    col = gtk_tree_view_get_column (GTK_TREE_VIEW (qview), (column - 1));
    return  gtk_tree_view_column_get_width (col);
}
Esempio n. 8
0
static gboolean
on_item_list_view_button_press_event (GtkWidget *treeview, GdkEventButton *event, gpointer user_data)
{
	ItemListView		*ilv = ITEM_LIST_VIEW (user_data);
	GtkTreePath		*path;
	GtkTreeIter		iter;
	GtkTreeViewColumn	*column;
	itemPtr			item = NULL;
	gboolean		result = FALSE;
	
	if (event->type != GDK_BUTTON_PRESS)
		return FALSE;

	/* avoid handling header clicks */
	if (event->window != gtk_tree_view_get_bin_window (ilv->priv->treeview))
		return FALSE;

	if (!gtk_tree_view_get_path_at_pos (ilv->priv->treeview, (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL))
		return FALSE;

	if (gtk_tree_model_get_iter (gtk_tree_view_get_model (ilv->priv->treeview), &iter, path))
		item = item_load (item_list_view_iter_to_id (ilv, &iter));
		
	gtk_tree_path_free (path);
	
	if (item) {
		GdkEventButton *eb = (GdkEventButton*)event; 
		switch (eb->button) {
			case 1:
				column = gtk_tree_view_get_column (ilv->priv->treeview, 0);
				if (column) {
					/* Allow flag toggling when left clicking in the flagging column.
					   We depend on the fact that the state column is the first!!! */
					if (event->x <= gtk_tree_view_column_get_width (column)) {
						itemlist_toggle_flag (item);
						result = TRUE;
					}
				}
				break;
			case 2:
				/* Middle mouse click toggles read status... */
				itemlist_toggle_read_status (item);
				result = TRUE;
				break;
			case 3:
				item_list_view_select (ilv, item);
				ui_popup_item_menu (item, eb->button, eb->time);
				result = TRUE;
				break;
		}
		item_unload (item);
	}
		
	return result;
}
Esempio n. 9
0
static void list_upcoming_destroy(GtkTreeView *treeview, gpointer user_data)
{
GtkTreeViewColumn  *column;

	DB( g_print ("\n[list_upcoming] destroy\n") );

	//todo: unsafe to use direct column index
	column = gtk_tree_view_get_column(treeview, 2);
	if( column )
	{
		PREFS->pnl_upc_col_pay_width = gtk_tree_view_column_get_width(column);
	}
	
	column = gtk_tree_view_get_column(treeview, 3);
	if( column )
	{
		PREFS->pnl_upc_col_mem_width = gtk_tree_view_column_get_width(column);
	}

}
Esempio n. 10
0
G_MODULE_EXPORT void
queue_list_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, GtkCellRenderer *cell)
{
    GtkTreeViewColumn *column;
    gint width;
    
    column = gtk_tree_view_get_column (GTK_TREE_VIEW(widget), 0);
    width = gtk_tree_view_column_get_width(column);
    g_debug("col width %d alloc width %d", width, allocation->width);
    // Set new wrap-width.  Shave a little off to accomidate the icons
    // that share this column.
    if (width >= 564) // Don't allow below a certain size
        g_object_set(cell, "wrap-width", width-70, NULL);
}
Esempio n. 11
0
int gTree::columnWidth(int ind)
{
	GtkTreeViewColumn *col = gt_tree_view_find_column(GTK_TREE_VIEW(widget), ind);
	int w;
	
	if (!col) 
		return 0;
	
	w = gtk_tree_view_column_get_width(col);
	if (w == 0)
		w = gtk_tree_view_column_get_fixed_width(col);
	
	return w;
}
Esempio n. 12
0
static void library_view_col_width_set(GtkTreeViewColumn* col, GParamSpec* spec, library_view_t* view)
{
  //log_debug2("changing %d", view->column_layout_changing);
  if (view->column_layout_changing) {
    return;
  }

  long long hash = playlist_model_tracks_hash(view->playlist_model);

  int i;
  const char* name = g_object_get_data(G_OBJECT(col), "column_id"); 
  for(i = 0; strcmp(name, column_id(i)) != 0; ++i);
  //log_debug4("i = %d, name = %s, colid = %s", i, name, column_id(i));
  
  if (column_id(i) != NULL) {
    char cfgitem[200];
    sprintf(cfgitem,"library.cols.hash_%lld.%s.width", hash, column_id(i));
    int width = gtk_tree_view_column_get_width(view->cols[i]);
    
    el_config_set_int(btb_config(view->btb), cfgitem, width);
  }
}
Esempio n. 13
0
static gboolean
save_column_width (gpointer data)
{
    gint width;
    gchar *key;
    int id;
    GSettings *settings;

    settings = g_settings_get_child (G_SETTINGS (data), "disktreenew");
    id = gtk_tree_view_column_get_sort_column_id (current_column);
    width = gtk_tree_view_column_get_width (current_column);

    key = g_strdup_printf ("col-%d-width", id);
    g_settings_set_int(settings, key, width);
    g_free (key);

    if (timeout_id) {
        g_source_remove (timeout_id);
        timeout_id = 0;
    }

    return FALSE;
}
Esempio n. 14
0
static gboolean
on_item_list_view_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, GtkTreeViewColumn *headline_column) 
{
	GtkTreeView *view = GTK_TREE_VIEW (widget);
	GtkTreeModel *model; GtkTreePath *path; GtkTreeIter iter;
	gboolean ret = FALSE;

	if (gtk_tree_view_get_tooltip_context (view, &x, &y, keyboard_mode, &model, &path, &iter)) {
		GtkTreeViewColumn *column;
		gint bx, by;
		gtk_tree_view_convert_widget_to_bin_window_coords (view, x, y, &bx, &by);
		gtk_tree_view_get_path_at_pos (view, x, y, NULL, &column, NULL, NULL);

		if (column == headline_column) {
			GtkCellRenderer *cell;
			GList *renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
			cell = GTK_CELL_RENDERER (renderers->data);
			g_list_free (renderers);

			gchar *text;
			gint weight;
			gtk_tree_model_get (model, &iter, IS_LABEL, &text, ITEMSTORE_UNREAD, &weight, -1);

			gint full_width = get_cell_renderer_width (widget, cell, text, weight);
			gint column_width = gtk_tree_view_column_get_width (column);
			if (full_width > column_width) {
				gtk_tooltip_set_text (tooltip, text);
				ret = TRUE;
			}
			g_free (text);
		}

		gtk_tree_view_set_tooltip_row (view, tooltip, path);
		gtk_tree_path_free (path);
	}
	return ret;
}
Esempio n. 15
0
/**
 * called when change the size of the columns,
 * save the percent and change the size of the form according the new size
 *
 * \param tree_view
 * \param allocation
 *
 * \return FALSE
 * */
gboolean gsb_form_config_change_column_size ( GtkWidget *tree_view,
					      GtkAllocation *allocation,
					      gpointer null )
{
    gint column;
    gint account_number;
    gint i;

    if ( !GTK_WIDGET_REALIZED (tree_view))
	return FALSE;

    account_number = gsb_account_get_combo_account_number ( accounts_combobox );

    for (i=0 ; i<gsb_data_account_get_accounts_amount () ; i++)
    {
	    for ( column=0 ; column < gsb_data_form_get_nb_columns (i) ; column++ )
	    {
		gint size_column;

		size_column = gtk_tree_view_column_get_width ( gtk_tree_view_get_column ( GTK_TREE_VIEW ( tree_view ),
											  column ));
		gsb_data_form_set_width_column ( i,
						 column,
						 size_column * 100 / allocation -> width );
	    }
    }

    gsb_file_set_modified ( TRUE );

    /* update the form if needed */
	saved_allocation_size = 0;
	gsb_form_allocate_size ( NULL, &(form_transaction_part -> allocation), NULL );
    gsb_form_create_widgets ();

    return FALSE;
}
Esempio n. 16
0
static gboolean
gnc_reconcile_view_tooltip_cb (GNCQueryView *qview, gint x, gint y,
    gboolean keyboard_mode, GtkTooltip *tooltip, gpointer *user_data)
{
    GtkTreeModel* model;
    GtkTreeIter iter;

    // If the Description is longer than can be display, show it in a tooltip
    if (gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (qview), &x, &y, keyboard_mode, &model, NULL, &iter))
    {
        GtkTreeViewColumn *col;
        GList *cols;
        gint col_pos, col_width;
        gchar* desc_text = NULL;

        /* Are we in keyboard tooltip mode, displays tooltip below/above treeview CTRL+F1 */
        if (keyboard_mode == FALSE)
        {
            if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (qview), x, y, NULL, &col, NULL, NULL) == FALSE)
                return FALSE;
        }
        else
            gtk_tree_view_get_cursor (GTK_TREE_VIEW (qview), NULL, &col);

        cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (qview));
        col_width = gtk_tree_view_column_get_width (col);
        col_pos = g_list_index (cols, col);
        g_list_free (cols);

        /* If column is not description, do not show tooltip */
        if (col_pos != (REC_DESC - 1)) // allow for the pointer model column at 0
            return FALSE;

        gtk_tree_model_get (model, &iter, REC_DESC, &desc_text, -1);

        if (desc_text)
        {
            PangoLayout* layout;
            gint text_width;
            gint root_x, root_y;
            gint cur_x, cur_y;

            layout = gtk_widget_create_pango_layout (GTK_WIDGET (qview), desc_text);
            pango_layout_get_pixel_size (layout, &text_width, NULL);
            g_object_unref (layout);

            /* If text_width + 10 <= column_width, do not show tooltip */
            if ((text_width + 10) <= col_width)
            {
                g_free (desc_text);
                return FALSE;
            }

            if (keyboard_mode == FALSE)
            {
#if GTK_CHECK_VERSION(3,20,0)
                GdkSeat *seat;
#else
                GdkDeviceManager *device_manager;
#endif
                GdkDevice *pointer;
                GtkWindow *tip_win = NULL;
                GdkWindow *parent_window;
                GList *win_list, *node;

                parent_window = gtk_widget_get_parent_window (GTK_WIDGET (qview));

#if GTK_CHECK_VERSION(3,20,0)
                seat = gdk_display_get_default_seat (gdk_window_get_display (parent_window));
                pointer = gdk_seat_get_pointer (seat);
#else
                device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent_window));
                pointer = gdk_device_manager_get_client_pointer (device_manager);
#endif
                gdk_window_get_device_position (parent_window, pointer, &cur_x, &cur_y, NULL);

                gdk_window_get_origin (parent_window, &root_x, &root_y);

                 /* Get a list of toplevel windows */
                win_list = gtk_window_list_toplevels ();

                /* Look for the gtk-tooltip window, we do this as gtk_widget_get_tooltip_window
                   does not seem to work for the default tooltip window, custom yes */
                for (node = win_list;  node != NULL;  node = node->next)
                {
                    if (g_strcmp0 (gtk_widget_get_name (node->data), "gtk-tooltip") == 0)
                    tip_win = node->data;
                }
                g_list_free (win_list);

                gtk_tooltip_set_text (tooltip, desc_text);

                if (GTK_IS_WINDOW (tip_win))
                {
#if GTK_CHECK_VERSION(3,22,0)
                    GdkMonitor *mon;
#else
                    GdkScreen *screen;
                    gint monitor_num;
#endif
                    GdkRectangle monitor;
                    GtkRequisition requisition;
                    gint x, y;

                    gtk_widget_get_preferred_size (GTK_WIDGET (tip_win), &requisition, NULL);

                    x = root_x + cur_x + 10;
                    y = root_y + cur_y + 10;

#if GTK_CHECK_VERSION(3,22,0)
                    mon = gdk_display_get_monitor_at_point (gdk_display_get_default(), x, y);
                    gdk_monitor_get_geometry (mon, &monitor);
#else
                    screen = gtk_widget_get_screen (GTK_WIDGET (qview));
                    monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
                    gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
#endif
                    if (x + requisition.width > monitor.x + monitor.width)
                        x -= x - (monitor.x + monitor.width) + requisition.width;
                    else if (x < monitor.x)
                        x = monitor.x;

                    if (y + requisition.height > monitor.y + monitor.height)
                        y -= y - (monitor.y + monitor.height) + requisition.height;

                    gtk_window_move (tip_win, x, y);
                }
            }
            gtk_tooltip_set_text (tooltip, desc_text);
            g_free (desc_text);
            return TRUE;
        }
    }
    return FALSE;
}
Esempio n. 17
0
void sigview_zoom(GtkWidget *sigview, gdouble zoom, gint offset)
{
	GObject *siglist;
	GtkTreeViewColumn *col;
	GtkCellRendererSignal *cel;
	GtkAdjustment *adj;
	/* data and scale refer to summary */
	GArray *data;
	gdouble scale;
	/* rdata and rscale refer to complete data */
	GArray *rdata;
	gdouble *rscale;
	gint ofs;
	gint width;
	guint nsamples;

	/* This is so that sigview_zoom() may be called with pointer
	 * to the GtkTreeView or containing GtkScrolledWindow, as is the
	 * case when called from outside this module.
	 */
	if (GTK_IS_SCROLLED_WINDOW(sigview))
		sigview = gtk_bin_get_child(GTK_BIN(sigview));

	g_return_if_fail(GTK_IS_TREE_VIEW(sigview));

	col = g_object_get_data(G_OBJECT(sigview), "signalcol");
	adj = g_object_get_data(G_OBJECT(sigview), "hadj");
	width = gtk_tree_view_column_get_width(col);

	siglist = G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(sigview)));
	rdata = g_object_get_data(siglist, "sampledata");
	rscale = g_object_get_data(siglist, "rscale");
	if (!rscale) {
		rscale = g_malloc(sizeof(rscale));
		*rscale = 1;
		g_object_set_data(siglist, "rscale", rscale);
	}
	data = g_object_get_data(siglist, "summarydata");
	if (!rdata)
		return;
	if (!data)
		data = rdata;
	nsamples = (rdata->len / g_array_get_element_size(rdata)) - 1;
	if ((fabs(*rscale - (double)width/nsamples) < 1e-12) && (zoom < 1))
		return;

	cel = g_object_get_data(G_OBJECT(sigview), "signalcel");
	g_object_get(cel, "scale", &scale, "offset", &ofs, NULL);

	ofs += offset;
		
	scale *= zoom;
	*rscale *= zoom;
	ofs *= zoom;

	ofs -= offset;

	if (ofs < 0)
		ofs = 0;

	if (*rscale < (double)width/nsamples) {
		*rscale = (double)width/nsamples;
		scale = *rscale;
		if (data && (data != rdata))
			g_array_free(data, TRUE);
		data = rdata;
	}

	if (ofs > nsamples * *rscale - width)
		ofs = nsamples * *rscale - width;

	gtk_adjustment_configure(adj, ofs, 0, nsamples * *rscale, 
			width/16, width/2, width);

	if (scale < 0.125) {
		g_object_set_data(siglist,
			"summarydata", summarize(data, &scale));
		if (data && (data != rdata))
			g_array_free(data, TRUE);
	} else if ((scale > 1) && (*rscale < 1)) {
		scale = *rscale;
		g_object_set_data(siglist,
			"summarydata", summarize(rdata, &scale));
		if (data && (data != rdata))
			g_array_free(data, TRUE);
	}

	g_object_set(cel, "scale", scale, "offset", ofs, NULL);
	gtk_widget_queue_draw(GTK_WIDGET(sigview));
}
Esempio n. 18
0
static gboolean
gnc_reconcile_view_tooltip_cb (GNCQueryView *qview, gint x, gint y,
	gboolean keyboard_mode, GtkTooltip *tooltip, gpointer *user_data)
{
    GtkTreeModel* model;
    GtkTreeIter iter;

    if (gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (qview), &x, &y, keyboard_mode, &model, NULL, &iter))
    {
        GtkTreeViewColumn *col;
        GList *cols;
        gint col_pos, col_width;
	gchar* desc_text = NULL;

        /* Are we in keyboard tooltip mode, CTRL+F1 */
        if (keyboard_mode == FALSE)
        {
            if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (qview), x, y, NULL, &col, NULL, NULL) == FALSE)
                return FALSE;
        }
        else
            gtk_tree_view_get_cursor (GTK_TREE_VIEW (qview), NULL, &col);

        cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (qview));
        col_width = gtk_tree_view_column_get_width (col);
        col_pos = g_list_index (cols, col);
        g_list_free (cols);

        /* If column is not description, do not show tooltip */
        if (col_pos != 2)
            return FALSE;

        gtk_tree_model_get (model, &iter, 3, &desc_text, -1);

        if (desc_text)
        {
            PangoLayout* layout;
            gint text_width;
            gint root_x, root_y;
            gint cur_x, cur_y;

            layout = gtk_widget_create_pango_layout (GTK_WIDGET (qview), desc_text);
            pango_layout_get_pixel_size (layout, &text_width, NULL);
            g_object_unref (layout);

            /* If text_width + 10 <= column_width, do not show tooltip */
            if ((text_width + 10) <= col_width)
            {
                g_free (desc_text);
                return FALSE;
            }

            if (keyboard_mode == FALSE)
            {
                GdkScreen *screen;
                GtkWindow *tip_win = NULL;
                GdkWindow *parent_window, *temp_window;
                GList *win_list, *node;

                parent_window = gtk_widget_get_parent_window (GTK_WIDGET (qview));
                temp_window = gdk_window_get_pointer (parent_window, &cur_x, &cur_y, NULL);
                gdk_window_get_origin (parent_window, &root_x, &root_y);

                screen = gtk_widget_get_screen (GTK_WIDGET (qview));

                /* Get a list of toplevel windows */
                win_list = gtk_window_list_toplevels ();

                /* Look for the gtk-tooltip window, we do this as gtk_widget_get_tooltip_window
                   does not seem to work for the default tooltip window, custom yes */
                for (node = win_list;  node != NULL;  node = node->next)
                {
                    if (g_strcmp0 (gtk_widget_get_name (node->data), "gtk-tooltip") == 0)
                    tip_win = node->data;
                }
                g_list_free (win_list);

	        gtk_tooltip_set_text (tooltip, desc_text);

                if (GTK_IS_WINDOW (tip_win))
                {
                    GdkRectangle monitor;
                    GtkRequisition requisition;
                    gint monitor_num;
                    gint x, y;

                    gtk_widget_size_request (GTK_WIDGET (tip_win), &requisition);

                    x = root_x + cur_x + 10;
                    y = root_y + cur_y + 10;

                    monitor_num = gdk_screen_get_monitor_at_point (screen, x, y);
                    gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);

                    if (x + requisition.width > monitor.x + monitor.width)
                        x -= x - (monitor.x + monitor.width) + requisition.width;
                    else if (x < monitor.x)
                        x = monitor.x;

                    if (y + requisition.height > monitor.y + monitor.height)
                        y -= y - (monitor.y + monitor.height) + requisition.height;

                    gtk_window_move (tip_win, x, y);
                }
            }
	    gtk_tooltip_set_text (tooltip, desc_text);
            g_free (desc_text);
	    return TRUE;
        }
    }
    return FALSE;
}
void trg_tree_view_persist(TrgTreeView * tv, guint flags)
{
    JsonObject *props = trg_prefs_get_tree_view_props(tv);
    GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv));
    GList *cols, *li;
    JsonArray *widths, *columns;
    gint sort_column_id;
    GtkSortType sort_type;

    if (flags & TRG_TREE_VIEW_PERSIST_SORT) {
        gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE
                                             ((flags &
                                               TRG_TREE_VIEW_SORTABLE_PARENT)
                                              ?
                                              gtk_tree_model_filter_get_model
                                              (GTK_TREE_MODEL_FILTER
                                               (model)) : model),
                                             &sort_column_id, &sort_type);

        if (json_object_has_member(props, TRG_PREFS_KEY_TV_SORT_COL))
            json_object_remove_member(props, TRG_PREFS_KEY_TV_SORT_COL);

        if (json_object_has_member(props, TRG_PREFS_KEY_TV_SORT_TYPE))
            json_object_remove_member(props, TRG_PREFS_KEY_TV_SORT_TYPE);

        json_object_set_int_member(props, TRG_PREFS_KEY_TV_SORT_COL,
                                   (gint64) sort_column_id);
        json_object_set_int_member(props, TRG_PREFS_KEY_TV_SORT_TYPE,
                                   (gint64) sort_type);
    }

    if (flags & TRG_TREE_VIEW_PERSIST_LAYOUT) {
        cols = gtk_tree_view_get_columns(GTK_TREE_VIEW(tv));

        if (json_object_has_member(props, TRG_PREFS_KEY_TV_WIDTHS))
            json_object_remove_member(props, TRG_PREFS_KEY_TV_WIDTHS);

        widths = json_array_new();
        json_object_set_array_member(props, TRG_PREFS_KEY_TV_WIDTHS,
                                     widths);

        if (json_object_has_member(props, TRG_PREFS_KEY_TV_COLUMNS))
            json_object_remove_member(props, TRG_PREFS_KEY_TV_COLUMNS);

        columns = json_array_new();
        json_object_set_array_member(props, TRG_PREFS_KEY_TV_COLUMNS,
                                     columns);

        for (li = cols; li; li = g_list_next(li)) {
            GtkTreeViewColumn *col = (GtkTreeViewColumn *) li->data;
            trg_column_description *desc =
                g_object_get_data(G_OBJECT(li->data),
                                  GDATA_KEY_COLUMN_DESC);

            json_array_add_string_element(columns, desc->id);
            json_array_add_int_element(widths,
                                       gtk_tree_view_column_get_width
                                       (col));
        }

        g_list_free(cols);
    }
}