Rework README.ruleset_civ2civ3 defense bonus description.
[freeciv.git] / tools / mpgui_qt.cpp
blobe07b85063c03ec916721f0e86032385099a57d9e
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 // Qt
19 #include <QApplication>
20 #include <QHBoxLayout>
21 #include <QHeaderView>
22 #include <QLabel>
23 #include <QLineEdit>
24 #include <QMainWindow>
25 #include <QProgressBar>
26 #include <QPushButton>
27 #include <QTableWidget>
28 #include <QVBoxLayout>
30 // utility
31 #include "fciconv.h"
32 #include "fcintl.h"
33 #include "log.h"
35 // common
36 #include "version.h"
38 // modinst
39 #include "download.h"
40 #include "mpcmdline.h"
41 #include "mpdb.h"
42 #include "mpgui_qt_worker.h"
43 #include "modinst.h"
45 #include "mpgui_qt.h"
47 struct fcmp_params fcmp = { MODPACK_LIST_URL, NULL, NULL };
49 static mpgui *gui;
51 static mpqt_worker *worker = nullptr;
53 static int mpcount = 0;
55 #define ML_COL_NAME 0
56 #define ML_COL_VER 1
57 #define ML_COL_INST 2
58 #define ML_COL_TYPE 3
59 #define ML_COL_SUBTYPE 4
60 #define ML_COL_LIC 5
61 #define ML_COL_URL 6
63 #define ML_TYPE 7
65 #define ML_COL_COUNT 8
67 static void setup_modpack_list(const char *name, const char *URL,
68 const char *version, const char *license,
69 enum modpack_type type, const char *subtype,
70 const char *notes);
71 static void msg_callback(const char *msg);
72 static void msg_callback_thr(const char *msg);
73 static void progress_callback_thr(int downloaded, int max);
75 static void gui_download_modpack(QString URL);
77 /**************************************************************************
78 Entry point for whole freeciv-mp-qt program.
79 **************************************************************************/
80 int main(int argc, char **argv)
82 enum log_level loglevel = LOG_NORMAL;
83 int ui_options;
85 fcmp_init(loglevel);
87 /* This modifies argv! */
88 ui_options = fcmp_parse_cmdline(argc, argv);
90 if (ui_options != -1) {
91 int i;
93 for (i = 1; i <= ui_options; i++) {
94 if (is_option("--help", argv[i])) {
95 fc_fprintf(stderr,
96 _("This modpack installer accepts the standard Qt command-line options\n"
97 "after '--'. See the Qt documentation.\n\n"));
99 /* TRANS: No full stop after the URL, could cause confusion. */
100 fc_fprintf(stderr, _("Report bugs at %s\n"), BUG_URL);
102 ui_options = -1;
107 if (ui_options != -1) {
108 QApplication *qapp;
109 QMainWindow *main_window;
110 QWidget *central;
111 const char *errmsg;
113 load_install_info_lists(&fcmp);
115 qapp = new QApplication(ui_options, argv);
116 main_window = new QMainWindow;
117 central = new QWidget;
119 main_window->setGeometry(0, 30, 640, 60);
120 main_window->setWindowTitle(QString::fromUtf8(_("Freeciv modpack installer (Qt)")));
122 gui = new mpgui;
124 gui->setup(central, &fcmp);
126 main_window->setCentralWidget(central);
127 main_window->setVisible(true);
129 errmsg = download_modpack_list(&fcmp, setup_modpack_list, msg_callback);
130 if (errmsg != nullptr) {
131 gui->display_msg(errmsg);
134 qapp->exec();
136 if (worker != nullptr) {
137 if (worker->isRunning()) {
138 worker->wait();
140 delete worker;
143 delete gui;
144 delete qapp;
146 save_install_info_lists(&fcmp);
149 fcmp_deinit();
151 return EXIT_SUCCESS;
154 /**************************************************************************
155 Progress indications from downloader
156 **************************************************************************/
157 static void msg_callback(const char *msg)
159 gui->display_msg(msg);
162 /**************************************************************************
163 Progress indications from downloader thread
164 **************************************************************************/
165 static void msg_callback_thr(const char *msg)
167 gui->display_msg_thr(msg);
170 /**************************************************************************
171 Progress indications from downloader
172 **************************************************************************/
173 static void progress_callback_thr(int downloaded, int max)
175 gui->progress_thr(downloaded, max);
178 /**************************************************************************
179 Setup GUI object
180 **************************************************************************/
181 void mpgui::setup(QWidget *central, struct fcmp_params *fcmp)
183 #define URL_LABEL_TEXT N_("Modpack URL")
184 QVBoxLayout *main_layout = new QVBoxLayout();
185 QHBoxLayout *hl = new QHBoxLayout();
186 QPushButton *install_button = new QPushButton(QString::fromUtf8(_("Install modpack")));
187 QStringList headers;
188 QLabel *URL_label;
189 QLabel *version_label;
190 char verbuf[2048];
191 const char *rev_ver = fc_svn_revision();
193 if (rev_ver == nullptr) {
194 rev_ver = fc_git_revision();
196 if (rev_ver == nullptr) {
197 fc_snprintf(verbuf, sizeof(verbuf), "%s%s", word_version(), VERSION_STRING);
198 } else {
199 fc_snprintf(verbuf, sizeof(verbuf), _("%s%s\ncommit: %s"),
200 word_version(), VERSION_STRING, rev_ver);
202 } else {
203 fc_snprintf(verbuf, sizeof(verbuf), "%s%s (%s)", word_version(), VERSION_STRING,
204 rev_ver);
207 version_label = new QLabel(QString::fromUtf8(verbuf));
208 version_label->setAlignment(Qt::AlignHCenter);
209 version_label->setParent(central);
210 version_label->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
211 main_layout->addWidget(version_label);
213 mplist_table = new QTableWidget();
214 mplist_table->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
215 mplist_table->setColumnCount(ML_COL_COUNT);
216 headers << QString::fromUtf8(_("Name")) << QString::fromUtf8(_("Version"));
217 headers << QString::fromUtf8(_("Installed")) << QString::fromUtf8(Q_("?modpack:Type"));
218 headers << QString::fromUtf8(_("Subtype")) << QString::fromUtf8(_("License"));
219 headers << QString::fromUtf8(_("URL")) << "typeint";
220 mplist_table->setHorizontalHeaderLabels(headers);
221 mplist_table->verticalHeader()->setVisible(false);
222 mplist_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
223 mplist_table->setSelectionBehavior(QAbstractItemView::SelectRows);
224 mplist_table->setSelectionMode(QAbstractItemView::SingleSelection);
225 mplist_table->hideColumn(ML_TYPE);
227 connect(mplist_table, SIGNAL(cellClicked(int, int)), this, SLOT(row_selected(int, int)));
228 connect(mplist_table, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(row_download(QModelIndex)));
229 connect(this, SIGNAL(display_msg_thr_signal(const char *)), this, SLOT(display_msg(const char *)));
230 connect(this, SIGNAL(progress_thr_signal(int, int)), this, SLOT(progress(int, int)));
231 connect(this, SIGNAL(refresh_list_versions_thr_signal()), this, SLOT(refresh_list_versions()));
233 main_layout->addWidget(mplist_table);
235 URL_label = new QLabel(QString::fromUtf8(_(URL_LABEL_TEXT)));
236 URL_label->setParent(central);
237 hl->addWidget(URL_label);
239 URLedit = new QLineEdit(central);
240 if (fcmp->autoinstall == nullptr) {
241 URLedit->setText(DEFAULT_URL_START);
242 } else {
243 URLedit->setText(QString::fromUtf8(fcmp->autoinstall));
245 URLedit->setFocus();
247 connect(URLedit, SIGNAL(returnPressed()), this, SLOT(URL_given()));
249 hl->addWidget(URLedit);
250 main_layout->addLayout(hl);
252 connect(install_button, SIGNAL(pressed()), this, SLOT(URL_given()));
253 main_layout->addWidget(install_button);
255 bar = new QProgressBar(central);
256 main_layout->addWidget(bar);
258 msg_dspl = new QLabel(QString::fromUtf8(_("Select modpack to install")));
259 msg_dspl->setParent(central);
260 main_layout->addWidget(msg_dspl);
262 msg_dspl->setAlignment(Qt::AlignHCenter);
264 central->setLayout(main_layout);
267 /**************************************************************************
268 Display status message
269 **************************************************************************/
270 void mpgui::display_msg(const char *msg)
272 msg_dspl->setText(QString::fromUtf8(msg));
275 /**************************************************************************
276 Display status message from another thread
277 **************************************************************************/
278 void mpgui::display_msg_thr(const char *msg)
280 emit display_msg_thr_signal(msg);
283 /**************************************************************************
284 Update progress bar
285 **************************************************************************/
286 void mpgui::progress(int downloaded, int max)
288 bar->setMaximum(max);
289 bar->setValue(downloaded);
292 /**************************************************************************
293 Update progress bar from another thread
294 **************************************************************************/
295 void mpgui::progress_thr(int downloaded, int max)
297 emit progress_thr_signal(downloaded, max);
300 /**************************************************************************
301 Download modpack from given URL
302 **************************************************************************/
303 static void gui_download_modpack(QString URL)
305 if (worker != nullptr) {
306 if (worker->isRunning()) {
307 gui->display_msg(_("Another download already active"));
308 return;
310 } else {
311 worker = new mpqt_worker;
314 worker->download(URL, gui, &fcmp, msg_callback_thr, progress_callback_thr);
317 /**************************************************************************
318 User entered URL
319 **************************************************************************/
320 void mpgui::URL_given()
322 gui_download_modpack(URLedit->text());
325 /**************************************************************************
326 Refresh display of modpack list modpack versions
327 **************************************************************************/
328 void mpgui::refresh_list_versions()
330 for (int i = 0; i < mpcount; i++) {
331 QString name_str;
332 int type_int;
333 const char *new_inst;
334 enum modpack_type type;
336 name_str = mplist_table->item(i, ML_COL_NAME)->text();
337 type_int = mplist_table->item(i, ML_TYPE)->text().toInt();
338 type = (enum modpack_type) type_int;
339 new_inst = get_installed_version(name_str.toUtf8().data(), type);
341 if (new_inst == nullptr) {
342 new_inst = _("Not installed");
345 mplist_table->item(i, ML_COL_INST)->setText(QString::fromUtf8(new_inst));
348 mplist_table->resizeColumnsToContents();
351 /**************************************************************************
352 Refresh display of modpack list modpack versions from another thread
353 **************************************************************************/
354 void mpgui::refresh_list_versions_thr()
356 emit refresh_list_versions_thr_signal();
359 /**************************************************************************
360 Build main modpack list view
361 **************************************************************************/
362 void mpgui::setup_list(const char *name, const char *URL,
363 const char *version, const char *license,
364 enum modpack_type type, const char *subtype,
365 const char *notes)
367 const char *type_str;
368 const char *lic_str;
369 const char *inst_str;
370 QString type_nbr;
371 QTableWidgetItem *item;
373 if (modpack_type_is_valid(type)) {
374 type_str = _(modpack_type_name(type));
375 } else {
376 /* TRANS: Unknown modpack type */
377 type_str = _("?");
380 if (license != nullptr) {
381 lic_str = license;
382 } else {
383 /* TRANS: License of modpack is not known */
384 lic_str = Q_("?license:Unknown");
387 inst_str = get_installed_version(name, type);
388 if (inst_str == nullptr) {
389 inst_str = _("Not installed");
392 mplist_table->setRowCount(mpcount+1);
394 item = new QTableWidgetItem(QString::fromUtf8(name));
395 item->setToolTip(QString::fromUtf8(notes));
396 mplist_table->setItem(mpcount, ML_COL_NAME, item);
397 item = new QTableWidgetItem(QString::fromUtf8(version));
398 item->setToolTip(QString::fromUtf8(notes));
399 mplist_table->setItem(mpcount, ML_COL_VER, item);
400 item = new QTableWidgetItem(QString::fromUtf8(inst_str));
401 item->setToolTip(QString::fromUtf8(notes));
402 mplist_table->setItem(mpcount, ML_COL_INST, item);
403 item = new QTableWidgetItem(QString::fromUtf8(type_str));
404 item->setToolTip(QString::fromUtf8(notes));
405 mplist_table->setItem(mpcount, ML_COL_TYPE, item);
406 item = new QTableWidgetItem(QString::fromUtf8(subtype));
407 item->setToolTip(QString::fromUtf8(notes));
408 mplist_table->setItem(mpcount, ML_COL_SUBTYPE, item);
409 item = new QTableWidgetItem(QString::fromUtf8(lic_str));
410 item->setToolTip(QString::fromUtf8(notes));
411 mplist_table->setItem(mpcount, ML_COL_LIC, item);
412 item = new QTableWidgetItem(QString::fromUtf8(URL));
413 item->setToolTip(QString::fromUtf8(notes));
414 mplist_table->setItem(mpcount, ML_COL_URL, item);
416 type_nbr.setNum(type);
417 item = new QTableWidgetItem(type_nbr);
418 item->setToolTip(notes);
419 mplist_table->setItem(mpcount, ML_TYPE, item);
421 mplist_table->resizeColumnsToContents();
422 mpcount++;
425 /**************************************************************************
426 Build main modpack list view
427 **************************************************************************/
428 static void setup_modpack_list(const char *name, const char *URL,
429 const char *version, const char *license,
430 enum modpack_type type, const char *subtype,
431 const char *notes)
433 // Just call setup_list for gui singleton
434 gui->setup_list(name, URL, version, license, type, subtype, notes);
437 /**************************************************************************
438 User activated another table row
439 **************************************************************************/
440 void mpgui::row_selected(int row, int column)
442 QString URL = mplist_table->item(row, ML_COL_URL)->text();
444 URLedit->setText(URL);
447 /**************************************************************************
448 User activated another table row
449 **************************************************************************/
450 void mpgui::row_download(const QModelIndex &index)
452 QString URL = mplist_table->item(index.row(), ML_COL_URL)->text();
454 URLedit->setText(URL);
456 URL_given();