Warning, file /office/calligra/libs/widgets/KoColorPopupAction.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (c) 2007 C. Boemann <cbo@boemann.dk>
0003  * Copyright (C) 2007 Fredy Yanardi <fyanardi@gmail.com>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Library General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * Library General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Library General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, write to
0017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  */
0020 
0021 #include "KoColorPopupAction.h"
0022 
0023 #include "KoColorSetWidget.h"
0024 #include "KoTriangleColorSelector.h"
0025 #include "KoColorSlider.h"
0026 #include "KoCheckerBoardPainter.h"
0027 #include "KoResourceServer.h"
0028 #include "KoResourceServerProvider.h"
0029 #include <KoColorSpaceRegistry.h>
0030 #include <KoColor.h>
0031 
0032 #include <WidgetsDebug.h>
0033 #include <klocalizedstring.h>
0034 
0035 #include <QPainter>
0036 #include <QWidgetAction>
0037 #include <QMenu>
0038 #include <QHBoxLayout>
0039 #include <QGridLayout>
0040 #include <QToolButton>
0041 
0042 
0043 class KoColorPopupAction::KoColorPopupActionPrivate
0044 {
0045 public:
0046     KoColorPopupActionPrivate()
0047         : colorSetWidget(0), colorChooser(0), opacitySlider(0), menu(0), checkerPainter(4)
0048         , showFilter(true), applyMode(true), firstTime(true)
0049     {}
0050 
0051     ~KoColorPopupActionPrivate()
0052     {
0053         delete colorSetWidget;
0054         delete colorChooser;
0055         delete opacitySlider;
0056         delete menu;
0057     }
0058 
0059     KoColor currentColor;
0060     KoColor buddyColor;
0061 
0062     KoColorSetWidget *colorSetWidget;
0063     KoTriangleColorSelector * colorChooser;
0064     KoColorSlider * opacitySlider;
0065     QMenu *menu;
0066     KoCheckerBoardPainter checkerPainter;
0067     bool showFilter;
0068     bool applyMode;
0069 
0070     bool firstTime;
0071 };
0072 
0073 KoColorPopupAction::KoColorPopupAction(QObject *parent)
0074     : QAction(parent),
0075     d(new KoColorPopupActionPrivate())
0076 {
0077     d->menu = new QMenu();
0078     QWidget *widget = new QWidget(d->menu);
0079     QWidgetAction *wdgAction = new QWidgetAction(d->menu);
0080     d->colorSetWidget = new KoColorSetWidget(widget);
0081 
0082     d->colorChooser = new KoTriangleColorSelector( widget );
0083     // prevent mouse release on color selector from closing popup
0084     d->colorChooser->setAttribute( Qt::WA_NoMousePropagation );
0085     d->opacitySlider = new KoColorSlider( Qt::Vertical, widget );
0086     d->opacitySlider->setFixedWidth(25);
0087     d->opacitySlider->setRange(0, 255);
0088     d->opacitySlider->setValue(255);
0089     d->opacitySlider->setToolTip( i18n( "Opacity" ) );
0090 
0091     QGridLayout * layout = new QGridLayout( widget );
0092     layout->addWidget( d->colorSetWidget, 0, 0, 1, -1 );
0093     layout->addWidget( d->colorChooser, 1, 0 );
0094     layout->addWidget( d->opacitySlider, 1, 1 );
0095     layout->setMargin(4);
0096 
0097     wdgAction->setDefaultWidget(widget);
0098     d->menu->addAction(wdgAction);
0099     setMenu(d->menu);
0100     new QHBoxLayout(d->menu);
0101     d->menu->layout()->addWidget(widget);
0102     d->menu->layout()->setMargin(0);
0103 
0104     connect(this, SIGNAL(triggered()), this, SLOT(emitColorChanged()));
0105 
0106     connect(d->colorSetWidget, SIGNAL(colorChanged(KoColor,bool)), this, SLOT(colorWasSelected(KoColor,bool)));
0107 
0108     connect( d->colorChooser, SIGNAL(colorChanged(KoColor)),
0109              this, SLOT(colorWasEdited(KoColor)) );
0110     connect( d->opacitySlider, SIGNAL(valueChanged(int)),
0111              this, SLOT(opacityWasChanged(int)));
0112 }
0113 
0114 KoColorPopupAction::~KoColorPopupAction()
0115 {
0116     delete d;
0117 }
0118 
0119 void KoColorPopupAction::setCurrentColor( const KoColor &color )
0120 {
0121     d->colorChooser->setColor( color );
0122 
0123     KoColor minColor( color );
0124     d->currentColor = minColor;
0125 
0126     KoColor maxColor( color );
0127     minColor.setOpacity( OPACITY_TRANSPARENT_U8 );
0128     maxColor.setOpacity( OPACITY_OPAQUE_U8 );
0129     d->opacitySlider->blockSignals( true );
0130     d->opacitySlider->setColors( minColor, maxColor );
0131     d->opacitySlider->setValue( color.opacityU8() );
0132     d->opacitySlider->blockSignals( false );
0133 
0134     updateIcon();
0135 }
0136 
0137 void KoColorPopupAction::setCurrentColor( const QColor &_color )
0138 {
0139 #ifndef NDEBUG
0140     if (!_color.isValid()) {
0141         warnWidgets << "Invalid color given, defaulting to black";
0142     }
0143 #endif
0144     const QColor color(_color.isValid() ? _color : QColor(0,0,0,255));
0145     setCurrentColor(KoColor(color, KoColorSpaceRegistry::instance()->rgb8() ));
0146 }
0147 
0148 QColor KoColorPopupAction::currentColor() const
0149 {
0150     return d->currentColor.toQColor();
0151 }
0152 
0153 KoColor KoColorPopupAction::currentKoColor() const
0154 {
0155     return d->currentColor;
0156 }
0157 
0158 void KoColorPopupAction::updateIcon()
0159 {
0160     QSize iconSize;
0161     QToolButton *toolButton = dynamic_cast<QToolButton*>(parentWidget());
0162     if (toolButton) {
0163         iconSize = QSize(toolButton->iconSize());
0164     } else {
0165         iconSize = QSize(16, 16);
0166     }
0167 
0168     // This must be a QImage, as drawing to a QPixmap outside the
0169     // UI thread will cause sporadic crashes.
0170     QImage pm;
0171 
0172     if (icon().isNull()) {
0173         d->applyMode = false;
0174     }
0175 
0176     if(d->applyMode) {
0177         pm = icon().pixmap(iconSize).toImage();
0178         if (pm.isNull()) {
0179             pm = QImage(iconSize, QImage::Format_ARGB32_Premultiplied);
0180             pm.fill(Qt::transparent);
0181         }
0182         QPainter p(&pm);
0183         p.fillRect(0, iconSize.height() - 4, iconSize.width(), 4, d->currentColor.toQColor());
0184         p.end();
0185     } else {
0186         pm = QImage(iconSize, QImage::Format_ARGB32_Premultiplied);
0187         pm.fill(Qt::transparent);
0188         QPainter p(&pm);
0189         d->checkerPainter.paint(p, QRect(QPoint(),iconSize));
0190         p.fillRect(0, 0, iconSize.width(), iconSize.height(), d->currentColor.toQColor());
0191         p.end();
0192     }
0193     setIcon(QIcon(QPixmap::fromImage(pm)));
0194 }
0195 
0196 void KoColorPopupAction::emitColorChanged()
0197 {
0198     emit colorChanged( d->currentColor );
0199 }
0200 
0201 void KoColorPopupAction::colorWasSelected(const KoColor &color, bool final)
0202 {
0203     d->currentColor = color;
0204     if (final) {
0205         menu()->hide();
0206         emitColorChanged();
0207     }
0208     updateIcon();
0209 }
0210 
0211 void KoColorPopupAction::colorWasEdited( const KoColor &color )
0212 {
0213     d->currentColor = color;
0214     quint8 opacity = d->opacitySlider->value();
0215     d->currentColor.setOpacity( opacity );
0216 
0217     KoColor minColor = d->currentColor;
0218     minColor.setOpacity( OPACITY_TRANSPARENT_U8 );
0219     KoColor maxColor = minColor;
0220     maxColor.setOpacity( OPACITY_OPAQUE_U8 );
0221 
0222     d->opacitySlider->setColors( minColor, maxColor );
0223 
0224     emitColorChanged();
0225 
0226     updateIcon();
0227 }
0228 
0229 void KoColorPopupAction::opacityWasChanged( int opacity )
0230 {
0231     d->currentColor.setOpacity( quint8(opacity) );
0232 
0233     emitColorChanged();
0234 }
0235 
0236 void KoColorPopupAction::slotTriggered(bool)
0237 {
0238     if (d->firstTime) {
0239         KoResourceServer<KoColorSet>* srv = KoResourceServerProvider::instance()->paletteServer(false);
0240         QList<KoColorSet*> palettes = srv->resources();
0241         if (!palettes.empty()) {
0242             d->colorSetWidget->setColorSet(palettes.first());
0243         }
0244         d->firstTime = false;
0245     }
0246 }