/ src / sat-pref-rig-editor.c
sat-pref-rig-editor.c
  1  /*
  2    Gpredict: Real-time satellite tracking and orbit prediction program
  3  
  4    Copyright (C)  2001-2017  Alexandru Csete, OZ9AEC.
  5   
  6    This program is free software; you can redistribute it and/or modify
  7    it under the terms of the GNU General Public License as published by
  8    the Free Software Foundation; either version 2 of the License, or
  9    (at your option) any later version.
 10    
 11    This program is distributed in the hope that it will be useful,
 12    but WITHOUT ANY WARRANTY; without even the implied warranty of
 13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14    GNU General Public License for more details.
 15    
 16    You should have received a copy of the GNU General Public License
 17    along with this program; if not, visit http://www.fsf.org/
 18  */
 19  #ifdef HAVE_CONFIG_H
 20  #include <build-config.h>
 21  #endif
 22  #include <glib/gi18n.h>
 23  #include <glib/gstdio.h>
 24  #include <gtk/gtk.h>
 25  #include <math.h>
 26  
 27  #include "gpredict-utils.h"
 28  #include "radio-conf.h"
 29  #include "sat-cfg.h"
 30  #include "sat-log.h"
 31  #include "sat-pref-rig-editor.h"
 32  
 33  
 34  extern GtkWidget *window;       /* dialog window defined in sat-pref.c */
 35  static GtkWidget *dialog;       /* dialog window */
 36  static GtkWidget *name;         /* config name */
 37  static GtkWidget *host;         /* host */
 38  static GtkWidget *port;         /* port number */
 39  static GtkWidget *type;         /* rig type */
 40  static GtkWidget *ptt;          /* PTT */
 41  static GtkWidget *vfo;          /* VFO Up/Down selector */
 42  static GtkWidget *lo;           /* local oscillator of downconverter */
 43  static GtkWidget *loup;         /* local oscillator of upconverter */
 44  static GtkWidget *sigaos;       /* AOS signalling */
 45  static GtkWidget *siglos;       /* LOS signalling */
 46  
 47  
 48  static void clear_widgets()
 49  {
 50      gtk_entry_set_text(GTK_ENTRY(name), "");
 51      gtk_entry_set_text(GTK_ENTRY(host), "localhost");
 52      gtk_spin_button_set_value(GTK_SPIN_BUTTON(port), 4532);     /* hamlib default? */
 53      gtk_spin_button_set_value(GTK_SPIN_BUTTON(lo), 0);
 54      gtk_spin_button_set_value(GTK_SPIN_BUTTON(loup), 0);
 55      gtk_combo_box_set_active(GTK_COMBO_BOX(type), RIG_TYPE_RX);
 56      gtk_combo_box_set_active(GTK_COMBO_BOX(ptt), PTT_TYPE_NONE);
 57      gtk_combo_box_set_active(GTK_COMBO_BOX(vfo), 0);
 58      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ptt), FALSE);
 59      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sigaos), FALSE);
 60      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(siglos), FALSE);
 61  }
 62  
 63  static void update_widgets(radio_conf_t * conf)
 64  {
 65      /* configuration name */
 66      gtk_entry_set_text(GTK_ENTRY(name), conf->name);
 67  
 68      /* host name */
 69      if (conf->host)
 70          gtk_entry_set_text(GTK_ENTRY(host), conf->host);
 71  
 72      /* port */
 73      if (conf->port > 1023)
 74          gtk_spin_button_set_value(GTK_SPIN_BUTTON(port), conf->port);
 75      else
 76          gtk_spin_button_set_value(GTK_SPIN_BUTTON(port), 4532); /* hamlib default? */
 77  
 78      /* radio type */
 79      gtk_combo_box_set_active(GTK_COMBO_BOX(type), conf->type);
 80  
 81      /* ptt */
 82      gtk_combo_box_set_active(GTK_COMBO_BOX(ptt), conf->ptt);
 83  
 84      /* vfo up/down */
 85      if (conf->type == RIG_TYPE_DUPLEX)
 86      {
 87          if (conf->vfoUp == VFO_MAIN)
 88              gtk_combo_box_set_active(GTK_COMBO_BOX(vfo), 1);
 89          else if (conf->vfoUp == VFO_SUB)
 90              gtk_combo_box_set_active(GTK_COMBO_BOX(vfo), 2);
 91          else if (conf->vfoUp == VFO_A)
 92              gtk_combo_box_set_active(GTK_COMBO_BOX(vfo), 3);
 93          else
 94              gtk_combo_box_set_active(GTK_COMBO_BOX(vfo), 4);
 95      }
 96  
 97      /* lo down in MHz */
 98      gtk_spin_button_set_value(GTK_SPIN_BUTTON(lo), conf->lo / 1000000.0);
 99  
100      /* lo up in MHz */
101      gtk_spin_button_set_value(GTK_SPIN_BUTTON(loup), conf->loup / 1000000.0);
102  
103      /* AOS / LOS signalling */
104      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sigaos), conf->signal_aos);
105      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(siglos), conf->signal_los);
106  }
107  
108  /*
109   * Manage VFO changed signals.
110   * Widget is the GtkComboBox that received the signal.
111   *  
112   * This function is called when the user selects a new VFO up/down combination.
113   */
114  static void vfo_changed(GtkWidget * widget, gpointer data)
115  {
116      (void)data;
117  
118      if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) == 0 &&
119          gtk_combo_box_get_active(GTK_COMBO_BOX(type)) == RIG_TYPE_DUPLEX)
120      {
121          /* not good, we need to have proper VFO combi for this type */
122          gtk_combo_box_set_active(GTK_COMBO_BOX(widget), 1);
123      }
124  }
125  
126  /*
127   * Manage ptt type changed signals.
128   * Widget is the GtkComboBox that received the signal.
129   *  
130   * This function is called when the user selects a new ptt type.
131   */
132  static void ptt_changed(GtkWidget * widget, gpointer data)
133  {
134      (void)data;
135  
136      if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) == PTT_TYPE_NONE &&
137          gtk_combo_box_get_active(GTK_COMBO_BOX(type)) == RIG_TYPE_TRX)
138      {
139          /* not good, we need to have PTT for this type */
140          gtk_combo_box_set_active(GTK_COMBO_BOX(widget), PTT_TYPE_CAT);
141      }
142  }
143  
144  /*
145   * Manage name changes.
146   *
147   * This function is called when the contents of the name entry changes.
148   * The primary purpose of this function is to check whether the char length
149   * of the name is greater than zero, if yes enable the OK button of the dialog.
150   */
151  static void name_changed(GtkWidget * widget, gpointer data)
152  {
153      const gchar    *text;
154      gchar          *entry, *end, *j;
155      gint            len, pos;
156  
157      (void)data;
158  
159      /* step 1: ensure that only valid characters are entered
160         (stolen from xlog, tnx pg4i)
161       */
162      entry = gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1);
163      if ((len = g_utf8_strlen(entry, -1)) > 0)
164      {
165          end = entry + g_utf8_strlen(entry, -1);
166          for (j = entry; j < end; ++j)
167          {
168              if (!gpredict_legal_char(*j))
169              {
170                  gdk_display_beep(gdk_display_get_default());
171                  pos = gtk_editable_get_position(GTK_EDITABLE(widget));
172                  gtk_editable_delete_text(GTK_EDITABLE(widget), pos, pos + 1);
173              }
174          }
175      }
176  
177      /* step 2: if name seems all right, enable OK button */
178      text = gtk_entry_get_text(GTK_ENTRY(widget));
179  
180      if (g_utf8_strlen(text, -1) > 0)
181      {
182          gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
183                                            GTK_RESPONSE_OK, TRUE);
184      }
185      else
186      {
187          gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
188                                            GTK_RESPONSE_OK, FALSE);
189      }
190  }
191  
192  /*
193   * Manage rig type changed signals.
194   * widget os the GtkComboBox that received the signal.
195   *  
196   * This function is called when the user selects a new radio type.
197   */
198  static void type_changed(GtkWidget * widget, gpointer data)
199  {
200      (void)data;
201  
202      /* PTT consistency */
203      if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) == RIG_TYPE_TRX)
204      {
205          if (gtk_combo_box_get_active(GTK_COMBO_BOX(ptt)) == PTT_TYPE_NONE)
206          {
207              gtk_combo_box_set_active(GTK_COMBO_BOX(ptt), PTT_TYPE_CAT);
208          }
209      }
210  
211      if ((gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) ==
212           RIG_TYPE_TOGGLE_AUTO) ||
213          (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) ==
214           RIG_TYPE_TOGGLE_MAN))
215      {
216          gtk_combo_box_set_active(GTK_COMBO_BOX(ptt), PTT_TYPE_CAT);
217      }
218  
219  
220      /* VFO consistency */
221      if (gtk_combo_box_get_active(GTK_COMBO_BOX(widget)) == RIG_TYPE_DUPLEX &&
222          gtk_combo_box_get_active(GTK_COMBO_BOX(vfo)) == 0)
223      {
224          gtk_combo_box_set_active(GTK_COMBO_BOX(vfo), 1);
225      }
226  }
227  
228  static GtkWidget *create_editor_widgets(radio_conf_t * conf)
229  {
230      GtkWidget      *table;
231      GtkWidget      *label;
232  
233      table = gtk_grid_new();
234      gtk_container_set_border_width(GTK_CONTAINER(table), 5);
235      gtk_grid_set_column_homogeneous(GTK_GRID(table), FALSE);
236      gtk_grid_set_row_homogeneous(GTK_GRID(table), FALSE);
237      gtk_grid_set_column_spacing(GTK_GRID(table), 5);
238      gtk_grid_set_row_spacing(GTK_GRID(table), 5);
239  
240      /* Config name */
241      label = gtk_label_new(_("Name"));
242      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
243      gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1);
244  
245      name = gtk_entry_new();
246      gtk_entry_set_max_length(GTK_ENTRY(name), 25);
247      g_signal_connect(name, "changed", G_CALLBACK(name_changed), NULL);
248      gtk_widget_set_tooltip_text(name,
249                                  _("Enter a short name for this configuration, "
250                                    "e.g. IC910-1.\n"
251                                    "Allowed characters: "
252                                    "0..9, a..z, A..Z, - and _"));
253      gtk_grid_attach(GTK_GRID(table), name, 1, 0, 3, 1);
254  
255      /* Host */
256      label = gtk_label_new(_("Host"));
257      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
258      gtk_grid_attach(GTK_GRID(table), label, 0, 1, 1, 1);
259  
260      host = gtk_entry_new();
261      gtk_entry_set_max_length(GTK_ENTRY(host), 50);
262      gtk_entry_set_text(GTK_ENTRY(host), "localhost");
263      gtk_widget_set_tooltip_text(host,
264                                  _("Enter the host where rigctld is running. "
265                                    "You can use both host name and IP address, "
266                                    "e.g. 192.168.1.100\n\n"
267                                    "If gpredict and rigctld are running on the "
268                                    "same computer use localhost"));
269      gtk_grid_attach(GTK_GRID(table), host, 1, 1, 3, 1);
270  
271      /* port */
272      label = gtk_label_new(_("Port"));
273      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
274      gtk_grid_attach(GTK_GRID(table), label, 0, 2, 1, 1);
275  
276      port = gtk_spin_button_new_with_range(1024, 65535, 1);
277      gtk_spin_button_set_value(GTK_SPIN_BUTTON(port), 4532);
278      gtk_spin_button_set_digits(GTK_SPIN_BUTTON(port), 0);
279      gtk_widget_set_tooltip_text(port,
280                                  _("Enter the port number where rigctld is "
281                                    "listening"));
282      gtk_grid_attach(GTK_GRID(table), port, 1, 2, 1, 1);
283  
284      /* radio type */
285      label = gtk_label_new(_("Radio type"));
286      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
287      //gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 3, 4);
288      gtk_grid_attach(GTK_GRID(table), label, 0, 3, 1, 1);
289  
290      type = gtk_combo_box_text_new();
291      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type), _("RX only"));
292      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type), _("TX only"));
293      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type), _("Half-duplex"));
294      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type), _("Full-duplex"));
295      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type),
296                                     _("FT817/857/897 (auto)"));
297      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(type),
298                                     _("FT817/857/897 (manual)"));
299      gtk_combo_box_set_active(GTK_COMBO_BOX(type), RIG_TYPE_RX);
300      g_signal_connect(type, "changed", G_CALLBACK(type_changed), NULL);
301      gtk_widget_set_tooltip_markup(type,
302                                    _("<b>RX only:</b>  The radio shall only be "
303                                      "used as receiver. If <i>Monitor PTT "
304                                      "status</i> is checked the doppler tuning "
305                                      "will be suspended while PTT is ON "
306                                      "(manual TX). If not, the controller will "
307                                      "always perform doppler tuning and "
308                                      "you cannot use the same RIG for uplink.\n\n"
309                                      "<b>TX only:</b>  The radio shall only be "
310                                      "used for uplink. If <i>Monitor PTT status</i>"
311                                      " is checked the doppler tuning will be "
312                                      "suspended while PTT is OFF (manual RX).\n\n"
313                                      "<b>Half-duplex:</b>  The radio should be "
314                                      "used for both up- and downlink but not at "
315                                      "the same time. This option requires "
316                                      "that the PTT status is monitored (otherwise "
317                                      "gpredict cannot know whether to tune the "
318                                      "RX or the TX).\n\n"
319                                      "<b>Full-duplex:</b>  The radio is a full-duplex"
320                                      " radio, such as the IC910H. Gpredict will "
321                                      "be continuously tuning both uplink and "
322                                      "downlink simultaneously and not care about "
323                                      "PTT setting.\n\n"
324                                      "<b>FT817/857/897 (auto):</b> "
325                                      "This is a special mode that can be used with "
326                                      "YAESU FT-817, 857 and 897 radios. These radios"
327                                      " do not allow computer control while in TX mode."
328                                      " Therefore, TX Doppler correction is applied "
329                                      "while the radio is in RX mode by toggling "
330                                      "between VFO A/B.\n\n"
331                                      "<b>FT817/857/897 (manual):</b> "
332                                      "This is similar to the previous mode except"
333                                      " that switching to TX is done by pressing the"
334                                      " SPACE key on the keyboard. Gpredict will "
335                                      "then update the TX Doppler before actually"
336                                      " switching to TX."));
337      gtk_grid_attach(GTK_GRID(table), type, 1, 3, 2, 1);
338  
339      /* ptt */
340      label = gtk_label_new(_("PTT status"));
341      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
342      gtk_grid_attach(GTK_GRID(table), label, 0, 4, 1, 1);
343  
344      ptt = gtk_combo_box_text_new();
345      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ptt), _("None"));
346      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ptt), _("Read PTT"));
347      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ptt), _("Read DCD"));
348      gtk_combo_box_set_active(GTK_COMBO_BOX(ptt), 0);
349      g_signal_connect(ptt, "changed", G_CALLBACK(ptt_changed), NULL);
350      gtk_widget_set_tooltip_markup(ptt,
351                                    _("Select PTT type.\n\n"
352                                      "<b>None:</b>\nDon't read PTT status from this radio.\n\n"
353                                      "<b>Read PTT:</b>\nRead PTT status using get_ptt CAT command. "
354                                      "You have to check that your radio and hamlib supports this.\n\n"
355                                      "<b>Read DCD:</b>\nRead PTT status using get_dcd command. "
356                                      "This can be used if your radio does not support the read_ptt "
357                                      "CAT command and you have a special interface that can "
358                                      "read squelch status and send it via CTS."));
359      gtk_grid_attach(GTK_GRID(table), ptt, 1, 4, 2, 1);
360  
361      /* VFO Up/Down */
362      label = gtk_label_new(_("VFO Up/Down"));
363      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
364      gtk_grid_attach(GTK_GRID(table), label, 0, 5, 1, 1);
365  
366      vfo = gtk_combo_box_text_new();
367      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vfo), _("Not applicable"));
368      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vfo),
369                                     _("MAIN \342\206\221 / SUB \342\206\223"));
370      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vfo),
371                                     _("SUB \342\206\221 / MAIN \342\206\223"));
372      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vfo),
373                                     _("A \342\206\221 / B \342\206\223"));
374      gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vfo),
375                                     _("B \342\206\221 / A \342\206\223"));
376      gtk_combo_box_set_active(GTK_COMBO_BOX(vfo), 0);
377      g_signal_connect(vfo, "changed", G_CALLBACK(vfo_changed), NULL);
378      gtk_widget_set_tooltip_markup(vfo,
379                                    _
380                                    ("Select which VFO to use for uplink and downlink. "
381                                     "This setting is used for full-duplex radios only, "
382                                     "such as the IC-910H, FT-847 and the TS-2000.\n\n"
383                                     "<b>IC-910H:</b> MAIN\342\206\221 / SUB\342\206\223\n"
384                                     "<b>FT-847:</b> SUB\342\206\221 / MAIN\342\206\223\n"
385                                     "<b>TS-2000:</b> B\342\206\221 / A\342\206\223"));
386      gtk_grid_attach(GTK_GRID(table), vfo, 1, 5, 2, 1);
387  
388      /* Downconverter LO frequency */
389      label = gtk_label_new(_("LO Down"));
390      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
391      gtk_grid_attach(GTK_GRID(table), label, 0, 6, 1, 1);
392  
393      lo = gtk_spin_button_new_with_range(-10000, 10000, 1);
394      gtk_spin_button_set_value(GTK_SPIN_BUTTON(lo), 0);
395      gtk_spin_button_set_digits(GTK_SPIN_BUTTON(lo), 0);
396      gtk_widget_set_tooltip_text(lo,
397                                  _
398                                  ("Enter the frequency of the local oscillator "
399                                   " of the downconverter, if any."));
400      gtk_grid_attach(GTK_GRID(table), lo, 1, 6, 2, 1);
401  
402      label = gtk_label_new(_("MHz"));
403      g_object_set(label, "xalign", 0.0, "yalign", 0.5, NULL);
404      gtk_grid_attach(GTK_GRID(table), label, 3, 6, 1, 1);
405  
406      /* Upconverter LO frequency */
407      label = gtk_label_new(_("LO Up"));
408      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
409      gtk_grid_attach(GTK_GRID(table), label, 0, 7, 1, 1);
410  
411      loup = gtk_spin_button_new_with_range(-10000, 10000, 1);
412      gtk_spin_button_set_value(GTK_SPIN_BUTTON(loup), 0);
413      gtk_spin_button_set_digits(GTK_SPIN_BUTTON(loup), 0);
414      gtk_widget_set_tooltip_text(loup,
415                                  _
416                                  ("Enter the frequency of the local oscillator "
417                                   "of the upconverter, if any."));
418      gtk_grid_attach(GTK_GRID(table), loup, 1, 7, 2, 1);
419  
420      label = gtk_label_new(_("MHz"));
421      g_object_set(label, "xalign", 0.0, "yalign", 0.5, NULL);
422      gtk_grid_attach(GTK_GRID(table), label, 3, 7, 1, 1);
423  
424      /* AOS / LOS signalling */
425      label = gtk_label_new(_("Signalling"));
426      g_object_set(label, "xalign", 1.0, "yalign", 0.5, NULL);
427      gtk_grid_attach(GTK_GRID(table), label, 0, 8, 1, 1);
428  
429      sigaos = gtk_check_button_new_with_label(_("AOS"));
430      gtk_grid_attach(GTK_GRID(table), sigaos, 1, 8, 1, 1);
431      gtk_widget_set_tooltip_text(sigaos,
432                                  _("Enable AOS signalling for this radio."));
433  
434      siglos = gtk_check_button_new_with_label(_("LOS"));
435      gtk_grid_attach(GTK_GRID(table), siglos, 2, 8, 1, 1);
436      gtk_widget_set_tooltip_text(siglos,
437                                  _("Enable LOS signalling for this radio."));
438  
439      if (conf->name != NULL)
440          update_widgets(conf);
441  
442      gtk_widget_show_all(table);
443  
444      return table;
445  }
446  
447  /* Apply changes. Returns TRUE if things are ok, FALSE otherwise */
448  static gboolean apply_changes(radio_conf_t * conf)
449  {
450      /* name */
451      if (conf->name)
452          g_free(conf->name);
453  
454      conf->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(name)));
455  
456      /* host */
457      if (conf->host)
458          g_free(conf->host);
459  
460      conf->host = g_strdup(gtk_entry_get_text(GTK_ENTRY(host)));
461  
462      /* port */
463      conf->port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(port));
464  
465      /* lo down freq */
466      conf->lo = 1000000.0 * gtk_spin_button_get_value(GTK_SPIN_BUTTON(lo));
467  
468      /* lo up freq */
469      conf->loup = 1000000.0 * gtk_spin_button_get_value(GTK_SPIN_BUTTON(loup));
470  
471      /* rig type */
472      conf->type = gtk_combo_box_get_active(GTK_COMBO_BOX(type));
473  
474      /* ptt */
475      conf->ptt = gtk_combo_box_get_active(GTK_COMBO_BOX(ptt));
476  
477      /* vfo up/down */
478      if (conf->type == RIG_TYPE_DUPLEX)
479      {
480          switch (gtk_combo_box_get_active(GTK_COMBO_BOX(vfo)))
481          {
482  
483          case 1:
484              conf->vfoUp = VFO_MAIN;
485              conf->vfoDown = VFO_SUB;
486              break;
487  
488          case 2:
489              conf->vfoUp = VFO_SUB;
490              conf->vfoDown = VFO_MAIN;
491              break;
492  
493          case 3:
494              conf->vfoUp = VFO_A;
495              conf->vfoDown = VFO_B;
496              break;
497  
498          case 4:
499              conf->vfoUp = VFO_B;
500              conf->vfoDown = VFO_A;
501              break;
502  
503          default:
504              conf->vfoUp = VFO_MAIN;
505              conf->vfoDown = VFO_SUB;
506              break;
507          }
508      }
509  
510      /* AOS / LOS signalling */
511      conf->signal_aos = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sigaos));
512      conf->signal_los = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(siglos));
513  
514      return TRUE;
515  }
516  
517  /* Add or edit a radio configuration */
518  void sat_pref_rig_editor_run(radio_conf_t * conf)
519  {
520      gint            response;
521      gboolean        finished = FALSE;
522  
523      /* create dialog and add contents */
524      dialog = gtk_dialog_new_with_buttons(_("Edit radio configuration"),
525                                           GTK_WINDOW(window),
526                                           GTK_DIALOG_MODAL |
527                                           GTK_DIALOG_DESTROY_WITH_PARENT,
528                                           "_Clear", GTK_RESPONSE_REJECT,
529                                           "_Cancel", GTK_RESPONSE_CANCEL,
530                                           "_Ok", GTK_RESPONSE_OK,
531                                           NULL);
532  
533      /* disable OK button to begin with */
534      gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
535                                        GTK_RESPONSE_OK, FALSE);
536  
537      gtk_container_add(GTK_CONTAINER
538                        (gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
539                        create_editor_widgets(conf));
540  
541      /* keep the dialog running when CLEAR button is plressed
542       * OK and CANCEL will exit the loop
543       */
544      while (!finished)
545      {
546          response = gtk_dialog_run(GTK_DIALOG(dialog));
547  
548          switch (response)
549          {
550              /* OK */
551          case GTK_RESPONSE_OK:
552              if (apply_changes(conf))
553                  finished = TRUE;
554              else
555                  finished = FALSE;
556              break;
557  
558              /* CLEAR */
559          case GTK_RESPONSE_REJECT:
560              clear_widgets();
561              break;
562  
563              /* Everything else is considered CANCEL */
564          default:
565              finished = TRUE;
566              break;
567          }
568      }
569  
570      gtk_widget_destroy(dialog);
571  }