You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/lib/kofficeui/KoTooluButton.cpp

859 lines
36 KiB

/* This file is part of the KDE project
Copyright (C) 2002 Werner Trobin <trobin@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <tqapplication.h>
#include <tqtooltip.h>
#include <tqpainter.h>
#include <tqdrawutil.h>
#include <tqpixmap.h>
#include <tqstyle.h>
#include <tqpopupmenu.h>
#include <kglobalsettings.h>
#include <ktoolbar.h>
#include <KoTooluButton.h>
#include <kcolordrag.h>
#include <klocale.h>
#include <kcolordialog.h>
#include <kdebug.h>
namespace {
// For the KoColorPanel
const int COLS = 15;
const int TILESIZE = 16;
// For the KoToolButton
int ARROW_WIDTH = 12;
}
KoColorPanel::KoColorPanel( TQWidget* parent, const char* name ) :
TQWidget( parent, name, WStaticContents | WRepaintNoErase | WResizeNoErase )
{
setMouseTracking( true );
setAcceptDrops( true );
init();
}
KoColorPanel::~KoColorPanel()
{
}
TQSize KoColorPanel::sizeHint() const
{
return minimumSizeHint();
}
TQSize KoColorPanel::minimumSizeHint() const
{
return TQSize( COLS << 4, lines() << 4 );
}
TQPopupMenu* KoColorPanel::createColorPopup( KoColorPanel::MenuStyle style, const TQColor& defaultColor,
const TQObject* receiver, const char* slot,
TQWidget* parent, const char* name )
{
TQPopupMenu* menu = new TQPopupMenu( parent, name );
KoColorPopupProxy* proxy = 0;
if ( defaultColor.isValid() ) {
TQPixmap pixmap( 12, 12 );
TQPainter p( &pixmap );
p.fillRect( 0, 0, 12, 12, defaultColor );
p.end();
proxy = new KoColorPopupProxy( defaultColor, 0, TQT_TQOBJECT(menu), "color proxy" );
connect( proxy, TQT_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
menu->insertItem( TQIconSet( pixmap ), i18n( "Default Color" ), proxy, TQT_SLOT( slotDefaultColor() ) );
menu->insertSeparator();
}
KoColorPanel* panel = new KoColorPanel( menu, "default colors" );
panel->insertDefaultColors();
connect( panel, TQT_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
menu->insertItem( panel );
if ( style == CustomColors ) {
menu->insertSeparator();
panel = new KoColorPanel( menu, "custom panel" );
connect( panel, TQT_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
menu->insertItem( panel );
if ( !proxy ) {
proxy = new KoColorPopupProxy( TQColor(), panel, TQT_TQOBJECT(menu), "color proxy" );
connect( proxy, TQT_SIGNAL( colorSelected( const TQColor& ) ), receiver, slot );
}
else
proxy->setRecentColorPanel( panel );
menu->insertSeparator();
menu->insertItem( i18n( "More Colors..." ), proxy, TQT_SLOT( slotMoreColors() ) );
}
return menu;
}
void KoColorPanel::clear()
{
if ( m_colorMap.isEmpty() )
return;
TQSize area( minimumSizeHint() );
m_colorMap.clear();
init();
updateGeometry();
erase( 0, 0, area.width(), area.height() );
}
void KoColorPanel::insertColor( const TQColor& color )
{
Position pos = m_nextPosition;
if ( insertColor( color, true ) ) // we want checking for external users
finalizeInsertion( pos );
}
void KoColorPanel::insertColor( const TQColor& color, const TQString& toolTip )
{
Position pos = m_nextPosition;
if ( insertColor( color, toolTip, true ) ) // we want checking for external users
finalizeInsertion( pos );
}
void KoColorPanel::insertDefaultColors()
{
if ( m_defaultsAdded )
return;
m_defaultsAdded = true;
int currentRow = m_nextPosition.y; // we have to repaint this row below
// Note: No checking for duplicates, so take care when you modify that list
insertColor(TQColor( 255 , 0 , 0 ), i18n( "color", "Red" ), false);
insertColor(TQColor( 255 , 165 , 0 ), i18n( "color", "Orange" ), false);
insertColor(TQColor( 255 , 0 , 255 ), i18n( "color", "Magenta" ), false);
insertColor(TQColor( 0 , 0 , 255 ), i18n( "color", "Blue" ), false);
insertColor(TQColor( 0 , 255 , 255 ), i18n( "color", "Cyan" ), false);
insertColor(TQColor( 0 , 255 , 0 ), i18n( "color", "Green" ), false);
insertColor(TQColor( 255 , 255 , 0 ), i18n( "color", "Yellow" ), false);
insertColor(TQColor( 165 , 42 , 42 ), i18n( "color", "Brown" ), false);
insertColor(TQColor( 139 , 0 , 0 ), i18n( "color", "DarkRed" ), false);
insertColor(TQColor( 255 , 140 , 0 ), i18n( "color", "DarkOrange" ), false);
insertColor(TQColor( 139 , 0 , 139 ), i18n( "color", "DarkMagenta" ), false);
insertColor(TQColor( 0 , 0 , 139 ), i18n( "color", "DarkBlue" ), false);
insertColor(TQColor( 0 , 139 , 139 ), i18n( "color", "DarkCyan" ), false);
insertColor(TQColor( 0 , 100 , 0 ), i18n( "color", "DarkGreen" ), false);
insertColor(TQColor( 130 , 127 , 0 ), i18n( "color", "DarkYellow" ), false);
insertColor(TQColor( 255 , 255 , 255 ), i18n( "color", "White" ), false);
// xgettext:no-c-format
insertColor(TQColor( 229 , 229 , 229 ), i18n( "color", "Gray 90%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 204 , 204 , 204 ), i18n( "color", "Gray 80%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 178 , 178 , 178 ), i18n( "color", "Gray 70%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 153 , 153 , 153 ), i18n( "color", "Gray 60%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 127 , 127 , 127 ), i18n( "color", "Gray 50%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 102 , 102 , 102 ), i18n( "color", "Gray 40%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 76 , 76 , 76 ), i18n( "color", "Gray 30%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 51 , 51 , 51 ), i18n( "color", "Gray 20%" ), false);
// xgettext:no-c-format
insertColor(TQColor( 25 , 25 , 25 ), i18n( "color", "Gray 10%" ), false);
insertColor(TQColor( 0 , 0 , 0 ), i18n( "color", "Black" ), false);
insertColor(TQColor( 255 , 255 , 240 ), i18n( "color", "Ivory" ), false);
insertColor(TQColor( 255 , 250 , 250 ), i18n( "color", "Snow" ), false);
insertColor(TQColor( 245 , 255 , 250 ), i18n( "color", "MintCream" ), false);
insertColor(TQColor( 255 , 250 , 240 ), i18n( "color", "FloralWhite" ), false);
insertColor(TQColor( 255 , 255 , 224 ), i18n( "color", "LightYellow" ), false);
insertColor(TQColor( 240 , 255 , 255 ), i18n( "color", "Azure" ), false);
insertColor(TQColor( 248 , 248 , 255 ), i18n( "color", "GhostWhite" ), false);
insertColor(TQColor( 240 , 255 , 240 ), i18n( "color", "Honeydew" ), false);
insertColor(TQColor( 255 , 245 , 238 ), i18n( "color", "Seashell" ), false);
insertColor(TQColor( 240 , 248 , 255 ), i18n( "color", "AliceBlue" ), false);
insertColor(TQColor( 255 , 248 , 220 ), i18n( "color", "Cornsilk" ), false);
insertColor(TQColor( 255 , 240 , 245 ), i18n( "color", "LavenderBlush" ), false);
insertColor(TQColor( 253 , 245 , 230 ), i18n( "color", "OldLace" ), false);
insertColor(TQColor( 245 , 245 , 245 ), i18n( "color", "WhiteSmoke" ), false);
insertColor(TQColor( 255 , 250 , 205 ), i18n( "color", "LemonChiffon" ), false);
insertColor(TQColor( 224 , 255 , 255 ), i18n( "color", "LightCyan" ), false);
insertColor(TQColor( 250 , 250 , 210 ), i18n( "color", "LightGoldenrodYellow" ), false);
insertColor(TQColor( 250 , 240 , 230 ), i18n( "color", "Linen" ), false);
insertColor(TQColor( 245 , 245 , 220 ), i18n( "color", "Beige" ), false);
insertColor(TQColor( 255 , 239 , 213 ), i18n( "color", "PapayaWhip" ), false);
insertColor(TQColor( 255 , 235 , 205 ), i18n( "color", "BlanchedAlmond" ), false);
insertColor(TQColor( 250 , 235 , 215 ), i18n( "color", "AntiqueWhite" ), false);
insertColor(TQColor( 255 , 228 , 225 ), i18n( "color", "MistyRose" ), false);
insertColor(TQColor( 230 , 230 , 250 ), i18n( "color", "Lavender" ), false);
insertColor(TQColor( 255 , 228 , 196 ), i18n( "color", "Bisque" ), false);
insertColor(TQColor( 255 , 228 , 181 ), i18n( "color", "Moccasin" ), false);
insertColor(TQColor( 255 , 222 , 173 ), i18n( "color", "NavajoWhite" ), false);
insertColor(TQColor( 255 , 218 , 185 ), i18n( "color", "PeachPuff" ), false);
insertColor(TQColor( 238 , 232 , 170 ), i18n( "color", "PaleGoldenrod" ), false);
insertColor(TQColor( 245 , 222 , 179 ), i18n( "color", "Wheat" ), false);
insertColor(TQColor( 220 , 220 , 220 ), i18n( "color", "Gainsboro" ), false);
insertColor(TQColor( 240 , 230 , 140 ), i18n( "color", "Khaki" ), false);
insertColor(TQColor( 175 , 238 , 238 ), i18n( "color", "PaleTurquoise" ), false);
insertColor(TQColor( 255 , 192 , 203 ), i18n( "color", "Pink" ), false);
insertColor(TQColor( 238 , 221 , 130 ), i18n( "color", "LightGoldenrod" ), false);
insertColor(TQColor( 211 , 211 , 211 ), i18n( "color", "LightGray" ), false);
insertColor(TQColor( 255 , 182 , 193 ), i18n( "color", "LightPink" ), false);
insertColor(TQColor( 176 , 224 , 230 ), i18n( "color", "PowderBlue" ), false);
insertColor(TQColor( 127 , 255 , 212 ), i18n( "color", "Aquamarine" ), false);
insertColor(TQColor( 216 , 191 , 216 ), i18n( "color", "Thistle" ), false);
insertColor(TQColor( 173 , 216 , 230 ), i18n( "color", "LightBlue" ), false);
insertColor(TQColor( 152 , 251 , 152 ), i18n( "color", "PaleGreen" ), false);
insertColor(TQColor( 255 , 215 , 0 ), i18n( "color", "Gold" ), false);
insertColor(TQColor( 173 , 255 , 47 ), i18n( "color", "GreenYellow" ), false);
insertColor(TQColor( 176 , 196 , 222 ), i18n( "color", "LightSteelBlue" ), false);
insertColor(TQColor( 144 , 238 , 144 ), i18n( "color", "LightGreen" ), false);
insertColor(TQColor( 221 , 160 , 221 ), i18n( "color", "Plum" ), false);
insertColor(TQColor( 190 , 190 , 190 ), i18n( "color", "Gray" ), false);
insertColor(TQColor( 222 , 184 , 135 ), i18n( "color", "BurlyWood" ), false);
insertColor(TQColor( 135 , 206 , 250 ), i18n( "color", "LightSkyBlue" ), false);
insertColor(TQColor( 255 , 160 , 122 ), i18n( "color", "LightSalmon" ), false);
insertColor(TQColor( 135 , 206 , 235 ), i18n( "color", "SkyBlue" ), false);
insertColor(TQColor( 210 , 180 , 140 ), i18n( "color", "Tan" ), false);
insertColor(TQColor( 238 , 130 , 238 ), i18n( "color", "Violet" ), false);
insertColor(TQColor( 244 , 164 , 96 ), i18n( "color", "SandyBrown" ), false);
insertColor(TQColor( 233 , 150 , 122 ), i18n( "color", "DarkSalmon" ), false);
insertColor(TQColor( 189 , 183 , 107 ), i18n( "color", "DarkKhaki" ), false);
insertColor(TQColor( 127 , 255 , 0 ), i18n( "color", "Chartreuse" ), false);
insertColor(TQColor( 169 , 169 , 169 ), i18n( "color", "DarkGray" ), false);
insertColor(TQColor( 124 , 252 , 0 ), i18n( "color", "LawnGreen" ), false);
insertColor(TQColor( 255 , 105 , 180 ), i18n( "color", "HotPink" ), false);
insertColor(TQColor( 250 , 128 , 114 ), i18n( "color", "Salmon" ), false);
insertColor(TQColor( 240 , 128 , 128 ), i18n( "color", "LightCoral" ), false);
insertColor(TQColor( 64 , 224 , 208 ), i18n( "color", "Turquoise" ), false);
insertColor(TQColor( 143 , 188 , 143 ), i18n( "color", "DarkSeaGreen" ), false);
insertColor(TQColor( 218 , 112 , 214 ), i18n( "color", "Orchid" ), false);
insertColor(TQColor( 102 , 205 , 170 ), i18n( "color", "MediumAquamarine" ), false);
insertColor(TQColor( 255 , 127 , 80 ), i18n( "color", "Coral" ), false);
insertColor(TQColor( 154 , 205 , 50 ), i18n( "color", "YellowGreen" ), false);
insertColor(TQColor( 218 , 165 , 32 ), i18n( "color", "Goldenrod" ), false);
insertColor(TQColor( 72 , 209 , 204 ), i18n( "color", "MediumTurquoise" ), false);
insertColor(TQColor( 188 , 143 , 143 ), i18n( "color", "RosyBrown" ), false);
insertColor(TQColor( 219 , 112 , 147 ), i18n( "color", "PaleVioletRed" ), false);
insertColor(TQColor( 0 , 250 , 154 ), i18n( "color", "MediumSpringGreen" ), false);
insertColor(TQColor( 255 , 99 , 71 ), i18n( "color", "Tomato" ), false);
insertColor(TQColor( 0 , 255 , 127 ), i18n( "color", "SpringGreen" ), false);
insertColor(TQColor( 205 , 133 , 63 ), i18n( "color", "Peru" ), false);
insertColor(TQColor( 100 , 149 , 237 ), i18n( "color", "CornflowerBlue" ), false);
insertColor(TQColor( 132 , 112 , 255 ), i18n( "color", "LightSlateBlue" ), false);
insertColor(TQColor( 147 , 112 , 219 ), i18n( "color", "MediumPurple" ), false);
insertColor(TQColor( 186 , 85 , 211 ), i18n( "color", "MediumOrchid" ), false);
insertColor(TQColor( 95 , 158 , 160 ), i18n( "color", "CadetBlue" ), false);
insertColor(TQColor( 0 , 206 , 209 ), i18n( "color", "DarkTurquoise" ), false);
insertColor(TQColor( 0 , 191 , 255 ), i18n( "color", "DeepSkyBlue" ), false);
insertColor(TQColor( 119 , 136 , 153 ), i18n( "color", "LightSlateGray" ), false);
insertColor(TQColor( 184 , 134 , 11 ), i18n( "color", "DarkGoldenrod" ), false);
insertColor(TQColor( 123 , 104 , 238 ), i18n( "color", "MediumSlateBlue" ), false);
insertColor(TQColor( 205 , 92 , 92 ), i18n( "color", "IndianRed" ), false);
insertColor(TQColor( 210 , 105 , 30 ), i18n( "color", "Chocolate" ), false);
insertColor(TQColor( 60 , 179 , 113 ), i18n( "color", "MediumSeaGreen" ), false);
insertColor(TQColor( 50 , 205 , 50 ), i18n( "color", "LimeGreen" ), false);
insertColor(TQColor( 32 , 178 , 170 ), i18n( "color", "LightSeaGreen" ), false);
insertColor(TQColor( 112 , 128 , 144 ), i18n( "color", "SlateGray" ), false);
insertColor(TQColor( 30 , 144 , 255 ), i18n( "color", "DodgerBlue" ), false);
insertColor(TQColor( 255 , 69 , 0 ), i18n( "color", "OrangeRed" ), false);
insertColor(TQColor( 255 , 20 , 147 ), i18n( "color", "DeepPink" ), false);
insertColor(TQColor( 70 , 130 , 180 ), i18n( "color", "SteelBlue" ), false);
insertColor(TQColor( 106 , 90 , 205 ), i18n( "color", "SlateBlue" ), false);
insertColor(TQColor( 107 , 142 , 35 ), i18n( "color", "OliveDrab" ), false);
insertColor(TQColor( 65 , 105 , 225 ), i18n( "color", "RoyalBlue" ), false);
insertColor(TQColor( 208 , 32 , 144 ), i18n( "color", "VioletRed" ), false);
insertColor(TQColor( 153 , 50 , 204 ), i18n( "color", "DarkOrchid" ), false);
insertColor(TQColor( 160 , 32 , 240 ), i18n( "color", "Purple" ), false);
insertColor(TQColor( 105 , 105 , 105 ), i18n( "color", "DimGray" ), false);
insertColor(TQColor( 138 , 43 , 226 ), i18n( "color", "BlueViolet" ), false);
insertColor(TQColor( 160 , 82 , 45 ), i18n( "color", "Sienna" ), false);
insertColor(TQColor( 199 , 21 , 133 ), i18n( "color", "MediumVioletRed" ), false);
insertColor(TQColor( 176 , 48 , 96 ), i18n( "color", "Maroon" ), false);
insertColor(TQColor( 46 , 139 , 87 ), i18n( "color", "SeaGreen" ), false);
insertColor(TQColor( 85 , 107 , 47 ), i18n( "color", "DarkOliveGreen" ), false);
insertColor(TQColor( 34 , 139 , 34 ), i18n( "color", "ForestGreen" ), false);
insertColor(TQColor( 139 , 69 , 19 ), i18n( "color", "SaddleBrown" ), false);
insertColor(TQColor( 148 , 0 , 211 ), i18n( "color", "DarkViolet" ), false);
insertColor(TQColor( 178 , 34 , 34 ), i18n( "color", "FireBrick" ), false);
insertColor(TQColor( 72 , 61 , 139 ), i18n( "color", "DarkSlateBlue" ), false);
insertColor(TQColor( 47 , 79 , 79 ), i18n( "color", "DarkSlateGray" ), false);
insertColor(TQColor( 25 , 25 , 112 ), i18n( "color", "MidnightBlue" ), false);
insertColor(TQColor( 0 , 0 , 205 ), i18n( "color", "MediumBlue" ), false);
insertColor(TQColor( 0 , 0 , 128 ), i18n( "color", "Navy" ), false);
finalizeInsertion( m_nextPosition ); // with a no-op paint() call as we repaint anyway
updateGeometry();
// we have to repaint the "old" current row explicitly due
// to WStaticContents
update( 0, currentRow << 4, COLS << 4, 16 );
}
void KoColorPanel::mousePressEvent( TQMouseEvent* e )
{
if ( e->button() == Qt::LeftButton )
m_pressedPos = e->pos();
}
void KoColorPanel::mouseReleaseEvent( TQMouseEvent* )
{
if ( isVisible() && parentWidget() && parentWidget()->inherits( TQPOPUPMENU_OBJECT_NAME_STRING ) )
parentWidget()->close();
emit colorSelected( mapToColor( m_pressedPos ) );
}
void KoColorPanel::mouseMoveEvent( TQMouseEvent* e )
{
if ( e->state() & Qt::LeftButton ) {
TQPoint p = m_pressedPos - e->pos();
if ( p.manhattanLength() > TQApplication::startDragDistance() ) {
TQColor color( mapToColor( m_pressedPos ) );
if ( color.isValid() ) {
KColorDrag *drag = new KColorDrag( color, this, name() );
drag->dragCopy();
}
}
}
else
updateFocusPosition( mapToPosition( e->pos() ) );
}
void KoColorPanel::paintEvent( TQPaintEvent* e )
{
int lns = lines();
int startRow, endRow, startCol, endCol;
paintArea( e->rect(), startRow, endRow, startCol, endCol );
TQPainter p( this );
// First clear all the areas we won't paint on later (only if the widget isn't erased)
if ( !e->erased() ) {
// vertical rects
int tmp = TILESIZE * lns;
if ( startCol == 0 )
erase( 0, 0, 2, tmp );
if ( endCol == COLS )
erase( width() - 2, 0, 2, tmp );
else
erase( ( endCol << 4 ) - 2, 0, 2, tmp );
int i = startCol == 0 ? 1 : startCol;
for ( ; i < endCol; ++i )
erase( ( i << 4 ) - 2, 0, 4, tmp );
// horizontal rects
tmp = TILESIZE * COLS;
if ( startRow == 0 )
erase( 0, 0, tmp, 2 );
if ( endRow == lns )
erase( 0, height() - 2, tmp, 2 );
else
erase( 0, ( endRow << 4 ) - 2, tmp, 2 );
i = startRow == 0 ? 1 : startRow;
for ( ; i < endRow; ++i )
erase( 0, ( i << 4 ) - 2, tmp, 4 );
}
// The "active" element (if there is one)
if ( hasFocus() && m_focusPosition.x != -1 && m_focusPosition.y != -1 &&
mapFromPosition( m_focusPosition ).intersects( e->rect() ) )
style().tqdrawPrimitive( TQStyle::PE_Panel, &p, TQRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
colorGroup(), TQStyle::Style_Sunken | TQStyle::Style_Enabled );
--lns; // Attention: We just avoid some lns - 1 statements
// ...all color tiles
if ( !m_colorMap.isEmpty() ) {
int currentRow = startRow, currentCol = startCol;
while ( currentRow < endRow && currentCol < endCol ) {
TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( Position( currentCol, currentRow ) );
if( it != m_colorMap.end() )
p.fillRect( ( currentCol << 4 ) + 2, ( currentRow << 4 ) + 2, 12, 12, it.data() );
// position of the next cell
++currentCol;
if ( currentCol == endCol ) {
++currentRow;
currentCol = startCol;
}
}
}
// clean up the last line (it's most likely that it's not totally filled)
if ( !e->erased() && endRow > lns ) {
int fields = m_colorMap.count() % COLS;
erase( fields << 4, lns * TILESIZE, ( COLS - fields ) << 4, 16 );
}
}
void KoColorPanel::keyPressEvent( TQKeyEvent* e )
{
Position newPos( validPosition( m_focusPosition ) );
if ( e->key() == TQt::Key_Up ) {
if ( newPos.y == 0 )
e->ignore();
else
--newPos.y;
}
else if ( e->key() == TQt::Key_Down ) {
if ( newPos < Position( m_colorMap.count() % COLS, lines() - 2 ) )
++newPos.y;
else
e->ignore();
}
else if ( e->key() == TQt::Key_Left ) {
if ( newPos.x == 0 )
e->ignore();
else
--newPos.x;
}
else if ( e->key() == TQt::Key_Right ) {
if ( newPos.x < COLS - 1 && newPos < Position( m_colorMap.count() % COLS - 1, lines() - 1 ) )
++newPos.x;
else
e->ignore();
}
else if ( e->key() == TQt::Key_Return ) {
if ( isVisible() && parentWidget() && parentWidget()->inherits( TQPOPUPMENU_OBJECT_NAME_STRING ) )
parentWidget()->close();
emit colorSelected( mapToColor( m_focusPosition ) );
}
updateFocusPosition( newPos );
}
void KoColorPanel::focusInEvent( TQFocusEvent* e )
{
if ( !m_colorMap.isEmpty() && m_focusPosition.x == -1 && m_focusPosition.y == -1 ) {
m_focusPosition.x = 0;
m_focusPosition.y = 0;
}
TQWidget::focusInEvent( e );
}
void KoColorPanel::dragEnterEvent( TQDragEnterEvent* e )
{
e->accept( KColorDrag::canDecode( e ) );
}
void KoColorPanel::dropEvent( TQDropEvent* e )
{
TQColor color;
if ( KColorDrag::decode( e, color ) )
insertColor( color );
}
void KoColorPanel::finalizeInsertion( const Position& pos )
{
paint( pos );
if ( !isFocusEnabled() )
setFocusPolicy( TQ_StrongFocus );
// Did we start a new row?
if ( m_nextPosition.x == 1 )
updateGeometry();
}
bool KoColorPanel::insertColor( const TQColor& color, bool checking )
{
if ( checking && isAvailable( color ) )
return false;
m_colorMap.insert( m_nextPosition, color );
++m_nextPosition.x;
if ( m_nextPosition.x == COLS ) {
m_nextPosition.x = 0;
++m_nextPosition.y;
}
return true;
}
bool KoColorPanel::insertColor( const TQColor& color, const TQString& toolTip, bool checking )
{
if ( checking && isAvailable( color ) )
return false;
// Remember the "old" m_nextPosition -- this is the place where the newly
// inserted color will be located
TQRect rect( mapFromPosition( m_nextPosition ) );
insertColor( color, false ); // check only once ;)
TQToolTip::add( this, rect, toolTip );
return true;
}
bool KoColorPanel::isAvailable( const TQColor& color )
{
// O(n) checking on insert, but this is better than O(n) checking
// on every mouse move...
TQMap<Position, TQColor>::ConstIterator it = m_colorMap.begin();
TQMap<Position, TQColor>::ConstIterator end = m_colorMap.end();
for ( ; it != end; ++it )
if ( it.data() == color )
return true;
return false;
}
KoColorPanel::Position KoColorPanel::mapToPosition( const TQPoint& point ) const
{
return Position( point.x() >> 4, point.y() >> 4 );
}
TQColor KoColorPanel::mapToColor( const TQPoint& point ) const
{
return mapToColor( mapToPosition( point ) );
}
TQColor KoColorPanel::mapToColor( const KoColorPanel::Position& position ) const
{
TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( position );
if ( it != m_colorMap.end() )
return it.data();
return TQColor();
}
TQRect KoColorPanel::mapFromPosition( const KoColorPanel::Position& position ) const
{
return TQRect( position.x << 4, position.y << 4, TILESIZE, TILESIZE );
}
KoColorPanel::Position KoColorPanel::validPosition( const Position& position )
{
Position pos( position );
int lns = lines() - 1;
int lastLineLen = m_colorMap.count() % COLS - 1;
// ensure the position is within the valid grid area
// note: special handling of the last line
if ( pos.x < 0 )
pos.x = 0;
else if ( pos.y == lns && pos.x > lastLineLen )
pos.x = lastLineLen;
else if ( pos.x >= COLS )
pos.x = COLS - 1;
if ( pos.y < 0 )
pos.y = 0;
else if ( pos.x > lastLineLen && pos.y > lns - 1 )
pos.y = lns - 1;
else if ( pos.y > lns )
pos.y = lns;
return pos;
}
int KoColorPanel::lines() const
{
if ( m_colorMap.isEmpty() )
return 1;
return ( m_colorMap.count() - 1 ) / COLS + 1;
}
void KoColorPanel::paintArea( const TQRect& rect, int& startRow, int& endRow, int& startCol, int& endCol ) const
{
startRow = rect.top() >> 4;
endRow = ( rect.bottom() >> 4 ) + 1;
startCol = rect.left() >> 4;
endCol = ( rect.right() >> 4 ) + 1;
}
void KoColorPanel::updateFocusPosition( const Position& newPosition )
{
TQPainter p( this );
// restore the old tile where we had the focus before
if ( m_focusPosition.x != -1 && m_focusPosition.y != -1 )
paint( m_focusPosition );
m_focusPosition = newPosition;
TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( m_focusPosition );
if ( it != m_colorMap.end() ) {
// draw at the new focus position
style().tqdrawPrimitive( TQStyle::PE_Panel, &p, TQRect( m_focusPosition.x << 4, m_focusPosition.y << 4, TILESIZE, TILESIZE ),
colorGroup(), TQStyle::Style_Sunken | TQStyle::Style_Enabled );
p.fillRect( ( m_focusPosition.x << 4 ) + 2, ( m_focusPosition.y << 4 ) + 2, 12, 12, it.data() );
}
}
void KoColorPanel::paint( const Position& position )
{
TQMap<Position, TQColor>::ConstIterator it = m_colorMap.find( position );
if ( it == m_colorMap.end() )
return;
erase( mapFromPosition( position ) );
TQPainter p( this );
p.fillRect( ( position.x << 4 ) + 2, ( position.y << 4 ) + 2, 12, 12, it.data() );
}
void KoColorPanel::init()
{
setFocusPolicy( TQ_NoFocus ); // it's empty
m_nextPosition.x = 0;
m_nextPosition.y = 0;
m_focusPosition.x = -1;
m_focusPosition.y = -1;
m_defaultsAdded = false;
}
bool operator<( const KoColorPanel::Position& lhs, const KoColorPanel::Position& rhs )
{
return ( lhs.y * COLS + lhs.x ) < ( rhs.y * COLS + rhs.x );
}
KoColorPopupProxy::KoColorPopupProxy( const TQColor& defaultColor, KoColorPanel* recentColors, TQObject* parent, const char* name ) :
TQObject( parent, name ), m_defaultColor( defaultColor ), m_recentColors( recentColors )
{
}
void KoColorPopupProxy::setRecentColorPanel( KoColorPanel* recentColors )
{
m_recentColors = recentColors;
}
void KoColorPopupProxy::slotDefaultColor()
{
emit colorSelected( m_defaultColor );
}
void KoColorPopupProxy::slotMoreColors()
{
if ( !m_recentColors )
return;
TQColor newColor;
TQWidget* p = 0;
if ( parent() && parent()->isWidgetType() )
p = TQT_TQWIDGET( parent() );
if ( KColorDialog::getColor( newColor, p ) == TQDialog::Accepted ) {
m_recentColors->insertColor( newColor );
emit colorSelected( newColor );
}
}
KoToolButton::KoToolButton( const TQString& icon, int id, TQWidget* parent,
const char* name, const TQString& txt, TDEInstance* _instance ) :
KToolBarButton( icon, id, parent, name, txt, _instance ), m_arrowPressed( false )
{
init();
}
KoToolButton::KoToolButton( const TQPixmap& pixmap, int id, TQWidget* parent,
const char* name, const TQString& txt ) :
KToolBarButton( pixmap, id, parent, name, txt ), m_arrowPressed( false )
{
init();
}
KoToolButton::~KoToolButton()
{
}
TQSize KoToolButton::sizeHint() const
{
return minimumSizeHint();
}
TQSize KoToolButton::minimumSizeHint() const
{
TQSize size = KToolBarButton::minimumSizeHint();
size.setWidth( size.width() + ARROW_WIDTH );
return size;
}
TQSize KoToolButton::minimumSize() const
{
return minimumSizeHint();
}
void KoToolButton::colorSelected( const TQColor& color )
{
kdDebug() << "selected::: " << TQString(color.name()) << endl;
}
void KoToolButton::drawButton(TQPainter *_painter)
{
TQStyle::SFlags flags = TQStyle::Style_Default;
TQStyle::SCFlags active = TQStyle::SC_None;
TQStyle::SCFlags arrowActive = TQStyle::SC_None;
TQStyleOption opt;
TQColorGroup cg( colorGroup() );
if ( isEnabled() ) {
flags |= TQStyle::Style_Enabled;
if ( KToolBarButton::isRaised() || m_arrowPressed )
flags |= TQStyle::Style_Raised;
}
if ( isOn() )
flags |= TQStyle::Style_On;
TQStyle::SFlags arrowFlags = flags;
if ( isDown() && !m_arrowPressed ) {
flags |= TQStyle::Style_Down;
active |= TQStyle::SC_ToolButton;
}
if ( m_arrowPressed )
arrowActive |= TQStyle::SC_ToolButton;
// Draw styled toolbuttons
_painter->setClipRect( 0, 0, width() - ARROW_WIDTH, height() );
style().drawComplexControl( TQStyle::CC_ToolButton, _painter, this, TQRect( 0, 0, width() - ARROW_WIDTH, height() ), cg,
flags, TQStyle::SC_ToolButton, active, opt );
_painter->setClipRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() );
style().drawComplexControl( TQStyle::CC_ToolButton, _painter, this, TQRect( width(), 0, ARROW_WIDTH, height() ), cg,
arrowFlags, TQStyle::SC_ToolButton, arrowActive, opt );
_painter->setClipping( false );
// ...and the arrow indicating the popup
style().tqdrawPrimitive( TQStyle::PE_ArrowDown, _painter, TQRect( width() - ARROW_WIDTH - 1, 0, ARROW_WIDTH, height() ),
cg, flags, opt );
if ( KToolBarButton::isRaised() || m_arrowPressed )
qDrawShadeLine( _painter, width() - ARROW_WIDTH - 1, 0, width() - ARROW_WIDTH - 1, height() - 1, colorGroup(), true );
int dx, dy;
TQFont tmp_font( KGlobalSettings::toolBarFont() );
TQFontMetrics fm( tmp_font );
TQRect textRect;
int textFlags = 0;
if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconOnly ) { // icon only
TQPixmap pixmap = iconSet().pixmap( TQIconSet::Automatic,
isEnabled() ? ( KToolBarButton::isActive() ? TQIconSet::Active : TQIconSet::Normal ) :
TQIconSet::Disabled, isOn() ? TQIconSet::On : TQIconSet::Off );
if ( !pixmap.isNull() ) {
dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
dy = ( height() - pixmap.height() ) / 2;
buttonShift( dx, dy );
_painter->drawPixmap( dx, dy, pixmap );
}
}
else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconTextRight ) { // icon and text (if any)
TQPixmap pixmap = iconSet().pixmap( TQIconSet::Automatic,
isEnabled() ? ( KToolBarButton::isActive() ? TQIconSet::Active : TQIconSet::Normal ) :
TQIconSet::Disabled, isOn() ? TQIconSet::On : TQIconSet::Off );
if( !pixmap.isNull()) {
dx = 4;
dy = ( height() - pixmap.height() ) / 2;
buttonShift( dx, dy );
_painter->drawPixmap( dx, dy, pixmap );
}
if (!textLabel().isNull()) {
textFlags = AlignVCenter | AlignLeft;
if ( !pixmap.isNull() )
dx = 4 + pixmap.width() + 2;
else
dx = 4;
dy = 0;
buttonShift( dx, dy );
textRect = TQRect( dx, dy, width() - dx, height() );
}
}
else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::TextOnly ) {
if ( !textLabel().isNull() ) {
textFlags = AlignTop | AlignLeft;
dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
dy = ( height() - fm.lineSpacing() ) / 2;
buttonShift( dx, dy );
textRect = TQRect( dx, dy, fm.width(textLabel()), fm.lineSpacing() );
}
}
else if ( static_cast<KToolBar::IconText>( iconTextMode() ) == KToolBar::IconTextBottom ) {
TQPixmap pixmap = iconSet().pixmap( TQIconSet::Automatic,
isEnabled() ? ( KToolBarButton::isActive() ? TQIconSet::Active : TQIconSet::Normal ) :
TQIconSet::Disabled, isOn() ? TQIconSet::On : TQIconSet::Off );
if( !pixmap.isNull()) {
dx = ( width() - ARROW_WIDTH - pixmap.width() ) / 2;
dy = ( height() - fm.lineSpacing() - pixmap.height() ) / 2;
buttonShift( dx, dy );
_painter->drawPixmap( dx, dy, pixmap );
}
if ( !textLabel().isNull() ) {
textFlags = AlignBottom | AlignHCenter;
dx = ( width() - ARROW_WIDTH - fm.width( textLabel() ) ) / 2;
dy = height() - fm.lineSpacing() - 4;
buttonShift( dx, dy );
textRect = TQRect( dx, dy, fm.width( textLabel() ), fm.lineSpacing() );
}
}
// Draw the text at the position given by textRect, and using textFlags
if (!textLabel().isNull() && !textRect.isNull()) {
_painter->setFont( KGlobalSettings::toolBarFont() );
if ( !isEnabled() )
_painter->setPen( palette().disabled().dark() );
else if( KToolBarButton::isRaised() )
_painter->setPen( KGlobalSettings::toolBarHighlightColor() );
else
_painter->setPen( colorGroup().buttonText() );
_painter->drawText( textRect, textFlags, textLabel() );
}
}
bool KoToolButton::eventFilter( TQObject* o, TQEvent* e )
{
if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_popup) ) {
if ( e->type() == TQEvent::MouseButtonPress )
if ( hitArrow( mapFromGlobal( TQT_TQMOUSEEVENT( e )->globalPos() ) ) ) {
kdDebug() << "KoToolButton::eventFilter-------------->" << endl;
m_popup->close();
m_arrowPressed = false;
return true;
}
return false;
}
if ( e->type() == TQEvent::MouseButtonPress ) {
m_arrowPressed = hitArrow( TQT_TQMOUSEEVENT( e )->pos() );
if ( m_arrowPressed )
m_popup->popup( mapToGlobal( TQPoint( 0, height() ) ) );
}
else if ( e->type() == TQEvent::MouseButtonRelease )
m_arrowPressed = false;
return KToolBarButton::eventFilter( o, e );
}
void KoToolButton::init()
{
m_popup = KoColorPanel::createColorPopup( KoColorPanel::CustomColors, TQt::yellow, TQT_TQOBJECT(this),
TQT_SLOT( colorSelected( const TQColor& ) ),
this, "no-name" );
// We are interested in the mouse clicks on the arrow button
m_popup->installEventFilter( this );
ARROW_WIDTH = style().pixelMetric(TQStyle::PM_MenuButtonIndicator) + 4;
kdDebug() << "##################### Arrow: " << ARROW_WIDTH << endl;
}
void KoToolButton::buttonShift( int& dx, int& dy )
{
if ( isDown() && !m_arrowPressed ) {
dx += style().pixelMetric( TQStyle::PM_ButtonShiftHorizontal );
dy += style().pixelMetric( TQStyle::PM_ButtonShiftVertical );
}
}
bool KoToolButton::hitArrow( const TQPoint& pos )
{
return TQRect( width() - ARROW_WIDTH, 0, ARROW_WIDTH, height() ).contains( pos );
}
#include <KoTooluButton.moc>