Freeciv-3.4
Loading...
Searching...
No Matches
mpgui_gtk5.c
Go to the documentation of this file.
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.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdlib.h>
19
20#include <gtk/gtk.h>
21
22/* utility */
23#include "executable.h"
24#include "fc_cmdline.h"
25#include "fciconv.h"
26#include "fcintl.h"
27#include "log.h"
28#include "mem.h"
29
30/* common */
31#include "version.h"
32
33/* modinst */
34#include "download.h"
35#include "mpcmdline.h"
36#include "mpdb.h"
37
38#include "modinst.h"
39
48
49struct fcmp_params fcmp = {
51 .inst_prefix = nullptr,
52 .autoinstall = nullptr
53};
54
56
58
59#define ML_COL_NAME 0
60#define ML_COL_VER 1
61#define ML_COL_INST 2
62#define ML_COL_TYPE 3
63#define ML_COL_SUBTYPE 4
64#define ML_COL_LIC 5
65#define ML_COL_URL 6
66
67#define ML_COL_COUNT 7
68
69#define ML_TYPE 7
70#define ML_NOTES 8
71#define ML_STORE_SIZE 9
72
73#define FC_TYPE_MPROW (fc_mprow_get_type())
74
76
78{
80
81 const char *name;
82 const char *ver;
83 const char *inst;
84 const char *type;
85 const char *subtype;
86 const char *lic;
87 char *URL;
88 const char *notes;
89
91};
92
97
99
100/**********************************************************************/
104{
106
107 free(row->URL);
108 row->URL = nullptr;
109
111}
112
113/**********************************************************************/
116static void
123
124/**********************************************************************/
127static void
129{
130 self->URL = nullptr;
131}
132
133/**********************************************************************/
137{
138 FcMPRow *result;
139
140 result = g_object_new(FC_TYPE_MPROW, nullptr);
141
142 return result;
143}
144
145/**********************************************************************/
148static void modinst_quit(void)
149{
151}
152
153/**********************************************************************/
157static void quit_dialog_response(GObject *dialog, GAsyncResult *result,
158 gpointer data)
159{
161 result, nullptr);
162
163 if (button == 0) {
164 modinst_quit();
165 }
166
167 quit_dialog = nullptr;
168}
169
170/**********************************************************************/
174{
175 if (downloading) {
176 /* Download in progress. Confirm quit from user. */
177
178 if (quit_dialog == nullptr) {
179 const char *buttons[] = { _("Quit"), _("Cancel"), nullptr };
180
181 quit_dialog = gtk_alert_dialog_new(_("Modpack installation in progress.\n"
182 "Are you sure you want to quit?"));
183
185
187 GTK_WINDOW(toplevel), nullptr,
188 quit_dialog_response, nullptr);
189 }
190
191 } else {
192 /* User loses no work by quitting, so let's not annoy them
193 * with confirmation dialog. */
194 modinst_quit();
195 }
196
197 /* Stop emission of event. */
198 return TRUE;
199}
200
201/**********************************************************************/
204static void msg_callback(const char *msg)
205{
206 log_verbose("%s", msg);
208}
209
210/**********************************************************************/
213static void pbar_callback(int downloaded, int max)
214{
215 /* Control file already downloaded */
216 double fraction = (double) downloaded / (max);
217
219}
220
221struct msg_data {
222 char *msg;
223};
224
225/**********************************************************************/
229{
230 struct msg_data *data = (struct msg_data *)user_data;
231
232 msg_callback(data->msg);
233
234 FC_FREE(data->msg);
235 FC_FREE(data);
236
237 return G_SOURCE_REMOVE;
238}
239
240/**********************************************************************/
243static void msg_dl_thread(const char *msg)
244{
245 struct msg_data *data = fc_malloc(sizeof(*data));
246
247 data->msg = fc_strdup(msg);
248
250}
251
252struct pbar_data {
253 int current;
254 int max;
255};
256
257/**********************************************************************/
261{
262 struct pbar_data *data = (struct pbar_data *)user_data;
263
264 pbar_callback(data->current, data->max);
265
266 FC_FREE(data);
267
268 return G_SOURCE_REMOVE;
269}
270
271/**********************************************************************/
274static void pbar_dl_thread(int current, int max)
275{
276 struct pbar_data *data = fc_malloc(sizeof(*data));
277
278 data->current = current;
279 data->max = max;
280
282}
283
284/**********************************************************************/
288{
289#if 0
291
293 do {
294 const char *name_str;
295 int type_int;
296 const char *new_inst;
297 enum modpack_type type;
298
301 ML_TYPE, &type_int,
302 -1);
303
304 type = type_int;
305
307
308 if (new_inst == nullptr) {
309 new_inst = _("Not installed");
310 }
311
314 -1);
315
317 }
318#endif
319
320 return G_SOURCE_REMOVE;
321}
322
323/**********************************************************************/
330
331/**********************************************************************/
335{
336 const char *errmsg;
337
339
340 if (errmsg == nullptr) {
341 msg_dl_thread(_("Ready"));
342 } else {
344 }
345
346 free(data);
347
349
351
352 return nullptr;
353}
354
355/**********************************************************************/
358static void gui_download_modpack(const char *URL)
359{
361 char *URLbuf;
362
363 if (downloading) {
365 _("Another download already active"));
366 return;
367 }
368
370
371 URLbuf = fc_malloc(strlen(URL) + 1);
372
373 strcpy(URLbuf, URL);
374
376 if (downloader == nullptr) {
378 _("Failed to start downloader"));
379 free(URLbuf);
380 } else {
382 }
383}
384
385/**********************************************************************/
388static void install_clicked(GtkWidget *w, gpointer data)
389{
390 GtkEntry *URL_in = data;
392 const char *URL = gtk_entry_buffer_get_text(buffer);
393
395}
396
397/**********************************************************************/
400static void URL_return(GtkEntry *w, gpointer data)
401{
402 const char *URL;
404
405 URL = gtk_entry_buffer_get_text(buffer);
407}
408
409/**********************************************************************/
413 gint x, gint y,
416 gpointer data)
417{
419 int row_number = -1; /* 0 after header */
420 int curr_y = 0;
421
422 while (GTK_IS_WIDGET(child)) {
424
425 if (curr_y > y) {
427
428 if (row != nullptr) {
429 log_debug("Tooltip row %d. Notes: %s", row_number,
430 row->notes == nullptr ? "-" : row->notes);
431
432 if (row->notes != nullptr) {
434
435 return TRUE;
436 }
437 }
438
439 return FALSE;
440 }
441
442 row_number++;
443
444 child = gtk_widget_get_next_sibling(child);
445 }
446
447 return FALSE;
448}
449
450/**********************************************************************/
453static void setup_modpack_list(const char *name, const char *URL,
454 const char *version, const char *license,
455 enum modpack_type type, const char *subtype,
456 const char *notes)
457{
458 FcMPRow *row;
459
460 row = fc_mprow_new();
461
463 row->type = _(modpack_type_name(type));
464 } else {
465 /* TRANS: Unknown modpack type */
466 row->type = _("?");
467 }
468
469 if (license != nullptr) {
470 row->lic = license;
471 } else {
472 /* TRANS: License of modpack is not known */
473 row->lic = Q_("?license:Unknown");
474 }
475
477 if (row->inst == nullptr) {
478 row->inst = _("Not installed");
479 }
480
481 row->name = name;
482 row->ver = version;
483 row->subtype = subtype;
484 row->URL = fc_strdup(URL);
485 row->notes = notes;
486
487 row->type_int = type;
488
491}
492
493/**********************************************************************/
497 guint position, guint n_items,
498 gpointer user_data)
499{
500 GtkSingleSelection *selection = GTK_SINGLE_SELECTION(model);
504 GtkEntryBuffer *buffer;
505
506 log_debug("Selected row: %d. URL: %s", row_number, row->URL);
507
509 gtk_entry_buffer_set_text(buffer, row->URL, -1);
510}
511
512/**********************************************************************/
517 gpointer user_data)
518{
519 FcMPRow *row;
520 const char *str = "-";
521
523
524 switch (GPOINTER_TO_INT(user_data)) {
525 case ML_COL_NAME:
526 str = row->name;
527 break;
528 case ML_COL_VER:
529 str = row->ver;
530 break;
531 case ML_COL_INST:
532 str = row->inst;
533 break;
534 case ML_COL_TYPE:
535 str = row->type;
536 break;
537 case ML_COL_SUBTYPE:
538 str = row->subtype;
539 break;
540 case ML_COL_LIC:
541 str = row->lic;
542 break;
543 case ML_COL_URL:
544 str = row->URL;
545 break;
546 }
547
549 str);
550}
551
552/**********************************************************************/
561
562/**********************************************************************/
565static void modinst_setup_widgets(void)
566{
568 GtkWidget *version_label;
573 GtkSingleSelection *selection;
574 const char *errmsg;
575 char verbuf[2048];
576 const char *rev_ver;
577
578 mbox = gtk_grid_new();
582
584
585 if (rev_ver == nullptr) {
587 } else {
588 fc_snprintf(verbuf, sizeof(verbuf), _("%s%s\ncommit: %s"),
590 }
591
592 version_label = gtk_label_new(verbuf);
593
596 g_signal_connect(selection, "selection-changed", G_CALLBACK(selection_change),
597 nullptr);
598
600
605
608
613
616
621
624
629
630 column = gtk_column_view_column_new(Q_("?modpack:Type"), factory);
632
637
640
645
648
653
656
658 gtk_button_set_label(GTK_BUTTON(install_button), _("Install modpack"));
659
660 Ubox = gtk_grid_new();
663 URL_label = gtk_label_new_with_mnemonic(_("Modpack URL"));
664
668 g_signal_connect(URL_input, "activate",
669 G_CALLBACK(URL_return), nullptr);
670
673
674 gtk_grid_attach(GTK_GRID(Ubox), URL_label, 0, 0, 1, 1);
675 gtk_grid_attach(GTK_GRID(Ubox), URL_input, 0, 1, 1, 1);
676
678
679 statusbar = gtk_label_new(_("Select modpack to install"));
680
683
684 gtk_grid_attach(GTK_GRID(mbox), version_label, 0, 0, 1, 1);
685 gtk_grid_attach(GTK_GRID(mbox), main_list, 0, 1, 1, 1);
686 gtk_grid_attach(GTK_GRID(mbox), Ubox, 0, 2, 1, 1);
689 gtk_grid_attach(GTK_GRID(mbox), statusbar, 0, 5, 1, 1);
690
692
694
695 g_object_set(main_list, "has-tooltip", TRUE, nullptr);
696 g_signal_connect(main_list, "query-tooltip",
698
699 if (errmsg != nullptr) {
701 }
702}
703
704/**********************************************************************/
708{
709 quit_dialog = nullptr;
710
712
714 gtk_widget_set_name(toplevel, "Freeciv-modpack");
716 _("Freeciv modpack installer (gtk4x)"));
717
718#if 0
719 /* Keep the icon of the executable on Windows */
720#ifndef FREECIV_MSWINDOWS
721 {
722 /* Unlike main client, this only works if installed. Ignore any
723 * errors loading the icon. */
724 GError *err;
725
727 MPICON_PATH, &err);
728 }
729#endif /* FREECIV_MSWINDOWS */
730#endif /* 0 */
731
732 g_signal_connect(toplevel, "close_request",
734
736
738
739 if (fcmp.autoinstall != nullptr) {
741 }
742}
743
744/**********************************************************************/
747int main(int argc, char *argv[])
748{
749 int ui_options;
750
752
753 fcmp_init();
754
755 /* This modifies argv! */
757
758 if (ui_options != -1) {
759 int i;
760
761 for (i = 1; i <= ui_options; i++) {
762 if (is_option("--help", argv[i])) {
763 /* TRANS: No full stop after the URL, could cause confusion. */
764 fc_fprintf(stderr, _("Report bugs at %s\n"), BUG_URL);
765
766 ui_options = -1;
767 }
768 }
769 }
770
771 if (ui_options != -1) {
773
774 if (gtk_init_check()) {
775 fcmp_app = gtk_application_new(nullptr, 0);
776 g_signal_connect(fcmp_app, "activate",
777 G_CALLBACK(activate_gui), nullptr);
779
781 } else {
782 log_fatal(_("Failed to open graphical mode."));
783 }
784
785 close_mpdbs();
786 }
787
788 fcmp_deinit();
790
791 return EXIT_SUCCESS;
792}
#define str
Definition astring.c:76
static struct ai_type * self
Definition classicai.c:46
char * incite_cost
Definition comments.c:76
const char * download_modpack(const char *URL, const struct fcmp_params *fcmp, dl_msg_callback mcb, dl_pb_callback pbcb)
Definition download.c:66
const char * download_modpack_list(const struct fcmp_params *fcmp, modpack_list_setup_cb cb, dl_msg_callback mcb)
Definition download.c:427
void executable_init(void)
Definition executable.c:34
bool is_option(const char *option_name, char *option)
Definition fc_cmdline.c:112
void cmdline_option_values_free(void)
Definition fc_cmdline.c:97
void fc_fprintf(FILE *stream, const char *format,...) fc__attribute((__format__(__printf__
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
const char * tooltip
Definition repodlgs.c:1315
GType type
Definition repodlgs.c:1313
const char * name
Definition inputfile.c:127
#define log_verbose(message,...)
Definition log.h:110
#define log_fatal(message,...)
Definition log.h:101
#define log_debug(message,...)
Definition log.h:116
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_strdup(str)
Definition mem.h:43
#define fc_malloc(sz)
Definition mem.h:34
void load_install_info_lists(struct fcmp_params *fcmp)
Definition modinst.c:44
void fcmp_deinit(void)
Definition modinst.c:98
void fcmp_init(void)
Definition modinst.c:82
#define DEFAULT_URL_START
Definition modinst.h:32
#define MODPACK_LIST_URL
Definition modinst.h:30
int fcmp_parse_cmdline(int argc, char *argv[])
Definition mpcmdline.c:45
const char * mpdb_installed_version(const char *name, enum modpack_type type)
Definition mpdb.c:253
void close_mpdbs(void)
Definition mpdb.c:202
#define ML_COL_SUBTYPE
Definition mpgui_gtk5.c:63
static void msg_dl_thread(const char *msg)
Definition mpgui_gtk5.c:243
#define ML_TYPE
Definition mpgui_gtk5.c:69
int main(int argc, char *argv[])
Definition mpgui_gtk5.c:747
static gboolean quit_dialog_callback(void)
Definition mpgui_gtk5.c:173
static GtkWidget * statusbar
Definition mpgui_gtk5.c:41
static GListStore * main_store
Definition mpgui_gtk5.c:44
static gboolean query_main_list_tooltip_cb(GtkWidget *widget, gint x, gint y, gboolean keyboard_tip, GtkTooltip *tooltip, gpointer data)
Definition mpgui_gtk5.c:412
static void selection_change(GtkSelectionModel *model, guint position, guint n_items, gpointer user_data)
Definition mpgui_gtk5.c:496
static FcMPRow * fc_mprow_new(void)
Definition mpgui_gtk5.c:136
static gboolean versionlist_update_main_thread(gpointer user_data)
Definition mpgui_gtk5.c:287
static void activate_gui(GtkApplication *app, gpointer data)
Definition mpgui_gtk5.c:707
#define ML_COL_NAME
Definition mpgui_gtk5.c:59
static GtkWidget * toplevel
Definition mpgui_gtk5.c:40
static void modinst_quit(void)
Definition mpgui_gtk5.c:148
#define ML_COL_LIC
Definition mpgui_gtk5.c:64
static void pbar_callback(int downloaded, int max)
Definition mpgui_gtk5.c:213
static void URL_return(GtkEntry *w, gpointer data)
Definition mpgui_gtk5.c:400
static GtkWidget * URL_input
Definition mpgui_gtk5.c:45
static void fc_mprow_class_init(FcMPRowClass *klass)
Definition mpgui_gtk5.c:117
static void fc_mprow_finalize(GObject *gobject)
Definition mpgui_gtk5.c:103
#define FC_TYPE_MPROW
Definition mpgui_gtk5.c:73
struct fcmp_params fcmp
Definition mpgui_gtk5.c:49
static gboolean downloading
Definition mpgui_gtk5.c:47
static GtkWidget * progressbar
Definition mpgui_gtk5.c:42
static void gui_download_modpack(const char *URL)
Definition mpgui_gtk5.c:358
static gboolean msg_main_thread(gpointer user_data)
Definition mpgui_gtk5.c:228
static void fc_mprow_init(FcMPRow *self)
Definition mpgui_gtk5.c:128
static void install_clicked(GtkWidget *w, gpointer data)
Definition mpgui_gtk5.c:388
static GtkAlertDialog * quit_dialog
Definition mpgui_gtk5.c:46
static void factory_bind(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition mpgui_gtk5.c:515
#define ML_COL_TYPE
Definition mpgui_gtk5.c:62
static void setup_modpack_list(const char *name, const char *URL, const char *version, const char *license, enum modpack_type type, const char *subtype, const char *notes)
Definition mpgui_gtk5.c:453
static GtkApplication * fcmp_app
Definition mpgui_gtk5.c:55
static void pbar_dl_thread(int current, int max)
Definition mpgui_gtk5.c:274
static void msg_callback(const char *msg)
Definition mpgui_gtk5.c:204
#define ML_COL_INST
Definition mpgui_gtk5.c:61
static GtkWidget * main_list
Definition mpgui_gtk5.c:43
static void quit_dialog_response(GObject *dialog, GAsyncResult *result, gpointer data)
Definition mpgui_gtk5.c:157
static void modinst_setup_widgets(void)
Definition mpgui_gtk5.c:565
static void versionlist_update_dl_thread(void)
Definition mpgui_gtk5.c:326
#define ML_COL_URL
Definition mpgui_gtk5.c:65
static gboolean pbar_main_thread(gpointer user_data)
Definition mpgui_gtk5.c:260
static void factory_setup(GtkSignalListItemFactory *self, GtkListItem *list_item, gpointer user_data)
Definition mpgui_gtk5.c:555
#define ML_COL_VER
Definition mpgui_gtk5.c:60
static gpointer download_thread(gpointer data)
Definition mpgui_gtk5.c:334
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
GObjectClass parent_class
Definition mpgui_gtk5.c:95
const char * ver
Definition mpgui_gtk5.c:82
const char * lic
Definition mpgui_gtk5.c:86
int type_int
Definition mpgui_gtk5.c:90
const char * inst
Definition mpgui_gtk5.c:83
GObject parent_instance
Definition mpgui_gtk5.c:79
const char * type
Definition mpgui_gtk5.c:84
const char * subtype
Definition mpgui_gtk5.c:85
char * URL
Definition mpgui_gtk5.c:87
const char * notes
Definition mpgui_gtk5.c:88
const char * name
Definition mpgui_gtk5.c:81
const char * list_url
Definition modinst.h:18
const char * autoinstall
Definition modinst.h:20
char * msg
Definition mpgui_gtk3.c:146
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:960
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
const char * fc_git_revision(void)
Definition version.c:75
const char * word_version(void)
Definition version.c:62
#define VERSION_STRING
Definition version_gen.h:14