1 /*
2 * Copyright (c) 2007 Cyrille Berger <cberger@cberger.net>
3 * Copyright (c) 2008 Boudewijn Rempt <boud@valdysa.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include "kis_dlg_filter.h"
22
23
24
25 #include <KoResourcePaths.h>
26 #include <QPushButton>
27 #include <filter/kis_filter.h>
28 #include <filter/kis_filter_configuration.h>
29 #include <kis_filter_mask.h>
30 #include <kis_node.h>
31 #include <kis_layer.h>
32 #include <kis_paint_layer.h>
33 #include <KisViewManager.h>
34 #include <kis_config.h>
35
36 #include "kis_selection.h"
37 #include "kis_node_commands_adapter.h"
38 #include "kis_filter_manager.h"
39 #include "ui_wdgfilterdialog.h"
40 #include "kis_canvas2.h"
41
42
43 struct KisDlgFilter::Private {
PrivateKisDlgFilter::Private44 Private(KisFilterManager *_filterManager, KisViewManager *_view)
45 : currentFilter(0)
46 , resizeCount(0)
47 , view(_view)
48 , filterManager(_filterManager)
49 , blockModifyingActionsGuard(new KisInputActionGroupsMaskGuard(view->canvasBase(), ViewTransformActionGroup))
50 {
51 }
52
53 KisFilterSP currentFilter;
54 Ui_FilterDialog uiFilterDialog;
55 KisNodeSP node;
56 int resizeCount;
57 KisViewManager *view;
58 KisFilterManager *filterManager;
59
60 // a special guard object that blocks all the painting input actions while the
61 // dialog is open
62 QScopedPointer<KisInputActionGroupsMaskGuard> blockModifyingActionsGuard;
63 };
64
KisDlgFilter(KisViewManager * view,KisNodeSP node,KisFilterManager * filterManager,QWidget * parent)65 KisDlgFilter::KisDlgFilter(KisViewManager *view, KisNodeSP node, KisFilterManager *filterManager, QWidget *parent) :
66 QDialog(parent),
67 d(new Private(filterManager, view))
68 {
69 setModal(false);
70
71 d->uiFilterDialog.setupUi(this);
72 d->node = node;
73
74 d->uiFilterDialog.filterSelection->setView(view);
75 d->uiFilterDialog.filterSelection->showFilterGallery(KisConfig(true).showFilterGallery());
76
77 d->uiFilterDialog.pushButtonCreateMaskEffect->show();
78 connect(d->uiFilterDialog.pushButtonCreateMaskEffect, SIGNAL(pressed()), SLOT(createMask()));
79 connect(d->uiFilterDialog.pushButtonCreateMaskEffect,SIGNAL(pressed()),SLOT(close()));
80
81 d->uiFilterDialog.filterGalleryToggle->setChecked(d->uiFilterDialog.filterSelection->isFilterGalleryVisible());
82 d->uiFilterDialog.filterGalleryToggle->setIcon(QPixmap(":/pics/sidebaricon.png"));
83 d->uiFilterDialog.filterGalleryToggle->setMaximumWidth(d->uiFilterDialog.filterGalleryToggle->height());
84 connect(d->uiFilterDialog.filterSelection, SIGNAL(sigFilterGalleryToggled(bool)), d->uiFilterDialog.filterGalleryToggle, SLOT(setChecked(bool)));
85 connect(d->uiFilterDialog.filterGalleryToggle, SIGNAL(toggled(bool)), d->uiFilterDialog.filterSelection, SLOT(showFilterGallery(bool)));
86 connect(d->uiFilterDialog.filterSelection, SIGNAL(sigSizeChanged()), this, SLOT(slotFilterWidgetSizeChanged()));
87
88 if (node->inherits("KisMask")) {
89 d->uiFilterDialog.pushButtonCreateMaskEffect->setVisible(false);
90 }
91
92 d->uiFilterDialog.filterSelection->setPaintDevice(true, d->node->paintDevice());
93
94 connect(d->uiFilterDialog.buttonBox, SIGNAL(accepted()), SLOT(accept()));
95 connect(d->uiFilterDialog.buttonBox, SIGNAL(rejected()), SLOT(reject()));
96 connect(d->uiFilterDialog.checkBoxPreview, SIGNAL(toggled(bool)), SLOT(enablePreviewToggled(bool)));
97
98 connect(d->uiFilterDialog.filterSelection, SIGNAL(configurationChanged()), SLOT(filterSelectionChanged()));
99
100 connect(this, SIGNAL(accepted()), SLOT(slotOnAccept()));
101 connect(this, SIGNAL(accepted()), d->uiFilterDialog.filterSelection, SLOT(slotBookMarkCurrentFilter()));
102 connect(this, SIGNAL(rejected()), SLOT(slotOnReject()));
103
104 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
105 d->uiFilterDialog.checkBoxPreview->setChecked(group.readEntry("showPreview", true));
106
107 restoreGeometry(KisConfig(true).readEntry("filterdialog/geometry", QByteArray()));
108
109 }
110
~KisDlgFilter()111 KisDlgFilter::~KisDlgFilter()
112 {
113 KisConfig(false).writeEntry("filterdialog/geometry", saveGeometry());
114 delete d;
115 }
116
setFilter(KisFilterSP f,KisFilterConfigurationSP overrideDefaultConfig)117 void KisDlgFilter::setFilter(KisFilterSP f, KisFilterConfigurationSP overrideDefaultConfig)
118 {
119 Q_ASSERT(f);
120 setDialogTitle(f);
121 d->uiFilterDialog.filterSelection->setFilter(f, overrideDefaultConfig);
122 d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(f->supportsAdjustmentLayers());
123 d->currentFilter = f;
124 updatePreview();
125 }
126
setDialogTitle(KisFilterSP filter)127 void KisDlgFilter::setDialogTitle(KisFilterSP filter)
128 {
129 setWindowTitle(filter.isNull() ? i18nc("@title:window", "Filter") : i18nc("@title:window", "Filter: %1", filter->name()));
130 }
131
startApplyingFilter(KisFilterConfigurationSP config)132 void KisDlgFilter::startApplyingFilter(KisFilterConfigurationSP config)
133 {
134 if (!d->uiFilterDialog.filterSelection->configuration()) return;
135
136 if (d->node->inherits("KisPaintLayer")) {
137 config->setChannelFlags(qobject_cast<KisPaintLayer*>(d->node.data())->channelLockFlags());
138 }
139
140 d->filterManager->apply(config);
141 }
142
updatePreview()143 void KisDlgFilter::updatePreview()
144 {
145 KisFilterConfigurationSP config = d->uiFilterDialog.filterSelection->configuration();
146 if (!config) return;
147
148 bool maskCreationAllowed = !d->currentFilter || d->currentFilter->configurationAllowedForMask(config);
149 d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(maskCreationAllowed);
150
151 if (d->uiFilterDialog.checkBoxPreview->isChecked()) {
152 KisFilterConfigurationSP config(d->uiFilterDialog.filterSelection->configuration());
153 startApplyingFilter(config);
154 }
155
156 d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
157 }
158
adjustSize()159 void KisDlgFilter::adjustSize()
160 {
161 QWidget::adjustSize();
162 }
163
slotFilterWidgetSizeChanged()164 void KisDlgFilter::slotFilterWidgetSizeChanged()
165 {
166 QMetaObject::invokeMethod(this, "adjustSize", Qt::QueuedConnection);
167 }
168
slotOnAccept()169 void KisDlgFilter::slotOnAccept()
170 {
171 if (!d->filterManager->isStrokeRunning()) {
172 KisFilterConfigurationSP config(d->uiFilterDialog.filterSelection->configuration());
173 startApplyingFilter(config);
174 }
175
176 d->filterManager->finish();
177
178 d->uiFilterDialog.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
179
180 KisConfig(false).setShowFilterGallery(d->uiFilterDialog.filterSelection->isFilterGalleryVisible());
181 }
182
slotOnReject()183 void KisDlgFilter::slotOnReject()
184 {
185 if (d->filterManager->isStrokeRunning()) {
186 d->filterManager->cancel();
187 }
188
189 KisConfig(false).setShowFilterGallery(d->uiFilterDialog.filterSelection->isFilterGalleryVisible());
190 }
191
createMask()192 void KisDlgFilter::createMask()
193 {
194 if (d->node->inherits("KisMask")) return;
195
196 if (d->filterManager->isStrokeRunning()) {
197 d->filterManager->cancel();
198 }
199
200 KisLayer *layer = qobject_cast<KisLayer*>(d->node.data());
201 KisFilterMaskSP mask = new KisFilterMask(d->view->image(), i18n("Filter Mask"));
202 mask->setName(d->currentFilter->name());
203 mask->initSelection(d->view->selection(), layer);
204 mask->setFilter(d->uiFilterDialog.filterSelection->configuration());
205
206 Q_ASSERT(layer->allowAsChild(mask));
207
208 KisNodeCommandsAdapter adapter(d->view);
209 adapter.addNode(mask, layer, layer->lastChild());
210 }
211
enablePreviewToggled(bool state)212 void KisDlgFilter::enablePreviewToggled(bool state)
213 {
214 if (state) {
215 updatePreview();
216 } else if (d->filterManager->isStrokeRunning()) {
217 d->filterManager->cancel();
218 }
219
220 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
221 group.writeEntry("showPreview", d->uiFilterDialog.checkBoxPreview->isChecked());
222
223 group.config()->sync();
224 }
225
filterSelectionChanged()226 void KisDlgFilter::filterSelectionChanged()
227 {
228 KisFilterSP filter = d->uiFilterDialog.filterSelection->currentFilter();
229 setDialogTitle(filter);
230 d->currentFilter = filter;
231 d->uiFilterDialog.pushButtonCreateMaskEffect->setEnabled(filter.isNull() ? false : filter->supportsAdjustmentLayers());
232 updatePreview();
233 }
234
235
resizeEvent(QResizeEvent * event)236 void KisDlgFilter::resizeEvent(QResizeEvent* event)
237 {
238 QDialog::resizeEvent(event);
239
240 // // Workaround, after the initialisation don't center the dialog anymore
241 // if(d->resizeCount < 2) {
242 // QWidget* canvas = d->view->canvas();
243 // QRect rect(canvas->mapToGlobal(canvas->geometry().topLeft()), size());
244 // int deltaX = (canvas->geometry().width() - geometry().width())/2;
245 // int deltaY = (canvas->geometry().height() - geometry().height())/2;
246 // rect.translate(deltaX, deltaY);
247 // setGeometry(rect);
248
249 // d->resizeCount++;
250 // }
251 }
252