/* Copyright (C) 2000-2003 Markus Lausser (sgop@users.sf.net) This is free software distributed under the terms of the GNU Public License. See the file COPYING for details. */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lopster.h" #include "global.h" #include "support.h" #include "dirselect.h" #include "scheme.h" #include "filetips.h" #include "file_tree.h" /* for matching lib-files in tooltips */ #include "utils.h" #define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \ ((row) + 1) + \ (clist)->voffset) #define COLUMN_LEFT_XPIXEL(clist, col) ((clist)->column[(col)].area.x + \ (clist)->hoffset) typedef struct { GtkWidget *widget; GtkWidget *tips; file_t *file; int x; int y; int timer; } file_tips_t; file_tips_t filetips; void filetips_init() { filetips.widget = NULL; filetips.tips = NULL; filetips.file = NULL; filetips.x = -1; filetips.y = -1; filetips.timer = 0; } static gint filetips_paint_window() { GtkStyle *style; gint y, baseline_skip, gap; char *text; file_t *file; GList* tlist; GList* dlist; if (!filetips.tips) return 0; if (!filetips.file) return 0; style = filetips.tips->style; file = filetips.file; gap = (style->font->ascent + style->font->descent) / 4; if (gap < 2) gap = 2; baseline_skip = style->font->ascent + style->font->descent + gap; gtk_paint_flat_box(style, filetips.tips->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, GTK_WIDGET(filetips.tips), "tooltip", 0, 0, -1, -1); y = style->font->ascent + 4; text = g_strdup_printf("Size: %lu", file->size); gtk_paint_string(style, filetips.tips->window, GTK_STATE_NORMAL, NULL, GTK_WIDGET(filetips.tips), "tooltip", 4, y, text); g_free(text); y += baseline_skip; text = g_strdup_printf("IP: %s", (!file->net) ? "unknown" : (ntoa(file->ip))); gtk_paint_string(style, filetips.tips->window, GTK_STATE_NORMAL, NULL, GTK_WIDGET(filetips.tips), "tooltip", 4, y, text); g_free(text); y += baseline_skip; /* [fvg] added tooltips containing library files with matching size */ tlist = file_tree_search_filesize(FILE_TREE(global.lib), filetips.file); if (g_list_length(tlist) > 1 || (tlist && tlist->data != filetips.file)) { text = g_strdup_printf(" Library files with same size: %d", g_list_length(tlist)); gtk_paint_string(style, filetips.tips->window, GTK_STATE_NORMAL, NULL, GTK_WIDGET(filetips.tips), "tooltip", 4, y, text); g_free(text); y += baseline_skip; for (dlist = tlist; dlist; dlist = dlist->next) { file_t* tfile = dlist->data; if (tfile == filetips.file) continue; text = g_strdup_printf("%s", tfile->shortname); gtk_paint_string(style, filetips.tips->window, GTK_STATE_NORMAL, NULL, GTK_WIDGET(filetips.tips), "tooltip", 4, y, text); g_free(text); y += baseline_skip; } } g_list_free(tlist); /* needed? yes! */ return 0; } void filetips_show_window() { if (!filetips.file) return; if (filetips.tips) return; filetips.tips = gtk_window_new(GTK_WINDOW_POPUP); gtk_widget_set_app_paintable(filetips.tips, TRUE); gtk_window_set_policy(GTK_WINDOW(filetips.tips), FALSE, FALSE, TRUE); gtk_widget_set_name(filetips.tips, "gtk-tooltips"); gtk_signal_connect_object(GTK_OBJECT(filetips.tips), "expose_event", GTK_SIGNAL_FUNC(filetips_paint_window), NULL); gtk_signal_connect_object(GTK_OBJECT(filetips.tips), "draw", GTK_SIGNAL_FUNC(filetips_paint_window), NULL); return; } int filetips_show_real(gpointer data ATTR_UNUSED) { GtkStyle *style; gint gap, x, y, w, h, lines, scr_w, scr_h, baseline_skip; int w2; char* text; GList* tlist; GList* dlist; if (filetips.timer) { gtk_timeout_remove(filetips.timer); filetips.timer = 0; } filetips_show_window(); gtk_widget_ensure_style(filetips.tips); style = filetips.tips->style; scr_w = gdk_screen_width(); scr_h = gdk_screen_height(); gap = (style->font->ascent + style->font->descent) / 4; if (gap < 2) gap = 2; baseline_skip = style->font->ascent + style->font->descent + gap; w = 0; lines = 0; text = g_strdup_printf("Size: %lu", filetips.file->size); w = gdk_string_width(style->font, text); lines++; g_free(text); text = g_strdup_printf("IP: %s", (!filetips.file->net) ? "local" : (ntoa(filetips.file->ip))); lines++; w2 = gdk_string_width(style->font, text); g_free(text); if (w2 > w) w = w2; /* [fvg] added tooltips containing library files with matching size */ tlist = file_tree_search_filesize(FILE_TREE(global.lib), filetips.file); if (g_list_length(tlist) > 1 || (tlist && tlist->data != filetips.file)) { text = g_strdup_printf(" Library files with same size: %d", g_list_length(tlist)); lines++; w2 = gdk_string_width(style->font, text); g_free(text); if (w2 > w) w = w2; for (dlist = tlist; dlist; dlist = dlist->next) { file_t* tfile = dlist->data; if (tfile == filetips.file) continue; text = g_strdup_printf("%s", tfile->shortname); lines++; w2 = gdk_string_width(style->font, text); if (w2 > w) w = w2; g_free(text); } } g_list_free(tlist); /* needed? yes again.. */ w += 10; h = 8 - gap; h += lines * baseline_skip; if (h < 8) h = 8; y = filetips.y; x = filetips.x; x -= w/2; y += 10; if (x + w > scr_w) x = scr_w - w; else if (x < 0) x = 0; if (y + h > scr_h) y = scr_h - h; else if (y < 0) y = 0; gtk_widget_set_usize(filetips.tips, w, h); gtk_widget_popup(filetips.tips, x, y); return 0; } void filetips_show(GtkWidget* temp, int x, int y, file_t* file) { file_t* old_file = filetips.file; if (!global.options.filetips) return; filetips.x = x; filetips.y = y; filetips.file = file; filetips.widget = temp; if (filetips.tips && old_file != file) { // delete tips if we change to another file gtk_widget_destroy(filetips.tips); filetips.tips = NULL; } else if (filetips.tips && old_file == file) { // keep tips if we have the same file } else if (filetips.timer && !file) { // remove timer, if we change to no file gtk_timeout_remove(filetips.timer); filetips.timer = 0; } else if (!file) { // do nothing if no file and no tips and no timer } else if (old_file != file) { // reset timer if we change the file if (filetips.timer) gtk_timeout_remove(filetips.timer); filetips.timer = gtk_timeout_add(500, filetips_show_real, NULL); } else if (filetips.timer) { // keep the timer running, if we have the same file } else { filetips.timer = gtk_timeout_add(500, filetips_show_real, NULL); } }