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 "krulersystemtray.h"
51 #include "qautosizelabel.h"
53 #include "ui_cfg_appearance.h"
54 #include "ui_cfg_advanced.h"
57 * this is our cursor bitmap:
58 * a line 48 pixels long with an arrow pointing down
59 * and a sqare with a one pixel hole at the top (end)
61 static const uchar cursorBits
[] = {
62 0x38, 0x28, 0x38, 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 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
67 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10,
71 * create the thingy with no borders and set up
74 KLineal::KLineal( QWidget
*parent
)
78 mLenMenu( 0 ), // INFO This member could be eventually deleted
79 // since if mFullScreenAction is initialized
80 // mLenMenu should have been, too.
81 mFullScreenAction( 0 ),
82 mScaleDirectionAction( 0 ),
83 mCenterOriginAction( 0 ),
86 mActionCollection( 0 ),
90 KWindowSystem::setType( winId(), NET::Override
); // or NET::Normal
91 KWindowSystem::setState( winId(), NET::KeepAbove
);
93 setAttribute( Qt::WA_TranslucentBackground
);
94 setWindowFlags( Qt::FramelessWindowHint
);
96 setMinimumSize( 60, 60 );
97 setMaximumSize( 8000, 8000 );
98 setWhatsThis( i18n( "This is a tool to measure pixel distances and colors on the screen. "
99 "It is useful for working on layouts of dialogs, web pages etc." ) );
100 setMouseTracking( true );
102 QBitmap bim
= QBitmap::fromData( QSize( 8, 48 ), cursorBits
, QImage::Format_Mono
);
105 mNorthCursor
= QCursor( bim
, bim
, 3, 47 );
106 bim
= bim
.transformed( m
);
107 mEastCursor
= QCursor( bim
, bim
, 0, 3 );
108 bim
= bim
.transformed( m
);
109 mSouthCursor
= QCursor( bim
, bim
, 4, 0 );
110 bim
= bim
.transformed( m
);
111 mWestCursor
= QCursor( bim
, bim
, 47, 4 );
113 mCurrentCursor
= mNorthCursor
;
114 mColor
= RulerSettings::self()->bgColor();
115 mScaleFont
= RulerSettings::self()->scaleFont();
116 mLongEdgeLen
= RulerSettings::self()->length();
117 mOrientation
= RulerSettings::self()->orientation();
118 mLeftToRight
= RulerSettings::self()->leftToRight();
119 mOffset
= RulerSettings::self()->offset();
120 mRelativeScale
= RulerSettings::self()->relativeScale();
122 mLabel
= new QAutoSizeLabel( this );
123 mLabel
->setGeometry( 0, height() - 12, 32, 12 );
124 QFont
labelFont( KGlobalSettings::generalFont().family(), 10 );
125 labelFont
.setPixelSize( 10 );
126 mLabel
->setFont( labelFont
);
127 mLabel
->setWhatsThis( i18n( "This is the current distance measured in pixels." ) );
128 mColorLabel
= new QAutoSizeLabel( this );
129 mColorLabel
->setAutoFillBackground( true );
130 QFont
colorFont( KGlobalSettings::fixedFont().family(), 10 );
131 colorFont
.setPixelSize( 10 );
132 mColorLabel
->setFont( colorFont
);
133 mColorLabel
->move( mLabel
->pos() + QPoint(0, 20) );
134 mColorLabel
->setWhatsThis(i18n("This is the current color in hexadecimal rgb representation"
135 " as you may use it in HTML or as a QColor name. "
136 "The rectangles background shows the color of the pixel inside the "
137 "little square at the end of the line cursor." ) );
139 mBtnRotateLeft
= new QToolButton( this );
140 mBtnRotateLeft
->setIcon( KIcon( "object-rotate-left" ) );
141 mBtnRotateLeft
->setToolTip( i18n( "Turn Left" ) );
142 connect( mBtnRotateLeft
, SIGNAL( clicked() ), this, SLOT( turnLeft() ) );
144 mBtnRotateRight
= new QToolButton( this );
145 mBtnRotateRight
->setIcon( KIcon( "object-rotate-right" ) );
146 mBtnRotateRight
->setToolTip( i18n( "Turn Right" ) );
147 connect( mBtnRotateRight
, SIGNAL( clicked() ), this, SLOT( turnRight() ) );
149 resize( QSize( mLongEdgeLen
, mShortEdgeLen
) );
151 //BEGIN setup menu and actions
152 mActionCollection
= new KActionCollection( this );
153 mActionCollection
->setConfigGroup( "Actions" );
155 mMenu
= new KMenu( this );
156 mMenu
->addTitle( i18n( "KRuler" ) );
157 KMenu
*oriMenu
= new KMenu( i18n( "&Orientation"), this );
158 addAction( oriMenu
, KIcon( "kruler-north" ), i18nc( "Turn Kruler North", "&North" ),
159 this, SLOT( setNorth() ), Qt::Key_N
, "turn_north" );
160 addAction( oriMenu
, KIcon( "kruler-east" ), i18nc( "Turn Kruler East", "&East" ),
161 this, SLOT( setEast() ), Qt::Key_E
, "turn_east" );
162 addAction( oriMenu
, KIcon( "kruler-south" ), i18nc( "Turn Kruler South", "&South" ),
163 this, SLOT( setSouth() ), Qt::Key_S
, "turn_south" );
164 addAction( oriMenu
, KIcon( "kruler-west" ), i18nc( "Turn Kruler West", "&West" ),
165 this, SLOT( setWest() ), Qt::Key_W
, "turn_west" );
166 addAction( oriMenu
, KIcon( "object-rotate-right" ), i18n( "&Turn Right" ),
167 this, SLOT( turnRight() ), Qt::Key_R
, "turn_right" );
168 addAction( oriMenu
, KIcon( "object-rotate-left" ), i18n( "Turn &Left" ),
169 this, SLOT( turnLeft() ), Qt::Key_L
, "turn_left" );
170 mMenu
->addMenu( oriMenu
);
172 mLenMenu
= new KMenu( i18n( "&Length" ), this );
173 addAction( mLenMenu
, KIcon(), i18nc( "Make Kruler Height Short", "&Short" ),
174 this, SLOT( setShortLength() ), Qt::CTRL
+ Qt::Key_S
, "length_short" );
175 addAction( mLenMenu
, KIcon(), i18nc( "Make Kruler Height Medium", "&Medium" ),
176 this, SLOT( setMediumLength() ), Qt::CTRL
+ Qt::Key_M
, "length_medium" );
177 addAction( mLenMenu
, KIcon(), i18nc( "Make Kruler Height Tall", "&Tall" ),
178 this, SLOT( setTallLength() ), Qt::CTRL
+ Qt::Key_T
, "length_tall" );
179 addAction( mLenMenu
, KIcon(), i18n("&Full Screen Width"),
180 this, SLOT( setFullLength() ), Qt::CTRL
+ Qt::Key_F
, "length_full_length" );
181 mLenMenu
->addSeparator();
182 addAction( mLenMenu
, KIcon(), i18n( "Length..." ),
183 this, SLOT( slotLength() ), QKeySequence(), "set_length" );
184 mMenu
->addMenu( mLenMenu
);
186 KMenu
* scaleMenu
= new KMenu( i18n( "&Scale" ), this );
187 mScaleDirectionAction
= addAction( scaleMenu
, KIcon(), i18n( "Right To Left" ),
188 this, SLOT( switchDirection() ), Qt::Key_D
, "right_to_left" );
189 mCenterOriginAction
= addAction( scaleMenu
, KIcon(), i18n( "Center origin" ),
190 this, SLOT( centerOrigin() ), Qt::Key_C
, "center_origin" );
191 mCenterOriginAction
->setEnabled( !mRelativeScale
);
192 mOffsetAction
= addAction( scaleMenu
, KIcon(), i18n( "Offset..." ),
193 this, SLOT( slotOffset() ), Qt::Key_O
, "set_offset" );
194 mOffsetAction
->setEnabled( !mRelativeScale
);
195 scaleMenu
->addSeparator();
196 KAction
*relativeScaleAction
= addAction( scaleMenu
, KIcon(), i18n( "Percentage" ),
197 0, 0, QKeySequence(), "toggle_percentage" );
198 relativeScaleAction
->setCheckable( true );
199 relativeScaleAction
->setChecked( mRelativeScale
);
200 connect( relativeScaleAction
, SIGNAL( toggled( bool ) ), this, SLOT( switchRelativeScale( bool ) ) );
201 mMenu
->addMenu( scaleMenu
);
203 mOpacity
= RulerSettings::self()->opacity();
204 KMenu
* opacityMenu
= new KMenu( i18n( "O&pacity" ), this );
205 QWidgetAction
*opacityAction
= new QWidgetAction( this );
206 QSlider
*slider
= new QSlider( this );
207 slider
->setMinimum( 0 );
208 slider
->setMaximum( 255 );
209 slider
->setSingleStep( 1 );
210 slider
->setOrientation( Qt::Horizontal
);
211 slider
->setValue( RulerSettings::self()->opacity() );
212 connect( slider
, SIGNAL( valueChanged( int ) ), this, SLOT( slotOpacity( int ) ) );
213 opacityAction
->setDefaultWidget( slider
);
214 opacityMenu
->addAction( opacityAction
);
215 mMenu
->addMenu( opacityMenu
);
217 KAction
*keyBindings
= KStandardAction::keyBindings( this, SLOT( slotKeyBindings() ), this );
218 mActionCollection
->addAction( "key_bindings", keyBindings
);
219 mMenu
->addAction( keyBindings
);
220 KAction
*preferences
= KStandardAction::preferences( this, SLOT( slotPreferences() ), this );
221 mActionCollection
->addAction( "preferences", preferences
);
222 mMenu
->addAction( preferences
);
223 mMenu
->addSeparator();
224 KAction
*copyColorAction
= KStandardAction::copy( this, SLOT( copyColor() ), this );
225 copyColorAction
->setText( i18n( "Copy Color" ) );
226 mActionCollection
->addAction( "copy_color", copyColorAction
);
227 mMenu
->addAction( copyColorAction
);
228 mMenu
->addSeparator();
229 mMenu
->addMenu( ( new KHelpMenu( this, KGlobal::mainComponent().aboutData(), true ) )->menu() );
230 mMenu
->addSeparator();
231 if ( RulerSettings::self()->trayIcon() ) {
235 KAction
*quit
= KStandardAction::quit( kapp
, SLOT( quit() ), this );
236 mActionCollection
->addAction( "quit", quit
);
237 mMenu
->addAction( quit
);
239 mActionCollection
->associateWidget( this );
240 mActionCollection
->readSettings();
242 mLastClickPos
= geometry().topLeft() + QPoint( width() / 2, height() / 2 );
245 setOrientation( mOrientation
);
253 void KLineal::createSystemTray()
255 KAction
*closeAction
= KStandardAction::close( this, SLOT( slotClose() ), this );
256 mActionCollection
->addAction( "close", closeAction
);
257 mMenu
->addAction( closeAction
);
259 mCloseButton
= new QToolButton( this );
260 mCloseButton
->setIcon( closeAction
->icon() );
261 mCloseButton
->setToolTip( closeAction
->text().remove( '&' ) );
262 connect( mCloseButton
, SIGNAL( clicked() ), this, SLOT( slotClose() ) );
263 mTrayIcon
= new KRulerSystemTray( KIcon( "kruler" ), this,mActionCollection
);
268 KAction
* KLineal::addAction( KMenu
*menu
, KIcon icon
, const QString
& text
,
269 const QObject
* receiver
, const char* member
,
270 const QKeySequence
&shortcut
, const QString
& name
)
272 KAction
*action
= new KAction( icon
, text
, mActionCollection
);
273 action
->setShortcut( shortcut
);
275 connect( action
, SIGNAL( triggered() ), receiver
, member
);
277 menu
->addAction( action
);
278 mActionCollection
->addAction( name
, action
);
282 void KLineal::slotClose()
287 void KLineal::slotQuit()
292 void KLineal::move( int x
, int y
)
294 move( QPoint( x
, y
) );
297 void KLineal::move(const QPoint
&p
)
299 setGeometry( QRect( p
, size() ) );
302 QPoint
KLineal::pos() const
304 return frameGeometry().topLeft();
307 int KLineal::x() const
312 int KLineal::y() const
317 void KLineal::drawBackground( QPainter
& painter
)
319 QColor a
, b
, bg
= mColor
;
320 QLinearGradient gradient
;
321 switch ( mOrientation
) {
325 gradient
= QLinearGradient( 1, 0, 1, height() );
331 gradient
= QLinearGradient( 1, 0, 1, height() );
337 gradient
= QLinearGradient( 0, 1, width(), 1 );
343 gradient
= QLinearGradient( 0, 1, width(), 1 );
346 a
.setAlpha( mOpacity
);
347 b
.setAlpha( mOpacity
);
348 gradient
.setColorAt( 0, a
);
349 gradient
.setColorAt( 1, b
);
350 painter
.fillRect( rect(), QBrush( gradient
) );
353 void KLineal::setOrientation( int inOrientation
)
355 QRect r
= frameGeometry();
356 int nineties
= (int)inOrientation
- (int)mOrientation
;
357 mOrientation
= ( inOrientation
+ 4 ) % 4;
358 QPoint center
= mLastClickPos
, newTopLeft
;
361 center
= mLastClickPos
;
364 center
= r
.topLeft() + QPoint( width() / 2, height() / 2 );
367 if ( nineties
% 2 ) {
368 newTopLeft
= QPoint( center
.x() - height() / 2, center
.y() - width() / 2 );
370 newTopLeft
= r
.topLeft();
373 if ( mOrientation
== North
|| mOrientation
== South
) {
374 r
.setSize( QSize( mLongEdgeLen
, mShortEdgeLen
) );
376 r
.setSize( QSize( mShortEdgeLen
, mLongEdgeLen
) );
379 r
.moveTo(newTopLeft
);
381 QRect desktop
= KGlobalSettings::desktopGeometry( this );
383 if ( r
.top() < desktop
.top() ) {
384 r
.moveTop( desktop
.top() );
387 if ( r
.bottom() > desktop
.bottom() ) {
388 r
.moveBottom( desktop
.bottom() );
391 if ( r
.left() < desktop
.left() ) {
392 r
.moveLeft( desktop
.left() );
395 if ( r
.right() > desktop
.right() ) {
396 r
.moveRight( desktop
.right() );
400 switch( mOrientation
) {
402 mLabel
->move( 4, height()-mLabel
->height() - 4 );
403 mColorLabel
->move( mLabel
->pos() + QPoint( 0, -20 ) );
404 mCurrentCursor
= mNorthCursor
;
408 mLabel
->move( 4, 4 );
409 mColorLabel
->move( mLabel
->pos() + QPoint( 0, 20 ) );
410 mCurrentCursor
= mSouthCursor
;
414 mLabel
->move( 4, 4 );
415 mColorLabel
->move( mLabel
->pos() + QPoint( 0, 20 ) );
416 mCurrentCursor
= mEastCursor
;
420 mLabel
->move( width()-mLabel
->width() - 4, 4 );
421 mColorLabel
->move( mLabel
->pos() + QPoint( -5, 20 ) );
422 mCurrentCursor
= mWestCursor
;
428 if ( mLenMenu
&& mFullScreenAction
) {
429 mFullScreenAction
->setText( mOrientation
% 2 ? i18n( "&Full Screen Height" ) : i18n( "&Full Screen Width" ) );
432 updateScaleDirectionMenuItem();
434 setCursor( mCurrentCursor
);
439 void KLineal::setNorth()
441 setOrientation( North
);
444 void KLineal::setEast()
446 setOrientation( East
);
449 void KLineal::setSouth()
451 setOrientation( South
);
454 void KLineal::setWest()
456 setOrientation( West
);
459 void KLineal::turnRight()
461 setOrientation( mOrientation
- 1 );
464 void KLineal::turnLeft()
466 setOrientation( mOrientation
+ 1 );
469 void KLineal::reLength( int percentOfScreen
)
471 if ( percentOfScreen
< 10 ) {
475 QRect r
= KGlobalSettings::desktopGeometry( this );
477 if ( mOrientation
== North
|| mOrientation
== South
) {
478 mLongEdgeLen
= r
.width() * percentOfScreen
/ 100;
479 resize( mLongEdgeLen
, height() );
481 mLongEdgeLen
= r
.height() * percentOfScreen
/ 100;
482 resize( width(), mLongEdgeLen
);
485 if ( x() + width() < 10 ) {
489 if ( y() + height() < 10 ) {
497 void KLineal::reLengthAbsolute( int length
)
499 if ( length
< 100 ) {
503 QRect r
= KGlobalSettings::desktopGeometry( this );
505 mLongEdgeLen
= length
;
506 if ( mOrientation
== North
|| mOrientation
== South
) {
507 resize( mLongEdgeLen
, height() );
509 resize( width(), mLongEdgeLen
);
512 if ( x() + width() < 10 ) {
516 if ( y() + height() < 10 ) {
524 void KLineal::updateScaleDirectionMenuItem()
526 if ( !mScaleDirectionAction
) return;
530 if ( mOrientation
== North
|| mOrientation
== South
) {
531 label
= mLeftToRight
? i18n( "Right To Left" ) : i18n( "Left To Right" );
533 label
= mLeftToRight
? i18n( "Bottom To Top" ) : i18n( "Top To Bottom" );
536 mScaleDirectionAction
->setText( label
);
539 void KLineal::setShortLength()
544 void KLineal::setMediumLength()
549 void KLineal::setTallLength()
554 void KLineal::setFullLength()
559 void KLineal::switchDirection()
561 mLeftToRight
= !mLeftToRight
;
562 updateScaleDirectionMenuItem();
568 void KLineal::centerOrigin()
570 mOffset
= -( mLongEdgeLen
/ 2 );
576 void KLineal::slotOffset()
579 int newOffset
= KInputDialog::getInteger( i18n( "Scale offset" ),
580 i18n( "Offset:" ), mOffset
,
581 -2147483647, 2147483647, 1, &ok
, this );
591 void KLineal::slotLength()
594 QRect r
= KGlobalSettings::desktopGeometry( this );
595 int width
= ( ( mOrientation
== North
) || ( mOrientation
== South
) ) ? r
.width() : r
.height();
596 int newLength
= KInputDialog::getInteger( i18n( "Ruler Length" ),
597 i18n( "Length:" ), mLongEdgeLen
,
598 0, width
, 1, &ok
, this );
601 reLengthAbsolute( newLength
);
605 void KLineal::slotOpacity( int value
)
609 RulerSettings::self()->setOpacity( value
);
610 RulerSettings::self()->writeConfig();
613 void KLineal::slotKeyBindings()
615 KShortcutsDialog::configure( mActionCollection
);
618 void KLineal::slotPreferences()
620 KConfigDialog
*dialog
= new KConfigDialog( this, "settings", RulerSettings::self() );
622 Ui::ConfigAppearance appearanceConfig
;
623 QWidget
*appearanceConfigWidget
= new QWidget( dialog
);
624 appearanceConfig
.setupUi( appearanceConfigWidget
);
625 appearanceConfig
.kcfg_CloseButtonVisible
->setEnabled( appearanceConfig
.kcfg_TrayIcon
->isChecked() );
626 dialog
->addPage( appearanceConfigWidget
, i18n( "Appearance" ), "preferences-desktop-default-applications" );
628 Ui::ConfigAdvanced advancedConfig
;
629 QWidget
*advancedConfigWidget
= new QWidget( dialog
);
630 advancedConfig
.setupUi( advancedConfigWidget
);
631 dialog
->addPage( advancedConfigWidget
, i18n( "Advanced" ), "preferences-other" );
633 connect(dialog
, SIGNAL(settingsChanged(const QString
&)), SLOT(loadConfig()));
638 void KLineal::loadConfig()
640 mColor
= RulerSettings::self()->bgColor();
641 mScaleFont
= RulerSettings::self()->scaleFont();
644 if ( RulerSettings::self()->trayIcon() ) {
647 //need to adjust button
662 void KLineal::switchRelativeScale( bool checked
)
664 mRelativeScale
= checked
;
666 mCenterOriginAction
->setEnabled( !mRelativeScale
);
667 mOffsetAction
->setEnabled( !mRelativeScale
);
675 * save the ruler color to the config file
677 void KLineal::saveSettings()
679 RulerSettings::self()->setBgColor( mColor
);
680 RulerSettings::self()->setScaleFont( mScaleFont
);
681 RulerSettings::self()->setLength( mLongEdgeLen
);
682 RulerSettings::self()->setOrientation( mOrientation
);
683 RulerSettings::self()->setLeftToRight( mLeftToRight
);
684 RulerSettings::self()->setOffset( mOffset
);
685 RulerSettings::self()->setRelativeScale( mRelativeScale
);
686 RulerSettings::self()->writeConfig();
689 void KLineal::copyColor()
691 QApplication::clipboard()->setText( mColorLabel
->text() );
695 * lets the context menu appear at current cursor position
697 void KLineal::showMenu()
699 QPoint pos
= QCursor::pos();
704 * overwritten to switch the value label and line cursor on
706 void KLineal::enterEvent( QEvent
*inEvent
)
716 * overwritten to switch the value label and line cursor off
718 void KLineal::leaveEvent( QEvent
*inEvent
)
722 if ( !geometry().contains( QCursor::pos() ) ) {
728 * shows the value lable
730 void KLineal::showLabel()
735 if ( RulerSettings::self()->rotateButtonsVisible() ) {
736 mBtnRotateLeft
->show();
737 mBtnRotateRight
->show();
740 RulerSettings::self()->closeButtonVisible() &&
741 RulerSettings::self()->trayIcon()) {
742 mCloseButton
->show();
747 * hides the value label
749 void KLineal::hideLabel()
753 mBtnRotateLeft
->hide();
754 mBtnRotateRight
->hide();
755 if ( mCloseButton
) {
756 mCloseButton
->hide();
761 * updates the current value label
763 void KLineal::adjustLabel()
766 QPoint cpos
= QCursor::pos();
768 int digit
= ( mOrientation
== North
|| mOrientation
== South
) ? cpos
.x() - x() : cpos
.y() - y();
770 if ( !mRelativeScale
) {
771 if ( mLeftToRight
) {
774 digit
= mLongEdgeLen
- digit
+ mOffset
;
777 // INFO: Perhaps use float also for displaying relative value
778 digit
= (int)( ( digit
* 100.f
) / mLongEdgeLen
);
780 if ( !mLeftToRight
) {
785 s
.sprintf( "%d%s", digit
, ( mRelativeScale
? "%" : " px" ) );
786 mLabel
->setText( s
);
790 * Updates the position of the tool buttons
792 void KLineal::adjustButtons()
794 switch( mOrientation
) {
796 mBtnRotateLeft
->move( mLongEdgeLen
/ 2 - 28, height() - 31 );
797 mBtnRotateRight
->move( mLongEdgeLen
/ 2 + 2, height() - 31 );
798 if ( mCloseButton
) {
799 mCloseButton
->move( width() - 31, height() - 31 );
804 mBtnRotateLeft
->move( mLongEdgeLen
/ 2 - 28, 5 );
805 mBtnRotateRight
->move( mLongEdgeLen
/ 2 + 2, 5 );
806 if ( mCloseButton
) {
807 mCloseButton
->move( width() - 31, 5 );
812 mBtnRotateLeft
->move( 5, mLongEdgeLen
/ 2 - 28 );
813 mBtnRotateRight
->move( 5, mLongEdgeLen
/ 2 + 2 );
814 if ( mCloseButton
) {
815 mCloseButton
->move( 5, height() - 31 );
820 mBtnRotateLeft
->move( width() - 31, mLongEdgeLen
/ 2 - 28 );
821 mBtnRotateRight
->move( width() - 31, mLongEdgeLen
/ 2 + 2 );
822 if ( mCloseButton
) {
823 mCloseButton
->move( width() - 31, height() - 31 );
829 void KLineal::keyPressEvent( QKeyEvent
*e
)
833 switch ( e
->key() ) {
835 KToolInvocation::invokeHelp();
855 QWidget::keyPressEvent(e
);
859 if ( e
->modifiers() & Qt::ShiftModifier
) {
863 move( pos() + dist
);
864 KNotification::event( 0, "cursormove", QString() );
868 * overwritten to handle the line cursor which is a separate widget outside the main
869 * window. Also used for dragging.
871 void KLineal::mouseMoveEvent( QMouseEvent
*inEvent
)
875 if ( mDragging
&& this == mouseGrabber() && !RulerSettings::self()->nativeMoving() ) {
876 move( QCursor::pos() - mDragOffset
);
878 QPoint p
= QCursor::pos();
880 switch (mOrientation
) {
882 p
.setY( p
.y() - 46 );
886 p
.setX( p
.x() + 46 );
890 p
.setX( p
.x() - 46 );
894 p
.setY( p
.y() + 46 );
898 QColor color
= KColorDialog::grabColor( p
);
900 color
.getHsv( &h
, &s
, &v
);
901 mColorLabel
->setText( color
.name().toUpper() );
902 QPalette palette
= mColorLabel
->palette();
903 palette
.setColor( mColorLabel
->backgroundRole(), color
);
909 color
.setHsv( h
, s
, v
);
910 palette
.setColor( mColorLabel
->foregroundRole(), color
);
911 mColorLabel
->setPalette( palette
);
917 * overwritten for dragging and context menu
919 void KLineal::mousePressEvent( QMouseEvent
*inEvent
)
921 mLastClickPos
= QCursor::pos();
924 QRect gr
= geometry();
925 mDragOffset
= mLastClickPos
- QPoint( gr
.left(), gr
.top() );
926 if ( inEvent
->button() == Qt::LeftButton
) {
928 if ( RulerSettings::self()->nativeMoving() ) {
929 XUngrabPointer( QX11Info::display(), QX11Info::appTime() );
930 NETRootInfo
wm_root( QX11Info::display(), NET::WMMoveResize
);
931 wm_root
.moveResizeRequest( winId(), inEvent
->globalX(), inEvent
->globalY(), NET::Move
);
935 grabMouse( Qt::SizeAllCursor
);
941 } else if ( inEvent
->button() == Qt::MidButton
) {
944 } else if ( inEvent
->button() == Qt::RightButton
) {
950 * overwritten for dragging
952 void KLineal::mouseReleaseEvent( QMouseEvent
*inEvent
)
957 if ( RulerSettings::self()->nativeMoving() ) {
958 NETRootInfo
wm_root( QX11Info::display(), NET::WMMoveResize
);
959 wm_root
.moveResizeRequest( winId(), inEvent
->globalX(), inEvent
->globalY(), NET::MoveResizeCancel
);
973 void KLineal::wheelEvent( QWheelEvent
*e
)
975 int numDegrees
= e
->delta() / 8;
976 int numSteps
= numDegrees
/ 15;
979 if ( e
->buttons() == Qt::LeftButton
) {
980 if ( !mRelativeScale
) {
985 mLabel
->setText( i18n( "Offset: %1", mOffset
) );
988 } else { // changing length
989 int newLength
= mLongEdgeLen
+ numSteps
;
990 reLengthAbsolute( newLength
);
991 mLabel
->setText( i18n( "Length: %1 px", newLength
) );
994 QWidget::wheelEvent( e
);
998 * draws the scale according to the orientation
1000 void KLineal::drawScale( QPainter
&painter
)
1002 painter
.setPen( Qt::black
);
1003 QFont font
= mScaleFont
;
1004 painter
.setFont( font
);
1005 QFontMetrics metrics
= painter
.fontMetrics();
1011 // draw a frame around the whole thing
1012 // (for some unknown reason, this doesn't show up anymore)
1013 switch ( mOrientation
) {
1018 painter
.drawLine( 0, 0, 0, h
- 1 );
1019 painter
.drawLine( 0, h
- 1, w
- 1, h
- 1 );
1020 painter
.drawLine( w
- 1, h
- 1, w
- 1, 0 );
1026 painter
.drawLine( 0, 0, 0, h
- 1 );
1027 painter
.drawLine( 0, h
- 1, w
- 1, h
- 1 );
1028 painter
.drawLine( w
- 1, 0, 0, 0 );
1034 painter
.drawLine( 0, 0, 0, h
- 1 );
1035 painter
.drawLine( w
- 1, h
- 1, w
- 1, 0 );
1036 painter
.drawLine( w
- 1, 0, 0, 0 );
1042 painter
.drawLine( 0, h
- 1, w
- 1, h
- 1 );
1043 painter
.drawLine( w
- 1, h
- 1, w
- 1, 0 );
1044 painter
.drawLine( w
- 1, 0, 0, 0 );
1048 if ( !mRelativeScale
) {
1051 for ( int x
= 0; x
< longLen
; ++x
) {
1052 if ( mLeftToRight
) {
1053 digit
= x
+ mOffset
;
1055 digit
= longLen
- x
+ mOffset
;
1058 if ( digit
% 2 ) continue;
1062 if ( digit
% 10 == 0 ) len
= 10;
1063 if ( digit
% 20 == 0 ) len
= 15;
1064 if ( digit
% 100 == 0 ) len
= 18;
1066 if ( digit
% 20 == 0 ) {
1067 font
.setBold( digit
% 100 == 0 );
1068 painter
.setFont( font
);
1070 units
.sprintf( "%d", digit
);
1071 QSize textSize
= metrics
.size( Qt::TextSingleLine
, units
);
1072 int tw
= textSize
.width();
1073 int th
= textSize
.height();
1075 switch ( mOrientation
) {
1077 painter
.drawText( x
- tw
/ 2, shortStart
+ len
+ th
, units
);
1081 painter
.drawText( x
- tw
/ 2, shortStart
- len
- 2, units
);
1085 painter
.drawText( shortStart
- len
- tw
- 2, x
+ th
/ 2 - 2, units
);
1089 painter
.drawText( shortStart
+ len
+ 2, x
+ th
/ 2 - 2, units
);
1094 switch( mOrientation
) {
1096 painter
.drawLine( x
, shortStart
, x
, shortStart
+ len
);
1099 painter
.drawLine( x
, shortStart
, x
, shortStart
- len
);
1102 painter
.drawLine( shortStart
, x
, shortStart
- len
, x
);
1105 painter
.drawLine( shortStart
, x
, shortStart
+ len
, x
);
1110 float step
= longLen
/ 100.f
;
1113 font
.setBold( true );
1114 painter
.setFont( font
);
1116 for ( int i
= 0; i
<= 100; ++i
) {
1117 int x
= (int)( i
* step
);
1118 len
= ( i
% 10 ) ? 6 : 15;
1120 if ( i
% 10 == 0 ) {
1122 int value
= mLeftToRight
? i
: ( 100 - i
);
1123 units
.sprintf( "%d%%", value
);
1124 QSize textSize
= metrics
.size( Qt::TextSingleLine
, units
);
1125 int tw
= textSize
.width();
1126 int th
= textSize
.height();
1128 switch ( mOrientation
) {
1130 painter
.drawText( x
- tw
/ 2, shortStart
+ len
+ th
, units
);
1134 painter
.drawText( x
- tw
/ 2, shortStart
- len
- 2, units
);
1138 painter
.drawText( shortStart
- len
- tw
- 2, x
+ th
/ 2 - 2, units
);
1142 painter
.drawText( shortStart
+ len
+ 2, x
+ th
/ 2 - 2, units
);
1147 switch( mOrientation
) {
1149 painter
.drawLine( x
, shortStart
, x
, shortStart
+ len
);
1152 painter
.drawLine( x
, shortStart
, x
, shortStart
- len
);
1155 painter
.drawLine( shortStart
, x
, shortStart
- len
, x
);
1158 painter
.drawLine( shortStart
, x
, shortStart
+ len
, x
);
1166 * actually draws the ruler
1168 void KLineal::paintEvent(QPaintEvent
*inEvent
)
1170 Q_UNUSED( inEvent
);
1172 QPainter
painter( this );
1173 drawBackground( painter
);
1174 drawScale( painter
);
1177 #include "klineal.moc"