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 textwidth = fm.width( str );
00421 int yOffset = qRound(i) - diffy + qRound(textwidth * 0.5);
00422 if(yOffset > paintRect.bottom())
00423 break;
00424 int textheight = fm.height();
00425 maxheight = QMAX( maxheight, textwidth );
00426 p.save();
00427 p.translate( qRound(( width() - textheight ) * 0.5), yOffset);
00428 p.rotate( -90 );
00429 p.drawText( 0, 0, textwidth + 1, textheight, AlignLeft | AlignTop, str );
00430 p.restore();
00431 }
00432
00433
00434 if ( dist > maxheight + 2 )
00435 {
00436 for ( double i = dist * 0.5;i <= (double)totalh;i += dist ) {
00437 int ii=qRound(i) - diffy;
00438 if(ii > paintRect.bottom())
00439 break;
00440 p.drawLine( 7, ii, width() - 7, ii);
00441 }
00442 }
00443
00444
00445 if ( dist * 0.5 > maxheight + 2 )
00446 {
00447 for ( double i = dist * 0.25;i <=(double)totalh;i += dist *0.5 ) {
00448 int ii=qRound(i) - diffy;
00449 if(ii > paintRect.bottom())
00450 break;
00451 p.drawLine( 9, ii, width() - 9, ii);
00452 }
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 }
00466
00467
00468 if ( d->action == A_NONE && showMPos ) {
00469 p.setPen( colorGroup().color( QColorGroup::Text ) );
00470 p.drawLine( 1, mposY, width() - 1, mposY );
00471 }
00472 hasToDelete = false;
00473
00474 p.end();
00475 _painter->drawPixmap( 0, 0, buffer );
00476 }
00477
00478 void KoRuler::mousePressEvent( QMouseEvent *e )
00479 {
00480 if( !d->m_bReadWrite)
00481 return;
00482
00483 d->oldMx = e->x();
00484 d->oldMy = e->y();
00485 d->mousePressed = true;
00486 d->removeTab.type = T_INVALID;
00487
00488 switch ( e->button() ) {
00489 case RightButton:
00490 if(d->currTab.type == T_INVALID || !(d->flags & F_TABS))
00491 d->rb_menu->setItemEnabled(d->mRemoveTab, false);
00492 else
00493 d->rb_menu->setItemEnabled(d->mRemoveTab, true);
00494 d->rb_menu->popup( QCursor::pos() );
00495 d->action = A_NONE;
00496 d->mousePressed = false;
00497 return;
00498 case MidButton:
00499
00500 handleDoubleClick();
00501 return;
00502 case LeftButton:
00503 if ( d->action == A_BR_RIGHT || d->action == A_BR_LEFT ) {
00504 if ( d->action == A_BR_RIGHT )
00505 d->whileMovingBorderRight = true;
00506 else
00507 d->whileMovingBorderLeft = true;
00508
00509 if ( d->canvas )
00510 drawLine(d->oldMx, -1);
00511 update();
00512 } else if ( d->action == A_BR_TOP || d->action == A_BR_BOTTOM ) {
00513 if ( d->action == A_BR_TOP )
00514 d->whileMovingBorderTop = true;
00515 else
00516 d->whileMovingBorderBottom = true;
00517
00518 if ( d->canvas ) {
00519 QPainter p( d->canvas );
00520 p.setRasterOp( Qt::NotROP );
00521 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00522 p.end();
00523 }
00524 update();
00525 } else if ( d->action == A_FIRST_INDENT || d->action == A_LEFT_INDENT || d->action == A_RIGHT_INDENT ) {
00526 if ( d->canvas )
00527 drawLine(d->oldMx, -1);
00528 } else if ( d->action == A_TAB ) {
00529 if ( d->canvas && d->currTab.type != T_INVALID ) {
00530 drawLine( qRound( applyRtlAndZoom(d->currTab.ptPos) ) + frameStart - diffx, -1 );
00531 }
00532 } else if ( d->tabChooser && ( d->flags & F_TABS ) && d->tabChooser->getCurrTabType() != 0 ) {
00533 int left = frameStart - diffx;
00534 int right = d->frameEnd - diffx;
00535
00536 if( e->x()-left < 0 || right-e->x() < 0 )
00537 return;
00538 KoTabulator tab;
00539 tab.filling = TF_BLANK;
00540 tab.ptWidth = 0.5;
00541 switch ( d->tabChooser->getCurrTabType() ) {
00542 case KoTabChooser::TAB_LEFT:
00543 tab.type = T_LEFT;
00544 break;
00545 case KoTabChooser::TAB_CENTER:
00546 tab.type = T_CENTER;
00547 break;
00548 case KoTabChooser::TAB_RIGHT:
00549 tab.type = T_RIGHT;
00550 break;
00551 case KoTabChooser::TAB_DEC_PNT:
00552 tab.type = T_DEC_PNT;
00553 tab.alignChar = KGlobal::locale()->decimalSymbol()[0];
00554 break;
00555 default: break;
00556 }
00557 tab.ptPos = unZoomItRtl( e->x() + diffx - frameStart );
00558
00559 KoTabulatorList::Iterator it=d->tabList.begin();
00560 while ( it!=d->tabList.end() && tab > (*it) )
00561 ++it;
00562
00563 d->tabList.insert(it, tab);
00564
00565 d->action = A_TAB;
00566 d->removeTab = tab;
00567 d->currTab = tab;
00568
00569 emit tabListChanged( d->tabList );
00570 update();
00571 }
00572 else if ( d->flags & F_HELPLINES )
00573 {
00574 setCursor( orientation == Qt::Horizontal ?
00575 Qt::sizeVerCursor : Qt::sizeHorCursor );
00576 d->action = A_HELPLINES;
00577 }
00578 default:
00579 break;
00580 }
00581 }
00582
00583 void KoRuler::mouseReleaseEvent( QMouseEvent *e )
00584 {
00585 d->mousePressed = false;
00586
00587
00588 bool fakeMovement=false;
00589 if(d->removeTab.type != T_INVALID) {
00590 mouseMoveEvent(e);
00591 fakeMovement=true;
00592 }
00593
00594 if ( d->action == A_BR_RIGHT || d->action == A_BR_LEFT ) {
00595 d->whileMovingBorderRight = false;
00596 d->whileMovingBorderLeft = false;
00597
00598 if ( d->canvas )
00599 drawLine(d->oldMx, -1);
00600 update();
00601 emit newPageLayout( d->layout );
00602 } else if ( d->action == A_BR_TOP || d->action == A_BR_BOTTOM ) {
00603 d->whileMovingBorderTop = false;
00604 d->whileMovingBorderBottom = false;
00605
00606 if ( d->canvas ) {
00607 QPainter p( d->canvas );
00608 p.setRasterOp( Qt::NotROP );
00609 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00610 p.end();
00611 }
00612 update();
00613 emit newPageLayout( d->layout );
00614 } else if ( d->action == A_FIRST_INDENT ) {
00615 if ( d->canvas )
00616 drawLine(d->oldMx, -1);
00617 update();
00618 emit newFirstIndent( i_first );
00619 } else if ( d->action == A_LEFT_INDENT ) {
00620 if ( d->canvas )
00621 drawLine(d->oldMx, -1);
00622 update();
00623 emit newLeftIndent( i_left );
00624 } else if ( d->action == A_RIGHT_INDENT ) {
00625 if ( d->canvas )
00626 drawLine(d->oldMx, -1);
00627 update();
00628 emit newRightIndent( d->i_right );
00629 } else if ( d->action == A_TAB ) {
00630 if ( d->canvas && !fakeMovement ) {
00631 drawLine( qRound( applyRtlAndZoom( d->currTab.ptPos ) ) + frameStart - diffx, -1);
00632 }
00633 if ( willRemoveTab( e->y() ) )
00634 {
00635 d->tabList.remove(d->currTab);
00636 }
00637 qHeapSort( d->tabList );
00638
00639
00640 KoTabulatorList::ConstIterator tmpTab=d->tabList.begin();
00641 int count=0;
00642 while(tmpTab!=d->tabList.end()) {
00643 if( equals( (*tmpTab).ptPos, d->currTab.ptPos ) ) {
00644 count++;
00645 if(count > 1) {
00646 d->tabList.remove(d->currTab);
00647 break;
00648 }
00649 }
00650 tmpTab++;
00651 }
00652
00653 emit tabListChanged( d->tabList );
00654 update();
00655 }
00656 else if( d->action == A_HELPLINES )
00657 {
00658 emit addGuide( e->pos(), orientation == Qt::Horizontal, orientation == Qt::Horizontal ? size().height() : size().width() );
00659 emit addHelpline( e->pos(), orientation == Qt::Horizontal);
00660 setCursor( ArrowCursor );
00661 }
00662 d->currTab.type = T_INVALID;
00663 }
00664
00665 void KoRuler::mouseMoveEvent( QMouseEvent *e )
00666 {
00667 hasToDelete = false;
00668
00669 int pw = d->frameEnd - frameStart;
00670 int ph = qRound(zoomIt(d->layout.ptHeight));
00671 int left = frameStart - diffx;
00672 int top = qRound(zoomIt(d->layout.ptTop));
00673 top -= diffy;
00674 int right = d->frameEnd - diffx;
00675 int bottom = qRound(zoomIt(d->layout.ptBottom));
00676 bottom = ph - bottom - diffy;
00677
00678 int ip_first = qRound( zoomIt( i_first + ( d->rtl ? d->i_right : i_left) ) );
00679 int ip_left = qRound(zoomIt(i_left));
00680 int ip_right = qRound(zoomIt(d->i_right));
00681
00682 int mx = e->x();
00683 mx = mx+diffx < 0 ? 0 : mx;
00684 int my = e->y();
00685 my = my+diffy < 0 ? 0 : my;
00686
00687 QToolTip::remove( this);
00688 switch ( orientation ) {
00689 case Qt::Horizontal: {
00690 if ( !d->mousePressed ) {
00691 setCursor( ArrowCursor );
00692 d->action = A_NONE;
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 if ( !m_bFrameStartSet )
00705 {
00706 if ( mx > left - 5 && mx < left + 5 ) {
00707 setCursor( Qt::sizeHorCursor );
00708 d->action = A_BR_LEFT;
00709 } else if ( mx > right - 5 && mx < right + 5 ) {
00710 setCursor( Qt::sizeHorCursor );
00711 d->action = A_BR_RIGHT;
00712 }
00713 }
00714 if ( d->flags & F_INDENTS ) {
00715 int firstX = d->rtl ? right - ip_first : left + ip_first;
00716 if ( mx > firstX - 5 && mx < firstX + 5 &&
00717 my >= 2 && my <= d->pmFirst.size().height() + 2 ) {
00718 QToolTip::add( this, i18n("First line indent") );
00719 setCursor( ArrowCursor );
00720 d->action = A_FIRST_INDENT;
00721 } else if ( mx > left + ip_left - 5 && mx < left + ip_left + 5 &&
00722 my >= height() - d->pmLeft.size().height() - 2 && my <= height() - 2 ) {
00723 QToolTip::add( this, i18n("Left indent") );
00724 setCursor( ArrowCursor );
00725 d->action = A_LEFT_INDENT;
00726 } else if ( mx > right - ip_right - 5 && mx < right - ip_right + 5 &&
00727 my >= height() - d->pmLeft.size().height() - 2 && my <= height() - 2 ) {
00728 QToolTip::add( this, i18n("Right indent") );
00729 setCursor( ArrowCursor );
00730 d->action = A_RIGHT_INDENT;
00731 }
00732 }
00733 if ( d->flags & F_TABS )
00734 searchTab(mx);
00735 } else {
00736
00737 int newPos=mx;
00738 if( newPos!=right && gridSize!=0.0 && (e->state() & ShiftButton)==0) {
00739 double grid=zoomIt(gridSize * 16);
00740 newPos=qRound( ((newPos * 16 / grid) * grid) / 16 );
00741 }
00742 if(newPos-left < 0) newPos=left;
00743 else if (right-newPos < 0) newPos=right;
00744 double newValue = unZoomIt(static_cast<double>(newPos) - frameStart + diffx);
00745
00746 switch ( d->action ) {
00747 case A_BR_LEFT: {
00748 if ( d->canvas && mx < right-10 && mx+diffx-2 > 0) {
00749 drawLine( d->oldMx, mx );
00750 d->layout.ptLeft = unZoomIt(static_cast<double>(mx + diffx));
00751 if( ip_left > right-left-15 ) {
00752 ip_left=right-left-15;
00753 ip_left=ip_left<0 ? 0 : ip_left;
00754 i_left=unZoomIt( ip_left );
00755 emit newLeftIndent( i_left );
00756 }
00757 if ( ip_right > right-left-15 ) {
00758 ip_right=right-left-15;
00759 ip_right=ip_right<0? 0 : ip_right;
00760 d->i_right=unZoomIt( ip_right );
00761 emit newRightIndent( d->i_right );
00762 }
00763 d->oldMx = mx;
00764 d->oldMy = my;
00765 update();
00766 }
00767 else
00768 return;
00769 } break;
00770 case A_BR_RIGHT: {
00771 if ( d->canvas && mx > left+10 && mx+diffx <= pw-2) {
00772 drawLine( d->oldMx, mx );
00773 d->layout.ptRight = unZoomIt(static_cast<double>(pw - ( mx + diffx )));
00774 if( ip_left > right-left-15 ) {
00775 ip_left=right-left-15;
00776 ip_left=ip_left<0 ? 0 : ip_left;
00777 i_left=unZoomIt( ip_left );
00778 emit newLeftIndent( i_left );
00779 }
00780 if ( ip_right > right-left-15 ) {
00781 ip_right=right-left-15;
00782 ip_right=ip_right<0? 0 : ip_right;
00783 d->i_right=unZoomIt( ip_right );
00784 emit newRightIndent( d->i_right );
00785 }
00786 d->oldMx = mx;
00787 d->oldMy = my;
00788 update();
00789 }
00790 else
00791 return;
00792 } break;
00793 case A_FIRST_INDENT: {
00794 if ( d->canvas ) {
00795 if (d->rtl)
00796 newValue = unZoomIt(pw) - newValue - d->i_right;
00797 else
00798 newValue -= i_left;
00799 if(newValue == i_first) break;
00800 drawLine( d->oldMx, newPos);
00801 d->oldMx=newPos;
00802 i_first = newValue;
00803 update();
00804 }
00805 } break;
00806 case A_LEFT_INDENT: {
00807 if ( d->canvas ) {
00808
00809 if(newValue == i_left) break;
00810
00811 drawLine( d->oldMx, newPos);
00812 i_left = newValue;
00813 d->oldMx = newPos;
00814 update();
00815 }
00816 } break;
00817 case A_RIGHT_INDENT: {
00818 if ( d->canvas ) {
00819 double rightValue = unZoomIt(right - newPos);
00820
00821 if(rightValue == d->i_right) break;
00822
00823 drawLine( d->oldMx, newPos);
00824 d->i_right=rightValue;
00825 d->oldMx = newPos;
00826 update();
00827 }
00828 } break;
00829 case A_TAB: {
00830 if ( d->canvas) {
00831 if (d->rtl) newValue = unZoomIt(pw) - newValue;
00832 if(newValue == d->currTab.ptPos) break;
00833 QPainter p( d->canvas );
00834 p.setRasterOp( Qt::NotROP );
00835
00836
00837 double pt;
00838 int pt_fr;
00839 if( d->currTab != d->removeTab )
00840 {
00841 pt = applyRtlAndZoom(d->currTab.ptPos);
00842 pt_fr = qRound(pt) + frameStart - diffx;
00843 p.drawLine( pt_fr, 0, pt_fr, d->canvas->height() );
00844 }
00845
00846 KoTabulatorList::Iterator it = d->tabList.find( d->currTab );
00847 Q_ASSERT( it != d->tabList.end() );
00848 if ( it != d->tabList.end() )
00849 (*it).ptPos = newValue;
00850 d->currTab.ptPos = newValue;
00851
00852 pt = applyRtlAndZoom( newValue );
00853 pt_fr = qRound(pt) + frameStart - diffx;
00854 p.drawLine( pt_fr, 0, pt_fr, d->canvas->height() );
00855
00856 p.end();
00857 d->oldMx = mx;
00858 d->oldMy = my;
00859 d->removeTab.type = T_INVALID;
00860 update();
00861 }
00862 } break;
00863 default: break;
00864 }
00865 }
00866 if( d->action == A_HELPLINES )
00867 {
00868 emit moveGuide( e->pos(), true, size().height() );
00869 emit moveHelpLines( e->pos(), true );
00870 }
00871
00872 return;
00873 } break;
00874 case Qt::Vertical: {
00875 if ( !d->mousePressed ) {
00876 setCursor( ArrowCursor );
00877 d->action = A_NONE;
00878 if ( d->flags & F_NORESIZE )
00879 break;
00880 if ( my > top - 5 && my < top + 5 ) {
00881 QToolTip::add( this, i18n("Top margin") );
00882 setCursor( Qt::sizeVerCursor );
00883 d->action = A_BR_TOP;
00884 } else if ( my > bottom - 5 && my < bottom + 5 ) {
00885 QToolTip::add( this, i18n("Bottom margin") );
00886 setCursor( Qt::sizeVerCursor );
00887 d->action = A_BR_BOTTOM;
00888 }
00889 } else {
00890 switch ( d->action ) {
00891 case A_BR_TOP: {
00892 if ( d->canvas && my < bottom-20 && my+diffy-2 > 0) {
00893 QPainter p( d->canvas );
00894 p.setRasterOp( Qt::NotROP );
00895 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00896 p.drawLine( 0, my, d->canvas->width(), my );
00897 p.end();
00898 d->layout.ptTop = unZoomIt(static_cast<double>(my + diffy));
00899 d->oldMx = mx;
00900 d->oldMy = my;
00901 update();
00902 }
00903 else
00904 return;
00905 } break;
00906 case A_BR_BOTTOM: {
00907 if ( d->canvas && my > top+20 && my+diffy < ph-2) {
00908 QPainter p( d->canvas );
00909 p.setRasterOp( Qt::NotROP );
00910 p.drawLine( 0, d->oldMy, d->canvas->width(), d->oldMy );
00911 p.drawLine( 0, my, d->canvas->width(), my );
00912 p.end();
00913 d->layout.ptBottom = unZoomIt(static_cast<double>(ph - ( my + diffy )));
00914 d->oldMx = mx;
00915 d->oldMy = my;
00916 update();
00917 }
00918 else
00919 return;
00920 } break;
00921 default: break;
00922 }
00923 }
00924
00925 if( d->action == A_HELPLINES )
00926 {
00927 emit moveGuide( e->pos(), false, size().width() );
00928 emit moveHelpLines( e->pos(), false );
00929 }
00930 } break;
00931 }
00932
00933 d->oldMx = mx;
00934 d->oldMy = my;
00935 }
00936
00937 void KoRuler::resizeEvent( QResizeEvent *e )
00938 {
00939 QFrame::resizeEvent( e );
00940 buffer.resize( size() );
00941 }
00942
00943 void KoRuler::mouseDoubleClickEvent( QMouseEvent* )
00944 {
00945 handleDoubleClick();
00946 }
00947
00948 void KoRuler::handleDoubleClick()
00949 {
00950 if ( !d->m_bReadWrite )
00951 return;
00952
00953 d->doubleClickedIndent = false;
00954 if ( d->tabChooser && ( d->flags & F_TABS ) ) {
00955
00956 if ( d->tabChooser->getCurrTabType() != 0 && d->removeTab.type != T_INVALID && !d->tabList.isEmpty()) {
00957 uint c = d->tabList.count();
00958 d->tabList.remove( d->removeTab );
00959 Q_ASSERT( d->tabList.count() < c );
00960
00961 d->removeTab.type = T_INVALID;
00962 d->currTab.type = T_INVALID;
00963 emit tabListChanged( d->tabList );
00964 setCursor( ArrowCursor );
00965 update();
00966
00967 } else if ( d->action == A_TAB ) {
00968
00969 emit doubleClicked( d->currTab.ptPos );
00970 return;
00971 }
00972 }
00973
00974
00975
00976
00977 if ( d->flags & F_INDENTS ) {
00978 if ( d->action == A_LEFT_INDENT || d->action == A_RIGHT_INDENT || d->action == A_FIRST_INDENT ) {
00979 d->doubleClickedIndent = true;
00980 emit doubleClicked();
00981 return;
00982 }
00983 }
00984
00985
00986 d->action = A_NONE;
00987 emit doubleClicked();
00988 }
00989
00990 void KoRuler::setTabList( const KoTabulatorList & _tabList )
00991 {
00992 d->tabList = _tabList;
00993 qHeapSort(d->tabList);
00994
00995
00996
00997
00998 update();
00999 }
01000
01001 double KoRuler::makeIntern( double _v )
01002 {
01003 return KoUnit::fromUserValue( _v, m_unit );
01004 }
01005
01006 void KoRuler::setupMenu()
01007 {
01008 d->rb_menu = new QPopupMenu();
01009 Q_CHECK_PTR( d->rb_menu );
01010 for ( uint i = 0 ; i <= KoUnit::U_LASTUNIT ; ++i )
01011 {
01012 KoUnit::Unit unit = static_cast<KoUnit::Unit>( i );
01013 d->rb_menu->insertItem( KoUnit::unitDescription( unit ), i );
01014 if ( m_unit == unit )
01015 d->rb_menu->setItemChecked( i, true );
01016 }
01017 connect( d->rb_menu, SIGNAL( activated( int ) ), SLOT( slotMenuActivated( int ) ) );
01018
01019 d->rb_menu->insertSeparator();
01020 d->mPageLayout=d->rb_menu->insertItem(i18n("Page Layout..."), this, SLOT(pageLayoutDia()));
01021 d->rb_menu->insertSeparator();
01022 d->mRemoveTab=d->rb_menu->insertItem(i18n("Remove Tabulator"), this, SLOT(rbRemoveTab()));
01023 d->rb_menu->setItemEnabled( d->mRemoveTab, false );
01024 }
01025
01026 void KoRuler::uncheckMenu()
01027 {
01028 for ( uint i = 0 ; i <= KoUnit::U_LASTUNIT ; ++i )
01029 d->rb_menu->setItemChecked( i, false );
01030 }
01031
01032 void KoRuler::setUnit( const QString& _unit )
01033 {
01034 setUnit( KoUnit::unit( _unit ) );
01035 }
01036
01037 void KoRuler::setUnit( KoUnit::Unit unit )
01038 {
01039 m_unit = unit;
01040 uncheckMenu();
01041 d->rb_menu->setItemChecked( m_unit, true );
01042 update();
01043 }
01044
01045 void KoRuler::setZoom( const double& zoom )
01046 {
01047 if(zoom==m_zoom)
01048 return;
01049 if(zoom < 1E-4)
01050 return;
01051 m_zoom=zoom;
01052 m_1_zoom=1/m_zoom;
01053 update();
01054 }
01055
01056 bool KoRuler::willRemoveTab( int y ) const
01057 {
01058 return (y < -50 || y > height() + 25) && d->currTab.type != T_INVALID;
01059 }
01060
01061 void KoRuler::rbRemoveTab() {
01062
01063 d->tabList.remove( d->currTab );
01064 d->currTab.type = T_INVALID;
01065 emit tabListChanged( d->tabList );
01066 update();
01067 }
01068
01069 void KoRuler::setReadWrite(bool _readWrite)
01070 {
01071 d->m_bReadWrite=_readWrite;
01072 }
01073
01074 void KoRuler::searchTab(int mx) {
01075
01076 int pos;
01077 d->currTab.type = T_INVALID;
01078 KoTabulatorList::ConstIterator it = d->tabList.begin();
01079 for ( ; it != d->tabList.end() ; ++it ) {
01080 pos = qRound(applyRtlAndZoom((*it).ptPos)) - diffx + frameStart;
01081 if ( mx > pos - 5 && mx < pos + 5 ) {
01082 setCursor( Qt::sizeHorCursor );
01083 d->action = A_TAB;
01084 d->currTab = *it;
01085 break;
01086 }
01087 }
01088 }
01089
01090 void KoRuler::drawLine(int oldX, int newX) {
01091
01092 QPainter p( d->canvas );
01093 p.setRasterOp( Qt::NotROP );
01094 p.drawLine( oldX, 0, oldX, d->canvas->height() );
01095 if(newX!=-1)
01096 p.drawLine( newX, 0, newX, d->canvas->height() );
01097 p.end();
01098 }
01099
01100 void KoRuler::showMousePos( bool _showMPos )
01101 {
01102 showMPos = _showMPos;
01103 hasToDelete = false;
01104 mposX = -1;
01105 mposY = -1;
01106 update();
01107 }
01108
01109 void KoRuler::setOffset( int _diffx, int _diffy )
01110 {
01111
01112 diffx = _diffx;
01113 diffy = _diffy;
01114 update();
01115 }
01116
01117 void KoRuler::setFrameStartEnd( int _frameStart, int _frameEnd )
01118 {
01119 if ( _frameStart != frameStart || _frameEnd != d->frameEnd || !m_bFrameStartSet )
01120 {
01121 frameStart = _frameStart;
01122 d->frameEnd = _frameEnd;
01123
01124
01125 m_bFrameStartSet = true;
01126 update();
01127 }
01128 }
01129
01130 void KoRuler::setRightIndent( double _right )
01131 {
01132 d->i_right = makeIntern( _right );
01133 update();
01134 }
01135
01136 void KoRuler::setDirection( bool rtl )
01137 {
01138 d->rtl = rtl;
01139 update();
01140 }
01141
01142 void KoRuler::changeFlags(int _flags)
01143 {
01144 d->flags = _flags;
01145 }
01146
01147 int KoRuler::flags() const
01148 {
01149 return d->flags;
01150 }
01151
01152 bool KoRuler::doubleClickedIndent() const
01153 {
01154 return d->doubleClickedIndent;
01155 }
01156
01157 double KoRuler::applyRtlAndZoom( double value ) const
01158 {
01159 int frameWidth = d->frameEnd - frameStart;
01160 return d->rtl ? ( frameWidth - zoomIt( value ) ) : zoomIt( value );
01161 }
01162
01163 double KoRuler::unZoomItRtl( int pixValue ) const
01164 {
01165 int frameWidth = d->frameEnd - frameStart;
01166 return d->rtl ? ( unZoomIt( (double)(frameWidth - pixValue) ) ) : unZoomIt( (double)pixValue );
01167 }
01168
01169 void KoRuler::slotMenuActivated( int i )
01170 {
01171 if ( i >= 0 && i <= KoUnit::U_LASTUNIT )
01172 {
01173 KoUnit::Unit unit = static_cast<KoUnit::Unit>(i);
01174 setUnit( unit );
01175 emit unitChanged( unit );
01176 }
01177 }
01178
01179 QSize KoRuler::minimumSizeHint() const
01180 {
01181 QSize size;
01182 QFont font = KGlobalSettings::toolBarFont();
01183 QFontMetrics fm( font );
01184
01185 size.setWidth( QMAX( fm.height() + 4, 20 ) );
01186 size.setHeight( QMAX( fm.height() + 4, 20 ) );
01187
01188 return size;
01189 }
01190
01191 QSize KoRuler::sizeHint() const
01192 {
01193 return minimumSizeHint();
01194 }
01195
01196 void KoRuler::setPageLayout( const KoPageLayout& _layout )
01197 {
01198 d->layout = _layout;
01199 update();
01200 }
01201
01202 #include "KoRuler.moc"