gpredict/src/qth-editor.c
2009-08-05 08:53:47 +00:00

817 lines
23 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/*
Gpredict: Real-time satellite tracking and orbit prediction program
Copyright (C) 2001-2008 Alexandru Csete, OZ9AEC.
Authors: Alexandru Csete <oz9aec@gmail.com>
Comments, questions and bugreports should be submitted via
http://sourceforge.net/projects/gpredict/
More details can be found at the project home page:
http://gpredict.oz9aec.net/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, visit http://www.fsf.org/
*/
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <math.h>
#ifdef HAVE_CONFIG_H
# include <build-config.h>
#endif
#include "gpredict-utils.h"
#include "loc-tree.h"
#include "sat-cfg.h"
#include "sat-log.h"
#include "locator.h"
#include "gtk-sat-data.h"
#include "qth-editor.h"
/** \brief Symbolic refs to be used when calling select_location in order
* to determine which mode the selection should run in, ie.
* select location or select weather station.
*/
enum {
SELECTION_MODE_LOC = 1,
SELECTION_MODE_WX = 2
};
extern GtkWidget *window; /* dialog window defined in sat-pref.c */
static GtkWidget *create_editor_widgets (qth_t *qth);
static void update_widgets (qth_t *qth);
static void clear_widgets (void);
static void name_changed (GtkWidget *widget, gpointer data);
static void select_location (GtkWidget *widget, gpointer data);
static gboolean apply_changes (qth_t *qth);
static void latlon_changed (GtkWidget *widget, gpointer data);
static void qra_changed (GtkEntry *entry, gpointer data);
/* private widgets */
static GtkWidget *dialog; /* dialog window */
static GtkWidget *name; /* QTH name */
static GtkWidget *location; /* QTH location */
static GtkWidget *desc; /* QTH description */
static GtkWidget *lat,*lon,*alt; /* LAT, LON and ALT */
static GtkWidget *ns,*ew;
static GtkWidget *qra; /* QRA locator */
static gulong latsigid,lonsigid,nssigid,ewsigid,qrasigid;
static GtkWidget *wx; /* weather station */
/** \brief Create and run QTH editor.
* \param qth Pointer to a qth_t structure where QTH data should be stored.
* \param parent The parent dialog window.
* \return GTK_RESPONSE_OK if the new QTH has been saved, GTK_RESPONSE_CANCEL
* otherwise (e.g. user cancelled the operation.
*
* The QTH editor is a dialog window containing widgets that can be used to
* edit an existing QTH or create a new one. If qth->name != NULL the function
* will run in edit mode, i.e. preload the widgets with values from qth, otherwise
* it will create empty widgets.
*
* To see the widget in action click on the "+" button in either the "New Module"
* or "Configure Module" dialog.
*
* \bug Edit mode doesn't really works, that is, it does, but probably leaks memory
* because I can't free existing data in qth_t
*/
GtkResponseType qth_editor_run (qth_t *qth, GtkWindow *parent)
{
gint response;
gboolean finished = FALSE;
/* crate dialog and add contents */
dialog = gtk_dialog_new_with_buttons (_("Edit ground station data"),
parent,
GTK_DIALOG_MODAL |
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_CLEAR,
GTK_RESPONSE_REJECT,
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL,
GTK_STOCK_OK,
GTK_RESPONSE_OK,
NULL);
/* disable OK button to begin with */
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
FALSE);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
create_editor_widgets (qth));
/* this hacky-thing is to keep the dialog running in case the
CLEAR button is plressed. OK and CANCEL will exit the loop
*/
while (!finished) {
response = gtk_dialog_run (GTK_DIALOG (dialog));
switch (response) {
/* OK */
case GTK_RESPONSE_OK:
if (apply_changes (qth)) {
finished = TRUE;
}
else {
/* and error occured; try again */
GtkWidget *errd;
errd = gtk_message_dialog_new (parent,
GTK_DIALOG_MODAL |
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
_("An error occurred while trying to save\n"\
"ground station data to %s.qth!\n"\
"Please try again using a different name."),
qth->name);
gtk_dialog_run (GTK_DIALOG (errd));
gtk_widget_destroy (errd);
finished = FALSE;
}
break;
/* CLEAR */
case GTK_RESPONSE_REJECT:
clear_widgets ();
break;
/* Everything else is considered CANCEL */
default:
finished = TRUE;
break;
}
}
gtk_widget_destroy (dialog);
return response;
}
/** \brief Create and initialise widgets */
static GtkWidget *
create_editor_widgets (qth_t *qth)
{
GtkWidget *table;
GtkWidget *label;
GtkTooltips *tooltips;
GtkWidget *locbut;
GtkWidget *wxbut;
table = gtk_table_new (9, 4, FALSE);
gtk_container_set_border_width (GTK_CONTAINER (table), 5);
gtk_table_set_col_spacings (GTK_TABLE (table), 5);
gtk_table_set_row_spacings (GTK_TABLE (table), 5);
/* QTH name */
label = gtk_label_new (_("Name"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
name = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (name), 25);
tooltips = gtk_tooltips_new ();
gtk_tooltips_set_tip (tooltips, name,
_("Enter a short name for this ground station, e.g. callsign.\n"\
"Allowed characters: 0..9, a..z, A..Z, - and _"),
_("The name will be used to identify the ground station "\
"when it is presented to the user. Maximum allowed length "\
"is 25 characters."));
gtk_table_attach_defaults (GTK_TABLE (table), name, 1, 4, 0, 1);
/* attach changed signal so that we can enable OK button when
a proper name has been entered
*/
g_signal_connect (name, "changed", G_CALLBACK (name_changed), NULL);
/* QTH description */
label = gtk_label_new (_("Description"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
desc = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (desc), 256);
tooltips = gtk_tooltips_new ();
gtk_tooltips_set_tip (tooltips, desc,
_("Enter an optional description for this ground station."),
_("The description for the ground station can be used as additional "\
"information. It may be included when generating reports. "\
"The maximum length for the description is 256 characters."));
gtk_table_attach_defaults (GTK_TABLE (table), desc, 1, 4, 1, 2);
/* location */
label = gtk_label_new (_("Location"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
location = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (location), 50);
tooltips = gtk_tooltips_new ();
gtk_tooltips_set_tip (tooltips, location,
_("Optional location of the ground station, fx. Copenhagen, Denmark."),
NULL);
gtk_table_attach_defaults (GTK_TABLE (table), location, 1, 3, 2, 3);
locbut = gpredict_hstock_button (GTK_STOCK_INDEX, _("Select"),
_("Select a predefined location from a list."));
g_signal_connect (locbut, "clicked",
G_CALLBACK (select_location),
GUINT_TO_POINTER (SELECTION_MODE_LOC));
gtk_table_attach_defaults (GTK_TABLE (table), locbut, 3, 4, 2, 3);
/* latitude */
label = gtk_label_new (_("Latitude (\302\260)"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4);
lat = gtk_spin_button_new_with_range (0.00, 90.00, 0.0001);
gtk_spin_button_set_increments (GTK_SPIN_BUTTON (lat), 0.01, 1.0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (lat), TRUE);
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (lat), 4);
tooltips = gtk_tooltips_new ();
gtk_tooltips_set_tip (tooltips, lat,
_("Select the latitude of the ground station in decimal degrees."),
NULL);
gtk_table_attach_defaults (GTK_TABLE (table), lat, 1, 2, 3, 4);
ns = gtk_combo_box_new_text ();
gtk_combo_box_append_text (GTK_COMBO_BOX (ns), _("North"));
gtk_combo_box_append_text (GTK_COMBO_BOX (ns), _("South"));
gtk_combo_box_set_active (GTK_COMBO_BOX (ns), 0);
/*** FIXME tooltips */
gtk_table_attach_defaults (GTK_TABLE (table), ns, 2, 3, 3, 4);
/* longitude */
label = gtk_label_new (_("Longitude (\302\260)"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 4, 5);
lon = gtk_spin_button_new_with_range (0.00, 180.00, 0.0001);
gtk_spin_button_set_increments (GTK_SPIN_BUTTON (lon), 0.01, 1.0);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (lon), TRUE);
gtk_spin_button_set_digits (GTK_SPIN_BUTTON (lon), 4);
gtk_tooltips_set_tip (tooltips, lon,
_("Select the longitude of the ground station in decimal degrees."),
NULL);
gtk_table_attach_defaults (GTK_TABLE (table), lon, 1, 2, 4, 5);
ew = gtk_combo_box_new_text ();
gtk_combo_box_append_text (GTK_COMBO_BOX (ew), _("East"));
gtk_combo_box_append_text (GTK_COMBO_BOX (ew), _("West"));
gtk_combo_box_set_active (GTK_COMBO_BOX (ew), 0);
/*** FIXME tooltips */
gtk_table_attach_defaults (GTK_TABLE (table), ew, 2, 3, 4, 5);
/* connect lat/lon spinners and combos to callback
remember signal id so that we can block signals
while doing automatic cross-updates
*/
latsigid = g_signal_connect (lat, "value-changed",
G_CALLBACK (latlon_changed),
NULL);
lonsigid = g_signal_connect (lon, "value-changed",
G_CALLBACK (latlon_changed),
NULL);
nssigid = g_signal_connect (ns, "changed",
G_CALLBACK (latlon_changed),
NULL);
ewsigid = g_signal_connect (ew, "changed",
G_CALLBACK (latlon_changed),
NULL);
/* QRA locator */
label = gtk_label_new (_("Locator"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
qra = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (qra), 6);
tooltips = gtk_tooltips_new ();
gtk_tooltips_set_tip (tooltips, qra,
_("Maidenhead locator grid."),
NULL);
gtk_table_attach_defaults (GTK_TABLE (table), qra, 1, 2, 5, 6);
qrasigid = g_signal_connect (qra, "changed",
G_CALLBACK (qra_changed),
NULL);
/* altitude */
label = gtk_label_new (_("Altitude"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 6, 7);
alt = gtk_spin_button_new_with_range (0, 5000, 1);
gtk_spin_button_set_increments (GTK_SPIN_BUTTON (alt), 1, 100);
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (alt), TRUE);
gtk_tooltips_set_tip (tooltips, alt,
_("Select the altitude of the ground station in meters or feet "\
"depending on your settings"),
NULL);
gtk_table_attach_defaults (GTK_TABLE (table), alt, 1, 2, 6, 7);
if (sat_cfg_get_bool (SAT_CFG_BOOL_USE_IMPERIAL)) {
label = gtk_label_new (_("ft asl"));
}
else {
label = gtk_label_new (_("m asl"));
}
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 2, 3, 6, 7);
/* weather station */
label = gtk_label_new (_("Weather St"));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 7, 8);
wx = gtk_entry_new ();
gtk_entry_set_max_length (GTK_ENTRY (wx), 4);
tooltips = gtk_tooltips_new ();
gtk_tooltips_set_tip (tooltips, wx,
_("Four letter code for weather station"),
NULL);
gtk_table_attach_defaults (GTK_TABLE (table), wx, 1, 3, 7, 8);
wxbut = gpredict_hstock_button (GTK_STOCK_INDEX, _("Select"),
_("Select a predefined weather station from a list."));
g_signal_connect (wxbut, "clicked",
G_CALLBACK (select_location),
GUINT_TO_POINTER (SELECTION_MODE_WX));
gtk_table_attach_defaults (GTK_TABLE (table), wxbut, 3, 4, 7, 8);
if (qth->name != NULL)
update_widgets (qth);
gtk_widget_show_all (table);
return table;
}
/** \brief Update widgets from the currently selected row in the treeview
*/
static void
update_widgets (qth_t *qth)
{
if (qth->name != NULL)
gtk_entry_set_text (GTK_ENTRY (name), qth->name);
if (qth->loc != NULL) {
gtk_entry_set_text (GTK_ENTRY (location), qth->loc);
}
if (qth->desc != NULL) {
gtk_entry_set_text (GTK_ENTRY (desc), qth->desc);
}
if (qth->wx != NULL) {
gtk_entry_set_text (GTK_ENTRY (wx), qth->wx);
}
if (qth->lat < 0.00)
gtk_combo_box_set_active (GTK_COMBO_BOX (ns), 1);
else
gtk_combo_box_set_active (GTK_COMBO_BOX (ns), 0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lat), fabs (qth->lat));
if (qth->lon < 0.00)
gtk_combo_box_set_active (GTK_COMBO_BOX (ew), 1);
else
gtk_combo_box_set_active (GTK_COMBO_BOX (ew), 0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lon), fabs (qth->lon));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (alt), qth->alt);
sat_log_log (SAT_LOG_LEVEL_DEBUG,
_("%s:%d: Loaded %s for editing:\n"\
"LAT:%.2f LON:%.2f ALT:%d"),
__FILE__, __LINE__,
(qth->name != NULL) ? qth->name : "???",
qth->lat, qth->lon, qth->alt);
}
/** \brief Clear the contents of all widgets.
*
* This function is usually called when the user clicks on the CLEAR button
*
*/
static void
clear_widgets ()
{
gtk_entry_set_text (GTK_ENTRY (name), "");
gtk_entry_set_text (GTK_ENTRY (location), "");
gtk_entry_set_text (GTK_ENTRY (desc), "");
gtk_entry_set_text (GTK_ENTRY (wx), "");
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lat), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lon), 0.0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (alt), 0);
gtk_entry_set_text (GTK_ENTRY (qra), "");
}
/** \brief Apply changes.
* \return TRUE if things are ok, FALSE otherwise.
*
* This function is usually called when the user clicks the OK button.
*/
static gboolean
apply_changes (qth_t *qth)
{
const gchar *qthname = NULL;
const gchar *qthloc = NULL;
const gchar *qthdesc = NULL;
const gchar *qthwx = NULL;
const gchar *qthqra= NULL;
gdouble qthlat;
gdouble qthlon;
guint qthalt;
gchar *fname;
gboolean retcode;
/* get values from widgets */
qthname = gtk_entry_get_text (GTK_ENTRY (name));
qthloc = gtk_entry_get_text (GTK_ENTRY (location));
qthdesc = gtk_entry_get_text (GTK_ENTRY (desc));
qthwx = gtk_entry_get_text (GTK_ENTRY (wx));
qthlat = gtk_spin_button_get_value (GTK_SPIN_BUTTON (lat));
if (gtk_combo_box_get_active (GTK_COMBO_BOX (ns)))
qthlat = -qthlat;
qthlon = gtk_spin_button_get_value (GTK_SPIN_BUTTON (lon));
if (gtk_combo_box_get_active (GTK_COMBO_BOX (ew)))
qthlon = -qthlon;
qthalt = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (alt));
qthqra = gtk_entry_get_text (GTK_ENTRY (qra));
/* clear qth struct if not empty */
/* if (qth->name != NULL) */
/* g_free (qth->name); */
/* if (qth->loc != NULL) */
/* g_free (qth->loc); */
/* if (qth->desc != NULL) */
/* g_free (qth->desc); */
/* if (qth->wx != NULL) */
/* g_free (qth->wx); */
/* if (qth->qra != NULL) */
/* g_free (qth->qra); */
/* if (qth->data != NULL) */
/* g_key_file_free (qth->data); */
/* copy new values to qth struct */
qth->name = g_strdup (qthname);
if (qthloc != NULL)
qth->loc = g_strdup (qthloc);
if (qthdesc != NULL)
qth->desc = g_strdup (qthdesc);
if (qthwx != NULL)
qth->wx = g_strdup (qthwx);
if (qthqra != NULL)
qth->qra = g_strdup (qthqra);
qth->lat = qthlat;
qth->lon = qthlon;
qth->alt = qthalt;
/* store values to disc */
fname = g_strconcat (g_get_home_dir (),
G_DIR_SEPARATOR_S,
".gpredict2",
G_DIR_SEPARATOR_S,
qth->name,
".qth",
NULL);
retcode = qth_data_save (fname, qth);
g_free (fname);
return retcode;
}
/** \brief Manage name changes.
*
* This function is called when the contents of the name entry changes.
* The primary purpose of this function is to check whether the char length
* of the name is greater than zero, if yes enable the OK button of the dialog.
*/
static void
name_changed (GtkWidget *widget, gpointer data)
{
const gchar *text;
gchar *entry, *end, *j;
gint len, pos;
/* step 1: ensure that only valid characters are entered
(stolen from xlog, tnx pg4i)
*/
entry = gtk_editable_get_chars (GTK_EDITABLE (widget), 0, -1);
if ((len = g_utf8_strlen (entry, -1)) > 0)
{
end = entry + g_utf8_strlen (entry, -1);
for (j = entry; j < end; ++j)
{
switch (*j)
{
case '0' ... '9':
case 'a' ... 'z':
case 'A' ... 'Z':
case '-':
case '_':
break;
default:
gdk_beep ();
pos = gtk_editable_get_position (GTK_EDITABLE (widget));
gtk_editable_delete_text (GTK_EDITABLE (widget),
pos, pos+1);
break;
}
}
}
/* step 2: if name seems all right, enable OK button */
text = gtk_entry_get_text (GTK_ENTRY (widget));
if (g_utf8_strlen (text, -1) > 0) {
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
TRUE);
}
else {
gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
FALSE);
}
}
/** \brief Manage SELECT button clicks.
*
* This function is called when the user clicks on one of the SELECT buttons.
* the data parameter contains information about which button has been clicked.
*/
static void
select_location (GtkWidget *widget, gpointer data)
{
guint mode = GPOINTER_TO_UINT (data);
guint flags;
gchar *qthloc;
gchar *qthwx;
gfloat qthlat;
gfloat qthlon;
guint qthalt;
gboolean selected = FALSE;
switch (mode) {
/* We distinguish only between WX mode and "everything else".
Although a value != 1 or 2 is definitely a bug, we need to
have some sensible fall-back.
*/
case SELECTION_MODE_WX:
flags = TREE_COL_FLAG_NAME | TREE_COL_FLAG_WX;
break;
default:
flags = TREE_COL_FLAG_NAME |
TREE_COL_FLAG_LAT |
TREE_COL_FLAG_LON |
TREE_COL_FLAG_ALT |
TREE_COL_FLAG_WX;
mode = SELECTION_MODE_LOC;
break;
}
selected = loc_tree_create (NULL, flags, &qthloc, &qthlat, &qthlon, &qthalt, &qthwx);
if (selected) {
/* update widgets */
switch (mode) {
case SELECTION_MODE_WX:
gtk_entry_set_text (GTK_ENTRY (wx), qthwx);
break;
case SELECTION_MODE_LOC:
gtk_entry_set_text (GTK_ENTRY (location), qthloc);
gtk_entry_set_text (GTK_ENTRY (wx), qthwx);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lat), fabs (qthlat));
if (qthlat < 0.00)
gtk_combo_box_set_active (GTK_COMBO_BOX (ns), 1);
else
gtk_combo_box_set_active (GTK_COMBO_BOX (ns), 0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lon), fabs (qthlon));
if (qthlon < 0.00)
gtk_combo_box_set_active (GTK_COMBO_BOX (ew), 1);
else
gtk_combo_box_set_active (GTK_COMBO_BOX (ew), 0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (alt), qthalt);
break;
default:
/*** FIXME: add some error reporting */
break;
}
/* free some memory */
g_free (qthloc);
g_free (qthwx);
}
/* else do nothing; we are finished */
}
/** \brief Manage coordinate changes.
*
* This function is called when the qth coordinates change. The change can
* be either one of the spin buttons or the combo boxes. It reads the
* coordinates and the calculates the new Maidenhead locator square.
*/
static void
latlon_changed (GtkWidget *widget, gpointer data)
{
gchar *locator;
gint retcode;
gdouble latf,lonf;
locator = g_try_malloc (7);
/* no need to check locator != NULL, since hamlib func will do it for us
and return RIGEINVAL
*/
lonf = gtk_spin_button_get_value (GTK_SPIN_BUTTON (lon));
latf = gtk_spin_button_get_value (GTK_SPIN_BUTTON (lat));
/* set the correct sign */
if (gtk_combo_box_get_active (GTK_COMBO_BOX (ns))) {
/* index 1 => South */
latf = -latf;
}
if (gtk_combo_box_get_active (GTK_COMBO_BOX (ew))) {
/* index 1 => Wesr */
lonf = -lonf;
}
retcode = longlat2locator (lonf, latf, locator, 3);
if (retcode == RIG_OK) {
/* debug message */
sat_log_log (SAT_LOG_LEVEL_DEBUG,
_("%s:%s: %.2f %.2f => %s"),
__FILE__, __FUNCTION__,
gtk_spin_button_get_value (GTK_SPIN_BUTTON (lon)),
gtk_spin_button_get_value (GTK_SPIN_BUTTON (lat)),
locator);
g_signal_handler_block (qra, qrasigid);
gtk_entry_set_text (GTK_ENTRY (qra), locator);
g_signal_handler_unblock (qra, qrasigid);
}
else {
/* send an error message and don't update */
sat_log_log (SAT_LOG_LEVEL_ERROR,
_("%s:%d: Error converting lon/lat to locator"),
__FILE__, __LINE__);
}
if (locator)
g_free (locator);
}
/** \brief Manage locator changes.
*
* This function is called when the Maidenhead locator is changed.
* It will calculate the new coordinates and update the spin butrtons and
* the combo boxes.
*/
static void
qra_changed (GtkEntry *entry, gpointer data)
{
gint retcode;
gdouble latf,lonf;
gchar *msg;
retcode = locator2longlat (&lonf, &latf, gtk_entry_get_text (GTK_ENTRY (qra)));
if (retcode == RIG_OK) {
/* debug message */
sat_log_log (SAT_LOG_LEVEL_DEBUG,
_("%s:%s: %s => %.2f %.2f"),
__FILE__, __FUNCTION__,
gtk_entry_get_text (GTK_ENTRY (qra)),
lonf, latf);
/* block signal emissions for lat/lon widgets */
g_signal_handler_block (lat, latsigid);
g_signal_handler_block (lon, lonsigid);
g_signal_handler_block (ns, nssigid);
g_signal_handler_block (ew, ewsigid);
g_signal_handler_block (qra, qrasigid);
/* update widgets */
if (latf < 0.00)
gtk_combo_box_set_active (GTK_COMBO_BOX (ns), 1);
else
gtk_combo_box_set_active (GTK_COMBO_BOX (ns), 0);
if (lonf < 0.00)
gtk_combo_box_set_active (GTK_COMBO_BOX (ew), 1);
else
gtk_combo_box_set_active (GTK_COMBO_BOX (ew), 0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lat), fabs (latf));
gtk_spin_button_set_value (GTK_SPIN_BUTTON (lon), fabs (lonf));
/* make sure text is upper case */
msg = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (qra)), -1);
gtk_entry_set_text (GTK_ENTRY (qra), msg);
g_free (msg);
/* unblock signal emissions */
g_signal_handler_unblock (lat, latsigid);
g_signal_handler_unblock (lon, lonsigid);
g_signal_handler_unblock (ns, nssigid);
g_signal_handler_unblock (ew, ewsigid);
g_signal_handler_unblock (qra, qrasigid);
}
else {
/* send an error message and don't update */
sat_log_log (SAT_LOG_LEVEL_ERROR,
_("%s:%d: Invalid locator: %s"),
__FILE__, __LINE__,
gtk_entry_get_text (GTK_ENTRY (qra)));
}
}