source: trunk/third/gnome-applets/gweather/gweather-applet.c @ 21373

Revision 21373, 14.3 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21372, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Id: gweather-applet.c,v 1.1.1.4 2005-03-10 19:44:37 ghudson Exp $ */
2
3/*
4 *  Papadimitriou Spiros <spapadim+@cs.cmu.edu>
5 *
6 *  This code released under the GNU GPL.
7 *  Read the file COPYING for more information.
8 *
9 *  Main applet widget
10 *
11 */
12
13#ifdef HAVE_CONFIG_H
14#  include <config.h>
15#endif
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <assert.h>
20
21#include <gnome.h>
22#include <panel-applet.h>
23#include <libgnomeui/gnome-window-icon.h>
24
25#include "weather.h"
26#include "gweather.h"
27#include "gweather-about.h"
28#include "gweather-pref.h"
29#include "gweather-dialog.h"
30#include "gweather-applet.h"
31
32static void place_widgets (GWeatherApplet *gw_applet)
33{
34    GtkRequisition req;
35    int total_size = 0;
36    gboolean horizontal = FALSE;
37    int panel_size = gw_applet->size;
38    const gchar *temp;   
39       
40    switch (gw_applet->orient) {
41        case PANEL_APPLET_ORIENT_LEFT:
42        case PANEL_APPLET_ORIENT_RIGHT:
43            horizontal = FALSE;
44            break;
45        case PANEL_APPLET_ORIENT_UP:
46        case PANEL_APPLET_ORIENT_DOWN:
47            horizontal = TRUE;
48            break;
49    }
50
51    /* Create the weather icon */
52    weather_info_get_pixbuf_mini(gw_applet->gweather_info,
53                                 &(gw_applet->applet_pixbuf));     
54    gw_applet->image = gtk_image_new_from_pixbuf (gw_applet->applet_pixbuf);
55    gtk_image_set_from_pixbuf (GTK_IMAGE (gw_applet->image),
56                               gw_applet->applet_pixbuf);
57
58    /* Check the weather icon sizes to determine box layout */
59    if (gw_applet->applet_pixbuf != NULL) {
60        gtk_widget_size_request(gw_applet->image, &req);
61        if (horizontal)
62            total_size += req.height;
63        else
64            total_size += req.width;
65    }
66
67    /* Create the temperature label */
68    gw_applet->label = gtk_label_new("0\302\260F");
69   
70    /* Update temperature text */
71    temp = weather_info_get_temp_summary(gw_applet->gweather_info);
72    if (temp)
73        gtk_label_set_text(GTK_LABEL(gw_applet->label), temp);
74
75    /* Check the label size to determine box layout */
76    gtk_widget_size_request(gw_applet->label, &req);
77    if (horizontal)
78        total_size += req.height;
79    else
80        total_size += req.width;
81
82    /* Pack the box */
83    if (gw_applet->box)
84        gtk_widget_destroy (gw_applet->box);
85   
86    if (horizontal && (total_size <= panel_size))
87        gw_applet->box = gtk_vbox_new(FALSE, 0);
88    else if (horizontal && (total_size > panel_size))
89        gw_applet->box = gtk_hbox_new(FALSE, 2);
90    else if (!horizontal && (total_size <= panel_size))
91        gw_applet->box = gtk_hbox_new(FALSE, 2);
92    else
93        gw_applet->box = gtk_vbox_new(FALSE, 0);
94
95    /* Rebuild the applet it's visual area */
96    gtk_container_add (GTK_CONTAINER (gw_applet->container), gw_applet->box);
97    gtk_box_pack_start (GTK_BOX (gw_applet->box), gw_applet->image, TRUE, TRUE, 0);
98    gtk_box_pack_start (GTK_BOX (gw_applet->box), gw_applet->label, TRUE, TRUE, 0);
99
100    gtk_widget_show_all (GTK_WIDGET (gw_applet->applet));
101}
102
103static void change_orient_cb (PanelApplet *w, PanelAppletOrient o, gpointer data)
104{
105    GWeatherApplet *gw_applet = (GWeatherApplet *)data;
106       
107    gw_applet->orient = o;
108    place_widgets(gw_applet);
109    return;
110}
111
112static void size_allocate_cb(PanelApplet *w, GtkAllocation *allocation, gpointer data)
113{
114    GWeatherApplet *gw_applet = (GWeatherApplet *)data;
115       
116    if ((gw_applet->orient == PANEL_APPLET_ORIENT_LEFT) || (gw_applet->orient == PANEL_APPLET_ORIENT_RIGHT)) {
117      if (gw_applet->size == allocation->width)
118        return;
119      gw_applet->size = allocation->width;
120    } else {
121      if (gw_applet->size == allocation->height)
122        return;
123      gw_applet->size = allocation->height;
124    }
125       
126    place_widgets(gw_applet);
127    return;
128}
129
130static void change_background_cb (
131                                PanelApplet *a,
132                                PanelAppletBackgroundType type,
133                                GdkColor *color, GdkPixmap *pixmap,
134                                gpointer data)
135{
136        GWeatherApplet *gw_applet = (GWeatherApplet *) data;
137        GtkRcStyle *rc_style = gtk_rc_style_new ();
138
139        switch (type) {
140                case PANEL_PIXMAP_BACKGROUND:
141                        gtk_widget_modify_style (GTK_WIDGET (gw_applet->applet), rc_style);
142                        break;
143
144                case PANEL_COLOR_BACKGROUND:
145                        gtk_widget_modify_bg (GTK_WIDGET (gw_applet->applet), GTK_STATE_NORMAL, color);
146                        break;
147
148                case PANEL_NO_BACKGROUND:
149                        gtk_widget_modify_style (GTK_WIDGET (gw_applet->applet), rc_style);
150                        break;
151
152                default:
153                        gtk_widget_modify_style (GTK_WIDGET (gw_applet->applet), rc_style);
154                        break;
155        }
156
157        gtk_rc_style_unref (rc_style);
158}
159
160
161static gboolean clicked_cb (GtkWidget *widget, GdkEventButton *ev, gpointer data)
162{
163    GWeatherApplet *gw_applet = data;
164
165    if ((ev == NULL) || (ev->button != 1))
166        return FALSE;
167
168    if (ev->type == GDK_BUTTON_PRESS) {
169        gweather_dialog_open(gw_applet);
170        return TRUE;
171    }
172   
173    return FALSE;
174}
175
176static gboolean
177key_press_cb (GtkWidget *widget, GdkEventKey *event, GWeatherApplet *gw_applet)
178{
179        switch (event->keyval) {       
180        case GDK_u:
181                if (event->state == GDK_CONTROL_MASK) {
182                        gweather_update (gw_applet);
183                        return TRUE;
184                }
185                break;
186        case GDK_d:
187                if (event->state == GDK_CONTROL_MASK) {
188                        gweather_dialog_open (gw_applet);
189                        return TRUE;
190                }
191                break;         
192        case GDK_KP_Enter:
193        case GDK_ISO_Enter:
194        case GDK_3270_Enter:
195        case GDK_Return:
196        case GDK_space:
197        case GDK_KP_Space:
198                gweather_dialog_open(gw_applet);
199                return TRUE;
200                break;
201        default:
202                break;
203        }
204
205        return FALSE;
206
207}
208
209static void about_cb (BonoboUIComponent *uic,
210                      GWeatherApplet    *gw_applet,
211                      const gchar       *verbname)
212{
213
214    gweather_about_run (gw_applet);
215}
216
217static void help_cb (BonoboUIComponent *uic,
218                     GWeatherApplet    *gw_applet,
219                     const gchar       *verbname)
220{
221    GError *error = NULL;
222
223    gnome_help_display_on_screen (
224                "gweather", NULL,
225                gtk_widget_get_screen (GTK_WIDGET (gw_applet->applet)),
226                &error);
227
228    if (error) { /* FIXME: the user needs to see this error */
229        g_warning ("help error: %s\n", error->message);
230        g_error_free (error);
231        error = NULL;
232    }
233}
234
235static void pref_cb (BonoboUIComponent *uic,
236                     GWeatherApplet    *gw_applet,
237                     const gchar       *verbname)
238{
239    gweather_pref_run (gw_applet);
240}
241
242static void details_cb (BonoboUIComponent *uic,
243                         GWeatherApplet    *gw_applet,
244                         const gchar       *verbname)
245{
246    gweather_dialog_open (gw_applet);
247}
248
249static void update_cb (BonoboUIComponent *uic,
250                       GWeatherApplet    *gw_applet,
251                       const gchar       *verbname)
252{
253    gweather_update (gw_applet);
254}
255
256
257static const BonoboUIVerb weather_applet_menu_verbs [] = {
258        BONOBO_UI_UNSAFE_VERB ("Details", details_cb),
259        BONOBO_UI_UNSAFE_VERB ("Update", update_cb),
260        BONOBO_UI_UNSAFE_VERB ("Props", pref_cb),
261        BONOBO_UI_UNSAFE_VERB ("Help", help_cb),
262        BONOBO_UI_UNSAFE_VERB ("About", about_cb),
263
264        BONOBO_UI_VERB_END
265};
266
267static void
268applet_destroy (GtkWidget *widget, GWeatherApplet *gw_applet)
269{
270    if (gw_applet->pref)
271       gtk_widget_destroy (gw_applet->pref);
272
273    if (gw_applet->about_dialog)
274        gtk_widget_destroy (gw_applet->about_dialog);
275
276    if (gw_applet->gweather_dialog)
277       gtk_widget_destroy (gw_applet->gweather_dialog);
278
279    if (gw_applet->timeout_tag > 0) {
280       gtk_timeout_remove(gw_applet->timeout_tag);
281       gw_applet->timeout_tag = 0;
282    }
283       
284    if (gw_applet->gweather_info->metar_handle) {
285       gnome_vfs_async_cancel(gw_applet->gweather_info->metar_handle);
286       gw_applet->gweather_info->metar_handle = NULL;
287    }
288
289    if (gw_applet->gweather_info->iwin_handle) {
290       gnome_vfs_async_cancel(gw_applet->gweather_info->iwin_handle);
291       gw_applet->gweather_info->iwin_handle = NULL;
292    }
293
294    if (gw_applet->gweather_info->wx_handle) {
295       gnome_vfs_async_cancel(gw_applet->gweather_info->wx_handle);
296       gw_applet->gweather_info->wx_handle = NULL;
297    }
298
299    if (gw_applet->gweather_info->met_handle) {
300       gnome_vfs_async_cancel(gw_applet->gweather_info->met_handle);
301       gw_applet->gweather_info->met_handle = NULL;
302    }
303
304    if (gw_applet->gweather_info->bom_handle) {
305       gnome_vfs_async_cancel(gw_applet->gweather_info->bom_handle);
306       gw_applet->gweather_info->bom_handle = NULL;
307    }
308}
309
310void gweather_applet_create (GWeatherApplet *gw_applet)
311{
312    GtkWidget *label;
313    GtkWidget *pixmap;
314    GtkTooltips *tooltips;
315    GtkIconInfo *icon_info;
316    AtkObject *atk_obj;
317
318    gw_applet->about_dialog = NULL;
319 
320    gw_applet->gweather_pref.location = NULL;
321    gw_applet->gweather_pref.update_interval = 1800;
322    gw_applet->gweather_pref.update_enabled = TRUE;
323    gw_applet->gweather_pref.detailed = FALSE;
324    gw_applet->gweather_pref.radar_enabled = TRUE;
325        gw_applet->gweather_pref.temperature_unit = TEMP_UNIT_INVALID;
326        gw_applet->gweather_pref.speed_unit = SPEED_UNIT_INVALID;
327        gw_applet->gweather_pref.pressure_unit = PRESSURE_UNIT_INVALID;
328        gw_applet->gweather_pref.distance_unit = DISTANCE_UNIT_INVALID;
329   
330    panel_applet_set_flags (gw_applet->applet, PANEL_APPLET_EXPAND_MINOR);
331   
332    icon_info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), "stock_weather-storm", 48, 0);
333    if (icon_info) {
334        gnome_window_icon_set_default_from_file (gtk_icon_info_get_filename (icon_info));
335        gtk_icon_info_free (icon_info);
336    }
337
338    gw_applet->container = gtk_alignment_new (0.5, 0.5, 0, 0);
339    gtk_container_add (GTK_CONTAINER (gw_applet->applet), gw_applet->container);
340
341    g_signal_connect (G_OBJECT(gw_applet->applet), "change_orient",
342                       G_CALLBACK(change_orient_cb), gw_applet);
343    g_signal_connect (G_OBJECT(gw_applet->applet), "size_allocate",
344                       G_CALLBACK(size_allocate_cb), gw_applet);
345    g_signal_connect (G_OBJECT(gw_applet->applet), "change_background",
346                       G_CALLBACK(change_background_cb), gw_applet);
347    g_signal_connect (G_OBJECT(gw_applet->applet), "destroy",
348                       G_CALLBACK (applet_destroy), gw_applet);
349    g_signal_connect (GTK_OBJECT(gw_applet->applet), "button_press_event",
350                       GTK_SIGNAL_FUNC(clicked_cb), gw_applet);
351    g_signal_connect (G_OBJECT(gw_applet->applet), "key_press_event",           
352                        G_CALLBACK(key_press_cb), gw_applet);                   
353                     
354    tooltips = gtk_tooltips_new();
355
356    gtk_tooltips_set_tip(tooltips, GTK_WIDGET(gw_applet->applet), _("GNOME Weather"), NULL);
357
358    atk_obj = gtk_widget_get_accessible (GTK_WIDGET (gw_applet->applet));
359    if (GTK_IS_ACCESSIBLE (atk_obj))
360           atk_object_set_name (atk_obj, _("GNOME Weather"));
361
362    gw_applet->size = panel_applet_get_size (gw_applet->applet);
363
364    gw_applet->orient = panel_applet_get_orient (gw_applet->applet);
365   
366    panel_applet_setup_menu_from_file (gw_applet->applet,
367                                       NULL,
368                                       "GNOME_GWeatherApplet.xml",
369                                       NULL,
370                                       weather_applet_menu_verbs,
371                                       gw_applet);
372
373    if (panel_applet_get_locked_down (gw_applet->applet)) {
374            BonoboUIComponent *popup_component;
375
376            popup_component = panel_applet_get_popup_component (gw_applet->applet);
377
378            bonobo_ui_component_set_prop (popup_component,
379                                          "/commands/Props",
380                                          "hidden", "1",
381                                          NULL);
382    }
383
384    gw_applet->tooltips = tooltips;
385       
386    place_widgets(gw_applet);
387 
388        return;
389}
390
391
392void gweather_info_save (const gchar *path, GWeatherApplet *gw_applet)
393{
394    gchar *prefix;
395
396    g_return_if_fail(gw_applet->gweather_info != NULL);
397    g_return_if_fail(path != NULL);
398
399    prefix = g_strconcat (path, "WeatherInfo/", NULL);
400    gnome_config_push_prefix(prefix);
401    /* fprintf(stderr, "gweather_info_save: %s\n", prefix); */
402    g_free(prefix);
403
404    weather_info_config_write(gw_applet->gweather_info);
405
406    gnome_config_pop_prefix();
407    gnome_config_sync();
408    gnome_config_drop_all();
409}
410
411void gweather_info_load (const gchar *path, GWeatherApplet *gw_applet)
412{
413    gchar *prefix;
414
415    g_return_if_fail(path != NULL);
416
417    prefix = g_strconcat (path, "WeatherInfo/", NULL);
418    gnome_config_push_prefix(prefix);
419    /* fprintf(stderr, "gweather_info_save: %s\n", prefix); */
420    g_free(prefix);
421
422    weather_info_free (gw_applet->gweather_info);
423    gw_applet->gweather_info = weather_info_config_read(gw_applet->applet);
424
425    gnome_config_pop_prefix();
426}
427
428gint timeout_cb (gpointer data)
429{
430    GWeatherApplet *gw_applet = (GWeatherApplet *)data;
431       
432    gweather_update(gw_applet);
433    return 0;  /* Do not repeat timeout (will be re-set by gweather_update) */
434}
435
436void update_finish (WeatherInfo *info)
437{
438    char *s;
439    GWeatherApplet *gw_applet = info->applet;
440   
441    weather_info_get_pixbuf_mini(gw_applet->gweather_info,
442                                 &(gw_applet->applet_pixbuf));
443    gtk_image_set_from_pixbuf (GTK_IMAGE (gw_applet->image),
444                               gw_applet->applet_pixbuf);
445     
446    gtk_label_set_text(GTK_LABEL(gw_applet->label),
447                        weather_info_get_temp_summary(gw_applet->gweather_info));
448   
449    s = weather_info_get_weather_summary(gw_applet->gweather_info);
450    gtk_tooltips_set_tip(gw_applet->tooltips, GTK_WIDGET(gw_applet->applet), s, NULL);
451    g_free (s);
452
453
454    /* Update timer */
455    if (gw_applet->timeout_tag > 0)
456        gtk_timeout_remove(gw_applet->timeout_tag);
457    if (gw_applet->gweather_pref.update_enabled)
458        gw_applet->timeout_tag = 
459                gtk_timeout_add (gw_applet->gweather_pref.update_interval * 1000,
460                                 timeout_cb, gw_applet);
461
462    /* Update dialog -- if one is present */
463    gweather_dialog_update(gw_applet);
464}
465
466void gweather_update (GWeatherApplet *gw_applet)
467{
468    gboolean update_success;
469
470    weather_info_get_pixbuf_mini(gw_applet->gweather_info,
471                                 &(gw_applet->applet_pixbuf));
472
473    gtk_image_set_from_pixbuf (GTK_IMAGE (gw_applet->image),
474                               gw_applet->applet_pixbuf);
475    gtk_tooltips_set_tip(gw_applet->tooltips, GTK_WIDGET(gw_applet->applet),
476                         _("Updating..."), NULL);
477
478    /* Set preferred forecast type */
479    weather_forecast_set(gw_applet->gweather_pref.detailed ?
480                                FORECAST_ZONE : FORECAST_STATE);
481
482    /* Set radar map retrieval option */
483    weather_radar_set(gw_applet->gweather_pref.radar_enabled);
484
485    /* Update current conditions */
486    if (gw_applet->gweather_info &&
487        weather_location_equal(gw_applet->gweather_info->location,
488                               gw_applet->gweather_pref.location)) {
489        update_success = weather_info_update(gw_applet,
490                                              gw_applet->gweather_info,
491                                              update_finish);
492    } else {
493        weather_info_free(gw_applet->gweather_info);
494        gw_applet->gweather_info = NULL;
495        update_success = weather_info_new((gpointer)gw_applet,
496                         gw_applet->gweather_pref.location, update_finish);
497    }
498   
499    return;
500}
Note: See TracBrowser for help on using the repository browser.