File indexing completed on 2025-01-26 04:11:27

0001 /*
0002  *  SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 #include "KisFilterOptionWidget.h"
0007 
0008 #include <QWidget>
0009 #include <QCheckBox>
0010 #include <QGridLayout>
0011 
0012 #include <kis_signals_blocker.h>
0013 
0014 #include <kis_config_widget.h>
0015 #include <filter/kis_filter.h>
0016 #include <filter/kis_filter_registry.h>
0017 #include <filter/kis_filter_configuration.h>
0018 
0019 #include <KisFilterOptionModel.h>
0020 #include <KisWidgetConnectionUtils.h>
0021 
0022 #include "ui_wdgfilteroption.h"
0023 
0024 
0025 namespace {
0026 class FilterWidget : public QWidget, public Ui::FilterOpOptions
0027 {
0028 public:
0029     FilterWidget(QWidget* parent = 0)
0030         : QWidget(parent) {
0031         setupUi(this);
0032     }
0033 };
0034 }
0035 
0036 
0037 struct KisFilterOptionWidget::Private
0038 {
0039     Private(lager::cursor<KisFilterOptionData> optionData)
0040         : model(optionData)
0041     {
0042     }
0043 
0044     QGridLayout *layout {0};
0045 
0046     KisFilterOptionModel model;
0047 
0048     KisImageWSP image;
0049     KisPaintDeviceSP paintDevice;
0050 
0051     KisFilterSP currentFilter;
0052     FilterWidget *page {0};
0053     KisConfigWidget *currentFilterConfigWidget {0};
0054 };
0055 
0056 
0057 KisFilterOptionWidget::KisFilterOptionWidget(lager::cursor<KisFilterOptionData> optionData)
0058     : KisPaintOpOption(i18n("Filter"), KisPaintOpOption::COLOR, true)
0059     , m_d(new Private(optionData))
0060 {
0061     setObjectName("KisFilterOption");
0062     m_checkable = false;
0063     using namespace KisWidgetConnectionUtils;
0064 
0065     m_d->page = new FilterWidget();
0066     setConfigurationPage(m_d->page);
0067 
0068     m_d->layout = new QGridLayout(m_d->page->grpFilterOptions);
0069 
0070     // Check which filters support painting
0071     QList<QString> allFilters = KisFilterRegistry::instance()->keys();
0072     QList<KoID> supportedFilters;
0073 
0074     for (auto it = allFilters.begin(); it != allFilters.end(); ++it) {
0075         KisFilterSP f = KisFilterRegistry::instance()->value((*it));
0076         if (f->supportsPainting()) {
0077             supportedFilters.push_back(KoID(*it, f->name()));
0078         }
0079     }
0080 
0081     m_d->page->filtersList->setIDList(supportedFilters);
0082 
0083     m_d->model.LAGER_QT(effectiveFilterState).bind(
0084                 kismpl::unzip_wrapper(
0085                     std::bind(&KisFilterOptionWidget::updateFilterState,
0086                               this,
0087                               std::placeholders::_1,
0088                               std::placeholders::_2,
0089                               false)));
0090 
0091     connect(m_d->page->filtersList, &KisCmbIDList::activated, this, &KisFilterOptionWidget::slotFilterIdChangedInGui);
0092 
0093     connectControl(m_d->page->checkBoxSmudgeMode, &m_d->model, "smudgeMode");
0094 
0095     m_d->model.optionData.bind(std::bind(&KisFilterOptionWidget::emitSettingChanged, this));
0096 }
0097 
0098 KisFilterOptionWidget::~KisFilterOptionWidget()
0099 {
0100 }
0101 
0102 void KisFilterOptionWidget::writeOptionSetting(KisPropertiesConfigurationSP setting) const
0103 {
0104     m_d->model.bakedOptionData().write(setting.data());
0105 }
0106 
0107 void KisFilterOptionWidget::readOptionSetting(const KisPropertiesConfigurationSP setting)
0108 {
0109     KisFilterOptionData data = m_d->model.bakedOptionData();
0110     data.read(setting.data());
0111     m_d->model.optionData.set(data);
0112 
0113 }
0114 
0115 void KisFilterOptionWidget::setImage(KisImageWSP image)
0116 {
0117     m_d->image = image;
0118     m_d->model.LAGER_QT(effectiveFilterState).nudge();
0119 }
0120 
0121 void KisFilterOptionWidget::setNode(KisNodeWSP node)
0122 {
0123     m_d->paintDevice = node && node->paintDevice() ? node->paintDevice() : nullptr;
0124 
0125     QString filterId;
0126     QString filterConfig;
0127     std::tie(filterId, filterConfig) = m_d->model.effectiveFilterState();
0128     updateFilterState(filterId, filterConfig, true);
0129 }
0130 
0131 void KisFilterOptionWidget::updateFilterState(const QString &filterId, const QString &filterConfig, bool forceResetWidget)
0132 {
0133     if (!m_d->currentFilter ||
0134         m_d->page->filtersList->currentItem().id() != filterId) {
0135 
0136         KisSignalsBlocker b(m_d->page->filtersList);
0137         m_d->page->filtersList->setCurrent(filterId);
0138 
0139         m_d->currentFilter = KisFilterRegistry::instance()->value(filterId);
0140         KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->currentFilter);
0141 
0142         forceResetWidget = true;
0143     }
0144 
0145     if (!m_d->paintDevice) {
0146         forceResetWidget = true;
0147     }
0148 
0149     if (forceResetWidget && m_d->currentFilterConfigWidget) {
0150         m_d->currentFilterConfigWidget->hide();
0151         m_d->layout->removeWidget(m_d->currentFilterConfigWidget);
0152         m_d->layout->invalidate();
0153         delete m_d->currentFilterConfigWidget;
0154         m_d->currentFilterConfigWidget = nullptr;
0155     }
0156 
0157     if (m_d->paintDevice && !m_d->currentFilterConfigWidget) {
0158         m_d->currentFilterConfigWidget =
0159             m_d->currentFilter->createConfigurationWidget(m_d->page->grpFilterOptions, m_d->paintDevice, true);
0160 
0161         if (m_d->currentFilterConfigWidget) {
0162             KisSignalsBlocker b(m_d->currentFilterConfigWidget);
0163 
0164             // TODO: init resources in ctor
0165             m_d->currentFilterConfigWidget->setCanvasResourcesInterface(canvasResourcesInterface());
0166             m_d->currentFilterConfigWidget->setConfiguration(m_d->currentFilter->defaultConfiguration(resourcesInterface()));
0167             m_d->layout->addWidget(m_d->currentFilterConfigWidget);
0168             m_d->page->grpFilterOptions->updateGeometry();
0169             m_d->currentFilterConfigWidget->show();
0170             connect(m_d->currentFilterConfigWidget, SIGNAL(sigConfigurationUpdated()),
0171                     this, SLOT(slotFilterConfigChangedInGui()));
0172         }
0173     }
0174 
0175     if (m_d->currentFilterConfigWidget) {
0176         KisFilterConfigurationSP config =
0177             m_d->currentFilter->factoryConfiguration(resourcesInterface());
0178 
0179         config->fromXML(filterConfig);
0180 
0181         KisSignalsBlocker b(m_d->currentFilterConfigWidget);
0182         m_d->currentFilterConfigWidget->setConfiguration(config);
0183     }
0184 }
0185 
0186 void KisFilterOptionWidget::slotFilterIdChangedInGui(const KoID &filterId)
0187 {
0188     if (m_d->currentFilter && m_d->currentFilter->id() == filterId.id()) return;
0189 
0190     KisFilterSP newFilter = KisFilterRegistry::instance()->value(filterId.id());
0191     KIS_SAFE_ASSERT_RECOVER_RETURN(newFilter);
0192 
0193     KisFilterConfigurationSP filterConfig = newFilter->defaultConfiguration(resourcesInterface());
0194     m_d->model.seteffectiveFilterState(std::make_tuple(filterId.id(), filterConfig->toXML()));
0195 }
0196 
0197 void KisFilterOptionWidget::slotFilterConfigChangedInGui()
0198 {
0199     KIS_SAFE_ASSERT_RECOVER_RETURN(m_d->currentFilter);
0200 
0201     QString config;
0202 
0203     if (m_d->currentFilterConfigWidget) {
0204         config = m_d->currentFilterConfigWidget->configuration()->toXML();
0205     } else {
0206         KisFilterConfigurationSP filterConfig = m_d->currentFilter->defaultConfiguration(resourcesInterface());
0207         config = filterConfig->toXML();
0208     }
0209 
0210     m_d->model.seteffectiveFilterState(std::make_tuple(m_d->currentFilter->id(), config));
0211 }