00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "KoRuler.h"
00022
00023 #include <klocale.h>
00024 #include <kdebug.h>
00025 #include <kglobalsettings.h>
00026
00027 #include <QPainter>
00028 #include <QResizeEvent>
00029 #include <QMouseEvent>
00030
00031 #include <KoViewConverter.h>
00032
00033 class KoRulerPrivate {
00034 public:
00035 KoUnit::Unit m_unit;
00036 Qt::Orientation m_orientation;
00037 KoViewConverter* m_viewConverter;
00038
00039 int m_offset;
00040 double m_rulerLength;
00041 double m_activeRangeStart;
00042 double m_activeRangeEnd;
00043
00044 int m_mouseCoordinate;
00045 int m_showMousePosition;
00046 };
00047
00048
00049 KoRuler::KoRuler(QWidget* parent, Qt::Orientation orientation, KoViewConverter* viewConverter)
00050 : QWidget(parent)
00051 {
00052 d = new KoRulerPrivate;
00053
00054 d->m_orientation = orientation;
00055 d->m_viewConverter = viewConverter;
00056
00057 setUnit(KoUnit::U_PT);
00058 setRulerLength(0);
00059 setOffset(0);
00060 setActiveRange(0, 0);
00061 setShowMousePosition(false);
00062 updateMouseCoordinate(-1);
00063 }
00064
00065 KoRuler::~KoRuler()
00066 {
00067 delete d;
00068 d = 0;
00069 }
00070
00071 KoUnit::Unit KoRuler::unit() const
00072 {
00073 return d->m_unit;
00074 }
00075
00076 void KoRuler::setUnit(KoUnit::Unit unit)
00077 {
00078 d->m_unit = unit;
00079 }
00080
00081 double KoRuler::rulerLength() const
00082 {
00083 return d->m_rulerLength;
00084 }
00085
00086 Qt::Orientation KoRuler::orientation() const
00087 {
00088 return d->m_orientation;
00089 }
00090
00091 void KoRuler::setOffset(int offset)
00092 {
00093 d->m_offset = offset;
00094 update();
00095 }
00096
00097 void KoRuler::setRulerLength(double length)
00098 {
00099 d->m_rulerLength = length;
00100 }
00101
00102 void KoRuler::paintEvent(QPaintEvent* event)
00103 {
00104 QPainter painter(this);
00105 painter.setClipRegion(event->region());
00106
00107 double numberStep = numberStepForUnit();
00108
00109 QRectF rectangle;
00110 QRectF activeRangeRectangle;
00111 double lengthPixel = 0;
00112 int numberStepPixel = 0;
00113
00114 if(orientation() == Qt::Horizontal) {
00115 lengthPixel = d->m_viewConverter->documentToViewX(rulerLength());
00116 numberStepPixel = qRound(d->m_viewConverter->documentToViewX(
00117 KoUnit::fromUserValue(numberStep, d->m_unit)));
00118 rectangle.setX(qMax(0, d->m_offset));
00119 rectangle.setY(0);
00120 rectangle.setWidth(qMin((double)width() - 1.0 - rectangle.x(), lengthPixel));
00121 rectangle.setHeight(height() - 1.0);
00122 activeRangeRectangle.setX(qMax(rectangle.x() + 1,
00123 d->m_viewConverter->documentToViewX(d->m_activeRangeStart) + d->m_offset));
00124 activeRangeRectangle.setY(rectangle.y() + 1);
00125 activeRangeRectangle.setRight(qMin(rectangle.right() - 1,
00126 d->m_viewConverter->documentToViewX(d->m_activeRangeEnd) + d->m_offset));
00127 activeRangeRectangle.setHeight(rectangle.height() - 2);
00128 } else {
00129 lengthPixel = d->m_viewConverter->documentToViewY(rulerLength());
00130 numberStepPixel = qRound(d->m_viewConverter->documentToViewY(
00131 KoUnit::fromUserValue(numberStep, d->m_unit)));
00132 rectangle.setX(0);
00133 rectangle.setY(qMax(0, d->m_offset));
00134 rectangle.setWidth(width() - 1.0);
00135 rectangle.setHeight(qMin((double)height() - 1.0 - rectangle.y(), lengthPixel));
00136 activeRangeRectangle.setX(rectangle.x() + 1);
00137 activeRangeRectangle.setY(qMax(rectangle.y() + 1,
00138 d->m_viewConverter->documentToViewY(d->m_activeRangeStart) + d->m_offset));
00139 activeRangeRectangle.setWidth(rectangle.width() - 2);
00140 activeRangeRectangle.setBottom(qMin(rectangle.bottom() - 1,
00141 d->m_viewConverter->documentToViewY(d->m_activeRangeEnd) + d->m_offset));
00142 }
00143
00144 painter.setPen(palette().color(QPalette::Mid));
00145 painter.drawRect(rectangle);
00146
00147 if(d->m_activeRangeStart != d->m_activeRangeEnd) {
00148 painter.fillRect(activeRangeRectangle, palette().brush(QPalette::Base));
00149 }
00150
00151 QFont font = KGlobalSettings::toolBarFont();
00152 QFontMetrics fontMetrics(font);
00153 int textLength = 0;
00154
00155
00156 for(int i = 0; i < lengthPixel; i += numberStepPixel) {
00157 textLength = qMax(textLength, fontMetrics.width(
00158 QString::number((i / numberStepPixel) * numberStep)));
00159 }
00160
00161 textLength += 4;
00162
00163
00164 while(textLength > numberStepPixel) {
00165 numberStepPixel += numberStepPixel;
00166 numberStep += numberStep;
00167 }
00168
00169 int start = 0;
00170 int stepCount = 0;
00171 int halfStepCount = 0;
00172 int quarterStepCount = 0;
00173 int mouseCoord = d->m_mouseCoordinate;
00174
00175
00176 if(d->m_offset < 0) {
00177 start = qAbs(d->m_offset);
00178 stepCount = (start / numberStepPixel) + 1;
00179 halfStepCount = (start / qRound(numberStepPixel * 0.5)) + 1;
00180 quarterStepCount = (start / qRound(numberStepPixel * 0.25)) + 1;
00181 mouseCoord = d->m_mouseCoordinate - start;
00182 }
00183
00184 int fontHeight = fontMetrics.height();
00185 int pos = 0;
00186 painter.setPen(palette().color(QPalette::Text));
00187
00188 if(orientation() == Qt::Horizontal) {
00189 if(d->m_offset > 0) {
00190 painter.translate(d->m_offset, 0);
00191 }
00192
00193 int len = qRound(rectangle.width()) + start;
00194 int nextStep = qRound(d->m_viewConverter->documentToViewX(
00195 KoUnit::fromUserValue(numberStep * stepCount, d->m_unit)));
00196 int nextHalfStep = qRound(d->m_viewConverter->documentToViewX(KoUnit::fromUserValue(
00197 numberStep * 0.5 * halfStepCount, d->m_unit)));
00198 int nextQuarterStep = qRound(d->m_viewConverter->documentToViewX(KoUnit::fromUserValue(
00199 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00200
00201 for(int i = start; i < len; ++i) {
00202 pos = i - start;
00203
00204 if(i == nextStep) {
00205 if(pos != 0) {
00206 painter.drawLine(QPointF(pos, 1), QPointF(pos, height() * 0.5));
00207 }
00208
00209 painter.drawText(QPoint(pos + 2, fontHeight + 2),
00210 QString::number(stepCount * numberStep));
00211 ++stepCount;
00212 nextStep = qRound(d->m_viewConverter->documentToViewX(
00213 KoUnit::fromUserValue(numberStep * stepCount, d->m_unit)));
00214 ++halfStepCount;
00215 nextHalfStep = qRound(d->m_viewConverter->documentToViewX(KoUnit::fromUserValue(
00216 numberStep * 0.5 * halfStepCount, d->m_unit)));
00217 ++quarterStepCount;
00218 nextQuarterStep = qRound(d->m_viewConverter->documentToViewX(KoUnit::fromUserValue(
00219 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00220 } else if(i == nextHalfStep) {
00221 if(pos != 0) {
00222 painter.drawLine(QPointF(pos, 1), QPointF(pos, height() * 0.25));
00223 }
00224
00225 ++halfStepCount;
00226 nextHalfStep = qRound(d->m_viewConverter->documentToViewX(KoUnit::fromUserValue(
00227 numberStep * 0.5 * halfStepCount, d->m_unit)));
00228 ++quarterStepCount;
00229 nextQuarterStep = qRound(d->m_viewConverter->documentToViewX(KoUnit::fromUserValue(
00230 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00231 } else if(i == nextQuarterStep) {
00232 if(pos != 0) {
00233 painter.drawLine(QPointF(pos, 1), QPointF(pos, height() * 0.125));
00234 }
00235
00236 ++quarterStepCount;
00237 nextQuarterStep = qRound(d->m_viewConverter->documentToViewX(KoUnit::fromUserValue(
00238 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00239 }
00240 }
00241
00242
00243 if(d->m_showMousePosition && (mouseCoord > 0)) {
00244 painter.drawLine(QPointF(mouseCoord, rectangle.y() + 1),
00245 QPointF(mouseCoord, rectangle.bottom() - 1));
00246 }
00247 } else {
00248 int textOffset = 0;
00249
00250 if(d->m_offset > 0) {
00251 painter.translate(0, d->m_offset);
00252 textOffset = d->m_offset;
00253 }
00254
00255 int len = qRound(rectangle.height()) + start;
00256 int nextStep = qRound(d->m_viewConverter->documentToViewY(
00257 KoUnit::fromUserValue(numberStep * stepCount, d->m_unit)));
00258 int nextHalfStep = qRound(d->m_viewConverter->documentToViewY(KoUnit::fromUserValue(
00259 numberStep * 0.5 * halfStepCount, d->m_unit)));
00260 int nextQuarterStep = qRound(d->m_viewConverter->documentToViewY(KoUnit::fromUserValue(
00261 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00262
00263 for(int i = start; i < len; ++i) {
00264 pos = i - start;
00265
00266 if(i == nextStep) {
00267 if(pos != 0) {
00268 painter.drawLine(QPointF(0, pos), QPointF(width() * 0.5, pos));
00269 }
00270
00271 int textY = pos + textLength + 2 + textOffset;
00272
00273 if(textY < len) {
00274 painter.save();
00275 painter.translate(width() - fontHeight + 2, textY);
00276 painter.rotate(-90);
00277 painter.drawText(QRect(0, 0, textLength, fontHeight),
00278 Qt::AlignRight | Qt::AlignTop,
00279 QString::number(stepCount * numberStep));
00280 painter.restore();
00281 }
00282
00283 ++stepCount;
00284 nextStep = qRound(d->m_viewConverter->documentToViewY(
00285 KoUnit::fromUserValue(numberStep * stepCount, d->m_unit)));
00286 ++halfStepCount;
00287 nextHalfStep = qRound(d->m_viewConverter->documentToViewY(KoUnit::fromUserValue(
00288 numberStep * 0.5 * halfStepCount, d->m_unit)));
00289 ++quarterStepCount;
00290 nextQuarterStep = qRound(d->m_viewConverter->documentToViewY(KoUnit::fromUserValue(
00291 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00292 } else if(i == nextHalfStep) {
00293 if(pos != 0) {
00294 painter.drawLine(QPointF(0, pos), QPointF(width() * 0.25, pos));
00295 }
00296
00297 ++halfStepCount;
00298 nextHalfStep = qRound(d->m_viewConverter->documentToViewY(KoUnit::fromUserValue(
00299 numberStep * 0.5 * halfStepCount, d->m_unit)));
00300 ++quarterStepCount;
00301 nextQuarterStep = qRound(d->m_viewConverter->documentToViewY(KoUnit::fromUserValue(
00302 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00303 } else if(i == nextQuarterStep) {
00304 if(pos != 0) {
00305 painter.drawLine(QPointF(0, pos), QPointF(width() * 0.125, pos));
00306 }
00307
00308 ++quarterStepCount;
00309 nextQuarterStep = qRound(d->m_viewConverter->documentToViewY(KoUnit::fromUserValue(
00310 numberStep * 0.25 * quarterStepCount, d->m_unit)));
00311 }
00312 }
00313
00314
00315 if(d->m_showMousePosition && (mouseCoord > 0)) {
00316 painter.drawLine(QPointF(rectangle.x() + 1, mouseCoord),
00317 QPointF(rectangle.right() - 1, mouseCoord));
00318 }
00319 }
00320 }
00321
00322 QSize KoRuler::minimumSizeHint() const
00323 {
00324 QSize size;
00325 QFont font = KGlobalSettings::toolBarFont();
00326 QFontMetrics fm(font);
00327
00328 int minimum = qMax(fm.height() + 4, 20);
00329
00330 size.setWidth( minimum );
00331 size.setHeight( minimum );
00332
00333 return size;
00334 }
00335
00336 QSize KoRuler::sizeHint() const
00337 {
00338 return minimumSizeHint();
00339 }
00340
00341 void KoRuler::setActiveRange(double start, double end)
00342 {
00343 d->m_activeRangeStart = start;
00344 d->m_activeRangeEnd = end;
00345 update();
00346 }
00347
00348 void KoRuler::updateMouseCoordinate(int coordinate)
00349 {
00350 d->m_mouseCoordinate = coordinate;
00351 update();
00352 }
00353
00354 void KoRuler::setShowMousePosition(bool show)
00355 {
00356 d->m_showMousePosition = show;
00357 }
00358
00359 double KoRuler::numberStepForUnit() const
00360 {
00361 double numberStep;
00362
00363 switch(d->m_unit) {
00364 case KoUnit::U_DD:
00365 case KoUnit::U_INCH:
00366 case KoUnit::U_CM:
00367 case KoUnit::U_DM:
00368 numberStep = 1.0;
00369 break;
00370 case KoUnit::U_MM:
00371 case KoUnit::U_PI:
00372 case KoUnit::U_CC:
00373 numberStep = 10.0;
00374 break;
00375 case KoUnit::U_PT:
00376 default:
00377 numberStep = 100.0;
00378 }
00379
00380 return numberStep;
00381 }
00382
00383 #include "KoRuler.moc"