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)
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 ***********************************************************************/
15 #include <fc_config.h>
18 #include <gdk/gdkkeysyms.h>
31 #include "chatline_g.h"
32 #include "citydlg_g.h"
33 #include "client_main.h"
35 #include "messagewin_g.h"
40 #include "gui_stuff.h"
46 #define BUFFER_SIZE 64
48 #define SPECLIST_TAG dialog
49 #define SPECLIST_TYPE struct cma_dialog
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
,
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
,
71 static void cma_add_preset_callback(GtkWidget
*w
, gpointer data
);
72 static void cma_preset_add_popup_callback(gpointer data
, gint response
,
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 **************************************************************************/
88 dialog_list
= dialog_list_new();
91 /**************************************************************************
92 Free resources allocated for cma front end system
93 **************************************************************************/
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 */
110 gtk_widget_destroy(pdialog
->shell
);
113 /**************************************************************************
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
);
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
) {
133 } dialog_list_iterate_end
;
138 /**************************************************************************
139 User has pressed button in cma dialog
140 **************************************************************************/
141 static gboolean
button_press_callback(GtkTreeView
*view
, GdkEventButton
*ev
,
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
, ¶m
);
156 cma_put_city_under_agent(pdialog
->pcity
, ¶m
);
157 refresh_city_dialog(pdialog
->pcity
);
160 gtk_tree_path_free(path
);
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
;
183 struct cm_parameter param
;
186 gtk_tree_model_get(model
, it
, 0, &s1
, -1);
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
, ¶m
);
195 s2
= cmafec_get_short_descr(¶m
);
196 i2
= cmafec_preset_get_index_of_parameter(¶m
);
198 if (!strcmp(s1
, s2
) && i1
== i2
) {
199 g_object_set(G_OBJECT(cell
), "style", PANGO_STYLE_ITALIC
,
200 "weight", PANGO_WEIGHT_BOLD
, NULL
);
202 g_object_set(G_OBJECT(cell
), "style", PANGO_STYLE_NORMAL
,
203 "weight", PANGO_WEIGHT_NORMAL
, NULL
);
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
;
219 GtkCellRenderer
*rend
;
221 GtkTreeViewColumn
*column
;
223 cmafec_get_fe_parameter(pcity
, ¶m
);
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
,
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
,
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);
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
],
343 G_CALLBACK(hscale_changed
), pdialog
);
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
,
371 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pdialog
->happy_button
),
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
],
388 G_CALLBACK(hscale_changed
), pdialog
);
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 */
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
, ¶m
);
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
, ¶m
));
447 /* if called from a hscale, we _don't_ want to do this */
448 if (refresh
!= DONT_REFRESH_HSCALES
) {
449 set_hscales(¶m
, 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
,
458 0, 0, NULL
, cma_active_callback
, NULL
);
459 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pdialog
->active_command
),
461 g_signal_connect(pdialog
->active_command
, "clicked",
462 G_CALLBACK(cma_active_callback
), pdialog
);
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"));
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
];
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
;
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
);
536 if ((index
= gtk_tree_selection_get_row(pdialog
->selection
)) != -1) {
537 default_name
= cmafec_preset_get_descr(index
);
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?"),
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
,
555 struct cma_dialog
*pdialog
= (struct cma_dialog
*) data
;
558 if (response
== GTK_RESPONSE_OK
) {
559 struct cm_parameter param
;
561 cmafec_get_fe_parameter(pdialog
->pcity
, ¶m
);
562 cmafec_preset_add(input
, ¶m
);
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
,
579 struct cma_dialog
*pdialog
= (struct cma_dialog
*) data
;
582 if ((index
= gtk_tree_selection_get_row(pdialog
->selection
)) == -1) {
586 if (ev
->type
== GDK_KEY_PRESS
) {
587 switch (ev
->keyval
) {
589 cma_preset_remove(pdialog
, index
);
592 cma_add_preset_callback(NULL
, pdialog
);
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
;
611 if ((index
= gtk_tree_selection_get_row(pdialog
->selection
)) == -1) {
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
,
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
,
649 struct cma_dialog
*pdialog
= (struct cma_dialog
*) data
;
651 if (response
== GTK_RESPONSE_YES
) {
652 cmafec_preset_remove(pdialog
->id
);
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
);
674 struct cm_parameter param
;
676 cmafec_get_fe_parameter(pdialog
->pcity
, ¶m
);
677 cma_put_city_under_agent(pdialog
->pcity
, ¶m
);
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
)
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
);
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
) {
714 cmafec_get_fe_parameter(pdialog
->pcity
, ¶m
);
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
, ¶m
);
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
, ¶m
);
730 refresh_city_dialog(pdialog
->pcity
);
732 refresh_cma_dialog(pdialog
->pcity
, DONT_REFRESH_HSCALES
);