klineal.cpp 21.9 KB
Newer Older
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
1 2 3
/***************************************************************************
                          klineal.cpp  -  description
                             -------------------
4 5 6
    Begin                : Fri Oct 13 2000
    Copyright            : 2000 by Till Krech
    Email                : till@snafu.de
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
7 8 9 10 11 12 13 14 15 16 17
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

Pino Toscano's avatar
Pino Toscano committed
18 19
#include "klineal.h"

Urs Wolfer's avatar
Urs Wolfer committed
20
#include <QBitmap>
21
#include <QBrush>
Urs Wolfer's avatar
Urs Wolfer committed
22 23 24
#include <QPainter>
#include <QMouseEvent>
#include <QLabel>
Laurent Montel's avatar
Laurent Montel committed
25
#include <QShortcut>
Andreas Simon's avatar
Andreas Simon committed
26

Mathias Soeken's avatar
Mathias Soeken committed
27
#include <KAction>
Mathias Soeken's avatar
Mathias Soeken committed
28
#include <KApplication>
Mathias Soeken's avatar
Mathias Soeken committed
29 30
#include <KConfig>
#include <KCursor>
Mathias Soeken's avatar
Mathias Soeken committed
31
#include <KFontDialog>
Mathias Soeken's avatar
Mathias Soeken committed
32 33
#include <KGlobalSettings>
#include <KHelpMenu>
Mathias Soeken's avatar
Mathias Soeken committed
34
#include <KIconLoader>
Mathias Soeken's avatar
Mathias Soeken committed
35
#include <KLocale>
Mathias Soeken's avatar
Mathias Soeken committed
36
#include <KMenu>
Mathias Soeken's avatar
Mathias Soeken committed
37
#include <KNotification>
Mathias Soeken's avatar
Mathias Soeken committed
38
#include <KStandardAction>
Mathias Soeken's avatar
Mathias Soeken committed
39
#include <KToolInvocation>
Mathias Soeken's avatar
Mathias Soeken committed
40
#include <KWindowSystem>
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
41

42
#define CFG_KEY_BGCOLOR "BgColor"
43 44
#define CFG_KEY_SCALE_FONT "ScaleFont"
#define CFG_KEY_LENGTH "Length"
45
#define CFG_GROUP_SETTINGS "StoredSettings"
46
#define DEFAULT_RULER_COLOR QColor(255, 200, 80)
47
#define FULLSCREENID 23
Urs Wolfer's avatar
Urs Wolfer committed
48

Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
/**
* this is our cursor bitmap:
* a line 48 pixels long with an arrow pointing down
* and a sqare with a one pixel hole at the top (end)
*/
static const uchar cursorBits[] = {
  0x38, 0x28, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10,
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x10,
};

/**
Mathias Soeken's avatar
Mathias Soeken committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
 * create the thingy with no borders and set up
 * its members
 */
KLineal::KLineal( QWidget*parent )
  : QWidget( parent ),
    mDragging( false ),
    mOrientation( South ),
    mShortEdgeLen( 70 ),    
    mLenMenu( 0 ),
    mColorSelector( this ),
    _clicked( false )
{
  KWindowSystem::setType( winId(), NET::Override );   // or NET::Normal
  KWindowSystem::setState( winId(), NET::KeepAbove );
  
  setMinimumSize(60,60);
  setMaximumSize(8000,8000);
  setWhatsThis( i18n( "This is a tool to measure pixel distances and colors on the screen. "
                      "It is useful for working on layouts of dialogs, web pages etc." ) );
  setMouseTracking( true );
 
  QBitmap bim = QBitmap::fromData( QSize( 8, 48 ), cursorBits, QImage::Format_Mono );
86
  QMatrix m;
Mathias Soeken's avatar
Mathias Soeken committed
87 88 89 90 91 92 93 94
  m.rotate( 90.0 );
  mNorthCursor = QCursor( bim, bim, 3, 47 );
  bim = bim.transformed( m );
  mEastCursor = QCursor( bim, bim, 0, 3 );
  bim = bim.transformed( m );
  mSouthCursor = QCursor( bim, bim, 4, 0 );
  bim = bim.transformed( m );
  mWestCursor = QCursor( bim, bim, 47, 4 );
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
95 96

  mCurrentCursor = mNorthCursor;
97
  KSharedConfig::Ptr cfg = KGlobal::config();
98
  QColor defaultColor = DEFAULT_RULER_COLOR;
Mathias Soeken's avatar
Mathias Soeken committed
99 100 101 102 103 104 105 106 107 108 109
  QFont defaultFont( KGlobalSettings::generalFont().family(), 8 );
  defaultFont.setPixelSize( 8 );
  if ( cfg ) {
    KConfigGroup cfgcg( cfg, CFG_GROUP_SETTINGS );
    mColor = cfgcg.readEntry( CFG_KEY_BGCOLOR, defaultColor );
    mScaleFont = cfgcg.readEntry( CFG_KEY_SCALE_FONT, defaultFont );
    mLongEdgeLen = cfgcg.readEntry( CFG_KEY_LENGTH, 600 );
  } else {
    mColor = defaultColor;
    mScaleFont = defaultFont;
    mLongEdgeLen = 400;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
110
  }
Mathias Soeken's avatar
Mathias Soeken committed
111 112 113 114 115 116 117 118 119 120

  mLabel = new QLabel( this );
  mLabel->setGeometry( 0, height() - 12, 32, 12 );
  QFont labelFont( KGlobalSettings::generalFont().family(), 10 );
  labelFont.setPixelSize( 10 );
  mLabel->setFont( labelFont );
  mLabel->setWhatsThis( i18n( "This is the current distance measured in pixels." ) );
  mColorLabel = new QLabel( this );
  mColorLabel->setAutoFillBackground( true );
  mColorLabel->resize( 45, 12 );
121
  mColorLabel->hide();
Mathias Soeken's avatar
Mathias Soeken committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135
  QFont colorFont( KGlobalSettings::fixedFont().family(), 10 );
  colorFont.setPixelSize( 10 );
  mColorLabel->setFont( colorFont );
  mColorLabel->move( mLabel->pos() + QPoint(0, 20) );
  mColorLabel->setWhatsThis(i18n("This is the current color in hexadecimal rgb representation"
                                 " as you may use it in HTML or as a QColor name. "
                                 "The rectangles background shows the color of the pixel inside the "
                                 "little square at the end of the line cursor." ) );

  resize( QSize( mLongEdgeLen, mShortEdgeLen ) );
  setOrientation( South );

  mMenu = new KMenu( this );
  mMenu->addTitle( i18n( "KRuler" ) );
136
  KMenu *oriMenu = new KMenu( i18n( "&Orientation"), this );
Mathias Soeken's avatar
Mathias Soeken committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
  oriMenu->addAction( KIcon( "kruler-north" ),
                      i18nc( "Turn Kruler North", "&North" ),
                      this, SLOT( setNorth() ), Qt::Key_N );
  oriMenu->addAction( KIcon( "kruler-east" ),
                      i18nc( "Turn Kruler East", "&East" ),
                      this, SLOT( setEast() ), Qt::Key_E );
  oriMenu->addAction( KIcon( "kruler-south" ),
                      i18nc( "Turn Kruler South", "&South" ),
                      this, SLOT( setSouth() ), Qt::Key_S );
  oriMenu->addAction( KIcon( "kruler-west" ),
                      i18nc( "Turn Kruler West", "&West" ),
                      this, SLOT( setWest() ), Qt::Key_W );
  oriMenu->addAction( KIcon( "object-rotate-right" ),
                      i18n( "&Turn Right" ),
                      this, SLOT( turnRight() ), Qt::Key_R );
  oriMenu->addAction( KIcon( "object-rotate-left" ),
                      i18n( "Turn &Left" ),
                      this, SLOT( turnLeft() ), Qt::Key_L );

  new QShortcut( Qt::Key_N, this, SLOT( setNorth() ) );
  new QShortcut( Qt::Key_E, this, SLOT( setEast() ) );
  new QShortcut( Qt::Key_S, this, SLOT( setSouth() ) );
  new QShortcut( Qt::Key_W, this, SLOT( setWest() ) );
  new QShortcut( Qt::Key_R, this, SLOT( turnRight() ) );
  new QShortcut( Qt::Key_L, this, SLOT( turnLeft() ) );
  mMenu->addMenu( oriMenu );
  mLenMenu = new KMenu( i18n( "&Length" ), this );
  mLenMenu->addAction( i18nc( "Make Kruler Height Short", "&Short" ),
                       this, SLOT( setShortLength() ), Qt::CTRL + Qt::Key_S );
  mLenMenu->addAction( i18nc( "Make Kruler Height Medium", "&Medium" ),
                       this, SLOT( setMediumLength() ), Qt::CTRL + Qt::Key_M );
  mLenMenu->addAction( i18nc( "Make Kruler Height Tall", "&Tall" ),
                       this, SLOT( setTallLength() ), Qt::CTRL + Qt::Key_T );
  mFullScreenAction = mLenMenu->addAction( i18n("&Full Screen Width"),
                                           this, SLOT( setFullLength() ),
                                           Qt::CTRL + Qt::Key_F );
  new QShortcut( Qt::CTRL + Qt::Key_S, this, SLOT( setShortLength() ) );
  new QShortcut( Qt::CTRL + Qt::Key_M, this, SLOT( setMediumLength() ) );
  new QShortcut( Qt::CTRL + Qt::Key_T, this, SLOT( setTallLength() ) );
  new QShortcut( Qt::CTRL + Qt::Key_F, this, SLOT( setFullLength() ) );
  mMenu->addMenu( mLenMenu );
  mMenu->addAction( KIcon( "preferences-desktop-color" ),
179
                    i18n( "&Choose Color..." ), this, SLOT( choseColor() ),
Mathias Soeken's avatar
Mathias Soeken committed
180 181
                    Qt::CTRL + Qt::Key_C );
  mMenu->addAction( KIcon( "preferences-desktop-font" ),
182
                    i18n( "Choose &Font..." ), this, SLOT( choseFont() ),
Mathias Soeken's avatar
Mathias Soeken committed
183
                    Qt::Key_F );
184 185
  new QShortcut(Qt::CTRL + Qt::Key_C, this, SLOT(choseColor() ) );
  new QShortcut(Qt::Key_F, this, SLOT( choseFont() ) );
Pascal Létourneau's avatar
porting  
Pascal Létourneau committed
186
  mMenu->addSeparator();
Mathias Soeken's avatar
Mathias Soeken committed
187
  mMenu->addMenu( ( new KHelpMenu( this, KGlobal::mainComponent().aboutData(), true ) )->menu() );
Pascal Létourneau's avatar
porting  
Pascal Létourneau committed
188
  mMenu->addSeparator();
Mathias Soeken's avatar
Mathias Soeken committed
189

Mathias Soeken's avatar
Mathias Soeken committed
190 191 192
  KAction *quit = KStandardAction::quit( kapp, SLOT( quit() ), this );
  mMenu->addAction( quit );
  new QShortcut( quit->shortcut().primary(), this, SLOT(slotQuit() ) );
Mathias Soeken's avatar
Mathias Soeken committed
193

Mathias Soeken's avatar
Mathias Soeken committed
194
  mLastClickPos = geometry().topLeft() + QPoint( width() / 2, height() / 2 );
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
195
}
196

Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
197 198 199
KLineal::~KLineal(){
}

Laurent Montel's avatar
Laurent Montel committed
200 201 202 203 204
void KLineal::slotQuit()
{
   kapp->quit();
}

Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
205 206 207 208 209 210 211 212 213
void KLineal::move(int x, int y) {
  move(QPoint(x, y));
}

void KLineal::move(const QPoint &p) {
  setGeometry(QRect(p, size()));
}

QPoint KLineal::pos() {
214
  QRect r = frameGeometry();
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
215 216 217 218 219 220 221 222 223
  return r.topLeft();
}
int KLineal::x() {
  return pos().x();
}
int KLineal::y() {
  return pos().y();
}

224
void KLineal::drawBackground(QPainter& painter) {
225
  QColor a, b, bg = mColor;
226
  QLinearGradient gradient;
227 228 229 230
  switch (mOrientation) {
    case North:
      a = bg.light(120);
      b = bg.dark(130);
231
      gradient = QLinearGradient(1, 0, 1, height());
232 233 234 235
      break;
    case South:
      b = bg.light(120);
      a = bg.dark(130);
236
      gradient = QLinearGradient(1, 0, 1, height());
237 238 239 240
      break;
    case West:
      a = bg.light(120);
      b = bg.dark(130);
241
      gradient = QLinearGradient(0, 1, width(), 1);
242 243 244 245
      break;
    case East:
      b = bg.light(120);
      a = bg.dark(130);
246
      gradient = QLinearGradient(0, 1, width(), 1);
247 248
      break;
  }
249 250
  gradient.setColorAt(0, a);
  gradient.setColorAt(1, b);
251
  painter.fillRect(rect(), QBrush(gradient));
252 253
}

254
void KLineal::setOrientation( int inOrientation ) {
255
  QRect r = frameGeometry();
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
256
  int nineties = (int)inOrientation - (int)mOrientation;
257
  mOrientation = ( inOrientation + 4 ) % 4;
258
  QPoint center = mLastClickPos, newTopLeft;
Laurent Montel's avatar
Laurent Montel committed
259

260
  if ( _clicked ) {
Ryan Cumming's avatar
Ryan Cumming committed
261 262
    center = mLastClickPos;
    _clicked = false;
263 264 265
  } else {
    center = r.topLeft() + QPoint( width() / 2, height() / 2 );
  }
Urs Wolfer's avatar
Urs Wolfer committed
266

267 268
  if ( nineties % 2 ) {
    newTopLeft = QPoint( center.x() - height() / 2, center.y() - width() / 2 );
269 270 271 272
  } else {
    newTopLeft = r.topLeft();
  }

273 274 275 276 277 278
  if ( mOrientation == North || mOrientation == South ) {
    r.setSize( QSize( mLongEdgeLen, mShortEdgeLen ) );
  } else {
    r.setSize( QSize( mShortEdgeLen, mLongEdgeLen ) );
  }

279
  r.moveTo(newTopLeft);
280

281 282 283
  QRect desktop = KGlobalSettings::desktopGeometry( this );

  if ( r.top() < desktop.top() ) {
284
     r.moveTop( desktop.top() );
285 286 287
  }

  if ( r.bottom() > desktop.bottom() ) {
288
     r.moveBottom( desktop.bottom() );
289 290 291
  }

  if ( r.left() < desktop.left() ) {
292
     r.moveLeft( desktop.left() );
293
  }
294

295 296 297 298 299 300
  if ( r.right() > desktop.right() ) {
    r.moveRight( desktop.right() );
  }

  setGeometry( r );
  switch( mOrientation ) {
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
301
  case North:
302 303
    mLabel->move( 4, height()-mLabel->height() - 4 );
    mColorLabel->move( mLabel->pos() + QPoint( 0, -20 ) );
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
304 305 306
    mCurrentCursor = mNorthCursor;
    break;
  case South:
307 308
    mLabel->move( 4, 4 );
    mColorLabel->move( mLabel->pos() + QPoint( 0, 20 ) );
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
309 310 311
    mCurrentCursor = mSouthCursor;
    break;
  case East:
312 313
    mLabel->move( 4, 4 );
    mColorLabel->move( mLabel->pos() + QPoint( 0, 20 ) );
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
314 315 316
    mCurrentCursor = mEastCursor;
    break;
  case West:
317 318
    mLabel->move( width()-mLabel->width() - 4, 4 );
    mColorLabel->move( mLabel->pos() + QPoint( -5, 20 ) );
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
319 320 321
    mCurrentCursor = mWestCursor;
    break;
  }
322 323 324 325
  if ( mLenMenu ) {
    if (mFullScreenAction) {
      mFullScreenAction->setText( mOrientation % 2 ? i18n( "&Full Screen Height" ) : i18n( "&Full Screen Width" ) );
    }
Pascal Létourneau's avatar
porting  
Pascal Létourneau committed
326
  }
327
  setCursor( mCurrentCursor );
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
328 329
  repaint();
}
330

Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
void KLineal::setNorth() {
  setOrientation(North);
}
void KLineal::setEast() {
  setOrientation(East);
}
void KLineal::setSouth() {
  setOrientation(South);
}
void KLineal::setWest() {
  setOrientation(West);
}
void KLineal::turnRight() {
  setOrientation(mOrientation - 1);
}
void KLineal::turnLeft() {
  setOrientation(mOrientation + 1);
}
void KLineal::reLength(int percentOfScreen) {
  if (percentOfScreen < 10) {
    return;
  }
George Staikos's avatar
George Staikos committed
353
  QRect r = KGlobalSettings::desktopGeometry(this);
George Staikos's avatar
George Staikos committed
354

Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
355
  if (mOrientation == North || mOrientation == South) {
George Staikos's avatar
George Staikos committed
356
    mLongEdgeLen = r.width() * percentOfScreen / 100;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
357 358
    resize(mLongEdgeLen, height());
  } else {
George Staikos's avatar
George Staikos committed
359
    mLongEdgeLen = r.height() * percentOfScreen / 100;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
360 361 362 363 364 365 366 367
    resize(width(), mLongEdgeLen);
  }
  if (x()+width() < 10) {
    move (10, y());
  }
  if (y()+height() < 10) {
    move (x(), 10);
  }
368
  saveSettings();
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
369 370 371 372 373 374 375 376 377 378 379 380 381
}
void KLineal::setShortLength() {
  reLength(30);
}
void KLineal::setMediumLength() {
  reLength(50);
}
void KLineal::setTallLength() {
  reLength(75);
}
void KLineal::setFullLength() {
  reLength(100);
}
382 383
void KLineal::choseColor() {
  QRect r = KGlobalSettings::desktopGeometry(this);
George Staikos's avatar
George Staikos committed
384 385

  QPoint pos = QCursor::pos();
386 387
  if (pos.x() + mColorSelector.width() > r.width()) {
    pos.setX(r.width() - mColorSelector.width());
George Staikos's avatar
George Staikos committed
388
  }
389 390
  if (pos.y() + mColorSelector.height() > r.height()) {
    pos.setY(r.height() - mColorSelector.height());
George Staikos's avatar
George Staikos committed
391
  }
392
  mStoredColor = mColor;
393 394
  mColorSelector.move(pos);
  mColorSelector.setColor(mColor);
395 396
  mColorSelector.setDefaultColor( DEFAULT_RULER_COLOR );
  mColorSelector.show();
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
397

398 399 400 401 402 403
  connect(&mColorSelector, SIGNAL(closeClicked()), this, SLOT(setColor()));
  connect(&mColorSelector, SIGNAL(colorSelected(const QColor&)), this, SLOT(setColor(const QColor&)));
	/*
  connect(&mColorSelector, SIGNAL(cancelPressed()), this, SLOT(restoreColor()));
  connect(&mColorSelector, SIGNAL(okPressed()), this, SLOT(saveColor()));
  */
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
404
}
405

406
/**
407 408 409
* slot to choose a font
*/
void KLineal::choseFont() {
410
  QFont font = mScaleFont;
411 412 413
  int result = KFontDialog::getFont(font, false, this);
  if (result == KFontDialog::Accepted) {
    setFont(font);
414 415 416 417
  }
}

/**
418 419 420 421 422
* set the ruler color to the previously selected color
*/
void KLineal::setFont(QFont &font) {
	mScaleFont = font;
	saveSettings();
423 424 425 426
  repaint();
}


427
/**
428 429
* set the ruler color to the previously selected color
*/
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
430
void KLineal::setColor() {
431 432
	setColor(mColorSelector.color());
	saveSettings();
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
433 434
}

435
/**
436 437
* set the ruler color to some color
*/
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
438
void KLineal::setColor(const QColor &color) {
439
  mColor = color;
440
  if ( !mColor.isValid() )
441
    mColor = DEFAULT_RULER_COLOR;
Eike Hein's avatar
Eike Hein committed
442 443

  repaint();
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
444
}
445 446

/**
447 448
* save the ruler color to the config file
*/
449
void KLineal::saveSettings() {
450
  KSharedConfig::Ptr cfg = KGlobal::config(); // new KConfig(locateLocal("config", kapp->name()+"rc"));
451 452 453 454 455 456 457
  if (cfg) {
      QColor color = mColor;
      KConfigGroup cfgcg(cfg, CFG_GROUP_SETTINGS);
      cfgcg.writeEntry(QString(CFG_KEY_BGCOLOR), color);
      cfgcg.writeEntry(QString(CFG_KEY_SCALE_FONT), mScaleFont);
      cfgcg.writeEntry(QString(CFG_KEY_LENGTH), mLongEdgeLen);
      cfg->sync();
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
458 459
  }
}
460

Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
461 462 463 464 465 466 467 468 469 470
/**
* restores the color
*/
void KLineal::restoreColor() {
  setColor(mStoredColor);
}
/**
* lets the context menu appear at current cursor position
*/
void KLineal::showMenu() {
Urs Wolfer's avatar
Urs Wolfer committed
471 472
  QPoint pos = QCursor::pos();
  mMenu->popup(pos);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
473
}
474

Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
/**
* overwritten to switch the value label and line cursor on
*/
void KLineal::enterEvent(QEvent * /*inEvent*/) {
  if (!mDragging) showLabel();
}
/**
* overwritten to switch the value label and line cursor off
*/
void KLineal::leaveEvent(QEvent * /*inEvent*/) {
  if (!geometry().contains(QCursor::pos())) {
    hideLabel();
  }
}
/**
* shows the value lable
*/
void KLineal::showLabel() {
  adjustLabel();
  mLabel->show();
  mColorLabel->show();
}
/**
* hides the value label
*/
void KLineal::hideLabel() {
  mLabel->hide();
  mColorLabel->hide();
}
/**
* updates the current value label
*/
void KLineal::adjustLabel() {
  QString s;
  QPoint cpos = QCursor::pos();
  switch (mOrientation) {
  case North:
512
    s.sprintf("%d px", cpos.x()-x());
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
513 514
    break;
  case East:
515
    s.sprintf("%d px", cpos.y()-y());
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
516 517
    break;
  case West:
518
    s.sprintf("%d px", cpos.y()-y());
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
519 520
    break;
  case South:
521
    s.sprintf("%d px", cpos.x()-x());
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
522 523 524 525
    break;
  }
  mLabel->setText(s);
}
526
void KLineal::keyPressEvent(QKeyEvent *e) {
Urs Wolfer's avatar
Urs Wolfer committed
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
  QPoint dist(0,0);
  switch (e->key()) {
  case Qt::Key_F1:
    KToolInvocation::invokeHelp();
    break;
  case Qt::Key_Left:
    dist.setX(-1);
    break;
  case Qt::Key_Right:
    dist.setX(1);
    break;
  case Qt::Key_Up:
    dist.setY(-1);
    break;
  case Qt::Key_Down:
    dist.setY(1);
    break;
  default:
    QWidget::keyPressEvent(e);
    return;
  }
  if (e->modifiers() & Qt::ShiftModifier) {
    dist *= 10;
550 551
  }
  move(pos()+dist);
Pascal Létourneau's avatar
porting  
Pascal Létourneau committed
552
  KNotification::event(0, "cursormove",  QString());
553
}
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
554
/**
Thorsten Roeder's avatar
Thorsten Roeder committed
555
* overwritten to handle the line cursor which is a separate widget outside the main
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
556 557 558 559 560 561
* window. Also used for dragging.
*/
void KLineal::mouseMoveEvent(QMouseEvent * /*inEvent*/) {
  if (mDragging && this == mouseGrabber()) {
    move(QCursor::pos() - mDragOffset);
  } else {
Urs Wolfer's avatar
Urs Wolfer committed
562 563
  QPoint p = QCursor::pos();
  switch (mOrientation) {
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
564
    case North:
Urs Wolfer's avatar
Urs Wolfer committed
565 566
        p.setY(p.y()-46);
        break;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
567
    case East:
Urs Wolfer's avatar
Urs Wolfer committed
568 569
        p.setX(p.x()+46);
        break;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
570
    case West:
Urs Wolfer's avatar
Urs Wolfer committed
571 572
        p.setX(p.x()-46);
        break;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
573
    case South:
Urs Wolfer's avatar
Urs Wolfer committed
574 575
        p.setY(p.y()+46);
        break;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
576 577 578 579
    }
    // cerr << p.x()-x() << "," << p.y()-y() << ": " << KColorDialog::grabColor(p).name() << endl;
    QColor color = KColorDialog::grabColor(p);
    int h, s, v;
Pascal Létourneau's avatar
porting  
Pascal Létourneau committed
580 581 582 583
    color.getHsv(&h, &s, &v);
    mColorLabel->setText(color.name().toUpper());
    QPalette palette = mColorLabel->palette();
    palette.setColor(mColorLabel->backgroundRole(), color);
Urs Wolfer's avatar
Urs Wolfer committed
584 585 586 587 588
    if (v < 255/2) {
        v = 255;
    } else {
        v = 0;
    }
Pascal Létourneau's avatar
porting  
Pascal Létourneau committed
589 590 591
    color.setHsv(h, s, v);
    palette.setColor(mColorLabel->foregroundRole(), color);
    mColorLabel->setPalette(palette);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
592 593 594 595 596 597 598 599 600 601 602 603 604
    adjustLabel();
  }
}

/**
* overwritten for dragging and contect menu
*/
void KLineal::mousePressEvent(QMouseEvent *inEvent) {
  mLastClickPos = QCursor::pos();
  hideLabel();

  QRect gr = geometry();
  mDragOffset = mLastClickPos - QPoint(gr.left(), gr.top());
605
  if (inEvent->button() == Qt::LeftButton) {
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
606
    if (!mDragging) {
Laurent Montel's avatar
Laurent Montel committed
607
      grabMouse(Qt::SizeAllCursor);
Thorsten Roeder's avatar
Thorsten Roeder committed
608
      mDragging = true;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
609
    }
610
  } else if (inEvent->button() == Qt::MidButton) {
Urs Wolfer's avatar
Urs Wolfer committed
611
    _clicked = true;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
612
    turnLeft();
613
  } else if (inEvent->button() == Qt::RightButton) {
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
614 615 616 617 618 619 620 621
    showMenu();
  }
}
/**
* overwritten for dragging
*/
void KLineal::mouseReleaseEvent(QMouseEvent * /*inEvent*/) {
  if (mDragging) {
Thorsten Roeder's avatar
Thorsten Roeder committed
622
    mDragging = false;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
623 624 625 626 627 628 629 630
    releaseMouse();
  }
  showLabel();
}
/**
* draws the scale according to the orientation
*/
void KLineal::drawScale(QPainter &painter) {
631
  painter.setPen(Qt::black);
632 633 634
  QFont font = mScaleFont;
  // font.setPixelSize(9);
  painter.setFont(font);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
635 636 637 638
  QFontMetrics metrics = painter.fontMetrics();
  int longCoo;
  int longLen;
  int shortStart;
639 640 641 642 643
  int w = width();
  int h = height();

  // draw a frame around the whole thing
  // (for some unknown reason, this doesn't show up anymore)
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
644 645 646 647
  switch (mOrientation) {
  case North:
  default:
    shortStart = 0;
648 649 650 651
    longLen = w;
    painter.drawLine(0, 0, 0, h-1);
    painter.drawLine(0, h-1, w-1, h-1);
    painter.drawLine(w-1, h-1, w-1, 0);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
652 653 654
    // painter.drawLine(width()-1, 0, 0, 0);
    break;
  case East:
655 656 657 658
    shortStart = w;
    longLen = h;
    painter.drawLine(0, 0, 0, h-1);
    painter.drawLine(0, h-1, w-1, h-1);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
659
    // painter.drawLine(width()-1, height()-1, width()-1, 0);
660
    painter.drawLine(w-1, 0, 0, 0);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
661 662
    break;
  case South:
663 664 665
    shortStart = h;
    longLen = w;
    painter.drawLine(0, 0, 0, h-1);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
666
    // painter.drawLine(0, height()-1, width()-1, height()-1);
667 668
    painter.drawLine(w-1, h-1, w-1, 0);
    painter.drawLine(w-1, 0, 0, 0);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
669 670 671
    break;
  case West:
    shortStart = 0;
672
    longLen = h;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
673
    // painter.drawLine(0, 0, 0, height()-1);
674 675 676
    painter.drawLine(0, h-1, w-1, h-1);
    painter.drawLine(w-1, h-1, w-1, 0);
    painter.drawLine(w-1, 0, 0, 0);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
677 678
    break;
  }
679
  int ten = 10, twenty = 20, fourty = 40, hundred = 100;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
680
  for (longCoo = 0; longCoo < longLen; longCoo+=2) {
681 682 683 684 685 686 687 688 689
    int len = 6;
    if (ten == 10) {
      if (twenty == 20) {
        /**/
        if (hundred == 100) {
          font.setBold(true);
          painter.setFont(font);
          len = 18;
        } else {
Urs Wolfer's avatar
Urs Wolfer committed
690
          len = 15;
691
        }
Urs Wolfer's avatar
Urs Wolfer committed
692
        QString units;
693 694 695 696 697 698
        int digits;
        if (hundred == 100 || mOrientation == West || mOrientation == East) {
          digits = longCoo;
        } else {
          digits = longCoo % 100;
        }
Urs Wolfer's avatar
Urs Wolfer committed
699 700
        units.sprintf("%d", digits);
        QSize textSize = metrics.size(Qt::TextSingleLine, units);
701 702
        int tw = textSize.width();
        int th = textSize.height();
Urs Wolfer's avatar
Urs Wolfer committed
703 704
        switch (mOrientation) {
        case North:
705 706
           if (digits < 1000  || fourty == 40 || hundred == 100) {
            if (longCoo != 0) {
Urs Wolfer's avatar
Urs Wolfer committed
707
                painter.drawText(longCoo - tw/2, shortStart + len + th, units);
708
            } else {
Urs Wolfer's avatar
Urs Wolfer committed
709
                painter.drawText(1, shortStart + len + th, units);
710 711
            }
           }
Urs Wolfer's avatar
Urs Wolfer committed
712 713
        break;
        case South:
714 715
           if (digits < 1000  || fourty == 40 || hundred == 100) {
            if (longCoo != 0) {
Urs Wolfer's avatar
Urs Wolfer committed
716
                painter.drawText(longCoo - tw/2, shortStart - len - 2, units);
717
            } else {
Urs Wolfer's avatar
Urs Wolfer committed
718
                painter.drawText(1, shortStart - len - 2, units);
719 720
            }
           }
Urs Wolfer's avatar
Urs Wolfer committed
721 722
        break;
        case East:
723
          if (longCoo != 0) {
Urs Wolfer's avatar
Urs Wolfer committed
724
            painter.drawText(shortStart - len - tw - 2, longCoo + th/2 - 2, units);
725
          } else {
Urs Wolfer's avatar
Urs Wolfer committed
726
            painter.drawText(shortStart - len - tw - 2, th-2, units);
727
          }
Urs Wolfer's avatar
Urs Wolfer committed
728 729
        break;
        case West:
730
          if (longCoo != 0) {
Urs Wolfer's avatar
Urs Wolfer committed
731
            painter.drawText(shortStart + len + 2, longCoo + th/2 - 2, units);
732
          } else {
Urs Wolfer's avatar
Urs Wolfer committed
733
            painter.drawText(shortStart + len + 2, th-2, units);
734
          }
Urs Wolfer's avatar
Urs Wolfer committed
735 736
        break;
        }
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
737
      } else {
Urs Wolfer's avatar
Urs Wolfer committed
738
        len = 10;
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
      }
    }
    switch(mOrientation) {
    case North:
      painter.drawLine(longCoo, shortStart, longCoo, shortStart+len);
      break;
    case South:
      painter.drawLine(longCoo, shortStart, longCoo, shortStart-len);
      break;
    case East:
      painter.drawLine(shortStart, longCoo, shortStart-len, longCoo);
      break;
    case West:
      painter.drawLine(shortStart, longCoo, shortStart+len, longCoo);
      break;
    }
755 756 757 758 759 760 761 762 763 764
    ten = (ten == 10) ? 2: ten + 2;
    twenty = (twenty == 20) ? 2: twenty + 2;
    fourty = (fourty == 40) ? 2: fourty + 2;
    if (hundred == 100) {
      hundred = 2;
      font.setBold(false);
      painter.setFont(font);
    } else {
      hundred += 2;
    }
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
765 766 767 768 769 770 771 772
  }
}
/**
* actually draws the ruler
*/
void KLineal::paintEvent(QPaintEvent * /*inEvent*/) {
  QPainter painter;
  painter.begin(this);
773
  drawBackground(painter);
Carsten Pfeiffer's avatar
Carsten Pfeiffer committed
774 775 776 777 778
  drawScale(painter);
  painter.end();
}

#include "klineal.moc"