File indexing completed on 2024-04-28 04:03:29

0001 /*
0002     SPDX-FileCopyrightText: 2003 Russell Steffen <rsteffen@bayarea.net>
0003     SPDX-FileCopyrightText: 2003 Stephan Zehetner <s.zehetner@nevox.org>
0004     SPDX-FileCopyrightText: 2006 Dmitry Suzdalev <dimsuz@gmail.com>
0005     SPDX-FileCopyrightText: 2006 Inge Wallin <inge@lysator.liu.se>
0006     SPDX-FileCopyrightText: 2006 Pierre Ducroquet <pinaraf@gmail.com>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "fleetdlg.h"
0012 
0013 #include <KLocalizedString>
0014 
0015 #include <QDialogButtonBox>
0016 #include <QHeaderView>
0017 #include <QPushButton>
0018 #include <QTableWidget>
0019 #include <QVBoxLayout>
0020 
0021 #include "planet.h"
0022 #include "../players/player.h"
0023 
0024 
0025 FleetDlg::FleetDlg( QWidget *parent,
0026                     const AttackFleetList &fleets,
0027                     const AttackFleetList &newFleets,
0028                     const AttackFleetList &standingOrders)
0029     : QDialog(parent), m_newFleetList(newFleets), m_standingOrders(standingOrders), m_fleetList(fleets)
0030 {
0031     setObjectName( QStringLiteral( "FleetDlg" ) );
0032     setModal( true );
0033     setWindowTitle(i18nc("@title:window", "Fleet Overview"));
0034     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
0035     QWidget *mainWidget = new QWidget(this);
0036     QVBoxLayout *mainLayout = new QVBoxLayout;
0037     setLayout(mainLayout);
0038     mainLayout->addWidget(mainWidget);
0039     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0040     okButton->setDefault(true);
0041     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0042     connect(buttonBox, &QDialogButtonBox::accepted, this, &FleetDlg::accept);
0043     connect(buttonBox, &QDialogButtonBox::rejected, this, &FleetDlg::reject);
0044 
0045     setupTable();
0046     update();
0047     mainLayout->addWidget(m_fleetTable);
0048     mainLayout->addWidget(buttonBox);
0049 }
0050 
0051 
0052 QSize
0053 FleetDlg::sizeHint() const
0054 {
0055     int w = m_fleetTable->verticalHeader()->width();
0056     int h = m_fleetTable->horizontalHeader()->height();
0057 
0058     for (int col = 0; col < m_fleetTable->columnCount(); ++col) {
0059         w += m_fleetTable->columnWidth(col);
0060     }
0061 
0062     for (int row = 0; row < m_fleetTable->rowCount(); ++row) {
0063         h += m_fleetTable->rowHeight(row);
0064     }
0065 
0066     /**
0067      * @todo The created dialogue should not be larger than the screen, and
0068      * ideally, it should not be larger than the main application window.
0069      * As the vertical main application window size is not (yet) known here,
0070      * simply use a hard-coded limit right now.
0071      */
0072 
0073     if (h > 480) {
0074 
0075         // As the height of the widget is reduced, a vertical scrollbar is
0076         // shown. Add the width of that scrollbar to the width of the widget to
0077         // prevent a horizontal scrollbar from appearing.
0078 
0079         h = 480;
0080         w += m_fleetTable->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
0081     }
0082 
0083     /**
0084      * @todo The size calculated here does not yet prevent scrollbars to be
0085      * shown for the table. Figure out the offsets needed to be added and remove
0086      * the hard-coded numbers below! One reason here is that this size hint is
0087      * for the whole dialogue and not just for the table.
0088      */
0089 
0090     return QSize(w, h) + QSize(40, 80);
0091 }
0092 
0093 
0094 void
0095 FleetDlg::setupTable()
0096 {
0097     m_fleetTable = new QTableWidget(this);
0098     m_fleetTable->setColumnCount(7);
0099     m_fleetTable->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
0100     m_fleetTable->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
0101     m_fleetTable->setSelectionMode(QAbstractItemView::NoSelection);
0102 
0103     QStringList headerLabels;
0104     headerLabels
0105         << QString()
0106         << i18n("Fleet No.")
0107         << i18n("Source")
0108         << i18n("Destination")
0109         << i18n("Ships")
0110         << i18n("Kill Percentage")
0111         << i18n("Arrival Turn");
0112 
0113     m_fleetTable->setHorizontalHeaderLabels(headerLabels);
0114     m_fleetTable->verticalHeader()->hide();
0115 }
0116 
0117 
0118 void
0119 FleetDlg::update()
0120 {
0121     const AttackFleetList fleets = m_standingOrders + m_newFleetList + m_fleetList;
0122     const int standingOrders = m_standingOrders.count();
0123     const int newFleets = standingOrders + m_newFleetList.count();
0124 
0125     m_fleetTable->setRowCount( fleets.count() );
0126 
0127     int row = 0;
0128     QTableWidgetItem *item;
0129 
0130     for (AttackFleet *curFleet : fleets) {
0131         item = new QTableWidgetItem();
0132         if( row < newFleets) {
0133           item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
0134           item->setCheckState(Qt::Checked);
0135           if( row < standingOrders )
0136               item->setText(i18n("Standing order"));
0137         } else {
0138           item->setFlags(Qt::ItemIsEnabled);
0139         }
0140         m_fleetTable->setItem(row, 0, item);
0141 
0142         item = new QTableWidgetItem();
0143         item->setData(Qt::DisplayRole, row + 1);
0144         item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
0145         item->setFlags(Qt::ItemIsEnabled);
0146         m_fleetTable->setItem(row, 1, item);
0147 
0148         item = new QTableWidgetItem();
0149         item->setData(Qt::DisplayRole, curFleet->source->name());
0150         item->setData(Qt::DecorationRole, curFleet->source->player()->color());
0151         item->setFlags(Qt::ItemIsEnabled);
0152         m_fleetTable->setItem(row, 2, item);
0153 
0154         item = new QTableWidgetItem();
0155         item->setData(Qt::DisplayRole, curFleet->destination->name());
0156         item->setData(Qt::DecorationRole, curFleet->destination->player()->color());
0157         item->setFlags(Qt::ItemIsEnabled);
0158         m_fleetTable->setItem(row, 3, item);
0159 
0160         item = new QTableWidgetItem();
0161         item->setData(Qt::DisplayRole, curFleet->shipCount());
0162         item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
0163         item->setFlags(Qt::ItemIsEnabled);
0164         m_fleetTable->setItem(row, 4, item);
0165 
0166         // The number is formatted and added as a string. Sorting by this
0167         // column sorts by string comparison rather than by floating point
0168         // number comparison. But as all values have the same amount of
0169         // characters/digits, sorting by string actually works.
0170 
0171         item = new QTableWidgetItem(QStringLiteral("%1").arg(curFleet->source->killPercentage(), 3, 'f', 3));
0172         item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
0173         item->setFlags(Qt::ItemIsEnabled);
0174         m_fleetTable->setItem(row, 5, item);
0175 
0176         item = new QTableWidgetItem();
0177         item->setData(Qt::DisplayRole, curFleet->arrivalTurn);
0178         item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
0179         item->setFlags(Qt::ItemIsEnabled);
0180         m_fleetTable->setItem(row, 6, item);
0181 
0182         ++row;
0183     }
0184 
0185     m_fleetTable->setSortingEnabled(true);
0186     m_fleetTable->resizeColumnsToContents();
0187 }
0188 
0189 
0190 AttackFleetList*
0191 FleetDlg::uncheckedFleets()
0192 {
0193     AttackFleetList *fleets = new AttackFleetList();
0194     QTableWidgetItem *item;
0195     int count = m_fleetTable->rowCount();
0196 
0197     for( int f = 0; f < count; ++f) {
0198         item = m_fleetTable->item(f,0);
0199         if( (item->flags() & Qt::ItemIsUserCheckable) &&
0200             (item->checkState() == Qt::Unchecked) ) {
0201 
0202             const int pos = m_fleetTable->item(f,1)->text().toInt() - 1;
0203             if (pos >= 0)
0204             {
0205                 if(pos < m_standingOrders.count())
0206                     fleets->append( m_standingOrders.at(pos) );
0207                 else
0208                     fleets->append( m_newFleetList.at(pos - m_standingOrders.count()) );
0209             }
0210         }
0211     }
0212 
0213     return fleets;
0214 }