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 }