00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "koRuler.h"
00025 #include <klocale.h>
00026 #include <kdebug.h>
00027 #include <kiconloader.h>
00028 #include <qcursor.h>
00029 #include <qpainter.h>
00030 #include <qpopupmenu.h>
00031 #include <qtooltip.h>
00032 #include <koPageLayout.h>
00033
00034 class KoRulerPrivate {
00035 public:
00036 KoRulerPrivate() {
00037 }
00038 ~KoRulerPrivate() {}
00039
00040 QWidget *canvas;
00041 int flags;
00042 int oldMx, oldMy;
00043 bool whileMovingBorderLeft, whileMovingBorderRight;
00044 bool whileMovingBorderTop, whileMovingBorderBottom;
00045 QPixmap pmFirst, pmLeft;
00046 KoPageLayout layout;
00047 KoTabChooser *tabChooser;
00048 KoTabulatorList tabList;
00049
00050 KoTabulator removeTab;
00051
00052 KoTabulator currTab;
00053
00054 KoRuler::Action action;
00055 QPopupMenu *rb_menu;
00056 int mRemoveTab, mPageLayout;
00057 int frameEnd;
00058 double i_right;
00059 bool m_bReadWrite;
00060 bool doubleClickedIndent;
00061 bool rtl;
00062 bool mousePressed;
00063 };
00064
00065
00066 static inline bool equals( double a, double b ) {
00067 return kAbs( a - b ) < 1E-4;
00068 }
00069
00070
00071
00072
00073
00074
00075 const int KoRuler::F_TABS = 1;
00076 const int KoRuler::F_INDENTS = 2;
00077 const int KoRuler::F_HELPLINES = 4;
00078 const int KoRuler::F_NORESIZE = 8;
00079
00080
00081 KoRuler::KoRuler( QWidget *_parent, QWidget *_canvas, Orientation _orientation,
00082 const KoPageLayout& _layout, int _flags, KoUnit::Unit _unit, KoTabChooser *_tabChooser )
00083 : QFrame( _parent ), buffer( width(), height() ), m_zoom(1.0), m_1_zoom(1.0),
00084 m_unit( _unit )
00085 {
00086 setWFlags( WResizeNoErase | WRepaintNoErase );
00087 setFrameStyle( Box | Raised );
00088
00089 d=new KoRulerPrivate();
00090
00091 d->tabChooser = _tabChooser;
00092
00093 d->canvas = _canvas;
00094 orientation = _orientation;
00095 d->layout = _layout;
00096 d->flags = _flags;
00097
00098 d->m_bReadWrite=true;
00099 d->doubleClickedIndent=false;
00100 diffx = 0;
00101 diffy = 0;
00102 i_left=0.0;
00103 i_first=0.0;
00104 d->i_right=0.0;
00105
00106 setMouseTracking( true );
00107 d->mousePressed = false;
00108 d->action = A_NONE;
00109
00110 d->oldMx = 0;
00111 d->oldMy = 0;
00112 d->rtl = false;
00113
00114 showMPos = false;
00115 mposX = 0;
00116 mposY = 0;
00117 gridSize=0.0;
00118 hasToDelete = false;
00119 d->whileMovingBorderLeft = d->whileMovingBorderRight = d->whileMovingBorderTop = d->whileMovingBorderBottom = false;
00120
00121 d->pmFirst = UserIcon( "koRulerFirst" );
00122 d->pmLeft = UserIcon( "koRulerLeft" );
00123 d->currTab.type = T_INVALID;
00124
00125 d->removeTab.type = T_INVALID;
00126 if ( orientation == Qt::Horizontal ) {
00127 frameStart = qRound( zoomIt(d->layout.ptLeft) );
00128 d->frameEnd = qRound( zoomIt(d->layout.ptWidth - d->layout.ptRight) );
00129 } else {
00130 frameStart = qRound( zoomIt(d->layout.ptTop) );
00131 d->frameEnd = qRound( zoomIt(d->layout.ptHeight - d->layout.ptBottom) );
00132 }
00133 m_bFrameStartSet = false;
00134
00135 setupMenu();
00136
00137
00138 connect( this, SIGNAL( doubleClicked() ), this, SIGNAL( openPageLayoutDia() ) );
00139 }
00140
00141
00142 KoRuler::~KoRuler()
00143 {
00144 delete d->rb_menu;
00145 delete d;
00146 }
00147
00148 void KoRuler::setPageLayoutMenuItemEnabled(bool b)
00149 {
00150 d->rb_menu->setItemEnabled(d->mPageLayout, b);
00151 }
00152
00153
00154 void KoRuler::setMousePos( int mx, int my )
00155 {
00156 if ( !showMPos || ( mx == mposX && my == mposY ) ) return;
00157
00158 QPainter p( this );
00159 p.setRasterOp( Qt::NotROP );
00160
00161 if ( orientation == Qt::Horizontal ) {
00162 if ( hasToDelete )
00163 p.drawLine( mposX, 1, mposX, height() - 1 );
00164 p.drawLine( mx, 1, mx, height() - 1 );
00165 hasToDelete = true;
00166 }
00167 else {
00168 if ( hasToDelete )
00169 p.drawLine( 1, mposY, width() - 1, mposY );
00170 p.drawLine( 1, my, width() - 1, my );
00171 hasToDelete = true;
00172 }
00173 p.end();
00174
00175 mposX = mx;
00176 mposY = my;
00177 }
00178
00179
00180 double KoRuler::lineDistance() const
00181 {
00182 switch( m_unit ) {
00183 case KoUnit::U_INCH:
00184 return INCH_TO_POINT( m_zoom );
00185 case KoUnit::U_PT:
00186 return 100.0 * m_zoom;
00187 case KoUnit::U_MM:
00188 case KoUnit::U_CM:
00189 case KoUnit::U_DM:
00190 return CM_TO_POINT ( m_zoom );
00191 case KoUnit::U_PI:
00192 return PI_TO_POINT ( 10.0 * m_zoom );
00193 case KoUnit::U_DD:
00194 return DD_TO_POINT( m_zoom );
00195 case KoUnit::U_CC:
00196 return CC_TO_POINT( 10.0 * m_zoom );
00197 }
00198
00199 return 100.0 * m_zoom;
00200 }
00201
00202
00203 void KoRuler::drawHorizontal( QPainter *_painter )
00204 {
00205
00206 QPainter p( &buffer );
00207 p.fillRect( 0, 0, width(), height(), QBrush( colorGroup().brush( QColorGroup::Background ) ) );
00208
00209 int totalw = qRound( zoomIt(d->layout.ptWidth) );
00210 QString str;
00211 QFont font;
00212 font.setPointSize( 8 );
00213 QFontMetrics fm( font );
00214
00215 p.setBrush( colorGroup().brush( QColorGroup::Base ) );
00216
00217
00218 QRect r;
00219 if ( !d->whileMovingBorderLeft )
00220 r.setLeft( -diffx + frameStart );
00221 else
00222 r.setLeft( d->oldMx );
00223 r.setTop( 0 );
00224 if ( !d->whileMovingBorderRight )
00225 r.setWidth(d->frameEnd-frameStart);
00226 else
00227 r.setRight( d->oldMx );
00228 r.setBottom( height() );
00229
00230 p.drawRect( r );
00231 p.setFont( font );
00232
00233
00234 double dist = lineDistance();
00235 int maxwidth = 0;
00236
00237 for ( double i = 0.0;i <= (double)totalw;i += dist ) {
00238 str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
00239 int textwidth = fm.width( str );
00240 maxwidth = QMAX( maxwidth, textwidth );
00241 }
00242
00243
00244 while( dist <= maxwidth ) {
00245 dist += lineDistance();
00246 }
00247
00248 for ( double i = 0.0;i <= (double)totalw;i += dist ) {
00249 str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
00250 int textwidth = fm.width( str );
00251 maxwidth = QMAX( maxwidth, textwidth );
00252 p.drawText( qRound(i) - diffx - qRound(textwidth * 0.5),
00253 qRound(( height() - fm.height() ) * 0.5),
00254 textwidth, height(), AlignLeft | AlignTop, str );
00255 }
00256
00257
00258
00259 if ( dist > maxwidth + 2 )
00260 {
00261 for ( double i = dist * 0.5;i <= (double)totalw;i += dist ) {
00262 int ii=qRound(i);
00263 p.drawLine( ii - diffx, 5, ii - diffx, height() - 5 );
00264 }
00265 }
00266
00267
00268
00269 if ( dist * 0.5 > maxwidth + 2 )
00270 {
00271 for ( double i = dist * 0.25;i <= (double)totalw;i += dist * 0.5 ) {
00272 int ii=qRound(i);
00273 p.drawLine( ii - diffx, 7, ii - diffx, height() - 7 );
00274 }
00275 }
00276
00277
00278 int constant=zoomIt(1);
00279 p.drawLine( totalw - diffx + constant, 1, totalw - diffx + constant, height() - 1 );
00280 p.setPen( colorGroup().color( QColorGroup::Base ) );
00281 p.drawLine( totalw - diffx, 1, totalw - diffx, height() - 1 );
00282
00283
00284 p.setPen( colorGroup().color( QColorGroup::Text ) );
00285 p.drawLine( -diffx, 1, -diffx, height() - 1 );
00286 p.setPen( colorGroup().color( QColorGroup::Base ) );
00287 p.drawLine( -diffx - constant, 1, -diffx - constant, height() - 1 );
00288
00289
00290 if ( d->flags & F_INDENTS ) {
00291 int top = 2;
00292 double halfPixmapWidth = d->pmFirst.width() * 0.5;
00293
00294 double firstLineIdent = i_first + ( d->rtl ? d->i_right : i_left );
00295 p.drawPixmap( qRound( static_cast<double>(r.left()) + applyRtlAndZoom( firstLineIdent ) - halfPixmapWidth ),
00296 top, d->pmFirst );
00297
00298 int bottom = height() - d->pmLeft.height() - 2;
00299 halfPixmapWidth = d->pmLeft.width() * 0.5;
00300 p.drawPixmap( qRound( static_cast<double>(r.left()) + zoomIt(i_left) - halfPixmapWidth ),
00301 bottom, d->pmLeft );
00302 p.drawPixmap( qRound( static_cast<double>(r.right()) - zoomIt(d->i_right) - halfPixmapWidth ),
00303 bottom, d->pmLeft );
00304 }
00305
00306
00307 if ( d->action == A_NONE && showMPos ) {
00308 p.setPen( colorGroup().color( QColorGroup::Text ) );
00309 p.drawLine( mposX, 1, mposX, height() - 1 );
00310 }
00311 hasToDelete = false;
00312
00313
00314 if ( d->tabChooser && ( d->flags & F_TABS ) && !d->tabList.isEmpty() )
00315 drawTabs( p );
00316
00317 p.end();
00318 _painter->drawPixmap( 0, 0, buffer );
00319 }
00320
00321
00322 void KoRuler::drawTabs( QPainter &_painter )
00323 {
00324 int ptPos = 0;
00325
00326 _painter.setPen( QPen( colorGroup().color( QColorGroup::Text ), 2, SolidLine ) );
00327
00328
00329 bool willRemove = d->mousePressed && willRemoveTab( d->oldMy ) && d->currTab.type != T_INVALID;
00330
00331 KoTabulatorList::ConstIterator it = d->tabList.begin();
00332 for ( ; it != d->tabList.end() ; it++ ) {
00333 if ( willRemove && equals( d->currTab.ptPos, (*it).ptPos ) )
00334 continue;
00335 ptPos = qRound(applyRtlAndZoom((*it).ptPos)) - diffx + frameStart;
00336 switch ( (*it).type ) {
00337 case T_LEFT: {
00338 ptPos -= 4;
00339 _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
00340 _painter.drawLine( ptPos + 5, 4, ptPos + 5, height() - 4 );
00341 } break;
00342 case T_CENTER: {
00343 ptPos -= 10;
00344 _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
00345 _painter.drawLine( ptPos + 20 / 2, 4, ptPos + 20 / 2, height() - 4 );
00346 } break;
00347 case T_RIGHT: {
00348 ptPos -= 16;
00349 _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
00350 _painter.drawLine( ptPos + 20 - 5, 4, ptPos + 20 - 5, height() - 4 );
00351 } break;
00352 case T_DEC_PNT: {
00353 ptPos -= 10;
00354 _painter.drawLine( ptPos + 4, height() - 4, ptPos + 20 - 4, height() - 4 );
00355 _painter.drawLine( ptPos + 20 / 2, 4, ptPos + 20 / 2, height() - 4 );
00356 _painter.fillRect( ptPos + 20 / 2 + 2, height() - 9, 3, 3,
00357 colorGroup().color( QColorGroup::Text ) );
00358 } break;
00359 default: break;
00360 }
00361 }
00362 }
00363
00364
00365 void KoRuler::drawVertical( QPainter *_painter )
00366 {
00367 QPainter p( &buffer );
00368 p.fillRect( 0, 0, width(), height(), QBrush( colorGroup().brush( QColorGroup::Background ) ) );
00369
00370 int totalh = qRound( zoomIt(d->layout.ptHeight) );
00371
00372 QRect paintRect = _painter->clipRegion( QPainter::CoordPainter ).boundingRect();
00373
00374 QRect rulerRect( 0, -diffy, width(), totalh );
00375
00376 if ( paintRect.intersects( rulerRect ) ) {
00377 QString str;
00378 QFont font;
00379 font.setPointSize( 8 );
00380 QFontMetrics fm( font );
00381
00382 p.setBrush( colorGroup().brush( QColorGroup::Base ) );
00383
00384
00385 QRect r;
00386 if ( !d->whileMovingBorderTop )
00387 r.setTop( -diffy + frameStart );
00388 else
00389 r.setTop( d->oldMy );
00390 r.setLeft( 0 );
00391 if ( !d->whileMovingBorderBottom )
00392 r.setHeight(d->frameEnd-frameStart);
00393 else
00394 r.setBottom( d->oldMy );
00395 r.setRight( width() );
00396
00397 p.drawRect( r );
00398 p.setFont( font );
00399
00400
00401 double dist = lineDistance();
00402 int maxheight = 0;
00403
00404 for ( double i = 0.0;i <= (double)totalh;i += dist ) {
00405 str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
00406 int textwidth = fm.width( str );
00407 maxheight = QMAX( maxheight, textwidth );
00408 }
00409
00410
00411 while( dist <= maxheight ) {
00412 dist += lineDistance();
00413 }
00414
00415 for ( double i = 0.0;i <= (double)totalh;i += dist ) {
00416 str = QString::number( KoUnit::toUserValue( i / m_zoom, m_unit ) );
00417 int textheight = fm.height();
00418 int textwidth = fm.width( str );
00419 maxheight = QMAX( maxheight, textwidth );
00420 p.save();
00421 p.translate( qRound(( width() - textheight ) * 0.5),
00422 qRound(i) - diffy + qRound(textwidth * 0.5) );
00423 p.rotate( -90 );
00424 p.drawText( 0, 0, textwidth + 1, textheight, AlignLeft | AlignTop, str );
00425 p.restore();
00426 }
00427
00428
00429 if ( dist > maxheight + 2 )
00430 {
00431 for ( double i = dist * 0.5;i <= (double)totalh;i += dist ) {
00432 int ii=qRound(i);
00433 p.drawLine( 5, ii - diffy, width() - 5, ii - diffy );
00434 }
00435 }
00436
00437
00438 if ( dist * 0.5 > maxheight + 2 )
00439 {
00440 for ( double i = dist * 0.25;i <=(double)totalh;i += dist *0.5 ) {
00441 int ii=qRound(i);
00442 p.drawLine( 7, ii - diffy, width() - 7, ii - diffy );
00443 }
00444 }
00445
00446
00447 p.drawLine( 1, totalh - diffy + 1, width() - 1, totalh - diffy + 1 );
00448 p.setPen( colorGroup().color( QColorGroup::Base ) );
00449 p.drawLine( 1, totalh - diffy, width() - 1, totalh - diffy );
00450
00451
00452 p.setPen( colorGroup().color( QColorGroup::Text ) );
00453 p.drawLine( 1, -diffy, width() - 1, -diffy );
00454 p.setPen( colorGroup().color( QColorGroup::Base ) );
00455 p.drawLine( 1, -diffy - 1, width() - 1, -diffy - 1 );
00456 }
00457
00458
00459 if ( d->action == A_NONE && showMPos ) {
00460 p.setPen( colorGroup().color( QColorGroup::Text ) );
00461 p.drawLine( 1, mposY, width() - 1, mposY );
00462 }
00463 hasToDelete = false;
00464
00465 p.end();
00466 _painter->drawPixmap( 0, 0, buffer );
00467 }
00468
00469 void KoRuler::mousePressEvent( QMouseEvent *e )
00470 {
00471 if( !d->m_bReadWrite)
00472 return;
00473
00474 d->oldMx = e->x();
00475 d->oldMy = e->y();
00476 d->mousePressed = true;
00477 d->removeTab.type = T_INVALID;
00478
00479 switch ( e->button() ) {
00480 case RightButton:
00481 if(d->currTab.type == T_INVALID || !(d->flags & F_TABS))
00482 d->rb_menu->setItemEnabled(d->mRemoveTab, false);
00483 else
00484 d->rb_menu->setItemEnabled(d->mRemoveTab, true);
00485 d->rb_menu->popup( QCursor::pos() );
00486 d->action = A_NONE;
00487 d->mousePressed = false;
00488 return;
00489 case MidButton:
00490
00491 handleDoubleClick();
00492 return;
00493 case LeftButton:
00494 if ( d->action == A_BR_RIGHT || d->action == A_BR_LEFT ) {
00495 if ( d->action == A_BR_RIGHT )
00496 d->whileMovingBorderRight = true;
00497 else
00498 d->whileMovingBorderLeft = true;
00499
00500 if ( d->canvas )
00501 drawLine(d->oldMx, -1);
00502 update();
00503 } else if ( d->action == A_BR_TOP || d->action == A_BR_BOTTOM ) {
00504 if ( d->action == A_BR_TOP )
00505 d->whileMovingBorderTop = true;
00506 else
00507 d->whileMovingBorderBottom = true;
00508
00509 if ( d->canvas ) {
00510 QPainter p( d->canvas );
00511 p.setRasterOp( Qt::NotROP );
00512 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00513 p.end();
00514 }
00515 update();
00516 } else if ( d->action == A_FIRST_INDENT || d->action == A_LEFT_INDENT || d->action == A_RIGHT_INDENT ) {
00517 if ( d->canvas )
00518 drawLine(d->oldMx, -1);
00519 } else if ( d->action == A_TAB ) {
00520 if ( d->canvas && d->currTab.type != T_INVALID ) {
00521 drawLine( qRound( applyRtlAndZoom(d->currTab.ptPos) ) + frameStart - diffx, -1 );
00522 }
00523 } else if ( d->tabChooser && ( d->flags & F_TABS ) && d->tabChooser->getCurrTabType() != 0 ) {
00524 int left = frameStart - diffx;
00525 int right = d->frameEnd - diffx;
00526
00527 if( e->x()-left < 0 || right-e->x() < 0 )
00528 return;
00529 KoTabulator tab;
00530 tab.filling = TF_BLANK;
00531 tab.ptWidth = 0.5;
00532 switch ( d->tabChooser->getCurrTabType() ) {
00533 case KoTabChooser::TAB_LEFT:
00534 tab.type = T_LEFT;
00535 break;
00536 case KoTabChooser::TAB_CENTER:
00537 tab.type = T_CENTER;
00538 break;
00539 case KoTabChooser::TAB_RIGHT:
00540 tab.type = T_RIGHT;
00541 break;
00542 case KoTabChooser::TAB_DEC_PNT:
00543 tab.type = T_DEC_PNT;
00544 tab.alignChar = KGlobal::locale()->decimalSymbol()[0];
00545 break;
00546 default: break;
00547 }
00548 tab.ptPos = unZoomItRtl( e->x() + diffx - frameStart );
00549
00550 KoTabulatorList::Iterator it=d->tabList.begin();
00551 while ( it!=d->tabList.end() && tab > (*it) )
00552 ++it;
00553
00554 d->tabList.insert(it, tab);
00555
00556 d->action = A_TAB;
00557 d->removeTab = tab;
00558 d->currTab = tab;
00559
00560 emit tabListChanged( d->tabList );
00561 update();
00562 }
00563 else if ( d->flags & F_HELPLINES )
00564 {
00565 setCursor( orientation == Qt::Horizontal ?
00566 Qt::sizeVerCursor : Qt::sizeHorCursor );
00567 d->action = A_HELPLINES;
00568 }
00569 default:
00570 break;
00571 }
00572 }
00573
00574 void KoRuler::mouseReleaseEvent( QMouseEvent *e )
00575 {
00576 d->mousePressed = false;
00577
00578
00579 bool fakeMovement=false;
00580 if(d->removeTab.type != T_INVALID) {
00581 mouseMoveEvent(e);
00582 fakeMovement=true;
00583 }
00584
00585 if ( d->action == A_BR_RIGHT || d->action == A_BR_LEFT ) {
00586 d->whileMovingBorderRight = false;
00587 d->whileMovingBorderLeft = false;
00588
00589 if ( d->canvas )
00590 drawLine(d->oldMx, -1);
00591 update();
00592 emit newPageLayout( d->layout );
00593 } else if ( d->action == A_BR_TOP || d->action == A_BR_BOTTOM ) {
00594 d->whileMovingBorderTop = false;
00595 d->whileMovingBorderBottom = false;
00596
00597 if ( d->canvas ) {
00598 QPainter p( d->canvas );
00599 p.setRasterOp( Qt::NotROP );
00600 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00601 p.end();
00602 }
00603 update();
00604 emit newPageLayout( d->layout );
00605 } else if ( d->action == A_FIRST_INDENT ) {
00606 if ( d->canvas )
00607 drawLine(d->oldMx, -1);
00608 update();
00609 emit newFirstIndent( i_first );
00610 } else if ( d->action == A_LEFT_INDENT ) {
00611 if ( d->canvas )
00612 drawLine(d->oldMx, -1);
00613 update();
00614 emit newLeftIndent( i_left );
00615 } else if ( d->action == A_RIGHT_INDENT ) {
00616 if ( d->canvas )
00617 drawLine(d->oldMx, -1);
00618 update();
00619 emit newRightIndent( d->i_right );
00620 } else if ( d->action == A_TAB ) {
00621 if ( d->canvas && !fakeMovement ) {
00622 drawLine( qRound( applyRtlAndZoom( d->currTab.ptPos ) ) + frameStart - diffx, -1);
00623 }
00624 if ( willRemoveTab( e->y() ) )
00625 {
00626 d->tabList.remove(d->currTab);
00627 }
00628 qHeapSort( d->tabList );
00629
00630
00631 KoTabulatorList::ConstIterator tmpTab=d->tabList.begin();
00632 int count=0;
00633 while(tmpTab!=d->tabList.end()) {
00634 if( equals( (*tmpTab).ptPos, d->currTab.ptPos ) ) {
00635 count++;
00636 if(count > 1) {
00637 d->tabList.remove(d->currTab);
00638 break;
00639 }
00640 }
00641 tmpTab++;
00642 }
00643
00644 emit tabListChanged( d->tabList );
00645 update();
00646 }
00647 else if( d->action == A_HELPLINES )
00648 {
00649 emit addHelpline( e->pos(), orientation == Qt::Horizontal);
00650 setCursor( ArrowCursor );
00651 }
00652 d->currTab.type = T_INVALID;
00653 }
00654
00655 void KoRuler::mouseMoveEvent( QMouseEvent *e )
00656 {
00657 hasToDelete = false;
00658
00659 int pw = d->frameEnd - frameStart;
00660 int ph = qRound(zoomIt(d->layout.ptHeight));
00661 int left = frameStart - diffx;
00662 int top = qRound(zoomIt(d->layout.ptTop));
00663 top -= diffy;
00664 int right = d->frameEnd - diffx;
00665 int bottom = qRound(zoomIt(d->layout.ptBottom));
00666 bottom = ph - bottom - diffy;
00667
00668 int ip_first = qRound( zoomIt( i_first + ( d->rtl ? d->i_right : i_left) ) );
00669 int ip_left = qRound(zoomIt(i_left));
00670 int ip_right = qRound(zoomIt(d->i_right));
00671
00672 int mx = e->x();
00673 mx = mx+diffx < 0 ? 0 : mx;
00674 int my = e->y();
00675 my = my+diffy < 0 ? 0 : my;
00676
00677 QToolTip::remove( this);
00678 switch ( orientation ) {
00679 case Qt::Horizontal: {
00680 if ( !d->mousePressed ) {
00681 setCursor( ArrowCursor );
00682 d->action = A_NONE;
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 if ( !m_bFrameStartSet )
00695 {
00696 if ( mx > left - 5 && mx < left + 5 ) {
00697 setCursor( Qt::sizeHorCursor );
00698 d->action = A_BR_LEFT;
00699 } else if ( mx > right - 5 && mx < right + 5 ) {
00700 setCursor( Qt::sizeHorCursor );
00701 d->action = A_BR_RIGHT;
00702 }
00703 }
00704 if ( d->flags & F_INDENTS ) {
00705 int firstX = d->rtl ? right - ip_first : left + ip_first;
00706 if ( mx > firstX - 5 && mx < firstX + 5 &&
00707 my >= 2 && my <= d->pmFirst.size().height() + 2 ) {
00708 QToolTip::add( this, i18n("First line indent") );
00709 setCursor( ArrowCursor );
00710 d->action = A_FIRST_INDENT;
00711 } else if ( mx > left + ip_left - 5 && mx < left + ip_left + 5 &&
00712 my >= height() - d->pmLeft.size().height() - 2 && my <= height() - 2 ) {
00713 QToolTip::add( this, i18n("Left indent") );
00714 setCursor( ArrowCursor );
00715 d->action = A_LEFT_INDENT;
00716 } else if ( mx > right - ip_right - 5 && mx < right - ip_right + 5 &&
00717 my >= height() - d->pmLeft.size().height() - 2 && my <= height() - 2 ) {
00718 QToolTip::add( this, i18n("Right indent") );
00719 setCursor( ArrowCursor );
00720 d->action = A_RIGHT_INDENT;
00721 }
00722 }
00723 if ( d->flags & F_TABS )
00724 searchTab(mx);
00725 } else {
00726
00727 int newPos=mx;
00728 if( newPos!=right && gridSize!=0.0 && (e->state() & ShiftButton)==0) {
00729 double grid=zoomIt(gridSize * 16);
00730 newPos=qRound( ((newPos * 16 / grid) * grid) / 16 );
00731 }
00732 if(newPos-left < 0) newPos=left;
00733 else if (right-newPos < 0) newPos=right;
00734 double newValue = unZoomIt(static_cast<double>(newPos) - frameStart + diffx);
00735
00736 switch ( d->action ) {
00737 case A_BR_LEFT: {
00738 if ( d->canvas && mx < right-10 && mx+diffx-2 > 0) {
00739 drawLine( d->oldMx, mx );
00740 d->layout.ptLeft = unZoomIt(static_cast<double>(mx + diffx));
00741 if( ip_left > right-left-15 ) {
00742 ip_left=right-left-15;
00743 ip_left=ip_left<0 ? 0 : ip_left;
00744 i_left=unZoomIt( ip_left );
00745 emit newLeftIndent( i_left );
00746 }
00747 if ( ip_right > right-left-15 ) {
00748 ip_right=right-left-15;
00749 ip_right=ip_right<0? 0 : ip_right;
00750 d->i_right=unZoomIt( ip_right );
00751 emit newRightIndent( d->i_right );
00752 }
00753 d->oldMx = mx;
00754 d->oldMy = my;
00755 update();
00756 }
00757 else
00758 return;
00759 } break;
00760 case A_BR_RIGHT: {
00761 if ( d->canvas && mx > left+10 && mx+diffx <= pw-2) {
00762 drawLine( d->oldMx, mx );
00763 d->layout.ptRight = unZoomIt(static_cast<double>(pw - ( mx + diffx )));
00764 if( ip_left > right-left-15 ) {
00765 ip_left=right-left-15;
00766 ip_left=ip_left<0 ? 0 : ip_left;
00767 i_left=unZoomIt( ip_left );
00768 emit newLeftIndent( i_left );
00769 }
00770 if ( ip_right > right-left-15 ) {
00771 ip_right=right-left-15;
00772 ip_right=ip_right<0? 0 : ip_right;
00773 d->i_right=unZoomIt( ip_right );
00774 emit newRightIndent( d->i_right );
00775 }
00776 d->oldMx = mx;
00777 d->oldMy = my;
00778 update();
00779 }
00780 else
00781 return;
00782 } break;
00783 case A_FIRST_INDENT: {
00784 if ( d->canvas ) {
00785 if (d->rtl)
00786 newValue = unZoomIt(pw) - newValue - d->i_right;
00787 else
00788 newValue -= i_left;
00789 if(newValue == i_first) break;
00790 drawLine( d->oldMx, newPos);
00791 d->oldMx=newPos;
00792 i_first = newValue;
00793 update();
00794 }
00795 } break;
00796 case A_LEFT_INDENT: {
00797 if ( d->canvas ) {
00798
00799 if(newValue == i_left) break;
00800
00801 drawLine( d->oldMx, newPos);
00802 i_left = newValue;
00803 d->oldMx = newPos;
00804 update();
00805 }
00806 } break;
00807 case A_RIGHT_INDENT: {
00808 if ( d->canvas ) {
00809 double rightValue = unZoomIt(right - newPos);
00810
00811 if(rightValue == d->i_right) break;
00812
00813 drawLine( d->oldMx, newPos);
00814 d->i_right=rightValue;
00815 d->oldMx = newPos;
00816 update();
00817 }
00818 } break;
00819 case A_TAB: {
00820 if ( d->canvas) {
00821 if (d->rtl) newValue = unZoomIt(pw) - newValue;
00822 if(newValue == d->currTab.ptPos) break;
00823 QPainter p( d->canvas );
00824 p.setRasterOp( Qt::NotROP );
00825
00826
00827 double pt;
00828 int pt_fr;
00829 if( d->currTab != d->removeTab )
00830 {
00831 pt = applyRtlAndZoom(d->currTab.ptPos);
00832 pt_fr = qRound(pt) + frameStart - diffx;
00833 p.drawLine( pt_fr, 0, pt_fr, d->canvas->height() );
00834 }
00835
00836 KoTabulatorList::Iterator it = d->tabList.find( d->currTab );
00837 Q_ASSERT( it != d->tabList.end() );
00838 if ( it != d->tabList.end() )
00839 (*it).ptPos = newValue;
00840 d->currTab.ptPos = newValue;
00841
00842 pt = applyRtlAndZoom( newValue );
00843 pt_fr = qRound(pt) + frameStart - diffx;
00844 p.drawLine( pt_fr, 0, pt_fr, d->canvas->height() );
00845
00846 p.end();
00847 d->oldMx = mx;
00848 d->oldMy = my;
00849 d->removeTab.type = T_INVALID;
00850 update();
00851 }
00852 } break;
00853 default: break;
00854 }
00855 }
00856 if( d->action == A_HELPLINES )
00857 {
00858 emit moveHelpLines( e->pos(), orientation == Qt::Horizontal);
00859 }
00860
00861 return;
00862 } break;
00863 case Qt::Vertical: {
00864 if ( !d->mousePressed ) {
00865 setCursor( ArrowCursor );
00866 d->action = A_NONE;
00867 if ( d->flags & F_NORESIZE )
00868 break;
00869 if ( my > top - 5 && my < top + 5 ) {
00870 QToolTip::add( this, i18n("Top margin") );
00871 setCursor( Qt::sizeVerCursor );
00872 d->action = A_BR_TOP;
00873 } else if ( my > bottom - 5 && my < bottom + 5 ) {
00874 QToolTip::add( this, i18n("Bottom margin") );
00875 setCursor( Qt::sizeVerCursor );
00876 d->action = A_BR_BOTTOM;
00877 }
00878 } else {
00879 switch ( d->action ) {
00880 case A_BR_TOP: {
00881 if ( d->canvas && my < bottom-20 && my+diffy-2 > 0) {
00882 QPainter p( d->canvas );
00883 p.setRasterOp( Qt::NotROP );
00884 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00885 p.drawLine( 0, my, d->canvas->width(), my );
00886 p.end();
00887 d->layout.ptTop = unZoomIt(static_cast<double>(my + diffy));
00888 d->oldMx = mx;
00889 d->oldMy = my;
00890 update();
00891 }
00892 else
00893 return;
00894 } break;
00895 case A_BR_BOTTOM: {
00896 if ( d->canvas && my > top+20 && my+diffy < ph-2) {
00897 QPainter p( d->canvas );
00898 p.setRasterOp( Qt::NotROP );
00899 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00900 p.drawLine( 0, my, d->canvas->width(), my );
00901 p.end();
00902 d->layout.ptBottom = unZoomIt(static_cast<double>(ph - ( my + diffy )));
00903 d->oldMx = mx;
00904 d->oldMy = my;
00905 update();
00906 }
00907 else
00908 return;
00909 } break;
00910 default: break;
00911 }
00912 }
00913 } break;
00914 }
00915 if( d->action == A_HELPLINES )
00916 {
00917 emit moveHelpLines( e->pos(), orientation == Qt::Horizontal);
00918 }
00919
00920 d->oldMx = mx;
00921 d->oldMy = my;
00922 }
00923
00924 void KoRuler::resizeEvent( QResizeEvent *e )
00925 {
00926 QFrame::resizeEvent( e );
00927 buffer.resize( size() );
00928 }
00929
00930 void KoRuler::mouseDoubleClickEvent( QMouseEvent* )
00931 {
00932 handleDoubleClick();
00933 }
00934
00935 void KoRuler::handleDoubleClick()
00936 {
00937 if ( !d->m_bReadWrite )
00938 return;
00939
00940 d->doubleClickedIndent = false;
00941 if ( d->tabChooser && ( d->flags & F_TABS ) ) {
00942
00943 if ( d->tabChooser->getCurrTabType() != 0 && d->removeTab.type != T_INVALID && !d->tabList.isEmpty()) {
00944 uint c = d->tabList.count();
00945 d->tabList.remove( d->removeTab );
00946 Q_ASSERT( d->tabList.count() < c );
00947
00948 d->removeTab.type = T_INVALID;
00949 d->currTab.type = T_INVALID;
00950 emit tabListChanged( d->tabList );
00951 setCursor( ArrowCursor );
00952 update();
00953
00954 } else if ( d->action == A_TAB ) {
00955
00956 emit doubleClicked( d->currTab.ptPos );
00957 return;
00958 }
00959 }
00960
00961
00962
00963
00964 if ( d->flags & F_INDENTS ) {
00965 if ( d->action == A_LEFT_INDENT || d->action == A_RIGHT_INDENT || d->action == A_FIRST_INDENT ) {
00966 d->doubleClickedIndent = true;
00967 emit doubleClicked();
00968 return;
00969 }
00970 }
00971
00972
00973 d->action = A_NONE;
00974 emit doubleClicked();
00975 }
00976
00977 void KoRuler::setTabList( const KoTabulatorList & _tabList )
00978 {
00979 d->tabList = _tabList;
00980 qHeapSort(d->tabList);
00981
00982
00983
00984
00985 update();
00986 }
00987
00988 double KoRuler::makeIntern( double _v )
00989 {
00990 return KoUnit::fromUserValue( _v, m_unit );
00991 }
00992
00993 void KoRuler::setupMenu()
00994 {
00995 d->rb_menu = new QPopupMenu();
00996 Q_CHECK_PTR( d->rb_menu );
00997 for ( uint i = 0 ; i <= KoUnit::U_LASTUNIT ; ++i )
00998 {
00999 KoUnit::Unit unit = static_cast<KoUnit::Unit>( i );
01000 d->rb_menu->insertItem( KoUnit::unitDescription( unit ), i );
01001 if ( m_unit == unit )
01002 d->rb_menu->setItemChecked( i, true );
01003 }
01004 connect( d->rb_menu, SIGNAL( activated( int ) ), SLOT( slotMenuActivated( int ) ) );
01005
01006 d->rb_menu->insertSeparator();
01007 d->mPageLayout=d->rb_menu->insertItem(i18n("Page Layout..."), this, SLOT(pageLayoutDia()));
01008 d->rb_menu->insertSeparator();
01009 d->mRemoveTab=d->rb_menu->insertItem(i18n("Remove Tabulator"), this, SLOT(rbRemoveTab()));
01010 d->rb_menu->setItemEnabled( d->mRemoveTab, false );
01011 }
01012
01013 void KoRuler::uncheckMenu()
01014 {
01015 for ( uint i = 0 ; i <= KoUnit::U_LASTUNIT ; ++i )
01016 d->rb_menu->setItemChecked( i, false );
01017 }
01018
01019 void KoRuler::setUnit( const QString& _unit )
01020 {
01021 setUnit( KoUnit::unit( _unit ) );
01022 }
01023
01024 void KoRuler::setUnit( KoUnit::Unit unit )
01025 {
01026 m_unit = unit;
01027 uncheckMenu();
01028 d->rb_menu->setItemChecked( m_unit, true );
01029 update();
01030 }
01031
01032 void KoRuler::setZoom( const double& zoom )
01033 {
01034 if(zoom==m_zoom)
01035 return;
01036 if(zoom < 1E-4)
01037 return;
01038 m_zoom=zoom;
01039 m_1_zoom=1/m_zoom;
01040 update();
01041 }
01042
01043 bool KoRuler::willRemoveTab( int y ) const
01044 {
01045 return (y < -50 || y > height() + 25) && d->currTab.type != T_INVALID;
01046 }
01047
01048 void KoRuler::rbRemoveTab() {
01049
01050 d->tabList.remove( d->currTab );
01051 d->currTab.type = T_INVALID;
01052 emit tabListChanged( d->tabList );
01053 update();
01054 }
01055
01056 void KoRuler::setReadWrite(bool _readWrite)
01057 {
01058 d->m_bReadWrite=_readWrite;
01059 }
01060
01061 void KoRuler::searchTab(int mx) {
01062
01063 int pos;
01064 d->currTab.type = T_INVALID;
01065 KoTabulatorList::ConstIterator it = d->tabList.begin();
01066 for ( ; it != d->tabList.end() ; ++it ) {
01067 pos = qRound(applyRtlAndZoom((*it).ptPos)) - diffx + frameStart;
01068 if ( mx > pos - 5 && mx < pos + 5 ) {
01069 setCursor( Qt::sizeHorCursor );
01070 d->action = A_TAB;
01071 d->currTab = *it;
01072 break;
01073 }
01074 }
01075 }
01076
01077 void KoRuler::drawLine(int oldX, int newX) {
01078
01079 QPainter p( d->canvas );
01080 p.setRasterOp( Qt::NotROP );
01081 p.drawLine( oldX, 0, oldX, d->canvas->height() );
01082 if(newX!=-1)
01083 p.drawLine( newX, 0, newX, d->canvas->height() );
01084 p.end();
01085 }
01086
01087 void KoRuler::showMousePos( bool _showMPos )
01088 {
01089 showMPos = _showMPos;
01090 hasToDelete = false;
01091 mposX = -1;
01092 mposY = -1;
01093 update();
01094 }
01095
01096 void KoRuler::setOffset( int _diffx, int _diffy )
01097 {
01098
01099 diffx = _diffx;
01100 diffy = _diffy;
01101 update();
01102 }
01103
01104 void KoRuler::setFrameStartEnd( int _frameStart, int _frameEnd )
01105 {
01106 if ( _frameStart != frameStart || _frameEnd != d->frameEnd || !m_bFrameStartSet )
01107 {
01108 frameStart = _frameStart;
01109 d->frameEnd = _frameEnd;
01110
01111
01112 m_bFrameStartSet = true;
01113 update();
01114 }
01115 }
01116
01117 void KoRuler::setRightIndent( double _right )
01118 {
01119 d->i_right = makeIntern( _right );
01120 update();
01121 }
01122
01123 void KoRuler::setDirection( bool rtl )
01124 {
01125 d->rtl = rtl;
01126 update();
01127 }
01128
01129 void KoRuler::changeFlags(int _flags)
01130 {
01131 d->flags = _flags;
01132 }
01133
01134 int KoRuler::flags() const
01135 {
01136 return d->flags;
01137 }
01138
01139 bool KoRuler::doubleClickedIndent() const
01140 {
01141 return d->doubleClickedIndent;
01142 }
01143
01144 double KoRuler::applyRtlAndZoom( double value ) const
01145 {
01146 int frameWidth = d->frameEnd - frameStart;
01147 return d->rtl ? ( frameWidth - zoomIt( value ) ) : zoomIt( value );
01148 }
01149
01150 double KoRuler::unZoomItRtl( int pixValue ) const
01151 {
01152 int frameWidth = d->frameEnd - frameStart;
01153 return d->rtl ? ( unZoomIt( (double)(frameWidth - pixValue) ) ) : unZoomIt( (double)pixValue );
01154 }
01155
01156 void KoRuler::slotMenuActivated( int i )
01157 {
01158 if ( i >= 0 && i <= KoUnit::U_LASTUNIT )
01159 {
01160 KoUnit::Unit unit = static_cast<KoUnit::Unit>(i);
01161 setUnit( unit );
01162 emit unitChanged( unit );
01163 }
01164 }
01165
01166 QSize KoRuler::minimumSizeHint() const
01167 {
01168 QSize size;
01169 QFont font;
01170 font.setPointSize( 8 );
01171 QFontMetrics fm( font );
01172
01173 size.setWidth( fm.height() + 4 );
01174 size.setHeight( fm.height() + 4 );
01175
01176 return size;
01177 }
01178
01179 QSize KoRuler::sizeHint() const
01180 {
01181 return minimumSizeHint();
01182 }
01183
01184 void KoRuler::setPageLayout( const KoPageLayout& _layout )
01185 {
01186 d->layout = _layout;
01187 update();
01188 }
01189
01190 #include "koRuler.moc"