00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "kivio_canvas.h"
00020 #include "kivio_page.h"
00021 #include "kivio_map.h"
00022 #include "kivio_view.h"
00023 #include "kivio_doc.h"
00024
00025 #include "kivio_icon_view.h"
00026 #include "kivio_stencil.h"
00027 #include "kivio_stencil_spawner.h"
00028 #include "kivio_stencil_spawner_info.h"
00029 #include "kivio_stackbar.h"
00030 #include "kivio_screen_painter.h"
00031 #include "kivio_grid_data.h"
00032 #include "kivio_layer.h"
00033
00034 #include "kivio_pluginmanager.h"
00035
00036 #include <kdebug.h>
00037 #include <klocale.h>
00038 #include <kmessagebox.h>
00039 #include <kcursor.h>
00040 #include <KoGlobal.h>
00041 #include <KoZoomHandler.h>
00042 #include <KoSize.h>
00043 #include <KoRuler.h>
00044 #include <KoPoint.h>
00045 #include <KoTabBar.h>
00046 #include <kapplication.h>
00047
00048 #include <assert.h>
00049 #include <stdio.h>
00050 #include <qlabel.h>
00051 #include <qpixmap.h>
00052 #include <qscrollbar.h>
00053 #include <qtimer.h>
00054 #include <qsize.h>
00055
00056 using namespace Kivio;
00057
00058 KivioCanvas::KivioCanvas( QWidget *par, KivioView* view, KivioDoc* doc, QScrollBar* vs, QScrollBar* hs)
00059 : QWidget(par, "KivioCanvas", WResizeNoErase | WRepaintNoErase),
00060 m_pView(view),
00061 m_pDoc(doc),
00062 m_pVertScrollBar(vs),
00063 m_pHorzScrollBar(hs),
00064 m_guides(view, view->zoomHandler())
00065 {
00066 setBackgroundMode(NoBackground);
00067 setAcceptDrops(true);
00068 setMouseTracking(true);
00069 setFocusPolicy(StrongFocus);
00070 setFocus();
00071
00072 m_showConnectorTargets = false;
00073 delegateThisEvent = true;
00074
00075 m_pVertScrollBar->setLineStep(1);
00076 m_pHorzScrollBar->setLineStep(1);
00077
00078
00079 m_pVertScrollBar->setPageStep(10);
00080 m_pHorzScrollBar->setPageStep(10);
00081
00082 connect(m_pVertScrollBar, SIGNAL(valueChanged(int)), SLOT(scrollV(int)));
00083 connect( m_pHorzScrollBar, SIGNAL(valueChanged(int)), SLOT(scrollH(int)));
00084
00085 m_iXOffset = 0;
00086 m_iYOffset = 0;
00087
00088 m_pScrollX = 0;
00089 m_pScrollY = 0;
00090
00091 m_pageOffsetX = 0;
00092 m_pageOffsetY = 0;
00093
00094 m_pasteMoving = false;
00095
00096 m_buffer = new QPixmap();
00097
00098 m_pDragStencil = 0L;
00099 unclippedSpawnerPainter = 0L;
00100 unclippedPainter = 0L;
00101
00102 m_borderTimer = new QTimer(this);
00103 connect(m_borderTimer,SIGNAL(timeout()),SLOT(borderTimerTimeout()));
00104 }
00105
00106 KivioCanvas::~KivioCanvas()
00107 {
00108 delete m_buffer;
00109 delete m_borderTimer;
00110 delete unclippedPainter;
00111 }
00112
00113 KivioPage* KivioCanvas::findPage( const QString& _name )
00114 {
00115 return m_pDoc->map()->findPage( _name );
00116 }
00117
00118 const KivioPage* KivioCanvas::activePage() const
00119 {
00120 return m_pView->activePage();
00121 }
00122
00123 KivioPage* KivioCanvas::activePage()
00124 {
00125 return m_pView->activePage();
00126 }
00127
00128 void KivioCanvas::scrollH( int value )
00129 {
00130
00131 int dx = m_iXOffset - value;
00132
00133 m_iXOffset = value;
00134
00135 bitBlt(m_buffer, dx, 0, m_buffer);
00136 scroll(dx, 0);
00137
00138 emit visibleAreaChanged();
00139 }
00140
00141 void KivioCanvas::scrollV( int value )
00142 {
00143
00144 int dy = m_iYOffset - value;
00145
00146 m_iYOffset = value;
00147
00148 bitBlt(m_buffer, 0, dy, m_buffer);
00149 scroll(0, dy);
00150
00151 emit visibleAreaChanged();
00152 }
00153
00154 void KivioCanvas::scrollDx( int dx )
00155 {
00156 if ( dx == 0 )
00157 return;
00158
00159 int value = m_iXOffset - dx;
00160 m_pHorzScrollBar->setValue(value);
00161 }
00162
00163 void KivioCanvas::scrollDy( int dy )
00164 {
00165 if ( dy == 0 )
00166 return;
00167
00168 int value = m_iYOffset - dy;
00169 m_pVertScrollBar->setValue(value);
00170 }
00171
00172 void KivioCanvas::resizeEvent( QResizeEvent* )
00173 {
00174 m_buffer->resize(size());
00175 updateScrollBars();
00176
00177 emit visibleAreaChanged();
00178 }
00179
00180 void KivioCanvas::wheelEvent( QWheelEvent* ev )
00181 {
00182 ev->accept();
00183
00184 if( (ev->delta()>0))
00185 {
00186 if(ev->state() == ControlButton) {
00187 zoomIn(ev->pos());
00188 } else if(ev->state() == ShiftButton) {
00189 m_pVertScrollBar->setValue(m_pVertScrollBar->value() - height());
00190 } else {
00191 m_pVertScrollBar->setValue(m_pVertScrollBar->value() - 30);
00192 }
00193 }
00194 else
00195 {
00196 if(ev->state() == ControlButton) {
00197 zoomOut(ev->pos());
00198 } else if(ev->state() == ShiftButton) {
00199 m_pVertScrollBar->setValue(m_pVertScrollBar->value() + height());
00200 } else {
00201 m_pVertScrollBar->setValue(m_pVertScrollBar->value() + 30);
00202 }
00203 }
00204 }
00205
00206 void KivioCanvas::setUpdatesEnabled( bool isUpdate )
00207 {
00208 static int i = 0;
00209
00210 QWidget::setUpdatesEnabled(isUpdate);
00211 if (isUpdate) {
00212 --i;
00213 if (i == 0) {
00214 update();
00215 updateScrollBars();
00216
00217 blockSignals(false);
00218
00219 emit visibleAreaChanged();
00220 }
00221 } else {
00222 i++;
00223 blockSignals(true);
00224 }
00225 }
00226
00227 void KivioCanvas::zoomIn(const QPoint &p)
00228 {
00229 setUpdatesEnabled(false);
00230 KoPoint p0 = mapFromScreen(p);
00231 m_pView->viewZoom(m_pView->zoomHandler()->zoom() + 25);
00232 QPoint p1 = mapToScreen(p0);
00233 scrollDx(-p1.x()+p.x());
00234 scrollDy(-p1.y()+p.y());
00235 setUpdatesEnabled(true);
00236 }
00237
00238 void KivioCanvas::zoomOut(const QPoint &p)
00239 {
00240 setUpdatesEnabled(false);
00241 KoPoint p0 = mapFromScreen(p);
00242 int newZoom = m_pView->zoomHandler()->zoom() - 25;
00243
00244 if(newZoom > 0) {
00245 m_pView->viewZoom(newZoom);
00246 QPoint p1 = mapToScreen(p0);
00247 scrollDx(-p1.x()+p.x());
00248 scrollDy(-p1.y()+p.y());
00249 }
00250 setUpdatesEnabled(true);
00251 }
00252
00253 void KivioCanvas::paintEvent( QPaintEvent* ev )
00254 {
00255 if ( m_pDoc->isLoading() || !activePage() )
00256 return;
00257
00258 KivioPage* page = activePage();
00259
00260 QPainter painter;
00261 painter.begin(m_buffer);
00262
00263 KoPageLayout pl = page->paperLayout();
00264 int pw = m_pView->zoomHandler()->zoomItX(pl.ptWidth);
00265 int ph = m_pView->zoomHandler()->zoomItY(pl.ptHeight);
00266 QRect fillRect(0, 0, pw, ph);
00267 QRect paintRect = ev->rect();
00268 QRegion grayRegion(paintRect);
00269 grayRegion.translate(m_iXOffset - m_pageOffsetX, m_iYOffset - m_pageOffsetY);
00270 grayRegion -= fillRect;
00271 grayRegion.translate(-m_iXOffset + m_pageOffsetX, -m_iYOffset + m_pageOffsetY);
00272
00273
00274
00275 painter.save();
00276 painter.setClipRegion(grayRegion, QPainter::CoordPainter);
00277 painter.setPen(Qt::NoPen);
00278 painter.fillRect(grayRegion.boundingRect(), KApplication::palette().active().brush(QColorGroup::Mid));
00279 painter.restore();
00280
00281
00282 painter.translate(-m_iXOffset + m_pageOffsetX, -m_iYOffset +m_pageOffsetY);
00283 painter.fillRect(fillRect, white);
00284
00285
00286 if(m_pDoc->grid().isShow) {
00287 KoPoint topLeft(0, 0);
00288 KoPoint bottomRight(pl.ptWidth, pl.ptHeight);
00289 QPoint zoomedTL = m_pView->zoomHandler()->zoomPoint(topLeft);
00290 QPoint zoomedBR = m_pView->zoomHandler()->zoomPoint(bottomRight);
00291
00292 KoSize freq = m_pDoc->grid().freq;
00293
00294 painter.setPen(m_pDoc->grid().color);
00295
00296 double x = qRound(topLeft.x() / freq.width()) * freq.width();
00297 int zoomed = 0;
00298
00299 while(x <= bottomRight.x()) {
00300 zoomed = m_pView->zoomHandler()->zoomItX(x);
00301 painter.drawLine(zoomed, zoomedTL.y(), zoomed, zoomedBR.y());
00302 x += freq.width();
00303 }
00304
00305 double y = qRound(topLeft.y() / freq.height()) * freq.height();
00306
00307 while(y <= bottomRight.y()) {
00308 zoomed = m_pView->zoomHandler()->zoomItY(y);
00309 painter.drawLine(zoomedTL.x(), zoomed, zoomedBR.x(), zoomed);
00310 y += freq.height();
00311 }
00312 }
00313
00314 if(m_pView->isShowPageMargins()) {
00315 int ml = m_pView->zoomHandler()->zoomItX(pl.ptLeft);
00316 int mt = m_pView->zoomHandler()->zoomItY(pl.ptTop);
00317 int mr = m_pView->zoomHandler()->zoomItX(pl.ptRight);
00318 int mb = m_pView->zoomHandler()->zoomItY(pl.ptBottom);
00319
00320 painter.save();
00321 painter.setPen(QPen("#C7C7C7",1,SolidLine));
00322 painter.drawRect(ml,mt,pw-ml-mr,ph-mt-mb);
00323 painter.restore();
00324 }
00325
00326
00327 painter.setPen(black);
00328 painter.fillRect(pw, 3, 5, ph, gray);
00329 painter.fillRect(3, ph, pw, 3, gray);
00330 painter.drawRect(0, 0, pw, ph);
00331
00332
00333 KivioScreenPainter kpainter;
00334 kpainter.start(m_buffer);
00335 kpainter.translateBy(-m_iXOffset + m_pageOffsetX, -m_iYOffset + m_pageOffsetY);
00336 m_pDoc->paintContent(kpainter, paintRect, false, page, QPoint(0, 0), m_pView->zoomHandler(), showConnectorTargets(), true);
00337 kpainter.stop();
00338
00339 if(m_pView->isShowGuides()) {
00340 m_guides.paintGuides(painter);
00341 }
00342
00343 painter.end();
00344
00345 bitBlt(this, paintRect.left(), paintRect.top(), m_buffer,
00346 paintRect.left(), paintRect.top(), paintRect.width(), paintRect.height());
00347 }
00348
00349 void KivioCanvas::updateScrollBars()
00350 {
00351 if(!activePage()) {
00352 return;
00353 }
00354
00355 KoPageLayout pl = activePage()->paperLayout();
00356 int pw = m_pView->zoomHandler()->zoomItX(pl.ptWidth);
00357 int ph = m_pView->zoomHandler()->zoomItY(pl.ptHeight);
00358
00359 m_pScrollX = QMAX(pw - width(), 0);
00360 m_pScrollY = QMAX(ph - height(), 0);
00361
00362 m_pHorzScrollBar->setRange(0, m_pScrollX);
00363 if ( m_pHorzScrollBar->value() > m_pHorzScrollBar->maxValue() ||
00364 m_pHorzScrollBar->value() < m_pHorzScrollBar->minValue() )
00365 {
00366 m_pHorzScrollBar->setValue(0);
00367 }
00368
00369 m_pVertScrollBar->setRange(0, m_pScrollY);
00370 if ( m_pVertScrollBar->value() > m_pVertScrollBar->maxValue() ||
00371 m_pVertScrollBar->value() < m_pVertScrollBar->minValue() )
00372 {
00373 m_pVertScrollBar->setValue(0);
00374 }
00375
00376 m_pVertScrollBar->setPageStep( height() );
00377 m_pHorzScrollBar->setPageStep( width() );
00378
00379 if(pw >= width()) {
00380 m_pageOffsetX = 0;
00381 } else {
00382 m_pageOffsetX = (width() - pw) / 2;
00383 }
00384
00385 if(ph >= height()) {
00386 m_pageOffsetY = 0;
00387 } else {
00388 m_pageOffsetY = (height() - ph) / 2;
00389 }
00390 }
00391
00392 QSize KivioCanvas::actualSize() const
00393 {
00394 return QSize(m_pScrollX, m_pScrollY);
00395 }
00396
00397 bool KivioCanvas::event( QEvent* e )
00398 {
00399 bool f = QWidget::event(e);
00400
00401 if (m_pView->pluginManager() && delegateThisEvent) {
00402 f = m_pView->pluginManager()->delegateEvent(e);
00403 }
00404
00405 delegateThisEvent = true;
00406 return f;
00407 }
00408
00409 void KivioCanvas::enterEvent( QEvent* )
00410 {
00411 }
00412
00413 void KivioCanvas::leaveEvent( QEvent* )
00414 {
00415 m_pView->setMousePos(-1, -1);
00416 }
00417
00418 void KivioCanvas::mousePressEvent(QMouseEvent* e)
00419 {
00420 if(!m_pDoc->isReadWrite())
00421 return;
00422
00423 if(m_pasteMoving) {
00424 endPasteMoving();
00425 return;
00426 }
00427
00428 Kivio::PluginManager* pluginManager = view()->pluginManager();
00429
00430 if(m_pView->isShowGuides() && (!pluginManager || (pluginManager->defaultTool() == pluginManager->activeTool()))) {
00431 if(m_guides.mousePressEvent(e)) {
00432 delegateThisEvent = false;
00433 return;
00434 }
00435 }
00436 }
00437
00438 void KivioCanvas::mouseReleaseEvent(QMouseEvent* e)
00439 {
00440 if(!m_pDoc->isReadWrite())
00441 return;
00442
00443 Kivio::PluginManager* pluginManager = view()->pluginManager();
00444
00445 if(view()->isShowGuides() && (!pluginManager || (pluginManager->defaultTool() == pluginManager->activeTool()))) {
00446 if(m_guides.mouseReleaseEvent(e)) {
00447 delegateThisEvent = false;
00448 return;
00449 }
00450 }
00451 }
00452
00453 void KivioCanvas::mouseMoveEvent(QMouseEvent* e)
00454 {
00455 if(!m_pDoc->isReadWrite())
00456 return;
00457
00458 if(m_pasteMoving) {
00459 continuePasteMoving(e->pos());
00460 } else {
00461 Kivio::PluginManager* pluginManager = view()->pluginManager();
00462
00463 if(m_pView->isShowGuides() && (!pluginManager || (pluginManager->defaultTool() == pluginManager->activeTool()))) {
00464 delegateThisEvent = !m_guides.mouseMoveEvent(e);
00465 }
00466 }
00467
00468 lastPoint = e->pos();
00469 view()->setMousePos(lastPoint.x(), lastPoint.y());
00470 }
00471
00472 QPoint KivioCanvas::mapToScreen(const KoPoint& pos)
00473 {
00474 QPoint p;
00475 int x = m_pView->zoomHandler()->zoomItX(pos.x());
00476 int y = m_pView->zoomHandler()->zoomItY(pos.y());
00477
00478 p.setX( x - m_iXOffset + m_pageOffsetX);
00479 p.setY( y - m_iYOffset + m_pageOffsetY);
00480
00481 return p;
00482 }
00483
00484 KoPoint KivioCanvas::mapFromScreen( const QPoint & pos )
00485 {
00486 int x = pos.x() + m_iXOffset - m_pageOffsetX;
00487 int y = pos.y() + m_iYOffset - m_pageOffsetY;
00488 double xf = m_pView->zoomHandler()->unzoomItX(x);
00489 double yf = m_pView->zoomHandler()->unzoomItY(y);
00490
00491 KoPoint p(xf, yf);
00492 return p;
00493 }
00494
00495 void KivioCanvas::startRectDraw( const QPoint &p, RectType )
00496 {
00497 currRect = QRect( 0, 0, -1, -1 );
00498
00499 QPoint pos( p );
00500 oldRectValid = false;
00501 beginUnclippedPainter();
00502 rectAnchor = pos;
00503 currRect = QRect( rectAnchor, QPoint(0,0) );
00504
00505 m_borderTimer->start(100);
00506 }
00507
00508 void KivioCanvas::continueRectDraw( const QPoint &p, RectType )
00509 {
00510 QPoint pos = p;
00511 QPoint p2 = pos;
00512 QRect r( rectAnchor, p2 );
00513 r = r.normalize();
00514
00515 if ( oldRectValid )
00516 unclippedPainter->drawRect( currRect );
00517 if ( r.width() > 1 || r.height() > 1 ) {
00518 oldRectValid = true;
00519 currRect = r;
00520 unclippedPainter->drawRect( currRect );
00521 } else {
00522 oldRectValid = false;
00523 }
00524 }
00525
00526 void KivioCanvas::endRectDraw()
00527 {
00528 m_borderTimer->stop();
00529
00530 if ( !unclippedPainter )
00531 return;
00532
00533 if ( oldRectValid )
00534 unclippedPainter->drawRect( currRect );
00535
00536 endUnclippedPainter();
00537 }
00538
00547 void KivioCanvas::startSpawnerDragDraw( const QPoint &p )
00548 {
00549 currRect = QRect( 0, 0, -1, -1 );
00550
00551 KivioStencilSpawner *pSpawner = KivioIconView::curDragSpawner();
00552 if( !pSpawner )
00553 return;
00554
00555
00556
00557 if( m_pDragStencil )
00558 {
00559 kdDebug(43000) << "KivioCanvas::startSpawnerDragDraw() - m_pDragStencil still exists. BUG!" << endl;
00560 delete m_pDragStencil;
00561 m_pDragStencil = 0L;
00562 }
00563
00564
00565 KoPoint qp = mapFromScreen( p );
00566 qp = snapToGrid(qp);
00567
00568
00569 m_pDragStencil = pSpawner->newStencil();
00570 m_pDragStencil->setPosition( qp.x(), qp.y() );
00571
00572
00573 oldRectValid = true;
00574
00575
00576 beginUnclippedSpawnerPainter();
00577
00578
00579 unclippedSpawnerPainter->painter()->save();
00580 unclippedSpawnerPainter->painter()->translate(-m_iXOffset + m_pageOffsetX, -m_iYOffset + m_pageOffsetY);
00581
00582
00583
00584 m_dragStencilData.painter = unclippedSpawnerPainter;
00585 m_dragStencilData.zoomHandler = m_pView->zoomHandler();
00586
00587
00588 m_pDragStencil->paintOutline( &m_dragStencilData );
00589
00590 unclippedSpawnerPainter->painter()->restore();
00591 }
00592
00596 void KivioCanvas::continueSpawnerDragDraw( const QPoint &p )
00597 {
00598 bool snappedX, snappedY;
00599
00600
00601 unclippedSpawnerPainter->painter()->save();
00602 unclippedSpawnerPainter->painter()->translate(-m_iXOffset + m_pageOffsetX, -m_iYOffset + m_pageOffsetY);
00603
00604
00605 if( oldRectValid )
00606 {
00607 m_pDragStencil->paintOutline( &m_dragStencilData );
00608 }
00609
00610
00611 KoPoint orig = mapFromScreen(p);
00612 KoPoint qp = snapToGrid( orig );
00613
00614
00615 qp = snapToGrid(qp);
00616 m_pDragStencil->setPosition( qp.x(), qp.y() );
00617
00618
00619 qp.setCoords(orig.x() + m_pDragStencil->w(), orig.y() + m_pDragStencil->h());
00620 qp = snapToGuides(qp, snappedX, snappedY);
00621
00622 if(snappedX) {
00623 m_pDragStencil->setX(qp.x() - m_pDragStencil->w());
00624 }
00625
00626 if(snappedY) {
00627 m_pDragStencil->setY(qp.y() - m_pDragStencil->h());
00628 }
00629
00630 qp.setCoords(orig.x() + (m_pDragStencil->w() / 2.0), orig.y() + (m_pDragStencil->h() / 2.0));
00631 qp = snapToGuides(qp, snappedX, snappedY);
00632
00633 if(snappedX) {
00634 m_pDragStencil->setX(qp.x() - (m_pDragStencil->w() / 2.0));
00635 }
00636
00637 if(snappedY) {
00638 m_pDragStencil->setY(qp.y() - (m_pDragStencil->h() / 2.0));
00639 }
00640
00641 qp.setCoords(orig.x(), orig.y());
00642 qp = snapToGuides(qp, snappedX, snappedY);
00643
00644 if(snappedX) {
00645 m_pDragStencil->setX(qp.x());
00646 }
00647
00648 if(snappedY) {
00649 m_pDragStencil->setY(qp.y());
00650 }
00651
00652
00653 oldRectValid = true;
00654 m_pDragStencil->paintOutline( &m_dragStencilData );
00655 unclippedSpawnerPainter->painter()->restore();
00656
00657 }
00658
00659
00663 void KivioCanvas::endSpawnerDragDraw()
00664 {
00665
00666 if ( !unclippedSpawnerPainter )
00667 return;
00668
00669
00670 if ( oldRectValid )
00671 {
00672 unclippedSpawnerPainter->painter()->save();
00673 unclippedSpawnerPainter->painter()->translate(-m_iXOffset + m_pageOffsetX, -m_iYOffset + m_pageOffsetY);
00674 m_pDragStencil->paintOutline( &m_dragStencilData );
00675 unclippedSpawnerPainter->painter()->restore();
00676 }
00677
00678
00679 endUnclippedSpawnerPainter();
00680
00681
00682 if( m_pDragStencil )
00683 {
00684 delete m_pDragStencil;
00685 m_pDragStencil = 0L;
00686 }
00687
00688 setFocus();
00689 }
00690
00691
00695 void KivioCanvas::beginUnclippedSpawnerPainter()
00696 {
00697
00698 endUnclippedSpawnerPainter();
00699
00700
00701 bool unclipped = testWFlags( WPaintUnclipped );
00702 setWFlags( WPaintUnclipped );
00703
00704
00705
00706 unclippedSpawnerPainter = new KivioScreenPainter();
00707
00708
00709 unclippedSpawnerPainter->start(this);
00710
00711
00712 if( !unclipped )
00713 clearWFlags( WPaintUnclipped );
00714
00715
00716
00717 unclippedSpawnerPainter->painter()->setRasterOp( NotROP );
00718 unclippedSpawnerPainter->painter()->setPen( QColor(0,0,250) );
00719
00720 }
00721
00722
00726 void KivioCanvas::endUnclippedSpawnerPainter()
00727 {
00728 if( unclippedSpawnerPainter )
00729 {
00730 unclippedSpawnerPainter->stop();
00731 delete unclippedSpawnerPainter;
00732 unclippedSpawnerPainter = 0L;
00733 }
00734 }
00735
00736 void KivioCanvas::beginUnclippedPainter()
00737 {
00738 endUnclippedPainter();
00739 bool unclipped = testWFlags( WPaintUnclipped );
00740
00741 setWFlags( WPaintUnclipped );
00742 unclippedPainter = new QPainter;
00743 unclippedPainter->begin( this );
00744
00745 if ( !unclipped )
00746 clearWFlags( WPaintUnclipped );
00747
00748 unclippedPainter->setRasterOp( NotROP );
00749 unclippedPainter->setPen( QPen(blue,1,DotLine) );
00750 }
00751
00752 void KivioCanvas::endUnclippedPainter()
00753 {
00754 if ( unclippedPainter )
00755 {
00756 unclippedPainter->end();
00757 delete unclippedPainter;
00758 unclippedPainter = 0;
00759 }
00760 }
00761
00762 void KivioCanvas::borderTimerTimeout()
00763 {
00764 QPoint p = mapFromGlobal(QCursor::pos());
00765 int dx = 0;
00766 int dy = 0;
00767 int d = 10;
00768
00769 QRect r(currRect);
00770 int vpos = m_pVertScrollBar->value();
00771 int vmax = m_pVertScrollBar->maxValue();
00772 int vmin = m_pVertScrollBar->minValue();
00773
00774 int hpos = m_pHorzScrollBar->value();
00775 int hmax = m_pHorzScrollBar->maxValue();
00776 int hmin = m_pHorzScrollBar->minValue();
00777
00778 if ( p.x() < 0 && hpos > hmin ) {
00779 dx = QMIN(d,hpos-hmin);
00780 r.setRight(r.right()+dx);
00781 rectAnchor.setX(rectAnchor.x()+dx);
00782 }
00783
00784 if ( p.y() < 0 && vpos > vmin ) {
00785 dy = QMIN(d,vpos-vmin);
00786 r.setBottom(r.bottom()+dy);
00787 rectAnchor.setY(rectAnchor.y()+dy);
00788 }
00789
00790 if ( p.x() > width() && hpos < hmax ) {
00791 dx = -QMIN(d,hmax-hpos);
00792 r.setLeft(r.left()+dx);
00793 rectAnchor.setX(rectAnchor.x()+dx);
00794 }
00795
00796 if ( p.y() > height() && vpos < vmax ) {
00797 dy = -QMIN(d,vmax-vpos);
00798 r.setTop(r.top()+dy);
00799 rectAnchor.setY(rectAnchor.y()+dy);
00800 }
00801
00802 if ( dx != 0 || dy != 0 ) {
00803 unclippedPainter->drawRect( currRect );
00804 scrollDx(dx);
00805 scrollDy(dy);
00806 unclippedPainter->drawRect( r );
00807 currRect = r;
00808 }
00809 }
00810
00811
00822 void KivioCanvas::dragEnterEvent( QDragEnterEvent *e )
00823 {
00824 if( e->provides("kivio/stencilSpawner") )
00825 {
00826 e->accept();
00827 startSpawnerDragDraw( e->pos() );
00828 activePage()->unselectAllStencils();
00829 updateAutoGuideLines();
00830 }
00831 }
00832
00833
00834
00844 void KivioCanvas::dragMoveEvent( QDragMoveEvent *e )
00845 {
00846
00847 if( e->provides("kivio/stencilSpawner") )
00848 {
00849 e->accept();
00850 continueSpawnerDragDraw( e->pos() );
00851 }
00852 }
00853
00854
00865 void KivioCanvas::dropEvent( QDropEvent *e )
00866 {
00867
00868 endSpawnerDragDraw();
00869
00870
00871 KivioStencilSpawner *pSpawner = KivioIconView::curDragSpawner();
00872
00873 if( !pSpawner )
00874 return;
00875
00876 QPoint pos = e->pos();
00877 KoPoint pagePoint = snapToGrid(mapFromScreen( pos ));
00878 view()->addStencilFromSpawner(pSpawner, pagePoint.x(), pagePoint.y());
00879
00880
00881 }
00882
00883
00892 void KivioCanvas::dragLeaveEvent( QDragLeaveEvent * )
00893 {
00894 endSpawnerDragDraw();
00895 }
00896
00897
00898
00899 void KivioCanvas::drawSelectedStencilsXOR()
00900 {
00901
00902 if ( !unclippedSpawnerPainter )
00903 return;
00904
00905
00906 unclippedSpawnerPainter->painter()->save();
00907 unclippedSpawnerPainter->painter()->translate(-m_iXOffset + m_pageOffsetX, -m_iYOffset + m_pageOffsetY);
00908
00909
00910
00911 m_dragStencilData.painter = unclippedSpawnerPainter;
00912 m_dragStencilData.zoomHandler = m_pView->zoomHandler();
00913
00914 KivioStencil *pStencil = activePage()->selectedStencils()->first();
00915 while( pStencil )
00916 {
00917 pStencil->paintOutline( &m_dragStencilData );
00918 pStencil->paintSelectionHandles( &m_dragStencilData );
00919
00920 pStencil = activePage()->selectedStencils()->next();
00921 }
00922
00923 unclippedSpawnerPainter->painter()->restore();
00924 }
00925
00926 void KivioCanvas::drawStencilXOR( KivioStencil *pStencil )
00927 {
00928
00929 if ( !unclippedSpawnerPainter )
00930 return;
00931
00932
00933 unclippedSpawnerPainter->painter()->save();
00934 unclippedSpawnerPainter->painter()->translate(-m_iXOffset + m_pageOffsetX, -m_iYOffset + m_pageOffsetY);
00935
00936
00937
00938 m_dragStencilData.painter = unclippedSpawnerPainter;
00939 m_dragStencilData.zoomHandler = m_pView->zoomHandler();
00940
00941 pStencil->paintOutline( &m_dragStencilData );
00942 pStencil->paintSelectionHandles( &m_dragStencilData );
00943
00944 unclippedSpawnerPainter->painter()->restore();
00945 }
00946
00947 void KivioCanvas::keyPressEvent( QKeyEvent *e )
00948 {
00949 if(view()->isShowGuides() && m_guides.keyPressEvent(e)) {
00950 return;
00951 }
00952 }
00953
00954 KoPoint KivioCanvas::snapToGridAndGuides(const KoPoint& point)
00955 {
00956 KoPoint p = point;
00957
00958 p = snapToGrid(p);
00959
00960 bool snappedX, snappedY;
00961 KoPoint guidePoint = snapToGuides(point, snappedX, snappedY);
00962
00963 if(snappedX) {
00964 p.setX(guidePoint.x());
00965 }
00966
00967 if(snappedY) {
00968 p.setY(guidePoint.y());
00969 }
00970
00971 return p;
00972 }
00973
00974 KoPoint KivioCanvas::snapToGrid(const KoPoint& point)
00975 {
00976 if (!m_pDoc->grid().isSnap)
00977 return point;
00978
00979 KoPoint p = point;
00980
00981 KoSize dist = m_pDoc->grid().snap;
00982 KoSize freq = m_pDoc->grid().freq;
00983
00984 double dx = qRound(p.x() / freq.width());
00985 double dy = qRound(p.y() / freq.height());
00986
00987 double distx = QABS(p.x() - (freq.width() * dx));
00988 double disty = QABS(p.y() - (freq.height() * dy));
00989
00990 if(distx < dist.width()) {
00991 p.setX(freq.width() * dx);
00992 }
00993
00994 if(disty < dist.height()) {
00995 p.setY(freq.height() * dy);
00996 }
00997
00998 return p;
00999 }
01000
01001 KoPoint KivioCanvas::snapToGuides(const KoPoint& point, bool &snappedX, bool &snappedY)
01002 {
01003 snappedX = false;
01004 snappedY = false;
01005 KoPoint p = point;
01006
01007 if (m_pView->isSnapGuides())
01008 {
01009 KoGuides::SnapStatus status = KoGuides::SNAP_NONE;
01010 KoPoint diff;
01011 m_guides.snapToGuideLines(p, 4, status, diff);
01012 p += diff;
01013
01014 if(status & KoGuides::SNAP_HORIZ) {
01015 snappedY = true;
01016 }
01017 if(status & KoGuides::SNAP_VERT) {
01018 snappedX = true;
01019 }
01020
01021 m_guides.repaintSnapping(p, status);
01022 }
01023
01024 return p;
01025 }
01026
01027 void KivioCanvas::setViewCenterPoint(const KoPoint &p)
01028 {
01029 setUpdatesEnabled(false);
01030
01031 KoRect va = visibleArea();
01032
01033 double x = QMAX(0.0, p.x() - (va.width() / 2.0));
01034 double y = QMAX(0.0, p.y() - (va.height() / 2.0));
01035
01036 m_pVertScrollBar->setValue(m_pView->zoomHandler()->zoomItY(y));
01037 m_pHorzScrollBar->setValue(m_pView->zoomHandler()->zoomItX(x));
01038
01039 setUpdatesEnabled(true);
01040 }
01041
01042 KoRect KivioCanvas::visibleArea()
01043 {
01044 KoPoint p0 = mapFromScreen(QPoint(0,0));
01045 KoPoint p1 = mapFromScreen(QPoint(width()-1,height()-1));
01046
01047 return KoRect(p0.x(), p0.y(), p1.x() - p0.x(), p1.y() - p0.y());
01048 }
01049
01050 void KivioCanvas::setVisibleArea(KoRect r, int margin)
01051 {
01052 setUpdatesEnabled(false);
01053 KoZoomHandler zoom;
01054 zoom.setZoomAndResolution(100, KoGlobal::dpiX(),
01055 KoGlobal::dpiY());
01056
01057 float cw = width() - 2 * margin;
01058 float ch = height() - 2 * margin;
01059
01060 float zw = cw / (float)zoom.zoomItX(r.width());
01061 float zh = ch / (float)zoom.zoomItY(r.height());
01062 float z = QMIN(zw, zh);
01063
01064 m_pView->viewZoom(qRound(z * 100));
01065
01066 KoPoint c = r.center();
01067
01068 setViewCenterPoint(KoPoint(c.x(), c.y()));
01069 setUpdatesEnabled(true);
01070 }
01071
01072 void KivioCanvas::setVisibleAreaByWidth(KoRect r, int margin)
01073 {
01074 setUpdatesEnabled(false);
01075 KoZoomHandler zoom;
01076 zoom.setZoomAndResolution(100, KoGlobal::dpiX(),
01077 KoGlobal::dpiY());
01078
01079 float cw = width() - 2*margin;
01080 float z = cw / (float)zoom.zoomItX(r.width());
01081
01082 m_pView->viewZoom(qRound(z * 100));
01083
01084 KoPoint c = r.center();
01085
01086 setViewCenterPoint(KoPoint(c.x(), c.y()));
01087 setUpdatesEnabled(true);
01088 }
01089
01090 void KivioCanvas::setVisibleAreaByHeight(KoRect r, int margin)
01091 {
01092 setUpdatesEnabled(false);
01093 KoZoomHandler zoom;
01094 zoom.setZoomAndResolution(100, KoGlobal::dpiX(),
01095 KoGlobal::dpiY());
01096
01097 float ch = height() - 2*margin;
01098 float z = ch / (float)zoom.zoomItY(r.height());
01099
01100 m_pView->viewZoom(qRound(z * 100));
01101
01102 KoPoint c = r.center();
01103
01104 setViewCenterPoint(KoPoint(c.x(), c.y()));
01105 setUpdatesEnabled(true);
01106 }
01107
01108 void KivioCanvas::startPasteMoving()
01109 {
01110 setEnabled(false);
01111 KoPoint p = activePage()->getRectForAllSelectedStencils().center();
01112 m_origPoint.setCoords(p.x(), p.y());
01113
01114
01115 beginUnclippedSpawnerPainter();
01116 drawSelectedStencilsXOR();
01117
01118
01119 KoRect *pData;
01120 m_lstOldGeometry.clear();
01121 KivioStencil* pStencil = activePage()->selectedStencils()->first();
01122
01123 while( pStencil )
01124 {
01125 pData = new KoRect;
01126 *pData = pStencil->rect();
01127 m_lstOldGeometry.append(pData);
01128
01129 pStencil = activePage()->selectedStencils()->next();
01130 }
01131
01132 continuePasteMoving(lastPoint);
01133 m_pasteMoving = true;
01134 setEnabled(true);
01135 }
01136
01137 void KivioCanvas::continuePasteMoving(const QPoint &pos)
01138 {
01139 KoPoint pagePoint = mapFromScreen( pos );
01140
01141 double dx = pagePoint.x() - m_origPoint.x();
01142 double dy = pagePoint.y() - m_origPoint.y();
01143
01144 bool snappedX;
01145 bool snappedY;
01146
01147 double newX, newY;
01148
01149
01150 drawSelectedStencilsXOR();
01151
01152
01153 KoPoint p;
01154 KoRect selectedRect = activePage()->getRectForAllSelectedStencils();
01155
01156 newX = selectedRect.x() + dx;
01157 newY = selectedRect.y() + dy;
01158
01159
01160 p.setCoords(newX, newY);
01161 p = snapToGrid(p);
01162
01163 newX = p.x();
01164 newY = p.y();
01165
01166
01167 p.setCoords(selectedRect.x() + dx + selectedRect.width(), selectedRect.y() + dy + selectedRect.height());
01168 p = snapToGuides(p, snappedX, snappedY);
01169
01170 if(snappedX) {
01171 newX = p.x() - selectedRect.width();
01172 }
01173
01174 if(snappedY) {
01175 newY = p.y() - selectedRect.height();
01176 }
01177
01178 p.setCoords(selectedRect.x() + dx + (selectedRect.width() / 2.0), selectedRect.y() + dy + (selectedRect.height() / 2.0));
01179 p = snapToGuides(p, snappedX, snappedY);
01180
01181 if(snappedX) {
01182 newX = p.x() - (selectedRect.width() / 2.0);
01183 }
01184
01185 if(snappedY) {
01186 newY = p.y() - (selectedRect.height() / 2.0);
01187 }
01188
01189 p.setCoords(selectedRect.x() + dx, selectedRect.y() + dy);
01190 p = snapToGuides(p, snappedX, snappedY);
01191
01192 if(snappedX) {
01193 newX = p.x();
01194 }
01195
01196 if(snappedY) {
01197 newY = p.y();
01198 }
01199
01200 dx = newX - selectedRect.x();
01201 dy = newY - selectedRect.y();
01202
01203
01204 KivioStencil *pStencil = activePage()->selectedStencils()->first();
01205 KoRect* pData = m_lstOldGeometry.first();
01206
01207
01208 while( pStencil && pData )
01209 {
01210 newX = pData->x() + dx;
01211 newY = pData->y() + dy;
01212
01213 if( pStencil->protection()->at( kpX ) == false ) {
01214 pStencil->setX(newX);
01215 }
01216 if( pStencil->protection()->at( kpY ) == false ) {
01217 pStencil->setY(newY);
01218 }
01219
01220 pData = m_lstOldGeometry.next();
01221 pStencil = activePage()->selectedStencils()->next();
01222 }
01223
01224
01225 drawSelectedStencilsXOR();
01226 m_pView->updateToolBars();
01227 }
01228
01229 void KivioCanvas::endPasteMoving()
01230 {
01231 KivioStencil *pStencil = activePage()->selectedStencils()->first();
01232 KoRect *pData = m_lstOldGeometry.first();
01233
01234 while( pStencil && pData )
01235 {
01236 if(pStencil->type() == kstConnector) {
01237 pStencil->searchForConnections(m_pView->activePage(), m_pView->zoomHandler()->unzoomItY(4));
01238 }
01239
01240 pData = m_lstOldGeometry.next();
01241 pStencil = activePage()->selectedStencils()->next();
01242 }
01243
01244 drawSelectedStencilsXOR();
01245
01246 endUnclippedSpawnerPainter();
01247
01248
01249 m_lstOldGeometry.clear();
01250 m_pasteMoving = false;
01251 }
01252
01253 void KivioCanvas::updateAutoGuideLines()
01254 {
01255 QValueList<double> hGuideLines;
01256 QValueList<double> vGuideLines;
01257 QPtrList<KivioLayer> layerList = *(activePage()->layers());
01258 QPtrListIterator<KivioLayer> layerIt(layerList);
01259 KivioLayer* layer = 0;
01260 QPtrList<KivioStencil> stencilList;
01261 QPtrListIterator<KivioStencil> stencilIt(stencilList);
01262 KivioStencil* stencil = 0;
01263
01264 while((layer = layerIt.current()) != 0) {
01265 ++layerIt;
01266
01267 if(layer->visible()) {
01268 stencilList = *(layer->stencilList());
01269 stencilIt.toFirst();
01270
01271 while((stencil = stencilIt.current()) != 0) {
01272 ++stencilIt;
01273
01274 if(!stencil->isSelected()) {
01275 hGuideLines << stencil->y() << (stencil->y() + (stencil->h() / 2.0)) << (stencil->y() + stencil->h());
01276 vGuideLines << stencil->x() << (stencil->x() + (stencil->w() / 2.0)) << (stencil->x() + stencil->w());
01277 }
01278 }
01279 }
01280 }
01281
01282 KoPageLayout pl = activePage()->paperLayout();
01283
01284
01285 hGuideLines << (pl.ptHeight / 2.0) << pl.ptTop << pl.ptBottom;
01286 vGuideLines << (pl.ptWidth / 2.0) << pl.ptLeft << pl.ptRight;
01287
01288 guideLines().setAutoGuideLines(hGuideLines, vGuideLines);
01289 }
01290
01291 #include "kivio_canvas.moc"