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