1 /**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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>
36 #include "mpcmdline.h"
41 static GtkWidget
*statusbar
;
42 static GtkWidget
*progressbar
;
43 static GtkWidget
*main_list
;
44 static GtkListStore
*main_store
;
45 static GtkWidget
*URL_input
;
46 static gboolean downloading
= FALSE
;
48 struct fcmp_params fcmp
= {
49 .list_url
= MODPACK_LIST_URL
,
54 static gboolean
quit_dialog_callback(void);
60 #define ML_COL_SUBTYPE 4
64 #define ML_COL_COUNT 7
68 #define ML_STORE_SIZE 9
70 /****************************************************************
72 ****************************************************************/
73 static void modinst_quit(void)
75 save_install_info_lists(&fcmp
);
77 registry_module_close();
83 /****************************************************************
84 This is the response callback for the dialog with the message:
85 Are you sure you want to quit?
86 ****************************************************************/
87 static void quit_dialog_response(GtkWidget
*dialog
, gint response
)
89 gtk_widget_destroy(dialog
);
90 if (response
== GTK_RESPONSE_YES
) {
95 /****************************************************************
96 Popups the quit dialog if
97 ****************************************************************/
98 static gboolean
quit_dialog_callback(void)
101 /* Download in progress. Confirm quit from user. */
102 static GtkWidget
*dialog
;
105 dialog
= gtk_message_dialog_new(NULL
,
109 _("Are you sure you want to quit?"));
111 gtk_window_set_position(GTK_WINDOW(dialog
), GTK_WIN_POS_MOUSE
);
113 g_signal_connect(dialog
, "response",
114 G_CALLBACK(quit_dialog_response
), NULL
);
115 g_signal_connect(dialog
, "destroy",
116 G_CALLBACK(gtk_widget_destroyed
), &dialog
);
119 gtk_window_present(GTK_WINDOW(dialog
));
122 /* User loses no work by quitting, so let's not annoy him/her
123 * with confirmation dialog. */
127 /* Stop emission of event. */
131 /**************************************************************************
132 Progress indications from downloader
133 **************************************************************************/
134 static void msg_callback(const char *msg
)
136 gtk_label_set_text(GTK_LABEL(statusbar
), msg
);
139 /**************************************************************************
140 Progress indications from downloader
141 **************************************************************************/
142 static void pbar_callback(int downloaded
, int max
)
144 /* Control file already downloaded */
145 double fraction
= (double) downloaded
/ (max
);
147 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar
), fraction
);
150 /**************************************************************************
151 Entry point for downloader thread
152 **************************************************************************/
153 static gpointer
download_thread(gpointer data
)
158 errmsg
= download_modpack(data
, &fcmp
, msg_callback
, pbar_callback
);
160 if (errmsg
== NULL
) {
161 gtk_label_set_text(GTK_LABEL(statusbar
), _("Ready"));
163 gtk_label_set_text(GTK_LABEL(statusbar
), errmsg
);
168 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(main_store
), &iter
)) {
170 const char *name_str
;
172 const char *new_inst
;
173 enum modpack_type type
;
175 gtk_tree_model_get(GTK_TREE_MODEL(main_store
), &iter
,
176 ML_COL_NAME
, &name_str
,
182 new_inst
= get_installed_version(name_str
, type
);
184 if (new_inst
== NULL
) {
185 new_inst
= _("Not installed");
188 gtk_list_store_set(main_store
, &iter
,
189 ML_COL_INST
, new_inst
,
192 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(main_store
), &iter
));
200 /**************************************************************************
201 Download modpack, display error message dialogs
202 **************************************************************************/
203 static void gui_download_modpack(const char *URL
)
209 gtk_label_set_text(GTK_LABEL(statusbar
),
210 _("Another download already active"));
216 URLbuf
= fc_malloc(strlen(URL
) + 1);
220 downloader
= g_thread_create(download_thread
, URLbuf
, FALSE
, NULL
);
221 if (downloader
== NULL
) {
222 gtk_label_set_text(GTK_LABEL(statusbar
),
223 _("Failed to start downloader"));
228 /**************************************************************************
229 Install modpack button clicked
230 **************************************************************************/
231 static void install_clicked(GtkWidget
*w
, gpointer data
)
233 GtkEntry
*URL_in
= data
;
234 const char *URL
= gtk_entry_get_text(URL_in
);
236 gui_download_modpack(URL
);
239 /**************************************************************************
241 **************************************************************************/
242 static void URL_return(GtkEntry
*w
, gpointer data
)
246 URL
= gtk_entry_get_text(w
);
247 gui_download_modpack(URL
);
250 /**************************************************************************
251 Callback for getting main list row tooltip
252 **************************************************************************/
253 static gboolean
query_main_list_tooltip_cb(GtkWidget
*widget
,
255 gboolean keyboard_tip
,
260 GtkTreeView
*tree_view
= GTK_TREE_VIEW(widget
);
264 if (!gtk_tree_view_get_tooltip_context(tree_view
, &x
, &y
,
266 &model
, NULL
, &iter
)) {
270 gtk_tree_model_get(model
, &iter
,
275 gtk_tooltip_set_markup(tooltip
, notes
);
283 /**************************************************************************
284 Build main modpack list view
285 **************************************************************************/
286 static void setup_modpack_list(const char *name
, const char *URL
,
287 const char *version
, const char *license
,
288 enum modpack_type type
, const char *subtype
,
292 const char *type_str
;
294 const char *inst_str
;
296 if (modpack_type_is_valid(type
)) {
297 type_str
= _(modpack_type_name(type
));
299 /* TRANS: Unknown modpack type */
303 if (license
!= NULL
) {
306 /* TRANS: License of modpack is not known */
307 lic_str
= Q_("?license:Unknown");
310 inst_str
= get_installed_version(name
, type
);
311 if (inst_str
== NULL
) {
312 inst_str
= _("Not installed");
315 gtk_list_store_append(main_store
, &iter
);
316 gtk_list_store_set(main_store
, &iter
,
319 ML_COL_INST
, inst_str
,
320 ML_COL_TYPE
, type_str
,
321 ML_COL_SUBTYPE
, subtype
,
329 /**************************************************************************
330 Callback called when entry from main modpack list selected
331 **************************************************************************/
332 static void select_from_list(GtkTreeSelection
*select
, gpointer data
)
338 if (!gtk_tree_selection_get_selected(select
, &model
, &it
)) {
342 gtk_tree_model_get(model
, &it
, ML_COL_URL
, &URL
, -1);
344 gtk_entry_set_text(GTK_ENTRY(URL_input
), URL
);
347 /**************************************************************************
349 **************************************************************************/
350 static void modinst_setup_widgets(GtkWidget
*toplevel
)
352 GtkWidget
*mbox
, *Ubox
;
353 GtkWidget
*version_label
;
354 GtkWidget
*install_button
, *install_label
;
355 GtkWidget
*URL_label
;
356 GtkCellRenderer
*renderer
;
357 GtkTreeSelection
*selection
;
360 const char *rev_ver
= fc_svn_revision();
362 mbox
= gtk_vbox_new(FALSE
, 4);
364 if (rev_ver
== NULL
) {
365 fc_snprintf(verbuf
, sizeof(verbuf
), "%s%s", word_version(), VERSION_STRING
);
367 fc_snprintf(verbuf
, sizeof(verbuf
), "%s%s (%s)", word_version(), VERSION_STRING
,
371 version_label
= gtk_label_new(verbuf
);
373 main_list
= gtk_tree_view_new();
374 renderer
= gtk_cell_renderer_text_new();
375 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list
),
377 _("Name"), renderer
, "text", 0,
379 renderer
= gtk_cell_renderer_text_new();
380 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list
),
382 _("Version"), renderer
, "text", 1,
384 renderer
= gtk_cell_renderer_text_new();
385 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list
),
387 _("Installed"), renderer
, "text", 2,
389 renderer
= gtk_cell_renderer_text_new();
390 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list
),
395 renderer
= gtk_cell_renderer_text_new();
396 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list
),
401 renderer
= gtk_cell_renderer_text_new();
402 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list
),
405 _("License"), renderer
, "text", 5,
407 renderer
= gtk_cell_renderer_text_new();
408 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list
),
410 _("URL"), renderer
, "text", 6,
412 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(main_list
));
413 g_signal_connect(selection
, "changed", G_CALLBACK(select_from_list
), NULL
);
415 install_button
= gtk_button_new();
416 install_label
= gtk_label_new(_("Install modpack"));
417 gtk_label_set_mnemonic_widget(GTK_LABEL(install_label
), install_button
);
418 g_object_set_data(G_OBJECT(install_button
), "label", install_label
);
419 gtk_container_add(GTK_CONTAINER(install_button
), install_label
);
421 Ubox
= gtk_hbox_new(FALSE
, 4);
422 URL_label
= gtk_label_new_with_mnemonic(_("Modpack URL"));
424 URL_input
= gtk_entry_new();
425 gtk_entry_set_width_chars(GTK_ENTRY(URL_input
),
426 strlen(EXAMPLE_URL
));
427 gtk_entry_set_text(GTK_ENTRY(URL_input
), DEFAULT_URL_START
);
428 g_signal_connect(URL_input
, "activate",
429 G_CALLBACK(URL_return
), NULL
);
431 g_signal_connect(install_button
, "clicked",
432 G_CALLBACK(install_clicked
), URL_input
);
434 gtk_box_pack_start(GTK_BOX(Ubox
), URL_label
, TRUE
, TRUE
, 0);
435 gtk_box_pack_end(GTK_BOX(Ubox
), URL_input
, TRUE
, TRUE
, 0);
437 progressbar
= gtk_progress_bar_new();
439 statusbar
= gtk_label_new(_("Select modpack to install"));
441 gtk_box_pack_start(GTK_BOX(mbox
), version_label
, TRUE
, TRUE
, 0);
442 gtk_box_pack_start(GTK_BOX(mbox
), main_list
, TRUE
, TRUE
, 0);
443 gtk_box_pack_start(GTK_BOX(mbox
), Ubox
, TRUE
, TRUE
, 0);
444 gtk_box_pack_start(GTK_BOX(mbox
), install_button
, TRUE
, TRUE
, 0);
445 gtk_box_pack_start(GTK_BOX(mbox
), progressbar
, TRUE
, TRUE
, 0);
446 gtk_box_pack_end(GTK_BOX(mbox
), statusbar
, TRUE
, TRUE
, 0);
448 gtk_container_add(GTK_CONTAINER(toplevel
), mbox
);
450 main_store
= gtk_list_store_new((ML_STORE_SIZE
), G_TYPE_STRING
, G_TYPE_STRING
,
451 G_TYPE_STRING
, G_TYPE_STRING
, G_TYPE_STRING
,
452 G_TYPE_STRING
, G_TYPE_STRING
, G_TYPE_INT
,
454 errmsg
= download_modpack_list(&fcmp
, setup_modpack_list
, msg_callback
);
455 gtk_tree_view_set_model(GTK_TREE_VIEW(main_list
), GTK_TREE_MODEL(main_store
));
457 g_object_set(main_list
, "has-tooltip", TRUE
, NULL
);
458 g_signal_connect(main_list
, "query-tooltip",
459 G_CALLBACK(query_main_list_tooltip_cb
), NULL
);
461 g_object_unref(main_store
);
463 if (errmsg
!= NULL
) {
464 gtk_label_set_text(GTK_LABEL(statusbar
), errmsg
);
468 /**************************************************************************
469 Entry point of the freeciv-modpack program
470 **************************************************************************/
471 int main(int argc
, char *argv
[])
474 int loglevel
= LOG_NORMAL
;
478 init_character_encodings(FC_DEFAULT_DATA_ENCODING
, FALSE
);
479 registry_module_init();
485 log_init(NULL
, loglevel
, NULL
, NULL
, -1);
487 /* This modifies argv! */
488 ui_options
= fcmp_parse_cmdline(argc
, argv
);
490 if (ui_options
!= -1) {
492 load_install_info_lists(&fcmp
);
494 /* Process GTK arguments */
495 gtk_init(&ui_options
, &argv
);
497 toplevel
= gtk_window_new(GTK_WINDOW_TOPLEVEL
);
499 gtk_widget_realize(toplevel
);
500 gtk_widget_set_name(toplevel
, "Freeciv-modpack");
501 gtk_window_set_title(GTK_WINDOW(toplevel
),
502 _("Freeciv modpack installer (gtk2)"));
504 /* Keep the icon of the executable on Windows */
507 /* Unlike main client, this only works if installed. Ignore any
508 * errors loading the icon. */
510 (void) gtk_window_set_icon_from_file(GTK_WINDOW(toplevel
), MPICON_PATH
,
513 #endif /* WIN32_NATIVE */
515 g_signal_connect(toplevel
, "delete_event",
516 G_CALLBACK(quit_dialog_callback
), NULL
);
518 modinst_setup_widgets(toplevel
);
520 gtk_widget_show_all(toplevel
);
522 if (fcmp
.autoinstall
!= NULL
) {
523 gui_download_modpack(fcmp
.autoinstall
);
528 save_install_info_lists(&fcmp
);