File indexing completed on 2024-12-08 06:46:06

0001 /*
0002     This file is part of Killbots.
0003 
0004     SPDX-FileCopyrightText: 2007-2009 Parker Coates <coates@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "rulesetselector.h"
0010 
0011 #include "ruleset.h"
0012 #include "rulesetdetailsdialog.h"
0013 #include "settings.h"
0014 
0015 #include <KLineEdit>
0016 #include <KLocalizedString>
0017 
0018 #include <QDir>
0019 #include <QGroupBox>
0020 #include <QLabel>
0021 #include <QListWidget>
0022 #include <QPushButton>
0023 #include <QGridLayout>
0024 #include <QVBoxLayout>
0025 
0026 Killbots::RulesetSelector::RulesetSelector(QWidget *parent)
0027     : QWidget(parent),
0028       m_rulesetMap(),
0029       m_detailsDialog(nullptr)
0030 {
0031     // Create a hidden KLineEdit to use the automatic KConfigXT connection
0032     kcfg_Ruleset = new KLineEdit();
0033     kcfg_Ruleset->setObjectName(QStringLiteral("kcfg_Ruleset"));
0034     kcfg_Ruleset->hide();
0035 
0036     m_listWidget = new QListWidget();
0037     m_listWidget->setWhatsThis(i18nc("@info:whatsthis", "A list of the Killbots rulesets installed on this computer."));
0038 
0039     QGroupBox *groupBox = new QGroupBox(i18nc("title:group", "Game Type Details"));
0040     groupBox->setWhatsThis(i18nc("@info:whatsthis", "Lists information on the currently selected game type."));
0041 
0042     QLabel *authorLabel = new QLabel(i18nc("@label", "Author:"));
0043     authorLabel->setAlignment(Qt::AlignRight | Qt::AlignTop);
0044 
0045     m_author = new QLabel();
0046     m_author->setAlignment(Qt::AlignLeft | Qt::AlignTop);
0047     m_author->setWordWrap(true);
0048 
0049     QLabel *contactLabel = new QLabel(i18nc("@label", "Contact:"));
0050     contactLabel->setAlignment(Qt::AlignRight | Qt::AlignTop);
0051 
0052     m_authorContact = new QLabel();
0053     m_authorContact->setAlignment(Qt::AlignLeft | Qt::AlignTop);
0054     m_authorContact->setWordWrap(true);
0055     m_authorContact->setOpenExternalLinks(true);
0056 
0057     QLabel *descriptionLabel = new QLabel(i18nc("@label", "Description:"));
0058     descriptionLabel->setAlignment(Qt::AlignRight | Qt::AlignTop);
0059 
0060     m_description = new QLabel();
0061     m_description->setAlignment(Qt::AlignLeft | Qt::AlignTop);
0062     m_description->setWordWrap(true);
0063 
0064     QPushButton *detailsButton = new QPushButton(i18nc("@action:button", "Details..."));
0065     detailsButton->setToolTip(i18nc("@info:tooltip", "Show the detailed parameters of the selected game type"));
0066     detailsButton->setWhatsThis(i18nc("@info:whatsthisp", "Opens a dialog listing the values of all internal parameters for the selected game type."));
0067 
0068     QGridLayout *boxLayout = new QGridLayout(groupBox);
0069     boxLayout->addWidget(authorLabel, 1, 0);
0070     boxLayout->addWidget(m_author, 1, 1);
0071     boxLayout->addWidget(contactLabel, 2, 0);
0072     boxLayout->addWidget(m_authorContact, 2, 1);
0073     boxLayout->addWidget(descriptionLabel, 3, 0);
0074     boxLayout->addWidget(m_description, 3, 1);
0075     boxLayout->addWidget(detailsButton, 4, 1, Qt::AlignLeft);
0076     boxLayout->setColumnStretch(1, 10);
0077     boxLayout->setRowStretch(5, 10);
0078 
0079     QVBoxLayout *layout = new QVBoxLayout(this);
0080     layout->setContentsMargins(0, 0, 0, 0);
0081     layout->addWidget(kcfg_Ruleset);
0082     layout->addWidget(m_listWidget);
0083     layout->addWidget(groupBox, 10);
0084 
0085     connect(m_listWidget, &QListWidget::currentTextChanged, this, &RulesetSelector::selectionChanged);
0086     connect(detailsButton, &QPushButton::clicked, this, &RulesetSelector::showDetailsDialog);
0087 
0088     findRulesets();
0089 }
0090 
0091 Killbots::RulesetSelector::~RulesetSelector()
0092 {
0093     qDeleteAll(m_rulesetMap);
0094 }
0095 
0096 void Killbots::RulesetSelector::findRulesets()
0097 {
0098     qDeleteAll(m_rulesetMap);
0099     m_rulesetMap.clear();
0100 
0101     m_listWidget->clear();
0102     m_listWidget->setSortingEnabled(true);
0103 
0104     const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("killbots/rulesets/"), QStandardPaths::LocateDirectory);
0105     for (const QString &dir : dirs) {
0106         const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.desktop"));
0107         for (const QString &file : fileNames) {
0108             const Ruleset *ruleset = Ruleset::load(file);
0109             if (ruleset) {
0110                 QString name = ruleset->name();
0111                 while (m_rulesetMap.contains(name)) {
0112                     name += QLatin1Char('_');
0113                 }
0114 
0115                 m_rulesetMap.insert(name, ruleset);
0116 
0117                 QListWidgetItem *item = new QListWidgetItem(name, m_listWidget);
0118                 if (file == Settings::ruleset()) {
0119                     m_listWidget->setCurrentItem(item);
0120                 }
0121             } else {
0122                 delete ruleset;
0123             }
0124         }
0125     }
0126 
0127     // Set the maximum height of the list widget to be no more than the size of its contents
0128     // This is slightly hackish, but the effect is nice.
0129     const int itemHeight = m_listWidget->visualItemRect(m_listWidget->item(0)).height();
0130     const int verticalMargin = m_listWidget->height() - m_listWidget->viewport()->height();
0131     m_listWidget->setMaximumHeight(itemHeight * m_listWidget->count() + verticalMargin);
0132 }
0133 
0134 void Killbots::RulesetSelector::selectionChanged(const QString &rulesetName)
0135 {
0136     const Ruleset *ruleset = m_rulesetMap.value(rulesetName);
0137 
0138     kcfg_Ruleset->setText(ruleset->fileName());
0139 
0140     m_author->setText(ruleset->author());
0141     if (ruleset->authorContact().contains(QLatin1Char(' '))) {
0142         m_authorContact->setText(ruleset->authorContact());
0143     } else if (ruleset->authorContact().contains(QLatin1Char('@'))) {
0144         m_authorContact->setText(QStringLiteral("<qt><a href=\"mailto:%1\">%1</a></qt>").arg(ruleset->authorContact()));
0145     } else if (ruleset->authorContact().contains(QLatin1Char('.'))) {
0146         m_authorContact->setText(QStringLiteral("<qt><a href=\"https://%1\">%1</a></qt>").arg(ruleset->authorContact()));
0147     } else {
0148         m_authorContact->setText(ruleset->authorContact());
0149     }
0150     m_description->setText(ruleset->description());
0151 
0152     if (m_detailsDialog && m_detailsDialog->isVisible()) {
0153         m_detailsDialog->loadRuleset(ruleset);
0154     }
0155 }
0156 
0157 void Killbots::RulesetSelector::showDetailsDialog()
0158 {
0159     if (!m_detailsDialog) {
0160         m_detailsDialog = new RulesetDetailsDialog(this);
0161     }
0162 
0163     const Ruleset *ruleset = m_rulesetMap.value(m_listWidget->currentItem()->text());
0164     m_detailsDialog->loadRuleset(ruleset);
0165     m_detailsDialog->show();
0166 }
0167 
0168 #include "moc_rulesetselector.cpp"