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