~ubuntu-branches/ubuntu/oneiric/gnome-panel/oneiric

« back to all changes in this revision

Viewing changes to applets/fish/fish.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher, Sebastien Bacher, Jeremy Bicha
  • Date: 2011-05-30 11:04:49 UTC
  • mfrom: (1.13.10 upstream) (2.2.5 experimental)
  • Revision ID: james.westby@ubuntu.com-20110530110449-hinl17kxkcefjw6x
Tags: 1:3.0.2-0ubuntu1
[ Sebastien Bacher ]
* New upstream version
* debian/control.in:
  - the new libgweather version is in oneiric, use it
  - drop the python and python-gconf depends, 
    they were added for gnome-panel-add which is still using gconf and buggy
* debian/gnome-panel-data.install:
  - don't install the apport hook, it's only getting gconf datas which 
    doesn't work since gnome-panel uses gsettings
* debian/patches/90_build_fixes.patch:
  - restore build fix from git not applied in the new serie
* debian/patches/01_panel_submenus.patch:
  - don't take that Debian diff, the .menus use the upstream naming in Ubuntu
* debian/patches/06_no_resize_grip.patch:
  - dropped, the issue is fixed in the new version
* debian/patches/50_fix-potfiles.patch:
  - dropped, the issue is fixed in the new version
* debian/watch:
  - track unstable series as well

Drop those delta, since gnome-panel is not the default Ubuntu session now we
can go back to an experience closer to the upstream one: 
* debian/control.in:
  - drop the indicators recommends, unity-2d is the ubuntu fallback session
    so we can get back to use an upstream config for gnome-panel and reduce
    the delta we carry
* debian/patches/04_default_panel_config.patch:
  - don't modify the upstream layout
* debian/patches/05_no_session_delay.patch:
  - no need to tweak the upstream session to optimize it
* debian/patches/16_compiz_workspace_switcher.patch:
  - go back to the upstream switcher behaviour    
* debian/patches/25_dynamic_fusa_detection.patch:
  - not needed since we use the upstream layout, could be ported if someone
    is wanting to do the work though
* debian/patches/30_disable-initial-animation.patch, debian/rules:
  - drop the --disable-initial-animation, that was some login optimization
    but since it's not the default desktop you should go back to the 
    upstream behaviour

[ Jeremy Bicha ]   
* New upstream version
* Merge from Debian experimental, remaining Ubuntu changes:
* debian/control:
  - Recommends gnome-settings-daemon which has the timezone polkit service
* debian/rules:
  - Update translations template.
* debian/gnome-panel-data.install:
  - Install apport hook
  - Install the "About Ubuntu" menu item.
* debian/patches/01_layout.patch:
  - Disabled, Help & About Ubuntu don't fit as well in Gnome Panel 3
* debian/patches/01_panel_submenus.patch.
  - Dropped
* debian/patches/03_dnd_places_link.patch:
  - Disabled, when using Drag'n'Drop from Places menu, install a link launcher
    (.desktop file) instead of copying the entire directory.
* debian/patches/17_about-ubuntu-translation.patch:
  - List ubuntu-about.desktop for translation.
* debian/patches/40_unset_menuproxy.patch:
  - Make sure gnome-panel and the applets don't pick up menu proxies.
* debian/patches/50_fix-potfiles.patch
  - Fix i18n
* debian/patches/85_disable_shutdown_on_ltsp.patch:
  - Suppress the shutdown option in the panel if LTSP_CLIENT is set.
* debian/patches/71_change_bookmark_submenu_limit_value.patch
  - Dropped, picked up by Debian
* debian/patches/18_lockdown_lock_editor.patch:
* debian/patches/90_git_wnck_show_realize.patch:
* debian/patches/90_fix_linking_DSO_link.patch:
* debian/patches/91_gir_annotations.patch
* debian/patches/92_git_calendar_day.patch
* debian/patches/92_git_fix_applets_in_multiscreen.patch:
  - Dropped, applied upstream
* debian/watch:
  - watch unstable versions

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <time.h>
32
32
 
33
33
#include <cairo.h>
 
34
#include <cairo-xlib.h>
34
35
 
35
36
#include <glib/gi18n.h>
36
37
#include <glib-object.h>
38
39
#include <gdk/gdkkeysyms.h>
39
40
 
40
41
#include <panel-applet.h>
41
 
#include <panel-applet-gconf.h>
42
 
#include <gconf/gconf-client.h>
43
42
 
44
43
#define FISH_APPLET(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), \
45
44
                        fish_applet_get_type(),          \
49
48
 
50
49
#define FISH_ICON "gnome-panel-fish"
51
50
 
52
 
#define N_FISH_PREFS 6
53
 
 
54
 
#define LOCKDOWN_COMMANDLINE_KEY "/desktop/gnome/lockdown/disable_command_line"
55
 
#define N_FISH_LOCKDOWN 1
56
 
 
57
 
#define N_FISH_LISTENERS (N_FISH_PREFS + N_FISH_LOCKDOWN)
 
51
#define FISH_SCHEMA      "org.gnome.gnome-panel.applet.fish"
 
52
#define FISH_NAME_KEY    "name"
 
53
#define FISH_IMAGE_KEY   "image"
 
54
#define FISH_COMMAND_KEY "command"
 
55
#define FISH_SPEED_KEY   "speed"
 
56
#define FISH_ROTATE_KEY  "rotate"
 
57
#define FISH_NAME_DEFAULT  "Wanda"
 
58
#define FISH_IMAGE_DEFAULT "wanda.fish"
 
59
#define FISH_SPEED_DEFAULT 0.3
 
60
 
 
61
#define LOCKDOWN_SCHEMA          "org.gnome.desktop.lockdown"
 
62
#define LOCKDOWN_COMMANDLINE_KEY "disable-command-line"
58
63
 
59
64
typedef struct {
60
65
        PanelApplet        applet;
61
66
 
62
 
        GConfClient       *client;
 
67
        GSettings         *settings;
 
68
        GSettings         *lockdown_settings;
63
69
 
64
70
        char              *name;
65
71
        char              *image;
73
79
        GtkWidget         *frame;
74
80
        GtkWidget         *drawing_area;
75
81
        GtkRequisition     requisition;
76
 
        GdkRectangle       prev_allocation;
77
 
        GdkPixmap         *pixmap;
 
82
        GtkAllocation      prev_allocation;
 
83
        cairo_surface_t   *surface;
78
84
        guint              timeout;
79
85
        int                current_frame;
80
86
        gboolean           in_applet;
81
87
 
82
88
        GdkPixbuf         *pixbuf;
83
89
 
84
 
        GtkWidget         *about_dialog;
85
 
 
86
90
        GtkWidget         *preferences_dialog;
87
 
        GtkWidget         *name_entry;
88
 
        GtkWidget         *command_label;
89
 
        GtkWidget         *command_entry;
90
 
        GtkWidget         *preview_image;
91
 
        GtkWidget         *image_chooser;
92
 
        GtkWidget         *frames_spin;
93
 
        GtkWidget         *speed_spin;
94
 
        GtkWidget         *rotate_toggle;
95
91
 
96
92
        GtkWidget         *fortune_dialog;
97
93
        GtkWidget         *fortune_view;
103
99
        GIOChannel        *io_channel;
104
100
 
105
101
        gboolean           april_fools;
106
 
 
107
 
        guint              listeners [N_FISH_LISTENERS];
108
102
} FishApplet;
109
103
 
110
104
typedef struct {
113
107
 
114
108
 
115
109
static gboolean load_fish_image          (FishApplet *fish);
116
 
static void     update_pixmap            (FishApplet *fish);
 
110
static void     update_surface           (FishApplet *fish);
117
111
static void     something_fishy_going_on (FishApplet *fish,
118
112
                                          const char *message);
119
113
static void     display_fortune_dialog   (FishApplet *fish);
199
193
}
200
194
 
201
195
static void
202
 
name_value_changed (GtkEntry   *entry,
203
 
                    FishApplet *fish)
204
 
{
205
 
        const char *text;
206
 
 
207
 
        text = gtk_entry_get_text (entry);
208
 
 
209
 
        if (!text || !text [0])
210
 
                return;
211
 
 
212
 
        panel_applet_gconf_set_string (
213
 
                PANEL_APPLET (fish), "name", text, NULL);
214
 
}
215
 
 
216
 
static void
217
 
image_value_changed (GtkFileChooser *chooser,
218
 
                     FishApplet     *fish)
219
 
{       char *path;
220
 
        char *image;
221
 
        char *path_gconf;
222
 
 
223
 
        path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
224
 
 
225
 
        if (!path || !path[0]) {
226
 
                g_free (path);
227
 
                return;
228
 
        }
229
 
 
230
 
        path_gconf = get_image_path (fish);
231
 
        if (!strcmp (path, path_gconf)) {
232
 
                g_free (path);
233
 
                g_free (path_gconf);
234
 
                return;
235
 
        }
236
 
        g_free (path_gconf);
237
 
 
238
 
        if (!strncmp (path, FISH_ICONDIR, strlen (FISH_ICONDIR))) {
239
 
                image = path + strlen (FISH_ICONDIR);
240
 
                while (*image && *image == G_DIR_SEPARATOR)
241
 
                        image++;
242
 
        } else
243
 
                image = path;
244
 
 
245
 
        panel_applet_gconf_set_string (PANEL_APPLET (fish), "image",
246
 
                                       image, NULL);
247
 
 
248
 
        g_free (path);
249
 
}
250
 
 
251
 
static void
252
196
command_value_changed (GtkEntry   *entry,
253
197
                       FishApplet *fish)
254
198
{
257
201
        text = gtk_entry_get_text (entry);
258
202
 
259
203
        if (!text || !text [0]) {
260
 
                panel_applet_gconf_set_string (PANEL_APPLET (fish), 
261
 
                                               "command", "", NULL);
 
204
                g_settings_set_string (fish->settings, FISH_COMMAND_KEY, "");
262
205
                return;
263
206
        }
264
207
 
291
234
                }
292
235
        }
293
236
 
294
 
        panel_applet_gconf_set_string (
295
 
                PANEL_APPLET (fish), "command", text, NULL);
296
 
}
297
 
 
298
 
static void
299
 
n_frames_value_changed (GtkSpinButton *button,
300
 
                        FishApplet    *fish)
301
 
{
302
 
        panel_applet_gconf_set_int (
303
 
                        PANEL_APPLET (fish), "frames",
304
 
                        gtk_spin_button_get_value_as_int (button), NULL);
305
 
}
306
 
 
307
 
static void
308
 
speed_value_changed (GtkSpinButton *button,
309
 
                     FishApplet    *fish)
310
 
{
311
 
        panel_applet_gconf_set_float (
312
 
                        PANEL_APPLET (fish), "speed",
313
 
                        gtk_spin_button_get_value (button), NULL);
314
 
}
315
 
 
316
 
static void
317
 
rotate_value_changed (GtkToggleButton *toggle,
318
 
                      FishApplet      *fish)
319
 
{
320
 
        panel_applet_gconf_set_bool (
321
 
                        PANEL_APPLET (fish), "rotate",
322
 
                        gtk_toggle_button_get_active (toggle), NULL);
 
237
        g_settings_set_string (fish->settings, FISH_COMMAND_KEY, text);
323
238
}
324
239
 
325
240
static gboolean
344
259
        gtk_widget_hide (fish->preferences_dialog);
345
260
}
346
261
 
347
 
static void
348
 
setup_sensitivity (FishApplet *fish,
349
 
                   GtkBuilder *builder,
350
 
                   const char *wid,
351
 
                   const char *label,
352
 
                   const char *label_post,
353
 
                   const char *key)
354
 
{
355
 
        PanelApplet *applet = (PanelApplet *) fish;
356
 
        char *fullkey;
357
 
        GtkWidget *w;
358
 
 
359
 
        fullkey = panel_applet_gconf_get_full_key (applet, key);
360
 
 
361
 
        if (gconf_client_key_is_writable (fish->client, fullkey, NULL)) {
362
 
                g_free (fullkey);
363
 
                return;
364
 
        }
365
 
        g_free (fullkey);
366
 
 
367
 
        w = GTK_WIDGET (gtk_builder_get_object (builder, wid));
368
 
        g_assert (w != NULL);
369
 
        gtk_widget_set_sensitive (w, FALSE);
370
 
 
371
 
        if (label != NULL) {
372
 
                w = GTK_WIDGET (gtk_builder_get_object (builder, label));
373
 
                g_assert (w != NULL);
374
 
                gtk_widget_set_sensitive (w, FALSE);
375
 
        }
376
 
        if (label_post != NULL) {
377
 
                w = GTK_WIDGET (gtk_builder_get_object (builder, label_post));
378
 
                g_assert (w != NULL);
379
 
                gtk_widget_set_sensitive (w, FALSE);
380
 
        }
381
 
 
382
 
}
383
 
 
384
 
static void
385
 
chooser_preview_update (GtkFileChooser *file_chooser,
386
 
                        gpointer data)
387
 
{
388
 
        GtkWidget *preview;
389
 
        char      *filename;
390
 
        GdkPixbuf *pixbuf;
391
 
        gboolean   have_preview;
392
 
 
393
 
        preview = GTK_WIDGET (data);
394
 
        filename = gtk_file_chooser_get_preview_filename (file_chooser);
395
 
 
396
 
        if (filename == NULL)
397
 
                return;
398
 
 
399
 
        pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
400
 
        have_preview = (pixbuf != NULL);
401
 
        g_free (filename);
402
 
 
403
 
        gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
404
 
        if (pixbuf)
405
 
                g_object_unref (pixbuf);
406
 
 
407
 
        gtk_file_chooser_set_preview_widget_active (file_chooser,
408
 
                                                    have_preview);
409
 
}
410
 
 
411
262
static void 
412
263
display_preferences_dialog (GtkAction  *action,
413
264
                            FishApplet *fish)
414
265
{
415
 
        GtkBuilder    *builder;
416
 
        GError        *error;
417
 
        GtkWidget     *button;
418
 
        GtkFileFilter *filter;
419
 
        GtkWidget     *chooser_preview;
420
 
        char          *path;
 
266
        GtkBuilder *builder;
 
267
        GError     *error;
 
268
        GtkWidget  *box;
 
269
        GtkWidget  *name_entry;
 
270
        GtkWidget  *command_entry;
 
271
        GtkWidget  *speed_spin;
 
272
        GtkWidget  *rotate_toggle;
 
273
        GtkWidget  *button;
421
274
 
422
275
        if (fish->preferences_dialog) {
423
276
                gtk_window_set_screen (GTK_WINDOW (fish->preferences_dialog),
449
302
        gtk_dialog_set_default_response (
450
303
                GTK_DIALOG (fish->preferences_dialog), GTK_RESPONSE_OK);
451
304
 
452
 
        fish->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
453
 
        gtk_entry_set_text (GTK_ENTRY (fish->name_entry), fish->name);
454
 
 
455
 
        g_signal_connect (fish->name_entry, "changed",
456
 
                          G_CALLBACK (name_value_changed), fish);
457
 
 
458
 
        setup_sensitivity (fish, builder,
459
 
                           "name_entry" /* wid */,
460
 
                           "name_label" /* label */,
461
 
                           NULL /* label_post */,
462
 
                           "name" /* key */);
463
 
 
464
 
        fish->preview_image = GTK_WIDGET (gtk_builder_get_object (builder, "preview_image"));
465
 
        if (fish->pixbuf)
466
 
                gtk_image_set_from_pixbuf (GTK_IMAGE (fish->preview_image),
467
 
                                           fish->pixbuf);
468
 
 
469
 
        fish->image_chooser =  GTK_WIDGET (gtk_builder_get_object (builder, "image_chooser"));
470
 
        filter = gtk_file_filter_new ();
471
 
        gtk_file_filter_set_name (filter, _("Images"));
472
 
        gtk_file_filter_add_pixbuf_formats (filter);
473
 
        gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (fish->image_chooser),
474
 
                                     filter);
475
 
        gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (fish->image_chooser),
476
 
                                     filter);
477
 
        chooser_preview = gtk_image_new ();
478
 
        gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (fish->image_chooser),
479
 
                                             chooser_preview);
480
 
        g_signal_connect (fish->image_chooser, "update-preview",
481
 
                          G_CALLBACK (chooser_preview_update), chooser_preview);
482
 
        path = get_image_path (fish);
483
 
        gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (fish->image_chooser),
484
 
                                       path);
485
 
        g_free (path);
486
 
 
487
 
        g_signal_connect (fish->image_chooser, "selection-changed",
488
 
                          G_CALLBACK (image_value_changed), fish);
489
 
 
490
 
        setup_sensitivity (fish, builder,
491
 
                           "image_chooser" /* wid */,
492
 
                           "image_label" /* label */,
493
 
                           NULL /* label_post */,
494
 
                           "image" /* key */);
495
 
 
496
 
        fish->command_label = GTK_WIDGET (gtk_builder_get_object (builder, "command_label"));
497
 
        fish->command_entry = GTK_WIDGET (gtk_builder_get_object (builder, "command_entry"));
498
 
        gtk_entry_set_text (GTK_ENTRY (fish->command_entry), fish->command);
499
 
 
500
 
        g_signal_connect (fish->command_entry, "changed",
 
305
        name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
 
306
        box = GTK_WIDGET (gtk_builder_get_object (builder, "name_box"));
 
307
        g_settings_bind (fish->settings, FISH_NAME_KEY,
 
308
                         name_entry, "text",
 
309
                         G_SETTINGS_BIND_DEFAULT);
 
310
        g_settings_bind_writable (fish->settings, FISH_NAME_KEY,
 
311
                                  box, "sensitive",
 
312
                                  FALSE);
 
313
 
 
314
        command_entry = GTK_WIDGET (gtk_builder_get_object (builder, "command_entry"));
 
315
        box = GTK_WIDGET (gtk_builder_get_object (builder, "command_box"));
 
316
        g_settings_bind (fish->settings, FISH_COMMAND_KEY,
 
317
                         command_entry, "text",
 
318
                         G_SETTINGS_BIND_GET);
 
319
        g_signal_connect (command_entry, "changed",
501
320
                          G_CALLBACK (command_value_changed), fish);
502
 
 
503
 
        setup_sensitivity (fish, builder,
504
 
                           "command_entry" /* wid */,
505
 
                           "command_label" /* label */,
506
 
                           NULL /* label_post */,
507
 
                           "command" /* key */);
508
 
 
509
 
        if (gconf_client_get_bool (fish->client,
510
 
                                   LOCKDOWN_COMMANDLINE_KEY,
511
 
                                   NULL)) {
512
 
                gtk_widget_set_sensitive (fish->command_label, FALSE);
513
 
                gtk_widget_set_sensitive (fish->command_entry, FALSE);
514
 
        }
515
 
 
516
 
        fish->frames_spin = GTK_WIDGET (gtk_builder_get_object (builder, "frames_spin"));
517
 
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (fish->frames_spin),
518
 
                                   fish->n_frames);
519
 
 
520
 
        g_signal_connect (fish->frames_spin, "value_changed",
521
 
                          G_CALLBACK (n_frames_value_changed), fish);
522
 
 
523
 
        setup_sensitivity (fish, builder,
524
 
                           "frames_spin" /* wid */,
525
 
                           "frames_label" /* label */,
526
 
                           "frames_post_label" /* label_post */,
527
 
                           "frames" /* key */);
528
 
 
529
 
        fish->speed_spin = GTK_WIDGET (gtk_builder_get_object (builder, "speed_spin"));
530
 
        gtk_spin_button_set_value (GTK_SPIN_BUTTON (fish->speed_spin), fish->speed);
531
 
 
532
 
        g_signal_connect (fish->speed_spin, "value_changed",
533
 
                          G_CALLBACK (speed_value_changed), fish);
534
 
 
535
 
        setup_sensitivity (fish, builder,
536
 
                           "speed_spin" /* wid */,
537
 
                           "speed_label" /* label */,
538
 
                           "speed_post_label" /* label_post */,
539
 
                           "speed" /* key */);
540
 
 
541
 
        fish->rotate_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "rotate_toggle"));
542
 
        gtk_toggle_button_set_active (
543
 
                GTK_TOGGLE_BUTTON (fish->rotate_toggle), fish->rotate);
544
 
 
545
 
        g_signal_connect (fish->rotate_toggle, "toggled",
546
 
                          G_CALLBACK (rotate_value_changed), fish);
547
 
 
548
 
        setup_sensitivity (fish, builder,
549
 
                           "rotate_toggle" /* wid */,
550
 
                           NULL /* label */,
551
 
                           NULL /* label_post */,
552
 
                           "rotate" /* key */);
 
321
        g_settings_bind_writable (fish->settings, FISH_COMMAND_KEY,
 
322
                                  box, "sensitive",
 
323
                                  FALSE);
 
324
 
 
325
        g_settings_bind (fish->lockdown_settings, LOCKDOWN_COMMANDLINE_KEY,
 
326
                         box, "visible",
 
327
                         G_SETTINGS_BIND_DEFAULT|G_SETTINGS_BIND_INVERT_BOOLEAN);
 
328
 
 
329
        speed_spin = GTK_WIDGET (gtk_builder_get_object (builder, "speed_spin"));
 
330
        box = GTK_WIDGET (gtk_builder_get_object (builder, "speed_box"));
 
331
        g_settings_bind (fish->settings, FISH_SPEED_KEY,
 
332
                         speed_spin, "value",
 
333
                         G_SETTINGS_BIND_DEFAULT);
 
334
        g_settings_bind_writable (fish->settings, FISH_SPEED_KEY,
 
335
                                  box, "sensitive",
 
336
                                  FALSE);
 
337
 
 
338
        rotate_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "rotate_toggle"));
 
339
        g_settings_bind (fish->settings, FISH_ROTATE_KEY,
 
340
                         rotate_toggle, "active",
 
341
                         G_SETTINGS_BIND_DEFAULT);
553
342
 
554
343
        g_signal_connect (fish->preferences_dialog, "delete_event",
555
344
                          G_CALLBACK (delete_event), fish);
570
359
}
571
360
 
572
361
static void
573
 
display_help_dialog (GtkAction  *action,
574
 
                     FishApplet *fish)
575
 
{
576
 
        show_help (fish, NULL);
577
 
}
578
 
 
579
 
static void
580
 
display_about_dialog (GtkAction  *action,
581
 
                      FishApplet *fish)
582
 
{
583
 
        const char *author_format = _("%s the Fish");
584
 
        const char *about_format = _("%s has no use what-so-ever. "
585
 
                                     "It only takes up disk space and "
586
 
                                     "compilation time, and if loaded it also "
587
 
                                     "takes up precious panel space and "
588
 
                                     "memory. Anybody found using it should be "
589
 
                                     "promptly sent for a psychiatric "
590
 
                                     "evaluation.");
591
 
        const char  *documenters [] = {
592
 
                "Telsa Gwynne <hobbit@aloss.ukuu.org.uk>",
593
 
                "Sun GNOME Documentation Team <gdocteam@sun.com>",
594
 
                NULL
595
 
        };
596
 
 
597
 
        char        *authors [3];
598
 
        char        *descr;
599
 
 
600
 
        if (fish->about_dialog) {
601
 
                gtk_window_set_screen (GTK_WINDOW (fish->about_dialog),
602
 
                                       gtk_widget_get_screen (GTK_WIDGET (fish)));
603
 
                gtk_window_present (GTK_WINDOW (fish->about_dialog));
604
 
                return;
605
 
        }
606
 
 
607
 
        authors [0] = g_strdup_printf (author_format, fish->name);
608
 
        authors [1] = _("(with minor help from George)");
609
 
        authors [2] = NULL;
610
 
 
611
 
        descr = g_strdup_printf (about_format, fish->name);
612
 
                
613
 
        fish->about_dialog = gtk_about_dialog_new ();
614
 
        g_object_set (fish->about_dialog,
615
 
                      "program-name", _("Fish"),
616
 
                      "version", "3.4.7.4ac19",
617
 
                      "copyright", "Copyright \xc2\xa9 1998-2002 Free Software Foundation, Inc.",
618
 
                      "comments", descr,
619
 
                      "authors", (const char **) authors,
620
 
                      "documenters", documenters,
621
 
                      "translator-credits", _("translator-credits"),
622
 
                      "logo-icon-name", FISH_ICON,
623
 
                      NULL);
624
 
 
625
 
        g_free (descr);
626
 
        g_free (authors [0]);
627
 
 
628
 
        gtk_window_set_icon_name (GTK_WINDOW (fish->about_dialog), FISH_ICON);
629
 
        gtk_window_set_wmclass (
630
 
                GTK_WINDOW (fish->about_dialog), "fish", "Fish");
631
 
        gtk_window_set_screen (GTK_WINDOW (fish->about_dialog),
632
 
                               gtk_widget_get_screen (GTK_WIDGET (fish)));
633
 
 
634
 
        g_signal_connect (fish->about_dialog, "destroy",
635
 
                          G_CALLBACK (gtk_widget_destroyed),
636
 
                          &fish->about_dialog);
637
 
 
638
 
        g_signal_connect (fish->about_dialog, "response",
639
 
                          G_CALLBACK (gtk_widget_destroy),
640
 
                          NULL);
641
 
 
642
 
        gtk_widget_show (fish->about_dialog);
643
 
}
644
 
 
645
 
static void
646
362
set_ally_name_desc (GtkWidget  *widget,
647
363
                    FishApplet *fish)
648
364
{
872
588
        return (status != G_IO_STATUS_EOF);
873
589
}
874
590
 
 
591
/*
 
592
 * Set the DISPLAY variable, to be use by g_spawn_async.
 
593
 */
 
594
static void
 
595
set_environment (gpointer display)
 
596
{
 
597
        g_setenv ("DISPLAY", display, TRUE);
 
598
}
 
599
 
875
600
static void 
876
601
display_fortune_dialog (FishApplet *fish)
877
602
{
881
606
        const char  *charset;
882
607
        int          argc;
883
608
        char       **argv;
 
609
        GdkScreen   *screen;
 
610
        char        *display;
884
611
 
885
612
        /* if there is still a pipe, close it */
886
613
        if (fish->source_id)
908
635
 
909
636
                gtk_window_set_icon_name (GTK_WINDOW (fish->fortune_dialog),
910
637
                                          FISH_ICON);
911
 
                gtk_dialog_set_has_separator (
912
 
                        GTK_DIALOG (fish->fortune_dialog), FALSE);
913
638
 
914
639
                gtk_dialog_set_default_response (
915
640
                        GTK_DIALOG (fish->fortune_dialog), GTK_RESPONSE_CLOSE);
1000
725
 
1001
726
        clear_fortune_text (fish);
1002
727
 
1003
 
        gdk_spawn_on_screen_with_pipes (gtk_widget_get_screen (GTK_WIDGET (fish)),
1004
 
                                        NULL, argv, NULL,
1005
 
                                        G_SPAWN_SEARCH_PATH|G_SPAWN_STDERR_TO_DEV_NULL,
1006
 
                                        NULL, NULL, NULL, NULL, &output, NULL,
1007
 
                                        &error);
 
728
        screen = gtk_widget_get_screen (GTK_WIDGET (fish));
 
729
        display = gdk_screen_make_display_name (screen);
 
730
 
 
731
        g_spawn_async_with_pipes (NULL, /* working directory */
 
732
                                  argv,
 
733
                                  NULL, /* envp */
 
734
                                  G_SPAWN_SEARCH_PATH|G_SPAWN_STDERR_TO_DEV_NULL,
 
735
                                  set_environment,
 
736
                                  &display,
 
737
                                  NULL, /* child pid */
 
738
                                  NULL, /* stdin */
 
739
                                  &output,
 
740
                                  NULL, /* stderr */
 
741
                                  &error);
 
742
 
 
743
        g_free (display);
1008
744
 
1009
745
        if (error) {
1010
746
                char *message;
1045
781
        gtk_window_present (GTK_WINDOW (fish->fortune_dialog));
1046
782
}
1047
783
 
1048
 
static void
1049
 
name_changed_notify (GConfClient *client,
1050
 
                     guint        cnxn_id,
1051
 
                     GConfEntry  *entry,
1052
 
                     FishApplet  *fish)
1053
 
{
1054
 
        const char *value;
1055
 
 
1056
 
        if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
1057
 
                return;
1058
 
 
1059
 
        value = gconf_value_get_string (entry->value);
1060
 
 
1061
 
        if (!value [0] || (fish->name && !strcmp (fish->name, value)))
1062
 
                return;
1063
 
 
1064
 
        if (fish->name)
1065
 
                g_free (fish->name);
1066
 
        fish->name = g_strdup (value);
1067
 
 
1068
 
        update_fortune_dialog (fish);
1069
 
        set_tooltip (fish);
1070
 
        set_ally_name_desc (GTK_WIDGET (fish), fish);
1071
 
 
1072
 
        if (fish->name_entry &&
1073
 
            strcmp (gtk_entry_get_text (GTK_ENTRY (fish->name_entry)), fish->name))
1074
 
                gtk_entry_set_text (GTK_ENTRY (fish->name_entry), fish->name);
1075
 
}
1076
 
 
1077
 
static void
1078
 
image_changed_notify (GConfClient *client,
1079
 
                      guint        cnxn_id,
1080
 
                      GConfEntry  *entry,
1081
 
                      FishApplet  *fish)
1082
 
{
1083
 
        const char *value;
1084
 
 
1085
 
        if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
1086
 
                return;
1087
 
 
1088
 
        value = gconf_value_get_string (entry->value);
1089
 
 
1090
 
        if (!value [0] || (fish->image && !strcmp (fish->image, value)))
1091
 
                return;
1092
 
 
1093
 
        if (fish->image)
1094
 
                g_free (fish->image);
1095
 
        fish->image = g_strdup (value);
1096
 
 
1097
 
        load_fish_image (fish);
1098
 
        update_pixmap (fish);
1099
 
 
1100
 
        if (fish->image_chooser) {
1101
 
                char *path_gconf;
1102
 
                char *path_chooser;
1103
 
 
1104
 
                path_gconf = get_image_path (fish);
1105
 
                path_chooser = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (fish->image_chooser));
1106
 
                if (strcmp (path_gconf, path_chooser))
1107
 
                        gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (fish->image_chooser),
1108
 
                                                       path_gconf);
1109
 
 
1110
 
                g_free (path_gconf);
1111
 
                g_free (path_chooser);
1112
 
        }
1113
 
}
1114
 
 
1115
 
static void
1116
 
command_changed_notify (GConfClient *client,
1117
 
                        guint        cnxn_id,
1118
 
                        GConfEntry  *entry,
1119
 
                        FishApplet  *fish)
1120
 
{
1121
 
        const char *value;
1122
 
 
1123
 
        if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
1124
 
                return;
1125
 
        
1126
 
        value = gconf_value_get_string (entry->value);
1127
 
 
1128
 
        if (fish->command && !strcmp (fish->command, value))
1129
 
                return;
1130
 
 
1131
 
        if (fish->command)
1132
 
                g_free (fish->command);
1133
 
        fish->command = g_strdup (value);
1134
 
 
1135
 
        if (fish->command_entry &&
1136
 
            strcmp (gtk_entry_get_text (GTK_ENTRY (fish->command_entry)), fish->command))
1137
 
                gtk_entry_set_text (GTK_ENTRY (fish->command_entry), fish->command);
1138
 
}
1139
 
 
1140
 
static void
1141
 
n_frames_changed_notify (GConfClient *client,
1142
 
                         guint        cnxn_id,
1143
 
                         GConfEntry  *entry,
1144
 
                         FishApplet  *fish)
1145
 
{
1146
 
        int value;
1147
 
 
1148
 
        if (!entry->value || entry->value->type != GCONF_VALUE_INT)
1149
 
                return;
1150
 
 
1151
 
        value = gconf_value_get_int (entry->value);
1152
 
 
1153
 
        if (fish->n_frames == value)
1154
 
                return;
1155
 
 
1156
 
        fish->n_frames = value;
1157
 
 
1158
 
        if (fish->n_frames <= 0)
1159
 
                fish->n_frames = 1;
1160
 
 
1161
 
        update_pixmap (fish);
1162
 
 
1163
 
        if (fish->frames_spin &&
1164
 
            gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (fish->frames_spin)) != fish->n_frames)
1165
 
                gtk_spin_button_set_value (GTK_SPIN_BUTTON (fish->frames_spin), fish->n_frames);
1166
 
}
1167
 
 
1168
784
static char *
1169
785
get_location (void)
1170
786
{
1254
870
             tm->tm_mday != fools_day   ||
1255
871
             tm->tm_hour >= fools_hour_end)) {
1256
872
                fish->april_fools = FALSE;
1257
 
                update_pixmap (fish);
 
873
                update_surface (fish);
1258
874
        } else if (tm->tm_mon  == fools_month    &&
1259
875
                 tm->tm_mday == fools_day        &&
1260
876
                 tm->tm_hour >= fools_hour_start &&
1261
877
                 tm->tm_hour <= fools_hour_end) {
1262
878
                fish->april_fools = TRUE;
1263
 
                update_pixmap (fish);
 
879
                update_surface (fish);
1264
880
        }
1265
881
}
1266
882
 
1294
910
                                       fish);
1295
911
}
1296
912
 
1297
 
static void
1298
 
speed_changed_notify (GConfClient *client,
1299
 
                      guint        cnxn_id,
1300
 
                      GConfEntry  *entry,
1301
 
                      FishApplet  *fish)
1302
 
{
1303
 
        gdouble value;
1304
 
 
1305
 
        if (!entry->value || entry->value->type != GCONF_VALUE_FLOAT)
1306
 
                return;
1307
 
 
1308
 
        value = gconf_value_get_float (entry->value);
1309
 
 
1310
 
        if (fish->speed == value)
1311
 
                return;
1312
 
        fish->speed = value;
1313
 
 
1314
 
        setup_timeout (fish);
1315
 
 
1316
 
        if (fish->speed_spin &&
1317
 
            gtk_spin_button_get_value (GTK_SPIN_BUTTON (fish->frames_spin)) != fish->speed)
1318
 
                gtk_spin_button_set_value (GTK_SPIN_BUTTON (fish->speed_spin), fish->speed);
1319
 
}
1320
 
 
1321
 
static void
1322
 
rotate_changed_notify (GConfClient *client,
1323
 
                       guint        cnxn_id,
1324
 
                       GConfEntry  *entry,
1325
 
                       FishApplet  *fish)
1326
 
{
1327
 
        gboolean value;
1328
 
 
1329
 
        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
1330
 
                return;
1331
 
 
1332
 
        value = gconf_value_get_bool (entry->value);
1333
 
 
1334
 
        if (fish->rotate == value)
1335
 
                return;
1336
 
        fish->rotate = value;
1337
 
 
1338
 
        if (fish->orientation == PANEL_APPLET_ORIENT_LEFT ||
1339
 
            fish->orientation == PANEL_APPLET_ORIENT_RIGHT)
1340
 
                update_pixmap (fish);
1341
 
 
1342
 
        if (fish->rotate_toggle &&
1343
 
            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fish->rotate_toggle)) != fish->rotate)
1344
 
                gtk_toggle_button_set_active (
1345
 
                        GTK_TOGGLE_BUTTON (fish->rotate_toggle), fish->rotate);
1346
 
}
1347
 
 
1348
 
static void
1349
 
fish_disable_commande_line_notify (GConfClient *client,
1350
 
                                   guint        cnxn_id,
1351
 
                                   GConfEntry  *entry,
1352
 
                                   FishApplet  *fish)
1353
 
{
1354
 
        gboolean locked_down;
1355
 
 
1356
 
        if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
1357
 
                return;
1358
 
 
1359
 
        locked_down = !gconf_value_get_bool (entry->value);
1360
 
 
1361
 
        if (fish->command_label != NULL)
1362
 
                gtk_widget_set_sensitive (fish->command_label, locked_down);
1363
 
        if (fish->command_entry != NULL)
1364
 
                gtk_widget_set_sensitive (fish->command_entry, locked_down);
1365
 
}
1366
 
 
1367
 
static void
1368
 
setup_gconf (FishApplet *fish)
1369
 
{
1370
 
        PanelApplet *applet = (PanelApplet *) fish;
1371
 
        char        *key;
1372
 
        int          i = 0;
1373
 
 
1374
 
        key = panel_applet_gconf_get_full_key (applet, "name");
1375
 
        fish->listeners [i++] = gconf_client_notify_add (
1376
 
                                        fish->client, key,
1377
 
                                        (GConfClientNotifyFunc) name_changed_notify,
1378
 
                                        fish, NULL, NULL);
1379
 
        g_free (key);
1380
 
 
1381
 
        key = panel_applet_gconf_get_full_key (applet, "image");
1382
 
        fish->listeners [i++] = gconf_client_notify_add (
1383
 
                                        fish->client, key,
1384
 
                                        (GConfClientNotifyFunc) image_changed_notify,
1385
 
                                        fish, NULL, NULL);
1386
 
        g_free (key);
1387
 
 
1388
 
        key = panel_applet_gconf_get_full_key (applet, "command");
1389
 
        fish->listeners [i++] = gconf_client_notify_add (
1390
 
                                        fish->client, key,
1391
 
                                        (GConfClientNotifyFunc) command_changed_notify,
1392
 
                                        fish, NULL, NULL);
1393
 
        g_free (key);
1394
 
 
1395
 
        key = panel_applet_gconf_get_full_key (applet, "frames");
1396
 
        fish->listeners [i++] = gconf_client_notify_add (
1397
 
                                        fish->client, key,
1398
 
                                        (GConfClientNotifyFunc) n_frames_changed_notify,
1399
 
                                        fish, NULL, NULL);
1400
 
        g_free (key);
1401
 
 
1402
 
        key = panel_applet_gconf_get_full_key (applet, "speed");
1403
 
        fish->listeners [i++] = gconf_client_notify_add (
1404
 
                                        fish->client, key,
1405
 
                                        (GConfClientNotifyFunc) speed_changed_notify,
1406
 
                                        fish, NULL, NULL);
1407
 
        g_free (key);
1408
 
 
1409
 
        key = panel_applet_gconf_get_full_key (applet, "rotate");
1410
 
        fish->listeners [i++] = gconf_client_notify_add (
1411
 
                                        fish->client, key,
1412
 
                                        (GConfClientNotifyFunc) rotate_changed_notify,
1413
 
                                        fish, NULL, NULL);
1414
 
        g_free (key);
1415
 
 
1416
 
        fish->listeners [i++] = gconf_client_notify_add (
1417
 
                                        fish->client,
1418
 
                                        LOCKDOWN_COMMANDLINE_KEY,
1419
 
                                        (GConfClientNotifyFunc) fish_disable_commande_line_notify,
1420
 
                                        fish, NULL, NULL);
1421
 
 
1422
 
        g_assert (i == N_FISH_LISTENERS);
1423
 
}
1424
 
 
1425
913
static gboolean
1426
914
load_fish_image (FishApplet *fish)
1427
915
{
1446
934
                g_object_unref (fish->pixbuf);
1447
935
        fish->pixbuf = pixbuf;
1448
936
 
1449
 
        if (fish->preview_image)
1450
 
                gtk_image_set_from_pixbuf (GTK_IMAGE (fish->preview_image),
1451
 
                                           fish->pixbuf);
1452
 
 
1453
937
        g_free (path);
1454
938
 
1455
939
        return TRUE;
1456
940
}
1457
941
 
 
942
static gboolean
 
943
update_surface_in_idle (gpointer data)
 
944
{
 
945
        update_surface (FISH_APPLET (data));
 
946
        return FALSE;
 
947
}
 
948
 
1458
949
static void
1459
 
update_pixmap (FishApplet *fish)
 
950
update_surface (FishApplet *fish)
1460
951
{
1461
952
        GtkWidget     *widget = fish->drawing_area;
 
953
        GtkRequisition prev_requisition;
1462
954
        GtkAllocation  allocation;
1463
955
        int            width  = -1;
1464
956
        int            height = -1;
1487
979
        pixbuf_width  = gdk_pixbuf_get_width  (fish->pixbuf);
1488
980
        pixbuf_height = gdk_pixbuf_get_height (fish->pixbuf);
1489
981
 
 
982
        prev_requisition = fish->requisition;
 
983
 
1490
984
        if (fish->orientation == PANEL_APPLET_ORIENT_UP ||
1491
985
            fish->orientation == PANEL_APPLET_ORIENT_DOWN) {
1492
986
                height = allocation.height;
1493
987
                width  = pixbuf_width * ((gdouble) height / pixbuf_height);
 
988
 
1494
989
                fish->requisition.width = width / fish->n_frames;
1495
990
                fish->requisition.height = height;
1496
991
        } else {
1497
992
                if (!rotate) {
1498
993
                        width = allocation.width * fish->n_frames;
1499
994
                        height = pixbuf_height * ((gdouble) width / pixbuf_width);
1500
 
                        fish->requisition.width = width;
 
995
                        fish->requisition.width = allocation.width;
1501
996
                        fish->requisition.height = height;
1502
997
                } else {
1503
998
                        width = allocation.width;
1507
1002
                }
1508
1003
        }
1509
1004
 
 
1005
        if (prev_requisition.width  != fish->requisition.width ||
 
1006
            prev_requisition.height != fish->requisition.height) {
 
1007
                gtk_widget_set_size_request (widget,
 
1008
                                             fish->requisition.width,
 
1009
                                             fish->requisition.height);
 
1010
        }
 
1011
 
1510
1012
        g_assert (width != -1 && height != -1);
1511
1013
 
1512
1014
        if (width == 0 || height == 0)
1513
1015
                return;
1514
1016
 
1515
 
        if (fish->pixmap)
1516
 
                g_object_unref (fish->pixmap);
1517
 
        fish->pixmap = gdk_pixmap_new (gtk_widget_get_window (widget),
1518
 
                                       width, height, -1);
 
1017
        if (fish->surface)
 
1018
                cairo_surface_destroy (fish->surface);
 
1019
        fish->surface = gdk_window_create_similar_surface (
 
1020
                                       gtk_widget_get_window (widget),
 
1021
                                       CAIRO_CONTENT_COLOR_ALPHA,
 
1022
                                       width, height);
1519
1023
 
1520
1024
        gtk_widget_queue_resize (widget);
1521
1025
 
1522
1026
        g_assert (pixbuf_width != -1 && pixbuf_height != -1);
1523
1027
 
1524
 
        cr = gdk_cairo_create (fish->pixmap);
 
1028
        cr = cairo_create (fish->surface);
1525
1029
 
1526
1030
        cairo_set_source_rgb (cr, 1, 1, 1);
1527
1031
        cairo_paint (cr);
1569
1073
}
1570
1074
 
1571
1075
static gboolean
1572
 
fish_applet_expose_event (GtkWidget      *widget,
1573
 
                          GdkEventExpose *event,
1574
 
                          FishApplet     *fish)
 
1076
fish_applet_draw (GtkWidget  *widget,
 
1077
                  cairo_t    *cr,
 
1078
                  FishApplet *fish)
1575
1079
{
1576
 
        GdkWindow    *window;
1577
 
        GtkStyle     *style;
1578
 
        GtkStateType  state;
 
1080
        GdkWindow *window;
1579
1081
        int width, height;
1580
1082
        int src_x, src_y;
1581
1083
 
1582
 
        g_return_val_if_fail (fish->pixmap != NULL, FALSE);
 
1084
        g_return_val_if_fail (fish->surface != NULL, FALSE);
1583
1085
 
1584
1086
        g_assert (fish->n_frames > 0);
1585
1087
 
1586
1088
        window = gtk_widget_get_window (widget);
1587
 
        style = gtk_widget_get_style (widget);
1588
 
        state = gtk_widget_get_state (widget);
1589
 
 
1590
 
        gdk_drawable_get_size (fish->pixmap, &width, &height);
1591
 
 
1592
 
        src_x = event->area.x;
1593
 
        src_y = event->area.y;
 
1089
 
 
1090
        width = cairo_xlib_surface_get_width (fish->surface);
 
1091
        height = cairo_xlib_surface_get_height (fish->surface);
 
1092
 
 
1093
        src_x = 0;
 
1094
        src_y = 0;
1594
1095
 
1595
1096
        if (fish->rotate) {
1596
1097
                if (fish->orientation == PANEL_APPLET_ORIENT_RIGHT)
1597
 
                        src_y += ((height * (fish->n_frames - 1 - fish->current_frame)) / fish->n_frames);
 
1098
                        src_y = ((height * (fish->n_frames - 1 - fish->current_frame)) / fish->n_frames);
1598
1099
                else if (fish->orientation == PANEL_APPLET_ORIENT_LEFT)
1599
 
                        src_y += ((height * fish->current_frame) / fish->n_frames);
 
1100
                        src_y = ((height * fish->current_frame) / fish->n_frames);
1600
1101
                else
1601
 
                        src_x += ((width * fish->current_frame) / fish->n_frames);
 
1102
                        src_x = ((width * fish->current_frame) / fish->n_frames);
1602
1103
        } else
1603
 
                src_x += ((width * fish->current_frame) / fish->n_frames);
 
1104
                src_x = ((width * fish->current_frame) / fish->n_frames);
1604
1105
 
1605
 
        gdk_draw_drawable (window,
1606
 
                           style->fg_gc [state],
1607
 
                           fish->pixmap,
1608
 
                           src_x, src_y,
1609
 
                           event->area.x, event->area.y,
1610
 
                           event->area.width, event->area.height);
 
1106
        cairo_save (cr);
 
1107
        cairo_set_source_surface (cr, fish->surface, -src_x, -src_y);
 
1108
        cairo_paint (cr);
 
1109
        cairo_restore (cr);
1611
1110
 
1612
1111
        return FALSE;
1613
1112
}
1614
1113
 
1615
1114
static void
1616
 
fish_applet_size_request (GtkWidget      *widget,
1617
 
                          GtkRequisition *requisition,
1618
 
                          FishApplet     *fish)
1619
 
{
1620
 
        *requisition = fish->requisition;
1621
 
}
1622
 
 
1623
 
static void
1624
1115
fish_applet_size_allocate (GtkWidget     *widget,
1625
1116
                           GtkAllocation *allocation,
1626
1117
                           FishApplet    *fish)
1627
1118
{
1628
 
        GtkAllocation widget_allocation;
1629
 
 
1630
 
        gtk_widget_get_allocation (widget, &widget_allocation);
1631
 
 
1632
 
        if (widget_allocation.width  != fish->prev_allocation.width ||
1633
 
            widget_allocation.height != fish->prev_allocation.height)
1634
 
                update_pixmap (fish);
 
1119
        if (allocation->width  == fish->prev_allocation.width &&
 
1120
            allocation->height == fish->prev_allocation.height)
 
1121
                return;
1635
1122
 
1636
1123
        fish->prev_allocation = *allocation;
 
1124
        g_idle_add (update_surface_in_idle, fish);
1637
1125
}
1638
1126
 
1639
1127
static void
1640
1128
fish_applet_realize (GtkWidget  *widget,
1641
1129
                     FishApplet *fish)
1642
1130
{
1643
 
        if (!fish->pixmap)
1644
 
                update_pixmap (fish);
 
1131
        if (!fish->surface)
 
1132
                update_surface (fish);
1645
1133
}
1646
1134
 
1647
1135
static void
1648
1136
fish_applet_unrealize (GtkWidget  *widget,
1649
1137
                       FishApplet *fish)
1650
1138
{
1651
 
        if (fish->pixmap)
1652
 
                g_object_unref (fish->pixmap);
1653
 
        fish->pixmap = NULL;
 
1139
        if (fish->surface)
 
1140
                cairo_surface_destroy (fish->surface);
 
1141
        fish->surface = NULL;
1654
1142
}
1655
1143
 
1656
1144
static void
1664
1152
 
1665
1153
        fish->orientation = orientation;
1666
1154
 
1667
 
        if (fish->pixmap)
1668
 
                update_pixmap (fish);
 
1155
        if (fish->surface)
 
1156
                update_surface (fish);
1669
1157
}
1670
1158
 
1671
1159
static void
1696
1184
                 FishApplet  *fish)
1697
1185
{
1698
1186
        switch (event->keyval) {
1699
 
        case GDK_space:
1700
 
        case GDK_KP_Space:
1701
 
        case GDK_Return:
1702
 
        case GDK_KP_Enter:
1703
 
        case GDK_ISO_Enter:
1704
 
        case GDK_3270_Enter:
 
1187
        case GDK_KEY_space:
 
1188
        case GDK_KEY_KP_Space:
 
1189
        case GDK_KEY_Return:
 
1190
        case GDK_KEY_KP_Enter:
 
1191
        case GDK_KEY_ISO_Enter:
 
1192
        case GDK_KEY_3270_Enter:
1705
1193
                if (fish->april_fools) {
1706
1194
                        change_water (fish);
1707
1195
                        return TRUE;
1795
1283
                          G_CALLBACK (fish_applet_realize), fish);
1796
1284
        g_signal_connect (fish->drawing_area, "unrealize",
1797
1285
                          G_CALLBACK (fish_applet_unrealize), fish);
1798
 
        g_signal_connect (fish->drawing_area, "size-request",
1799
 
                          G_CALLBACK (fish_applet_size_request), fish);
1800
1286
        g_signal_connect (fish->drawing_area, "size-allocate",
1801
1287
                          G_CALLBACK (fish_applet_size_allocate), fish);
1802
 
        g_signal_connect (fish->drawing_area, "expose-event",
1803
 
                          G_CALLBACK (fish_applet_expose_event), fish);
 
1288
        g_signal_connect (fish->drawing_area, "draw",
 
1289
                          G_CALLBACK (fish_applet_draw), fish);
1804
1290
 
1805
1291
        gtk_widget_add_events (widget, GDK_ENTER_NOTIFY_MASK | 
1806
1292
                                       GDK_LEAVE_NOTIFY_MASK |
1819
1305
 
1820
1306
        load_fish_image (fish);
1821
1307
 
1822
 
        update_pixmap (fish);
1823
 
 
1824
 
        setup_timeout (fish);
1825
 
 
1826
 
        set_tooltip (fish);
1827
 
        set_ally_name_desc (GTK_WIDGET (fish), fish);
 
1308
        update_surface (fish);
1828
1309
 
1829
1310
        g_signal_connect (fish, "key_press_event",
1830
1311
                          G_CALLBACK (handle_keypress), fish);
1835
1316
static const GtkActionEntry fish_menu_verbs [] = {
1836
1317
        { "FishPreferences", GTK_STOCK_PROPERTIES, N_("_Preferences"),
1837
1318
          NULL, NULL,
1838
 
          G_CALLBACK (display_preferences_dialog) },
1839
 
        { "FishHelp", GTK_STOCK_HELP, N_("_Help"),
1840
 
          NULL, NULL,
1841
 
          G_CALLBACK (display_help_dialog) },
1842
 
        { "FishAbout", GTK_STOCK_ABOUT, N_("_About"),
1843
 
          NULL, NULL,
1844
 
          G_CALLBACK (display_about_dialog) }
 
1319
          G_CALLBACK (display_preferences_dialog) }
1845
1320
};
1846
1321
 
1847
1322
static void
1848
 
fish_migrate_to_210 (FishApplet *fish)
1849
 
{
1850
 
        char *new_image;
1851
 
 
1852
 
        g_assert (fish->image);
1853
 
 
1854
 
        if (!strncmp (fish->image, "fish/", 5)) {
1855
 
                new_image = g_strdup (fish->image + 5);
1856
 
                g_free (fish->image);
1857
 
                fish->image = new_image;
1858
 
                panel_applet_gconf_set_string (PANEL_APPLET (fish), "image",
1859
 
                                               fish->image, NULL);
1860
 
        }
 
1323
fish_applet_update_name (FishApplet *fish,
 
1324
                         const char *name)
 
1325
{
 
1326
        if (name[0] == '\0')
 
1327
                name = FISH_NAME_DEFAULT;
 
1328
        fish->name = g_strdup (name);
 
1329
 
 
1330
        update_fortune_dialog (fish);
 
1331
        set_tooltip (fish);
 
1332
        set_ally_name_desc (GTK_WIDGET (fish), fish);
 
1333
}
 
1334
 
 
1335
static void
 
1336
fish_applet_update_image (FishApplet *fish,
 
1337
                          const char *image)
 
1338
{
 
1339
        char     *keyfile_path;
 
1340
        GKeyFile *keyfile;
 
1341
 
 
1342
        if (image[0] == '\0')
 
1343
                image = FISH_IMAGE_DEFAULT;
 
1344
        keyfile_path = g_build_filename (FISH_ICONDIR, image, NULL);
 
1345
 
 
1346
        keyfile = g_key_file_new ();
 
1347
        if (!g_key_file_load_from_file (keyfile, keyfile_path,
 
1348
                                        G_KEY_FILE_NONE, NULL)) {
 
1349
                if (g_strcmp0 (image, FISH_IMAGE_DEFAULT) == 0) {
 
1350
                        g_critical ("Cannot load default image ('%s')", image);
 
1351
                        g_assert_not_reached ();
 
1352
                }
 
1353
 
 
1354
                g_key_file_free (keyfile);
 
1355
                g_free (keyfile_path);
 
1356
 
 
1357
                fish_applet_update_image (fish, FISH_IMAGE_DEFAULT);
 
1358
                return;
 
1359
        }
 
1360
 
 
1361
        fish->image = g_key_file_get_string (keyfile, "Fish Animation",
 
1362
                                             "image", NULL);
 
1363
        fish->n_frames = g_key_file_get_integer (keyfile, "Fish Animation",
 
1364
                                                 "frames", NULL);
 
1365
        if (fish->n_frames <= 0)
 
1366
                fish->n_frames = 1;
 
1367
 
 
1368
        load_fish_image (fish);
 
1369
        update_surface (fish);
 
1370
 
 
1371
        g_key_file_free (keyfile);
 
1372
        g_free (keyfile_path);
 
1373
}
 
1374
 
 
1375
static void
 
1376
fish_applet_update_command (FishApplet *fish,
 
1377
                            const char *command)
 
1378
{
 
1379
        g_free (fish->command);
 
1380
        fish->command = g_strdup (command);
 
1381
}
 
1382
 
 
1383
static void
 
1384
fish_applet_update_speed (FishApplet *fish,
 
1385
                          gdouble     speed)
 
1386
{
 
1387
        if (speed <= 0)
 
1388
                speed = FISH_SPEED_DEFAULT;
 
1389
        fish->speed = speed;
 
1390
        setup_timeout (fish);
 
1391
}
 
1392
 
 
1393
static void
 
1394
fish_applet_update_rotate (FishApplet *fish,
 
1395
                           gboolean    rotate)
 
1396
{
 
1397
        fish->rotate = rotate;
 
1398
 
 
1399
        if (fish->orientation == PANEL_APPLET_ORIENT_LEFT ||
 
1400
            fish->orientation == PANEL_APPLET_ORIENT_RIGHT)
 
1401
                update_surface (fish);
 
1402
}
 
1403
 
 
1404
static void
 
1405
fish_applet_settings_changed (GSettings  *settings,
 
1406
                              char       *key,
 
1407
                              FishApplet *fish)
 
1408
{
 
1409
        char     *value_str = NULL;
 
1410
        gdouble   value_double;
 
1411
        gboolean  value_boolean;
 
1412
 
 
1413
        /* key == NULL is a locak hack to mean all keys */
 
1414
 
 
1415
        if (!key || g_strcmp0 (key, FISH_NAME_KEY) == 0) {
 
1416
                value_str = g_settings_get_string (settings, FISH_NAME_KEY);
 
1417
                fish_applet_update_name (fish, value_str);
 
1418
        }
 
1419
        if (!key || g_strcmp0 (key, FISH_IMAGE_KEY) == 0) {
 
1420
                value_str = g_settings_get_string (settings, FISH_IMAGE_KEY);
 
1421
                fish_applet_update_image (fish, value_str);
 
1422
        }
 
1423
        if (!key || g_strcmp0 (key, FISH_COMMAND_KEY) == 0) {
 
1424
                value_str = g_settings_get_string (settings, FISH_COMMAND_KEY);
 
1425
                fish_applet_update_command (fish, value_str);
 
1426
        }
 
1427
        if (!key || g_strcmp0 (key, FISH_SPEED_KEY) == 0) {
 
1428
                value_double = g_settings_get_double (settings, FISH_SPEED_KEY);
 
1429
                fish_applet_update_speed (fish, value_double);
 
1430
        }
 
1431
        if (!key || g_strcmp0 (key, FISH_ROTATE_KEY) == 0) {
 
1432
                value_boolean = g_settings_get_boolean (settings, FISH_ROTATE_KEY);
 
1433
                fish_applet_update_rotate (fish, value_boolean);
 
1434
        }
 
1435
 
 
1436
        g_free (value_str);
1861
1437
}
1862
1438
 
1863
1439
static gboolean
1865
1441
{
1866
1442
        PanelApplet    *applet = (PanelApplet *) fish;
1867
1443
        GtkActionGroup *action_group;
 
1444
        GtkAction      *action;
1868
1445
        gchar          *ui_path;
1869
 
        GError         *error = NULL;
1870
1446
 
1871
1447
        fish->orientation = panel_applet_get_orient (applet);
1872
1448
 
1873
 
        panel_applet_add_preferences (
1874
 
                applet, "/schemas/apps/fish_applet/prefs", NULL);
1875
 
 
1876
 
        setup_gconf (fish);
1877
 
 
1878
 
        fish->name = panel_applet_gconf_get_string (applet, "name", &error);
1879
 
        if (error) {
1880
 
                g_warning ("Error getting 'name' preference: %s", error->message);
1881
 
                g_error_free (error);
1882
 
                error = NULL;
1883
 
        }
1884
 
        if (!fish->name)
1885
 
                fish->name = g_strdup ("Wanda"); /* Fallback */
1886
 
 
1887
 
        fish->image = panel_applet_gconf_get_string (applet, "image", &error);
1888
 
        if (error) {
1889
 
                g_warning ("Error getting 'image' preference: %s", error->message);
1890
 
                g_error_free (error);
1891
 
                error = NULL;
1892
 
        }
1893
 
        if (!fish->image)
1894
 
                fish->image = g_strdup ("fishanim.png"); /* Fallback */
1895
 
        fish_migrate_to_210 (fish);
1896
 
 
1897
 
        fish->command = panel_applet_gconf_get_string (applet, "command", &error);
1898
 
        if (error) {
1899
 
                g_warning ("Error getting 'command' preference: %s", error->message);
1900
 
                g_error_free (error);
1901
 
                error = NULL;
1902
 
        }
1903
 
 
1904
 
        fish->n_frames = panel_applet_gconf_get_int (applet, "frames", &error);
1905
 
        if (error) {
1906
 
                g_warning ("Error getting 'frames' preference: %s", error->message);
1907
 
                g_error_free (error);
1908
 
                error = NULL;
1909
 
 
1910
 
                fish->n_frames = 3; /* Fallback */
1911
 
        }
1912
 
        if (fish->n_frames <= 0)
1913
 
                fish->n_frames = 1;
1914
 
 
1915
 
        fish->speed = panel_applet_gconf_get_float (applet, "speed", &error);
1916
 
        if (error) {
1917
 
                g_warning ("Error getting 'speed' preference: %s", error->message);
1918
 
                g_error_free (error);
1919
 
                error = NULL;
1920
 
 
1921
 
                fish->speed = 1.0; /* Fallback */
1922
 
        }
1923
 
 
1924
 
        fish->rotate = panel_applet_gconf_get_bool (applet, "rotate", &error);
1925
 
        if (error) {
1926
 
                g_warning ("Error getting 'rotate' preference: %s", error->message);
1927
 
                g_error_free (error);
1928
 
                error = NULL;
1929
 
 
1930
 
                fish->rotate = FALSE; /* Fallback */
1931
 
        }
 
1449
        fish->settings = panel_applet_settings_new (applet, FISH_SCHEMA);
 
1450
        fish->lockdown_settings = g_settings_new (LOCKDOWN_SCHEMA);
 
1451
 
 
1452
        g_signal_connect (fish->settings, "changed",
 
1453
                          G_CALLBACK (fish_applet_settings_changed), fish);
 
1454
        /* NULL means we will update for all settings */
 
1455
        fish_applet_settings_changed (fish->settings, NULL, fish);
1932
1456
 
1933
1457
        action_group = gtk_action_group_new ("Fish Applet Actions");
1934
1458
        gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1940
1464
        panel_applet_setup_menu_from_file (applet, ui_path, action_group);
1941
1465
        g_free (ui_path);
1942
1466
 
1943
 
        if (panel_applet_get_locked_down (applet)) {
1944
 
                GtkAction *action;
 
1467
        action = gtk_action_group_get_action (action_group, "FishPreferences");
 
1468
        g_object_bind_property (applet, "locked-down",
 
1469
                                action, "visible",
 
1470
                                G_BINDING_DEFAULT|G_BINDING_INVERT_BOOLEAN|G_BINDING_SYNC_CREATE);
1945
1471
 
1946
 
                action = gtk_action_group_get_action (action_group, "FishPreferences");
1947
 
                gtk_action_set_visible (action, FALSE);
1948
 
        }
1949
1472
        g_object_unref (action_group);
1950
1473
 
1951
1474
#ifndef FISH_INPROCESS
1970
1493
}
1971
1494
 
1972
1495
static void
1973
 
fish_applet_destroy (GtkObject *object)
 
1496
fish_applet_dispose (GObject *object)
1974
1497
{
1975
1498
        FishApplet *fish = (FishApplet *) object;
1976
 
        int         i;
1977
1499
 
1978
1500
        if (fish->timeout)
1979
1501
                g_source_remove (fish->timeout);
1980
1502
        fish->timeout = 0;
1981
1503
 
1982
 
        for (i = 0; i < N_FISH_LISTENERS; i++) {
1983
 
                if (fish->client && fish->listeners [i] != 0)
1984
 
                        gconf_client_notify_remove (
1985
 
                                fish->client, fish->listeners [i]);
1986
 
                fish->listeners [i] = 0;
1987
 
        }
1988
 
 
1989
1504
        if (fish->name)
1990
1505
                g_free (fish->name);
1991
1506
        fish->name = NULL;
1998
1513
                g_free (fish->command);
1999
1514
        fish->command = NULL;
2000
1515
 
2001
 
        if (fish->client)
2002
 
                g_object_unref (fish->client);
2003
 
        fish->client = NULL;
2004
 
 
2005
 
        if (fish->pixmap)
2006
 
                g_object_unref (fish->pixmap);
2007
 
        fish->pixmap = NULL;
 
1516
        if (fish->settings)
 
1517
                g_object_unref (fish->settings);
 
1518
        fish->settings = NULL;
 
1519
 
 
1520
        if (fish->lockdown_settings)
 
1521
                g_object_unref (fish->lockdown_settings);
 
1522
        fish->lockdown_settings = NULL;
 
1523
 
 
1524
        if (fish->surface)
 
1525
                cairo_surface_destroy (fish->surface);
 
1526
        fish->surface = NULL;
2008
1527
 
2009
1528
        if (fish->pixbuf)
2010
1529
                g_object_unref (fish->pixbuf);
2011
1530
        fish->pixbuf = NULL;
2012
1531
 
2013
 
        if (fish->about_dialog)
2014
 
                gtk_widget_destroy (fish->about_dialog);
2015
 
        fish->about_dialog = NULL;
2016
 
 
2017
1532
        if (fish->preferences_dialog)
2018
1533
                gtk_widget_destroy (fish->preferences_dialog);
2019
1534
        fish->preferences_dialog = NULL;
2028
1543
 
2029
1544
        fish_close_channel (fish);
2030
1545
 
2031
 
        GTK_OBJECT_CLASS (parent_class)->destroy (object);
 
1546
        G_OBJECT_CLASS (parent_class)->dispose (object);
2032
1547
}
2033
1548
 
2034
1549
static void
2035
1550
fish_applet_instance_init (FishApplet      *fish,
2036
1551
                           FishAppletClass *klass)
2037
1552
{
2038
 
        int i;
2039
 
 
2040
 
        fish->client = gconf_client_get_default ();
 
1553
        fish->settings          = NULL;
 
1554
        fish->lockdown_settings = NULL;
2041
1555
 
2042
1556
        fish->name     = NULL;
2043
1557
        fish->image    = NULL;
2050
1564
 
2051
1565
        fish->frame         = NULL;
2052
1566
        fish->drawing_area  = NULL;
2053
 
        fish->pixmap        = NULL;
 
1567
        fish->surface       = NULL;
2054
1568
        fish->timeout       = 0;
2055
1569
        fish->current_frame = 0;
2056
1570
        fish->in_applet     = FALSE;
2065
1579
 
2066
1580
        fish->pixbuf = NULL;
2067
1581
 
2068
 
        fish->about_dialog = NULL;
2069
 
 
2070
1582
        fish->preferences_dialog = NULL;
2071
 
        fish->name_entry         = NULL;
2072
 
        fish->command_label      = NULL;
2073
 
        fish->command_entry      = NULL;
2074
 
        fish->preview_image      = NULL;
2075
 
        fish->image_chooser      = NULL;
2076
 
        fish->frames_spin        = NULL;
2077
 
        fish->speed_spin         = NULL;
2078
 
        fish->rotate_toggle      = NULL;
2079
1583
 
2080
1584
        fish->fortune_dialog = NULL;
2081
1585
        fish->fortune_view   = NULL;
2086
1590
        fish->source_id  = 0;
2087
1591
        fish->io_channel = NULL;
2088
1592
 
2089
 
        for (i = 0; i < N_FISH_LISTENERS; i++)
2090
 
                fish->listeners [i] = 0;
2091
 
 
2092
1593
        fish->april_fools = FALSE;
2093
1594
 
2094
1595
        panel_applet_set_flags (PANEL_APPLET (fish),
2101
1602
static void
2102
1603
fish_applet_class_init (FishAppletClass *klass)
2103
1604
{
2104
 
        PanelAppletClass *applet_class    = (PanelAppletClass *) klass;
2105
 
        GtkObjectClass   *gtkobject_class = (GtkObjectClass *) klass;
 
1605
        PanelAppletClass *applet_class  = (PanelAppletClass *) klass;
 
1606
        GObjectClass     *gobject_class = (GObjectClass *) klass;
2106
1607
 
2107
1608
        parent_class = g_type_class_peek_parent (klass);
2108
1609
 
2109
1610
        applet_class->change_orient = fish_applet_change_orient;
2110
1611
 
2111
 
        gtkobject_class->destroy = fish_applet_destroy;
 
1612
        gobject_class->dispose = fish_applet_dispose;
2112
1613
 
2113
1614
        init_fools_day ();
2114
1615
}
2140
1641
#ifdef FISH_INPROCESS
2141
1642
PANEL_APPLET_IN_PROCESS_FACTORY ("FishAppletFactory",
2142
1643
                                 fish_applet_get_type (),
2143
 
                                 "That-stupid-fish",
2144
1644
                                 fishy_factory,
2145
1645
                                 NULL)
2146
1646
 
2147
1647
#else
2148
1648
PANEL_APPLET_OUT_PROCESS_FACTORY ("FishAppletFactory",
2149
1649
                                  fish_applet_get_type (),
2150
 
                                  "That-stupid-fish",
2151
1650
                                  fishy_factory,
2152
1651
                                  NULL)
2153
1652
#endif