/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* mateweather-xml.c - Locations.xml parsing code
*
* Copyright (C) 2005 Ryan Lortie, 2004 Gareth Owen
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see
* .
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
#include "mateweather-xml.h"
#include "weather-priv.h"
static gboolean
mateweather_xml_parse_node (MateWeatherLocation *gloc,
GtkTreeStore *store, GtkTreeIter *parent)
{
GtkTreeIter iter, *self = &iter;
MateWeatherLocation **children, *parent_loc;
MateWeatherLocationLevel level;
WeatherLocation *wloc;
const char *name;
int i;
name = mateweather_location_get_name (gloc);
children = mateweather_location_get_children (gloc);
level = mateweather_location_get_level (gloc);
if (!children[0] && level < MATEWEATHER_LOCATION_WEATHER_STATION) {
mateweather_location_free_children (gloc, children);
return TRUE;
}
switch (mateweather_location_get_level (gloc)) {
case MATEWEATHER_LOCATION_WORLD:
case MATEWEATHER_LOCATION_ADM2:
self = parent;
break;
case MATEWEATHER_LOCATION_REGION:
case MATEWEATHER_LOCATION_COUNTRY:
case MATEWEATHER_LOCATION_ADM1:
/* Create a row with a name but no WeatherLocation */
gtk_tree_store_append (store, &iter, parent);
gtk_tree_store_set (store, &iter,
MATEWEATHER_XML_COL_LOC, name,
-1);
break;
case MATEWEATHER_LOCATION_CITY:
/* If multiple children, treat this like a
* region/country/adm1. If a single child, merge with that
* location.
*/
gtk_tree_store_append (store, &iter, parent);
gtk_tree_store_set (store, &iter,
MATEWEATHER_XML_COL_LOC, name,
-1);
if (children[0] && !children[1]) {
wloc = mateweather_location_to_weather_location (children[0], name);
gtk_tree_store_set (store, &iter,
MATEWEATHER_XML_COL_POINTER, wloc,
-1);
}
break;
case MATEWEATHER_LOCATION_WEATHER_STATION:
gtk_tree_store_append (store, &iter, parent);
gtk_tree_store_set (store, &iter,
MATEWEATHER_XML_COL_LOC, name,
-1);
parent_loc = mateweather_location_get_parent (gloc);
if (parent_loc && mateweather_location_get_level (parent_loc) == MATEWEATHER_LOCATION_CITY)
name = mateweather_location_get_name (parent_loc);
wloc = mateweather_location_to_weather_location (gloc, name);
gtk_tree_store_set (store, &iter,
MATEWEATHER_XML_COL_POINTER, wloc,
-1);
break;
}
for (i = 0; children[i]; i++) {
if (!mateweather_xml_parse_node (children[i], store, self)) {
mateweather_location_free_children (gloc, children);
return FALSE;
}
}
mateweather_location_free_children (gloc, children);
return TRUE;
}
GtkTreeModel *
mateweather_xml_load_locations (void)
{
MateWeatherLocation *world;
GtkTreeStore *store;
world = mateweather_location_new_world (TRUE);
if (!world)
return NULL;
store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
if (!mateweather_xml_parse_node (world, store, NULL)) {
mateweather_xml_free_locations ((GtkTreeModel *)store);
store = NULL;
}
mateweather_location_unref (world);
return (GtkTreeModel *)store;
}
static gboolean
free_locations (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
WeatherLocation *loc = NULL;
gtk_tree_model_get (model, iter,
MATEWEATHER_XML_COL_POINTER, &loc,
-1);
if (loc) {
weather_location_free (loc);
gtk_tree_store_set ((GtkTreeStore *)model, iter,
MATEWEATHER_XML_COL_POINTER, NULL,
-1);
}
return FALSE;
}
/* Frees model returned from @mateweather_xml_load_locations. It contains allocated
WeatherLocation-s, thus this takes care of the freeing of that memory. */
void
mateweather_xml_free_locations (GtkTreeModel *locations)
{
if (locations && GTK_IS_TREE_STORE (locations)) {
gtk_tree_model_foreach (locations, free_locations, NULL);
g_object_unref (locations);
}
}