File indexing completed on 2025-01-05 03:35:18

0001 /*
0002     File                 : ColorMapsWidget.h
0003     Project              : LabPlot
0004     Description          : widget showing the available color maps
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2021 Alexander Semke <alexander.semke@web.de>
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "kdefrontend/colormaps/ColorMapsWidget.h"
0011 #include "backend/core/Settings.h"
0012 #include "backend/lib/macros.h"
0013 #include "tools/ColorMapsManager.h"
0014 
0015 #include <QCompleter>
0016 #include <QMessageBox>
0017 #include <QPainter>
0018 #include <QStandardItemModel>
0019 #include <QWhatsThis>
0020 
0021 #include <KConfigGroup>
0022 #include <KLocalizedString>
0023 
0024 /*!
0025     \class ColorMapsWidget
0026     \brief Widget for importing data from a dataset.
0027 
0028     \ingroup kdefrontend
0029  */
0030 ColorMapsWidget::ColorMapsWidget(QWidget* parent)
0031     : QWidget(parent) {
0032     ui.setupUi(this);
0033     ui.bInfo->setIcon(QIcon::fromTheme(QLatin1String("help-about")));
0034     ui.bViewMode->setIcon(QIcon::fromTheme(QLatin1String("view-list-icons")));
0035     ui.bViewMode->setToolTip(i18n("Switch between icon and list views"));
0036 
0037     ui.lvColorMaps->setViewMode(QListView::IconMode);
0038     ui.lvColorMaps->setSelectionMode(QAbstractItemView::SingleSelection);
0039     ui.lvColorMaps->setWordWrap(true);
0040     ui.lvColorMaps->setResizeMode(QListWidget::Adjust);
0041     ui.lvColorMaps->setDragDropMode(QListView::NoDragDrop);
0042     ui.lvColorMaps->setEditTriggers(QAbstractItemView::NoEditTriggers);
0043     ui.lvColorMaps->setIconSize(QSize(128, 128));
0044     connect(ui.lvColorMaps, &QAbstractItemView::doubleClicked, this, &ColorMapsWidget::doubleClicked);
0045 
0046     const int size = ui.leSearch->height();
0047     ui.lSearch->setPixmap(QIcon::fromTheme(QLatin1String("edit-find")).pixmap(size, size));
0048 
0049     QString info = i18n("Enter the keyword you want to search for");
0050     ui.lSearch->setToolTip(info);
0051     ui.leSearch->setToolTip(info);
0052     ui.leSearch->setPlaceholderText(i18n("Search..."));
0053     ui.leSearch->setFocus();
0054 
0055     m_manager = ColorMapsManager::instance();
0056     ui.cbCollections->addItems(m_manager->collectionNames());
0057 
0058     connect(ui.cbCollections, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &ColorMapsWidget::collectionChanged);
0059     connect(ui.bInfo, &QPushButton::clicked, this, &ColorMapsWidget::showInfo);
0060     connect(ui.bViewMode, &QPushButton::clicked, this, &ColorMapsWidget::toggleIconView);
0061     connect(ui.stackedWidget, &QStackedWidget::currentChanged, this, &ColorMapsWidget::viewModeChanged);
0062     connect(ui.lwColorMaps, &QListWidget::itemSelectionChanged, this, &ColorMapsWidget::colorMapChanged);
0063 
0064     // select the last used collection
0065     KConfigGroup conf = Settings::group(QStringLiteral("ColorMapsWidget"));
0066     const QString& collection = conf.readEntry("Collection", QString());
0067     if (collection.isEmpty())
0068         ui.cbCollections->setCurrentIndex(0);
0069     else {
0070         for (int i = 0; i < ui.cbCollections->count(); ++i) {
0071             if (ui.cbCollections->itemText(i) == collection) {
0072                 ui.cbCollections->setCurrentIndex(i);
0073                 break;
0074             }
0075         }
0076 
0077         const QString& colorMap = conf.readEntry("ColorMap", QString());
0078         auto items = ui.lwColorMaps->findItems(colorMap, Qt::MatchExactly);
0079         if (items.count() == 1)
0080             ui.lwColorMaps->setCurrentItem(items.constFirst());
0081     }
0082 
0083     collectionChanged(ui.cbCollections->currentIndex());
0084 
0085     ui.stackedWidget->setCurrentIndex(conf.readEntry("ViewIndex", 0));
0086 }
0087 
0088 ColorMapsWidget::~ColorMapsWidget() {
0089     // save the selected collection
0090     KConfigGroup conf = Settings::group(QStringLiteral("ColorMapsWidget"));
0091     conf.writeEntry("Collection", ui.cbCollections->currentText());
0092     conf.writeEntry("ViewIndex", ui.stackedWidget->currentIndex());
0093     if (ui.lwColorMaps->currentItem())
0094         conf.writeEntry("ColorMap", ui.lwColorMaps->currentItem()->text());
0095 }
0096 
0097 /**
0098  * Shows all categories and sub-categories for the currently selected collection
0099  */
0100 void ColorMapsWidget::collectionChanged(int) {
0101     const QString& collection = ui.cbCollections->currentText();
0102 
0103     // populate the list view for the icon mode
0104     if (m_model)
0105         delete m_model;
0106 
0107     m_model = new QStandardItemModel(this);
0108     const auto& colorMapNames = m_manager->colorMapNames(collection);
0109     for (const auto& name : colorMapNames) {
0110         auto* item = new QStandardItem();
0111         QPixmap pixmap;
0112         m_manager->render(pixmap, name);
0113         item->setIcon(QIcon(pixmap));
0114         item->setText(name);
0115         m_model->appendRow(item);
0116     }
0117 
0118     ui.lvColorMaps->setModel(m_model);
0119 
0120     // populate the list widget for the list mode
0121     ui.lwColorMaps->clear();
0122     ui.lwColorMaps->addItems(colorMapNames);
0123 
0124     // select the first color map in the current collection
0125     ui.lvColorMaps->setCurrentIndex(ui.lvColorMaps->model()->index(0, 0));
0126     ui.lwColorMaps->setCurrentRow(0);
0127 
0128     // update the completer
0129     if (m_completer)
0130         delete m_completer;
0131 
0132     m_completer = new QCompleter(colorMapNames, this);
0133     connect(m_completer, QOverload<const QString&>::of(&QCompleter::activated), this, &ColorMapsWidget::activated);
0134     m_completer->setCompletionMode(QCompleter::PopupCompletion);
0135     m_completer->setCaseSensitivity(Qt::CaseInsensitive);
0136     m_completer->setFilterMode(Qt::MatchContains);
0137     ui.leSearch->setCompleter(m_completer);
0138 }
0139 
0140 void ColorMapsWidget::colorMapChanged() {
0141     const QString& name = ui.lwColorMaps->currentItem()->text();
0142     m_manager->render(m_pixmap, name);
0143     ui.lPreview->setPixmap(m_pixmap);
0144 }
0145 
0146 void ColorMapsWidget::showInfo() {
0147     const QString& collection = ui.cbCollections->currentText();
0148     const QString& info = m_manager->collectionInfo(collection);
0149     QWhatsThis::showText(ui.bInfo->mapToGlobal(QPoint(0, 0)), info, ui.bInfo);
0150 }
0151 
0152 void ColorMapsWidget::toggleIconView() {
0153     if (ui.bViewMode->isChecked())
0154         ui.stackedWidget->setCurrentIndex(0);
0155     else
0156         ui.stackedWidget->setCurrentIndex(1);
0157 }
0158 
0159 void ColorMapsWidget::viewModeChanged(int index) {
0160     if (index == 0) {
0161         // switching form list to icon view mode
0162         if (ui.lwColorMaps->currentItem()) {
0163             const auto& name = ui.lwColorMaps->currentItem()->text();
0164             activateIconViewItem(name);
0165         }
0166     } else {
0167         // switching form icon to list view mode
0168         if (ui.lvColorMaps->currentIndex().isValid()) {
0169             const auto& name = ui.lvColorMaps->currentIndex().data(Qt::DisplayRole).toString();
0170             activateListViewItem(name);
0171         }
0172     }
0173 }
0174 
0175 void ColorMapsWidget::activated(const QString& name) {
0176     if (ui.bViewMode->isChecked())
0177         activateIconViewItem(name);
0178     else
0179         activateListViewItem(name);
0180 }
0181 
0182 void ColorMapsWidget::activateIconViewItem(const QString& name) {
0183     auto* model = ui.lvColorMaps->model();
0184     for (int i = 0; i < model->rowCount(); ++i) {
0185         const auto& index = model->index(i, 0);
0186         if (index.data(Qt::DisplayRole).toString() == name) {
0187             ui.lvColorMaps->setCurrentIndex(index);
0188             ui.lvColorMaps->scrollTo(index);
0189         }
0190     }
0191 }
0192 
0193 void ColorMapsWidget::activateListViewItem(const QString& name) {
0194     const auto& items = ui.lwColorMaps->findItems(name, Qt::MatchExactly);
0195     if (items.count())
0196         ui.lwColorMaps->setCurrentItem(items.constFirst());
0197 }
0198 
0199 QPixmap ColorMapsWidget::previewPixmap() {
0200     if (ui.stackedWidget->currentIndex() == 0 && ui.lvColorMaps->currentIndex().isValid()) {
0201         const QString& name = ui.lvColorMaps->currentIndex().data(Qt::DisplayRole).toString();
0202         m_manager->render(m_pixmap, name);
0203     }
0204 
0205     return m_pixmap;
0206 }
0207 
0208 /*!
0209  * returns the name of the currently selected color map.
0210  */
0211 QString ColorMapsWidget::name() const {
0212     if (ui.stackedWidget->currentIndex() == 0) {
0213         if (ui.lvColorMaps->currentIndex().isValid())
0214             return ui.lvColorMaps->currentIndex().data(Qt::DisplayRole).toString();
0215     } else {
0216         if (ui.lwColorMaps->currentItem())
0217             return ui.lwColorMaps->currentItem()->text();
0218     }
0219 
0220     return {};
0221 }
0222 
0223 /*!
0224  * returns the vector with the colors of the currently selected color map.
0225  */
0226 QVector<QColor> ColorMapsWidget::colors() const {
0227     return m_manager->colors();
0228 }