/*
* Copyright (C) 2006, 2007 John Costigan.
*
* POI and GPS-Info code originally written by Cezary Jackiewicz.
*
* Default map data provided by http://www.openstreetmap.org/
*
* This file is part of Maemo Mapper.
*
* Maemo Mapper 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 3 of the License, or
* (at your option) any later version.
*
* Maemo Mapper 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 Maemo Mapper. If not, see .
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define _GNU_SOURCE
#include
#include
#ifndef LEGACY
# include
# include
# include
# include
# include
#else
# include
# include
# include
# include
# include
# include
#endif
#include
#include "types.h"
#include "data.h"
#include "defines.h"
#include "display.h"
#include "gdk-pixbuf-rotate.h"
#include "gpx.h"
#include "main.h"
#include "poi.h"
#include "util.h"
static sqlite3 *_poi_db = NULL;
static sqlite3_stmt *_stmt_browse_poi = NULL;
static sqlite3_stmt *_stmt_browsecat_poi = NULL;
static sqlite3_stmt *_stmt_select_poi = NULL;
static sqlite3_stmt *_stmt_select_nearest_poi = NULL;
static sqlite3_stmt *_stmt_insert_poi = NULL;
static sqlite3_stmt *_stmt_update_poi = NULL;
static sqlite3_stmt *_stmt_delete_poi = NULL;
static sqlite3_stmt *_stmt_delete_poi_by_catid = NULL;
static sqlite3_stmt *_stmt_nextlabel_poi = NULL;
static sqlite3_stmt *_stmt_select_cat = NULL;
static sqlite3_stmt *_stmt_insert_cat = NULL;
static sqlite3_stmt *_stmt_update_cat = NULL;
static sqlite3_stmt *_stmt_delete_cat = NULL;
static sqlite3_stmt *_stmt_toggle_cat = NULL;
static sqlite3_stmt *_stmt_selall_cat = NULL;
typedef struct _PoiListInfo PoiListInfo;
struct _PoiListInfo
{
GtkWidget *dialog;
GtkWidget *dialog2;
GtkTreeViewColumn *select_column;
GtkWidget *tree_view;
gboolean select_all;
};
typedef struct _OriginToggleInfo OriginToggleInfo;
struct _OriginToggleInfo {
GtkWidget *rad_use_gps;
GtkWidget *rad_use_route;
GtkWidget *rad_use_text;
GtkWidget *txt_origin;
GtkWidget *txt_query;
};
typedef struct _PoiCategoryEditInfo PoiCategoryEditInfo;
struct _PoiCategoryEditInfo
{
GtkWidget *dialog;
GtkWidget *cmb_category;
gint cat_id;
GtkWidget *tree_view;
};
/** Data used during action: add or edit category/poi **/
typedef struct _DeletePOI DeletePOI;
struct _DeletePOI {
GtkWidget *dialog;
gchar *txt_label;
gint id;
gboolean deleted;
};
void
poi_db_connect()
{
gchar buffer[100];
gchar **pszResult;
gint nRow, nColumn;
gchar *db_dirname = NULL;
printf("%s()\n", __PRETTY_FUNCTION__);
if(_poi_db)
{
sqlite3_close(_poi_db);
_poi_db = NULL;
}
if(!_poi_db_filename)
{
/* Do nothing. */
}
else if(NULL == (db_dirname = g_path_get_dirname(_poi_db_filename))
|| (g_mkdir_with_parents(db_dirname, 0755), /* comma operator */
(SQLITE_OK != (sqlite3_open(_poi_db_filename, &_poi_db)))))
{
gchar buffer2[BUFFER_SIZE];
snprintf(buffer2, sizeof(buffer2),
"%s: %s", _("Error with POI database"),
sqlite3_errmsg(_poi_db));
sqlite3_close(_poi_db);
_poi_db = NULL;
popup_error(_window, buffer2);
}
else if(SQLITE_OK != sqlite3_get_table(_poi_db,
"select label from poi limit 1",
&pszResult, &nRow, &nColumn, NULL))
{
gchar *create_sql = sqlite3_mprintf(
"create table poi (poi_id integer PRIMARY KEY, lat real, "
"lon real, label text, desc text, cat_id integer);"
"create table category (cat_id integer PRIMARY KEY,"
"label text, desc text, enabled integer);"
/* Add some default categories... */
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); "
"insert into category (label, desc, enabled) "
"values ('%q', '%q', 1); ",
_("Service Station"),
_("Stations for purchasing fuel for vehicles."),
_("Residence"),
_("Houses, apartments, or other residences of import."),
_("Restaurant"),
_("Places to eat or drink."),
_("Shopping/Services"),
_("Places to shop or acquire services."),
_("Recreation"),
_("Indoor or Outdoor places to have fun."),
_("Transportation"),
_("Bus stops, airports, train stations, etc."),
_("Lodging"),
_("Places to stay temporarily or for the night."),
_("School"),
_("Elementary schools, college campuses, etc."),
_("Business"),
_("General places of business."),
_("Landmark"),
_("General landmarks."),
_("Other"),
_("Miscellaneous category for everything else."));
if(SQLITE_OK != sqlite3_exec(_poi_db, create_sql, NULL, NULL, NULL)
&& (SQLITE_OK != sqlite3_get_table(_poi_db,
"select label from poi limit 1",
&pszResult, &nRow, &nColumn, NULL)))
{
snprintf(buffer, sizeof(buffer), "%s:\n%s",
_("Failed to open or create database"),
sqlite3_errmsg(_poi_db));
sqlite3_close(_poi_db);
_poi_db = NULL;
popup_error(_window, buffer);
}
}
else
sqlite3_free_table(pszResult);
g_free(db_dirname);
if(_poi_db)
{
/* Prepare our SQL statements. */
/* browse poi */
sqlite3_prepare(_poi_db,
"select p.poi_id, p.cat_id, p.lat, p.lon,"
" p.label, p.desc, c.label"
" from poi p inner join category c"
" on p.cat_id = c.cat_id"
" where c.enabled = 1"
" and p.label like $QUERY or p.desc like $QUERY"
" order by (($LAT - p.lat) * ($LAT - p.lat) "
"+ ($LON - p.lon) * ($LON - p.lon)) DESC "
" limit 100",
-1, &_stmt_browse_poi, NULL);
/* browse poi by category */
sqlite3_prepare(_poi_db,
"select p.poi_id, p.cat_id, p.lat, p.lon,"
" p.label, p.desc, c.label"
" from poi p inner join category c"
" on p.cat_id = c.cat_id"
" where c.enabled = 1"
" and p.cat_id = $CATID"
" and ( p.label like $QUERY or p.desc like $QUERY )"
" order by (($LAT - p.lat) * ($LAT - p.lat) "
"+ ($LON - p.lon) * ($LON - p.lon)) DESC"
" limit 100",
-1, &_stmt_browsecat_poi, NULL);
/* Prepare our SQL statements. */
/* select from poi */
sqlite3_prepare(_poi_db,
"select p.lat, p.lon, p.poi_id, p.label, p.desc,"
" p.cat_id, c.label, c.desc"
" from poi p inner join category c"
" on p.cat_id = c.cat_id"
" where c.enabled = 1"
" and p.lat between ? and ? "
" and p.lon between ? and ? ",
-1, &_stmt_select_poi, NULL);
/* select nearest pois */
sqlite3_prepare(_poi_db,
"select p.poi_id, p.cat_id, p.lat, p.lon,"
" p.label, p.desc, c.label"
" from poi p inner join category c"
" on p.cat_id = c.cat_id"
" where c.enabled = 1"
" order by (($LAT - p.lat) * ($LAT - p.lat) "
"+ ($LON - p.lon) * ($LON - p.lon)) limit 1",
-1, &_stmt_select_nearest_poi, NULL);
/* insert poi */
sqlite3_prepare(_poi_db,
"insert into poi (lat, lon, label, desc, cat_id)"
" values (?, ?, ?, ?, ?)",
-1, &_stmt_insert_poi, NULL);
/* update poi */
sqlite3_prepare(_poi_db,
"update poi set lat = ?, lon = ?, "
"label = ?, desc = ?, cat_id = ? where poi_id = ?",
-1, &_stmt_update_poi, NULL);
/* delete from poi */
sqlite3_prepare(_poi_db,
" delete from poi where poi_id = ?",
-1, &_stmt_delete_poi, NULL);
/* delete from poi by cat_id */
sqlite3_prepare(_poi_db,
"delete from poi where cat_id = ?",
-1, &_stmt_delete_poi_by_catid, NULL);
/* get next poilabel */
sqlite3_prepare(_poi_db,
"select ifnull(max(poi_id) + 1,1) from poi",
-1, &_stmt_nextlabel_poi, NULL);
/* select from category */
sqlite3_prepare(_poi_db,
"select c.label, c.desc, c.enabled"
" from category c where c.cat_id = ?",
-1, &_stmt_select_cat, NULL);
/* insert into category */
sqlite3_prepare(_poi_db,
"insert into category (label, desc, enabled)"
" values (?, ?, ?)",
-1, &_stmt_insert_cat, NULL);
/* update category */
sqlite3_prepare(_poi_db,
"update category set label = ?, desc = ?,"
" enabled = ? where cat_id = ?",
-1, &_stmt_update_cat, NULL);
/* delete from category */
sqlite3_prepare(_poi_db,
"delete from category where cat_id = ?",
-1, &_stmt_delete_cat, NULL);
/* enable category */
sqlite3_prepare(_poi_db,
"update category set enabled = ?"
" where cat_id = ?",
-1, &_stmt_toggle_cat, NULL);
/* select all category */
sqlite3_prepare(_poi_db,
"select c.cat_id, c.label, c.desc, c.enabled,"
" count(p.poi_id)"
" from category c"
" left outer join poi p on c.cat_id = p.cat_id"
" group by c.cat_id, c.label, c.desc, c.enabled "
" order by c.label",
-1, &_stmt_selall_cat, NULL);
}
_poi_enabled = _poi_db != NULL;
gtk_widget_set_sensitive(_menu_poi_item, _poi_enabled);
gtk_widget_set_sensitive(_cmenu_loc_add_poi_item, _poi_enabled);
gtk_widget_set_sensitive(_cmenu_loc_download_poi_item, _poi_enabled);
gtk_widget_set_sensitive(_cmenu_loc_browse_poi_item, _poi_enabled);
gtk_widget_set_sensitive(_cmenu_way_add_poi_item, _poi_enabled);
gtk_widget_set_sensitive(_cmenu_poi_submenu, _poi_enabled);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
gboolean
get_nearest_poi(gint unitx, gint unity, PoiInfo *poi)
{
printf("%s(%d, %d)\n", __PRETTY_FUNCTION__, unitx, unity);
gboolean result;
gdouble lat, lon;
unit2latlon(unitx, unity, lat, lon);
if(SQLITE_OK == sqlite3_bind_double(_stmt_select_nearest_poi, 1, lat)
&& SQLITE_OK == sqlite3_bind_double(_stmt_select_nearest_poi, 2, lon)
&& SQLITE_ROW == sqlite3_step(_stmt_select_nearest_poi))
{
poi->poi_id = sqlite3_column_int(_stmt_select_nearest_poi, 0);
poi->cat_id = sqlite3_column_int(_stmt_select_nearest_poi, 1);
poi->lat = sqlite3_column_double(_stmt_select_nearest_poi, 2);
poi->lon = sqlite3_column_double(_stmt_select_nearest_poi, 3);
poi->label =g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 4));
poi->desc = g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 5));
poi->clabel=g_strdup(sqlite3_column_text(_stmt_select_nearest_poi, 6));
result = TRUE;
}
else
result = FALSE;
sqlite3_reset(_stmt_select_nearest_poi);
vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, result);
return result;
}
gboolean
select_poi(gint unitx, gint unity, PoiInfo *poi, gboolean quick)
{
gint x, y;
gdouble lat1, lon1, lat2, lon2;
static GtkWidget *dialog = NULL;
static GtkWidget *list = NULL;
static GtkWidget *sw = NULL;
static GtkTreeViewColumn *column = NULL;
static GtkCellRenderer *renderer = NULL;
GtkListStore *store = NULL;
GtkTreeIter iter;
gboolean selected = FALSE;
gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
gint num_cats = 0;
printf("%s()\n", __PRETTY_FUNCTION__);
x = unitx - pixel2unit(3 * _draw_width);
y = unity + pixel2unit(3 * _draw_width);
unit2latlon(x, y, lat1, lon1);
x = unitx + pixel2unit(3 * _draw_width);
y = unity - pixel2unit(3 * _draw_width);
unit2latlon(x, y, lat2, lon2);
if(SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 1, lat1) ||
SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 2, lat2) ||
SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 3, lon1) ||
SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 4, lon2))
{
g_printerr("Failed to bind values for _stmt_select_poi\n");
return FALSE;
}
/* Initialize store. */
store = gtk_list_store_new(POI_NUM_COLUMNS,
G_TYPE_BOOLEAN,/* Selected */
G_TYPE_INT, /* POI ID */
G_TYPE_INT, /* Category ID */
G_TYPE_DOUBLE, /* Latitude */
G_TYPE_DOUBLE, /* Longitude */
G_TYPE_STRING, /* Lat/Lon */
G_TYPE_FLOAT, /* Bearing */
G_TYPE_FLOAT, /* Distance */
G_TYPE_STRING, /* POI Label */
G_TYPE_STRING, /* POI Desc. */
G_TYPE_STRING);/* Category Label */
while(SQLITE_ROW == sqlite3_step(_stmt_select_poi))
{
gdouble lat, lon;
lat = sqlite3_column_double(_stmt_select_poi, 0);
lon = sqlite3_column_double(_stmt_select_poi, 1);
format_lat_lon(lat, lon, tmp1, tmp2);
//lat_format(lat, tmp1);
//lon_format(lon, tmp2);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
POI_POIID, sqlite3_column_int(_stmt_select_poi, 2),
POI_CATID, sqlite3_column_int(_stmt_select_poi, 5),
POI_LAT, lat,
POI_LON, lon,
POI_LATLON, g_strdup_printf("%s, %s", tmp1, tmp2),
POI_LABEL, sqlite3_column_text(_stmt_select_poi, 3),
POI_DESC, sqlite3_column_text(_stmt_select_poi, 4),
POI_CLABEL, sqlite3_column_text(_stmt_select_poi, 6),
-1);
num_cats++;
}
sqlite3_reset(_stmt_select_poi);
switch(num_cats)
{
case 0:
g_object_unref(G_OBJECT(store));
if(!quick)
{
MACRO_BANNER_SHOW_INFO(_window, _("No POIs found."));
}
return FALSE;
break;
case 1:
/* iter is still set to the most-recently added POI. */
gtk_tree_model_get(GTK_TREE_MODEL(store),
&iter,
POI_POIID, &(poi->poi_id),
POI_CATID, &(poi->cat_id),
POI_LAT, &(poi->lat),
POI_LON, &(poi->lon),
POI_LABEL, &(poi->label),
POI_DESC, &(poi->desc),
POI_CLABEL, &(poi->clabel),
-1);
g_object_unref(G_OBJECT(store));
return TRUE;
break;
default:
if(quick)
{
g_object_unref(G_OBJECT(store));
return get_nearest_poi(unitx, unity, poi);
}
}
/* There are at least 2 matching POI's - let the user select one. */
if(dialog == NULL)
{
dialog = gtk_dialog_new_with_buttons(_("Select POI"),
GTK_WINDOW(_window), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 300);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
sw, TRUE, TRUE, 0);
list = gtk_tree_view_new();
gtk_container_add(GTK_CONTAINER(sw), list);
gtk_tree_selection_set_mode(
gtk_tree_view_get_selection(GTK_TREE_VIEW(list)),
GTK_SELECTION_SINGLE);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), TRUE);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("Location"), renderer, "text", POI_LATLON, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("Label"), renderer, "text", POI_LABEL, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("Category"), renderer, "text", POI_CLABEL, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
}
gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
gtk_widget_show_all(dialog);
while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
if(gtk_tree_selection_get_selected(
gtk_tree_view_get_selection(GTK_TREE_VIEW(list)),
NULL, &iter))
{
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
POI_POIID, &(poi->poi_id),
POI_CATID, &(poi->cat_id),
POI_LAT, &(poi->lat),
POI_LON, &(poi->lon),
POI_LABEL, &(poi->label),
POI_DESC, &(poi->desc),
POI_CLABEL, &(poi->clabel),
-1);
selected = TRUE;
break;
}
else
popup_error(dialog, _("Select one POI from the list."));
}
map_force_redraw();
gtk_widget_hide(dialog);
vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, selected);
return selected;
}
static gboolean
category_delete(GtkWidget *widget, DeletePOI *dpoi)
{
GtkWidget *confirm;
gint i;
gchar *buffer;
printf("%s()\n", __PRETTY_FUNCTION__);
buffer = g_strdup_printf("%s\n\t%s\n%s",
_("Delete category?"),
dpoi->txt_label,
_("WARNING: All POIs in that category will also be deleted!"));
confirm = hildon_note_new_confirmation(GTK_WINDOW(dpoi->dialog), buffer);
g_free(buffer);
i = gtk_dialog_run(GTK_DIALOG(confirm));
gtk_widget_destroy(GTK_WIDGET(confirm));
if(i == GTK_RESPONSE_OK)
{
/* delete dpoi->poi_id */
if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi_by_catid, 1,
dpoi->id) ||
SQLITE_DONE != sqlite3_step(_stmt_delete_poi_by_catid))
{
MACRO_BANNER_SHOW_INFO(dpoi->dialog, _("Error deleting POI"));
sqlite3_reset(_stmt_delete_poi_by_catid);
return FALSE;
}
sqlite3_reset(_stmt_delete_poi_by_catid);
if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_cat, 1, dpoi->id) ||
SQLITE_DONE != sqlite3_step(_stmt_delete_cat))
{
MACRO_BANNER_SHOW_INFO(dpoi->dialog, _("Error deleting category"));
sqlite3_reset(_stmt_delete_cat);
return FALSE;
}
sqlite3_reset(_stmt_delete_cat);
map_force_redraw();
}
gtk_widget_destroy(confirm);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
gboolean
category_edit_dialog(GtkWidget *parent, gint cat_id)
{
gchar *cat_label = NULL, *cat_desc = NULL;
gint cat_enabled;
GtkWidget *dialog;
GtkWidget *table;
GtkWidget *label;
GtkWidget *txt_label;
GtkWidget *txt_desc;
GtkWidget *btn_delete = NULL;
GtkWidget *txt_scroll;
GtkWidget *chk_enabled;
GtkTextBuffer *desc_txt;
GtkTextIter begin, end;
gboolean results = TRUE;
DeletePOI dpoi = {NULL, NULL, 0};
printf("%s()\n", __PRETTY_FUNCTION__);
if(cat_id > 0)
{
if(SQLITE_OK != sqlite3_bind_double(_stmt_select_cat, 1, cat_id) ||
SQLITE_ROW != sqlite3_step(_stmt_select_cat))
{
vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
sqlite3_reset(_stmt_select_cat);
return FALSE;
}
cat_label = g_strdup(sqlite3_column_text(_stmt_select_cat, 0));
cat_desc = g_strdup(sqlite3_column_text(_stmt_select_cat, 1));
cat_enabled = sqlite3_column_int(_stmt_select_cat, 2);
sqlite3_reset(_stmt_select_cat);
dialog = gtk_dialog_new_with_buttons(_("Edit Category"),
GTK_WINDOW(parent), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
btn_delete = gtk_button_new_with_label(_("Delete...")));
dpoi.dialog = dialog;
dpoi.txt_label = g_strdup(cat_label);
dpoi.id = cat_id;
dpoi.deleted = FALSE;
g_signal_connect(G_OBJECT(btn_delete), "clicked",
G_CALLBACK(category_delete), &dpoi);
gtk_dialog_add_button(GTK_DIALOG(dialog),
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
}
else
{
cat_enabled = 1;
cat_label = g_strdup("");
cat_id = -1;
cat_desc = g_strdup("");
dialog = gtk_dialog_new_with_buttons(_("Add Category"),
GTK_WINDOW(parent), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
}
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Label")),
0, 1, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
txt_label = gtk_entry_new(),
1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Description")),
0, 1, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
txt_scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
GTK_SHADOW_IN);
gtk_table_attach(GTK_TABLE(table),
txt_scroll,
1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
txt_desc = gtk_text_view_new();
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 400, 60);
desc_txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txt_desc));
gtk_table_attach(GTK_TABLE(table),
chk_enabled = gtk_check_button_new_with_label(
_("Enabled")),
0, 2, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
/* label */
gtk_entry_set_text(GTK_ENTRY(txt_label), cat_label);
/* desc */
gtk_text_buffer_set_text(desc_txt, cat_desc, -1);
/* enabled */
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chk_enabled),
(cat_enabled == 1 ? TRUE : FALSE));
g_free(cat_label);
cat_label = NULL;
g_free(cat_desc);
cat_desc = NULL;
gtk_widget_show_all(dialog);
while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
cat_label = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label)));
else
{
popup_error(dialog, _("Please specify a name for the category."));
continue;
}
gtk_text_buffer_get_iter_at_offset(desc_txt, &begin,0 );
gtk_text_buffer_get_end_iter (desc_txt, &end);
cat_desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
cat_enabled = (gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(chk_enabled)) ? 1 : 0);
if(cat_id > 0)
{
/* edit category */
if(SQLITE_OK != sqlite3_bind_text(_stmt_update_cat, 1, cat_label,
-1, g_free) ||
SQLITE_OK != sqlite3_bind_text(_stmt_update_cat, 2, cat_desc,
-1, g_free) ||
SQLITE_OK != sqlite3_bind_int(_stmt_update_cat, 3,cat_enabled)||
SQLITE_OK != sqlite3_bind_int(_stmt_update_cat, 4, cat_id) ||
SQLITE_DONE != sqlite3_step(_stmt_update_cat))
{
MACRO_BANNER_SHOW_INFO(parent,_("Error updating category"));
results = FALSE;
}
sqlite3_reset(_stmt_update_cat);
}
else
{
/* add category */
if(SQLITE_OK != sqlite3_bind_text(_stmt_insert_cat, 1, cat_label,
-1, g_free) ||
SQLITE_OK != sqlite3_bind_text(_stmt_insert_cat, 2, cat_desc,
-1, g_free) ||
SQLITE_OK != sqlite3_bind_int(_stmt_insert_cat, 3,cat_enabled)||
SQLITE_DONE != sqlite3_step(_stmt_insert_cat))
{
MACRO_BANNER_SHOW_INFO(parent, _("Error adding category"));
results = FALSE;
}
sqlite3_reset(_stmt_insert_cat);
}
break;
}
g_free(dpoi.txt_label);
g_object_unref (desc_txt);
if(results)
map_force_redraw();
gtk_widget_hide(dialog);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
return results;
}
static void
category_toggled(GtkCellRendererToggle *cell, gchar *path, GtkListStore *data)
{
GtkTreeIter iter;
gboolean cat_enabled;
gint cat_id;
printf("%s()\n", __PRETTY_FUNCTION__);
GtkTreeModel *model = GTK_TREE_MODEL(data);
if( !gtk_tree_model_get_iter_from_string(model, &iter, path) )
return;
gtk_tree_model_get(model, &iter,
CAT_ENABLED, &cat_enabled,
CAT_ID, &cat_id,
-1);
cat_enabled ^= 1;
if(SQLITE_OK != sqlite3_bind_int(_stmt_toggle_cat, 1, cat_enabled) ||
SQLITE_OK != sqlite3_bind_int(_stmt_toggle_cat, 2, cat_id) ||
SQLITE_DONE != sqlite3_step(_stmt_toggle_cat))
{
MACRO_BANNER_SHOW_INFO(_window, _("Error updating Category"));
}
else
{
gtk_list_store_set(GTK_LIST_STORE(model), &iter,
CAT_ENABLED, cat_enabled, -1);
map_force_redraw();
}
sqlite3_reset(_stmt_toggle_cat);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
}
static GtkListStore*
generate_store()
{
GtkTreeIter iter;
GtkListStore *store;
printf("%s()\n", __PRETTY_FUNCTION__);
store = gtk_list_store_new(CAT_NUM_COLUMNS,
G_TYPE_UINT,
G_TYPE_BOOLEAN,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_UINT);
while(SQLITE_ROW == sqlite3_step(_stmt_selall_cat))
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
CAT_ID, sqlite3_column_int(_stmt_selall_cat, 0),
CAT_ENABLED, sqlite3_column_int(_stmt_selall_cat, 3),
CAT_LABEL, sqlite3_column_text(_stmt_selall_cat, 1),
CAT_DESC, sqlite3_column_text(_stmt_selall_cat, 2),
CAT_POI_CNT, sqlite3_column_int(_stmt_selall_cat, 4),
-1);
}
sqlite3_reset(_stmt_selall_cat);
vprintf("%s(): return %p\n", __PRETTY_FUNCTION__, store);
return store;
}
static gboolean
category_add(GtkWidget *widget, PoiCategoryEditInfo *pcedit)
{
GtkListStore *store;
printf("%s()\n", __PRETTY_FUNCTION__);
if(category_edit_dialog(pcedit->dialog, 0))
{
store = generate_store();
gtk_tree_view_set_model(
GTK_TREE_VIEW(pcedit->tree_view),
GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
category_edit(GtkWidget *widget, PoiCategoryEditInfo *pcedit)
{
GtkTreeIter iter;
GtkTreeModel *store;
GtkTreeSelection *selection;
printf("%s()\n", __PRETTY_FUNCTION__);
store = gtk_tree_view_get_model(GTK_TREE_VIEW(pcedit->tree_view));
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pcedit->tree_view));
if(gtk_tree_selection_get_selected(selection, &store, &iter))
{
GValue val;
memset(&val, 0, sizeof(val));
gtk_tree_model_get_value(store, &iter, 0, &val);
if(category_edit_dialog(pcedit->dialog, g_value_get_uint(&val)))
{
GtkListStore *new_store = generate_store();
gtk_tree_view_set_model(
GTK_TREE_VIEW(pcedit->tree_view),
GTK_TREE_MODEL(new_store));
g_object_unref(G_OBJECT(new_store));
}
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
gboolean
category_list_dialog(GtkWidget *parent)
{
static GtkWidget *dialog = NULL;
static GtkWidget *tree_view = NULL;
static GtkWidget *sw = NULL;
static GtkWidget *btn_edit = NULL;
static GtkWidget *btn_add = NULL;
static GtkTreeViewColumn *column = NULL;
static GtkCellRenderer *renderer = NULL;
static GtkListStore *store;
static PoiCategoryEditInfo pcedit;
printf("%s()\n", __PRETTY_FUNCTION__);
store = generate_store();
if(!store)
return TRUE;
dialog = gtk_dialog_new_with_buttons(_("POI Categories"),
GTK_WINDOW(parent), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
/* Enable the help button. */
#ifndef LEGACY
hildon_help_dialog_help_enable(
#else
ossohelp_dialog_help_enable(
#endif
GTK_DIALOG(dialog), HELP_ID_POICAT, _osso);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
btn_edit = gtk_button_new_with_label(_("Edit...")));
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
btn_add = gtk_button_new_with_label(_("Add...")));
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
sw, TRUE, TRUE, 0);
tree_view = gtk_tree_view_new();
/* Maemo-related? */
g_object_set(tree_view, "allow-checkbox-mode", FALSE, NULL);
gtk_container_add (GTK_CONTAINER (sw), tree_view);
gtk_tree_selection_set_mode(
gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)),
GTK_SELECTION_SINGLE);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), TRUE);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("ID"), renderer, "text", CAT_ID, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
gtk_tree_view_column_set_max_width (column, 1);
renderer = gtk_cell_renderer_toggle_new();
g_signal_connect (renderer, "toggled",
G_CALLBACK (category_toggled), store);
column = gtk_tree_view_column_new_with_attributes(
_("Enabled"), renderer, "active", CAT_ENABLED, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("Label"), renderer, "text", CAT_LABEL, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("Description"), renderer, "text", CAT_DESC, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("# POIs"), renderer, "text", CAT_POI_CNT, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
gtk_window_set_default_size(GTK_WINDOW(dialog), -1, 400);
pcedit.dialog = dialog;
pcedit.tree_view = tree_view;
g_signal_connect(G_OBJECT(btn_edit), "clicked",
G_CALLBACK(category_edit), &pcedit);
g_signal_connect(G_OBJECT(btn_add), "clicked",
G_CALLBACK(category_add), &pcedit);
gtk_tree_view_set_model(GTK_TREE_VIEW(tree_view), GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
gtk_widget_show_all(dialog);
while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
break;
}
gtk_widget_destroy(dialog);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_delete(GtkWidget *widget, DeletePOI *dpoi)
{
GtkWidget *confirm;
gint i;
gchar *buffer;
printf("%s()\n", __PRETTY_FUNCTION__);
buffer = g_strdup_printf("%s\n%s", _("Delete POI?"), dpoi->txt_label);
confirm = hildon_note_new_confirmation(GTK_WINDOW(dpoi->dialog), buffer);
g_free(buffer);
i = gtk_dialog_run(GTK_DIALOG(confirm));
gtk_widget_destroy(GTK_WIDGET(confirm));
if(i == GTK_RESPONSE_OK)
{
if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi, 1, dpoi->id) ||
SQLITE_DONE != sqlite3_step(_stmt_delete_poi))
{
MACRO_BANNER_SHOW_INFO(dpoi->dialog, _("Error deleting POI"));
}
else
{
dpoi->deleted = TRUE;
gtk_widget_hide(dpoi->dialog);
map_force_redraw();
}
sqlite3_reset(_stmt_delete_poi);
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_populate_categories(GtkListStore *store, gint cat_id,
GtkTreeIter *out_active)
{
gboolean has_active = FALSE;
printf("%s()\n", __PRETTY_FUNCTION__);
gtk_list_store_clear(store);
while(SQLITE_ROW == sqlite3_step(_stmt_selall_cat))
{
GtkTreeIter iter;
gint cid = sqlite3_column_int(_stmt_selall_cat, 0);
const gchar *clab = sqlite3_column_text(_stmt_selall_cat, 1);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter, 0, cid, 1, clab, -1);
if(cid == cat_id || !has_active)
{
if(out_active)
*out_active = iter;
has_active = TRUE;
}
}
sqlite3_reset(_stmt_selall_cat);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
return has_active;
}
static gboolean
poi_edit_cat(GtkWidget *widget, PoiCategoryEditInfo *data)
{
printf("%s()\n", __PRETTY_FUNCTION__);
if(category_list_dialog(data->dialog))
{
GtkTreeIter active;
if(poi_populate_categories(GTK_LIST_STORE(gtk_combo_box_get_model(
GTK_COMBO_BOX(data->cmb_category))),
data->cat_id, &active))
{
gtk_combo_box_set_active_iter(
GTK_COMBO_BOX(data->cmb_category), &active);
}
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
return TRUE;
}
static GtkWidget*
poi_create_cat_combo()
{
GtkWidget *cmb_category;
GtkTreeModel *model;
printf("%s()\n", __PRETTY_FUNCTION__);
model = GTK_TREE_MODEL(gtk_list_store_new(2,
G_TYPE_INT, /* Category ID */
G_TYPE_STRING)); /* Category Label */
cmb_category = gtk_combo_box_new_with_model(model);
g_object_unref(model);
/* Set up the view for the combo box. */
{
GtkCellRenderer *renderer;
GtkTreeIter active;
renderer = gtk_cell_renderer_text_new();
gtk_cell_layout_pack_start(
GTK_CELL_LAYOUT(cmb_category), renderer, TRUE);
gtk_cell_layout_set_attributes(
GTK_CELL_LAYOUT(cmb_category), renderer, "text", 1, NULL);
poi_populate_categories(GTK_LIST_STORE(gtk_combo_box_get_model(
GTK_COMBO_BOX(cmb_category))), -1, &active);
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
return cmb_category;
}
gboolean
poi_add_dialog(GtkWidget *parent, gint unitx, gint unity)
{
static PoiInfo poi;
static GtkWidget *dialog;
static GtkWidget *table;
static GtkWidget *label;
static GtkWidget *txt_label;
static GtkWidget *txt_lat;
static GtkWidget *txt_lon;
static GtkWidget *cmb_category;
static GtkWidget *txt_desc;
static GtkWidget *btn_catedit;
static GtkWidget *hbox;
static GtkWidget *txt_scroll;
static GtkTextBuffer *desc_txt;
static GtkTextIter begin, end;
static DeletePOI dpoi = {NULL, NULL, 0};
static PoiCategoryEditInfo pcedit;
static int last_deg_format = 0;
printf("%s()\n", __PRETTY_FUNCTION__);
unit2latlon(unitx, unity, poi.lat, poi.lon);
gint fallback_deg_format = _degformat;
if(!coord_system_check_lat_lon (poi.lat, poi.lon, &fallback_deg_format))
{
last_deg_format = _degformat;
_degformat = fallback_deg_format;
if(dialog != NULL) gtk_widget_destroy(dialog);
dialog = NULL;
}
else if(_degformat != last_deg_format)
{
last_deg_format = _degformat;
if(dialog != NULL) gtk_widget_destroy(dialog);
dialog = NULL;
}
if(dialog == NULL)
{
dialog = gtk_dialog_new_with_buttons(_("Add POI"),
GTK_WINDOW(parent), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
/* Set the lat/lon strings. */
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(DEG_FORMAT_ENUM_TEXT[_degformat].short_field_1),
0, 1, 0, 1, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
txt_lat = gtk_entry_new(),
1, (DEG_FORMAT_ENUM_TEXT[_degformat].field_2_in_use ? 2 : 4),
0, 1, GTK_FILL, 0, 2, 0);
if(DEG_FORMAT_ENUM_TEXT[_degformat].field_2_in_use )
{
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(DEG_FORMAT_ENUM_TEXT[_degformat].short_field_2),
2, 3, 0, 1, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
txt_lon = gtk_entry_new(),
3, 4, 0, 1, GTK_FILL, 0, 2, 0);
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Label")),
0, 1, 1, 2, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
txt_label = gtk_entry_new(),
1, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 0);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Category")),
0, 1, 3, 4, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
hbox = gtk_hbox_new(FALSE, 4),
1, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 0);
gtk_box_pack_start(GTK_BOX(hbox),
cmb_category = poi_create_cat_combo(),
FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox),
btn_catedit = gtk_button_new_with_label(
_("Edit Categories...")),
FALSE, FALSE, 0);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Description")),
0, 1, 5, 6, GTK_FILL, GTK_FILL, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.0f);
txt_scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
GTK_SHADOW_IN);
gtk_table_attach(GTK_TABLE(table),
txt_scroll,
1, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
txt_desc = gtk_text_view_new ();
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 550, 120);
desc_txt = gtk_text_view_get_buffer(GTK_TEXT_VIEW (txt_desc));
g_signal_connect(G_OBJECT(btn_catedit), "clicked",
G_CALLBACK(poi_edit_cat), &pcedit);
}
poi.poi_id = -1;
poi.cat_id = -1;
poi.clabel = NULL;
poi.desc = g_strdup("");
/* Lat/Lon */
{
gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
format_lat_lon(poi.lat, poi.lon, tmp1, tmp2);
//lat_format(poi.lat, tmp1);
//lon_format(poi.lon, tmp2);
gtk_entry_set_text(GTK_ENTRY(txt_lat), tmp1);
if(txt_lon != NULL)
gtk_entry_set_text(GTK_ENTRY(txt_lon), tmp2);
}
/* Label */
if(SQLITE_ROW == sqlite3_step(_stmt_nextlabel_poi))
poi.label = g_strdup_printf("Point%06d",
sqlite3_column_int(_stmt_nextlabel_poi, 0));
else
poi.label = g_strdup("");
sqlite3_reset(_stmt_nextlabel_poi);
gtk_entry_set_text(GTK_ENTRY(txt_label), poi.label);
/* POI Desc. */
gtk_text_buffer_set_text(desc_txt, "", -1);
/* Category. */
{
GtkTreeIter iter;
gint cat_id = -1;
gboolean had_cat_id = FALSE;
if(gtk_combo_box_get_active_iter(
GTK_COMBO_BOX(cmb_category), &iter))
{
gtk_tree_model_get(
gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),&iter,
0, &cat_id,
-1);
had_cat_id = TRUE;
}
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(
GTK_COMBO_BOX(cmb_category))));
if(poi_populate_categories(GTK_LIST_STORE(gtk_combo_box_get_model(
GTK_COMBO_BOX(cmb_category))), cat_id, &iter)
&& had_cat_id)
{
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cmb_category), &iter);
}
}
pcedit.dialog = dialog;
pcedit.cmb_category = cmb_category;
pcedit.cat_id = poi.cat_id;
gtk_widget_show_all(dialog);
while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
GtkTreeIter iter;
const gchar *lat, *lon = NULL;
lat = gtk_entry_get_text(GTK_ENTRY(txt_lat));
if(txt_lon != NULL)
lon = gtk_entry_get_text(GTK_ENTRY(txt_lon));
if(!parse_coords(lat, lon, &poi.lat, &poi.lon))
{
popup_error(dialog, _("Invalid Coordinate specified"));
continue;
}
if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
{
if(poi.label)
g_free(poi.label);
poi.label = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label)));
}
else
{
popup_error(dialog, _("Please specify a name."));
continue;
}
if(!gtk_combo_box_get_active_iter(
GTK_COMBO_BOX(cmb_category), &iter))
{
popup_error(dialog, _("Please specify a category."));
continue;
}
gtk_text_buffer_get_iter_at_offset(desc_txt, &begin,0 );
gtk_text_buffer_get_end_iter (desc_txt, &end);
if(poi.desc)
g_free(poi.desc);
poi.desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
if(poi.clabel)
g_free(poi.clabel);
gtk_tree_model_get(
gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter,
0, &poi.cat_id,
1, &poi.clabel,
-1);
/* add poi */
if(SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 1, poi.lat)
|| SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 2, poi.lon)
|| SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 3, poi.label,
-1, SQLITE_STATIC)
|| SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 4, poi.desc,
-1, SQLITE_STATIC)
|| SQLITE_OK != sqlite3_bind_int(_stmt_insert_poi, 5, poi.cat_id)
|| SQLITE_DONE != sqlite3_step(_stmt_insert_poi))
{
MACRO_BANNER_SHOW_INFO(parent, _("Error adding POI"));
}
sqlite3_reset(_stmt_insert_poi);
/* We're done. */
break;
}
g_free(poi.label);
g_free(poi.desc);
g_free(dpoi.txt_label);
map_force_redraw();
gtk_widget_hide(dialog);
_degformat = last_deg_format;
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return !dpoi.deleted;
}
gboolean
poi_view_dialog(GtkWidget *parent, PoiInfo *poi)
{
GtkTreeIter iter;
static GtkWidget *dialog;
static GtkWidget *table;
static GtkWidget *label;
static GtkWidget *txt_label;
static GtkWidget *txt_lat;
static GtkWidget *txt_lon;
static GtkWidget *cmb_category;
static GtkWidget *txt_desc;
static GtkWidget *btn_delete = NULL;
static GtkWidget *btn_catedit;
static GtkWidget *hbox;
static GtkWidget *txt_scroll;
static GtkTextBuffer *desc_txt;
static GtkTextIter begin, end;
static DeletePOI dpoi = {NULL, NULL, 0};
static PoiCategoryEditInfo pcedit;
static int last_deg_format = 0;
printf("%s()\n", __PRETTY_FUNCTION__);
gint fallback_deg_format = _degformat;
if(!coord_system_check_lat_lon (poi->lat, poi->lon, &fallback_deg_format))
{
last_deg_format = _degformat;
_degformat = fallback_deg_format;
if(dialog != NULL) gtk_widget_destroy(dialog);
dialog = NULL;
}
else if(_degformat != last_deg_format)
{
last_deg_format = _degformat;
if(dialog != NULL) gtk_widget_destroy(dialog);
dialog = NULL;
}
if(dialog == NULL)
{
dialog = gtk_dialog_new_with_buttons(_("Edit POI"),
GTK_WINDOW(parent), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
NULL);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
btn_delete = gtk_button_new_with_label(_("Delete...")));
gtk_dialog_add_button(GTK_DIALOG(dialog),
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
/* Set the lat/lon strings. */
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
table = gtk_table_new(6, 4, FALSE), TRUE, TRUE, 0);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(DEG_FORMAT_ENUM_TEXT[_degformat].short_field_1),
0, 1, 0, 1, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
txt_lat = gtk_entry_new(),
1, 2, 0, 1, GTK_FILL, 0, 2, 0);
if(DEG_FORMAT_ENUM_TEXT[_degformat].field_2_in_use)
{
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(DEG_FORMAT_ENUM_TEXT[_degformat].short_field_2),
2, 3, 0, 1, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
txt_lon = gtk_entry_new(),
3, 4, 0, 1, GTK_FILL, 0, 2, 0);
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Label")),
0, 1, 1, 2, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
txt_label = gtk_entry_new(),
1, 4, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 0);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Category")),
0, 1, 3, 4, GTK_FILL, 0, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
hbox = gtk_hbox_new(FALSE, 4),
1, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 0);
gtk_box_pack_start(GTK_BOX(hbox),
cmb_category = poi_create_cat_combo(),
FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox),
btn_catedit = gtk_button_new_with_label(
_("Edit Categories...")),
FALSE, FALSE, 0);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Description")),
0, 1, 5, 6, GTK_FILL, GTK_FILL, 2, 0);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.0f);
txt_scroll = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(txt_scroll),
GTK_SHADOW_IN);
gtk_table_attach(GTK_TABLE(table),
txt_scroll,
1, 4, 5, 6, GTK_EXPAND | GTK_FILL, 0, 2, 0);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(txt_scroll),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
txt_desc = gtk_text_view_new ();
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(txt_desc), GTK_WRAP_WORD);
gtk_container_add(GTK_CONTAINER(txt_scroll), txt_desc);
gtk_widget_set_size_request(GTK_WIDGET(txt_scroll), 550, 120);
desc_txt = gtk_text_view_get_buffer (GTK_TEXT_VIEW (txt_desc));
g_signal_connect(G_OBJECT(btn_delete), "clicked",
G_CALLBACK(poi_delete), &dpoi);
g_signal_connect(G_OBJECT(btn_catedit), "clicked",
G_CALLBACK(poi_edit_cat), &pcedit);
}
dpoi.dialog = dialog;
dpoi.txt_label = g_strdup(poi->label);
dpoi.id = poi->poi_id;
dpoi.deleted = FALSE;
/* Lat/Lon */
{
gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
format_lat_lon(poi->lat, poi->lon, tmp1, tmp2);
//lat_format(poi->lat, tmp1);
//lon_format(poi->lon, tmp2);
gtk_entry_set_text(GTK_ENTRY(txt_lat), tmp1);
if(DEG_FORMAT_ENUM_TEXT[_degformat].field_2_in_use)
gtk_entry_set_text(GTK_ENTRY(txt_lon), tmp2);
else
gtk_entry_set_text(GTK_ENTRY(txt_lon), g_strdup(""));
}
/* label */
gtk_entry_set_text(GTK_ENTRY(txt_label), poi->label);
/* poi_desc */
gtk_text_buffer_set_text(desc_txt, poi->desc, -1);
/* Category. */
gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(
GTK_COMBO_BOX(cmb_category))));
if(poi_populate_categories(GTK_LIST_STORE(gtk_combo_box_get_model(
GTK_COMBO_BOX(cmb_category))), poi->cat_id, &iter))
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cmb_category), &iter);
/* Connect Signals */
pcedit.dialog = dialog;
pcedit.cmb_category = cmb_category;
pcedit.cat_id = poi->cat_id;
gtk_widget_show_all(dialog);
while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
const gchar *text_lat, *text_lon;
text_lat = gtk_entry_get_text(GTK_ENTRY(txt_lat));
text_lon = gtk_entry_get_text(GTK_ENTRY(txt_lon));
if(!parse_coords(text_lat, text_lon, &poi->lat, &poi->lon))
{
popup_error(dialog, _("Invalid coordinate specified"));
continue;
}
if(strlen(gtk_entry_get_text(GTK_ENTRY(txt_label))))
{
if(poi->label)
g_free(poi->label);
poi->label = g_strdup(gtk_entry_get_text(GTK_ENTRY(txt_label)));
}
else
{
popup_error(dialog, _("Please specify a name."));
continue;
}
if(!gtk_combo_box_get_active_iter(
GTK_COMBO_BOX(cmb_category), &iter))
{
popup_error(dialog, _("Please specify a category."));
continue;
}
gtk_text_buffer_get_iter_at_offset(desc_txt, &begin,0 );
gtk_text_buffer_get_end_iter (desc_txt, &end);
if(poi->desc)
g_free(poi->desc);
poi->desc = gtk_text_buffer_get_text(desc_txt, &begin, &end, TRUE);
if(poi->clabel)
g_free(poi->clabel);
gtk_tree_model_get(
gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter,
0, &poi->cat_id,
1, &poi->clabel,
-1);
/* edit poi */
if(SQLITE_OK != sqlite3_bind_double(
_stmt_update_poi, 1, poi->lat) ||
SQLITE_OK != sqlite3_bind_double(
_stmt_update_poi, 2, poi->lon) ||
SQLITE_OK != sqlite3_bind_text(_stmt_update_poi, 3, poi->label,
-1, SQLITE_STATIC) ||
SQLITE_OK != sqlite3_bind_text(_stmt_update_poi, 4, poi->desc,
-1, SQLITE_STATIC) ||
SQLITE_OK != sqlite3_bind_int(
_stmt_update_poi, 5, poi->cat_id) ||
SQLITE_OK != sqlite3_bind_int(
_stmt_update_poi, 6, poi->poi_id) ||
SQLITE_DONE != sqlite3_step(_stmt_update_poi))
{
MACRO_BANNER_SHOW_INFO(parent, _("Error updating POI"));
}
sqlite3_reset(_stmt_update_poi);
/* We're done. */
break;
}
g_free(dpoi.txt_label);
map_force_redraw();
gtk_widget_hide(dialog); /* Destroying causes a crash.... ??? */
_degformat = last_deg_format;
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return !dpoi.deleted;
}
static gint
poi_list_insert(GtkWidget *parent, GList *poi_list, GtkComboBox *cmb_category)
{
gint default_cat_id;
gchar *default_cat_label;
gint num_inserts = 0;
GList *curr;
GtkTreeIter iter;
printf("%s()\n", __PRETTY_FUNCTION__);
/* Get defaults from the given GtkComboBox */
if(!gtk_combo_box_get_active_iter(
GTK_COMBO_BOX(cmb_category), &iter))
{
vprintf("%s(): return 0\n", __PRETTY_FUNCTION__);
return 0;
}
gtk_tree_model_get(
gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),
&iter,
0, &default_cat_id,
1, &default_cat_label,
-1);
/* Iterate through the data model and import as desired. */
for(curr = poi_list; curr; )
{
PoiInfo *poi = curr->data;
if(
( SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 1, poi->lat)
|| SQLITE_OK != sqlite3_bind_double(_stmt_insert_poi, 2, poi->lon)
|| SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 3, poi->label,
-1, SQLITE_STATIC)
|| SQLITE_OK != sqlite3_bind_text(_stmt_insert_poi, 4, poi->desc,
-1, SQLITE_STATIC)
|| SQLITE_OK != sqlite3_bind_int(_stmt_insert_poi, 5,
poi->cat_id = default_cat_id)
|| SQLITE_DONE != sqlite3_step(_stmt_insert_poi)
))
{
/* Failure. */
GList *tmp = curr->next;
if(poi->label)
g_free(poi->label);
if(poi->desc)
g_free(poi->desc);
g_slice_free(PoiInfo, poi);
poi_list = g_list_delete_link(poi_list, curr);
curr = tmp;
}
else
{
/* Success. */
++num_inserts;
if(default_cat_label)
poi->clabel = g_strdup(default_cat_label);
poi->poi_id = sqlite3_last_insert_rowid(_poi_db);
curr = curr->next;
}
sqlite3_reset(_stmt_insert_poi);
}
if(num_inserts)
{
gchar buffer[BUFFER_SIZE];
map_force_redraw();
snprintf(buffer, sizeof(buffer), "%d %s", num_inserts,
_("POIs were added to the POI database. The following screen will "
"allow you to modify or delete any of the new POIs."));
popup_error(parent, buffer);
}
else
{
popup_error(parent, _("No POIs were found."));
}
if(default_cat_label)
g_free(default_cat_label);
vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, num_inserts);
return num_inserts;
}
static void
poi_list_free(GList *poi_list)
{
GList *curr;
printf("%s()\n", __PRETTY_FUNCTION__);
for(curr = poi_list; curr; curr = curr->next)
{
PoiInfo *poi_info = curr->data;
if(poi_info)
{
if(poi_info->label)
g_free(poi_info->label);
if(poi_info->desc)
g_free(poi_info->desc);
if(poi_info->clabel)
g_free(poi_info->clabel);
g_slice_free(PoiInfo, poi_info);
}
}
g_list_free(poi_list);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
static void
poi_list_bearing_cell_data_func(
GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
gchar buffer[80];
gfloat f;
vprintf("%s()\n", __PRETTY_FUNCTION__);
gtk_tree_model_get(tree_model, iter, POI_BEARING, &f, -1);
snprintf(buffer, sizeof(buffer), "%.1f", f);
g_object_set(cell, "text", buffer, NULL);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
static void
poi_list_distance_cell_data_func(
GtkTreeViewColumn *tree_column,
GtkCellRenderer *cell,
GtkTreeModel *tree_model,
GtkTreeIter *iter)
{
gchar buffer[80];
gfloat f;
vprintf("%s()\n", __PRETTY_FUNCTION__);
gtk_tree_model_get(tree_model, iter, POI_DISTANCE, &f, -1);
snprintf(buffer, sizeof(buffer), "%.2f", f);
g_object_set(cell, "text", buffer, NULL);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
static gboolean
poi_list_row_selected(GtkCellRendererToggle *renderer,
gchar *path_string, GtkTreeModel *tree_model)
{
GtkTreeIter iter;
vprintf("%s()\n", __PRETTY_FUNCTION__);
if(gtk_tree_model_get_iter_from_string(tree_model, &iter, path_string))
{
gboolean old_value;
gtk_tree_model_get(tree_model, &iter, POI_SELECTED, &old_value, -1);
gtk_list_store_set(GTK_LIST_STORE(tree_model), &iter,
POI_SELECTED, !old_value,
-1);
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_list_set_category(GtkWidget *widget, PoiListInfo *pli)
{
static GtkWidget *dialog = NULL;
static GtkWidget *cmb_category = NULL;
static GtkWidget *btn_catedit = NULL;
static PoiCategoryEditInfo pcedit;
printf("%s()\n", __PRETTY_FUNCTION__);
if(dialog == NULL)
{
GtkWidget *hbox;
GtkWidget *label;
dialog = gtk_dialog_new_with_buttons(_("Set Category..."),
GTK_WINDOW(pli->dialog2), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(hbox),
label = gtk_label_new(_("Category")),
FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox),
cmb_category = poi_create_cat_combo(),
FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(hbox),
btn_catedit = gtk_button_new_with_label(
_("Edit Categories...")),
FALSE, FALSE, 0);
/* Connect Signals */
pcedit.dialog = dialog;
pcedit.cmb_category = cmb_category;
pcedit.cat_id = -1;
g_signal_connect(G_OBJECT(btn_catedit), "clicked",
G_CALLBACK(poi_edit_cat), &pcedit);
}
gtk_widget_show_all(dialog);
while(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog)))
{
GtkTreeIter iter;
GtkListStore *store;
gint cat_id;
const gchar *cat_label;
/* Get the text of the chosen category. */
if(!gtk_combo_box_get_active_iter(
GTK_COMBO_BOX(cmb_category), &iter))
{
popup_error(dialog, _("Please specify a category."));
continue;
}
gtk_tree_model_get(
gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),
&iter,
0, &cat_id,
1, &cat_label,
-1);
/* Iterate through the data store and categorize as desired. */
store = GTK_LIST_STORE(gtk_tree_view_get_model(
GTK_TREE_VIEW(pli->tree_view)));
if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) do
{
PoiInfo poi;
gboolean selected;
memset(&poi, 0, sizeof(poi));
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
POI_SELECTED, &selected,
POI_POIID, &(poi.poi_id),
POI_LAT, &(poi.lat),
POI_LON, &(poi.lon),
POI_LABEL, &(poi.label),
POI_DESC, &(poi.desc),
-1);
if(selected)
{
gtk_list_store_set(store, &iter,
POI_CATID, cat_id,
POI_CLABEL, cat_label,
-1);
/* edit poi */
if(SQLITE_OK != sqlite3_bind_double(
_stmt_update_poi, 1, poi.lat) ||
SQLITE_OK != sqlite3_bind_double(
_stmt_update_poi, 2, poi.lon) ||
SQLITE_OK != sqlite3_bind_text(_stmt_update_poi,
3, poi.label, -1, SQLITE_STATIC) ||
SQLITE_OK != sqlite3_bind_text(_stmt_update_poi,
4, poi.desc, -1, SQLITE_STATIC) ||
SQLITE_OK != sqlite3_bind_int(
_stmt_update_poi, 5, cat_id) ||
SQLITE_OK != sqlite3_bind_int(
_stmt_update_poi, 6, poi.poi_id) ||
SQLITE_DONE != sqlite3_step(_stmt_update_poi))
{
MACRO_BANNER_SHOW_INFO(pli->dialog2,
_("Error updating POI"));
}
sqlite3_reset(_stmt_update_poi);
}
} while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
break;
}
map_force_redraw();
gtk_widget_hide(dialog);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_list_select_all(GtkTreeViewColumn *column, PoiListInfo *pli)
{
GtkTreeIter iter;
GtkListStore *store;
printf("%s()\n", __PRETTY_FUNCTION__);
/* Iterate through the data store and select as desired. */
store = GTK_LIST_STORE(gtk_tree_view_get_model(
GTK_TREE_VIEW(pli->tree_view)));
if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) do
{
gtk_list_store_set(store, &iter,
POI_SELECTED, pli->select_all,
-1);
} while(gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
pli->select_all = !pli->select_all;
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_list_view(GtkWidget *widget, PoiListInfo *pli)
{
GtkTreeIter iter;
GtkTreeSelection *selection;
GtkListStore *store;
printf("%s()\n", __PRETTY_FUNCTION__);
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pli->tree_view));
store = GTK_LIST_STORE(gtk_tree_view_get_model(
GTK_TREE_VIEW(pli->tree_view)));
/* Iterate through the data store and import as desired. */
if(gtk_tree_selection_get_selected(selection, NULL, &iter))
{
PoiInfo poi;
memset(&poi, 0, sizeof(poi));
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
POI_POIID, &(poi.poi_id),
POI_CATID, &(poi.cat_id),
POI_LAT, &(poi.lat),
POI_LON, &(poi.lon),
POI_LABEL, &(poi.label),
POI_DESC, &(poi.desc),
POI_CLABEL, &(poi.clabel),
-1);
if(poi_view_dialog(pli->dialog, &poi))
{
gtk_list_store_set(store, &iter,
POI_POIID, poi.poi_id,
POI_CATID, poi.cat_id,
POI_LAT, poi.lat,
POI_LON, poi.lon,
POI_LABEL, poi.label,
POI_DESC, poi.desc,
POI_CLABEL, poi.clabel,
-1);
}
else
{
/* POI was deleted. */
gtk_list_store_remove(store, &iter);
}
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static void
poi_list_row_activated(GtkTreeView *tree_view, GtkTreePath *path,
GtkTreeViewColumn *column, PoiListInfo *pli)
{
printf("%s()\n", __PRETTY_FUNCTION__);
if(column != pli->select_column)
poi_list_view(GTK_WIDGET(tree_view), pli);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
}
static gboolean
poi_list_goto(GtkWidget *widget, PoiListInfo *pli)
{
GtkTreeIter iter;
GtkTreeSelection *selection;
GtkListStore *store;
printf("%s()\n", __PRETTY_FUNCTION__);
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(pli->tree_view));
store = GTK_LIST_STORE(gtk_tree_view_get_model(
GTK_TREE_VIEW(pli->tree_view)));
/* Iterate through the data store and import as desired. */
if(gtk_tree_selection_get_selected(selection, NULL, &iter))
{
gdouble lat, lon;
Point unit;
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
POI_LAT, &lat,
POI_LON, &lon,
-1);
latlon2unit(lat, lon, unit.unitx, unit.unity);
if(_center_mode > 0)
gtk_check_menu_item_set_active(
GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
map_center_unit(unit);
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_list_delete(GtkWidget *widget, PoiListInfo *pli)
{
GtkWidget *confirm;
printf("%s()\n", __PRETTY_FUNCTION__);
confirm = hildon_note_new_confirmation(
GTK_WINDOW(pli->dialog2), _("Delete selected POI?"));
if(GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
{
GtkTreeIter iter;
GtkListStore *store;
gboolean already_next;
gboolean must_iterate;;
/* Iterate through the data store and import as desired. */
store = GTK_LIST_STORE(gtk_tree_view_get_model(
GTK_TREE_VIEW(pli->tree_view)));
if(gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) do
{
gboolean selected;
must_iterate = TRUE;
already_next = FALSE;
gint poi_id;
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
POI_SELECTED, &selected,
POI_POIID, &poi_id,
-1);
if(selected)
{
/* Delete POI. */
if(SQLITE_OK != sqlite3_bind_int(_stmt_delete_poi, 1, poi_id)
|| SQLITE_DONE != sqlite3_step(_stmt_delete_poi))
{
MACRO_BANNER_SHOW_INFO(pli->dialog2,
_("Error deleting POI"));
}
else
{
already_next = gtk_list_store_remove(store, &iter);
must_iterate = FALSE;
}
sqlite3_reset(_stmt_delete_poi);
}
} while(already_next || (must_iterate
&& gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)));
}
map_force_redraw();
gtk_widget_destroy(confirm);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_list_export_gpx(GtkWidget *widget, PoiListInfo *pli)
{
GnomeVFSHandle *handle;
printf("%s()\n", __PRETTY_FUNCTION__);
if(display_open_file(GTK_WINDOW(pli->dialog2), NULL, &handle, NULL,
NULL, NULL, GTK_FILE_CHOOSER_ACTION_SAVE))
{
gint num_exported = gpx_poi_write(
gtk_tree_view_get_model(GTK_TREE_VIEW(pli->tree_view)), handle);
if(num_exported >= 0)
{
gchar buffer[80];
snprintf(buffer, sizeof(buffer), "%d %s\n", num_exported,
_("POIs Exported"));
MACRO_BANNER_SHOW_INFO(pli->dialog2, buffer);
}
else
popup_error(pli->dialog2, _("Error writing GPX file."));
gnome_vfs_close(handle);
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_list_manage_checks(GtkWidget *widget, PoiListInfo *pli)
{
GtkWidget *btn_category;
GtkWidget *btn_delete;
GtkWidget *btn_export_gpx;
printf("%s()\n", __PRETTY_FUNCTION__);
pli->dialog2 = gtk_dialog_new_with_buttons(_("Checked POI Actions..."),
GTK_WINDOW(pli->dialog), GTK_DIALOG_MODAL,
NULL);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
gtk_label_new(_("Select an operation to perform\n"
"on the POIs that you checked\n"
"in the POI list.")),
FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
btn_category = gtk_button_new_with_label(_("Set Category...")),
FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
btn_delete = gtk_button_new_with_label(_("Delete...")),
FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli->dialog2)->vbox),
btn_export_gpx = gtk_button_new_with_label(
_("Export to GPX...")),
FALSE, FALSE, 4);
gtk_dialog_add_button(GTK_DIALOG(pli->dialog2),
GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT);
g_signal_connect(G_OBJECT(btn_category), "clicked",
G_CALLBACK(poi_list_set_category), pli);
g_signal_connect(G_OBJECT(btn_delete), "clicked",
G_CALLBACK(poi_list_delete), pli);
g_signal_connect(G_OBJECT(btn_export_gpx), "clicked",
G_CALLBACK(poi_list_export_gpx), pli);
gtk_widget_show_all(pli->dialog2);
gtk_dialog_run(GTK_DIALOG(pli->dialog2));
gtk_widget_destroy(pli->dialog2);
pli->dialog2 = NULL;
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
poi_list_dialog(GtkWidget *parent, gint unitx, gint unity, GList *poi_list)
{
static PoiListInfo pli = { NULL, NULL };
static GtkWidget *scroller;
static GtkWidget *btn_goto;
static GtkWidget *btn_edit;
static GtkWidget *btn_manage_checks;
static GtkListStore *store;
GtkTreeIter iter;
GList *curr;
gdouble src_lat, src_lon;
printf("%s()\n", __PRETTY_FUNCTION__);
if(pli.dialog == NULL)
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
pli.dialog = gtk_dialog_new_with_buttons(_("POI List"),
GTK_WINDOW(parent), GTK_DIALOG_MODAL,
NULL);
store = gtk_list_store_new(POI_NUM_COLUMNS,
G_TYPE_BOOLEAN,/* Selected */
G_TYPE_INT, /* POI ID */
G_TYPE_INT, /* Category ID */
G_TYPE_DOUBLE, /* Latitude */
G_TYPE_DOUBLE, /* Longitude */
G_TYPE_STRING, /* Lat/Lon */
G_TYPE_FLOAT, /* Bearing */
G_TYPE_FLOAT, /* Distance */
G_TYPE_STRING, /* POI Label */
G_TYPE_STRING, /* POI Desc. */
G_TYPE_STRING);/* Category Label */
/* Set up the tree view. */
pli.tree_view = gtk_tree_view_new();
g_object_set(G_OBJECT(pli.tree_view),
"allow-checkbox-mode", FALSE, NULL);
gtk_tree_selection_set_mode(
gtk_tree_view_get_selection(GTK_TREE_VIEW(pli.tree_view)),
GTK_SELECTION_SINGLE);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pli.tree_view), TRUE);
renderer = gtk_cell_renderer_toggle_new();
gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(renderer),
TRUE);
g_signal_connect(G_OBJECT(renderer), "toggled",
G_CALLBACK(poi_list_row_selected), store);
pli.select_column = gtk_tree_view_column_new_with_attributes(
"*", renderer, "active", POI_SELECTED, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(pli.tree_view),
pli.select_column);
gtk_tree_view_column_set_clickable(pli.select_column, TRUE);
g_signal_connect(G_OBJECT(pli.select_column), "clicked",
G_CALLBACK(poi_list_select_all), &pli);
renderer = gtk_cell_renderer_combo_new();
column = gtk_tree_view_column_new_with_attributes(
_("Category"), renderer, "text", POI_CLABEL, NULL);
gtk_tree_view_column_set_sizing(column,GTK_TREE_VIEW_COLUMN_GROW_ONLY);
gtk_tree_view_column_set_sort_column_id(column, POI_CLABEL);
gtk_tree_view_append_column(GTK_TREE_VIEW(pli.tree_view), column);
renderer = gtk_cell_renderer_text_new();
g_object_set(renderer, "xalign", 1.f, NULL);
column = gtk_tree_view_column_new_with_attributes(
_("Dist."), renderer, "text", POI_DISTANCE, NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
(GtkTreeCellDataFunc)poi_list_distance_cell_data_func,
NULL, NULL);
gtk_tree_view_column_set_sort_column_id(column, POI_DISTANCE);
gtk_tree_view_append_column(GTK_TREE_VIEW(pli.tree_view), column);
renderer = gtk_cell_renderer_text_new();
g_object_set(renderer, "xalign", 1.f, NULL);
column = gtk_tree_view_column_new_with_attributes(
_("Bear."), renderer, "text", POI_BEARING, NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
(GtkTreeCellDataFunc)poi_list_bearing_cell_data_func,
NULL, NULL);
gtk_tree_view_column_set_sort_column_id(column, POI_BEARING);
gtk_tree_view_append_column(GTK_TREE_VIEW(pli.tree_view), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(
_("Label"), renderer, "text", POI_LABEL, NULL);
gtk_tree_view_column_set_sort_column_id(column, POI_LABEL);
gtk_tree_view_append_column(GTK_TREE_VIEW(pli.tree_view), column);
g_signal_connect(G_OBJECT(pli.tree_view), "row-activated",
G_CALLBACK(poi_list_row_activated), &pli);
gtk_tree_view_set_model(GTK_TREE_VIEW(pli.tree_view),
GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
/* Enable the help button. */
#ifndef LEGACY
hildon_help_dialog_help_enable(
#else
ossohelp_dialog_help_enable(
#endif
GTK_DIALOG(pli.dialog), HELP_ID_POILIST, _osso);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(pli.dialog)->action_area),
btn_goto = gtk_button_new_with_label(_("Go to")));
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(pli.dialog)->action_area),
btn_edit = gtk_button_new_with_label(_("Edit...")));
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(pli.dialog)->action_area),
btn_manage_checks = gtk_button_new_with_label(
_("Checked POI Actions...")));
gtk_dialog_add_button(GTK_DIALOG(pli.dialog),
GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT);
gtk_window_set_default_size(GTK_WINDOW(pli.dialog), 500, 400);
scroller = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroller),
GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(pli.dialog)->vbox),
scroller, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(scroller), pli.tree_view);
g_signal_connect(G_OBJECT(btn_goto), "clicked",
G_CALLBACK(poi_list_goto), &pli);
g_signal_connect(G_OBJECT(btn_edit), "clicked",
G_CALLBACK(poi_list_view), &pli);
g_signal_connect(G_OBJECT(btn_manage_checks), "clicked",
G_CALLBACK(poi_list_manage_checks), &pli);
}
/* Initialize the tree store. */
gtk_list_store_clear(store);
pli.select_all = FALSE;
unit2latlon(unitx, unity, src_lat, src_lon);
for(curr = poi_list; curr; curr = curr->next)
{
PoiInfo *poi_info = curr->data;
gchar tmp1[LL_FMT_LEN], tmp2[LL_FMT_LEN];
printf("poi: (%f, %f, %s, %s)\n",
poi_info->lat, poi_info->lon,
poi_info->label, poi_info->desc);
format_lat_lon(poi_info->lat, poi_info->lon, tmp1, tmp2);
//lat_format(poi_info->lat, tmp1);
//lon_format(poi_info->lon, tmp2);
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
POI_SELECTED, TRUE,
POI_POIID, poi_info->poi_id,
POI_LAT, poi_info->lat,
POI_LON, poi_info->lon,
POI_BEARING, calculate_bearing(src_lat, src_lon,
poi_info->lat, poi_info->lon),
POI_DISTANCE, calculate_distance(src_lat,src_lon,
poi_info->lat, poi_info->lon) * UNITS_CONVERT[_units],
POI_LABEL, poi_info->label,
POI_DESC, poi_info->desc,
POI_CATID, poi_info->cat_id,
POI_CLABEL, poi_info->clabel,
-1);
}
gtk_widget_show_all(pli.dialog);
GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(pli.dialog));
map_force_redraw();
gtk_widget_hide(pli.dialog);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
gboolean
poi_import_dialog(gint unitx, gint unity)
{
GtkWidget *dialog = NULL;
gboolean success = FALSE;
printf("%s()\n", __PRETTY_FUNCTION__);
dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(_window),
GTK_FILE_CHOOSER_ACTION_OPEN);
gtk_widget_show_all(dialog);
while(!success && gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
{
gchar *file_uri_str = NULL;
gchar *bytes = NULL;
gint size;
GnomeVFSResult vfs_result;
GList *poi_list = NULL;
file_uri_str = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
/* Parse the given file as GPX. */
if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
file_uri_str, &size, &bytes)))
{
popup_error(dialog, gnome_vfs_result_to_string(vfs_result));
}
else if(gpx_poi_parse(bytes, size, &poi_list))
{
static GtkWidget *cat_dialog = NULL;
static GtkWidget *cmb_category = NULL;
static GtkWidget *btn_catedit = NULL;
static PoiCategoryEditInfo pcedit;
if(!cat_dialog)
{
GtkWidget *hbox;
GtkWidget *label;
cat_dialog = gtk_dialog_new_with_buttons(_("Default Category"),
GTK_WINDOW(dialog), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(cat_dialog)->vbox),
hbox = gtk_hbox_new(FALSE, 4), FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(hbox),
label = gtk_label_new(_("Category")),
FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox),
cmb_category = poi_create_cat_combo(),
FALSE, FALSE, 4);
gtk_box_pack_start(GTK_BOX(hbox),
btn_catedit = gtk_button_new_with_label(
_("Edit Categories...")),
FALSE, FALSE, 0);
/* Connect Signals */
pcedit.dialog = dialog;
pcedit.cmb_category = cmb_category;
pcedit.cat_id = -1;
g_signal_connect(G_OBJECT(btn_catedit), "clicked",
G_CALLBACK(poi_edit_cat), &pcedit);
}
gtk_widget_show_all(cat_dialog);
while(GTK_RESPONSE_ACCEPT ==gtk_dialog_run(GTK_DIALOG(cat_dialog)))
{
if(gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_category)) == -1)
{
popup_error(dialog,
_("Please specify a default category."));
continue;
}
/* Insert the POIs into the database. */
gint num_inserts = poi_list_insert(dialog,
poi_list, GTK_COMBO_BOX(cmb_category));
if(num_inserts)
{
/* Hide the dialogs. */
gtk_widget_hide(cat_dialog);
/* Create a new dialog with the results. */
poi_list_dialog(dialog, unitx, unity, poi_list);
success = TRUE;
}
break;
}
gtk_widget_hide(cat_dialog);
poi_list_free(poi_list);
}
else
popup_error(dialog, _("Error parsing GPX file."));
g_free(file_uri_str);
g_free(bytes);
}
/* Hide the dialog. */
gtk_widget_destroy(dialog);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return success;
}
static gboolean
poi_download_cat_selected(GtkComboBox *cmb_category, GtkEntry *txt_query)
{
GtkTreeIter iter;
printf("%s()\n", __PRETTY_FUNCTION__);
if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(cmb_category), &iter))
{
gchar buffer[BUFFER_SIZE];
GtkWidget *confirm = NULL;
gchar *category = NULL;
gtk_tree_model_get(
gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)), &iter,
1, &category,
-1);
if(*gtk_entry_get_text(txt_query))
{
snprintf(buffer, sizeof(buffer), "%s\n %s",
_("Overwrite query with the following text?"), category);
confirm = hildon_note_new_confirmation(GTK_WINDOW(_window),buffer);
}
if(confirm == NULL
|| GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm)))
gtk_entry_set_text(txt_query, category);
if(confirm)
gtk_widget_destroy(confirm);
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
static gboolean
origin_type_selected(GtkWidget *toggle, OriginToggleInfo *oti)
{
printf("%s()\n", __PRETTY_FUNCTION__);
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)))
gtk_widget_set_sensitive(oti->txt_origin, toggle == oti->rad_use_text);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
gboolean
poi_download_dialog(gint unitx, gint unity)
{
static GtkWidget *dialog = NULL;
static GtkWidget *hbox = NULL;
static GtkWidget *table = NULL;
static GtkWidget *table2 = NULL;
static GtkWidget *label = NULL;
static GtkWidget *num_page = NULL;
static GtkWidget *txt_source_url = NULL;
static OriginToggleInfo oti;
static GtkWidget *cmb_category;
printf("%s()\n", __PRETTY_FUNCTION__);
conic_recommend_connected();
if(!dialog)
{
GtkEntryCompletion *origin_comp;
dialog = gtk_dialog_new_with_buttons(_("Download POIs"),
GTK_WINDOW(_window), GTK_DIALOG_MODAL,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
NULL);
/* Enable the help button. */
#ifndef LEGACY
hildon_help_dialog_help_enable(
#else
ossohelp_dialog_help_enable(
#endif
GTK_DIALOG(dialog), HELP_ID_DOWNPOI, _osso);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
table = gtk_table_new(4, 4, FALSE), TRUE, TRUE, 0);
/* Source URL. */
gtk_table_attach(GTK_TABLE(table),
hbox = gtk_hbox_new(FALSE, 4),
0, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_box_pack_start(GTK_BOX(hbox),
label = gtk_label_new(_("Source URL")), FALSE, TRUE, 4);
gtk_box_pack_start(GTK_BOX(hbox),
txt_source_url = gtk_entry_new(), TRUE, TRUE, 4);
/* Auto. */
gtk_table_attach(GTK_TABLE(table),
oti.rad_use_gps = gtk_radio_button_new_with_label(NULL,
_("Use GPS Location")),
0, 1, 1, 2, GTK_FILL, 0, 2, 4);
/* Use End of Route. */
gtk_table_attach(GTK_TABLE(table),
oti.rad_use_route = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(oti.rad_use_gps), _("Use End of Route")),
0, 1, 2, 3, GTK_FILL, 0, 2, 4);
gtk_table_attach(GTK_TABLE(table),
gtk_vseparator_new(),
1, 2, 1, 3, GTK_FILL, GTK_FILL, 2,4);
/* Category. */
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Category")),
2, 3, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
cmb_category = poi_create_cat_combo(),
3, 4, 1, 2, GTK_FILL, 0, 2, 4);
/* Page. */
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Page")),
2, 3, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
num_page = hildon_number_editor_new(1, 999),
3, 4, 2, 3, GTK_FILL, 0, 2, 4);
/* Another table for the Origin and Query. */
gtk_table_attach(GTK_TABLE(table),
table2 = gtk_table_new(2, 2, FALSE),
0, 4, 3, 4, GTK_EXPAND | GTK_FILL, 0, 2, 4);
/* Origin. */
gtk_table_attach(GTK_TABLE(table2),
oti.rad_use_text = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")),
0, 1, 0, 1, GTK_FILL, 0, 2, 4);
gtk_table_attach(GTK_TABLE(table2),
oti.txt_origin = gtk_entry_new(),
1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_origin), 25);
#ifdef MAEMO_CHANGES
#ifndef LEGACY
g_object_set(G_OBJECT(oti.txt_origin), "hildon-input-mode",
HILDON_GTK_INPUT_MODE_FULL, NULL);
#else
g_object_set(G_OBJECT(oti.txt_origin), HILDON_AUTOCAP, FALSE, NULL);
#endif
#endif
/* Query. */
gtk_table_attach(GTK_TABLE(table2),
label = gtk_label_new(_("Query")),
0, 1, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table2),
oti.txt_query = gtk_entry_new(),
1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_query), 25);
#ifdef MAEMO_CHANGES
#ifndef LEGACY
g_object_set(G_OBJECT(oti.txt_query), "hildon-input-mode",
HILDON_GTK_INPUT_MODE_FULL, NULL);
#else
g_object_set(G_OBJECT(oti.txt_query), HILDON_AUTOCAP, FALSE, NULL);
#endif
#endif
/* Set up auto-completion. */
origin_comp = gtk_entry_completion_new();
gtk_entry_completion_set_model(origin_comp,GTK_TREE_MODEL(_loc_model));
gtk_entry_completion_set_text_column(origin_comp, 0);
gtk_entry_set_completion(GTK_ENTRY(oti.txt_origin), origin_comp);
g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled",
G_CALLBACK(origin_type_selected), &oti);
g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled",
G_CALLBACK(origin_type_selected), &oti);
g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled",
G_CALLBACK(origin_type_selected), &oti);
g_signal_connect(G_OBJECT(cmb_category), "changed",
G_CALLBACK(poi_download_cat_selected), oti.txt_query);
}
/* Initialize fields. */
hildon_number_editor_set_value(HILDON_NUMBER_EDITOR(num_page), 1);
gtk_entry_set_text(GTK_ENTRY(txt_source_url), _poi_dl_url);
if(unity != 0)
{
gchar buffer[80];
gchar strlat[32];
gchar strlon[32];
gdouble lat, lon;
unit2latlon(unitx, unity, lat, lon);
g_ascii_formatd(strlat, 32, "%.06f", lat);
g_ascii_formatd(strlon, 32, "%.06f", lon);
snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
gtk_entry_set_text(GTK_ENTRY(oti.txt_origin), buffer);
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
}
/* Else use "End of Route" by default if they have a route. */
else if(_route.head != _route.tail)
{
/* There is no route, so make it the default. */
gtk_widget_set_sensitive(oti.rad_use_route, TRUE);
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_route), TRUE);
gtk_widget_grab_focus(oti.rad_use_route);
}
/* Else use "GPS Location" if they have GPS enabled. */
else
{
/* There is no route, so desensitize "Use End of Route." */
gtk_widget_set_sensitive(oti.rad_use_route, FALSE);
if(_enable_gps)
{
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_gps), TRUE);
gtk_widget_grab_focus(oti.rad_use_gps);
}
/* Else use text. */
else
{
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
gtk_widget_grab_focus(oti.txt_origin);
}
}
gtk_widget_show_all(dialog);
while(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
gchar origin_buffer[BUFFER_SIZE];
const gchar *source_url, *origin, *query;
gchar *file_uri_str = NULL;
gchar *bytes = NULL;
gint size;
GnomeVFSResult vfs_result;
GList *poi_list = NULL;
source_url = gtk_entry_get_text(GTK_ENTRY(txt_source_url));
if(!strlen(source_url))
{
popup_error(dialog, _("Please specify a source URL."));
continue;
}
else
{
g_free(_poi_dl_url);
_poi_dl_url = g_strdup(source_url);
}
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)))
{
gchar strlat[32];
gchar strlon[32];
latlon2unit(_gps.lat, _gps.lon, unitx, unity);
g_ascii_formatd(strlat, 32, "%.06f", _gps.lat);
g_ascii_formatd(strlon, 32, "%.06f", _gps.lon);
snprintf(origin_buffer, sizeof(origin_buffer),
"%s, %s", strlat, strlon);
origin = origin_buffer;
}
else if(gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(oti.rad_use_route)))
{
gchar strlat[32];
gchar strlon[32];
Point *p;
gdouble lat, lon;
/* Use last non-zero route point. */
for(p = _route.tail; !p->unity; p--) { }
unitx = p->unitx;
unity = p->unity;
unit2latlon(p->unitx, p->unity, lat, lon);
g_ascii_formatd(strlat, 32, "%.06f", lat);
g_ascii_formatd(strlon, 32, "%.06f", lon);
snprintf(origin_buffer, sizeof(origin_buffer),
"%s, %s", strlat, strlon);
origin = origin_buffer;
}
else
{
Point porig;
origin = gtk_entry_get_text(GTK_ENTRY(oti.txt_origin));
if(*origin)
{
porig = locate_address(dialog, origin);
if(!porig.unity)
continue;
}
}
if(!*origin)
{
popup_error(dialog, _("Please specify an origin."));
continue;
}
if(gtk_combo_box_get_active(GTK_COMBO_BOX(cmb_category)) == -1)
{
popup_error(dialog, _("Please specify a default category."));
continue;
}
query = gtk_entry_get_text(GTK_ENTRY(oti.txt_query));
if(!strlen(query))
{
popup_error(dialog, _("Please specify a query."));
continue;
}
/* Construct the URL. */
{
gchar *origin_escaped;
gchar *query_escaped;
origin_escaped = gnome_vfs_escape_string(origin);
query_escaped = gnome_vfs_escape_string(query);
file_uri_str = g_strdup_printf(
source_url, origin_escaped, query_escaped,
hildon_number_editor_get_value(
HILDON_NUMBER_EDITOR(num_page)));
g_free(origin_escaped);
g_free(query_escaped);
}
/* Parse the given file as GPX. */
if(GNOME_VFS_OK != (vfs_result = gnome_vfs_read_entire_file(
file_uri_str, &size, &bytes)))
{
popup_error(dialog, gnome_vfs_result_to_string(vfs_result));
}
else if(strncmp(bytes, "vbox),
table = gtk_table_new(3, 4, FALSE), TRUE, TRUE, 0);
/* Auto. */
gtk_table_attach(GTK_TABLE(table),
oti.rad_use_gps = gtk_radio_button_new_with_label(NULL,
_("Use GPS Location")),
0, 1, 0, 1, GTK_FILL, 0, 2, 4);
/* Use End of Route. */
gtk_table_attach(GTK_TABLE(table),
oti.rad_use_route = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(oti.rad_use_gps), _("Use End of Route")),
0, 1, 1, 2, GTK_FILL, 0, 2, 4);
gtk_table_attach(GTK_TABLE(table),
gtk_vseparator_new(),
1, 2, 0, 2, GTK_FILL, GTK_FILL, 2, 4);
/* Category. */
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(_("Category")),
2, 3, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
cmb_category = poi_create_cat_combo(),
3, 4, 0, 1, GTK_FILL, 0, 2, 4);
/* Add an extra, "" category. */
{
GtkTreeIter iter;
GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(
GTK_COMBO_BOX(cmb_category)));
gtk_list_store_prepend(store, &iter);
gtk_list_store_set(store, &iter, 0, -1, 1, "", -1);
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(cmb_category), &iter);
}
/* Another table for the Origin and Query. */
gtk_table_attach(GTK_TABLE(table),
table2 = gtk_table_new(2, 2, FALSE),
0, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 2, 4);
/* Origin. */
gtk_table_attach(GTK_TABLE(table2),
oti.rad_use_text = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(oti.rad_use_gps), _("Origin")),
0, 1, 0, 1, GTK_FILL, 0, 2, 4);
gtk_table_attach(GTK_TABLE(table2),
oti.txt_origin = gtk_entry_new(),
1, 2, 0, 1, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_origin), 25);
#ifdef MAEMO_CHANGES
#ifndef LEGACY
g_object_set(G_OBJECT(oti.txt_origin), "hildon-input-mode",
HILDON_GTK_INPUT_MODE_FULL, NULL);
#else
g_object_set(G_OBJECT(oti.txt_origin), HILDON_AUTOCAP, FALSE, NULL);
#endif
#endif
/* Destination. */
gtk_table_attach(GTK_TABLE(table2),
label = gtk_label_new(_("Query")),
0, 1, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table2),
oti.txt_query = gtk_entry_new(),
1, 2, 1, 2, GTK_EXPAND | GTK_FILL, 0, 2, 4);
gtk_entry_set_width_chars(GTK_ENTRY(oti.txt_query), 25);
#ifdef MAEMO_CHANGES
#ifndef LEGACY
g_object_set(G_OBJECT(oti.txt_query), "hildon-input-mode",
HILDON_GTK_INPUT_MODE_FULL, NULL);
#else
g_object_set(G_OBJECT(oti.txt_query), HILDON_AUTOCAP, FALSE, NULL);
#endif
#endif
/* Set up auto-completion. */
origin_comp = gtk_entry_completion_new();
gtk_entry_completion_set_model(origin_comp,GTK_TREE_MODEL(_loc_model));
gtk_entry_completion_set_text_column(origin_comp, 0);
gtk_entry_set_completion(GTK_ENTRY(oti.txt_origin), origin_comp);
g_signal_connect(G_OBJECT(oti.rad_use_gps), "toggled",
G_CALLBACK(origin_type_selected), &oti);
g_signal_connect(G_OBJECT(oti.rad_use_route), "toggled",
G_CALLBACK(origin_type_selected), &oti);
g_signal_connect(G_OBJECT(oti.rad_use_text), "toggled",
G_CALLBACK(origin_type_selected), &oti);
}
/* Initialize fields. */
if(unity != 0)
{
gchar buffer[80];
gchar strlat[32];
gchar strlon[32];
gdouble lat, lon;
unit2latlon(unitx, unity, lat, lon);
g_ascii_formatd(strlat, 32, "%.06f", lat);
g_ascii_formatd(strlon, 32, "%.06f", lon);
snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
gtk_entry_set_text(GTK_ENTRY(oti.txt_origin), buffer);
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
}
/* Else use "End of Route" by default if they have a route. */
else if(_route.head != _route.tail)
{
/* There is no route, so make it the default. */
gtk_widget_set_sensitive(oti.rad_use_route, TRUE);
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_route), TRUE);
gtk_widget_grab_focus(oti.rad_use_route);
}
/* Else use "GPS Location" if they have GPS enabled. */
else
{
/* There is no route, so desensitize "Use End of Route." */
gtk_widget_set_sensitive(oti.rad_use_route, FALSE);
if(_enable_gps)
{
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_gps), TRUE);
gtk_widget_grab_focus(oti.rad_use_gps);
}
/* Else use text. */
else
{
gtk_toggle_button_set_active(
GTK_TOGGLE_BUTTON(oti.rad_use_text), TRUE);
gtk_widget_grab_focus(oti.txt_origin);
}
}
gtk_widget_show_all(dialog);
while(gtk_dialog_run(GTK_DIALOG(dialog)) ==GTK_RESPONSE_ACCEPT)
{
gchar buffer[BUFFER_SIZE];
const gchar *origin, *query;
gdouble lat, lon;
GList *poi_list = NULL;
gint cat_id;
gboolean is_cat = FALSE;
sqlite3_stmt *stmt;
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(oti.rad_use_gps)))
{
gchar strlat[32];
gchar strlon[32];
latlon2unit(_gps.lat, _gps.lon, unitx, unity);
g_ascii_formatd(strlat, 32, "%.06f", _gps.lat);
g_ascii_formatd(strlon, 32, "%.06f", _gps.lon);
snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
origin = buffer;
}
else if(gtk_toggle_button_get_active(
GTK_TOGGLE_BUTTON(oti.rad_use_route)))
{
gchar strlat[32];
gchar strlon[32];
Point *p;
gdouble lat, lon;
/* Use last non-zero route point. */
for(p = _route.tail; !p->unity; p--) { }
unitx = p->unitx;
unity = p->unity;
unit2latlon(p->unitx, p->unity, lat, lon);
g_ascii_formatd(strlat, 32, "%.06f", lat);
g_ascii_formatd(strlon, 32, "%.06f", lon);
snprintf(buffer, sizeof(buffer), "%s, %s", strlat, strlon);
origin = buffer;
}
else
{
Point porig;
origin = gtk_entry_get_text(GTK_ENTRY(oti.txt_origin));
porig = locate_address(dialog, origin);
if(!porig.unity)
continue;
}
if(!strlen(origin))
{
popup_error(dialog, _("Please specify an origin."));
continue;
}
/* Check if we're doing a category search. */
{
GtkTreeIter iter;
if(gtk_combo_box_get_active_iter(
GTK_COMBO_BOX(cmb_category), &iter))
{
gtk_tree_model_get(
gtk_combo_box_get_model(GTK_COMBO_BOX(cmb_category)),
&iter, 0, &cat_id, -1);
if(cat_id >= 0)
{
is_cat = TRUE;
}
}
}
query = g_strdup_printf("%%%s%%",
gtk_entry_get_text(GTK_ENTRY(oti.txt_query)));
unit2latlon(unitx, unity, lat, lon);
if(is_cat)
{
if(SQLITE_OK != sqlite3_bind_int(_stmt_browsecat_poi, 1, cat_id) ||
SQLITE_OK != sqlite3_bind_text(_stmt_browsecat_poi, 2, query,
-1, g_free) ||
SQLITE_OK != sqlite3_bind_double(_stmt_browsecat_poi, 3, lat) ||
SQLITE_OK != sqlite3_bind_double(_stmt_browsecat_poi, 4, lon))
{
g_printerr("Failed to bind values for _stmt_browsecat_poi\n");
continue;
}
stmt = _stmt_browsecat_poi;
}
else
{
if(SQLITE_OK != sqlite3_bind_text(_stmt_browse_poi, 1, query,
-1, g_free) ||
SQLITE_OK != sqlite3_bind_double(_stmt_browse_poi, 2, lat) ||
SQLITE_OK != sqlite3_bind_double(_stmt_browse_poi, 3, lon))
{
g_printerr("Failed to bind values for _stmt_browse_poi\n");
continue;
}
stmt = _stmt_browse_poi;
}
while(SQLITE_ROW == sqlite3_step(stmt))
{
PoiInfo *poi = g_slice_new(PoiInfo);
poi->poi_id = sqlite3_column_int(stmt, 0);
poi->cat_id = sqlite3_column_int(stmt, 1);
poi->lat = sqlite3_column_double(stmt, 2);
poi->lon = sqlite3_column_double(stmt, 3);
poi->label =g_strdup(sqlite3_column_text(stmt, 4));
poi->desc = g_strdup(sqlite3_column_text(stmt, 5));
poi->clabel=g_strdup(sqlite3_column_text(stmt, 6));
poi_list = g_list_prepend(poi_list, poi);
}
sqlite3_reset(stmt);
if(poi_list)
{
/* Create a new dialog with the results. */
poi_list_dialog(dialog, unitx, unity, poi_list);
poi_list_free(poi_list);
}
else
popup_error(dialog, _("No POIs found."));
}
map_force_redraw();
/* Hide the dialog. */
gtk_widget_hide(dialog);
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
/**
* Render all the POI data. This should be done before rendering track data.
*/
void
map_render_poi()
{
gint unitx, unity;
gdouble lat1, lat2, lon1, lon2;
gchar buffer[100];
gint poix, poiy;
GdkPixbuf *pixbuf = NULL;
GError *error = NULL;
printf("%s()\n", __PRETTY_FUNCTION__);
if(_poi_db && _poi_zoom > _zoom)
{
gint diag_offset = pixel2unit(MAX(_view_width_pixels,
_view_height_pixels) / 2);
buf2unit(0, _view_height_pixels, unitx, unity);
unitx = _center.unitx - diag_offset;
unity = _center.unity + diag_offset;
unit2latlon(unitx, unity, lat1, lon1);
unitx = _center.unitx + diag_offset;
unity = _center.unity - diag_offset;
unit2latlon(unitx, unity, lat2, lon2);
if(SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 1, lat1) ||
SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 2, lat2) ||
SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 3, lon1) ||
SQLITE_OK != sqlite3_bind_double(_stmt_select_poi, 4, lon2))
{
g_printerr("Failed to bind values for _stmt_select_poi\n");
return;
}
while(SQLITE_ROW == sqlite3_step(_stmt_select_poi))
{
lat1 = sqlite3_column_double(_stmt_select_poi, 0);
lon1 = sqlite3_column_double(_stmt_select_poi, 1);
gchar *poi_label = g_utf8_strdown(sqlite3_column_text(
_stmt_select_poi, 3), -1);
gchar *cat_label = g_utf8_strdown(sqlite3_column_text(
_stmt_select_poi, 6), -1);
latlon2unit(lat1, lon1, unitx, unity);
unit2buf(unitx, unity, poix, poiy);
/* Try to get icon for specific POI first. */
snprintf(buffer, sizeof(buffer), "%s/%s.jpg",
_poi_db_dirname, poi_label);
pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
if(error)
{
/* No icon for specific POI - try for category. */
error = NULL;
snprintf(buffer, sizeof(buffer), "%s/%s.jpg",
_poi_db_dirname, cat_label);
pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
}
if(error)
{
/* No icon for POI or for category.
* Try default POI icon file. */
error = NULL;
snprintf(buffer, sizeof(buffer), "%s/poi.jpg",
_poi_db_dirname);
pixbuf = gdk_pixbuf_new_from_file(buffer, &error);
}
if(error)
{
/* No icon for POI or for category or default POI icon file.
Draw default purple square. */
error = NULL;
gdk_draw_rectangle(_map_pixmap, _gc[COLORABLE_POI], TRUE,
poix - (gint)(1.5f * _draw_width),
poiy - (gint)(1.5f * _draw_width),
3 * _draw_width,
3 * _draw_width);
}
else
{
/* We found an icon to draw. */
gdk_draw_pixbuf(
_map_pixmap,
_gc[COLORABLE_POI],
pixbuf,
0, 0,
poix - gdk_pixbuf_get_width(pixbuf) / 2,
poiy - gdk_pixbuf_get_height(pixbuf) / 2,
-1,-1,
GDK_RGB_DITHER_NONE, 0, 0);
g_object_unref(pixbuf);
}
g_free(poi_label);
g_free(cat_label);
}
sqlite3_reset(_stmt_select_poi);
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
void
poi_destroy()
{
printf("%s()\n", __PRETTY_FUNCTION__);
if(_poi_db)
{
sqlite3_close(_poi_db);
_poi_db = NULL;
}
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
#ifdef INCLUDE_APRS
extern AprsDataRow *n_first; // pointer to first element in name sorted station list
/////////////////////
/**
* Render all the APRS data.
*/
void
map_render_aprs()
{
printf("%s()\n", __PRETTY_FUNCTION__);
if(_poi_zoom > _zoom)
{
AprsDataRow *p_station = n_first;
while ( (p_station) != NULL)
{
if( p_station->coord_lat != 0.0f
|| p_station->coord_lon != 0.0f )
{
plot_aprs_station( p_station, FALSE);
} // If valid data
(p_station) = (p_station)->n_next; // Next element in list
} // End of while loop
} // check for zoom level
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
#endif // INCLUDE_APRS