/*
* Created by Rob Williams - 10 Aug 2008
*
* 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
#ifdef INCLUDE_APRS
#include "aprs_display.h"
#include "aprs_message.h"
#include "types.h"
#include "aprs.h"
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#ifndef LEGACY
# include
# include
# include
# include
# include
# include
#else
# include
# include
# include
# include
# include
# include
# include
#endif
#include "types.h"
#include "data.h"
#include "defines.h"
#include "gps.h"
#include "display.h"
#include "gdk-pixbuf-rotate.h"
#include "maps.h"
#include "marshal.h"
#include "poi.h"
#include "settings.h"
#include "util.h"
extern AprsDataRow *n_first;
typedef struct _AprsStationSelectInfo AprsStationSelectInfo;
struct _AprsStationSelectInfo
{
GtkWidget *dialog;
GtkWidget *tree_view;
gint column_index;
gchar *call_sign;
};
static AprsStationSelectInfo selected_station;
double convert_lat_l2d(long lat);
double convert_lon_l2d(long lon);
static gboolean panto_station(GtkWidget *widget, AprsStationSelectInfo *aprs_station_sel);
void convert_temp_f_to_c(gchar * f, gchar ** c)
{
*c = g_strdup(" ");
gdouble df = 0.0;
gdouble dc = 0.0;
// Convert fahrenheit to fahrenheit (double)
df = g_ascii_strtod ( f, (gchar*)(f + strlen(f)));
// Convert ff to fc
dc = 5*((df - 32.0)/9);
// Convert fc to celsius
snprintf(*c, 8, "%0.1f°C", dc);
}
void setup_aprs_basic_wx_display_page(GtkWidget *notebook, AprsDataRow *p_station)
{
GtkWidget *table;
GtkWidget *label;
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
table = gtk_table_new(4/*rows*/, 4/*columns*/, FALSE/*All cells same size*/),
label = gtk_label_new(_("WX")));
/* Last update */
gchar last_update_time[26];
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Updated:"),
0, 1, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
if(p_station->weather_data && p_station->weather_data->wx_sec_time)
{
strftime(last_update_time, 25, "%x %X", localtime(&p_station->weather_data->wx_sec_time));
}
else
{
snprintf(last_update_time, 25, " ");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( last_update_time ),
1, 4, 0, 1, GTK_EXPAND |GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
/* Temperature */
gchar * temp = NULL;
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Temp:"),
0, 1, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
if(p_station->weather_data && p_station->weather_data->wx_temp)
{
convert_temp_f_to_c(p_station->weather_data->wx_temp, &temp);
}
else
{
temp = g_strdup("");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( temp ),
1, 2, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
g_free(temp);
/////////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( (p_station->weather_data->wx_storm ? "SEVERE STORM" : "") ),
2, 4, 1, 2, GTK_EXPAND |GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.5f, 0.5f);
/////
gchar course[7];
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( "Wind course:" ),
0, 1, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
snprintf(course, 6, "%0.f°",
g_ascii_strtod (p_station->weather_data->wx_course, p_station->weather_data->wx_course + strlen(p_station->weather_data->wx_course))
);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( course ),
1, 2, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
// g_free(course);
/////
gchar speed[15];
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( "Wind speed:" ),
2, 3, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
snprintf(speed, 14, "%0.f->%0.f MPH",
g_ascii_strtod (p_station->weather_data->wx_speed, p_station->weather_data->wx_speed + strlen(p_station->weather_data->wx_speed)),
g_ascii_strtod (p_station->weather_data->wx_gust, p_station->weather_data->wx_gust + strlen(p_station->weather_data->wx_gust))
);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( speed ),
3, 4, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
/////
gchar rain_ph[17];
gchar rain_total[17];
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( "Rain fall:" ),
0, 1, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
if(p_station->weather_data->wx_rain)
{
snprintf(rain_ph, 16, "%0.f \"/hr",
g_ascii_strtod (p_station->weather_data->wx_rain, p_station->weather_data->wx_rain + strlen(p_station->weather_data->wx_rain))
);
}
else
{
snprintf(rain_ph, 1, " ");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( rain_ph ),
1, 2, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( "Total:" ),
2, 3, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
if(p_station->weather_data->wx_rain_total)
{
snprintf(rain_total, 16, "%0.f \"",
g_ascii_strtod (p_station->weather_data->wx_rain_total, p_station->weather_data->wx_rain_total + strlen(p_station->weather_data->wx_rain_total))
);
}
else
{
snprintf(rain_total, 1, " ");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( rain_total ),
3, 4, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
/*
char wx_hurricane_radius[4]; //nautical miles 3
char wx_trop_storm_radius[4]; //nautical miles 3
char wx_whole_gale_radius[4]; // nautical miles 3
char wx_snow[6]; // in inches/24h 3
char wx_prec_24[10]; // in hundredths inch/day 3
char wx_prec_00[10]; // in hundredths inch 3
char wx_hum[5]; // in % 3
char wx_baro[10]; // in hPa 6
char wx_fuel_temp[5]; // in °F 3
char wx_fuel_moisture[5];// in % 2
char wx_type;
char wx_station[MAX_WXSTATION];
*/
}
void setup_aprs_moving_display_page(GtkWidget *notebook, AprsDataRow *p_station)
{
GtkWidget *table;
GtkWidget *label;
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
table = gtk_table_new(4/*rows*/, 4/*columns*/, FALSE/*All cells same size*/),
label = gtk_label_new(_("Moving")));
////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Speed:"),
0, 1, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gchar speed[15];
// snprintf(speed, sizeof(speed), "%.01f %s", atof(p_station->speed) * UNITS_CONVERT[_units],
// UNITS_ENUM_TEXT[_units]);
if(_units == UNITS_NM)
snprintf(speed, sizeof(speed), "%.01f nmph", atof(p_station->speed));
else if(_units == UNITS_KM)
snprintf(speed, sizeof(speed), "%.01f kph", atof(p_station->speed)*1.852);
else if(_units == UNITS_MI)
snprintf(speed, sizeof(speed), "%.01f mph", atof(p_station->speed)*1.1508);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( speed ),
1, 2, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Course:"),
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(table),
label = gtk_label_new( p_station->course ),
1, 2, 1, 2, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Alt (m):"),
0, 1, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( p_station->altitude ),
1, 2, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Bearing:"),
0, 1, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( p_station->bearing ),
1, 2, 3, 4, GTK_FILL, 0, 2, 4);
/*
GdkPixmap *pixmap=gdk_pixmap_new(table->window,100,100,16);
//gdk_drawable_set_colormap (pixmap,gdk_colormap_get_system ());
GtkWidget *image = NULL;
GdkColor color;
GdkGC * gc;
gc = gdk_gc_new(pixmap);
color.red = 0;
color.green = 0;
color.blue = 0;
gdk_gc_set_foreground(gc, &color);
color.red = 255;
color.green = 255;
color.blue = 255;
gdk_gc_set_background(gc, &color);
gdk_gc_set_line_attributes(gc, _draw_width, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
gdk_draw_arc (
pixmap,
gc,
FALSE,
2, 2,
96, 96,
0, 360*64
);
gdouble heading = deg2rad(atof(p_station->course));
gint y = (gint)(48.0 * cosf(heading) );
gint x = (gint)(48.0 * sinf(heading) );
gdk_draw_line (
pixmap,
gc,
50, 50,
50+x, 50-y);
gtk_table_attach(GTK_TABLE(table),
image = gtk_image_new_from_pixmap(pixmap, NULL),
2, 3, 0, 4, GTK_FILL, 0, 2, 4);
//2, 3, 0, 4, GTK_SHRINK, GTK_SHRINK, 2, 4);
gtk_misc_set_alignment(GTK_MISC(image), 1.0f, 0.5f);
// g_object_unref(image);
// gdk_pixmap_unref(pixmap);
* */
}
void setup_aprs_station_stats_page(GtkWidget *notebook, AprsDataRow *p_station)
{
GtkWidget *table;
GtkWidget *label;
gchar distance[15];
gchar lat[15], lon[15];
gchar course_deg[9];
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
table = gtk_table_new(4/*rows*/, 5/*columns*/, FALSE/*All cells same size*/),
label = gtk_label_new(_("Location")));
////////////
course_deg[0] = '\0';
distance[0] = '\0';
lat[0] = '\0';
lon[0] = '\0';
if(p_station->coord_lat != 0 || p_station->coord_lon != 0)
{
gdouble d_lat = convert_lat_l2d(p_station->coord_lat);
gdouble d_lon = convert_lon_l2d(p_station->coord_lon);
format_lat_lon(d_lat, d_lon, lat, lon);
gfloat dist = (float)calculate_distance(_gps.lat, _gps.lon, d_lat, d_lon);
snprintf(distance, sizeof(distance), "%.01f %s", dist * UNITS_CONVERT[_units], UNITS_ENUM_TEXT[_units]);
snprintf(course_deg, sizeof(course_deg),
"%.01f°",
calculate_bearing(_gps.lat, _gps.lon, d_lat, d_lon));
}
/* Last heard */
gchar last_update_time[26];
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Last Heard:"),
0, 1, 4, 5, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
if(p_station->sec_heard)
{
strftime(last_update_time, 25, "%x %X", localtime(&p_station->sec_heard));
}
else
{
snprintf(last_update_time, 25, " ");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( last_update_time ),
1, 4, 4, 5, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Location:"),
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(table),
label = gtk_label_new( lat ),
1, 3, 1, 2, GTK_EXPAND |GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( lon ),
3, 5, 1, 2, GTK_EXPAND |GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(""),
0, 5, 2, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
////////////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Distance:"),
0, 1, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( distance ),
1, 2, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
//
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Bearing:"),
2, 4, 3, 4, GTK_EXPAND |GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( course_deg ),
4, 5, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
////////////
}
void setup_aprs_basic_display_page(GtkWidget *notebook, AprsDataRow *p_station)
{
GtkWidget *table;
GtkWidget *label;
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
table = gtk_table_new(5/*rows*/, 5/*columns*/, FALSE/*All cells same size*/),
label = gtk_label_new(_("Basic")));
/* Callsign. */
// Label
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Callsign:"),
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),
label = gtk_label_new( p_station->call_sign ),
1, 2, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
GdkPixbuf *pixbuf = NULL;
gint symbol_column = 0;
gint symbol_row = 0;
gint symbol_size = 0;
extract_aprs_symbol(p_station->aprs_symbol.aprs_symbol, p_station->aprs_symbol.aprs_type, &pixbuf,
&symbol_size,
&symbol_column,
&symbol_row);
GdkPixmap *pixmap=gdk_pixmap_new(table->window,symbol_size,symbol_size,16);
// We found an icon to draw.
gdk_draw_pixbuf(
pixmap,
_gc[COLORABLE_POI],
pixbuf,
symbol_size*symbol_column, symbol_size*symbol_row,
0,
0,
symbol_size, symbol_size,
GDK_RGB_DITHER_NONE, 0, 0);
g_object_unref(pixbuf);
GtkWidget *image;
gtk_table_attach(GTK_TABLE(table),
image = gtk_image_new_from_pixmap(pixmap, NULL),
2, 3, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Packets:"),
3, 4, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f);
gchar packets[5];
snprintf(packets, 4, "%u", p_station->num_packets);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new( packets ),
4, 5, 0, 1, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f);
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Comment:"),
0, 1, 1, 3, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label ), 1.f, 0.5f);
gchar * comment = NULL;
if(p_station->comment_data && p_station->comment_data->text_ptr)
{
comment = g_strdup(p_station->comment_data->text_ptr);
}
else
{
comment = g_strdup("");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(comment),
1, 5, 1, 3, GTK_EXPAND |GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label ), 0.f, 0.5f);
gtk_label_set_width_chars(label, 30);
////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Status:"),
0, 1, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label ), 1.f, 0.5f);
gchar * status = NULL;
if(p_station->status_data && p_station->status_data->text_ptr)
{
status = g_strdup(p_station->status_data->text_ptr);
}
else
{
status = g_strdup("");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(status),
1, 5, 3, 4, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label ), 0.f, 0.5f);
////
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new("Path:"),
0, 1, 4, 5, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label ), 1.f, 0.5f);
gchar * path = NULL;
if(p_station->node_path_ptr)
{
path = g_strdup(p_station->node_path_ptr);
}
else
{
path = g_strdup("");
}
gtk_table_attach(GTK_TABLE(table),
label = gtk_label_new(path),
1, 5, 4, 5, GTK_FILL, 0, 2, 4);
gtk_misc_set_alignment(GTK_MISC(label ), 0.f, 0.5f);
}
void ShowAprsStationPopup(AprsDataRow *p_station)
{
GtkWidget *dialog = NULL;
GtkWidget *notebook = NULL;
GtkWidget *btn_panto = NULL;
dialog = gtk_dialog_new_with_buttons(_("Station Details"),
GTK_WINDOW(_window), GTK_DIALOG_MODAL,
GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT,
// "Send Message...", GTK_RESPONSE_ACCEPT,
NULL);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
btn_panto = gtk_button_new_with_mnemonic(_("C_entre Map...")));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
notebook = gtk_notebook_new(), TRUE, TRUE, 0);
selected_station.dialog = NULL;
selected_station.tree_view = NULL;
selected_station.column_index = 0;
selected_station.call_sign = p_station->call_sign;
g_signal_connect(G_OBJECT(btn_panto), "clicked",
G_CALLBACK(panto_station), &selected_station);
setup_aprs_basic_display_page(notebook, p_station);
if(p_station->weather_data )
setup_aprs_basic_wx_display_page(notebook, p_station);
if( ( p_station->flag & ST_MOVING) == ST_MOVING){
setup_aprs_moving_display_page(notebook, p_station);
}
setup_aprs_station_stats_page(notebook, p_station);
gtk_widget_show_all(dialog);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_hide(dialog);
}
void list_stations()
{
static GtkWidget *dialog = NULL;
static GtkWidget *list = NULL;
static GtkWidget *sw = NULL;
static GtkWidget *btn_panto = NULL;
static GtkTreeViewColumn *column = NULL;
static GtkCellRenderer *renderer = NULL;
GtkListStore *store = NULL;
GtkTreeIter iter;
gint station_count = 0;
gint num_cats = 0;
printf("%s()\n", __PRETTY_FUNCTION__);
typedef enum
{
STATION_CALLSIGN,
STATION_DISTANCE,
STATION_BEARING,
STATION_COMMENT,
STATION_DISTANCE_NUM,
STATION_NUM_COLUMNS
} StationList;
/* Initialize store. */
store = gtk_list_store_new(STATION_NUM_COLUMNS,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_DOUBLE);/* Category Label */
AprsDataRow *p_station = n_first;
while ( (p_station) != NULL)
{
station_count++;
gchar * comment = NULL;
gchar * callsign = g_strdup(p_station->call_sign);
gchar course_deg[8];
gchar * formatted_distance = NULL;
gdouble distance = 0;
course_deg[0] = '\0';
if(p_station->coord_lat != 0 && p_station->coord_lon != 0)
{
distance = distance_from_my_station(callsign, course_deg, sizeof(course_deg));
if(_units == UNITS_KM)
formatted_distance = g_strdup_printf("%.01f km", distance);
else if(_units == UNITS_MI)
formatted_distance = g_strdup_printf("%.01f miles", distance);
else if(_units == UNITS_NM)
formatted_distance = g_strdup_printf("%.01f nm", distance);
}
else
{
formatted_distance = g_strdup_printf("");
}
if(p_station->comment_data) comment = g_strdup(p_station->comment_data->text_ptr);
else comment = g_strdup("");
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
STATION_CALLSIGN, callsign,
STATION_DISTANCE, formatted_distance,
STATION_BEARING, course_deg,
STATION_COMMENT, comment,
STATION_DISTANCE_NUM, distance,
-1);
num_cats++;
g_free(comment);
g_free(callsign);
g_free(formatted_distance);
(p_station) = (p_station)->n_next; // Next element in list
} // End of while loop
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), STATION_DISTANCE_NUM, GTK_SORT_ASCENDING);
if(dialog == NULL)
{
dialog = gtk_dialog_new_with_buttons(_("Stations"),
GTK_WINDOW(_window), GTK_DIALOG_MODAL,
"Details", GTK_RESPONSE_ACCEPT,
GTK_STOCK_CLOSE, GTK_RESPONSE_REJECT,
NULL);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
btn_panto = gtk_button_new_with_mnemonic(_("C_entre Map...")));
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(
_("Callsign"), renderer, "text", STATION_CALLSIGN, 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(
_("Distance"), renderer, "text", STATION_DISTANCE, 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(
_("Bearing"), renderer, "text", STATION_BEARING, 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(
_("Comment"), renderer, "text", STATION_COMMENT, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(list), column);
}
selected_station.dialog = dialog;
selected_station.tree_view = list;
selected_station.call_sign = NULL;
selected_station.column_index = STATION_CALLSIGN;
g_signal_connect(G_OBJECT(btn_panto), "clicked",
G_CALLBACK(panto_station), &selected_station);
gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
//
gchar *title = g_strdup_printf("Stations (Total: %u)", station_count);
gtk_window_set_title(GTK_WINDOW(dialog), title);
g_free(title);
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))
{
gchar * callsign = NULL;
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
STATION_CALLSIGN, &(callsign),
-1);
// Find the callsign
p_station = n_first;
while(p_station != NULL)
{
if(strcmp(p_station->call_sign,callsign) == 0)
{
ShowAprsStationPopup(p_station);
break;
}
p_station = p_station->n_next;
}
}
// Setup event again
selected_station.dialog = dialog;
selected_station.tree_view = list;
selected_station.call_sign = NULL;
selected_station.column_index = STATION_CALLSIGN;
g_signal_connect(G_OBJECT(btn_panto), "clicked",
G_CALLBACK(panto_station), &selected_station);
}
gtk_widget_hide(dialog);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
static gboolean
send_message(GtkWidget *widget)
{
fprintf(stderr, "Send message...");
return FALSE;
}
static gboolean
panto_station(GtkWidget *widget, AprsStationSelectInfo *aprs_station_selected)
{
GtkTreeModel *store;
GtkTreeIter iter;
GtkTreeSelection *selection;
gchar * callsign = NULL;
AprsDataRow *p_station = n_first;
printf("%s()\n", __PRETTY_FUNCTION__);
if(aprs_station_selected->call_sign != NULL)
callsign = aprs_station_selected->call_sign;
else
{
store = gtk_tree_view_get_model(GTK_TREE_VIEW(aprs_station_selected->tree_view));
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(aprs_station_selected->tree_view));
if(gtk_tree_selection_get_selected(selection, &store, &iter))
{
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
aprs_station_selected->column_index, &(callsign),
-1);
}
}
// Now findout the location of callsign
p_station = n_first;
while(p_station != NULL)
{
if(strcmp(p_station->call_sign,callsign) == 0)
{
if(p_station->coord_lat == 0 && p_station->coord_lon == 0)
{
// Invalid position
}
else
{
gdouble d_lat = convert_lat_l2d(p_station->coord_lat);
gdouble d_lon = convert_lon_l2d(p_station->coord_lon);
Point unit;
latlon2unit(d_lat, d_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);
}
break;
}
p_station = p_station->n_next;
}
vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
return TRUE;
}
void list_messages()
{
static GtkWidget *dialog = NULL;
// static GtkWidget *btn_send = NULL;
static GtkWidget *list = NULL;
static GtkWidget *sw = NULL;
static GtkTreeViewColumn *column = NULL;
static GtkCellRenderer *renderer = NULL;
GtkListStore *store = NULL;
GtkTreeIter iter;
printf("%s()\n", __PRETTY_FUNCTION__);
typedef enum
{
MSG_FROM,
MSG_TO,
MSG_TEXT,
MSG_TIMESTAMP,
MSG_NUM_COLUMNS
} MessageList;
/* Initialize store. */
store = gtk_list_store_new(MSG_NUM_COLUMNS,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_DOUBLE);
// Loop through each message
gint i = 0;
for (i = 0; i < msg_index_end; i++)
{
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
MSG_FROM, msg_data[msg_index[i]].from_call_sign,
MSG_TO, msg_data[msg_index[i]].call_sign,
MSG_TEXT, msg_data[msg_index[i]].message_line,
MSG_TIMESTAMP, (gdouble)msg_data[msg_index[i]].sec_heard,
-1);
}
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store), MSG_TIMESTAMP, GTK_SORT_ASCENDING);
if(dialog == NULL)
{
dialog = gtk_dialog_new_with_buttons(_("Messages"),
GTK_WINDOW(_window), GTK_DIALOG_MODAL,
GTK_STOCK_CLOSE, GTK_RESPONSE_REJECT,
NULL);
gtk_window_set_default_size(GTK_WINDOW(dialog), 550, 300);
// gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
// btn_send = gtk_button_new_with_label(_("Send...")));
// g_signal_connect(G_OBJECT(btn_send), "clicked",
// G_CALLBACK(send_message), dialog);
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(
_("From"), renderer, "text", MSG_FROM, 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(
_("To"), renderer, "text", MSG_TO, 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(
_("Message"), renderer, "text", MSG_TEXT, 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)))
{
}
gtk_widget_hide(dialog);
vprintf("%s(): return\n", __PRETTY_FUNCTION__);
}
#endif //INCLUDE_APRS