~ubuntu-branches/ubuntu/natty/xfce4-weather-plugin/natty-proposed

« back to all changes in this revision

Viewing changes to panel-plugin/weather-search.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2009-06-24 08:37:55 UTC
  • mfrom: (0.2.1 upstream) (2.1.15 karmic)
  • Revision ID: james.westby@ubuntu.com-20090624083755-b8dhv7muoebp7au9
Tags: 0.7.0-1
* New upstream release.
* debian/control:
  - update standards version to 3.8.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  $Id: weather-search.c 3212 2007-09-12 20:08:14Z nick $
 
1
/*  $Id: weather-search.c 7609 2009-06-18 17:29:09Z colin $
2
2
 *
3
3
 *  Copyright (c) 2003-2007 Xfce Development Team
4
4
 *
59
59
    {
60
60
      if (g_ascii_isspace (c))
61
61
        g_string_append (retstr, "%20");
62
 
      else if (g_ascii_isalnum (c) == FALSE)
63
 
        {
64
 
          g_string_free (retstr, TRUE);
65
 
          return NULL;
66
 
        }
67
62
      else
68
63
        g_string_append_c (retstr, c);
69
64
    }
86
81
  xmlDoc        *doc;
87
82
  xmlNode       *cur_node;
88
83
  gchar         *id, *city;
 
84
  gint           found = 0;
 
85
  GtkTreeIter       iter;
 
86
  GtkTreeSelection *selection;
 
87
 
 
88
  gtk_widget_set_sensitive(dialog->find_button, TRUE);
89
89
 
90
90
  if (!succeed || received == NULL)
91
91
    return;
92
92
 
93
 
  doc = xmlParseMemory (received, strlen (received));
 
93
  if (g_utf8_validate(received, -1, NULL)) {
 
94
    /* force parsing as UTF-8, the XML encoding header may lie */
 
95
    doc = xmlReadMemory (received, strlen (received), NULL, "UTF-8", 0);
 
96
  } else {
 
97
    doc = xmlParseMemory (received, strlen(received));
 
98
  }
94
99
  g_free (received);
95
100
 
96
101
  if (!doc)
118
123
                }
119
124
 
120
125
              append_result (dialog->result_mdl, id, city);
 
126
              found++;
121
127
              g_free (id);
122
128
              g_free (city);
123
129
            }
126
132
 
127
133
  xmlFreeDoc (doc);
128
134
 
 
135
  if (found > 0) {
 
136
    if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL (dialog->result_mdl), &iter)) {
 
137
      selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->result_list));
 
138
      gtk_tree_selection_select_iter(selection, &iter);
 
139
      gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog->dialog), GTK_RESPONSE_ACCEPT, TRUE);
 
140
    }
 
141
  }
 
142
  
 
143
gtk_tree_view_column_set_title(dialog->column, _("Results"));
129
144
  return;
130
145
}
131
146
 
138
153
  search_dialog *dialog = (search_dialog *) user_data;
139
154
  gchar         *sane_str, *url;
140
155
  const gchar   *str;
141
 
 
142
156
  str = gtk_entry_get_text (GTK_ENTRY (dialog->search_entry));
143
157
 
144
158
  if (strlen (str) == 0)
145
159
    return;
146
160
 
 
161
  if (dialog->last_search && !strcmp(str, dialog->last_search)) {
 
162
    GtkTreeSelection *selection;
 
163
    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->result_list));
 
164
    if (gtk_tree_selection_count_selected_rows(selection) == 1) {
 
165
      gtk_dialog_response(GTK_DIALOG(dialog->dialog), GTK_RESPONSE_ACCEPT);
 
166
      return;
 
167
    }
 
168
  }
 
169
  
 
170
  g_free(dialog->last_search);
 
171
  dialog->last_search = g_strdup(str);
 
172
 
147
173
  gtk_list_store_clear (GTK_LIST_STORE (dialog->result_mdl));
148
174
 
149
175
  if ((sane_str = sanitize_str (str)) == NULL)
150
176
    return;
151
177
 
 
178
  gtk_widget_set_sensitive(dialog->find_button, FALSE);
 
179
  gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog->dialog), GTK_RESPONSE_ACCEPT, FALSE);
 
180
 
152
181
  url = g_strdup_printf ("/search/search?where=%s", sane_str);
153
182
  g_free (sane_str);
154
183
 
 
184
  gtk_tree_view_column_set_title(dialog->column, _("Searching..."));
155
185
  weather_http_receive_data ("xoap.weather.com", url,
156
186
                             dialog->proxy_host, dialog->proxy_port,
157
187
                             cb_searchdone, dialog);
177
207
                      gchar     *proxy_host,
178
208
                      gint       proxy_port)
179
209
{
180
 
  GtkWidget         *vbox, *button, *hbox, *scroll, *frame;
181
 
  GtkTreeViewColumn *column;
 
210
  GtkWidget         *vbox, *hbox, *scroll, *frame;
182
211
  GtkCellRenderer   *renderer = gtk_cell_renderer_text_new ();
183
212
  search_dialog     *dialog;
 
213
  GtkWidget         *dialog_vbox, *dialog_action;
184
214
 
185
215
  dialog = panel_slice_new0 (search_dialog);
186
216
 
197
227
                                                GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
198
228
                                                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
199
229
 
 
230
  gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog->dialog), GTK_RESPONSE_ACCEPT, FALSE);
 
231
 
200
232
  gtk_window_set_icon_name (GTK_WINDOW (dialog->dialog), GTK_STOCK_FIND);
201
233
 
 
234
#if GTK_CHECK_VERSION(2,14,0)
 
235
  dialog_vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog->dialog));
 
236
  dialog_action = gtk_dialog_get_action_area(GTK_DIALOG(dialog->dialog));
 
237
#else
 
238
  dialog_vbox = GTK_DIALOG (dialog->dialog)->vbox;
 
239
  dialog_action = GTK_DIALOG (dialog->dialog)->action_area;
 
240
#endif
 
241
 
202
242
  vbox = gtk_vbox_new (FALSE, BORDER);
203
243
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
204
 
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->dialog)->vbox), vbox,
 
244
  gtk_box_pack_start (GTK_BOX (dialog_vbox), vbox,
205
245
                      TRUE, TRUE, 0);
206
 
 
 
246
  
207
247
  xfce_titled_dialog_set_subtitle (XFCE_TITLED_DIALOG (dialog->dialog),
208
248
                                   _("Enter a city name or zip code"));
209
249
 
212
252
 
213
253
  dialog->search_entry = gtk_entry_new ();
214
254
  gtk_box_pack_start (GTK_BOX (hbox), dialog->search_entry, TRUE, TRUE, 0);
 
255
  
215
256
  g_signal_connect (G_OBJECT (dialog->search_entry), "activate",
216
257
                    G_CALLBACK (search_cb), dialog);
217
258
 
218
 
  button = gtk_button_new_from_stock (GTK_STOCK_FIND);
219
 
  gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
220
 
  g_signal_connect (G_OBJECT (button), "clicked",
 
259
  dialog->find_button = gtk_button_new_from_stock (GTK_STOCK_FIND);
 
260
  gtk_box_pack_start (GTK_BOX (hbox), dialog->find_button, TRUE, TRUE, 0);
 
261
  g_signal_connect (G_OBJECT (dialog->find_button), "clicked",
221
262
                    G_CALLBACK (search_cb), dialog);
222
263
 
223
264
  frame = gtk_frame_new (NULL);
231
272
 
232
273
  dialog->result_mdl = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
233
274
  dialog->result_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog->result_mdl));
234
 
  column = gtk_tree_view_column_new_with_attributes (_("Results"), renderer, "text", 0, NULL);
235
 
  gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->result_list), column);
 
275
  dialog->column = gtk_tree_view_column_new_with_attributes (_("Results"), renderer, "text", 0, NULL);
 
276
  gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->result_list), dialog->column);
236
277
  g_signal_connect (G_OBJECT (dialog->result_list), "row-activated",
237
278
                    G_CALLBACK (pass_search_results), dialog->dialog);
238
279
  gtk_container_add (GTK_CONTAINER (scroll), dialog->result_list);
265
306
 
266
307
          g_value_unset (&value);
267
308
 
 
309
          gtk_tree_model_get_value (GTK_TREE_MODEL (dialog->result_mdl),
 
310
                                    &iter, 0, &value);
 
311
          dialog->result_name = g_strdup (g_value_get_string (&value));
 
312
 
 
313
          g_value_unset (&value);
 
314
 
268
315
          return TRUE;
269
316
        }
270
317
    }
272
319
  return FALSE;
273
320
}
274
321
 
275
 
 
276
 
 
277
322
void
278
323
free_search_dialog (search_dialog * dialog)
279
324
{
280
325
  g_free (dialog->result);
 
326
  g_free (dialog->result_name);
 
327
  g_free (dialog->last_search);
281
328
 
282
329
  gtk_widget_destroy (dialog->dialog);
283
330
 
284
331
  panel_slice_free (search_dialog, dialog);
285
332
}
 
333
 
 
334
typedef struct {
 
335
  const gchar *proxy_host;
 
336
  gint proxy_port;
 
337
  void (*cb)(const gchar *loc_name, const gchar *loc_code, gpointer user_data);
 
338
  gpointer user_data;
 
339
 
340
geolocation_data;
 
341
 
 
342
static void
 
343
cb_geo_searchdone (gboolean  succeed,
 
344
               gchar    *received,
 
345
               gpointer  user_data)
 
346
{
 
347
  geolocation_data *data = (geolocation_data *) user_data;
 
348
  xmlDoc        *doc;
 
349
  xmlNode       *cur_node;
 
350
  gchar         *id, *city;
 
351
  gboolean      found = FALSE;
 
352
  GtkTreeIter       iter;
 
353
  GtkTreeSelection *selection;
 
354
 
 
355
  if (!succeed || received == NULL) {
 
356
    data->cb(NULL, NULL, data->user_data);
 
357
    g_free(data);
 
358
    return;
 
359
  }
 
360
 
 
361
  if (g_utf8_validate(received, -1, NULL)) {
 
362
    /* force parsing as UTF-8, the XML encoding header may lie */
 
363
    doc = xmlReadMemory (received, strlen (received), NULL, "UTF-8", 0);
 
364
  } else {
 
365
    doc = xmlParseMemory (received, strlen(received));
 
366
  }
 
367
  g_free (received);
 
368
 
 
369
  if (!doc) {
 
370
    data->cb(NULL, NULL, data->user_data);
 
371
    g_free(data);
 
372
    return;
 
373
  }
 
374
 
 
375
  cur_node = xmlDocGetRootElement (doc);
 
376
 
 
377
  if (cur_node)
 
378
    {
 
379
      for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
 
380
        {
 
381
          if (NODE_IS_TYPE (cur_node, "loc"))
 
382
            {
 
383
              id = (gchar *) xmlGetProp (cur_node, (const xmlChar *) "id");
 
384
 
 
385
              if (!id)
 
386
                continue;
 
387
 
 
388
              city = DATA (cur_node);
 
389
 
 
390
              if (!city)
 
391
                {
 
392
                  g_free (id);
 
393
                  continue;
 
394
                }
 
395
 
 
396
              data->cb(city, id, data->user_data);
 
397
              g_free (id);
 
398
              g_free (city);
 
399
              break;
 
400
            }
 
401
        }
 
402
    }
 
403
  
 
404
  g_free(data);
 
405
  xmlFreeDoc (doc);
 
406
}
 
407
 
 
408
static void
 
409
cb_geolocation (gboolean  succeed,
 
410
                gchar    *received,
 
411
                gpointer  user_data)
 
412
{
 
413
  geolocation_data *data = (geolocation_data *) user_data;
 
414
  xmlDoc        *doc;
 
415
  xmlNode       *cur_node;
 
416
  gchar         *city = NULL, *country = NULL;
 
417
  gchar         *country_code = NULL, *region = NULL;
 
418
  gboolean      found = FALSE;
 
419
 
 
420
  if (!succeed || received == NULL) {
 
421
    data->cb(NULL, NULL, data->user_data);
 
422
    g_free(data);
 
423
    return;
 
424
  }
 
425
  if (g_utf8_validate(received, -1, NULL)) {
 
426
    /* force parsing as UTF-8, the XML encoding header may lie */
 
427
    doc = xmlReadMemory (received, strlen (received), NULL, "UTF-8", 0);
 
428
  } else {
 
429
    doc = xmlParseMemory (received, strlen(received));
 
430
  }
 
431
  g_free (received);
 
432
 
 
433
  if (!doc) {
 
434
    data->cb(NULL, NULL, data->user_data);
 
435
    g_free(data);
 
436
    return;
 
437
  }
 
438
 
 
439
  cur_node = xmlDocGetRootElement (doc);
 
440
 
 
441
  if (cur_node)
 
442
    {
 
443
      for (cur_node = cur_node->children; cur_node; cur_node = cur_node->next)
 
444
        {
 
445
          if (NODE_IS_TYPE (cur_node, "City"))
 
446
            {
 
447
              city = DATA (cur_node);
 
448
            }
 
449
          if (NODE_IS_TYPE (cur_node, "CountryName"))
 
450
            {
 
451
              country = DATA (cur_node);
 
452
            }
 
453
          if (NODE_IS_TYPE (cur_node, "CountryCode"))
 
454
            {
 
455
              country_code = DATA (cur_node);
 
456
            }
 
457
          if (NODE_IS_TYPE (cur_node, "RegionName"))
 
458
            {
 
459
              region = DATA (cur_node);
 
460
            }
 
461
        }
 
462
    }
 
463
  
 
464
  if (country_code && region && !strcmp(country_code, "US")) {
 
465
    g_free(country);
 
466
    country = region;
 
467
    region = NULL;
 
468
  }
 
469
  g_free(country_code);
 
470
  g_free(region);
 
471
  
 
472
  xmlFreeDoc (doc);
 
473
 
 
474
  if (city && country) {
 
475
     gchar *full_loc = g_strdup_printf("%s, %s", city, country);
 
476
     gchar *url, *sane_str;
 
477
     g_free(city);
 
478
     g_free(country);
 
479
     
 
480
     if ((sane_str = sanitize_str (full_loc)) == NULL) {
 
481
       data->cb(NULL, NULL, data->user_data);
 
482
       g_free(data);
 
483
       return;
 
484
     }
 
485
     g_free(full_loc);
 
486
     
 
487
     url = g_strdup_printf ("/search/search?where=%s", sane_str);
 
488
     g_free (sane_str);
 
489
 
 
490
     weather_http_receive_data ("xoap.weather.com", url,
 
491
                                data->proxy_host, data->proxy_port,
 
492
                                cb_geo_searchdone, data);
 
493
     g_free(url);
 
494
  }
 
495
}
 
496
 
 
497
 
 
498
 
 
499
gboolean weather_search_by_ip(
 
500
        const gchar *proxy_host, gint proxy_port,
 
501
        void (*gui_cb)(const gchar *loc_name, const gchar *loc_code, gpointer user_data),
 
502
        gpointer user_data)
 
503
{
 
504
  gchar *city = NULL, *country = NULL;
 
505
  gchar *search = NULL;
 
506
  geolocation_data *data;
 
507
  
 
508
  if (!gui_cb)
 
509
    return;
 
510
 
 
511
  data = g_new0(geolocation_data, 1);
 
512
  data->cb = gui_cb;
 
513
  data->user_data = user_data;
 
514
  data->proxy_host = proxy_host;
 
515
  data->proxy_port = proxy_port;
 
516
 
 
517
  weather_http_receive_data ("ipinfodb.com", "/ip_query.php",
 
518
                             proxy_host, proxy_port,
 
519
                             cb_geolocation, data);
 
520
 
 
521
}