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