00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <assert.h>
00045 #include <float.h>
00046 #include <stdlib.h>
00047
00048 #include <qapplication.h>
00049 #include <qbuffer.h>
00050 #include <qclipboard.h>
00051 #include <qdrawutil.h>
00052 #include <qlabel.h>
00053 #include <qpoint.h>
00054 #include <qscrollbar.h>
00055 #include <qtimer.h>
00056 #include <qtooltip.h>
00057 #include <qwidgetlist.h>
00058
00059 #include <kcursor.h>
00060 #include <kdebug.h>
00061 #include <kmessagebox.h>
00062 #include <kmultipledrag.h>
00063 #include <krun.h>
00064 #include <kmimetype.h>
00065 #include <ksharedptr.h>
00066 #include <kwordwrap.h>
00067
00068 #include <KoOasisStore.h>
00069 #include <KoSpeaker.h>
00070 #include <KoStore.h>
00071 #include <KoStoreDrag.h>
00072 #include <KoXmlWriter.h>
00073 #include <KoDocumentChild.h>
00074 #include <KoRect.h>
00075
00076 #include "commands.h"
00077 #include "kspread_doc.h"
00078 #include "kspread_editors.h"
00079 #include "kspread_global.h"
00080 #include "kspread_locale.h"
00081 #include "kspread_map.h"
00082 #include "kspread_sheet.h"
00083 #include "kspread_undo.h"
00084 #include "kspread_util.h"
00085 #include "kspread_view.h"
00086 #include "selection.h"
00087
00088 #include "kspread_canvas.h"
00089
00090
00091
00092 #define NONCONTIGUOUSSELECTION
00093
00094 #define MIN_SIZE 10
00095
00096 using namespace KSpread;
00097
00098 class Canvas::Private
00099 {
00100 public:
00101 ComboboxLocationEditWidget *posWidget;
00102 KSpread::EditWidget *editWidget;
00103 KSpread::CellEditor *cellEditor;
00104
00105 View *view;
00106 QTimer* scrollTimer;
00107
00108
00109
00110
00111 double xOffset;
00112
00113
00114
00115
00116 double yOffset;
00117
00118
00119
00120 QPen defaultGridPen;
00121
00122
00123 Canvas::EditorType focusEditorType;
00124
00125 QLabel *validationInfo;
00126
00127
00128 bool chooseCell;
00129
00130
00131 bool mousePressed;
00132
00133
00134
00135
00136
00137
00138
00139 Canvas::MouseActions mouseAction;
00140
00141
00142
00143
00144 QRect autoFillSource;
00145
00146
00147 QPoint dragStart;
00148 bool dragging;
00149
00150
00151 bool rubberBandStarted;
00152 QPoint rubberBandStart;
00153 QPoint rubberBandEnd;
00154
00155
00156 QString anchor;
00157
00158 bool mouseSelectedObject;
00159 bool drawContour;
00160 ModifyType modType;
00164 QPoint m_savedMousePos;
00165
00166
00168 EmbeddedObject *m_resizeObject;
00170 double m_ratio;
00171 bool m_isResizing;
00173 KoPoint m_origMousePos;
00174
00175
00176 bool m_isMoving;
00177 KoPoint m_moveStartPoint;
00178
00180 KoRect m_rectBeforeResize;
00182 KoPoint m_moveStartPosMouse;
00183
00185 EmbeddedObject * m_objectDisplayAbove;
00186
00187
00188
00189
00190
00191 int prevSpokenPointerRow;
00192 int prevSpokenPointerCol;
00193 int prevSpokenFocusRow;
00194 int prevSpokenFocusCol;
00195 int prevSpokenRow;
00196 int prevSpokenCol;
00197 };
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 Canvas::Canvas (View *_view)
00208 : QWidget( _view, "", WStaticContents| WResizeNoErase | WRepaintNoErase )
00209 {
00210 d = new Private;
00211
00212 d->cellEditor = 0;
00213 d->chooseCell = false;
00214 d->validationInfo = 0L;
00215
00216 QWidget::setFocusPolicy( QWidget::StrongFocus );
00217
00218 d->dragStart = QPoint( -1, -1 );
00219 d->dragging = false;
00220
00221
00222 d->defaultGridPen.setColor( lightGray );
00223 d->defaultGridPen.setWidth( 1 );
00224 d->defaultGridPen.setStyle( SolidLine );
00225
00226 d->xOffset = 0.0;
00227 d->yOffset = 0.0;
00228 d->view = _view;
00229
00230 d->mouseAction = NoAction;
00231 d->rubberBandStarted = false;
00232
00233
00234
00235
00236 d->posWidget = d->view->posWidget();
00237
00238 setBackgroundMode( PaletteBase );
00239
00240 setMouseTracking( true );
00241 d->mousePressed = false;
00242 d->mouseSelectedObject = false;
00243 d->drawContour = false;
00244 d->modType = MT_NONE;
00245
00246 d->m_resizeObject = 0L;
00247 d->m_ratio = 0.0;
00248 d->m_isMoving = false;
00249 d->m_objectDisplayAbove = false;
00250 d->m_isResizing = false;
00251
00252 d->prevSpokenPointerRow = -1;
00253 d->prevSpokenPointerCol = -1;
00254 d->prevSpokenFocusRow = -1;
00255 d->prevSpokenFocusCol = -1;
00256 d->prevSpokenRow = -1;
00257 d->prevSpokenCol = -1;
00258
00259 d->scrollTimer = new QTimer( this );
00260 connect (d->scrollTimer, SIGNAL( timeout() ), this, SLOT( doAutoScroll() ) );
00261
00262 if( d->view)
00263 {
00264 connect( d->view, SIGNAL( autoScroll( const QPoint & )), this, SLOT( slotAutoScroll( const QPoint &)));
00265 }
00266 if (kospeaker)
00267 {
00268 connect (kospeaker, SIGNAL(customSpeakWidget(QWidget*, const QPoint&, uint)),
00269 this, SLOT(speakCell(QWidget*, const QPoint&, uint)));
00270 }
00271
00272 setFocus();
00273 installEventFilter( this );
00274 (void)new ToolTip( this );
00275 setAcceptDrops( true );
00276 setInputMethodEnabled( true );
00277
00278 setWFlags(Qt::WNoAutoErase);
00279 }
00280
00281 Canvas::~Canvas()
00282 {
00283 delete d->scrollTimer;
00284 delete d->validationInfo;
00285 delete d;
00286 }
00287
00288 KSpread::View* Canvas::view() const
00289 {
00290 return d->view;
00291 }
00292
00293 Doc* Canvas::doc() const
00294 {
00295 return d->view->doc();
00296 }
00297
00298 void Canvas::setEditWidget( KSpread::EditWidget * ew )
00299 {
00300 d->editWidget = ew;
00301 }
00302
00303 KSpread::EditWidget* Canvas::editWidget() const
00304 {
00305 return d->editWidget;
00306 }
00307
00308 CellEditor* Canvas::editor() const
00309 {
00310 return d->cellEditor;
00311 }
00312
00313 double Canvas::xOffset() const
00314 {
00315 return d->xOffset;
00316 }
00317
00318 double Canvas::yOffset() const
00319 {
00320 return d->yOffset;
00321 }
00322
00323 void Canvas::setXOffset( double _xOffset )
00324 {
00325 d->xOffset = _xOffset;
00326 kdDebug(36001) << "setXOffset(): XOffset before scrollToCell: "
00327 << d->xOffset << endl;
00328 scrollToCell( marker() );
00329 kdDebug(36001) << "setXOffset(): XOffset after scrollToCell: "
00330 << d->xOffset << endl;
00331 }
00332
00333 void Canvas::setYOffset( double _yOffset )
00334 {
00335 d->yOffset = _yOffset;
00336 kdDebug(36001) << "setyOffset(): YOffset before scrollToCell: "
00337 << d->yOffset << endl;
00338 scrollToCell( marker() );
00339 kdDebug(36001) << "setYOffset(): YOffset after scrollToCell: "
00340 << d->yOffset << endl;
00341 }
00342
00343 const QPen& Canvas::defaultGridPen() const
00344 {
00345 return d->defaultGridPen;
00346 }
00347
00348 void Canvas::setLastEditorWithFocus( Canvas::EditorType type )
00349 {
00350 d->focusEditorType = type;
00351 }
00352
00353 Canvas::EditorType Canvas::lastEditorWithFocus() const
00354 {
00355 return d->focusEditorType;
00356 }
00357
00358
00359 bool Canvas::eventFilter( QObject *o, QEvent *e )
00360 {
00361
00362
00363
00364 if ( !o || !e )
00365 return true;
00366 switch ( e->type() )
00367 {
00368 case QEvent::KeyPress:
00369 {
00370 QKeyEvent * keyev = static_cast<QKeyEvent *>(e);
00371 if ((keyev->key()==Key_Tab) || (keyev->key()==Key_Backtab))
00372 {
00373 keyPressEvent ( keyev );
00374 return true;
00375 }
00376 break;
00377 }
00378 case QEvent::IMStart:
00379 case QEvent::IMCompose:
00380 case QEvent::IMEnd:
00381 {
00382 QIMEvent * imev = static_cast<QIMEvent *>(e);
00383 processIMEvent( imev );
00384 break;
00385 }
00386 default:
00387 break;
00388 }
00389 return false;
00390 }
00391
00392 bool Canvas::focusNextPrevChild( bool )
00393 {
00394 return true;
00395 }
00396
00397 Selection* Canvas::selectionInfo() const
00398 {
00399 return d->view->selectionInfo();
00400 }
00401
00402 Selection* Canvas::choice() const
00403 {
00404 return d->view->choice();
00405 }
00406
00407 QRect Canvas::selection() const
00408 {
00409 return d->view->selectionInfo()->selection();
00410 }
00411
00412 QPoint Canvas::marker() const
00413 {
00414 return d->view->selectionInfo()->marker();
00415 }
00416
00417 int Canvas::markerColumn() const
00418 {
00419 return d->view->selectionInfo()->marker().x();
00420 }
00421
00422 int Canvas::markerRow() const
00423 {
00424 return d->view->selectionInfo()->marker().y();
00425 }
00426
00427 double Canvas::zoom() const
00428 {
00429 return d->view->zoom();
00430 }
00431
00432 void Canvas::setChooseMode(bool state)
00433 {
00434 d->chooseCell = state;
00435 }
00436
00437 bool Canvas::chooseMode() const
00438 {
00439 return d->chooseCell;
00440 }
00441
00442 void Canvas::startChoose()
00443 {
00444 if ( d->chooseCell )
00445 return;
00446
00447 choice()->clear();
00448 choice()->setSheet(activeSheet());
00449
00450
00451 d->chooseCell = true;
00452 }
00453
00454 void Canvas::startChoose( const QRect& rect )
00455 {
00456 if (d->chooseCell)
00457 return;
00458
00459 choice()->setSheet(activeSheet());
00460 choice()->initialize(rect);
00461
00462
00463 d->chooseCell = true;
00464 }
00465
00466 void Canvas::endChoose()
00467 {
00468
00469
00470
00471 if (!choice()->isEmpty())
00472 {
00473 choice()->clear();
00474 update();
00475 }
00476
00477 if ( !d->chooseCell )
00478 return;
00479
00480 d->chooseCell = false;
00481
00482 Sheet *sheet = choice()->sheet();
00483 if (sheet)
00484 {
00485 d->view->setActiveSheet(sheet);
00486 }
00487 }
00488
00489 HBorder* Canvas::hBorderWidget() const
00490 {
00491 return d->view->hBorderWidget();
00492 }
00493
00494 VBorder* Canvas::vBorderWidget() const
00495 {
00496 return d->view->vBorderWidget();
00497 }
00498
00499 QScrollBar* Canvas::horzScrollBar() const
00500 {
00501 return d->view->horzScrollBar();
00502 }
00503
00504 QScrollBar* Canvas::vertScrollBar() const
00505 {
00506 return d->view->vertScrollBar();
00507 }
00508
00509 Sheet* Canvas::findSheet( const QString& _name ) const
00510 {
00511 return d->view->doc()->map()->findSheet( _name );
00512 }
00513
00514 Sheet* Canvas::activeSheet() const
00515 {
00516 return d->view->activeSheet();
00517 }
00518
00519 void Canvas::validateSelection()
00520 {
00521 Sheet* sheet = activeSheet();
00522 if (!sheet)
00523 {
00524 return;
00525 }
00526
00527 if ( selectionInfo()->isSingular() )
00528 {
00529 int col = selectionInfo()->marker().x();
00530 int row = selectionInfo()->marker().y();
00531 Cell * cell = sheet->cellAt( col,row );
00532 if ( cell && cell->getValidity(0) && cell->getValidity()->displayValidationInformation)
00533 {
00534 QString title = cell->getValidity(0)->titleInfo;
00535 QString message = cell->getValidity(0)->messageInfo;
00536 if ( title.isEmpty() && message.isEmpty() )
00537 return;
00538
00539 if ( !d->validationInfo )
00540 d->validationInfo = new QLabel( this );
00541 kdDebug()<<" display info validation\n";
00542 double u = cell->dblWidth( col );
00543 double v = cell->dblHeight( row );
00544 double xpos = sheet->dblColumnPos( markerColumn() ) - xOffset();
00545 double ypos = sheet->dblRowPos( markerRow() ) - yOffset();
00546
00547 if ( cell->isObscured() && cell->isPartOfMerged() )
00548 {
00549 cell = cell->obscuringCells().first();
00550 int moveX = cell->column();
00551 int moveY = cell->row();
00552
00553
00554 u = cell->dblWidth( moveX );
00555 v = cell->dblHeight( moveY );
00556 xpos = sheet->dblColumnPos( moveX );
00557 ypos = sheet->dblRowPos( moveY );
00558 }
00559
00560 d->validationInfo->setAlignment( Qt::AlignVCenter );
00561 QPainter painter;
00562 painter.begin( this );
00563 int len = 0;
00564 int hei = 0;
00565 QString resultText;
00566 if ( !title.isEmpty() )
00567 {
00568 len = painter.fontMetrics().width( title );
00569 hei = painter.fontMetrics().height();
00570 resultText = title + "\n";
00571 }
00572 if ( !message.isEmpty() )
00573 {
00574 int i = 0;
00575 int pos = 0;
00576 QString t;
00577 do
00578 {
00579 i = message.find( "\n", pos );
00580 if ( i == -1 )
00581 t = message.mid( pos, message.length() - pos );
00582 else
00583 {
00584 t = message.mid( pos, i - pos );
00585 pos = i + 1;
00586 }
00587 hei += painter.fontMetrics().height();
00588 len = QMAX( len, painter.fontMetrics().width( t ) );
00589 }
00590 while ( i != -1 );
00591 resultText += message;
00592 }
00593 painter.end();
00594 d->validationInfo->setText( resultText );
00595
00596 KoRect unzoomedMarker( xpos - xOffset()+u,
00597 ypos - yOffset()+v,
00598 len,
00599 hei );
00600 QRect marker( d->view->doc()->zoomRect( unzoomedMarker ) );
00601
00602 d->validationInfo->setGeometry( marker );
00603 d->validationInfo->show();
00604 }
00605 else
00606 {
00607 delete d->validationInfo;
00608 d->validationInfo = 0L;
00609 }
00610 }
00611 else
00612 {
00613 delete d->validationInfo;
00614 d->validationInfo = 0L;
00615 }
00616 }
00617
00618
00619 void Canvas::scrollToCell(QPoint location) const
00620 {
00621 Sheet* sheet = activeSheet();
00622 if (sheet == NULL)
00623 return;
00624
00625 kdDebug(36001) << "------------------------------------------------" << endl;
00626 kdDebug(36001) << "scrollToCell(): at location [" << location.x() << ","
00627 << location.y() << "]" << endl;
00628
00629
00630
00631
00632
00633 Cell* cell = sheet->cellAt(location.x(), location.y(), true);
00634 Q_UNUSED(cell);
00635
00636 double unzoomedWidth = d->view->doc()->unzoomItX( width() );
00637 double unzoomedHeight = d->view->doc()->unzoomItY( height() );
00638
00639 kdDebug(36001) << "Unzoomed view size: [" << unzoomedWidth << ","
00640 << unzoomedHeight << "]" << endl;
00641
00642
00643
00644 double xpos;
00645 if ( sheet->layoutDirection()==Sheet::LeftToRight )
00646 xpos = sheet->dblColumnPos( location.x() ) - xOffset();
00647 else
00648 xpos = unzoomedWidth - sheet->dblColumnPos( location.x() ) + xOffset();
00649 double ypos = sheet->dblRowPos( location.y() ) - yOffset();
00650
00651 kdDebug(36001) << "Position: [" << xpos << "," << ypos << "]" << endl;
00652
00653 double minY = 40.0;
00654 double maxY = unzoomedHeight - 40.0;
00655 kdDebug(36001) << "Canvas::scrollToCell : height=" << height() << endl;
00656 kdDebug(36001) << "Canvas::scrollToCell : width=" << width() << endl;
00657
00658 if ( sheet->layoutDirection()==Sheet::RightToLeft ) {
00659
00660
00661 double minX = unzoomedWidth - 100.0;
00662 double maxX = 100.0;
00663
00664
00665
00666
00667 if ( xpos > minX )
00668 horzScrollBar()->setValue( horzScrollBar()->maxValue() -
00669 d->view->doc()->zoomItX( xOffset() - xpos + minX ) );
00670
00671
00672 else if ( xpos < maxX )
00673 {
00674 double horzScrollBarValue = xOffset() - xpos + maxX;
00675 double horzScrollBarValueMax = sheet->sizeMaxX() - unzoomedWidth;
00676
00677
00678 if ( horzScrollBarValue > horzScrollBarValueMax )
00679 horzScrollBarValue = horzScrollBarValueMax;
00680
00681 horzScrollBar()->setValue( horzScrollBar()->maxValue() -
00682 d->view->doc()->zoomItX( horzScrollBarValue ) );
00683 }
00684 }
00685 else {
00686
00687
00688 double minX = 100.0;
00689 double maxX = unzoomedWidth - 100.0;
00690
00691 kdDebug() << "ltr: XPos: " << xpos << ", min: " << minX << ", maxX: " << maxX << endl;
00692
00693
00694 if ( xpos < minX )
00695 horzScrollBar()->setValue( d->view->doc()->zoomItX( xOffset() + xpos - minX ) );
00696
00697
00698 else if ( xpos > maxX )
00699 {
00700 double horzScrollBarValue = xOffset() + xpos - maxX;
00701 double horzScrollBarValueMax = sheet->sizeMaxX() - unzoomedWidth;
00702
00703
00704 if ( horzScrollBarValue > horzScrollBarValueMax )
00705 horzScrollBarValue = horzScrollBarValueMax;
00706
00707 horzScrollBar()->setValue( d->view->doc()->zoomItX( horzScrollBarValue ) );
00708 }
00709 }
00710
00711
00712 if ( ypos < minY )
00713 vertScrollBar()->setValue( d->view->doc()->zoomItY( yOffset() + ypos - minY ) );
00714
00715
00716 else if ( ypos > maxY )
00717 {
00718 double vertScrollBarValue = yOffset() + ypos - maxY;
00719 double vertScrollBarValueMax = sheet->sizeMaxY() - unzoomedHeight;
00720
00721
00722 if ( vertScrollBarValue > vertScrollBarValueMax )
00723 vertScrollBarValue = vertScrollBarValueMax;
00724
00725 vertScrollBar()->setValue( d->view->doc()->zoomItY( vertScrollBarValue ) );
00726 }
00727 }
00728
00729 void Canvas::slotScrollHorz( int _value )
00730 {
00731 Sheet * sheet = activeSheet();
00732
00733 if ( sheet == 0L )
00734 return;
00735
00736 kdDebug(36001) << "slotScrollHorz: value = " << _value << endl;
00737
00738
00739 if ( sheet->layoutDirection()==Sheet::RightToLeft )
00740 _value = horzScrollBar()->maxValue() - _value;
00741
00742 double unzoomedValue = d->view->doc()->unzoomItX( _value );
00743 double dwidth = d->view->doc()->unzoomItX( width() );
00744
00745 d->view->doc()->emitBeginOperation(false);
00746
00747 if ( unzoomedValue < 0.0 ) {
00748 kdDebug (36001)
00749 << "Canvas::slotScrollHorz: value out of range (unzoomedValue: "
00750 << unzoomedValue << ")" << endl;
00751 unzoomedValue = 0.0;
00752 }
00753
00754 double xpos = sheet->dblColumnPos( QMIN( KS_colMax, d->view->activeSheet()->maxColumn()+10 ) ) - d->xOffset;
00755 if ( unzoomedValue > ( xpos + d->xOffset ) )
00756 unzoomedValue = xpos + d->xOffset;
00757
00758 sheet->enableScrollBarUpdates( false );
00759
00760
00761 int dx = d->view->doc()->zoomItX( d->xOffset - unzoomedValue );
00762
00763
00764
00765 QRect area = visibleCells();
00766 double tmp;
00767 if (dx > 0)
00768 {
00769 area.setRight( area.left() );
00770 area.setLeft( sheet->leftColumn( unzoomedValue, tmp ) );
00771 }
00772 else
00773 {
00774 area.setLeft( area.right() );
00775 area.setRight( sheet->rightColumn( dwidth + unzoomedValue ) );
00776 }
00777
00778 sheet->setRegionPaintDirty(area);
00779
00780
00781 kdDebug(36001) << "slotScrollHorz(): XOffset before setting: "
00782 << d->xOffset << endl;
00783 d->xOffset = unzoomedValue;
00784 kdDebug(36001) << "slotScrollHorz(): XOffset after setting: "
00785 << d->xOffset << endl;
00786
00787 if ( sheet->layoutDirection()==Sheet::RightToLeft )
00788 dx = -dx;
00789
00790 scroll( dx, 0 );
00791
00792 hBorderWidget()->scroll( dx, 0 );
00793
00794 sheet->enableScrollBarUpdates( true );
00795
00796 d->view->doc()->emitEndOperation( sheet->visibleRect( this ) );
00797 }
00798
00799 void Canvas::slotScrollVert( int _value )
00800 {
00801 if ( activeSheet() == 0L )
00802 return;
00803
00804 d->view->doc()->emitBeginOperation(false);
00805 double unzoomedValue = d->view->doc()->unzoomItY( _value );
00806
00807 if ( unzoomedValue < 0 )
00808 {
00809 unzoomedValue = 0;
00810 kdDebug (36001) << "Canvas::slotScrollVert: value out of range (unzoomedValue: " <<
00811 unzoomedValue << ")" << endl;
00812 }
00813
00814 double ypos = activeSheet()->dblRowPos( QMIN( KS_rowMax, d->view->activeSheet()->maxRow()+10 ) );
00815 if ( unzoomedValue > ypos )
00816 unzoomedValue = ypos;
00817
00818 activeSheet()->enableScrollBarUpdates( false );
00819
00820
00821 int dy = d->view->doc()->zoomItY( d->yOffset - unzoomedValue );
00822
00823
00824
00825 QRect area = visibleCells();
00826 double tmp;
00827 if (dy > 0)
00828 {
00829 area.setBottom(area.top());
00830 area.setTop(activeSheet()->topRow(unzoomedValue, tmp));
00831 }
00832 else
00833 {
00834 area.setTop(area.bottom());
00835 area.setBottom(activeSheet()->bottomRow(d->view->doc()->unzoomItY(height()) +
00836 unzoomedValue));
00837 }
00838
00839 activeSheet()->setRegionPaintDirty( area );
00840
00841
00842 d->yOffset = unzoomedValue;
00843 scroll( 0, dy );
00844 vBorderWidget()->scroll( 0, dy );
00845
00846 activeSheet()->enableScrollBarUpdates( true );
00847
00848 d->view->doc()->emitEndOperation( activeSheet()->visibleRect( this ) );
00849 }
00850
00851 void Canvas::slotMaxColumn( int _max_column )
00852 {
00853 int oldValue = horzScrollBar()->maxValue() - horzScrollBar()->value();
00854 double xpos = activeSheet()->dblColumnPos( QMIN( KS_colMax, _max_column + 10 ) ) - xOffset();
00855 double unzoomWidth = d->view->doc()->unzoomItX( width() );
00856
00857
00858 double sizeMaxX = activeSheet()->sizeMaxX();
00859 if ( xpos > sizeMaxX - xOffset() - unzoomWidth )
00860 xpos = sizeMaxX - xOffset() - unzoomWidth;
00861
00862 horzScrollBar()->setRange( 0, d->view->doc()->zoomItX( xpos + xOffset() ) );
00863
00864 if ( activeSheet()->layoutDirection()==Sheet::RightToLeft )
00865 horzScrollBar()->setValue( horzScrollBar()->maxValue() - oldValue );
00866 }
00867
00868 void Canvas::slotMaxRow( int _max_row )
00869 {
00870 double ypos = activeSheet()->dblRowPos( QMIN( KS_rowMax, _max_row + 10 ) ) - yOffset();
00871 double unzoomHeight = d->view->doc()->unzoomItY( height() );
00872
00873
00874 double sizeMaxY = activeSheet()->sizeMaxY();
00875 if ( ypos > sizeMaxY - yOffset() - unzoomHeight )
00876 ypos = sizeMaxY - yOffset() - unzoomHeight;
00877
00878 vertScrollBar()->setRange( 0, d->view->doc()->zoomItY( ypos + yOffset() ) );
00879 }
00880
00881 void Canvas::mouseMoveEvent( QMouseEvent * _ev )
00882 {
00883
00884 if ( (!d->view->koDocument()->isReadWrite()) && (d->mouseAction!=Mark))
00885 return;
00886
00887 if ( d->mousePressed && d->modType != MT_NONE )
00888 {
00889 KoPoint docPoint ( doc()->unzoomPoint( _ev->pos() ) );
00890 docPoint += KoPoint( xOffset(), yOffset() );
00891
00892 if ( d->modType == MT_MOVE )
00893 {
00894 if ( !d->m_isMoving )
00895 {
00896 d->m_moveStartPoint = objectRect( false ).topLeft();
00897 d->m_isMoving = true;
00898 }
00899 moveObjectsByMouse( docPoint, _ev->state() & AltButton || _ev->state() & ControlButton );
00900 }
00901 else if ( d->m_resizeObject )
00902 {
00903 if ( !d->m_isResizing )
00904 d->m_isResizing = true;
00905
00906 bool keepRatio = d->m_resizeObject->isKeepRatio();
00907 if ( _ev->state() & AltButton )
00908 {
00909 keepRatio = true;
00910 }
00911 docPoint = KoPoint( doc()->unzoomPoint( _ev->pos() ) );
00912 resizeObject( d->modType, docPoint, keepRatio );
00913 }
00914 return;
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 if ( d->dragging )
00987 {
00988 return;
00989 }
00990 if ( d->dragStart.x() != -1 )
00991 {
00992 QPoint p ( (int) _ev->pos().x() + (int) xOffset(),
00993 (int) _ev->pos().y() + (int) yOffset() );
00994
00995 if ( ( d->dragStart - p ).manhattanLength() > 4 )
00996 {
00997 d->dragging = true;
00998 startTheDrag();
00999 d->dragStart.setX( -1 );
01000 }
01001 d->dragging = false;
01002 return;
01003 }
01004
01005
01006
01007 Sheet *sheet = activeSheet();
01008 if ( !sheet )
01009 {
01010 return;
01011 }
01012
01013 if ( d->mouseSelectedObject )
01014 {
01015 EmbeddedObject *obj = 0;
01016 QPoint p ( (int) _ev->x(),
01017 (int) _ev->y() );
01018 if ( ( obj = getObject( p, activeSheet() ) ) && obj->isSelected() )
01019 {
01020 KoRect const bound = obj->geometry();
01021 QRect zoomedBound = doc()->zoomRect( KoRect(bound.left(), bound.top(),
01022 bound.width(),
01023 bound.height() ) );
01024 zoomedBound.moveBy( (int)(-xOffset() * doc()->zoomedResolutionX() ), (int)(-yOffset() * doc()->zoomedResolutionY() ));
01025 setCursor( obj->getCursor( p, d->modType, zoomedBound ) );
01026 return;
01027 }
01028 }
01029
01030 double dwidth = d->view->doc()->unzoomItX( width() );
01031 double ev_PosX;
01032 if ( sheet->layoutDirection()==Sheet::RightToLeft )
01033 {
01034 ev_PosX = dwidth - d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01035 }
01036 else
01037 {
01038 ev_PosX = d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01039 }
01040 double ev_PosY = d->view->doc()->unzoomItY( _ev->pos().y() ) + yOffset();
01041
01042
01043 double xpos;
01044 double ypos;
01045 int col = sheet->leftColumn( ev_PosX, xpos );
01046 int row = sheet->topRow( ev_PosY, ypos );
01047
01048
01049 if ( col > KS_colMax || row > KS_rowMax )
01050 {
01051 kdDebug(36001) << "Canvas::mouseMoveEvent: col or row is out of range: "
01052 << "col: " << col << " row: " << row << endl;
01053 return;
01054 }
01055
01056
01057
01058 if (d->mouseAction == ResizeSelection)
01059 {
01060 choice()->update(QPoint(col,row));
01061 return;
01062 }
01063
01064
01065
01066 if (highlightRangeSizeGripAt(ev_PosX,ev_PosY))
01067 {
01068 if ( sheet->layoutDirection()==Sheet::RightToLeft )
01069 setCursor( sizeBDiagCursor );
01070 else
01071 setCursor( sizeFDiagCursor );
01072 return;
01073 }
01074
01075 QRect rct( (d->chooseCell ? choice() : selectionInfo())->lastRange() );
01076
01077 QRect r1;
01078 QRect r2;
01079
01080 double lx = sheet->dblColumnPos( rct.left() );
01081 double rx = sheet->dblColumnPos( rct.right() + 1 );
01082 double ty = sheet->dblRowPos( rct.top() );
01083 double by = sheet->dblRowPos( rct.bottom() + 1 );
01084
01085 r1.setLeft( (int) (lx - 1) );
01086 r1.setTop( (int) (ty - 1) );
01087 r1.setRight( (int) (rx + 1) );
01088 r1.setBottom( (int) (by + 1) );
01089
01090 r2.setLeft( (int) (lx + 1) );
01091 r2.setTop( (int) (ty + 1) );
01092 r2.setRight( (int) (rx - 1) );
01093 r2.setBottom( (int) (by - 1) );
01094
01095
01096 {
01097 Cell *cell = sheet->visibleCellAt( col, row );
01098 QString anchor;
01099 if ( sheet->layoutDirection()==Sheet::RightToLeft )
01100 {
01101 anchor = cell->testAnchor( d->view->doc()->zoomItX( cell->dblWidth() - ev_PosX + xpos ),
01102 d->view->doc()->zoomItY( ev_PosY - ypos ) );
01103 }
01104 else
01105 {
01106 anchor = cell->testAnchor( d->view->doc()->zoomItX( ev_PosX - xpos ),
01107 d->view->doc()->zoomItY( ev_PosY - ypos ) );
01108 }
01109 if ( !anchor.isEmpty() && anchor != d->anchor )
01110 {
01111 setCursor( KCursor::handCursor() );
01112 }
01113
01114 d->anchor = anchor;
01115 }
01116
01117
01118 QRect selectionHandle = d->view->selectionInfo()->selectionHandleArea();
01119 if ( selectionHandle.contains( QPoint( d->view->doc()->zoomItX( ev_PosX ),
01120 d->view->doc()->zoomItY( ev_PosY ) ) ) )
01121 {
01122
01123
01124 col = sheet->leftColumn( ev_PosX - d->view->doc()->unzoomItX( 2 ), xpos );
01125 row = sheet->topRow( ev_PosY - d->view->doc()->unzoomItY( 2 ), ypos );
01126
01127 if ( !sheet->isProtected() )
01128 {
01129 if ( sheet->layoutDirection()==Sheet::RightToLeft )
01130 setCursor( sizeBDiagCursor );
01131 else
01132 setCursor( sizeFDiagCursor );
01133 }
01134 }
01135 else if ( !d->anchor.isEmpty() )
01136 {
01137 if ( !sheet->isProtected() )
01138 setCursor( KCursor::handCursor() );
01139 }
01140 else if ( r1.contains( QPoint( (int) ev_PosX, (int) ev_PosY ) )
01141 && !r2.contains( QPoint( (int) ev_PosX, (int) ev_PosY ) ) )
01142 {
01143 setCursor( KCursor::handCursor() );
01144 }
01145 else if ( d->chooseCell )
01146 {
01147
01148 setCursor( KCursor::crossCursor() );
01149 }
01150 else
01151 {
01152
01153 setCursor( arrowCursor );
01154 }
01155
01156
01157 if ( d->mouseAction == NoAction )
01158 return;
01159
01160
01161 (d->chooseCell ? choice() : selectionInfo())->update(QPoint(col,row));
01162 }
01163
01164 void Canvas::mouseReleaseEvent( QMouseEvent* )
01165 {
01166 if ( d->scrollTimer->isActive() )
01167 d->scrollTimer->stop();
01168
01169 d->mousePressed = false;
01170 d->view->disableAutoScroll();
01171
01172 if ( d->modType != MT_NONE )
01173 {
01174 switch ( d->modType )
01175 {
01176 case MT_MOVE:
01177 {
01178 KoPoint move( objectRect( false ).topLeft() - d->m_moveStartPosMouse );
01179 if ( move != KoPoint( 0, 0 ) )
01180 {
01181 KCommand *cmd= activeSheet()->moveObject( view(), move.x(), move.y() );
01182 if(cmd)
01183 doc()->addCommand( cmd );
01184 } else
01185 {
01186 repaint();
01187 }
01188 d->m_isMoving = false;
01189 break;
01190 }
01191 case MT_RESIZE_UP: case MT_RESIZE_LF: case MT_RESIZE_RT: case MT_RESIZE_LU: case MT_RESIZE_LD: case MT_RESIZE_RU: case MT_RESIZE_RD:
01192 finishResizeObject( i18n("Resize Object") );
01193 break;
01194 case MT_RESIZE_DN:
01195 finishResizeObject( i18n("Resize Object"), false );
01196 break;
01197 default:
01198 break;
01199 }
01200 return;
01201 }
01202
01203 Sheet *sheet = activeSheet();
01204 if ( !sheet )
01205 return;
01206
01207 Selection* selectionInfo = d->view->selectionInfo();
01208 QRect s( selectionInfo->lastRange() );
01209
01210
01211 if ( d->mouseAction == ResizeCell && !sheet->isProtected() )
01212 {
01213 sheet->mergeCells(selectionInfo->lastRange());
01214 d->view->updateEditWidget();
01215 }
01216 else if ( d->mouseAction == AutoFill && !sheet->isProtected() )
01217 {
01218 QRect dest = s;
01219 sheet->autofill( d->autoFillSource, dest );
01220
01221 d->view->updateEditWidget();
01222 }
01223
01224 else if ( d->mouseAction == Mark && !d->chooseCell )
01225 {
01226 d->view->updateEditWidget();
01227 }
01228
01229 d->mouseAction = NoAction;
01230 d->dragging = false;
01231 d->dragStart.setX( -1 );
01232 }
01233
01234 void Canvas::processClickSelectionHandle( QMouseEvent *event )
01235 {
01236
01237 if ( event->button() == LeftButton )
01238 {
01239 d->mouseAction = AutoFill;
01240 d->autoFillSource = selectionInfo()->lastRange();
01241 }
01242
01243
01244 else if ( event->button() == MidButton && selectionInfo()->isSingular())
01245 {
01246 d->mouseAction = ResizeCell;
01247 }
01248
01249 return;
01250 }
01251
01252 void Canvas::processLeftClickAnchor()
01253 {
01254 bool isRefLink = localReferenceAnchor( d->anchor );
01255 bool isLocalLink = (d->anchor.find("file:") == 0);
01256 if ( !isRefLink )
01257 {
01258 QString type=KMimeType::findByURL(d->anchor, 0, isLocalLink)->name();
01259
01260 if ( KRun::isExecutableFile( d->anchor , type ) )
01261 {
01262
01263
01264
01265
01266
01267 QString question = i18n("This link points to the program or script '%1'.\n"
01268 "Malicious programs can harm your computer. Are you sure that you want to run this program?").arg(d->anchor);
01269
01270
01271 int choice = KMessageBox::warningYesNo(this, question, i18n("Open Link?"));
01272 if ( choice != KMessageBox::Yes )
01273 {
01274 return;
01275
01276 }
01277 }
01278
01279 new KRun(d->anchor);
01280 }
01281 else
01282 {
01283 selectionInfo()->initialize(Region(d->view, d->anchor));
01284 }
01285 }
01286
01287 bool Canvas::highlightRangeSizeGripAt(double x, double y)
01288 {
01289 if (!d->chooseCell)
01290 return 0;
01291
01292 Region::ConstIterator end = choice()->constEnd();
01293 for (Region::ConstIterator it = choice()->constBegin(); it != end; ++it)
01294 {
01295
01296 KoRect visibleRect;
01297 sheetAreaToRect((*it)->rect().normalize(), visibleRect);
01298
01299 QPoint bottomRight((int) visibleRect.right(), (int) visibleRect.bottom());
01300 QRect handle( ( (int) bottomRight.x() - 6 ),
01301 ( (int) bottomRight.y() - 6 ),
01302 ( 6 ),
01303 ( 6 ) );
01304
01305 if (handle.contains(QPoint((int) x,(int) y)))
01306 {
01307 return true;
01308 }
01309 }
01310
01311 return false;
01312 }
01313
01314 void Canvas::mousePressEvent( QMouseEvent * _ev )
01315 {
01316 if ( _ev->button() == LeftButton )
01317 {
01318 d->mousePressed = true;
01319 d->view->enableAutoScroll();
01320 }
01321
01322 if ( activeSheet() && _ev->button() == LeftButton)
01323 {
01324 d->m_moveStartPosMouse = objectRect( false ).topLeft();
01325 EmbeddedObject *obj = getObject( _ev->pos(), activeSheet() );
01326
01327 if ( obj )
01328 {
01329
01330 if ( _ev->state() & ControlButton && obj->isSelected() )
01331 deselectObject( obj );
01332 else if ( _ev->state() & ControlButton )
01333 {
01334 if ( d->modType == MT_NONE)
01335 return;
01336
01337 selectObject( obj );
01338 raiseObject( obj );
01339 d->m_moveStartPosMouse = objectRect( false ).topLeft();
01340 }
01341 else
01342 {
01343 if ( d->modType != MT_MOVE || !obj->isSelected() )
01344 deselectAllObjects();
01345
01346 selectObject( obj );
01347
01348 raiseObject( obj );
01349 d->m_moveStartPosMouse = objectRect( false ).topLeft();
01350 }
01351
01352
01353 if ( d->modType != MT_MOVE && d->modType != MT_NONE && !obj->isProtect() )
01354 {
01355 deselectAllObjects();
01356 selectObject( obj );
01357 raiseObject( obj );
01358
01359 d->m_resizeObject = obj;
01360
01361 d->m_ratio = static_cast<double>( obj->geometry().width() ) /
01362 static_cast<double>( obj->geometry().height() );
01363 d->m_rectBeforeResize = obj->geometry();
01364 }
01365
01366 KoPoint docPoint ( doc()->unzoomPoint( _ev->pos() ) );
01367 docPoint += KoPoint( xOffset(), yOffset() );
01368 d->m_origMousePos = docPoint;
01369 d->m_moveStartPosMouse = objectRect( false ).topLeft();
01370 return;
01371 }
01372 else
01373 {
01374 d->modType = MT_NONE;
01375 if ( !( _ev->state() & ShiftButton ) && !( _ev->state() & ControlButton ) )
01376 deselectAllObjects();
01377 }
01378 }
01379
01380
01381
01382 Sheet *sheet = activeSheet();
01383 if ( !sheet )
01384 {
01385 return;
01386 }
01387
01388 double dwidth = d->view->doc()->unzoomItX( width() );
01389 double ev_PosX;
01390 if ( sheet->layoutDirection()==Sheet::RightToLeft )
01391 {
01392 ev_PosX = dwidth - d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01393 }
01394 else
01395 {
01396 ev_PosX = d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01397 }
01398 double ev_PosY = d->view->doc()->unzoomItY( _ev->pos().y() ) + yOffset();
01399
01400
01401 double xpos;
01402 double ypos;
01403 int col = sheet->leftColumn( ev_PosX, xpos );
01404 int row = sheet->topRow( ev_PosY, ypos );
01405
01406 if ( col > KS_colMax || row > KS_rowMax )
01407 {
01408 kdDebug(36001) << "Canvas::mousePressEvent: col or row is out of range: "
01409 << "col: " << col << " row: " << row << endl;
01410 return;
01411 }
01412
01413
01414 if ( col > KS_colMax || row > KS_rowMax )
01415 {
01416 kdDebug(36001) << "Canvas::mousePressEvent: col or row is out of range: "
01417 << "col: " << col << " row: " << row << endl;
01418 return;
01419 }
01420
01421 if (d->chooseCell && highlightRangeSizeGripAt(ev_PosX,ev_PosY))
01422 {
01423 choice()->setActiveElement(QPoint(col,row));
01424 d->mouseAction = ResizeSelection;
01425 return;
01426 }
01427
01428
01429 if ( d->cellEditor && !d->chooseCell )
01430 {
01431 deleteEditor( true );
01432 }
01433
01434 d->scrollTimer->start( 50 );
01435
01436
01437 if ( selectionInfo()->selectionHandleArea().contains( QPoint( d->view->doc()->zoomItX( ev_PosX ),
01438 d->view->doc()->zoomItY( ev_PosY ) ) ) )
01439 {
01440 processClickSelectionHandle( _ev );
01441 return;
01442 }
01443
01444
01445
01446 {
01447
01448 QRect rct( selectionInfo()->lastRange() );
01449
01450 QRect r1;
01451 QRect r2;
01452 {
01453 double lx = sheet->dblColumnPos( rct.left() );
01454 double rx = sheet->dblColumnPos( rct.right() + 1 );
01455 double ty = sheet->dblRowPos( rct.top() );
01456 double by = sheet->dblRowPos( rct.bottom() + 1 );
01457
01458 r1.setLeft( (int) (lx - 1) );
01459 r1.setTop( (int) (ty - 1) );
01460 r1.setRight( (int) (rx + 1) );
01461 r1.setBottom( (int) (by + 1) );
01462
01463 r2.setLeft( (int) (lx + 1) );
01464 r2.setTop( (int) (ty + 1) );
01465 r2.setRight( (int) (rx - 1) );
01466 r2.setBottom( (int) (by - 1) );
01467 }
01468
01469 d->dragStart.setX( -1 );
01470
01471 if ( r1.contains( QPoint( (int) ev_PosX, (int) ev_PosY ) )
01472 && !r2.contains( QPoint( (int) ev_PosX, (int) ev_PosY ) ) )
01473 {
01474 d->dragStart.setX( (int) ev_PosX );
01475 d->dragStart.setY( (int) ev_PosY );
01476
01477 return;
01478 }
01479 }
01480
01481
01482
01483
01484 if ((_ev->state() & ShiftButton) &&
01485 d->view->koDocument()->isReadWrite() &&
01486 !selectionInfo()->isColumnOrRowSelected())
01487 {
01488 (d->chooseCell ? choice() : selectionInfo())->update(QPoint(col,row));
01489 return;
01490 }
01491
01492
01493
01494 Cell *cell = sheet->cellAt( col, row );
01495 if (cell->isPartOfMerged())
01496 {
01497 cell = cell->obscuringCells().first();
01498 col = cell->column();
01499 row = cell->row();
01500 }
01501
01502 switch (_ev->button())
01503 {
01504 case LeftButton:
01505 if (!d->anchor.isEmpty())
01506 {
01507
01508 processLeftClickAnchor();
01509 }
01510 #ifdef NONCONTIGUOUSSELECTION
01511 else if ( _ev->state() & ControlButton )
01512 {
01513 if (d->chooseCell)
01514 {
01515 #if 0 // TODO Stefan: remove for NCS of choices
01516
01517 d->mouseAction = Mark;
01518
01519 choice()->extend(QPoint(col,row), activeSheet());
01520 #endif
01521 }
01522 else
01523 {
01524
01525 d->mouseAction = Mark;
01526
01527 selectionInfo()->extend(QPoint(col,row), activeSheet());
01528 }
01529
01530
01531 }
01532 #endif
01533 else
01534 {
01535
01536 d->mouseAction = Mark;
01537
01538 (d->chooseCell ? choice() : selectionInfo())->initialize(QPoint(col,row), activeSheet());
01539 }
01540 break;
01541 case MidButton:
01542
01543 if ( d->view->koDocument()->isReadWrite() && !sheet->isProtected() )
01544 {
01545 (d->chooseCell ? choice() : selectionInfo())->initialize( QPoint( col, row ), activeSheet() );
01546 sheet->paste(selectionInfo()->lastRange(), true, Paste::Normal,
01547 Paste::OverWrite, false, 0, false, QClipboard::Selection);
01548 sheet->setRegionPaintDirty(*selectionInfo());
01549 }
01550 break;
01551 case RightButton:
01552 if (!selectionInfo()->contains( QPoint( col, row ) ))
01553 {
01554
01555 (d->chooseCell ? choice() : selectionInfo())->initialize(QPoint(col,row), activeSheet());
01556 }
01557 break;
01558 default:
01559 break;
01560 }
01561
01562 scrollToCell(selectionInfo()->marker());
01563 if ( !d->chooseCell )
01564 {
01565 d->view->updateEditWidgetOnPress();
01566 }
01567 updatePosWidget();
01568
01569
01570 if ( _ev->button() == RightButton )
01571 {
01572
01573 QPoint p = mapToGlobal( _ev->pos() );
01574 d->view->openPopupMenu( p );
01575 }
01576 }
01577
01578 void Canvas::startTheDrag()
01579 {
01580 Sheet * sheet = activeSheet();
01581 if ( !sheet )
01582 return;
01583
01584
01585 TextDrag * d = new TextDrag( this );
01586 setCursor( KCursor::handCursor() );
01587
01588 QDomDocument doc = sheet->saveCellRegion(*selectionInfo());
01589
01590
01591 QBuffer buffer;
01592 buffer.open( IO_WriteOnly );
01593 QTextStream str( &buffer );
01594 str.setEncoding( QTextStream::UnicodeUTF8 );
01595 str << doc;
01596 buffer.close();
01597
01598 d->setPlain( sheet->copyAsText( selectionInfo() ) );
01599 d->setKSpread( buffer.buffer() );
01600
01601 d->dragCopy();
01602 setCursor( KCursor::arrowCursor() );
01603 }
01604
01605 void Canvas::mouseDoubleClickEvent( QMouseEvent* _ev)
01606 {
01607
01608 EmbeddedObject *obj;
01609 if ( ( obj = getObject( _ev->pos(), activeSheet() ) ) )
01610 {
01611 switch ( obj->getType() )
01612 {
01613 case OBJECT_KOFFICE_PART: case OBJECT_CHART:
01614 {
01615 dynamic_cast<EmbeddedKOfficeObject*>(obj)->activate( view(), this );
01616 return;
01617 break;
01618 }
01619 default:
01620 {
01621 view()->extraProperties();
01622 return;
01623 break;
01624 }
01625 }
01626 }
01627
01628 if ( d->view->koDocument()->isReadWrite() && activeSheet() )
01629 createEditor(true);
01630 }
01631
01632 void Canvas::wheelEvent( QWheelEvent* _ev )
01633 {
01634 if ( _ev->orientation() == Qt::Vertical )
01635 {
01636 if ( vertScrollBar() )
01637 QApplication::sendEvent( vertScrollBar(), _ev );
01638 }
01639 else if ( horzScrollBar() )
01640 {
01641 QApplication::sendEvent( horzScrollBar(), _ev );
01642 }
01643 }
01644
01645 void Canvas::paintEvent( QPaintEvent* _ev )
01646 {
01647 if ( d->view->doc()->isLoading() )
01648 return;
01649
01650 Sheet* sheet = activeSheet();
01651 if ( !sheet )
01652 return;
01653
01654
01655
01656 double dwidth = d->view->doc()->unzoomItX( width() );
01657 KoRect rect = d->view->doc()->unzoomRect( _ev->rect() & QWidget::rect() );
01658 if ( sheet->layoutDirection()==Sheet::RightToLeft )
01659 rect.moveBy( -xOffset(), yOffset() );
01660 else
01661 rect.moveBy( xOffset(), yOffset() );
01662
01663 KoPoint tl = rect.topLeft();
01664 KoPoint br = rect.bottomRight();
01665
01666 double tmp;
01667 int left_col;
01668 int right_col;
01669
01670
01671 if ( sheet->layoutDirection()==Sheet::RightToLeft )
01672 {
01673 right_col = sheet->leftColumn( dwidth - tl.x(), tmp );
01674 left_col = sheet->rightColumn( dwidth - br.x() + 1.0 );
01675 }
01676 else
01677 {
01678 left_col = sheet->leftColumn( tl.x(), tmp );
01679 right_col = sheet->rightColumn( br.x() + 1.0 );
01680 }
01681 int top_row = sheet->topRow( tl.y(), tmp );
01682 int bottom_row = sheet->bottomRow( br.y() + 1.0 );
01683
01684 QRect vr( QPoint(left_col, top_row),
01685 QPoint(right_col, bottom_row) );
01686 d->view->doc()->emitBeginOperation( false );
01687 sheet->setRegionPaintDirty( vr );
01688 d->view->doc()->emitEndOperation( vr );
01689 }
01690
01691 void Canvas::focusInEvent( QFocusEvent* )
01692 {
01693 if ( !d->cellEditor )
01694 return;
01695
01696
01697
01698
01699
01700
01701 if ( lastEditorWithFocus() == EditWidget )
01702 {
01703 d->editWidget->setFocus();
01704
01705 return;
01706 }
01707
01708
01709 d->cellEditor->setFocus();
01710 }
01711
01712 void Canvas::focusOutEvent( QFocusEvent* )
01713 {
01714 if ( d->scrollTimer->isActive() )
01715 d->scrollTimer->stop();
01716 d->mousePressed = false;
01717 d->view->disableAutoScroll();
01718 }
01719
01720 void Canvas::dragMoveEvent( QDragMoveEvent * _ev )
01721 {
01722 Sheet * sheet = activeSheet();
01723 if ( !sheet )
01724 {
01725 _ev->ignore();
01726 return;
01727 }
01728
01729 _ev->accept( TextDrag::canDecode( _ev ) );
01730
01731 double dwidth = d->view->doc()->unzoomItX( width() );
01732 double xpos = sheet->dblColumnPos( selectionInfo()->lastRange().left() );
01733 double ypos = sheet->dblRowPos( selectionInfo()->lastRange().top() );
01734 double width = sheet->columnFormat( selectionInfo()->lastRange().left() )->dblWidth( this );
01735 double height = sheet->rowFormat( selectionInfo()->lastRange().top() )->dblHeight( this );
01736
01737 QRect r1 ((int) xpos - 1, (int) ypos - 1, (int) width + 3, (int) height + 3);
01738
01739 double ev_PosX;
01740 if (sheet->layoutDirection()==Sheet::RightToLeft)
01741 ev_PosX = dwidth - d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01742 else
01743 ev_PosX = d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01744
01745 double ev_PosY = d->view->doc()->unzoomItY( _ev->pos().y() ) + yOffset();
01746
01747 if ( r1.contains( QPoint ((int) ev_PosX, (int) ev_PosY) ) )
01748 _ev->ignore( r1 );
01749 }
01750
01751 void Canvas::dragLeaveEvent( QDragLeaveEvent * )
01752 {
01753 if ( d->scrollTimer->isActive() )
01754 d->scrollTimer->stop();
01755 }
01756
01757 void Canvas::dropEvent( QDropEvent * _ev )
01758 {
01759 d->dragging = false;
01760 if ( d->scrollTimer->isActive() )
01761 d->scrollTimer->stop();
01762 Sheet * sheet = activeSheet();
01763 if ( !sheet || sheet->isProtected() )
01764 {
01765 _ev->ignore();
01766 return;
01767 }
01768
01769 double dwidth = d->view->doc()->unzoomItX( width() );
01770 double xpos = sheet->dblColumnPos( selectionInfo()->lastRange().left() );
01771 double ypos = sheet->dblRowPos( selectionInfo()->lastRange().top() );
01772 double width = sheet->columnFormat( selectionInfo()->lastRange().left() )->dblWidth( this );
01773 double height = sheet->rowFormat( selectionInfo()->lastRange().top() )->dblHeight( this );
01774
01775 QRect r1 ((int) xpos - 1, (int) ypos - 1, (int) width + 3, (int) height + 3);
01776
01777 double ev_PosX;
01778 if (sheet->layoutDirection()==Sheet::RightToLeft)
01779 ev_PosX = dwidth - d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01780 else
01781 ev_PosX = d->view->doc()->unzoomItX( _ev->pos().x() ) + xOffset();
01782
01783 double ev_PosY = d->view->doc()->unzoomItY( _ev->pos().y() ) + yOffset();
01784
01785 if ( r1.contains( QPoint ((int) ev_PosX, (int) ev_PosY) ) )
01786 {
01787 _ev->ignore( );
01788 return;
01789 }
01790 else
01791 _ev->accept( );
01792
01793 double tmp;
01794 int col = sheet->leftColumn( ev_PosX, tmp );
01795 int row = sheet->topRow( ev_PosY, tmp );
01796
01797 if ( !TextDrag::canDecode( _ev ) )
01798 {
01799 _ev->ignore();
01800 return;
01801 }
01802
01803 QByteArray b;
01804
01805 bool makeUndo = true;
01806
01807 if ( _ev->provides( TextDrag::selectionMimeType() ) )
01808 {
01809 if ( TextDrag::target() == _ev->source() )
01810 {
01811 if ( !d->view->doc()->undoLocked() )
01812 {
01813 UndoDragDrop * undo
01814 = new UndoDragDrop(d->view->doc(), sheet, *selectionInfo(),
01815 QRect(col, row,
01816 selectionInfo()->boundingRect().width(),
01817 selectionInfo()->boundingRect().height()));
01818 d->view->doc()->addCommand( undo );
01819 makeUndo = false;
01820 }
01821 sheet->deleteSelection( selectionInfo(), false );
01822 }
01823
01824
01825 b = _ev->encodedData( TextDrag::selectionMimeType() );
01826 sheet->paste( b, QRect( col, row, 1, 1 ), makeUndo );
01827
01828 if ( _ev->source() == this )
01829 _ev->acceptAction();
01830 _ev->accept();
01831 }
01832 else
01833 {
01834 QString text;
01835 if ( !QTextDrag::decode( _ev, text ) )
01836 {
01837 _ev->ignore();
01838 return;
01839 }
01840
01841
01842
01843 sheet->pasteTextPlain( text, QRect( col, row, 1, 1 ) );
01844 _ev->accept();
01845 if ( _ev->source() == this )
01846 _ev->acceptAction();
01847
01848 return;
01849 }
01850 }
01851
01852 void Canvas::resizeEvent( QResizeEvent* _ev )
01853 {
01854 if (!activeSheet())
01855 return;
01856
01857
01858 double ev_Width = d->view->doc()->unzoomItX( _ev->size().width() );
01859 double ev_Height = d->view->doc()->unzoomItY( _ev->size().height() );
01860
01861
01862
01863
01864 if ( activeSheet() && activeSheet()->layoutDirection()==Sheet::RightToLeft && !QApplication::reverseLayout() )
01865 {
01866 int dx = _ev->size().width() - _ev->oldSize().width();
01867 scroll(dx, 0);
01868 }
01869 else if ( activeSheet() && activeSheet()->layoutDirection()==Sheet::LeftToRight && QApplication::reverseLayout() )
01870 {
01871 int dx = _ev->size().width() - _ev->oldSize().width();
01872 scroll(-dx, 0);
01873 }
01874
01875
01876 if ( _ev->size().width() > _ev->oldSize().width() )
01877 {
01878 int oldValue = horzScrollBar()->maxValue() - horzScrollBar()->value();
01879
01880 if ( ( xOffset() + ev_Width ) >
01881 d->view->doc()->zoomItX( activeSheet()->sizeMaxX() ) )
01882 {
01883 horzScrollBar()->setRange( 0, d->view->doc()->zoomItX( activeSheet()->sizeMaxX() - ev_Width ) );
01884 if ( activeSheet()->layoutDirection()==Sheet::RightToLeft )
01885 horzScrollBar()->setValue( horzScrollBar()->maxValue() - oldValue );
01886 }
01887 }
01888
01889 else if ( _ev->size().width() < _ev->oldSize().width() )
01890 {
01891 int oldValue = horzScrollBar()->maxValue() - horzScrollBar()->value();
01892
01893 if ( horzScrollBar()->maxValue() ==
01894 int( d->view->doc()->zoomItX( activeSheet()->sizeMaxX() ) - ev_Width ) )
01895 {
01896 horzScrollBar()->setRange( 0, d->view->doc()->zoomItX( activeSheet()->sizeMaxX() - ev_Width ) );
01897 if ( activeSheet()->layoutDirection()==Sheet::RightToLeft )
01898 horzScrollBar()->setValue( horzScrollBar()->maxValue() - oldValue );
01899 }
01900 }
01901
01902
01903 if ( _ev->size().height() > _ev->oldSize().height() )
01904 {
01905 if ( ( yOffset() + ev_Height ) >
01906 d->view->doc()->zoomItY( activeSheet()->sizeMaxY() ) )
01907 {
01908 vertScrollBar()->setRange( 0, d->view->doc()->zoomItY( activeSheet()->sizeMaxY() - ev_Height ) );
01909 }
01910 }
01911
01912 else if ( _ev->size().height() < _ev->oldSize().height() )
01913 {
01914 if ( vertScrollBar()->maxValue() ==
01915 int( d->view->doc()->zoomItY( activeSheet()->sizeMaxY() ) - ev_Height ) )
01916 {
01917 vertScrollBar()->setRange( 0, d->view->doc()->zoomItY( activeSheet()->sizeMaxY() - ev_Height ) );
01918 }
01919 }
01920 }
01921
01922 QPoint Canvas::cursorPos()
01923 {
01924 QPoint cursor;
01925 if (d->chooseCell && !choice()->isEmpty())
01926 cursor = choice()->cursor();
01927 else
01928 cursor = selectionInfo()->cursor();
01929
01930 return cursor;
01931 }
01932
01933 QRect Canvas::moveDirection( KSpread::MoveTo direction, bool extendSelection )
01934 {
01935 kdDebug(36001) << "Canvas::moveDirection" << endl;
01936
01937 QPoint destination;
01938 QPoint cursor = cursorPos();
01939
01940 QPoint cellCorner = cursor;
01941 Cell* cell = activeSheet()->cellAt(cursor.x(), cursor.y());
01942
01943
01944
01945
01946 if (cell->isPartOfMerged())
01947 {
01948 cell = cell->obscuringCells().first();
01949 cellCorner = QPoint(cell->column(), cell->row());
01950 }
01951
01952
01953 int offset = 0;
01954 RowFormat *rl = NULL;
01955 ColumnFormat *cl = NULL;
01956 switch (direction)
01957
01958
01959
01960
01961
01962 {
01963 case Bottom:
01964 offset = cell->mergedYCells() - (cursor.y() - cellCorner.y()) + 1;
01965 rl = activeSheet()->rowFormat( cursor.y() + offset );
01966 while ( ((cursor.y() + offset) <= KS_rowMax) && rl->isHide())
01967 {
01968 offset++;
01969 rl = activeSheet()->rowFormat( cursor.y() + offset );
01970 }
01971
01972 destination = QPoint(cursor.x(), QMIN(cursor.y() + offset, KS_rowMax));
01973 break;
01974 case Top:
01975 offset = (cellCorner.y() - cursor.y()) - 1;
01976 rl = activeSheet()->rowFormat( cursor.y() + offset );
01977 while ( ((cursor.y() + offset) >= 1) && rl->isHide())
01978 {
01979 offset--;
01980 rl = activeSheet()->rowFormat( cursor.y() + offset );
01981 }
01982 destination = QPoint(cursor.x(), QMAX(cursor.y() + offset, 1));
01983 break;
01984 case Left:
01985 offset = (cellCorner.x() - cursor.x()) - 1;
01986 cl = activeSheet()->columnFormat( cursor.x() + offset );
01987 while ( ((cursor.x() + offset) >= 1) && cl->isHide())
01988 {
01989 offset--;
01990 cl = activeSheet()->columnFormat( cursor.x() + offset );
01991 }
01992 destination = QPoint(QMAX(cursor.x() + offset, 1), cursor.y());
01993 break;
01994 case Right:
01995 offset = cell->mergedXCells() - (cursor.x() - cellCorner.x()) + 1;
01996 cl = activeSheet()->columnFormat( cursor.x() + offset );
01997 while ( ((cursor.x() + offset) <= KS_colMax) && cl->isHide())
01998 {
01999 offset++;
02000 cl = activeSheet()->columnFormat( cursor.x() + offset );
02001 }
02002 destination = QPoint(QMIN(cursor.x() + offset, KS_colMax), cursor.y());
02003 break;
02004 case BottomFirst:
02005 offset = cell->mergedYCells() - (cursor.y() - cellCorner.y()) + 1;
02006 rl = activeSheet()->rowFormat( cursor.y() + offset );
02007 while ( ((cursor.y() + offset) <= KS_rowMax) && rl->isHide())
02008 {
02009 ++offset;
02010 rl = activeSheet()->rowFormat( cursor.y() + offset );
02011 }
02012
02013 destination = QPoint( 1, QMIN( cursor.y() + offset, KS_rowMax ) );
02014 break;
02015 }
02016
02017 if (extendSelection)
02018 {
02019 (d->chooseCell ? choice() : selectionInfo())->update(destination);
02020 }
02021 else
02022 {
02023 (d->chooseCell ? choice() : selectionInfo())->initialize(destination, activeSheet());
02024 }
02025 d->view->updateEditWidget();
02026
02027 return QRect( cursor, destination );
02028 }
02029
02030 void Canvas::processEnterKey(QKeyEvent* event)
02031 {
02032
02033 bool array = (event->state() & Qt::AltButton) &&
02034 (event->state() & Qt::ControlButton);
02035
02036
02037 if (!d->chooseCell)
02038 {
02039 deleteEditor(true, array);
02040 }
02041
02042
02043
02044
02045 KSpread::MoveTo direction = d->view->doc()->getMoveToValue();
02046
02047
02048 if (event->state() & Qt::ShiftButton)
02049 {
02050 switch( direction )
02051 {
02052 case Bottom:
02053 direction = Top;
02054 break;
02055 case Top:
02056 direction = Bottom;
02057 break;
02058 case Left:
02059 direction = Right;
02060 break;
02061 case Right:
02062 direction = Left;
02063 break;
02064 case BottomFirst:
02065 direction = BottomFirst;
02066 break;
02067 }
02068 }
02069
02070
02071
02072
02073 QRect r( moveDirection( direction, false ) );
02074 d->view->doc()->emitEndOperation( r );
02075 }
02076
02077 void Canvas::processArrowKey( QKeyEvent *event)
02078 {
02079
02080
02081
02082
02083
02084 if (!d->chooseCell)
02085 {
02086 deleteEditor( true );
02087 }
02088
02089 KSpread::MoveTo direction = Bottom;
02090 bool makingSelection = event->state() & ShiftButton;
02091
02092 switch (event->key())
02093 {
02094 case Key_Down:
02095 direction = Bottom;
02096 break;
02097 case Key_Up:
02098 direction = Top;
02099 break;
02100 case Key_Left:
02101 if (activeSheet()->layoutDirection()==Sheet::RightToLeft)
02102 direction = Right;
02103 else
02104 direction = Left;
02105 break;
02106 case Key_Right:
02107 if (activeSheet()->layoutDirection()==Sheet::RightToLeft)
02108 direction = Left;
02109 else
02110 direction = Right;
02111 break;
02112 case Key_Tab:
02113 direction = Right;
02114 break;
02115 case Key_Backtab:
02116
02117 direction = Left;
02118 makingSelection = false;
02119 break;
02120 default:
02121 Q_ASSERT(false);
02122 break;
02123 }
02124
02125 QRect r( moveDirection( direction, makingSelection ) );
02126 d->view->doc()->emitEndOperation( r );
02127 }
02128
02129 void Canvas::processEscapeKey(QKeyEvent * event)
02130 {
02131 if ( d->cellEditor )
02132 deleteEditor( false );
02133
02134 if ( view()->isInsertingObject() )
02135 {
02136 view()->resetInsertHandle();
02137 setCursor( arrowCursor );
02138 return;
02139 }
02140
02141 event->accept();
02142 QPoint cursor = cursorPos();
02143
02144 d->view->doc()->emitEndOperation( QRect( cursor, cursor ) );
02145
02146 if ( d->mousePressed )
02147 {
02148 switch (d->modType)
02149 {
02150 case MT_RESIZE_UP:
02151 case MT_RESIZE_DN:
02152 case MT_RESIZE_LF:
02153 case MT_RESIZE_RT:
02154 case MT_RESIZE_LU:
02155 case MT_RESIZE_LD:
02156 case MT_RESIZE_RU:
02157 case MT_RESIZE_RD:
02158 {
02159 QRect oldBoundingRect = doc()->zoomRect( d->m_resizeObject->geometry());
02160 d->m_resizeObject->setGeometry( d->m_rectBeforeResize );
02161 oldBoundingRect.moveBy( (int)( -xOffset()*doc()->zoomedResolutionX() ) ,
02162 (int)( -yOffset() * doc()->zoomedResolutionY()) );
02163
02164 activeSheet()->setRegionPaintDirty( oldBoundingRect );
02165 repaint( oldBoundingRect );
02166 repaintObject( d->m_resizeObject );
02167 d->m_ratio = 0.0;
02168 d->m_resizeObject = 0;
02169 d->m_isResizing = false;
02170 view()->disableAutoScroll();
02171 d->mousePressed = false;
02172 d->modType = MT_NONE;
02173 break;
02174 }
02175 case MT_MOVE:
02176 {
02177 if ( d->m_isMoving )
02178 {
02179 KoPoint move( d->m_moveStartPoint - objectRect( false ).topLeft() );
02180 activeSheet()->moveObject( view(), move, false );
02181 view()->disableAutoScroll();
02182 d->mousePressed = false;
02183 d->modType = MT_NONE;
02184 d->m_isMoving = false;
02185 update();
02186 }
02187 break;
02188 }
02189 default:
02190 break;
02191 }
02192 }
02193 }
02194
02195 bool Canvas::processHomeKey(QKeyEvent* event)
02196 {
02197 bool makingSelection = event->state() & ShiftButton;
02198 Sheet* sheet = activeSheet();
02199
02200 if ( d->cellEditor )
02201
02202 {
02203 QApplication::sendEvent( d->editWidget, event );
02204 return false;
02205 }
02206 else
02207 {
02208 QPoint destination;
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219 if (event->state() & ControlButton)
02220 {
02221
02222 destination = QPoint( 1, 1 );
02223 }
02224 else
02225 {
02226 QPoint marker = d->chooseCell ? choice()->marker() : selectionInfo()->marker();
02227
02228 Cell * cell = sheet->getFirstCellRow(marker.y());
02229 while (cell != NULL && cell->column() < marker.x() && cell->isEmpty())
02230 {
02231 cell = sheet->getNextCellRight(cell->column(), cell->row());
02232 }
02233
02234 int col = ( cell ? cell->column() : 1 );
02235 if ( col == marker.x())
02236 col = 1;
02237 destination = QPoint(col, marker.y());
02238 }
02239
02240 if ( selectionInfo()->marker() == destination )
02241 {
02242 d->view->doc()->emitEndOperation( QRect( destination, destination ) );
02243 return false;
02244 }
02245
02246 if (makingSelection)
02247 {
02248 (d->chooseCell ? choice() : selectionInfo())->update(destination);
02249 }
02250 else
02251 {
02252 (d->chooseCell ? choice() : selectionInfo())->initialize(destination, activeSheet());
02253 }
02254 }
02255 return true;
02256 }
02257
02258 bool Canvas::processEndKey( QKeyEvent *event )
02259 {
02260 bool makingSelection = event->state() & ShiftButton;
02261 Sheet* sheet = activeSheet();
02262 Cell* cell = NULL;
02263 QPoint marker = d->chooseCell ? choice()->marker() : selectionInfo()->marker();
02264
02265
02266
02267 if ( d->cellEditor )
02268 {
02269 QApplication::sendEvent( d->editWidget, event );
02270 d->view->doc()->emitEndOperation( QRect( marker, marker ) );
02271 return false;
02272 }
02273 else
02274 {
02275 int col = 1;
02276
02277 cell = sheet->getLastCellRow(marker.y());
02278 while (cell != NULL && cell->column() > markerColumn() && cell->isEmpty())
02279 {
02280 cell = sheet->getNextCellLeft(cell->column(), cell->row());
02281 }
02282
02283 col = (cell == NULL) ? KS_colMax : cell->column();
02284
02285 QPoint destination( col, marker.y() );
02286 if ( destination == marker )
02287 {
02288 d->view->doc()->emitEndOperation( QRect( destination, destination ) );
02289 return false;
02290 }
02291
02292 if (makingSelection)
02293 {
02294 (d->chooseCell ? choice() : selectionInfo())->update(destination);
02295 }
02296 else
02297 {
02298 (d->chooseCell ? choice() : selectionInfo())->initialize(destination, activeSheet());
02299 }
02300 }
02301 return true;
02302 }
02303
02304 bool Canvas::processPriorKey(QKeyEvent *event)
02305 {
02306 bool makingSelection = event->state() & ShiftButton;
02307 if (!d->chooseCell)
02308 {
02309 deleteEditor( true );
02310 }
02311
02312 QPoint marker = d->chooseCell ? choice()->marker() : selectionInfo()->marker();
02313
02314 QPoint destination(marker.x(), QMAX(1, marker.y() - 10));
02315 if ( destination == marker )
02316 {
02317 d->view->doc()->emitEndOperation( QRect( destination, destination ) );
02318 return false;
02319 }
02320
02321 if (makingSelection)
02322 {
02323 (d->chooseCell ? choice() : selectionInfo())->update(destination);
02324 }
02325 else
02326 {
02327 (d->chooseCell ? choice() : selectionInfo())->initialize(destination, activeSheet());
02328 }
02329 return true;
02330 }
02331
02332 bool Canvas::processNextKey(QKeyEvent *event)
02333 {
02334 bool makingSelection = event->state() & ShiftButton;
02335
02336 if (!d->chooseCell)
02337 {
02338 deleteEditor( true );
02339 }
02340
02341 QPoint marker = d->chooseCell ? choice()->marker() : selectionInfo()->marker();
02342 QPoint destination(marker.x(), QMAX(1, marker.y() + 10));
02343
02344 if ( marker == destination )
02345 {
02346 d->view->doc()->emitEndOperation( QRect( destination, destination ) );
02347 return false;
02348 }
02349
02350 if (makingSelection)
02351 {
02352 (d->chooseCell ? choice() : selectionInfo())->update(destination);
02353 }
02354 else
02355 {
02356 (d->chooseCell ? choice() : selectionInfo())->initialize(destination, activeSheet());
02357 }
02358 return true;
02359 }
02360
02361 void Canvas::processDeleteKey(QKeyEvent* )
02362 {
02363 if ( isObjectSelected() )
02364 {
02365 d->view->doc()->emitEndOperation( activeSheet()->visibleRect( this ) );
02366 d->view->deleteSelectedObjects();
02367 return;
02368 }
02369
02370 activeSheet()->clearTextSelection( selectionInfo() );
02371 d->editWidget->setText( "" );
02372
02373 QPoint cursor = cursorPos();
02374
02375 d->view->doc()->emitEndOperation( QRect( cursor, cursor ) );
02376 return;
02377 }
02378
02379 void Canvas::processF2Key(QKeyEvent* )
02380 {
02381 d->editWidget->setFocus();
02382 if ( d->cellEditor )
02383 d->editWidget->setCursorPosition( d->cellEditor->cursorPosition() - 1 );
02384 d->editWidget->cursorForward( false );
02385
02386
02387 QPoint cursor = cursorPos();
02388
02389 d->view->doc()->emitEndOperation( QRect( cursor, cursor ) );
02390 return;
02391 }
02392
02393 void Canvas::processF4Key(QKeyEvent* event)
02394 {
02395
02396
02397 if ( d->cellEditor )
02398 {
02399 d->cellEditor->handleKeyPressEvent( event );
02400
02401 d->editWidget->setCursorPosition( d->cellEditor->cursorPosition() );
02402 }
02403 QPoint cursor = cursorPos();
02404
02405 d->view->doc()->emitEndOperation( QRect( cursor, cursor ) );
02406 return;
02407 }
02408
02409 void Canvas::processOtherKey(QKeyEvent *event)
02410 {
02411
02412 if ( event->text().isEmpty() || !d->view->koDocument()->isReadWrite()
02413 || !activeSheet() || activeSheet()->isProtected() )
02414 {
02415 event->accept();
02416 }
02417 else
02418 {
02419 if ( !d->cellEditor && !d->chooseCell )
02420 {
02421
02422 createEditor( CellEditor );
02423 d->cellEditor->handleKeyPressEvent( event );
02424 }
02425 else if ( d->cellEditor )
02426 d->cellEditor->handleKeyPressEvent( event );
02427 }
02428
02429 QPoint cursor = cursorPos();
02430
02431 d->view->doc()->emitEndOperation( QRect( cursor, cursor ) );
02432
02433 return;
02434 }
02435
02436 bool Canvas::processControlArrowKey( QKeyEvent *event )
02437 {
02438 bool makingSelection = event->state() & ShiftButton;
02439
02440 Sheet* sheet = activeSheet();
02441 Cell* cell = NULL;
02442 Cell* lastCell;
02443 QPoint destination;
02444 bool searchThroughEmpty = true;
02445 int row;
02446 int col;
02447
02448 QPoint marker = d->chooseCell ? choice()->marker() : selectionInfo()->marker();
02449
02450
02451
02452 switch ( event->key() )
02453 {
02454
02455 case Key_Up:
02456
02457 cell = sheet->cellAt( marker.x(), marker.y() );
02458 if ( (cell != NULL) && (!cell->isEmpty()) && (marker.y() != 1))
02459 {
02460 lastCell = cell;
02461 row = marker.y()-1;
02462 cell = sheet->cellAt(cell->column(), row);
02463 while ((cell != NULL) && (row > 0) && (!cell->isEmpty()) )
02464 {
02465 if (!(sheet->rowFormat(cell->row())->isHide()))
02466 {
02467 lastCell = cell;
02468 searchThroughEmpty = false;
02469 }
02470 row--;
02471 if ( row > 0 )
02472 cell = sheet->cellAt(cell->column(), row);
02473 }
02474 cell = lastCell;
02475 }
02476 if (searchThroughEmpty)
02477 {
02478 cell = sheet->getNextCellUp(marker.x(), marker.y());
02479
02480 while ((cell != NULL) &&
02481 (cell->isEmpty() || (sheet->rowFormat(cell->row())->isHide())))
02482 {
02483 cell = sheet->getNextCellUp(cell->column(), cell->row());
02484 }
02485 }
02486
02487 if (cell == NULL)
02488 row = 1;
02489 else
02490 row = cell->row();
02491
02492 while ( sheet->rowFormat(row)->isHide() )
02493 {
02494 row++;
02495 }
02496
02497 destination.setX(marker.x());
02498 destination.setY(row);
02499 break;
02500
02501
02502 case Key_Down:
02503
02504 cell = sheet->cellAt( marker.x(), marker.y() );
02505 if ( (cell != NULL) && (!cell->isEmpty()) && (marker.y() != KS_rowMax))
02506 {
02507 lastCell = cell;
02508 row = marker.y()+1;
02509 cell = sheet->cellAt(cell->column(), row);
02510 while ((cell != NULL) && (row < KS_rowMax) && (!cell->isEmpty()) )
02511 {
02512 if (!(sheet->rowFormat(cell->row())->isHide()))
02513 {
02514 lastCell = cell;
02515 searchThroughEmpty = false;
02516 }
02517 row++;
02518 cell = sheet->cellAt(cell->column(), row);
02519 }
02520 cell = lastCell;
02521 }
02522 if (searchThroughEmpty)
02523 {
02524 cell = sheet->getNextCellDown(marker.x(), marker.y());
02525
02526 while ((cell != NULL) &&
02527 (cell->isEmpty() || (sheet->rowFormat(cell->row())->isHide())))
02528 {
02529 cell = sheet->getNextCellDown(cell->column(), cell->row());
02530 }
02531 }
02532
02533 if (cell == NULL)
02534 row = marker.y();
02535 else
02536 row = cell->row();
02537
02538 while ( sheet->rowFormat(row)->isHide() )
02539 {
02540 row--;
02541 }
02542
02543 destination.setX(marker.x());
02544 destination.setY(row);
02545 break;
02546
02547
02548 case Key_Left:
02549
02550 if ( sheet->layoutDirection()==Sheet::RightToLeft )
02551 {
02552 cell = sheet->cellAt( marker.x(), marker.y() );
02553 if ( (cell != NULL) && (!cell->isEmpty()) && (marker.x() != KS_colMax))
02554 {
02555 lastCell = cell;
02556 col = marker.x()+1;
02557 cell = sheet->cellAt(col, cell->row());
02558 while ((cell != NULL) && (col < KS_colMax) && (!cell->isEmpty()) )
02559 {
02560 if (!(sheet->columnFormat(cell->column())->isHide()))
02561 {
02562 lastCell = cell;
02563 searchThroughEmpty = false;
02564 }
02565 col++;
02566 cell = sheet->cellAt(col, cell->row());
02567 }
02568 cell = lastCell;
02569 }
02570 if (searchThroughEmpty)
02571 {
02572 cell = sheet->getNextCellRight(marker.x(), marker.y());
02573
02574 while ((cell != NULL) &&
02575 (cell->isEmpty() || (sheet->columnFormat(cell->column())->isHide())))
02576 {
02577 cell = sheet->getNextCellRight(cell->column(), cell->row());
02578 }
02579 }
02580
02581 if (cell == NULL)
02582 col = marker.x();
02583 else
02584 col = cell->column();
02585
02586 while ( sheet->columnFormat(col)->isHide() )
02587 {
02588 col--;
02589 }
02590
02591 destination.setX(col);
02592 destination.setY(marker.y());
02593 }
02594 else
02595 {
02596 cell = sheet->cellAt( marker.x(), marker.y() );
02597 if ( (cell != NULL) && (!cell->isEmpty()) && (marker.x() != 1))
02598 {
02599 lastCell = cell;
02600 col = marker.x()-1;
02601 cell = sheet->cellAt(col, cell->row());
02602 while ((cell != NULL) && (col > 0) && (!cell->isEmpty()) )
02603 {
02604 if (!(sheet->columnFormat(cell->column())->isHide()))
02605 {
02606 lastCell = cell;
02607 searchThroughEmpty = false;
02608 }
02609 col--;
02610 if ( col > 0 )
02611 cell = sheet->cellAt(col, cell->row());
02612 }
02613 cell = lastCell;
02614 }
02615 if (searchThroughEmpty)
02616 {
02617 cell = sheet->getNextCellLeft(marker.x(), marker.y());
02618
02619 while ((cell != NULL) &&
02620 (cell->isEmpty() || (sheet->columnFormat(cell->column())->isHide())))
02621 {
02622 cell = sheet->getNextCellLeft(cell->column(), cell->row());
02623 }
02624 }
02625
02626 if (cell == NULL)
02627 col = 1;
02628 else
02629 col = cell->column();
02630
02631 while ( sheet->columnFormat(col)->isHide() )
02632 {
02633 col++;
02634 }
02635
02636 destination.setX(col);
02637 destination.setY(marker.y());
02638 }
02639 break;
02640
02641
02642 case Key_Right:
02643
02644 if ( sheet->layoutDirection()==Sheet::RightToLeft )
02645 {
02646 cell = sheet->cellAt( marker.x(), marker.y() );
02647 if ( (cell != NULL) && (!cell->isEmpty()) && (marker.x() != 1))
02648 {
02649 lastCell = cell;
02650 col = marker.x()-1;
02651 cell = sheet->cellAt(col, cell->row());
02652 while ((cell != NULL) && (col > 0) && (!cell->isEmpty()) )
02653 {
02654 if (!(sheet->columnFormat(cell->column())->isHide()))
02655 {
02656 lastCell = cell;
02657 searchThroughEmpty = false;
02658 }
02659 col--;
02660 if ( col > 0 )
02661 cell = sheet->cellAt(col, cell->row());
02662 }
02663 cell = lastCell;
02664 }
02665 if (searchThroughEmpty)
02666 {
02667 cell = sheet->getNextCellLeft(marker.x(), marker.y());
02668
02669 while ((cell != NULL) &&
02670 (cell->isEmpty() || (sheet->columnFormat(cell->column())->isHide())))
02671 {
02672 cell = sheet->getNextCellLeft(cell->column(), cell->row());
02673 }
02674 }
02675
02676 if (cell == NULL)
02677 col = 1;
02678 else
02679 col = cell->column();
02680
02681 while ( sheet->columnFormat(col)->isHide() )
02682 {
02683 col++;
02684 }
02685
02686 destination.setX(col);
02687 destination.setY(marker.y());
02688 }
02689 else
02690 {
02691 cell = sheet->cellAt( marker.x(), marker.y() );
02692 if ( (cell != NULL) && (!cell->isEmpty()) && (marker.x() != KS_colMax))
02693 {
02694 lastCell = cell;
02695 col = marker.x()+1;
02696 cell = sheet->cellAt(col, cell->row());
02697 while ((cell != NULL) && (col < KS_colMax) && (!cell->isEmpty()) )
02698 {
02699 if (!(sheet->columnFormat(cell->column())->isHide()))
02700 {
02701 lastCell = cell;
02702 searchThroughEmpty = false;
02703 }
02704 col++;
02705 cell = sheet->cellAt(col, cell->row());
02706 }
02707 cell = lastCell;
02708 }
02709 if (searchThroughEmpty)
02710 {
02711 cell = sheet->getNextCellRight(marker.x(), marker.y());
02712
02713 while ((cell != NULL) &&
02714 (cell->isEmpty() || (sheet->columnFormat(cell->column())->isHide())))
02715 {
02716 cell = sheet->getNextCellRight(cell->column(), cell->row());
02717 }
02718 }
02719
02720 if (cell == NULL)
02721 col = marker.x();
02722 else
02723 col = cell->column();
02724
02725 while ( sheet->columnFormat(col)->isHide() )
02726 {
02727 col--;
02728 }
02729
02730 destination.setX(col);
02731 destination.setY(marker.y());
02732 }
02733 break;
02734
02735 }
02736
02737 if ( marker == destination )
02738 {
02739 d->view->doc()->emitEndOperation( QRect( destination, destination ) );
02740 return false;
02741 }
02742
02743 if (makingSelection)
02744 {
02745 (d->chooseCell ? choice() : selectionInfo())->update(destination);
02746 }
02747 else
02748 {
02749 (d->chooseCell ? choice() : selectionInfo())->initialize(destination, activeSheet());
02750 }
02751 return true;
02752 }
02753
02754
02755 void Canvas::keyPressEvent ( QKeyEvent * _ev )
02756 {
02757 Sheet * sheet = activeSheet();
02758
02759 if ( !sheet || formatKeyPress( _ev ))
02760 return;
02761
02762
02763 if ( _ev->state() & ( Qt::AltButton | Qt::ControlButton ) &&
02764 (_ev->key() != Key_Down) &&
02765 (_ev->key() != Key_Up) &&
02766 (_ev->key() != Key_Right) &&
02767 (_ev->key() != Key_Left) &&
02768 (_ev->key() != Key_Home) &&
02769 (_ev->key() != Key_Enter) &&
02770 (_ev->key() != Key_Return) &&
02771 (_ev->key() != KGlobalSettings::contextMenuKey()))
02772 {
02773 QWidget::keyPressEvent( _ev );
02774 return;
02775 }
02776
02777
02778
02779 _ev->accept();
02780
02781 d->view->doc()->emitBeginOperation(false);
02782 if ( _ev->key() == KGlobalSettings::contextMenuKey() ) {
02783 int row = markerRow();
02784 int col = markerColumn();
02785 KoPoint kop(sheet->columnPos(col, this), sheet->rowPos(row, this));
02786 QPoint p = d->view->doc()->zoomPoint(kop);
02787 p = mapToGlobal(p);
02788 d->view->openPopupMenu( p );
02789 }
02790 switch( _ev->key() )
02791 {
02792 case Key_Return:
02793 case Key_Enter:
02794 processEnterKey( _ev );
02795 return;
02796 break;
02797 case Key_Down:
02798 case Key_Up:
02799 case Key_Left:
02800 case Key_Right:
02801 case Key_Tab:
02802 case Key_Backtab:
02803 if (_ev->state() & ControlButton)
02804 {
02805 if ( !processControlArrowKey( _ev ) )
02806 return;
02807 }
02808 else
02809 {
02810 processArrowKey( _ev );
02811 return;
02812 }
02813 break;
02814
02815 case Key_Escape:
02816 processEscapeKey( _ev );
02817 return;
02818 break;
02819
02820 case Key_Home:
02821 if ( !processHomeKey( _ev ) )
02822 return;
02823 break;
02824
02825 case Key_End:
02826 if ( !processEndKey( _ev ) )
02827 return;
02828 break;
02829
02830 case Key_Prior:
02831 if ( !processPriorKey( _ev ) )
02832 return;
02833 break;
02834
02835 case Key_Next:
02836 if ( !processNextKey( _ev ) )
02837 return;
02838 break;
02839
02840 case Key_Delete:
02841 processDeleteKey( _ev );
02842 return;
02843 break;
02844
02845 case Key_F2:
02846 processF2Key( _ev );
02847 return;
02848 break;
02849
02850 case Key_F4:
02851 processF4Key( _ev );
02852 return;
02853 break;
02854
02855 default:
02856 processOtherKey( _ev );
02857 return;
02858 break;
02859 }
02860
02861
02862
02863 d->view->doc()->emitEndOperation( sheet->visibleRect( this ) );
02864 return;
02865 }
02866
02867 void Canvas::processIMEvent( QIMEvent * event )
02868 {
02869 d->view->doc()->emitBeginOperation( false );
02870 if ( !d->cellEditor && !d->chooseCell )
02871 {
02872
02873 createEditor( CellEditor );
02874 d->cellEditor->handleIMEvent( event );
02875 }
02876
02877 QPoint cursor;
02878
02879 if ( d->chooseCell )
02880 {
02881 cursor = choice()->cursor();
02882
02883 if (cursor.x() == 0 || cursor.y() == 0)
02884 cursor = choice()->cursor();
02885 }
02886 else
02887 cursor = selectionInfo()->cursor();
02888
02889 d->view->doc()->emitEndOperation( QRect( cursor, cursor ) );
02890 }
02891
02892 bool Canvas::formatKeyPress( QKeyEvent * _ev )
02893 {
02894 if (!(_ev->state() & ControlButton ))
02895 return false;
02896
02897 int key = _ev->key();
02898 if ( key != Key_Exclam && key != Key_At && key != Key_Ampersand
02899 && key != Key_Dollar && key != Key_Percent && key != Key_AsciiCircum
02900 && key != Key_NumberSign )
02901 return false;
02902
02903 Cell * cell = 0L;
02904 Sheet * sheet = activeSheet();
02905
02906 d->view->doc()->emitBeginOperation(false);
02907
02908 if ( !d->view->doc()->undoLocked() )
02909 {
02910 QString dummy;
02911 UndoCellFormat * undo = new UndoCellFormat( d->view->doc(), sheet, *selectionInfo(), dummy );
02912 d->view->doc()->addCommand( undo );
02913 }
02914
02915 Region::ConstIterator end(selectionInfo()->constEnd());
02916 for (Region::ConstIterator it = selectionInfo()->constBegin(); it != end; ++it)
02917 {
02918 QRect rect = (*it)->rect().normalize();
02919
02920 int right = rect.right();
02921 int bottom = rect.bottom();
02922
02923 if ( util_isRowSelected(rect) )
02924 {
02925 for ( int r = rect.top(); r <= bottom; ++r )
02926 {
02927 cell = sheet->getFirstCellRow( r );
02928 while ( cell )
02929 {
02930 if ( cell->isPartOfMerged() )
02931 {
02932 cell = sheet->getNextCellRight( cell->column(), r );
02933 continue;
02934 }
02935
02936 formatCellByKey (cell, _ev->key(), rect);
02937
02938 cell = sheet->getNextCellRight( cell->column(), r );
02939 }
02940 RowFormat * rw = sheet->nonDefaultRowFormat( r );
02941 QPen pen;
02942 switch ( _ev->key() )
02943 {
02944 case Key_Exclam:
02945 rw->setFormatType (Number_format);
02946 rw->setPrecision( 2 );
02947 break;
02948
02949 case Key_Dollar:
02950 rw->setFormatType (Money_format);
02951 rw->setPrecision( d->view->doc()->locale()->fracDigits() );
02952 break;
02953
02954 case Key_Percent:
02955 rw->setFormatType (Percentage_format);
02956 break;
02957
02958 case Key_At:
02959 rw->setFormatType( SecondeTime_format );
02960 break;
02961
02962 case Key_NumberSign:
02963 rw->setFormatType( ShortDate_format );
02964 break;
02965
02966 case Key_AsciiCircum:
02967 rw->setFormatType( Scientific_format );
02968 break;
02969
02970 case Key_Ampersand:
02971 if ( r == rect.top() )
02972 {
02973 pen = QPen( d->view->borderColor(), 1, SolidLine);
02974 rw->setTopBorderPen( pen );
02975 }
02976 if ( r == rect.bottom() )
02977 {
02978 pen = QPen( d->view->borderColor(), 1, SolidLine);
02979 rw->setBottomBorderPen( pen );
02980 }
02981 break;
02982
02983 default:
02984 d->view->doc()->emitEndOperation( rect );
02985 return false;
02986 }
02987 sheet->emit_updateRow( rw, r );
02988 }
02989
02990 d->view->doc()->emitEndOperation( rect );
02991 return true;
02992 }
02993
02994 if ( util_isColumnSelected(rect) )
02995 {
02996 for ( int c = rect.left(); c <= right; ++c )
02997 {
02998 cell = sheet->getFirstCellColumn( c );
02999 while ( cell )
03000 {
03001 if ( cell->isPartOfMerged() )
03002 {
03003 cell = sheet->getNextCellDown( c, cell->row() );
03004 continue;
03005 }
03006
03007 formatCellByKey (cell, _ev->key(), rect);
03008
03009 cell = sheet->getNextCellDown( c, cell->row() );
03010 }
03011
03012 ColumnFormat * cw = sheet->nonDefaultColumnFormat( c );
03013 QPen pen;
03014 switch ( _ev->key() )
03015 {
03016 case Key_Exclam:
03017 cw->setFormatType( Number_format );
03018 cw->setPrecision( 2 );
03019 break;
03020
03021 case Key_Dollar:
03022 cw->setFormatType( Money_format );
03023 cw->setPrecision( d->view->doc()->locale()->fracDigits() );
03024 break;
03025
03026 case Key_Percent:
03027 cw->setFormatType( Percentage_format );
03028 break;
03029
03030 case Key_At:
03031 cw->setFormatType( SecondeTime_format );
03032 break;
03033
03034 case Key_NumberSign:
03035 cw->setFormatType( ShortDate_format );
03036 break;
03037
03038 case Key_AsciiCircum:
03039 cw->setFormatType( Scientific_format );
03040 break;
03041
03042 case Key_Ampersand:
03043 if ( c == rect.left() )
03044 {
03045 pen = QPen( d->view->borderColor(), 1, SolidLine);
03046 cw->setLeftBorderPen( pen );
03047 }
03048 if ( c == rect.right() )
03049 {
03050 pen = QPen( d->view->borderColor(), 1, SolidLine);
03051 cw->setRightBorderPen( pen );
03052 }
03053 break;
03054
03055 default:
03056 d->view->doc()->emitEndOperation( rect );
03057 return false;
03058 }
03059 sheet->emit_updateColumn( cw, c );
03060 }
03061 d->view->doc()->emitEndOperation( rect );
03062 return true;
03063 }
03064
03065 for ( int row = rect.top(); row <= bottom; ++row )
03066 {
03067 for ( int col = rect.left(); col <= right; ++ col )
03068 {
03069 cell = sheet->nonDefaultCell( col, row );
03070
03071 if ( cell->isPartOfMerged() )
03072 continue;
03073
03074 formatCellByKey (cell, _ev->key(), rect);
03075 }
03076 }
03077
03078 }
03079 _ev->accept();
03080
03081 d->view->doc()->emitEndOperation( *selectionInfo() );
03082 return true;
03083 }
03084
03085 bool Canvas::formatCellByKey (Cell *cell, int key, const QRect &rect)
03086 {
03087 QPen pen;
03088 switch (key)
03089 {
03090 case Key_Exclam:
03091 cell->convertToDouble ();
03092 cell->format()->setFormatType (Number_format);
03093 cell->format()->setPrecision( 2 );
03094 break;
03095
03096 case Key_Dollar:
03097 cell->convertToMoney ();
03098 break;
03099
03100 case Key_Percent:
03101 cell->convertToPercent ();
03102 break;
03103
03104 case Key_At:
03105 cell->convertToTime ();
03106 break;
03107
03108 case Key_NumberSign:
03109 cell->convertToDate ();
03110 break;
03111
03112 case Key_AsciiCircum:
03113 cell->format()->setFormatType (Scientific_format);
03114 cell->convertToDouble ();
03115 break;
03116
03117 case Key_Ampersand:
03118 if ( cell->row() == rect.top() )
03119 {
03120 pen = QPen( d->view->borderColor(), 1, SolidLine);
03121 cell->setTopBorderPen( pen );
03122 }
03123 if ( cell->row() == rect.bottom() )
03124 {
03125 pen = QPen( d->view->borderColor(), 1, SolidLine);
03126 cell->setBottomBorderPen( pen );
03127 }
03128 if ( cell->column() == rect.left() )
03129 {
03130 pen = QPen( d->view->borderColor(), 1, SolidLine);
03131 cell->setLeftBorderPen( pen );
03132 }
03133 if ( cell->column() == rect.right() )
03134 {
03135 pen = QPen( d->view->borderColor(), 1, SolidLine);
03136 cell->setRightBorderPen( pen );
03137 }
03138 break;
03139 }
03140
03141 return true;
03142 }
03143
03144
03145 void Canvas::slotAutoScroll(const QPoint &scrollDistance)
03146 {
03147 QPoint d = scrollDistance;
03148 horzScrollBar()->setValue( horzScrollBar()->value() + d.x() );
03149 vertScrollBar()->setValue( vertScrollBar()->value() + d.y() );
03150 }
03151
03152 void Canvas::doAutoScroll()
03153 {
03154 if ( !d->mousePressed )
03155 {
03156 d->scrollTimer->stop();
03157 return;
03158 }
03159 bool select = false;
03160 QPoint pos = mapFromGlobal( QCursor::pos() );
03161
03162
03163 if ( pos.y() < 0 )
03164 {
03165 vertScrollBar()->setValue ((int) (vertScrollBar()->value() -
03166 autoScrollAccelerationY( - pos.y())));
03167 select = true;
03168 }
03169 else if ( pos.y() > height() )
03170 {
03171 vertScrollBar()->setValue ((int) (vertScrollBar()->value() +
03172 autoScrollAccelerationY (pos.y() - height())));
03173 select = true;
03174 }
03175
03176 if ( pos.x() < 0 )
03177 {
03178 horzScrollBar()->setValue ((int) (horzScrollBar()->value() -
03179 autoScrollAccelerationX( - pos.x() )));
03180 select = true;
03181 }
03182 else if ( pos.x() > width() )
03183 {
03184 horzScrollBar()->setValue ((int) (horzScrollBar()->value() +
03185 autoScrollAccelerationX( pos.x() - width())));
03186 select = true;
03187 }
03188
03189 if ( select )
03190 {
03191 QMouseEvent * event = new QMouseEvent(QEvent::MouseMove, pos, 0, 0);
03192 mouseMoveEvent( event );
03193 delete event;
03194 }
03195
03196
03197 d->scrollTimer->start( 50 );
03198 }
03199
03200 void Canvas::speakCell(QWidget* w, const QPoint& p, uint flags)
03201 {
03202 Q_UNUSED(flags);
03203 if (w != this) return;
03204 Sheet* sheet = activeSheet();
03205 if (!sheet) return;
03206 int row = -1;
03207 int col = -1;
03208 if (p == QPoint()) {
03209 row = markerRow();
03210 col = markerColumn();
03211 if (row == d->prevSpokenFocusRow && col == d->prevSpokenFocusCol) return;
03212 d->prevSpokenFocusRow = row;
03213 d->prevSpokenFocusCol = col;
03214 } else {
03215 QPoint wp = w->mapFromGlobal(p);
03216 double tmp;
03217 double posX;
03218 if ( sheet->layoutDirection()==Sheet::RightToLeft )
03219 {
03220 double dwidth = d->view->doc()->unzoomItX( width() );
03221 posX = dwidth - d->view->doc()->unzoomItX( wp.x() );
03222 }
03223 else
03224 posX = d->view->doc()->unzoomItX( wp.x() );
03225
03226 double posY = d->view->doc()->unzoomItY( wp.y() );
03227 col = sheet->leftColumn( (posX + xOffset()), tmp );
03228 row = sheet->topRow( (posY + yOffset()), tmp );
03229 if (row == d->prevSpokenPointerRow && col == d->prevSpokenPointerCol) return;
03230 d->prevSpokenPointerRow = row;
03231 d->prevSpokenPointerCol = col;
03232 }
03233 if (row == d->prevSpokenRow && col == d->prevSpokenCol) return;
03234 d->prevSpokenRow = row;
03235 d->prevSpokenCol = col;
03236
03237 if (row >=0 && col >= 0) {
03238 Cell* cell = sheet->cellAt( col, row );
03239 if (!cell) return;
03240 QString text = cell->strOutText();
03241 if (!text.isEmpty()) {
03242 text.prepend(i18n("Spreadsheet cell", "Cell ") + cell->name() + " ");
03243 if (cell->isFormula()) {
03244 QString f = cell->text();
03245
03246 QString f2;
03247 for (uint i = 0; i < f.length(); i++) f2 += f[i] + " ";
03248 f2.replace("(", i18n("character (", "left paren"));
03249 f2.replace(")", i18n("character )", "right paren"));
03250 f2.replace(":", i18n("character :", "colon"));
03251 f2.replace(";", i18n("character ;", "semicolon"));
03252 f2.replace("=", i18n("character =", "equals"));
03253 f2.replace(".", i18n("character .", "point"));
03254 f2.replace(",", i18n("character ,", "comma"));
03255 f2.replace(" . . ", i18n("characters ..", " dot dot "));
03256 text.append(i18n("Spreadsheet formula", " Formula ") + f2);
03257 }
03258
03259 kospeaker->sayWidget(text);
03260 }
03261 }
03262 }
03263
03264 double Canvas::autoScrollAccelerationX( int offset )
03265 {
03266 switch( static_cast<int>( offset / 20 ) )
03267 {
03268 case 0: return 5.0;
03269 case 1: return 20.0;
03270 case 2: return d->view->doc()->unzoomItX( width() );
03271 case 3: return d->view->doc()->unzoomItX( width() );
03272 default: return d->view->doc()->unzoomItX( (int) (width() * 5.0) );
03273 }
03274 }
03275
03276 double Canvas::autoScrollAccelerationY( int offset )
03277 {
03278 switch( static_cast<int>( offset / 20 ) )
03279 {
03280 case 0: return 5.0;
03281 case 1: return 20.0;
03282 case 2: return d->view->doc()->unzoomItY( height() );
03283 case 3: return d->view->doc()->unzoomItY( height() );
03284 default: return d->view->doc()->unzoomItY( (int) (height() * 5.0) );
03285 }
03286 }
03287
03288
03289 KSpread::EmbeddedObject *Canvas::getObject( const QPoint &pos, Sheet *_sheet )
03290 {
03291 QPoint const p ( (int) pos.x() ,
03292 (int) pos.y() );
03293
03294 QPtrListIterator<EmbeddedObject> itObject( doc()->embeddedObjects() );
03295 for( ; itObject.current(); ++itObject )
03296 {
03297 if ( itObject.current()->sheet() == _sheet )
03298 {
03299 KoRect const bound = ( itObject.current() )->geometry();
03300 QRect zoomedBound = doc()->zoomRect( KoRect(bound.left(), bound.top(),
03301 bound.width(),
03302 bound.height() ) );
03303 zoomedBound.moveBy( (int)( -xOffset() * doc()->zoomedResolutionX() ), (int)( -yOffset() * doc()->zoomedResolutionY() ) );
03304 if ( zoomedBound.contains( p ) )
03305 return itObject.current();
03306 }
03307 }
03308 return 0;
03309 }
03310
03311 void Canvas::selectObject( EmbeddedObject *obj )
03312 {
03313 if ( obj->sheet() != activeSheet() || obj->isSelected() )
03314 return;
03315 obj->setSelected( true );
03316 repaintObject( obj );
03317
03318 d->mouseSelectedObject = true;
03319 emit objectSelectedChanged();
03320 deleteEditor( true );
03321 }
03322
03323 void Canvas::deselectObject( EmbeddedObject *obj )
03324 {
03325 if ( obj->sheet() != activeSheet() || !obj->isSelected() )
03326 return;
03327 obj->setSelected( false );
03328 repaintObject( obj );
03329
03330 d->mouseSelectedObject = false;
03331 emit objectSelectedChanged();
03332 }
03333
03334 void Canvas::selectAllObjects()
03335 {
03336 QPtrListIterator<EmbeddedObject> it( doc()->embeddedObjects() );
03337 for ( ; it.current() ; ++it )
03338 {
03339 if ( it.current()->sheet() == activeSheet() )
03340 it.current()->setSelected( true );
03341 }
03342
03343 d->mouseSelectedObject = true;
03344
03345 }
03346
03347 void Canvas::deselectAllObjects()
03348 {
03349 if( activeSheet()->numSelected() == 0 )
03350 return;
03351
03352
03353
03354 QPtrListIterator<EmbeddedObject> it( doc()->embeddedObjects() );
03355 for ( ; it.current() ; ++it )
03356 deselectObject( it.current() );
03357
03358 d->mouseSelectedObject = false;
03359
03360 }
03361
03362
03363
03364 void Canvas::setMouseSelectedObject(bool b)
03365 {
03366 d->mouseSelectedObject = b;
03367 emit objectSelectedChanged();
03368 }
03369
03370 bool Canvas::isObjectSelected()
03371 {
03372 return d->mouseSelectedObject;
03373 }
03374
03375
03376 void Canvas::moveObjectsByMouse( KoPoint &pos, bool keepXorYunchanged )
03377 {
03378 KoRect rect( objectRect( false ) );
03379 KoPoint move( 0, 0 );
03380 double diffx = pos.x() - d->m_origMousePos.x();
03381 double diffy = pos.y() - d->m_origMousePos.y();
03382
03383 move = KoPoint( diffx, diffy );
03384 d->m_origMousePos = pos;
03385
03386
03387 KoRect movedRect( rect );
03388 movedRect.moveBy( diffx, diffy );
03389
03390
03391 KoPoint diffDueToBorders(0,0);
03392
03393 if ( rect.left() + move.x() < 0 )
03394 diffDueToBorders.setX( -rect.left() - move.x() );
03395
03396
03397
03398
03399
03400 if ( rect.top() + move.y() < 0 )
03401 diffDueToBorders.setY( -rect.top() - move.y() );
03402
03403
03404
03405
03406 move += diffDueToBorders;
03407
03408
03409 if ( keepXorYunchanged )
03410 {
03411 KoPoint diff( d->m_moveStartPosMouse - movedRect.topLeft() );
03412 if ( fabs( diff.x() ) > fabs( diff.y() ) )
03413 {
03414
03415 movedRect.moveTopLeft( KoPoint( movedRect.x(), d->m_moveStartPosMouse.y() ) );
03416 move.setY( movedRect.y() - rect.y() );
03417 }
03418 else
03419 {
03420
03421 movedRect.moveTopLeft( KoPoint( d->m_moveStartPosMouse.x(), movedRect.y() ) );
03422 move.setX( movedRect.x() - rect.x() );
03423 }
03424 }
03425
03426 if ( move != KoPoint( 0, 0 ) )
03427 {
03428
03429 activeSheet()->moveObject( view(), move, false );
03430 }
03431 }
03432
03433
03434 void Canvas::resizeObject( ModifyType _modType, const KoPoint & point, bool keepRatio )
03435 {
03436 EmbeddedObject *obj = d->m_resizeObject;
03437
03438 KoRect objRect = obj->geometry();
03439 objRect.moveBy( -xOffset(), -yOffset() );
03440 QRect oldBoundingRect( doc()->zoomRect( objRect ) );
03441
03442 bool left = false;
03443 bool right = false;
03444 bool top = false;
03445 bool bottom = false;
03446 if ( _modType == MT_RESIZE_UP || _modType == MT_RESIZE_LU || _modType == MT_RESIZE_RU )
03447 {
03448 top = true;
03449
03450 }
03451 if ( _modType == MT_RESIZE_DN || _modType == MT_RESIZE_LD || _modType == MT_RESIZE_RD )
03452 {
03453 bottom = true;
03454
03455 }
03456 if ( _modType == MT_RESIZE_LF || _modType == MT_RESIZE_LU || _modType == MT_RESIZE_LD )
03457 {
03458 left = true;
03459
03460 }
03461 if ( _modType == MT_RESIZE_RT || _modType == MT_RESIZE_RU || _modType == MT_RESIZE_RD )
03462 {
03463 right = true;
03464
03465 }
03466
03467 double newLeft = objRect.left();
03468 double newRight = objRect.right();
03469 double newTop = objRect.top();
03470 double newBottom = objRect.bottom();
03471 if ( top )
03472 {
03473 if ( point.y() < objRect.bottom() - MIN_SIZE )
03474 {
03475 newTop = point.y();
03476 }
03477 else
03478 {
03479 newTop = objRect.bottom() - MIN_SIZE;
03480 }
03481 }
03482 if ( bottom )
03483 {
03484 if ( point.y() > objRect.top() + MIN_SIZE )
03485 {
03486 newBottom = point.y();
03487 }
03488 else
03489 {
03490 newBottom = objRect.top() + MIN_SIZE;
03491 }
03492 }
03493 if ( left )
03494 {
03495 if ( point.x() < objRect.right() - MIN_SIZE )
03496 {
03497 newLeft = point.x();
03498 }
03499 else
03500 {
03501 newLeft = objRect.right() - MIN_SIZE;
03502 }
03503 }
03504 if ( right )
03505 {
03506 if ( point.x() > objRect.left() + MIN_SIZE )
03507 {
03508 newRight = point.x();
03509 }
03510 else
03511 {
03512 newRight = objRect.left() + MIN_SIZE;
03513 }
03514 }
03515
03516 double width = newRight - newLeft;
03517 double height = newBottom - newTop;
03518
03519 if ( keepRatio && d->m_ratio != 0 )
03520 {
03521 if ( ( top || bottom ) && ( right || left ) )
03522 {
03523 if ( height * height * d->m_ratio > width * width / d->m_ratio )
03524 {
03525 width = height * d->m_ratio;
03526 }
03527 else
03528 {
03529 height = width / d->m_ratio;
03530 }
03531 }
03532 else if ( top || bottom )
03533 {
03534 width = height * d->m_ratio;
03535 }
03536 else
03537 {
03538 height = width / d->m_ratio;
03539 }
03540
03541 if ( top )
03542 {
03543 newTop = objRect.bottom() - height;
03544 }
03545 else
03546 {
03547 newBottom = objRect.top() + height;
03548 }
03549 if ( left )
03550 {
03551 newLeft = objRect.right() - width;
03552 }
03553 else
03554 {
03555 newRight = objRect.right() + width;
03556 }
03557 }
03558
03559 if ( newLeft != objRect.left() || newRight != objRect.right() || newTop != objRect.top() || newBottom != objRect.bottom() )
03560 {
03561
03562 obj->resizeBy( width - objRect.width(), height - objRect.height() );
03563
03564 if ( objRect.left() != newLeft || objRect.top() != newTop )
03565 {
03566 obj->moveBy( KoPoint( newLeft - objRect.left(), newTop - objRect.top() ) );
03567 }
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584 repaint( oldBoundingRect );
03585 repaintObject( obj );
03586 emit objectSizeChanged();
03587 }
03588 }
03589
03590
03591 void Canvas::finishResizeObject( const QString &, bool )
03592 {
03593 if ( d->m_resizeObject )
03594 {
03595 KoPoint move = KoPoint( d->m_resizeObject->geometry().x() - d->m_rectBeforeResize.x(),
03596 d->m_resizeObject->geometry().y() - d->m_rectBeforeResize.y() );
03597 KoSize size = KoSize( d->m_resizeObject->geometry().width() - d->m_rectBeforeResize.width(),
03598 d->m_resizeObject->geometry().height() - d->m_rectBeforeResize.height() );
03599
03600 if ( ( d->m_resizeObject->geometry() ) != d->m_rectBeforeResize )
03601 {
03602 ChangeObjectGeometryCommand *resizeCmd = new ChangeObjectGeometryCommand( d->m_resizeObject, move, size );
03603
03604 doc()->addCommand( resizeCmd );
03605 }
03606
03607
03608
03609
03610 d->m_ratio = 0.0;
03611 d->m_isResizing = false;
03612 repaintObject( d->m_resizeObject );
03613 d->m_resizeObject = NULL;
03614 }
03615 }
03616
03617 void Canvas::raiseObject( EmbeddedObject *object )
03618 {
03619 if ( doc()->embeddedObjects().count() <= 1 )
03620 return;
03621
03622 if ( d->m_objectDisplayAbove == 0 )
03623 {
03624 if ( activeSheet()->numSelected() == 1 )
03625 {
03626 d->m_objectDisplayAbove = object;
03627 }
03628 }
03629 }
03630
03631 void Canvas::lowerObject()
03632 {
03633 d->m_objectDisplayAbove = 0;
03634 }
03635
03636 void Canvas::displayObjectList( QPtrList<EmbeddedObject> &list )
03637 {
03638 list = doc()->embeddedObjects();
03639 list.setAutoDelete( false );
03640
03641 if ( d->m_objectDisplayAbove )
03642 {
03643
03644
03645 int pos = doc()->embeddedObjects().findRef( d->m_objectDisplayAbove );
03646 if ( pos != -1 && d->m_objectDisplayAbove->isSelected() )
03647 {
03648 list.take( pos );
03649 list.append( d->m_objectDisplayAbove );
03650 }
03651 else
03652 {
03653
03654
03655 }
03656 }
03657 }
03658
03659
03660 KoRect Canvas::objectRect( bool all ) const
03661 {
03662 return activeSheet()->getRealRect( all );
03663 }
03664
03665 void Canvas::deleteEditor (bool saveChanges, bool array)
03666 {
03667 if ( !d->cellEditor )
03668 return;
03669
03670
03671
03672 setSelectionChangePaintDirty( activeSheet() , *choice() );
03673
03674 d->editWidget->setEditMode( false );
03675
03676 QString t = d->cellEditor->text();
03677
03678
03679
03680 delete d->cellEditor;
03681 d->cellEditor = 0;
03682
03683 if ( saveChanges )
03684 {
03685 if ( t.at(0)=='=' )
03686 {
03687
03688 int openParenthese = t.contains('(' );
03689 int closeParenthese = t.contains(')' );
03690 int diff = QABS( openParenthese - closeParenthese );
03691 if ( openParenthese > closeParenthese )
03692 {
03693 for (int i=0; i < diff;i++)
03694 {
03695 t=t+')';
03696 }
03697 }
03698 }
03699 d->view->setText (t, array);
03700 }
03701 else
03702 {
03703 d->view->updateEditWidget();
03704 }
03705
03706 setFocus();
03707 }
03708
03709
03710 void Canvas::createEditor(bool captureArrowKeys)
03711 {
03712 if (!activeSheet())
03713 return;
03714
03715 Cell * cell = activeSheet()->nonDefaultCell( markerColumn(), markerRow(), false );
03716
03717 if ( !createEditor( CellEditor , true , captureArrowKeys ) )
03718 return;
03719 if ( cell )
03720 d->cellEditor->setText( cell->text() );
03721 }
03722
03723 bool Canvas::createEditor( EditorType ed, bool addFocus, bool captureArrowKeys )
03724 {
03725 Sheet * sheet = activeSheet();
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739 if (!choice()->sheet())
03740 choice()->setSheet( activeSheet() );
03741
03742 if ( !d->cellEditor )
03743 {
03744 Cell * cell = sheet->nonDefaultCell( marker().x(), marker().y(), false );
03745
03746 if ( sheet->isProtected() && !cell->format()->notProtected( marker().x(), marker().y() ) )
03747 return false;
03748
03749 if ( ed == CellEditor )
03750 {
03751 d->editWidget->setEditMode( true );
03752 d->cellEditor = new KSpread::CellEditor( cell, this, captureArrowKeys );
03753 }
03754
03755 double w, h;
03756 double min_w = cell->dblWidth( markerColumn() );
03757 double min_h = cell->dblHeight( markerRow() );
03758 if ( cell->isDefault() )
03759 {
03760 w = min_w;
03761 h = min_h;
03762
03763 }
03764 else
03765 {
03766 w = cell->extraWidth();
03767 h = cell->extraHeight();
03768
03769 }
03770
03771 double xpos = sheet->dblColumnPos( markerColumn() ) - xOffset();
03772
03773 Sheet::LayoutDirection sheetDir = sheet->layoutDirection();
03774 bool rtlText = cell->strOutText().isRightToLeft();
03775
03776
03777
03778 if ( w > 0 && ( ( sheetDir == Sheet::RightToLeft && !rtlText ) ||
03779 ( sheetDir == Sheet::LeftToRight && rtlText ) ) )
03780 xpos -= w - min_w;
03781
03782
03783 if ( sheetDir == Sheet::RightToLeft )
03784 {
03785 double dwidth = d->view->doc()->unzoomItX( width() );
03786 double w2 = QMAX( w, min_w );
03787 xpos = dwidth - w2 - xpos;
03788 }
03789
03790 double ypos = sheet->dblRowPos( markerRow() ) - yOffset();
03791 QPalette p = d->cellEditor->palette();
03792 QColorGroup g( p.active() );
03793
03794 QColor color = cell->format()->textColor( markerColumn(), markerRow() );
03795 if ( !color.isValid() )
03796 color = QApplication::palette().active().text();
03797 g.setColor( QColorGroup::Text, color);
03798
03799 color = cell->bgColor( markerColumn(), markerRow() );
03800 if ( !color.isValid() )
03801 color = g.base();
03802 g.setColor( QColorGroup::Background, color );
03803
03804 d->cellEditor->setPalette( QPalette( g, p.disabled(), g ) );
03805 QFont tmpFont = cell->format()->textFont( markerColumn(), markerRow() );
03806 tmpFont.setPointSizeFloat( 0.01 * d->view->doc()->zoom() * tmpFont.pointSizeFloat() );
03807 d->cellEditor->setFont( tmpFont );
03808
03809 KoRect rect( xpos, ypos, w, h );
03810
03811
03812 QRect zoomedRect=d->view->doc()->zoomRect( rect );
03813
03814
03815
03816
03817
03818 d->cellEditor->setGeometry( zoomedRect );
03819 d->cellEditor->setMinimumSize( QSize( d->view->doc()->zoomItX( min_w ), d->view->doc()->zoomItY( min_h ) ) );
03820 d->cellEditor->show();
03821
03822
03823
03824
03825
03826
03827
03828 if ( addFocus )
03829 d->cellEditor->setFocus();
03830
03831 setSelectionChangePaintDirty(sheet, *selectionInfo());
03832 paintUpdates();
03833 }
03834
03835 return true;
03836 }
03837
03838 void Canvas::repaintObject( EmbeddedObject *obj )
03839 {
03840
03841 QRect canvasRelativeGeometry = doc()->zoomRect( obj->geometry() );
03842 canvasRelativeGeometry.moveBy( (int)( -xOffset()*doc()->zoomedResolutionX() ) ,
03843 (int)( -yOffset() * doc()->zoomedResolutionY()) );
03844
03845 update( canvasRelativeGeometry );
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862 }
03863
03864 void Canvas::copyOasisObjects()
03865 {
03866
03867 QBuffer buffer;
03868 QCString mimeType = "application/vnd.oasis.opendocument.spreadsheet";
03869 KoStore* store = KoStore::createStore( &buffer, KoStore::Write, mimeType );
03870 Q_ASSERT( store );
03871 Q_ASSERT( !store->bad() );
03872 KoOasisStore oasisStore( store );
03873
03874 KoXmlWriter* manifestWriter = oasisStore.manifestWriter( mimeType );
03875
03876 QString plainText;
03877 KoPicture picture;
03878 if ( !doc()->saveOasisHelper( store, manifestWriter, Doc::SaveSelected, &plainText, &picture )
03879 || !oasisStore.closeManifestWriter() )
03880 {
03881 delete store;
03882 return;
03883 }
03884 delete store;
03885
03886 KMultipleDrag* multiDrag = new KMultipleDrag();
03887 if ( !plainText.isEmpty() )
03888 multiDrag->addDragObject( new QTextDrag( plainText, 0 ) );
03889 if ( !picture.isNull() )
03890 multiDrag->addDragObject( picture.dragObject( 0 ) );
03891 KoStoreDrag* storeDrag = new KoStoreDrag( mimeType, 0 );
03892 kdDebug() << k_funcinfo << "setting zip data: " << buffer.buffer().size() << " bytes." << endl;
03893 storeDrag->setEncodedData( buffer.buffer() );
03894 multiDrag->addDragObject( storeDrag );
03895
03896
03897 QPtrListIterator<EmbeddedObject> itObject( doc()->embeddedObjects() );
03898 itObject.toFirst();
03899 if ( itObject.current() )
03900 {
03901 KoRect kr = objectRect(false);
03902 QRect r( kr.toQRect() );
03903 QPixmap pixmap( r.width(), r.height() );
03904 pixmap.fill( "white" );
03905 QPainter p(&pixmap);
03906 for( ; itObject.current(); ++itObject )
03907 {
03908 if ( itObject.current()->isSelected() )
03909 p.drawPixmap( itObject.current()->geometry().toQRect().left() - r.left(), itObject.current()->geometry().toQRect().top() - r.top(), itObject.current()->toPixmap( 1.0 , 1.0 ) );
03910 }
03911 p.end();
03912 if (!pixmap.isNull())
03913 {
03914 QImageDrag *imagedrag = new QImageDrag( pixmap.convertToImage() );
03915 multiDrag->addDragObject( imagedrag );
03916 }
03917 }
03918
03919 QDragObject *dragObject = multiDrag;
03920 QApplication::clipboard()->setData( dragObject, QClipboard::Clipboard );
03921 }
03922
03923 void Canvas::closeEditor()
03924 {
03925 if ( d->chooseCell )
03926 return;
03927
03928 if ( d->cellEditor )
03929 {
03930 deleteEditor( true );
03931 }
03932 }
03933
03934 void Canvas::updateEditor()
03935 {
03936 if (!d->chooseCell)
03937 return;
03938
03939 Sheet* sheet = activeSheet();
03940 if (!sheet)
03941 return;
03942
03943 if (d->cellEditor)
03944 {
03945 if (choice()->sheet() != sheet)
03946 {
03947 d->cellEditor->hide();
03948 }
03949 else
03950 {
03951 d->cellEditor->show();
03952 }
03953 d->cellEditor->updateChoice();
03954 }
03955 }
03956
03957 void Canvas::setSelectionChangePaintDirty(Sheet* sheet, const Region& region)
03958 {
03959 sheet->setRegionPaintDirty(region);
03960 }
03961
03962
03963 void Canvas::updatePosWidget()
03964 {
03965 QString buffer;
03966
03967 if ( selectionInfo()->isSingular() )
03968 {
03969 if (activeSheet()->getLcMode())
03970 {
03971 buffer = "L" + QString::number( markerRow() ) +
03972 "C" + QString::number( markerColumn() );
03973 }
03974 else
03975 {
03976 buffer = Cell::columnName( markerColumn() ) +
03977 QString::number( markerRow() );
03978 }
03979 }
03980 else
03981 {
03982 if (activeSheet()->getLcMode())
03983 {
03984 buffer = QString::number( (selectionInfo()->lastRange().bottom()-selectionInfo()->lastRange().top()+1) )+"Lx";
03985 if ( util_isRowSelected( selectionInfo()->lastRange() ) )
03986 buffer+=QString::number((KS_colMax-selectionInfo()->lastRange().left()+1))+"C";
03987 else
03988 buffer+=QString::number((selectionInfo()->lastRange().right()-selectionInfo()->lastRange().left()+1))+"C";
03989 }
03990 else
03991 {
03992
03993
03994
03995 buffer=Cell::columnName( selectionInfo()->lastRange().left() ) +
03996 QString::number(selectionInfo()->lastRange().top()) + ":" +
03997 Cell::columnName( QMIN( KS_colMax, selectionInfo()->lastRange().right() ) ) +
03998 QString::number(selectionInfo()->lastRange().bottom());
03999
04000
04001 }
04002 }
04003
04004 if (buffer != d->posWidget->lineEdit()->text())
04005 d->posWidget->lineEdit()->setText(buffer);
04006 }
04007
04008 void Canvas::equalizeRow()
04009 {
04010 QRect s( selection() );
04011 RowFormat *rl = d->view->activeSheet()->rowFormat(s.top());
04012 int size=rl->height(this);
04013 if ( s.top() == s.bottom() )
04014 return;
04015 for(int i=s.top()+1;i<=s.bottom();i++)
04016 {
04017 Sheet *sheet = activeSheet();
04018 if ( !sheet )
04019 return;
04020 size=QMAX(d->view->activeSheet()->rowFormat(i)->height(this),size);
04021 }
04022 d->view->vBorderWidget()->equalizeRow(size);
04023 }
04024
04025 void Canvas::equalizeColumn()
04026 {
04027 QRect s( selection() );
04028 ColumnFormat *cl = d->view->activeSheet()->columnFormat(s.left());
04029 int size=cl->width(this);
04030 if ( s.left() == s.right() )
04031 return;
04032
04033 for(int i=s.left()+1;i<=s.right();i++)
04034 {
04035 size=QMAX(d->view->activeSheet()->columnFormat(i)->width(this),size);
04036 }
04037 d->view->hBorderWidget()->equalizeColumn(size);
04038 }
04039
04040 QRect Canvas::cellsInArea( const QRect area ) const
04041 {
04042 KoRect unzoomedRect = d->view->doc()->unzoomRect( area );
04043
04044 unzoomedRect.moveBy( (int)xOffset(), (int)yOffset() );
04045
04046 double tmp;
04047 int left_col = activeSheet()->leftColumn( unzoomedRect.left(), tmp );
04048 int right_col = activeSheet()->rightColumn( unzoomedRect.right() );
04049 int top_row = activeSheet()->topRow( unzoomedRect.top(), tmp );
04050 int bottom_row = activeSheet()->bottomRow( unzoomedRect.bottom() );
04051
04052 return QRect( left_col, top_row,
04053 right_col - left_col + 1, bottom_row - top_row + 1 );
04054 }
04055
04056 QRect Canvas::visibleCells() const
04057 {
04058 return cellsInArea( QRect(0,0,width(),height()) );
04059
04060 }
04061
04062
04063
04064
04065
04066
04067
04068
04069 void Canvas::paintUpdates()
04070 {
04071 if (activeSheet() == NULL)
04072 return;
04073
04074 QPainter painter(this);
04075
04076
04077 QRegion rgnComplete( painter.clipRegion() );
04078 QWMatrix matrix;
04079 if ( d->view )
04080 {
04081 matrix = d->view->matrix();
04082 }
04083 else
04084 {
04085 matrix = painter.worldMatrix();
04086 }
04087
04088
04089 paintChildren( painter, matrix );
04090
04091 painter.save();
04092 clipoutChildren( painter );
04093
04094 KoRect unzoomedRect = d->view->doc()->unzoomRect( QRect( 0, 0, width(), height() ) );
04095
04096
04097
04098
04099 QRect range = visibleCells();
04100 Cell* cell = NULL;
04101
04102 double topPos = activeSheet()->dblRowPos(range.top());
04103 double leftPos = activeSheet()->dblColumnPos(range.left());
04104
04105 KoPoint dblCorner( leftPos - xOffset(), topPos - yOffset() );
04106
04107 int x;
04108 int y;
04109
04110 int right = range.right();
04111 int bottom = range.bottom();
04112 Sheet * sheet = activeSheet();
04113
04114 #if 0
04115 kdDebug(36001)
04116 << "================================================================"
04117 << endl;
04118 kdDebug(36001) << "painting dirty cells " << endl;
04119 #endif
04120
04121 QValueList<QPoint> mergedCellsPainted;
04122 for ( x = range.left(); x <= right; ++x )
04123 {
04124 for ( y = range.top(); y <= bottom; ++y )
04125 {
04126 if ( sheet->cellIsPaintDirty( QPoint( x, y ) ) )
04127 {
04128 cell = sheet->cellAt( x, y );
04129
04130
04131 if (!cell->isDefault())
04132 {
04133 if (cell->calcDirtyFlag()) cell->calc();
04134 if (cell->layoutDirtyFlag()) cell->makeLayout( painter, x, y );
04135 }
04136
04137
04138
04139
04140
04141
04142 int paintBorder=Cell::Border_None;
04143
04144 QPen bottomPen( cell->effBottomBorderPen( x, y ) );
04145 QPen rightPen( cell->effRightBorderPen( x, y ) );
04146 QPen leftPen( cell->effLeftBorderPen( x, y ) );
04147 QPen topPen( cell->effTopBorderPen( x, y ) );
04148
04149
04150
04151
04152 if ( x >= KS_colMax )
04153
04154 paintBorder |= Cell::Border_Right;
04155 else
04156 if ( sheet->cellIsPaintDirty( QPoint( x + 1, y ) ) )
04157 {
04158
04159 paintBorder |= Cell::Border_Right;
04160 if ( cell->effRightBorderValue( x, y ) < sheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
04161 rightPen = sheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
04162 }
04163 else
04164 {
04165
04166 paintBorder |= Cell::Border_Right;
04167 if ( cell->effRightBorderValue( x, y ) < sheet->cellAt( x + 1, y )->effLeftBorderValue( x + 1, y ) )
04168 rightPen = sheet->cellAt( x + 1, y )->effLeftBorderPen( x + 1, y );
04169 }
04170
04171
04172
04173 if ( y >= KS_rowMax )
04174
04175 paintBorder |= Cell::Border_Bottom;
04176 else
04177 if ( sheet->cellIsPaintDirty( QPoint( x, y + 1 ) ) )
04178 {
04179 if ( cell->effBottomBorderValue( x, y ) > sheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1 ) )
04180
04181 paintBorder |= Cell::Border_Bottom;
04182 }
04183 else
04184 {
04185
04186 paintBorder |= Cell::Border_Bottom;
04187 if ( cell->effBottomBorderValue( x, y ) < sheet->cellAt( x, y + 1 )->effTopBorderValue( x, y + 1 ) )
04188 bottomPen = sheet->cellAt( x, y + 1 )->effTopBorderPen( x, y + 1 );
04189 }
04190
04191
04192 if ( x == 1 )
04193
04194 paintBorder |= Cell::Border_Left;
04195 else
04196 if ( sheet->cellIsPaintDirty( QPoint( x - 1, y ) ) )
04197 {
04198
04199 paintBorder |= Cell::Border_Left;
04200 if ( cell->effLeftBorderValue( x, y ) < sheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
04201 leftPen = sheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
04202 }
04203 else
04204 {
04205 paintBorder |= Cell::Border_Left;
04206 if ( cell->effLeftBorderValue( x, y ) < sheet->cellAt( x - 1, y )->effRightBorderValue( x - 1, y ) )
04207 leftPen = sheet->cellAt( x - 1, y )->effRightBorderPen( x - 1, y );
04208 }
04209
04210
04211 if ( y == 1 )
04212
04213 paintBorder |= Cell::Border_Top;
04214 else
04215 if ( sheet->cellIsPaintDirty( QPoint( x, y - 1 ) ) )
04216 {
04217
04218 paintBorder |= Cell::Border_Top;
04219 if ( cell->effTopBorderValue( x, y ) < sheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
04220 topPen = sheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
04221 }
04222 else
04223 {
04224
04225 paintBorder |= Cell::Border_Top;
04226 if ( cell->effTopBorderValue( x, y ) < sheet->cellAt( x, y - 1 )->effBottomBorderValue( x, y - 1 ) )
04227 topPen = sheet->cellAt( x, y - 1 )->effBottomBorderPen( x, y - 1 );
04228 }
04229
04230 cell->paintCell( unzoomedRect, painter, d->view, dblCorner,
04231 QPoint( x, y), paintBorder,
04232 rightPen,bottomPen,leftPen,topPen,
04233 mergedCellsPainted);
04234
04235
04236 }
04237 dblCorner.setY( dblCorner.y() + sheet->rowFormat( y )->dblHeight( ) );
04238 }
04239 dblCorner.setY( topPos - yOffset() );
04240 dblCorner.setX( dblCorner.x() + sheet->columnFormat( x )->dblWidth( ) );
04241 }
04242
04243
04244
04245
04246
04247 paintHighlightedRanges(painter, unzoomedRect);
04248 paintNormalMarker(painter, unzoomedRect);
04249
04250
04251 painter.restore();
04252
04253 }
04254
04255
04256
04257 void Canvas::clipoutChildren( QPainter& painter ) const
04258 {
04259 QRegion rgn = painter.clipRegion();
04260 if ( rgn.isEmpty() )
04261 rgn = QRegion( QRect( 0, 0, width(), height() ) );
04262
04263 const double horizontalOffset = -xOffset() * doc()->zoomedResolutionX();
04264 const double verticalOffset = -yOffset() * doc()->zoomedResolutionY();
04265
04266 QPtrListIterator<EmbeddedObject> itObject( doc()->embeddedObjects() );
04267 for( ; itObject.current(); ++itObject )
04268 {
04269 if ( ( itObject.current() )->sheet() == activeSheet() )
04270 {
04271 QRect childGeometry = doc()->zoomRect( itObject.current()->geometry());
04272
04273
04274
04275 childGeometry.moveBy( (int)horizontalOffset , (int)verticalOffset );
04276
04277 if (painter.window().intersects(childGeometry))
04278 rgn -= childGeometry;
04279
04280
04281 }
04282 }
04283
04284 painter.setClipRegion( rgn );
04285 }
04286
04287 QRect Canvas::painterWindowGeometry( const QPainter& painter ) const
04288 {
04289 QRect zoomedWindowGeometry = painter.window();
04290
04291 zoomedWindowGeometry.moveBy( (int)( xOffset() * doc()->zoomedResolutionX() ) , (int)( yOffset() * doc()->zoomedResolutionY() ) );
04292
04293 return zoomedWindowGeometry;
04294 }
04295
04296 void Canvas::paintChildren( QPainter& painter, QWMatrix& )
04297 {
04298 QPtrListIterator<EmbeddedObject> itObject( doc()->embeddedObjects() );
04299 itObject.toFirst();
04300 if ( !itObject.current() )
04301 return;
04302
04303 painter.save();
04304 painter.translate( -xOffset() * doc()->zoomedResolutionX() , -yOffset() * doc()->zoomedResolutionY() );
04305
04306 const QRect zoomedWindowGeometry = painterWindowGeometry( painter );
04307 const Sheet* sheet = activeSheet();
04308
04309 for( ; itObject.current(); ++itObject )
04310 {
04311 QRect const zoomedObjectGeometry = doc()->zoomRect( itObject.current()->geometry() );
04312 if ( ( itObject.current() )->sheet() == activeSheet() &&
04313 zoomedWindowGeometry.intersects( zoomedObjectGeometry ) )
04314 {
04315
04316
04317
04318 QRect canvasRelativeGeometry = zoomedObjectGeometry;
04319 canvasRelativeGeometry.moveBy( (int)( -xOffset()*doc()->zoomedResolutionX() ) ,
04320 (int)( -yOffset() * doc()->zoomedResolutionY()) );
04321
04322 const QRect cellsUnderObject=cellsInArea( canvasRelativeGeometry );
04323 bool redraw=false;
04324
04325 for (int x=cellsUnderObject.left();x<=cellsUnderObject.right();x++)
04326 {
04327 for (int y=cellsUnderObject.top();y<=cellsUnderObject.bottom();y++)
04328 if ( sheet->cellIsPaintDirty( QPoint(x,y) ) )
04329 {
04330 redraw=true;
04331 break;
04332 }
04333 if (redraw)
04334 break;
04335 }
04336
04337 if ( redraw )
04338 itObject.current()->draw( &painter );
04339 }
04340 }
04341 painter.restore();
04342 }
04343
04344 void Canvas::paintHighlightedRanges(QPainter& painter, const KoRect& )
04345 {
04346 QValueList<QColor> colors = choice()->colors();
04347 QBrush nullBrush;
04348 int index = 0;
04349 Region::ConstIterator end(choice()->constEnd());
04350 for (Region::ConstIterator it = choice()->constBegin(); it != end; ++it)
04351 {
04352
04353 if ((*it)->sheet() != activeSheet())
04354 {
04355 index++;
04356 continue;
04357 }
04358
04359 QRect region = (*it)->rect().normalize();
04360
04361
04362
04363 KoRect unzoomedRect;
04364
04365 sheetAreaToVisibleRect(region,unzoomedRect);
04366
04367
04368
04369 QPen highlightPen( colors[(index) % colors.size()] );
04370 painter.setPen(highlightPen);
04371
04372
04373
04374 QRect zoomedRect;
04375
04376 zoomedRect.setCoords ( d->view->doc()->zoomItX(unzoomedRect.left()),
04377 d->view->doc()->zoomItY(unzoomedRect.top()),
04378 d->view->doc()->zoomItX(unzoomedRect.right()),
04379 d->view->doc()->zoomItY(unzoomedRect.bottom()) );
04380
04381
04382
04383
04384 zoomedRect.setLeft(zoomedRect.left()+1);
04385 zoomedRect.setTop(zoomedRect.top()+1);
04386 zoomedRect.setRight(zoomedRect.right()-1);
04387 zoomedRect.setBottom(zoomedRect.bottom()-1);
04388
04389 painter.setBrush(nullBrush);
04390 painter.drawRect(zoomedRect);
04391
04392
04393
04394
04395
04396 QBrush sizeGripBrush( colors[(index) % colors.size()] );
04397 QPen sizeGripPen(Qt::white);
04398
04399 painter.setPen(sizeGripPen);
04400 painter.setBrush(sizeGripBrush);
04401
04402 painter.drawRect(zoomedRect.right()-3,zoomedRect.bottom()-3,6,6);
04403 index++;
04404 }
04405 }
04406
04407 void Canvas::paintNormalMarker(QPainter& painter, const KoRect &viewRect)
04408 {
04409
04410
04411 if( d->chooseCell )
04412 return;
04413
04414 if (d->cellEditor)
04415 return;
04416
04417 if (!selectionInfo()->activeElement())
04418 return;
04419
04420 QRect range=selectionInfo()->activeElement()->rect().normalize();
04421
04422 double positions[4];
04423 bool paintSides[4];
04424
04425 bool current = QRect(selectionInfo()->anchor(), selectionInfo()->marker()).normalize() == range;
04426 QPen pen( Qt::black, 2 );
04427 painter.setPen( pen );
04428
04429 retrieveMarkerInfo( selectionInfo()->extendToMergedAreas(range), viewRect, positions, paintSides );
04430
04431 double left = positions[0];
04432 double top = positions[1];
04433 double right = positions[2];
04434 double bottom = positions[3];
04435
04436 bool paintLeft = paintSides[0];
04437 bool paintTop = paintSides[1];
04438 bool paintRight = paintSides[2];
04439 bool paintBottom = paintSides[3];
04440
04441
04442
04443
04444
04445
04446
04447 int l = 1;
04448
04449 if ( paintTop )
04450 {
04451 painter.drawLine( d->view->doc()->zoomItX( left ) - l, d->view->doc()->zoomItY( top ),
04452 d->view->doc()->zoomItX( right ) + l, d->view->doc()->zoomItY( top ) );
04453 }
04454 if ( activeSheet()->layoutDirection()==Sheet::RightToLeft )
04455 {
04456 if ( paintRight )
04457 {
04458 painter.drawLine( d->view->doc()->zoomItX( right ), d->view->doc()->zoomItY( top ),
04459 d->view->doc()->zoomItX( right ), d->view->doc()->zoomItY( bottom ) );
04460 }
04461 if ( paintLeft && paintBottom && current )
04462 {
04463
04464 painter.drawLine( d->view->doc()->zoomItX( left ), d->view->doc()->zoomItY( top ),
04465 d->view->doc()->zoomItX( left ), d->view->doc()->zoomItY( bottom ) - 3 );
04466 painter.drawLine( d->view->doc()->zoomItX( left ) + 4, d->view->doc()->zoomItY( bottom ),
04467 d->view->doc()->zoomItX( right ) + l + 1, d->view->doc()->zoomItY( bottom ) );
04468 painter.fillRect( d->view->doc()->zoomItX( left ) - 2, d->view->doc()->zoomItY( bottom ) -2, 5, 5,
04469 painter.pen().color() );
04470 }
04471 else
04472 {
04473 if ( paintLeft )
04474 {
04475 painter.drawLine( d->view->doc()->zoomItX( left ), d->view->doc()->zoomItY( top ),
04476 d->view->doc()->zoomItX( left ), d->view->doc()->zoomItY( bottom ) );
04477 }
04478 if ( paintBottom )
04479 {
04480 painter.drawLine( d->view->doc()->zoomItX( left ) - l, d->view->doc()->zoomItY( bottom ),
04481 d->view->doc()->zoomItX( right ) + l + 1, d->view->doc()->zoomItY( bottom ));
04482 }
04483 }
04484 }
04485 else
04486 {
04487 if ( paintLeft )
04488 {
04489 painter.drawLine( d->view->doc()->zoomItX( left ), d->view->doc()->zoomItY( top ),
04490 d->view->doc()->zoomItX( left ), d->view->doc()->zoomItY( bottom ) );
04491 }
04492 if ( paintRight && paintBottom && current )
04493 {
04494
04495 painter.drawLine( d->view->doc()->zoomItX( right ), d->view->doc()->zoomItY( top ),
04496 d->view->doc()->zoomItX( right ), d->view->doc()->zoomItY( bottom ) - 3 );
04497 painter.drawLine( d->view->doc()->zoomItX( left ) - l, d->view->doc()->zoomItY( bottom ),
04498 d->view->doc()->zoomItX( right ) - 3, d->view->doc()->zoomItY( bottom ) );
04499 painter.fillRect( d->view->doc()->zoomItX( right ) - 2, d->view->doc()->zoomItY( bottom ) - 2, 5, 5,
04500 painter.pen().color() );
04501 }
04502 else
04503 {
04504 if ( paintRight )
04505 {
04506 painter.drawLine( d->view->doc()->zoomItX( right ), d->view->doc()->zoomItY( top ),
04507 d->view->doc()->zoomItX( right ), d->view->doc()->zoomItY( bottom ) );
04508 }
04509 if ( paintBottom )
04510 {
04511 painter.drawLine( d->view->doc()->zoomItX( left ) - l, d->view->doc()->zoomItY( bottom ),
04512 d->view->doc()->zoomItX( right ) + l + 1, d->view->doc()->zoomItY( bottom ) );
04513 }
04514 }
04515 }
04516 }
04517
04518 void Canvas::sheetAreaToRect(const QRect& sheetArea, KoRect& rect)
04519 {
04520 Sheet* sheet=activeSheet();
04521
04522 if ( sheet->layoutDirection()==Sheet::RightToLeft )
04523 {
04524 rect.setLeft(sheet->dblColumnPos( sheetArea.right()+1 ) );
04525 rect.setRight(sheet->dblColumnPos( sheetArea.left() ));
04526 }
04527 else
04528 {
04529 rect.setLeft(sheet->dblColumnPos( sheetArea.left() ));
04530 rect.setRight(sheet->dblColumnPos( sheetArea.right()+1 ));
04531 }
04532
04533 rect.setTop(sheet->dblRowPos(sheetArea.top()));
04534 rect.setBottom(sheet->dblRowPos(sheetArea.bottom()+1));
04535
04536 }
04537
04538 void Canvas::sheetAreaToVisibleRect( const QRect& sheetArea,
04539 KoRect& visibleRect )
04540 {
04541 Sheet* sheet=activeSheet();
04542
04543 if (!sheet)
04544 return;
04545
04546 double dwidth=d->view->doc()->unzoomItX(width());
04547 double xpos;
04548 double x;
04549
04550 if ( sheet->layoutDirection()==Sheet::RightToLeft )
04551 {
04552 xpos = dwidth - sheet->dblColumnPos( sheetArea.right() ) + xOffset();
04553 x = dwidth - sheet->dblColumnPos( sheetArea.left() ) + xOffset();
04554 }
04555 else
04556 {
04557 xpos = sheet->dblColumnPos( sheetArea.left() ) - xOffset();
04558 x = sheet->dblColumnPos( sheetArea.right() ) - xOffset();
04559 }
04560
04561 double ypos = sheet->dblRowPos(sheetArea.top())-yOffset();
04562
04563 const ColumnFormat *columnFormat = sheet->columnFormat( sheetArea.right() );
04564 double tw = columnFormat->dblWidth( );
04565 double w = x - xpos + tw;
04566
04567 double y = sheet->dblRowPos( sheetArea.bottom() ) - yOffset();
04568 const RowFormat* rowFormat = sheet->rowFormat( sheetArea.bottom() );
04569 double th = rowFormat->dblHeight( );
04570 double h = ( y - ypos ) + th;
04571
04572
04573 if ( sheet->layoutDirection()==Sheet::RightToLeft )
04574 {
04575 visibleRect.setLeft(xpos - tw );
04576 visibleRect.setRight(xpos - tw + w );
04577 }
04578 else
04579 {
04580 visibleRect.setLeft(xpos );
04581 visibleRect.setRight(xpos + w );
04582 }
04583 visibleRect.setTop(ypos);
04584 visibleRect.setBottom(ypos + h);
04585 }
04586
04587 void Canvas::retrieveMarkerInfo( const QRect &marker,
04588 const KoRect &viewRect,
04589 double positions[],
04590 bool paintSides[] )
04591 {
04592
04593 Sheet* sheet=activeSheet();
04594
04595 if (!sheet) return;
04596
04597 KoRect visibleRect;
04598 sheetAreaToVisibleRect(marker,visibleRect);
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645 double left = visibleRect.left();
04646 double top = visibleRect.top();
04647 double right = visibleRect.right();
04648 double bottom = visibleRect.bottom();
04649
04650
04651 paintSides[0] = (viewRect.left() <= left) && (left <= viewRect.right()) &&
04652 (bottom >= viewRect.top()) && (top <= viewRect.bottom());
04653 paintSides[1] = (viewRect.top() <= top) && (top <= viewRect.bottom())
04654 && (right >= viewRect.left()) && (left <= viewRect.right());
04655 if ( sheet->layoutDirection()==Sheet::RightToLeft )
04656 paintSides[2] = (viewRect.left() <= right ) &&
04657 (right - 1 <= viewRect.right()) &&
04658 (bottom >= viewRect.top()) && (top <= viewRect.bottom());
04659 else
04660 paintSides[2] = (viewRect.left() <= right ) &&
04661 (right <= viewRect.right()) &&
04662 (bottom >= viewRect.top()) && (top <= viewRect.bottom());
04663 paintSides[3] = (viewRect.top() <= bottom) && (bottom <= viewRect.bottom())
04664 && (right >= viewRect.left()) && (left <= viewRect.right());
04665
04666 positions[0] = QMAX( left, viewRect.left() );
04667 positions[1] = QMAX( top, viewRect.top() );
04668 positions[2] = QMIN( right, viewRect.right() );
04669 positions[3] = QMIN( bottom, viewRect.bottom() );
04670 }
04671
04672
04673
04674
04675
04676
04677
04678
04679 VBorder::VBorder( QWidget *_parent, Canvas *_canvas, View *_view)
04680 : QWidget( _parent, "", WStaticContents | WResizeNoErase | WRepaintNoErase )
04681 {
04682 m_pView = _view;
04683 m_pCanvas = _canvas;
04684 m_lSize = 0L;
04685
04686 setBackgroundMode( PaletteButton );
04687 setMouseTracking( true );
04688 m_bResize = false;
04689 m_bSelection = false;
04690 m_iSelectionAnchor=1;
04691 m_bMousePressed = false;
04692
04693 m_scrollTimer = new QTimer( this );
04694 connect (m_scrollTimer, SIGNAL( timeout() ), this, SLOT( doAutoScroll() ) );
04695 }
04696
04697
04698 VBorder::~VBorder()
04699 {
04700 delete m_scrollTimer;
04701 }
04702
04703 QSize VBorder::sizeHint() const
04704 {
04705 return QSize( 40, 10 );
04706 }
04707
04708
04709 void VBorder::mousePressEvent( QMouseEvent * _ev )
04710 {
04711 if ( !m_pView->koDocument()->isReadWrite() )
04712 return;
04713
04714 if ( _ev->button() == LeftButton )
04715 m_bMousePressed = true;
04716
04717 const Sheet *sheet = m_pCanvas->activeSheet();
04718 if (!sheet)
04719 return;
04720
04721 double ev_PosY = m_pCanvas->d->view->doc()->unzoomItY( _ev->pos().y() ) + m_pCanvas->yOffset();
04722 double dHeight = m_pCanvas->d->view->doc()->unzoomItY( height() );
04723 m_bResize = false;
04724 m_bSelection = false;
04725
04726
04727 if ( m_pCanvas->editor() )
04728 {
04729 m_pCanvas->deleteEditor( true );
04730 }
04731
04732 m_scrollTimer->start( 50 );
04733
04734
04735 double y;
04736 int row = sheet->topRow( m_pCanvas->yOffset(), y );
04737
04738
04739 while ( y < ( dHeight + m_pCanvas->yOffset() ) && ( !m_bResize ) )
04740 {
04741 double h = sheet->rowFormat( row )->dblHeight();
04742 row++;
04743 if ( row > KS_rowMax )
04744 row = KS_rowMax;
04745 if ( ( ev_PosY >= y + h - 2 ) &&
04746 ( ev_PosY <= y + h + 1 ) &&
04747 !( sheet->rowFormat( row )->isHide() && row == 1 ) )
04748 m_bResize = true;
04749 y += h;
04750 }
04751
04752
04753
04754 double tmp2;
04755 int tmpRow = sheet->topRow( ev_PosY - 1, tmp2 );
04756 if ( sheet->rowFormat( tmpRow )->isHide() && tmpRow == 1 )
04757 m_bResize = false;
04758
04759
04760 if ( m_bResize )
04761 {
04762
04763 double tmp;
04764 m_iResizedRow = sheet->topRow( ev_PosY - 1, tmp );
04765 if ( !sheet->isProtected() )
04766 paintSizeIndicator( _ev->pos().y(), true );
04767 }
04768 else
04769 {
04770 m_bSelection = true;
04771
04772 double tmp;
04773 int hit_row = sheet->topRow( ev_PosY, tmp );
04774 if ( hit_row > KS_rowMax )
04775 return;
04776
04777 m_iSelectionAnchor = hit_row;
04778
04779 if ( !m_pView->selectionInfo()->contains( QPoint(1, hit_row) ) ||
04780 !( _ev->button() == RightButton ) ||
04781 !m_pView->selectionInfo()->isRowSelected() )
04782 {
04783 QPoint newMarker( 1, hit_row );
04784 QPoint newAnchor( KS_colMax, hit_row );
04785 #ifdef NONCONTIGUOUSSELECTION
04786 if (_ev->state() == ControlButton)
04787 {
04788 m_pView->selectionInfo()->extend(QRect(newAnchor, newMarker));
04789 }
04790 else
04791 #endif
04792 if (_ev->state() == ShiftButton)
04793 {
04794 m_pView->selectionInfo()->update(newMarker);
04795 }
04796 else
04797 {
04798 m_pView->selectionInfo()->initialize(QRect(newAnchor, newMarker));
04799 }
04800 }
04801
04802 if ( _ev->button() == RightButton )
04803 {
04804 QPoint p = mapToGlobal( _ev->pos() );
04805 m_pView->popupRowMenu( p );
04806 m_bSelection = false;
04807 }
04808 m_pView->updateEditWidget();
04809 }
04810 }
04811
04812 void VBorder::mouseReleaseEvent( QMouseEvent * _ev )
04813 {
04814 if ( m_scrollTimer->isActive() )
04815 m_scrollTimer->stop();
04816
04817 m_bMousePressed = false;
04818
04819 if ( !m_pView->koDocument()->isReadWrite() )
04820 return;
04821
04822 Sheet *sheet = m_pCanvas->activeSheet();
04823 if (!sheet)
04824 return;
04825
04826 double ev_PosY = m_pCanvas->d->view->doc()->unzoomItY( _ev->pos().y() ) + m_pCanvas->yOffset();
04827
04828 if ( m_bResize )
04829 {
04830
04831 QPainter painter;
04832 painter.begin( m_pCanvas );
04833 painter.setRasterOp( NotROP );
04834 painter.drawLine( 0, m_iResizePos, m_pCanvas->width(), m_iResizePos );
04835 painter.end();
04836
04837 int start = m_iResizedRow;
04838 int end = m_iResizedRow;
04839 QRect rect;
04840 rect.setCoords( 1, m_iResizedRow, KS_colMax, m_iResizedRow );
04841 if ( m_pView->selectionInfo()->isRowSelected() )
04842 {
04843 if ( m_pView->selectionInfo()->contains( QPoint( 1, m_iResizedRow ) ) )
04844 {
04845 start = m_pView->selectionInfo()->lastRange().top();
04846 end = m_pView->selectionInfo()->lastRange().bottom();
04847 rect = m_pView->selectionInfo()->lastRange();
04848 }
04849 }
04850
04851 double height = 0.0;
04852 double y = sheet->dblRowPos( m_iResizedRow );
04853 if ( ev_PosY - y <= 0.0 )
04854 height = 0.0;
04855 else
04856 height = ev_PosY - y;
04857
04858 if ( !sheet->isProtected() )
04859 {
04860 if ( !m_pCanvas->d->view->doc()->undoLocked() )
04861 {
04862
04863 if ( height != 0.0 )
04864 {
04865
04866 UndoResizeColRow *undo = new UndoResizeColRow( m_pCanvas->d->view->doc(), m_pCanvas->activeSheet(), rect );
04867 m_pCanvas->d->view->doc()->addCommand( undo );
04868 }
04869 }
04870
04871 for( int i = start; i <= end; i++ )
04872 {
04873 RowFormat *rl = sheet->nonDefaultRowFormat( i );
04874 if ( height != 0.0 )
04875 {
04876 if ( !rl->isHide() )
04877 rl->setDblHeight( height );
04878 }
04879 else
04880 {
04881 sheet->hideRow(*m_pView->selectionInfo());
04882 }
04883 }
04884
04885 delete m_lSize;
04886 m_lSize = 0;
04887 }
04888 }
04889 else if ( m_bSelection )
04890 {
04891 QRect rect = m_pView->selectionInfo()->lastRange();
04892
04893
04894
04895 bool m_frozen = false;
04896 if ( m_frozen )
04897 {
04898 kdDebug(36001) << "selected: T " << rect.top() << " B " << rect.bottom() << endl;
04899
04900 int i;
04901 RowFormat * row;
04902 QValueList<int>hiddenRows;
04903
04904 for ( i = rect.top(); i <= rect.bottom(); ++i )
04905 {
04906 row = m_pView->activeSheet()->rowFormat( i );
04907 if ( row->isHide() )
04908 {
04909 hiddenRows.append(i);
04910 }
04911 }
04912
04913 if ( hiddenRows.count() > 0 )
04914 m_pView->activeSheet()->showRow(*m_pView->selectionInfo());
04915 }
04916 }
04917
04918 m_bSelection = false;
04919 m_bResize = false;
04920 }
04921
04922 void VBorder::equalizeRow( double resize )
04923 {
04924 Sheet *sheet = m_pCanvas->activeSheet();
04925 Q_ASSERT( sheet );
04926
04927 QRect selection( m_pView->selectionInfo()->selection() );
04928 if ( !m_pCanvas->d->view->doc()->undoLocked() )
04929 {
04930 UndoResizeColRow *undo = new UndoResizeColRow( m_pCanvas->d->view->doc(), m_pCanvas->activeSheet(), selection );
04931 m_pCanvas->d->view->doc()->addCommand( undo );
04932 }
04933 RowFormat *rl;
04934 for ( int i = selection.top(); i <= selection.bottom(); i++ )
04935 {
04936 rl = sheet->nonDefaultRowFormat( i );
04937 resize = QMAX( 2.0, resize);
04938 rl->setDblHeight( resize );
04939 }
04940 }
04941
04942 void VBorder::mouseDoubleClickEvent(QMouseEvent*)
04943 {
04944 Sheet *sheet = m_pCanvas->activeSheet();
04945 if (!sheet)
04946 return;
04947
04948 if ( !m_pView->koDocument()->isReadWrite() || sheet->isProtected() )
04949 return;
04950
04951 sheet->adjustRow(*m_pCanvas->selectionInfo());
04952 }
04953
04954
04955 void VBorder::mouseMoveEvent( QMouseEvent * _ev )
04956 {
04957 if ( !m_pView->koDocument()->isReadWrite() )
04958 return;
04959
04960 Sheet *sheet = m_pCanvas->activeSheet();
04961
04962 if (!sheet)
04963 return;
04964
04965 double ev_PosY = m_pCanvas->d->view->doc()->unzoomItY( _ev->pos().y() ) + m_pCanvas->yOffset();
04966 double dHeight = m_pCanvas->d->view->doc()->unzoomItY( height() );
04967
04968
04969 if ( m_bResize )
04970 {
04971 if ( !sheet->isProtected() )
04972 paintSizeIndicator( _ev->pos().y(), false );
04973 }
04974
04975 else if ( m_bSelection )
04976 {
04977 double y;
04978 int row = sheet->topRow( ev_PosY, y );
04979 if ( row > KS_rowMax )
04980 return;
04981
04982 QPoint newAnchor = m_pView->selectionInfo()->anchor();
04983 QPoint newMarker = m_pView->selectionInfo()->marker();
04984 newMarker.setY( row );
04985 newAnchor.setY( m_iSelectionAnchor );
04986 m_pView->selectionInfo()->update(newMarker);
04987
04988 if ( _ev->pos().y() < 0 )
04989 m_pCanvas->vertScrollBar()->setValue( m_pCanvas->d->view->doc()->zoomItY( ev_PosY ) );
04990 else if ( _ev->pos().y() > m_pCanvas->height() )
04991 {
04992 if ( row < KS_rowMax )
04993 {
04994 RowFormat *rl = sheet->rowFormat( row + 1 );
04995 y = sheet->dblRowPos( row + 1 );
04996 m_pCanvas->vertScrollBar()->setValue ((int) (m_pCanvas->d->view->doc()->zoomItY
04997 (ev_PosY + rl->dblHeight()) - dHeight));
04998 }
04999 }
05000 }
05001
05002 else
05003 {
05004
05005
05006 const double unzoomedPixel = m_pCanvas->d->view->doc()->unzoomItY( 1 );
05007 double y;
05008 int tmpRow = sheet->topRow( m_pCanvas->yOffset(), y );
05009
05010 while ( y < m_pCanvas->d->view->doc()->unzoomItY( height() ) + m_pCanvas->yOffset() )
05011 {
05012 double h = sheet->rowFormat( tmpRow )->dblHeight();
05013
05014
05015 if ( ev_PosY >= y + h - 2 * unzoomedPixel &&
05016 ev_PosY <= y + h + unzoomedPixel &&
05017 !( sheet->rowFormat( tmpRow )->isHide() && tmpRow == 1 ) )
05018 {
05019 setCursor( splitVCursor );
05020 return;
05021 }
05022 y += h;
05023 tmpRow++;
05024 }
05025 setCursor( arrowCursor );
05026 }
05027 }
05028
05029 void VBorder::doAutoScroll()
05030 {
05031 if ( !m_bMousePressed )
05032 {
05033 m_scrollTimer->stop();
05034 return;
05035 }
05036
05037 QPoint pos( mapFromGlobal( QCursor::pos() ) );
05038
05039 if ( pos.y() < 0 || pos.y() > height() )
05040 {
05041 QMouseEvent * event = new QMouseEvent( QEvent::MouseMove, pos, 0, 0 );
05042 mouseMoveEvent( event );
05043 delete event;
05044 }
05045
05046
05047 m_scrollTimer->start( 50 );
05048 }
05049
05050 void VBorder::wheelEvent( QWheelEvent* _ev )
05051 {
05052 if ( m_pCanvas->vertScrollBar() )
05053 QApplication::sendEvent( m_pCanvas->vertScrollBar(), _ev );
05054 }
05055
05056
05057 void VBorder::paintSizeIndicator( int mouseY, bool firstTime )
05058 {
05059 Sheet *sheet = m_pCanvas->activeSheet();
05060 if (!sheet)
05061 return;
05062
05063 QPainter painter;
05064 painter.begin( m_pCanvas );
05065 painter.setRasterOp( NotROP );
05066
05067 if ( !firstTime )
05068 painter.drawLine( 0, m_iResizePos, m_pCanvas->width(), m_iResizePos );
05069
05070 m_iResizePos = mouseY;
05071
05072
05073 int y = m_pCanvas->d->view->doc()->zoomItY( sheet->dblRowPos( m_iResizedRow ) - m_pCanvas->yOffset() );
05074 if ( m_iResizePos < y + 2 )
05075 m_iResizePos = y;
05076
05077 painter.drawLine( 0, m_iResizePos, m_pCanvas->width(), m_iResizePos );
05078
05079 painter.end();
05080
05081 QString tmpSize;
05082 if ( m_iResizePos != y )
05083 tmpSize = i18n("Height: %1 %2").arg( KoUnit::toUserValue( m_pCanvas->doc()->unzoomItY( m_iResizePos - y ),
05084 m_pView->doc()->unit() ) )
05085 .arg( m_pView->doc()->unitName() );
05086 else
05087 tmpSize = i18n( "Hide Row" );
05088
05089 painter.begin( this );
05090 int len = painter.fontMetrics().width( tmpSize );
05091 int hei = painter.fontMetrics().height();
05092 painter.end();
05093
05094 if ( !m_lSize )
05095 {
05096 m_lSize = new QLabel( m_pCanvas );
05097
05098 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05099 m_lSize->setGeometry( m_pCanvas->width() - len - 5,
05100 y + 3, len + 2, hei + 2 );
05101 else
05102 m_lSize->setGeometry( 3, y + 3, len + 2,hei + 2 );
05103
05104 m_lSize->setAlignment( Qt::AlignVCenter );
05105 m_lSize->setText( tmpSize );
05106 m_lSize->setPalette( QToolTip::palette() );
05107 m_lSize->show();
05108 }
05109 else
05110 {
05111 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05112 m_lSize->setGeometry( m_pCanvas->width() - len - 5,
05113 y + 3, len + 2, hei + 2 );
05114 else
05115 m_lSize->setGeometry( 3, y + 3, len + 2,hei + 2 );
05116
05117 m_lSize->setText( tmpSize );
05118 }
05119 }
05120
05121 void VBorder::updateRows( int from, int to )
05122 {
05123 Sheet *sheet = m_pCanvas->activeSheet();
05124 if ( !sheet )
05125 return;
05126
05127 int y0 = sheet->rowPos( from, m_pCanvas );
05128 int y1 = sheet->rowPos( to+1, m_pCanvas );
05129 update( 0, y0, width(), y1-y0 );
05130 }
05131
05132 void VBorder::paintEvent( QPaintEvent* _ev )
05133 {
05134 Sheet *sheet = m_pCanvas->activeSheet();
05135 if ( !sheet )
05136 return;
05137
05138 QPainter painter( this );
05139 QColor highlightColor = View::highlightColor();
05140 QPen pen( Qt::black, 1 );
05141 painter.setPen( pen );
05142
05143
05144
05145
05146
05147
05148
05149
05150
05151 painter.setClipRect( _ev->rect() );
05152
05153 double yPos;
05154
05155 int y = sheet->topRow( (m_pCanvas->d->view->doc()->unzoomItY( _ev->rect().y() ) + m_pCanvas->yOffset()), yPos );
05156
05157 yPos = yPos - m_pCanvas->yOffset();
05158 int width = m_pCanvas->d->view->doc()->zoomItX( YBORDER_WIDTH );
05159
05160 QFont normalFont = painter.font();
05161 if ( m_pCanvas->d->view->doc()->zoom() < 100 )
05162 {
05163 normalFont.setPointSizeFloat( 0.01 * m_pCanvas->d->view->doc()->zoom() *
05164 normalFont.pointSizeFloat() );
05165 }
05166 QFont boldFont = normalFont;
05167 boldFont.setBold( true );
05168
05169
05170 while ( yPos <= m_pCanvas->d->view->doc()->unzoomItY( _ev->rect().bottom() ) )
05171 {
05172 bool selected = (m_pView->selectionInfo()->isRowSelected(y));
05173 bool highlighted = (!selected && m_pView->selectionInfo()->isRowAffected(y));
05174
05175 const RowFormat *row_lay = sheet->rowFormat( y );
05176 int zoomedYPos = m_pCanvas->d->view->doc()->zoomItY( yPos );
05177 int height = m_pCanvas->d->view->doc()->zoomItY( yPos + row_lay->dblHeight() ) - zoomedYPos;
05178
05179 if ( selected )
05180 {
05181 QBrush fillSelected( highlightColor );
05182 qDrawPlainRect ( &painter, 0, zoomedYPos, width, height+1, highlightColor.dark(150),
05183 1, &fillSelected );
05184 }
05185 else if ( highlighted )
05186 {
05187 QBrush fillHighlighted( highlightColor );
05188 qDrawPlainRect ( &painter, 0, zoomedYPos, width, height+1, highlightColor.dark(150),
05189 1, &fillHighlighted );
05190 }
05191 else
05192 {
05193 QColor c = colorGroup().background();
05194 QBrush fill( c );
05195 qDrawPlainRect ( &painter, 0, zoomedYPos, width, height+1, c.dark(150),
05196 1, &fill );
05197 }
05198
05199 QString rowText = QString::number( y );
05200
05201
05202 painter.setFont( normalFont );
05203 painter.setPen( colorGroup().text() );
05204
05205 if ( selected )
05206 painter.setPen( colorGroup().highlightedText() );
05207 else if ( highlighted )
05208 painter.setFont( boldFont );
05209
05210 int len = painter.fontMetrics().width( rowText );
05211 if (!row_lay->isHide())
05212 painter.drawText( ( width-len )/2, zoomedYPos +
05213 ( height + painter.fontMetrics().ascent() -
05214 painter.fontMetrics().descent() ) / 2, rowText );
05215
05216 yPos += row_lay->dblHeight();
05217 y++;
05218 }
05219 }
05220
05221
05222 void VBorder::focusOutEvent( QFocusEvent* )
05223 {
05224 if ( m_scrollTimer->isActive() )
05225 m_scrollTimer->stop();
05226 m_bMousePressed = false;
05227 }
05228
05229
05230
05231
05232
05233
05234
05235
05236 HBorder::HBorder( QWidget *_parent, Canvas *_canvas,View *_view )
05237 : QWidget( _parent, "", WStaticContents| WResizeNoErase | WRepaintNoErase )
05238 {
05239 m_pView = _view;
05240 m_pCanvas = _canvas;
05241 m_lSize = 0L;
05242 setBackgroundMode( PaletteButton );
05243 setMouseTracking( true );
05244 m_bResize = false;
05245 m_bSelection = false;
05246 m_iSelectionAnchor=1;
05247 m_bMousePressed = false;
05248
05249 m_scrollTimer = new QTimer( this );
05250 connect( m_scrollTimer, SIGNAL( timeout() ), this, SLOT( doAutoScroll() ) );
05251 }
05252
05253
05254 HBorder::~HBorder()
05255 {
05256 delete m_scrollTimer;
05257 }
05258
05259 QSize HBorder::sizeHint() const
05260 {
05261 return QSize( 40, 10 );
05262 }
05263
05264 void HBorder::mousePressEvent( QMouseEvent * _ev )
05265 {
05266 if (!m_pView->koDocument()->isReadWrite())
05267 return;
05268
05269 if ( _ev->button() == LeftButton )
05270 m_bMousePressed = true;
05271
05272 const Sheet *sheet = m_pCanvas->activeSheet();
05273 if (!sheet)
05274 return;
05275
05276
05277 if ( m_pCanvas->editor() )
05278 {
05279 m_pCanvas->deleteEditor( true );
05280 }
05281
05282 m_scrollTimer->start( 50 );
05283
05284 double ev_PosX;
05285 double dWidth = m_pCanvas->d->view->doc()->unzoomItX( width() );
05286 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05287 ev_PosX = dWidth - m_pCanvas->d->view->doc()->unzoomItX( _ev->pos().x() ) + m_pCanvas->xOffset();
05288 else
05289 ev_PosX = m_pCanvas->d->view->doc()->unzoomItX( _ev->pos().x() ) + m_pCanvas->xOffset();
05290 m_bResize = false;
05291 m_bSelection = false;
05292
05293
05294 double x;
05295
05296 const double unzoomedPixel = m_pCanvas->d->view->doc()->unzoomItX( 1 );
05297 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05298 {
05299 int tmpCol = sheet->leftColumn( m_pCanvas->xOffset(), x );
05300
05301 kdDebug() << "evPos: " << ev_PosX << ", x: " << x << ", COL: " << tmpCol << endl;
05302 while ( ev_PosX > x && ( !m_bResize ) )
05303 {
05304 double w = sheet->columnFormat( tmpCol )->dblWidth();
05305
05306 kdDebug() << "evPos: " << ev_PosX << ", x: " << x << ", w: " << w << ", COL: " << tmpCol << endl;
05307
05308 ++tmpCol;
05309 if ( tmpCol > KS_colMax )
05310 tmpCol = KS_colMax;
05311
05312
05313
05314 if ( ev_PosX >= x + w - unzoomedPixel &&
05315 ev_PosX <= x + w + unzoomedPixel &&
05316 !( sheet->columnFormat( tmpCol )->isHide() && tmpCol == 1 ) )
05317 {
05318 m_bResize = true;
05319 }
05320 x += w;
05321 }
05322
05323
05324
05325 double tmp2;
05326 tmpCol = sheet->leftColumn( dWidth - ev_PosX + 1, tmp2 );
05327 if ( sheet->columnFormat( tmpCol )->isHide() && tmpCol == 0 )
05328 {
05329 kdDebug() << "No resize: " << tmpCol << ", " << sheet->columnFormat( tmpCol )->isHide() << endl;
05330 m_bResize = false;
05331 }
05332
05333 kdDebug() << "Resize: " << m_bResize << endl;
05334 }
05335 else
05336 {
05337 int col = sheet->leftColumn( m_pCanvas->xOffset(), x );
05338
05339
05340 while ( x < ( dWidth + m_pCanvas->xOffset() ) && ( !m_bResize ) )
05341 {
05342 double w = sheet->columnFormat( col )->dblWidth();
05343 col++;
05344 if ( col > KS_colMax )
05345 col = KS_colMax;
05346 if ( ( ev_PosX >= x + w - unzoomedPixel ) &&
05347 ( ev_PosX <= x + w + unzoomedPixel ) &&
05348 !( sheet->columnFormat( col )->isHide() && col == 1 ) )
05349 m_bResize = true;
05350 x += w;
05351 }
05352
05353
05354
05355 double tmp2;
05356 int tmpCol = sheet->leftColumn( ev_PosX - 1, tmp2 );
05357 if ( sheet->columnFormat( tmpCol )->isHide() && tmpCol == 1 )
05358 m_bResize = false;
05359 }
05360
05361
05362 if ( m_bResize )
05363 {
05364
05365 double tmp;
05366 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05367 {
05368 m_iResizedColumn = sheet->leftColumn( ev_PosX - 1, tmp );
05369
05370
05371 if ( !sheet->isProtected() )
05372 paintSizeIndicator( _ev->pos().x(), true );
05373 }
05374 else
05375 {
05376 m_iResizedColumn = sheet->leftColumn( ev_PosX - 1, tmp );
05377
05378 if ( !sheet->isProtected() )
05379 paintSizeIndicator( _ev->pos().x(), true );
05380 }
05381
05382
05383 }
05384 else
05385 {
05386 m_bSelection = true;
05387
05388 double tmp;
05389 int hit_col = sheet->leftColumn( ev_PosX, tmp );
05390 if ( hit_col > KS_colMax )
05391 return;
05392
05393 m_iSelectionAnchor = hit_col;
05394
05395 if ( !m_pView->selectionInfo()->contains( QPoint( hit_col, 1 ) ) ||
05396 !( _ev->button() == RightButton ) ||
05397 !m_pView->selectionInfo()->isColumnSelected() )
05398 {
05399 QPoint newMarker( hit_col, 1 );
05400 QPoint newAnchor( hit_col, KS_rowMax );
05401 #ifdef NONCONTIGUOUSSELECTION
05402 if (_ev->state() == ControlButton)
05403 {
05404 m_pView->selectionInfo()->extend(QRect(newAnchor, newMarker));
05405 }
05406 else
05407 #endif
05408 if (_ev->state() == ShiftButton)
05409 {
05410 m_pView->selectionInfo()->update(newMarker);
05411 }
05412 else
05413 {
05414 m_pView->selectionInfo()->initialize(QRect(newAnchor, newMarker));
05415 }
05416 }
05417
05418 if ( _ev->button() == RightButton )
05419 {
05420 QPoint p = mapToGlobal( _ev->pos() );
05421 m_pView->popupColumnMenu( p );
05422 m_bSelection = false;
05423 }
05424 m_pView->updateEditWidget();
05425 }
05426 }
05427
05428 void HBorder::mouseReleaseEvent( QMouseEvent * _ev )
05429 {
05430 if ( m_scrollTimer->isActive() )
05431 m_scrollTimer->stop();
05432
05433 m_bMousePressed = false;
05434
05435 if ( !m_pView->koDocument()->isReadWrite() )
05436 return;
05437
05438 Sheet * sheet = m_pCanvas->activeSheet();
05439 if (!sheet)
05440 return;
05441
05442 if ( m_bResize )
05443 {
05444 double dWidth = m_pCanvas->d->view->doc()->unzoomItX( width() );
05445 double ev_PosX;
05446
05447
05448 QPainter painter;
05449 painter.begin( m_pCanvas );
05450 painter.setRasterOp( NotROP );
05451 painter.drawLine( m_iResizePos, 0, m_iResizePos, m_pCanvas->height() );
05452 painter.end();
05453
05454 int start = m_iResizedColumn;
05455 int end = m_iResizedColumn;
05456 QRect rect;
05457 rect.setCoords( m_iResizedColumn, 1, m_iResizedColumn, KS_rowMax );
05458 if ( m_pView->selectionInfo()->isColumnSelected() )
05459 {
05460 if ( m_pView->selectionInfo()->contains( QPoint( m_iResizedColumn, 1 ) ) )
05461 {
05462 start = m_pView->selectionInfo()->lastRange().left();
05463 end = m_pView->selectionInfo()->lastRange().right();
05464 rect = m_pView->selectionInfo()->lastRange();
05465 }
05466 }
05467
05468 double width = 0.0;
05469 double x;
05470
05471 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05472 ev_PosX = dWidth - m_pCanvas->d->view->doc()->unzoomItX( _ev->pos().x() ) + m_pCanvas->xOffset();
05473 else
05474 ev_PosX = m_pCanvas->d->view->doc()->unzoomItX( _ev->pos().x() ) + m_pCanvas->xOffset();
05475
05476 x = sheet->dblColumnPos( m_iResizedColumn );
05477
05478 if ( ev_PosX - x <= 0.0 )
05479 width = 0.0;
05480 else
05481 width = ev_PosX - x;
05482
05483 if ( !sheet->isProtected() )
05484 {
05485 if ( !m_pCanvas->d->view->doc()->undoLocked() )
05486 {
05487
05488 if ( width != 0.0 )
05489 {
05490
05491 UndoResizeColRow *undo = new UndoResizeColRow( m_pCanvas->d->view->doc(), m_pCanvas->activeSheet(), rect );
05492 m_pCanvas->d->view->doc()->addCommand( undo );
05493 }
05494 }
05495
05496 for( int i = start; i <= end; i++ )
05497 {
05498 ColumnFormat *cl = sheet->nonDefaultColumnFormat( i );
05499 if ( width != 0.0 )
05500 {
05501 if ( !cl->isHide() )
05502 cl->setDblWidth( width );
05503 }
05504 else
05505 {
05506 sheet->hideColumn(*m_pView->selectionInfo());
05507 }
05508 }
05509
05510 delete m_lSize;
05511 m_lSize = 0;
05512 }
05513 }
05514 else if ( m_bSelection )
05515 {
05516 QRect rect = m_pView->selectionInfo()->lastRange();
05517
05518
05519
05520 bool m_frozen = false;
05521 if ( m_frozen )
05522 {
05523 kdDebug(36001) << "selected: L " << rect.left() << " R " << rect.right() << endl;
05524
05525 int i;
05526 ColumnFormat * col;
05527 QValueList<int>hiddenCols;
05528
05529 for ( i = rect.left(); i <= rect.right(); ++i )
05530 {
05531 col = m_pView->activeSheet()->columnFormat( i );
05532 if ( col->isHide() )
05533 {
05534 hiddenCols.append(i);
05535 }
05536 }
05537
05538 if ( hiddenCols.count() > 0 )
05539 m_pView->activeSheet()->showColumn(*m_pView->selectionInfo());
05540 }
05541 }
05542
05543 m_bSelection = false;
05544 m_bResize = false;
05545 }
05546
05547 void HBorder::equalizeColumn( double resize )
05548 {
05549 Sheet *sheet = m_pCanvas->activeSheet();
05550 Q_ASSERT( sheet );
05551
05552 QRect selection( m_pView->selectionInfo()->selection() );
05553 if ( !m_pCanvas->d->view->doc()->undoLocked() )
05554 {
05555 UndoResizeColRow *undo = new UndoResizeColRow( m_pCanvas->d->view->doc(), m_pCanvas->activeSheet(), selection );
05556 m_pCanvas->d->view->doc()->addCommand( undo );
05557 }
05558 ColumnFormat *cl;
05559 for ( int i = selection.left(); i <= selection.right(); i++ )
05560 {
05561 cl = sheet->nonDefaultColumnFormat( i );
05562 resize = QMAX( 2.0, resize );
05563 cl->setDblWidth( resize );
05564 }
05565
05566 }
05567
05568 void HBorder::mouseDoubleClickEvent(QMouseEvent*)
05569 {
05570 Sheet *sheet = m_pCanvas->activeSheet();
05571 if (!sheet)
05572 return;
05573
05574 if ( !m_pView->koDocument()->isReadWrite() || sheet->isProtected() )
05575 return;
05576
05577 sheet->adjustColumn(*m_pCanvas->selectionInfo());
05578 }
05579
05580 void HBorder::mouseMoveEvent( QMouseEvent * _ev )
05581 {
05582 if ( !m_pView->koDocument()->isReadWrite() )
05583 return;
05584
05585 Sheet *sheet = m_pCanvas->activeSheet();
05586
05587 if (!sheet)
05588 return;
05589
05590 double dWidth = m_pCanvas->d->view->doc()->unzoomItX( width() );
05591 double ev_PosX;
05592 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05593 ev_PosX = dWidth - m_pCanvas->d->view->doc()->unzoomItX( _ev->pos().x() ) + m_pCanvas->xOffset();
05594 else
05595 ev_PosX = m_pCanvas->d->view->doc()->unzoomItX( _ev->pos().x() ) + m_pCanvas->xOffset();
05596
05597
05598 if ( m_bResize )
05599 {
05600 if ( !sheet->isProtected() )
05601 paintSizeIndicator( _ev->pos().x(), false );
05602 }
05603
05604 else if ( m_bSelection )
05605 {
05606 double x;
05607 int col = sheet->leftColumn( ev_PosX, x );
05608
05609 if ( col > KS_colMax )
05610 return;
05611
05612 QPoint newMarker = m_pView->selectionInfo()->marker();
05613 QPoint newAnchor = m_pView->selectionInfo()->anchor();
05614 newMarker.setX( col );
05615 newAnchor.setX( m_iSelectionAnchor );
05616 m_pView->selectionInfo()->update(newMarker);
05617
05618 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05619 {
05620 if ( _ev->pos().x() < width() - m_pCanvas->width() )
05621 {
05622 ColumnFormat *cl = sheet->columnFormat( col + 1 );
05623 x = sheet->dblColumnPos( col + 1 );
05624 m_pCanvas->horzScrollBar()->setValue ( m_pCanvas->horzScrollBar()->maxValue() - (int)
05625 (m_pCanvas->d->view->doc()->zoomItX (ev_PosX + cl->dblWidth()) - m_pCanvas->d->view->doc()->unzoomItX( m_pCanvas->width() )));
05626 }
05627 else if ( _ev->pos().x() > width() )
05628 m_pCanvas->horzScrollBar()->setValue( m_pCanvas->horzScrollBar()->maxValue() - m_pCanvas->d->view->doc()->zoomItX( ev_PosX - dWidth + m_pCanvas->d->view->doc()->unzoomItX( m_pCanvas->width() ) ) );
05629 }
05630 else
05631 {
05632 if ( _ev->pos().x() < 0 )
05633 m_pCanvas->horzScrollBar()->setValue( m_pCanvas->d->view->doc()->zoomItX( ev_PosX ) );
05634 else if ( _ev->pos().x() > m_pCanvas->width() )
05635 {
05636 if ( col < KS_colMax )
05637 {
05638 ColumnFormat *cl = sheet->columnFormat( col + 1 );
05639 x = sheet->dblColumnPos( col + 1 );
05640 m_pCanvas->horzScrollBar()->setValue ((int)
05641 (m_pCanvas->d->view->doc()->zoomItX (ev_PosX + cl->dblWidth()) - dWidth));
05642 }
05643 }
05644 }
05645
05646 }
05647
05648 else
05649 {
05650
05651 const double unzoomedPixel = m_pCanvas->d->view->doc()->unzoomItX( 1 );
05652 double x;
05653
05654 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05655 {
05656 int tmpCol = sheet->leftColumn( m_pCanvas->xOffset(), x );
05657
05658 while ( ev_PosX > x )
05659 {
05660 double w = sheet->columnFormat( tmpCol )->dblWidth();
05661 ++tmpCol;
05662
05663
05664
05665 if ( ev_PosX >= x + w - unzoomedPixel &&
05666 ev_PosX <= x + w + unzoomedPixel &&
05667 !( sheet->columnFormat( tmpCol )->isHide() && tmpCol == 0 ) )
05668 {
05669 setCursor( splitHCursor );
05670 return;
05671 }
05672 x += w;
05673 }
05674 setCursor( arrowCursor );
05675 }
05676 else
05677 {
05678 int tmpCol = sheet->leftColumn( m_pCanvas->xOffset(), x );
05679
05680 while ( x < m_pCanvas->d->view->doc()->unzoomItY( width() ) + m_pCanvas->xOffset() )
05681 {
05682 double w = sheet->columnFormat( tmpCol )->dblWidth();
05683
05684
05685 if ( ev_PosX >= x + w - unzoomedPixel &&
05686 ev_PosX <= x + w + unzoomedPixel &&
05687 !( sheet->columnFormat( tmpCol )->isHide() && tmpCol == 1 ) )
05688 {
05689 setCursor( splitHCursor );
05690 return;
05691 }
05692 x += w;
05693 tmpCol++;
05694 }
05695 setCursor( arrowCursor );
05696 }
05697 }
05698 }
05699
05700 void HBorder::doAutoScroll()
05701 {
05702 if ( !m_bMousePressed )
05703 {
05704 m_scrollTimer->stop();
05705 return;
05706 }
05707
05708 QPoint pos( mapFromGlobal( QCursor::pos() ) );
05709
05710 if ( pos.x() < 0 || pos.x() > width() )
05711 {
05712 QMouseEvent * event = new QMouseEvent( QEvent::MouseMove, pos, 0, 0 );
05713 mouseMoveEvent( event );
05714 delete event;
05715 }
05716
05717
05718 m_scrollTimer->start( 50 );
05719 }
05720
05721 void HBorder::wheelEvent( QWheelEvent* _ev )
05722 {
05723 if ( m_pCanvas->horzScrollBar() )
05724 QApplication::sendEvent( m_pCanvas->horzScrollBar(), _ev );
05725 }
05726
05727 void HBorder::resizeEvent( QResizeEvent* _ev )
05728 {
05729
05730
05731
05732 if ( m_pCanvas->activeSheet() && m_pCanvas->activeSheet()->layoutDirection()==Sheet::RightToLeft && !QApplication::reverseLayout() )
05733 {
05734 int dx = _ev->size().width() - _ev->oldSize().width();
05735 scroll(dx, 0);
05736 }
05737 else if ( m_pCanvas->activeSheet() && m_pCanvas->activeSheet()->layoutDirection()==Sheet::LeftToRight && QApplication::reverseLayout() )
05738 {
05739 int dx = _ev->size().width() - _ev->oldSize().width();
05740 scroll(-dx, 0);
05741 }
05742 }
05743
05744 void HBorder::paintSizeIndicator( int mouseX, bool firstTime )
05745 {
05746 Sheet *sheet = m_pCanvas->activeSheet();
05747 if (!sheet)
05748 return;
05749
05750 QPainter painter;
05751 painter.begin( m_pCanvas );
05752 painter.setRasterOp( NotROP );
05753
05754 if ( !firstTime )
05755 painter.drawLine( m_iResizePos, 0, m_iResizePos, m_pCanvas->height() );
05756
05757 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05758 m_iResizePos = mouseX + m_pCanvas->width() - width();
05759 else
05760 m_iResizePos = mouseX;
05761
05762
05763 int x = m_pCanvas->d->view->doc()->zoomItX( sheet->dblColumnPos( m_iResizedColumn ) - m_pCanvas->xOffset() );
05764
05765 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05766 {
05767 x = m_pCanvas->width() - x;
05768
05769 if ( m_iResizePos > x - 2 )
05770 m_iResizePos = x;
05771 }
05772 else
05773 {
05774 if ( m_iResizePos < x + 2 )
05775 m_iResizePos = x;
05776 }
05777
05778 painter.drawLine( m_iResizePos, 0, m_iResizePos, m_pCanvas->height() );
05779
05780 painter.end();
05781
05782 QString tmpSize;
05783 if ( m_iResizePos != x )
05784 tmpSize = i18n("Width: %1 %2")
05785 .arg( KGlobal::locale()->formatNumber( KoUnit::toUserValue( m_pCanvas->doc()->unzoomItX( (sheet->layoutDirection()==Sheet::RightToLeft) ? x - m_iResizePos : m_iResizePos - x ),
05786 m_pView->doc()->unit() )))
05787 .arg( m_pView->doc()->unitName() );
05788 else
05789 tmpSize = i18n( "Hide Column" );
05790
05791 painter.begin( this );
05792 int len = painter.fontMetrics().width( tmpSize );
05793 int hei = painter.fontMetrics().height();
05794 painter.end();
05795
05796 if ( !m_lSize )
05797 {
05798 m_lSize = new QLabel( m_pCanvas );
05799
05800 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05801 m_lSize->setGeometry( x - len - 5, 3, len + 2, hei + 2 );
05802 else
05803 m_lSize->setGeometry( x + 3, 3, len + 2, hei + 2 );
05804
05805 m_lSize->setAlignment( Qt::AlignVCenter );
05806 m_lSize->setText( tmpSize );
05807 m_lSize->setPalette( QToolTip::palette() );
05808 m_lSize->show();
05809 }
05810 else
05811 {
05812 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05813 m_lSize->setGeometry( x - len - 5, 3, len + 2, hei + 2 );
05814 else
05815 m_lSize->setGeometry( x + 3, 3, len + 2, hei + 2 );
05816
05817 m_lSize->setText( tmpSize );
05818 }
05819 }
05820
05821 void HBorder::updateColumns( int from, int to )
05822 {
05823 Sheet *sheet = m_pCanvas->activeSheet();
05824 if ( !sheet )
05825 return;
05826
05827 int x0 = sheet->columnPos( from, m_pCanvas );
05828 int x1 = sheet->columnPos( to+1, m_pCanvas );
05829 update( x0, 0, x1-x0, height() );
05830 }
05831
05832 void HBorder::paintEvent( QPaintEvent* _ev )
05833 {
05834 Sheet * sheet = m_pCanvas->activeSheet();
05835 if ( !sheet )
05836 return;
05837
05838 QColor highlightColor = View::highlightColor();
05839 QPainter painter( this );
05840 QPen pen( Qt::black, 1 );
05841 painter.setPen( pen );
05842 painter.setBackgroundColor( white );
05843
05844 painter.setClipRect( _ev->rect() );
05845
05846
05847
05848
05849
05850
05851
05852
05853 double xPos;
05854 int x;
05855
05856 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05857 {
05858
05859 x = sheet->leftColumn( int( m_pCanvas->d->view->doc()->unzoomItX( width() ) - m_pCanvas->d->view->doc()->unzoomItX( _ev->rect().x() ) + m_pCanvas->xOffset() ), xPos );
05860
05861 xPos = m_pCanvas->d->view->doc()->unzoomItX( width() ) - xPos + m_pCanvas->xOffset();
05862 }
05863 else
05864 {
05865
05866 x = sheet->leftColumn( int( m_pCanvas->d->view->doc()->unzoomItX( _ev->rect().x() ) + m_pCanvas->xOffset() ), xPos );
05867
05868 xPos = xPos - m_pCanvas->xOffset();
05869 }
05870
05871 int height = m_pCanvas->d->view->doc()->zoomItY( Format::globalRowHeight() + 2 );
05872
05873 QFont normalFont = painter.font();
05874 if ( m_pCanvas->d->view->doc()->zoom() < 100 )
05875 {
05876 normalFont.setPointSizeFloat( 0.01 * m_pCanvas->d->view->doc()->zoom() *
05877 normalFont.pointSizeFloat() );
05878 }
05879 QFont boldFont = normalFont;
05880 boldFont.setBold( true );
05881
05882 if ( sheet->layoutDirection()==Sheet::RightToLeft )
05883 {
05884 if ( x > KS_colMax )
05885 x = KS_colMax;
05886
05887 xPos -= sheet->columnFormat( x )->dblWidth();
05888
05889
05890 while ( xPos <= m_pCanvas->d->view->doc()->unzoomItX( _ev->rect().right() ) )
05891 {
05892 bool selected = (m_pView->selectionInfo()->isColumnSelected(x));
05893 bool highlighted = (!selected && m_pView->selectionInfo()->isColumnAffected(x));
05894
05895 const ColumnFormat * col_lay = sheet->columnFormat( x );
05896 int zoomedXPos = m_pCanvas->d->view->doc()->zoomItX( xPos );
05897 int width = m_pCanvas->d->view->doc()->zoomItX( xPos + col_lay->dblWidth() ) - zoomedXPos;
05898
05899 if ( selected )
05900 {
05901 QBrush fillSelected( highlightColor );
05902 qDrawPlainRect ( &painter, zoomedXPos, 0, width+1, height, highlightColor.dark(150),
05903 1, &fillSelected );
05904 }
05905 else if ( highlighted )
05906 {
05907 QBrush fillHighlighted( highlightColor );
05908 qDrawPlainRect ( &painter, zoomedXPos, 0, width+1, height, highlightColor.dark(150),
05909 1, &fillHighlighted );
05910 }
05911 else
05912 {
05913 QColor c = colorGroup().background();
05914 QBrush fill( c );
05915 qDrawPlainRect ( &painter, zoomedXPos, 0, width+1, height, c.dark(150),
05916 1, &fill );
05917 }
05918
05919
05920 painter.setFont( normalFont );
05921 painter.setPen( colorGroup().text() );
05922
05923 if ( selected )
05924 painter.setPen( colorGroup().highlightedText() );
05925 else if ( highlighted )
05926 painter.setFont( boldFont );
05927 if ( !m_pView->activeSheet()->getShowColumnNumber() )
05928 {
05929 QString colText = Cell::columnName( x );
05930 int len = painter.fontMetrics().width( colText );
05931 if ( !col_lay->isHide() )
05932 painter.drawText( zoomedXPos + ( width - len ) / 2,
05933 ( height + painter.fontMetrics().ascent() -
05934 painter.fontMetrics().descent() ) / 2, colText );
05935 }
05936 else
05937 {
05938 QString tmp;
05939 int len = painter.fontMetrics().width( tmp.setNum(x) );
05940 if (!col_lay->isHide())
05941 painter.drawText( zoomedXPos + ( width - len ) / 2,
05942 ( height + painter.fontMetrics().ascent() -
05943 painter.fontMetrics().descent() ) / 2,
05944 tmp.setNum(x) );
05945 }
05946 xPos += col_lay->dblWidth();
05947 --x;
05948 }
05949 }
05950 else
05951 {
05952
05953 while ( xPos <= m_pCanvas->d->view->doc()->unzoomItX( _ev->rect().right() ) )
05954 {
05955 bool selected = (m_pView->selectionInfo()->isColumnSelected(x));
05956 bool highlighted = (!selected && m_pView->selectionInfo()->isColumnAffected(x));
05957
05958 const ColumnFormat *col_lay = sheet->columnFormat( x );
05959 int zoomedXPos = m_pCanvas->d->view->doc()->zoomItX( xPos );
05960 int width = m_pCanvas->d->view->doc()->zoomItX( xPos + col_lay->dblWidth() ) - zoomedXPos;
05961
05962 if ( selected )
05963 {
05964 QBrush fillSelected( highlightColor );
05965 qDrawPlainRect ( &painter, zoomedXPos, 0, width+1, height, highlightColor.dark(),
05966 1, &fillSelected );
05967 }
05968 else if ( highlighted )
05969 {
05970 QBrush fillHighlighted( highlightColor );
05971 qDrawPlainRect ( &painter, zoomedXPos, 0, width+1, height, highlightColor.dark(),
05972 1, &fillHighlighted );
05973 }
05974 else
05975 {
05976 QColor c = colorGroup().background();
05977 QBrush fill( c );
05978 qDrawPlainRect ( &painter, zoomedXPos, 0, width+1, height, c.dark(150),
05979 1, &fill );
05980 }
05981
05982
05983 painter.setFont( normalFont );
05984 painter.setPen( colorGroup().text() );
05985
05986 if ( selected )
05987 painter.setPen( colorGroup().highlightedText() );
05988 else if ( highlighted )
05989 painter.setFont( boldFont );
05990 if ( !m_pView->activeSheet()->getShowColumnNumber() )
05991 {
05992 QString colText = Cell::columnName( x );
05993 int len = painter.fontMetrics().width( colText );
05994 if (!col_lay->isHide())
05995 painter.drawText( zoomedXPos + ( width - len ) / 2,
05996 ( height + painter.fontMetrics().ascent() -
05997 painter.fontMetrics().descent() ) / 2, colText );
05998 }
05999 else
06000 {
06001 QString tmp;
06002 int len = painter.fontMetrics().width( tmp.setNum(x) );
06003 if (!col_lay->isHide())
06004 painter.drawText( zoomedXPos + ( width - len ) / 2,
06005 ( height + painter.fontMetrics().ascent() -
06006 painter.fontMetrics().descent() ) / 2,
06007 tmp.setNum(x) );
06008 }
06009 xPos += col_lay->dblWidth();
06010 ++x;
06011 }
06012 }
06013 }
06014
06015
06016 void HBorder::focusOutEvent( QFocusEvent* )
06017 {
06018 if ( m_scrollTimer->isActive() )
06019 m_scrollTimer->stop();
06020 m_bMousePressed = false;
06021 }
06022
06023
06024
06025
06026
06027
06028
06029 ToolTip::ToolTip( Canvas* canvas )
06030 : QToolTip( canvas ), m_canvas( canvas )
06031 {
06032 }
06033
06034
06035
06036 QLabel *tip_findLabel()
06037 {
06038 QWidgetList *list = QApplication::allWidgets();
06039 QWidgetListIt it( *list );
06040 QWidget * w;
06041 while ( (w=it.current()) != 0 )
06042 {
06043 if(w->isA("QTipLabel"))
06044 return static_cast<QLabel*>(w);
06045 ++it;
06046 }
06047 delete list;
06048 return 0;
06049 }
06050
06051 void ToolTip::maybeTip( const QPoint& p )
06052 {
06053 Sheet *sheet = m_canvas->activeSheet();
06054 if ( !sheet )
06055 return;
06056
06057
06058 double ypos, xpos;
06059 double dwidth = m_canvas->doc()->unzoomItX( m_canvas->width() );
06060 int col;
06061 if ( sheet->layoutDirection()==Sheet::RightToLeft )
06062 col = sheet->leftColumn( (dwidth - m_canvas->doc()->unzoomItX( p.x() ) +
06063 m_canvas->xOffset()), xpos );
06064 else
06065 col = sheet->leftColumn( (m_canvas->doc()->unzoomItX( p.x() ) +
06066 m_canvas->xOffset()), xpos );
06067
06068
06069 int row = sheet->topRow( (m_canvas->doc()->unzoomItY( p.y() ) +
06070 m_canvas->yOffset()), ypos );
06071
06072 Cell* cell = sheet->visibleCellAt( col, row );
06073 if ( !cell )
06074 return;
06075
06076 #if 0
06077
06078 if( cell->strOutText().isEmpty() )
06079 return;
06080 #endif
06081
06082
06083
06084
06085 QString tipText;
06086
06087
06088 if ( cell->testFlag( Cell::Flag_CellTooShortX ) ||
06089 cell->testFlag( Cell::Flag_CellTooShortY ) )
06090 {
06091 tipText = cell->strOutText();
06092
06093
06094 QString comment = cell->format()->comment( col, row );
06095 if ( !comment.isEmpty() )
06096 comment = "\n\n" + i18n("Comment:") + "\n" + comment;
06097
06098 tipText += comment;
06099 }
06100
06101
06102 if( tipText.isEmpty() )
06103 {
06104 tipText = cell->format()->comment( col, row );
06105 }
06106
06107
06108 if( tipText.isEmpty() )
06109 {
06110 tipText = cell->link();
06111 }
06112
06113
06114 if( tipText.isEmpty() )
06115 return;
06116
06117
06118 unsigned maxLen = 256;
06119 if(tipText.length() > maxLen )
06120 tipText = tipText.left(maxLen).append("...");
06121
06122
06123 cell = sheet->cellAt( col, row );
06124 double u = cell->dblWidth( col );
06125 double v = cell->dblHeight( row );
06126
06127
06128 if ( cell->isObscured() && cell->isPartOfMerged() )
06129 {
06130 cell = cell->obscuringCells().first();
06131 int moveX = cell->column();
06132 int moveY = cell->row();
06133
06134
06135 u = cell->dblWidth( moveX );
06136 v = cell->dblHeight( moveY );
06137 xpos = sheet->dblColumnPos( moveX );
06138 ypos = sheet->dblRowPos( moveY );
06139 }
06140
06141
06142 QRect marker;
06143 bool insideMarker = false;
06144
06145 if ( sheet->layoutDirection()==Sheet::RightToLeft )
06146 {
06147 KoRect unzoomedMarker( dwidth - u - xpos + m_canvas->xOffset(),
06148 ypos - m_canvas->yOffset(),
06149 u,
06150 v );
06151
06152 marker = m_canvas->doc()->zoomRect( unzoomedMarker );
06153 insideMarker = marker.contains( p );
06154 }
06155 else
06156 {
06157 KoRect unzoomedMarker( xpos - m_canvas->xOffset(),
06158 ypos - m_canvas->yOffset(),
06159 u,
06160 v );
06161
06162 marker = m_canvas->doc()->zoomRect( unzoomedMarker );
06163 insideMarker = marker.contains( p );
06164 }
06165
06166
06167 if( !insideMarker )
06168 return;
06169
06170
06171
06172 QLabel* tipLabel = tip_findLabel();
06173
06174
06175
06176 if( tipLabel )
06177 tipLabel->setTextFormat( Qt::PlainText );
06178
06179
06180 if( tipText.length() > 16 )
06181 {
06182 QFontMetrics fm = tipLabel? tipLabel->fontMetrics() : m_canvas->fontMetrics();
06183 QRect r( 0, 0, 200, -1 );
06184 KWordWrap* wrap = KWordWrap::formatText( fm, r, 0, tipText );
06185 tipText = wrap->wrappedString();
06186 delete wrap;
06187 }
06188
06189
06190 tip( marker, tipText );
06191
06192
06193
06194 if( !tipLabel )
06195 {
06196 tipLabel = tip_findLabel();
06197 if( tipLabel )
06198 tipLabel->setTextFormat( Qt::PlainText );
06199 }
06200
06201 }
06202
06203 #include "kspread_canvas.moc"