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>
19 #include <QApplication>
20 #include <QCloseEvent>
21 #include <QHBoxLayout>
22 #include <QHeaderView>
25 #include <QMainWindow>
26 #include <QMessageBox>
27 #include <QProgressBar>
28 #include <QPushButton>
29 #include <QTableWidget>
30 #include <QVBoxLayout>
33 #include "fc_cmdline.h"
43 #include "mpcmdline.h"
45 #include "mpgui_qt_worker.h"
50 struct fcmp_params fcmp
= { MODPACK_LIST_URL
, NULL
, NULL
};
54 static mpqt_worker
*worker
= nullptr;
56 static int mpcount
= 0;
62 #define ML_COL_SUBTYPE 4
68 #define ML_COL_COUNT 8
70 static void setup_modpack_list(const char *name
, const char *URL
,
71 const char *version
, const char *license
,
72 enum modpack_type type
, const char *subtype
,
74 static void msg_callback(const char *msg
);
75 static void msg_callback_thr(const char *msg
);
76 static void progress_callback_thr(int downloaded
, int max
);
78 static void gui_download_modpack(QString URL
);
80 /**************************************************************************
81 Entry point for whole freeciv-mp-qt program.
82 **************************************************************************/
83 int main(int argc
, char **argv
)
89 /* This modifies argv! */
90 ui_options
= fcmp_parse_cmdline(argc
, argv
);
92 if (ui_options
!= -1) {
95 for (i
= 1; i
<= ui_options
; i
++) {
96 if (is_option("--help", argv
[i
])) {
98 _("This modpack installer accepts the standard Qt command-line options\n"
99 "after '--'. See the Qt documentation.\n\n"));
101 /* TRANS: No full stop after the URL, could cause confusion. */
102 fc_fprintf(stderr
, _("Report bugs at %s\n"), BUG_URL
);
109 if (ui_options
!= -1) {
111 mpgui_main
*main_window
;
115 load_install_info_lists(&fcmp
);
117 qapp
= new QApplication(ui_options
, argv
);
118 central
= new QWidget
;
119 main_window
= new mpgui_main(qapp
, central
);
121 main_window
->setGeometry(0, 30, 640, 60);
122 main_window
->setWindowTitle(QString::fromUtf8(_("Freeciv modpack installer (Qt)")));
126 gui
->setup(central
, &fcmp
);
128 main_window
->setCentralWidget(central
);
129 main_window
->setVisible(true);
131 errmsg
= download_modpack_list(&fcmp
, setup_modpack_list
, msg_callback
);
132 if (errmsg
!= nullptr) {
133 gui
->display_msg(errmsg
);
138 if (worker
!= nullptr) {
139 if (worker
->isRunning()) {
148 save_install_info_lists(&fcmp
);
152 cmdline_option_values_free();
157 /**************************************************************************
158 Progress indications from downloader
159 **************************************************************************/
160 static void msg_callback(const char *msg
)
162 gui
->display_msg(msg
);
165 /**************************************************************************
166 Progress indications from downloader thread
167 **************************************************************************/
168 static void msg_callback_thr(const char *msg
)
170 gui
->display_msg_thr(msg
);
173 /**************************************************************************
174 Progress indications from downloader
175 **************************************************************************/
176 static void progress_callback_thr(int downloaded
, int max
)
178 gui
->progress_thr(downloaded
, max
);
181 /**************************************************************************
183 **************************************************************************/
184 void mpgui::setup(QWidget
*central
, struct fcmp_params
*params
)
186 #define URL_LABEL_TEXT N_("Modpack URL")
187 QVBoxLayout
*main_layout
= new QVBoxLayout();
188 QHBoxLayout
*hl
= new QHBoxLayout();
189 QPushButton
*install_button
= new QPushButton(QString::fromUtf8(_("Install modpack")));
192 QLabel
*version_label
;
194 const char *rev_ver
= fc_svn_revision();
196 if (rev_ver
== nullptr) {
197 rev_ver
= fc_git_revision();
199 if (rev_ver
== nullptr) {
200 fc_snprintf(verbuf
, sizeof(verbuf
), "%s%s", word_version(), VERSION_STRING
);
202 fc_snprintf(verbuf
, sizeof(verbuf
), _("%s%s\ncommit: %s"),
203 word_version(), VERSION_STRING
, rev_ver
);
206 fc_snprintf(verbuf
, sizeof(verbuf
), "%s%s (%s)", word_version(), VERSION_STRING
,
210 version_label
= new QLabel(QString::fromUtf8(verbuf
));
211 version_label
->setAlignment(Qt::AlignHCenter
);
212 version_label
->setParent(central
);
213 version_label
->setSizePolicy(QSizePolicy::Ignored
, QSizePolicy::Fixed
);
214 main_layout
->addWidget(version_label
);
216 mplist_table
= new QTableWidget();
217 mplist_table
->setSizePolicy(QSizePolicy::MinimumExpanding
, QSizePolicy::MinimumExpanding
);
218 mplist_table
->setColumnCount(ML_COL_COUNT
);
219 headers
<< QString::fromUtf8(_("Name")) << QString::fromUtf8(_("Version"));
220 headers
<< QString::fromUtf8(_("Installed")) << QString::fromUtf8(Q_("?modpack:Type"));
221 headers
<< QString::fromUtf8(_("Subtype")) << QString::fromUtf8(_("License"));
222 headers
<< QString::fromUtf8(_("URL")) << "typeint";
223 mplist_table
->setHorizontalHeaderLabels(headers
);
224 mplist_table
->verticalHeader()->setVisible(false);
225 mplist_table
->setEditTriggers(QAbstractItemView::NoEditTriggers
);
226 mplist_table
->setSelectionBehavior(QAbstractItemView::SelectRows
);
227 mplist_table
->setSelectionMode(QAbstractItemView::SingleSelection
);
228 mplist_table
->hideColumn(ML_TYPE
);
230 connect(mplist_table
, SIGNAL(cellClicked(int, int)), this, SLOT(row_selected(int, int)));
231 connect(mplist_table
, SIGNAL(doubleClicked(QModelIndex
)), this, SLOT(row_download(QModelIndex
)));
232 connect(this, SIGNAL(display_msg_thr_signal(const char *)), this, SLOT(display_msg(const char *)));
233 connect(this, SIGNAL(progress_thr_signal(int, int)), this, SLOT(progress(int, int)));
234 connect(this, SIGNAL(refresh_list_versions_thr_signal()), this, SLOT(refresh_list_versions()));
236 main_layout
->addWidget(mplist_table
);
238 URL_label
= new QLabel(QString::fromUtf8(_(URL_LABEL_TEXT
)));
239 URL_label
->setParent(central
);
240 hl
->addWidget(URL_label
);
242 URLedit
= new QLineEdit(central
);
243 if (params
->autoinstall
== nullptr) {
244 URLedit
->setText(DEFAULT_URL_START
);
246 URLedit
->setText(QString::fromUtf8(params
->autoinstall
));
250 connect(URLedit
, SIGNAL(returnPressed()), this, SLOT(URL_given()));
252 hl
->addWidget(URLedit
);
253 main_layout
->addLayout(hl
);
255 connect(install_button
, SIGNAL(pressed()), this, SLOT(URL_given()));
256 main_layout
->addWidget(install_button
);
258 bar
= new QProgressBar(central
);
259 main_layout
->addWidget(bar
);
261 msg_dspl
= new QLabel(QString::fromUtf8(_("Select modpack to install")));
262 msg_dspl
->setParent(central
);
263 main_layout
->addWidget(msg_dspl
);
265 msg_dspl
->setAlignment(Qt::AlignHCenter
);
267 central
->setLayout(main_layout
);
270 /**************************************************************************
271 Display status message
272 **************************************************************************/
273 void mpgui::display_msg(const char *msg
)
275 log_verbose("%s", msg
);
276 msg_dspl
->setText(QString::fromUtf8(msg
));
279 /**************************************************************************
280 Display status message from another thread
281 **************************************************************************/
282 void mpgui::display_msg_thr(const char *msg
)
284 emit
display_msg_thr_signal(msg
);
287 /**************************************************************************
289 **************************************************************************/
290 void mpgui::progress(int downloaded
, int max
)
292 bar
->setMaximum(max
);
293 bar
->setValue(downloaded
);
296 /**************************************************************************
297 Update progress bar from another thread
298 **************************************************************************/
299 void mpgui::progress_thr(int downloaded
, int max
)
301 emit
progress_thr_signal(downloaded
, max
);
304 /**************************************************************************
305 Download modpack from given URL
306 **************************************************************************/
307 static void gui_download_modpack(QString URL
)
309 if (worker
!= nullptr) {
310 if (worker
->isRunning()) {
311 gui
->display_msg(_("Another download already active"));
315 worker
= new mpqt_worker
;
318 worker
->download(URL
, gui
, &fcmp
, msg_callback_thr
, progress_callback_thr
);
321 /**************************************************************************
323 **************************************************************************/
324 void mpgui::URL_given()
326 gui_download_modpack(URLedit
->text());
329 /**************************************************************************
330 Refresh display of modpack list modpack versions
331 **************************************************************************/
332 void mpgui::refresh_list_versions()
334 for (int i
= 0; i
< mpcount
; i
++) {
337 const char *new_inst
;
338 enum modpack_type type
;
340 name_str
= mplist_table
->item(i
, ML_COL_NAME
)->text();
341 type_int
= mplist_table
->item(i
, ML_TYPE
)->text().toInt();
342 type
= (enum modpack_type
) type_int
;
343 new_inst
= get_installed_version(name_str
.toUtf8().data(), type
);
345 if (new_inst
== nullptr) {
346 new_inst
= _("Not installed");
349 mplist_table
->item(i
, ML_COL_INST
)->setText(QString::fromUtf8(new_inst
));
352 mplist_table
->resizeColumnsToContents();
355 /**************************************************************************
356 Refresh display of modpack list modpack versions from another thread
357 **************************************************************************/
358 void mpgui::refresh_list_versions_thr()
360 emit
refresh_list_versions_thr_signal();
363 /**************************************************************************
364 Build main modpack list view
365 **************************************************************************/
366 void mpgui::setup_list(const char *name
, const char *URL
,
367 const char *version
, const char *license
,
368 enum modpack_type type
, const char *subtype
,
371 const char *type_str
;
373 const char *inst_str
;
375 QTableWidgetItem
*item
;
377 if (modpack_type_is_valid(type
)) {
378 type_str
= _(modpack_type_name(type
));
380 /* TRANS: Unknown modpack type */
384 if (license
!= nullptr) {
387 /* TRANS: License of modpack is not known */
388 lic_str
= Q_("?license:Unknown");
391 inst_str
= get_installed_version(name
, type
);
392 if (inst_str
== nullptr) {
393 inst_str
= _("Not installed");
396 mplist_table
->setRowCount(mpcount
+1);
398 item
= new QTableWidgetItem(QString::fromUtf8(name
));
399 item
->setToolTip(QString::fromUtf8(notes
));
400 mplist_table
->setItem(mpcount
, ML_COL_NAME
, item
);
401 item
= new QTableWidgetItem(QString::fromUtf8(version
));
402 item
->setToolTip(QString::fromUtf8(notes
));
403 mplist_table
->setItem(mpcount
, ML_COL_VER
, item
);
404 item
= new QTableWidgetItem(QString::fromUtf8(inst_str
));
405 item
->setToolTip(QString::fromUtf8(notes
));
406 mplist_table
->setItem(mpcount
, ML_COL_INST
, item
);
407 item
= new QTableWidgetItem(QString::fromUtf8(type_str
));
408 item
->setToolTip(QString::fromUtf8(notes
));
409 mplist_table
->setItem(mpcount
, ML_COL_TYPE
, item
);
410 item
= new QTableWidgetItem(QString::fromUtf8(subtype
));
411 item
->setToolTip(QString::fromUtf8(notes
));
412 mplist_table
->setItem(mpcount
, ML_COL_SUBTYPE
, item
);
413 item
= new QTableWidgetItem(QString::fromUtf8(lic_str
));
414 item
->setToolTip(QString::fromUtf8(notes
));
415 mplist_table
->setItem(mpcount
, ML_COL_LIC
, item
);
416 item
= new QTableWidgetItem(QString::fromUtf8(URL
));
417 item
->setToolTip(QString::fromUtf8(notes
));
418 mplist_table
->setItem(mpcount
, ML_COL_URL
, item
);
420 type_nbr
.setNum(type
);
421 item
= new QTableWidgetItem(type_nbr
);
422 item
->setToolTip(notes
);
423 mplist_table
->setItem(mpcount
, ML_TYPE
, item
);
425 mplist_table
->resizeColumnsToContents();
429 /**************************************************************************
430 Build main modpack list view
431 **************************************************************************/
432 static void setup_modpack_list(const char *name
, const char *URL
,
433 const char *version
, const char *license
,
434 enum modpack_type type
, const char *subtype
,
437 // Just call setup_list for gui singleton
438 gui
->setup_list(name
, URL
, version
, license
, type
, subtype
, notes
);
441 /**************************************************************************
442 User activated another table row
443 **************************************************************************/
444 void mpgui::row_selected(int row
, int column
)
446 QString URL
= mplist_table
->item(row
, ML_COL_URL
)->text();
448 URLedit
->setText(URL
);
451 /**************************************************************************
452 User activated another table row
453 **************************************************************************/
454 void mpgui::row_download(const QModelIndex
&index
)
456 QString URL
= mplist_table
->item(index
.row(), ML_COL_URL
)->text();
458 URLedit
->setText(URL
);
463 /**************************************************************************
464 Main window constructor
465 **************************************************************************/
466 mpgui_main::mpgui_main(QApplication
*qapp_in
, QWidget
*central_in
) : QMainWindow()
469 central
= central_in
;
472 /**************************************************************************
473 Open dialog to confirm that user wants to quit modpack installer.
474 **************************************************************************/
475 void mpgui_main::popup_quit_dialog()
477 QMessageBox
ask(central
);
480 ask
.setText(_("Modpack installation in progress.\nAre you sure you want to quit?"));
481 ask
.setStandardButtons(QMessageBox::Cancel
| QMessageBox::Ok
);
482 ask
.setDefaultButton(QMessageBox::Cancel
);
483 ask
.setIcon(QMessageBox::Warning
);
484 ask
.setWindowTitle(_("Quit?"));
488 case QMessageBox::Cancel
:
491 case QMessageBox::Ok
:
497 /**************************************************************************
498 User clicked windows close button.
499 **************************************************************************/
500 void mpgui_main::closeEvent(QCloseEvent
*event
)
502 if (worker
!= nullptr && worker
->isRunning()) {
503 // Download in progress. Confirm quit from user.