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 }