Krita Source Code Documentation
Loading...
Searching...
No Matches
KoRuler.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 SPDX-FileCopyrightText: 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3 SPDX-FileCopyrightText: 2006 Peter Simonsson <peter.simonsson@gmail.com>
4 SPDX-FileCopyrightText: 2007 C. Boemann <cbo@boemann.dk>
5 SPDX-FileCopyrightText: 2007-2008 Jan Hambrecht <jaham@gmx.net>
6 SPDX-FileCopyrightText: 2007 Thomas Zander <zander@kde.org>
7
8 SPDX-License-Identifier: LGPL-2.0-or-later
9*/
10
11#include "KoRuler.h"
12
13#include "KoRuler_p.h"
14#include <KoToolBase.h>
15#include <KoToolManager.h>
16
17#include <klocalizedstring.h>
18#include <WidgetsDebug.h>
19
20#include <QPainter>
21#include <QResizeEvent>
22#include <QMenu>
23#include <QMouseEvent>
24#include <QFontDatabase>
25#include <QtMath>
26#include <cmath>
27
28#include <KoViewConverter.h>
29
30// the distance in pixels of a mouse position considered outside the rule
31static const int OutsideRulerThreshold = 20;
32//
33static const int fullStepMarkerLength = 6;
34static const int halfStepMarkerLength = 6;
35static const int quarterStepMarkerLength = 3;
37
38
40{
41 if (! m_showTabs) {
42 return;
43 }
44
45 switch(m_type) {
46 case QTextOption::LeftTab:
47 m_type = QTextOption::RightTab;
48 break;
49 case QTextOption::RightTab:
50 m_type = QTextOption::CenterTab;
51 break;
52 case QTextOption::CenterTab:
53 m_type = QTextOption::DelimiterTab;
54 break;
55 case QTextOption::DelimiterTab:
56 m_type = QTextOption::LeftTab;
57 break;
58 }
59 update();
60}
61
62void RulerTabChooser::paintEvent(QPaintEvent *)
63{
64 if (! m_showTabs) {
65 return;
66 }
67
68 QPainter painter(this);
69 QPolygonF polygon;
70
71 painter.setPen(QPen(palette().color(QPalette::Text), 0));
72 painter.setBrush(palette().color(QPalette::Text));
73 painter.setRenderHint( QPainter::Antialiasing );
74
75 qreal x = 0.5 * width();
76 painter.translate(0,-height()/2+5);
77
78 switch (m_type) {
79 case QTextOption::LeftTab:
80 polygon << QPointF(x+0.5, height() - 8.5)
81 << QPointF(x+6.5, height() - 2.5)
82 << QPointF(x+0.5, height() - 2.5);
83 painter.drawPolygon(polygon);
84 break;
85 case QTextOption::RightTab:
86 polygon << QPointF(x+0.5, height() - 8.5)
87 << QPointF(x-5.5, height() - 2.5)
88 << QPointF(x+0.5, height() - 2.5);
89 painter.drawPolygon(polygon);
90 break;
91 case QTextOption::CenterTab:
92 polygon << QPointF(x+0.5, height() - 8.5)
93 << QPointF(x-5.5, height() - 2.5)
94 << QPointF(x+6.5, height() - 2.5);
95 painter.drawPolygon(polygon);
96 break;
97 case QTextOption::DelimiterTab:
98 polygon << QPointF(x-5.5, height() - 2.5)
99 << QPointF(x+6.5, height() - 2.5);
100 painter.drawPolyline(polygon);
101 polygon << QPointF(x+0.5, height() - 2.5)
102 << QPointF(x+0.5, height() - 8.5);
103 painter.drawPolyline(polygon);
104 break;
105 default:
106 break;
107 }
108}
109
110struct {
111 bool operator()(KoRuler::Tab tab1, KoRuler::Tab tab2) const
112 {
113 return tab1.position < tab2.position;
114 }
116
117
119{
120 lengthInPixel = d->viewConverter->documentToViewX(d->rulerLength);
121 QRectF rectangle;
122
123 rectangle.setX(qMax(0, d->offset));
124 rectangle.setY(0);
125 rectangle.setWidth(qMin(qreal(d->ruler->width() - 1.0 - rectangle.x()),
126 (d->offset >= 0) ? lengthInPixel : lengthInPixel + d->offset));
127 rectangle.setHeight(d->ruler->height() - 1);
128 QRectF activeRangeRectangle;
129 activeRangeRectangle.setX(qMax(rectangle.x() + 1,
130 d->viewConverter->documentToViewX(d->effectiveActiveRangeStart()) + d->offset));
131 activeRangeRectangle.setY(rectangle.y() + 1);
132 activeRangeRectangle.setRight(qMin(rectangle.right() - 1,
133 d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()) + d->offset));
134 activeRangeRectangle.setHeight(rectangle.height() - 2);
135
136 painter.setPen(QPen(d->ruler->palette().color(QPalette::Mid), 0));
137
138 painter.fillRect(rectangle,d->ruler->palette().color(QPalette::AlternateBase)); // make background slightly different so it is easier to see
139 painter.drawRect(rectangle);
140
141 if(d->effectiveActiveRangeStart() != d->effectiveActiveRangeEnd())
142 painter.fillRect(activeRangeRectangle, d->ruler->palette().brush(QPalette::Base));
143
144 if(d->showSelectionBorders) {
145 // Draw first selection border
146 if(d->firstSelectionBorder > 0) {
147 qreal border = d->viewConverter->documentToViewX(d->firstSelectionBorder) + d->offset;
148 painter.drawLine(QPointF(border, rectangle.y() + 1), QPointF(border, rectangle.bottom() - 1));
149 }
150 // Draw second selection border
151 if(d->secondSelectionBorder > 0) {
152 qreal border = d->viewConverter->documentToViewX(d->secondSelectionBorder) + d->offset;
153 painter.drawLine(QPointF(border, rectangle.y() + 1), QPointF(border, rectangle.bottom() - 1));
154 }
155 }
156
157 return rectangle;
158}
159
161{
162 if (! d->showTabs)
163 return;
164 QPolygonF polygon;
165
166 const QColor tabColor = d->ruler->palette().color(QPalette::Text);
167 painter.setPen(QPen(tabColor, 0));
168 painter.setBrush(tabColor);
169 painter.setRenderHint( QPainter::Antialiasing );
170
171 qreal position = -10000;
172
173 foreach (const KoRuler::Tab & t, d->tabs) {
174 qreal x;
175 if (d->rightToLeft) {
176 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()
177 - (d->relativeTabs ? d->paragraphIndent : 0) - t.position) + d->offset;
178 } else {
179 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeStart()
180 + (d->relativeTabs ? d->paragraphIndent : 0) + t.position) + d->offset;
181 }
182 position = qMax(position, t.position);
183
184 polygon.clear();
185 switch (t.type) {
186 case QTextOption::LeftTab:
187 polygon << QPointF(x+0.5, d->ruler->height() - 6.5)
188 << QPointF(x+6.5, d->ruler->height() - 0.5)
189 << QPointF(x+0.5, d->ruler->height() - 0.5);
190 painter.drawPolygon(polygon);
191 break;
192 case QTextOption::RightTab:
193 polygon << QPointF(x+0.5, d->ruler->height() - 6.5)
194 << QPointF(x-5.5, d->ruler->height() - 0.5)
195 << QPointF(x+0.5, d->ruler->height() - 0.5);
196 painter.drawPolygon(polygon);
197 break;
198 case QTextOption::CenterTab:
199 polygon << QPointF(x+0.5, d->ruler->height() - 6.5)
200 << QPointF(x-5.5, d->ruler->height() - 0.5)
201 << QPointF(x+6.5, d->ruler->height() - 0.5);
202 painter.drawPolygon(polygon);
203 break;
204 case QTextOption::DelimiterTab:
205 polygon << QPointF(x-5.5, d->ruler->height() - 0.5)
206 << QPointF(x+6.5, d->ruler->height() - 0.5);
207 painter.drawPolyline(polygon);
208 polygon << QPointF(x+0.5, d->ruler->height() - 0.5)
209 << QPointF(x+0.5, d->ruler->height() - 6.5);
210 painter.drawPolyline(polygon);
211 break;
212 default:
213 break;
214 }
215 }
216
217 // and also draw the regular interval tab that are non editable
218 if (d->tabDistance > 0.0) {
219 // first possible position
220 position = qMax(position, d->relativeTabs ? 0 : d->paragraphIndent);
221 if (position < 0) {
222 position = int(position / d->tabDistance) * d->tabDistance;
223 } else {
224 position = (int(position / d->tabDistance) + 1) * d->tabDistance;
225 }
226 while (position < d->effectiveActiveRangeEnd() - d->effectiveActiveRangeStart()
227 - d->endIndent) {
228 qreal x;
229 if (d->rightToLeft) {
230 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()
231 - (d->relativeTabs ? d->paragraphIndent : 0) - position) + d->offset;
232 } else {
233 x = d->viewConverter->documentToViewX(d->effectiveActiveRangeStart()
234 + (d->relativeTabs ? d->paragraphIndent : 0) + position) + d->offset;
235 }
236
237 polygon.clear();
238 polygon << QPointF(x+0.5, d->ruler->height() - 3.5)
239 << QPointF(x+4.5, d->ruler->height() - 0.5)
240 << QPointF(x+0.5, d->ruler->height() - 0.5);
241 painter.drawPolygon(polygon);
242
243 position += d->tabDistance;
244 }
245 }
246}
247
248void HorizontalPaintingStrategy::drawMeasurements(const KoRulerPrivate *d, QPainter &painter, const QRectF &rectangle)
249{
250 const QFont font = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont);
251 const QFontMetrics fontMetrics(font);
252 const QPen numberPen(d->ruler->palette().color(QPalette::Text), 0);
253 const QPen markerPen(d->ruler->palette().color(QPalette::Inactive, QPalette::Text), 0);
254 painter.setPen(markerPen);
255 painter.setFont(font);
256
257 // length of the ruler in pixels
258 const int rulerLengthPixel = d->viewConverter->documentToViewX(d->rulerLength);
259 // length of the ruler in the chosen unit
260 const qreal rulerLengthUnit = d->unit.toUserValue(d->rulerLength);
261 // length of a unit in pixels
262 const qreal unitLength = d->viewConverter->documentToViewX(d->unit.fromUserValue(1.0));
263 // length of the text for longest number with some padding
264 const int textLength = fontMetrics.horizontalAdvance(QString::number(qCeil(rulerLengthUnit))) + 20;
265 // the minimal separation of numbers that won't make the text a mess
266 const qreal minimalNumberSeparation = qCeil(textLength / unitLength);
267 // the chosen separation of numbers so that we have "whole" numbers
268 qreal numberSeparation = minimalNumberSeparation;
269 if (minimalNumberSeparation <= 5) {
270 } else if (minimalNumberSeparation <= 10) {
271 numberSeparation = 10;
272 } else if (minimalNumberSeparation <= 20) {
273 numberSeparation = 20;
274 } else if (minimalNumberSeparation <= 50) {
275 numberSeparation = 50;
276 } else if (minimalNumberSeparation <= 100) {
277 numberSeparation = 100;
278 } else if (minimalNumberSeparation <= 200) {
279 numberSeparation = 200;
280 } else if (minimalNumberSeparation <= 500) {
281 numberSeparation = 500;
282 } else {
283 numberSeparation = qRound(qreal(numberSeparation / 100)) * 100;
284 }
285 // the chosen separation converted to pixel
286 const int pixelSeparation = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(numberSeparation)));
287 // the value used to calculate displacement of secondary marks
288 const int secondarydisplacement = d->rightToLeft ? -pixelSeparation : pixelSeparation;
289
290 // Draw the marks
291 int rulerEnd;
292 qreal numberStart, numberEnd;
293 if (d->rightToLeft) {
294 rulerEnd = d->offset;
295 numberStart = d->unit.toUserValue(d->viewConverter->viewToDocumentX(
296 rulerLengthPixel + d->offset - rectangle.right()));
297 // draw the partly hidden mark when the left part of the ruler is
298 // invisible
299 int pixelEnd = rulerLengthPixel + d->offset - rectangle.left();
300 if (rulerEnd + textLength < rectangle.left()) {
301 pixelEnd -= textLength;
302 }
303 numberEnd = d->unit.toUserValue(d->viewConverter->viewToDocumentX(
304 pixelEnd));
305 if (rulerLengthPixel + d->offset > rectangle.right()) {
306 numberStart -= fmod(numberStart, numberSeparation);
307 }
308 } else {
309 rulerEnd = d->offset + rulerLengthPixel;
310 numberStart = d->unit.toUserValue(d->viewConverter->viewToDocumentX(
311 rectangle.left() - d->offset));
312 // draw the partly hidden mark when the right part of the ruler is
313 // invisible
314 int pixelEnd = rectangle.right() - d->offset;
315 if (rulerEnd - textLength > rectangle.right()) {
316 pixelEnd += textLength;
317 }
318 numberEnd = d->unit.toUserValue(d->viewConverter->viewToDocumentX(
319 pixelEnd));
320 if (d->offset < 0) {
321 numberStart -= fmod(numberStart, numberSeparation);
322 }
323 }
324 for(qreal n = numberStart; n < numberEnd; n += numberSeparation) {
325 int posOnRuler = qRound(d->viewConverter->documentToViewX(d->unit.fromUserValue(n)));
326 int x = posOnRuler + d->offset;
327 if (d->rightToLeft) {
328 x = d->offset + rulerLengthPixel - posOnRuler;
329 }
330
331 // to draw the primary mark
332 painter.drawLine(QPointF(x, rectangle.bottom()-1),
333 QPointF(x, rectangle.bottom() - fullStepMarkerLength));
334 QString numberText = QString::number(n);
335 painter.setPen(numberPen);
336 painter.drawText(QPointF(x - fontMetrics.horizontalAdvance(numberText)/2.0,
338 numberText);
339 // start to draw secondary marks following the primary mark
340 painter.setPen(markerPen);
341
342 int xQuarterMark1 = qRound(qreal(x) + qreal(secondarydisplacement) / 4.0);
343 if (d->rightToLeft ? xQuarterMark1 < rulerEnd : xQuarterMark1 > rulerEnd)
344 break;
345 painter.drawLine(QPointF(xQuarterMark1, rectangle.bottom() - 1),
346 QPointF(xQuarterMark1, rectangle.bottom() - quarterStepMarkerLength));
347
348 int xHalfMark = qRound(qreal(x) + qreal(secondarydisplacement) / 2.0);
349 if (d->rightToLeft ? xHalfMark < rulerEnd : xHalfMark > rulerEnd)
350 break;
351 painter.drawLine(QPointF(xHalfMark, rectangle.bottom() - 1),
352 QPointF(xHalfMark, rectangle.bottom() - halfStepMarkerLength));
353
354 int xQuarterMark2 = qRound(qreal(x) + 3.0 * qreal(secondarydisplacement) / 4.0);
355 if (d->rightToLeft ? xQuarterMark2 < rulerEnd : xQuarterMark2 > rulerEnd)
356 break;
357 painter.drawLine(QPointF(xQuarterMark2, rectangle.bottom() - 1),
358 QPointF(xQuarterMark2, rectangle.bottom() - quarterStepMarkerLength));
359 }
360
361 // Draw the mouse indicator
362 const int mouseCoord = d->mouseCoordinate + d->offset;
363 if (d->selected == KoRulerPrivate::None || d->selected == KoRulerPrivate::HotSpot) {
364 const qreal top = rectangle.y() + 1;
365 const qreal bottom = rectangle.bottom() -1;
366 if (d->selected == KoRulerPrivate::None
367 && d->showMousePosition
368 && d->mouseCoordinate > 0
369 && d->mouseCoordinate < rulerLengthPixel)
370 painter.drawLine(QPointF(mouseCoord, top), QPointF(mouseCoord, bottom));
371 foreach (const KoRulerPrivate::HotSpotData & hp, d->hotspots) {
372 const qreal x = d->viewConverter->documentToViewX(hp.position) + d->offset;
373 painter.drawLine(QPointF(x, top), QPointF(x, bottom));
374 }
375 }
376}
377
379{
380 QPolygonF polygon;
381
382 painter.setBrush(d->ruler->palette().brush(QPalette::Base));
383 painter.setRenderHint( QPainter::Antialiasing );
384
385 qreal x;
386 // Draw first line start indent
387 if (d->rightToLeft)
388 x = d->effectiveActiveRangeEnd() - d->firstLineIndent - d->paragraphIndent;
389 else
390 x = d->effectiveActiveRangeStart() + d->firstLineIndent + d->paragraphIndent;
391 // convert and use the +0.5 to go to nearest integer so that the 0.5 added below ensures sharp lines
392 x = int(d->viewConverter->documentToViewX(x) + d->offset + 0.5);
393 polygon << QPointF(x+6.5, 0.5)
394 << QPointF(x+0.5, 8.5)
395 << QPointF(x-5.5, 0.5)
396 << QPointF(x+5.5, 0.5);
397 painter.drawPolygon(polygon);
398
399 // draw the hanging indent.
400 if (d->rightToLeft)
401 x = d->effectiveActiveRangeStart() + d->endIndent;
402 else
403 x = d->effectiveActiveRangeStart() + d->paragraphIndent;
404 // convert and use the +0.5 to go to nearest integer so that the 0.5 added below ensures sharp lines
405 x = int(d->viewConverter->documentToViewX(x) + d->offset + 0.5);
406 const int bottom = d->ruler->height();
407 polygon.clear();
408 polygon << QPointF(x+6.5, bottom - 0.5)
409 << QPointF(x+0.5, bottom - 8.5)
410 << QPointF(x-5.5, bottom - 0.5)
411 << QPointF(x+5.5, bottom - 0.5);
412 painter.drawPolygon(polygon);
413
414 // Draw end-indent or paragraph indent if mode is rightToLeft
415 qreal diff;
416 if (d->rightToLeft)
417 diff = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd()
418 - d->paragraphIndent) + d->offset - x;
419 else
420 diff = d->viewConverter->documentToViewX(d->effectiveActiveRangeEnd() - d->endIndent)
421 + d->offset - x;
422 polygon.translate(diff, 0);
423 painter.drawPolygon(polygon);
424}
425
427{
428 // assumes that digits for the number only use glyphs which do not go below the baseline
429 const QFontMetrics fm(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
430 const int digitsHeight = fm.ascent() + 1; // +1 for baseline
431 const int minimum = digitsHeight + fullStepMarkerLength + 2*measurementTextAboveBelowMargin;
432
433 return QSize(0, minimum);
434}
435
437{
438 lengthInPixel = d->viewConverter->documentToViewY(d->rulerLength);
439 QRectF rectangle;
440 rectangle.setX(0);
441 rectangle.setY(qMax(0, d->offset));
442 rectangle.setWidth(d->ruler->width() - 1.0);
443 rectangle.setHeight(qMin(qreal(d->ruler->height() - 1.0 - rectangle.y()),
444 (d->offset >= 0) ? lengthInPixel : lengthInPixel + d->offset));
445
446 QRectF activeRangeRectangle;
447 activeRangeRectangle.setX(rectangle.x() + 1);
448 activeRangeRectangle.setY(qMax(rectangle.y() + 1,
449 d->viewConverter->documentToViewY(d->effectiveActiveRangeStart()) + d->offset));
450 activeRangeRectangle.setWidth(rectangle.width() - 2);
451 activeRangeRectangle.setBottom(qMin(rectangle.bottom() - 1,
452 d->viewConverter->documentToViewY(d->effectiveActiveRangeEnd()) + d->offset));
453
454 painter.setPen(QPen(d->ruler->palette().color(QPalette::Mid), 0));
455
456 painter.fillRect(rectangle,d->ruler->palette().color(QPalette::AlternateBase));
457 painter.drawRect(rectangle);
458
459 if(d->effectiveActiveRangeStart() != d->effectiveActiveRangeEnd())
460 painter.fillRect(activeRangeRectangle, d->ruler->palette().brush(QPalette::Base));
461
462 if(d->showSelectionBorders) {
463 // Draw first selection border
464 if(d->firstSelectionBorder > 0) {
465 qreal border = d->viewConverter->documentToViewY(d->firstSelectionBorder) + d->offset;
466 painter.drawLine(QPointF(rectangle.x() + 1, border), QPointF(rectangle.right() - 1, border));
467 }
468 // Draw second selection border
469 if(d->secondSelectionBorder > 0) {
470 qreal border = d->viewConverter->documentToViewY(d->secondSelectionBorder) + d->offset;
471 painter.drawLine(QPointF(rectangle.x() + 1, border), QPointF(rectangle.right() - 1, border));
472 }
473 }
474
475 return rectangle;
476}
477
478void VerticalPaintingStrategy::drawMeasurements(const KoRulerPrivate *d, QPainter &painter, const QRectF &rectangle)
479{
480 const QFont font = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont);
481 const QFontMetrics fontMetrics(font);
482 const QPen numberPen(d->ruler->palette().color(QPalette::Text), 0);
483 const QPen markerPen(d->ruler->palette().color(QPalette::Inactive, QPalette::Text), 0);
484 painter.setPen(markerPen);
485 painter.setFont(font);
486
487 // length of the ruler in pixels
488 const int rulerLengthPixel = d->viewConverter->documentToViewY(d->rulerLength);
489 // length of the ruler in the chosen unit
490 const qreal rulerLengthUnit = d->unit.toUserValue(d->rulerLength);
491 // length of a unit in pixels
492 const qreal unitLength = d->viewConverter->documentToViewY(d->unit.fromUserValue(1.0));
493 // length of the text for longest number with some padding
494 const int textLength = fontMetrics.horizontalAdvance(QString::number(qCeil(rulerLengthUnit))) + 20;
495
496 // the minimal separation of numbers that won't make the text a mess
497 const qreal minimalNumberSeparation = qCeil(textLength / unitLength);
498 // the chosen separation of numbers so that we have "whole" numbers
499 qreal numberSeparation = minimalNumberSeparation;
500 if (minimalNumberSeparation <= 5) {
501 } else if (minimalNumberSeparation <= 10) {
502 numberSeparation = 10;
503 } else if (minimalNumberSeparation <= 20) {
504 numberSeparation = 20;
505 } else if (minimalNumberSeparation <= 50) {
506 numberSeparation = 50;
507 } else if (minimalNumberSeparation <= 100) {
508 numberSeparation = 100;
509 } else if (minimalNumberSeparation <= 200) {
510 numberSeparation = 200;
511 } else if (minimalNumberSeparation <= 500) {
512 numberSeparation = 500;
513 } else {
514 numberSeparation = qRound(qreal(numberSeparation / 100.0)) * 100;
515 }
516 // the chosen separation converted to pixel
517 const int pixelSeparation = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(numberSeparation)));
518
519 // Draw the marks
520 const int rulerEnd = rulerLengthPixel + d->offset;
521 qreal numberStart = d->unit.toUserValue(d->viewConverter->viewToDocumentY(
522 rectangle.top() - d->offset));
523 // draw the partly hidden mark when the bottom part of the ruler is
524 // invisible
525 int pixelEnd = rectangle.bottom() - d->offset;
526 if (rulerEnd - textLength > rectangle.bottom()) {
527 pixelEnd += textLength;
528 }
529 qreal numberEnd = d->unit.toUserValue(d->viewConverter->viewToDocumentX(
530 pixelEnd));
531 if (d->offset < 0) {
532 numberStart -= fmod(numberStart, numberSeparation);
533 }
534 for(qreal n = numberStart; n < numberEnd; n += numberSeparation) {
535 int posOnRuler = qRound(d->viewConverter->documentToViewY(d->unit.fromUserValue(n)));
536 int y = d->offset + posOnRuler;
537
538 // to draw the primary mark
539 QString numberText = QString::number(n);
540 painter.save();
541 painter.translate(rectangle.right() - fullStepMarkerLength, y);
542 painter.drawLine(QPointF(0, 0),
543 QPointF(rectangle.right() - fullStepMarkerLength, 0));
544 painter.setPen(numberPen);
545 painter.rotate(-90);
546 painter.drawText(QPointF(-fontMetrics.horizontalAdvance(numberText) / 2.0, 0),
547 numberText);
548 painter.restore();
549
550 // start to draw secondary marks following the primary mark
551 painter.setPen(markerPen);
552
553 int yQuarterMark1 = qRound(qreal(y + pixelSeparation / 4.0));
554 if (yQuarterMark1 > rulerEnd)
555 break;
556 painter.drawLine(QPointF(rectangle.right() - 1, yQuarterMark1),
557 QPointF(rectangle.right() - quarterStepMarkerLength, yQuarterMark1));
558
559 int yHalfMark = qRound(qreal(y + pixelSeparation / 2.0));
560 if (yHalfMark > rulerEnd)
561 break;
562 painter.drawLine(QPointF(rectangle.right() - 1, yHalfMark),
563 QPointF(rectangle.right() - halfStepMarkerLength, yHalfMark));
564
565 int yQuarterMark2 = qRound(qreal(y + 3.0 * pixelSeparation / 4.0));
566 if (yQuarterMark2 > rulerEnd)
567 break;
568 painter.drawLine(QPointF(rectangle.right() - 1, yQuarterMark2),
569 QPointF(rectangle.right() - quarterStepMarkerLength, yQuarterMark2));
570 }
571
572 // Draw the mouse indicator
573 const int mouseCoord = d->mouseCoordinate + d->offset;
574 if (d->selected == KoRulerPrivate::None || d->selected == KoRulerPrivate::HotSpot) {
575 const qreal left = rectangle.left() + 1;
576 const qreal right = rectangle.right() -1;
577 if (d->selected == KoRulerPrivate::None
578 && d->showMousePosition
579 && d->mouseCoordinate > 0
580 && d->mouseCoordinate < rulerLengthPixel)
581 painter.drawLine(QPointF(left, mouseCoord), QPointF(right, mouseCoord));
582 foreach (const KoRulerPrivate::HotSpotData & hp, d->hotspots) {
583 const qreal y = d->viewConverter->documentToViewY(hp.position) + d->offset;
584 painter.drawLine(QPointF(left, y), QPointF(right, y));
585 }
586 }
587}
588
590{
591 // assumes that digits for the number only use glyphs which do not go below the baseline
592 const QFontMetrics fm(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
593 const int digitsHeight = fm.ascent() + 1; // +1 for baseline
594 const int minimum = digitsHeight + fullStepMarkerLength + 2*measurementTextAboveBelowMargin;
595
596 return QSize(minimum, 0);
597}
598
599
600void HorizontalDistancesPaintingStrategy::drawDistanceLine(const KoRulerPrivate *d, QPainter &painter, const qreal start, const qreal end)
601{
602
603 // Don't draw too short lines
604 if (qMax(start, end) - qMin(start, end) < 1)
605 return;
606
607 painter.save();
608 painter.translate(d->offset, d->ruler->height() / 2);
609 painter.setPen(QPen(d->ruler->palette().color(QPalette::Text), 0));
610 painter.setBrush(d->ruler->palette().color(QPalette::Text));
611
612 QLineF line(QPointF(d->viewConverter->documentToViewX(start), 0),
613 QPointF(d->viewConverter->documentToViewX(end), 0));
614 QPointF midPoint = line.pointAt(0.5);
615
616 // Draw the label text
617 const QFont font = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont);
618 const QFontMetrics fontMetrics(font);
619 QString label = d->unit.toUserStringValue(
620 d->viewConverter->viewToDocumentX(line.length())) + ' ' + d->unit.symbol();
621 QPointF labelPosition = QPointF(midPoint.x() - fontMetrics.horizontalAdvance(label)/2,
622 midPoint.y() + fontMetrics.ascent()/2);
623 painter.setFont(font);
624 painter.drawText(labelPosition, label);
625
626 // Draw the arrow lines
627 qreal arrowLength = (line.length() - fontMetrics.horizontalAdvance(label)) / 2 - 2;
628 arrowLength = qMax(qreal(0.0), arrowLength);
629 QLineF startArrow(line.p1(), line.pointAt(arrowLength / line.length()));
630 QLineF endArrow(line.p2(), line.pointAt(1.0 - arrowLength / line.length()));
631 painter.drawLine(startArrow);
632 painter.drawLine(endArrow);
633
634 // Draw the arrow heads
635 QPolygonF arrowHead;
636 arrowHead << line.p1() << QPointF(line.x1()+3, line.y1()-3)
637 << QPointF(line.x1()+3, line.y1()+3);
638 painter.drawPolygon(arrowHead);
639 arrowHead.clear();
640 arrowHead << line.p2() << QPointF(line.x2()-3, line.y2()-3)
641 << QPointF(line.x2()-3, line.y2()+3);
642 painter.drawPolygon(arrowHead);
643
644 painter.restore();
645}
646
647void HorizontalDistancesPaintingStrategy::drawMeasurements(const KoRulerPrivate *d, QPainter &painter, const QRectF&)
648{
649 QList<qreal> points;
650 points << 0.0;
651 points << d->effectiveActiveRangeStart() + d->paragraphIndent + d->firstLineIndent;
652 points << d->effectiveActiveRangeStart() + d->paragraphIndent;
653 points << d->effectiveActiveRangeEnd() - d->endIndent;
654 points << d->effectiveActiveRangeStart();
655 points << d->effectiveActiveRangeEnd();
656 points << d->rulerLength;
657 std::sort(points.begin(), points.end());
658 QListIterator<qreal> i(points);
659 i.next();
660 while (i.hasNext() && i.hasPrevious()) {
661 drawDistanceLine(d, painter, i.peekPrevious(), i.peekNext());
662 i.next();
663 }
664}
665
666KoRulerPrivate::KoRulerPrivate(KoRuler *parent, const KoViewConverter *vc, Qt::Orientation o)
667 : unit(KoUnit(KoUnit::Point)),
668 orientation(o),
669 viewConverter(vc),
670 offset(0),
671 rulerLength(0),
672 activeRangeStart(0),
673 activeRangeEnd(0),
674 activeOverrideRangeStart(0),
675 activeOverrideRangeEnd(0),
676 mouseCoordinate(-1),
677 showMousePosition(0),
678 showSelectionBorders(false),
679 firstSelectionBorder(0),
680 secondSelectionBorder(0),
681 showIndents(false),
682 firstLineIndent(0),
683 paragraphIndent(0),
684 endIndent(0),
685 showTabs(false),
686 relativeTabs(false),
687 tabMoved(false),
688 originalIndex(-1),
689 currentIndex(0),
690 rightToLeft(false),
691 selected(None),
692 selectOffset(0),
693 tabChooser(0),
694 normalPaintingStrategy(o == Qt::Horizontal ?
696 distancesPaintingStrategy((PaintingStrategy*)new HorizontalDistancesPaintingStrategy()),
697 paintingStrategy(normalPaintingStrategy),
698 ruler(parent),
699 guideCreationStarted(false),
700 pixelStep(100.0)
701{
702}
703
709
711{
712 switch(unit.type()) {
713 case KoUnit::Inch:
717 return 1.0;
718 case KoUnit::Pica:
719 case KoUnit::Cicero:
720 return 10.0;
721 case KoUnit::Point:
722 default:
723 return pixelStep;
724 }
725}
726
727qreal KoRulerPrivate::doSnapping(const qreal value) const
728{
729 qreal numberStep = unit.fromUserValue(numberStepForUnit()/4.0);
730 return numberStep * qRound(value / numberStep);
731}
732
734{
735 const int height = ruler->height();
736 if (rightToLeft) {
738 if (pos.x() >= x - 8 && pos.x() <= x +8 && pos.y() < height / 2) {
739 if (selectOffset)
740 *selectOffset = x - pos.x();
742 }
743
745 if (pos.x() >= x - 8 && pos.x() <= x +8 && pos.y() > height / 2) {
746 if (selectOffset)
747 *selectOffset = x - pos.x();
749 }
750
752 if (pos.x() >= x - 8 && pos.x() <= x + 8) {
753 if (selectOffset)
754 *selectOffset = x - pos.x();
756 }
757 }
758 else {
760 if (pos.x() >= x -8 && pos.x() <= x + 8 && pos.y() < height / 2) {
761 if (selectOffset)
762 *selectOffset = x - pos.x();
764 }
765
767 if (pos.x() >= x - 8 && pos.x() <= x + 8 && pos.y() > height/2) {
768 if (selectOffset)
769 *selectOffset = x - pos.x();
771 }
772
774 if (pos.x() >= x - 8 && pos.x() <= x + 8) {
775 if (selectOffset)
776 *selectOffset = x - pos.x();
778 }
779 }
780
782}
783
784int KoRulerPrivate::hotSpotIndex(const QPoint & pos)
785{
786 for(int counter = 0; counter < hotspots.count(); counter++) {
787 bool hit;
788 if (orientation == Qt::Horizontal)
789 hit = qAbs(viewConverter->documentToViewX(hotspots[counter].position) - pos.x() + offset) < 3;
790 else
791 hit = qAbs(viewConverter->documentToViewY(hotspots[counter].position) - pos.y() + offset) < 3;
792
793 if (hit)
794 return counter;
795 }
796 return -1;
797}
798
807
809{
812 } else {
813 return activeRangeEnd;
814 }
815}
816
818{
819 KoRuler::Tab tab;
820 if (currentIndex >= 0)
821 tab = tabs[currentIndex];
822 Q_EMIT ruler->tabChanged(originalIndex, currentIndex >= 0 ? &tab : 0);
823}
824
825
826KoRuler::KoRuler(QWidget* parent, Qt::Orientation orientation, const KoViewConverter* viewConverter)
827 : QWidget(parent)
828 , d( new KoRulerPrivate( this, viewConverter, orientation) )
829{
830 setMouseTracking( true );
831}
832
834{
835 delete d;
836}
837
839{
840 return d->unit;
841}
842
843void KoRuler::setUnit(const KoUnit &unit)
844{
845 d->unit = unit;
846 update();
847}
848
850{
851 return d->rulerLength;
852}
853
854Qt::Orientation KoRuler::orientation() const
855{
856 return d->orientation;
857}
858
859void KoRuler::setOffset(int offset)
860{
861 d->offset = offset;
862 update();
863}
864
866{
868 update();
869}
870
871void KoRuler::paintEvent(QPaintEvent* event)
872{
873 QPainter painter(this);
874
875 painter.setClipRegion(event->region());
876
877 painter.save();
878 // Add subtle shade to entire widget to separate from neighbors..
879 painter.fillRect(rect(), QColor(0, 0, 0, 24));
880
881 QRectF rectangle = d->paintingStrategy->drawBackground(d, painter);
882 painter.restore();
883
884 painter.save();
885 d->paintingStrategy->drawMeasurements(d, painter, rectangle);
886 painter.restore();
887
888 if (d->showIndents) {
889 painter.save();
890 d->paintingStrategy->drawIndents(d, painter);
891 painter.restore();
892 }
893
894 d->paintingStrategy->drawTabs(d, painter);
895}
896
898{
899 return d->paintingStrategy->sizeHint();
900}
901
902QSize KoRuler::sizeHint() const
903{
904 return d->paintingStrategy->sizeHint();
905}
906
907void KoRuler::setActiveRange(qreal start, qreal end)
908{
909 d->activeRangeStart = start;
910 d->activeRangeEnd = end;
911 update();
912}
913
914void KoRuler::setOverrideActiveRange(qreal start, qreal end)
915{
918 update();
919}
920
922{
923 if(d->mouseCoordinate == coordinate)
924 return;
925 d->mouseCoordinate = coordinate;
926 update();
927}
928
930{
931 d->showMousePosition = show;
932 update();
933}
934
936{
937 return d->showMousePosition;
938}
939
940void KoRuler::setRightToLeft(bool isRightToLeft)
941{
942 d->rightToLeft = isRightToLeft;
943 update();
944}
945
947{
948 d->showIndents = show;
949 update();
950}
951
953{
954 d->firstLineIndent = indent;
955 if (d->showIndents) {
956 update();
957 }
958}
959
961{
962 d->paragraphIndent = indent;
963 if (d->showIndents) {
964 update();
965 }
966}
967
968void KoRuler::setEndIndent(qreal indent)
969{
970 d->endIndent = indent;
971 if (d->showIndents) {
972 update();
973 }
974}
975
977{
978 return d->firstLineIndent;
979}
980
982{
983 return d->paragraphIndent;
984}
985
987{
988 return d->endIndent;
989}
990
992{
993 if ((d->tabChooser == 0) && (d->orientation == Qt::Horizontal)) {
994 d->tabChooser = new RulerTabChooser(parentWidget());
996 }
997
998 return d->tabChooser;
999}
1000
1002{
1003 d->showSelectionBorders = show;
1004 update();
1005}
1006
1007void KoRuler::updateSelectionBorders(qreal first, qreal second)
1008{
1009 d->firstSelectionBorder = first;
1010 d->secondSelectionBorder = second;
1011
1013 update();
1014}
1015
1017{
1018 if (d->showTabs == show) {
1019 return;
1020 }
1021
1022 d->showTabs = show;
1023 if (d->tabChooser) {
1024 d->tabChooser->setShowTabs(show);
1025 }
1026 update();
1027}
1028
1029void KoRuler::setRelativeTabs(bool relative)
1030{
1031 d->relativeTabs = relative;
1032 if (d->showTabs) {
1033 update();
1034 }
1035}
1036
1037void KoRuler::updateTabs(const QList<KoRuler::Tab> &tabs, qreal tabDistance)
1038{
1039 d->tabs = tabs;
1040 d->tabDistance = tabDistance;
1041 if (d->showTabs) {
1042 update();
1043 }
1044}
1045
1047{
1048 QList<Tab> answer = d->tabs;
1049 std::sort(answer.begin(), answer.end(), compareTabs);
1050
1051 return answer;
1052}
1053
1055{
1057}
1058
1060{
1061 return d->popupActions;
1062}
1063
1064void KoRuler::mousePressEvent ( QMouseEvent* ev )
1065{
1066 d->tabMoved = false;
1068 if (ev->button() == Qt::RightButton && !d->popupActions.isEmpty())
1069 QMenu::exec(d->popupActions, ev->globalPos());
1070 if (ev->button() != Qt::LeftButton) {
1071 ev->ignore();
1072 return;
1073 }
1074
1080 d->guideCreationStarted = true;
1081 return;
1082 }
1083
1084 QPoint pos = ev->pos();
1085
1086 if (d->showTabs) {
1087 int i = 0;
1088 int x;
1089 foreach (const Tab & t, d->tabs) {
1090 if (d->rightToLeft) {
1092 - (d->relativeTabs ? d->paragraphIndent : 0) - t.position) + d->offset;
1093 } else {
1095 + (d->relativeTabs ? d->paragraphIndent : 0) + t.position) + d->offset;
1096 }
1097 if (pos.x() >= x-6 && pos.x() <= x+6) {
1099 d->selectOffset = x - pos.x();
1100 d->currentIndex = i;
1101 break;
1102 }
1103 i++;
1104 }
1106 }
1107
1109 d->selected = d->selectionAtPosition(ev->pos(), &d->selectOffset);
1111 int hotSpotIndex = d->hotSpotIndex(ev->pos());
1112 if (hotSpotIndex >= 0) {
1114 update();
1115 }
1116 }
1117
1119 // still haven't found something so let assume the user wants to add a tab
1120 qreal tabpos;
1121 if (d->rightToLeft) {
1122 tabpos = d->viewConverter->viewToDocumentX(pos.x() - d->offset)
1124 } else {
1125 tabpos = d->viewConverter->viewToDocumentX(pos.x() - d->offset)
1127 }
1128 Tab t = {tabpos, d->tabChooser ? d->tabChooser->type() :
1129 d->rightToLeft ? QTextOption::RightTab :
1130 QTextOption::LeftTab};
1131 d->tabs.append(t);
1132 d->selectOffset = 0;
1134 d->currentIndex = d->tabs.count() - 1;
1135 d->originalIndex = -1; // new!
1136 update();
1137 }
1138 if (d->orientation == Qt::Horizontal && (ev->modifiers() & Qt::ShiftModifier) &&
1144
1146 Q_EMIT aboutToChange();
1147}
1148
1149void KoRuler::mouseReleaseEvent ( QMouseEvent* ev )
1150{
1151 ev->accept();
1153 d->guideCreationStarted = false;
1154 Q_EMIT guideCreationFinished(d->orientation, ev->globalPos());
1155 } else if (d->selected == KoRulerPrivate::Tab) {
1156 if (d->originalIndex >= 0 && !d->tabMoved) {
1157 int type = d->tabs[d->currentIndex].type;
1158 type++;
1159 if (type > 3)
1160 type = 0;
1161 d->tabs[d->currentIndex].type = static_cast<QTextOption::TabType> (type);
1162 update();
1163 }
1164 d->emitTabChanged();
1165 }
1166 else if( d->selected != KoRulerPrivate::None)
1167 Q_EMIT indentsChanged(true);
1168 else
1169 ev->ignore();
1170
1173}
1174
1175void KoRuler::mouseMoveEvent ( QMouseEvent* ev )
1176{
1177 QPoint pos = ev->pos();
1178
1180 Q_EMIT guideCreationInProgress(d->orientation, ev->globalPos());
1181 ev->accept();
1182 update();
1183 return;
1184 }
1185
1186 qreal activeLength = d->effectiveActiveRangeEnd() - d->effectiveActiveRangeStart();
1187
1188 switch (d->selected) {
1190 if (d->rightToLeft)
1193 else
1196 if( ! (ev->modifiers() & Qt::ShiftModifier)) {
1199 } else {
1200 if (d->orientation == Qt::Horizontal)
1202 }
1203
1204 Q_EMIT indentsChanged(false);
1205 break;
1207 if (d->rightToLeft)
1210 else
1213 if( ! (ev->modifiers() & Qt::ShiftModifier)) {
1216 } else {
1217 if (d->orientation == Qt::Horizontal)
1219 }
1220
1221 if (d->paragraphIndent + d->endIndent > activeLength)
1222 d->paragraphIndent = activeLength - d->endIndent;
1223 Q_EMIT indentsChanged(false);
1224 break;
1226 if (d->rightToLeft)
1229 else
1231 + d->selectOffset - d->offset);
1232 if (!(ev->modifiers() & Qt::ShiftModifier)) {
1235 } else {
1236 if (d->orientation == Qt::Horizontal)
1238 }
1239
1240 if (d->paragraphIndent + d->endIndent > activeLength)
1241 d->endIndent = activeLength - d->paragraphIndent;
1242 Q_EMIT indentsChanged(false);
1243 break;
1245 d->tabMoved = true;
1246 if (d->currentIndex < 0) { // tab is deleted.
1247 if (ev->pos().y() < height()) { // reinstate it.
1248 d->currentIndex = d->tabs.count();
1249 d->tabs.append(d->deletedTab);
1250 } else {
1251 break;
1252 }
1253 }
1254 if (d->rightToLeft)
1255 d->tabs[d->currentIndex].position = d->effectiveActiveRangeEnd() -
1257 else
1258 d->tabs[d->currentIndex].position = d->viewConverter->viewToDocumentX(pos.x() + d->selectOffset
1260 if (!(ev->modifiers() & Qt::ShiftModifier))
1261 d->tabs[d->currentIndex].position = d->doSnapping(d->tabs[d->currentIndex].position);
1262 if (d->tabs[d->currentIndex].position < 0)
1263 d->tabs[d->currentIndex].position = 0;
1264 if (d->tabs[d->currentIndex].position > activeLength)
1265 d->tabs[d->currentIndex].position = activeLength;
1266
1267 if (ev->pos().y() > height() + OutsideRulerThreshold ) { // moved out of the ruler, delete it.
1268 d->deletedTab = d->tabs.takeAt(d->currentIndex);
1269 d->currentIndex = -1;
1270 // was that a temporary added tab?
1271 if ( d->originalIndex == -1 )
1273 d->orientation == Qt::Horizontal
1274 ? d->viewConverter->viewToDocumentY(ev->pos().y())
1275 : d->viewConverter->viewToDocumentX(ev->pos().x()));
1276 }
1277
1278 d->emitTabChanged();
1279 break;
1281 qreal newPos;
1282 if (d->orientation == Qt::Horizontal)
1283 newPos= d->viewConverter->viewToDocumentX(pos.x() - d->offset);
1284 else
1285 newPos= d->viewConverter->viewToDocumentY(pos.y() - d->offset);
1286 d->hotspots[d->currentIndex].position = newPos;
1287 Q_EMIT hotSpotChanged(d->hotspots[d->currentIndex].id, newPos);
1288 break;
1290 d->mouseCoordinate = (d->orientation == Qt::Horizontal ? pos.x() : pos.y()) - d->offset;
1291 int hotSpotIndex = d->hotSpotIndex(pos);
1292 if (hotSpotIndex >= 0) {
1293 setCursor(QCursor( d->orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor ));
1294 break;
1295 }
1296 unsetCursor();
1297
1299 QString text;
1300 switch(selection) {
1301 case KoRulerPrivate::FirstLineIndent: text = i18n("First line indent"); break;
1302 case KoRulerPrivate::ParagraphIndent: text = i18n("Left indent"); break;
1303 case KoRulerPrivate::EndIndent: text = i18n("Right indent"); break;
1305 if (ev->buttons() & Qt::LeftButton) {
1306 if (d->orientation == Qt::Horizontal && ev->pos().y() > height() + OutsideRulerThreshold)
1307 Q_EMIT guideLineCreated(d->orientation, d->viewConverter->viewToDocumentY(ev->pos().y()));
1308 else if (d->orientation == Qt::Vertical && ev->pos().x() > width() + OutsideRulerThreshold)
1309 Q_EMIT guideLineCreated(d->orientation, d->viewConverter->viewToDocumentX(ev->pos().x()));
1310 }
1311 break;
1312 default:
1313 break;
1314 }
1315 setToolTip(text);
1316 }
1317 update();
1318}
1319
1321{
1322 if (d->hotspots.isEmpty())
1323 return;
1324 d->hotspots.clear();
1325 update();
1326}
1327
1328void KoRuler::setHotSpot(qreal position, int id)
1329{
1330 uint hotspotCount = d->hotspots.count();
1331 for( uint i = 0; i < hotspotCount; ++i ) {
1333 if (hs.id == id) {
1334 hs.position = position;
1335 update();
1336 return;
1337 }
1338 }
1339 // not there yet, then insert it.
1341 hs.position = position;
1342 hs.id = id;
1343 d->hotspots.append(hs);
1344}
1345
1347{
1349 while(iter != d->hotspots.end()) {
1350 if (iter->id == id) {
1351 d->hotspots.erase(iter);
1352 update();
1353 return true;
1354 }
1355 }
1356 return false;
1357}
1358
1360{
1361 Q_ASSERT(canvas);
1362 KoToolBase *tool = KoToolManager::instance()->toolById(canvas, QLatin1String("GuidesTool"));
1363 if (!tool) return; // It's perfectly fine to have no guides tool, we don't have to warn the user about it
1364 connect(this, SIGNAL(guideLineCreated(Qt::Orientation,qreal)),
1365 tool, SLOT(createGuideLine(Qt::Orientation,qreal)));
1366}
1367
1369{
1370 if (enabled) {
1371 d->pixelStep = 64.0;
1372 }
1373 else {
1374 d->pixelStep = 100.0;
1375 }
1376}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
float value(const T *src, size_t ch)
unsigned int uint
struct @8 compareTabs
static const int OutsideRulerThreshold
Definition KoRuler.cpp:31
static const int measurementTextAboveBelowMargin
Definition KoRuler.cpp:36
static const int halfStepMarkerLength
Definition KoRuler.cpp:34
static const int fullStepMarkerLength
Definition KoRuler.cpp:33
static const int quarterStepMarkerLength
Definition KoRuler.cpp:35
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void drawDistanceLine(const KoRulerPrivate *d, QPainter &painter, const qreal start, const qreal end)
Definition KoRuler.cpp:600
void drawMeasurements(const KoRulerPrivate *ruler, QPainter &painter, const QRectF &rectangle) override
Definition KoRuler.cpp:647
void drawIndents(const KoRulerPrivate *ruler, QPainter &painter) override
Definition KoRuler.cpp:378
void drawTabs(const KoRulerPrivate *ruler, QPainter &painter) override
Definition KoRuler.cpp:160
QSize sizeHint() override
Definition KoRuler.cpp:426
QRectF drawBackground(const KoRulerPrivate *ruler, QPainter &painter) override
Definition KoRuler.cpp:118
void drawMeasurements(const KoRulerPrivate *ruler, QPainter &painter, const QRectF &rectangle) override
Definition KoRuler.cpp:248
qreal tabDistance
Definition KoRuler_p.h:150
qreal firstLineIndent
Definition KoRuler_p.h:139
int hotSpotIndex(const QPoint &pos)
Definition KoRuler.cpp:784
bool guideCreationStarted
Definition KoRuler_p.h:183
RulerTabChooser * tabChooser
Definition KoRuler_p.h:172
KoRuler * ruler
Definition KoRuler_p.h:181
qreal paragraphIndent
Definition KoRuler_p.h:140
PaintingStrategy * paintingStrategy
Definition KoRuler_p.h:179
qreal activeRangeEnd
Definition KoRuler_p.h:127
QList< HotSpotData > hotspots
Definition KoRuler_p.h:156
QList< QAction * > popupActions
Definition KoRuler_p.h:170
int showMousePosition
Definition KoRuler_p.h:132
qreal firstSelectionBorder
Definition KoRuler_p.h:135
qreal effectiveActiveRangeEnd() const
Definition KoRuler.cpp:808
qreal secondSelectionBorder
Definition KoRuler_p.h:136
KoRuler::Tab deletedTab
Definition KoRuler_p.h:149
qreal numberStepForUnit() const
Definition KoRuler.cpp:710
qreal activeOverrideRangeStart
Definition KoRuler_p.h:128
KoRulerPrivate(KoRuler *parent, const KoViewConverter *vc, Qt::Orientation orientation)
Definition KoRuler.cpp:666
qreal activeOverrideRangeEnd
Definition KoRuler_p.h:129
void emitTabChanged()
Definition KoRuler.cpp:817
qreal doSnapping(const qreal value) const
Definition KoRuler.cpp:727
const KoViewConverter *const viewConverter
Definition KoRuler_p.h:122
qreal effectiveActiveRangeStart() const
Definition KoRuler.cpp:799
qreal activeRangeStart
Definition KoRuler_p.h:126
QList< KoRuler::Tab > tabs
Definition KoRuler_p.h:146
qreal rulerLength
Definition KoRuler_p.h:125
const Qt::Orientation orientation
Definition KoRuler_p.h:121
Selection selectionAtPosition(const QPoint &pos, int *selectOffset=0)
Definition KoRuler.cpp:733
PaintingStrategy * distancesPaintingStrategy
Definition KoRuler_p.h:176
PaintingStrategy * normalPaintingStrategy
Definition KoRuler_p.h:175
Selection selected
Definition KoRuler_p.h:167
bool showSelectionBorders
Definition KoRuler_p.h:134
bool showMousePosition() const
Definition KoRuler.cpp:935
void updateMouseCoordinate(int coordinate)
Definition KoRuler.cpp:921
void setEndIndent(qreal indent)
Definition KoRuler.cpp:968
void updateSelectionBorders(qreal first, qreal second)
Definition KoRuler.cpp:1007
KoUnit unit() const
The ruler's unit.
Definition KoRuler.cpp:838
void guideCreationFinished(Qt::Orientation orientation, const QPoint &globalPos)
QWidget * tabChooser()
Definition KoRuler.cpp:991
void guideLineCreated(Qt::Orientation orientation, qreal viewPosition)
emitted when the mouse is drag+released outside the ruler
void aboutToChange()
emitted when there the user is about to change a tab or hotspot
void setUnit(const KoUnit &unit)
Set the unit of the ruler.
Definition KoRuler.cpp:843
void setParagraphIndent(qreal indent)
Definition KoRuler.cpp:960
void createGuideToolConnection(KoCanvasBase *canvas)
Definition KoRuler.cpp:1359
void setRightToLeft(bool isRightToLeft)
Definition KoRuler.cpp:940
void setShowIndents(bool show)
Definition KoRuler.cpp:946
void paintEvent(QPaintEvent *event) override
reimplemented
Definition KoRuler.cpp:871
KoRuler(QWidget *parent, Qt::Orientation orientation, const KoViewConverter *viewConverter)
Definition KoRuler.cpp:826
~KoRuler() override
Definition KoRuler.cpp:833
void indentsChanged(bool final)
void setRulerLength(qreal length)
Sets the length of the ruler to length in points (pt)
Definition KoRuler.cpp:865
qreal endIndent() const
The end indent of all lines.
Definition KoRuler.cpp:986
void mouseReleaseEvent(QMouseEvent *ev) override
reimplemented
Definition KoRuler.cpp:1149
void setOverrideActiveRange(qreal start, qreal end)
Definition KoRuler.cpp:914
QSize minimumSizeHint() const override
reimplemented
Definition KoRuler.cpp:897
void guideCreationInProgress(Qt::Orientation orientation, const QPoint &globalPos)
void setHotSpot(qreal position, int id=-1)
Definition KoRuler.cpp:1328
void clearHotSpots()
Definition KoRuler.cpp:1320
void setRelativeTabs(bool relative)
Definition KoRuler.cpp:1029
QList< Tab > tabs() const
Definition KoRuler.cpp:1046
qreal rulerLength() const
The length of the ruler in points (pt)
Definition KoRuler.cpp:849
KoRulerPrivate *const d
Definition KoRuler.h:268
void setUnitPixelMultiple2(bool enabled)
Definition KoRuler.cpp:1368
void setShowTabs(bool show)
Definition KoRuler.cpp:1016
void updateTabs(const QList< Tab > &tabs, qreal tabDistance)
Definition KoRuler.cpp:1037
void setOffset(int offset)
Definition KoRuler.cpp:859
void hotSpotChanged(int id, qreal newPosition)
qreal firstLineIndent() const
The start indent of the first line.
Definition KoRuler.cpp:976
void setActiveRange(qreal start, qreal end)
Definition KoRuler.cpp:907
bool removeHotSpot(int id)
Definition KoRuler.cpp:1346
void mouseMoveEvent(QMouseEvent *ev) override
reimplemented
Definition KoRuler.cpp:1175
QList< QAction * > popupActionList() const
Definition KoRuler.cpp:1059
void setShowSelectionBorders(bool show)
Definition KoRuler.cpp:1001
void setPopupActionList(const QList< QAction * > &popupActionList)
Definition KoRuler.cpp:1054
QSize sizeHint() const override
reimplemented
Definition KoRuler.cpp:902
void mousePressEvent(QMouseEvent *ev) override
reimplemented
Definition KoRuler.cpp:1064
void tabChanged(int originalTabIndex, KoRuler::Tab *tab)
void setShowMousePosition(bool show)
Definition KoRuler.cpp:929
void setFirstLineIndent(qreal indent)
Definition KoRuler.cpp:952
Qt::Orientation orientation() const
The orientation of the ruler.
Definition KoRuler.cpp:854
qreal paragraphIndent() const
The start indent of the rest of the lines.
Definition KoRuler.cpp:981
KoToolBase * toolById(KoCanvasBase *canvas, const QString &id) const
static KoToolManager * instance()
Return the toolmanager singleton.
qreal fromUserValue(qreal value) const
Definition KoUnit.cpp:201
KoUnit::Type type() const
Definition KoUnit.h:118
@ Point
Postscript point, 1/72th of an Inco.
Definition KoUnit.h:76
@ Centimeter
Definition KoUnit.h:78
@ Decimeter
Definition KoUnit.h:79
@ Pica
Definition KoUnit.h:80
@ Millimeter
Definition KoUnit.h:75
@ Inch
Definition KoUnit.h:77
@ Cicero
Definition KoUnit.h:81
virtual qreal documentToViewY(qreal documentY) const
virtual qreal viewToDocumentY(qreal viewY) const
virtual qreal documentToViewX(qreal documentX) const
virtual qreal viewToDocumentX(qreal viewX) const
virtual void drawTabs(const KoRulerPrivate *ruler, QPainter &painter)=0
virtual QRectF drawBackground(const KoRulerPrivate *ruler, QPainter &painter)=0
virtual QSize sizeHint()=0
virtual void drawIndents(const KoRulerPrivate *ruler, QPainter &painter)=0
virtual void drawMeasurements(const KoRulerPrivate *ruler, QPainter &painter, const QRectF &rectangle)=0
void setShowTabs(bool showTabs)
Definition KoRuler_p.h:18
QTextOption::TabType type()
Definition KoRuler_p.h:17
void paintEvent(QPaintEvent *) override
Definition KoRuler.cpp:62
QTextOption::TabType m_type
Definition KoRuler_p.h:24
void mousePressEvent(QMouseEvent *) override
Definition KoRuler.cpp:39
void drawMeasurements(const KoRulerPrivate *ruler, QPainter &painter, const QRectF &rectangle) override
Definition KoRuler.cpp:478
QRectF drawBackground(const KoRulerPrivate *ruler, QPainter &painter) override
Definition KoRuler.cpp:436
QSize sizeHint() override
Definition KoRuler.cpp:589
rgba palette[MAX_PALETTE]
Definition palette.c:35
For paragraphs each tab definition is represented by this struct.
Definition KoRuler.h:43
qreal position
distance in point from the start of the text-shape
Definition KoRuler.h:44
QTextOption::TabType type
Determine which type is used.
Definition KoRuler.h:45