F:/KPlato/koffice/libs/kofficeui/KoRuler.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00003    Copyright (C) 2006 Peter Simonsson <peter.simonsson@gmail.com>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
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(); // number step in unit
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     // Calc the longest text length
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;  // Add some padding
00162 
00163     // Change number step so all digits fits
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     // Calc the first number step
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         // Draw the mouse indicator
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         // Draw the mouse indicator
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"

Généré le Wed Nov 22 23:41:05 2006 pour KPlato par  doxygen 1.5.1-p1