champlain-base-marker.h \
champlain-marker.h \
champlain-map.h \
- champlain-zoom-level.h \
champlain-enum-types.h \
champlain-tile.h \
champlain-map-source.h \
champlain-network-map-source.h \
+ champlain-map-source-factory.h \
champlain-version.h
champlain-tile.c \
champlain-map-source.c \
champlain-network-map-source.c \
+ champlain-map-source-factory.c \
champlain-cache.c
noinst_HEADERS = \
champlain-enum-types.h \
champlain-map-source.h \
champlain-network-map-source.h \
+ champlain-map-source-factory.h \
champlain-version.h \
champlain-cache.h
champlain-layer.h \
champlain-map-source.h \
champlain-network-map-source.h \
+ champlain-map-source-factory.h \
champlain-tile.h \
champlain-zoom-level.h \
champlain-base-marker.h \
--- /dev/null
+/*
+ * Copyright (C) 2009 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include "champlain-map-source-factory.h"
+
+#define DEBUG_FLAG CHAMPLAIN_DEBUG_NETWORK
+#include "champlain-debug.h"
+
+#include "champlain.h"
+#include "champlain-cache.h"
+#include "champlain-defines.h"
+#include "champlain-enum-types.h"
+#include "champlain-map-source.h"
+#include "champlain-marshal.h"
+#include "champlain-private.h"
+#include "champlain-zoom-level.h"
+
+#include <glib.h>
+#include <string.h>
+
+enum
+{
+ /* normal signals */
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_0,
+};
+
+/* static guint champlain_map_source_factory_signals[LAST_SIGNAL] = { 0, }; */
+
+G_DEFINE_TYPE (ChamplainMapSourceFactory, champlain_map_source_factory, G_TYPE_OBJECT);
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY, ChamplainMapSourceFactoryPrivate))
+
+struct _ChamplainMapSourceFactoryPrivate
+{
+ GSList *registered_sources;
+};
+
+static ChamplainMapSource * champlain_map_source_new_osm_mapnik (void);
+static ChamplainMapSource * champlain_map_source_new_osm_cyclemap (void);
+static ChamplainMapSource * champlain_map_source_new_osm_osmarender (void);
+static ChamplainMapSource * champlain_map_source_new_oam (void);
+static ChamplainMapSource * champlain_map_source_new_mff_relief (void);
+
+
+static void
+champlain_map_source_factory_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ //ChamplainMapSourceFactory *map_source_factory = CHAMPLAIN_MAP_SOURCE_FACTORY(object);
+ //ChamplainMapSourceFactoryPrivate *priv = map_source_factory->priv;
+
+ switch(prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void
+champlain_map_source_factory_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ //ChamplainMapSourceFactory *map_source_factory = CHAMPLAIN_MAP_SOURCE_FACTORY(object);
+ //ChamplainMapSourceFactoryPrivate *priv = map_source_factory->priv;
+
+ switch(prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void
+champlain_map_source_factory_finalize (GObject *object)
+{
+ ChamplainMapSourceFactory *factory = CHAMPLAIN_MAP_SOURCE_FACTORY (object);
+
+ g_slist_free (factory->priv->registered_sources);
+
+ G_OBJECT_CLASS (champlain_map_source_factory_parent_class)->finalize (object);
+}
+
+static void
+champlain_map_source_factory_class_init (ChamplainMapSourceFactoryClass *klass)
+{
+ g_type_class_add_private (klass, sizeof (ChamplainMapSourceFactoryPrivate));
+
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = champlain_map_source_factory_finalize;
+ object_class->get_property = champlain_map_source_factory_get_property;
+ object_class->set_property = champlain_map_source_factory_set_property;
+}
+
+typedef struct {
+ gchar *name;
+ ChamplainMapSourceConstructor constructor;
+} MapSourceConstructor;
+
+static void
+champlain_map_source_factory_init (ChamplainMapSourceFactory *factory)
+{
+ ChamplainMapSourceFactoryPrivate *priv = GET_PRIVATE (factory);
+
+ factory->priv = priv;
+
+ priv->registered_sources = NULL;
+
+ champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK,
+ champlain_map_source_new_osm_mapnik);
+ champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OSM_CYCLEMAP,
+ champlain_map_source_new_osm_cyclemap);
+ champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OSM_OSMARENDER,
+ champlain_map_source_new_osm_osmarender);
+ champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OAM,
+ champlain_map_source_new_oam);
+ champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_MFF_RELIEF,
+ champlain_map_source_new_mff_relief);
+}
+
+ChamplainMapSourceFactory *
+champlain_map_source_factory_get_default (void)
+{
+ static ChamplainMapSourceFactory *instance = NULL;
+
+ if (G_UNLIKELY (instance == NULL))
+ {
+ instance = g_object_new (CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY, NULL);
+ return instance;
+ }
+
+ return g_object_ref (instance);
+}
+
+gchar **
+champlain_map_source_factory_get_list (ChamplainMapSourceFactory *factory)
+{
+
+ gint count;
+ gchar **ret;
+ GSList *item;
+
+ count = g_slist_length (factory->priv->registered_sources);
+ ret = g_new0(char*, count + 1);
+ item = factory->priv->registered_sources;
+
+ count = 0;
+ while (item != NULL)
+ {
+ MapSourceConstructor *cons = (MapSourceConstructor*) item->data;
+ ret[count] = g_strdup (cons->name);
+ item = g_slist_next (item);
+ count++;
+ }
+ ret[count] = NULL;
+
+ return ret;
+}
+
+ChamplainMapSource *
+champlain_map_source_factory_create (ChamplainMapSourceFactory *factory,
+ const gchar *name)
+{
+ GSList *item;
+
+ item = factory->priv->registered_sources;
+
+ while (item != NULL)
+ {
+ MapSourceConstructor *cons = (MapSourceConstructor*) item->data;
+ if (strcmp (cons->name, name) == 0)
+ return cons->constructor ();
+ item = g_slist_next (item);
+ }
+ return NULL;
+}
+
+gboolean
+champlain_map_source_factory_register (ChamplainMapSourceFactory *factory,
+ const gchar *name,
+ ChamplainMapSourceConstructor callback)
+{
+ MapSourceConstructor *cons;
+
+ /* FIXME: check for existing factory with that name? */
+ cons = g_slice_new0(MapSourceConstructor);
+ cons->name = g_strdup (name);
+ cons->constructor = callback;
+ factory->priv->registered_sources = g_slist_append (factory->priv->registered_sources, cons);
+ return TRUE;
+}
+
+static ChamplainMapSource *
+champlain_map_source_new_osm_cyclemap (void)
+{
+ return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OSM_CYCLEMAP,
+ "(CC) BY 2.0 OpenStreetMap contributors",
+ "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256,
+ CHAMPLAIN_MAP_PROJECTION_MERCATOR,
+ "http://andy.sandbox.cloudmade.com/tiles/cycle/#Z#/#X#/#Y#.png"));
+}
+
+static ChamplainMapSource *
+champlain_map_source_new_osm_osmarender (void)
+{
+ return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OSM_OSMARENDER,
+ "(CC) BY 2.0 OpenStreetMap contributors",
+ "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256,
+ CHAMPLAIN_MAP_PROJECTION_MERCATOR,
+ "http://tah.openstreetmap.org/Tiles/tile/#Z#/#X#/#Y#.png"));
+}
+
+static ChamplainMapSource *
+champlain_map_source_new_osm_mapnik (void)
+{
+ return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK,
+ "(CC) BY 2.0 OpenStreetMap contributors",
+ "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256,
+ CHAMPLAIN_MAP_PROJECTION_MERCATOR,
+ "http://tile.openstreetmap.org/#Z#/#X#/#Y#.png"));
+}
+
+static ChamplainMapSource *
+champlain_map_source_new_oam (void)
+{
+ return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OAM,
+ "(CC) BY 3.0 OpenArialMap contributors",
+ "http://creativecommons.org/licenses/by/3.0/", 0, 17, 256,
+ CHAMPLAIN_MAP_PROJECTION_MERCATOR,
+ "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/#Z#/#X#/#Y#.jpg"));
+}
+
+static ChamplainMapSource *
+champlain_map_source_new_mff_relief (void)
+{
+ return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_MFF_RELIEF,
+ "Map data available under GNU Free Documentation license, Version 1.2 or later",
+ "http://www.gnu.org/copyleft/fdl.html", 0, 11, 256,
+ CHAMPLAIN_MAP_PROJECTION_MERCATOR,
+ "http://maps-for-free.com/layer/relief/z#Z#/row#Y#/#Z#_#X#-#Y#.jpg"));
+}
--- /dev/null
+/*
+ * Copyright (C) 2009 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (__CHAMPLAIN_CHAMPLAIN_H_INSIDE__) && !defined (CHAMPLAIN_COMPILATION)
+#error "Only <champlain/champlain.h> can be included directly."
+#endif
+
+#ifndef CHAMPLAIN_MAP_SOURCE_FACTORY_H
+#define CHAMPLAIN_MAP_SOURCE_FACTORY_H
+
+#include <champlain/champlain-defines.h>
+#include <champlain/champlain-map-source.h>
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY (champlain_map_source_factory_get_type())
+#define CHAMPLAIN_MAP_SOURCE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY, ChamplainMapSourceFactory))
+#define CHAMPLAIN_MAP_SOURCE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY, ChamplainMapSourceFactoryClass))
+#define CHAMPLAIN_IS_MAP_SOURCE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY))
+#define CHAMPLAIN_IS_MAP_SOURCE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY))
+#define CHAMPLAIN_MAP_SOURCE_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), CHAMPLAIN_TYPE_MAP_SOURCE_FACTORY, ChamplainMapSourceFactoryClass))
+
+typedef struct _ChamplainMapSourceFactory ChamplainMapSourceFactory;
+typedef struct _ChamplainMapSourceFactoryClass ChamplainMapSourceFactoryClass;
+typedef struct _ChamplainMapSourceFactoryPrivate ChamplainMapSourceFactoryPrivate;
+
+struct _ChamplainMapSourceFactory
+{
+ GObject parent;
+ ChamplainMapSourceFactoryPrivate *priv;
+};
+
+struct _ChamplainMapSourceFactoryClass
+{
+ GObjectClass parent_class;
+};
+
+GType champlain_map_source_factory_get_type (void);
+
+ChamplainMapSourceFactory * champlain_map_source_factory_get_default (void);
+
+gchar ** champlain_map_source_factory_get_list (ChamplainMapSourceFactory *factory);
+
+ChamplainMapSource * champlain_map_source_factory_create (ChamplainMapSourceFactory *factory,
+ const gchar *id);
+
+typedef ChamplainMapSource * (*ChamplainMapSourceConstructor) ();
+#define CHAMPLAIN_MAP_SOURCE_CONSTRUCTOR (f) ((ChamplainMapSourceConstructor) (f))
+
+gboolean champlain_map_source_factory_register (ChamplainMapSourceFactory *factory,
+ const gchar *id,
+ ChamplainMapSourceConstructor callback);
+
+#define CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK "OpenStreetMap Mapnik"
+#define CHAMPLAIN_MAP_SOURCE_OSM_OSMARENDER "OpenStreetMap Osmarender"
+#define CHAMPLAIN_MAP_SOURCE_OSM_CYCLEMAP "OpenStreetMap CycleMap"
+#define CHAMPLAIN_MAP_SOURCE_OAM "OpenArialMap"
+#define CHAMPLAIN_MAP_SOURCE_MFF_RELIEF "MapsForFree Relief"
+
+G_END_DECLS
+
+#endif
priv->uri_format = g_strdup (uri_format);
}
-ChamplainMapSource *
-champlain_map_source_new_osm_cyclemap (void)
-{
- return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full ("OpenStreetMap Cycle Map",
- "(CC) BY 2.0 OpenStreetMap contributors",
- "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256,
- CHAMPLAIN_MAP_PROJECTION_MERCATOR,
- "http://andy.sandbox.cloudmade.com/tiles/cycle/#Z#/#X#/#Y#.png"));
-}
-
-ChamplainMapSource *
-champlain_map_source_new_osm_osmarender (void)
-{
- return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full ("OpenStreetMap Osmarender",
- "(CC) BY 2.0 OpenStreetMap contributors",
- "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256,
- CHAMPLAIN_MAP_PROJECTION_MERCATOR,
- "http://tah.openstreetmap.org/Tiles/tile/#Z#/#X#/#Y#.png"));
-}
-
-ChamplainMapSource *
-champlain_map_source_new_osm_mapnik (void)
-{
- return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full ("OpenStreetMap Mapnik",
- "(CC) BY 2.0 OpenStreetMap contributors",
- "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256,
- CHAMPLAIN_MAP_PROJECTION_MERCATOR,
- "http://tile.openstreetmap.org/#Z#/#X#/#Y#.png"));
-}
-
-ChamplainMapSource *
-champlain_map_source_new_oam (void)
-{
- return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full ("OpenArialMap",
- "(CC) BY 3.0 OpenArialMap contributors",
- "http://creativecommons.org/licenses/by/3.0/", 0, 17, 256,
- CHAMPLAIN_MAP_PROJECTION_MERCATOR,
- "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/#Z#/#X#/#Y#.jpg"));
-}
-
-ChamplainMapSource *
-champlain_map_source_new_mff_relief (void)
-{
- return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full ("MapsForFree Relief",
- "Map data available under GNU Free Documentation license, Version 1.2 or later",
- "http://www.gnu.org/copyleft/fdl.html", 0, 11, 256,
- CHAMPLAIN_MAP_PROJECTION_MERCATOR,
- "http://maps-for-free.com/layer/relief/z#Z#/row#Y#/#Z#_#X#-#Y#.jpg"));
-}
-
static gchar *
get_filename (ChamplainNetworkMapSource *network_map_source,
ChamplainTile *tile)
guint min_zoom, guint map_zoom, guint tile_size,
ChamplainMapProjection projection, const gchar *uri_format);
-ChamplainMapSource * champlain_map_source_new_osm_mapnik (void);
-ChamplainMapSource * champlain_map_source_new_osm_cyclemap (void);
-ChamplainMapSource * champlain_map_source_new_osm_osmarender (void);
-ChamplainMapSource * champlain_map_source_new_oam (void);
-ChamplainMapSource * champlain_map_source_new_mff_relief (void);
-
gchar * champlain_network_map_source_get_tile_uri (ChamplainNetworkMapSource *source,
gint x,
gint y,
#include "champlain-map.h"
#include "champlain-marshal.h"
#include "champlain-map-source.h"
+#include "champlain-map-source-factory.h"
#include "champlain-private.h"
#include "champlain-tile.h"
#include "champlain-zoom-level.h"
{
ClutterActor *stage;
+ ChamplainMapSourceFactory *factory; /* The map source factory */
ChamplainMapSource *map_source; /* Current map tile source */
ChamplainScrollMode scroll_mode;
gint zoom_level; /* Holds the current zoom level number */
{
ChamplainView *view = CHAMPLAIN_VIEW (object);
ChamplainViewPrivate *priv = view->priv;
+ g_object_unref (priv->factory);
g_object_unref (priv->map_source);
if (priv->license_actor)
g_object_unref (priv->license_actor);
view->priv = priv;
- priv->map_source = g_object_ref (champlain_map_source_new_osm_mapnik ());
+ priv->factory = champlain_map_source_factory_get_default ();
+ priv->map_source = champlain_map_source_factory_create (priv->factory, CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK);
priv->zoom_level = 0;
priv->min_zoom_level = champlain_map_source_get_min_zoom_level (priv->map_source);
priv->max_zoom_level = champlain_map_source_get_max_zoom_level (priv->map_source);
/*
- * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ * Copyright (C) 2008-2009 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include "champlain/champlain-view.h"
#include "champlain/champlain-enum-types.h"
#include "champlain/champlain-map-source.h"
+#include "champlain/champlain-map-source-factory.h"
#include "champlain/champlain-network-map-source.h"
#include "champlain/champlain-version.h"
#include <markers.h>
-#define OSM_MAP "Open Street Map"
-#define OAM_MAP "Open Arial Map"
-#define MFF_MAP "Maps for free - Relief"
-#define OSM_CYCLE "OSM Cycle Map"
-#define OSM_OSMA "OSM Osmarender"
-
/*
* Terminate the main loop.
*/
map_source_changed (GtkWidget *widget,
ChamplainView *view)
{
- gchar* selection = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
- if (g_strcmp0 (selection, OSM_MAP) == 0)
- {
- g_object_set (G_OBJECT (view), "map-source", champlain_map_source_new_osm_mapnik (), NULL);
- }
- else if (g_strcmp0 (selection, OAM_MAP) == 0)
- {
- g_object_set (G_OBJECT (view), "map-source", champlain_map_source_new_oam (), NULL);
- }
- else if (g_strcmp0 (selection, MFF_MAP) == 0)
- {
- g_object_set (G_OBJECT (view), "map-source", champlain_map_source_new_mff_relief (), NULL);
- }
- else if (g_strcmp0 (selection, OSM_CYCLE) == 0)
- {
- g_object_set (G_OBJECT (view), "map-source", champlain_map_source_new_osm_cyclemap (), NULL);
- }
- else if (g_strcmp0 (selection, OSM_OSMA) == 0)
- {
- g_object_set (G_OBJECT (view), "map-source", champlain_map_source_new_osm_osmarender (), NULL);
- }
+ gchar* selection;
+ ChamplainMapSource *source;
+
+ selection = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
+ ChamplainMapSourceFactory *factory = champlain_map_source_factory_get_default ();
+ source = champlain_map_source_factory_create (factory, selection);
+
+ g_object_set (G_OBJECT (view), "map-source", source, NULL);
+
+ g_object_unref (factory);
+ g_object_unref (source);
}
static void
champlain_view_zoom_out(view);
}
+static void
+build_combo_box (GtkComboBox *box)
+{
+ ChamplainMapSourceFactory *factory;
+ gchar **sources;
+ gchar *name;
+ gint i = 0;
+
+ factory = champlain_map_source_factory_get_default ();
+ sources = champlain_map_source_factory_get_list (factory);
+ name = sources[i];
+
+ while (name != NULL)
+ {
+ gtk_combo_box_append_text(GTK_COMBO_BOX(box), g_strdup (name));
+ name = sources[++i];
+ }
+
+ g_strfreev (sources);
+ g_object_unref (factory);
+}
+
int
main (int argc,
char *argv[])
gtk_container_add (GTK_CONTAINER (bbox), button);
button = gtk_combo_box_new_text();
- gtk_combo_box_append_text(GTK_COMBO_BOX(button), OSM_MAP);
- gtk_combo_box_append_text(GTK_COMBO_BOX(button), OAM_MAP);
- gtk_combo_box_append_text(GTK_COMBO_BOX(button), MFF_MAP);
- gtk_combo_box_append_text(GTK_COMBO_BOX(button), OSM_CYCLE);
- gtk_combo_box_append_text(GTK_COMBO_BOX(button), OSM_OSMA);
+ build_combo_box (button);
gtk_combo_box_set_active(GTK_COMBO_BOX(button), 0);
g_signal_connect (button, "changed", G_CALLBACK (map_source_changed), view);
gtk_container_add (GTK_CONTAINER (bbox), button);