[Gpredict-svn] SF.net SVN: gpredict: [21] trunk/src
Real time satellite tracking and orbit prediction
Status: Beta
Brought to you by:
csete
From: <cs...@us...> - 2008-01-24 22:58:38
|
Revision: 21 http://gpredict.svn.sourceforge.net/gpredict/?rev=21&view=rev Author: csete Date: 2008-01-24 14:58:40 -0800 (Thu, 24 Jan 2008) Log Message: ----------- Added files. Added Paths: ----------- trunk/src/sat-pref-rot-editor.c trunk/src/sat-pref-rot-editor.h Added: trunk/src/sat-pref-rot-editor.c =================================================================== --- trunk/src/sat-pref-rot-editor.c (rev 0) +++ trunk/src/sat-pref-rot-editor.c 2008-01-24 22:58:40 UTC (rev 21) @@ -0,0 +1,822 @@ +/* -*- 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-2007 Alexandru Csete, OZ9AEC. + + Authors: Alexandru Csete <oz...@gm...> + + Comments, questions and bugreports should be submitted via + http://sourceforge.net/projects/groundstation/ + More details can be found at the project home page: + + http://groundstation.sourceforge.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/ +*/ + +/** \brief Edit radio configuration. + * + */ + +#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 "sat-cfg.h" +#include "sat-log.h" +#include "radio-conf.h" +#include "sat-pref-rig-editor.h" + +#ifdef HAVE_HAMLIB +# include <hamlib/rig.h> + + +extern GtkWidget *window; /* dialog window defined in sat-pref.c */ + + + +/* private widgets */ +static GtkWidget *dialog; /* dialog window */ +static GtkWidget *name; /* Configuration name */ +static GtkWidget *model; /* radio model, e.g. TS-2000 */ +static GtkWidget *civ; /* Icom CI-V address */ +static GtkWidget *type; /* radio type */ +static GtkWidget *port; /* port selector */ +static GtkWidget *speed; /* serial speed selector */ +static GtkWidget *dtr,*rts; /* DTR and RTS line states */ + + +static GtkWidget *create_editor_widgets (radio_conf_t *conf); +static void update_widgets (radio_conf_t *conf); +static void clear_widgets (void); +static gboolean apply_changes (radio_conf_t *conf); +static void name_changed (GtkWidget *widget, gpointer data); +static GtkTreeModel *create_rig_model (void); +static gint rig_list_add (const struct rig_caps *, void *); +static gint rig_list_compare_mfg (gconstpointer, gconstpointer); +static gint rig_list_compare_mod (gconstpointer, gconstpointer); +static void is_rig_model (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data); +static void select_rig (guint rigid); + + +/** \brief Add or edit a radio configuration. + * \param conf Pointer to a radio configuration. + * + * Of conf->name is not NULL the widgets will be populated with the data. + */ +void +sat_pref_rig_editor_run (radio_conf_t *conf) +{ + gint response; + gboolean finished = FALSE; + + + /* crate dialog and add contents */ + dialog = gtk_dialog_new_with_buttons (_("Edit radio configuration"), + GTK_WINDOW (window), + 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 (conf)); + + /* 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 (conf)) { + finished = TRUE; + } + else { + finished = FALSE; + } + break; + + /* CLEAR */ + case GTK_RESPONSE_REJECT: + clear_widgets (); + break; + + /* Everything else is considered CANCEL */ + default: + finished = TRUE; + break; + } + } + + gtk_widget_destroy (dialog); +} + + +/** \brief Create and initialise widgets */ +static GtkWidget * +create_editor_widgets (radio_conf_t *conf) +{ + GtkWidget *table; + GtkWidget *label; + GtkTreeModel *riglist; + GtkCellRenderer *renderer; + gchar *buff; + guint i; + + + table = gtk_table_new (5, 5, 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); + + /* Config 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, 4, 0, 1); + + name = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (name), 25); + gtk_widget_set_tooltip_text (name, + _("Enter a short name for this configuration, e.g. IC910-1.\n"\ + "Allowed charachters: 0..9, a..z, A..Z, - and _")); + 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); + + /* Model */ + label = gtk_label_new (_("Model")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2); + + riglist = create_rig_model (); + model = gtk_combo_box_new_with_model (riglist); + g_object_unref (riglist); + gtk_table_attach_defaults (GTK_TABLE (table), model, 1, 2, 1, 2); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (model), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (model), renderer, + "text", 0, + NULL); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (model), + renderer, + is_rig_model, + NULL, NULL); + gtk_widget_set_tooltip_text (model, _("Click to select a radio.")); + select_rig (1); + + /* ICOM CI-V adress */ + label = gtk_label_new (_("ICOM CI-V")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 1, 2); + + civ = gtk_combo_box_new_text (); + gtk_widget_set_tooltip_text (civ, + _("Select ICOM CI-V address of the radio.")); + + /* works, but pretty lame... */ + gtk_combo_box_append_text (GTK_COMBO_BOX (civ), _("Default")); + for (i = 1; i < 0xF0; i++) { + if (i < 0x10) + buff = g_strdup_printf ("0x0%X", i); + else + buff = g_strdup_printf ("0x%X", i); + gtk_combo_box_append_text (GTK_COMBO_BOX (civ), buff); + g_free (buff); + } + gtk_combo_box_set_active (GTK_COMBO_BOX (civ), 0); + gtk_table_attach_defaults (GTK_TABLE (table), civ, 4, 5, 1, 2); + + + /* Type */ + label = gtk_label_new (_("Type")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3); + type = gtk_combo_box_new_text (); + gtk_combo_box_append_text (GTK_COMBO_BOX (type), _("Receiver")); + gtk_combo_box_append_text (GTK_COMBO_BOX (type), _("Transmitter")); + gtk_combo_box_append_text (GTK_COMBO_BOX (type), _("RX + TX")); + gtk_combo_box_append_text (GTK_COMBO_BOX (type), _("Full Duplex")); + gtk_combo_box_set_active (GTK_COMBO_BOX (type), 0); + gtk_widget_set_tooltip_text (type, + _("Select radio type. Consult the user manual, if unsure")); + gtk_table_attach_defaults (GTK_TABLE (table), type, 1, 2, 2, 3); + + /* Port */ + label = gtk_label_new (_("Port")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 3, 4); + + port = gtk_combo_box_entry_new_text (); + if (conf->port != NULL) { + gtk_combo_box_append_text (GTK_COMBO_BOX (port), conf->port); + } + gtk_combo_box_append_text (GTK_COMBO_BOX (port), "/dev/ttyS0"); + gtk_combo_box_append_text (GTK_COMBO_BOX (port), "/dev/ttyS1"); + gtk_combo_box_append_text (GTK_COMBO_BOX (port), "/dev/ttyS2"); + gtk_combo_box_append_text (GTK_COMBO_BOX (port), "/dev/ttyUSB0"); + gtk_combo_box_append_text (GTK_COMBO_BOX (port), "/dev/ttyUSB1"); + gtk_combo_box_append_text (GTK_COMBO_BOX (port), "/dev/ttyUSB2"); + gtk_combo_box_set_active (GTK_COMBO_BOX (port), 0); + gtk_widget_set_tooltip_text (port, _("Select or enter communication port")); + gtk_table_attach_defaults (GTK_TABLE (table), port, 1, 2, 3, 4); + + /* DTR State */ + label = gtk_label_new (_("DTR Line")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 3, 4); + + dtr = gtk_combo_box_new_text (); + gtk_combo_box_append_text (GTK_COMBO_BOX (dtr), _("Undefined")); + gtk_combo_box_append_text (GTK_COMBO_BOX (dtr), _("OFF")); + gtk_combo_box_append_text (GTK_COMBO_BOX (dtr), _("ON")); + gtk_combo_box_append_text (GTK_COMBO_BOX (dtr), _("PTT")); + gtk_combo_box_append_text (GTK_COMBO_BOX (dtr), _("CW")); + gtk_combo_box_set_active (GTK_COMBO_BOX (dtr), 0); + gtk_widget_set_tooltip_text (dtr, _("Select status and use of DTR line")); + gtk_table_attach_defaults (GTK_TABLE (table), dtr, 4, 5, 3, 4); + + + /* Speed */ + label = gtk_label_new (_("Rate")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 4, 5); + speed = gtk_combo_box_new_text (); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "300"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "1200"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "2400"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "4800"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "9600"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "19200"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "38400"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "57600"); + gtk_combo_box_append_text (GTK_COMBO_BOX (speed), "115200"); + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 4); + gtk_widget_set_tooltip_text (speed, _("Select serial port speed")); + gtk_table_attach_defaults (GTK_TABLE (table), speed, 1, 2, 4, 5); + + /* RTS State */ + label = gtk_label_new (_("RTS Line")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach_defaults (GTK_TABLE (table), label, 3, 4, 4, 5); + + rts = gtk_combo_box_new_text (); + gtk_combo_box_append_text (GTK_COMBO_BOX (rts), _("Undefined")); + gtk_combo_box_append_text (GTK_COMBO_BOX (rts), _("OFF")); + gtk_combo_box_append_text (GTK_COMBO_BOX (rts), _("ON")); + gtk_combo_box_append_text (GTK_COMBO_BOX (rts), _("PTT")); + gtk_combo_box_append_text (GTK_COMBO_BOX (rts), _("CW")); + gtk_combo_box_set_active (GTK_COMBO_BOX (rts), 0); + gtk_widget_set_tooltip_text (rts, _("Select status and use of RTS line")); + gtk_table_attach_defaults (GTK_TABLE (table), rts, 4, 5, 4, 5); + + /* separator between port/speed and DTR/RTS */ + gtk_table_attach (GTK_TABLE (table), gtk_vseparator_new(), 2, 3, 1, 5, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 5, 0); + + if (conf->name != NULL) + update_widgets (conf); + + gtk_widget_show_all (table); + + return table; +} + + +/** \brief Update widgets from the currently selected row in the treeview + */ +static void +update_widgets (radio_conf_t *conf) +{ + + /* configuration name */ + gtk_entry_set_text (GTK_ENTRY (name), conf->name); + + /* model */ + select_rig (conf->id); + + /* type */ + gtk_combo_box_set_active (GTK_COMBO_BOX (type), conf->type); + + /* port */ + gtk_combo_box_prepend_text (GTK_COMBO_BOX (port), conf->port); + gtk_combo_box_set_active (GTK_COMBO_BOX (port), 0); + + /*serial speed */ + switch (conf->speed) { + case 300: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 0); + break; + case 1200: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 1); + break; + case 2400: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 2); + break; + case 9600: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 3); + break; + case 19200: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 4); + break; + case 38400: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 5); + break; + case 57600: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 6); + break; + case 115200: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 7); + break; + default: + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 4); + break; + } + + /* CI-V */ + gtk_combo_box_set_active (GTK_COMBO_BOX (civ), conf->civ); + + /* DTR and RTS lines */ + gtk_combo_box_set_active (GTK_COMBO_BOX (dtr), conf->dtr); + gtk_combo_box_set_active (GTK_COMBO_BOX (rts), conf->rts); +} + + + +/** \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), ""); + select_rig (1); + gtk_combo_box_set_active (GTK_COMBO_BOX (type), 0); + gtk_combo_box_set_active (GTK_COMBO_BOX (port), 0); + gtk_combo_box_set_active (GTK_COMBO_BOX (speed), 4); + gtk_combo_box_set_active (GTK_COMBO_BOX (civ), 0); + gtk_combo_box_set_active (GTK_COMBO_BOX (dtr), 0); + gtk_combo_box_set_active (GTK_COMBO_BOX (rts), 0); +} + + +/** \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 (radio_conf_t *conf) +{ + GtkTreeIter iter1,iter2; + GtkTreeModel *riglist; + gchar *b1,*b2; + guint id; + + + /* name */ + if (conf->name) + g_free (conf->name); + + conf->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (name))); + + /* model */ + if (conf->model) + g_free (conf->model); + + /* iter1 is needed to construct full model name */ + gtk_combo_box_get_active_iter (GTK_COMBO_BOX (model), &iter2); + riglist = gtk_combo_box_get_model (GTK_COMBO_BOX (model)); + gtk_tree_model_iter_parent (riglist, &iter1, &iter2); + + /* build model string */ + gtk_tree_model_get (riglist, &iter1, 0, &b1, -1); + gtk_tree_model_get (riglist, &iter2, 0, &b2, -1); + conf->model = g_strconcat (b1, " ", b2, NULL); + g_free (b1); + g_free (b2); + + /* ID */ + gtk_tree_model_get (riglist, &iter2, 1, &id, -1); + conf->id = id; + + /* radio type */ + conf->type = gtk_combo_box_get_active (GTK_COMBO_BOX (type)); + + /* port / device */ + if (conf->port) + g_free (conf->port); + + conf->port = gtk_combo_box_get_active_text (GTK_COMBO_BOX (port)); + + /* CI-V */ + conf->civ = gtk_combo_box_get_active (GTK_COMBO_BOX (civ)); + + /* serial speed */ + switch (gtk_combo_box_get_active (GTK_COMBO_BOX (speed))) { + case 0: + conf->speed = 300; + break; + case 1: + conf->speed = 1200; + break; + case 2: + conf->speed = 2400; + break; + case 3: + conf->speed = 4800; + break; + case 4: + conf->speed = 9600; + break; + case 5: + conf->speed = 19200; + break; + case 6: + conf->speed = 38400; + break; + case 7: + conf->speed = 57600; + break; + case 8: + conf->speed = 115200; + break; + default: + conf->speed = 9600; + break; + } + + /* DTR and RTS */ + conf->dtr = gtk_combo_box_get_active (GTK_COMBO_BOX (dtr)); + conf->rts = gtk_combo_box_get_active (GTK_COMBO_BOX (rts)); + + return TRUE; +} + + + +/** \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 Radio info to be used when building the rig model */ +typedef struct { + gint id; /*!< Model ID. */ + gchar *mfg; /*!< Manufacurer name (eg. KENWOOD). */ + gchar *model; /*!< Radio model (eg. TS-440). */ +} rig_info_t; + + +/** \brief Build tree model containing radios. + * \return A tree model where the radios are ordered according to + * manufacturer. + * + */ +static GtkTreeModel *create_rig_model () +{ + GArray *array; + rig_info_t *info; + GtkTreeIter iter1; /* iter used for manufacturer */ + GtkTreeIter iter2; /* iter used for model */ + GtkTreeStore *store; + gchar *buff; + gint status; + gint i; + + + /* create araay containing rigs */ + array = g_array_new (FALSE, FALSE, sizeof (rig_info_t)); + rig_load_all_backends(); + + /* fill list using rig_list_foreach */ + status = rig_list_foreach (rig_list_add, (void *) array); + + /* sort the array, first by model then by mfg */ + g_array_sort (array, rig_list_compare_mod); + g_array_sort (array, rig_list_compare_mfg); + + sat_log_log (SAT_LOG_LEVEL_DEBUG, + _("%s:%d: Read %d distinct radios into array."), + __FILE__, __LINE__, array->len); + + /* create a tree store with two cols (name and ID) */ + store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT); + + /* add array contents to treestore */ + for (i = 0; i < array->len; i++) { + + /* get rig info struct */ + info = &g_array_index (array, rig_info_t, i); + + if (gtk_tree_store_iter_is_valid (store, &iter1)) { + /* iter1 is valid, i.e. we already have a manufacturer */ + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter1, + 0, &buff, + -1); + if (g_ascii_strcasecmp (buff, info->mfg)) { + /* mfg different, add new mfg */ + gtk_tree_store_append (store, &iter1, NULL); + gtk_tree_store_set (store, &iter1, 0, info->mfg, -1); + } + /* else: mfg are identical; nothing to do */ + } + else { + /* iter1 is not valid, so add the first manufacturer */ + gtk_tree_store_append (store, &iter1, NULL); + gtk_tree_store_set (store, &iter1, 0, info->mfg, -1); + } + + /* iter1 points to the parent mfg; insert this rig */ + gtk_tree_store_append (store, &iter2, &iter1); + gtk_tree_store_set (store, &iter2, + 0, info->model, + 1, info->id, + -1); + + /* done with this model */ + g_free (info->mfg); + g_free (info->model); + } + + g_array_free (array,TRUE); + + return GTK_TREE_MODEL (store); +} + + +/** \brief Add new entry to list of radios. + * \param caps Structure with the capablities of thecurrent radio. + * \param array Pointer to the GArray into which the new entry should be + * stored. + * \return Always 1 to keep rig_list_foreach running. + * + * This function is called by the rig_list_foreach hamlib function for each + * supported radio. It copies the relevant data into a grig_rig_info_t + * structure and adds the new entry to the GArray containing the list of + * supported radios. + * + * \sa rig_list_compare + */ +static gint +rig_list_add (const struct rig_caps *caps, void *array) +{ + rig_info_t *info; + + /* create new entry */ + info = g_malloc (sizeof (rig_info_t)); + + /* fill values */ + info->id = caps->rig_model; + info->mfg = g_strdup (caps->mfg_name); + info->model = g_strdup (caps->model_name); + + /* append new element to array */ + array = (void *) g_array_append_vals ((GArray *) array, info, 1); + + /* keep on running */ + return 1; +} + + + +/** \brief Compare two rig info entries. + * \param a Pointer to the first entry. + * \param b Pointer to the second entry. + * \return Negative value if a < b; zero if a = b; positive value if a > b. + * + * This function is used to compare two rig entries in the list of radios + * when the list is sorted. It compares the manufacturer of the two radios. + * + * \sa rig_list_add + */ +static gint +rig_list_compare_mfg (gconstpointer a, gconstpointer b) +{ + gchar *ida, *idb; + + ida = ((rig_info_t *) a)->mfg; + idb = ((rig_info_t *) b)->mfg; + + if (g_ascii_strcasecmp(ida,idb) < 0) { + return -1; + } + else if (g_ascii_strcasecmp(ida,idb) > 0) { + return 1; + } + else { + return 0; + } + +} + + + +/** \brief Compare two rig info entries. + * \param a Pointer to the first entry. + * \param b Pointer to the second entry. + * \return Negative value if a < b; zero if a = b; positive value if a > b. + * + * This function is used to compare two rig entries in the list of radios + * when the list is sorted. It compares the model of the two radios. + * + * \sa rig_list_add + */ +static gint +rig_list_compare_mod (gconstpointer a, gconstpointer b) +{ + gchar *ida, *idb; + + ida = ((rig_info_t *) a)->model; + idb = ((rig_info_t *) b)->model; + + if (g_ascii_strcasecmp(ida,idb) < 0) { + return -1; + } + else if (g_ascii_strcasecmp(ida,idb) > 0) { + return 1; + } + else { + return 0; + } + +} + + +/** \brief Set cell sensitivity. + * + * This function is used to disable the sensitive of manifacturer entries + * as children. Otherwise, the manufacturer would appear as the first entry + * in a submenu. + * */ +static void +is_rig_model (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + gboolean sensitive; + + sensitive = !gtk_tree_model_iter_has_child (tree_model, iter); + + g_object_set (cell, "sensitive", sensitive, NULL); +} + + +/** \brief Select a radio in the combo box. + * \param rigid The hamlib id of the radio. + * + * This function selects the specified radio in the combobox. This is done + * by looping over all items in the tree model until a match is reached + * (or there are no more items left). + */ +static void +select_rig (guint rigid) +{ + GtkTreeIter iter1,iter2; + GtkTreeModel *riglist; + guint i,j,n,m; + guint thisrig = 0; + + + /* get the tree model */ + riglist = gtk_combo_box_get_model (GTK_COMBO_BOX (model)); + + /* get the number of toplevel nodes */ + n = gtk_tree_model_iter_n_children (riglist, NULL); + for (i = 0; i < n; i++) { + + /* get the i'th toplevel node */ + if (gtk_tree_model_iter_nth_child (riglist, &iter1, NULL, i)) { + + /* get the number of children */ + m = gtk_tree_model_iter_n_children (riglist, &iter1); + for (j = 0; j < m; j++) { + + /* get the j'th child */ + if (gtk_tree_model_iter_nth_child (riglist, &iter2, &iter1, j)) { + + /* get ID of this model */ + gtk_tree_model_get (riglist, &iter2, 1, &thisrig, -1); + + if (thisrig == rigid) { + /* select this rig and terminate loop */ + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (model), &iter2); + j = m; + i = n; + } + } + else { + sat_log_log (SAT_LOG_LEVEL_BUG, + _("%s:%s: NULL child node at index %d:%d"), + __FILE__, __FUNCTION__, i, j); + + } + } + + } + else { + sat_log_log (SAT_LOG_LEVEL_BUG, + _("%s:%s: NULL toplevel node at index %d"), + __FILE__, __FUNCTION__, i); + } + } + + +} + +#endif Added: trunk/src/sat-pref-rot-editor.h =================================================================== --- trunk/src/sat-pref-rot-editor.h (rev 0) +++ trunk/src/sat-pref-rot-editor.h 2008-01-24 22:58:40 UTC (rev 21) @@ -0,0 +1,38 @@ +/* -*- 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-2007 Alexandru Csete, OZ9AEC. + + Authors: Alexandru Csete <oz...@gm...> + + Comments, questions and bugreports should be submitted via + http://sourceforge.net/projects/groundstation/ + More details can be found at the project home page: + + http://groundstation.sourceforge.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/ +*/ +#ifndef SAT_PREF_ROT_EDITOR_H +#define SAT_PREF_ROT_EDITOR_H 1 + +#include <gtk/gtk.h> +#include "rotor-conf.h" + +#ifdef HAVE_HAMLIB +void sat_pref_rot_editor_run (rotor_conf_t *conf); +#endif + +#endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |