~neon/kruler/master

1 by Carsten Pfeiffer
import of KRuler for Till
1
/***************************************************************************
2
                          klineal.cpp  -  description
3
                             -------------------
271 by Arto Hytönen
This commit fixes Krazy issue 12 on kdegraphics/kruler.
4
    Begin                : Fri Oct 13 2000
338 by Mathias Soeken
coding style. some cleanup
5
    Copyright            : 2000 by Till Krech <till@snafu.de>
6
                           2008 by Mathias Soeken <msoeken@informatik.uni-bremen.de>
534.1.22 by Aurélien Gâteau
Add copyright
7
                           2017 by Aurélien Gâteau <agateau@kde.org>
1 by Carsten Pfeiffer
import of KRuler for Till
8
 ***************************************************************************/
9
10
/***************************************************************************
11
 *                                                                         *
12
 *   This program is free software; you can redistribute it and/or modify  *
13
 *   it under the terms of the GNU General Public License as published by  *
14
 *   the Free Software Foundation; either version 2 of the License, or     *
15
 *   (at your option) any later version.                                   *
16
 *                                                                         *
17
 ***************************************************************************/
18
257 by Pino Toscano
own header first
19
#include "klineal.h"
20
486.1.1 by Christoph Feck
Port KRuler to KF5
21
#include <QAction>
22
#include <QApplication>
269 by Pino Toscano
use QLinearGradient instead of KImageEffect::gradient()
23
#include <QBrush>
486.1.1 by Christoph Feck
Port KRuler to KF5
24
#include <QDesktopWidget>
25
#include <QInputDialog>
26
#include <QMenu>
27
#include <QMouseEvent>
237 by Urs Wolfer
* deprecated--
28
#include <QPainter>
359 by Mathias Soeken
kruler is now configurable to be (semi-)transparent. There is a new menu "Opacity" in the context menu
29
#include <QSlider>
30
#include <QWidgetAction>
119 by Andreas Simon
- s/iostream.h/iostream
31
486.1.1 by Christoph Feck
Port KRuler to KF5
32
#include <KAboutData>
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
33
#include <KActionCollection>
331 by Mathias Soeken
Make use of KStandardAction
34
#include <KConfig>
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
35
#include <KConfigDialog>
486.1.1 by Christoph Feck
Port KRuler to KF5
36
#include <KHelpClient>
332 by Mathias Soeken
fix includes
37
#include <KHelpMenu>
486.1.1 by Christoph Feck
Port KRuler to KF5
38
#include <KLocalizedString>
331 by Mathias Soeken
Make use of KStandardAction
39
#include <KNotification>
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
40
#include <KShortcutsDialog>
330 by Mathias Soeken
Make use of KStandardAction
41
#include <KStandardAction>
332 by Mathias Soeken
fix includes
42
#include <KWindowSystem>
1 by Carsten Pfeiffer
import of KRuler for Till
43
486.1.5 by Christoph Feck
Port native window moving to XCB
44
#include "krulerconfig.h"
45
46
#ifdef KRULER_HAVE_X11
47
#include <QX11Info>
370 by Mathias Soeken
There is now an advanced option which enables moving the window by using NETRootInfo::moveResizeRequest,
48
#include <netwm.h>
486.1.5 by Christoph Feck
Port native window moving to XCB
49
#endif
370 by Mathias Soeken
There is now an advanced option which enables moving the window by using NETRootInfo::moveResizeRequest,
50
344 by Mathias Soeken
Use KConfig XT instead of hard coded KConfig calls
51
#include "kruler.h"
378 by Laurent Montel
Add preference in systemtray menu
52
#include "krulersystemtray.h"
339 by Mathias Soeken
This fixes some clipping bugs with the two labels.
53
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
54
#include "ui_cfg_appearance.h"
370 by Mathias Soeken
There is now an advanced option which enables moving the window by using NETRootInfo::moveResizeRequest,
55
#include "ui_cfg_advanced.h"
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
56
534.1.13 by Aurélien Gâteau
Remove length actions
57
static const int RESIZE_HANDLE_LENGTH = 7;
58
static const int RESIZE_HANDLE_THICKNESS = 24;
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
59
static const qreal RESIZE_HANDLE_OPACITY = 0.3;
1 by Carsten Pfeiffer
import of KRuler for Till
60
534.1.11 by Aurélien Gâteau
Draw ruler indicator
61
static const int SMALL_TICK_SIZE = 6;
62
static const int MEDIUM1_TICK_SIZE = 10;
63
static const int MEDIUM2_TICK_SIZE = 15;
64
static const int LARGE_TICK_SIZE = 18;
534.1.17 by Aurélien Gâteau
Make ticks not fully opaque
65
static const qreal TICK_OPACITY = 0.3;
534.1.11 by Aurélien Gâteau
Draw ruler indicator
66
67
static const int THICKNESS = 70;
534.1.16 by Aurélien Gâteau
Add indicator overlay
68
69
static const qreal OVERLAY_OPACITY = 0.1;
70
static const qreal OVERLAY_BORDER_OPACITY = 0.3;
71
72
static const int INDICATOR_MARGIN = 6;
73
static const int INDICATOR_RECT_RADIUS = 3;
74
static const qreal INDICATOR_RECT_OPACITY = 0.6;
75
534.1.15 by Aurélien Gâteau
Use a red cross cursor
76
static const int CURSOR_SIZE = 15; // Must be an odd number
534.1.11 by Aurélien Gâteau
Draw ruler indicator
77
1 by Carsten Pfeiffer
import of KRuler for Till
78
/**
335 by Mathias Soeken
some code cleanup
79
 * create the thingy with no borders and set up
80
 * its members
81
 */
338 by Mathias Soeken
coding style. some cleanup
82
KLineal::KLineal( QWidget *parent )
562 by Laurent Montel
USe nullptr + explicit + override
83
  : QWidget( parent )
335 by Mathias Soeken
some code cleanup
84
{
486.1.1 by Christoph Feck
Port KRuler to KF5
85
  setAttribute( Qt::WA_TranslucentBackground );
335 by Mathias Soeken
some code cleanup
86
  KWindowSystem::setType( winId(), NET::Override );   // or NET::Normal
87
  KWindowSystem::setState( winId(), NET::KeepAbove );
338 by Mathias Soeken
coding style. some cleanup
88
458 by Alexander Potashev
Add message contexts "@title:window" to all window and dialog titles
89
  setWindowTitle( i18nc( "@title:window", "KRuler" ) );
363 by Mathias Soeken
This forces not to use a frame border.
90
534.1.11 by Aurélien Gâteau
Draw ruler indicator
91
  setMinimumSize( THICKNESS, THICKNESS );
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
92
  setMaximumSize( 8000, 8000 );
534.1.4 by Aurélien Gâteau
Remove color picker
93
  setWhatsThis( i18n( "This is a tool to measure pixel distances on the screen. "
335 by Mathias Soeken
some code cleanup
94
                      "It is useful for working on layouts of dialogs, web pages etc." ) );
95
  setMouseTracking( true );
338 by Mathias Soeken
coding style. some cleanup
96
344 by Mathias Soeken
Use KConfig XT instead of hard coded KConfig calls
97
  mColor = RulerSettings::self()->bgColor();
98
  mScaleFont = RulerSettings::self()->scaleFont();
534.1.13 by Aurélien Gâteau
Remove length actions
99
  int len = RulerSettings::self()->length();
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
100
  mHorizontal = RulerSettings::self()->horizontal();
348 by Mathias Soeken
Save 'Orientation', 'Offset' and 'Direction' and restore them at restart.
101
  mLeftToRight = RulerSettings::self()->leftToRight();
102
  mOffset = RulerSettings::self()->offset();
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
103
  mRelativeScale = RulerSettings::self()->relativeScale();
508 by Alex Neundorf
-add option to stay "always on top" #317463
104
  mAlwaysOnTopLayer = RulerSettings::self()->alwaysOnTop();
1 by Carsten Pfeiffer
import of KRuler for Till
105
534.1.13 by Aurélien Gâteau
Remove length actions
106
  if ( mHorizontal ) {
107
    resize( QSize( len, THICKNESS ) );
108
  } else {
109
    resize( QSize( THICKNESS, len ) );
110
  }
335 by Mathias Soeken
some code cleanup
111
534.1.15 by Aurélien Gâteau
Use a red cross cursor
112
  createCrossCursor();
113
365 by Mathias Soeken
Add buttons to rotate the ruler (turn left, turn right). The buttons are only visible when hovering over
114
  //BEGIN setup menu and actions
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
115
  mActionCollection = new KActionCollection( this );
503 by Montel Laurent
Use new connect api + QStringLiteral
116
  mActionCollection->setConfigGroup( QStringLiteral( "Actions" ) );
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
117
486.1.1 by Christoph Feck
Port KRuler to KF5
118
  mMenu = new QMenu( this );
534.1.6 by Aurélien Gâteau
Keep only one orientation action: Rotate
119
  addAction( mMenu, QIcon::fromTheme( QStringLiteral( "object-rotate-left" ) ), i18n( "Rotate" ),
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
120
             this, SLOT(rotate()), Qt::Key_R, QStringLiteral( "turn_right" ) );
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
121
486.1.1 by Christoph Feck
Port KRuler to KF5
122
  QMenu* scaleMenu = new QMenu( i18n( "&Scale" ), this );
123
  mScaleDirectionAction = addAction( scaleMenu, QIcon(), i18n( "Right to Left" ),
503 by Montel Laurent
Use new connect api + QStringLiteral
124
                                     this, SLOT(switchDirection()), Qt::Key_D, QStringLiteral( "right_to_left" ) );
486.1.1 by Christoph Feck
Port KRuler to KF5
125
  mCenterOriginAction = addAction( scaleMenu, QIcon(), i18n( "Center Origin" ),
503 by Montel Laurent
Use new connect api + QStringLiteral
126
                                   this, SLOT(centerOrigin()), Qt::Key_C, QStringLiteral( "center_origin" ) );
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
127
  mCenterOriginAction->setEnabled( !mRelativeScale );
486.1.1 by Christoph Feck
Port KRuler to KF5
128
  mOffsetAction = addAction( scaleMenu, QIcon(), i18n( "Offset..." ),
503 by Montel Laurent
Use new connect api + QStringLiteral
129
                             this, SLOT(slotOffset()), Qt::Key_O, QStringLiteral( "set_offset" ) );
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
130
  mOffsetAction->setEnabled( !mRelativeScale );
131
  scaleMenu->addSeparator();
486.1.1 by Christoph Feck
Port KRuler to KF5
132
  QAction *relativeScaleAction = addAction( scaleMenu, QIcon(), i18n( "Percentage" ),
562 by Laurent Montel
USe nullptr + explicit + override
133
                                            nullptr, nullptr, QKeySequence(), QStringLiteral( "toggle_percentage" ) );
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
134
  relativeScaleAction->setCheckable( true );
135
  relativeScaleAction->setChecked( mRelativeScale );
486.1.2 by Montel Laurent
Port to new connect api. Port to reverse dns desktop
136
  connect(relativeScaleAction, &QAction::toggled, this, &KLineal::switchRelativeScale);
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
137
  mMenu->addMenu( scaleMenu );
344 by Mathias Soeken
Use KConfig XT instead of hard coded KConfig calls
138
364 by Mathias Soeken
With Qt 4.5 we can create real ARGB translucent widgets. Now kruler can be made transparent, but with
139
  mOpacity = RulerSettings::self()->opacity();
486.1.1 by Christoph Feck
Port KRuler to KF5
140
  QMenu* opacityMenu = new QMenu( i18n( "O&pacity" ), this );
359 by Mathias Soeken
kruler is now configurable to be (semi-)transparent. There is a new menu "Opacity" in the context menu
141
  QWidgetAction *opacityAction = new QWidgetAction( this );
142
  QSlider *slider = new QSlider( this );
547 by Aurélien Gâteau
Improve opacity handling
143
  slider->setMinimum( 30 );
364 by Mathias Soeken
With Qt 4.5 we can create real ARGB translucent widgets. Now kruler can be made transparent, but with
144
  slider->setMaximum( 255 );
359 by Mathias Soeken
kruler is now configurable to be (semi-)transparent. There is a new menu "Opacity" in the context menu
145
  slider->setSingleStep( 1 );
146
  slider->setOrientation( Qt::Horizontal );
364 by Mathias Soeken
With Qt 4.5 we can create real ARGB translucent widgets. Now kruler can be made transparent, but with
147
  slider->setValue( RulerSettings::self()->opacity() );
547 by Aurélien Gâteau
Improve opacity handling
148
  // Show ticks so that the slider is a bit taller, thus easier to grab
149
  slider->setTickPosition( QSlider::TicksBothSides );
150
  slider->setTickInterval( 30 );
486.1.2 by Montel Laurent
Port to new connect api. Port to reverse dns desktop
151
  connect(slider, &QSlider::valueChanged, this, &KLineal::slotOpacity);
359 by Mathias Soeken
kruler is now configurable to be (semi-)transparent. There is a new menu "Opacity" in the context menu
152
  opacityAction->setDefaultWidget( slider );
153
  opacityMenu->addAction( opacityAction );
154
  mMenu->addMenu( opacityMenu );
155
486.1.7 by Christoph Feck
Fix warnings about renamed actions
156
  QAction *keyBindings = mActionCollection->addAction( KStandardAction::KeyBindings, this, SLOT(slotKeyBindings()) );
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
157
  mMenu->addAction( keyBindings );
486.1.7 by Christoph Feck
Fix warnings about renamed actions
158
  QAction *preferences = mActionCollection->addAction( KStandardAction::Preferences, this, SLOT(slotPreferences()) );
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
159
  mMenu->addAction( preferences );
351 by Mathias Soeken
Copy color under cursor with Ctrl+C (standard Copy shortcut)
160
  mMenu->addSeparator();
486.1.1 by Christoph Feck
Port KRuler to KF5
161
  mMenu->addMenu( ( new KHelpMenu( this, KAboutData::applicationData(), true ) )->menu() );
335 by Mathias Soeken
some code cleanup
162
  mMenu->addSeparator();
358 by Mathias Soeken
Tray Icon for kruler. But it is configurable and hidden by default.
163
  if ( RulerSettings::self()->trayIcon() ) {
373 by Laurent Montel
Fix show/hide close button when we show/hide systemtray
164
      createSystemTray();
165
  }
166
486.1.7 by Christoph Feck
Fix warnings about renamed actions
167
  QAction *quit = mActionCollection->addAction( KStandardAction::Quit, qApp, SLOT(quit()) );
373 by Laurent Montel
Fix show/hide close button when we show/hide systemtray
168
  mMenu->addAction( quit );
169
170
  mActionCollection->associateWidget( this );
171
  mActionCollection->readSettings();
172
173
  mLastClickPos = geometry().topLeft() + QPoint( width() / 2, height() / 2 );
174
508 by Alex Neundorf
-add option to stay "always on top" #317463
175
  setWindowFlags( mAlwaysOnTopLayer ? Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
176
                                    : Qt::FramelessWindowHint );
177
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
178
  setHorizontal( mHorizontal );
373 by Laurent Montel
Fix show/hide close button when we show/hide systemtray
179
}
180
181
KLineal::~KLineal()
182
{
398 by Mathias Soeken
* Fix indention
183
  delete mTrayIcon;
373 by Laurent Montel
Fix show/hide close button when we show/hide systemtray
184
}
185
534.1.15 by Aurélien Gâteau
Use a red cross cursor
186
void KLineal::createCrossCursor()
187
{
188
  QPixmap pix( CURSOR_SIZE, CURSOR_SIZE );
189
  int halfSize = CURSOR_SIZE / 2;
190
  {
191
    pix.fill( Qt::transparent );
192
    QPainter painter( &pix );
193
    painter.setPen( Qt::red );
194
    painter.drawLine( 0, halfSize, CURSOR_SIZE - 1, halfSize );
195
    painter.drawLine( halfSize, 0, halfSize, CURSOR_SIZE - 1 );
196
  }
197
  mCrossCursor = QCursor( pix, halfSize, halfSize );
198
}
199
373 by Laurent Montel
Fix show/hide close button when we show/hide systemtray
200
void KLineal::createSystemTray()
201
{
534.1.7 by Aurélien Gâteau
Remove buttons
202
  mCloseAction = mActionCollection->addAction( KStandardAction::Close, this, SLOT(slotClose()) );
203
  mMenu->addAction( mCloseAction );
444 by Laurent Montel
Fix compile with "DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII"
204
398 by Mathias Soeken
* Fix indention
205
  if ( !mTrayIcon ) {
503 by Montel Laurent
Use new connect api + QStringLiteral
206
    mTrayIcon = new KRulerSystemTray( QStringLiteral( "kruler" ), this, mActionCollection );
406 by Aurélien Gâteau
notification -> statusnotifier
207
    mTrayIcon->setCategory( KStatusNotifierItem::ApplicationStatus );
398 by Mathias Soeken
* Fix indention
208
  }
1 by Carsten Pfeiffer
import of KRuler for Till
209
}
115 by Till Krech
Nicer look with gradient. Font selection. Border works again. Some tweaking with scale drawing to avoid overlapping text - if a reasonable font is chosen
210
1 by Carsten Pfeiffer
import of KRuler for Till
211
486.1.1 by Christoph Feck
Port KRuler to KF5
212
QAction* KLineal::addAction( QMenu *menu, const QIcon& icon, const QString& text,
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
213
                             const QObject* receiver, const char* member,
214
                             const QKeySequence &shortcut, const QString& name )
215
{
486.1.1 by Christoph Feck
Port KRuler to KF5
216
  QAction *action = new QAction( icon, text, mActionCollection );
217
  mActionCollection->setDefaultShortcut( action, shortcut );
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
218
  if ( receiver ) {
465 by Montel Laurent
Normalize
219
    connect( action, SIGNAL(triggered()), receiver, member );
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
220
  }
221
  menu->addAction( action );
222
  mActionCollection->addAction( name, action );
223
  return action;
224
}
225
358 by Mathias Soeken
Tray Icon for kruler. But it is configurable and hidden by default.
226
void KLineal::slotClose()
227
{
228
  hide();
229
}
230
310 by Laurent Montel
Fix use shortcut.
231
void KLineal::slotQuit()
232
{
486.1.1 by Christoph Feck
Port KRuler to KF5
233
   qApp->quit();
310 by Laurent Montel
Fix use shortcut.
234
}
235
338 by Mathias Soeken
coding style. some cleanup
236
void KLineal::move( int x, int y )
237
{
238
  move( QPoint( x, y ) );
239
}
240
241
void KLineal::move(const QPoint &p)
242
{
243
  setGeometry( QRect( p, size() ) );
244
}
245
379 by Laurent Montel
const'ify
246
QPoint KLineal::pos() const
338 by Mathias Soeken
coding style. some cleanup
247
{
248
  return frameGeometry().topLeft();
249
}
250
379 by Laurent Montel
const'ify
251
int KLineal::x() const
338 by Mathias Soeken
coding style. some cleanup
252
{
1 by Carsten Pfeiffer
import of KRuler for Till
253
  return pos().x();
254
}
338 by Mathias Soeken
coding style. some cleanup
255
379 by Laurent Montel
const'ify
256
int KLineal::y() const
338 by Mathias Soeken
coding style. some cleanup
257
{
1 by Carsten Pfeiffer
import of KRuler for Till
258
  return pos().y();
259
}
260
338 by Mathias Soeken
coding style. some cleanup
261
void KLineal::drawBackground( QPainter& painter )
262
{
115 by Till Krech
Nicer look with gradient. Font selection. Border works again. Some tweaking with scale drawing to avoid overlapping text - if a reasonable font is chosen
263
  QColor a, b, bg = mColor;
269 by Pino Toscano
use QLinearGradient instead of KImageEffect::gradient()
264
  QLinearGradient gradient;
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
265
  if ( mHorizontal ) {
571 by Laurent Montel
Make it compile with qt5.13
266
    a = bg.lighter( 120 );
267
    b = bg.darker( 130 );
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
268
    gradient = QLinearGradient( 1, 0, 1, height() );
269
  } else {
571 by Laurent Montel
Make it compile with qt5.13
270
    a = bg.lighter( 120 );
271
    b = bg.darker( 130 );
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
272
    gradient = QLinearGradient( 0, 1, width(), 1 );
115 by Till Krech
Nicer look with gradient. Font selection. Border works again. Some tweaking with scale drawing to avoid overlapping text - if a reasonable font is chosen
273
  }
364 by Mathias Soeken
With Qt 4.5 we can create real ARGB translucent widgets. Now kruler can be made transparent, but with
274
  a.setAlpha( mOpacity );
275
  b.setAlpha( mOpacity );
338 by Mathias Soeken
coding style. some cleanup
276
  gradient.setColorAt( 0, a );
277
  gradient.setColorAt( 1, b );
278
  painter.fillRect( rect(), QBrush( gradient ) );
115 by Till Krech
Nicer look with gradient. Font selection. Border works again. Some tweaking with scale drawing to avoid overlapping text - if a reasonable font is chosen
279
}
280
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
281
void KLineal::setHorizontal( bool horizontal )
338 by Mathias Soeken
coding style. some cleanup
282
{
115 by Till Krech
Nicer look with gradient. Font selection. Border works again. Some tweaking with scale drawing to avoid overlapping text - if a reasonable font is chosen
283
  QRect r = frameGeometry();
534.1.13 by Aurélien Gâteau
Remove length actions
284
  if ( mHorizontal != horizontal ) {
285
    r.setSize( r.size().transposed() );
286
  }
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
287
  mHorizontal = horizontal;
288
  QPoint center = mLastClickPos;
162 by Laurent Montel
Deprecated--
289
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
290
  if ( mClicked ) {
132 by Ryan Cumming
Fix an error found by valgrind
291
    center = mLastClickPos;
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
292
    mClicked = false;
334 by Mathias Soeken
Set explicitely the size. Just rotating can cause errors
293
  } else {
294
    center = r.topLeft() + QPoint( width() / 2, height() / 2 );
295
  }
237 by Urs Wolfer
* deprecated--
296
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
297
  QPoint newTopLeft = QPoint( center.x() - height() / 2, center.y() - width() / 2 );
329 by Mathias Soeken
Fix "Window moves when changing orientation"
298
  r.moveTo(newTopLeft);
190 by Waldo Bastian
Stay on screen when changing orientation. (BR83293)
299
486.1.1 by Christoph Feck
Port KRuler to KF5
300
  QRect desktop = QApplication::desktop()->screenGeometry( this );
334 by Mathias Soeken
Set explicitely the size. Just rotating can cause errors
301
534.1.13 by Aurélien Gâteau
Remove length actions
302
  if ( r.width() > desktop.width() ) {
303
    r.setWidth( desktop.width() );
304
  }
305
306
  if ( r.height() > desktop.height() ) {
307
    r.setHeight( desktop.height() );
308
  }
309
334 by Mathias Soeken
Set explicitely the size. Just rotating can cause errors
310
  if ( r.top() < desktop.top() ) {
338 by Mathias Soeken
coding style. some cleanup
311
    r.moveTop( desktop.top() );
334 by Mathias Soeken
Set explicitely the size. Just rotating can cause errors
312
  }
313
314
  if ( r.bottom() > desktop.bottom() ) {
338 by Mathias Soeken
coding style. some cleanup
315
    r.moveBottom( desktop.bottom() );
334 by Mathias Soeken
Set explicitely the size. Just rotating can cause errors
316
  }
317
318
  if ( r.left() < desktop.left() ) {
338 by Mathias Soeken
coding style. some cleanup
319
    r.moveLeft( desktop.left() );
334 by Mathias Soeken
Set explicitely the size. Just rotating can cause errors
320
  }
321
322
  if ( r.right() > desktop.right() ) {
323
    r.moveRight( desktop.right() );
324
  }
325
326
  setGeometry( r );
338 by Mathias Soeken
coding style. some cleanup
327
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
328
  updateScaleDirectionMenuItem();
329
348 by Mathias Soeken
Save 'Orientation', 'Offset' and 'Direction' and restore them at restart.
330
  saveSettings();
1 by Carsten Pfeiffer
import of KRuler for Till
331
}
334 by Mathias Soeken
Set explicitely the size. Just rotating can cause errors
332
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
333
void KLineal::rotate()
334
{
335
  setHorizontal( !mHorizontal );
338 by Mathias Soeken
coding style. some cleanup
336
}
337
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
338
void KLineal::updateScaleDirectionMenuItem()
339
{
340
  if ( !mScaleDirectionAction ) return;
341
342
  QString label;
343
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
344
  if ( mHorizontal ) {
385 by Stephan Binner
i18n style guide fixes: http://techbase.kde.org/Projects/Usability/HIG/Capitalization
345
    label = mLeftToRight ? i18n( "Right to Left" ) : i18n( "Left to Right" );
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
346
  } else {
385 by Stephan Binner
i18n style guide fixes: http://techbase.kde.org/Projects/Usability/HIG/Capitalization
347
    label = mLeftToRight ? i18n( "Bottom to Top" ) : i18n( "Top to Bottom" );
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
348
  }
349
350
  mScaleDirectionAction->setText( label );
351
}
352
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
353
QRect KLineal::beginRect() const
354
{
534.1.13 by Aurélien Gâteau
Remove length actions
355
  int shortLen = RESIZE_HANDLE_THICKNESS;
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
356
  return mHorizontal
534.1.13 by Aurélien Gâteau
Remove length actions
357
    ? QRect( 0, ( height() - shortLen ) / 2 + 1, RESIZE_HANDLE_LENGTH, shortLen )
358
    : QRect( ( width() - shortLen ) / 2, 0, shortLen, RESIZE_HANDLE_LENGTH );
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
359
}
360
361
QRect KLineal::endRect() const
362
{
534.1.13 by Aurélien Gâteau
Remove length actions
363
  int shortLen = RESIZE_HANDLE_THICKNESS;
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
364
  return mHorizontal
534.1.13 by Aurélien Gâteau
Remove length actions
365
    ? QRect( width() - RESIZE_HANDLE_LENGTH, ( height() - shortLen ) / 2 + 1, RESIZE_HANDLE_LENGTH, shortLen )
366
    : QRect( ( width() - shortLen ) / 2, height() - RESIZE_HANDLE_LENGTH, shortLen, RESIZE_HANDLE_LENGTH );
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
367
}
368
369
Qt::CursorShape KLineal::resizeCursor() const
370
{
371
  return mHorizontal ? Qt::SizeHorCursor : Qt::SizeVerCursor;
372
}
373
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
374
void KLineal::switchDirection()
375
{
376
  mLeftToRight = !mLeftToRight;
377
  updateScaleDirectionMenuItem();
378
  repaint();
348 by Mathias Soeken
Save 'Orientation', 'Offset' and 'Direction' and restore them at restart.
379
  saveSettings();
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
380
}
381
382
void KLineal::centerOrigin()
383
{
534.1.13 by Aurélien Gâteau
Remove length actions
384
  mOffset = -( length() / 2 );
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
385
  repaint();
348 by Mathias Soeken
Save 'Orientation', 'Offset' and 'Direction' and restore them at restart.
386
  saveSettings();
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
387
}
388
389
void KLineal::slotOffset()
390
{
391
  bool ok;
486.1.1 by Christoph Feck
Port KRuler to KF5
392
  int newOffset = QInputDialog::getInt( this, i18nc( "@title:window", "Scale Offset" ),
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
393
                                            i18n( "Offset:" ), mOffset,
486.1.1 by Christoph Feck
Port KRuler to KF5
394
                                            -2147483647, 2147483647, 1, &ok );
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
395
396
  if ( ok ) {
397
    mOffset = newOffset;
398
    repaint();
348 by Mathias Soeken
Save 'Orientation', 'Offset' and 'Direction' and restore them at restart.
399
    saveSettings();
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
400
  }
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
401
}
402
359 by Mathias Soeken
kruler is now configurable to be (semi-)transparent. There is a new menu "Opacity" in the context menu
403
void KLineal::slotOpacity( int value )
404
{
364 by Mathias Soeken
With Qt 4.5 we can create real ARGB translucent widgets. Now kruler can be made transparent, but with
405
  mOpacity = value;
406
  repaint();
359 by Mathias Soeken
kruler is now configurable to be (semi-)transparent. There is a new menu "Opacity" in the context menu
407
  RulerSettings::self()->setOpacity( value );
486.1.1 by Christoph Feck
Port KRuler to KF5
408
  RulerSettings::self()->save();
359 by Mathias Soeken
kruler is now configurable to be (semi-)transparent. There is a new menu "Opacity" in the context menu
409
}
410
362 by Mathias Soeken
Make all actions configurable via a KActionCollection and KShortcutsDialog
411
void KLineal::slotKeyBindings()
412
{
413
  KShortcutsDialog::configure( mActionCollection );
414
}
415
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
416
void KLineal::slotPreferences()
417
{
503 by Montel Laurent
Use new connect api + QStringLiteral
418
  KConfigDialog *dialog = new KConfigDialog( this, QStringLiteral( "settings" ), RulerSettings::self() );
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
419
420
  Ui::ConfigAppearance appearanceConfig;
421
  QWidget *appearanceConfigWidget = new QWidget( dialog );
422
  appearanceConfig.setupUi( appearanceConfigWidget );
503 by Montel Laurent
Use new connect api + QStringLiteral
423
  dialog->addPage( appearanceConfigWidget, i18n( "Appearance" ), QStringLiteral( "preferences-desktop-default-applications" ) );
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
424
489 by Christoph Feck
Fix build on non-X11 systems
425
#ifdef KRULER_HAVE_X11
508 by Alex Neundorf
-add option to stay "always on top" #317463
426
  // Advanced page only contains the "Native moving" and "Always on top" settings, disable when not running on X11
488 by Christoph Feck
Add runtime checks for X11 platform
427
  if ( QX11Info::isPlatformX11() ) {
428
    Ui::ConfigAdvanced advancedConfig;
429
    QWidget *advancedConfigWidget = new QWidget( dialog );
430
    advancedConfig.setupUi( advancedConfigWidget );
503 by Montel Laurent
Use new connect api + QStringLiteral
431
    dialog->addPage( advancedConfigWidget, i18n( "Advanced" ), QStringLiteral( "preferences-other" ) );
488 by Christoph Feck
Add runtime checks for X11 platform
432
  }
489 by Christoph Feck
Fix build on non-X11 systems
433
#endif
370 by Mathias Soeken
There is now an advanced option which enables moving the window by using NETRootInfo::moveResizeRequest,
434
486.1.2 by Montel Laurent
Port to new connect api. Port to reverse dns desktop
435
  connect(dialog, &KConfigDialog::settingsChanged, this, &KLineal::loadConfig);
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
436
  dialog->exec();
371 by Laurent Montel
Fix mem leak
437
  delete dialog;
375 by Laurent Montel
Now make "apply" in config dialog works
438
}
439
440
void KLineal::loadConfig()
441
{
398 by Mathias Soeken
* Fix indention
442
  mColor = RulerSettings::self()->bgColor();
443
  mScaleFont = RulerSettings::self()->scaleFont();
508 by Alex Neundorf
-add option to stay "always on top" #317463
444
  mAlwaysOnTopLayer = RulerSettings::self()->alwaysOnTop();
398 by Mathias Soeken
* Fix indention
445
  saveSettings();
446
508 by Alex Neundorf
-add option to stay "always on top" #317463
447
  setWindowFlags( mAlwaysOnTopLayer ? Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
448
                                    : Qt::FramelessWindowHint );
449
398 by Mathias Soeken
* Fix indention
450
  if ( RulerSettings::self()->trayIcon() ) {
451
    if ( !mTrayIcon ) {
452
      createSystemTray();
453
    }
454
  } else {
450 by Laurent Montel
Not necessary to check pointer
455
    delete mTrayIcon;
562 by Laurent Montel
USe nullptr + explicit + override
456
    mTrayIcon = nullptr;
398 by Mathias Soeken
* Fix indention
457
458
    if ( mCloseAction ) {
459
      mCloseAction->setVisible( false );
460
    }
461
  }
508 by Alex Neundorf
-add option to stay "always on top" #317463
462
  show();
398 by Mathias Soeken
* Fix indention
463
  repaint();
375 by Laurent Montel
Now make "apply" in config dialog works
464
}
465
352 by Mathias Soeken
I moved the menu items for setting color and font to a new config dialog. There will come some more
466
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
467
void KLineal::switchRelativeScale( bool checked )
468
{
469
  mRelativeScale = checked;
470
471
  mCenterOriginAction->setEnabled( !mRelativeScale );
472
  mOffsetAction->setEnabled( !mRelativeScale );
473
474
  repaint();
475
  saveSettings();
476
}
477
14 by Till Krech
fixed color display truncation, added cursor keys to move one pixel (10 with shift), added sound event
478
/**
338 by Mathias Soeken
coding style. some cleanup
479
 * save the ruler color to the config file
480
 */
481
void KLineal::saveSettings()
482
{
344 by Mathias Soeken
Use KConfig XT instead of hard coded KConfig calls
483
  RulerSettings::self()->setBgColor( mColor );
484
  RulerSettings::self()->setScaleFont( mScaleFont );
534.1.13 by Aurélien Gâteau
Remove length actions
485
  RulerSettings::self()->setLength( length() );
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
486
  RulerSettings::self()->setHorizontal( mHorizontal );
348 by Mathias Soeken
Save 'Orientation', 'Offset' and 'Direction' and restore them at restart.
487
  RulerSettings::self()->setLeftToRight( mLeftToRight );
488
  RulerSettings::self()->setOffset( mOffset );
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
489
  RulerSettings::self()->setRelativeScale( mRelativeScale );
508 by Alex Neundorf
-add option to stay "always on top" #317463
490
  RulerSettings::self()->setAlwaysOnTop( mAlwaysOnTopLayer );
486.1.1 by Christoph Feck
Port KRuler to KF5
491
  RulerSettings::self()->save();
1 by Carsten Pfeiffer
import of KRuler for Till
492
}
14 by Till Krech
fixed color display truncation, added cursor keys to move one pixel (10 with shift), added sound event
493
1 by Carsten Pfeiffer
import of KRuler for Till
494
/**
338 by Mathias Soeken
coding style. some cleanup
495
 * lets the context menu appear at current cursor position
496
 */
497
void KLineal::showMenu()
498
{
237 by Urs Wolfer
* deprecated--
499
  QPoint pos = QCursor::pos();
338 by Mathias Soeken
coding style. some cleanup
500
  mMenu->popup( pos );
501
}
502
534.1.11 by Aurélien Gâteau
Draw ruler indicator
503
bool KLineal::isResizing() const
504
{
505
  return mouseGrabber() == this && ( mRulerState == StateBegin || mRulerState == StateEnd );
506
}
507
534.1.13 by Aurélien Gâteau
Remove length actions
508
int KLineal::length() const
509
{
510
  return mHorizontal ? width() : height();
511
}
512
534.1.11 by Aurélien Gâteau
Draw ruler indicator
513
QPoint KLineal::localCursorPos() const
514
{
515
  // For some reason mapFromGlobal( QCursor::pos() ) thinks the ruler is at 0, 0 at startup.
516
  // compute the position ourselves to avoid that.
517
  return QCursor::pos() - pos();
518
}
519
534.1.16 by Aurélien Gâteau
Add indicator overlay
520
QString KLineal::indicatorText() const
338 by Mathias Soeken
coding style. some cleanup
521
{
534.1.16 by Aurélien Gâteau
Add indicator overlay
522
  int xy = mHorizontal ? localCursorPos().x() : localCursorPos().y();
534.1.14 by Aurélien Gâteau
Remove display of ruler size
523
  if ( !mRelativeScale ) {
534.1.16 by Aurélien Gâteau
Add indicator overlay
524
    int len = mLeftToRight ? xy + 1 : length() - xy;
525
    return i18n( "%1 px", len );
534.1.11 by Aurélien Gâteau
Draw ruler indicator
526
  } else {
534.1.16 by Aurélien Gâteau
Add indicator overlay
527
    int len = ( xy * 100.f ) / length();
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
528
534.1.14 by Aurélien Gâteau
Remove display of ruler size
529
    if ( !mLeftToRight ) {
530
      len = 100 - len;
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
531
    }
534.1.16 by Aurélien Gâteau
Add indicator overlay
532
    return i18n( "%1%", len );
1 by Carsten Pfeiffer
import of KRuler for Till
533
  }
534
}
338 by Mathias Soeken
coding style. some cleanup
535
536
void KLineal::keyPressEvent( QKeyEvent *e )
537
{
538
  QPoint dist;
539
540
  switch ( e->key() ) {
237 by Urs Wolfer
* deprecated--
541
  case Qt::Key_F1:
486.1.1 by Christoph Feck
Port KRuler to KF5
542
    KHelpClient::invokeHelp();
338 by Mathias Soeken
coding style. some cleanup
543
    return;
544
237 by Urs Wolfer
* deprecated--
545
  case Qt::Key_Left:
338 by Mathias Soeken
coding style. some cleanup
546
    dist.setX( -1 );
237 by Urs Wolfer
* deprecated--
547
    break;
338 by Mathias Soeken
coding style. some cleanup
548
237 by Urs Wolfer
* deprecated--
549
  case Qt::Key_Right:
338 by Mathias Soeken
coding style. some cleanup
550
    dist.setX( 1 );
237 by Urs Wolfer
* deprecated--
551
    break;
338 by Mathias Soeken
coding style. some cleanup
552
237 by Urs Wolfer
* deprecated--
553
  case Qt::Key_Up:
338 by Mathias Soeken
coding style. some cleanup
554
    dist.setY( -1 );
237 by Urs Wolfer
* deprecated--
555
    break;
338 by Mathias Soeken
coding style. some cleanup
556
237 by Urs Wolfer
* deprecated--
557
  case Qt::Key_Down:
338 by Mathias Soeken
coding style. some cleanup
558
    dist.setY( 1 );
237 by Urs Wolfer
* deprecated--
559
    break;
338 by Mathias Soeken
coding style. some cleanup
560
237 by Urs Wolfer
* deprecated--
561
  default:
562
    QWidget::keyPressEvent(e);
563
    return;
564
  }
338 by Mathias Soeken
coding style. some cleanup
565
566
  if ( e->modifiers() & Qt::ShiftModifier ) {
237 by Urs Wolfer
* deprecated--
567
    dist *= 10;
14 by Till Krech
fixed color display truncation, added cursor keys to move one pixel (10 with shift), added sound event
568
  }
338 by Mathias Soeken
coding style. some cleanup
569
536.1.1 by Aurélien Gâteau
Use alt+arrow keys to move the mouse cursor
570
  if ( e->modifiers() & Qt::AltModifier ) {
571
    QCursor::setPos( QCursor::pos() + dist );
572
  } else {
573
    move( pos() + dist );
574
    update();
575
  }
503 by Montel Laurent
Use new connect api + QStringLiteral
576
  KNotification::event( QString(), QStringLiteral( "cursormove" ), QString() );
14 by Till Krech
fixed color display truncation, added cursor keys to move one pixel (10 with shift), added sound event
577
}
338 by Mathias Soeken
coding style. some cleanup
578
534.1.11 by Aurélien Gâteau
Draw ruler indicator
579
void KLineal::leaveEvent( QEvent *e )
580
{
581
  Q_UNUSED( e );
534.1.16 by Aurélien Gâteau
Add indicator overlay
582
  update();
534.1.11 by Aurélien Gâteau
Draw ruler indicator
583
}
584
338 by Mathias Soeken
coding style. some cleanup
585
void KLineal::mouseMoveEvent( QMouseEvent *inEvent )
586
{
587
  Q_UNUSED( inEvent );
588
534.1.11 by Aurélien Gâteau
Draw ruler indicator
589
  if ( mRulerState >= StateMove ) {
590
    if ( mouseGrabber() != this ) {
591
      return;
592
    }
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
593
    if ( mRulerState == StateMove ) {
486.1.5 by Christoph Feck
Port native window moving to XCB
594
      move( QCursor::pos() - mDragOffset );
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
595
    } else if ( mRulerState == StateBegin ) {
596
      QRect r = geometry();
597
      if ( mHorizontal ) {
598
        r.setLeft( QCursor::pos().x() - mDragOffset.x() );
599
      } else {
600
        r.setTop( QCursor::pos().y() - mDragOffset.y() );
601
      }
602
      setGeometry( r );
603
    } else if ( mRulerState == StateEnd ) {
604
      QPoint end = QCursor::pos() + mDragOffset - pos();
605
      QSize size = mHorizontal
606
        ? QSize( end.x(), height() )
607
        : QSize( width(), end.y() );
608
      resize( size );
486.1.5 by Christoph Feck
Port native window moving to XCB
609
    }
1 by Carsten Pfeiffer
import of KRuler for Till
610
  } else {
534.1.11 by Aurélien Gâteau
Draw ruler indicator
611
    QPoint cpos = localCursorPos();
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
612
    mRulerState = StateNone;
613
    if ( beginRect().contains( cpos ) || endRect().contains( cpos) ) {
614
      setCursor( resizeCursor() );
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
615
    } else {
534.1.15 by Aurélien Gâteau
Use a red cross cursor
616
      setCursor( mCrossCursor );
1 by Carsten Pfeiffer
import of KRuler for Till
617
    }
534.1.16 by Aurélien Gâteau
Add indicator overlay
618
    update();
1 by Carsten Pfeiffer
import of KRuler for Till
619
  }
620
}
621
622
/**
338 by Mathias Soeken
coding style. some cleanup
623
 * overwritten for dragging and context menu
624
 */
625
void KLineal::mousePressEvent( QMouseEvent *inEvent )
626
{
1 by Carsten Pfeiffer
import of KRuler for Till
627
  mLastClickPos = QCursor::pos();
628
629
  QRect gr = geometry();
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
630
  mDragOffset = mLastClickPos - gr.topLeft();
338 by Mathias Soeken
coding style. some cleanup
631
  if ( inEvent->button() == Qt::LeftButton ) {
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
632
    if ( mRulerState < StateMove ) {
633
      if ( beginRect().contains( mDragOffset ) ) {
634
        mRulerState = StateBegin;
635
        grabMouse( resizeCursor() );
636
      } else if ( endRect().contains( mDragOffset ) ) {
637
        mDragOffset = gr.bottomRight() - mLastClickPos;
638
        mRulerState = StateEnd;
639
        grabMouse( resizeCursor() );
640
      } else {
641
        if ( nativeMove() ) {
642
          startNativeMove( inEvent );
643
        } else {
644
          mRulerState = StateMove;
645
          grabMouse( Qt::SizeAllCursor );
646
        }
370 by Mathias Soeken
There is now an advanced option which enables moving the window by using NETRootInfo::moveResizeRequest,
647
      }
1 by Carsten Pfeiffer
import of KRuler for Till
648
    }
338 by Mathias Soeken
coding style. some cleanup
649
  } else if ( inEvent->button() == Qt::MidButton ) {
346 by Mathias Soeken
kruler can now measure from right to left or from bottom to top, when orientation is north/south or west/east, respectively.
650
    mClicked = true;
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
651
    rotate();
338 by Mathias Soeken
coding style. some cleanup
652
  } else if ( inEvent->button() == Qt::RightButton ) {
1 by Carsten Pfeiffer
import of KRuler for Till
653
    showMenu();
654
  }
655
}
338 by Mathias Soeken
coding style. some cleanup
656
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
657
#ifdef KRULER_HAVE_X11
658
bool KLineal::nativeMove() const
659
{
660
  return QX11Info::isPlatformX11() && RulerSettings::self()->nativeMoving();
661
}
662
663
void KLineal::startNativeMove( QMouseEvent *inEvent )
664
{
665
  xcb_ungrab_pointer( QX11Info::connection(), QX11Info::appTime() );
666
  NETRootInfo wm_root( QX11Info::connection(), NET::WMMoveResize );
667
  wm_root.moveResizeRequest( winId(), inEvent->globalX(), inEvent->globalY(), NET::Move );
668
}
669
670
void KLineal::stopNativeMove( QMouseEvent *inEvent )
671
{
672
  NETRootInfo wm_root( QX11Info::connection(), NET::WMMoveResize );
673
  wm_root.moveResizeRequest( winId(), inEvent->globalX(), inEvent->globalY(), NET::MoveResizeCancel );
674
}
675
#else
676
bool KLineal::nativeMove() const
677
{
678
  return false;
679
}
680
681
void KLineal::startNativeMove( QMouseEvent *inEvent )
682
{
683
  Q_UNUSED( inEvent );
684
}
685
686
void KLineal::stopNativeMove( QMouseEvent *inEvent )
687
{
688
  Q_UNUSED( inEvent );
689
}
690
#endif
691
1 by Carsten Pfeiffer
import of KRuler for Till
692
/**
338 by Mathias Soeken
coding style. some cleanup
693
 * overwritten for dragging
694
 */
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
695
void KLineal::mouseReleaseEvent( QMouseEvent *inEvent )
338 by Mathias Soeken
coding style. some cleanup
696
{
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
697
  if ( mRulerState != StateNone ) {
698
    mRulerState = StateNone;
699
    releaseMouse();
534.1.13 by Aurélien Gâteau
Remove length actions
700
    saveSettings();
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
701
  } else if ( nativeMove() ) {
702
    stopNativeMove( inEvent );
1 by Carsten Pfeiffer
import of KRuler for Till
703
  }
704
}
338 by Mathias Soeken
coding style. some cleanup
705
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
706
void KLineal::wheelEvent( QWheelEvent *e )
707
{
581 by Laurent Montel
Make it compiles without deprecated method
708
  int numDegrees = e->angleDelta().y() / 8;
360 by Mathias Soeken
Changing the offset via the mouse wheel is now possible when holding the left mouse button.
709
  int numSteps = numDegrees / 15;
710
711
  // changing offset
712
  if ( e->buttons() == Qt::LeftButton ) {
713
    if ( !mRelativeScale ) {
714
      mOffset += numSteps;
715
716
      repaint();
717
      saveSettings();
718
    }
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
719
  }
720
721
  QWidget::wheelEvent( e );
347 by Mathias Soeken
Now it is possible to change the origin of the scale.
722
}
723
1 by Carsten Pfeiffer
import of KRuler for Till
724
/**
338 by Mathias Soeken
coding style. some cleanup
725
 * draws the scale according to the orientation
726
 */
727
void KLineal::drawScale( QPainter &painter )
728
{
729
  painter.setPen( Qt::black );
115 by Till Krech
Nicer look with gradient. Font selection. Border works again. Some tweaking with scale drawing to avoid overlapping text - if a reasonable font is chosen
730
  QFont font = mScaleFont;
338 by Mathias Soeken
coding style. some cleanup
731
  painter.setFont( font );
534.1.16 by Aurélien Gâteau
Add indicator overlay
732
  int longLen = length();
338 by Mathias Soeken
coding style. some cleanup
733
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
734
  if ( !mRelativeScale ) {
735
    int digit;
736
    int len;
534.1.18 by Aurélien Gâteau
Fix missing ticks at ends of ruler
737
    // Draw from -1 to longLen rather than from 0 to longLen - 1 to take into
738
    // account the offset applied in drawScaleTick
739
    for ( int x = -1; x <= longLen; ++x ) {
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
740
      if ( mLeftToRight ) {
741
        digit = x + mOffset;
742
      } else {
743
        digit = longLen - x + mOffset;
744
      }
745
746
      if ( digit % 2 ) continue;
747
534.1.11 by Aurélien Gâteau
Draw ruler indicator
748
      if ( digit % 100 == 0 ) {
749
        len = LARGE_TICK_SIZE;
750
      } else if ( digit % 20 == 0 ) {
751
        len = MEDIUM2_TICK_SIZE;
752
      } else if (digit % 10 == 0) {
753
        len = MEDIUM1_TICK_SIZE;
754
      } else {
755
        len = SMALL_TICK_SIZE;
756
      }
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
757
534.1.10 by Aurélien Gâteau
Do not draw text under resize handles
758
      if ( digit % 100 == 0 && digit != 0 ) {
581 by Laurent Montel
Make it compiles without deprecated method
759
        QString units = QStringLiteral("%1").arg(digit);
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
760
        drawScaleText( painter, x, units );
761
      }
762
763
      drawScaleTick( painter, x, len );
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
764
    }
765
  } else {
766
    float step = longLen / 100.f;
767
    int len;
768
769
    for ( int i = 0; i <= 100; ++i ) {
770
      int x = (int)( i * step );
771
534.1.10 by Aurélien Gâteau
Do not draw text under resize handles
772
      if ( i % 10 == 0 && i != 0 && i != 100 ) {
350 by Mathias Soeken
kruler is now able to handle relative scales (in both directions). If you have relative scales you can
773
        int value = mLeftToRight ? i : ( 100 - i );
581 by Laurent Montel
Make it compiles without deprecated method
774
        const QString units = QString::asprintf( "%d%%", value );
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
775
        drawScaleText( painter, x, units );
534.1.11 by Aurélien Gâteau
Draw ruler indicator
776
        len = MEDIUM2_TICK_SIZE;
777
      } else {
778
        len = SMALL_TICK_SIZE;
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
779
      }
780
781
      drawScaleTick( painter, x, len );
1 by Carsten Pfeiffer
import of KRuler for Till
782
    }
783
  }
784
}
338 by Mathias Soeken
coding style. some cleanup
785
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
786
void KLineal::drawScaleText( QPainter &painter, int x, const QString &text )
787
{
788
  QFontMetrics metrics = painter.fontMetrics();
789
  QSize textSize = metrics.size( Qt::TextSingleLine, text );
790
  int w = width();
791
  int h = height();
792
  int tw = textSize.width();
793
  int th = metrics.ascent();
794
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
795
  if ( mHorizontal ) {
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
796
    painter.drawText( x - tw / 2, (h + th) / 2, text );
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
797
  } else {
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
798
    painter.drawText( (w - tw) / 2, x + th / 2, text );
799
  }
800
}
801
802
void KLineal::drawScaleTick( QPainter &painter, int x, int len )
803
{
534.1.17 by Aurélien Gâteau
Make ticks not fully opaque
804
  painter.setOpacity( TICK_OPACITY );
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
805
  int w = width();
806
  int h = height();
534.1.16 by Aurélien Gâteau
Add indicator overlay
807
  // Offset by one because we are measuring lengths, not positions, so when the
534.1.12 by Aurélien Gâteau
Measure lengths, not positions
808
  // indicator is at position 0 it measures a length of 1 pixel.
534.1.16 by Aurélien Gâteau
Add indicator overlay
809
  if ( mLeftToRight ) {
810
    --x;
811
  } else {
812
    ++x;
813
  }
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
814
  if ( mHorizontal ) {
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
815
    painter.drawLine( x, 0, x, len );
816
    painter.drawLine( x, h, x, h - len );
534.1.8 by Aurélien Gâteau
Replace mOrientation with mHorizontal
817
  } else {
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
818
    painter.drawLine( 0, x, len, x );
819
    painter.drawLine( w, x, w - len, x );
820
  }
534.1.17 by Aurélien Gâteau
Make ticks not fully opaque
821
  painter.setOpacity( 1 );
534.1.3 by Aurélien Gâteau
Factorize tick and text drawing code
822
}
823
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
824
void KLineal::drawResizeHandle( QPainter &painter, Qt::Edge edge )
825
{
826
  QRect rect;
827
  switch ( edge ) {
828
  case Qt::LeftEdge:
829
  case Qt::TopEdge:
830
    rect = beginRect();
831
    break;
832
  case Qt::RightEdge:
833
  case Qt::BottomEdge:
834
    rect = endRect();
835
    break;
836
  }
837
  painter.setOpacity( RESIZE_HANDLE_OPACITY );
838
  if ( mHorizontal ) {
534.1.13 by Aurélien Gâteau
Remove length actions
839
    int y1 = ( THICKNESS - RESIZE_HANDLE_THICKNESS ) / 2;
840
    int y2 = y1 + RESIZE_HANDLE_THICKNESS - 1;
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
841
    for ( int x = rect.left() + 1; x < rect.right(); x += 2 ) {
842
      painter.drawLine( x, y1, x, y2 );
843
    }
844
  } else {
534.1.13 by Aurélien Gâteau
Remove length actions
845
    int x1 = ( THICKNESS - RESIZE_HANDLE_THICKNESS ) / 2;
846
    int x2 = x1 + RESIZE_HANDLE_THICKNESS - 1;
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
847
    for ( int y = rect.top() + 1; y < rect.bottom(); y += 2 ) {
848
      painter.drawLine( x1, y, x2, y );
849
    }
850
  }
851
  painter.setOpacity( 1 );
852
}
853
534.1.16 by Aurélien Gâteau
Add indicator overlay
854
void KLineal::drawIndicatorOverlay( QPainter &painter, int xy )
855
{
856
  painter.setPen( Qt::red );
857
  painter.setOpacity( OVERLAY_OPACITY );
858
  if ( mHorizontal ) {
859
    QPointF p1( mLeftToRight ? 0 : width(), 0 );
860
    QPointF p2( xy, THICKNESS );
861
    QRectF rect( p1, p2 );
862
    painter.fillRect( rect, Qt::red );
863
864
    painter.setOpacity( OVERLAY_BORDER_OPACITY );
865
    painter.drawLine( xy, 0, xy, THICKNESS );
866
  } else {
867
    QPointF p1( 0, mLeftToRight ? 0 : height() );
868
    QPointF p2( THICKNESS, xy );
869
    QRectF rect( p1, p2 );
870
    painter.fillRect( rect, Qt::red );
871
872
    painter.setOpacity( OVERLAY_BORDER_OPACITY );
873
    painter.drawLine( 0, xy, THICKNESS, xy );
874
  }
875
}
876
877
void KLineal::drawIndicatorText( QPainter &painter, int xy )
878
{
879
  QString text = indicatorText();
880
  painter.setFont( font() );
881
  QFontMetrics fm = QFontMetrics( font() );
882
  int tx, ty;
555 by Laurent Montel
fix compile without deprecated method
883
  int tw = fm.boundingRect(text).width();
534.1.16 by Aurélien Gâteau
Add indicator overlay
884
  if ( mHorizontal ) {
885
    tx = xy + INDICATOR_MARGIN;
886
    if ( tx + tw > width() ) {
887
      tx = xy - tw - INDICATOR_MARGIN;
888
    }
889
    ty = height() - SMALL_TICK_SIZE - INDICATOR_RECT_RADIUS;
890
  } else {
891
    tx = ( width() - tw ) / 2;
892
    ty = xy + fm.ascent() + INDICATOR_MARGIN;
893
    if ( ty > height() ) {
894
      ty = xy - INDICATOR_MARGIN;
895
    }
896
  }
897
898
  // Draw background rect
899
  painter.setRenderHint( QPainter::Antialiasing );
900
  painter.setOpacity( INDICATOR_RECT_OPACITY );
901
  painter.setBrush( Qt::red );
902
  QRectF bgRect( tx, ty - fm.ascent() + 1, tw, fm.ascent() );
903
  bgRect.adjust( -INDICATOR_RECT_RADIUS, -INDICATOR_RECT_RADIUS, INDICATOR_RECT_RADIUS, INDICATOR_RECT_RADIUS );
904
  bgRect.translate( 0.5, 0.5 );
905
  painter.drawRoundedRect( bgRect, INDICATOR_RECT_RADIUS, INDICATOR_RECT_RADIUS );
906
907
  // Draw text
908
  painter.setOpacity( 1 );
909
  painter.setPen( Qt::white );
910
  painter.drawText( tx, ty, text );
911
}
912
1 by Carsten Pfeiffer
import of KRuler for Till
913
/**
338 by Mathias Soeken
coding style. some cleanup
914
 * actually draws the ruler
915
 */
916
void KLineal::paintEvent(QPaintEvent *inEvent )
917
{
918
  Q_UNUSED( inEvent );
919
920
  QPainter painter( this );
921
  drawBackground( painter );
922
  drawScale( painter );
534.1.9 by Aurélien Gâteau
Make edges resizeable by drag'n'drop
923
924
  drawResizeHandle( painter, mHorizontal ? Qt::LeftEdge : Qt::TopEdge );
925
  drawResizeHandle( painter, mHorizontal ? Qt::RightEdge : Qt::BottomEdge );
534.1.11 by Aurélien Gâteau
Draw ruler indicator
926
  if ( underMouse() && !isResizing() ) {
534.1.16 by Aurélien Gâteau
Add indicator overlay
927
    int xy = mHorizontal ? localCursorPos().x() : localCursorPos().y();
928
    drawIndicatorOverlay( painter, xy );
929
    drawIndicatorText( painter, xy );
534.1.11 by Aurélien Gâteau
Draw ruler indicator
930
  }
1 by Carsten Pfeiffer
import of KRuler for Till
931
}