1 /* $Id$ */
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  *  Preferences dialog
10  *
11  */
12 
13 /* Radar map on by default. */
14 #define RADARMAP
15 
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <assert.h>
24 #include <ctype.h>
25 #include <locale.h>
26 
27 #include <mate-panel-applet.h>
28 #include <gio/gio.h>
29 
30 #define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
31 
32 #include <libmateweather/mateweather-xml.h>
33 #include "mateweather.h"
34 #include "mateweather-pref.h"
35 #include "mateweather-applet.h"
36 #include "mateweather-dialog.h"
37 
38 #define NEVER_SENSITIVE "never_sensitive"
39 
40 struct _MateWeatherPrefPrivate {
41 	GtkWidget* notebook;
42 
43 	GtkWidget* basic_temp_combo;
44 	GtkWidget* basic_speed_combo;
45 	GtkWidget* basic_dist_combo;
46 	GtkWidget* basic_pres_combo;
47 	GtkWidget* find_entry;
48 	GtkWidget* find_next_btn;
49 
50 #ifdef RADARMAP
51 	GtkWidget* basic_radar_btn;
52 	GtkWidget* basic_radar_url_btn;
53 	GtkWidget* basic_radar_url_hbox;
54 	GtkWidget* basic_radar_url_entry;
55 #endif /* RADARMAP */
56 
57 #ifdef HAVE_LIBNOTIFY
58 	GtkWidget* basic_show_notifications_btn;
59 #endif /* HAVE_LIBNOTIFY */
60 
61 	GtkWidget* basic_update_spin;
62 	GtkWidget* basic_update_btn;
63 	GtkWidget* tree;
64 
65 	GtkTreeModel* model;
66 
67 	MateWeatherApplet* applet;
68 };
69 
70 enum {
71 	PROP_0,
72 	PROP_MATEWEATHER_APPLET,
73 };
74 
75 G_DEFINE_TYPE_WITH_PRIVATE (MateWeatherPref, mateweather_pref, GTK_TYPE_DIALOG);
76 
77 /* set sensitive and setup NEVER_SENSITIVE appropriately */
hard_set_sensitive(GtkWidget * w,gboolean sensitivity)78 static void hard_set_sensitive(GtkWidget* w, gboolean sensitivity)
79 {
80 	gtk_widget_set_sensitive(w, sensitivity);
81 	g_object_set_data(G_OBJECT(w), NEVER_SENSITIVE, GINT_TO_POINTER(!sensitivity));
82 }
83 
84 /* set sensitive, but always insensitive if NEVER_SENSITIVE is set */
soft_set_sensitive(GtkWidget * w,gboolean sensitivity)85 static void soft_set_sensitive(GtkWidget* w, gboolean sensitivity)
86 {
87 	if (g_object_get_data(G_OBJECT(w), NEVER_SENSITIVE))
88 	{
89 		gtk_widget_set_sensitive(w, FALSE);
90 	}
91 	else
92 	{
93 		gtk_widget_set_sensitive(w, sensitivity);
94 	}
95 }
96 
97 /* sets up ATK Relation between the widgets */
add_atk_relation(GtkWidget * widget1,GtkWidget * widget2,AtkRelationType type)98 static void add_atk_relation(GtkWidget* widget1, GtkWidget* widget2, AtkRelationType type)
99 {
100 	AtkObject* atk_obj1;
101 	AtkObject* atk_obj2;
102 	AtkRelationSet* relation_set;
103 	AtkRelation* relation;
104 
105 	atk_obj1 = gtk_widget_get_accessible(widget1);
106 
107 	if (!GTK_IS_ACCESSIBLE(atk_obj1))
108 	{
109 		return;
110 	}
111 
112 	atk_obj2 = gtk_widget_get_accessible(widget2);
113 
114 	relation_set = atk_object_ref_relation_set(atk_obj1);
115 	relation = atk_relation_new(&atk_obj2, 1, type);
116 	atk_relation_set_add(relation_set, relation);
117 	g_object_unref(G_OBJECT(relation));
118 }
119 
120 /* sets accessible name and description */
set_access_namedesc(GtkWidget * widget,const gchar * name,const gchar * desc)121 void set_access_namedesc(GtkWidget* widget, const gchar* name, const gchar* desc)
122 {
123 	AtkObject* obj = gtk_widget_get_accessible(widget);
124 
125 	if (!GTK_IS_ACCESSIBLE(obj))
126 	{
127 		return;
128 	}
129 
130 	if (desc)
131 	{
132 		atk_object_set_description(obj, desc);
133 	}
134 
135 	if (name)
136 	{
137 		atk_object_set_name(obj, name);
138 	}
139 }
140 
141 /* sets accessible name, description, CONTROLLED_BY
142  * and CONTROLLER_FOR relations for the components
143  * in mateweather preference dialog.
144  */
mateweather_pref_set_accessibility(MateWeatherPref * pref)145 static void mateweather_pref_set_accessibility(MateWeatherPref* pref)
146 {
147     /* Relation between components in General page */
148     add_atk_relation(pref->priv->basic_update_btn, pref->priv->basic_update_spin, ATK_RELATION_CONTROLLER_FOR);
149     add_atk_relation(pref->priv->basic_radar_btn, pref->priv->basic_radar_url_btn, ATK_RELATION_CONTROLLER_FOR);
150     add_atk_relation(pref->priv->basic_radar_btn, pref->priv->basic_radar_url_entry, ATK_RELATION_CONTROLLER_FOR);
151 
152     add_atk_relation(pref->priv->basic_update_spin, pref->priv->basic_update_btn, ATK_RELATION_CONTROLLED_BY);
153     add_atk_relation(pref->priv->basic_radar_url_btn, pref->priv->basic_radar_btn, ATK_RELATION_CONTROLLED_BY);
154     add_atk_relation(pref->priv->basic_radar_url_entry, pref->priv->basic_radar_btn, ATK_RELATION_CONTROLLED_BY);
155 
156     /* Accessible Name and Description for the components in Preference Dialog */
157     set_access_namedesc(pref->priv->tree, _("Location view"), _("Select Location from the list"));
158     set_access_namedesc(pref->priv->basic_update_spin, _("Update spin button"), _("Spinbutton for updating"));
159     set_access_namedesc(pref->priv->basic_radar_url_entry, _("Address Entry"), _("Enter the URL"));
160 }
161 
162 /* Update pref dialog from mateweather_pref */
update_dialog(MateWeatherPref * pref)163 static gboolean update_dialog(MateWeatherPref* pref)
164 {
165     MateWeatherApplet* gw_applet = pref->priv->applet;
166 
167     g_return_val_if_fail(gw_applet->mateweather_pref.location != NULL, FALSE);
168 
169     gtk_spin_button_set_value(GTK_SPIN_BUTTON(pref->priv->basic_update_spin), gw_applet->mateweather_pref.update_interval / 60);
170     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pref->priv->basic_update_btn), gw_applet->mateweather_pref.update_enabled);
171     soft_set_sensitive(pref->priv->basic_update_spin, gw_applet->mateweather_pref.update_enabled);
172 
173     gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->basic_temp_combo),
174                               (gint) gw_applet->mateweather_pref.temperature_unit - 2);
175 
176     gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->basic_speed_combo),
177                               (gint) gw_applet->mateweather_pref.speed_unit - 2);
178 
179     gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->basic_pres_combo),
180                               (gint) gw_applet->mateweather_pref.pressure_unit - 2);
181 
182     gtk_combo_box_set_active (GTK_COMBO_BOX (pref->priv->basic_dist_combo),
183                               (gint) gw_applet->mateweather_pref.distance_unit - 2);
184 
185 	#ifdef RADARMAP
186 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pref->priv->basic_radar_btn), gw_applet->mateweather_pref.radar_enabled);
187 
188 		soft_set_sensitive(pref->priv->basic_radar_url_btn, gw_applet->mateweather_pref.radar_enabled);
189 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pref->priv->basic_radar_url_btn), gw_applet->mateweather_pref.use_custom_radar_url);
190 		soft_set_sensitive(pref->priv->basic_radar_url_hbox, gw_applet->mateweather_pref.radar_enabled);
191 
192 		if (gw_applet->mateweather_pref.radar)
193 		{
194 			gtk_entry_set_text(GTK_ENTRY(pref->priv->basic_radar_url_entry), gw_applet->mateweather_pref.radar);
195 		}
196 
197 	#endif /* RADARMAP */
198 
199 	#ifdef HAVE_LIBNOTIFY
200 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pref->priv->basic_show_notifications_btn), gw_applet->mateweather_pref.show_notifications);
201 	#endif
202     return TRUE;
203 }
204 
205 static void
on_row_selected(GtkTreeSelection * selection,MateWeatherPref * pref)206 on_row_selected (GtkTreeSelection *selection,
207                  MateWeatherPref  *pref)
208 {
209 	MateWeatherApplet* gw_applet = pref->priv->applet;
210 	GtkTreeModel* model;
211 	WeatherLocation* loc = NULL;
212 	GtkTreeIter iter;
213 
214 	if (!gtk_tree_selection_get_selected(selection, &model, &iter))
215 		return;
216 
217 	gtk_tree_model_get(model, &iter, MATEWEATHER_XML_COL_POINTER, &loc, -1);
218 
219 	if (!loc)
220 	{
221 		return;
222 	}
223 
224 	g_settings_set_string (gw_applet->settings, "location1", loc->code);
225 	g_settings_set_string (gw_applet->settings, "location2", loc->zone);
226 	g_settings_set_string (gw_applet->settings, "location3", loc->radar);
227 	g_settings_set_string (gw_applet->settings, "location4", loc->name);
228 	g_settings_set_string (gw_applet->settings, "coordinates", loc->coordinates);
229 
230 	if (gw_applet->mateweather_pref.location)
231 	{
232 		weather_location_free(gw_applet->mateweather_pref.location);
233 	}
234 
235 	gw_applet->mateweather_pref.location =
236 		weather_location_new (loc->name, loc->code, loc->zone, loc->radar, loc->coordinates,
237 			NULL, NULL);
238 
239 	mateweather_update(gw_applet);
240 }
241 
compare_location(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer user_data)242 static gboolean compare_location(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer user_data)
243 {
244     MateWeatherPref* pref = user_data;
245     WeatherLocation* loc;
246     GtkTreeView* view;
247 
248     gtk_tree_model_get(model, iter, MATEWEATHER_XML_COL_POINTER, &loc, -1);
249 
250     if (!loc)
251     {
252 		return FALSE;
253 	}
254 
255     if (!weather_location_equal(loc, pref->priv->applet->mateweather_pref.location))
256     {
257 		return FALSE;
258 	}
259 
260     view = GTK_TREE_VIEW(pref->priv->tree);
261     gtk_tree_view_expand_to_path(view, path);
262     gtk_tree_view_set_cursor(view, path, NULL, FALSE);
263     gtk_tree_view_scroll_to_cell(view, path, NULL, TRUE, 0.5, 0.5);
264 
265     return TRUE;
266 }
267 
load_locations(MateWeatherPref * pref)268 static void load_locations(MateWeatherPref* pref)
269 {
270 	GtkTreeView* tree = GTK_TREE_VIEW(pref->priv->tree);
271 	GtkTreeViewColumn* column;
272 	GtkCellRenderer* cell_renderer;
273 
274 	/* Add a column for the locations */
275 	cell_renderer = gtk_cell_renderer_text_new();
276 	column = gtk_tree_view_column_new_with_attributes("not used", cell_renderer, "text", MATEWEATHER_XML_COL_LOC, NULL);
277 	gtk_tree_view_append_column(tree, column);
278 	gtk_tree_view_set_expander_column(GTK_TREE_VIEW(tree), column);
279 
280 	/* load locations from xml file */
281 	pref->priv->model = mateweather_xml_load_locations();
282 
283 	if (!pref->priv->model)
284 	{
285 		GtkWidget* d = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Failed to load the Locations XML database.  Please report this as a bug."));
286 		gtk_dialog_run(GTK_DIALOG(d));
287 		gtk_widget_destroy(d);
288 	}
289 
290 	gtk_tree_view_set_model (tree, pref->priv->model);
291 
292 	if (pref->priv->applet->mateweather_pref.location)
293 	{
294 		/* Select the current (default) location */
295 		gtk_tree_model_foreach(GTK_TREE_MODEL(pref->priv->model), compare_location, pref);
296 	}
297 }
298 
299 static void
on_show_notifications_toggled(GtkToggleButton * button,MateWeatherPref * pref)300 on_show_notifications_toggled (GtkToggleButton *button,
301                                MateWeatherPref *pref)
302 {
303 	MateWeatherApplet* gw_applet = pref->priv->applet;
304 
305 	gboolean toggled = gtk_toggle_button_get_active(button);
306 
307 	if (toggled != gw_applet->mateweather_pref.show_notifications)
308 	{
309 		/* sync with mateweather_pref struct */
310 		gw_applet->mateweather_pref.show_notifications = toggled;
311 
312 		/* sync with gsettings */
313 		g_settings_set_boolean (gw_applet->settings, "show-notifications", toggled);
314 	}
315 }
316 
317 static void
on_auto_update_toggled(GtkToggleButton * button,MateWeatherPref * pref)318 on_auto_update_toggled (GtkToggleButton *button,
319                         MateWeatherPref *pref)
320 {
321 	MateWeatherApplet* gw_applet = pref->priv->applet;
322 	gboolean toggled;
323 	gint nxtSunEvent;
324 
325 	toggled = gtk_toggle_button_get_active(button);
326 	gw_applet->mateweather_pref.update_enabled = toggled;
327 	soft_set_sensitive(pref->priv->basic_update_spin, toggled);
328 	g_settings_set_boolean (gw_applet->settings, "auto-update", toggled);
329 
330 	if (gw_applet->timeout_tag > 0)
331 	{
332 		g_source_remove(gw_applet->timeout_tag);
333 	}
334 
335 	if (gw_applet->suncalc_timeout_tag > 0)
336 	{
337 		g_source_remove(gw_applet->suncalc_timeout_tag);
338 	}
339 
340 	if (gw_applet->mateweather_pref.update_enabled)
341 	{
342 		gw_applet->timeout_tag
343 			= g_timeout_add_seconds ((guint) gw_applet->mateweather_pref.update_interval,
344 		                                 timeout_cb, gw_applet);
345 
346 		nxtSunEvent = weather_info_next_sun_event (gw_applet->mateweather_info);
347 		if (nxtSunEvent >= 0)
348 		{
349 			gw_applet->suncalc_timeout_tag
350 				= g_timeout_add_seconds ((guint) nxtSunEvent,
351 				                         suncalc_timeout_cb, gw_applet);
352 		}
353 	}
354 }
355 
356 static void
on_temp_combo_changed(GtkComboBox * combo,MateWeatherPref * pref)357 on_temp_combo_changed (GtkComboBox     *combo,
358                        MateWeatherPref *pref)
359 {
360 	MateWeatherApplet* gw_applet = pref->priv->applet;
361 	TempUnit new_unit, old_unit;
362 
363 	g_return_if_fail(gw_applet != NULL);
364 
365 	new_unit = gtk_combo_box_get_active(combo) + 2;
366 
367 	old_unit = gw_applet->mateweather_pref.temperature_unit;
368 
369 	if (new_unit == old_unit)
370 	{
371 		return;
372 	}
373 
374 	gw_applet->mateweather_pref.temperature_unit = new_unit;
375 
376 	g_settings_set_enum (gw_applet->settings, "temperature-unit", new_unit);
377 
378 	gtk_label_set_text(GTK_LABEL(gw_applet->label), weather_info_get_temp_summary(gw_applet->mateweather_info));
379 
380 	if (gw_applet->details_dialog)
381 	{
382 		mateweather_dialog_update(MATEWEATHER_DIALOG(gw_applet->details_dialog));
383 	}
384 }
385 
386 static void
on_speed_combo_changed(GtkComboBox * combo,MateWeatherPref * pref)387 on_speed_combo_changed (GtkComboBox     *combo,
388                         MateWeatherPref *pref)
389 {
390 	MateWeatherApplet* gw_applet = pref->priv->applet;
391 	SpeedUnit new_unit, old_unit;
392 
393 	g_return_if_fail(gw_applet != NULL);
394 
395 	new_unit = gtk_combo_box_get_active(combo) + 2;
396 
397 	old_unit = gw_applet->mateweather_pref.speed_unit;
398 
399 	if (new_unit == old_unit)
400 	{
401 		return;
402 	}
403 
404 	gw_applet->mateweather_pref.speed_unit = new_unit;
405 
406 	g_settings_set_enum (gw_applet->settings, "speed-unit", new_unit);
407 
408 	if (gw_applet->details_dialog)
409 	{
410 		mateweather_dialog_update(MATEWEATHER_DIALOG(gw_applet->details_dialog));
411 	}
412 }
413 
414 static void
on_pres_combo_changed(GtkComboBox * combo,MateWeatherPref * pref)415 on_pres_combo_changed (GtkComboBox     *combo,
416                        MateWeatherPref *pref)
417 {
418 	MateWeatherApplet* gw_applet = pref->priv->applet;
419 	PressureUnit new_unit, old_unit;
420 
421 	g_return_if_fail(gw_applet != NULL);
422 
423 	new_unit = gtk_combo_box_get_active(combo) + 2;
424 
425 	old_unit = gw_applet->mateweather_pref.pressure_unit;
426 
427 	if (new_unit == old_unit)
428 	{
429 		return;
430 	}
431 
432 	gw_applet->mateweather_pref.pressure_unit = new_unit;
433 
434 	g_settings_set_enum (gw_applet->settings, "pressure-unit", new_unit);
435 
436 	if (gw_applet->details_dialog)
437 	{
438 		mateweather_dialog_update(MATEWEATHER_DIALOG(gw_applet->details_dialog));
439 	}
440 }
441 
442 static void
on_dist_combo_changed(GtkComboBox * combo,MateWeatherPref * pref)443 on_dist_combo_changed (GtkComboBox     *combo,
444                        MateWeatherPref *pref)
445 {
446 	MateWeatherApplet* gw_applet = pref->priv->applet;
447 	DistanceUnit new_unit, old_unit;
448 
449 	g_return_if_fail(gw_applet != NULL);
450 
451 	new_unit = gtk_combo_box_get_active(combo) + 2;
452 
453 	old_unit = gw_applet->mateweather_pref.distance_unit;
454 
455 	if (new_unit == old_unit)
456 	{
457 		return;
458 	}
459 
460 	gw_applet->mateweather_pref.distance_unit = new_unit;
461 
462 	g_settings_set_enum (gw_applet->settings, "distance-unit", new_unit);
463 
464 	if (gw_applet->details_dialog)
465 	{
466 		mateweather_dialog_update(MATEWEATHER_DIALOG(gw_applet->details_dialog));
467 	}
468 }
469 
470 static void
on_radar_toggled(GtkToggleButton * button,MateWeatherPref * pref)471 on_radar_toggled (GtkToggleButton *button,
472                   MateWeatherPref *pref)
473 {
474     MateWeatherApplet* gw_applet = pref->priv->applet;
475     gboolean toggled;
476 
477     toggled = gtk_toggle_button_get_active(button);
478     gw_applet->mateweather_pref.radar_enabled = toggled;
479     g_settings_set_boolean (gw_applet->settings, "enable-radar-map", toggled);
480     soft_set_sensitive(pref->priv->basic_radar_url_btn, toggled);
481 
482     if (toggled == FALSE || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (pref->priv->basic_radar_url_btn)) == TRUE)
483     {
484 		soft_set_sensitive (pref->priv->basic_radar_url_hbox, toggled);
485 	}
486 }
487 
488 static void
on_use_radar_url_toggled(GtkToggleButton * button,MateWeatherPref * pref)489 on_use_radar_url_toggled (GtkToggleButton *button,
490                           MateWeatherPref *pref)
491 {
492     MateWeatherApplet* gw_applet = pref->priv->applet;
493     gboolean toggled;
494 
495     toggled = gtk_toggle_button_get_active(button);
496     gw_applet->mateweather_pref.use_custom_radar_url = toggled;
497     g_settings_set_boolean (gw_applet->settings, "use-custom-radar-url", toggled);
498     soft_set_sensitive(pref->priv->basic_radar_url_hbox, toggled);
499 }
500 
501 static gboolean
on_radar_url_changed(GtkWidget * widget,GdkEventFocus * event,MateWeatherPref * pref)502 on_radar_url_changed  (GtkWidget       *widget,
503                        GdkEventFocus   *event,
504                        MateWeatherPref *pref)
505 {
506 	MateWeatherApplet* gw_applet = pref->priv->applet;
507 	gchar *text;
508 
509 	text = gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1);
510 
511 	if (gw_applet->mateweather_pref.radar)
512 	{
513 		g_free(gw_applet->mateweather_pref.radar);
514 	}
515 
516 	if (text)
517 	{
518 		gw_applet->mateweather_pref.radar = g_strdup(text);
519 		g_free (text);
520 	}
521 	else
522 	{
523 		gw_applet->mateweather_pref.radar = NULL;
524 	}
525 
526 	g_settings_set_string (gw_applet->settings, "radar", gw_applet->mateweather_pref.radar);
527 
528 	return FALSE;
529 }
530 
531 static void
on_update_interval_changed(GtkSpinButton * button,MateWeatherPref * pref)532 on_update_interval_changed (GtkSpinButton   *button,
533                             MateWeatherPref *pref)
534 {
535 	MateWeatherApplet* gw_applet = pref->priv->applet;
536 
537 	gw_applet->mateweather_pref.update_interval = gtk_spin_button_get_value_as_int(button)*60;
538 	g_settings_set_int (gw_applet->settings, "auto-update-interval", gw_applet->mateweather_pref.update_interval);
539 
540 	if (gw_applet->timeout_tag > 0)
541 	{
542 		g_source_remove(gw_applet->timeout_tag);
543 	}
544 
545 	if (gw_applet->mateweather_pref.update_enabled)
546 	{
547 		gw_applet->timeout_tag
548 			= g_timeout_add_seconds ((guint) gw_applet->mateweather_pref.update_interval,
549 			                         timeout_cb, gw_applet);
550 	}
551 }
552 
free_data(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,gpointer data)553 static gboolean free_data(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter* iter, gpointer data)
554 {
555 	WeatherLocation* location;
556 
557 	gtk_tree_model_get(model, iter, MATEWEATHER_XML_COL_POINTER, &location, -1);
558 
559 	if (!location)
560 	{
561 	   return FALSE;
562 	}
563 
564 	weather_location_free(location);
565 
566 	return FALSE;
567 }
568 
create_hig_category(GtkWidget * main_box,gchar * title)569 static GtkWidget* create_hig_category(GtkWidget* main_box, gchar* title)
570 {
571 	GtkWidget* vbox;
572 	GtkWidget* vbox2;
573 	GtkWidget* hbox;
574 	GtkWidget*label;
575 	gchar* tmp;
576 
577 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
578 	gtk_box_pack_start (GTK_BOX (main_box), vbox, FALSE, FALSE, 0);
579 
580 	tmp = g_strdup_printf ("<b>%s</b>", title);
581 	label = gtk_label_new (NULL);
582 	gtk_label_set_xalign (GTK_LABEL (label), 0.0);
583 	gtk_label_set_markup (GTK_LABEL (label), tmp);
584 	g_free (tmp);
585 	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
586 
587 	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
588 	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
589 
590 	label = gtk_label_new ("    ");
591 	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
592 
593 	vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
594 	gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
595 
596 	return vbox2;
597 }
598 
find_location(GtkTreeModel * model,GtkTreeIter * iter,const gchar * location,gboolean go_parent)599 static gboolean find_location(GtkTreeModel* model, GtkTreeIter* iter, const gchar* location, gboolean go_parent)
600 {
601 	GtkTreeIter iter_child;
602 	GtkTreeIter iter_parent;
603 	gchar* aux_loc;
604 	gboolean valid;
605 	size_t len;
606 
607 	if ((len = strlen (location)) == 0)
608 		return FALSE;
609 
610 	do {
611 
612 		gtk_tree_model_get (model, iter, MATEWEATHER_XML_COL_LOC, &aux_loc, -1);
613 
614 		if (g_ascii_strncasecmp (aux_loc, location, len) == 0)
615 		{
616 			g_free (aux_loc);
617 			return TRUE;
618 		}
619 
620 		if (gtk_tree_model_iter_has_child(model, iter))
621 		{
622 			gtk_tree_model_iter_nth_child(model, &iter_child, iter, 0);
623 
624 			if (find_location (model, &iter_child, location, FALSE))
625 			{
626 				/* Manual copying of the iter */
627 				iter->stamp = iter_child.stamp;
628 				iter->user_data = iter_child.user_data;
629 				iter->user_data2 = iter_child.user_data2;
630 				iter->user_data3 = iter_child.user_data3;
631 
632 				g_free (aux_loc);
633 
634 				return TRUE;
635 			}
636 		}
637 
638 		g_free (aux_loc);
639 
640 		valid = gtk_tree_model_iter_next(model, iter);
641 
642 	} while (valid);
643 
644 	if (go_parent)
645 	{
646 		iter_parent = *iter;
647 
648 		while (gtk_tree_model_iter_parent (model, iter, &iter_parent))
649 		{
650 			if (gtk_tree_model_iter_next (model, iter))
651 			{
652 				return find_location (model, iter, location, TRUE);
653 			}
654 
655 			iter_parent = *iter;
656 		}
657 	}
658 
659 	return FALSE;
660 }
661 
662 static void
on_find_next_clicked(GtkButton * button,MateWeatherPref * pref)663 on_find_next_clicked (GtkButton       *button,
664                       MateWeatherPref *pref)
665 {
666 	GtkTreeView *tree;
667 	GtkTreeModel *model;
668 	GtkEntry *entry;
669 	GtkTreeSelection *selection;
670 	GtkTreeIter iter;
671 	GtkTreeIter iter_parent;
672 	GtkTreePath *path;
673 	const gchar *location;
674 
675 	tree = GTK_TREE_VIEW (pref->priv->tree);
676 	model = gtk_tree_view_get_model (tree);
677 	entry = GTK_ENTRY (pref->priv->find_entry);
678 
679 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
680 
681 	if (gtk_tree_selection_count_selected_rows (selection) >= 1)
682 	{
683 		gtk_tree_selection_get_selected (selection, &model, &iter);
684 		/* Select next or select parent */
685 		if (!gtk_tree_model_iter_next (model, &iter))
686 		{
687 			iter_parent = iter;
688 
689 			if (!gtk_tree_model_iter_parent (model, &iter, &iter_parent) || !gtk_tree_model_iter_next (model, &iter))
690 			{
691 				gtk_tree_model_get_iter_first (model, &iter);
692 			}
693 		}
694 
695 	}
696 	else
697 	{
698 		gtk_tree_model_get_iter_first (model, &iter);
699 	}
700 
701 	location = gtk_entry_get_text (entry);
702 
703 	if (find_location (model, &iter, location, TRUE))
704 	{
705 		gtk_widget_set_sensitive (pref->priv->find_next_btn, TRUE);
706 
707 		path = gtk_tree_model_get_path (model, &iter);
708 		gtk_tree_view_expand_to_path (tree, path);
709 		gtk_tree_selection_select_path (selection, path);
710 		gtk_tree_view_scroll_to_cell (tree, path, NULL, TRUE, 0.5, 0);
711 
712 		gtk_tree_path_free (path);
713 	}
714 	else
715 	{
716 		gtk_widget_set_sensitive (pref->priv->find_next_btn, FALSE);
717 	}
718 }
719 
720 static void
find_entry_changed(GtkEditable * entry,MateWeatherPref * pref)721 find_entry_changed (GtkEditable     *entry,
722                     MateWeatherPref *pref)
723 {
724 	GtkTreeView *tree;
725 	GtkTreeModel *model;
726 	GtkTreeSelection *selection;
727 	GtkTreeIter iter;
728 	GtkTreePath *path;
729 	const gchar *location;
730 
731 	tree = GTK_TREE_VIEW (pref->priv->tree);
732 	model = gtk_tree_view_get_model (tree);
733 
734 	g_return_if_fail (model != NULL);
735 
736 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
737 	gtk_tree_model_get_iter_first (model, &iter);
738 
739 	location = gtk_entry_get_text (GTK_ENTRY (entry));
740 
741 	if (find_location (model, &iter, location, TRUE))
742 	{
743 		gtk_widget_set_sensitive (pref->priv->find_next_btn, TRUE);
744 
745 		path = gtk_tree_model_get_path (model, &iter);
746 		gtk_tree_view_expand_to_path (tree, path);
747 		gtk_tree_selection_select_iter (selection, &iter);
748 		gtk_tree_view_scroll_to_cell (tree, path, NULL, TRUE, 0.5, 0);
749 
750 		gtk_tree_path_free (path);
751 	}
752 	else
753 	{
754 		gtk_widget_set_sensitive (pref->priv->find_next_btn, FALSE);
755 	}
756 }
757 
help_cb(GtkDialog * dialog,MateWeatherPref * pref)758 static void help_cb(GtkDialog* dialog, MateWeatherPref* pref)
759 {
760 	gint current_page;
761 	gchar *uri;
762 	GError* error = NULL;
763 
764 	current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (pref->priv->notebook));
765 	uri = g_strdup_printf ("help:mateweather/mateweather-prefs#mateweather-%s", (current_page == 0) ? "metric" : "change-location");
766 	gtk_show_uri_on_window (GTK_WINDOW (dialog),
767 	                        uri,
768 	                        gtk_get_current_event_time (),
769 	                        &error);
770 	g_free (uri);
771 
772 	if (error)
773 	{
774 		GtkWidget* error_dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("There was an error displaying help: %s"), error->message);
775 		g_signal_connect (error_dialog, "response",
776 		                  G_CALLBACK (gtk_widget_destroy),
777 		                  NULL);
778 		gtk_window_set_resizable (GTK_WINDOW (error_dialog), FALSE);
779 		gtk_window_set_screen (GTK_WINDOW (error_dialog), gtk_widget_get_screen (GTK_WIDGET (dialog)));
780 		gtk_widget_show (error_dialog);
781 		g_error_free (error);
782 		error = NULL;
783 	}
784 }
785 
786 static void
on_response(GtkDialog * dialog,gint id,MateWeatherPref * pref)787 on_response (GtkDialog       *dialog,
788              gint             id,
789              MateWeatherPref *pref)
790 {
791 	if (id == GTK_RESPONSE_HELP)
792 	{
793 		help_cb(dialog, pref);
794 	}
795 	else
796 	{
797 		gtk_widget_destroy(GTK_WIDGET(dialog));
798 	}
799 }
800 
801 
802 static void
mateweather_pref_create(MateWeatherPref * pref)803 mateweather_pref_create (MateWeatherPref* pref)
804 {
805 	GtkWidget* pref_vbox;
806 	#ifdef RADARMAP
807 		GtkWidget* radar_toggle_hbox;
808 	#endif /* RADARMAP */
809 	GtkWidget* pref_basic_update_lbl;
810 	GtkWidget* pref_basic_update_hbox;
811 	GtkAdjustment* pref_basic_update_spin_adj;
812 	GtkWidget* pref_basic_update_sec_lbl;
813 	GtkWidget* pref_basic_note_lbl;
814 	GtkWidget* pref_loc_hbox;
815 	GtkWidget* pref_loc_note_lbl;
816 	GtkWidget* scrolled_window;
817 	GtkWidget* label;
818 	GtkWidget* value_hbox;
819 	GtkWidget* tree_label;
820 	GtkTreeSelection *selection;
821 	GtkWidget* pref_basic_vbox;
822 	GtkWidget* vbox;
823 	GtkWidget* frame;
824 	GtkWidget* temp_label;
825 	GtkWidget* temp_combo;
826 	GtkWidget* speed_label;
827 	GtkWidget* speed_combo;
828 	GtkWidget* pres_label;
829 	GtkWidget* pres_combo;
830 	GtkWidget* dist_label;
831 	GtkWidget* dist_combo;
832 	GtkWidget* unit_grid;
833 	GtkWidget* pref_find_label;
834 	GtkWidget* pref_find_hbox;
835 	GtkWidget* image;
836 
837 
838 	g_object_set (pref, "destroy-with-parent", TRUE, NULL);
839 	gtk_window_set_title (GTK_WINDOW (pref), _("Weather Preferences"));
840 	gtk_dialog_add_buttons (GTK_DIALOG (pref), "gtk-close", GTK_RESPONSE_CLOSE, "gtk-help", GTK_RESPONSE_HELP, NULL);
841 	gtk_dialog_set_default_response (GTK_DIALOG (pref), GTK_RESPONSE_CLOSE);
842 	gtk_container_set_border_width (GTK_CONTAINER (pref), 5);
843 	gtk_window_set_resizable (GTK_WINDOW (pref), TRUE);
844 	gtk_window_set_screen (GTK_WINDOW (pref), gtk_widget_get_screen (GTK_WIDGET (pref->priv->applet->applet)));
845 
846 	pref_vbox = gtk_dialog_get_content_area (GTK_DIALOG (pref));
847 	gtk_box_set_spacing (GTK_BOX (pref_vbox), 2);
848 	gtk_widget_show (pref_vbox);
849 
850 	pref->priv->notebook = gtk_notebook_new ();
851 	gtk_container_set_border_width (GTK_CONTAINER (pref->priv->notebook), 5);
852 	gtk_widget_show (pref->priv->notebook);
853 	gtk_box_pack_start (GTK_BOX (pref_vbox), pref->priv->notebook, TRUE, TRUE, 0);
854 
855   /*
856    * General settings page.
857    */
858 
859 	pref_basic_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 18);
860 	gtk_container_set_border_width (GTK_CONTAINER (pref_basic_vbox), 12);
861 	gtk_container_add (GTK_CONTAINER (pref->priv->notebook), pref_basic_vbox);
862 
863 	pref->priv->basic_update_btn = gtk_check_button_new_with_mnemonic (_("_Automatically update every:"));
864 	gtk_widget_set_halign (pref->priv->basic_update_btn, GTK_ALIGN_START);
865 	gtk_widget_set_vexpand (pref->priv->basic_update_btn, TRUE);
866 	gtk_widget_show (pref->priv->basic_update_btn);
867 
868 	if (!g_settings_is_writable (pref->priv->applet->settings, "auto-update"))
869 	{
870 		hard_set_sensitive (pref->priv->basic_update_btn, FALSE);
871 	}
872 
873 	/*
874 	 * Units settings page.
875 	 */
876 
877 	/* Temperature Unit */
878 	temp_label = gtk_label_new_with_mnemonic (_("_Temperature unit:"));
879 	gtk_label_set_use_markup (GTK_LABEL (temp_label), TRUE);
880 	gtk_label_set_justify (GTK_LABEL (temp_label), GTK_JUSTIFY_LEFT);
881 	gtk_label_set_xalign (GTK_LABEL (temp_label), 0.0);
882 	gtk_widget_show (temp_label);
883 
884 	temp_combo = gtk_combo_box_text_new ();
885 	pref->priv->basic_temp_combo = temp_combo;
886 	gtk_label_set_mnemonic_widget (GTK_LABEL (temp_label), temp_combo);
887 	//gtk_combo_box_append_text (GTK_COMBO_BOX (temp_combo), _("Default"));
888 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (temp_combo), _("Kelvin"));
889 	/* TRANSLATORS: Celsius is sometimes referred Centigrade */
890 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (temp_combo), _("Celsius"));
891 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (temp_combo), _("Fahrenheit"));
892 	gtk_widget_show (temp_combo);
893 
894 	if ( ! g_settings_is_writable (pref->priv->applet->settings, "temperature-unit"))
895 	{
896 		hard_set_sensitive (pref->priv->basic_temp_combo, FALSE);
897 	}
898 
899 	/* Speed Unit */
900 	speed_label = gtk_label_new_with_mnemonic (_("_Wind speed unit:"));
901 	gtk_label_set_use_markup (GTK_LABEL (speed_label), TRUE);
902 	gtk_label_set_justify (GTK_LABEL (speed_label), GTK_JUSTIFY_LEFT);
903 	gtk_label_set_xalign (GTK_LABEL (speed_label), 0.0);
904 	gtk_widget_show (speed_label);
905 
906 	speed_combo = gtk_combo_box_text_new ();
907 	pref->priv->basic_speed_combo = speed_combo;
908 	gtk_label_set_mnemonic_widget (GTK_LABEL (speed_label), speed_combo);
909 	//gtk_combo_box_append_text (GTK_COMBO_BOX (speed_combo), _("Default"));
910 	/* TRANSLATOR: The wind speed unit "meters per second" */
911 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (speed_combo), _("m/s"));
912 	/* TRANSLATOR: The wind speed unit "kilometers per hour" */
913 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (speed_combo), _("km/h"));
914 	/* TRANSLATOR: The wind speed unit "miles per hour" */
915 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (speed_combo), _("mph"));
916 	/* TRANSLATOR: The wind speed unit "knots" */
917 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (speed_combo), _("knots"));
918 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (speed_combo), _("Beaufort scale"));
919 	gtk_widget_show (speed_combo);
920 
921 	if (!g_settings_is_writable (pref->priv->applet->settings, "speed-unit"))
922 	{
923 		hard_set_sensitive (pref->priv->basic_speed_combo, FALSE);
924 	}
925 
926 	/* Pressure Unit */
927 	pres_label = gtk_label_new_with_mnemonic (_("_Pressure unit:"));
928 	gtk_label_set_use_markup (GTK_LABEL (pres_label), TRUE);
929 	gtk_label_set_justify (GTK_LABEL (pres_label), GTK_JUSTIFY_LEFT);
930 	gtk_label_set_xalign (GTK_LABEL (pres_label), 0.0);
931 	gtk_widget_show (pres_label);
932 
933 	pres_combo = gtk_combo_box_text_new ();
934 	pref->priv->basic_pres_combo = pres_combo;
935 	gtk_label_set_mnemonic_widget (GTK_LABEL (pres_label), pres_combo);
936 	//gtk_combo_box_append_text (GTK_COMBO_BOX (pres_combo), _("Default"));
937 	/* TRANSLATOR: The pressure unit "kiloPascals" */
938 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pres_combo), _("kPa"));
939 	/* TRANSLATOR: The pressure unit "hectoPascals" */
940 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pres_combo), _("hPa"));
941 	/* TRANSLATOR: The pressure unit "millibars" */
942 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pres_combo), _("mb"));
943 	/* TRANSLATOR: The pressure unit "millibars of mercury" */
944 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pres_combo), _("mmHg"));
945 	/* TRANSLATOR: The pressure unit "inches of mercury" */
946 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pres_combo), _("inHg"));
947 	/* TRANSLATOR: The pressure unit "atmospheres" */
948 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (pres_combo), _("atm"));
949 	gtk_widget_show (pres_combo);
950 
951 	if (!g_settings_is_writable(pref->priv->applet->settings, "pressure-unit"))
952 	{
953 		hard_set_sensitive(pref->priv->basic_pres_combo, FALSE);
954 	}
955 
956 	/* Distance Unit */
957 	dist_label = gtk_label_new_with_mnemonic (_("_Visibility unit:"));
958 	gtk_label_set_use_markup (GTK_LABEL (dist_label), TRUE);
959 	gtk_label_set_justify (GTK_LABEL (dist_label), GTK_JUSTIFY_LEFT);
960 	gtk_label_set_xalign (GTK_LABEL (dist_label), 0.0);
961 	gtk_widget_show (dist_label);
962 
963 	dist_combo = gtk_combo_box_text_new ();
964 	pref->priv->basic_dist_combo = dist_combo;
965 	gtk_label_set_mnemonic_widget (GTK_LABEL (dist_label), dist_combo);
966 	//gtk_combo_box_append_text (GTK_COMBO_BOX (dist_combo), _("Default"));
967 	/* TRANSLATOR: The distance unit "meters" */
968 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dist_combo), _("meters"));
969 	/* TRANSLATOR: The distance unit "kilometers" */
970 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dist_combo), _("km"));
971 	/* TRANSLATOR: The distance unit "miles" */
972 	gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dist_combo), _("miles"));
973 	gtk_widget_show (dist_combo);
974 
975 	if ( ! g_settings_is_writable (pref->priv->applet->settings, "distance-unit"))
976 		hard_set_sensitive (pref->priv->basic_dist_combo, FALSE);
977 
978 	unit_grid = gtk_grid_new ();
979 	gtk_grid_set_row_spacing(GTK_GRID(unit_grid), 6);
980 	gtk_grid_set_column_spacing(GTK_GRID(unit_grid), 12);
981 	gtk_widget_set_halign (temp_label, GTK_ALIGN_START);
982 	gtk_grid_attach(GTK_GRID(unit_grid), temp_label, 0, 0, 1, 1);
983 	gtk_grid_attach(GTK_GRID(unit_grid), temp_combo,  1, 0, 1, 1);
984 	gtk_widget_set_halign (speed_label, GTK_ALIGN_START);
985 	gtk_grid_attach(GTK_GRID(unit_grid), speed_label, 0, 1, 1, 1);
986 	gtk_grid_attach(GTK_GRID(unit_grid), speed_combo, 1, 1, 1, 1);
987 	gtk_widget_set_halign (pres_label, GTK_ALIGN_START);
988 	gtk_grid_attach(GTK_GRID(unit_grid), pres_label, 0, 2, 1, 1);
989 	gtk_grid_attach(GTK_GRID(unit_grid), pres_combo,  1, 2, 1, 1);
990 	gtk_widget_set_halign (dist_label, GTK_ALIGN_START);
991 	gtk_grid_attach(GTK_GRID(unit_grid), dist_label, 0, 3, 1, 1);
992 	gtk_grid_attach(GTK_GRID(unit_grid), dist_combo,  1, 3, 1, 1);
993 	gtk_widget_show(unit_grid);
994 
995 	#ifdef RADARMAP
996 		pref->priv->basic_radar_btn = gtk_check_button_new_with_mnemonic (_("Enable _radar map"));
997 		gtk_widget_show (pref->priv->basic_radar_btn);
998 
999 		if (!g_settings_is_writable (pref->priv->applet->settings, "enable-radar-map"))
1000 		{
1001 			hard_set_sensitive(pref->priv->basic_radar_btn, FALSE);
1002 		}
1003 
1004 		radar_toggle_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
1005 		gtk_widget_show(radar_toggle_hbox);
1006 
1007 		label = gtk_label_new ("    ");
1008 		gtk_widget_show (label);
1009 		gtk_box_pack_start (GTK_BOX (radar_toggle_hbox), label, FALSE, FALSE, 0);
1010 
1011 		pref->priv->basic_radar_url_btn = gtk_check_button_new_with_mnemonic (_("Use _custom address for radar map"));
1012 		gtk_widget_show (pref->priv->basic_radar_url_btn);
1013 		gtk_box_pack_start (GTK_BOX (radar_toggle_hbox), pref->priv->basic_radar_url_btn, FALSE, FALSE, 0);
1014 
1015 		if ( ! g_settings_is_writable (pref->priv->applet->settings, "use-custom-radar-url"))
1016 		{
1017 			hard_set_sensitive (pref->priv->basic_radar_url_btn, FALSE);
1018 		}
1019 
1020 		pref->priv->basic_radar_url_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
1021 		gtk_widget_show (pref->priv->basic_radar_url_hbox);
1022 
1023 		label = gtk_label_new ("    ");
1024 		gtk_widget_show (label);
1025 		gtk_box_pack_start (GTK_BOX (pref->priv->basic_radar_url_hbox), label, FALSE, FALSE, 0);
1026 
1027 		label = gtk_label_new_with_mnemonic (_("A_ddress:"));
1028 		gtk_widget_show (label);
1029 		gtk_box_pack_start (GTK_BOX (pref->priv->basic_radar_url_hbox), label, FALSE, FALSE, 0);
1030 		pref->priv->basic_radar_url_entry = gtk_entry_new ();
1031 		gtk_widget_show (pref->priv->basic_radar_url_entry);
1032 		gtk_box_pack_start (GTK_BOX (pref->priv->basic_radar_url_hbox), pref->priv->basic_radar_url_entry, TRUE, TRUE, 0);
1033 
1034 		if ( ! g_settings_is_writable (pref->priv->applet->settings, "radar"))
1035 		{
1036 			hard_set_sensitive (pref->priv->basic_radar_url_entry, FALSE);
1037 		}
1038 	#endif /* RADARMAP */
1039 
1040     #ifdef HAVE_LIBNOTIFY
1041 		/* setup show-notifications button */
1042 		pref->priv->basic_show_notifications_btn = gtk_check_button_new_with_mnemonic (_("Show _notifications"));
1043 
1044 		if (!g_settings_is_writable (pref->priv->applet->settings, "show-notifications"))
1045 		{
1046 			hard_set_sensitive (pref->priv->basic_show_notifications_btn, FALSE);
1047 		}
1048     #endif
1049 
1050 	frame = create_hig_category (pref_basic_vbox, _("Update"));
1051 
1052 	pref_basic_update_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
1053 
1054 	pref_basic_update_lbl = gtk_label_new_with_mnemonic (_("_Automatically update every:"));
1055 	gtk_widget_show (pref_basic_update_lbl);
1056 
1057 	gtk_widget_show (pref_basic_update_hbox);
1058 
1059 	pref_basic_update_spin_adj = gtk_adjustment_new (30, 1, 3600, 5, 25, 1);
1060 	pref->priv->basic_update_spin = gtk_spin_button_new (pref_basic_update_spin_adj, 1, 0);
1061 	gtk_widget_show (pref->priv->basic_update_spin);
1062 
1063 	gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (pref->priv->basic_update_spin), TRUE);
1064 	gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (pref->priv->basic_update_spin), GTK_UPDATE_IF_VALID);
1065 
1066 	pref_basic_update_sec_lbl = gtk_label_new (_("minutes"));
1067 	gtk_widget_show (pref_basic_update_sec_lbl);
1068 
1069 	if ( ! g_settings_is_writable (pref->priv->applet->settings, "auto-update-interval"))
1070 	{
1071 		hard_set_sensitive (pref->priv->basic_update_spin, FALSE);
1072 		hard_set_sensitive (pref_basic_update_sec_lbl, FALSE);
1073 	}
1074 
1075 	value_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1076 
1077 	gtk_box_pack_start (GTK_BOX (pref_basic_update_hbox), pref->priv->basic_update_btn, FALSE, TRUE, 0);
1078 	gtk_box_pack_start (GTK_BOX (pref_basic_update_hbox), value_hbox, FALSE, FALSE, 0);
1079 	gtk_box_pack_start (GTK_BOX (value_hbox), pref->priv->basic_update_spin, FALSE, FALSE, 0);
1080 	gtk_box_pack_start (GTK_BOX (value_hbox), pref_basic_update_sec_lbl, FALSE, FALSE, 0);
1081 
1082 	gtk_container_add (GTK_CONTAINER (frame), pref_basic_update_hbox);
1083 
1084 	frame = create_hig_category (pref_basic_vbox, _("Display"));
1085 
1086 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1087 
1088 	gtk_box_pack_start (GTK_BOX (vbox), unit_grid, TRUE, TRUE, 0);
1089 
1090 	#ifdef RADARMAP
1091 		gtk_box_pack_start (GTK_BOX (vbox), pref->priv->basic_radar_btn, TRUE, TRUE, 0);
1092 		gtk_box_pack_start (GTK_BOX (vbox), radar_toggle_hbox, TRUE, TRUE, 0);
1093 		gtk_box_pack_start (GTK_BOX (vbox), pref->priv->basic_radar_url_hbox, TRUE, TRUE, 0);
1094 	#endif /* RADARMAP */
1095 
1096 	#ifdef HAVE_LIBNOTIFY
1097 		/* add the show-notification toggle button to the vbox of the display section */
1098 		gtk_box_pack_start (GTK_BOX (vbox), pref->priv->basic_show_notifications_btn, TRUE, TRUE, 0);
1099 	#endif
1100 
1101 	gtk_container_add (GTK_CONTAINER (frame), vbox);
1102 
1103 	pref_basic_note_lbl = gtk_label_new (_("General"));
1104 	gtk_widget_show (pref_basic_note_lbl);
1105 	gtk_notebook_set_tab_label (GTK_NOTEBOOK (pref->priv->notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (pref->priv->notebook), 0), pref_basic_note_lbl);
1106 
1107   /*
1108    * Location page.
1109    */
1110 	pref_loc_hbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
1111 	gtk_container_set_border_width (GTK_CONTAINER (pref_loc_hbox), 12);
1112 	gtk_container_add (GTK_CONTAINER (pref->priv->notebook), pref_loc_hbox);
1113 
1114 	tree_label = gtk_label_new_with_mnemonic (_("_Select a location:"));
1115 	gtk_label_set_xalign (GTK_LABEL (tree_label), 0.0);
1116 	gtk_box_pack_start (GTK_BOX (pref_loc_hbox), tree_label, FALSE, FALSE, 0);
1117 
1118 	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1119 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
1120 	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1121 
1122 	pref->priv->tree = gtk_tree_view_new ();
1123 	gtk_label_set_mnemonic_widget (GTK_LABEL (tree_label), GTK_WIDGET (pref->priv->tree));
1124 	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (pref->priv->tree), FALSE);
1125 
1126 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pref->priv->tree));
1127 
1128 	gtk_container_add (GTK_CONTAINER (scrolled_window), pref->priv->tree);
1129 	gtk_widget_show (pref->priv->tree);
1130 	gtk_widget_show (scrolled_window);
1131 	gtk_box_pack_start (GTK_BOX (pref_loc_hbox), scrolled_window, TRUE, TRUE, 0);
1132 	load_locations(pref);
1133 
1134 	pref_find_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
1135 	pref_find_label = gtk_label_new (_("_Find:"));
1136 	gtk_label_set_use_underline (GTK_LABEL (pref_find_label), TRUE);
1137 
1138 	pref->priv->find_entry = gtk_entry_new ();
1139 	gtk_label_set_mnemonic_widget (GTK_LABEL (pref_find_label), pref->priv->find_entry);
1140 
1141 	pref->priv->find_next_btn = gtk_button_new_with_mnemonic (_("Find _Next"));
1142 	gtk_widget_set_sensitive (pref->priv->find_next_btn, FALSE);
1143 
1144 	image = gtk_image_new_from_icon_name ("edit-find", GTK_ICON_SIZE_BUTTON);
1145 	gtk_button_set_image (GTK_BUTTON (pref->priv->find_next_btn), image);
1146 
1147 	gtk_container_set_border_width (GTK_CONTAINER (pref_find_hbox), 0);
1148 	gtk_box_pack_start (GTK_BOX (pref_find_hbox), pref_find_label, FALSE, FALSE, 0);
1149 	gtk_box_pack_start (GTK_BOX (pref_find_hbox), pref->priv->find_entry, TRUE, TRUE, 0);
1150 	gtk_box_pack_start (GTK_BOX (pref_find_hbox), pref->priv->find_next_btn, FALSE, FALSE, 0);
1151 
1152 	gtk_box_pack_start (GTK_BOX (pref_loc_hbox), pref_find_hbox, FALSE, FALSE, 0);
1153 
1154 	if ( ! g_settings_is_writable (pref->priv->applet->settings, "location0"))
1155 	{
1156 		hard_set_sensitive (scrolled_window, FALSE);
1157 	}
1158 
1159 	pref_loc_note_lbl = gtk_label_new (_("Location"));
1160 	gtk_widget_show (pref_loc_note_lbl);
1161 	gtk_notebook_set_tab_label (GTK_NOTEBOOK (pref->priv->notebook), gtk_notebook_get_nth_page (GTK_NOTEBOOK (pref->priv->notebook), 1), pref_loc_note_lbl);
1162 
1163 	mateweather_pref_set_accessibility (pref);
1164 	gtk_label_set_mnemonic_widget (GTK_LABEL (pref_basic_update_sec_lbl), pref->priv->basic_update_spin);
1165 	gtk_label_set_mnemonic_widget (GTK_LABEL (label), pref->priv->basic_radar_url_entry);
1166 
1167     /* Set the initial values */
1168     update_dialog (pref);
1169 
1170     /* signals */
1171     g_signal_connect (temp_combo,  "changed", G_CALLBACK (on_temp_combo_changed), pref);
1172     g_signal_connect (speed_combo, "changed", G_CALLBACK (on_speed_combo_changed), pref);
1173     g_signal_connect (dist_combo,  "changed", G_CALLBACK (on_dist_combo_changed), pref);
1174     g_signal_connect (pres_combo,  "changed", G_CALLBACK (on_pres_combo_changed), pref);
1175     g_signal_connect (pref->priv->basic_update_btn, "toggled", G_CALLBACK (on_auto_update_toggled), pref);
1176 #ifdef RADARMAP
1177     g_signal_connect (pref->priv->basic_radar_btn, "toggled", G_CALLBACK (on_radar_toggled), pref);
1178     g_signal_connect (pref->priv->basic_radar_url_btn, "toggled", G_CALLBACK (on_use_radar_url_toggled), pref);
1179     g_signal_connect (pref->priv->basic_radar_url_entry, "focus_out_event", G_CALLBACK (on_radar_url_changed), pref);
1180 #endif /* RADARMAP */
1181 #ifdef HAVE_LIBNOTIFY
1182     g_signal_connect (pref->priv->basic_show_notifications_btn, "toggled", G_CALLBACK (on_show_notifications_toggled), pref);
1183 #endif /* HAVE_LIBNOTIFY */
1184     g_signal_connect (pref->priv->find_next_btn, "clicked", G_CALLBACK (on_find_next_clicked), pref);
1185     g_signal_connect (pref->priv->find_entry, "changed", G_CALLBACK (find_entry_changed), pref);
1186     g_signal_connect (selection, "changed", G_CALLBACK (on_row_selected), pref);
1187     g_signal_connect (pref->priv->basic_update_spin, "value-changed", G_CALLBACK (on_update_interval_changed), pref);
1188     g_signal_connect (pref, "response", G_CALLBACK (on_response), pref);
1189 }
1190 
mateweather_pref_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)1191 static void mateweather_pref_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec *pspec)
1192 {
1193     MateWeatherPref* pref = MATEWEATHER_PREF(object);
1194 
1195     switch (prop_id) {
1196         case PROP_MATEWEATHER_APPLET:
1197             pref->priv->applet = g_value_get_pointer(value);
1198             break;
1199         default:
1200             /* We don't have any other property... */
1201             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1202             break;
1203     }
1204 }
1205 
mateweather_pref_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)1206 static void mateweather_pref_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
1207 {
1208     MateWeatherPref* pref = MATEWEATHER_PREF(object);
1209 
1210     switch (prop_id) {
1211         case PROP_MATEWEATHER_APPLET:
1212             g_value_set_pointer(value, pref->priv->applet);
1213             break;
1214         default:
1215             /* We don't have any other property... */
1216             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1217             break;
1218     }
1219 }
1220 
mateweather_pref_init(MateWeatherPref * self)1221 static void mateweather_pref_init(MateWeatherPref* self)
1222 {
1223 	self->priv = mateweather_pref_get_instance_private(self);
1224 }
1225 
1226 static GObject*
mateweather_pref_constructor(GType type,guint n_construct_params,GObjectConstructParam * construct_params)1227 mateweather_pref_constructor (GType                  type,
1228                               guint                  n_construct_params,
1229                               GObjectConstructParam *construct_params)
1230 {
1231     GObject *object;
1232     MateWeatherPref *self;
1233 
1234     object = G_OBJECT_CLASS (mateweather_pref_parent_class)->constructor(type, n_construct_params, construct_params);
1235     self = MATEWEATHER_PREF (object);
1236 
1237     mateweather_pref_create (self);
1238 
1239     return object;
1240 }
1241 
mateweather_pref_new(MateWeatherApplet * applet)1242 GtkWidget* mateweather_pref_new(MateWeatherApplet* applet)
1243 {
1244     return g_object_new(MATEWEATHER_TYPE_PREF, "mateweather-applet", applet, NULL);
1245 }
1246 
mateweather_pref_finalize(GObject * object)1247 static void mateweather_pref_finalize(GObject* object)
1248 {
1249 	MateWeatherPref* self = MATEWEATHER_PREF(object);
1250 
1251 	gtk_tree_model_foreach(self->priv->model, free_data, NULL);
1252 	g_object_unref(G_OBJECT(self->priv->model));
1253 
1254 	G_OBJECT_CLASS(mateweather_pref_parent_class)->finalize(object);
1255 }
1256 
mateweather_pref_class_init(MateWeatherPrefClass * klass)1257 static void mateweather_pref_class_init(MateWeatherPrefClass* klass)
1258 {
1259     GObjectClass* object_class = G_OBJECT_CLASS(klass);
1260 
1261     mateweather_pref_parent_class = g_type_class_peek_parent(klass);
1262 
1263     object_class->set_property = mateweather_pref_set_property;
1264     object_class->get_property = mateweather_pref_get_property;
1265     object_class->constructor = mateweather_pref_constructor;
1266     object_class->finalize = mateweather_pref_finalize;
1267 
1268     /* This becomes an OBJECT property when MateWeatherApplet is redone */
1269     g_object_class_install_property(object_class, PROP_MATEWEATHER_APPLET, g_param_spec_pointer("mateweather-applet", "MateWeather Applet", "The MateWeather Applet", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
1270 }
1271