summaryrefslogtreecommitdiffstats
path: root/kolourpaint/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'kolourpaint/widgets')
-rw-r--r--kolourpaint/widgets/Makefile.am21
-rw-r--r--kolourpaint/widgets/kpcolorsimilaritycube.cpp348
-rw-r--r--kolourpaint/widgets/kpcolorsimilaritycube.h72
-rw-r--r--kolourpaint/widgets/kpcolorsimilaritydialog.cpp123
-rw-r--r--kolourpaint/widgets/kpcolorsimilaritydialog.h62
-rw-r--r--kolourpaint/widgets/kpcolortoolbar.cpp1112
-rw-r--r--kolourpaint/widgets/kpcolortoolbar.h297
-rw-r--r--kolourpaint/widgets/kpresizesignallinglabel.cpp67
-rw-r--r--kolourpaint/widgets/kpresizesignallinglabel.h52
-rw-r--r--kolourpaint/widgets/kpsqueezedtextlabel.cpp215
-rw-r--r--kolourpaint/widgets/kpsqueezedtextlabel.h65
-rw-r--r--kolourpaint/widgets/kptooltoolbar.cpp640
-rw-r--r--kolourpaint/widgets/kptooltoolbar.h155
-rw-r--r--kolourpaint/widgets/kptoolwidgetbase.cpp608
-rw-r--r--kolourpaint/widgets/kptoolwidgetbase.h112
-rw-r--r--kolourpaint/widgets/kptoolwidgetbrush.cpp184
-rw-r--r--kolourpaint/widgets/kptoolwidgetbrush.h61
-rw-r--r--kolourpaint/widgets/kptoolwidgeterasersize.cpp161
-rw-r--r--kolourpaint/widgets/kptoolwidgeterasersize.h59
-rw-r--r--kolourpaint/widgets/kptoolwidgetfillstyle.cpp222
-rw-r--r--kolourpaint/widgets/kptoolwidgetfillstyle.h80
-rw-r--r--kolourpaint/widgets/kptoolwidgetlinewidth.cpp97
-rw-r--r--kolourpaint/widgets/kptoolwidgetlinewidth.h51
-rw-r--r--kolourpaint/widgets/kptoolwidgetopaqueortransparent.cpp100
-rw-r--r--kolourpaint/widgets/kptoolwidgetopaqueortransparent.h56
-rw-r--r--kolourpaint/widgets/kptoolwidgetspraycansize.cpp119
-rw-r--r--kolourpaint/widgets/kptoolwidgetspraycansize.h51
27 files changed, 5190 insertions, 0 deletions
diff --git a/kolourpaint/widgets/Makefile.am b/kolourpaint/widgets/Makefile.am
new file mode 100644
index 00000000..f6501fac
--- /dev/null
+++ b/kolourpaint/widgets/Makefile.am
@@ -0,0 +1,21 @@
+INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../cursors -I$(srcdir)/../interfaces \
+ -I$(srcdir)/../pixmapfx \
+ -I$(srcdir)/../tools \
+ -I$(srcdir)/../views \
+ -I$(srcdir)/../widgets $(all_includes)
+
+noinst_LTLIBRARIES = libkolourpaintwidgets.la
+libkolourpaintwidgets_la_SOURCES = kpcolorsimilaritycube.cpp \
+ kpcolorsimilaritydialog.cpp \
+ kpcolortoolbar.cpp \
+ kpresizesignallinglabel.cpp \
+ kpsqueezedtextlabel.cpp \
+ kptooltoolbar.cpp \
+ kptoolwidgetbase.cpp kptoolwidgetbrush.cpp \
+ kptoolwidgeterasersize.cpp kptoolwidgetfillstyle.cpp \
+ kptoolwidgetlinewidth.cpp \
+ kptoolwidgetopaqueortransparent.cpp \
+ kptoolwidgetspraycansize.cpp
+
+METASOURCES = AUTO
+
diff --git a/kolourpaint/widgets/kpcolorsimilaritycube.cpp b/kolourpaint/widgets/kpcolorsimilaritycube.cpp
new file mode 100644
index 00000000..9fe3f29b
--- /dev/null
+++ b/kolourpaint/widgets/kpcolorsimilaritycube.cpp
@@ -0,0 +1,348 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG_KP_COLOR_SIMILARITY_CUBE 0
+
+
+#include <kpcolorsimilaritycube.h>
+
+#include <math.h>
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qwhatsthis.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kpcolor.h>
+#include <kpcolorsimilaritydialog.h>
+#include <kpdefs.h>
+
+
+const double kpColorSimilarityCube::colorCubeDiagonalDistance =
+ sqrt (255 * 255 * 3);
+
+kpColorSimilarityCube::kpColorSimilarityCube (int look,
+ kpMainWindow *mainWindow,
+ QWidget *parent,
+ const char *name)
+ : QFrame (parent, name, Qt::WNoAutoErase/*no flicker*/),
+ m_mainWindow (mainWindow),
+ m_colorSimilarity (-1)
+{
+ if (look & Depressed)
+ setFrameStyle (QFrame::Panel | QFrame::Sunken);
+
+ setColorSimilarity (0);
+
+
+ // Don't cause the translators grief by appending strings
+ // - duplicate text with 2 cases
+
+ if (look & DoubleClickInstructions)
+ {
+ QWhatsThis::add (this,
+ i18n ("<qt><p><b>Color Similarity</b> is how close "
+ "colors must be in the RGB Color Cube "
+ "to be considered the same.</p>"
+
+ "<p>If you set it to something "
+ "other than <b>Exact</b>, "
+ "you can work more effectively with dithered "
+ "images and photos.</p>"
+
+ "<p>This feature applies to transparent selections, as well as "
+ "the Flood Fill, Color Eraser and Autocrop "
+ "tools.</p>"
+
+ // sync: different to else case
+ "<p>To configure it, double click on the cube.</p>"
+
+ "</qt>"));
+ }
+ else
+ {
+ QWhatsThis::add (this,
+ i18n ("<qt><p><b>Color Similarity</b> is how close "
+ "colors must be in the RGB Color Cube "
+ "to be considered the same.</p>"
+
+ "<p>If you set it to something "
+ "other than <b>Exact</b>, "
+ "you can work more effectively with dithered "
+ "images and photos.</p>"
+
+ "<p>This feature applies to transparent selections, as well as "
+ "the Flood Fill, Color Eraser and Autocrop "
+ "tools.</p>"
+
+ "</qt>"));
+ }
+}
+
+kpColorSimilarityCube::~kpColorSimilarityCube ()
+{
+}
+
+
+// public
+double kpColorSimilarityCube::colorSimilarity () const
+{
+ return m_colorSimilarity;
+}
+
+// public
+void kpColorSimilarityCube::setColorSimilarity (double similarity)
+{
+#if DEBUG_KP_COLOR_SIMILARITY_CUBE
+ kdDebug () << "kpColorSimilarityCube::setColorSimilarity(" << similarity << ")" << endl;
+#endif
+
+ if (m_colorSimilarity == similarity)
+ return;
+
+ if (similarity < 0)
+ similarity = 0;
+ else if (similarity > kpColorSimilarityDialog::maximumColorSimilarity)
+ similarity = kpColorSimilarityDialog::maximumColorSimilarity;
+
+ m_colorSimilarity = similarity;
+
+ repaint (false/*no erase*/);
+}
+
+
+// protected virtual [base QWidget]
+QSize kpColorSimilarityCube::sizeHint () const
+{
+ return QSize (52, 52);
+}
+
+
+// protected
+QColor kpColorSimilarityCube::color (int redOrGreenOrBlue,
+ int baseBrightness,
+ int similarityDirection) const
+{
+ int brightness = int (baseBrightness +
+ similarityDirection *
+ .5 * m_colorSimilarity * kpColorSimilarityCube::colorCubeDiagonalDistance);
+
+ if (brightness < 0)
+ brightness = 0;
+ else if (brightness > 255)
+ brightness = 255;
+
+ switch (redOrGreenOrBlue)
+ {
+ default:
+ case 0: return QColor (brightness, 0, 0);
+ case 1: return QColor (0, brightness, 0);
+ case 2: return QColor (0, 0, brightness);
+ }
+}
+
+static QPoint pointBetween (const QPoint &p, const QPoint &q)
+{
+ return QPoint ((p.x () + q.x ()) / 2, (p.y () + q.y ()) / 2);
+}
+
+static void drawQuadrant (QPainter *p,
+ const QColor &col,
+ const QPoint &p1, const QPoint &p2, const QPoint &p3,
+ const QPoint pointNotOnOutline)
+{
+ p->save ();
+
+
+ QPointArray points (4);
+ points [0] = p1;
+ points [1] = p2;
+ points [2] = p3;
+ points [3] = pointNotOnOutline;
+
+ p->setPen (col);
+ p->setBrush (col);
+ p->drawPolygon (points);
+
+
+ points.resize (3);
+
+ p->setPen (Qt::black);
+ p->setBrush (Qt::NoBrush);
+ p->drawPolyline (points);
+
+
+ p->restore ();
+}
+
+// protected
+void kpColorSimilarityCube::drawFace (QPainter *p,
+ int redOrGreenOrBlue,
+ const QPoint &tl, const QPoint &tr,
+ const QPoint &bl, const QPoint &br)
+{
+#if DEBUG_KP_COLOR_SIMILARITY_CUBE
+ kdDebug () << "kpColorSimilarityCube(RorGorB=" << redOrGreenOrBlue
+ << ",tl=" << tl
+ << ",tr=" << tr
+ << ",bl=" << bl
+ << ",br=" << br
+ << ")"
+ << endl;
+#endif
+
+ // tl --- tm --- tr
+ // | | |
+ // | | |
+ // ml --- mm --- mr
+ // | | |
+ // | | |
+ // bl --- bm --- br
+
+ const QPoint tm (::pointBetween (tl, tr));
+ const QPoint bm (::pointBetween (bl, br));
+
+ const QPoint ml (::pointBetween (tl, bl));
+ const QPoint mr (::pointBetween (tr, br));
+ const QPoint mm (::pointBetween (ml, mr));
+
+
+ const int baseBrightness = QMAX (127,
+ 255 - int (kpColorSimilarityDialog::maximumColorSimilarity *
+ kpColorSimilarityCube::colorCubeDiagonalDistance / 2));
+ QColor colors [2] =
+ {
+ color (redOrGreenOrBlue, baseBrightness, -1),
+ color (redOrGreenOrBlue, baseBrightness, +1)
+ };
+
+ if (!isEnabled ())
+ {
+ #if DEBUG_KP_COLOR_SIMILARITY_CUBE
+ kdDebug () << "\tnot enabled - making us grey" << endl;
+ #endif
+ colors [0] = colorGroup ().background ();
+ colors [1] = colorGroup ().background ();
+ }
+
+#if DEBUG_KP_COLOR_SIMILARITY_CUBE
+ kdDebug () << "\tmaxColorSimilarity=" << kpColorSimilarityDialog::maximumColorSimilarity
+ << " colorCubeDiagDist=" << kpColorSimilarityCube::colorCubeDiagonalDistance
+ << endl
+ << "\tbaseBrightness=" << baseBrightness
+ << " color[0]=" << ((colors [0].rgb () & RGB_MASK) >> ((2 - redOrGreenOrBlue) * 8))
+ << " color[1]=" << ((colors [1].rgb () & RGB_MASK) >> ((2 - redOrGreenOrBlue) * 8))
+ << endl;
+#endif
+
+
+ ::drawQuadrant (p, colors [0], tm, tl, ml, mm);
+ ::drawQuadrant (p, colors [1], tm, tr, mr, mm);
+ ::drawQuadrant (p, colors [1], ml, bl, bm, mm);
+ ::drawQuadrant (p, colors [0], bm, br, mr, mm);
+}
+
+// protected virtual [base QFrame]
+void kpColorSimilarityCube::drawContents (QPainter *p)
+{
+ QRect cr (contentsRect ());
+
+ QPixmap backBuffer (cr.width (), cr.height ());
+ backBuffer.fill (colorGroup ().background ());
+
+ QPainter backBufferPainter (&backBuffer);
+
+ int cubeRectSize = QMIN (cr.width () * 6 / 8, cr.height () * 6 / 8);
+ int dx = (cr.width () - cubeRectSize) / 2,
+ dy = (cr.height () - cubeRectSize) / 2;
+ backBufferPainter.translate (dx, dy);
+
+ //
+ // P------- Q --- ---
+ // / / | | |
+ // /A / | side |
+ // R-------S T --- cubeRectSize
+ // | | / / |
+ // S | | / side |
+ // U-------V --- ---
+ // |-------|
+ // side
+ // |-----------|
+ // cubeRectSize
+ //
+ //
+
+ const double angle = KP_DEGREES_TO_RADIANS (45);
+ // S + S sin A = cubeRectSize
+ // (1 + sin A) x S = cubeRectSize
+ const double side = double (cubeRectSize) / (1 + sin (angle));
+
+
+ const QPoint pointP ((int) (side * cos (angle)), 0);
+ const QPoint pointQ ((int) (side * cos (angle) + side), 0);
+ const QPoint pointR (0, (int) (side * sin (angle)));
+ const QPoint pointS ((int) (side), (int) (side * sin (angle)));
+ const QPoint pointU (0, (int) (side * sin (angle) + side));
+ const QPoint pointT ((int) (side + side * cos (angle)), (int) (side));
+ const QPoint pointV ((int) (side), (int) (side * sin (angle) + side));
+
+
+ // Top Face
+ drawFace (&backBufferPainter,
+ 0/*red*/,
+ pointP, pointQ,
+ pointR, pointS);
+
+
+ // Bottom Face
+ drawFace (&backBufferPainter,
+ 1/*green*/,
+ pointR, pointS,
+ pointU, pointV);
+
+
+ // Right Face
+ drawFace (&backBufferPainter,
+ 2/*blue*/,
+ pointS, pointQ,
+ pointV, pointT);
+
+
+#if 0
+ backBufferPainter.save ();
+ backBufferPainter.setPen (Qt::cyan);
+ backBufferPainter.drawRect (0, 0, cubeRectSize, cubeRectSize);
+ backBufferPainter.restore ();
+#endif
+
+
+ backBufferPainter.end ();
+
+ p->drawPixmap (cr, backBuffer);
+}
diff --git a/kolourpaint/widgets/kpcolorsimilaritycube.h b/kolourpaint/widgets/kpcolorsimilaritycube.h
new file mode 100644
index 00000000..358d4b3a
--- /dev/null
+++ b/kolourpaint/widgets/kpcolorsimilaritycube.h
@@ -0,0 +1,72 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kp_color_similarity_cube_h__
+#define __kp_color_similarity_cube_h__
+
+#include <qframe.h>
+
+class kpColor;
+class kpMainWindow;
+
+class kpColorSimilarityCube : public QFrame
+{
+public:
+ enum Look
+ {
+ Plain = 0,
+ Depressed = 1,
+ DoubleClickInstructions = 2
+ };
+
+ kpColorSimilarityCube (int look,
+ kpMainWindow *mainWindow,
+ QWidget *parent,
+ const char *name = 0);
+ virtual ~kpColorSimilarityCube ();
+
+ static const double colorCubeDiagonalDistance;
+
+ double colorSimilarity () const;
+ void setColorSimilarity (double similarity);
+
+ virtual QSize sizeHint () const;
+
+protected:
+ QColor color (int redOrGreenOrBlue, int baseBrightness, int similarityDirection) const;
+ void drawFace (QPainter *p,
+ int redOrGreenOrBlue,
+ const QPoint &tl, const QPoint &tr,
+ const QPoint &bl, const QPoint &br);
+ virtual void drawContents (QPainter *p);
+
+ kpMainWindow *m_mainWindow;
+ double m_colorSimilarity;
+};
+
+#endif // __kp_color_similarity_cube_h__
diff --git a/kolourpaint/widgets/kpcolorsimilaritydialog.cpp b/kolourpaint/widgets/kpcolorsimilaritydialog.cpp
new file mode 100644
index 00000000..d2766568
--- /dev/null
+++ b/kolourpaint/widgets/kpcolorsimilaritydialog.cpp
@@ -0,0 +1,123 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <kpcolorsimilaritydialog.h>
+
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+
+#include <klocale.h>
+#include <knuminput.h>
+
+#include <kpcolorsimilaritycube.h>
+
+
+// public static
+const double kpColorSimilarityDialog::maximumColorSimilarity = .30;
+
+
+kpColorSimilarityDialog::kpColorSimilarityDialog (kpMainWindow *mainWindow,
+ QWidget *parent,
+ const char *name)
+ : KDialogBase (parent, name, true/*modal*/,
+ i18n ("Color Similarity"),
+ KDialogBase::Ok | KDialogBase::Cancel),
+ m_mainWindow (mainWindow)
+{
+ QWidget *baseWidget = new QWidget (this);
+ setMainWidget (baseWidget);
+
+
+ QGroupBox *cubeGroupBox = new QGroupBox (i18n ("Preview"), baseWidget);
+
+ m_colorSimilarityCube = new kpColorSimilarityCube (kpColorSimilarityCube::Plain,
+ mainWindow, cubeGroupBox);
+ m_colorSimilarityCube->setMinimumSize (240, 180);
+
+ QPushButton *updatePushButton = new QPushButton (i18n ("&Update"), cubeGroupBox);
+
+
+ QVBoxLayout *cubeLayout = new QVBoxLayout (cubeGroupBox, marginHint () * 2, spacingHint ());
+ cubeLayout->addWidget (m_colorSimilarityCube, 1/*stretch*/);
+ cubeLayout->addWidget (updatePushButton, 0/*stretch*/, Qt::AlignHCenter);
+
+
+ connect (updatePushButton, SIGNAL (clicked ()),
+ this, SLOT (slotColorSimilarityValueChanged ()));
+
+
+ QGroupBox *inputGroupBox = new QGroupBox (i18n ("RGB Color Cube Distance"), baseWidget);
+
+ m_colorSimilarityInput = new KIntNumInput (inputGroupBox);
+ m_colorSimilarityInput->setRange (0, int (kpColorSimilarityDialog::maximumColorSimilarity * 100 + .1/*don't floor below target int*/),
+ 5/*step*/, true/*slider*/);
+ m_colorSimilarityInput->setSuffix (i18n ("%"));
+ m_colorSimilarityInput->setSpecialValueText (i18n ("Exact Match"));
+
+
+ QVBoxLayout *inputLayout = new QVBoxLayout (inputGroupBox, marginHint () * 2, spacingHint ());
+ inputLayout->addWidget (m_colorSimilarityInput);
+
+
+ connect (m_colorSimilarityInput, SIGNAL (valueChanged (int)),
+ this, SLOT (slotColorSimilarityValueChanged ()));
+
+
+ QVBoxLayout *baseLayout = new QVBoxLayout (baseWidget, 0/*margin*/, spacingHint () * 2);
+ baseLayout->addWidget (cubeGroupBox, 1/*stretch*/);
+ baseLayout->addWidget (inputGroupBox);
+}
+
+kpColorSimilarityDialog::~kpColorSimilarityDialog ()
+{
+}
+
+
+// public
+double kpColorSimilarityDialog::colorSimilarity () const
+{
+ return m_colorSimilarityCube->colorSimilarity ();
+}
+
+// public
+void kpColorSimilarityDialog::setColorSimilarity (double similarity)
+{
+ m_colorSimilarityInput->setValue (qRound (similarity * 100));
+}
+
+
+// private slot
+void kpColorSimilarityDialog::slotColorSimilarityValueChanged ()
+{
+ m_colorSimilarityCube->setColorSimilarity (double (m_colorSimilarityInput->value ()) / 100);
+}
+
+
+#include <kpcolorsimilaritydialog.moc>
diff --git a/kolourpaint/widgets/kpcolorsimilaritydialog.h b/kolourpaint/widgets/kpcolorsimilaritydialog.h
new file mode 100644
index 00000000..fd70ecd0
--- /dev/null
+++ b/kolourpaint/widgets/kpcolorsimilaritydialog.h
@@ -0,0 +1,62 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __kp_color_similarity_dialog_h__
+#define __kp_color_similarity_dialog_h__
+
+#include <kdialogbase.h>
+
+class KIntNumInput;
+
+class kpColorSimilarityCube;
+class kpMainWindow;
+
+class kpColorSimilarityDialog : public KDialogBase
+{
+Q_OBJECT
+
+public:
+ kpColorSimilarityDialog (kpMainWindow *mainWindow,
+ QWidget *parent,
+ const char *name = 0);
+ virtual ~kpColorSimilarityDialog ();
+
+ double colorSimilarity () const;
+ void setColorSimilarity (double similarity);
+
+ static const double maximumColorSimilarity;
+
+private slots:
+ void slotColorSimilarityValueChanged ();
+
+private:
+ kpMainWindow *m_mainWindow;
+ kpColorSimilarityCube *m_colorSimilarityCube;
+ KIntNumInput *m_colorSimilarityInput;
+};
+
+#endif // __kp_color_similarity_dialog_h__
diff --git a/kolourpaint/widgets/kpcolortoolbar.cpp b/kolourpaint/widgets/kpcolortoolbar.cpp
new file mode 100644
index 00000000..cba73b4f
--- /dev/null
+++ b/kolourpaint/widgets/kpcolortoolbar.cpp
@@ -0,0 +1,1112 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#define DEBUG_KP_COLOR_TOOL_BAR 0
+
+
+#include <kpcolortoolbar.h>
+
+#include <qbitmap.h>
+#include <qdrawutil.h>
+#include <qframe.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qsize.h>
+#include <qtooltip.h>
+#include <qwidget.h>
+
+#include <kapplication.h>
+#include <kcolordialog.h>
+#include <kcolordrag.h>
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include <kpcolorsimilaritydialog.h>
+#include <kpdefs.h>
+#include <kpmainwindow.h>
+#include <kppixmapfx.h>
+#include <kptool.h>
+#include <kpview.h>
+
+
+/*
+ * kpDualColorButton
+ */
+
+kpDualColorButton::kpDualColorButton (kpMainWindow *mainWindow,
+ QWidget *parent, const char *name)
+ : QFrame (parent, name, Qt::WNoAutoErase/*no flicker*/),
+ m_mainWindow (mainWindow),
+ m_backBuffer (0)
+{
+ setFrameStyle (QFrame::Panel | QFrame::Sunken);
+
+ m_color [0] = kpColor (0, 0, 0); // black
+ m_color [1] = kpColor (255, 255, 255); // white
+
+ setAcceptDrops (true);
+}
+
+kpDualColorButton::~kpDualColorButton ()
+{
+ delete m_backBuffer; m_backBuffer = 0;
+}
+
+
+kpColor kpDualColorButton::color (int which) const
+{
+ if (which < 0 || which > 1)
+ {
+ kdWarning () << "kpDualColorButton::color (" << which
+ << ") - out of range" << endl;
+ which = 0;
+ }
+
+ return m_color [which];
+}
+
+kpColor kpDualColorButton::foregroundColor () const
+{
+ return color (0);
+}
+
+kpColor kpDualColorButton::backgroundColor () const
+{
+ return color (1);
+}
+
+
+void kpDualColorButton::setColor (int which, const kpColor &color)
+{
+ if (which < 0 || which > 1)
+ {
+ kdWarning () << "kpDualColorButton::setColor (" << which
+ << ") - out of range" << endl;
+ which = 0;
+ }
+
+ if (m_color [which] == color)
+ return;
+
+ m_oldColor [which] = m_color [which];
+ m_color [which] = color;
+ update ();
+
+ if (which == 0)
+ emit foregroundColorChanged (color);
+ else
+ emit backgroundColorChanged (color);
+}
+
+void kpDualColorButton::setForegroundColor (const kpColor &color)
+{
+ setColor (0, color);
+}
+
+void kpDualColorButton::setBackgroundColor (const kpColor &color)
+{
+ setColor (1, color);
+}
+
+
+// public
+kpColor kpDualColorButton::oldForegroundColor () const
+{
+ return m_oldColor [0];
+}
+
+// public
+kpColor kpDualColorButton::oldBackgroundColor () const
+{
+ return m_oldColor [1];
+}
+
+
+// public virtual [base QWidget]
+QSize kpDualColorButton::sizeHint () const
+{
+ return QSize (52, 52);
+}
+
+
+// protected
+QRect kpDualColorButton::swapPixmapRect () const
+{
+ QPixmap swapPixmap = UserIcon ("colorbutton_swap_16x16");
+
+ return QRect (contentsRect ().width () - swapPixmap.width (),
+ 0,
+ swapPixmap.width (),
+ swapPixmap.height ());
+}
+
+// protected
+QRect kpDualColorButton::foregroundBackgroundRect () const
+{
+ QRect cr (contentsRect ());
+ return QRect (cr.width () / 8,
+ cr.height () / 8,
+ cr.width () * 6 / 8,
+ cr.height () * 6 / 8);
+}
+
+// protected
+QRect kpDualColorButton::foregroundRect () const
+{
+ QRect fbr (foregroundBackgroundRect ());
+ return QRect (fbr.x (),
+ fbr.y (),
+ fbr.width () * 3 / 4,
+ fbr.height () * 3 / 4);
+}
+
+// protected
+QRect kpDualColorButton::backgroundRect () const
+{
+ QRect fbr (foregroundBackgroundRect ());
+ return QRect (fbr.x () + fbr.width () / 4,
+ fbr.y () + fbr.height () / 4,
+ fbr.width () * 3 / 4,
+ fbr.height () * 3 / 4);
+}
+
+
+// TODO: drag a colour from this widget
+
+// protected virtual [base QWidget]
+void kpDualColorButton::dragMoveEvent (QDragMoveEvent *e)
+{
+ e->accept ((foregroundRect ().contains (e->pos ()) ||
+ backgroundRect ().contains (e->pos ())) &&
+ KColorDrag::canDecode (e));
+}
+
+// protected virtual [base QWidget]
+void kpDualColorButton::dropEvent (QDropEvent *e)
+{
+ QColor col;
+ KColorDrag::decode (e, col/*ref*/);
+
+ if (col.isValid ())
+ {
+ if (foregroundRect ().contains (e->pos ()))
+ setForegroundColor (kpColor (col.rgb ()));
+ else if (backgroundRect ().contains (e->pos ()))
+ setBackgroundColor (kpColor (col.rgb ()));
+ }
+}
+
+
+// protected virtual [base QWidget]
+void kpDualColorButton::mousePressEvent (QMouseEvent * /*e*/)
+{
+ // eat right-mouse click to prevent it from getting to the toolbar
+}
+
+// protected virtual [base QWidget]
+void kpDualColorButton::mouseDoubleClickEvent (QMouseEvent *e)
+{
+ int whichColor = -1;
+
+ if (foregroundRect ().contains (e->pos ()))
+ whichColor = 0;
+ else if (backgroundRect ().contains (e->pos ()))
+ whichColor = 1;
+
+ if (whichColor == 0 || whichColor == 1)
+ {
+ QColor col = Qt::black;
+ if (color (whichColor).isOpaque ())
+ col = color (whichColor).toQColor ();
+ else
+ {
+ // TODO: If you double-click on a transparent color and press OK, you get
+ // black, instead of the color staying as transparent.
+ //
+ // We should modify or fork KColorDialog to allow us to fix this.
+ //
+ // It would be wrong to stop the user from double-clicking on a
+ // transparent color as that would make the UI inconsistent, compared
+ // to opaque colors.
+ }
+
+ // TODO: parent
+ if (KColorDialog::getColor (col/*ref*/))
+ setColor (whichColor, kpColor (col.rgb ()));
+ }
+}
+
+// protected virtual [base QWidget]
+void kpDualColorButton::mouseReleaseEvent (QMouseEvent *e)
+{
+ if (swapPixmapRect ().contains (e->pos ()) &&
+ m_color [0] != m_color [1])
+ {
+ #if DEBUG_KP_COLOR_TOOL_BAR && 1
+ kdDebug () << "kpDualColorButton::mouseReleaseEvent() swap colors:" << endl;
+ #endif
+ m_oldColor [0] = m_color [0];
+ m_oldColor [1] = m_color [1];
+
+ kpColor temp = m_color [0];
+ m_color [0] = m_color [1];
+ m_color [1] = temp;
+
+ update ();
+
+ emit colorsSwapped (m_color [0], m_color [1]);
+ emit foregroundColorChanged (m_color [0]);
+ emit backgroundColorChanged (m_color [1]);
+ }
+}
+
+
+// protected virtual [base QFrame]
+void kpDualColorButton::drawContents (QPainter *p)
+{
+#if DEBUG_KP_COLOR_TOOL_BAR && 1
+ kdDebug () << "kpDualColorButton::draw() rect=" << rect ()
+ << " contentsRect=" << contentsRect ()
+ << endl;
+#endif
+
+ if (!m_backBuffer ||
+ m_backBuffer->width () != contentsRect ().width () ||
+ m_backBuffer->height () != contentsRect ().height ())
+ {
+ delete m_backBuffer;
+ m_backBuffer = new QPixmap (contentsRect ().width (), contentsRect ().height ());
+ }
+
+
+ QPainter backBufferPainter (m_backBuffer);
+
+ if (isEnabled () && m_mainWindow)
+ {
+ kpView::drawTransparentBackground (&backBufferPainter,
+ m_backBuffer->width (), m_backBuffer->height (),
+ m_backBuffer->rect (),
+ true/*preview*/);
+ }
+ else
+ {
+ backBufferPainter.fillRect (m_backBuffer->rect (),
+ colorGroup ().color (QColorGroup::Background));
+ }
+
+ QPixmap swapPixmap = UserIcon ("colorbutton_swap_16x16");
+ if (!isEnabled ())
+ {
+ // swapPixmap has a mask after all
+ swapPixmap.fill (colorGroup ().color (QColorGroup::Dark));
+ }
+ backBufferPainter.drawPixmap (swapPixmapRect ().topLeft (), swapPixmap);
+
+ // foreground patch must be drawn after background patch
+ // as it overlaps on top of background patch
+ QRect bgRect = backgroundRect ();
+ QRect bgRectInside = QRect (bgRect.x () + 2, bgRect.y () + 2,
+ bgRect.width () - 4, bgRect.height () - 4);
+ if (isEnabled ())
+ {
+ #if DEBUG_KP_COLOR_TOOL_BAR && 1
+ kdDebug () << "\tbackgroundColor=" << (int *) m_color [1].toQRgb ()
+ << endl;
+ #endif
+ if (m_color [1].isOpaque ())
+ backBufferPainter.fillRect (bgRectInside, m_color [1].toQColor ());
+ else
+ backBufferPainter.drawPixmap (bgRectInside, UserIcon ("color_transparent_26x26"));
+ }
+ else
+ backBufferPainter.fillRect (bgRectInside, colorGroup ().color (QColorGroup::Button));
+ qDrawShadePanel (&backBufferPainter, bgRect, colorGroup (),
+ false/*not sunken*/, 2/*lineWidth*/,
+ 0/*never fill*/);
+
+ QRect fgRect = foregroundRect ();
+ QRect fgRectInside = QRect (fgRect.x () + 2, fgRect.y () + 2,
+ fgRect.width () - 4, fgRect.height () - 4);
+ if (isEnabled ())
+ {
+ #if DEBUG_KP_COLOR_TOOL_BAR && 1
+ kdDebug () << "\tforegroundColor=" << (int *) m_color [0].toQRgb ()
+ << endl;
+ #endif
+ if (m_color [0].isOpaque ())
+ backBufferPainter.fillRect (fgRectInside, m_color [0].toQColor ());
+ else
+ backBufferPainter.drawPixmap (fgRectInside, UserIcon ("color_transparent_26x26"));
+ }
+ else
+ backBufferPainter.fillRect (fgRectInside, colorGroup ().color (QColorGroup::Button));
+ qDrawShadePanel (&backBufferPainter, fgRect, colorGroup (),
+ false/*not sunken*/, 2/*lineWidth*/,
+ 0/*never fill*/);
+
+ backBufferPainter.end ();
+
+ p->drawPixmap (contentsRect (), *m_backBuffer);
+}
+
+
+/*
+ * kpColorCells
+ */
+
+static inline int roundUp2 (int val)
+{
+ return val % 2 ? val + 1 : val;
+}
+
+static inline int btwn0_255 (int val)
+{
+ if (val < 0)
+ return 0;
+ else if (val > 255)
+ return 255;
+ else
+ return val;
+}
+
+enum
+{
+ blendDark = 25,
+ blendNormal = 50,
+ blendLight = 75,
+ blendAdd = 100
+};
+
+static QColor blend (const QColor &a, const QColor &b, int percent = blendNormal)
+{
+ return QColor (btwn0_255 (roundUp2 (a.red () + b.red ()) * percent / 100),
+ btwn0_255 (roundUp2 (a.green () + b.green ()) * percent / 100),
+ btwn0_255 (roundUp2 (a.blue () + b.blue ()) * percent / 100));
+}
+
+static QColor add (const QColor &a, const QColor &b)
+{
+ return blend (a, b, blendAdd);
+}
+
+
+
+
+
+//
+// make our own colors in case weird ones like "Qt::cyan"
+// (turquoise) get changed by Qt
+//
+
+// primary colors + B&W
+static QColor kpRed;
+static QColor kpGreen;
+static QColor kpBlue;
+static QColor kpBlack;
+static QColor kpWhite;
+
+// intentionally _not_ an HSV darkener
+static QColor dark (const QColor &color)
+{
+ return blend (color, kpBlack);
+}
+
+// full-brightness colors
+static QColor kpYellow;
+static QColor kpPurple;
+static QColor kpAqua;
+
+// mixed colors
+static QColor kpGrey;
+static QColor kpLightGrey;
+static QColor kpOrange;
+
+// pastel colors
+static QColor kpPink;
+static QColor kpLightGreen;
+static QColor kpLightBlue;
+static QColor kpTan;
+
+static bool ownColorsInitialised = false;
+
+/* TODO: clean up this code!!!
+ * (probably when adding palette load/save)
+ */
+#define rows 2
+#define cols 11
+kpColorCells::kpColorCells (QWidget *parent,
+ Qt::Orientation o,
+ const char *name)
+ : KColorCells (parent, rows, cols),
+ m_mouseButton (-1)
+{
+ setName (name);
+
+ setShading (false); // no 3D look
+
+ // Trap KColorDrag so that kpMainWindow does not trap it.
+ // See our impl of dropEvent().
+ setAcceptDrops (true);
+ setAcceptDrags (true);
+
+ connect (this, SIGNAL (colorDoubleClicked (int)),
+ SLOT (slotColorDoubleClicked (int)));
+
+ if (!ownColorsInitialised)
+ {
+ // Don't initialise globally when we probably don't have a colour
+ // allocation context. This way, the colours aren't sometimes
+ // invalid (e.g. at 8-bit).
+
+ kpRed = QColor (255, 0, 0);
+ kpGreen = QColor (0, 255, 0);
+ kpBlue = QColor (0, 0, 255);
+ kpBlack = QColor (0, 0, 0);
+ kpWhite = QColor (255, 255, 255);
+
+ kpYellow = add (kpRed, kpGreen);
+ kpPurple = add (kpRed, kpBlue);
+ kpAqua = add (kpGreen, kpBlue);
+
+ kpGrey = blend (kpBlack, kpWhite);
+ kpLightGrey = blend (kpGrey, kpWhite);
+ kpOrange = blend (kpRed, kpYellow);
+
+ kpPink = blend (kpRed, kpWhite);
+ kpLightGreen = blend (kpGreen, kpWhite);
+ kpLightBlue = blend (kpBlue, kpWhite);
+ kpTan = blend (kpYellow, kpWhite);
+
+ ownColorsInitialised = true;
+ }
+
+ setOrientation (o);
+}
+
+kpColorCells::~kpColorCells ()
+{
+}
+
+Qt::Orientation kpColorCells::orientation () const
+{
+ return m_orientation;
+}
+
+void kpColorCells::setOrientation (Qt::Orientation o)
+{
+ int c, r;
+
+ if (o == Qt::Horizontal)
+ {
+ c = cols;
+ r = rows;
+ }
+ else
+ {
+ c = rows;
+ r = cols;
+ }
+
+#if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpColorCells::setOrientation(): r=" << r << " c=" << c << endl;
+#endif
+
+ setNumRows (r);
+ setNumCols (c);
+
+ setCellWidth (26);
+ setCellHeight (26);
+
+ setFixedSize (numCols () * cellWidth () + frameWidth () * 2,
+ numRows () * cellHeight () + frameWidth () * 2);
+
+/*
+ kdDebug () << "\tlimits: array=" << sizeof (colors) / sizeof (colors [0])
+ << " r*c=" << r * c << endl;
+ kdDebug () << "\tsizeof (colors)=" << sizeof (colors)
+ << " sizeof (colors [0])=" << sizeof (colors [0])
+ << endl;*/
+ QColor colors [] =
+ {
+ kpBlack,
+ kpGrey,
+ kpRed,
+ kpOrange,
+ kpYellow,
+ kpGreen,
+ kpAqua,
+ kpBlue,
+ kpPurple,
+ kpPink,
+ kpLightGreen,
+
+ kpWhite,
+ kpLightGrey,
+ dark (kpRed),
+ dark (kpOrange)/*brown*/,
+ dark (kpYellow),
+ dark (kpGreen),
+ dark (kpAqua),
+ dark (kpBlue),
+ dark (kpPurple),
+ kpLightBlue,
+ kpTan
+ };
+
+ for (int i = 0;
+ /*i < int (sizeof (colors) / sizeof (colors [0])) &&*/
+ i < r * c;
+ i++)
+ {
+ int y, x;
+ int pos;
+
+ if (o == Qt::Horizontal)
+ {
+ y = i / cols;
+ x = i % cols;
+ pos = i;
+ }
+ else
+ {
+ y = i % cols;
+ x = i / cols;
+ // int x = rows - 1 - i / cols;
+ pos = y * rows + x;
+ }
+
+ KColorCells::setColor (pos, colors [i]);
+ //QToolTip::add (this, cellGeometry (y, x), colors [i].name ());
+ }
+
+ m_orientation = o;
+}
+
+// virtual protected [base KColorCells]
+void kpColorCells::dropEvent (QDropEvent *e)
+{
+ // Eat event so that:
+ //
+ // 1. User doesn't clobber the palette (until we support reconfigurable
+ // palettes)
+ // 2. kpMainWindow::dropEvent() doesn't try to paste colour code as text
+ // (when the user slips and drags colour cell a little instead of clicking)
+ e->accept ();
+}
+
+// virtual protected
+void kpColorCells::paintCell (QPainter *painter, int row, int col)
+{
+ QColor oldColor;
+ int cellNo;
+
+ if (!isEnabled ())
+ {
+ cellNo = row * numCols () + col;
+
+ // make all cells 3D (so that disabled palette doesn't look flat)
+ setShading (true);
+
+ oldColor = KColorCells::color (cellNo);
+ KColorCells::colors [cellNo] = backgroundColor ();
+ }
+
+
+ // no focus rect as it doesn't make sense
+ // since 2 colors (foreground & background) can be selected
+ KColorCells::selected = -1;
+ KColorCells::paintCell (painter, row, col);
+
+
+ if (!isEnabled ())
+ {
+ KColorCells::colors [cellNo] = oldColor;
+ setShading (false);
+ }
+}
+
+// virtual protected
+void kpColorCells::mouseReleaseEvent (QMouseEvent *e)
+{
+ m_mouseButton = -1;
+
+ Qt::ButtonState button = e->button ();
+#if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpColorCells::mouseReleaseEvent(left="
+ << (button & Qt::LeftButton)
+ << ",right="
+ << (button & Qt::RightButton)
+ << ")"
+ << endl;
+#endif
+ if (!((button & Qt::LeftButton) && (button & Qt::RightButton)))
+ {
+ if (button & Qt::LeftButton)
+ m_mouseButton = 0;
+ else if (button & Qt::RightButton)
+ m_mouseButton = 1;
+ }
+
+ connect (this, SIGNAL (colorSelected (int)), this, SLOT (slotColorSelected (int)));
+ KColorCells::mouseReleaseEvent (e);
+ disconnect (this, SIGNAL (colorSelected (int)), this, SLOT (slotColorSelected (int)));
+
+#if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpColorCells::mouseReleaseEvent() setting m_mouseButton back to -1" << endl;
+#endif
+ m_mouseButton = -1;
+}
+
+// protected virtual [base KColorCells]
+void kpColorCells::resizeEvent (QResizeEvent *e)
+{
+ // KColorCells::resizeEvent() tries to adjust the cellWidth and cellHeight
+ // to the current dimensions but doesn't take into account
+ // frame{Width,Height}().
+ //
+ // In any case, we already set the cell{Width,Height} and a fixed
+ // widget size and don't want any of it changed. Eat the resize event.
+ (void) e;
+}
+
+// protected slot
+void kpColorCells::slotColorSelected (int cell)
+{
+#if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpColorCells::slotColorSelected(cell=" << cell
+ << ") mouseButton = " << m_mouseButton << endl;
+#endif
+ QColor c = KColorCells::color (cell);
+
+ if (m_mouseButton == 0)
+ {
+ emit foregroundColorChanged (c);
+ emit foregroundColorChanged (kpColor (c.rgb ()));
+ }
+ else if (m_mouseButton == 1)
+ {
+ emit backgroundColorChanged (c);
+ emit backgroundColorChanged (kpColor (c.rgb ()));
+ }
+
+ m_mouseButton = -1; // just in case
+}
+
+// protected slot
+void kpColorCells::slotColorDoubleClicked (int cell)
+{
+#if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpColorCells::slotColorDoubleClicked(cell="
+ << cell << ")" << endl;
+#endif
+
+ QColor color = KColorCells::color (cell);
+
+ // TODO: parent
+ if (KColorDialog::getColor (color/*ref*/))
+ KColorCells::setColor (cell, color);
+}
+
+
+/*
+ * kpTransparentColorCell
+ */
+
+kpTransparentColorCell::kpTransparentColorCell (QWidget *parent, const char *name)
+ : QFrame (parent, name)
+{
+#if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpTransparentColorCell::kpTransparentColorCell()" << endl;
+#endif
+
+ setFrameStyle (QFrame::Panel | QFrame::Sunken);
+#if DEBUG_KP_COLOR_TOOL_BAR && 0
+ kdDebug () << "\tdefault line width=" << lineWidth ()
+ << " frame width=" << frameWidth () << endl;
+#endif
+ //setLineWidth (2);
+#if DEBUG_KP_COLOR_TOOL_BAR && 0
+ kdDebug () << "\tline width=" << lineWidth ()
+ << " frame width=" << frameWidth () << endl;
+#endif
+
+ m_pixmap = UserIcon ("color_transparent_26x26");
+
+ QToolTip::add (this, i18n ("Transparent"));
+}
+
+kpTransparentColorCell::~kpTransparentColorCell ()
+{
+}
+
+
+// public virtual [base QWidget]
+QSize kpTransparentColorCell::sizeHint () const
+{
+ return QSize (m_pixmap.width () + frameWidth () * 2,
+ m_pixmap.height () + frameWidth () * 2);
+}
+
+// protected virtual [base QWidget]
+void kpTransparentColorCell::mousePressEvent (QMouseEvent * /*e*/)
+{
+ // eat right-mouse click to prevent it from getting to the toolbar
+}
+
+// protected virtual [base QWidget]
+void kpTransparentColorCell::mouseReleaseEvent (QMouseEvent *e)
+{
+ if (rect ().contains (e->pos ()))
+ {
+ if (e->button () == Qt::LeftButton)
+ {
+ emit transparentColorSelected (0);
+ emit foregroundColorChanged (kpColor::transparent);
+ }
+ else if (e->button () == Qt::RightButton)
+ {
+ emit transparentColorSelected (1);
+ emit backgroundColorChanged (kpColor::transparent);
+ }
+ }
+}
+
+// protected virtual [base QFrame]
+void kpTransparentColorCell::drawContents (QPainter *p)
+{
+ QFrame::drawContents (p);
+ if (isEnabled ())
+ {
+ #if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpTransparentColorCell::drawContents() contentsRect="
+ << contentsRect ()
+ << endl;
+ #endif
+ p->drawPixmap (contentsRect (), m_pixmap);
+ }
+}
+
+
+/*
+ * kpColorPalette
+ */
+
+kpColorPalette::kpColorPalette (QWidget *parent,
+ Qt::Orientation o,
+ const char *name)
+ : QWidget (parent, name),
+ m_boxLayout (0)
+{
+#if DEBUG_KP_COLOR_TOOL_BAR
+ kdDebug () << "kpColorPalette::kpColorPalette()" << endl;
+#endif
+
+ m_transparentColorCell = new kpTransparentColorCell (this);
+ m_transparentColorCell->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
+ connect (m_transparentColorCell, SIGNAL (foregroundColorChanged (const kpColor &)),
+ this, SIGNAL (foregroundColorChanged (const kpColor &)));
+ connect (m_transparentColorCell, SIGNAL (backgroundColorChanged (const kpColor &)),
+ this, SIGNAL (backgroundColorChanged (const kpColor &)));
+
+ m_colorCells = new kpColorCells (this);
+ connect (m_colorCells, SIGNAL (foregroundColorChanged (const kpColor &)),
+ this, SIGNAL (foregroundColorChanged (const kpColor &)));
+ connect (m_colorCells, SIGNAL (backgroundColorChanged (const kpColor &)),
+ this, SIGNAL (backgroundColorChanged (const kpColor &)));
+
+ setOrientation (o);
+}
+
+kpColorPalette::~kpColorPalette ()
+{
+}
+
+// public
+Qt::Orientation kpColorPalette::orientation () const
+{
+ return m_orientation;
+}
+
+void kpColorPalette::setOrientation (Qt::Orientation o)
+{
+ m_colorCells->setOrientation (o);
+
+ delete m_boxLayout;
+
+ if (o == Qt::Horizontal)
+ {
+ m_boxLayout = new QBoxLayout (this, QBoxLayout::LeftToRight, 0/*margin*/, 5/*spacing*/);
+ m_boxLayout->addWidget (m_transparentColorCell, 0/*stretch*/, Qt::AlignVCenter);
+ m_boxLayout->addWidget (m_colorCells);
+ }
+ else
+ {
+ m_boxLayout = new QBoxLayout (this, QBoxLayout::TopToBottom, 0/*margin*/, 5/*spacing*/);
+ m_boxLayout->addWidget (m_transparentColorCell, 0/*stretch*/, Qt::AlignHCenter);
+ m_boxLayout->addWidget (m_colorCells);
+ }
+
+ m_orientation = o;
+}
+
+
+/*
+ * kpColorSimilarityToolBarItem
+ */
+
+kpColorSimilarityToolBarItem::kpColorSimilarityToolBarItem (kpMainWindow *mainWindow,
+ QWidget *parent,
+ const char *name)
+ : kpColorSimilarityCube (kpColorSimilarityCube::Depressed |
+ kpColorSimilarityCube::DoubleClickInstructions,
+ mainWindow, parent, name),
+ m_mainWindow (mainWindow),
+ m_processedColorSimilarity (kpColor::Exact)
+{
+ setColorSimilarity (mainWindow->configColorSimilarity ());
+}
+
+kpColorSimilarityToolBarItem::~kpColorSimilarityToolBarItem ()
+{
+}
+
+
+// public
+int kpColorSimilarityToolBarItem::processedColorSimilarity () const
+{
+ return m_processedColorSimilarity;
+}
+
+
+// public slot
+void kpColorSimilarityToolBarItem::setColorSimilarity (double similarity)
+{
+ m_oldColorSimilarity = colorSimilarity ();
+
+ kpColorSimilarityCube::setColorSimilarity (similarity);
+ if (similarity > 0)
+ QToolTip::add (this, i18n ("Color similarity: %1%").arg (qRound (similarity * 100)));
+ else
+ QToolTip::add (this, i18n ("Color similarity: Exact"));
+
+ m_processedColorSimilarity = kpColor::processSimilarity (colorSimilarity ());
+
+ m_mainWindow->configSetColorSimilarity (colorSimilarity ());
+
+ emit colorSimilarityChanged (colorSimilarity (), m_processedColorSimilarity);
+}
+
+// public
+double kpColorSimilarityToolBarItem::oldColorSimilarity () const
+{
+ return m_oldColorSimilarity;
+}
+
+
+// private virtual [base QWidget]
+void kpColorSimilarityToolBarItem::mousePressEvent (QMouseEvent * /*e*/)
+{
+ // eat right-mouse click to prevent it from getting to the toolbar
+}
+
+// private virtual [base QWidget]
+void kpColorSimilarityToolBarItem::mouseDoubleClickEvent (QMouseEvent * /*e*/)
+{
+ kpColorSimilarityDialog dialog (m_mainWindow, this);
+ dialog.setColorSimilarity (colorSimilarity ());
+ if (dialog.exec ())
+ {
+ setColorSimilarity (dialog.colorSimilarity ());
+ }
+}
+
+
+/*
+ * kpColorToolBar
+ */
+
+kpColorToolBar::kpColorToolBar (const QString &label, kpMainWindow *mainWindow, const char *name)
+ : KToolBar (mainWindow, name),
+ m_mainWindow (mainWindow)
+{
+ setText (label);
+
+
+ QWidget *base = new QWidget (this);
+ m_boxLayout = new QBoxLayout (base, QBoxLayout::LeftToRight,
+ 5/*margin*/, (10 * 4)/*spacing*/);
+
+ m_dualColorButton = new kpDualColorButton (mainWindow, base);
+ m_dualColorButton->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
+ connect (m_dualColorButton, SIGNAL (colorsSwapped (const kpColor &, const kpColor &)),
+ this, SIGNAL (colorsSwapped (const kpColor &, const kpColor &)));
+ connect (m_dualColorButton, SIGNAL (foregroundColorChanged (const kpColor &)),
+ this, SIGNAL (foregroundColorChanged (const kpColor &)));
+ connect (m_dualColorButton, SIGNAL (backgroundColorChanged (const kpColor &)),
+ this, SIGNAL (backgroundColorChanged (const kpColor &)));
+ m_boxLayout->addWidget (m_dualColorButton, 0/*stretch*/);
+
+ m_colorPalette = new kpColorPalette (base);
+ connect (m_colorPalette, SIGNAL (foregroundColorChanged (const kpColor &)),
+ m_dualColorButton, SLOT (setForegroundColor (const kpColor &)));
+ connect (m_colorPalette, SIGNAL (backgroundColorChanged (const kpColor &)),
+ m_dualColorButton, SLOT (setBackgroundColor (const kpColor &)));
+ m_boxLayout->addWidget (m_colorPalette, 0/*stretch*/);
+
+ m_colorSimilarityToolBarItem = new kpColorSimilarityToolBarItem (mainWindow, base);
+ m_colorSimilarityToolBarItem->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
+ connect (m_colorSimilarityToolBarItem, SIGNAL (colorSimilarityChanged (double, int)),
+ this, SIGNAL (colorSimilarityChanged (double, int)));
+ m_boxLayout->addWidget (m_colorSimilarityToolBarItem, 0/*stretch*/);
+
+ // HACK: couldn't get QSpacerItem to work
+ QWidget *fakeSpacer = new QWidget (base);
+ m_boxLayout->addWidget (fakeSpacer, 1/*stretch*/);
+
+ m_lastDockedOrientationSet = false;
+ setOrientation (orientation ());
+
+ KToolBar::insertWidget (0, base->width (), base);
+}
+
+// virtual
+void kpColorToolBar::setOrientation (Qt::Orientation o)
+{
+ // (QDockWindow::undock() calls us)
+ bool isOutsideDock = (place () == QDockWindow::OutsideDock);
+
+ if (!m_lastDockedOrientationSet || !isOutsideDock)
+ {
+ m_lastDockedOrientation = o;
+ m_lastDockedOrientationSet = true;
+ }
+
+ if (isOutsideDock)
+ {
+ //kdDebug () << "\toutside dock, forcing orientation to last" << endl;
+ o = m_lastDockedOrientation;
+ }
+
+ if (o == Qt::Horizontal)
+ {
+ m_boxLayout->setDirection (QBoxLayout::LeftToRight);
+ }
+ else
+ {
+ m_boxLayout->setDirection (QBoxLayout::TopToBottom);
+ }
+
+ m_colorPalette->setOrientation (o);
+
+ KToolBar::setOrientation (o);
+}
+
+kpColorToolBar::~kpColorToolBar ()
+{
+}
+
+kpColor kpColorToolBar::color (int which) const
+{
+ if (which < 0 || which > 1)
+ {
+ kdWarning () << "kpColorToolBar::color (" << which
+ << ") - out of range" << endl;
+ which = 0;
+ }
+
+ return m_dualColorButton->color (which);
+}
+
+void kpColorToolBar::setColor (int which, const kpColor &color)
+{
+ if (which < 0 || which > 1)
+ {
+ kdWarning () << "kpColorToolBar::setColor (" << which
+ << ") - out of range" << endl;
+ which = 0;
+ }
+
+ m_dualColorButton->setColor (which, color);
+}
+
+kpColor kpColorToolBar::foregroundColor () const
+{
+ return m_dualColorButton->foregroundColor ();
+}
+
+void kpColorToolBar::setForegroundColor (const kpColor &color)
+{
+ m_dualColorButton->setForegroundColor (color);
+}
+
+kpColor kpColorToolBar::backgroundColor () const
+{
+ return m_dualColorButton->backgroundColor ();
+}
+
+void kpColorToolBar::setBackgroundColor (const kpColor &color)
+{
+ m_dualColorButton->setBackgroundColor (color);
+}
+
+
+kpColor kpColorToolBar::oldForegroundColor () const
+{
+ return m_dualColorButton->oldForegroundColor ();
+}
+
+kpColor kpColorToolBar::oldBackgroundColor () const
+{
+ return m_dualColorButton->oldBackgroundColor ();
+}
+
+double kpColorToolBar::oldColorSimilarity () const
+{
+ return m_colorSimilarityToolBarItem->oldColorSimilarity ();
+}
+
+
+double kpColorToolBar::colorSimilarity () const
+{
+ return m_colorSimilarityToolBarItem->colorSimilarity ();
+}
+
+void kpColorToolBar::setColorSimilarity (double similarity)
+{
+ m_colorSimilarityToolBarItem->setColorSimilarity (similarity);
+}
+
+int kpColorToolBar::processedColorSimilarity () const
+{
+ return m_colorSimilarityToolBarItem->processedColorSimilarity ();
+}
+
+
+#include <kpcolortoolbar.moc>
diff --git a/kolourpaint/widgets/kpcolortoolbar.h b/kolourpaint/widgets/kpcolortoolbar.h
new file mode 100644
index 00000000..b4a77bfb
--- /dev/null
+++ b/kolourpaint/widgets/kpcolortoolbar.h
@@ -0,0 +1,297 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kp_color_toolbar_h__
+#define __kp_color_toolbar_h__
+
+
+#include <qframe.h>
+#include <qwidget.h>
+
+#include <kcolordialog.h>
+#include <ktoolbar.h>
+
+#include <kpcolor.h>
+#include <kpcolorsimilaritycube.h>
+
+
+class QGridLayout;
+class KColorButton;
+
+class kpColorSimilarityCube;
+class kpMainWindow;
+
+
+//
+// Widget similar to KDualColorButton.
+// Main differences:
+// - more consistent feel with other KolourPaint widgets
+// (esp. kpColorPalette)
+// - displays the transparent colour using the special pixmap
+// used by kpTransparentColorCell
+// - no obscure "current" colour
+//
+class kpDualColorButton : public QFrame
+{
+Q_OBJECT
+
+public:
+ kpDualColorButton (kpMainWindow *mainWindow,
+ QWidget *parent, const char *name = 0);
+ virtual ~kpDualColorButton ();
+
+ kpColor color (int which) const;
+ kpColor foregroundColor () const;
+ kpColor backgroundColor () const;
+
+public slots:
+ void setColor (int which, const kpColor &color);
+ void setForegroundColor (const kpColor &color);
+ void setBackgroundColor (const kpColor &color);
+
+signals:
+ // If you connect to this signal, ignore the following
+ // foregroundColorChanged() and backgroundColorChanged() signals
+ void colorsSwapped (const kpColor &newForegroundColor,
+ const kpColor &newBackgroundColor);
+
+ void foregroundColorChanged (const kpColor &color);
+ void backgroundColorChanged (const kpColor &color);
+
+public:
+ // (only valid in slots connected to foregroundColorChanged())
+ kpColor oldForegroundColor () const;
+ // (only valid in slots connected to backgroundColorChanged())
+ kpColor oldBackgroundColor () const;
+
+public:
+ virtual QSize sizeHint () const;
+
+protected:
+ QRect swapPixmapRect () const;
+ QRect foregroundBackgroundRect () const;
+ QRect foregroundRect () const;
+ QRect backgroundRect () const;
+
+ //virtual void dragEnterEvent (QDragEnterEvent *e);
+ virtual void dragMoveEvent (QDragMoveEvent *e);
+ virtual void dropEvent (QDropEvent *e);
+
+ virtual void mousePressEvent (QMouseEvent *e);
+ virtual void mouseDoubleClickEvent (QMouseEvent *e);
+ virtual void mouseReleaseEvent (QMouseEvent *e);
+
+ virtual void drawContents (QPainter *p);
+
+ kpMainWindow *m_mainWindow;
+ kpColor m_color [2];
+ kpColor m_oldColor [2];
+ QPixmap *m_backBuffer;
+};
+
+
+class kpColorCells : public KColorCells
+{
+Q_OBJECT
+
+public:
+ kpColorCells (QWidget *parent,
+ Qt::Orientation o = Qt::Horizontal,
+ const char *name = 0);
+ virtual ~kpColorCells ();
+
+ Qt::Orientation orientation () const;
+ void setOrientation (Qt::Orientation o);
+
+signals:
+ void foregroundColorChanged (const QColor &color);
+ void backgroundColorChanged (const QColor &color);
+
+ // lazy
+ void foregroundColorChanged (const kpColor &color);
+ void backgroundColorChanged (const kpColor &color);
+
+protected:
+ Qt::Orientation m_orientation;
+
+ virtual void dropEvent (QDropEvent *e);
+ virtual void paintCell (QPainter *painter, int row, int col);
+ virtual void mouseReleaseEvent (QMouseEvent *e);
+ virtual void resizeEvent (QResizeEvent *e);
+
+ int m_mouseButton;
+
+protected slots:
+ void slotColorSelected (int cell);
+ void slotColorDoubleClicked (int cell);
+};
+
+
+class kpTransparentColorCell : public QFrame
+{
+Q_OBJECT
+
+public:
+ kpTransparentColorCell (QWidget *parent, const char *name = 0);
+ virtual ~kpTransparentColorCell ();
+
+ virtual QSize sizeHint () const;
+
+signals:
+ void transparentColorSelected (int mouseButton);
+
+ // lazy
+ void foregroundColorChanged (const kpColor &color);
+ void backgroundColorChanged (const kpColor &color);
+
+protected:
+ virtual void mousePressEvent (QMouseEvent *e);
+ virtual void mouseReleaseEvent (QMouseEvent *e);
+
+ virtual void drawContents (QPainter *p);
+
+ QPixmap m_pixmap;
+};
+
+
+class kpColorPalette : public QWidget
+{
+Q_OBJECT
+
+public:
+ kpColorPalette (QWidget *parent,
+ Qt::Orientation o = Qt::Horizontal,
+ const char *name = 0);
+ virtual ~kpColorPalette ();
+
+ Qt::Orientation orientation () const;
+ void setOrientation (Qt::Orientation o);
+
+signals:
+ void foregroundColorChanged (const kpColor &color);
+ void backgroundColorChanged (const kpColor &color);
+
+protected:
+ Qt::Orientation m_orientation;
+
+ QBoxLayout *m_boxLayout;
+ kpTransparentColorCell *m_transparentColorCell;
+ kpColorCells *m_colorCells;
+};
+
+
+class kpColorSimilarityToolBarItem : public kpColorSimilarityCube
+{
+Q_OBJECT
+
+public:
+ kpColorSimilarityToolBarItem (kpMainWindow *mainWindow,
+ QWidget *parent,
+ const char *name = 0);
+ virtual ~kpColorSimilarityToolBarItem ();
+
+public:
+ int processedColorSimilarity () const;
+
+public slots:
+ void setColorSimilarity (double similarity);
+
+signals:
+ void colorSimilarityChanged (double similarity, int processedSimilarity);
+
+public:
+ // (only valid in slots connected to colorSimilarityChanged());
+ double oldColorSimilarity () const;
+
+private:
+ virtual void mousePressEvent (QMouseEvent *e);
+ virtual void mouseDoubleClickEvent (QMouseEvent *e);
+
+private:
+ kpMainWindow *m_mainWindow;
+
+ double m_oldColorSimilarity;
+ int m_processedColorSimilarity;
+};
+
+
+class kpColorToolBar : public KToolBar
+{
+Q_OBJECT
+
+public:
+ kpColorToolBar (const QString &label, kpMainWindow *mainWindow, const char *name = 0);
+ virtual ~kpColorToolBar ();
+
+ kpColor color (int which) const;
+ void setColor (int which, const kpColor &color);
+
+ kpColor foregroundColor () const;
+ kpColor backgroundColor () const;
+
+ double colorSimilarity () const;
+ void setColorSimilarity (double similarity);
+ int processedColorSimilarity () const;
+
+signals:
+ // If you connect to this signal, ignore the following
+ // foregroundColorChanged() and backgroundColorChanged() signals
+ void colorsSwapped (const kpColor &newForegroundColor,
+ const kpColor &newBackgroundColor);
+
+ void foregroundColorChanged (const kpColor &color);
+ void backgroundColorChanged (const kpColor &color);
+ void colorSimilarityChanged (double similarity, int processedSimilarity);
+
+public:
+ // (only valid in slots connected to foregroundColorChanged())
+ kpColor oldForegroundColor () const;
+ // (only valid in slots connected to backgroundColorChanged())
+ kpColor oldBackgroundColor () const;
+
+ // (only valid in slots connected to colorSimilarityChanged())
+ double oldColorSimilarity () const;
+
+public slots:
+ void setForegroundColor (const kpColor &color);
+ void setBackgroundColor (const kpColor &color);
+
+private:
+ kpMainWindow *m_mainWindow;
+
+ Qt::Orientation m_lastDockedOrientation;
+ bool m_lastDockedOrientationSet;
+ virtual void setOrientation (Qt::Orientation o);
+
+ QBoxLayout *m_boxLayout;
+ kpDualColorButton *m_dualColorButton;
+ kpColorPalette *m_colorPalette;
+ kpColorSimilarityToolBarItem *m_colorSimilarityToolBarItem;
+};
+
+#endif // __kp_color_toolbar_h__
diff --git a/kolourpaint/widgets/kpresizesignallinglabel.cpp b/kolourpaint/widgets/kpresizesignallinglabel.cpp
new file mode 100644
index 00000000..77d0ad2b
--- /dev/null
+++ b/kolourpaint/widgets/kpresizesignallinglabel.cpp
@@ -0,0 +1,67 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG_KP_RESIZE_SIGNALLING_LABEL 0
+
+
+#include <kpresizesignallinglabel.h>
+
+#include <kdebug.h>
+
+
+kpResizeSignallingLabel::kpResizeSignallingLabel (const QString &string,
+ QWidget *parent,
+ const char *name)
+ : QLabel (string, parent, name)
+{
+}
+
+kpResizeSignallingLabel::kpResizeSignallingLabel (QWidget *parent,
+ const char *name)
+ : QLabel (parent, name)
+{
+}
+
+kpResizeSignallingLabel::~kpResizeSignallingLabel ()
+{
+}
+
+
+// protected virtual [base QLabel]
+void kpResizeSignallingLabel::resizeEvent (QResizeEvent *e)
+{
+#if DEBUG_KP_RESIZE_SIGNALLING_LABEL
+ kdDebug () << "kpResizeSignallingLabel::resizeEvent() newSize=" << e->size ()
+ << " oldSize=" << e->oldSize () << endl;
+#endif
+ QLabel::resizeEvent (e);
+
+ emit resized ();
+}
+
+
+#include <kpresizesignallinglabel.moc>
diff --git a/kolourpaint/widgets/kpresizesignallinglabel.h b/kolourpaint/widgets/kpresizesignallinglabel.h
new file mode 100644
index 00000000..6cd3beba
--- /dev/null
+++ b/kolourpaint/widgets/kpresizesignallinglabel.h
@@ -0,0 +1,52 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef KP_RESIZE_SIGNALLING_LABEL
+#define KP_RESIZE_SIGNALLING_LABEL
+
+
+#include <qlabel.h>
+
+
+class kpResizeSignallingLabel : public QLabel
+{
+Q_OBJECT
+
+public:
+ kpResizeSignallingLabel (const QString &string, QWidget *parent, const char *name = 0);
+ kpResizeSignallingLabel (QWidget *parent, const char *name = 0);
+ virtual ~kpResizeSignallingLabel ();
+
+signals:
+ void resized ();
+
+protected:
+ virtual void resizeEvent (QResizeEvent *e);
+};
+
+
+#endif // KP_RESIZE_SIGNALLING_LABEL
diff --git a/kolourpaint/widgets/kpsqueezedtextlabel.cpp b/kolourpaint/widgets/kpsqueezedtextlabel.cpp
new file mode 100644
index 00000000..53fd85c9
--- /dev/null
+++ b/kolourpaint/widgets/kpsqueezedtextlabel.cpp
@@ -0,0 +1,215 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG_KP_SQUEEZED_TEXT_LABEL 0
+
+
+#include <kpsqueezedtextlabel.h>
+
+#include <qfont.h>
+#include <qfontmetrics.h>
+#include <qstring.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+
+kpSqueezedTextLabel::kpSqueezedTextLabel (QWidget *parent, const char *name)
+ : QLabel (parent, name),
+ m_showEllipsis (true)
+{
+}
+
+kpSqueezedTextLabel::kpSqueezedTextLabel (const QString &text, QWidget *parent, const char *name)
+ : QLabel (parent, name),
+ m_showEllipsis (true)
+{
+ setText (text);
+}
+
+
+// public virtual
+QSize kpSqueezedTextLabel::minimumSizeHint () const
+{
+#if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "kpSqueezedTextLabel::minimumSizeHint() qLabel prefers"
+ << QLabel::minimumSizeHint () << endl;
+#endif
+ return QSize (-1/*no minimum width*/, QLabel::minimumHeight ());
+}
+
+
+// public
+QString kpSqueezedTextLabel::fullText () const
+{
+ return m_fullText;
+}
+
+
+// public
+bool kpSqueezedTextLabel::showEllipsis () const
+{
+ return m_showEllipsis;
+}
+
+// public
+void kpSqueezedTextLabel::setShowEllipsis (bool yes)
+{
+ if (m_showEllipsis == yes)
+ return;
+
+ m_showEllipsis = yes;
+
+ squeezeText ();
+}
+
+
+// public slots virtual [base QLabel]
+void kpSqueezedTextLabel::setText (const QString &text)
+{
+ m_fullText = text;
+ squeezeText ();
+}
+
+
+// protected virtual [base QWidget]
+void kpSqueezedTextLabel::resizeEvent (QResizeEvent *e)
+{
+#if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "kpSqueezedTextLabeL::resizeEvent() size=" << e->size ()
+ << " oldSize=" << e->oldSize ()
+ << endl;
+#endif
+ squeezeText ();
+}
+
+
+// protected
+QString kpSqueezedTextLabel::ellipsisText () const
+{
+ return m_showEllipsis ? i18n ("...") : QString::null;
+}
+
+// protected
+void kpSqueezedTextLabel::squeezeText ()
+{
+#if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "kpSqueezedTextLabeL::squeezeText" << endl;
+#endif
+
+ QFontMetrics fontMetrics (font ());
+ int fullTextWidth = fontMetrics.width (m_fullText);
+#if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\tfullText=" << m_fullText
+ << " fullTextWidth=" << fullTextWidth
+ << " labelWidth=" << width ()
+ << endl;
+#endif
+
+ if (fullTextWidth <= width ())
+ {
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\tfullText will fit - display" << endl;
+ #endif
+ QLabel::setText (m_fullText);
+ }
+ else
+ {
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\tfullText won't fit :( - squeeze" << endl;
+ kdDebug () << "\t\twidth of \"...\"="
+ << fontMetrics.width (ellipsisText ())
+ << endl;
+
+ #endif
+ if (fontMetrics.width (ellipsisText ()) > width ())
+ {
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\t\t\tcan't even fit \"...\" - forget it" << endl;
+ #endif
+ QLabel::setText (QString::null);
+ return;
+ }
+
+ // Binary search our way to fit squeezed text
+ int numLettersToUseLo = 0;
+ int numLettersToUseHi = m_fullText.length ();
+ int numLettersToUse = 0;
+
+ while (numLettersToUseLo <= numLettersToUseHi)
+ {
+ int numLettersToUseMid = (numLettersToUseLo + numLettersToUseHi) / 2;
+ int squeezedWidth = fontMetrics.width (m_fullText.left (numLettersToUseMid) + ellipsisText ());
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\tbsearch: lo=" << numLettersToUseLo
+ << " hi=" << numLettersToUseHi
+ << " mid=" << numLettersToUseMid
+ << " acceptable=" << numLettersToUse
+ << " squeezedWidth=" << squeezedWidth
+ << endl;
+ #endif
+
+ if (squeezedWidth == width ())
+ {
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\t\tperfect match!" << endl;
+ #endif
+ numLettersToUse = numLettersToUseMid;
+ break;
+ }
+ else if (squeezedWidth < width ())
+ {
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\t\tsmall enough - numLettersToUse="
+ << numLettersToUse << endl;
+ #endif
+ if (numLettersToUseMid > numLettersToUse)
+ {
+ numLettersToUse = numLettersToUseMid;
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\t\t\tset numLettersToUse="
+ << numLettersToUse
+ << endl;
+ #endif
+ }
+
+ numLettersToUseLo = numLettersToUseMid + 1;
+ }
+ else
+ {
+ #if DEBUG_KP_SQUEEZED_TEXT_LABEL && 1
+ kdDebug () << "\t\ttoo big" << endl;
+ #endif
+ numLettersToUseHi = numLettersToUseMid - 1;
+ }
+ }
+
+ QLabel::setText (m_fullText.left (numLettersToUse) + ellipsisText ());
+ }
+}
+
+#include <kpsqueezedtextlabel.moc>
diff --git a/kolourpaint/widgets/kpsqueezedtextlabel.h b/kolourpaint/widgets/kpsqueezedtextlabel.h
new file mode 100644
index 00000000..57aa7b2f
--- /dev/null
+++ b/kolourpaint/widgets/kpsqueezedtextlabel.h
@@ -0,0 +1,65 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __kp_squeezed_text_label_h__
+#define __kp_squeezed_text_label_h__
+
+#include <qlabel.h>
+#include <qstring.h>
+
+
+// KSqueezedTextLabel done properly - squeeze at the end of the string,
+// not the middle.
+class kpSqueezedTextLabel : public QLabel
+{
+Q_OBJECT
+
+public:
+ kpSqueezedTextLabel (QWidget *parent, const char *name = 0);
+ kpSqueezedTextLabel (const QString &text, QWidget *parent, const char *name = 0);
+
+ virtual QSize minimumSizeHint () const;
+
+ // TODO: maybe text() should return the full text?
+ QString fullText () const;
+
+ bool showEllipsis () const;
+ void setShowEllipsis (bool yes = true);
+
+public slots:
+ virtual void setText (const QString &text);
+
+protected:
+ virtual void resizeEvent (QResizeEvent *);
+ QString ellipsisText () const;
+ void squeezeText ();
+
+ QString m_fullText;
+ bool m_showEllipsis;
+};
+
+#endif // __kp_squeezed_text_label_h__
diff --git a/kolourpaint/widgets/kptooltoolbar.cpp b/kolourpaint/widgets/kptooltoolbar.cpp
new file mode 100644
index 00000000..b8d1985c
--- /dev/null
+++ b/kolourpaint/widgets/kptooltoolbar.cpp
@@ -0,0 +1,640 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#define DEBUG_KP_TOOL_TOOL_BAR 0
+
+
+#include <kptooltoolbar.h>
+
+#include <qbuttongroup.h>
+#include <qlayout.h>
+#include <qdatetime.h>
+#include <qtoolbutton.h>
+#include <qtooltip.h>
+#include <qwidget.h>
+#include <qwhatsthis.h>
+
+#include <kconfig.h>
+#include <kdebug.h>
+#include <kglobalsettings.h>
+#include <kicontheme.h>
+
+#include <kpdefs.h>
+#include <kptool.h>
+#include <kptoolaction.h>
+#include <kptoolwidgetbrush.h>
+#include <kptoolwidgeterasersize.h>
+#include <kptoolwidgetfillstyle.h>
+#include <kptoolwidgetlinewidth.h>
+#include <kptoolwidgetopaqueortransparent.h>
+#include <kptoolwidgetspraycansize.h>
+
+
+class kpToolButton : public QToolButton
+{
+public:
+ kpToolButton (kpTool *tool, QWidget *parent)
+ : QToolButton (parent),
+ m_tool (tool)
+ {
+ }
+
+ virtual ~kpToolButton ()
+ {
+ }
+
+protected:
+ // virtual [base QWidget]
+ void mouseDoubleClickEvent (QMouseEvent *e)
+ {
+ if (e->button () == Qt::LeftButton && m_tool)
+ m_tool->globalDraw ();
+ }
+
+ kpTool *m_tool;
+};
+
+
+kpToolToolBar::kpToolToolBar (const QString &label, kpMainWindow *mainWindow, int colsOrRows, const char *name)
+ : KToolBar ((QWidget *) mainWindow, name, false/*don't use global toolBar settings*/, true/*readConfig*/),
+ m_vertCols (colsOrRows),
+ m_buttonGroup (0),
+ m_baseWidget (0),
+ m_baseLayout (0),
+ m_toolLayout (0),
+ m_previousTool (0), m_currentTool (0),
+ m_defaultIconSize (0)
+{
+ setText (label);
+
+
+ // With these lines enabled, mousePressEvent's weren't being generated
+ // when right clicking in empty part of the toolbar (each call affects
+ // the toolbar in its respective orientation). They don't seem to be
+ // needed anyway since !isResizeEnabled().
+
+ //setHorizontallyStretchable (false);
+ //setVerticallyStretchable (false);
+
+
+ m_baseWidget = new QWidget (this);
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ QTime timer;
+ timer.start ();
+#endif
+
+ m_toolWidgets.append (m_toolWidgetBrush =
+ new kpToolWidgetBrush (m_baseWidget, "Tool Widget Brush"));
+ m_toolWidgets.append (m_toolWidgetEraserSize =
+ new kpToolWidgetEraserSize (m_baseWidget, "Tool Widget Eraser Size"));
+ m_toolWidgets.append (m_toolWidgetFillStyle =
+ new kpToolWidgetFillStyle (m_baseWidget, "Tool Widget Fill Style"));
+ m_toolWidgets.append (m_toolWidgetLineWidth =
+ new kpToolWidgetLineWidth (m_baseWidget, "Tool Widget Line Width"));
+ m_toolWidgets.append (m_toolWidgetOpaqueOrTransparent =
+ new kpToolWidgetOpaqueOrTransparent (m_baseWidget, "Tool Widget Opaque/Transparent"));
+ m_toolWidgets.append (m_toolWidgetSpraycanSize =
+ new kpToolWidgetSpraycanSize (m_baseWidget, "Tool Widget Spraycan Size"));
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::<ctor> create tool widgets msec="
+ << timer.restart () << endl;
+#endif
+
+ for (QValueVector <kpToolWidgetBase *>::const_iterator it = m_toolWidgets.begin ();
+ it != m_toolWidgets.end ();
+ it++)
+ {
+ connect (*it, SIGNAL (optionSelected (int, int)),
+ this, SIGNAL (toolWidgetOptionSelected ()));
+ }
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::<ctor> connect widgets msec="
+ << timer.restart () << endl;
+#endif
+
+ m_lastDockedOrientationSet = false;
+ setOrientation (orientation ());
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::<ctor> layout tool widgets msec="
+ << timer.elapsed () << endl;
+#endif
+
+ m_buttonGroup = new QButtonGroup (); // invisible
+ m_buttonGroup->setExclusive (true);
+
+ connect (m_buttonGroup, SIGNAL (clicked (int)), SLOT (slotToolButtonClicked ()));
+
+ hideAllToolWidgets ();
+}
+
+kpToolToolBar::~kpToolToolBar ()
+{
+ unregisterAllTools ();
+ delete m_buttonGroup;
+}
+
+
+// private
+int kpToolToolBar::defaultIconSize ()
+{
+ // Cached?
+ if (m_defaultIconSize > 0)
+ return m_defaultIconSize;
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::defaultIconSize()" << endl;
+#endif
+
+
+ KConfigGroupSaver cfgGroupSaver (KGlobal::config (),
+ kpSettingsGroupTools);
+ KConfigBase *cfg = cfgGroupSaver.config ();
+
+ if (cfg->hasKey (kpSettingToolBoxIconSize))
+ {
+ m_defaultIconSize = cfg->readNumEntry (kpSettingToolBoxIconSize);
+ #if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\tread: " << m_defaultIconSize << endl;
+ #endif
+ }
+ else
+ {
+ m_defaultIconSize = -1;
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\tfirst time - writing default: " << m_defaultIconSize << endl;
+#endif
+ cfg->writeEntry (kpSettingToolBoxIconSize, m_defaultIconSize);
+ cfg->sync ();
+ }
+
+
+ if (m_defaultIconSize <= 0)
+ {
+ // Adapt according to screen geometry
+ const QRect desktopSize = KGlobalSettings::desktopGeometry (this);
+ #if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\tadapting to screen size=" << desktopSize << endl;
+ #endif
+
+ if (desktopSize.width () >= 1024 && desktopSize.height () >= 768)
+ m_defaultIconSize = KIcon::SizeSmallMedium/*22x22*/;
+ else
+ m_defaultIconSize = KIcon::SizeSmall/*16x16*/;
+ }
+
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\treturning " << m_defaultIconSize << endl;
+#endif
+ return m_defaultIconSize;
+}
+
+// public
+void kpToolToolBar::registerTool (kpTool *tool)
+{
+ for (QValueVector <kpButtonToolPair>::const_iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ if ((*it).m_tool == tool)
+ return;
+ }
+ int num = m_buttonToolPairs.count ();
+
+ QToolButton *b = new kpToolButton (tool, m_baseWidget);
+ b->setAutoRaise (true);
+ b->setUsesBigPixmap (false);
+ b->setUsesTextLabel (false);
+ b->setToggleButton (true);
+
+ b->setText (tool->text ());
+ b->setIconSet (tool->iconSet (defaultIconSize ()));
+ QToolTip::add (b, tool->toolTip ());
+ QWhatsThis::add (b, tool->description ());
+
+ m_buttonGroup->insert (b);
+ addButton (b, orientation (), num);
+
+ m_buttonToolPairs.append (kpButtonToolPair (b, tool));
+
+
+ connect (tool, SIGNAL (actionActivated ()),
+ this, SLOT (slotToolActionActivated ()));
+ connect (tool, SIGNAL (actionToolTipChanged (const QString &)),
+ this, SLOT (slotToolActionToolTipChanged ()));
+}
+
+// public
+void kpToolToolBar::unregisterTool (kpTool *tool)
+{
+ for (QValueVector <kpButtonToolPair>::iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ if ((*it).m_tool == tool)
+ {
+ delete ((*it).m_button);
+ m_buttonToolPairs.erase (it);
+
+ disconnect (tool, SIGNAL (actionActivated ()),
+ this, SLOT (slotToolActionActivated ()));
+ disconnect (tool, SIGNAL (actionToolTipChanged (const QString &)),
+ this, SLOT (slotToolActionToolTipChanged ()));
+ break;
+ }
+ }
+}
+
+// public
+void kpToolToolBar::unregisterAllTools ()
+{
+ for (QValueVector <kpButtonToolPair>::iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ delete ((*it).m_button);
+ }
+
+ m_buttonToolPairs.clear ();
+}
+
+
+// public
+kpTool *kpToolToolBar::tool () const
+{
+ return m_currentTool;
+}
+
+// public
+void kpToolToolBar::selectTool (const kpTool *tool, bool reselectIfSameTool)
+{
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::selectTool (tool=" << tool
+ << ") currentTool=" << m_currentTool
+ << endl;
+#endif
+
+ if (!reselectIfSameTool && tool == m_currentTool)
+ return;
+
+ if (tool)
+ {
+ for (QValueVector <kpButtonToolPair>::iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ if ((*it).m_tool == tool)
+ {
+ m_buttonGroup->setButton (m_buttonGroup->id ((*it).m_button));
+ slotToolButtonClicked ();
+ break;
+ }
+ }
+ }
+ else
+ {
+ QButton *b = m_buttonGroup->selected ();
+ #if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\twant to select no tool - button selected=" << b << endl;
+ #endif
+ if (b)
+ {
+ b->toggle ();
+ slotToolButtonClicked ();
+ }
+ }
+}
+
+
+// public
+kpTool *kpToolToolBar::previousTool () const
+{
+ return m_previousTool;
+}
+
+// public
+void kpToolToolBar::selectPreviousTool ()
+{
+ selectTool (m_previousTool);
+}
+
+
+// public
+void kpToolToolBar::hideAllToolWidgets ()
+{
+ for (QValueVector <kpToolWidgetBase *>::const_iterator it = m_toolWidgets.begin ();
+ it != m_toolWidgets.end ();
+ it++)
+ {
+ (*it)->hide ();
+ }
+}
+
+// public
+int kpToolToolBar::numShownToolWidgets () const
+{
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::numShownToolWidgets()" << endl;
+#endif
+
+ int ret = 0;
+
+ for (QValueVector <kpToolWidgetBase *>::const_iterator it = m_toolWidgets.begin ();
+ it != m_toolWidgets.end ();
+ it++)
+ {
+ #if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\t" << (*it)->name ()
+ << " isShown=" << (*it)->isShown ()
+ << endl;
+ #endif
+ if ((*it)->isShown ())
+ ret++;
+ }
+
+ return ret;
+}
+
+// public
+kpToolWidgetBase *kpToolToolBar::shownToolWidget (int which) const
+{
+ int uptoVisibleWidget = 0;
+
+ for (QValueVector <kpToolWidgetBase *>::const_iterator it = m_toolWidgets.begin ();
+ it != m_toolWidgets.end ();
+ it++)
+ {
+ if ((*it)->isShown ())
+ {
+ if (which == uptoVisibleWidget)
+ return *it;
+
+ uptoVisibleWidget++;
+ }
+ }
+
+ return 0;
+}
+
+
+// public
+bool kpToolToolBar::toolsSingleKeyTriggersEnabled () const
+{
+ for (QValueVector <kpButtonToolPair>::const_iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ if (!(*it).m_tool->singleKeyTriggersEnabled ())
+ return false;
+ }
+
+ return true;
+}
+
+// public
+void kpToolToolBar::enableToolsSingleKeyTriggers (bool enable)
+{
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::enableToolsSingleKeyTriggers(" << enable << ")" << endl;
+#endif
+
+ for (QValueVector <kpButtonToolPair>::const_iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ (*it).m_tool->enableSingleKeyTriggers (enable);
+ }
+}
+
+
+// private slot
+void kpToolToolBar::slotToolButtonClicked ()
+{
+ QButton *b = m_buttonGroup->selected ();
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::slotToolButtonClicked() button=" << b << endl;
+#endif
+
+ kpTool *tool = 0;
+ for (QValueVector <kpButtonToolPair>::iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ if ((*it).m_button == b)
+ {
+ tool = (*it).m_tool;
+ break;
+ }
+ }
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\ttool=" << tool
+ << " currentTool=" << m_currentTool
+ << endl;
+#endif
+
+ if (tool == m_currentTool)
+ {
+ if (m_currentTool)
+ m_currentTool->reselect ();
+
+ return;
+ }
+
+ if (m_currentTool)
+ m_currentTool->endInternal ();
+
+ m_previousTool = m_currentTool;
+ m_currentTool = tool;
+
+ if (m_currentTool)
+ {
+ kpToolAction *action = m_currentTool->action ();
+ if (action)
+ {
+ action->setChecked (true);
+ }
+
+ m_currentTool->beginInternal ();
+ }
+
+ emit sigToolSelected (m_currentTool);
+}
+
+
+#define CONST_KP_TOOL_SENDER() (dynamic_cast <const kpTool *> (sender ()))
+
+// private slot
+void kpToolToolBar::slotToolActionActivated ()
+{
+ const kpTool *tool = CONST_KP_TOOL_SENDER ();
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::slotToolActionActivated() tool="
+ << (tool ? tool->name () : "null")
+ << endl;
+#endif
+
+ if (m_currentTool)
+ {
+ // If the user clicks on the same KToggleAction, it unchecks it
+ // - this is inconsistent with the Tool Box so always make sure it's
+ // checked.
+ kpToolAction *action = m_currentTool->action ();
+ if (action)
+ {
+ action->setChecked (true);
+ }
+ }
+
+ selectTool (tool, true/*reselect if same tool*/);
+}
+
+// private slot
+void kpToolToolBar::slotToolActionToolTipChanged ()
+{
+ const kpTool *tool = CONST_KP_TOOL_SENDER ();
+
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::slotToolActionToolTipChanged() tool="
+ << (tool ? tool->name () : "null")
+ << endl;
+#endif
+
+ if (!tool)
+ return;
+
+ for (QValueVector <kpButtonToolPair>::const_iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ if (tool == (*it).m_tool)
+ {
+ QToolTip::add ((*it).m_button, tool->toolTip ());
+ return;
+ }
+ }
+}
+
+
+// public slot virtual [base QDockWindow]
+void kpToolToolBar::setOrientation (Qt::Orientation o)
+{
+#if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "kpToolToolBar::setOrientation("
+ << (o == Qt::Vertical ? "vertical" : "horizontal")
+ << ") called!" << endl;
+#endif
+
+ // (QDockWindow::undock() calls us)
+ bool isOutsideDock = (place () == QDockWindow::OutsideDock);
+
+ if (!m_lastDockedOrientationSet || !isOutsideDock)
+ {
+ m_lastDockedOrientation = o;
+ m_lastDockedOrientationSet = true;
+ }
+
+ if (isOutsideDock)
+ {
+ #if DEBUG_KP_TOOL_TOOL_BAR
+ kdDebug () << "\toutside dock, forcing orientation to last" << endl;
+ #endif
+ o = m_lastDockedOrientation;
+ }
+
+ delete m_toolLayout;
+ delete m_baseLayout;
+ if (o == Qt::Vertical)
+ {
+ m_baseLayout = new QBoxLayout (m_baseWidget, QBoxLayout::TopToBottom,
+ 5/*margin*/,
+ 10/*spacing*/);
+ m_toolLayout = new QGridLayout (m_baseLayout,
+ 5/*arbitrary rows since toolBar auto-expands*/,
+ m_vertCols,
+ 0/*margin*/,
+ 0/*spacing*/);
+ }
+ else // if (o == Qt::Horizontal)
+ {
+ m_baseLayout = new QBoxLayout (m_baseWidget, QBoxLayout::LeftToRight,
+ 5/*margin*/,
+ 10/*spacing*/);
+ m_toolLayout = new QGridLayout (m_baseLayout,
+ m_vertCols/*rows in this case, since horiz*/,
+ 5/*arbitrary cols since toolBar auto-expands*/,
+ 0/*margin*/,
+ 0/*spacing*/);
+ }
+
+ int num = 0;
+
+ for (QValueVector <kpButtonToolPair>::iterator it = m_buttonToolPairs.begin ();
+ it != m_buttonToolPairs.end ();
+ it++)
+ {
+ addButton ((*it).m_button, o, num);
+ num++;
+ }
+
+ for (QValueVector <kpToolWidgetBase *>::const_iterator it = m_toolWidgets.begin ();
+ it != m_toolWidgets.end ();
+ it++)
+ {
+ if (*it)
+ {
+ m_baseLayout->addWidget (*it,
+ 0/*stretch*/,
+ o == Qt::Vertical ? Qt::AlignHCenter : Qt::AlignVCenter);
+ }
+ }
+
+ KToolBar::setOrientation (o);
+}
+
+// private
+void kpToolToolBar::addButton (QButton *button, Qt::Orientation o, int num)
+{
+ if (o == Qt::Vertical)
+ m_toolLayout->addWidget (button, num / m_vertCols, num % m_vertCols);
+ else
+ {
+ // maps Left (o = vertical) to Bottom (o = horizontal)
+ int row = (m_vertCols - 1) - (num % m_vertCols);
+ m_toolLayout->addWidget (button, row, num / m_vertCols);
+ }
+}
+
+
+#include <kptooltoolbar.moc>
diff --git a/kolourpaint/widgets/kptooltoolbar.h b/kolourpaint/widgets/kptooltoolbar.h
new file mode 100644
index 00000000..c3a7d1b7
--- /dev/null
+++ b/kolourpaint/widgets/kptooltoolbar.h
@@ -0,0 +1,155 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kp_tool_tool_bar_h__
+#define __kp_tool_tool_bar_h__
+
+#include <qvaluevector.h>
+
+#include <ktoolbar.h>
+
+
+class QBoxLayout;
+class QButton;
+class QButtonGroup;
+class QWidget;
+class QGridLayout;
+
+class kpMainWindow;
+class kpTool;
+
+class kpToolWidgetBase;
+class kpToolWidgetBrush;
+class kpToolWidgetEraserSize;
+class kpToolWidgetFillStyle;
+class kpToolWidgetLineWidth;
+class kpToolWidgetOpaqueOrTransparent;
+class kpToolWidgetSpraycanSize;
+
+class kpToolToolBar : public KToolBar
+{
+Q_OBJECT
+
+public:
+ kpToolToolBar (const QString &label, kpMainWindow *mainWindow, int colsOrRows = 2, const char *name = 0);
+ virtual ~kpToolToolBar ();
+
+private:
+ int defaultIconSize ();
+public:
+ void registerTool (kpTool *tool);
+ void unregisterTool (kpTool *tool);
+ void unregisterAllTools ();
+
+ kpTool *tool () const;
+ void selectTool (const kpTool *tool, bool reselectIfSameTool = false);
+
+ kpTool *previousTool () const;
+ void selectPreviousTool ();
+
+ void hideAllToolWidgets ();
+ // could this be cleaner (the tools have to access them individually somehow)?
+ kpToolWidgetBrush *toolWidgetBrush () const { return m_toolWidgetBrush; }
+ kpToolWidgetEraserSize *toolWidgetEraserSize () const { return m_toolWidgetEraserSize; }
+ kpToolWidgetFillStyle *toolWidgetFillStyle () const { return m_toolWidgetFillStyle; }
+ kpToolWidgetLineWidth *toolWidgetLineWidth () const { return m_toolWidgetLineWidth; }
+ kpToolWidgetOpaqueOrTransparent *toolWidgetOpaqueOrTransparent () const { return m_toolWidgetOpaqueOrTransparent; }
+ kpToolWidgetSpraycanSize *toolWidgetSpraycanSize () const { return m_toolWidgetSpraycanSize; }
+
+public:
+ int numShownToolWidgets () const;
+ kpToolWidgetBase *shownToolWidget (int which) const;
+
+ bool toolsSingleKeyTriggersEnabled () const;
+ void enableToolsSingleKeyTriggers (bool enable);
+
+signals:
+ void sigToolSelected (kpTool *tool); // tool may be 0
+ void toolWidgetOptionSelected ();
+
+private slots:
+ void slotToolButtonClicked ();
+
+ void slotToolActionActivated ();
+ void slotToolActionToolTipChanged ();
+
+public slots:
+ virtual void setOrientation (Qt::Orientation o);
+
+private:
+ void addButton (QButton *button, Qt::Orientation o, int num);
+
+ Qt::Orientation m_lastDockedOrientation;
+ bool m_lastDockedOrientationSet;
+ int m_vertCols;
+
+ QButtonGroup *m_buttonGroup;
+ QWidget *m_baseWidget;
+ QBoxLayout *m_baseLayout;
+ QGridLayout *m_toolLayout;
+
+ kpToolWidgetBrush *m_toolWidgetBrush;
+ kpToolWidgetEraserSize *m_toolWidgetEraserSize;
+ kpToolWidgetFillStyle *m_toolWidgetFillStyle;
+ kpToolWidgetLineWidth *m_toolWidgetLineWidth;
+ kpToolWidgetOpaqueOrTransparent *m_toolWidgetOpaqueOrTransparent;
+ kpToolWidgetSpraycanSize *m_toolWidgetSpraycanSize;
+
+ QValueVector <kpToolWidgetBase *> m_toolWidgets;
+
+private:
+ struct kpButtonToolPair
+ {
+ kpButtonToolPair (QButton *button, kpTool *tool)
+ : m_button (button), m_tool (tool)
+ {
+ }
+
+ kpButtonToolPair ()
+ : m_button (0), m_tool (0)
+ {
+ }
+
+ QButton *m_button;
+ kpTool *m_tool;
+ };
+
+ QValueVector <kpButtonToolPair> m_buttonToolPairs;
+
+ kpTool *m_previousTool, *m_currentTool;
+
+ int m_defaultIconSize;
+
+private:
+ // There is no need to maintain binary compatibility at this stage.
+ // The d-pointer is just so that you can experiment without recompiling
+ // the kitchen sink.
+ class kpToolToolBarPrivate *d;
+};
+
+#endif // __kp_tool_tool_bar_h__
diff --git a/kolourpaint/widgets/kptoolwidgetbase.cpp b/kolourpaint/widgets/kptoolwidgetbase.cpp
new file mode 100644
index 00000000..a0042dbc
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetbase.cpp
@@ -0,0 +1,608 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#define DEBUG_KP_TOOL_WIDGET_BASE 0
+
+
+#include <kptoolwidgetbase.h>
+
+#include <qbitmap.h>
+#include <qcolor.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <kdebug.h>
+
+#include <kpdefs.h>
+#include <kpeffectinvert.h>
+
+
+kpToolWidgetBase::kpToolWidgetBase (QWidget *parent, const char *name)
+ : QFrame (parent, name),
+ m_invertSelectedPixmap (true),
+ m_selectedRow (-1), m_selectedCol (-1)
+{
+ if (!name)
+ kdError () << "kpToolWidgetBase::kpToolWidgetBase() without name" << endl;
+
+ setFrameStyle (QFrame::Panel | QFrame::Sunken);
+ setFixedSize (44, 66);
+}
+
+kpToolWidgetBase::~kpToolWidgetBase ()
+{
+}
+
+
+// public
+void kpToolWidgetBase::addOption (const QPixmap &pixmap, const QString &toolTip)
+{
+ if (m_pixmaps.isEmpty ())
+ startNewOptionRow ();
+
+ m_pixmaps.last ().append (pixmap);
+ m_pixmapRects.last ().append (QRect ());
+ m_toolTips.last ().append (toolTip);
+}
+
+// public
+void kpToolWidgetBase::startNewOptionRow ()
+{
+ m_pixmaps.resize (m_pixmaps.count () + 1);
+ m_pixmapRects.resize (m_pixmapRects.count () + 1);
+ m_toolTips.resize (m_toolTips.count () + 1);
+}
+
+// public
+void kpToolWidgetBase::finishConstruction (int fallBackRow, int fallBackCol)
+{
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "kpToolWidgetBase(" << name ()
+ << ")::kpToolWidgetBase(fallBack:row=" << fallBackRow
+ << ",col=" << fallBackCol
+ << ")"
+ << endl;
+#endif
+
+ relayoutOptions ();
+
+ const QPair <int, int> rowColPair = defaultSelectedRowAndCol ();
+ if (!setSelected (rowColPair.first, rowColPair.second, false/*don't save*/))
+ {
+ if (!setSelected (fallBackRow, fallBackCol))
+ {
+ if (!setSelected (0, 0))
+ {
+ kdError () << "kpToolWidgetBase::finishConstruction() "
+ "can't even fall back to setSelected(row=0,col=0)" << endl;
+ }
+ }
+ }
+}
+
+
+// private
+QValueVector <int> kpToolWidgetBase::spreadOutElements (const QValueVector <int> &sizes, int max)
+{
+ if (sizes.count () == 0)
+ return QValueVector <int> ();
+ else if (sizes.count () == 1)
+ return QValueVector <int> (1, sizes.first () > max ? 0 : 1/*margin*/);
+
+ QValueVector <int> retOffsets (sizes.count ());
+
+ int totalSize = 0;
+ for (int i = 0; i < (int) sizes.count (); i++)
+ totalSize += sizes [i];
+
+ int margin = 1;
+
+ // if don't fit with margin, then just return elements
+ // packed right next to each other
+ if (totalSize + margin * 2 > max)
+ {
+ retOffsets [0] = 0;
+ for (int i = 1; i < (int) sizes.count (); i++)
+ retOffsets [i] = retOffsets [i - 1] + sizes [i - 1];
+
+ return retOffsets;
+ }
+
+ int maxLeftOver = max - (totalSize + margin * 2);
+
+ int startCompensating = -1;
+ int numCompensate = 0;
+
+ int spacing = 0;
+
+ spacing = maxLeftOver / (sizes.count () - 1);
+ if (spacing * int (sizes.count () - 1) < maxLeftOver)
+ {
+ numCompensate = maxLeftOver - spacing * (sizes.count () - 1);
+ startCompensating = ((sizes.count () - 1) - numCompensate) / 2;
+ }
+
+ retOffsets [0] = margin;
+ for (int i = 1; i < (int) sizes.count (); i++)
+ {
+ retOffsets [i] += retOffsets [i - 1] +
+ sizes [i - 1] +
+ spacing +
+ ((numCompensate &&
+ i >= startCompensating &&
+ i < startCompensating + numCompensate) ? 1 : 0);
+ }
+
+ return retOffsets;
+}
+
+
+// public
+QPair <int, int> kpToolWidgetBase::defaultSelectedRowAndCol () const
+{
+ int row = -1, col = -1;
+
+ if (name ())
+ {
+ KConfigGroupSaver cfgGroupSaver (kapp->config (), kpSettingsGroupTools);
+ KConfigBase *cfg = cfgGroupSaver.config ();
+
+ QString nameString = QString::fromLatin1 (name ());
+
+ row = cfg->readNumEntry (nameString + QString::fromLatin1 (" Row"), -1);
+ col = cfg->readNumEntry (nameString + QString::fromLatin1 (" Col"), -1);
+ }
+
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "kpToolWidgetBase(" << name ()
+ << ")::defaultSelectedRowAndCol() returning row=" << row
+ << " col=" << col
+ << endl;
+#endif
+
+ return qMakePair (row, col);
+}
+
+// public
+int kpToolWidgetBase::defaultSelectedRow () const
+{
+ return defaultSelectedRowAndCol ().first;
+}
+
+// public
+int kpToolWidgetBase::defaultSelectedCol () const
+{
+ return defaultSelectedRowAndCol ().second;
+}
+
+// public
+void kpToolWidgetBase::saveSelectedAsDefault () const
+{
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "kpToolWidgetBase(" << name ()
+ << ")::saveSelectedAsDefault() row=" << m_selectedRow
+ << " col=" << m_selectedCol << endl;
+#endif
+
+ if (!name ())
+ return;
+
+ KConfigGroupSaver cfgGroupSaver (kapp->config (), kpSettingsGroupTools);
+ KConfigBase *cfg = cfgGroupSaver.config ();
+
+ QString nameString = QString::fromLatin1 (name ());
+ cfg->writeEntry (nameString + QString::fromLatin1 (" Row"), m_selectedRow);
+ cfg->writeEntry (nameString + QString::fromLatin1 (" Col"), m_selectedCol);
+ cfg->sync ();
+}
+
+
+// public
+void kpToolWidgetBase::relayoutOptions ()
+{
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "kpToolWidgetBase::relayoutOptions()" << endl;
+#endif
+
+ while (!m_pixmaps.isEmpty () && m_pixmaps.last ().count () == 0)
+ {
+ #if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\tkilling #" << m_pixmaps.count () - 1 << endl;
+ #endif
+ m_pixmaps.resize (m_pixmaps.count () - 1);
+ m_pixmapRects.resize (m_pixmapRects.count () - 1);
+ m_toolTips.resize (m_toolTips.count () - 1);
+ }
+
+ if (m_pixmaps.isEmpty ())
+ return;
+
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\tsurvived killing of empty rows" << endl;
+ kdDebug () << "\tfinding heights of rows:" << endl;
+#endif
+
+ QValueVector <int> maxHeightOfRow (m_pixmaps.count ());
+
+ for (int r = 0; r < (int) m_pixmaps.count (); r++)
+ {
+ for (int c = 0; c < (int) m_pixmaps [r].count (); c++)
+ {
+ if (c == 0 || m_pixmaps [r][c].height () > maxHeightOfRow [r])
+ maxHeightOfRow [r] = m_pixmaps [r][c].height ();
+ }
+ #if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\t\t" << r << ": " << maxHeightOfRow [r] << endl;
+ #endif
+ }
+
+ QValueVector <int> rowYOffset = spreadOutElements (maxHeightOfRow, height ());
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\tspread out offsets of rows:" << endl;
+ for (int r = 0; r < (int) rowYOffset.count (); r++)
+ kdDebug () << "\t\t" << r << ": " << rowYOffset [r] << endl;
+#endif
+
+ for (int r = 0; r < (int) m_pixmaps.count (); r++)
+ {
+ #if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\tlaying out row " << r << ":" << endl;
+ #endif
+
+ QValueVector <int> widths (m_pixmaps [r].count ());
+ for (int c = 0; c < (int) m_pixmaps [r].count (); c++)
+ widths [c] = m_pixmaps [r][c].width ();
+ #if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\t\twidths of cols:" << endl;
+ for (int c = 0; c < (int) m_pixmaps [r].count (); c++)
+ kdDebug () << "\t\t\t" << c << ": " << widths [c] << endl;
+ #endif
+
+ QValueVector <int> colXOffset = spreadOutElements (widths, width ());
+ #if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\t\tspread out offsets of cols:" << endl;
+ for (int c = 0; c < (int) colXOffset.count (); c++)
+ kdDebug () << "\t\t\t" << c << ": " << colXOffset [c] << endl;
+ #endif
+
+ for (int c = 0; c < (int) colXOffset.count (); c++)
+ {
+ int x = colXOffset [c];
+ int y = rowYOffset [r];
+ int w, h;
+
+ if (c == (int) colXOffset.count () - 1)
+ {
+ if (x + m_pixmaps [r][c].width () >= width ())
+ w = m_pixmaps [r][c].width ();
+ else
+ w = width () - 1 - x;
+ }
+ else
+ w = colXOffset [c + 1] - x;
+
+ if (r == (int) m_pixmaps.count () - 1)
+ {
+ if (y + m_pixmaps [r][c].height () >= height ())
+ h = m_pixmaps [r][c].height ();
+ else
+ h = height () - 1 - y;
+ }
+ else
+ h = rowYOffset [r + 1] - y;
+
+ m_pixmapRects [r][c] = QRect (x, y, w, h);
+
+ if (!m_toolTips [r][c].isEmpty ())
+ QToolTip::add (this, m_pixmapRects [r][c], m_toolTips [r][c]);
+ }
+ }
+
+ update ();
+}
+
+
+// public
+int kpToolWidgetBase::selectedRow () const
+{
+ return m_selectedRow;
+}
+
+// public
+int kpToolWidgetBase::selectedCol () const
+{
+ return m_selectedCol;
+}
+
+// public
+int kpToolWidgetBase::selected () const
+{
+ if (m_selectedRow < 0 ||
+ m_selectedRow >= (int) m_pixmaps.count () ||
+ m_selectedCol < 0)
+ {
+ return -1;
+ }
+
+ int upto = 0;
+ for (int y = 0; y < m_selectedRow; y++)
+ upto += m_pixmaps [y].count ();
+
+ if (m_selectedCol >= (int) m_pixmaps [m_selectedRow].count ())
+ return -1;
+
+ upto += m_selectedCol;
+
+ return upto;
+}
+
+
+// public
+bool kpToolWidgetBase::hasPreviousOption (int *row, int *col) const
+{
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "kpToolWidgetBase" << name ()
+ << "::hasPreviousOption() current row=" << m_selectedRow
+ << " col=" << m_selectedCol
+ << endl;
+#endif
+ if (row)
+ *row = -1;
+ if (col)
+ *col = -1;
+
+
+ if (m_selectedRow < 0 || m_selectedCol < 0)
+ return false;
+
+ int newRow = m_selectedRow,
+ newCol = m_selectedCol;
+
+ newCol--;
+ if (newCol < 0)
+ {
+ newRow--;
+ if (newRow < 0)
+ return false;
+
+ newCol = m_pixmaps [newRow].count () - 1;
+ if (newCol < 0)
+ return false;
+ }
+
+
+ if (row)
+ *row = newRow;
+ if (col)
+ *col = newCol;
+
+ return true;
+}
+
+// public
+bool kpToolWidgetBase::hasNextOption (int *row, int *col) const
+{
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "kpToolWidgetBase" << name ()
+ << "::hasNextOption() current row=" << m_selectedRow
+ << " col=" << m_selectedCol
+ << endl;
+#endif
+
+ if (row)
+ *row = -1;
+ if (col)
+ *col = -1;
+
+
+ if (m_selectedRow < 0 || m_selectedCol < 0)
+ return false;
+
+ int newRow = m_selectedRow,
+ newCol = m_selectedCol;
+
+ newCol++;
+ if (newCol >= (int) m_pixmaps [newRow].count ())
+ {
+ newRow++;
+ if (newRow >= (int) m_pixmaps.count ())
+ return false;
+
+ newCol = 0;
+ if (newCol >= (int) m_pixmaps [newRow].count ())
+ return false;
+ }
+
+
+ if (row)
+ *row = newRow;
+ if (col)
+ *col = newCol;
+
+ return true;
+}
+
+
+// public slot virtual
+bool kpToolWidgetBase::setSelected (int row, int col, bool saveAsDefault)
+{
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "kpToolWidgetBase::setSelected(row=" << row
+ << ",col=" << col
+ << ",saveAsDefault=" << saveAsDefault
+ << ")"
+ << endl;
+#endif
+
+ if (row < 0 || col < 0 ||
+ row >= (int) m_pixmapRects.count () || col >= (int) m_pixmapRects [row].count ())
+ {
+ #if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\tout of range" << endl;
+ #endif
+ return false;
+ }
+
+ if (row == m_selectedRow && col == m_selectedCol)
+ {
+ #if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\tNOP" << endl;
+ #endif
+
+ if (saveAsDefault)
+ saveSelectedAsDefault ();
+
+ return true;
+ }
+
+ const int wasSelectedRow = m_selectedRow;
+ const int wasSelectedCol = m_selectedCol;
+
+ m_selectedRow = row, m_selectedCol = col;
+
+ if (wasSelectedRow >= 0 && wasSelectedCol >= 0)
+ {
+ // unhighlight old option
+ update (m_pixmapRects [wasSelectedRow][wasSelectedCol]);
+ }
+
+ // highlight new option
+ update (m_pixmapRects [row][col]);
+
+#if DEBUG_KP_TOOL_WIDGET_BASE
+ kdDebug () << "\tOK" << endl;
+#endif
+
+ if (saveAsDefault)
+ saveSelectedAsDefault ();
+
+ emit optionSelected (row, col);
+ return true;
+}
+
+// public slot
+bool kpToolWidgetBase::setSelected (int row, int col)
+{
+ return setSelected (row, col, true/*set as default*/);
+}
+
+
+// public slot
+bool kpToolWidgetBase::selectPreviousOption ()
+{
+ int newRow, newCol;
+ if (!hasPreviousOption (&newRow, &newCol))
+ return false;
+
+ return setSelected (newRow, newCol);
+}
+
+// public slot
+bool kpToolWidgetBase::selectNextOption ()
+{
+ int newRow, newCol;
+ if (!hasNextOption (&newRow, &newCol))
+ return false;
+
+ return setSelected (newRow, newCol);
+}
+
+
+// protected virtual [base QWidget]
+void kpToolWidgetBase::mousePressEvent (QMouseEvent *e)
+{
+ e->ignore ();
+
+ if (e->button () != Qt::LeftButton)
+ return;
+
+
+ for (int i = 0; i < (int) m_pixmapRects.count (); i++)
+ {
+ for (int j = 0; j < (int) m_pixmapRects [i].count (); j++)
+ {
+ if (m_pixmapRects [i][j].contains (e->pos ()))
+ {
+ setSelected (i, j);
+ e->accept ();
+ return;
+ }
+ }
+ }
+}
+
+// protected virtual [base QFrame]
+void kpToolWidgetBase::drawContents (QPainter *painter)
+{
+#if DEBUG_KP_TOOL_WIDGET_BASE && 1
+ kdDebug () << "kpToolWidgetBase::drawContents(): rect=" << contentsRect () << endl;
+#endif
+
+ for (int i = 0; i < (int) m_pixmaps.count (); i++)
+ {
+ #if DEBUG_KP_TOOL_WIDGET_BASE && 1
+ kdDebug () << "\tRow: " << i << endl;
+ #endif
+
+ for (int j = 0; j < (int) m_pixmaps [i].count (); j++)
+ {
+ QRect rect = m_pixmapRects [i][j];
+ QPixmap pixmap = m_pixmaps [i][j];
+
+ #if DEBUG_KP_TOOL_WIDGET_BASE && 1
+ kdDebug () << "\t\tCol: " << j << " rect=" << rect << endl;
+ #endif
+
+ if (i == m_selectedRow && j == m_selectedCol)
+ {
+ painter->fillRect (rect, Qt::blue/*selection color*/);
+
+ if (m_invertSelectedPixmap)
+ kpEffectInvertCommand::apply (&pixmap);
+ }
+
+ #if DEBUG_KP_TOOL_WIDGET_BASE && 1
+ kdDebug () << "\t\t\tdraw pixmap @ x="
+ << rect.x () + (rect.width () - pixmap.width ()) / 2
+ << " y="
+ << rect.y () + (rect.height () - pixmap.height ()) / 2
+ << endl;
+
+ #endif
+
+ painter->drawPixmap (QPoint (rect.x () + (rect.width () - pixmap.width ()) / 2,
+ rect.y () + (rect.height () - pixmap.height ()) / 2),
+ pixmap);
+ }
+ }
+}
+
+#include <kptoolwidgetbase.moc>
diff --git a/kolourpaint/widgets/kptoolwidgetbase.h b/kolourpaint/widgets/kptoolwidgetbase.h
new file mode 100644
index 00000000..a23f9a16
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetbase.h
@@ -0,0 +1,112 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kp_tool_widget_base_h__
+#define __kp_tool_widget_base_h__
+
+#include <qframe.h>
+#include <qpair.h>
+#include <qpixmap.h>
+#include <qrect.h>
+#include <qvaluevector.h>
+#include <qwidget.h>
+
+
+class QPainter;
+
+
+// TODO: frame becomes a combobox when its parent kpToolToolBar becomes too small
+class kpToolWidgetBase : public QFrame
+{
+Q_OBJECT
+
+public:
+ kpToolWidgetBase (QWidget *parent, const char *name); // must provide a name for config to work
+ virtual ~kpToolWidgetBase ();
+
+public:
+ void addOption (const QPixmap &pixmap, const QString &toolTip = QString::null);
+ void startNewOptionRow ();
+
+ // Call this at the end of your constructor.
+ // If the default row & col could not be read from the config,
+ // <fallBackRow> & <fallBackCol> are passed to setSelected().
+ void finishConstruction (int fallBackRow, int fallBackCol);
+
+private:
+ QValueVector <int> spreadOutElements (const QValueVector <int> &sizes, int maxSize);
+
+public: // (only have to use these if you don't use finishConstruction())
+ // (rereads from config file)
+ QPair <int, int> defaultSelectedRowAndCol () const;
+ int defaultSelectedRow () const;
+ int defaultSelectedCol () const;
+
+ void saveSelectedAsDefault () const;
+
+ void relayoutOptions ();
+
+public:
+ int selectedRow () const;
+ int selectedCol () const;
+
+ int selected () const;
+
+ bool hasPreviousOption (int *row = 0, int *col = 0) const;
+ bool hasNextOption (int *row = 0, int *col = 0) const;
+
+public slots:
+ // (returns whether <row> and <col> were in range)
+ virtual bool setSelected (int row, int col, bool saveAsDefault);
+ bool setSelected (int row, int col);
+
+ bool selectPreviousOption ();
+ bool selectNextOption ();
+
+signals:
+ void optionSelected (int row, int col);
+
+protected:
+ virtual void mousePressEvent (QMouseEvent *e);
+ virtual void drawContents (QPainter *painter);
+
+ void setInvertSelectedPixmap (bool yes = true) { m_invertSelectedPixmap = yes; }
+ bool m_invertSelectedPixmap;
+
+ // coulbe be a QFrame or a ComboBox
+ QWidget *m_baseWidget;
+
+ QValueVector < QValueVector <QPixmap> > m_pixmaps;
+ QValueVector < QValueVector <QString> > m_toolTips;
+
+ QValueVector < QValueVector <QRect> > m_pixmapRects;
+
+ int m_selectedRow, m_selectedCol;
+};
+
+#endif // __kp_tool_widget_base_h__
diff --git a/kolourpaint/widgets/kptoolwidgetbrush.cpp b/kolourpaint/widgets/kptoolwidgetbrush.cpp
new file mode 100644
index 00000000..046dc8b5
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetbrush.cpp
@@ -0,0 +1,184 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#define DEBUG_KP_TOOL_WIDGET_BRUSH 0
+
+
+#include <kptoolwidgetbrush.h>
+
+#include <qbitmap.h>
+#include <qpainter.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kpdefs.h>
+
+
+/* sync: <brushes> */
+static int brushSize [][3] =
+{
+ {8, 4, 1/*like Pen*/},
+ {9, 5, 2},
+ {9, 5, 2},
+ {9, 5, 2}
+};
+
+#define BRUSH_SIZE_NUM_COLS (int (sizeof (brushSize [0]) / sizeof (brushSize [0][0])))
+#define BRUSH_SIZE_NUM_ROWS (int (sizeof (brushSize) / sizeof (brushSize [0])))
+
+kpToolWidgetBrush::kpToolWidgetBrush (QWidget *parent, const char *name)
+ : kpToolWidgetBase (parent, name)
+{
+ setInvertSelectedPixmap ();
+
+ QPixmap *pm = m_brushBitmaps;
+
+ for (int shape = 0; shape < BRUSH_SIZE_NUM_ROWS; shape++)
+ {
+ for (int i = 0; i < BRUSH_SIZE_NUM_COLS; i++)
+ {
+ int w = (width () - 2/*margin*/ - 2/*spacing*/) / BRUSH_SIZE_NUM_COLS;
+ int h = (height () - 2/*margin*/ - 3/*spacing*/) / BRUSH_SIZE_NUM_ROWS;
+ pm->resize ((w <= 0 ? width () : w),
+ (h <= 0 ? height () : h));
+
+ const int s = brushSize [shape][i];
+ QRect rect;
+
+ if (s >= pm->width () || s >= pm->height ())
+ rect = QRect (0, 0, pm->width (), pm->height ());
+ else
+ {
+ rect = QRect ((pm->width () - s) / 2,
+ (pm->height () - s) / 2,
+ s,
+ s);
+ }
+
+ #if DEBUG_KP_TOOL_WIDGET_BRUSH
+ kdDebug () << "kpToolWidgetBrush::kpToolWidgetBrush() rect=" << rect << endl;
+ #endif
+
+ pm->fill (Qt::white);
+
+ QPainter painter (pm);
+ painter.setPen (Qt::black);
+ painter.setBrush (Qt::black);
+
+ // sync: <brushes>
+ switch (shape)
+ {
+ case 0:
+ painter.drawEllipse (rect);
+ break;
+ case 1:
+ painter.drawRect (rect);
+ break;
+ case 2:
+ painter.drawLine (rect.topRight (), rect.bottomLeft ());
+ break;
+ case 3:
+ painter.drawLine (rect.topLeft (), rect.bottomRight ());
+ break;
+ }
+ painter.end ();
+
+ pm->setMask (pm->createHeuristicMask ());
+ addOption (*pm, brushName (shape, i)/*tooltip*/);
+
+ pm++;
+ }
+
+ startNewOptionRow ();
+ }
+
+ finishConstruction (0, 0);
+}
+
+kpToolWidgetBrush::~kpToolWidgetBrush ()
+{
+}
+
+
+// private
+QString kpToolWidgetBrush::brushName (int shape, int whichSize)
+{
+ int s = brushSize [shape][whichSize];
+
+ if (s == 1)
+ return i18n ("1x1");
+
+ QString shapeName;
+
+ // sync: <brushes>
+ switch (shape)
+ {
+ case 0:
+ shapeName = i18n ("Circle");
+ break;
+ case 1:
+ shapeName = i18n ("Square");
+ break;
+ case 2:
+ // TODO: is this really the name of a shape? :)
+ shapeName = i18n ("Slash");
+ break;
+ case 3:
+ // TODO: is this really the name of a shape? :)
+ shapeName = i18n ("Backslash");
+ break;
+ }
+
+ if (shapeName.isEmpty ())
+ return QString::null;
+
+ return i18n ("%1x%2 %3").arg (s).arg (s).arg (shapeName);
+}
+
+QPixmap kpToolWidgetBrush::brush () const
+{
+ return m_brushBitmaps [selectedRow () * BRUSH_SIZE_NUM_COLS + selectedCol ()];
+}
+
+bool kpToolWidgetBrush::brushIsDiagonalLine () const
+{
+ // sync: <brushes>
+ return (selectedRow () >= 2);
+}
+
+// virtual protected slot [base kpToolWidgetBase]
+bool kpToolWidgetBrush::setSelected (int row, int col, bool saveAsDefault)
+{
+ const bool ret = kpToolWidgetBase::setSelected (row, col, saveAsDefault);
+ if (ret)
+ emit brushChanged (brush (), brushIsDiagonalLine ());
+ return ret;
+}
+
+#include <kptoolwidgetbrush.moc>
diff --git a/kolourpaint/widgets/kptoolwidgetbrush.h b/kolourpaint/widgets/kptoolwidgetbrush.h
new file mode 100644
index 00000000..db222e79
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetbrush.h
@@ -0,0 +1,61 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kptoolwidgetbrush_h__
+#define __kptoolwidgetbrush_h__
+
+#include <qpixmap.h>
+
+#include <kptoolwidgetbase.h>
+
+class kpToolWidgetBrush : public kpToolWidgetBase
+{
+Q_OBJECT
+
+public:
+ kpToolWidgetBrush (QWidget *parent, const char *name);
+ virtual ~kpToolWidgetBrush ();
+
+private:
+ QString brushName (int shape, int whichSize);
+
+public:
+ QPixmap brush () const;
+ bool brushIsDiagonalLine () const;
+
+signals:
+ void brushChanged (const QPixmap &pixmap, bool isDiagonalLine);
+
+protected slots:
+ virtual bool setSelected (int row, int col, bool saveAsDefault);
+
+private:
+ QPixmap m_brushBitmaps [16];
+};
+
+#endif // __kptoolwidgetbrush_h__
diff --git a/kolourpaint/widgets/kptoolwidgeterasersize.cpp b/kolourpaint/widgets/kptoolwidgeterasersize.cpp
new file mode 100644
index 00000000..cc58c0d1
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgeterasersize.cpp
@@ -0,0 +1,161 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG_KP_TOOL_WIDGET_ERASER_SIZE 0
+
+
+#include <kptoolwidgeterasersize.h>
+
+#include <qbitmap.h>
+#include <qpainter.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kpcolor.h>
+#include <kptool.h>
+
+
+static int eraserSizes [] = {2, 3, 5, 9, 17, 29};
+static const int numEraserSizes = int (sizeof (eraserSizes) / sizeof (eraserSizes [0]));
+
+
+kpToolWidgetEraserSize::kpToolWidgetEraserSize (QWidget *parent, const char *name)
+ : kpToolWidgetBase (parent, name)
+{
+ setInvertSelectedPixmap ();
+
+ m_cursorPixmaps = new QPixmap [numEraserSizes];
+ QPixmap *cursorPixmap = m_cursorPixmaps;
+
+ for (int i = 0; i < numEraserSizes; i++)
+ {
+ if (i == 3 || i == 5)
+ startNewOptionRow ();
+
+ int s = eraserSizes [i];
+
+ cursorPixmap->resize (s, s);
+ cursorPixmap->fill (Qt::black);
+
+
+ QPixmap previewPixmap (s, s);
+ if (i < 3)
+ {
+ // HACK: kpToolWidgetBase's layout code sucks and gives uneven spacing
+ previewPixmap.resize ((width () - 4) / 3, 9);
+ }
+
+ QPainter painter (&previewPixmap);
+ QRect rect ((previewPixmap.width () - s) / 2, (previewPixmap.height () - s) / 2, s, s);
+ painter.fillRect (rect, Qt::black);
+ painter.end ();
+
+ QBitmap mask (previewPixmap.width (), previewPixmap.height ());
+ mask.fill (Qt::color0/*transparent*/);
+
+ QPainter maskPainter (&mask);
+ maskPainter.fillRect (rect, Qt::color1/*opaque*/);
+ maskPainter.end ();
+
+ previewPixmap.setMask (mask);
+
+
+ addOption (previewPixmap, i18n ("%1x%2").arg (s).arg (s)/*tooltip*/);
+
+
+ cursorPixmap++;
+ }
+
+ finishConstruction (1, 0);
+}
+
+kpToolWidgetEraserSize::~kpToolWidgetEraserSize ()
+{
+ delete [] m_cursorPixmaps;
+}
+
+int kpToolWidgetEraserSize::eraserSize () const
+{
+ return eraserSizes [selected ()];
+}
+
+QPixmap kpToolWidgetEraserSize::cursorPixmap (const kpColor &color) const
+{
+#if DEBUG_KP_TOOL_WIDGET_ERASER_SIZE
+ kdDebug () << "kpToolWidgetEraseSize::cursorPixmap() selected=" << selected ()
+ << " numEraserSizes=" << numEraserSizes
+ << endl;
+#endif
+
+ // TODO: why are we even storing m_cursorPixmaps?
+ QPixmap pixmap = m_cursorPixmaps [selected ()];
+ if (color.isOpaque ())
+ pixmap.fill (color.toQColor ());
+
+
+ bool showBorder = (pixmap.width () > 2 && pixmap.height () > 2);
+
+ if (showBorder)
+ {
+ QPainter painter (&pixmap);
+ painter.setPen (Qt::black);
+ painter.drawRect (pixmap.rect ());
+ }
+
+
+ if (color.isTransparent ())
+ {
+ QBitmap maskBitmap (pixmap.width (), pixmap.height ());
+ maskBitmap.fill (Qt::color0/*transparent*/);
+
+
+ if (showBorder)
+ {
+ QPainter maskBitmapPainter (&maskBitmap);
+ maskBitmapPainter.setPen (Qt::color1/*opaque*/);
+ maskBitmapPainter.drawRect (maskBitmap.rect ());
+ }
+
+
+ pixmap.setMask (maskBitmap);
+ }
+
+
+ return pixmap;
+}
+
+// virtual protected slot [base kpToolWidgetBase]
+bool kpToolWidgetEraserSize::setSelected (int row, int col, bool saveAsDefault)
+{
+ const bool ret = kpToolWidgetBase::setSelected (row, col, saveAsDefault);
+ if (ret)
+ emit eraserSizeChanged (eraserSize ());
+ return ret;
+}
+
+#include <kptoolwidgeterasersize.moc>
diff --git a/kolourpaint/widgets/kptoolwidgeterasersize.h b/kolourpaint/widgets/kptoolwidgeterasersize.h
new file mode 100644
index 00000000..71093fd6
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgeterasersize.h
@@ -0,0 +1,59 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kptoolwidgeterasersize_h__
+#define __kptoolwidgeterasersize_h__
+
+#include <qpixmap.h>
+#include <kptoolwidgetbase.h>
+
+
+class kpColor;
+
+class kpToolWidgetEraserSize : public kpToolWidgetBase
+{
+Q_OBJECT
+
+public:
+ kpToolWidgetEraserSize (QWidget *parent, const char *name);
+ virtual ~kpToolWidgetEraserSize ();
+
+ int eraserSize () const;
+ QPixmap cursorPixmap (const kpColor &color) const;
+
+signals:
+ void eraserSizeChanged (int size);
+
+protected slots:
+ virtual bool setSelected (int row, int col, bool saveAsDefault);
+
+private:
+ QPixmap *m_cursorPixmaps;
+};
+
+#endif // __kptoolwidgeterasersize_h__
diff --git a/kolourpaint/widgets/kptoolwidgetfillstyle.cpp b/kolourpaint/widgets/kptoolwidgetfillstyle.cpp
new file mode 100644
index 00000000..74c174ce
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetfillstyle.cpp
@@ -0,0 +1,222 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG_KP_TOOL_WIDGET_FILL_STYLE 0
+
+
+#include <kptoolwidgetfillstyle.h>
+
+#include <qbitmap.h>
+#include <qbrush.h>
+#include <qpainter.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <kpcolor.h>
+#include <kpdefs.h>
+#include <kptool.h>
+
+
+kpToolWidgetFillStyle::kpToolWidgetFillStyle (QWidget *parent, const char *name)
+ : kpToolWidgetBase (parent, name)
+{
+ setInvertSelectedPixmap ();
+
+ for (int i = 0; i < (int) FillStyleNum; i++)
+ {
+ QPixmap pixmap;
+
+ pixmap = fillStylePixmap ((FillStyle) i,
+ (width () - 2/*margin*/) * 3 / 4,
+ (height () - 2/*margin*/ - 2/*spacing*/) * 3 / (3 * 4));
+ addOption (pixmap, fillStyleName ((FillStyle) i)/*tooltip*/);
+
+ startNewOptionRow ();
+ }
+
+ finishConstruction (0, 0);
+}
+
+kpToolWidgetFillStyle::~kpToolWidgetFillStyle ()
+{
+}
+
+
+// private
+QPixmap kpToolWidgetFillStyle::fillStylePixmap (FillStyle fs, int w, int h)
+{
+ QPixmap pixmap ((w <= 0 ? width () : w), (h <= 0 ? height () : h));
+ pixmap.fill (Qt::white);
+
+ QPainter painter (&pixmap);
+
+ painter.setPen (QPen (Qt::black, 2));
+ painter.setBrush (brushForFillStyle (fs,
+ kpColor (Qt::black.rgb ())/*foreground*/,
+ kpColor (Qt::gray.rgb ())/*background*/));
+
+ painter.drawRect (2, 2, w - 3, h - 3);
+
+ painter.end ();
+
+
+ QBitmap mask (pixmap.width (), pixmap.height ());
+ mask.fill (Qt::color0);
+
+ painter.begin (&mask);
+ painter.setPen (QPen (Qt::color1, 2));
+
+ if (fs == FillWithBackground || fs == FillWithForeground)
+ painter.setBrush (Qt::color1);
+
+ painter.drawRect (2, 2, w - 3, h - 3);
+
+ painter.end ();
+
+ pixmap.setMask (mask);
+
+ return pixmap;
+}
+
+// private
+QString kpToolWidgetFillStyle::fillStyleName (FillStyle fs) const
+{
+ // do not complain about the "useless" breaks
+ // as the return statements might not be return statements one day
+
+ switch (fs)
+ {
+ case NoFill:
+ return i18n ("No Fill");
+ break;
+ case FillWithBackground:
+ return i18n ("Fill with Background Color");
+ break;
+ case FillWithForeground:
+ return i18n ("Fill with Foreground Color");
+ break;
+ default:
+ return QString::null;
+ break;
+ }
+}
+
+
+// public
+kpToolWidgetFillStyle::FillStyle kpToolWidgetFillStyle::fillStyle () const
+{
+#if DEBUG_KP_TOOL_WIDGET_FILL_STYLE
+ kdDebug () << "kpToolWidgetFillStyle::fillStyle() selected="
+ << selectedRow ()
+ << endl;
+#endif
+ return (FillStyle) selectedRow ();
+}
+
+// public static
+QBrush kpToolWidgetFillStyle::maskBrushForFillStyle (FillStyle fs,
+ const kpColor &foregroundColor,
+ const kpColor &backgroundColor)
+{
+ // do not complain about the "useless" breaks
+ // as the return statements might not be return statements one day
+
+ switch (fs)
+ {
+ case NoFill:
+ return Qt::NoBrush;
+ break;
+ case FillWithBackground:
+ return QBrush (backgroundColor.maskColor ());
+ break;
+ case FillWithForeground:
+ return QBrush (foregroundColor.maskColor ());
+ break;
+ default:
+ return Qt::NoBrush;
+ break;
+ }
+}
+
+QBrush kpToolWidgetFillStyle::maskBrush (const kpColor &foregroundColor,
+ const kpColor &backgroundColor)
+{
+ return maskBrushForFillStyle (fillStyle (), foregroundColor, backgroundColor);
+}
+
+// public static
+QBrush kpToolWidgetFillStyle::brushForFillStyle (FillStyle fs,
+ const kpColor &foregroundColor,
+ const kpColor &backgroundColor)
+{
+ // do not complain about the "useless" breaks
+ // as the return statements might not be return statements one day
+
+ // sync: kptoolpolygon.cpp pixmap()
+
+ switch (fs)
+ {
+ case NoFill:
+ return Qt::NoBrush;
+ break;
+ case FillWithBackground:
+ if (backgroundColor.isOpaque ())
+ return QBrush (backgroundColor.toQColor ());
+ else
+ return Qt::NoBrush;
+ break;
+ case FillWithForeground:
+ if (foregroundColor.isOpaque ())
+ return QBrush (foregroundColor.toQColor ());
+ else
+ return Qt::NoBrush;
+ break;
+ default:
+ return Qt::NoBrush;
+ break;
+ }
+}
+
+// public
+QBrush kpToolWidgetFillStyle::brush (const kpColor &foregroundColor,
+ const kpColor &backgroundColor)
+{
+ return brushForFillStyle (fillStyle (), foregroundColor, backgroundColor);
+}
+
+
+// virtual protected slot [base kpToolWidgetBase]
+bool kpToolWidgetFillStyle::setSelected (int row, int col, bool saveAsDefault)
+{
+ const bool ret = kpToolWidgetBase::setSelected (row, col, saveAsDefault);
+ if (ret)
+ emit fillStyleChanged (fillStyle ());
+ return ret;
+}
+
+#include <kptoolwidgetfillstyle.moc>
diff --git a/kolourpaint/widgets/kptoolwidgetfillstyle.h b/kolourpaint/widgets/kptoolwidgetfillstyle.h
new file mode 100644
index 00000000..219d47f2
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetfillstyle.h
@@ -0,0 +1,80 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kptoolwidgetfillstyle_h__
+#define __kptoolwidgetfillstyle_h__
+
+#include <kptoolwidgetbase.h>
+
+class QBrush;
+
+class kpColor;
+
+class kpToolWidgetFillStyle : public kpToolWidgetBase
+{
+Q_OBJECT
+
+public:
+ kpToolWidgetFillStyle (QWidget *parent, const char *name);
+ virtual ~kpToolWidgetFillStyle ();
+
+ enum FillStyle
+ {
+ NoFill,
+ FillWithBackground,
+ FillWithForeground,
+ FillStyleNum /* not (a valid FillStyle) */
+ };
+
+private:
+ QPixmap fillStylePixmap (FillStyle fs, int width, int height);
+ QString fillStyleName (FillStyle fs) const;
+
+public:
+ FillStyle fillStyle () const;
+
+ static QBrush maskBrushForFillStyle (FillStyle fs,
+ const kpColor &foregroundColor,
+ const kpColor &backgroundColor);
+ QBrush maskBrush (const kpColor &foregroundColor,
+ const kpColor &backgroundColor);
+
+ static QBrush brushForFillStyle (FillStyle fs,
+ const kpColor &foregroundColor,
+ const kpColor &backgroundColor);
+ QBrush brush (const kpColor &foregroundColor,
+ const kpColor &backgroundColor);
+
+signals:
+ void fillStyleChanged (kpToolWidgetFillStyle::FillStyle fillStyle);
+
+protected slots:
+ virtual bool setSelected (int row, int col, bool saveAsDefault);
+};
+
+#endif // __kptoolwidgetfillstyle_h__
diff --git a/kolourpaint/widgets/kptoolwidgetlinewidth.cpp b/kolourpaint/widgets/kptoolwidgetlinewidth.cpp
new file mode 100644
index 00000000..27e34ecb
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetlinewidth.cpp
@@ -0,0 +1,97 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include <kptoolwidgetlinewidth.h>
+
+#include <qbitmap.h>
+#include <qpainter.h>
+
+#include <klocale.h>
+
+
+static int lineWidths [] = {1, 2, 3, 5, 8};
+
+kpToolWidgetLineWidth::kpToolWidgetLineWidth (QWidget *parent, const char *name)
+ : kpToolWidgetBase (parent, name)
+{
+ setInvertSelectedPixmap ();
+
+ int numLineWidths = sizeof (lineWidths) / sizeof (lineWidths [0]);
+
+ int w = (width () - 2/*margin*/) * 3 / 4;
+ int h = (height () - 2/*margin*/ - (numLineWidths - 1)/*spacing*/) * 3 / (numLineWidths * 4);
+
+ for (int i = 0; i < numLineWidths; i++)
+ {
+ QPixmap pixmap ((w <= 0 ? width () : w),
+ (h <= 0 ? height () : h));
+ pixmap.fill (Qt::white);
+
+ QBitmap maskBitmap (pixmap.width (), pixmap.height ());
+ maskBitmap.fill (Qt::color0/*transparent*/);
+
+
+ QPainter painter (&pixmap), maskPainter (&maskBitmap);
+ painter.setPen (Qt::black), maskPainter.setPen (Qt::color1/*opaque*/);
+ painter.setBrush (Qt::black), maskPainter.setBrush (Qt::color1/*opaque*/);
+
+ QRect rect = QRect (0, (pixmap.height () - lineWidths [i]) / 2,
+ pixmap.width (), lineWidths [i]);
+ painter.drawRect (rect), maskPainter.drawRect (rect);
+
+ painter.end (), maskPainter.end ();
+
+
+ pixmap.setMask (maskBitmap);
+
+ addOption (pixmap, QString::number (lineWidths [i]));
+ startNewOptionRow ();
+ }
+
+ finishConstruction (0, 0);
+}
+
+kpToolWidgetLineWidth::~kpToolWidgetLineWidth ()
+{
+}
+
+int kpToolWidgetLineWidth::lineWidth () const
+{
+ return lineWidths [selectedRow ()];
+}
+
+// virtual protected slot [base kpToolWidgetBase]
+bool kpToolWidgetLineWidth::setSelected (int row, int col, bool saveAsDefault)
+{
+ const bool ret = kpToolWidgetBase::setSelected (row, col, saveAsDefault);
+ if (ret)
+ emit lineWidthChanged (lineWidth ());
+ return ret;
+}
+
+#include <kptoolwidgetlinewidth.moc>
diff --git a/kolourpaint/widgets/kptoolwidgetlinewidth.h b/kolourpaint/widgets/kptoolwidgetlinewidth.h
new file mode 100644
index 00000000..3255e443
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetlinewidth.h
@@ -0,0 +1,51 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kptoolwidgetlinewidth_h__
+#define __kptoolwidgetlinewidth_h__
+
+#include <kptoolwidgetbase.h>
+
+class kpToolWidgetLineWidth : public kpToolWidgetBase
+{
+Q_OBJECT
+
+public:
+ kpToolWidgetLineWidth (QWidget *parent, const char *name);
+ virtual ~kpToolWidgetLineWidth ();
+
+ int lineWidth () const;
+
+signals:
+ void lineWidthChanged (int width);
+
+protected slots:
+ virtual bool setSelected (int row, int col, bool saveAsDefault);
+};
+
+#endif // __kptoolwidgetlinewidth_h__
diff --git a/kolourpaint/widgets/kptoolwidgetopaqueortransparent.cpp b/kolourpaint/widgets/kptoolwidgetopaqueortransparent.cpp
new file mode 100644
index 00000000..41b55d0f
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetopaqueortransparent.cpp
@@ -0,0 +1,100 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define DEBUG_KP_TOOL_WIDGET_OPAQUE_OR_TRANSPARENT 0
+
+
+#include <kptoolwidgetopaqueortransparent.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+
+kpToolWidgetOpaqueOrTransparent::kpToolWidgetOpaqueOrTransparent (QWidget *parent, const char *name)
+ : kpToolWidgetBase (parent, name)
+{
+ setInvertSelectedPixmap (false);
+
+ addOption (UserIcon ("option_opaque"), i18n ("Opaque")/*tooltip*/);
+ startNewOptionRow ();
+ addOption (UserIcon ("option_transparent"), i18n ("Transparent")/*tooltip*/);
+
+ finishConstruction (0, 0);
+}
+
+kpToolWidgetOpaqueOrTransparent::~kpToolWidgetOpaqueOrTransparent ()
+{
+}
+
+
+// public
+bool kpToolWidgetOpaqueOrTransparent::isOpaque () const
+{
+ return (selected () == 0);
+}
+
+// public
+bool kpToolWidgetOpaqueOrTransparent::isTransparent () const
+{
+ return (!isOpaque ());
+}
+
+// public
+void kpToolWidgetOpaqueOrTransparent::setOpaque (bool yes)
+{
+#if DEBUG_KP_TOOL_WIDGET_OPAQUE_OR_TRANSPARENT && 1
+ kdDebug () << "kpToolWidgetOpaqueOrTransparent::setOpaque(" << yes << ")" << endl;
+#endif
+ setSelected (yes ? 0 : 1, 0, false/*don't save*/);
+}
+
+// public
+void kpToolWidgetOpaqueOrTransparent::setTransparent (bool yes)
+{
+#if DEBUG_KP_TOOL_WIDGET_OPAQUE_OR_TRANSPARENT && 1
+ kdDebug () << "kpToolWidgetOpaqueOrTransparent::setTransparent(" << yes << ")" << endl;
+#endif
+ setSelected (yes ? 1 : 0, 0, false/*don't save*/);
+}
+
+
+// protected slot virtual [base kpToolWidgetBase]
+bool kpToolWidgetOpaqueOrTransparent::setSelected (int row, int col, bool saveAsDefault)
+{
+#if DEBUG_KP_TOOL_WIDGET_OPAQUE_OR_TRANSPARENT && 1
+ kdDebug () << "kpToolWidgetOpaqueOrTransparent::setSelected("
+ << row << "," << col << ")" << endl;
+#endif
+ const bool ret = kpToolWidgetBase::setSelected (row, col, saveAsDefault);
+ if (ret)
+ emit isOpaqueChanged (isOpaque ());
+ return ret;
+}
+
+
+#include <kptoolwidgetopaqueortransparent.moc>
diff --git a/kolourpaint/widgets/kptoolwidgetopaqueortransparent.h b/kolourpaint/widgets/kptoolwidgetopaqueortransparent.h
new file mode 100644
index 00000000..c24cd308
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetopaqueortransparent.h
@@ -0,0 +1,56 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kp_tool_widget_opaque_or_transparent_h__
+#define __kp_tool_widget_opaque_or_transparent_h__
+
+
+#include <kptoolwidgetbase.h>
+
+class kpToolWidgetOpaqueOrTransparent : public kpToolWidgetBase
+{
+Q_OBJECT
+
+public:
+ kpToolWidgetOpaqueOrTransparent (QWidget *parent, const char *name);
+ virtual ~kpToolWidgetOpaqueOrTransparent ();
+
+ bool isOpaque () const;
+ bool isTransparent () const;
+ void setOpaque (bool yes = true);
+ void setTransparent (bool yes = true);
+
+signals:
+ void isOpaqueChanged (bool isOpaque_);
+
+protected slots:
+ virtual bool setSelected (int row, int col, bool saveAsDefault);
+};
+
+
+#endif // kp_tool_widget_opaque_or_transparent_h__
diff --git a/kolourpaint/widgets/kptoolwidgetspraycansize.cpp b/kolourpaint/widgets/kptoolwidgetspraycansize.cpp
new file mode 100644
index 00000000..161e5015
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetspraycansize.cpp
@@ -0,0 +1,119 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#define DEBUG_KP_TOOL_WIDGET_SPRAYCAN_SIZE 0
+
+
+#include <kptoolwidgetspraycansize.h>
+
+#include <qbitmap.h>
+#include <qimage.h>
+#include <qpainter.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include <kppixmapfx.h>
+
+
+static int spraycanSizes [] = {9, 17, 29};
+
+kpToolWidgetSpraycanSize::kpToolWidgetSpraycanSize (QWidget *parent, const char *name)
+ : kpToolWidgetBase (parent, name)
+{
+#if DEBUG_KP_TOOL_WIDGET_SPRAYCAN_SIZE
+ kdDebug () << "kpToolWidgetSpraycanSize::kpToolWidgetSpraycanSize() CALLED!" << endl;
+#endif
+
+ for (int i = 0; i < int (sizeof (spraycanSizes) / sizeof (spraycanSizes [0])); i++)
+ {
+ int s = spraycanSizes [i];
+ QString iconName = QString ("tool_spraycan_%1x%1").arg (s).arg(s);
+
+ #if DEBUG_KP_TOOL_WIDGET_SPRAYCAN_SIZE
+ kdDebug () << "\ticonName=" << iconName << endl;
+ #endif
+
+ QPixmap pixmap (s, s);
+ pixmap.fill (Qt::white);
+
+ QPainter painter (&pixmap);
+ painter.drawPixmap (0, 0, UserIcon (iconName));
+ painter.end ();
+
+ QImage image = kpPixmapFX::convertToImage (pixmap);
+
+ QBitmap mask (pixmap.width (), pixmap.height ());
+ mask.fill (Qt::color0);
+
+ painter.begin (&mask);
+ painter.setPen (Qt::color1);
+
+ for (int y = 0; y < image.height (); y++)
+ {
+ for (int x = 0; x < image.width (); x++)
+ {
+ if ((image.pixel (x, y) & RGB_MASK) == 0/*black*/)
+ painter.drawPoint (x, y); // mark as opaque
+ }
+ }
+
+ painter.end ();
+
+ pixmap.setMask (mask);
+
+ addOption (pixmap, i18n ("%1x%2").arg (s).arg (s)/*tooltip*/);
+ if (i == 1)
+ startNewOptionRow ();
+ }
+
+ finishConstruction (0, 0);
+}
+
+kpToolWidgetSpraycanSize::~kpToolWidgetSpraycanSize ()
+{
+}
+
+
+// public
+int kpToolWidgetSpraycanSize::spraycanSize () const
+{
+ return spraycanSizes [selected ()];
+}
+
+// protected slot virtual [base kpToolWidgetBase]
+bool kpToolWidgetSpraycanSize::setSelected (int row, int col, bool saveAsDefault)
+{
+ const bool ret = kpToolWidgetBase::setSelected (row, col, saveAsDefault);
+ if (ret)
+ emit spraycanSizeChanged (spraycanSize ());
+ return ret;
+}
+
+#include <kptoolwidgetspraycansize.moc>
diff --git a/kolourpaint/widgets/kptoolwidgetspraycansize.h b/kolourpaint/widgets/kptoolwidgetspraycansize.h
new file mode 100644
index 00000000..b4233a80
--- /dev/null
+++ b/kolourpaint/widgets/kptoolwidgetspraycansize.h
@@ -0,0 +1,51 @@
+
+/*
+ Copyright (c) 2003,2004,2005 Clarence Dang <dang@kde.org>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __kptoolwidgetspraycansize_h__
+#define __kptoolwidgetspraycansize_h__
+
+#include <kptoolwidgetbase.h>
+
+class kpToolWidgetSpraycanSize : public kpToolWidgetBase
+{
+Q_OBJECT
+
+public:
+ kpToolWidgetSpraycanSize (QWidget *parent, const char *name);
+ virtual ~kpToolWidgetSpraycanSize ();
+
+ int spraycanSize () const;
+
+signals:
+ void spraycanSizeChanged (int size);
+
+protected slots:
+ virtual bool setSelected (int row, int col, bool saveAsDefault);
+};
+
+#endif // __kptoolwidgetspraycansize_h__