1 /*
2  *  Copyright (c) 2016 Kapustin Alexey <akapust1n@yandex.ru>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "kis_dlg_stroke_selection_properties.h"
20 
21 #include <QPushButton>
22 #include <QRadioButton>
23 #include <QLayout>
24 #include <QLabel>
25 #include <QSpinBox>
26 #include <QSlider>
27 #include <QCheckBox>
28 #include <QPlainTextEdit>
29 #include <QTextEdit>
30 
31 #include <klocalizedstring.h>
32 
33 #include <KoColorSpace.h>
34 #include "KoColorProfile.h"
35 #include "KoColorSpaceRegistry.h"
36 #include "KoColor.h"
37 #include "KoColorConversionTransformation.h"
38 #include "KoColorPopupAction.h"
39 #include "kis_icon_utils.h"
40 #include "KoID.h"
41 #include "kis_image.h"
42 #include "kis_annotation.h"
43 #include "kis_config.h"
44 #include "kis_signal_compressor.h"
45 #include "widgets/kis_cmb_idlist.h"
46 #include <KisSqueezedComboBox.h>
47 #include "kis_layer_utils.h"
48 #include <kis_ls_utils.h>
49 #include "kis_canvas_resource_provider.h"
50 #include "KoUnit.h"
51 #include "kis_display_color_converter.h"
52 
53 #include <kis_signals_blocker.h>
54 
KisDlgStrokeSelection(KisImageWSP image,KisViewManager * view,bool isVectorLayer)55 KisDlgStrokeSelection::KisDlgStrokeSelection(KisImageWSP image, KisViewManager *view, bool isVectorLayer)
56     : KoDialog(view->mainWindow())
57 {
58     m_resourceManager = view->mainWindow()->resourceManager();
59     KisPropertiesConfigurationSP cfg = KisConfig(true).exportConfiguration("StrokeSelection");
60 
61     m_converter = view->canvasBase()->displayColorConverter();
62     setButtons(Ok | Cancel);
63     setDefaultButton(Ok);
64     setCaption(i18nc("@title:window", "Stroke Selection Properties"));
65     m_page = new WdgStrokeSelection(this);
66     m_page->m_isVectorLayer = isVectorLayer;
67     m_page->m_cfg = cfg;
68 
69     m_image = image;
70 
71     setMainWidget(m_page);
72 
73     StrokeSelectionOptions &m_options = m_page->m_options;
74     m_options.color = cfg->getColor("color");
75     m_options.colorLineSource = static_cast<ColorLineSource>(cfg->getInt("lineColorSource"));
76     m_page->lineColorBox->setCurrentIndex(static_cast<int>(m_options.colorLineSource));
77 
78     m_page->colorSelector->setColor(getSelectedColor().toQColor());
79 
80     m_options.brushSelected = cfg->getBool("useBrush", 0);
81     m_page->typeBox->setCurrentIndex(m_options.brushSelected? 0 : 1);
82 
83     m_options.colorFillSource = static_cast<ColorFillSource>(cfg->getInt("colorFillSource", 0));
84     m_page->fillBox->setCurrentIndex(static_cast<int>(m_options.colorFillSource));
85     m_options.customColor = cfg->getColor("customColor");
86 
87     if (m_options.colorFillSource == ColorFillSource::CustomColor) {
88         m_page->colorFillSelector->setColor(m_options.customColor.toQColor());
89     }
90     else {
91         m_page->colorFillSelector->setColor(getFillSelectedColor().toQColor());
92     }
93 
94     m_options.lineSize = cfg->getInt("lineSize", 1);
95     m_page->lineSize->setValue(m_options.lineSize);
96 
97     m_options.lineDimension = cfg->getInt("lineDimension", 0);
98     m_page->sizeBox->setCurrentIndex(m_options.lineDimension);
99 
100     connect(m_page, SIGNAL(colorSelectorChanged()), SLOT(setColorButton()));
101     connect(m_page, SIGNAL(colorFillSelectorChanged()), SLOT(setColorFillButton()));
102     connect(m_page->colorFillSelector, SIGNAL(changed(QColor)), SLOT(colorFillChanged(QColor)));
103     connect(m_page->colorSelector, SIGNAL(changed(QColor)), SLOT(colorChanged(QColor)));
104 
105     m_page->enableControls();
106 
107 }
108 
~KisDlgStrokeSelection()109 KisDlgStrokeSelection::~KisDlgStrokeSelection()
110 {
111     StrokeSelectionOptions &m_options = m_page->m_options;
112     m_options.lineSize = m_page->lineSize->value();
113 
114     m_options.lineDimension = m_page->sizeBox->currentIndex();
115     m_options.colorLineSource = static_cast<ColorLineSource>(m_page->lineColorBox->currentIndex());
116 
117     KisPropertiesConfigurationSP cfg(new KisPropertiesConfiguration());
118     cfg->setProperty("lineSize", m_options.lineSize);
119     cfg->setProperty("colorFillSource", static_cast<int>(m_options.colorFillSource));
120     cfg->setProperty("useBrush", m_options.brushSelected);
121     cfg->setProperty("lineDimension", m_options.lineDimension);
122     cfg->setProperty("lineColorSource", static_cast<int>(m_options.colorLineSource));
123 
124     QVariant colorVariant;
125     colorVariant.setValue(m_options.customColor);
126     cfg->setProperty("customColor", colorVariant);
127 
128     colorVariant.setValue(m_options.color);
129     cfg->setProperty("color", colorVariant);
130 
131     colorVariant.setValue(m_options.fillColor);
132     cfg->setProperty("fillColor", colorVariant);
133 
134     KisConfig(false).setExportConfiguration("StrokeSelection", cfg);
135 
136     delete m_page;
137 }
138 
getSelectedColor() const139 KoColor KisDlgStrokeSelection::getSelectedColor() const
140 {
141     KoColor color;
142 
143     ColorLineSource currentSource = static_cast<ColorLineSource>(m_page->lineColorBox->currentIndex());
144     switch(currentSource) {
145     case ColorLineSource::FGColor:
146         return m_resourceManager->resource(KoCanvasResourceProvider::ForegroundColor).value<KoColor>();
147     case ColorLineSource::BGColor:
148         return m_resourceManager->resource(KoCanvasResourceProvider::BackgroundColor).value<KoColor>();
149     default:
150         return m_page->m_options.color;
151     }
152 }
153 
getFillSelectedColor() const154 KoColor KisDlgStrokeSelection::getFillSelectedColor() const
155 {
156     KoColor color;
157 
158     ColorFillSource currentSource = static_cast<ColorFillSource>(m_page->fillBox->currentIndex());
159     switch (currentSource) {
160     case ColorFillSource::FGColor:
161         return m_resourceManager->resource(KoCanvasResourceProvider::ForegroundColor).value<KoColor>();
162     case ColorFillSource::BGColor:
163         return m_resourceManager->resource(KoCanvasResourceProvider::BackgroundColor).value<KoColor>();
164     case ColorFillSource::PaintColor:
165         return m_converter->approximateFromRenderedQColor(m_page->colorSelector->color());
166     default:
167         return m_page->m_options.customColor;
168     }
169 
170 }
171 
172 
isBrushSelected() const173 bool KisDlgStrokeSelection::isBrushSelected() const
174 {
175     return (static_cast<DrawType>(m_page->typeBox->currentIndex()) == DrawType::CurrentBrush);
176 }
177 
getParams() const178 StrokeSelectionOptions KisDlgStrokeSelection::getParams() const
179 {
180     StrokeSelectionOptions params;
181 
182     params.lineSize = getLineSize();
183     params.brushSelected = isBrushSelected();
184     params.colorFillSource = m_page->m_options.colorFillSource;
185     params.colorLineSource = m_page->m_options.colorLineSource;
186     params.lineDimension = m_page->m_options.lineDimension;
187     params.color = getSelectedColor();
188     params.fillColor = getFillSelectedColor();
189     params.customColor = m_page->m_options.customColor;
190 
191     return params;
192 
193 }
194 
setColorFillButton()195 void KisDlgStrokeSelection::setColorFillButton()
196 {
197     m_page->colorFillSelector->setColor(getFillSelectedColor().toQColor());
198 }
199 
setColorButton()200 void KisDlgStrokeSelection::setColorButton()
201 {
202     m_page->colorSelector->setColor(getSelectedColor().toQColor());
203 }
204 
getLineSize() const205 int KisDlgStrokeSelection::getLineSize() const
206 {
207     int value = m_page->lineSize->value();
208 
209     if (m_page->sizeBox->currentIndex() == 0) {
210         return value;
211     }
212     else if (m_page->sizeBox->currentIndex() == 1) {
213         int pixels =  static_cast<int>(KoUnit::convertFromUnitToUnit(value,KoUnit(KoUnit::Millimeter), KoUnit(KoUnit::Pixel)));
214         return pixels;
215     }
216     else {
217         int  pixels = static_cast<int>(KoUnit::convertFromUnitToUnit(value, KoUnit(KoUnit::Inch), KoUnit(KoUnit::Pixel)));
218         return pixels;
219     }
220 }
221 
getLinePosition() const222 LinePosition KisDlgStrokeSelection::getLinePosition() const
223 {/* TODO
224    int index = m_page->linePosition->currentIndex();
225    switch(index)
226    {
227    case(0):
228        return linePosition::OUTSIDE;
229    case(1):
230        return linePosition::INSIDE;
231    case(2):
232        return linePosition::CENTER;
233    default:
234        return linePosition::CENTER;
235    }*/
236     return LinePosition::Center;
237 }
238 
colorChanged(const QColor & newColor)239 void KisDlgStrokeSelection::colorChanged(const QColor &newColor)
240 {
241     KisSignalsBlocker blocker(m_page->fillBox, m_page->lineColorBox);
242 
243     if (m_page->fillBox->currentIndex() == static_cast<int>(ColorFillSource::PaintColor)) {
244         m_page->colorFillSelector->setColor(newColor);
245     }
246 
247     KoColor FGColor = m_resourceManager->resource(KoCanvasResourceProvider::ForegroundColor).value<KoColor>();
248     KoColor BGColor = m_resourceManager->resource(KoCanvasResourceProvider::BackgroundColor).value<KoColor>();
249     KoColor tempColor = m_converter->approximateFromRenderedQColor(newColor);
250 
251     if (tempColor.toQColor() == FGColor.toQColor()) {
252         m_page->lineColorBox->setCurrentIndex(static_cast<int>(ColorLineSource::FGColor));
253     }
254     else if (tempColor.toQColor() == BGColor.toQColor()) {
255         m_page->lineColorBox->setCurrentIndex(static_cast<int>(ColorLineSource::BGColor));
256     }
257     else {
258         m_page->lineColorBox->setCurrentIndex((int)ColorLineSource::CustomColor);
259     }
260     m_page->m_options.color = tempColor;
261 }
262 
colorFillChanged(const QColor & newColor)263 void KisDlgStrokeSelection::colorFillChanged(const QColor &newColor)
264 {
265     KisSignalsBlocker blocker(m_page->fillBox);
266 
267     KoColor PaintColor = m_converter->approximateFromRenderedQColor(m_page->colorSelector->color());
268     KoColor FGColor = m_resourceManager->resource(KoCanvasResourceProvider::ForegroundColor).value<KoColor>();
269     KoColor BGColor = m_resourceManager->resource(KoCanvasResourceProvider::BackgroundColor).value<KoColor>();
270     KoColor tempColor= m_converter->approximateFromRenderedQColor(newColor);
271 
272     if (tempColor.toQColor() == FGColor.toQColor()) {
273         m_page->fillBox->setCurrentIndex(static_cast<int>(ColorFillSource::FGColor));
274 
275     }
276     else if (tempColor.toQColor() == BGColor.toQColor()) {
277         m_page->fillBox->setCurrentIndex(static_cast<int>(ColorFillSource::BGColor));
278     }
279     else if (PaintColor.toQColor() != tempColor.toQColor() ) {
280         m_page->fillBox->setCurrentIndex((int)ColorFillSource::CustomColor);
281         m_page->m_options.customColor = tempColor;
282     }
283 
284     m_page->m_options.fillColor = tempColor;
285 }
286 
287 
288 
WdgStrokeSelection(QWidget * parent)289 WdgStrokeSelection::WdgStrokeSelection(QWidget *parent) : QWidget(parent)
290 {
291     setupUi(this);
292 }
293 
enableControls()294 void WdgStrokeSelection::enableControls()
295 {
296     m_options.fillColor = m_cfg->getColor("fillColor");
297     if (m_options.colorFillSource == ColorFillSource::None) {
298         colorFillSelector->setEnabled(false);
299     }
300     else {
301         colorFillSelector->setEnabled(true);
302     }
303 
304     if (m_isVectorLayer) {
305         typeBox->setCurrentIndex(1);
306         typeBox->setEnabled(false);
307     }
308     else {
309         typeBox->setEnabled(true);
310     }
311 
312     on_typeBox_currentIndexChanged(typeBox->currentIndex());
313 }
314 
on_fillBox_currentIndexChanged(int index)315 void WdgStrokeSelection::on_fillBox_currentIndexChanged(int index)
316 {
317     if (index == static_cast<int>(ColorFillSource::None)) {
318         colorFillSelector->setDisabled(true);
319     }
320     else {
321         colorFillSelector->setDisabled(false);
322         emit colorFillSelectorChanged();
323     }
324     m_options.colorFillSource = static_cast<ColorFillSource>(index);
325 }
326 
on_typeBox_currentIndexChanged(int arg1)327 void WdgStrokeSelection::on_typeBox_currentIndexChanged(int arg1)
328 {
329     if (arg1 == 0) {
330         m_options.brushSelected = true;
331         lineSize->setEnabled(false);
332         fillBox->setEnabled(false);
333         colorFillSelector->setEnabled(false);
334         sizeBox->setEnabled(false);
335     }
336     else {
337         m_options.brushSelected = false;
338         lineSize->setEnabled(true);
339         fillBox->setEnabled(true);
340         colorFillSelector->setEnabled(true);
341         sizeBox->setEnabled(true);
342     }
343 }
344 
on_lineColorBox_currentIndexChanged(int)345 void WdgStrokeSelection::on_lineColorBox_currentIndexChanged(int/*arg1*/)
346 {
347     emit colorSelectorChanged();
348 }
349 
350 
StrokeSelectionOptions()351 StrokeSelectionOptions ::StrokeSelectionOptions()
352 {
353     color.fromQColor(Qt::black);
354     fillColor.fromQColor(Qt::black);
355     customColor.fromQColor(Qt::black);
356 }
357 
fillStyle() const358 KisToolShapeUtils::FillStyle StrokeSelectionOptions::fillStyle() const
359 {
360     using namespace KisToolShapeUtils;
361 
362     ColorFillSource tempColor = static_cast<ColorFillSource>(colorFillSource);
363     FillStyle style = FillStyleNone;
364 
365     switch (tempColor) {
366     case ColorFillSource::PaintColor:
367         style = FillStyleForegroundColor;
368         break;
369     case ColorFillSource::BGColor:
370         style = FillStyleBackgroundColor;
371         break;
372     case ColorFillSource::CustomColor:
373         style = FillStyleBackgroundColor;
374         break;
375     case ColorFillSource::None:
376         style = FillStyleNone;
377         break;
378     case ColorFillSource::FGColor:
379         style = FillStyleBackgroundColor;
380         break;
381     }
382     return style;
383 }
384 
385 
386