9 #include <hildon/hildon.h>
10 #include "lib-stock-home-widget.h"
11 #include "lib-stock-settings.h"
13 HD_DEFINE_PLUGIN_MODULE (StockPlugin, stock_plugin, HD_TYPE_HOME_PLUGIN_ITEM)
16 OnClickRefresh(GtkWidget *widget, StockPluginContext *psContext)
18 DebugOut(("OnClickRefresh"));
20 /* Disable button while getting latest stocks */
21 gtk_widget_set_sensitive(GTK_WIDGET(psContext->psButton),FALSE);
27 if(RetrieveStockPrice(psContext->hSG,psContext->psSettings->ppszTickers[0],&fPrice,NULL,&fChange) == SG_OK)
34 timeinfo = localtime(&rawtime);
35 strftime(szTime,80,"(%I:%M%p)",timeinfo);
37 /* Update to latest price */
38 sprintf(szBuffer,"%s %.2f %.2f%% %s",psContext->psSettings->ppszTickers[0],fPrice,fChange,szTime);
40 hildon_button_set_title(HILDON_BUTTON(psContext->psButton),szBuffer);
41 gtk_widget_queue_draw(GTK_WIDGET(psContext->psBox));
44 If it fails, leave the old price as the user can see the timestamp
45 and know it's not up-to-date. So just notify them of the failure.
49 hildon_banner_show_information(GTK_WIDGET(widget),NULL,"Failed to retrieve stock information, check ticker symbol and try again.");
52 gtk_widget_set_sensitive(GTK_WIDGET(psContext->psButton),TRUE);
56 UpdateStockOnTimeout(gpointer data)
58 StockPluginContext *psContext = (StockPluginContext*)data;
60 DebugOut(("UpdateStockOnTimeout"));
65 /* If no longer a timeout, don't do anything and stop */
66 if(!psContext->psSettings->uiUpdateTime)
69 /* Update stock price */
70 OnClickRefresh(GTK_WIDGET(psContext->psButton),psContext);
75 stock_show_settings_dialog(GtkWidget* widget, gpointer data)
77 StockPluginContext *psContext = (StockPluginContext*)data;
81 GtkWidget *addselector;
83 GtkWidget *timeselector;
84 GtkWidget *timebutton;
86 DebugOut(("stock_show_settings_dialog"));
88 /* Stop timer while settings are one */
89 if(psContext->nTimerID != -1)
91 g_source_remove(psContext->nTimerID);
92 psContext->nTimerID = -1;
95 dialog = gtk_dialog_new_with_buttons("Settings",NULL,0,"Save",GTK_RESPONSE_ACCEPT,NULL);
96 content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
97 group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
99 /* Add new stock symbol */
103 addbutton = hildon_picker_button_new (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT,
104 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
106 addselector = hildon_touch_selector_entry_new_text();
108 for(i=0; i < psContext->psSettings->uiNumTickers; i++)
110 hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(addselector),psContext->psSettings->ppszTickers[i]);
113 /* First ticker in ppszTickers is the chosen one */
114 hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(addselector), 0, 0);
116 hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (addbutton), HILDON_TOUCH_SELECTOR (addselector));
118 hildon_button_set_title(HILDON_BUTTON(addbutton), "Select Ticker");
121 /* Set auto update time */
126 char *aszUpdateTimes[] =
135 timebutton = hildon_picker_button_new (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT,
136 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
138 timeselector = hildon_touch_selector_new_text();
140 for(i=0; i < sizeof(aszUpdateTimes)/sizeof(aszUpdateTimes[0]); i++)
142 hildon_touch_selector_append_text(HILDON_TOUCH_SELECTOR(timeselector),aszUpdateTimes[i]);
145 switch(psContext->psSettings->uiUpdateTime)
147 case 0: sel = 0; break;
148 case 1: sel = 1; break;
149 case 15: sel = 2; break;
150 case 30: sel = 3; break;
151 case 60: sel = 4; break;
154 hildon_touch_selector_set_active(HILDON_TOUCH_SELECTOR(timeselector), 0, sel);
155 hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (timebutton), HILDON_TOUCH_SELECTOR (timeselector));
156 hildon_button_set_title(HILDON_BUTTON(timebutton), "Automatic Update Period");
159 gtk_container_add(GTK_CONTAINER(content),addbutton);
160 gtk_container_add(GTK_CONTAINER(content),timebutton);
161 gtk_widget_show_all(dialog);
163 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
165 const char *pszNewTicker;
166 char aszOldTicker[255]={0};
167 guint uiUpdateSelection = 0;
169 /* Only perform ops if they actually changed the ticker */
170 if(strcmp(aszOldTicker,psContext->psSettings->ppszTickers[0]))
172 /* Save off old ticker */
173 strcpy(aszOldTicker,psContext->psSettings->ppszTickers[0]);
176 pszNewTicker = hildon_button_get_value(HILDON_BUTTON(addbutton));
178 /* Check if ticker already exists */
181 gboolean bFound = FALSE;
183 /* Check it doesn't exist already */
184 for(i=0; i < psContext->psSettings->uiNumTickers; i++)
186 if(!strcmp(pszNewTicker,psContext->psSettings->ppszTickers[i]))
193 /* If they just chose another one, just swap the pointers so new one is at the top:
197 /* Swapped ith and 0th element */
198 char *psTmp = psContext->psSettings->ppszTickers[i];
199 psContext->psSettings->ppszTickers[i] = psContext->psSettings->ppszTickers[0];
200 psContext->psSettings->ppszTickers[0] = psTmp;
202 DebugOut(("Swapped ticker %d (%s) with 0 (%s)",
204 psContext->psSettings->ppszTickers[i],
205 psContext->psSettings->ppszTickers[0]));
207 /* If it doesn't add it to the list, placing chosen one at the front */
210 gchar **ppszTickers = g_malloc0(sizeof(char*) * (psContext->psSettings->uiNumTickers+2));
212 /* Place the selected one first */
213 ppszTickers[0] = g_strdup(pszNewTicker);
215 /* Copy across old tickers */
216 for(i=0; i < psContext->psSettings->uiNumTickers; i++)
218 /* offset by one as the selected one is first */
219 ppszTickers[i+1] = g_strdup(psContext->psSettings->ppszTickers[i]);
222 /* Free current array */
223 g_strfreev(psContext->psSettings->ppszTickers);
225 /* Assign new array */
226 psContext->psSettings->ppszTickers = ppszTickers;
229 psContext->psSettings->uiNumTickers++;
233 /* Force a refresh as the ticker changed */
234 OnClickRefresh(GTK_WIDGET(psContext->psButton),psContext);
237 uiUpdateSelection = hildon_touch_selector_get_active(HILDON_TOUCH_SELECTOR(timeselector),0);
239 switch(uiUpdateSelection)
242 case 0: psContext->psSettings->uiUpdateTime = 0; break;
243 case 1: psContext->psSettings->uiUpdateTime = 1; break;
244 case 2: psContext->psSettings->uiUpdateTime = 15; break;
245 case 3: psContext->psSettings->uiUpdateTime = 30; break;
246 case 4: psContext->psSettings->uiUpdateTime = 60; break;
249 if(psContext->psSettings->uiUpdateTime != 0)
251 /* Remove previous timeout if there was one */
252 if(psContext->nTimerID != -1)
254 g_source_remove(psContext->nTimerID);
257 /* Add timer (in seconds) */
258 psContext->nTimerID = g_timeout_add_seconds(psContext->psSettings->uiUpdateTime * 60,
259 UpdateStockOnTimeout,
264 stock_save_settings(psContext->psSettings);
267 gtk_widget_destroy (dialog);
270 static GtkWidget *stock_create_gui(gchar *pszStockLabel,
271 StockPluginContext *psContext)
273 HildonButton *psButton = NULL;
275 DebugOut(("stock_create_gui"));
277 psButton = (HildonButton*)hildon_button_new_with_text (HILDON_SIZE_AUTO_WIDTH | HILDON_SIZE_FINGER_HEIGHT,
278 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
282 psContext->psButton = psButton;
284 /* Setup button click signal for refreshing stocks */
285 gtk_signal_connect (GTK_OBJECT(psButton),"clicked",GTK_SIGNAL_FUNC(OnClickRefresh),(gpointer)psContext);
288 gtk_widget_show_all(GTK_WIDGET(psButton));
290 return GTK_WIDGET(psButton);
294 stock_plugin_finalize (GObject *object)
296 StockPluginContext *psContext = ((StockPlugin*)object)->context;
298 DebugOut(("stock_plugin_finalize"));
302 if(psContext->psSettings)
304 if(psContext->psSettings)
305 g_free(psContext->psSettings->iD);
307 stock_free_settings(psContext->psSettings);
308 g_free(psContext->psSettings);
311 if(psContext->nTimerID != -1)
313 g_source_remove(psContext->nTimerID);
314 psContext->nTimerID = -1;
318 FreeStockGetter(psContext->hSG);
325 stock_plugin_init (StockPlugin *desktop_plugin)
327 StockPluginContext *psContext;
330 DebugOut(("stock_plugin_init"));
332 hSG = InitStockGetter();
339 /* Create plugin context */
340 psContext = g_new0(StockPluginContext,1);
342 /* Always create a settings */
343 psContext->psSettings = g_new0(StockPluginSettings,1);
344 psContext->psSettings->iD = g_strdup(STOCK_PLUGIN_APPLET_ID);
346 /* Attempt to load settings (defaulted if not present) */
347 stock_read_settings(psContext->psSettings);
349 /* Create GUI widget interface (and sets links in context) */
350 psContext->psBox = stock_create_gui("Click to Update",psContext);
352 gtk_container_add (GTK_CONTAINER (desktop_plugin), psContext->psBox);
354 psContext->hSG = hSG;
355 psContext->nTimerID = -1;
357 /* Assign private data to plugin */
358 desktop_plugin->context = psContext;
360 /* Remove previous timeout if there was one */
361 if(psContext->nTimerID != -1)
363 g_source_remove(psContext->nTimerID);
366 /* Setup new one if required */
367 if(psContext->psSettings->uiUpdateTime > 0)
369 psContext->nTimerID = g_timeout_add_seconds(psContext->psSettings->uiUpdateTime * 60,
370 UpdateStockOnTimeout,
374 /* Show a settings button */
375 hd_home_plugin_item_set_settings (HD_HOME_PLUGIN_ITEM (desktop_plugin), TRUE);
377 /* Connect to the settings button */
378 g_signal_connect(desktop_plugin, "show-settings", G_CALLBACK(stock_show_settings_dialog), psContext);
382 stock_plugin_class_init (StockPluginClass *klass)
384 G_OBJECT_CLASS(klass)->finalize = stock_plugin_finalize;
388 stock_plugin_class_finalize (StockPluginClass *klass)