1 /* This file is part of the KDE project
2  * Copyright (C) Boudewijn Rempt <boud@valdyas.org>, (C) 2008
3  *  Copyright (c) 2020 L. E. Segovia <amy@amyspark.me>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include "kis_dlg_generator_layer.h"
22 
23 #include <QGroupBox>
24 #include <QLabel>
25 #include <QLayout>
26 #include <QGridLayout>
27 #include <QPushButton>
28 #include <QCheckBox>
29 
30 #include <klocalizedstring.h>
31 
32 #include <kis_config_widget.h>
33 #include <filter/kis_filter_configuration.h>
34 #include <kis_paint_device.h>
35 #include <kis_transaction.h>
36 #include <commands/kis_change_filter_command.h>
37 #include <kis_generator_layer.h>
38 #include <KisViewManager.h>
39 #include <KisDocument.h>
40 
41 #define UPDATE_DELAY 100 /*ms */
42 
KisDlgGeneratorLayer(const QString & defaultName,KisViewManager * view,QWidget * parent,KisGeneratorLayerSP glayer=0,const KisFilterConfigurationSP previousConfig=0,const KisStrokeId stroke=KisStrokeId ())43 KisDlgGeneratorLayer::KisDlgGeneratorLayer(const QString & defaultName, KisViewManager *view, QWidget *parent, KisGeneratorLayerSP glayer = 0, const KisFilterConfigurationSP previousConfig = 0, const KisStrokeId stroke = KisStrokeId())
44         : QDialog(parent)
45         , layer(glayer)
46         , m_view(view)
47         , isEditing(layer && previousConfig)
48         , m_customName(false)
49         , m_freezeName(false)
50         , m_stroke(stroke)
51         , m_compressor(UPDATE_DELAY, KisSignalCompressor::FIRST_INACTIVE)
52 {
53     if(isEditing){
54         setModal(false);
55         configBefore = previousConfig;
56     }
57 
58     dlgWidget.setupUi(this);
59     dlgWidget.wdgGenerator->initialize(m_view);
60     dlgWidget.btnBox->button(QDialogButtonBox::Ok)->setDefault(true);
61 
62     dlgWidget.txtLayerName->setText( isEditing ? layer->name() : defaultName );
63     connect(dlgWidget.txtLayerName, SIGNAL(textChanged(QString)),
64             this, SLOT(slotNameChanged(QString)));
65     connect(dlgWidget.wdgGenerator, SIGNAL(previewConfiguration()), this, SLOT(previewGenerator()));
66     connect(&m_compressor, SIGNAL(timeout()), this, SLOT(slotDelayedPreviewGenerator()));
67 
68     dlgWidget.filterGalleryToggle->setIcon(QPixmap(":/pics/sidebaricon.png"));
69     dlgWidget.filterGalleryToggle->setChecked(true);
70     connect(dlgWidget.filterGalleryToggle, &QCheckBox::toggled, dlgWidget.wdgGenerator, &KisWdgGenerator::showFilterGallery);
71     connect(dlgWidget.btnBox, SIGNAL(accepted()), this, SLOT(accept()));
72     connect(dlgWidget.btnBox, SIGNAL(rejected()), this, SLOT(reject()));
73     connect(this, SIGNAL(accepted()), this, SLOT(saveLayer()));
74     connect(this, SIGNAL(rejected()), this, SLOT(restoreLayer()));
75 
76     if (layer && !isEditing) {
77         slotDelayedPreviewGenerator();
78     }
79     restoreGeometry(KisConfig(true).readEntry("generatordialog/geometry", QByteArray()));
80 }
81 
saveLayer()82 void KisDlgGeneratorLayer::saveLayer()
83 {
84     /*
85      * Editing a layer should be using the show function with automatic deletion on close.
86      * Because of this, the action should be taken care of when the window is closed and
87      * the user has accepted the changes.
88      */
89     if (isEditing) {
90         layer->setName(layerName());
91 
92         KisFilterConfigurationSP configAfter(configuration());
93         Q_ASSERT(configAfter);
94         QString xmlBefore = configBefore->toXML();
95         QString xmlAfter = configAfter->toXML();
96 
97         if (xmlBefore != xmlAfter) {
98             KisChangeFilterCmd *cmd
99                     = new KisChangeFilterCmd(layer,
100                                              configBefore->name(),
101                                              xmlBefore,
102                                              configAfter->name(),
103                                              xmlAfter,
104                                              true);
105 
106             m_view->undoAdapter()->addCommand(cmd);
107             m_view->document()->setModified(true);
108         }
109     } else {
110         KIS_ASSERT_RECOVER_RETURN(layer);
111         layer->setFilter(configuration());
112     }
113 }
114 
restoreLayer()115 void KisDlgGeneratorLayer::restoreLayer()
116 {
117     if (isEditing)
118     {
119         layer->setFilter(configBefore);
120     }
121 }
122 
~KisDlgGeneratorLayer()123 KisDlgGeneratorLayer::~KisDlgGeneratorLayer()
124 {
125     KisConfig(false).writeEntry("generatordialog/geometry", saveGeometry());
126 }
127 
slotNameChanged(const QString & text)128 void KisDlgGeneratorLayer::slotNameChanged(const QString & text)
129 {
130     if (m_freezeName)
131         return;
132 
133     m_customName = !text.isEmpty();
134     dlgWidget.btnBox->button(QDialogButtonBox::Ok)->setEnabled(m_customName);
135 }
136 
slotDelayedPreviewGenerator()137 void KisDlgGeneratorLayer::slotDelayedPreviewGenerator()
138 {
139     if (!m_stroke.isNull()) {
140         layer->setFilterWithoutUpdate(configuration());
141         layer->previewWithStroke(m_stroke);
142     }
143 }
144 
previewGenerator()145 void KisDlgGeneratorLayer::previewGenerator()
146 {
147     if (!m_stroke.isNull()) {
148         m_compressor.start();
149     }
150     else {
151         KIS_ASSERT_RECOVER_RETURN(layer);
152         layer->setFilter(configuration());
153     }
154 }
155 
setConfiguration(const KisFilterConfigurationSP config)156 void KisDlgGeneratorLayer::setConfiguration(const KisFilterConfigurationSP  config)
157 {
158     dlgWidget.wdgGenerator->setConfiguration(config);
159 }
160 
configuration() const161 KisFilterConfigurationSP  KisDlgGeneratorLayer::configuration() const
162 {
163     return dlgWidget.wdgGenerator->configuration();
164 }
165 
layerName() const166 QString KisDlgGeneratorLayer::layerName() const
167 {
168     return dlgWidget.txtLayerName->text();
169 }
170 
171