/* GKrellM-trayicons
Author, current maintainer:
Tomas Styblo <tripie@cpan.org>
Copyright (C) 2003
This program is free software which I release under the GNU General Public
License. You may redistribute and/or modify this program under the terms
of that license as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
To get a copy of the GNU General Puplic License, write to the
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <gkrellm2/gkrellm.h>
#include <utime.h>
#include <dirent.h>
#include <errno.h>
#include <math.h>
#define xstr(s) str(s)
#define str(s) #s
#define MY_BUFLEN 1024
typedef struct
{
gchar *activation_file;
gchar *icon_active_file;
gchar *icon_inactive_file;
gchar *left_click_active_command;
gchar *left_click_inactive_command;
gboolean blink;
gboolean popup;
gboolean activated;
gboolean icon_state;
time_t activation_file_mtime;
gint x;
gint y;
GkrellmDecalbutton *but;
/*
GString *buf;
*/
} item_t;
enum
{
ACTIVATION_FILE_COLUMN,
ICON_ACTIVE_PIXBUF_COLUMN,
ICON_ACTIVE_FILE_COLUMN,
ICON_INACTIVE_PIXBUF_COLUMN,
ICON_INACTIVE_FILE_COLUMN,
LEFT_CLICK_ACTIVE_COMMAND_COLUMN,
LEFT_CLICK_INACTIVE_COMMAND_COLUMN,
BLINK_COLUMN,
POPUP_COLUMN,
N_COLUMNS
};
#ifndef VERSION
#error "VERSION is not defined."
#endif
#define NOTICE_SEPARATOR "\n- - - - - - - - - - - -\n"
#define TREE_SIZE_PADDING 300
#define TREE_SIZE_MAX 600
#define TREE_HEIGHT 150
static GkrellmMonitor *monitor;
static GArray *trayicons;
static GkrellmPanel *panel;
static gint icon_size = 16; /* the default */
static gint icon_padding = 4; /* the default */
static gint popup_timeout = 5; /* the default */
static GtkWidget *trayicons_vbox;
static GtkWidget *win_bubble;
static GdkColor popup_fg_color = { 0, 0xFFFF, 0xFFFF, 0xFFFF };
static GdkColor popup_bg_color = { 0, 0xFFFF, 0x0000, 0x0000 };
static GtkWidget *active_popup = NULL;
static gint active_popup_icon;
static gint active_timeout = 0;
static gchar *active_popup_str = NULL;
void setup_trayicons(gint first_create);
static GdkPixbuf *get_pixbuf(const gchar *filename, gint size);
static void draw_icon(gint i, gboolean state);
static void deactivate_icon(gint icon);
static void destroy_bubble() {
if (active_popup) {
gtk_widget_destroy(active_popup);
active_popup = NULL;
g_free(active_popup_str);
active_popup_str = NULL;
}
if (active_timeout) {
gtk_timeout_remove(active_timeout);
}
}
static gint bubble_timeout(gpointer data)
{
destroy_bubble();
return 0; /* cancel the timeout */
}
static gboolean bubble_button_press(GtkWidget *widget,
GdkEventButton *event, gpointer data)
{
destroy_bubble();
deactivate_icon(active_popup_icon);
return TRUE;
}
static gint bubble_paint_window(gchar *str)
{
gtk_paint_flat_box(win_bubble->style, win_bubble->window,
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
NULL, GTK_WIDGET(win_bubble), "tooltip",
0, 0, -1, -1);
return FALSE;
}
static void create_bubble(gchar *str, gint icon)
{
GtkWidget *label;
GtkRequisition requisition;
GtkWidget *widget;
GtkStyle *style;
gint x, y, w, h, scr_w, scr_h;
GdkScreen *screen;
if (active_popup) {
gchar *oldstr = g_strdup(active_popup_str);
destroy_bubble();
active_popup_str = g_strconcat(oldstr, NOTICE_SEPARATOR, str, NULL);
g_free(oldstr);
}
else {
active_popup_str = g_strdup(str);
}
win_bubble = gtk_window_new(GTK_WINDOW_POPUP);
active_popup = win_bubble;
active_popup_icon = icon;
gtk_widget_set_app_paintable(win_bubble, TRUE);
gtk_window_set_resizable(GTK_WINDOW(win_bubble), FALSE);
gtk_widget_set_name(win_bubble, "gkrellm-trayicons-buuble");
gtk_container_set_border_width(GTK_CONTAINER(win_bubble), 4);
g_signal_connect_swapped(win_bubble, "expose_event",
G_CALLBACK(bubble_paint_window), NULL);
label = gtk_label_new(NULL);
gtk_widget_set_events (win_bubble, GDK_BUTTON_PRESS_MASK);
g_signal_connect(GTK_OBJECT(win_bubble), "button-press-event",
G_CALLBACK(bubble_button_press), NULL);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &popup_fg_color);
gtk_widget_modify_bg(win_bubble, GTK_STATE_NORMAL, &popup_bg_color);
gtk_widget_show(label);
gtk_container_add(GTK_CONTAINER(win_bubble), label);
g_signal_connect (win_bubble, "destroy",
G_CALLBACK(gtk_widget_destroyed),
&win_bubble);
gtk_widget_ensure_style(win_bubble);
style = win_bubble->style;
screen = gtk_widget_get_screen(win_bubble);
scr_w = gdk_screen_get_width(screen);
scr_h = gdk_screen_get_height(screen);
gtk_label_set_text(GTK_LABEL(label), active_popup_str);
gtk_widget_size_request(win_bubble, &requisition);
w = requisition.width;
h = requisition.height;
/*
gdk_window_get_pointer(gdk_screen_get_root_window (screen),
&x, &y, NULL);
*/
widget = panel->drawing_area;
gdk_window_get_origin (widget->window, &x, &y);
if (GTK_WIDGET_NO_WINDOW (widget))
{
x += widget->allocation.x;
y += widget->allocation.y;
}
x -= (w / 2 + 4);
if ((x + w) > scr_w)
x -= (x + w) - scr_w;
else if (x < 0)
x = 0;
y -= (h + 6);
if ((y + h) > scr_h)
y -= (y + w) - scr_h;
else if (y < 0)
y = 0;
/* printf("w=%d, h=%d, x=%d, y=%d\n", w, h, x, y); */
gtk_window_move(GTK_WINDOW(win_bubble), x, y);
gtk_widget_show(win_bubble);
if (popup_timeout > 0) {
active_timeout = gtk_timeout_add(popup_timeout * 1000, bubble_timeout, NULL);
}
}
void append_file_to_buf(const gchar *filename, GString *gs)
{
FILE *fh;
char buf[1024];
size_t num;
if (! (fh = fopen(filename, "r"))) {
fprintf(stderr, "gkrellm-trayicons: cannot read activation file: %s (%s)",
filename, strerror(errno));
gkrellm_message_dialog("Error", "Cannot read activation file.");
return;
}
while ((num = fread(buf, sizeof(char), sizeof(buf), fh)) > 0) {
if (ferror(fh))
break;
g_string_append_len(gs, buf, num);
}
if (ferror(fh)) {
fprintf(stderr, "gkrellm-trayicons: cannot read activation file: %s (%s)",
filename, strerror(errno));
gkrellm_message_dialog("Error", "Cannot read activation file.");
}
if (fclose(fh) == EOF) {
fprintf(stderr, "gkrellm-trayicons: cannot close activation file: %s (%s)",
filename, strerror(errno));
gkrellm_message_dialog("Error", "Cannot close activation file.");
}
if (gs->str[gs->len - 1] == '\n') {
g_string_truncate(gs, gs->len - 1);
}
}
static void update_trayicons_real()
{
gint i;
struct stat st;
for (i = 0; i < trayicons->len; i++) {
gchar *acfile = g_array_index(trayicons,item_t, i).activation_file;
GString *new = g_string_new("");
/* check icons that should blink */
if (g_array_index(trayicons,item_t, i).activated &&
g_array_index(trayicons,item_t, i).blink) {
draw_icon(i, !g_array_index(trayicons,item_t, i).icon_state);
}
/* check new activations */
if (stat(acfile, &st) == -1) {
// gkrellm_message_dialog("Error", "Cannot stat activation file.");
continue;
}
if (S_ISDIR(st.st_mode)) {
DIR *d;
struct dirent *de;
gboolean first = TRUE;
if (chdir(acfile) == -1) {
fprintf(stderr,
"gkrellm-trayicons: cannot chdir to the activation directory: %s (%s)",
acfile, strerror(errno));
}
if (! (d = opendir(acfile))) {
fprintf(stderr, "gkrellm-trayicons: cannot open activation directory: %s (%s)", acfile, strerror(errno));
gkrellm_message_dialog("Error", "Cannot open activation directory.");
continue;
}
while ((de = readdir(d))) {
if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) {
if (! first) {
g_string_append(new, NOTICE_SEPARATOR);
}
first = FALSE;
append_file_to_buf(de->d_name, new);
if (unlink(de->d_name) == -1) {
fprintf(stderr, "gkrellm-trayicons: cannot unlink activation file: %s (%s)", de->d_name, strerror(errno));
gkrellm_message_dialog("Error", "Cannot unlink activation file.");
}
}
}
if (closedir(d) == -1) {
fprintf(stderr,
"gkrellm-trayicons: cannot close activation directory: %s (%s)",
acfile, strerror(errno));
gkrellm_message_dialog("Error", "Cannot close activation directory.");
continue;
}
if (first) {
/* no file was read */
continue;
}
else {
/* activate icon */
draw_icon(i, TRUE);
g_array_index(trayicons,item_t, i).activated = TRUE;
if (g_array_index(trayicons,item_t, i).popup) {
create_bubble(new->str, i);
}
}
}
else {
if (g_array_index(trayicons,item_t, i).activation_file_mtime != 0 &&
st.st_mtime != g_array_index(trayicons,item_t, i).activation_file_mtime) {
append_file_to_buf(acfile, new);
/* activate icon */
draw_icon(i, TRUE);
g_array_index(trayicons,item_t, i).activated = TRUE;
if (g_array_index(trayicons,item_t, i).popup) {
create_bubble(new->str, i);
}
}
g_array_index(trayicons,item_t, i).activation_file_mtime = st.st_mtime;
}
g_string_free(new, TRUE);
}
gkrellm_draw_panel_layers(panel);
}
static void update_trayicons()
{
if (GK.second_tick) {
update_trayicons_real();
}
}
static gint panel_expose_event(GtkWidget *widget, GdkEventExpose *ev, GkrellmPanel *p)
{
gdk_draw_pixmap(widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)], p->pixmap,
ev->area.x, ev->area.y, ev->area.x, ev->area.y,
ev->area.width, ev->area.height);
return TRUE;
}
static void deactivate_icon(gint icon)
{
g_array_index(trayicons, item_t, icon).activated = FALSE;
draw_icon(icon, FALSE);
gkrellm_draw_panel_layers(panel);
/*
if (g_array_index(trayicons, item_t, icon).buf) {
g_string_free(g_array_index(trayicons, item_t, icon).buf, TRUE);
g_array_index(trayicons, item_t, icon).buf = NULL;
}
*/
}
static gboolean cb_panel_button(GtkWidget *widget, GdkEventButton *ev,
gpointer data)
{
if (ev->button == 2)
{
gkrellm_open_config_window(monitor);
return TRUE;
}
return FALSE;
}
static void cb_icon_click_left(GkrellmDecalbutton *button, gpointer data)
{
gint icon = GPOINTER_TO_INT(data);
gchar *cmd;
/* printf("left button on icon %d was pressed\n", GPOINTER_TO_INT(data)); */
if (g_array_index(trayicons, item_t, icon).activated) {
cmd = g_array_index(trayicons, item_t, icon).left_click_active_command;
}
else {
cmd = g_array_index(trayicons, item_t, icon).left_click_inactive_command;
}
if (cmd) {
/* fprintf(stderr, "running command: %s\n", cmd); */
g_spawn_command_line_async(cmd, NULL);
}
deactivate_icon(icon);
if (active_popup) {
destroy_bubble();
}
}
static void cb_icon_click_right(GkrellmDecalbutton *button, gpointer data)
{
gint icon = GPOINTER_TO_INT(data);
/* printf("right button on icon %d was pressed\n", icon); */
if (active_popup) {
destroy_bubble();
}
else {
/*
if (g_array_index(trayicons, item_t, icon).buf) {
create_bubble(g_array_index(trayicons, item_t, icon).buf->str, icon);
}
*/
}
deactivate_icon(icon);
}
static void draw_icon(gint i, gboolean state)
{
GkrellmPiximage *pix_prim;
GkrellmPiximage *pix_sec;
gchar *filename_prim;
gchar *filename_sec;
if (state) {
filename_prim = g_array_index(trayicons, item_t, i).icon_active_file;
filename_sec = g_array_index(trayicons, item_t, i).icon_inactive_file;
}
else {
filename_prim = g_array_index(trayicons, item_t, i).icon_inactive_file;
filename_sec = g_array_index(trayicons, item_t, i).icon_active_file;
}
if (g_array_index(trayicons, item_t, i).but) {
gkrellm_destroy_button(g_array_index(trayicons, item_t, i).but);
}
if ((pix_prim = gkrellm_piximage_new_from_file(filename_prim)) &&
(pix_sec = gkrellm_piximage_new_from_file(filename_sec))) {
/*
GkrellmDecalbutton *but = gkrellm_make_scaled_button(panel,
pix_prim, cb_icon_click_left, GINT_TO_POINTER(i),
FALSE, FALSE,
0, 0, 1,
g_array_index(trayicons, item_t, i).x,
g_array_index(trayicons, item_t, i).y,
icon_size, icon_size);
*/
GkrellmDecalbutton *but = gkrellm_make_overlay_button(panel,
cb_icon_click_left, GINT_TO_POINTER(i),
g_array_index(trayicons, item_t, i).x,
g_array_index(trayicons, item_t, i).y,
icon_size, icon_size,
pix_prim,
pix_sec);
but->type = 0; /* disable auto hide */
gkrellm_destroy_piximage(pix_prim);
gkrellm_destroy_piximage(pix_sec);
if (but) {
g_array_index(trayicons, item_t, i).icon_state = state;
g_array_index(trayicons, item_t, i).but = but;
gkrellm_decal_button_right_connect(but, cb_icon_click_right, GINT_TO_POINTER(i));
gkrellm_show_button(but);
}
else {
gkrellm_message_dialog("Error", "Cannot create button.");
}
}
else {
gkrellm_message_dialog("Error", "Cannot load icon.");
}
}
void setup_trayicons(gint first_create)
{
GkrellmStyle *trayicons_style;
gint i;
GkrellmMargin *margin;
gint x, y;
GdkPixmap *bg_scaled = NULL;
GkrellmDecal *decal_bg = NULL;
GkrellmPiximage *bg = NULL;
if (panel) {
gkrellm_destroy_decal_list(panel);
for (i = 0; i < trayicons->len; i++) {
g_array_index(trayicons, item_t, i).but = NULL;
}
gkrellm_panel_destroy(panel);
}
panel = gkrellm_panel_new0();
trayicons_style = gkrellm_meter_style(DEFAULT_STYLE_ID);
margin = gkrellm_get_style_margins(trayicons_style);
/*
fprintf(stderr, "num icons: %d\n", trayicons->len);
fprintf(stderr, "chart width: %d\n", gkrellm_chart_width());
fprintf(stderr, "margin left: %d\n", margin->left);
fprintf(stderr, "margin right: %d\n", margin->right);
*/
/* calculate height so we can create the background first */
x = margin->left;
y = margin->top;
for (i = 0; i < trayicons->len; i++) {
if (x + icon_size + margin->right > gkrellm_chart_width()) {
x = margin->left;
y += icon_size;
y += icon_padding;
}
x += icon_size;
x += icon_padding;
}
/* create the background */
if ((bg = gkrellm_bg_meter_piximage(DEFAULT_STYLE_ID))) {
gkrellm_scale_piximage_to_pixmap(bg, &bg_scaled, NULL,
gkrellm_chart_width(), y + icon_size + margin->bottom);
}
if (bg_scaled) {
decal_bg = gkrellm_create_decal_pixmap(panel, bg_scaled, NULL, 0, NULL, 0, 0);
gkrellm_draw_decal_pixmap(panel, decal_bg, 0);
}
/* position and draw all the icons */
x = margin->left;
y = margin->top;
for (i = 0; i < trayicons->len; i++) {
if (x + icon_size + margin->right > gkrellm_chart_width()) {
x = margin->left;
y += icon_size;
y += icon_padding;
}
/* fprintf(stderr, "%d, %d, %d\n", i, x, y); */
g_array_index(trayicons, item_t, i).x = x;
g_array_index(trayicons, item_t, i).y = y;
draw_icon(i, FALSE);
x += icon_size;
x += icon_padding;
}
/* configure and create the panel */
gkrellm_panel_configure(panel, NULL, trayicons_style);
if (trayicons->len > 0) {
gkrellm_panel_configure_set_height(panel, y + icon_size + margin->bottom);
}
else {
gkrellm_panel_configure_set_height(panel, 1);
gkrellm_panel_hide(panel);
}
gkrellm_panel_create(trayicons_vbox, monitor, panel);
gkrellm_draw_panel_layers(panel);
g_signal_connect(G_OBJECT(panel->drawing_area), "expose_event",
G_CALLBACK(panel_expose_event), panel);
g_signal_connect(G_OBJECT(panel->drawing_area), "button_press_event",
G_CALLBACK(cb_panel_button), NULL);
}
void create_trayicons(GtkWidget *vbox, gint first_create)
{
trayicons_vbox = vbox;
setup_trayicons(first_create);
update_trayicons_real();
}
/*
* Configuration page
*/
static GtkWidget *activation_file_entry;
static GtkWidget *icon_active_file_entry;
static GtkWidget *icon_inactive_file_entry;
static GtkWidget *left_click_active_command_entry;
static GtkWidget *left_click_inactive_command_entry;
static GtkListStore *store_trayicons;
static GtkWidget *tree_trayicons;
static gint trayicons_item=0;
static GtkTreePath *path_selected = NULL;
static GtkWidget *btn_modify;
static GtkWidget *popup_fg_draw;
static GtkWidget *popup_bg_draw;
void error_msg(gchar *message)
{
gkrellm_config_message_dialog("Error", message);
}
/*
static void
destroy_item(gpointer data)
{
g_free(((item_t *)data)->activation_file);
g_free(((item_t *)data)->icon_active_file);
g_free(((item_t *)data)->icon_inactive_file);
g_free(((item_t *)data)->left_click_active_command);
g_free(((item_t *)data)->left_click_inactive_command);
g_free(data);
}
*/
static void on_clear_click(GtkButton *button, gpointer *data)
{
gtk_entry_set_text(GTK_ENTRY(activation_file_entry), "");
gtk_entry_set_text(GTK_ENTRY(icon_active_file_entry), "");
gtk_entry_set_text(GTK_ENTRY(icon_inactive_file_entry), "");
gtk_entry_set_text(GTK_ENTRY(left_click_active_command_entry), "");
gtk_entry_set_text(GTK_ENTRY(left_click_inactive_command_entry), "");
}
static void on_add_click(GtkButton *button, gpointer *data)
{
struct stat st;
GtkTreeIter iter;
const gchar *activation_file = gtk_entry_get_text(GTK_ENTRY(activation_file_entry));
const gchar *icon_active_file = gtk_entry_get_text(GTK_ENTRY(icon_active_file_entry));
const gchar *icon_inactive_file = gtk_entry_get_text(GTK_ENTRY(icon_inactive_file_entry));
const gchar *left_click_active_command = gtk_entry_get_text(GTK_ENTRY(left_click_active_command_entry));
const gchar *left_click_inactive_command = gtk_entry_get_text(GTK_ENTRY(left_click_inactive_command_entry));
if (!activation_file[0])
{
error_msg("Please enter activation file path.");
return;
}
if (!icon_active_file[0]) {
error_msg("Please enter active icon path.");
return;
}
if (!icon_inactive_file[0]) {
error_msg("Please enter inactive icon path.");
return;
}
if (stat(activation_file, &st) == -1) {
error_msg("Activation file/dir doesn't exist.");
return;
}
if (stat(icon_active_file, &st) == -1) {
error_msg("Active icon file doesn't exist.");
return;
}
if (stat(icon_inactive_file, &st) == -1) {
error_msg("Inactive icon file doesn't exist.");
return;
}
if (GPOINTER_TO_INT(data) == 1) {
if (path_selected && gtk_tree_model_get_iter(GTK_TREE_MODEL(store_trayicons), &iter, path_selected)) {
gtk_list_store_set(store_trayicons, &iter,
ACTIVATION_FILE_COLUMN, activation_file,
ICON_ACTIVE_FILE_COLUMN, icon_active_file,
ICON_INACTIVE_FILE_COLUMN, icon_inactive_file,
LEFT_CLICK_ACTIVE_COMMAND_COLUMN, left_click_active_command,
LEFT_CLICK_INACTIVE_COMMAND_COLUMN, left_click_inactive_command,
ICON_ACTIVE_PIXBUF_COLUMN, get_pixbuf(icon_active_file, 16),
ICON_INACTIVE_PIXBUF_COLUMN, get_pixbuf(icon_inactive_file, 16),
-1);
}
}
else {
gtk_list_store_append(store_trayicons, &iter);
gtk_list_store_set(store_trayicons, &iter,
ACTIVATION_FILE_COLUMN, activation_file,
ICON_ACTIVE_FILE_COLUMN, icon_active_file,
ICON_INACTIVE_FILE_COLUMN, icon_inactive_file,
LEFT_CLICK_ACTIVE_COMMAND_COLUMN, left_click_active_command,
LEFT_CLICK_INACTIVE_COMMAND_COLUMN, left_click_inactive_command,
ICON_ACTIVE_PIXBUF_COLUMN, get_pixbuf(icon_active_file, 16),
ICON_INACTIVE_PIXBUF_COLUMN, get_pixbuf(icon_inactive_file, 16),
-1);
}
return;
}
static void on_del_click(GtkButton *button, gpointer *data)
{
GtkTreeSelection *sel;
GtkListStore *store;
GtkTreeIter iter;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_trayicons));
if (gtk_tree_selection_get_selected(sel, (GtkTreeModel **)&store, &iter)) {
gtk_list_store_remove(store, &iter);
}
}
static void on_up_click(GtkButton *button, gpointer *data)
{
GtkTreeSelection *sel;
GtkListStore *store;
GtkTreeIter iter;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_trayicons));
if (gtk_tree_selection_get_selected(sel, (GtkTreeModel **)&store, &iter)) {
gchar *path_str;
gint path_num;
path_str = gtk_tree_model_get_string_from_iter(GTK_TREE_MODEL(store), &iter);
path_num = atoi(path_str);
if (path_num - 2 >= -1) {
gchar npath[256];
GtkTreeIter iter2;
GtkTreePath *path;
if (path_num - 2 == -1) {
gtk_list_store_move_after(store, &iter, NULL);
}
else {
snprintf(npath, sizeof(npath), "%d", path_num - 2);
path = gtk_tree_path_new_from_string(npath);
gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter2, path);
gtk_list_store_move_after(store, &iter, &iter2);
}
}
g_free(path_str);
}
}
static void on_down_click(GtkButton *button, gpointer *data)
{
GtkTreeSelection *sel;
GtkListStore *store;
GtkTreeIter iter;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_trayicons));
if (gtk_tree_selection_get_selected(sel, (GtkTreeModel **)&store, &iter)) {
GtkTreeIter iter2;
memcpy(&iter2, &iter, sizeof(iter));
if (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter2)) {
gtk_list_store_move_after(store, &iter, &iter2);
}
}
}
static void on_colorsel_click(GtkButton *button, gpointer *data)
{
gint response;
GtkColorSelection *cs;
GtkWidget *colorseldlg;
gboolean fg = (GPOINTER_TO_INT(data) == 1 ? TRUE : FALSE);
/* Create color selection dialog */
colorseldlg = gtk_color_selection_dialog_new(fg ? "Select foreground color" : "Select background color");
/* Get the ColorSelection widget */
cs = GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(colorseldlg)->colorsel);
gtk_color_selection_set_previous_color(cs, fg ? &popup_fg_color : &popup_bg_color);
gtk_color_selection_set_current_color(cs, fg ? &popup_fg_color : &popup_bg_color);
gtk_color_selection_set_has_palette(cs, TRUE);
/* Show the dialog */
response = gtk_dialog_run(GTK_DIALOG(colorseldlg));
if (response == GTK_RESPONSE_OK) {
gtk_color_selection_get_current_color(cs, fg ? &popup_fg_color : &popup_bg_color);
gtk_widget_modify_bg(fg ? popup_fg_draw : popup_bg_draw,
GTK_STATE_NORMAL, fg ? &popup_fg_color : &popup_bg_color);
}
gtk_widget_destroy (colorseldlg);
}
static void cursor_changed(GtkTreeView *tree, gpointer data)
{
GtkTreeIter iter;
GtkTreePath *path;
gchar *activation_file;
gchar *icon_active_file;
gchar *icon_inactive_file;
gchar *left_click_active_command;
gchar *left_click_inactive_command;
gtk_tree_view_get_cursor(tree, &path, NULL);
if (path == NULL) {
return;
}
if (path_selected) gtk_tree_path_free(path_selected);
path_selected = gtk_tree_path_copy(path);
g_object_set(G_OBJECT(btn_modify), "sensitive", TRUE, NULL);
if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store_trayicons), &iter, path)) {
gtk_tree_model_get(GTK_TREE_MODEL(store_trayicons), &iter,
ACTIVATION_FILE_COLUMN, &activation_file,
ICON_ACTIVE_FILE_COLUMN, &icon_active_file,
ICON_INACTIVE_FILE_COLUMN, &icon_inactive_file,
LEFT_CLICK_ACTIVE_COMMAND_COLUMN, &left_click_active_command,
LEFT_CLICK_INACTIVE_COMMAND_COLUMN, &left_click_inactive_command,
-1);
gtk_entry_set_text(GTK_ENTRY(activation_file_entry), activation_file);
gtk_entry_set_text(GTK_ENTRY(icon_active_file_entry), icon_active_file);
gtk_entry_set_text(GTK_ENTRY(icon_inactive_file_entry), icon_inactive_file);
gtk_entry_set_text(GTK_ENTRY(left_click_active_command_entry), left_click_active_command ?
left_click_active_command : "");
gtk_entry_set_text(GTK_ENTRY(left_click_inactive_command_entry),
left_click_inactive_command ? left_click_inactive_command : "");
}
}
static void row_toggled(GtkCellRendererText *renderer,
gchar *row, gpointer data)
{
GtkTreeIter iter;
if (gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store_trayicons), &iter,
NULL, atoi(row))) {
gtk_list_store_set(store_trayicons, &iter, GPOINTER_TO_INT(data),
!gtk_cell_renderer_toggle_get_active(GTK_CELL_RENDERER_TOGGLE(renderer)), -1);
}
}
static void cb_icon_size(GtkMenuItem *item, gpointer data)
{
icon_size = GPOINTER_TO_INT(data);
}
static void cb_icon_padding(GtkMenuItem *item, gpointer data)
{
icon_padding = GPOINTER_TO_INT(data);
}
static void cb_popup_timeout(GtkMenuItem *item, gpointer data)
{
popup_timeout = GPOINTER_TO_INT(data);
}
static GtkWidget *picker;
static void store_filename(GtkButton *but, gpointer user_data)
{
const gchar *selected_filename;
selected_filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (picker));
gtk_entry_set_text(GTK_ENTRY(user_data), selected_filename);
}
static void config_filepicker(GtkButton *button, gpointer *data)
{
picker = gtk_file_selection_new("Select file");
g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(picker)->ok_button),
"clicked", G_CALLBACK(store_filename), data);
/* Ensure that the dialog box is destroyed when the user clicks a button. */
g_signal_connect_swapped (GTK_OBJECT (GTK_FILE_SELECTION (picker)->ok_button),
"clicked",
G_CALLBACK (gtk_widget_destroy),
(gpointer) picker);
g_signal_connect_swapped (GTK_OBJECT (GTK_FILE_SELECTION (picker)->cancel_button),
"clicked",
G_CALLBACK (gtk_widget_destroy),
(gpointer) picker);
gtk_widget_show(picker);
}
/* Create a new hbox with an image and a label packed into it
* and return the box. */
GtkWidget *button_box(const gchar *label_text, const gchar *stock_id)
{
GtkWidget *box;
GtkWidget *label;
GtkWidget *image;
GtkWidget *button;
/* Create box for image and label */
box = gtk_hbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER (box), 2);
/* Now on to the image stuff */
image = gtk_image_new_from_stock(stock_id, GTK_ICON_SIZE_SMALL_TOOLBAR);
/* Create a label for the button */
label = gtk_label_new(label_text);
/* Pack the image and label into the box */
gtk_box_pack_start(GTK_BOX (box), image, FALSE, FALSE, 3);
gtk_box_pack_start(GTK_BOX (box), label, FALSE, FALSE, 3);
gtk_widget_show(image);
gtk_widget_show(label);
gtk_widget_show (box);
button = gtk_button_new();
gtk_container_add(GTK_CONTAINER(button), box);
gtk_widget_show(button);
return button;
}
static void create_trayicons_tab(GtkWidget *tab_vbox)
{
GtkWidget *vbox;
GtkWidget *tabs;
GtkWidget *btn_hbox;
GtkWidget *table;
GtkWidget *table_set;
gint i;
tabs = gtk_notebook_new();
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
gtk_box_pack_start(GTK_BOX(tab_vbox), tabs, TRUE, TRUE, 0);
/* File location tab */
vbox = gkrellm_gtk_notebook_page(tabs, "Icons");
btn_hbox = gtk_hbox_new(FALSE, 5);
/* buttons */
{
GtkWidget *btn_add;
GtkWidget *btn_del;
GtkWidget *btn_clear;
GtkWidget *btn_up;
GtkWidget *btn_down;
btn_add = button_box("Add", GTK_STOCK_ADD);
gtk_signal_connect(GTK_OBJECT(btn_add), "clicked",
GTK_SIGNAL_FUNC(on_add_click), GINT_TO_POINTER(0));
btn_del = button_box("Remove", GTK_STOCK_REMOVE);
gtk_signal_connect(GTK_OBJECT(btn_del), "clicked",
GTK_SIGNAL_FUNC(on_del_click), NULL);
btn_modify = button_box("Modify selected", GTK_STOCK_APPLY);
gtk_signal_connect(GTK_OBJECT(btn_modify), "clicked",
GTK_SIGNAL_FUNC(on_add_click), GINT_TO_POINTER(1));
g_object_set(G_OBJECT(btn_modify), "sensitive", FALSE, NULL);
btn_clear = button_box("Clear", GTK_STOCK_CLEAR);
gtk_signal_connect(GTK_OBJECT(btn_clear), "clicked",
GTK_SIGNAL_FUNC(on_clear_click), NULL);
btn_up = button_box("Up", GTK_STOCK_GO_UP);
gtk_signal_connect(GTK_OBJECT(btn_up), "clicked",
GTK_SIGNAL_FUNC(on_up_click), NULL);
btn_down = button_box("Down", GTK_STOCK_GO_DOWN);
gtk_signal_connect(GTK_OBJECT(btn_down), "clicked",
GTK_SIGNAL_FUNC(on_down_click), NULL);
gtk_box_pack_start(GTK_BOX(btn_hbox), btn_add, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(btn_hbox), btn_del, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(btn_hbox), btn_modify, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(btn_hbox), btn_up, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(btn_hbox), btn_down, TRUE, TRUE, 2);
gtk_box_pack_start(GTK_BOX(btn_hbox), btn_clear, TRUE, TRUE, 2);
}
store_trayicons = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING,
GDK_TYPE_PIXBUF, G_TYPE_STRING,
GDK_TYPE_PIXBUF, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
for (i = 0; i < trayicons->len; i++)
{
GtkTreeIter iter;
gtk_list_store_append(store_trayicons, &iter);
gtk_list_store_set(store_trayicons, &iter,
ACTIVATION_FILE_COLUMN, g_strdup(g_array_index(trayicons,item_t,i).activation_file),
ICON_ACTIVE_PIXBUF_COLUMN, get_pixbuf(g_array_index(trayicons,item_t,i).icon_active_file, 16),
ICON_ACTIVE_FILE_COLUMN, g_strdup(g_array_index(trayicons,item_t,i).icon_active_file),
ICON_INACTIVE_PIXBUF_COLUMN, get_pixbuf(g_array_index(trayicons,item_t,i).icon_inactive_file, 16),
ICON_INACTIVE_FILE_COLUMN, g_strdup(g_array_index(trayicons,item_t,i).icon_inactive_file),
LEFT_CLICK_ACTIVE_COMMAND_COLUMN, g_strdup(g_array_index(trayicons,item_t,i).left_click_active_command),
LEFT_CLICK_INACTIVE_COMMAND_COLUMN, g_strdup(g_array_index(trayicons,item_t,i).left_click_inactive_command),
BLINK_COLUMN, g_array_index(trayicons,item_t,i).blink,
POPUP_COLUMN, g_array_index(trayicons,item_t,i).popup,
-1
);
}
trayicons_item=0;
table = gtk_table_new(4, 3, FALSE);
/* activation file */
{
GtkWidget *activation_file_picker_but;
GtkWidget *activation_file_lbl;
GtkWidget *activation_file_align;
GtkWidget *warning_lbl;
activation_file_entry = gtk_entry_new_with_max_length(255);
activation_file_picker_but = button_box("Pick file", GTK_STOCK_OPEN);
g_signal_connect(G_OBJECT(activation_file_picker_but), "clicked",
G_CALLBACK(config_filepicker), activation_file_entry);
activation_file_align = gtk_alignment_new(0, 0.5, 0, 0);
activation_file_lbl=gtk_label_new("Activation file/dir path:");
gtk_container_add(GTK_CONTAINER(activation_file_align), activation_file_lbl);
gtk_table_attach(GTK_TABLE(table), activation_file_align, 0, 1, 0, 1, GTK_FILL, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), activation_file_entry, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), activation_file_picker_but, 2, 3, 0, 1, GTK_FILL, 0, 5, 5);
/* warning */
warning_lbl=gtk_label_new("WARNING: All files in the specified directory are *deleted*.");
gtk_table_attach(GTK_TABLE(table), warning_lbl, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, 0, 5, 5);
}
/* icon active */
{
GtkWidget *icon_active_file_picker_but;
GtkWidget *icon_active_file_align;
GtkWidget *icon_active_file_lbl;
icon_active_file_entry = gtk_entry_new_with_max_length(255);
icon_active_file_picker_but = button_box("Pick file", GTK_STOCK_OPEN);
g_signal_connect(G_OBJECT(icon_active_file_picker_but), "clicked",
G_CALLBACK(config_filepicker), icon_active_file_entry);
icon_active_file_align = gtk_alignment_new(0, 0.5, 0, 0);
icon_active_file_lbl=gtk_label_new("Active icon file path:");
gtk_container_add(GTK_CONTAINER(icon_active_file_align), icon_active_file_lbl);
gtk_table_attach(GTK_TABLE(table), icon_active_file_align, 0, 1, 2, 3, GTK_FILL, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), icon_active_file_entry, 1, 2, 2, 3, GTK_FILL | GTK_EXPAND, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), icon_active_file_picker_but, 2, 3, 2, 3, GTK_FILL, 0, 5, 5);
}
/* icon inactive */
{
GtkWidget *icon_inactive_file_picker_but;
GtkWidget *icon_inactive_file_align;
GtkWidget *icon_inactive_file_lbl;
icon_inactive_file_entry = gtk_entry_new_with_max_length(255);
icon_inactive_file_picker_but = button_box("Pick file", GTK_STOCK_OPEN);
g_signal_connect(G_OBJECT(icon_inactive_file_picker_but), "clicked",
G_CALLBACK(config_filepicker), icon_inactive_file_entry);
icon_inactive_file_align = gtk_alignment_new(0, 0.5, 0, 0);
icon_inactive_file_lbl=gtk_label_new("Inactive icon file path:");
gtk_container_add(GTK_CONTAINER(icon_inactive_file_align), icon_inactive_file_lbl);
gtk_table_attach(GTK_TABLE(table), icon_inactive_file_align, 0, 1, 3, 4, GTK_FILL, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), icon_inactive_file_entry, 1, 2, 3, 4, GTK_FILL | GTK_EXPAND, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), icon_inactive_file_picker_but, 2, 3, 3, 4, GTK_FILL, 0, 5, 5);
}
/* left click active command */
{
GtkWidget *left_click_active_command_align;
GtkWidget *left_click_active_command_lbl;
left_click_active_command_align = gtk_alignment_new(0, 0.5, 0, 0);
left_click_active_command_lbl=gtk_label_new("Active command:");
gtk_container_add(GTK_CONTAINER(left_click_active_command_align), left_click_active_command_lbl);
left_click_active_command_entry = gtk_entry_new_with_max_length(255);
gtk_table_attach(GTK_TABLE(table), left_click_active_command_align, 0, 1, 4, 5, GTK_FILL, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), left_click_active_command_entry, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND, 0, 5, 5);
}
/* left click inactive command */
{
GtkWidget *left_click_inactive_command_align;
GtkWidget *left_click_inactive_command_lbl;
left_click_inactive_command_align = gtk_alignment_new(0, 0.5, 0, 0);
left_click_inactive_command_lbl=gtk_label_new("Inactive command:");
gtk_container_add(GTK_CONTAINER(left_click_inactive_command_align), left_click_inactive_command_lbl);
left_click_inactive_command_entry = gtk_entry_new_with_max_length(255);
gtk_table_attach(GTK_TABLE(table), left_click_inactive_command_align, 0, 1, 5, 6, GTK_FILL, 0, 5, 5);
gtk_table_attach(GTK_TABLE(table), left_click_inactive_command_entry, 1, 2, 5, 6, GTK_FILL | GTK_EXPAND, 0, 5, 5);
}
gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(vbox), btn_hbox, FALSE, FALSE, 2);
/* tree view and its columns */
{
GtkTreeSelection *select;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GdkScreen *screen;
GtkWidget *scrolled_window;
gint tree_width;
tree_trayicons = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store_trayicons));
select = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_trayicons));
gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
screen = gtk_widget_get_screen(tree_trayicons);
tree_width = gdk_screen_get_width(screen) - TREE_SIZE_PADDING;
if (tree_width > TREE_SIZE_MAX) tree_width = TREE_SIZE_MAX;
/* column pixbuf - icon active */
renderer = gtk_cell_renderer_pixbuf_new();
column = gtk_tree_view_column_new_with_attributes ("Active icon", renderer,
"pixbuf", ICON_ACTIVE_PIXBUF_COLUMN, NULL);
g_object_set(G_OBJECT(column), "resizable", FALSE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(tree_trayicons), column);
/* column pixbuf - icon inactive */
renderer = gtk_cell_renderer_pixbuf_new();
column = gtk_tree_view_column_new_with_attributes ("Inactive icon", renderer,
"pixbuf", ICON_INACTIVE_PIXBUF_COLUMN, NULL);
g_object_set(G_OBJECT(column), "resizable", FALSE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(tree_trayicons), column);
/* column blink */
renderer = gtk_cell_renderer_toggle_new();
g_object_set(G_OBJECT(renderer), "activatable", TRUE, NULL);
g_signal_connect(G_OBJECT(renderer), "toggled",
G_CALLBACK(row_toggled), GINT_TO_POINTER(BLINK_COLUMN));
column = gtk_tree_view_column_new_with_attributes ("Blink", renderer,
"active", BLINK_COLUMN,
NULL);
g_object_set(G_OBJECT(column), "resizable", FALSE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(tree_trayicons), column);
/* column popup */
renderer = gtk_cell_renderer_toggle_new();
g_object_set(G_OBJECT(renderer), "activatable", TRUE, NULL);
g_signal_connect(G_OBJECT(renderer), "toggled",
G_CALLBACK(row_toggled), GINT_TO_POINTER(POPUP_COLUMN));
column = gtk_tree_view_column_new_with_attributes ("Popup", renderer,
"active", POPUP_COLUMN,
NULL);
g_object_set(G_OBJECT(column), "resizable", FALSE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(tree_trayicons), column);
/* column activation file */
renderer = gtk_cell_renderer_text_new();
g_object_set(G_OBJECT(renderer), "editable", FALSE, NULL);
column = gtk_tree_view_column_new_with_attributes ("Activation file/dir", renderer,
"text", ACTIVATION_FILE_COLUMN, NULL);
g_object_set(G_OBJECT(column), "resizable", TRUE, NULL);
gtk_tree_view_column_set_max_width(column, 300);
gtk_tree_view_append_column (GTK_TREE_VIEW(tree_trayicons), column);
/* tree view settings */
g_object_set(G_OBJECT(tree_trayicons), "headers-visible", TRUE, NULL);
gtk_widget_set_size_request(tree_trayicons, tree_width, TREE_HEIGHT);
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(tree_trayicons));
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scrolled_window), tree_trayicons);
gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 12);
g_signal_connect(G_OBJECT(tree_trayicons), "cursor-changed",
G_CALLBACK(cursor_changed), NULL);
}
/****************/
/* Settings tab */
/****************/
vbox = gkrellm_gtk_notebook_page(tabs, "Settings");
table_set = gtk_table_new(5, 2, FALSE);
/* icon size */
{
GtkWidget *icon_size_lbl;
GtkWidget *icon_size_align;
GtkWidget *icon_size_align_optmenu;
GtkWidget *icon_size_menu;
GtkWidget *icon_size_optmenu;
gint select_icon_size = 0;
static const struct ConfigIconSize {
gchar *title;
gint size;
} config_icon_size[] = {
{ "16 x 16", 16 },
{ "20 x 20", 20 },
{ "24 x 24", 24 },
{ "32 x 32", 32 },
{ "48 x 48", 48 },
{ "64 x 64", 64 },
};
icon_size_lbl = gtk_label_new("Size at which icons will be displayed:");
icon_size_align = gtk_alignment_new(1, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(icon_size_align), icon_size_lbl);
gtk_table_attach(GTK_TABLE(table_set), icon_size_align, 0, 1, 0, 1, GTK_FILL, 0, 5, 5);
icon_size_menu = gtk_menu_new();
for (i = 0; i < sizeof(config_icon_size) / sizeof(struct ConfigIconSize); i++) {
GtkWidget *item;
item = gtk_menu_item_new_with_label(config_icon_size[i].title);
g_signal_connect(G_OBJECT(item), "select", G_CALLBACK(cb_icon_size),
GINT_TO_POINTER(config_icon_size[i].size));
gtk_menu_shell_append(GTK_MENU_SHELL(icon_size_menu), item);
if (config_icon_size[i].size == icon_size) {
select_icon_size = i;
}
}
icon_size_optmenu = gtk_option_menu_new();
gtk_option_menu_set_menu(GTK_OPTION_MENU(icon_size_optmenu), icon_size_menu);
gtk_option_menu_set_history(GTK_OPTION_MENU(icon_size_optmenu), select_icon_size);
icon_size_align_optmenu = gtk_alignment_new(0, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(icon_size_align_optmenu), icon_size_optmenu);
gtk_table_attach(GTK_TABLE(table_set), icon_size_align_optmenu, 1, 2, 0, 1, GTK_FILL, 0, 5, 5);
}
/* icon padding */
{
GtkWidget *icon_padding_lbl;
GtkWidget *icon_padding_align;
GtkWidget *icon_padding_align_optmenu;
GtkWidget *icon_padding_menu;
GtkWidget *icon_padding_optmenu;
gint select_icon_padding = 0;
icon_padding_lbl = gtk_label_new("Padding between icons:");
icon_padding_align = gtk_alignment_new(1, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(icon_padding_align), icon_padding_lbl);
gtk_table_attach(GTK_TABLE(table_set), icon_padding_align, 0, 1, 1, 2, GTK_FILL, 0, 5, 5);
icon_padding_menu = gtk_menu_new();
for (i = 1; i <= 16; i++) {
GtkWidget *item;
gchar label[128];
snprintf(label, sizeof(label), "%d", i);
item = gtk_menu_item_new_with_label(label);
g_signal_connect(G_OBJECT(item), "select", G_CALLBACK(cb_icon_padding),
GINT_TO_POINTER(i));
gtk_menu_shell_append(GTK_MENU_SHELL(icon_padding_menu), item);
if (i == icon_padding) {
select_icon_padding = i - 1;
}
}
icon_padding_optmenu = gtk_option_menu_new();
gtk_option_menu_set_menu(GTK_OPTION_MENU(icon_padding_optmenu), icon_padding_menu);
gtk_option_menu_set_history(GTK_OPTION_MENU(icon_padding_optmenu), select_icon_padding);
icon_padding_align_optmenu = gtk_alignment_new(0, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(icon_padding_align_optmenu), icon_padding_optmenu);
gtk_table_attach(GTK_TABLE(table_set), icon_padding_align_optmenu, 1, 2, 1, 2, GTK_FILL, 0, 5, 5);
}
/* popup timeout */
{
GtkWidget *popup_timeout_lbl;
GtkWidget *popup_timeout_align;
GtkWidget *popup_timeout_align_optmenu;
GtkWidget *popup_timeout_menu;
GtkWidget *popup_timeout_optmenu;
gint select_popup_timeout = 0;
static const gint config_popup_timeout[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
12, 14, 16, 18, 20, 25, 30, 40, 50, 60,
-1 /* end */
};
popup_timeout_lbl = gtk_label_new("Popup timeout:");
popup_timeout_align = gtk_alignment_new(1, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(popup_timeout_align), popup_timeout_lbl);
gtk_table_attach(GTK_TABLE(table_set), popup_timeout_align, 0, 1, 2, 3, GTK_FILL, 0, 5, 5);
popup_timeout_menu = gtk_menu_new();
i = 0;
while (config_popup_timeout[i] != -1) {
GtkWidget *item;
gchar label[128];
gint timeout = config_popup_timeout[i];
snprintf(label, sizeof(label), "%d", timeout);
item = gtk_menu_item_new_with_label(label);
g_signal_connect(G_OBJECT(item), "select", G_CALLBACK(cb_popup_timeout),
GINT_TO_POINTER(timeout));
gtk_menu_shell_append(GTK_MENU_SHELL(popup_timeout_menu), item);
if (timeout == popup_timeout) {
select_popup_timeout = i;
}
i++;
}
popup_timeout_optmenu = gtk_option_menu_new();
gtk_option_menu_set_menu(GTK_OPTION_MENU(popup_timeout_optmenu), popup_timeout_menu);
gtk_option_menu_set_history(GTK_OPTION_MENU(popup_timeout_optmenu), select_popup_timeout);
popup_timeout_align_optmenu = gtk_alignment_new(0, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(popup_timeout_align_optmenu), popup_timeout_optmenu);
gtk_table_attach(GTK_TABLE(table_set), popup_timeout_align_optmenu, 1, 2, 2, 3, GTK_FILL, 0, 5, 5);
}
/* popup foreground color */
{
GtkWidget *popup_fg_lbl;
GtkWidget *popup_fg_align;
GtkWidget *popup_fg_button;
popup_fg_lbl = gtk_label_new("Popup foreground color:");
popup_fg_align = gtk_alignment_new(1, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(popup_fg_align), popup_fg_lbl);
gtk_table_attach(GTK_TABLE(table_set), popup_fg_align, 0, 1, 3, 4, GTK_FILL, 0, 5, 5);
popup_fg_draw = gtk_drawing_area_new();
gtk_widget_modify_bg(popup_fg_draw, GTK_STATE_NORMAL, &popup_fg_color);
gtk_widget_set_size_request(GTK_WIDGET(popup_fg_draw), 40, 15);
popup_fg_button = gtk_button_new();
gtk_container_add(GTK_CONTAINER(popup_fg_button), popup_fg_draw);
gtk_signal_connect(GTK_OBJECT(popup_fg_button), "clicked",
GTK_SIGNAL_FUNC(on_colorsel_click), GINT_TO_POINTER(1));
gtk_table_attach(GTK_TABLE(table_set), popup_fg_button, 1, 2, 3, 4, GTK_FILL, 0, 5, 5);
}
/* popup background color */
{
GtkWidget *popup_bg_lbl;
GtkWidget *popup_bg_align;
GtkWidget *popup_bg_button;
popup_bg_lbl = gtk_label_new("Popup background color:");
popup_bg_align = gtk_alignment_new(1, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(popup_bg_align), popup_bg_lbl);
gtk_table_attach(GTK_TABLE(table_set), popup_bg_align, 0, 1, 4, 5, GTK_FILL, 0, 5, 5);
popup_bg_draw = gtk_drawing_area_new();
gtk_widget_modify_bg(popup_bg_draw, GTK_STATE_NORMAL, &popup_bg_color);
gtk_widget_set_size_request(GTK_WIDGET(popup_bg_draw), 40, 15);
popup_bg_button = gtk_button_new();
gtk_container_add(GTK_CONTAINER(popup_bg_button), popup_bg_draw);
gtk_signal_connect(GTK_OBJECT(popup_bg_button), "clicked",
GTK_SIGNAL_FUNC(on_colorsel_click), GINT_TO_POINTER(0));
gtk_table_attach(GTK_TABLE(table_set), popup_bg_button, 1, 2, 4, 5, GTK_FILL, 0, 5, 5);
}
gtk_box_pack_start(GTK_BOX(vbox), table_set, FALSE, FALSE, 2);
/************/
/* Info tab */
/************/
{
GtkWidget *info_text_w;
static const gchar *trayicons_info_text[] = {
"<b>Trayicons plugin " VERSION "\n",
"\n",
"<b>Usage:\n",
"left click - deactivate the icon and run the command\n"
"right click - deactivate the icon\n"
"middle click - open the configuration dialog\n"
"\n",
"<b>Homepage: ",
"http://sweb.cz/tripie/gkrellm/trayicons/\n",
"<b>Author: ",
"Tomas Styblo <tripie@cpan.org>\n"
"\n"
"Copyright (C) 2003\n"
"Distributed under the ",
"<b>GNU General Public License (GPL)\n"
};
vbox = gkrellm_gtk_notebook_page(tabs, "Info");
info_text_w = gkrellm_gtk_scrolled_text_view(vbox, NULL,
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gkrellm_gtk_text_view_append_strings(info_text_w, (char **)trayicons_info_text,
sizeof(trayicons_info_text) / sizeof(gchar *));
}
}
static GdkPixbuf *get_pixbuf(const gchar *filename, gint size)
{
GdkPixbuf *px = NULL;
if (! (px = gdk_pixbuf_new_from_file(filename, NULL))) {
return NULL;
}
return gdk_pixbuf_scale_simple(px, size, size, GDK_INTERP_BILINEAR);
}
static void save_trayicons_config(FILE *f)
{
gint i;
/*
printf("Saving config...\n");
*/
fprintf(f, "trayicons icon_size %i\n", icon_size);
fprintf(f, "trayicons icon_padding %i\n", icon_padding);
fprintf(f, "trayicons popup_timeout %i\n", popup_timeout);
fprintf(f, "trayicons popup_fg_color #%04X%04X%04X\n",
popup_fg_color.red, popup_fg_color.green, popup_fg_color.blue);
fprintf(f, "trayicons popup_bg_color #%04X%04X%04X\n",
popup_bg_color.red, popup_bg_color.green, popup_bg_color.blue);
for (i = 0; i < trayicons->len; i++)
{
fprintf(f,"trayicons activation_file%i %s\n",i,g_array_index(trayicons,item_t,i).activation_file);
fprintf(f,"trayicons icon_active_file%i %s\n",i,g_array_index(trayicons,item_t,i).icon_active_file);
fprintf(f,"trayicons icon_inactive_file%i %s\n",i,g_array_index(trayicons,item_t,i).icon_inactive_file);
if (g_array_index(trayicons,item_t,i).left_click_active_command) {
fprintf(f,"trayicons left_click_active_command%i %s\n",i,g_array_index(trayicons,item_t,i).left_click_active_command);
}
if (g_array_index(trayicons,item_t,i).left_click_inactive_command) {
fprintf(f,"trayicons left_click_inactive_command%i %s\n",i,g_array_index(trayicons,item_t,i).left_click_inactive_command);
}
fprintf(f,"trayicons blink%i %d\n",i,g_array_index(trayicons,item_t,i).blink);
/* popup must be the last - see load_trayicons_config() */
fprintf(f,"trayicons popup%i %d\n",i,g_array_index(trayicons,item_t,i).popup);
}
}
static item_t c;
static void load_trayicons_config(gchar *arg)
{
gchar buf[MY_BUFLEN+1];
gint i;
gboolean boolean;
/*
printf("trayicons_config=<%s>\n", arg);
*/
if (sscanf(arg, "icon_size %i",&i) == 1) {
icon_size = i;
}
else if (sscanf(arg, "icon_padding %i",&i) == 1) {
icon_padding = i;
}
else if (sscanf(arg, "popup_timeout %i",&i) == 1) {
popup_timeout = i;
}
else if (sscanf(arg, "popup_fg_color %" xstr(MY_BUFLEN) "s", buf) == 1) {
if (!gdk_color_parse(buf, &popup_fg_color)) {
fprintf(stderr, "gkrellm-trayicons: cannot parse color: %s\n", buf);
}
}
else if (sscanf(arg, "popup_bg_color %" xstr(MY_BUFLEN) "s", buf) == 1) {
if (!gdk_color_parse(buf, &popup_bg_color)) {
fprintf(stderr, "gkrellm-trayicons: cannot parse color: %s\n", buf);
}
}
else if (sscanf(arg, "activation_file%i %" xstr(MY_BUFLEN) "s", &i, buf) == 2) {
c.activation_file = g_strdup(buf);
}
else if (sscanf(arg, "icon_active_file%i %" xstr(MY_BUFLEN) "s", &i, buf) == 2) {
c.icon_active_file = g_strdup(buf);
}
else if (sscanf(arg, "icon_inactive_file%i %" xstr(MY_BUFLEN) "s", &i, buf) == 2) {
c.icon_inactive_file = g_strdup(buf);
}
else if (strncmp(arg, "left_click_active_command", strlen("left_click_active_command")) == 0) {
char *p;
if ((p = strchr(arg, ' '))) {
c.left_click_active_command = g_strdup(p+1);
}
}
else if (strncmp(arg, "left_click_inactive_command", strlen("left_click_inactive_command")) == 0) {
char *p;
if ((p = strchr(arg, ' '))) {
c.left_click_inactive_command = g_strdup(p+1);
}
}
else if (sscanf(arg, "blink%i %i",&i,&boolean) == 2) {
c.blink = boolean;
}
else if (sscanf(arg, "popup%i %i",&i,&boolean) == 2) {
c.popup = boolean;
/* finish the item */
g_array_append_val(trayicons, c);
memset(&c, 0, sizeof(c));
}
}
static void apply_trayicons_config()
{
gint i;
GtkTreeIter iter;
/*
printf("Applying config...\n");
*/
for (i = 0; i < trayicons->len; i++)
{
g_free(g_array_index(trayicons, item_t, i).activation_file);
g_free(g_array_index(trayicons, item_t, i).icon_active_file);
g_free(g_array_index(trayicons, item_t, i).icon_inactive_file);
g_free(g_array_index(trayicons, item_t, i).left_click_active_command);
g_free(g_array_index(trayicons, item_t, i).left_click_inactive_command);
gkrellm_destroy_button(g_array_index(trayicons, item_t, i).but);
/*
if (g_array_index(trayicons, item_t, i).buf) {
g_string_free(g_array_index(trayicons, item_t, i).buf, TRUE);
}
*/
}
g_array_free(trayicons, TRUE);
trayicons=g_array_new(FALSE, TRUE, sizeof(item_t));
if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store_trayicons), &iter)) {
do {
item_t item;
memset(&item, 0, sizeof(item));
gtk_tree_model_get(GTK_TREE_MODEL(store_trayicons), &iter,
ACTIVATION_FILE_COLUMN, &item.activation_file,
ICON_ACTIVE_FILE_COLUMN, &item.icon_active_file,
ICON_INACTIVE_FILE_COLUMN, &item.icon_inactive_file,
LEFT_CLICK_ACTIVE_COMMAND_COLUMN, &item.left_click_active_command,
LEFT_CLICK_INACTIVE_COMMAND_COLUMN, &item.left_click_inactive_command,
BLINK_COLUMN, &item.blink,
POPUP_COLUMN, &item.popup,
-1);
if (item.left_click_active_command != NULL &&
strlen(item.left_click_active_command) == 0) {
item.left_click_active_command = NULL;
}
if (item.left_click_inactive_command != NULL &&
strlen(item.left_click_inactive_command) == 0) {
item.left_click_inactive_command = NULL;
}
g_array_append_val(trayicons, item);
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store_trayicons), &iter));
}
setup_trayicons(0);
update_trayicons_real();
}
static GkrellmMonitor plugin_mon =
{
"Trayicons", /* Name, for config tab. */
0, /* Id, 0 if a plugin */
create_trayicons, /* The create function */
update_trayicons, /* The update function */
create_trayicons_tab, /* The config tab create function */
apply_trayicons_config, /* Apply the config function */
save_trayicons_config, /* Save user config */
load_trayicons_config, /* Load user config */
"trayicons", /* config keyword */
NULL, /* Undefined 2 */
NULL, /* Undefined 1 */
NULL, /* Undefined 0 */
MON_APM, /* Insert plugin before this monitor */
NULL, /* Handle if a plugin, filled in by GKrellM */
NULL /* path if a plugin, filled in by GKrellM */
};
GkrellmMonitor * gkrellm_init_plugin()
{
trayicons=g_array_new(FALSE,TRUE,sizeof(item_t));
monitor = &plugin_mon;
return &plugin_mon;
}
syntax highlighted by Code2HTML, v. 0.9.1