Merging upstream version 0.7.1 (Closes: #696677, #754229, #759554, #760971).
[debian/lxpanel.git] / plugins / weather / weather.c
1 /**
2 * Copyright (c) 2012-2014 Piotr Sipika; see the AUTHORS file for more.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * See the COPYRIGHT file for more information.
19 */
20
21 #include "location.h"
22 #include "weatherwidget.h"
23 #include "yahooutil.h"
24 #include "logutil.h"
25
26 #include "plugin.h"
27
28 #include <glib.h>
29 #include <glib/gi18n.h>
30 #include <gtk/gtk.h>
31 #include <stdlib.h>
32
33 /* Need to maintain count for bookkeeping */
34 static gint g_iCount = 0;
35
36 typedef struct
37 {
38 gint iMyId_;
39 GtkWidget *pWeather_;
40 config_setting_t *pConfig_;
41 } WeatherPluginPrivate;
42
43
44 /**
45 * Weather Plugin destructor.
46 *
47 * @param pData Pointer to the plugin data (private).
48 */
49 static void
50 weather_destructor(gpointer pData)
51 {
52 WeatherPluginPrivate * pPriv = (WeatherPluginPrivate *) pData;
53
54 LXW_LOG(LXW_DEBUG, "weather_destructor(%d): %d", pPriv->iMyId_, g_iCount);
55
56 g_free(pPriv);
57
58 --g_iCount;
59
60 if (g_iCount == 0)
61 {
62 cleanupYahooUtil();
63
64 cleanupLogUtil();
65 }
66 }
67
68 /**
69 * Weather Plugin constructor
70 *
71 * @param pPlugin Pointer to the PluginClass wrapper instance.
72 * @param setting Pointer to the configuration settings for this plugin.
73 *
74 * @return Pointer to a new weather widget.
75 */
76 static GtkWidget *
77 weather_constructor(LXPanel *pPanel, config_setting_t *pConfig)
78 {
79 WeatherPluginPrivate * pPriv = g_new0(WeatherPluginPrivate, 1);
80
81 pPriv->pConfig_ = pConfig;
82
83 /* There is one more now... */
84 ++g_iCount;
85
86 pPriv->iMyId_ = g_iCount;
87
88 if (g_iCount == 1)
89 {
90 initializeLogUtil("syslog");
91
92 setMaxLogLevel(LXW_ERROR);
93
94 initializeYahooUtil();
95 }
96
97 LXW_LOG(LXW_DEBUG, "weather_constructor()");
98
99 GtkWidget * pWidg = gtk_weather_new(FALSE);
100
101 pPriv->pWeather_ = pWidg;
102
103 GtkWidget * pEventBox = gtk_event_box_new();
104
105 lxpanel_plugin_set_data(pEventBox, pPriv, weather_destructor);
106 gtk_container_add(GTK_CONTAINER(pEventBox), pWidg);
107
108 gtk_widget_set_has_window(pEventBox, FALSE);
109
110 gtk_widget_show_all(pEventBox);
111
112 /* use config settings */
113 LocationInfo * pLocation = g_new0(LocationInfo, 1);
114 const char *pczDummy = NULL;
115 int iDummyVal = 0;
116
117 if (config_setting_lookup_string(pConfig, "alias", &pczDummy))
118 {
119 pLocation->pcAlias_ = g_strndup(pczDummy, (pczDummy) ? strlen(pczDummy) : 0);
120 }
121 else if (config_setting_lookup_int(pConfig, "alias", &iDummyVal))
122 {
123 pLocation->pcAlias_ = g_strdup_printf("%d", iDummyVal);
124 }
125 else
126 {
127 LXW_LOG(LXW_ERROR, "Weather: could not lookup alias in config.");
128 }
129
130 if (config_setting_lookup_string(pConfig, "city", &pczDummy))
131 {
132 pLocation->pcCity_ = g_strndup(pczDummy, (pczDummy) ? strlen(pczDummy) : 0);
133 }
134 else
135 {
136 LXW_LOG(LXW_ERROR, "Weather: could not lookup city in config.");
137 }
138
139 if (config_setting_lookup_string(pConfig, "state", &pczDummy))
140 {
141 pLocation->pcState_ = g_strndup(pczDummy, (pczDummy) ? strlen(pczDummy) : 0);
142 }
143 else
144 {
145 LXW_LOG(LXW_ERROR, "Weather: could not lookup state in config.");
146 }
147
148 if (config_setting_lookup_string(pConfig, "country", &pczDummy))
149 {
150 pLocation->pcCountry_ = g_strndup(pczDummy, (pczDummy) ? strlen(pczDummy) : 0);
151 }
152 else
153 {
154 LXW_LOG(LXW_ERROR, "Weather: could not lookup country in config.");
155 }
156
157 if (config_setting_lookup_string(pConfig, "woeid", &pczDummy))
158 {
159 pLocation->pcWOEID_ = g_strndup(pczDummy, (pczDummy) ? strlen(pczDummy) : 0);
160 }
161 else if (config_setting_lookup_int(pConfig, "woeid", &iDummyVal))
162 {
163 pLocation->pcWOEID_ = g_strdup_printf("%d", iDummyVal);
164 }
165 else
166 {
167 LXW_LOG(LXW_ERROR, "Weather: could not lookup woeid in config.");
168 }
169
170 if (config_setting_lookup_string(pConfig, "units", &pczDummy))
171 {
172 pLocation->cUnits_ = pczDummy[0];
173 }
174 else
175 {
176 LXW_LOG(LXW_ERROR, "Weather: could not lookup units in config.");
177 }
178
179 if (config_setting_lookup_int(pConfig, "interval", &iDummyVal))
180 {
181 pLocation->uiInterval_ = (guint)iDummyVal;
182 }
183 else
184 {
185 LXW_LOG(LXW_ERROR, "Weather: could not lookup interval in config.");
186 }
187
188 iDummyVal = 0;
189 if (config_setting_lookup_int(pConfig, "enabled", &iDummyVal))
190 {
191 pLocation->bEnabled_ = (gint)iDummyVal;
192 }
193 else
194 {
195 LXW_LOG(LXW_ERROR, "Weather: could not lookup enabled flag in config.");
196 }
197
198 if (pLocation->pcAlias_ && pLocation->pcWOEID_)
199 {
200 GValue locationValue = G_VALUE_INIT;
201
202 g_value_init(&locationValue, G_TYPE_POINTER);
203
204 /* location is copied by the widget */
205 g_value_set_pointer(&locationValue, pLocation);
206
207 g_object_set_property(G_OBJECT(pWidg),
208 "location",
209 &locationValue);
210 }
211
212 freeLocation(pLocation);
213
214 return pEventBox;
215 }
216
217 /**
218 * Weather Plugin callback to save configuration
219 *
220 * @param pWidget Pointer to this widget.
221 */
222 void weather_save_configuration(GtkWidget * pWeather, LocationInfo * pLocation)
223 {
224 GtkWidget * pWidget = gtk_widget_get_parent(pWeather);
225 WeatherPluginPrivate * pPriv = NULL;
226
227 if (pWidget)
228 {
229 pPriv = (WeatherPluginPrivate *) lxpanel_plugin_get_data(pWidget);
230 }
231 if (pPriv == NULL)
232 {
233 LXW_LOG(LXW_ERROR, "Weather: weather_save_configuration() for invalid widget");
234 return;
235 }
236
237 LXW_LOG(LXW_DEBUG, "weather_save_configuration(%d)", pPriv->iMyId_);
238
239 if (pLocation)
240 {
241 /* save configuration */
242 config_group_set_string(pPriv->pConfig_, "alias", pLocation->pcAlias_);
243 config_group_set_string(pPriv->pConfig_, "city", pLocation->pcCity_);
244 config_group_set_string(pPriv->pConfig_, "state", pLocation->pcState_);
245 config_group_set_string(pPriv->pConfig_, "country", pLocation->pcCountry_);
246 config_group_set_string(pPriv->pConfig_, "woeid", pLocation->pcWOEID_);
247
248 char units[2] = {0};
249 if (snprintf(units, 2, "%c", pLocation->cUnits_) > 0)
250 {
251 config_group_set_string(pPriv->pConfig_, "units", units);
252 }
253
254 config_group_set_int(pPriv->pConfig_, "interval", (int) pLocation->uiInterval_);
255 config_group_set_int(pPriv->pConfig_, "enabled", (int) pLocation->bEnabled_);
256 }
257
258 }
259
260 /**
261 * Weather Plugin configuration change callback.
262 *
263 * @param pPanel Pointer to the panel instance.
264 * @param pPlugin Pointer to the PluginClass wrapper instance.
265 */
266 static void
267 weather_configuration_changed(LXPanel *pPanel, GtkWidget *pWidget)
268 {
269 LXW_LOG(LXW_DEBUG, "weather_configuration_changed()");
270
271 if (pPanel && pWidget)
272 {
273 LXW_LOG(LXW_DEBUG,
274 " orientation: %s, width: %d, height: %d, icon size: %d\n",
275 (panel_get_orientation(pPanel) == GTK_ORIENTATION_HORIZONTAL)?"HORIZONTAL":
276 (panel_get_orientation(pPanel) == GTK_ORIENTATION_VERTICAL)?"VERTICAL":"NONE",
277 pPanel->width, panel_get_height(pPanel),
278 panel_get_icon_size(pPanel));
279 }
280 }
281
282 /**
283 * Weather Plugin configuration dialog callback.
284 *
285 * @param pPanel Pointer to the panel instance.
286 * @param pWidget Pointer to the Plugin widget instance.
287 * @param pParent Pointer to the GtkWindow parent.
288 *
289 * @return Instance of the widget.
290 */
291 static GtkWidget *
292 weather_configure(LXPanel *pPanel G_GNUC_UNUSED, GtkWidget *pWidget)
293 {
294 LXW_LOG(LXW_DEBUG, "weather_configure()");
295
296 WeatherPluginPrivate * pPriv = (WeatherPluginPrivate *) lxpanel_plugin_get_data(pWidget);
297
298 GtkWidget * pDialog = gtk_weather_create_preferences_dialog(GTK_WIDGET(pPriv->pWeather_));
299
300 return pDialog;
301 }
302
303 FM_DEFINE_MODULE(lxpanel_gtk, weather)
304
305 /**
306 * Definition of the weather plugin module
307 */
308 LXPanelPluginInit fm_module_init_lxpanel_gtk =
309 {
310 .name = N_("Weather Plugin"),
311 .description = N_("Show weather conditions for a location."),
312
313 // API functions
314 .new_instance = weather_constructor,
315 .config = weather_configure,
316 .reconfigure = weather_configuration_changed
317 };