1 /* This file is part of the KDE project
2    Made by Tomislav Lukman (tomislav.lukman@ck.t-com.hr)
3    Copyright (c) 2005 Tomislav Lukman <tomislav.lukman@ck.t-com.hr>
4    Copyright (C) 2006 Tim Beaulen <tbscope@gmail.com>
5    Copyright (c) 2008 Jan Hambrecht <jaham@gmx.net>
6 
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public
9    License as published by the Free Software Foundation; either
10    version 2 of the License, or (at your option) any later version.
11 
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Library General Public License for more details.
16 
17    You should have received a copy of the GNU Library General Public License
18    along with this library; see the file COPYING.LIB.  If not, write to
19    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21 */
22 
23 #include "KarbonSmallStylePreview.h"
24 #include <KoGradientHelper.h>
25 #include <KoCheckerBoardPainter.h>
26 #include <KoGradientBackground.h>
27 #include <KoCanvasBase.h>
28 #include <KoToolManager.h>
29 #include <KoCanvasController.h>
30 #include <KoShapeManager.h>
31 #include <KoShape.h>
32 #include <KoSelection.h>
33 #include <KoShapePaintingContext.h>
34 #include <KoShapeStroke.h>
35 #include <KoViewConverter.h>
36 
37 #include <klocalizedstring.h>
38 
39 #include <QFontDatabase>
40 #include <QPushButton>
41 #include <QLabel>
42 #include <QPainter>
43 #include <QPainterPath>
44 #include <QPaintEvent>
45 #include <QHBoxLayout>
46 
47 #define FRAMEWIDTH 75
48 #define FRAMEHEIGHT 15
49 
50 class KarbonFillStyleWidget : public QPushButton {
51 public:
KarbonFillStyleWidget(QWidget * parent)52     KarbonFillStyleWidget(QWidget * parent)
53             : QPushButton(parent), m_fill(0), m_checkerPainter(5) {
54         setCursor(Qt::PointingHandCursor);
55         setToolTip(i18n("Press to apply fill to selection"));
56     }
57 
~KarbonFillStyleWidget()58     ~KarbonFillStyleWidget() override {
59     }
60 
setFill(QSharedPointer<KoShapeBackground> fill)61     void setFill(QSharedPointer<KoShapeBackground>  fill) {
62         m_fill = fill;
63         update();
64     }
65 protected:
paintEvent(QPaintEvent * event)66     void paintEvent(QPaintEvent* event) override {
67         QPainter painter(this);
68         painter.setClipRect(event->rect());
69 
70         if (m_fill) {
71             m_checkerPainter.paint(painter, rect());
72 
73             QSharedPointer<KoGradientBackground>  gradientFill = qSharedPointerDynamicCast<KoGradientBackground>(m_fill);
74             if (gradientFill) {
75                 const QGradient * gradient = gradientFill->gradient();
76                 QGradient * defGradient = KoGradientHelper::defaultGradient(gradient->type(), gradient->spread(), gradient->stops());
77                 QBrush brush(*defGradient);
78                 delete defGradient;
79                 painter.setBrush(brush);
80                 painter.setPen(Qt::NoPen);
81                 painter.drawRect(rect());
82             } else {
83                 // use the background to draw
84                 painter.setPen(Qt::NoPen);
85                 QPainterPath p;
86                 p.addRect(rect());
87                 KoViewConverter converter;
88                 KoShapePaintingContext context;
89                 m_fill->paint(painter, converter, context, p);
90             }
91         } else {
92             painter.setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
93             painter.setBrush(Qt::black);
94             painter.setPen(Qt::black);
95             painter.drawText(rect(), Qt::AlignCenter, i18nc("The style has no fill", "None"));
96         }
97 
98         painter.end();
99 
100         //QPushButton::paintEvent( event );
101     }
102 
103 private:
104     QSharedPointer<KoShapeBackground>  m_fill; ///< the fill to preview
105     KoCheckerBoardPainter m_checkerPainter;
106 };
107 
108 class KarbonStrokeStyleWidget : public QPushButton {
109 public:
KarbonStrokeStyleWidget(QWidget * parent)110     KarbonStrokeStyleWidget(QWidget * parent)
111             : QPushButton(parent), m_stroke(0), m_checkerPainter(5) {
112         setCursor(Qt::PointingHandCursor);
113         setToolTip(i18n("Press to apply stroke to selection"));
114     }
115 
~KarbonStrokeStyleWidget()116     ~KarbonStrokeStyleWidget() override {
117         if (m_stroke && !m_stroke->deref())
118             delete m_stroke;
119     }
120 
setStroke(KoShapeStrokeModel * stroke)121     void setStroke(KoShapeStrokeModel * stroke) {
122         if (stroke != m_stroke) {
123             if (m_stroke && !m_stroke->deref())
124                 delete m_stroke;
125             m_stroke = stroke;
126             if (m_stroke)
127                 m_stroke->ref();
128         }
129         update();
130     }
131 protected:
paintEvent(QPaintEvent * event)132     void paintEvent(QPaintEvent* event) override {
133         QPainter painter(this);
134         painter.setClipRect(event->rect());
135 
136         if (m_stroke) {
137             m_checkerPainter.paint(painter, rect());
138             const KoShapeStroke * line = dynamic_cast<const KoShapeStroke*>(m_stroke);
139             if (line) {
140                 painter.setPen(Qt::NoPen);
141                 QBrush brush = line->lineBrush();
142                 if (brush.gradient()) {
143                     QGradient * defGradient = KoGradientHelper::defaultGradient(brush.gradient()->type(), brush.gradient()->spread(), brush.gradient()->stops());
144                     QBrush brush(*defGradient);
145                     delete defGradient;
146                     painter.setBrush(brush);
147                     painter.setPen(Qt::NoPen);
148                     painter.drawRect(rect());
149                 } else if (brush.style() == Qt::TexturePattern) {
150                     painter.fillRect(rect(), brush);
151                 } else {
152                     painter.fillRect(rect(), QBrush(line->color()));
153                 }
154             } else {
155                 painter.setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
156                 painter.setBrush(Qt::black);
157                 painter.setPen(Qt::black);
158                 painter.drawText(rect(), Qt::AlignCenter, i18nc("The style has a custom stroking", "Custom"));
159             }
160         } else {
161             painter.setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
162             painter.setBrush(Qt::black);
163             painter.setPen(Qt::black);
164             painter.drawText(rect(), Qt::AlignCenter, i18nc("The style has no stroking", "None"));
165         }
166 
167         painter.end();
168 
169         //QPushButton::paintEvent( event );
170     }
171 
172 private:
173     KoShapeStrokeModel * m_stroke; ///< the stroke to preview
174     KoCheckerBoardPainter m_checkerPainter;
175 };
176 
KarbonSmallStylePreview(QWidget * parent)177 KarbonSmallStylePreview::KarbonSmallStylePreview(QWidget* parent)
178         : QWidget(parent)
179 {
180     setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
181 
182     /* Create widget layout */
183     QHBoxLayout *layout = new QHBoxLayout(this);
184     QLabel * strokeLabel = new QLabel(i18n("Stroke:"), this);
185     strokeLabel->setMinimumHeight(FRAMEHEIGHT);
186     m_strokeFrame = new KarbonStrokeStyleWidget(this);
187     m_strokeFrame->setMinimumSize(QSize(FRAMEWIDTH, FRAMEHEIGHT));
188 
189     QLabel * fillLabel = new QLabel(i18n("Fill:"), this);
190     fillLabel->setMinimumHeight(FRAMEHEIGHT);
191     m_fillFrame = new KarbonFillStyleWidget(this);
192     m_fillFrame->setMinimumSize(QSize(FRAMEWIDTH, FRAMEHEIGHT));
193 
194     layout->addWidget(strokeLabel);
195     layout->addWidget(m_strokeFrame);
196     layout->addWidget(fillLabel);
197     layout->addWidget(m_fillFrame);
198     layout->setContentsMargins(0, 0, 0, 0);
199 
200     setLayout(layout);
201 
202     connect(KoToolManager::instance(), SIGNAL(changedCanvas(const KoCanvasBase *)),
203             this, SLOT(canvasChanged(const KoCanvasBase *)));
204     connect(m_strokeFrame, SIGNAL(clicked()), this, SIGNAL(strokeApplied()));
205     connect(m_fillFrame, SIGNAL(clicked()), this, SIGNAL(fillApplied()));
206 }
207 
~KarbonSmallStylePreview()208 KarbonSmallStylePreview::~KarbonSmallStylePreview()
209 {
210 }
211 
canvasChanged(const KoCanvasBase * canvas)212 void KarbonSmallStylePreview::canvasChanged(const KoCanvasBase *canvas)
213 {
214     if (canvas) {
215         connect(canvas->shapeManager(), SIGNAL(selectionChanged()),
216                 this, SLOT(selectionChanged()));
217         connect(canvas->shapeManager(), SIGNAL(selectionContentChanged()),
218                 this, SLOT(selectionChanged()));
219     }
220     selectionChanged();
221 }
222 
selectionChanged()223 void KarbonSmallStylePreview::selectionChanged()
224 {
225     KoCanvasController * controller = KoToolManager::instance()->activeCanvasController();
226     if (! controller || ! controller->canvas()) {
227         m_fillFrame->setFill(QSharedPointer<KoShapeBackground>(0));
228         m_strokeFrame->setStroke(0);
229         QWidget::update();
230         return;
231     }
232 
233     KoShape * shape = controller->canvas()->shapeManager()->selection()->firstSelectedShape();
234     if (shape) {
235         m_fillFrame->setFill(shape->background());
236         m_strokeFrame->setStroke(shape->stroke());
237     } else {
238         m_fillFrame->setFill(QSharedPointer<KoShapeBackground>(0));
239         m_strokeFrame->setStroke(0);
240     }
241     QWidget::update();
242 }
243 
244 
245