Miscellaneous typo fixes, grammar tweaks, TRANS comments etc.
[freeciv.git] / tools / mpgui_gtk2.c
blob2fbdba90b153a5a380dc1909cb5395b254c3193b
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)
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 <stdlib.h>
20 #include <gtk/gtk.h>
22 /* utility */
23 #include "fciconv.h"
24 #include "fcintl.h"
25 #include "log.h"
26 #include "mem.h"
27 #include "netintf.h"
28 #include "registry.h"
29 #include "shared.h"
31 /* common */
32 #include "version.h"
34 /* modinst */
35 #include "download.h"
36 #include "mpcmdline.h"
37 #include "mpdb.h"
39 #include "modinst.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,
50 .inst_prefix = NULL,
51 .autoinstall = NULL
54 static gboolean quit_dialog_callback(void);
56 #define ML_COL_NAME 0
57 #define ML_COL_VER 1
58 #define ML_COL_INST 2
59 #define ML_COL_TYPE 3
60 #define ML_COL_SUBTYPE 4
61 #define ML_COL_LIC 5
62 #define ML_COL_URL 6
64 #define ML_COL_COUNT 7
66 #define ML_TYPE 7
67 #define ML_NOTES 8
68 #define ML_STORE_SIZE 9
70 /****************************************************************
71 freeciv-modpack quit
72 ****************************************************************/
73 static void modinst_quit(void)
75 save_install_info_lists(&fcmp);
77 registry_module_close();
78 free_nls();
80 exit(EXIT_SUCCESS);
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) {
91 modinst_quit();
95 /****************************************************************
96 Popups the quit dialog if
97 ****************************************************************/
98 static gboolean quit_dialog_callback(void)
100 if (downloading) {
101 /* Download in progress. Confirm quit from user. */
102 static GtkWidget *dialog;
104 if (!dialog) {
105 dialog = gtk_message_dialog_new(NULL,
107 GTK_MESSAGE_WARNING,
108 GTK_BUTTONS_YES_NO,
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));
121 } else {
122 /* User loses no work by quitting, so let's not annoy him/her
123 * with confirmation dialog. */
124 modinst_quit();
127 /* Stop emission of event. */
128 return TRUE;
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)
155 const char *errmsg;
156 GtkTreeIter iter;
158 errmsg = download_modpack(data, &fcmp, msg_callback, pbar_callback);
160 if (errmsg == NULL) {
161 gtk_label_set_text(GTK_LABEL(statusbar), _("Ready"));
162 } else {
163 gtk_label_set_text(GTK_LABEL(statusbar), errmsg);
166 free(data);
168 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(main_store), &iter)) {
169 do {
170 const char *name_str;
171 int type_int;
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,
177 ML_TYPE, &type_int,
178 -1);
180 type = type_int;
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,
190 -1);
192 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(main_store), &iter));
195 downloading = FALSE;
197 return NULL;
200 /**************************************************************************
201 Download modpack, display error message dialogs
202 **************************************************************************/
203 static void gui_download_modpack(const char *URL)
205 GThread *downloader;
206 char *URLbuf;
208 if (downloading) {
209 gtk_label_set_text(GTK_LABEL(statusbar),
210 _("Another download already active"));
211 return;
214 downloading = TRUE;
216 URLbuf = fc_malloc(strlen(URL) + 1);
218 strcpy(URLbuf, URL);
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"));
224 free(URLbuf);
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 /**************************************************************************
240 URL entered
241 **************************************************************************/
242 static void URL_return(GtkEntry *w, gpointer data)
244 const char *URL;
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,
254 gint x, gint y,
255 gboolean keyboard_tip,
256 GtkTooltip *tooltip,
257 gpointer data)
259 GtkTreeIter iter;
260 GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
261 GtkTreeModel *model;
262 const char *notes;
264 if (!gtk_tree_view_get_tooltip_context(tree_view, &x, &y,
265 keyboard_tip,
266 &model, NULL, &iter)) {
267 return FALSE;
270 gtk_tree_model_get(model, &iter,
271 ML_NOTES, &notes,
272 -1);
274 if (notes != NULL) {
275 gtk_tooltip_set_markup(tooltip, notes);
277 return TRUE;
280 return FALSE;
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,
289 const char *notes)
291 GtkTreeIter iter;
292 const char *type_str;
293 const char *lic_str;
294 const char *inst_str;
296 if (modpack_type_is_valid(type)) {
297 type_str = _(modpack_type_name(type));
298 } else {
299 /* TRANS: Unknown modpack type */
300 type_str = _("?");
303 if (license != NULL) {
304 lic_str = license;
305 } else {
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,
317 ML_COL_NAME, name,
318 ML_COL_VER, version,
319 ML_COL_INST, inst_str,
320 ML_COL_TYPE, type_str,
321 ML_COL_SUBTYPE, subtype,
322 ML_COL_LIC, lic_str,
323 ML_COL_URL, URL,
324 ML_TYPE, type,
325 ML_NOTES, notes,
326 -1);
329 /**************************************************************************
330 Callback called when entry from main modpack list selected
331 **************************************************************************/
332 static void select_from_list(GtkTreeSelection *select, gpointer data)
334 GtkTreeModel *model;
335 GtkTreeIter it;
336 const char *URL;
338 if (!gtk_tree_selection_get_selected(select, &model, &it)) {
339 return;
342 gtk_tree_model_get(model, &it, ML_COL_URL, &URL, -1);
344 gtk_entry_set_text(GTK_ENTRY(URL_input), URL);
347 /**************************************************************************
348 Build widgets
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;
358 const char *errmsg;
359 char verbuf[2048];
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);
366 } else {
367 fc_snprintf(verbuf, sizeof(verbuf), "%s%s (%s)", word_version(), VERSION_STRING,
368 rev_ver);
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),
376 ML_COL_NAME,
377 _("Name"), renderer, "text", 0,
378 NULL);
379 renderer = gtk_cell_renderer_text_new();
380 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list),
381 ML_COL_VER,
382 _("Version"), renderer, "text", 1,
383 NULL);
384 renderer = gtk_cell_renderer_text_new();
385 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list),
386 ML_COL_INST,
387 _("Installed"), renderer, "text", 2,
388 NULL);
389 renderer = gtk_cell_renderer_text_new();
390 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list),
391 ML_COL_TYPE,
392 Q_("?modpack:Type"),
393 renderer, "text", 3,
394 NULL);
395 renderer = gtk_cell_renderer_text_new();
396 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list),
397 ML_COL_SUBTYPE,
398 _("Subtype"),
399 renderer, "text", 4,
400 NULL);
401 renderer = gtk_cell_renderer_text_new();
402 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list),
403 ML_COL_LIC,
404 /* TRANS: noun */
405 _("License"), renderer, "text", 5,
406 NULL);
407 renderer = gtk_cell_renderer_text_new();
408 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(main_list),
409 ML_COL_URL,
410 _("URL"), renderer, "text", 6,
411 NULL);
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,
453 G_TYPE_STRING);
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[])
473 GtkWidget *toplevel;
474 int loglevel = LOG_NORMAL;
475 int ui_options;
477 init_nls();
478 init_character_encodings(FC_DEFAULT_DATA_ENCODING, FALSE);
479 registry_module_init();
481 fc_init_network();
483 g_thread_init(NULL);
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 */
505 #ifndef WIN32_NATIVE
507 /* Unlike main client, this only works if installed. Ignore any
508 * errors loading the icon. */
509 GError *err;
510 (void) gtk_window_set_icon_from_file(GTK_WINDOW(toplevel), MPICON_PATH,
511 &err);
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);
526 gtk_main();
528 save_install_info_lists(&fcmp);
531 log_close();
533 return EXIT_SUCCESS;