Hello Vladimir

Here is another patch for the GPS map software. It requires libchamplain-0.3, which can be downloaded from the libchamplain mainline repository. Run autogen.sh with --enable-gps CFLAGS=O0.

Unfortunately this is a more of a step backwards than forwards, as I get intermittent memory and exception errors that I cannot solve.

However this version has the Cycle Map and Osmarender in addition to the previous maps.

There are two additional functions that sort-of work. Most of my photos are not geocoded, so I coded some things to make things easy for me.

If I select a place-name on geonames.org and copy the lat/lon to the clipboard, middle-click on the geeqie map allows me to centre the map on that location.

I can then drag-and-drop thumbnails onto the map to geocode them. There are problems with both these functions, but they work well enough for me. I doubt other users of geeqie will need this facility, so there is little point in resolving these problems.



There is also an extra item on the search page to locate photos within a given range of a lat/lon position. There are a couple of problems with this also.

Something with  math.h, which is the reason for the CFLAGS option.

And it is not possible to select all the files in the result of the search and show them on the geeqie map. This rather limits the usefulness of this function. But again, if this is of no use to other users of geeqie there is no point in solving problems that do not need to be solved.


This is just to let you know the current standing. Meanwhile I'll continue to bang my head against a brick wall with these memory and exception errors.

Colin Clark...

Index: configure.in
===================================================================
--- configure.in	(revision 1600)
+++ configure.in	(working copy)
@@ -328,6 +328,45 @@
 AC_SUBST(LDFLAGS)
 
 
+#  Libchamplain support - used for GPS map facility
+# ----------------------------------------------------------------------
+
+AC_ARG_ENABLE([gps],
+  AC_HELP_STRING([--enable-gps], [enable GPS map support]),
+    [libgps=$enableval], [libgps=auto])
+
+if test "x${libgps}" == "xyes"; then
+  PKG_CHECK_MODULES(LIBCHAMPLAIN, [champlain-0.2 >= 0.2.9],
+    [
+      HAVE_LIBCHAMPLAIN=yes
+      AC_DEFINE(HAVE_LIBCHAMPLAIN, 1, [define to enable use of GPS maps])
+    ],
+    [
+      HAVE_LIBCHAMPLAIN=no
+      AC_MSG_WARN([$LIBCHAMPLAIN_PKG_ERRORS])
+    ])
+else
+  HAVE_LIBCHAMPLAIN=disabled
+fi
+
+if test "x${libgps}" == "xyes"; then
+  PKG_CHECK_MODULES(LIBCHAMPLAIN_GTK, [champlain-gtk-0.2 >= 0.2.9],
+    [
+      HAVE_LIBCHAMPLAIN_GTK=yes
+      AC_DEFINE(HAVE_LIBCHAMPLAIN_GTK, 1, [define to enable use of GPS maps])
+    ],
+    [
+      HAVE_LIBCHAMPLAIN_GTK=no
+      AC_MSG_WARN([$LIBCHAMPLAIN_GTK_PKG_ERRORS])
+    ])
+else
+  HAVE_LIBCHAMPLAIN_GTK=disabled
+fi
+	
+AM_CONDITIONAL(HAVE_LIBCHAMPLAIN_GTK, [test "x$HAVE_LIBCHAMPLAIN_GTK" = xyes])
+AC_SUBST(LIBCHAMPLAIN_GTK_CFLAGS)
+AC_SUBST(LIBCHAMPLAIN_GTK_LIBS)
+
 AH_TOP([
 /** @file config.h
  * autogenerated definition by autoheader.
@@ -398,7 +437,7 @@
   Gtk:           $GTK_CFLAGS
   Glib:          $GLIB_CFLAGS
   Thread:        $GTHREAD_LIBS
-  Others:	 $LCMS_LIBS $EXIV2_LIBS
+  Others:	 $LCMS_LIBS $EXIV2_LIBS $LIBCHAMPLAIN_LIBS $LIBCHAMPLAIN_GTK_LIBS
 
 Localization:
   NLS support:   $USE_NLS
@@ -414,6 +453,8 @@
   LCMS:          $HAVE_LCMS
   Exiv2:	 $HAVE_EXIV2
   Lirc:          $HAVE_LIRC
+  Libchamplain:		$HAVE_LIBCHAMPLAIN
+  Libchamplain-gtk:	$HAVE_LIBCHAMPLAIN_GTK
 
 Documentation:
   Doxygen:       $DOXYGEN
Index: src/bar.c
===================================================================
--- src/bar.c	(revision 1600)
+++ src/bar.c	(working copy)
@@ -24,11 +24,13 @@
 
 #include "ui_menu.h"
 #include "bar_comment.h"
+#include "bar_gps.h"
 #include "bar_keywords.h"
 #include "bar_exif.h"
 #include "bar_histogram.h"
 #include "histogram.h"
 #include "rcfile.h"
+#include "bar_gps.h"
 
 typedef struct _KnownPanes KnownPanes;
 struct _KnownPanes
@@ -144,6 +146,21 @@
 "    </layout>"
 "</gq>";
 
+static const gchar default_config_gps[] = 
+"<gq>"
+"    <layout id = '_current_'>"
+"        <bar>"
+"            <pane_gps id = 'gps' expanded = 'true' >"
+"                map-source = 'Open Street Map - Mapnik'"
+"                zoom-level = '11'"
+"                latitude = '0.000000'"
+"                longitude = '0.000000'" 
+"                marker-icon = './src/icons/red-dot.png'"
+"            </>"
+"        </bar>"
+"    </layout>"
+"</gq>";
+
 static const KnownPanes known_panes[] = {
 /* default sidebar */
 	{PANE_HISTOGRAM,	"histogram",	N_("Histogram"),	default_config_histogram},
@@ -155,6 +172,7 @@
 	{PANE_EXIF,		"file_info",	N_("File info"),	default_config_file_info},
 	{PANE_EXIF,		"location",	N_("Location"),		default_config_location},
 	{PANE_EXIF,		"copyright",	N_("Copyright"),	default_config_copyright},
+	{PANE_GPS,		"gps",	N_("GPS Map"),	default_config_gps},
 
 	{PANE_UNDEF,		NULL,		NULL,			NULL}
 };
Index: src/bar.h
===================================================================
--- src/bar.h	(revision 1600)
+++ src/bar.h	(working copy)
@@ -17,6 +17,7 @@
 typedef enum {
 	PANE_UNDEF = 0,
 	PANE_COMMENT,
+	PANE_GPS,
 	PANE_EXIF,
 	PANE_HISTOGRAM,
 	PANE_KEYWORDS
Index: src/main.c
===================================================================
--- src/main.c	(revision 1600)
+++ src/main.c	(working copy)
@@ -748,7 +748,8 @@
 	file_data_register_notify_func(collect_manager_notify_cb, NULL, NOTIFY_PRIORITY_LOW);
 
 	gtkrc_load();
-	gtk_init(&argc, &argv);
+//	gtk_init(&argc, &argv);
+	gtk_clutter_init (&argc, &argv);
 
 	if (gtk_major_version < GTK_MAJOR_VERSION ||
 	    (gtk_major_version == GTK_MAJOR_VERSION && gtk_minor_version < GTK_MINOR_VERSION) )
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 1600)
+++ src/Makefile.am	(working copy)
@@ -5,6 +5,8 @@
 	$(GLIB_CFLAGS) $(GTK_CFLAGS)	\
 	$(LCMS_CFLAGS)			\
 	$(EXIV2_CFLAGS)			\
+	$(LIBCHAMPLAIN_CFLAGS)	\
+	$(LIBCHAMPLAIN_GTK_CFLAGS)
 	-I$(top_srcdir)			\
 	-I$(top_builddir)
 
@@ -13,6 +15,8 @@
 	$(GLIB_CFLAGS) $(GTK_CFLAGS)	\
 	$(LCMS_CFLAGS)			\
 	$(EXIV2_CFLAGS)			\
+	$(LIBCHAMPLAIN_CFLAGS)	\
+	$(LIBCHAMPLAIN_GTK_CFLAGS)	
 	-I$(top_srcdir)			\
 	-I$(top_builddir)
 
@@ -82,6 +86,8 @@
 	bar.h		\
 	bar_comment.c	\
 	bar_comment.h	\
+	bar_gps.c	\
+	bar_gps.h	\
 	bar_histogram.c	\
 	bar_histogram.h	\
 	bar_keywords.c	\
@@ -112,8 +118,8 @@
 	compat.h	\
 	debug.c		\
 	debug.h		\
-	desktop_file.c	\
-	desktop_file.h	\
+	desktop_file.c		\
+	desktop_file.h		\
 	dnd.c		\
 	dnd.h		\
 	dupe.c		\
@@ -237,7 +243,7 @@
 	window.c	\
 	window.h
 
-geeqie_LDADD = $(GTK_LIBS) $(GLIB_LIBS) $(INTLLIBS) $(LCMS_LIBS) $(EXIV2_LIBS)
+geeqie_LDADD = $(GTK_LIBS) $(GLIB_LIBS) $(INTLLIBS) $(LCMS_LIBS) $(EXIV2_LIBS) $(LIBCHAMPLAIN_LIBS) $(LIBCHAMPLAIN_GTK_LIBS)
 
 EXTRA_DIST = \
 	$(extra_SLIK)
Index: src/rcfile.c
===================================================================
--- src/rcfile.c	(revision 1600)
+++ src/rcfile.c	(working copy)
@@ -930,7 +930,25 @@
 			bar_add(bar, pane);
 			}
 		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
+		}	
+#ifdef HAVE_LIBCHAMPLAIN
+#ifdef HAVE_LIBCHAMPLAIN_GTK
+	else if (g_ascii_strcasecmp(element_name, "pane_gps") == 0)
+		{
+		GtkWidget *pane = bar_find_pane_by_id(bar, PANE_GPS, options_get_id(attribute_names, attribute_values));
+		if (pane)
+			{
+			bar_pane_gps_update_from_config(pane, attribute_names, attribute_values);
+			}
+		else
+			{
+			pane = bar_pane_gps_new_from_config(attribute_names, attribute_values);
+			bar_add(bar, pane);
+			}
+		options_parse_func_push(parser_data, options_parse_leaf, NULL, NULL);
 		}
+#endif
+#endif
 	else if (g_ascii_strcasecmp(element_name, "pane_exif") == 0)
 		{
 		GtkWidget *pane = bar_find_pane_by_id(bar, PANE_EXIF, options_get_id(attribute_names, attribute_values));
Index: src/exif-common.c
===================================================================
--- src/exif-common.c	(revision 1600)
+++ src/exif-common.c	(working copy)
@@ -41,6 +41,7 @@
 #include "format_raw.h"
 #include "ui_fileops.h"
 #include "cache.h"
+#include "exif-common.h"
 
 
 static gdouble exif_rational_to_double(ExifRational *r, gint sign)
@@ -433,6 +434,60 @@
 	return g_strdup_printf("%s (%s)", name, source);
 }
 
+void exif_build_unformatted_GPSPosition(ExifData *exif, gdouble gpsposn[])
+{
+	GString *string;
+	gchar *text, *ref;
+	ExifRational *value;
+	ExifItem *item;
+	guint i;
+	gdouble p;
+
+	string = g_string_new("");
+	gpsposn[0]=0;
+	gpsposn[1]=0;
+
+	item = exif_get_item(exif, "Exif.GPSInfo.GPSLatitude");
+	ref = exif_get_data_as_text(exif, "Exif.GPSInfo.GPSLatitudeRef");
+	if (item && ref)
+		{
+		p = 0;
+		for (i = 0; i < exif_item_get_elements(item); i++)
+			{
+			value = exif_item_get_rational(item, NULL, i);
+			if (value && value->num && value->den)
+				p += (gdouble)value->num / (gdouble)value->den / pow(60.0, (gdouble)i);
+			}
+			
+		if (!strcmp(ref,"South"))
+			{
+			p=-p;
+			}
+		gpsposn[0]=p;
+		} // if (item && ref)
+	
+	item = exif_get_item(exif, "Exif.GPSInfo.GPSLongitude");
+	ref = exif_get_data_as_text(exif, "Exif.GPSInfo.GPSLongitudeRef");
+	if (item && ref)
+		{
+		p = 0;
+		for (i = 0; i < exif_item_get_elements(item); i++)
+			{
+			value = exif_item_get_rational(item, NULL, i);
+			if (value && value->num && value->den)
+			p += (gdouble)value->num / (gdouble)value->den / pow(60.0, (gdouble)i);
+			}
+			
+		if (!strcmp(ref,"West"))
+			{
+			p=-p;
+			}
+		gpsposn[1]=p;		
+		} // if (item && ref)
+	
+	return;
+} 
+
 static gchar *exif_build_formatted_GPSPosition(ExifData *exif)
 {
 	GString *string;
/*
 * Geeqie
 * (C) 2004 John Ellis
 * Copyright (C) 2008 - 2009 The Geeqie Team
 *
 * Author: John Ellis
 *
 * This software is released under the GNU General Public License (GNU GPL).
 * Please read the included file COPYING for more information.
 * This software comes with no warranty of any kind, use at your own risk!
 */


#include "main.h"
#ifdef HAVE_LIBCHAMPLAIN
#ifdef HAVE_LIBCHAMPLAIN_GTK

#include "bar_gps.h"

#include "bar.h"
#include "metadata.h"
#include "filedata.h"
#include "ui_menu.h"
#include "ui_misc.h"
#include "rcfile.h"
#include "layout.h"
#include "exif.h"
#include "exif-common.h"

#include <champlain/champlain.h>
#include <champlain-gtk/champlain-gtk.h>
#include <clutter-gtk/gtk-clutter-embed.h>
#include <clutter-cairo/clutter-cairo.h>

#define PADDING 0
#define FACTOR 2.0

static void bar_pane_gps_changed(ChamplainView *buffer, gpointer data);

/*
 *-------------------------------------------------------------------
 * GPS Map utils
 *-------------------------------------------------------------------
 */


typedef struct _PaneGPSData PaneGPSData;
struct _PaneGPSData
{
	PaneData pane;
	GtkWidget *widget;
	FileData *fd;
	gchar *map_source;
	gchar *marker_icon;
	gint height;
	ClutterActor *gps_view;
	ClutterActor *icon_layer;
	ClutterActor *text_layer;
	ClutterActor *image_layer;
	ClutterActor *icon_marker;
	ClutterActor *text_marker;
	ClutterActor *image_marker;
};

static ClutterActor* bar_pane_gps_create_icon_layer (PaneGPSData *pane)
{
	ClutterActor *layer, *marker;
	gint index;
	GError *error;

	layer = champlain_layer_new();
	clutter_container_add(CLUTTER_CONTAINER(layer), marker, NULL);
	pane->icon_marker=marker;

	return layer;
}

static ClutterActor* bar_pane_gps_create_image_layer (PaneGPSData *pane)
{
	ClutterActor *layer, *marker;
	gint index;
	GError *error;

	layer = champlain_layer_new();

	clutter_container_add(CLUTTER_CONTAINER(layer), marker, NULL);
	pane->image_marker=marker;

	return layer;
}

static ClutterActor* bar_pane_gps_create_text_layer (PaneGPSData *pane)
{
	ClutterActor *layer, *marker;
	gint index;
	GError *error;

	layer = champlain_layer_new();

	ClutterColor orange = { 0xf3, 0x94, 0x07, 0xbb };
	ClutterColor white = { 0xff, 0xff, 0xff, 0xff };

	marker = champlain_marker_new_with_label("test", "Airmole 14", NULL, NULL);
	champlain_marker_set_position(CHAMPLAIN_MARKER(marker), 54, -4);
	clutter_container_add(CLUTTER_CONTAINER(layer), marker, NULL);
	pane->text_marker=marker;

	return layer;
}


static void bar_pane_gps_update(PaneGPSData *pcd)
{
	gchar *comment = NULL;
	gdouble item1, item2;
	gdouble gpsposition[2];
	gchar *thumbnail_path1;
	gchar *thumbnail_path2;
	gchar *thumbnail_path3;
	guint width, height, point;
	GList *list = NULL;
	GList *work;
	ClutterActor *layer, *marker, *thumb;
	ClutterActor  *thumb_frame;
	gint active_layer;
	gboolean file_found;
	ClutterColor color = { 0x99, 0x99, 0x99, 0xff };
	ClutterColor darker_color;

	file_found = FALSE;

	if (CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(pcd->gps_view)))
		{
		if (CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(pcd->icon_layer)))
			{
			active_layer = 1;
			clutter_actor_hide(pcd->icon_layer);
			}
		else if (CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(pcd->text_layer)))
			{
			active_layer = 2;
			clutter_actor_hide(pcd->text_layer);
			}
		else if (CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(pcd->image_layer)))
			{
			active_layer = 3;
			clutter_actor_hide(pcd->image_layer);
			}
		else
			active_layer =4 ;
		}
	else
		active_layer = 1;

	clutter_actor_destroy(pcd->icon_layer);
	layer = champlain_layer_new();
	pcd->icon_layer = layer;
	champlain_view_add_layer(CHAMPLAIN_VIEW (pcd->gps_view), pcd->icon_layer);
	clutter_actor_hide(pcd->icon_layer);

	clutter_actor_destroy(pcd->text_layer);
	layer = champlain_layer_new();
	pcd->text_layer = layer;
	champlain_view_add_layer(CHAMPLAIN_VIEW (pcd->gps_view), pcd->text_layer);
	clutter_actor_hide(pcd->text_layer);

	clutter_actor_destroy(pcd->image_layer);
	layer = champlain_layer_new();
	pcd->image_layer = layer;
	champlain_view_add_layer(CHAMPLAIN_VIEW (pcd->gps_view), pcd->image_layer);
	clutter_actor_hide(pcd->image_layer);

	list = layout_selection_list(pcd->pane.lw);
	work = list;
	while (work)
		{
		FileData *fd = work->data;
		work = work->next;

		if ( fd->exif != 0)
			{		
			exif_build_unformatted_GPSPosition(fd->exif,gpsposition);

			if (gpsposition[0] != 0 && gpsposition[1] != 0)
				{
				file_found = TRUE;

				marker = champlain_marker_new_with_image_full(pcd->marker_icon, 50, 50, 25, 50, NULL);
				champlain_marker_set_position(CHAMPLAIN_MARKER(marker), gpsposition[0], gpsposition[1]);
				clutter_container_add(CLUTTER_CONTAINER(pcd->icon_layer), marker, NULL);

				marker = champlain_marker_new_with_label(fd->name, "Airmole 14", NULL, NULL);
				champlain_marker_set_position(CHAMPLAIN_MARKER(marker), gpsposition[0], gpsposition[1]);
				clutter_container_add(CLUTTER_CONTAINER(pcd->text_layer), marker, NULL);

				marker = champlain_marker_new ();
				thumb = clutter_texture_new ();
				gtk_clutter_texture_set_from_pixbuf (CLUTTER_TEXTURE (thumb),
										 pcd->fd->thumb_pixbuf);
				clutter_actor_set_scale (thumb, 1 / FACTOR, 1 / FACTOR);
				width = clutter_actor_get_width (thumb) / FACTOR;
				height = clutter_actor_get_height (thumb) / FACTOR - PADDING;

				point = width / 3;

				thumb_frame = clutter_cairo_new (width, height + point);
				cairo_t * cr = clutter_cairo_create (CLUTTER_CAIRO (thumb_frame));

				cairo_set_source_rgb (cr, 0, 0, 0);
				cairo_set_line_width (cr, 1);

				cairo_line_to (cr, 0, height);
				cairo_line_to (cr, 0, height + point);
				cairo_line_to (cr, point, height);
				cairo_close_path (cr);

				cairo_set_source_rgba (cr,
							   color.red / 255.0,
							   color.green / 255.0,
							   color.blue / 255.0,
							   color.alpha / 255.0);
				cairo_fill (cr);
				clutter_color_darken (&color, &darker_color);
				cairo_set_source_rgba (cr,
							   darker_color.red / 255.0,
								   darker_color.green / 255.0,
				darker_color.blue / 255.0,
							   darker_color.alpha / 255.0);
				cairo_stroke (cr);
				cairo_destroy (cr);

				clutter_actor_show_all(thumb_frame);
				clutter_container_add (CLUTTER_CONTAINER (marker), thumb_frame, NULL);
				clutter_container_add (CLUTTER_CONTAINER (marker), thumb, NULL);

				clutter_container_add(CLUTTER_CONTAINER(pcd->image_layer), marker, NULL);
				clutter_actor_set_anchor_point (marker, width / 2, height + point);
				clutter_actor_set_anchor_point (marker, 0, height +5 + point);
				champlain_marker_set_position(CHAMPLAIN_MARKER(marker), gpsposition[0], gpsposition[1]);
				}
			}
		}
	champlain_view_center_on(CHAMPLAIN_VIEW(pcd->gps_view),  gpsposition[0], gpsposition[1]);

	if (file_found)
		{
		clutter_actor_show_all(pcd->gps_view);
		
		if (active_layer == 1)
			{
			clutter_actor_show(pcd->icon_layer);
			}
		else if (active_layer == 2)
			{
			clutter_actor_show(pcd->text_layer);
			}
		else if (active_layer == 3)
			{
			clutter_actor_show_all(pcd->image_layer);
			}
		else
			;
		}
	else
		clutter_actor_hide_all(pcd->gps_view);
			
		g_free(comment);
}


static void bar_pane_gps_change_map_cb(GtkWidget *widget, gpointer data)
{
	PaneGPSData *pcd = data;
	gint mapsource;
	
	if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return;

	pcd = submenu_item_get_data(widget);

	if (!pcd) return;

	mapsource = GPOINTER_TO_INT(data);
	g_object_set(G_OBJECT(pcd->gps_view), "map-source", mapsource, NULL);

}

static void bar_pane_gps_change_layer_cb(GtkWidget *button, gpointer data)
{
	PaneGPSData *pcd = data;
	gint mapsource;

	if (CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(pcd->icon_layer)))
		{
		clutter_actor_hide(pcd->icon_layer);
		clutter_actor_show_all(pcd->text_layer);
		}
		else if (CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(pcd->text_layer)))
			{
			clutter_actor_hide(pcd->text_layer);
			clutter_actor_show_all(pcd->image_layer);
			}
		else if (CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(pcd->image_layer)))
			{
			clutter_actor_hide(pcd->image_layer);
			}
		else
			clutter_actor_show_all (pcd->icon_layer);
}


static void bar_pane_gps_set_fd(GtkWidget *bar, FileData *fd)
{
	PaneGPSData *pcd;

	pcd = g_object_get_data(G_OBJECT(bar), "pane_data");
	if (!pcd) return;

	file_data_unref(pcd->fd);
	pcd->fd = file_data_ref(fd);

	bar_pane_gps_update(pcd);
}

static gint bar_pane_gps_event(GtkWidget *bar, GdkEvent *event)
{
	PaneGPSData *pcd;

	pcd = g_object_get_data(G_OBJECT(bar), "pane_data");
	if (!pcd) return FALSE;

	return FALSE;
}

static void bar_pane_gps_write_config(GtkWidget *pane, GString *outstr, gint indent)
{
	PaneGPSData *pcd;
	gint mapsource;
	gint zoom;
	gchar *result;
	gchar *smapsource = "Open Street Map";
	gchar *str = NULL;
	GString *buffer = g_string_new(str);
	gfloat position;

	pcd = g_object_get_data(G_OBJECT(pane), "pane_data");
	if (!pcd) return;

	WRITE_NL(); WRITE_STRING("<pane_gps ");
	write_char_option(outstr, indent, "id", pcd->pane.id);
	write_char_option(outstr, indent, "title", gtk_label_get_text(GTK_LABEL(pcd->pane.title)));
	WRITE_BOOL(pcd->pane, expanded);
	WRITE_INT(*pcd, height);
	indent++;

	g_object_get(G_OBJECT(pcd->gps_view),"map-source",&mapsource,NULL);
	switch (mapsource)
		{
		case CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP:
			smapsource = "Open Street Map - Mapnik";
			break;
		case CHAMPLAIN_MAP_SOURCE_OPENARIALMAP:
			smapsource = "Open Aerial Map";
			break;
		case CHAMPLAIN_MAP_SOURCE_MAPSFORFREE_RELIEF:
			smapsource = "Maps for free - Relief tiles";
			break;
		default:
			smapsource = "Open Street Map - Mapnik";
		}

	WRITE_NL(); write_char_option(outstr, indent, "map-source", smapsource);

	g_object_get(G_OBJECT(pcd->gps_view),"zoom-level",&zoom,NULL);
	g_string_printf(buffer, "%d", zoom);
	WRITE_NL(); write_char_option(outstr, indent, "zoom-level", buffer->str);

	g_object_get(G_OBJECT(pcd->gps_view),"latitude",&position,NULL);
	g_string_printf(buffer, "%lf", position);
	WRITE_NL(); write_char_option(outstr, indent, "latitude", buffer->str);

	g_object_get(G_OBJECT(pcd->gps_view),"longitude",&position,NULL);
	g_string_printf(buffer, "%lf", position);
	WRITE_NL(); write_char_option(outstr, indent, "longitude", buffer->str);
	WRITE_NL(); write_char_option(outstr, indent, "marker-icon", pcd->marker_icon);

	indent--;
	WRITE_NL(); WRITE_STRING("/>");
}

static void bar_pane_gps_notify_cb(FileData *fd, NotifyType type, gpointer data)
{
	PaneGPSData *pcd = data;
	//if (fd == pcd->fd) bar_pane_gps_update(pcd);
	//cc2 if (fd != pcd->fd) bar_pane_gps_update(pcd);
}

//static void bar_pane_gps_changed(ChamplainView *buffer, gpointer data)
//{
	//PaneGPSData *pcd = data;

	//file_data_unregister_notify_func(bar_pane_gps_notify_cb, pcd);
	//bar_pane_gps_write(pcd);
	//file_data_register_notify_func(bar_pane_gps_notify_cb, pcd, NOTIFY_PRIORITY_LOW);
//}


gint bar_pane_gps_get_map_id(PaneGPSData *pcd)
{
	gint mapsource;

	g_object_get(G_OBJECT(pcd->gps_view),"map-source",&mapsource,NULL);
	return mapsource;
}

static GtkWidget *bar_pane_gps_add_radio(GtkWidget *menu, GtkWidget *parent,
					const gchar *label,
					GCallback func, gint value,
					gboolean show_current, gint current_value)
{
	GtkWidget *item;

	if (show_current)
		{
		item = menu_item_add_radio(menu, parent,
					   label, (value == current_value),
					   func, GINT_TO_POINTER((gint)value));
		}
	else
		{
		item = menu_item_add(menu, label,
				     func, GINT_TO_POINTER((gint)value));
		}

	return item;
}


GtkWidget *bar_pane_gps_add_maps(GtkWidget *menu, GCallback func, gpointer data,
			    		   gboolean show_current, gint current_value)
{
	GtkWidget *submenu;
	GtkWidget *parent;

	submenu = gtk_menu_new();
	g_object_set_data(G_OBJECT(submenu), "submenu_data", data);

	parent = bar_pane_gps_add_radio(submenu, NULL, _("_OSM Mapnik"), func, CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP, show_current, current_value);
	bar_pane_gps_add_radio(submenu, parent, _("_Terrain"), func, CHAMPLAIN_MAP_SOURCE_OPENARIALMAP, show_current, current_value);
	bar_pane_gps_add_radio(submenu, parent, _("_Relief"),func, CHAMPLAIN_MAP_SOURCE_MAPSFORFREE_RELIEF, show_current, current_value);

	if (menu)
		{
		GtkWidget *item;

		item = menu_item_add(menu, _("Available Maps"), NULL, NULL);
		gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
		return item;
		}

	return submenu;
}

static GtkWidget *bar_pane_gps_menu(PaneGPSData *phd)
{
	GtkWidget *menu;
	static gboolean show_current = TRUE;

	menu = popup_menu_short_lived();
	bar_pane_gps_add_maps(menu, G_CALLBACK(bar_pane_gps_change_map_cb), phd,
					show_current, bar_pane_gps_get_map_id(phd));

	return menu;
}

static void bar_pane_gps_press(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
{
	PaneGPSData *phd = data;
	GtkWidget *menu;

	if (bevent->button == MOUSE_BUTTON_RIGHT)
		{
		menu = bar_pane_gps_menu(phd);
		gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time);
		}
	else if (bevent->button == MOUSE_BUTTON_MIDDLE)
		{
		bar_pane_gps_change_layer_cb(NULL, phd);
		}
}


static void bar_pane_gps_close(GtkWidget *bar)
{
	PaneGPSData *pcd;

	pcd = g_object_get_data(G_OBJECT(bar), "pane_data");
	if (!pcd) return;

	gtk_widget_destroy(pcd->widget);
}

static void bar_pane_gps_destroy(GtkWidget *widget, gpointer data)
{
	PaneGPSData *pcd = data;

	file_data_unregister_notify_func(bar_pane_gps_notify_cb, pcd);

	file_data_unref(pcd->fd);
	g_free(pcd->map_source);

	g_free(pcd->pane.id);

	g_free(pcd);
}


GtkWidget *bar_pane_gps_new(const gchar *id, const gchar *title, const gchar *map_source, const gint zoom, const gfloat latitude, const gfloat longitude, const gchar *marker_icon, gboolean expanded, gint height)
{
	PaneGPSData *pcd;
	GtkWidget *scrolled;
	GtkTextBuffer *buffer;
	GtkWidget *gpswidget;
	gint test;
	gint mapsource;
	ClutterActor *view, *layer1, *layer2, *layer3;

	pcd = g_new0(PaneGPSData, 1);

	pcd->pane.pane_set_fd = bar_pane_gps_set_fd;
	pcd->pane.pane_event = bar_pane_gps_event;
	pcd->pane.pane_write_config = bar_pane_gps_write_config;
	pcd->pane.title = bar_pane_expander_title(title);
	pcd->pane.id = g_strdup(id);
	pcd->pane.type = PANE_GPS;

	pcd->pane.expanded = expanded;

	pcd->height = height;

	scrolled = gtk_scrolled_window_new(NULL, NULL);

	pcd->widget = scrolled;
	pcd->marker_icon =  g_strdup(g_strconcat(g_path_get_dirname(g_get_prgname()), "/icons/red-dot.png", NULL));

	g_object_set_data(G_OBJECT(pcd->widget), "pane_data", pcd);
	g_signal_connect(G_OBJECT(pcd->widget), "destroy",
			 G_CALLBACK(bar_pane_gps_destroy), pcd);

	if	(g_strcmp0(map_source, "Open Street Map - Mapnik")==0)
		mapsource = CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP;
	else if (g_strcmp0(map_source, "Open Aerial Map")==0)
		mapsource = CHAMPLAIN_MAP_SOURCE_OPENARIALMAP;
	else if (g_strcmp0(map_source, "Maps for free - Relief tiles")==0)
		mapsource = CHAMPLAIN_MAP_SOURCE_MAPSFORFREE_RELIEF;
	else
		mapsource = CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP;

	view = champlain_view_new (CHAMPLAIN_VIEW_MODE_KINETIC);
	clutter_actor_show_all(view);
	g_object_set(G_OBJECT(view), "map-source", mapsource, NULL);
	g_object_set(G_OBJECT(view), "zoom-level", zoom, NULL);

	gpswidget = champlain_view_embed_new(CHAMPLAIN_VIEW (view));

	gtk_container_add (GTK_CONTAINER (scrolled), gpswidget);

	layer1 = bar_pane_gps_create_icon_layer(pcd);
	champlain_view_add_layer(CHAMPLAIN_VIEW (view), layer1);
	pcd->icon_layer = layer1;

	layer2 = bar_pane_gps_create_text_layer(pcd);
	champlain_view_add_layer(CHAMPLAIN_VIEW (view), layer2);
	pcd->text_layer = layer2;

	layer3 = bar_pane_gps_create_image_layer(pcd);
	champlain_view_add_layer(CHAMPLAIN_VIEW (view), layer3);
	pcd->image_layer = layer3;

	pcd->gps_view = view;

	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
					   GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS);

	gtk_widget_set_size_request(pcd->widget, -1, height);

	g_signal_connect(G_OBJECT(scrolled), "button_press_event",
			 G_CALLBACK(bar_pane_gps_press), pcd);

	gtk_widget_show(scrolled); 
	gtk_widget_show_all(gpswidget);


	file_data_register_notify_func(bar_pane_gps_notify_cb, pcd, NOTIFY_PRIORITY_LOW);

	return pcd->widget;
}

GtkWidget *bar_pane_gps_new_from_config(const gchar **attribute_names, const gchar **attribute_values)
{
	gchar *title = g_strdup("GPS Map");
	gchar *map_source = g_strdup("Open Street Map - Mapnik");
	gchar *marker_icon = g_strdup("/home/cclark/bin/geeqie/trunk_working/src/icons/red-dot.png");
	gboolean expanded = TRUE;
	gint height = 350;
	gint zoom = 7;
	gfloat latitude = 54.0;
	gfloat longitude =-4.0;
	gchar *id = g_strdup("gps");
	GtkWidget *ret;

	marker_icon =  g_strdup(g_strconcat(g_path_get_dirname(g_get_prgname()), "/icons/red-dot.png", NULL));

	while (*attribute_names)
		{
		const gchar *option = *attribute_names++;
		const gchar *value = *attribute_values++;

		if (READ_CHAR_FULL("title", title)) continue;
		if (READ_CHAR_FULL("map-source", map_source)) continue;
		if (READ_INT_FULL("zoom-level", zoom)) continue;
		if (READ_CHAR_FULL("marker-icon", marker_icon)) continue;
		if (READ_BOOL_FULL("expanded", expanded)) continue;
		if (READ_INT_FULL("height", height)) continue;
		if (READ_CHAR_FULL("id", id)) continue;

		log_printf("unknown attribute %s = %s\n", option, value);
		}

	bar_pane_translate_title(PANE_COMMENT, id, &title);
	ret = bar_pane_gps_new(id, title, map_source, zoom, latitude, longitude, marker_icon, expanded, height);
	g_free(title);
	g_free(map_source);
	g_free(marker_icon);
	g_free(id);
	return ret;
}

void bar_pane_gps_update_from_config(GtkWidget *pane, const gchar **attribute_names, const gchar **attribute_values)
{
	PaneGPSData *pcd;

	pcd = g_object_get_data(G_OBJECT(pane), "pane_data");
	if (!pcd) return;

	gchar *title = NULL;

	while (*attribute_names)
		{
		const gchar *option = *attribute_names++;
		const gchar *value = *attribute_values++;

		if (READ_CHAR_FULL("title", title)) continue;
		if (READ_CHAR_FULL("map_source", pcd->map_source)) continue;
		if (READ_BOOL_FULL("expanded", pcd->pane.expanded)) continue;
		if (READ_INT_FULL("height", pcd->height)) continue;
		if (READ_CHAR_FULL("id", pcd->pane.id)) continue;

		log_printf("unknown attribute %s = %s\n", option, value);
		}

	if (title)
		{
		bar_pane_translate_title(PANE_COMMENT, pcd->pane.id, &title);
		gtk_label_set_text(GTK_LABEL(pcd->pane.title), title);
		g_free(title);
		}
		
	gtk_widget_set_size_request(pcd->widget, -1, pcd->height);
	bar_update_expander(pane);
	//cc3 bar_pane_gps_update(pcd);
}

#endif
#endif

/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
/*
 * Geeqie
 * (C) 2004 John Ellis
 * Copyright (C) 2008 - 2009 The Geeqie Team
 *
 * Author: Vladimir Nadvornik
 *
 * This software is released under the GNU General Public License (GNU GPL).
 * Please read the included file COPYING for more information.
 * This software comes with no warranty of any kind, use at your own risk!
 */

#ifndef BAR_GPS_H
#define BAR_GPS_H

GtkWidget *bar_pane_gps_new(const gchar *id, const gchar *title, const gchar *map_source, const gint zoom, const gfloat latitude, const gfloat longitude, const gchar *marker_icon, gboolean expanded, gint height);
GtkWidget *bar_pane_gps_new_from_config(const gchar **attribute_names, const gchar **attribute_values);
void bar_pane_gps_update_from_config(GtkWidget *pane, const gchar **attribute_names, const gchar **attribute_values);

#endif


/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
------------------------------------------------------------------------------
Crystal Reports &#45; New Free Runtime and 30 Day Trial
Check out the new simplified licensign option that enables unlimited
royalty&#45;free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Geeqie-devel mailing list
Geeqie-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geeqie-devel

Reply via email to