Qt client - remove right click menu from end turn sidebar
[freeciv.git] / client / gui-gtk-2.0 / cma_fe.c
blobcf15f64b3d096350f45f509ae95a7a36059cc223
1 /***********************************************************************
2 Freeciv - Copyright (C) 2001 - R. Falke, M. Kaufman
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <gdk/gdkkeysyms.h>
20 /* utility */
21 #include "fcintl.h"
22 #include "log.h"
23 #include "mem.h"
24 #include "support.h"
26 /* common */
27 #include "events.h"
28 #include "game.h"
30 /* client */
31 #include "chatline_g.h"
32 #include "citydlg_g.h"
33 #include "client_main.h"
34 #include "cma_fec.h"
35 #include "messagewin_g.h"
37 /* gtk-2.0 */
38 #include "cityrep.h"
39 #include "dialogs.h"
40 #include "gui_stuff.h"
41 #include "helpdlg.h"
42 #include "inputdlg.h"
44 #include "cma_fe.h"
46 #define BUFFER_SIZE 64
48 #define SPECLIST_TAG dialog
49 #define SPECLIST_TYPE struct cma_dialog
50 #include "speclist.h"
52 #define dialog_list_iterate(dialoglist, pdialog) \
53 TYPED_LIST_ITERATE(struct cma_dialog, dialoglist, pdialog)
54 #define dialog_list_iterate_end LIST_ITERATE_END
56 static struct dialog_list *dialog_list;
58 static int allow_refreshes = 1;
60 static struct cma_dialog *get_cma_dialog(struct city *pcity);
62 static void update_cma_preset_list(struct cma_dialog *pdialog);
64 static gboolean cma_preset_key_pressed_callback(GtkWidget *w, GdkEventKey *ev,
65 gpointer data);
66 static void cma_del_preset_callback(GtkWidget *w, gpointer data);
67 static void cma_preset_remove(struct cma_dialog *pdialog, int preset_index);
68 static void cma_preset_remove_response(GtkWidget *w, gint response,
69 gpointer data);
71 static void cma_add_preset_callback(GtkWidget *w, gpointer data);
72 static void cma_preset_add_popup_callback(gpointer data, gint response,
73 const char *input);
75 static void cma_active_callback(GtkWidget *w, gpointer data);
76 static void cma_activate_preset_callback(GtkTreeView *view, GtkTreePath *path,
77 GtkTreeViewColumn *col, gpointer data);
79 static void hscale_changed(GtkAdjustment *get, gpointer data);
80 static void set_hscales(const struct cm_parameter *const parameter,
81 struct cma_dialog *pdialog);
83 /**************************************************************************
84 Initialize cma front end system
85 **************************************************************************/
86 void cma_fe_init()
88 dialog_list = dialog_list_new();
91 /**************************************************************************
92 Free resources allocated for cma front end system
93 **************************************************************************/
94 void cma_fe_done()
96 dialog_list_destroy(dialog_list);
99 /**************************************************************************
100 only called when the city dialog is closed.
101 **************************************************************************/
102 void close_cma_dialog(struct city *pcity)
104 struct cma_dialog *pdialog = get_cma_dialog(pcity);
106 if (pdialog == NULL) {
107 /* A city which is being investigated doesn't contain cma dialog */
108 return;
110 gtk_widget_destroy(pdialog->shell);
113 /**************************************************************************
114 Destroy cma dialog
115 **************************************************************************/
116 static void cma_dialog_destroy_callback(GtkWidget *w, gpointer data)
118 struct cma_dialog *pdialog = (struct cma_dialog *) data;
120 dialog_list_remove(dialog_list, pdialog);
121 free(pdialog);
124 /****************************************************************
125 return the cma_dialog for a given city.
126 *****************************************************************/
127 struct cma_dialog *get_cma_dialog(struct city *pcity)
129 dialog_list_iterate(dialog_list, pdialog) {
130 if (pdialog->pcity == pcity) {
131 return pdialog;
133 } dialog_list_iterate_end;
135 return NULL;
138 /**************************************************************************
139 User has pressed button in cma dialog
140 **************************************************************************/
141 static gboolean button_press_callback(GtkTreeView *view, GdkEventButton *ev,
142 gpointer data)
144 GtkTreePath *path;
145 GtkTreeViewColumn *column;
147 if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(view),
148 ev->x, ev->y, &path, &column, NULL, NULL)) {
149 if (ev->type == GDK_BUTTON_PRESS) {
150 cma_activate_preset_callback(view, path, column, data);
151 } else if (ev->type == GDK_2BUTTON_PRESS) {
152 struct cma_dialog *pdialog = (struct cma_dialog *) data;
153 struct cm_parameter param;
155 cmafec_get_fe_parameter(pdialog->pcity, &param);
156 cma_put_city_under_agent(pdialog->pcity, &param);
157 refresh_city_dialog(pdialog->pcity);
160 gtk_tree_path_free(path);
162 return FALSE;
165 /**************************************************************************
166 User has requested help
167 **************************************************************************/
168 static void help_callback(GtkWidget *w, gpointer data)
170 popup_help_dialog_string(HELP_CMA_ITEM);
173 /**************************************************************************
174 Cell data function for cma dialog
175 **************************************************************************/
176 static void cell_data_func(GtkTreeViewColumn *col, GtkCellRenderer *cell,
177 GtkTreeModel *model, GtkTreeIter *it, gpointer data)
179 struct cma_dialog *pdialog = (struct cma_dialog *) data;
180 char *s1;
181 const char *s2;
182 int i1, i2;
183 struct cm_parameter param;
184 GtkTreePath *path;
186 gtk_tree_model_get(model, it, 0, &s1, -1);
187 if (s1 == NULL) {
188 return;
190 path = gtk_tree_model_get_path(model, it);
191 i1 = gtk_tree_path_get_indices(path)[0];
192 gtk_tree_path_free(path);
194 cmafec_get_fe_parameter(pdialog->pcity, &param);
195 s2 = cmafec_get_short_descr(&param);
196 i2 = cmafec_preset_get_index_of_parameter(&param);
198 if (!strcmp(s1, s2) && i1 == i2) {
199 g_object_set(G_OBJECT(cell), "style", PANGO_STYLE_ITALIC,
200 "weight", PANGO_WEIGHT_BOLD, NULL);
201 } else {
202 g_object_set(G_OBJECT(cell), "style", PANGO_STYLE_NORMAL,
203 "weight", PANGO_WEIGHT_NORMAL, NULL);
206 g_free(s1);
209 /**************************************************************************
210 Instantiates a new struct for each city_dialog window that is open.
211 **************************************************************************/
212 struct cma_dialog *create_cma_dialog(struct city *pcity)
214 struct cma_dialog *pdialog;
215 struct cm_parameter param;
216 GtkWidget *frame, *page, *hbox, *label, *table;
217 GtkWidget *vbox, *sw, *hscale, *button, *align, *image;
218 GtkListStore *store;
219 GtkCellRenderer *rend;
220 GtkWidget *view;
221 GtkTreeViewColumn *column;
223 cmafec_get_fe_parameter(pcity, &param);
224 pdialog = fc_malloc(sizeof(struct cma_dialog));
225 pdialog->pcity = pcity;
226 pdialog->shell = gtk_vbox_new(FALSE, 8);
227 gtk_container_set_border_width(GTK_CONTAINER(pdialog->shell), 8);
228 g_signal_connect(pdialog->shell, "destroy",
229 G_CALLBACK(cma_dialog_destroy_callback), pdialog);
231 page = gtk_hbox_new(FALSE, 12);
232 gtk_box_pack_start(GTK_BOX(pdialog->shell), page, TRUE, TRUE, 0);
234 vbox = gtk_vbox_new(FALSE, 2);
235 gtk_box_pack_start(GTK_BOX(page), vbox, TRUE, TRUE, 0);
237 sw = gtk_scrolled_window_new(NULL, NULL);
238 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
239 GTK_SHADOW_ETCHED_IN);
240 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
241 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
243 store = gtk_list_store_new(1, G_TYPE_STRING);
244 pdialog->store = store;
246 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
247 g_object_unref(store);
248 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE);
249 pdialog->preset_list = view;
250 pdialog->selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
252 g_signal_connect(pdialog->preset_list, "button_press_event",
253 G_CALLBACK(button_press_callback), pdialog);
255 gtk_widget_set_tooltip_text(view,
256 _("For information on\n"
257 "the citizen governor and governor presets,\n"
258 "including sample presets,\n"
259 "see README.governor."));
261 rend = gtk_cell_renderer_text_new();
262 column = gtk_tree_view_column_new_with_attributes(NULL, rend,
263 "text", 0, NULL);
264 gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);
265 gtk_tree_view_column_set_cell_data_func(column, rend, cell_data_func,
266 pdialog, NULL);
268 label = g_object_new(GTK_TYPE_LABEL,
269 "use-underline", TRUE,
270 "mnemonic-widget", view,
271 "label", _("Prese_ts:"),
272 "xalign", 0.0, "yalign", 0.5, NULL);
273 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
275 gtk_container_add(GTK_CONTAINER(sw), view);
276 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
278 g_signal_connect(view, "row_activated",
279 G_CALLBACK(cma_activate_preset_callback), pdialog);
280 g_signal_connect(view, "key-press-event",
281 G_CALLBACK(cma_preset_key_pressed_callback), pdialog);
283 hbox = gtk_hbutton_box_new();
284 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_EDGE);
285 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
287 button = gtk_button_new_with_mnemonic(_("Ne_w"));
288 image = gtk_image_new_from_stock(GTK_STOCK_NEW, GTK_ICON_SIZE_BUTTON);
289 gtk_button_set_image(GTK_BUTTON(button), image);
290 gtk_container_add(GTK_CONTAINER(hbox), button);
291 g_signal_connect(button, "clicked",
292 G_CALLBACK(cma_add_preset_callback), pdialog);
293 pdialog->add_preset_command = button;
295 pdialog->del_preset_command = gtk_button_new_from_stock(GTK_STOCK_DELETE);
296 gtk_container_add(GTK_CONTAINER(hbox), pdialog->del_preset_command);
297 g_signal_connect(pdialog->del_preset_command, "clicked",
298 G_CALLBACK(cma_del_preset_callback), pdialog);
300 /* the right-hand side */
302 vbox = gtk_vbox_new(FALSE, 0);
303 gtk_box_pack_start(GTK_BOX(page), vbox, FALSE, FALSE, 2);
305 /* Result */
307 frame = gtk_frame_new(_("Results"));
308 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, FALSE, 0);
310 pdialog->result_label =
311 gtk_label_new("food\n prod\n trade\n\n people\n grow\n prod\n name");
312 gtk_widget_set_name(pdialog->result_label, "city_label");
313 gtk_container_add(GTK_CONTAINER(frame), pdialog->result_label);
314 gtk_label_set_justify(GTK_LABEL(pdialog->result_label), GTK_JUSTIFY_LEFT);
316 /* Minimal Surplus and Factor */
318 table = gtk_table_new(O_LAST + 2, 3, TRUE);
319 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 2);
321 label = gtk_label_new(_("Minimal Surplus"));
322 gtk_misc_set_alignment(GTK_MISC(label), 0.1, 0.5);
323 gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 0, 1);
324 label = gtk_label_new(_("Factor"));
325 gtk_misc_set_alignment(GTK_MISC(label), 0.1, 0.5);
326 gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 0, 1);
328 output_type_iterate(i) {
329 label = gtk_label_new(get_output_name(i));
330 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, i + 1, i + 2);
331 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
333 pdialog->minimal_surplus[i] =
334 GTK_ADJUSTMENT(gtk_adjustment_new(-20, -20, 20, 1, 1, 0));
336 hscale = gtk_hscale_new(GTK_ADJUSTMENT(pdialog->minimal_surplus[i]));
337 gtk_table_attach_defaults(GTK_TABLE(table), hscale, 1, 2, i + 1, i + 2);
338 gtk_scale_set_digits(GTK_SCALE(hscale), 0);
339 gtk_scale_set_value_pos(GTK_SCALE(hscale), GTK_POS_LEFT);
341 g_signal_connect(pdialog->minimal_surplus[i],
342 "value_changed",
343 G_CALLBACK(hscale_changed), pdialog);
345 pdialog->factor[i] =
346 GTK_ADJUSTMENT(gtk_adjustment_new(1, 0, 25, 1, 1, 0));
348 hscale = gtk_hscale_new(GTK_ADJUSTMENT(pdialog->factor[i]));
349 gtk_table_attach_defaults(GTK_TABLE(table), hscale, 2, 3, i + 1, i + 2);
350 gtk_scale_set_digits(GTK_SCALE(hscale), 0);
351 gtk_scale_set_value_pos(GTK_SCALE(hscale), GTK_POS_LEFT);
353 g_signal_connect(pdialog->factor[i], "value_changed",
354 G_CALLBACK(hscale_changed), pdialog);
355 } output_type_iterate_end;
357 /* Happy Surplus and Factor */
359 label = gtk_label_new(_("Celebrate"));
360 gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1,
361 O_LAST + 1, O_LAST + 2);
362 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
364 hbox = gtk_hbox_new(FALSE, 0);
365 gtk_table_attach_defaults(GTK_TABLE(table), hbox, 1, 2,
366 O_LAST + 1, O_LAST + 2);
368 pdialog->happy_button = gtk_check_button_new();
369 gtk_box_pack_start(GTK_BOX(hbox), pdialog->happy_button, FALSE, FALSE,
370 20);
371 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pdialog->happy_button),
372 FALSE);
374 g_signal_connect(pdialog->happy_button, "toggled",
375 G_CALLBACK(hscale_changed), pdialog);
377 pdialog->factor[O_LAST] =
378 GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, 50, 1, 1, 0));
380 hscale = gtk_hscale_new(GTK_ADJUSTMENT(pdialog->factor[O_LAST]));
381 gtk_table_attach_defaults(GTK_TABLE(table), hscale, 2, 3,
382 O_LAST + 1, O_LAST + 2);
383 gtk_scale_set_digits(GTK_SCALE(hscale), 0);
384 gtk_scale_set_value_pos(GTK_SCALE(hscale), GTK_POS_LEFT);
386 g_signal_connect(pdialog->factor[O_LAST],
387 "value_changed",
388 G_CALLBACK(hscale_changed), pdialog);
390 /* buttons */
392 hbox = gtk_hbutton_box_new();
393 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_EDGE);
394 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
396 button = gtk_button_new_from_stock(GTK_STOCK_HELP);
397 g_signal_connect(button, "clicked",
398 G_CALLBACK(help_callback), NULL);
399 gtk_container_add(GTK_CONTAINER(hbox), button);
401 pdialog->active_command = gtk_toggle_button_new();
402 gtk_container_add(GTK_CONTAINER(hbox), pdialog->active_command);
404 align = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
405 gtk_container_add(GTK_CONTAINER(pdialog->active_command), align);
407 vbox = gtk_vbox_new(FALSE, 2);
408 gtk_container_add(GTK_CONTAINER(align), vbox);
410 pdialog->active_image = gtk_image_new();
411 gtk_box_pack_start(GTK_BOX(vbox), pdialog->active_image, FALSE, FALSE, 0);
413 pdialog->active_label = gtk_label_new(NULL);
414 gtk_widget_set_name(pdialog->active_label, "comment_label");
415 gtk_box_pack_end(GTK_BOX(vbox), pdialog->active_label, FALSE, FALSE, 0);
417 gtk_widget_show_all(pdialog->shell);
419 dialog_list_prepend(dialog_list, pdialog);
421 update_cma_preset_list(pdialog);
423 gtk_tree_view_focus(GTK_TREE_VIEW(view));
425 /* refresh is done in refresh_city_dialog */
427 return pdialog;
430 /**************************************************************************
431 refreshes the cma dialog
432 **************************************************************************/
433 void refresh_cma_dialog(struct city *pcity, enum cma_refresh refresh)
435 struct cm_result *result = cm_result_new(pcity);
436 struct cm_parameter param;
437 struct cma_dialog *pdialog = get_cma_dialog(pcity);
438 int controlled = cma_is_city_under_agent(pcity, NULL);
440 cmafec_get_fe_parameter(pcity, &param);
442 /* fill in result label */
443 cm_result_from_main_map(result, pcity);
444 gtk_label_set_text(GTK_LABEL(pdialog->result_label),
445 cmafec_get_result_descr(pcity, result, &param));
447 /* if called from a hscale, we _don't_ want to do this */
448 if (refresh != DONT_REFRESH_HSCALES) {
449 set_hscales(&param, pdialog);
452 gtk_widget_queue_draw(pdialog->preset_list);
454 gtk_widget_set_sensitive(pdialog->active_command, can_client_issue_orders());
456 g_signal_handlers_disconnect_matched(pdialog->active_command,
457 G_SIGNAL_MATCH_FUNC,
458 0, 0, NULL, cma_active_callback, NULL);
459 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pdialog->active_command),
460 controlled);
461 g_signal_connect(pdialog->active_command, "clicked",
462 G_CALLBACK(cma_active_callback), pdialog);
464 if (controlled) {
465 gtk_image_set_from_stock(GTK_IMAGE(pdialog->active_image),
466 GTK_STOCK_YES, GTK_ICON_SIZE_DND);
467 gtk_label_set_text_with_mnemonic(GTK_LABEL(pdialog->active_label),
468 _("Governor Enabl_ed"));
469 } else {
470 gtk_image_set_from_stock(GTK_IMAGE(pdialog->active_image),
471 GTK_STOCK_NO, GTK_ICON_SIZE_DND);
472 gtk_label_set_text_with_mnemonic(GTK_LABEL(pdialog->active_label),
473 _("Governor Disabl_ed"));
475 gtk_widget_set_sensitive(pdialog->result_label, controlled);
477 cm_result_destroy(result);
480 /**************************************************************************
481 fills in the preset list
482 **************************************************************************/
483 static void update_cma_preset_list(struct cma_dialog *pdialog)
485 char buf[BUFFER_SIZE];
486 GtkTreeIter it;
487 int i;
489 /* Fill preset list */
490 gtk_list_store_clear(pdialog->store);
492 /* Append the presets */
493 if (cmafec_preset_num()) {
494 for (i = 0; i < cmafec_preset_num(); i++) {
495 fc_strlcpy(buf, cmafec_preset_get_descr(i), sizeof(buf));
496 gtk_list_store_append(pdialog->store, &it);
497 gtk_list_store_set(pdialog->store, &it, 0, buf, -1);
502 /****************************************************************
503 callback for selecting a preset from the preset view
504 *****************************************************************/
505 static void cma_activate_preset_callback(GtkTreeView *view, GtkTreePath *path,
506 GtkTreeViewColumn *col, gpointer data)
508 struct cma_dialog *pdialog = (struct cma_dialog *) data;
509 int preset_index;
510 const struct cm_parameter *pparam;
512 preset_index = gtk_tree_path_get_indices(path) [0];
514 pparam = cmafec_preset_get_parameter(preset_index);
516 /* save the change */
517 cmafec_set_fe_parameter(pdialog->pcity, pparam);
519 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
520 cma_release_city(pdialog->pcity);
521 cma_put_city_under_agent(pdialog->pcity, pparam);
523 refresh_city_dialog(pdialog->pcity);
526 /**************************************************************************
527 pops up a dialog to allow to name your new preset
528 **************************************************************************/
529 static void cma_add_preset_callback(GtkWidget *w, gpointer data)
531 struct cma_dialog *pdialog = (struct cma_dialog *) data;
532 const char *default_name;
533 GtkWidget *parent = gtk_widget_get_toplevel(pdialog->shell);
534 int index;
536 if ((index = gtk_tree_selection_get_row(pdialog->selection)) != -1) {
537 default_name = cmafec_preset_get_descr(index);
538 } else {
539 default_name = _("new preset");
542 pdialog->name_shell = input_dialog_create(GTK_WINDOW(parent),
543 _("Name new preset"),
544 _("What should we name the preset?"),
545 default_name,
546 cma_preset_add_popup_callback, pdialog);
549 /****************************************************************
550 callback for the add_preset popup
551 *****************************************************************/
552 static void cma_preset_add_popup_callback(gpointer data, gint response,
553 const char *input)
555 struct cma_dialog *pdialog = (struct cma_dialog *) data;
557 if (pdialog) {
558 if (response == GTK_RESPONSE_OK) {
559 struct cm_parameter param;
561 cmafec_get_fe_parameter(pdialog->pcity, &param);
562 cmafec_preset_add(input, &param);
563 update_cma_preset_list(pdialog);
564 refresh_cma_dialog(pdialog->pcity, DONT_REFRESH_HSCALES);
565 /* if this or other cities have this set as "custom" */
566 city_report_dialog_update();
567 } /* else CANCEL or DELETE_EVENT */
569 pdialog->name_shell = NULL;
573 /****************************************************************
574 Key pressed in preset list
575 *****************************************************************/
576 static gboolean cma_preset_key_pressed_callback(GtkWidget *w, GdkEventKey *ev,
577 gpointer data)
579 struct cma_dialog *pdialog = (struct cma_dialog *) data;
580 int index;
582 if ((index = gtk_tree_selection_get_row(pdialog->selection)) == -1) {
583 return FALSE;
586 if (ev->type == GDK_KEY_PRESS) {
587 switch (ev->keyval) {
588 case GDK_Delete:
589 cma_preset_remove(pdialog, index);
590 break;
591 case GDK_Insert:
592 cma_add_preset_callback(NULL, pdialog);
593 break;
594 default:
595 return FALSE;
597 return TRUE;
599 return FALSE;
603 /**************************************************************************
604 callback for del_preset
605 **************************************************************************/
606 static void cma_del_preset_callback(GtkWidget *w, gpointer data)
608 struct cma_dialog *pdialog = (struct cma_dialog *) data;
609 int index;
611 if ((index = gtk_tree_selection_get_row(pdialog->selection)) == -1) {
612 return;
615 cma_preset_remove(pdialog, index);
618 /**************************************************************************
619 pops up a dialog to remove a preset
620 **************************************************************************/
621 static void cma_preset_remove(struct cma_dialog *pdialog, int preset_index)
623 GtkWidget *parent = gtk_widget_get_toplevel(pdialog->shell), *shl;
625 pdialog->id = preset_index;
626 shl = gtk_message_dialog_new(NULL,
627 GTK_DIALOG_DESTROY_WITH_PARENT,
628 GTK_MESSAGE_QUESTION,
629 GTK_BUTTONS_YES_NO,
630 _("Remove this preset?"));
631 setup_dialog(shl, parent);
632 pdialog->preset_remove_shell = shl;
634 gtk_window_set_title(GTK_WINDOW(shl), cmafec_preset_get_descr(preset_index));
635 gtk_window_set_position(GTK_WINDOW(shl), GTK_WIN_POS_CENTER_ON_PARENT);
637 g_signal_connect(shl, "response",
638 G_CALLBACK(cma_preset_remove_response), pdialog);
640 gtk_window_present(GTK_WINDOW(shl));
643 /****************************************************************
644 callback for the remove_preset popup
645 *****************************************************************/
646 static void cma_preset_remove_response(GtkWidget *w, gint response,
647 gpointer data)
649 struct cma_dialog *pdialog = (struct cma_dialog *) data;
651 if (response == GTK_RESPONSE_YES) {
652 cmafec_preset_remove(pdialog->id);
653 pdialog->id = -1;
654 update_cma_preset_list(pdialog);
655 refresh_cma_dialog(pdialog->pcity, DONT_REFRESH_HSCALES);
656 /* if this or other cities have this set, reset to "custom" */
657 city_report_dialog_update();
659 gtk_widget_destroy(w);
661 pdialog->preset_remove_shell = NULL;
664 /**************************************************************************
665 activates/deactivates agent control.
666 **************************************************************************/
667 static void cma_active_callback(GtkWidget *w, gpointer data)
669 struct cma_dialog *pdialog = (struct cma_dialog *) data;
671 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
672 cma_release_city(pdialog->pcity);
673 } else {
674 struct cm_parameter param;
676 cmafec_get_fe_parameter(pdialog->pcity, &param);
677 cma_put_city_under_agent(pdialog->pcity, &param);
679 refresh_city_dialog(pdialog->pcity);
682 /****************************************************************
683 called to adjust the sliders when a preset is selected
684 notice that we don't want to call update_result here.
685 *****************************************************************/
686 static void set_hscales(const struct cm_parameter *const parameter,
687 struct cma_dialog *pdialog)
689 allow_refreshes = 0;
690 output_type_iterate(i) {
691 gtk_adjustment_set_value(pdialog->minimal_surplus[i],
692 parameter->minimal_surplus[i]);
693 gtk_adjustment_set_value(pdialog->factor[i], parameter->factor[i]);
694 } output_type_iterate_end;
695 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pdialog->happy_button),
696 parameter->require_happy);
697 gtk_adjustment_set_value(pdialog->factor[O_LAST],
698 parameter->happy_factor);
699 allow_refreshes = 1;
702 /************************************************************************
703 callback if we moved the sliders.
704 *************************************************************************/
705 static void hscale_changed(GtkAdjustment *get, gpointer data)
707 struct cma_dialog *pdialog = (struct cma_dialog *) data;
708 struct cm_parameter param;
710 if (!allow_refreshes) {
711 return;
714 cmafec_get_fe_parameter(pdialog->pcity, &param);
715 output_type_iterate(i) {
716 param.minimal_surplus[i] = (int) (pdialog->minimal_surplus[i]->value);
717 param.factor[i] = (int) (pdialog->factor[i]->value);
718 } output_type_iterate_end;
719 param.require_happy =
720 (GTK_TOGGLE_BUTTON(pdialog->happy_button)->active ? 1 : 0);
721 param.happy_factor = (int) (pdialog->factor[O_LAST]->value);
723 /* save the change */
724 cmafec_set_fe_parameter(pdialog->pcity, &param);
726 /* refreshes the cma */
727 if (cma_is_city_under_agent(pdialog->pcity, NULL)) {
728 cma_release_city(pdialog->pcity);
729 cma_put_city_under_agent(pdialog->pcity, &param);
730 refresh_city_dialog(pdialog->pcity);
731 } else {
732 refresh_cma_dialog(pdialog->pcity, DONT_REFRESH_HSCALES);