gnome-panel-properties.c 11.8 KB
Newer Older
1 2 3
/*   gnome-panel-properties: crapplet for global panel properties
 *
 *   Copyright (C) 1999 Free Software Foundation
4
 *   Copyright 2000 Helix Code, Inc.
5
 *   Copyright 2000 Eazel, Inc.
6 7
 *   Authors: George Lebl <jirka@5z.com>
 *            Jacob Berkman <jacob@helixcode.com>
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include <config.h>
26
#include <libgnome/libgnome.h>
27
#include <libgnomeui/libgnomeui.h>
28 29 30
#include <gtk/gtk.h>
#include <glade/glade.h>

31 32
#include <gdk/gdkx.h>
#include "global-keys.h"
33
#include "panel-util.h"
34

35
#include <libart_lgpl/art_misc.h>
George Lebl's avatar
George Lebl committed
36
#include <libart_lgpl/art_affine.h>
37 38 39 40
#include <libart_lgpl/art_rgb_affine.h>
#include <libart_lgpl/art_rgb_rgba_affine.h>
#include <libart_lgpl/art_filterlevel.h>
#include <libart_lgpl/art_alphagamma.h>
George Lebl's avatar
George Lebl committed
41

42 43
#include <gconf/gconf-client.h>

44 45 46 47 48 49
/* Just so we can link with panel-util.c for the convert keys stuff*/
GSList *applets;

/* Ugly globals to help reduce code size */
GladeXML *glade_gui;
GConfClient *gconf_client;
50

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
/*
 * GEGL Wants Winners,
 * GEGL Wants Solutions,
 * GEGL Wants TV,
 * GEGL Wants Repeated Code...
 *
 * See rgb-stuff.c.
 */

void transform_pixbuf(guchar *dst, int x0, int y0, int x1, int y1, int drs,
                      GdkPixbuf *pixbuf, double affine[6],
                      int level, ArtAlphaGamma *ag);

void transform_pixbuf(guchar *dst, int x0, int y0, int x1, int y1, int drs,
                      GdkPixbuf *pixbuf, double affine[6],
                      int level, ArtAlphaGamma *ag)
{
        gint w, h, rs;

        rs = gdk_pixbuf_get_rowstride(pixbuf);
        h =  gdk_pixbuf_get_height(pixbuf);
        w =  gdk_pixbuf_get_width(pixbuf);

        if (gdk_pixbuf_get_has_alpha(pixbuf)) {
                art_rgb_rgba_affine(dst, x0, y0, x1, y1, drs,
                                    gdk_pixbuf_get_pixels(pixbuf),
                                    w, h, rs, affine, level, ag);
        } else {
                art_rgb_affine(dst, x0, y0, x1, y1, drs,
                               gdk_pixbuf_get_pixels(pixbuf),
                               w, h, rs, affine, level, ag);
        }
}

85
#include "nothing.cP"
86

87 88
static GtkWidget *grab_dialog;

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
static gboolean 
is_modifier (guint keycode)
{
	gint i;
	gint map_size;
	XModifierKeymap *mod_keymap;
	gboolean retval = FALSE;

	mod_keymap = XGetModifierMapping (gdk_display);

	map_size = 8 * mod_keymap->max_keypermod;
	i = 0;
	while (i < map_size) {
		
		if (keycode == mod_keymap->modifiermap[i]) {
			retval = TRUE;
			break;
		}
		++i;
	}

	XFreeModifiermap (mod_keymap);

	return retval;
}

115
static GdkFilterReturn
116
grab_key_filter (GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
117 118
{
	XEvent *xevent = (XEvent *)gdk_xevent;
119 120
	GtkEntry *entry;
	char *key;
121 122 123
	guint keycode, state;
	char buf[10];
	KeySym keysym;
124

125
	if (xevent->type != KeyPress && xevent->type != KeyRelease)
126 127
		return GDK_FILTER_CONTINUE;
	
128
	entry = GTK_ENTRY (data);
129

130 131 132 133 134
	keycode = xevent->xkey.keycode;

	if (is_modifier (keycode))
		return GDK_FILTER_CONTINUE;

135
	state = xevent->xkey.state & USED_MODS;
136 137 138 139 140

	XLookupString (&xevent->xkey, buf, 0, &keysym, NULL);
  
	key = convert_keysym_state_to_string (keysym,
					      state);
141

142 143
	gtk_entry_set_text (entry, key != NULL ? key : "");
	g_free (key);
144 145 146

	gdk_keyboard_ungrab (GDK_CURRENT_TIME);
	gtk_widget_destroy (grab_dialog);
147
	gdk_window_remove_filter (GDK_ROOT_PARENT (),
148 149 150 151 152 153 154 155 156 157 158 159 160 161
				  grab_key_filter, data);

	return GDK_FILTER_REMOVE;
}

static void
grab_button_pressed (GtkButton *button, gpointer data)
{
	GtkWidget *frame;
	GtkWidget *box;
	GtkWidget *label;
	grab_dialog = gtk_window_new (GTK_WINDOW_POPUP);


162
	gdk_keyboard_grab (GDK_ROOT_PARENT(), FALSE, GDK_CURRENT_TIME);
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
	gdk_window_add_filter (GDK_ROOT_PARENT(), grab_key_filter, data);

	gtk_window_set_policy (GTK_WINDOW (grab_dialog), FALSE, FALSE, TRUE);
	gtk_window_set_position (GTK_WINDOW (grab_dialog), GTK_WIN_POS_CENTER);
	gtk_window_set_modal (GTK_WINDOW (grab_dialog), TRUE);

	frame = gtk_frame_new (NULL);
	gtk_container_add (GTK_CONTAINER (grab_dialog), frame);

	box = gtk_hbox_new (0, 0);
	gtk_container_set_border_width (GTK_CONTAINER (box), 20);
	gtk_container_add (GTK_CONTAINER (frame), box);

	label = gtk_label_new (_("Press a key..."));
	gtk_container_add (GTK_CONTAINER (box), label);
	
	gtk_widget_show_all (grab_dialog);
	return;
181
}
182

183
static void
184
update_sensitive_for_checkbox(gchar *key, int checked)
185
{
186 187 188 189 190 191 192 193
	GtkWidget *associate = NULL;

	if (strcmp(key,"/apps/panel/global/enable-animations") == 0)
                associate = glade_xml_get_widget(glade_gui,"animation-vbox");
        if (strcmp(key,"/apps/panel/global/enable-key-bindings") == 0)
                associate = glade_xml_get_widget(glade_gui,"kb-table");
        if (associate !=NULL)
                gtk_widget_set_sensitive(associate,checked);
194 195
}

196
static void
197
checkbox_clicked (GtkWidget *widget, gpointer data)
198
{
199 200
	int checked = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
	gchar *key = (gchar*)data;
201

202 203
	gconf_client_set_bool(gconf_client,key,checked,NULL);
	update_sensitive_for_checkbox(key, checked);
204 205 206
}

static void
207
option_menu_changed (GtkWidget *widget, gpointer data)
208
{
209 210 211
	gchar *key = (gchar *)data;

	gconf_client_set_int(gconf_client,key,
212 213 214 215
		gtk_option_menu_get_history(GTK_OPTION_MENU(widget)),NULL);	
}

static void
216
spin_button_changed (GtkWidget *widget, gpointer data)
217
{
218 219 220
	gchar *key = (gchar *)data;

	gconf_client_set_int(gconf_client,key,
221 222 223 224
		gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget)),NULL);
}

static void
225
entry_changed (GtkWidget *widget, gpointer data)
226
{
227 228 229 230
        gchar *key = (gchar *)data;

        gconf_client_set_string(gconf_client,key,
                gtk_entry_get_text(GTK_ENTRY(widget)),NULL);
231 232
}

233
static void
234
load_checkboxes (void)
235
{
236
	gchar* checkboxes[] = {"drawer-autoclose", "auto-raise-panel",
237
        	"enable-animations", "enable-key-bindings",
238
		"auto-update-menus", NULL };
239
	int i = 0;
240 241

	while(checkboxes[i]!=NULL){
242 243 244 245
		GtkWidget *checkbox;
		gchar *key;
		int checked;
		checkbox= glade_xml_get_widget(glade_gui,checkboxes[i]);
246
		key = g_strdup_printf("/apps/panel/global/%s",checkboxes[i]);
247
		checked = gconf_client_get_bool(gconf_client,key,NULL);
248
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), 
249
			checked);
250 251 252 253
		g_signal_connect_data(G_OBJECT(checkbox),"clicked",
			G_CALLBACK(checkbox_clicked), key,
			(GClosureNotify)g_free, 
			0 /* connect_flags */);
254
		update_sensitive_for_checkbox(key, checked);
255 256
		i++;
	}
257 258 259
}

static void
260
load_option_menus (void)
261
{
262 263 264 265 266 267 268 269 270 271 272 273
	gchar *optionmenus[] = {"panel-animation-speed", "panel-window-layer",
				 NULL };
	int i = 0;

	while(optionmenus[i]!=NULL){
		GtkWidget *option;
		gchar *key;

        	option = glade_xml_get_widget(glade_gui,optionmenus[i]);
        	key = g_strdup_printf("/apps/panel/global/%s",optionmenus[i]);
        	gtk_option_menu_set_history(GTK_OPTION_MENU(option),
                	gconf_client_get_int(gconf_client,key,NULL));
274 275 276 277 278
        	g_signal_connect_data (G_OBJECT (option), "changed",
				       G_CALLBACK (option_menu_changed),
				       key,
				       (GClosureNotify)g_free,
				       0 /* connect_flags */);
279 280
		i++;
	}
281 282 283
}

static void
284
load_spin_buttons (void)
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
{
	/* keep the spin buttons and their associated adjustment in sync */
	gchar *spinbuttons[] = {"panel-hide-delay", "panel-show-delay", NULL };
	GtkAdjustment *adjustments[] = {GTK_ADJUSTMENT(gtk_adjustment_new(30.0,
						30.0,3000.0,10.0,10.0,0.0)),
				        GTK_ADJUSTMENT(gtk_adjustment_new(0.0,
						0.0, 3000.0,10.0,10.0,0.0))
					};
        int i = 0;

        while(spinbuttons[i]!=NULL){
		GtkWidget *spin_button;
		gchar* key;

        	spin_button = glade_xml_get_widget(glade_gui,spinbuttons[i]);
        	gtk_spin_button_configure(GTK_SPIN_BUTTON(spin_button),
                	adjustments[i],10.0,0);
		key = g_strdup_printf("/apps/panel/global/%s",spinbuttons[i]);
        	gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button),
                	(double)gconf_client_get_int(gconf_client, key, NULL));
305 306 307 308 309
        	g_signal_connect_data (G_OBJECT (spin_button), "value-changed",
				       G_CALLBACK (spin_button_changed),
				       key,
				       (GClosureNotify)g_free,
				       0 /* connect_flags */);
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
		i++;
        }
}

static void
load_key_bindings()
{
        gchar *entries[] = {"menu-key", "run-key", NULL };
        int i = 0;

        while(entries[i]!=NULL){
                GtkWidget *button, *entry;
		gchar *button_name, *key;

                entry = glade_xml_get_widget(glade_gui,entries[i]);
		key = g_strdup_printf("/apps/panel/global/%s",entries[i]);
326 327
		gtk_entry_set_text(GTK_ENTRY(entry),
			gconf_client_get_string(gconf_client, key, NULL));
328 329 330 331
		button_name = g_strdup_printf("grab-%s", entries[i]);
		button = glade_xml_get_widget(glade_gui, button_name);
                g_signal_connect(G_OBJECT(button),"clicked",
                        G_CALLBACK(grab_button_pressed), entry);
332 333 334 335 336
        	g_signal_connect_data (G_OBJECT (entry), "changed",
				       G_CALLBACK (entry_changed),
				       key,
				       (GClosureNotify)g_free,
				       0 /* connect_flags */);
337
                i++;
338
                g_free (button_name);
339 340 341 342 343 344 345 346 347 348 349 350 351 352
        }
}

static void
load_config_into_gui()
{
	load_checkboxes();
	load_option_menus();
	load_spin_buttons();
	load_key_bindings();
}

static void
setup_the_ui(GtkWidget *main_window)
353
{
354 355 356 357 358
	gchar *glade_file;
	GtkWidget *notebook;

	glade_file = GLADEDIR "/gnome-panel-properties.glade2";

359 360
	glade_gui = glade_xml_new(glade_file, "main_notebook",NULL);
	if (!glade_gui) {
361 362 363
		g_warning("Error loading `%s'",glade_file);
		return;
	}
364
	glade_xml_signal_autoconnect(glade_gui);
365

366
	notebook=glade_xml_get_widget(glade_gui,"main_notebook");
367

368 369 370
	g_signal_connect (G_OBJECT (notebook), "event",
                          G_CALLBACK (config_event),
                          notebook);
371

372 373 374
	gtk_box_pack_start(GTK_BOX(GTK_DIALOG(main_window)->vbox),notebook,
		TRUE,TRUE,0);

375
	load_config_into_gui();
376 377 378
}

static void
379
main_dialog_response(GtkWindow *window, int button, gpointer data)
380
{
381 382 383 384 385 386 387
	switch (button) {
		case GTK_RESPONSE_OK:
			gtk_main_quit();
			break;
		default:
			break;
	}
388 389 390 391 392
}

int
main (int argc, char **argv)
{
393 394
  	GtkWidget *main_window;

395
	bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR);
396
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
397
	textdomain(GETTEXT_PACKAGE);
398

399 400 401 402 403 404
	gnome_program_init("gnome-panel-properties",VERSION,
                LIBGNOMEUI_MODULE, argc, argv,
		GNOME_PROGRAM_STANDARD_PROPERTIES, NULL);

  	main_window = gtk_dialog_new();

405 406
	gtk_dialog_add_button (GTK_DIALOG(main_window),
		GTK_STOCK_OK, GTK_RESPONSE_OK);
407

408 409 410 411 412
	gtk_signal_connect(GTK_OBJECT(main_window), "response",
        	GTK_SIGNAL_FUNC(main_dialog_response), main_window);

	g_signal_connect(G_OBJECT(main_window), "destroy",
		G_CALLBACK(gtk_main_quit),NULL);
413

414 415
	gconf_client = gconf_client_get_default();

416
	/* Ahhh, yes the infamous commie mode, don't allow running of this,
417
	 * just display a label */
418

419 420
	if(gconf_client_get_bool(gconf_client,
		"/apps/panel/global/lock-down",NULL)) 
421 422
	{
		GtkWidget *label;
423 424

		label = gtk_label_new (_("The system administrator has "
425
					 "disallowed\n modification of the "
426
					 "panel configuration"));
427 428
		gtk_box_pack_start (GTK_BOX(GTK_DIALOG(main_window)->vbox),
			label,TRUE,TRUE,0);
429

430 431 432 433
		gtk_widget_set_usize(main_window,350,350);
	}
	else
	{
434
		setup_the_ui(main_window);
435
	}
436

437 438
	gtk_window_set_title(GTK_WINDOW(main_window),
		_("Panel Global Properties"));
439

440
	gtk_widget_show_all(main_window);
441

442
	gtk_main();
443 444 445

	return 0;
}