Hello Vladimir

Please look at bar_comment.c

Replacing the text widget with libchamplain widget should be enough for the beginning.
Vladimir

I have made an attempt to do something with libchamplain. The patch and files are attached. Beware that I don't know the C language, nor the gnu make system, nor gnome/gtk, nor geeqie! In many places things will be wrong, and there are places where to get something to work I have simply made a quick-and-dirty hack. This is just to let you - and anyone else - know where I'm at so far with this.

You will need the libchamplain-0.2.9 and libchamplain-gtk-0.2.9 from http://projects.gnome.org/libchamplain/download. Run autogen.sh with --enable-gps. The .png file goes in trunk/src/icons. And of course you have to enable the gps map from the newly designed sidebar.

Right-click on the map shows the available maps. Middle-click cycles through the layers (unfortunately the thumbnail view only works if thumbnails are currently being shown). Multiple file selection is a total mess.

Unless someone else comes up with another solution, I'll just keep hacking away to try to improve things.

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;

<<inline: red-dot.png>>

/*
 * 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: */
/*
 *  This file is a part of Geeqie project (http://geeqie.sourceforge.net/).
 *  Copyright (C) 2008 - 2009 The Geeqie Team
 *
 *  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.
 */

static gdouble exif_get_rational_as_double(ExifData *exif, const gchar *key);
static gchar *exif_build_formatted_GPSPosition(ExifData *exif);
void exif_build_unformatted_GPSPosition(ExifData *exif, gdouble[]);
------------------------------------------------------------------------------
_______________________________________________
Geeqie-devel mailing list
Geeqie-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geeqie-devel

Reply via email to