1 /***************************************************************************
2 klineal.cpp - description
4 Begin : Fri Oct 13 2000
5 Copyright : 2000 by Till Krech <till@snafu.de>
6 2008 by Mathias Soeken <msoeken@informatik.uni-bremen.de>
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
24 #include <QMouseEvent>
26 #include <QToolButton>
27 #include <QWidgetAction>
30 #include <KActionCollection>
31 #include <KColorDialog>
33 #include <KConfigDialog>
34 #include <KGlobalSettings>
36 #include <KInputDialog>
39 #include <KNotification>
40 #include <KShortcutsDialog>
41 #include <KStandardAction>
42 #include <KSystemTrayIcon>
43 #include <KToolInvocation>
44 #include <KWindowSystem>
45 #include <KApplication>
50 #include "qautosizelabel.h"
52 #include "ui_cfg_appearance.h"
53 #include "ui_cfg_advanced.h"
56 * this is our cursor bitmap:
57 * a line 48 pixels long with an arrow pointing down
58 * and a sqare with a one pixel hole at the top (end)
60 static const uchar cursorBits
[] = {
61 0x38, 0x28, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10,
62 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
63 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
64 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
65 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
66 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10,
70 * create the thingy with no borders and set up
73 KLineal::KLineal( QWidget
*parent
)
77 mLenMenu( 0 ), // INFO This member could be eventually deleted
78 // since if mFullScreenAction is initialized
79 // mLenMenu should have been, too.
80 mFullScreenAction( 0 ),
81 mScaleDirectionAction( 0 ),
82 mCenterOriginAction( 0 ),
85 mActionCollection( 0 ),
88 KWindowSystem::setType( winId(), NET::Override
); // or NET::Normal
89 KWindowSystem::setState( winId(), NET::KeepAbove
);
91 setAttribute( Qt::WA_TranslucentBackground
);
92 setWindowFlags( Qt::FramelessWindowHint
);
94 setMinimumSize( 60, 60 );
95 setMaximumSize( 8000, 8000 );
96 setWhatsThis( i18n( "This is a tool to measure pixel distances and colors on the screen. "
97 "It is useful for working on layouts of dialogs, web pages etc." ) );
98 setMouseTracking( true );
100 QBitmap bim
= QBitmap::fromData( QSize( 8, 48 ), cursorBits
, QImage::Format_Mono
);
103 mNorthCursor
= QCursor( bim
, bim
, 3, 47 );
104 bim
= bim
.transformed( m
);
105 mEastCursor
= QCursor( bim
, bim
, 0, 3 );
106 bim
= bim
.transformed( m
);
107 mSouthCursor
= QCursor( bim
, bim
, 4, 0 );
108 bim
= bim
.transformed( m
);
109 mWestCursor
= QCursor( bim
, bim
, 47, 4 );
111 mCurrentCursor
= mNorthCursor
;
112 mColor
= RulerSettings::self()->bgColor();
113 mScaleFont
= RulerSettings::self()->scaleFont();
114 mLongEdgeLen
= RulerSettings::self()->length();
115 mOrientation
= RulerSettings::self()->orientation();
116 mLeftToRight
= RulerSettings::self()->leftToRight();
117 mOffset
= RulerSettings::self()->offset();
118 mRelativeScale
= RulerSettings::self()->relativeScale();
120 mLabel
= new QAutoSizeLabel( this );
121 mLabel
->setGeometry( 0, height() - 12, 32, 12 );
122 QFont
labelFont( KGlobalSettings::generalFont().family(), 10 );
123 labelFont
.setPixelSize( 10 );
124 mLabel
->setFont( labelFont
);
125 mLabel
->setWhatsThis( i18n( "This is the current distance measured in pixels." ) );
126 mColorLabel
= new QAutoSizeLabel( this );
127 mColorLabel
->setAutoFillBackground( true );
128 QFont
colorFont( KGlobalSettings::fixedFont().family(), 10 );
129 colorFont
.setPixelSize( 10 );
130 mColorLabel
->setFont( colorFont
);
131 mColorLabel
->move( mLabel
->pos() + QPoint(0, 20) );
132 mColorLabel
->setWhatsThis(i18n("This is the current color in hexadecimal rgb representation"
133 " as you may use it in HTML or as a QColor name. "
134 "The rectangles background shows the color of the pixel inside the "
135 "little square at the end of the line cursor." ) );
137 mBtnRotateLeft
= new QToolButton( this );
138 mBtnRotateLeft
->setIcon( KIcon( "object-rotate-left" ) );
139 mBtnRotateLeft
->setToolTip( i18n( "Turn Left" ) );
140 connect( mBtnRotateLeft
, SIGNAL( clicked() ), this, SLOT( turnLeft() ) );
142 mBtnRotateRight
= new QToolButton( this );
143 mBtnRotateRight
->setIcon( KIcon( "object-rotate-right" ) );
144 mBtnRotateRight
->setToolTip( i18n( "Turn Right" ) );
145 connect( mBtnRotateRight
, SIGNAL( clicked() ), this, SLOT( turnRight() ) );
147 resize( QSize( mLongEdgeLen
, mShortEdgeLen
) );
149 //BEGIN setup menu and actions
150 mActionCollection
= new KActionCollection( this );
151 mActionCollection
->setConfigGroup( "Actions" );
153 mMenu
= new KMenu( this );
154 mMenu
->addTitle( i18n( "KRuler" ) );
155 KMenu
*oriMenu
= new KMenu( i18n( "&Orientation"), this );
156 addAction( oriMenu
, KIcon( "kruler-north" ), i18nc( "Turn Kruler North", "&North" ),
157 this, SLOT( setNorth() ), Qt::Key_N
, "turn_north" );
158 addAction( oriMenu
, KIcon( "kruler-east" ), i18nc( "Turn Kruler East", "&East" ),
159 this, SLOT( setEast() ), Qt::Key_E
, "turn_east" );
160 addAction( oriMenu
, KIcon( "kruler-south" ), i18nc( "Turn Kruler South", "&South" ),
161 this, SLOT( setSouth() ), Qt::Key_S
, "turn_south" );
162 addAction( oriMenu
, KIcon( "kruler-west" ), i18nc( "Turn Kruler West", "&West" ),
163 this, SLOT( setWest() ), Qt::Key_W
, "turn_west" );
164 addAction( oriMenu
, KIcon( "object-rotate-right" ), i18n( "&Turn Right" ),
165 this, SLOT( turnRight() ), Qt::Key_R
, "turn_right" );
166 addAction( oriMenu
, KIcon( "object-rotate-left" ), i18n( "Turn &Left" ),
167 this, SLOT( turnLeft() ), Qt::Key_L
, "turn_left" );
168 mMenu
->addMenu( oriMenu
);
170 mLenMenu
= new KMenu( i18n( "&Length" ), this );
171 addAction( mLenMenu
, KIcon(), i18nc( "Make Kruler Height Short", "&Short" ),
172 this, SLOT( setShortLength() ), Qt::CTRL
+ Qt::Key_S
, "length_short" );
173 addAction( mLenMenu
, KIcon(), i18nc( "Make Kruler Height Medium", "&Medium" ),
174 this, SLOT( setMediumLength() ), Qt::CTRL
+ Qt::Key_M
, "length_medium" );
175 addAction( mLenMenu
, KIcon(), i18nc( "Make Kruler Height Tall", "&Tall" ),
176 this, SLOT( setTallLength() ), Qt::CTRL
+ Qt::Key_T
, "length_tall" );
177 addAction( mLenMenu
, KIcon(), i18n("&Full Screen Width"),
178 this, SLOT( setFullLength() ), Qt::CTRL
+ Qt::Key_F
, "length_full_length" );
179 mLenMenu
->addSeparator();
180 addAction( mLenMenu
, KIcon(), i18n( "Length..." ),
181 this, SLOT( slotLength() ), QKeySequence(), "set_length" );
182 mMenu
->addMenu( mLenMenu
);
184 KMenu
* scaleMenu
= new KMenu( i18n( "&Scale" ), this );
185 mScaleDirectionAction
= addAction( scaleMenu
, KIcon(), i18n( "Right To Left" ),
186 this, SLOT( switchDirection() ), Qt::Key_D
, "right_to_left" );
187 mCenterOriginAction
= addAction( scaleMenu
, KIcon(), i18n( "Center origin" ),
188 this, SLOT( centerOrigin() ), Qt::Key_C
, "center_origin" );
189 mCenterOriginAction
->setEnabled( !mRelativeScale
);
190 mOffsetAction
= addAction( scaleMenu
, KIcon(), i18n( "Offset..." ),
191 this, SLOT( slotOffset() ), Qt::Key_O
, "set_offset" );
192 mOffsetAction
->setEnabled( !mRelativeScale
);
193 scaleMenu
->addSeparator();
194 KAction
*relativeScaleAction
= addAction( scaleMenu
, KIcon(), i18n( "Percentage" ),
195 0, 0, QKeySequence(), "toggle_percentage" );
196 relativeScaleAction
->setCheckable( true );
197 relativeScaleAction
->setChecked( mRelativeScale
);
198 connect( relativeScaleAction
, SIGNAL( toggled( bool ) ), this, SLOT( switchRelativeScale( bool ) ) );
199 mMenu
->addMenu( scaleMenu
);
201 mOpacity
= RulerSettings::self()->opacity();
202 KMenu
* opacityMenu
= new KMenu( i18n( "O&pacity" ), this );
203 QWidgetAction
*opacityAction
= new QWidgetAction( this );
204 QSlider
*slider
= new QSlider( this );
205 slider
->setMinimum( 0 );
206 slider
->setMaximum( 255 );
207 slider
->setSingleStep( 1 );
208 slider
->setOrientation( Qt::Horizontal
);
209 slider
->setValue( RulerSettings::self()->opacity() );
210 connect( slider
, SIGNAL( valueChanged( int ) ), this, SLOT( slotOpacity( int ) ) );
211 opacityAction
->setDefaultWidget( slider
);
212 opacityMenu
->addAction( opacityAction
);
213 mMenu
->addMenu( opacityMenu
);
215 KAction
*keyBindings
= KStandardAction::keyBindings( this, SLOT( slotKeyBindings() ), this );
216 mActionCollection
->addAction( "key_bindings", keyBindings
);
217 mMenu
->addAction( keyBindings
);
218 KAction
*preferences
= KStandardAction::preferences( this, SLOT( slotPreferences() ), this );
219 mActionCollection
->addAction( "preferences", preferences
);
220 mMenu
->addAction( preferences
);
221 mMenu
->addSeparator();
222 KAction
*copyColorAction
= KStandardAction::copy( this, SLOT( copyColor() ), this );
223 copyColorAction
->setText( i18n( "Copy Color" ) );
224 mActionCollection
->addAction( "copy_color", copyColorAction
);
225 mMenu
->addAction( copyColorAction
);
226 mMenu
->addSeparator();
227 mMenu
->addMenu( ( new KHelpMenu( this, KGlobal::mainComponent().aboutData(), true ) )->menu() );
228 mMenu
->addSeparator();
230 if ( RulerSettings::self()->trayIcon() ) {
231 KAction
*closeAction
= KStandardAction::close( this, SLOT( slotClose() ), this );
232 mActionCollection
->addAction( "close", closeAction
);
233 mMenu
->addAction( closeAction
);
235 mCloseButton
= new QToolButton( this );
236 mCloseButton
->setIcon( closeAction
->icon() );
237 mCloseButton
->setToolTip( closeAction
->text().remove( '&' ) );
238 connect( mCloseButton
, SIGNAL( clicked() ), this, SLOT( slotClose() ) );
241 KAction
*quit
= KStandardAction::quit( kapp
, SLOT( quit() ), this );
242 mActionCollection
->addAction( "quit", quit
);
243 mMenu
->addAction( quit
);
245 mActionCollection
->associateWidget( this );
246 mActionCollection
->readSettings();
248 mLastClickPos
= geometry().topLeft() + QPoint( width() / 2, height() / 2 );
251 setOrientation( mOrientation
);
253 if ( RulerSettings::self()->trayIcon() ) {
254 KSystemTrayIcon
*tray
= new KSystemTrayIcon( KIcon( "kruler" ), this );
263 KAction
* KLineal::addAction( KMenu
*menu
, KIcon icon
, const QString
& text
,
264 const QObject
* receiver
, const char* member
,
265 const QKeySequence
&shortcut
, const QString
& name
)
267 KAction
*action
= new KAction( icon
, text
, mActionCollection
);
268 action
->setShortcut( shortcut
);
270 connect( action
, SIGNAL( triggered() ), receiver
, member
);
272 menu
->addAction( action
);
273 mActionCollection
->addAction( name
, action
);
277 void KLineal::slotClose()
282 void KLineal::slotQuit()
287 void KLineal::move( int x
, int y
)
289 move( QPoint( x
, y
) );
292 void KLineal::move(const QPoint
&p
)
294 setGeometry( QRect( p
, size() ) );
297 QPoint
KLineal::pos()
299 return frameGeometry().topLeft();
312 void KLineal::drawBackground( QPainter
& painter
)
314 QColor a
, b
, bg
= mColor
;
315 QLinearGradient gradient
;
316 switch ( mOrientation
) {
320 gradient
= QLinearGradient( 1, 0, 1, height() );
326 gradient
= QLinearGradient( 1, 0, 1, height() );
332 gradient
= QLinearGradient( 0, 1, width(), 1 );
338 gradient
= QLinearGradient( 0, 1, width(), 1 );
341 a
.setAlpha( mOpacity
);
342 b
.setAlpha( mOpacity
);
343 gradient
.setColorAt( 0, a
);
344 gradient
.setColorAt( 1, b
);
345 painter
.fillRect( rect(), QBrush( gradient
) );
348 void KLineal::setOrientation( int inOrientation
)
350 QRect r
= frameGeometry();
351 int nineties
= (int)inOrientation
- (int)mOrientation
;
352 mOrientation
= ( inOrientation
+ 4 ) % 4;
353 QPoint center
= mLastClickPos
, newTopLeft
;
356 center
= mLastClickPos
;
359 center
= r
.topLeft() + QPoint( width() / 2, height() / 2 );
362 if ( nineties
% 2 ) {
363 newTopLeft
= QPoint( center
.x() - height() / 2, center
.y() - width() / 2 );
365 newTopLeft
= r
.topLeft();
368 if ( mOrientation
== North
|| mOrientation
== South
) {
369 r
.setSize( QSize( mLongEdgeLen
, mShortEdgeLen
) );
371 r
.setSize( QSize( mShortEdgeLen
, mLongEdgeLen
) );
374 r
.moveTo(newTopLeft
);
376 QRect desktop
= KGlobalSettings::desktopGeometry( this );
378 if ( r
.top() < desktop
.top() ) {
379 r
.moveTop( desktop
.top() );
382 if ( r
.bottom() > desktop
.bottom() ) {
383 r
.moveBottom( desktop
.bottom() );
386 if ( r
.left() < desktop
.left() ) {
387 r
.moveLeft( desktop
.left() );
390 if ( r
.right() > desktop
.right() ) {
391 r
.moveRight( desktop
.right() );
395 switch( mOrientation
) {
397 mLabel
->move( 4, height()-mLabel
->height() - 4 );
398 mColorLabel
->move( mLabel
->pos() + QPoint( 0, -20 ) );
399 mCurrentCursor
= mNorthCursor
;
403 mLabel
->move( 4, 4 );
404 mColorLabel
->move( mLabel
->pos() + QPoint( 0, 20 ) );
405 mCurrentCursor
= mSouthCursor
;
409 mLabel
->move( 4, 4 );
410 mColorLabel
->move( mLabel
->pos() + QPoint( 0, 20 ) );
411 mCurrentCursor
= mEastCursor
;
415 mLabel
->move( width()-mLabel
->width() - 4, 4 );
416 mColorLabel
->move( mLabel
->pos() + QPoint( -5, 20 ) );
417 mCurrentCursor
= mWestCursor
;
423 if ( mLenMenu
&& mFullScreenAction
) {
424 mFullScreenAction
->setText( mOrientation
% 2 ? i18n( "&Full Screen Height" ) : i18n( "&Full Screen Width" ) );
427 updateScaleDirectionMenuItem();
429 setCursor( mCurrentCursor
);
434 void KLineal::setNorth()
436 setOrientation( North
);
439 void KLineal::setEast()
441 setOrientation( East
);
444 void KLineal::setSouth()
446 setOrientation( South
);
449 void KLineal::setWest()
451 setOrientation( West
);
454 void KLineal::turnRight()
456 setOrientation( mOrientation
- 1 );
459 void KLineal::turnLeft()
461 setOrientation( mOrientation
+ 1 );
464 void KLineal::reLength( int percentOfScreen
)
466 if ( percentOfScreen
< 10 ) {
470 QRect r
= KGlobalSettings::desktopGeometry( this );
472 if ( mOrientation
== North
|| mOrientation
== South
) {
473 mLongEdgeLen
= r
.width() * percentOfScreen
/ 100;
474 resize( mLongEdgeLen
, height() );
476 mLongEdgeLen
= r
.height() * percentOfScreen
/ 100;
477 resize( width(), mLongEdgeLen
);
480 if ( x() + width() < 10 ) {
484 if ( y() + height() < 10 ) {
492 void KLineal::reLengthAbsolute( int length
)
494 if ( length
< 100 ) {
498 QRect r
= KGlobalSettings::desktopGeometry( this );
500 mLongEdgeLen
= length
;
501 if ( mOrientation
== North
|| mOrientation
== South
) {
502 resize( mLongEdgeLen
, height() );
504 resize( width(), mLongEdgeLen
);
507 if ( x() + width() < 10 ) {
511 if ( y() + height() < 10 ) {
519 void KLineal::updateScaleDirectionMenuItem()
521 if ( !mScaleDirectionAction
) return;
525 if ( mOrientation
== North
|| mOrientation
== South
) {
526 label
= mLeftToRight
? i18n( "Right To Left" ) : i18n( "Left To Right" );
528 label
= mLeftToRight
? i18n( "Bottom To Top" ) : i18n( "Top To Bottom" );
531 mScaleDirectionAction
->setText( label
);
534 void KLineal::setShortLength()
539 void KLineal::setMediumLength()
544 void KLineal::setTallLength()
549 void KLineal::setFullLength()
554 void KLineal::switchDirection()
556 mLeftToRight
= !mLeftToRight
;
557 updateScaleDirectionMenuItem();
563 void KLineal::centerOrigin()
565 mOffset
= -( mLongEdgeLen
/ 2 );
571 void KLineal::slotOffset()
574 int newOffset
= KInputDialog::getInteger( i18n( "Scale offset" ),
575 i18n( "Offset:" ), mOffset
,
576 -2147483647, 2147483647, 1, &ok
, this );
586 void KLineal::slotLength()
589 QRect r
= KGlobalSettings::desktopGeometry( this );
590 int width
= ( ( mOrientation
== North
) || ( mOrientation
== South
) ) ? r
.width() : r
.height();
591 int newLength
= KInputDialog::getInteger( i18n( "Ruler Length" ),
592 i18n( "Length:" ), mLongEdgeLen
,
593 0, width
, 1, &ok
, this );
596 reLengthAbsolute( newLength
);
600 void KLineal::slotOpacity( int value
)
604 RulerSettings::self()->setOpacity( value
);
605 RulerSettings::self()->writeConfig();
608 void KLineal::slotKeyBindings()
610 KShortcutsDialog::configure( mActionCollection
);
613 void KLineal::slotPreferences()
615 KConfigDialog
*dialog
= new KConfigDialog( this, "settings", RulerSettings::self() );
617 Ui::ConfigAppearance appearanceConfig
;
618 QWidget
*appearanceConfigWidget
= new QWidget( dialog
);
619 appearanceConfig
.setupUi( appearanceConfigWidget
);
620 appearanceConfig
.kcfg_CloseButtonVisible
->setEnabled( appearanceConfig
.kcfg_TrayIcon
->isChecked() );
621 dialog
->addPage( appearanceConfigWidget
, i18n( "Appearance" ), "preferences-desktop-default-applications" );
623 Ui::ConfigAdvanced advancedConfig
;
624 QWidget
*advancedConfigWidget
= new QWidget( dialog
);
625 advancedConfig
.setupUi( advancedConfigWidget
);
626 dialog
->addPage( advancedConfigWidget
, i18n( "Advanced" ), "preferences-other" );
629 mColor
= RulerSettings::self()->bgColor();
630 mScaleFont
= RulerSettings::self()->scaleFont();
635 void KLineal::switchRelativeScale( bool checked
)
637 mRelativeScale
= checked
;
639 mCenterOriginAction
->setEnabled( !mRelativeScale
);
640 mOffsetAction
->setEnabled( !mRelativeScale
);
648 * save the ruler color to the config file
650 void KLineal::saveSettings()
652 RulerSettings::self()->setBgColor( mColor
);
653 RulerSettings::self()->setScaleFont( mScaleFont
);
654 RulerSettings::self()->setLength( mLongEdgeLen
);
655 RulerSettings::self()->setOrientation( mOrientation
);
656 RulerSettings::self()->setLeftToRight( mLeftToRight
);
657 RulerSettings::self()->setOffset( mOffset
);
658 RulerSettings::self()->setRelativeScale( mRelativeScale
);
659 RulerSettings::self()->writeConfig();
662 void KLineal::copyColor()
664 QApplication::clipboard()->setText( mColorLabel
->text() );
668 * lets the context menu appear at current cursor position
670 void KLineal::showMenu()
672 QPoint pos
= QCursor::pos();
677 * overwritten to switch the value label and line cursor on
679 void KLineal::enterEvent( QEvent
*inEvent
)
689 * overwritten to switch the value label and line cursor off
691 void KLineal::leaveEvent( QEvent
*inEvent
)
695 if ( !geometry().contains( QCursor::pos() ) ) {
701 * shows the value lable
703 void KLineal::showLabel()
708 if ( RulerSettings::self()->rotateButtonsVisible() ) {
709 mBtnRotateLeft
->show();
710 mBtnRotateRight
->show();
712 if ( mCloseButton
&& RulerSettings::self()->closeButtonVisible() ) {
713 mCloseButton
->show();
718 * hides the value label
720 void KLineal::hideLabel()
724 mBtnRotateLeft
->hide();
725 mBtnRotateRight
->hide();
726 if ( mCloseButton
) {
727 mCloseButton
->hide();
732 * updates the current value label
734 void KLineal::adjustLabel()
737 QPoint cpos
= QCursor::pos();
739 int digit
= ( mOrientation
== North
|| mOrientation
== South
) ? cpos
.x() - x() : cpos
.y() - y();
741 if ( !mRelativeScale
) {
742 if ( mLeftToRight
) {
745 digit
= mLongEdgeLen
- digit
+ mOffset
;
748 // INFO: Perhaps use float also for displaying relative value
749 digit
= (int)( ( digit
* 100.f
) / mLongEdgeLen
);
751 if ( !mLeftToRight
) {
756 s
.sprintf( "%d%s", digit
, ( mRelativeScale
? "%" : " px" ) );
757 mLabel
->setText( s
);
761 * Updates the position of the tool buttons
763 void KLineal::adjustButtons()
765 switch( mOrientation
) {
767 mBtnRotateLeft
->move( mLongEdgeLen
/ 2 - 28, height() - 31 );
768 mBtnRotateRight
->move( mLongEdgeLen
/ 2 + 2, height() - 31 );
769 if ( mCloseButton
) {
770 mCloseButton
->move( width() - 31, height() - 31 );
775 mBtnRotateLeft
->move( mLongEdgeLen
/ 2 - 28, 5 );
776 mBtnRotateRight
->move( mLongEdgeLen
/ 2 + 2, 5 );
777 if ( mCloseButton
) {
778 mCloseButton
->move( width() - 31, 5 );
783 mBtnRotateLeft
->move( 5, mLongEdgeLen
/ 2 - 28 );
784 mBtnRotateRight
->move( 5, mLongEdgeLen
/ 2 + 2 );
785 if ( mCloseButton
) {
786 mCloseButton
->move( 5, height() - 31 );
791 mBtnRotateLeft
->move( width() - 31, mLongEdgeLen
/ 2 - 28 );
792 mBtnRotateRight
->move( width() - 31, mLongEdgeLen
/ 2 + 2 );
793 if ( mCloseButton
) {
794 mCloseButton
->move( width() - 31, height() - 31 );
800 void KLineal::keyPressEvent( QKeyEvent
*e
)
804 switch ( e
->key() ) {
806 KToolInvocation::invokeHelp();
826 QWidget::keyPressEvent(e
);
830 if ( e
->modifiers() & Qt::ShiftModifier
) {
834 move( pos() + dist
);
835 KNotification::event( 0, "cursormove", QString() );
839 * overwritten to handle the line cursor which is a separate widget outside the main
840 * window. Also used for dragging.
842 void KLineal::mouseMoveEvent( QMouseEvent
*inEvent
)
846 if ( mDragging
&& this == mouseGrabber() && !RulerSettings::self()->nativeMoving() ) {
847 move( QCursor::pos() - mDragOffset
);
849 QPoint p
= QCursor::pos();
851 switch (mOrientation
) {
853 p
.setY( p
.y() - 46 );
857 p
.setX( p
.x() + 46 );
861 p
.setX( p
.x() - 46 );
865 p
.setY( p
.y() + 46 );
869 QColor color
= KColorDialog::grabColor( p
);
871 color
.getHsv( &h
, &s
, &v
);
872 mColorLabel
->setText( color
.name().toUpper() );
873 QPalette palette
= mColorLabel
->palette();
874 palette
.setColor( mColorLabel
->backgroundRole(), color
);
880 color
.setHsv( h
, s
, v
);
881 palette
.setColor( mColorLabel
->foregroundRole(), color
);
882 mColorLabel
->setPalette( palette
);
888 * overwritten for dragging and context menu
890 void KLineal::mousePressEvent( QMouseEvent
*inEvent
)
892 mLastClickPos
= QCursor::pos();
895 QRect gr
= geometry();
896 mDragOffset
= mLastClickPos
- QPoint( gr
.left(), gr
.top() );
897 if ( inEvent
->button() == Qt::LeftButton
) {
899 if ( RulerSettings::self()->nativeMoving() ) {
900 XUngrabPointer( QX11Info::display(), QX11Info::appTime() );
901 NETRootInfo
wm_root( QX11Info::display(), NET::WMMoveResize
);
902 wm_root
.moveResizeRequest( winId(), inEvent
->globalX(), inEvent
->globalY(), NET::Move
);
906 grabMouse( Qt::SizeAllCursor
);
912 } else if ( inEvent
->button() == Qt::MidButton
) {
915 } else if ( inEvent
->button() == Qt::RightButton
) {
921 * overwritten for dragging
923 void KLineal::mouseReleaseEvent( QMouseEvent
*inEvent
)
928 if ( RulerSettings::self()->nativeMoving() ) {
929 NETRootInfo
wm_root( QX11Info::display(), NET::WMMoveResize
);
930 wm_root
.moveResizeRequest( winId(), inEvent
->globalX(), inEvent
->globalY(), NET::MoveResizeCancel
);
944 void KLineal::wheelEvent( QWheelEvent
*e
)
946 int numDegrees
= e
->delta() / 8;
947 int numSteps
= numDegrees
/ 15;
950 if ( e
->buttons() == Qt::LeftButton
) {
951 if ( !mRelativeScale
) {
956 mLabel
->setText( i18n( "Offset: %1", mOffset
) );
959 } else { // changing length
960 int newLength
= mLongEdgeLen
+ numSteps
;
961 reLengthAbsolute( newLength
);
962 mLabel
->setText( i18n( "Length: %1 px", newLength
) );
965 QWidget::wheelEvent( e
);
969 * draws the scale according to the orientation
971 void KLineal::drawScale( QPainter
&painter
)
973 painter
.setPen( Qt::black
);
974 QFont font
= mScaleFont
;
975 painter
.setFont( font
);
976 QFontMetrics metrics
= painter
.fontMetrics();
982 // draw a frame around the whole thing
983 // (for some unknown reason, this doesn't show up anymore)
984 switch ( mOrientation
) {
989 painter
.drawLine( 0, 0, 0, h
- 1 );
990 painter
.drawLine( 0, h
- 1, w
- 1, h
- 1 );
991 painter
.drawLine( w
- 1, h
- 1, w
- 1, 0 );
997 painter
.drawLine( 0, 0, 0, h
- 1 );
998 painter
.drawLine( 0, h
- 1, w
- 1, h
- 1 );
999 painter
.drawLine( w
- 1, 0, 0, 0 );
1005 painter
.drawLine( 0, 0, 0, h
- 1 );
1006 painter
.drawLine( w
- 1, h
- 1, w
- 1, 0 );
1007 painter
.drawLine( w
- 1, 0, 0, 0 );
1013 painter
.drawLine( 0, h
- 1, w
- 1, h
- 1 );
1014 painter
.drawLine( w
- 1, h
- 1, w
- 1, 0 );
1015 painter
.drawLine( w
- 1, 0, 0, 0 );
1019 if ( !mRelativeScale
) {
1022 for ( int x
= 0; x
< longLen
; ++x
) {
1023 if ( mLeftToRight
) {
1024 digit
= x
+ mOffset
;
1026 digit
= longLen
- x
+ mOffset
;
1029 if ( digit
% 2 ) continue;
1033 if ( digit
% 10 == 0 ) len
= 10;
1034 if ( digit
% 20 == 0 ) len
= 15;
1035 if ( digit
% 100 == 0 ) len
= 18;
1037 if ( digit
% 20 == 0 ) {
1038 font
.setBold( digit
% 100 == 0 );
1039 painter
.setFont( font
);
1041 units
.sprintf( "%d", digit
);
1042 QSize textSize
= metrics
.size( Qt::TextSingleLine
, units
);
1043 int tw
= textSize
.width();
1044 int th
= textSize
.height();
1046 switch ( mOrientation
) {
1048 painter
.drawText( x
- tw
/ 2, shortStart
+ len
+ th
, units
);
1052 painter
.drawText( x
- tw
/ 2, shortStart
- len
- 2, units
);
1056 painter
.drawText( shortStart
- len
- tw
- 2, x
+ th
/ 2 - 2, units
);
1060 painter
.drawText( shortStart
+ len
+ 2, x
+ th
/ 2 - 2, units
);
1065 switch( mOrientation
) {
1067 painter
.drawLine( x
, shortStart
, x
, shortStart
+ len
);
1070 painter
.drawLine( x
, shortStart
, x
, shortStart
- len
);
1073 painter
.drawLine( shortStart
, x
, shortStart
- len
, x
);
1076 painter
.drawLine( shortStart
, x
, shortStart
+ len
, x
);
1081 float step
= longLen
/ 100.f
;
1084 font
.setBold( true );
1085 painter
.setFont( font
);
1087 for ( int i
= 0; i
<= 100; ++i
) {
1088 int x
= (int)( i
* step
);
1089 len
= ( i
% 10 ) ? 6 : 15;
1091 if ( i
% 10 == 0 ) {
1093 int value
= mLeftToRight
? i
: ( 100 - i
);
1094 units
.sprintf( "%d%%", value
);
1095 QSize textSize
= metrics
.size( Qt::TextSingleLine
, units
);
1096 int tw
= textSize
.width();
1097 int th
= textSize
.height();
1099 switch ( mOrientation
) {
1101 painter
.drawText( x
- tw
/ 2, shortStart
+ len
+ th
, units
);
1105 painter
.drawText( x
- tw
/ 2, shortStart
- len
- 2, units
);
1109 painter
.drawText( shortStart
- len
- tw
- 2, x
+ th
/ 2 - 2, units
);
1113 painter
.drawText( shortStart
+ len
+ 2, x
+ th
/ 2 - 2, units
);
1118 switch( mOrientation
) {
1120 painter
.drawLine( x
, shortStart
, x
, shortStart
+ len
);
1123 painter
.drawLine( x
, shortStart
, x
, shortStart
- len
);
1126 painter
.drawLine( shortStart
, x
, shortStart
- len
, x
);
1129 painter
.drawLine( shortStart
, x
, shortStart
+ len
, x
);
1137 * actually draws the ruler
1139 void KLineal::paintEvent(QPaintEvent
*inEvent
)
1141 Q_UNUSED( inEvent
);
1143 QPainter
painter( this );
1144 drawBackground( painter
);
1145 drawScale( painter
);
1148 #include "klineal.moc"