Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_dlg_filter.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
3 * SPDX-FileCopyrightText: 2008 Boudewijn Rempt <boud@valdysa.org>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8#include "kis_dlg_filter.h"
9
10
11
12#include <KoResourcePaths.h>
13#include <filter/kis_filter.h>
15#include <kis_filter_mask.h>
16#include <kis_node.h>
17#include <kis_layer.h>
18#include <kis_paint_layer.h>
19#include <KisViewManager.h>
20#include <kis_config.h>
21
22#include "kis_selection.h"
24#include "kis_filter_manager.h"
25#include "ui_wdgfilterdialog.h"
26#include "kis_canvas2.h"
28#include <kis_icon_utils.h>
29
30#include <kstandardguiitem.h>
31
33 Private(KisFilterManager *_filterManager, KisViewManager *_view)
34 : currentFilter(0)
35 , resizeCount(0)
36 , view(_view)
37 , filterManager(_filterManager)
38 , blockModifyingActionsGuard(new KisInputActionGroupsMaskGuard(view->canvasBase()->inputActionGroupsMaskInterface(), ViewTransformActionGroup))
39 , updateCompressor(200, KisSignalCompressor::FIRST_ACTIVE)
40 {
42 [this] () {
43 return filterManager->isIdle();
44 },
45 20, 200);
46 }
47
49 Ui_FilterDialog uiFilterDialog;
54
55 // a special guard object that blocks all the painting input actions while the
56 // dialog is open
57 QScopedPointer<KisInputActionGroupsMaskGuard> blockModifyingActionsGuard;
59};
60
61KisDlgFilter::KisDlgFilter(KisViewManager *view, KisNodeSP node, KisFilterManager *filterManager, QWidget *parent) :
62 QDialog(parent),
63 d(new Private(filterManager, view))
64{
65 setModal(false);
66
67 d->uiFilterDialog.setupUi(this);
68 d->node = node;
69
70 d->uiFilterDialog.filterSelection->setView(view);
71 d->uiFilterDialog.filterSelection->showFilterGallery(KisConfig(true).showFilterGallery());
72
73 d->uiFilterDialog.pushButtonCreateMaskEffect->show();
74 connect(d->uiFilterDialog.pushButtonCreateMaskEffect, SIGNAL(pressed()), SLOT(createMask()));
75
76 d->uiFilterDialog.filterGalleryToggle->setChecked(d->uiFilterDialog.filterSelection->isFilterGalleryVisible());
77 d->uiFilterDialog.filterGalleryToggle->setIcon(KisIconUtils::loadIcon("sidebaricon"));
78 d->uiFilterDialog.filterGalleryToggle->setMaximumWidth(d->uiFilterDialog.filterGalleryToggle->height());
79 connect(d->uiFilterDialog.filterSelection, SIGNAL(sigFilterGalleryToggled(bool)), d->uiFilterDialog.filterGalleryToggle, SLOT(setChecked(bool)));
80 connect(d->uiFilterDialog.filterGalleryToggle, SIGNAL(toggled(bool)), d->uiFilterDialog.filterSelection, SLOT(showFilterGallery(bool)));
81 connect(d->uiFilterDialog.filterSelection, SIGNAL(sigSizeChanged()), this, SLOT(slotFilterWidgetSizeChanged()));
82
83 if (node->inherits("KisMask")) {
84 d->uiFilterDialog.pushButtonCreateMaskEffect->setVisible(false);
85 }
86
87 d->uiFilterDialog.filterSelection->setPaintDevice(true, d->node->paintDevice());
88
89 KGuiItem::assign(d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
90 KGuiItem::assign(d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
91
92 connect(d->uiFilterDialog.buttonBox, SIGNAL(accepted()), SLOT(accept()));
93 connect(d->uiFilterDialog.buttonBox, SIGNAL(rejected()), SLOT(reject()));
94 connect(d->uiFilterDialog.checkBoxPreview, SIGNAL(toggled(bool)), SLOT(enablePreviewToggled(bool)));
95 connect(d->uiFilterDialog.filterSelection, SIGNAL(configurationChanged()), SLOT(filterSelectionChanged()));
96
97 connect(this, SIGNAL(accepted()), SLOT(slotOnAccept()));
98 connect(this, SIGNAL(accepted()), d->uiFilterDialog.filterSelection, SLOT(slotBookMarkCurrentFilter()));
99 connect(this, SIGNAL(rejected()), SLOT(slotOnReject()));
100
101 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
102 d->uiFilterDialog.checkBoxPreview->setChecked(group.readEntry("showPreview", true));
103
104 d->uiFilterDialog.chkFilterSelectedFrames->setChecked(d->filterManager->filterAllSelectedFrames());
105
106 //Handle create mask toggle based on state of chkFilterSelectedFrames
107 connect(d->uiFilterDialog.chkFilterSelectedFrames, &QCheckBox::toggled, [this](const bool state){
108 if (d->currentFilter) {
109 d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(!state && d->currentFilter->supportsAdjustmentLayers());
110 }
111 });
112
113 d->uiFilterDialog.chkFilterSelectedFrames->setToolTip(i18n("In addition to filtering the currently visible frame, \nfilter all other keyframe selected in the Animation Timeline docker."));
114
115 restoreGeometry(KisConfig(true).readEntry("filterdialog/geometry", QByteArray()));
116 connect(&d->updateCompressor, SIGNAL(timeout()), this, SLOT(updatePreview()));
117
118}
119
121{
122 KisConfig(false).writeEntry("filterdialog/geometry", saveGeometry());
123 delete d;
124}
125
127{
128 Q_ASSERT(f);
130 d->uiFilterDialog.filterSelection->setFilter(f, overrideDefaultConfig);
131 const bool multiframeEnabled = d->uiFilterDialog.chkFilterSelectedFrames->isChecked();
132 d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(f->supportsAdjustmentLayers() && !multiframeEnabled);
133 d->currentFilter = f;
135}
136
138{
139 setWindowTitle(filter.isNull() ? i18nc("@title:window", "Filter") : i18nc("@title:window", "Filter: %1", filter->name()));
140}
141
143{
144 if (!d->uiFilterDialog.filterSelection->configuration()) return;
145
146 if (d->node->inherits("KisPaintLayer")) {
147 config->setChannelFlags(qobject_cast<KisPaintLayer*>(d->node.data())->channelLockFlags());
148 }
149
150 d->filterManager->apply(config);
151}
152
154{
155 KisFilterConfigurationSP config = d->uiFilterDialog.filterSelection->configuration();
156 if (!config) return;
157
158 bool maskCreationAllowed = !d->currentFilter || d->currentFilter->configurationAllowedForMask(config);
159 const bool multiframeEnabled = d->uiFilterDialog.chkFilterSelectedFrames->isChecked();
160 d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(maskCreationAllowed && !multiframeEnabled);
161
162 if (d->uiFilterDialog.checkBoxPreview->isChecked()) {
163 KisFilterConfigurationSP config(d->uiFilterDialog.filterSelection->configuration());
164 startApplyingFilter(config);
165 }
166
167 d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
168}
169
171{
172 QWidget::adjustSize();
173}
174
176{
177 QMetaObject::invokeMethod(this, "adjustSize", Qt::QueuedConnection);
178}
179
181{
183 KisFilterConfigurationSP config(d->uiFilterDialog.filterSelection->configuration());
184 startApplyingFilter(config);
185 }
186
187 d->filterManager->setFilterAllSelectedFrames(d->uiFilterDialog.chkFilterSelectedFrames->isChecked());
189
190 d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
191
192 KisConfig(false).setShowFilterGallery(d->uiFilterDialog.filterSelection->isFilterGalleryVisible());
193}
194
196{
199 }
200
201 KisConfig(false).setShowFilterGallery(d->uiFilterDialog.filterSelection->isFilterGalleryVisible());
202}
203
205{
206 if (d->node->inherits("KisMask")) return;
207
212 return;
213 }
214 }
215
216 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
217 KisFilterMaskSP mask = new KisFilterMask(d->view->image(), i18n("Filter Mask"));
218 mask->setName(d->currentFilter->name());
219 mask->initSelection(d->view->selection(), layer);
220 mask->setFilter(d->uiFilterDialog.filterSelection->configuration()->cloneWithResourcesSnapshot());
221
222 Q_ASSERT(layer->allowAsChild(mask));
223
224 KisNodeCommandsAdapter adapter(d->view);
225 adapter.addNode(mask, layer, layer->lastChild());
226
227 close();
228}
229
231{
232 if (checked) {
234 } else if (d->filterManager->isStrokeRunning()) {
236 }
237
238 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
239 group.writeEntry("showPreview", checked);
240
241 group.config()->sync();
242}
243
245{
246 KisFilterSP filter = d->uiFilterDialog.filterSelection->currentFilter();
247 setDialogTitle(filter);
248 d->currentFilter = filter;
249 const bool multiframeEnabled = d->uiFilterDialog.chkFilterSelectedFrames->isChecked();
250 d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(filter.isNull() ? false : (filter->supportsAdjustmentLayers() && !multiframeEnabled));
252}
@ ViewTransformActionGroup
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void writeEntry(const QString &name, const T &value)
Definition kis_config.h:779
void setShowFilterGallery(bool showFilterGallery) const
void slotFilterWidgetSizeChanged()
KisDlgFilter::Private *const d
void enablePreviewToggled(bool checked)
void setFilter(KisFilterSP f, KisFilterConfigurationSP overrideDefaultConfig)
void filterSelectionChanged()
void setDialogTitle(KisFilterSP f)
~KisDlgFilter() override
void startApplyingFilter(KisFilterConfigurationSP config)
KisDlgFilter(KisViewManager *view, KisNodeSP node, KisFilterManager *filterManager, QWidget *parent=0)
bool isStrokeRunning() const
void apply(KisFilterConfigurationSP filterConfig)
void cancelRunningStroke()
Cancel current running stroke.
void setFilterAllSelectedFrames(bool filterAllSelectedFrames)
virtual bool configurationAllowedForMask(KisFilterConfigurationSP config) const
void addNode(KisNodeSP node, KisNodeSP parent, KisNodeSP aboveThis, KisImageLayerAddCommand::Flags flags=KisImageLayerAddCommand::DoRedoUpdates|KisImageLayerAddCommand::DoUndoUpdates)
bool isNull() const
void setDelay(std::function< bool()> idleCallback, int idleDelay, int timeout)
bool blockUntilOperationsFinished(KisImageSP image)
blockUntilOperationsFinished blocks the GUI of the application until execution of actions on image is...
KisSelectionSP selection()
KisImageWSP image() const
Return the image this view is displaying.
QIcon loadIcon(const QString &name)
virtual KisPaintDeviceSP paintDevice() const =0
KisViewManager * view
Ui_FilterDialog uiFilterDialog
QScopedPointer< KisInputActionGroupsMaskGuard > blockModifyingActionsGuard
KisSignalCompressor updateCompressor
Private(KisFilterManager *_filterManager, KisViewManager *_view)
KisFilterManager * filterManager
KisNodeSP lastChild() const
Definition kis_node.cpp:367
virtual bool allowAsChild(KisNodeSP) const =0