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 #include "tool_select.h"
00028
00029 #include "kivio_view.h"
00030 #include "kivio_doc.h"
00031 #include "kivio_canvas.h"
00032 #include "kivio_page.h"
00033
00034 #include "kivio_custom_drag_data.h"
00035 #include "kivio_layer.h"
00036 #include "kivio_stencil.h"
00037
00038 #include <kactionclasses.h>
00039 #include <kpopupmenu.h>
00040 #include <kdebug.h>
00041 #include <KoZoomHandler.h>
00042 #include <KoPoint.h>
00043 #include <klocale.h>
00044 #include <KoGuides.h>
00045 #include "kivio_command.h"
00046
00047 #include <qwmatrix.h>
00048
00049 #include "kivio_pluginmanager.h"
00050
00051 SelectTool::SelectTool( KivioView* parent ) : Kivio::MouseTool(parent, "Selection Mouse Tool")
00052 {
00053 view()->pluginManager()->setDefaultTool(this);
00054
00055 KShortcut selectShortCut(Key_Space);
00056 selectShortCut.setSeq(1, QKeySequence(Key_Escape));
00057 m_selectAction = new KRadioAction(i18n("&Select"), "select", selectShortCut, actionCollection(), "select");
00058 connect(m_selectAction, SIGNAL(toggled(bool)), this, SLOT(setActivated(bool)));
00059
00060 m_textEditAction = new KAction(i18n("&Edit Text..."), "text", Key_F2,
00061 this, SLOT(editStencilText()), actionCollection(), "editText");
00062 (void) new KAction(i18n("Format &Stencils && Connectors..."), 0, 0, view(), SLOT(stencilFormat()),
00063 actionCollection(), "formatStencil");
00064 m_arrowHeadAction = new KAction(i18n("Format &Arrowheads..."), 0, 0, view(), SLOT(arrowHeadFormat()),
00065 actionCollection(), "formatConnector");
00066
00067 m_mode = stmNone;
00068 m_pResizingStencil = NULL;
00069 m_pCustomDraggingStencil = NULL;
00070
00071 m_lstOldGeometry.setAutoDelete(true);
00072
00073 m_customDragID = 0;
00074 }
00075
00076 SelectTool::~SelectTool()
00077 {
00078 }
00079
00080
00087 bool SelectTool::processEvent(QEvent* e)
00088 {
00089 KivioCanvas* canvas = view()->canvasWidget();
00090 QMouseEvent *m;
00091
00092 switch (e->type())
00093 {
00094 case QEvent::MouseButtonDblClick:
00095 m = (QMouseEvent *)e;
00096
00097 if( m->button() == LeftButton ) {
00098 leftDoubleClick(m->pos());
00099 }
00100
00101 canvas->setFocus();
00102 return true;
00103 break;
00104
00105 case QEvent::MouseButtonPress:
00106 m = (QMouseEvent *)e;
00107
00108 if( m->button() == RightButton ) {
00109 showPopupMenu(m->globalPos());
00110 } else if( m->button() == LeftButton ) {
00111 if(m->state() & ControlButton) {
00112 m_controlKey = true;
00113 } else {
00114 m_controlKey = false;
00115 }
00116
00117 mousePress( m->pos() );
00118 }
00119
00120 canvas->setFocus();
00121 return true;
00122 break;
00123
00124 case QEvent::MouseButtonRelease:
00125 mouseRelease( ((QMouseEvent *)e)->pos() );
00126 canvas->setFocus();
00127 return true;
00128 break;
00129
00130 case QEvent::MouseMove:
00131 mouseMove( static_cast<QMouseEvent*>(e));
00132 return true;
00133 break;
00134
00135 case QEvent::KeyPress:
00136 if((static_cast<QKeyEvent*>(e)->key() >= Key_Left) && (static_cast<QKeyEvent*>(e)->key() <= Key_Down)) {
00137 keyPress(static_cast<QKeyEvent*>(e));
00138 return true;
00139 }
00140 break;
00141
00142 default:
00143 break;
00144 }
00145
00146 return false;
00147 }
00148
00149 void SelectTool::setActivated(bool a)
00150 {
00151 if(a) {
00152 m_selectAction->setChecked(true);
00153 view()->canvasWidget()->unsetCursor();
00154 m_mode = stmNone;
00155 emit activated(this);
00156 } else if(m_selectAction->isChecked()) {
00157 m_selectAction->setChecked(false);
00158 view()->canvasWidget()->activePage()->setPaintSelected(true);
00159 }
00160 }
00161
00165 void SelectTool::select(const QRect &r)
00166 {
00167
00168 KoPoint startPoint = view()->canvasWidget()->mapFromScreen( QPoint( r.x(), r.y() ) );
00169 KoPoint releasePoint = view()->canvasWidget()->mapFromScreen( QPoint( r.x() + r.width(), r.y() + r.height() ) );
00170
00171
00172 double x, y, w, h;
00173
00174
00175 x = startPoint.x() < releasePoint.x() ? startPoint.x() : releasePoint.x();
00176 y = startPoint.y() < releasePoint.y() ? startPoint.y() : releasePoint.y();
00177
00178
00179 w = releasePoint.x() - startPoint.x();
00180
00181 if( w < 0.0 ) {
00182 w *= -1.0;
00183 }
00184
00185 h = releasePoint.y() - startPoint.y();
00186
00187 if( h < 0.0 ) {
00188 h *= -1.0;
00189 }
00190
00191
00192 view()->activePage()->selectStencils( x, y, w, h );
00193 }
00194
00195 void SelectTool::mousePress(const QPoint &pos)
00196 {
00197
00198 m_lastPoint = view()->canvasWidget()->mapFromScreen(pos);
00199 m_origPoint = m_lastPoint;
00200
00201
00202 if( startCustomDragging(pos, true) )
00203 {
00204 m_mode = stmCustomDragging;
00205 return;
00206 }
00207
00208
00209 if( startResizing(pos) )
00210 {
00211 m_mode = stmResizing;
00212 return;
00213 }
00214
00215
00216
00217 if( startCustomDragging(pos, false) )
00218 {
00219 m_mode = stmCustomDragging;
00220 return;
00221 }
00222
00223
00224 if( startDragging(pos, false) )
00225 {
00226 m_mode = stmDragging;
00227 return;
00228 }
00229
00230
00231 if( startRubberBanding(pos) )
00232 {
00233 m_mode = stmDrawRubber;
00234 return;
00235 }
00236 }
00237
00238
00242 bool SelectTool::startRubberBanding(const QPoint &pos)
00243 {
00244 KivioCanvas* canvas = view()->canvasWidget();
00245
00246 if( !m_controlKey )
00247 canvas->activePage()->unselectAllStencils();
00248
00249 canvas->startRectDraw( pos, KivioCanvas::Rubber );
00250 canvas->repaint();
00251
00252 return true;
00253 }
00254
00255
00259 bool SelectTool::startDragging(const QPoint &pos, bool onlySelected)
00260 {
00261 KivioCanvas* canvas = view()->canvasWidget();
00262 KivioPage *pPage = canvas->activePage();
00263 KivioStencil *pStencil;
00264 int colType;
00265
00266
00267 double threshold = view()->zoomHandler()->unzoomItY(4);
00268
00269 KoPoint pagePoint = canvas->mapFromScreen( pos );
00270
00271 pStencil = pPage->checkForStencil( &pagePoint, &colType, threshold, onlySelected );
00272
00273 if( !pStencil )
00274 return false;
00275
00276 canvas->setEnabled(false);
00277
00278 if( pStencil->isSelected() )
00279 {
00280
00281
00282 if( m_controlKey==true ) {
00283 pPage->unselectStencil( pStencil );
00284 }
00285
00286
00287 }
00288 else
00289 {
00290
00291 if( !m_controlKey )
00292 pPage->unselectAllStencils();
00293
00294 pPage->selectStencil( pStencil );
00295
00296 view()->canvasWidget()->updateAutoGuideLines();
00297 }
00298
00299
00300 canvas->beginUnclippedSpawnerPainter();
00301
00302
00303 KivioSelectDragData *pData;
00304 m_lstOldGeometry.clear();
00305 pStencil = canvas->activePage()->selectedStencils()->first();
00306
00307 while( pStencil )
00308 {
00309 pData = new KivioSelectDragData;
00310 pData->rect = pStencil->rect();
00311 m_lstOldGeometry.append(pData);
00312
00313 pStencil = canvas->activePage()->selectedStencils()->next();
00314 }
00315
00316 m_selectedRect = view()->activePage()->getRectForAllSelectedStencils();
00317 changeMouseCursor(pos);
00318
00319 m_mode = stmDragging;
00320 m_firstTime = true;
00321 canvas->setEnabled(true);
00322 return true;
00323 }
00324
00325 bool SelectTool::startCustomDragging(const QPoint &pos, bool selectedOnly )
00326 {
00327 KivioCanvas* canvas = view()->canvasWidget();
00328 KivioPage *pPage = canvas->activePage();
00329 KivioStencil *pStencil;
00330 int colType;
00331
00332 KoPoint pagePoint = canvas->mapFromScreen( pos );
00333
00334
00335 double threshold = view()->zoomHandler()->unzoomItY(4);
00336
00337 pStencil = pPage->checkForStencil( &pagePoint, &colType, threshold, selectedOnly );
00338
00339 if( !pStencil || colType < kctCustom ) {
00340 return false;
00341 }
00342
00343
00344 if(pStencil->isSelected()) {
00345
00346
00347 if(m_controlKey) {
00348 pPage->unselectStencil(pStencil);
00349 }
00350 } else {
00351
00352 if(!m_controlKey) {
00353 pPage->unselectAllStencils();
00354 }
00355
00356 pPage->selectStencil( pStencil );
00357 }
00358
00359 m_pCustomDraggingStencil = pStencil;
00360
00361
00362 m_mode = stmCustomDragging;
00363
00364 m_customDragID = colType;
00365 m_customDragOrigPoint = pStencil->customIDPoint(m_customDragID);
00366
00367 view()->canvasWidget()->setShowConnectorTargets(true);
00368 view()->canvasWidget()->repaint();
00369
00370
00371 canvas->beginUnclippedSpawnerPainter();
00372 m_firstTime = true;
00373
00374 return true;
00375 }
00376
00380 bool SelectTool::startResizing(const QPoint &pos)
00381 {
00382 KivioCanvas* canvas = view()->canvasWidget();
00383 KoPoint pagePoint = canvas->mapFromScreen(pos);
00384 KivioSelectDragData *pData;
00385
00386 double x = pagePoint.x();
00387 double y = pagePoint.y();
00388
00389
00390 KivioStencil *pStencil = canvas->activePage()->selectedStencils()->first();
00391 while( pStencil )
00392 {
00393 m_resizeHandle = isOverResizeHandle(pStencil, x, y);
00394 if( m_resizeHandle > 0 )
00395 {
00396 switch( m_resizeHandle )
00397 {
00398 case 1:
00399 m_origPoint.setCoords(pStencil->x(), pStencil->y());
00400 break;
00401
00402 case 2:
00403 m_origPoint.setCoords((pStencil->x() + pStencil->w()) / 2.0, pStencil->y());
00404 break;
00405
00406 case 3:
00407 m_origPoint.setCoords(pStencil->x() + pStencil->w(), pStencil->y());
00408 break;
00409
00410 case 4:
00411 m_origPoint.setCoords(pStencil->x() + pStencil->w(), (pStencil->y() + pStencil->h()) / 2.0);
00412 break;
00413
00414 case 5:
00415 m_origPoint.setCoords(pStencil->x() + pStencil->w(), pStencil->y() + pStencil->h());
00416 break;
00417
00418 case 6:
00419 m_origPoint.setCoords((pStencil->x() + pStencil->w()) / 2.0, pStencil->y() + pStencil->h());
00420 break;
00421
00422 case 7:
00423 m_origPoint.setCoords(pStencil->x(), pStencil->y() + pStencil->h());
00424 break;
00425
00426 case 8:
00427 m_origPoint.setCoords(pStencil->x(), (pStencil->y() + pStencil->h()) / 2.0);
00428 break;
00429 }
00430
00431 m_lstOldGeometry.clear();
00432 pData = new KivioSelectDragData;
00433 pData->rect = pStencil->rect();
00434 m_lstOldGeometry.append(pData);
00435
00436 m_pResizingStencil = pStencil;
00437
00438
00439 canvas->beginUnclippedSpawnerPainter();
00440 m_firstTime = true;
00441
00442 return true;
00443 }
00444
00445 pStencil = canvas->activePage()->selectedStencils()->next();
00446 }
00447
00448 return false;
00449 }
00450
00451
00452
00453 void SelectTool::mouseMove(QMouseEvent* e)
00454 {
00455 QPoint pos = e->pos();
00456 bool ignoreGridGuides = e->state() & ShiftButton;
00457
00458 switch( m_mode )
00459 {
00460 case stmDrawRubber:
00461 continueRubberBanding(pos);
00462 break;
00463
00464 case stmDragging:
00465 continueDragging(pos, ignoreGridGuides);
00466 break;
00467
00468 case stmCustomDragging:
00469 continueCustomDragging(pos);
00470 break;
00471
00472 case stmResizing:
00473 continueResizing(pos, ignoreGridGuides);
00474 break;
00475
00476 default:
00477 changeMouseCursor(pos);
00478 break;
00479 }
00480
00481 m_lastPoint = view()->canvasWidget()->mapFromScreen(pos);
00482 }
00483
00484 void SelectTool::continueRubberBanding(const QPoint &pos)
00485 {
00486 view()->canvasWidget()->continueRectDraw( pos, KivioCanvas::Rubber );
00487 }
00488
00489
00497 void SelectTool::continueDragging(const QPoint &pos, bool ignoreGridGuides)
00498 {
00499 KivioCanvas* canvas = view()->canvasWidget();
00500 KoPoint pagePoint = canvas->mapFromScreen( pos );
00501
00502 double dx = pagePoint.x() - m_origPoint.x();
00503 double dy = pagePoint.y() - m_origPoint.y();
00504
00505 bool snappedX;
00506 bool snappedY;
00507
00508 double newX, newY;
00509
00510
00511 if(!m_firstTime) {
00512 canvas->drawSelectedStencilsXOR();
00513 } else {
00514 canvas->activePage()->setPaintSelected(false);
00515 canvas->repaint();
00516 m_firstTime = false;
00517 }
00518
00519
00520 KoPoint p;
00521
00522 newX = m_selectedRect.x() + dx;
00523 newY = m_selectedRect.y() + dy;
00524
00525 if(!ignoreGridGuides) {
00526
00527 p.setCoords(newX, newY);
00528
00529 p = canvas->snapToGrid(p);
00530
00531 newX = p.x();
00532 newY = p.y();
00533
00534
00535
00536 p.setCoords(m_selectedRect.x() + dx + m_selectedRect.width(), m_selectedRect.y() + dy + m_selectedRect.height());
00537 p = canvas->snapToGuides(p, snappedX, snappedY);
00538
00539 if(snappedX) {
00540 newX = p.x() - m_selectedRect.width();
00541 }
00542
00543 if(snappedY) {
00544 newY = p.y() - m_selectedRect.height();
00545 }
00546
00547
00548 p.setCoords(m_selectedRect.x() + dx + (m_selectedRect.width() / 2.0),
00549 m_selectedRect.y() + dy + (m_selectedRect.height() / 2.0));
00550 p = canvas->snapToGuides(p, snappedX, snappedY);
00551
00552 if(snappedX) {
00553 newX = p.x() - (m_selectedRect.width() / 2.0);
00554 }
00555
00556 if(snappedY) {
00557 newY = p.y() - (m_selectedRect.height() / 2.0);
00558 }
00559
00560
00561 p.setCoords(m_selectedRect.x() + dx, m_selectedRect.y() + dy);
00562 p = canvas->snapToGuides(p, snappedX, snappedY);
00563
00564 if(snappedX) {
00565 newX = p.x();
00566 }
00567
00568 if(snappedY) {
00569 newY = p.y();
00570 }
00571 }
00572
00573 dx = newX - m_selectedRect.x();
00574 dy = newY - m_selectedRect.y();
00575
00576 KivioSelectDragData *pData;
00577 KivioStencil *pStencil = canvas->activePage()->selectedStencils()->first();
00578 pData = m_lstOldGeometry.first();
00579
00580 while( pStencil && pData )
00581 {
00582 newX = pData->rect.x() + dx;
00583 newY = pData->rect.y() + dy;
00584
00585 if( pStencil->protection()->at( kpX ) == false ) {
00586 pStencil->setX(newX);
00587 }
00588 if( pStencil->protection()->at( kpY ) == false ) {
00589 pStencil->setY(newY);
00590 }
00591
00592 pData = m_lstOldGeometry.next();
00593 pStencil = canvas->activePage()->selectedStencils()->next();
00594 }
00595
00596
00597 canvas->drawSelectedStencilsXOR();
00598 view()->updateToolBars();
00599 }
00600
00601 void SelectTool::continueCustomDragging(const QPoint &pos)
00602 {
00603 KivioCanvas* canvas = view()->canvasWidget();
00604 KoPoint pagePoint = canvas->mapFromScreen(pos);
00605 bool hit = false;
00606
00607 if(m_pCustomDraggingStencil->type() == kstConnector){
00608 pagePoint = canvas->activePage()->snapToTarget(pagePoint, 8.0, hit);
00609 }
00610
00611 if(!hit) {
00612 pagePoint = canvas->snapToGridAndGuides( pagePoint );
00613 }
00614
00615 KivioCustomDragData data;
00616 data.page = canvas->activePage();
00617 data.dx = pagePoint.x() - m_lastPoint.x();
00618 data.dy = pagePoint.y() - m_lastPoint.y();
00619 data.x = pagePoint.x();
00620 data.y = pagePoint.y();
00621 data.id = m_customDragID;
00622 data.scale = view()->zoomHandler()->zoomedResolutionY();
00623
00624
00625 if(m_pCustomDraggingStencil->type() != kstConnector){
00626
00627 if(!m_firstTime) {
00628 canvas->drawStencilXOR(m_pCustomDraggingStencil);
00629 } else {
00630 m_pCustomDraggingStencil->setHidden(true);
00631 canvas->repaint();
00632 m_firstTime = false;
00633 }
00634 }
00635
00636
00637 if( m_pCustomDraggingStencil )
00638 m_pCustomDraggingStencil->customDrag( &data );
00639
00640
00641 if(m_pCustomDraggingStencil->type() != kstConnector){
00642 canvas->drawStencilXOR(m_pCustomDraggingStencil);
00643 } else {
00644 view()->canvasWidget()->repaint();
00645 }
00646
00647 view()->updateToolBars();
00648 }
00649
00650
00651 void SelectTool::continueResizing(const QPoint &pos, bool ignoreGridGuides)
00652 {
00653 KivioCanvas* canvas = view()->canvasWidget();
00654 KoPoint pagePoint = canvas->mapFromScreen(pos);
00655
00656 if(!ignoreGridGuides) {
00657 pagePoint = canvas->snapToGridAndGuides( pagePoint );
00658 }
00659
00660 KivioSelectDragData *pData = m_lstOldGeometry.first();
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 if( !pData )
00676 {
00677 kdDebug(43000) << "SelectTool::continueResizing() - Original geometry not found" << endl;
00678 return;
00679 }
00680
00681 double dx = pagePoint.x() - m_origPoint.x();
00682 double dy = pagePoint.y() - m_origPoint.y();
00683
00684 if((dx > 0) || (dy > 0) || (dx < 0) || (dy < 0)) {
00685
00686 if(!m_firstTime) {
00687 canvas->drawStencilXOR( m_pResizingStencil );
00688 } else {
00689 m_pResizingStencil->setHidden(true);
00690 canvas->repaint();
00691 m_firstTime = false;
00692 }
00693
00694 double sx = pData->rect.x();
00695 double sy = pData->rect.y();
00696 double sw = pData->rect.width();
00697 double sh = pData->rect.height();
00698 double ratio = sw / sh;
00699
00700 switch( m_resizeHandle )
00701 {
00702 case 1:
00703 if( m_pResizingStencil->protection()->testBit( kpWidth )==false &&
00704 m_pResizingStencil->protection()->testBit( kpHeight )==false )
00705 {
00706 if((dx > dy) && (dx != 0)) {
00707 dy = dx / ratio;
00708 } else {
00709 dx = dy * ratio;
00710 }
00711
00712 m_pResizingStencil->setX( sx + dx );
00713 m_pResizingStencil->setW( sw - dx );
00714
00715 m_pResizingStencil->setY( sy + dy );
00716 m_pResizingStencil->setH( sh - dy );
00717 }
00718 break;
00719
00720 case 2:
00721 if( m_pResizingStencil->protection()->testBit( kpHeight )==false )
00722 {
00723 m_pResizingStencil->setY( sy + dy );
00724 m_pResizingStencil->setH( sh - dy );
00725 }
00726 break;
00727
00728 case 3:
00729 if( m_pResizingStencil->protection()->testBit( kpHeight )==false &&
00730 m_pResizingStencil->protection()->testBit( kpWidth )==false )
00731 {
00732 if((dx > dy) && (dx != 0)) {
00733 dy = -(dx / ratio);
00734 } else {
00735 dx = -(dy * ratio);
00736 }
00737
00738 m_pResizingStencil->setY( sy + dy );
00739 m_pResizingStencil->setH( sh - dy );
00740
00741 m_pResizingStencil->setW( sw + dx );
00742 }
00743 break;
00744
00745 case 4:
00746 if( m_pResizingStencil->protection()->testBit( kpWidth )==false )
00747 {
00748
00749
00750 m_pResizingStencil->setW( sw + dx );
00751 }
00752 break;
00753
00754 case 5:
00755 if( m_pResizingStencil->protection()->testBit( kpWidth )==false &&
00756 m_pResizingStencil->protection()->testBit( kpHeight )==false )
00757 {
00758 if((dx > dy) && (dx != 0)) {
00759 dy = dx / ratio;
00760 } else {
00761 dx = dy * ratio;
00762 }
00763
00764 m_pResizingStencil->setW( sw + dx );
00765 m_pResizingStencil->setH( sh + dy );
00766 }
00767 break;
00768
00769 case 6:
00770 if( m_pResizingStencil->protection()->testBit( kpHeight )==false )
00771 {
00772 m_pResizingStencil->setH( sh + dy );
00773 }
00774 break;
00775
00776 case 7:
00777 if( m_pResizingStencil->protection()->testBit( kpWidth )==false &&
00778 m_pResizingStencil->protection()->testBit( kpHeight )==false )
00779 {
00780 if((dx > dy) && (dx != 0)) {
00781 dy = -(dx / ratio);
00782 } else {
00783 dx = -(dy * ratio);
00784 }
00785
00786 m_pResizingStencil->setX( sx + dx );
00787 m_pResizingStencil->setW( sw - dx );
00788
00789 m_pResizingStencil->setH( sh + dy );
00790 }
00791 break;
00792
00793 case 8:
00794 if( m_pResizingStencil->protection()->testBit( kpWidth )==false )
00795 {
00796 KoPoint pinPoint = m_pResizingStencil->pinPoint();
00797 m_pResizingStencil->setPinPoint(KoPoint(pinPoint.x() - (dx / 2.0), pinPoint.y()));
00798 m_pResizingStencil->setX( sx + dx );
00799 m_pResizingStencil->setW( sw - dx );
00800 }
00801 break;
00802
00803 default:
00804 kdDebug(43000) << "SelectTool::continueResizing() - unknown resize handle: " << m_resizeHandle << endl;
00805 break;
00806 }
00807
00808 canvas->drawStencilXOR( m_pResizingStencil );
00809 view()->updateToolBars();
00810 }
00811 }
00812
00813
00817 void SelectTool::changeMouseCursor(const QPoint &pos)
00818 {
00819 KivioCanvas* canvas = view()->canvasWidget();
00820 KoPoint pagePoint = canvas->mapFromScreen(pos);
00821 KivioStencil *pStencil;
00822 double threshold = view()->zoomHandler()->unzoomItY(4);
00823 int cursorType;
00824
00825
00826 pStencil = canvas->activePage()->selectedStencils()->first();
00827 while( pStencil )
00828 {
00829 cursorType = isOverResizeHandle(pStencil, pagePoint.x(), pagePoint.y());
00830 switch( cursorType )
00831 {
00832 case 1:
00833 canvas->setCursor( sizeFDiagCursor );
00834 return;
00835
00836 case 2:
00837 canvas->setCursor( sizeVerCursor );
00838 return;
00839
00840 case 3:
00841 canvas->setCursor( sizeBDiagCursor );
00842 return;
00843
00844 case 4:
00845 canvas->setCursor( sizeHorCursor );
00846 return;
00847
00848 case 5:
00849 canvas->setCursor( sizeFDiagCursor );
00850 return;
00851
00852 case 6:
00853 canvas->setCursor( sizeVerCursor );
00854 return;
00855
00856 case 7:
00857 canvas->setCursor( sizeBDiagCursor );
00858 return;
00859
00860 case 8:
00861 canvas->setCursor( sizeHorCursor );
00862 return;
00863
00864 default:
00865 if( pStencil->checkForCollision( &pagePoint, threshold )!= kctNone )
00866 {
00867 canvas->setCursor( sizeAllCursor );
00868 return;
00869 }
00870 break;
00871
00872 }
00873
00874
00875 pStencil = canvas->activePage()->selectedStencils()->next();
00876 }
00877
00878 canvas->unsetCursor();
00879 }
00880
00881
00885 #define RESIZE_BOX_TEST( x, y, bx, by ) \
00886 x >= bx-three_pixels && \
00887 x <= bx+three_pixels && \
00888 y >= by-three_pixels && \
00889 y <= by+three_pixels
00890
00894 int SelectTool::isOverResizeHandle( KivioStencil *pStencil, const double x, const double y )
00895 {
00896 double three_pixels = 4.0;
00897
00898 int available;
00899
00900 QWMatrix m;
00901 double w = pStencil->w();
00902 double h = pStencil->h();
00903 double w2 = pStencil->w() / 2.0;
00904 double h2 = pStencil->h() / 2.0;
00905 m.translate(pStencil->x(), pStencil->y());
00906 m.translate(w2, h2);
00907 m.rotate(pStencil->rotation());
00908 m.translate(-w2, -h2);
00909
00910
00911 KoPoint tl(0 * m.m11() + 0 * m.m21() + m.dx(), 0 * m.m12() + 0 * m.m22() + m.dy());
00912 KoPoint t(w2 * m.m11() + 0 * m.m21() + m.dx(), w2 * m.m12() + 0 * m.m22() + m.dy());
00913 KoPoint tr(w * m.m11() + 0 * m.m21() + m.dx(), w * m.m12() + 0 * m.m22() + m.dy());
00914 KoPoint r(w * m.m11() + h2 * m.m21() + m.dx(), w * m.m12() + h2 * m.m22() + m.dy());
00915 KoPoint br(w * m.m11() + h * m.m21() + m.dx(), w * m.m12() + h * m.m22() + m.dy());
00916 KoPoint b(w2 * m.m11() + h * m.m21() + m.dx(), w2 * m.m12() + h * m.m22() + m.dy());
00917 KoPoint bl(0 * m.m11() + h * m.m21() + m.dx(), 0 * m.m12() + h * m.m22() + m.dy());
00918 KoPoint l(0 * m.m11() + h2 * m.m21() + m.dx(), 0 * m.m12() + h2 * m.m22() + m.dy());
00919
00920 available = pStencil->resizeHandlePositions();
00921
00922
00923 if( !available )
00924 return 0;
00925
00926
00927
00928 if( available & krhpNW &&
00929 RESIZE_BOX_TEST( x, y, tl.x(), tl.y() ) )
00930 return 1;
00931
00932
00933 if( available & krhpN &&
00934 RESIZE_BOX_TEST( x, y, t.x(), t.y() ) )
00935 return 2;
00936
00937
00938 if( available & krhpNE &&
00939 RESIZE_BOX_TEST( x, y, tr.x(), tr.y() ) )
00940 return 3;
00941
00942
00943 if( available & krhpE &&
00944 RESIZE_BOX_TEST( x, y, r.x(), r.y() ) )
00945 return 4;
00946
00947
00948 if( available & krhpSE &&
00949 RESIZE_BOX_TEST( x, y, br.x(), br.y() ) )
00950 return 5;
00951
00952
00953 if( available & krhpS &&
00954 RESIZE_BOX_TEST( x, y, b.x(), b.y() ) )
00955 return 6;
00956
00957
00958 if( available & krhpSW &&
00959 RESIZE_BOX_TEST( x, y, bl.x(), bl.y() ) )
00960 return 7;
00961
00962
00963 if( available & krhpW &&
00964 RESIZE_BOX_TEST( x, y, l.x(), l.y() ) )
00965 return 8;
00966
00967
00968 return 0;
00969 }
00970
00971
00972 void SelectTool::mouseRelease(const QPoint &pos)
00973 {
00974 m_releasePoint = pos;
00975
00976 switch( m_mode )
00977 {
00978 case stmDrawRubber:
00979 endRubberBanding(pos);
00980 break;
00981
00982 case stmCustomDragging:
00983 endCustomDragging(pos);
00984 break;
00985
00986 case stmDragging:
00987 endDragging(pos);
00988 break;
00989
00990 case stmResizing:
00991 endResizing(pos);
00992 break;
00993 }
00994
00995 m_mode = stmNone;
00996
00997 view()->canvasWidget()->guideLines().repaintAfterSnapping();
00998 view()->doc()->updateView(view()->activePage());
00999 }
01000
01001 void SelectTool::endRubberBanding(const QPoint &pos)
01002 {
01003 KivioCanvas* canvas = view()->canvasWidget();
01004
01005 canvas->endRectDraw();
01006
01007 KoPoint p = canvas->mapFromScreen(pos);
01008
01009
01010 if( m_origPoint.x() != p.x() && m_origPoint.y() != p.y() )
01011 {
01012 select(canvas->rect());
01013 }
01014
01015 view()->updateToolBars();
01016 }
01017
01018 void SelectTool::endDragging(const QPoint&)
01019 {
01020 KivioCanvas* canvas = view()->canvasWidget();
01021 canvas->activePage()->setPaintSelected(true);
01022 KMacroCommand *macro=new KMacroCommand( i18n("Move Stencil"));
01023 KivioStencil *pStencil = canvas->activePage()->selectedStencils()->first();
01024 KivioSelectDragData *pData = m_lstOldGeometry.first();
01025 bool moved = false;
01026
01027 while( pStencil && pData )
01028 {
01029 if((pData->rect.x() != pStencil->rect().x()) || (pData->rect.y() != pStencil->rect().y())) {
01030 KivioMoveStencilCommand * cmd = new KivioMoveStencilCommand( i18n("Move Stencil"),
01031 pStencil, pData->rect, pStencil->rect(), canvas->activePage());
01032 macro->addCommand( cmd);
01033
01034 if(pStencil->type() == kstConnector) {
01035 pStencil->searchForConnections(view()->activePage(), view()->zoomHandler()->unzoomItY(4));
01036 }
01037
01038 moved = true;
01039 }
01040
01041 pData = m_lstOldGeometry.next();
01042 pStencil = canvas->activePage()->selectedStencils()->next();
01043 }
01044
01045 if(moved) {
01046 canvas->doc()->addCommand( macro );
01047 } else {
01048 delete macro;
01049 }
01050
01051 canvas->drawSelectedStencilsXOR();
01052 canvas->endUnclippedSpawnerPainter();
01053
01054 m_lstOldGeometry.clear();
01055 }
01056
01057 void SelectTool::endCustomDragging(const QPoint&)
01058 {
01059 KivioCanvas* canvas = view()->canvasWidget();
01060 m_pCustomDraggingStencil->setHidden(false);
01061 KivioCustomDragCommand* cmd = new KivioCustomDragCommand(i18n("Move Connector Point"), view()->activePage(),
01062 m_pCustomDraggingStencil, m_customDragID, m_customDragOrigPoint,
01063 m_pCustomDraggingStencil->customIDPoint(m_customDragID));
01064 view()->doc()->addCommand(cmd);
01065 m_customDragID = 0;
01066 KivioStencil *pStencil = canvas->activePage()->selectedStencils()->first();
01067
01068 while( pStencil )
01069 {
01070 if(pStencil->type() == kstConnector) {
01071 pStencil->searchForConnections(view()->activePage(), view()->zoomHandler()->unzoomItY(4));
01072 }
01073
01074 pStencil = canvas->activePage()->selectedStencils()->next();
01075 }
01076
01077 canvas->endUnclippedSpawnerPainter();
01078
01079 canvas->setShowConnectorTargets(false);
01080 canvas->repaint();
01081 }
01082
01083 void SelectTool::endResizing(const QPoint&)
01084 {
01085 KivioCanvas* canvas = view()->canvasWidget();
01086 m_pResizingStencil->setHidden(false);
01087 KivioResizeStencilCommand * cmd = new KivioResizeStencilCommand( i18n("Resize Stencil"),
01088 m_pResizingStencil, m_lstOldGeometry.first()->rect, m_pResizingStencil->rect(), view()->activePage());
01089 canvas->doc()->addCommand( cmd );
01090
01091 canvas->drawStencilXOR( m_pResizingStencil );
01092
01093 if(m_pResizingStencil->type() == kstConnector) {
01094 m_pResizingStencil->searchForConnections(view()->activePage(), view()->zoomHandler()->unzoomItY(4));
01095 }
01096
01097
01098 canvas->endUnclippedSpawnerPainter();
01099
01100
01101 m_pResizingStencil = NULL;
01102 m_resizeHandle = 0;
01103 }
01104
01108 void SelectTool::showPopupMenu( const QPoint &pos )
01109 {
01110 KPopupMenu* menu = 0;
01111
01112 if(view()->activePage()->selectedStencils()->count() < 1) {
01113 menu = static_cast<KPopupMenu*>(view()->factory()->container("PagePopup", view()));
01114 } else {
01115 menu = static_cast<KPopupMenu*>(view()->factory()->container("StencilPopup", view()));
01116 m_arrowHeadAction->setEnabled(view()->activePage()->checkForStencilTypeInSelection(kstConnector));
01117
01118 if(view()->activePage()->checkForTextBoxesInSelection()) {
01119 m_textEditAction->setEnabled(true);
01120 } else {
01121 m_textEditAction->setEnabled(false);
01122 }
01123 }
01124
01125 if(menu) {
01126 m_lastPoint = view()->canvasWidget()->mapFromScreen(pos);
01127 menu->popup(pos);
01128 } else {
01129 kdDebug(43000) << "What no popup! *ARGH*!" << endl;
01130 }
01131 }
01132
01133
01141 void SelectTool::leftDoubleClick(const QPoint& pos)
01142 {
01143 if( view()->activePage()->selectedStencils()->count() <= 0 )
01144 return;
01145
01146 KoPoint pagePoint = view()->canvasWidget()->mapFromScreen(pos);
01147
01148 double threshold = view()->zoomHandler()->unzoomItY(4);
01149 int colType;
01150 KivioPage *page = view()->activePage();
01151 KivioStencil* stencil = page->checkForStencil( &pagePoint, &colType, threshold, false);
01152
01153 if(stencil) {
01154
01155 Kivio::Plugin *p = view()->pluginManager()->findPlugin("Text Mouse Tool");
01156
01157 if( !p )
01158 {
01159 kdDebug(43000) << "SelectTool::leftDoubleClick() - unable to locate Text Tool" << endl;
01160 return;
01161 }
01162
01163 static_cast<Kivio::MouseTool*>(p)->applyToolAction(stencil, pagePoint);
01164 }
01165 }
01166
01167 void SelectTool::editText(QPtrList<KivioStencil>* stencils)
01168 {
01169
01170 Kivio::Plugin *p = view()->pluginManager()->findPlugin("Text Mouse Tool");
01171 if( !p )
01172 {
01173 kdDebug(43000) << "SelectTool::leftDoubleClick() - unable to locate Text Tool" << endl;
01174 return;
01175 }
01176
01177
01178 static_cast<Kivio::MouseTool*>(p)->applyToolAction(stencils);
01179 }
01180
01181 void SelectTool::showProperties()
01182 {
01183
01184 if(view()->activePage()->selectedStencils()->count() == 0) {
01185 view()->paperLayoutDlg();
01186 }
01187 }
01188
01189 void SelectTool::editStencilText()
01190 {
01191 editText(view()->activePage()->selectedStencils());
01192 }
01193
01194 void SelectTool::keyPress(QKeyEvent* e)
01195 {
01196 KivioCanvas* canvas = view()->canvasWidget();
01197
01198 canvas->setEnabled(false);
01199
01200
01201 canvas->beginUnclippedSpawnerPainter();
01202
01203
01204 KivioSelectDragData *pData;
01205 m_lstOldGeometry.clear();
01206 KivioStencil* pStencil = canvas->activePage()->selectedStencils()->first();
01207
01208 while( pStencil )
01209 {
01210 pData = new KivioSelectDragData;
01211 pData->rect = pStencil->rect();
01212 m_lstOldGeometry.append(pData);
01213
01214
01215 pStencil = canvas->activePage()->selectedStencils()->next();
01216 }
01217
01218 m_selectedRect = view()->activePage()->getRectForAllSelectedStencils();
01219
01220 m_mode = stmDragging;
01221 canvas->setEnabled(true);
01222 m_origPoint = m_selectedRect.topLeft();
01223 KivioGridData gd = view()->doc()->grid();
01224 bool ignoreGridGuides = e->state() & ShiftButton;
01225 double distX, distY;
01226
01227 if(ignoreGridGuides || !view()->doc()->grid().isSnap) {
01228 distX = view()->zoomHandler()->unzoomItX(1);
01229 distY = view()->zoomHandler()->unzoomItY(1);
01230 } else {
01231 distX = gd.freq.width();
01232 distY = gd.freq.height();
01233 }
01234
01235 switch(e->key()) {
01236 case Key_Left:
01237 continueDragging(canvas->mapToScreen(KoPoint(m_selectedRect.x() - distX,
01238 m_selectedRect.y())), ignoreGridGuides);
01239 break;
01240 case Key_Up:
01241 continueDragging(canvas->mapToScreen(KoPoint(m_selectedRect.x(),
01242 m_selectedRect.y() - distY)), ignoreGridGuides);
01243 break;
01244 case Key_Right:
01245 continueDragging(canvas->mapToScreen(KoPoint(m_selectedRect.x() + distX,
01246 m_selectedRect.y())), ignoreGridGuides);
01247 break;
01248 case Key_Down:
01249 continueDragging(canvas->mapToScreen(KoPoint(m_selectedRect.x(),
01250 m_selectedRect.y() + distY)), ignoreGridGuides);
01251 break;
01252 default:
01253 break;
01254 }
01255
01256 endDragging(QPoint());
01257 canvas->guideLines().repaintAfterSnapping();
01258 canvas->setFocus();
01259 }
01260
01261 #include "tool_select.moc"