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