File indexing completed on 2024-05-12 17:07:14

0001 /*
0002     SPDX-FileCopyrightText: 2010 Andriy Rysin <rysin@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include <algorithm>
0008 
0009 #include "kcm_add_layout_dialog.h"
0010 #include <KLocalizedString>
0011 #include <QDebug>
0012 
0013 #include "flags.h"
0014 #include "iso_codes.h"
0015 #include "tastenbrett.h"
0016 #include "xkb_rules.h"
0017 
0018 #include "ui_kcm_add_layout_dialog.h"
0019 
0020 AddLayoutDialog::AddLayoutDialog(const Rules *rules_, Flags *flags_, const QString &model_, const QStringList &options_, bool showLabel, QWidget *parent)
0021     : QDialog(parent)
0022     , rules(rules_)
0023     , flags(flags_)
0024     , model(model_)
0025     , options(options_)
0026 {
0027     layoutDialogUi = new Ui_AddLayoutDialog();
0028     layoutDialogUi->setupUi(this);
0029 
0030     for (const LayoutInfo *layoutInfo : qAsConst(rules->layoutInfos)) {
0031         QIcon icon;
0032         if (flags) {
0033             icon = flags->getIcon(layoutInfo->name);
0034             if (icon.isNull()) {
0035                 // HACK: QListWidget->iconSize() returns an invalid size, so we can't use that to construct an empty icon
0036                 // instead we pick a large size and QListWidget will scale it down automatically
0037                 QPixmap emptyPixmap(QSize(48, 48));
0038                 emptyPixmap.fill(Qt::transparent);
0039                 icon = QIcon(emptyPixmap); // align text with no icons
0040             }
0041         }
0042         QListWidgetItem *defaultVariantItem = new QListWidgetItem(layoutInfo->description);
0043         if (flags) {
0044             defaultVariantItem->setIcon(icon);
0045         }
0046         defaultVariantItem->setData(LayoutNameRole, layoutInfo->name);
0047         defaultVariantItem->setData(VariantNameRole, QStringLiteral(""));
0048         layoutDialogUi->layoutListWidget->addItem(defaultVariantItem);
0049         for (const VariantInfo *variantInfo : layoutInfo->variantInfos) {
0050             QListWidgetItem *newItem = new QListWidgetItem(variantInfo->description);
0051             if (flags) {
0052                 newItem->setIcon(icon);
0053             }
0054             newItem->setData(LayoutNameRole, layoutInfo->name);
0055             newItem->setData(VariantNameRole, variantInfo->name);
0056             layoutDialogUi->layoutListWidget->addItem(newItem);
0057         }
0058     }
0059 
0060     if (showLabel) {
0061         layoutDialogUi->labelEdit->setMaxLength(LayoutUnit::MAX_LABEL_LENGTH);
0062     } else {
0063         layoutDialogUi->labelLabel->setVisible(false);
0064         layoutDialogUi->labelEdit->setVisible(false);
0065     }
0066 
0067     connect(layoutDialogUi->layoutSearchField,
0068             static_cast<void (QLineEdit::*)(const QString &)>(&QLineEdit::textChanged),
0069             this,
0070             &AddLayoutDialog::layoutSearched);
0071     connect(layoutDialogUi->layoutListWidget,
0072             static_cast<void (QListWidget::*)(QListWidgetItem *, QListWidgetItem *)>(&QListWidget::currentItemChanged),
0073             this,
0074             &AddLayoutDialog::layoutChanged);
0075 
0076     connect(layoutDialogUi->prevbutton, &QPushButton::clicked, this, &AddLayoutDialog::preview);
0077     layoutDialogUi->prevbutton->setVisible(Tastenbrett::exists());
0078     layoutDialogUi->prevbutton->setEnabled(false);
0079     layoutDialogUi->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
0080 }
0081 
0082 void AddLayoutDialog::layoutSearched(const QString &searchText)
0083 {
0084     QListWidget *list = layoutDialogUi->layoutListWidget;
0085     for (int row = 0; row < list->count(); ++row) {
0086         QString itemText = list->item(row)->text();
0087         bool match = (itemText.contains(searchText, Qt::CaseInsensitive));
0088         const QStringList words = searchText.split(QLatin1Char(' '), Qt::SkipEmptyParts);
0089         match = match || std::all_of(words.cbegin(), words.cend(), [&itemText](const QString &word) {
0090                     return itemText.contains(word, Qt::CaseInsensitive);
0091                 });
0092         list->item(row)->setHidden(!match);
0093     }
0094 }
0095 
0096 void AddLayoutDialog::layoutChanged(QListWidgetItem *current, QListWidgetItem *previous)
0097 {
0098     Q_UNUSED(previous);
0099     if (current) {
0100         selectedLayout = current->data(LayoutNameRole).toString();
0101         selectedLayoutUnit.setLayout(selectedLayout);
0102         selectedLayoutUnit.setVariant(current->data(VariantNameRole).toString());
0103     }
0104     layoutDialogUi->prevbutton->setEnabled((bool)(current));
0105     layoutDialogUi->buttonBox->button(QDialogButtonBox::Ok)->setEnabled((bool)(current));
0106 }
0107 
0108 void AddLayoutDialog::accept()
0109 {
0110     QString label = layoutDialogUi->labelEdit->text();
0111     if (label == selectedLayout) {
0112         label = QString();
0113     }
0114     selectedLayoutUnit.setDisplayName(label);
0115     selectedLayoutUnit.setShortcut(layoutDialogUi->kkeysequencewidget->keySequence());
0116     QDialog::accept();
0117 }
0118 
0119 void AddLayoutDialog::preview()
0120 {
0121     QString variant = layoutDialogUi->layoutListWidget->currentItem()->data(VariantNameRole).toString();
0122     Tastenbrett::launch(model, selectedLayout, variant, options.join(','));
0123 }