1 /***************************************************************************
2 * Copyright (C) 2004-2006 by David Saxton *
3 * david@bluehaze.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 ***************************************************************************/
10
11 #include "cnitemgroup.h"
12 #include "canvasitemparts.h"
13 #include "dptext.h"
14 #include "canvasmanipulator.h"
15 #include "connector.h"
16 #include "flowcontainer.h"
17 #include "icndocument.h"
18 #include "itemview.h"
19 #include "mechanicsdocument.h"
20 #include "mechanicsgroup.h"
21 #include "mechanicsitem.h"
22 #include "node.h"
23 #include "nodegroup.h"
24 #include "picitem.h"
25 #include "resizeoverlay.h"
26
27 #include "utils.h"
28 #include <cmath>
29 #include <cstdlib>
30
31 #include <KConfigGroup>
32 #include <KSharedConfig>
33
34 #include <QDebug>
35 #include <QCursor>
36 #include <QPainter>
37 #include <QTimer>
38
39 // FIXME: This source file is HUUUGE!!!, contains numerous clases, should be broken down.
40
41
42 //BEGIN class CMManager
CMManager(ItemDocument * itemDocument)43 CMManager::CMManager( ItemDocument *itemDocument )
44 : QObject()
45 {
46 b_allowItemScroll = true;
47 p_lastMouseOverResizeHandle = nullptr;
48 m_canvasManipulator = nullptr;
49 p_itemDocument = itemDocument;
50 m_cmState = 0;
51 p_lastMouseOverItem = nullptr;
52 p_lastItemClicked = nullptr;
53 m_drawAction = -1;
54 m_allowItemScrollTmr = new QTimer(this);
55 connect( m_allowItemScrollTmr, SIGNAL(timeout()), this, SLOT(slotAllowItemScroll()) );
56
57 KConfigGroup grGen = KSharedConfig::openConfig()->group("General");
58 slotSetManualRoute( grGen.readEntry( "ManualRouting", false ) );
59 }
60
61
~CMManager()62 CMManager::~CMManager()
63 {
64 delete m_allowItemScrollTmr;
65 delete m_canvasManipulator;
66
67 const ManipulatorInfoList::iterator end = m_manipulatorInfoList.end();
68 for ( ManipulatorInfoList::iterator it = m_manipulatorInfoList.begin(); it != end; ++it )
69 {
70 delete *it;
71 }
72 m_manipulatorInfoList.clear();
73 }
74
75
addManipulatorInfo(ManipulatorInfo * eventInfo)76 void CMManager::addManipulatorInfo( ManipulatorInfo *eventInfo )
77 {
78 if ( eventInfo && !m_manipulatorInfoList.contains(eventInfo) ) {
79 m_manipulatorInfoList.prepend(eventInfo);
80 }
81 }
82
83
cancelCurrentManipulation()84 void CMManager::cancelCurrentManipulation()
85 {
86 delete m_canvasManipulator;
87 m_canvasManipulator = nullptr;
88 setRepeatedAddId();
89 }
90
91
mousePressEvent(EventInfo eventInfo)92 void CMManager::mousePressEvent( EventInfo eventInfo )
93 {
94 if (m_canvasManipulator)
95 {
96 if (m_canvasManipulator->mousePressedRepeat(eventInfo))
97 {
98 delete m_canvasManipulator;
99 m_canvasManipulator = nullptr;
100 }
101 return;
102 }
103
104 uint eventState=0;
105 if (eventInfo.isRightClick)
106 eventState |= CMManager::es_right_click;
107
108 if (eventInfo.ctrlPressed)
109 eventState |= CMManager::es_ctrl_pressed;
110
111 uint itemType=0;
112 uint cnItemType=0;
113
114 KtlQCanvasItem * qcanvasItem = eventInfo.qcanvasItemClickedOn;
115
116 if ( ! qcanvasItem ) itemType = it_none;
117 else if ( dynamic_cast<Node*>(qcanvasItem) ) itemType = it_node;
118 else if ( dynamic_cast<ConnectorLine*>(qcanvasItem) || dynamic_cast<Connector*>(qcanvasItem) )
119 itemType = it_connector;
120 else if ( dynamic_cast<PinItem*>(qcanvasItem) ) itemType = it_pin;
121 else if ( dynamic_cast<ResizeHandle*>(qcanvasItem) ) itemType = it_resize_handle;
122 else if ( DrawPart *drawPartClickedOn = dynamic_cast<DrawPart*>(qcanvasItem) )
123 {
124 itemType = it_drawpart;
125
126 if ( drawPartClickedOn->mousePressEvent(eventInfo) ) {
127 p_lastItemClicked = drawPartClickedOn;
128 return;
129 }
130
131 if ( drawPartClickedOn->isMovable() )
132 cnItemType |= CMManager::isi_isMovable;
133 } else if ( MechanicsItem *p_mechanicsItemClickedOn = dynamic_cast<MechanicsItem*>(qcanvasItem) )
134 {
135 itemType = it_mechanics_item;
136
137 if ( p_mechanicsItemClickedOn->mousePressEvent(eventInfo) )
138 {
139 p_lastItemClicked = p_mechanicsItemClickedOn;
140 return;
141 }
142 } else {
143 if ( Widget *widget = dynamic_cast<Widget*>(qcanvasItem) )
144 qcanvasItem = widget->parent();
145
146 if ( CNItem *cnItemClickedOn = dynamic_cast<CNItem*>(qcanvasItem) )
147 {
148 itemType = it_canvas_item;
149
150 if ( cnItemClickedOn->mousePressEvent(eventInfo) )
151 {
152 p_lastItemClicked = cnItemClickedOn;
153 return;
154 }
155
156 if ( cnItemClickedOn->isMovable() )
157 cnItemType |= CMManager::isi_isMovable;
158 }
159 }
160
161 // uint highestScore=0;
162 // ManipulatorInfo *best = nullptr;
163 const ManipulatorInfoList::iterator end = m_manipulatorInfoList.end();
164 for ( ManipulatorInfoList::iterator it = m_manipulatorInfoList.begin(); it != end && !m_canvasManipulator; ++it )
165 {
166 if ( (*it)->m_acceptManipulationPtr( eventState, m_cmState, itemType, cnItemType ) )
167 {
168 m_canvasManipulator = (*it)->m_createManipulatorPtr( p_itemDocument, this );
169 }
170 }
171
172 if (m_canvasManipulator)
173 {
174 if (m_canvasManipulator->mousePressedInitial(eventInfo))
175 {
176 delete m_canvasManipulator;
177 m_canvasManipulator = nullptr;
178 }
179 }
180 }
181
182
mouseDoubleClickEvent(const EventInfo & eventInfo)183 void CMManager::mouseDoubleClickEvent( const EventInfo &eventInfo )
184 {
185 if (m_canvasManipulator)
186 {
187 // Translate this into a repeat-click event
188 if (m_canvasManipulator->mousePressedRepeat(eventInfo))
189 {
190 delete m_canvasManipulator;
191 m_canvasManipulator = nullptr;
192 }
193 return;
194 }
195
196 Item *item = dynamic_cast<Item*>(eventInfo.qcanvasItemClickedOn);
197 if (item)
198 {
199 item->mouseDoubleClickEvent(eventInfo);
200 return;
201 }
202
203 Widget *widget = dynamic_cast<Widget*>(eventInfo.qcanvasItemClickedOn);
204 if (widget)
205 {
206 widget->parent()->mouseDoubleClickEvent(eventInfo);
207 return;
208 }
209 }
210
211
mouseMoveEvent(const EventInfo & eventInfo)212 void CMManager::mouseMoveEvent( const EventInfo &eventInfo )
213 {
214 if (m_canvasManipulator)
215 {
216 if (m_canvasManipulator->mouseMoved(eventInfo))
217 {
218 delete m_canvasManipulator;
219 m_canvasManipulator = nullptr;
220 }
221 ItemView *itemView = dynamic_cast<ItemView*>(p_itemDocument->activeView());
222 if (itemView)
223 itemView->scrollToMouse(eventInfo.pos);
224 return;
225 }
226
227 //BEGIN
228 KtlQCanvasItem *qcnItem = p_itemDocument->itemAtTop(eventInfo.pos);
229 Item *item;
230 Widget *widget = dynamic_cast<Widget*>(qcnItem);
231 if (widget) item = widget->parent();
232 else item = dynamic_cast<Item*>(qcnItem);
233
234 if ( p_lastMouseOverItem != (QPointer<Item>)item ) {
235 QEvent event(QEvent::Leave);
236
237 if (p_lastMouseOverItem)
238 p_lastMouseOverItem->leaveEvent(nullptr);
239
240 if (item) item->enterEvent(nullptr);
241
242 p_lastMouseOverItem = item;
243 }
244
245 // If we clicked on an item, then continue to pass mouse events to that item until we release the mouse...
246 if (p_lastItemClicked) {
247 p_lastItemClicked->mouseMoveEvent(eventInfo);
248 } else if (item) {
249 item->mouseMoveEvent(eventInfo);
250 }
251 //END
252
253 updateCurrentResizeHandle( dynamic_cast<ResizeHandle*>(qcnItem) );
254 }
255
256
updateCurrentResizeHandle(ResizeHandle * resizeHandle)257 void CMManager::updateCurrentResizeHandle( ResizeHandle * resizeHandle )
258 {
259 if ( p_lastMouseOverResizeHandle != (QPointer<ResizeHandle>)resizeHandle )
260 {
261 if (p_lastMouseOverResizeHandle)
262 p_lastMouseOverResizeHandle->setHover(false);
263 p_lastMouseOverResizeHandle = resizeHandle;
264 if (resizeHandle)
265 resizeHandle->setHover(true);
266 }
267 }
268
269
mouseReleaseEvent(const EventInfo & eventInfo)270 void CMManager::mouseReleaseEvent( const EventInfo &eventInfo )
271 {
272 // If it returns true, then it has finished its editing operation
273 if ( m_canvasManipulator && m_canvasManipulator->mouseReleased(eventInfo) )
274 {
275 delete m_canvasManipulator;
276 m_canvasManipulator = nullptr;
277 }
278
279 if (p_lastItemClicked)
280 {
281 p_lastItemClicked->mouseReleaseEvent(eventInfo);
282 p_lastItemClicked = nullptr;
283 }
284
285 updateCurrentResizeHandle( dynamic_cast<ResizeHandle*>( p_itemDocument->itemAtTop(eventInfo.pos) ) );
286 }
287
288
wheelEvent(const EventInfo & eventInfo)289 void CMManager::wheelEvent( const EventInfo &eventInfo )
290 {
291 bool accepted = false;
292 if (b_allowItemScroll)
293 {
294 KtlQCanvasItem *qcnItem = p_itemDocument->itemAtTop(eventInfo.pos);
295 Item *item;
296 Widget *widget = dynamic_cast<Widget*>(qcnItem);
297 if (widget)
298 item = widget->parent();
299 else item = dynamic_cast<Item*>(qcnItem);
300 if (item) accepted = item->wheelEvent(eventInfo);
301 }
302 if (!accepted)
303 {
304 // Only allow scrolling of items if we have not just been scrolling the canvas
305 b_allowItemScroll = false;
306 m_allowItemScrollTmr->stop();
307 m_allowItemScrollTmr->setSingleShot(true);
308 m_allowItemScrollTmr->start(500 /*,true */ );
309
310 ItemView *itemView = dynamic_cast<ItemView*>(p_itemDocument->activeView());
311 if (itemView)
312 {
313 itemView->cvbEditor()->setPassEventsToView(false);
314 itemView->cvbEditor()->contentsWheelEvent( eventInfo.wheelEvent( 0, 0 ) );
315 itemView->cvbEditor()->setPassEventsToView(true);
316 }
317 }
318 }
319
320
setDrawAction(int drawAction)321 void CMManager::setDrawAction( int drawAction )
322 {
323 if ( m_drawAction == drawAction )
324 return;
325
326 m_drawAction = drawAction;
327 setCMState( cms_draw, (m_drawAction != -1) );
328 }
329
330
slotSetManualRoute(bool manualRoute)331 void CMManager::slotSetManualRoute( bool manualRoute )
332 {
333 KConfigGroup grGen = KSharedConfig::openConfig()->group("General");
334 grGen.writeEntry( "ManualRouting", manualRoute );
335
336 setCMState( cms_manual_route, manualRoute );
337 }
338
339
setCMState(CMState type,bool state)340 void CMManager::setCMState( CMState type, bool state )
341 {
342 // Set or clear the correct bit
343 state ? (m_cmState|=type) : (m_cmState&=(~type));
344
345 if ( type == CMManager::cms_manual_route )
346 emit manualRoutingChanged(state);
347 }
348
349
setRepeatedAddId(const QString & repeatedId)350 void CMManager::setRepeatedAddId( const QString & repeatedId )
351 {
352 m_repeatedItemId = repeatedId;
353 }
354 //END class CMManager
355
356
357
358 //BEGIN class CanvasManipulator
CanvasManipulator(ItemDocument * itemDocument,CMManager * cmManager)359 CanvasManipulator::CanvasManipulator( ItemDocument *itemDocument, CMManager *cmManager )
360 {
361 p_itemDocument = itemDocument;
362 p_icnDocument = dynamic_cast<ICNDocument*>(itemDocument);
363 p_mechanicsDocument = dynamic_cast<MechanicsDocument*>(itemDocument);
364 p_canvas = p_itemDocument->canvas();
365 // b_connectorsAllowedRouting = true;
366 p_selectList = p_itemDocument->selectList();
367 p_cnItemSelectList = dynamic_cast<CNItemGroup*>(p_selectList);
368 p_mechItemSelectList = dynamic_cast<MechanicsGroup*>(p_selectList);
369 p_cnItemClickedOn = nullptr;
370 p_cmManager = cmManager;
371
372 connect( itemDocument->canvas(), SIGNAL(resized( const QRect&, const QRect& )), this, SLOT(canvasResized( const QRect&, const QRect& )) );
373 }
374
375
~CanvasManipulator()376 CanvasManipulator::~CanvasManipulator()
377 {
378 }
379
380
snapPoint(QPoint point)381 QPoint CanvasManipulator::snapPoint( QPoint point )
382 {
383 point /= 8;
384 point *= 8;
385 point += QPoint( 4, 4 );
386 return point;
387 }
388 //END class CanvasManipulator
389
390
CMRepeatedItemAdd(ItemDocument * itemDocument,CMManager * cmManager)391 CMRepeatedItemAdd::CMRepeatedItemAdd( ItemDocument *itemDocument, CMManager *cmManager )
392 : CanvasManipulator( itemDocument, cmManager )
393 {
394 }
395
~CMRepeatedItemAdd()396 CMRepeatedItemAdd::~CMRepeatedItemAdd()
397 {
398 }
399
construct(ItemDocument * itemDocument,CMManager * cmManager)400 CanvasManipulator* CMRepeatedItemAdd::construct( ItemDocument *itemDocument, CMManager *cmManager )
401 {
402 return new CMRepeatedItemAdd(itemDocument,cmManager);
403 }
404
manipulatorInfo()405 ManipulatorInfo *CMRepeatedItemAdd::manipulatorInfo()
406 {
407 ManipulatorInfo *eventInfo = new ManipulatorInfo();
408 eventInfo->m_acceptManipulationPtr = CMRepeatedItemAdd::acceptManipulation;
409 eventInfo->m_createManipulatorPtr = CMRepeatedItemAdd::construct;
410 return eventInfo;
411 }
412
acceptManipulation(uint,uint cmState,uint,uint)413 bool CMRepeatedItemAdd::acceptManipulation( uint /*eventState*/, uint cmState, uint /*itemType*/, uint /*cnItemType*/ )
414 {
415 return (cmState & CMManager::cms_repeated_add);
416 }
417
mousePressedRepeat(const EventInfo & eventInfo)418 bool CMRepeatedItemAdd::mousePressedRepeat( const EventInfo &eventInfo )
419 {
420 return mousePressedInitial(eventInfo);
421 }
422
mousePressedInitial(const EventInfo & eventInfo)423 bool CMRepeatedItemAdd::mousePressedInitial( const EventInfo &eventInfo )
424 {
425 m_eventInfo = eventInfo;
426 if (eventInfo.isRightClick)
427 {
428 p_cmManager->setCMState( CMManager::cms_repeated_add, false );
429 return true;
430 }
431
432 p_icnDocument->addItem( p_cmManager->repeatedItemId(), eventInfo.pos, true );
433 p_itemDocument->requestStateSave();
434 return false;
435 }
436
437
mouseMoved(const EventInfo &)438 bool CMRepeatedItemAdd::mouseMoved( const EventInfo &/*eventInfo*/ )
439 {
440 return false;
441 }
442
443
mouseReleased(const EventInfo &)444 bool CMRepeatedItemAdd::mouseReleased( const EventInfo &/*eventInfo*/ )
445 {
446 return false;
447 }
448
449
CMRightClick(ItemDocument * itemDocument,CMManager * cmManager)450 CMRightClick::CMRightClick( ItemDocument *itemDocument, CMManager *cmManager )
451 : CanvasManipulator( itemDocument, cmManager )
452 {
453 }
454
~CMRightClick()455 CMRightClick::~CMRightClick()
456 {
457 }
458
construct(ItemDocument * itemDocument,CMManager * cmManager)459 CanvasManipulator* CMRightClick::construct( ItemDocument *itemDocument, CMManager *cmManager )
460 {
461 return new CMRightClick(itemDocument,cmManager);
462 }
463
manipulatorInfo()464 ManipulatorInfo *CMRightClick::manipulatorInfo()
465 {
466 ManipulatorInfo *eventInfo = new ManipulatorInfo();
467 // eventInfo->m_eventState.m_activate = CMManager::es_right_click;
468 eventInfo->m_acceptManipulationPtr = CMRightClick::acceptManipulation;
469 eventInfo->m_createManipulatorPtr = CMRightClick::construct;
470 return eventInfo;
471 }
472
acceptManipulation(uint eventState,uint,uint,uint)473 bool CMRightClick::acceptManipulation( uint eventState, uint /*cmState*/, uint /*itemType*/, uint /*cnItemType*/ )
474 {
475 return eventState & CMManager::es_right_click;
476 }
477
478
mousePressedInitial(const EventInfo & eventInfo)479 bool CMRightClick::mousePressedInitial( const EventInfo &eventInfo )
480 {
481 m_eventInfo = eventInfo;
482 p_itemDocument->canvasRightClick( eventInfo.globalPos, eventInfo.qcanvasItemClickedOn );
483 return true;
484 }
485
486
mouseMoved(const EventInfo &)487 bool CMRightClick::mouseMoved( const EventInfo &/*eventInfo*/ )
488 {
489 return true;
490 }
491
492
mouseReleased(const EventInfo &)493 bool CMRightClick::mouseReleased( const EventInfo &/*eventInfo*/ )
494 {
495 return true;
496 }
497
498
499
500 //BEGIN class ConnectorDraw
ConnectorDraw(ItemDocument * itemDocument,CMManager * cmManager)501 ConnectorDraw::ConnectorDraw( ItemDocument *itemDocument, CMManager *cmManager )
502 : CanvasManipulator( itemDocument, cmManager )
503 {
504 p_startNode = nullptr;
505 p_startConnector = nullptr;
506 p_endNode = nullptr;
507 p_endConnector = nullptr;
508 }
509
510
~ConnectorDraw()511 ConnectorDraw::~ConnectorDraw()
512 {
513 }
514
515
validConnectionColor()516 QColor ConnectorDraw::validConnectionColor()
517 {
518 return QColor( 255, 166, 0 );
519 }
520
521
toValidPos(const QPoint & clickPos,Connector * clickedConnector) const522 QPoint ConnectorDraw::toValidPos( const QPoint & clickPos, Connector * clickedConnector ) const
523 {
524 if ( !clickedConnector )
525 return clickPos;
526
527 const QPointList pointList = clickedConnector->connectorPoints();
528
529 QPointList::const_iterator end = pointList.end();
530
531 double dl[] = { 0.5, 8.5, 11.5, 18.0, 23.0 }; // various distances rounded up of (0,0) cells, (0,1), etc
532 for ( unsigned i = 0; i < 5; ++i )
533 {
534 for ( QPointList::const_iterator it = pointList.begin(); it != end; ++it )
535 {
536 if ( qpoint_distance( *it, clickPos ) <= dl[i] )
537 return *it;
538 }
539 }
540
541 return clickPos;
542 }
543
544
toConnector(Node * node)545 Connector * ConnectorDraw::toConnector( Node * node )
546 {
547 if ( !node || node->numCon( true, false ) < 3 )
548 return nullptr;
549
550 return node->getAConnector();
551 }
552
553
grabEndStuff(KtlQCanvasItem * endItem,const QPoint & pos,bool posIsExact)554 void ConnectorDraw::grabEndStuff( KtlQCanvasItem * endItem, const QPoint & pos, bool posIsExact )
555 {
556 if (!endItem)
557 return;
558
559 CNItem * cnItem = dynamic_cast<CNItem*>(endItem);
560 if ( cnItem && !posIsExact )
561 p_endNode = cnItem->getClosestNode(pos);
562 else
563 p_endNode = dynamic_cast<Node*>(endItem);
564
565 if ( p_endNode && p_endNode->numCon( true, false ) > 2 )
566 {
567 p_endConnector = toConnector(p_endNode);
568 p_endNode = nullptr;
569 }
570
571 // If the endItem is a node, we have to finish exactly on the end when posIsExact is true
572 if ( posIsExact && p_endNode && (p_endNode->x() != pos.x() || p_endNode->y() != pos.y()) )
573 p_endNode = nullptr;
574
575 if (!p_endConnector)
576 p_endConnector = dynamic_cast<Connector*>(endItem);
577 }
578 //END class ConnectorDraw
579
580
581 //BEGIN class CMAutoConnector
CMAutoConnector(ItemDocument * itemDocument,CMManager * cmManager)582 CMAutoConnector::CMAutoConnector( ItemDocument *itemDocument, CMManager *cmManager )
583 : ConnectorDraw( itemDocument, cmManager )
584 {
585 m_connectorLine = nullptr;
586 p_startNode = nullptr;
587 p_startConnector = nullptr;
588 }
589
~CMAutoConnector()590 CMAutoConnector::~CMAutoConnector()
591 {
592 delete m_connectorLine;
593
594 }
595
construct(ItemDocument * itemDocument,CMManager * cmManager)596 CanvasManipulator* CMAutoConnector::construct( ItemDocument *itemDocument, CMManager *cmManager )
597 {
598 return new CMAutoConnector(itemDocument,cmManager);
599 }
600
manipulatorInfo()601 ManipulatorInfo *CMAutoConnector::manipulatorInfo()
602 {
603 ManipulatorInfo *eventInfo = new ManipulatorInfo();
604 eventInfo->m_acceptManipulationPtr = CMAutoConnector::acceptManipulation;
605 eventInfo->m_createManipulatorPtr = CMAutoConnector::construct;
606 return eventInfo;
607 }
608
acceptManipulation(uint,uint cmState,uint itemType,uint)609 bool CMAutoConnector::acceptManipulation( uint /*eventState*/, uint cmState, uint itemType, uint /*cnItemType*/ )
610 {
611 return (itemType & (CMManager::it_node | CMManager::it_connector)) && !(cmState & CMManager::cms_manual_route);
612 }
613
mousePressedInitial(const EventInfo & eventInfo)614 bool CMAutoConnector::mousePressedInitial( const EventInfo &eventInfo )
615 {
616 m_eventInfo = eventInfo;
617
618 p_startNode = dynamic_cast<Node*>(eventInfo.qcanvasItemClickedOn);
619
620 if (p_startNode)
621 {
622 m_eventInfo.pos = m_prevPos = p_icnDocument->gridSnap( QPoint( (int)p_startNode->x(), (int)p_startNode->y() ) );
623 if (p_startNode->numCon( true, false ) > 2)
624 {
625 p_startConnector = toConnector(p_startNode);
626 p_startNode = nullptr;
627 }
628 } else if ((p_startConnector = dynamic_cast<Connector*>(eventInfo.qcanvasItemClickedOn) ))
629 {
630 // startConnectorPoint = m_eventInfo.pos = m_prevPos = p_icnDocument->gridSnap(m_eventInfo.pos);
631 startConnectorPoint = m_eventInfo.pos = m_prevPos = toValidPos( m_eventInfo.pos, p_startConnector );
632 } else return true;
633
634 p_icnDocument->unselectAll();
635
636 delete m_connectorLine;
637 m_connectorLine = new KtlQCanvasLine(p_canvas);
638 m_connectorLine->setPen( QColor(0,0,0) );
639 m_connectorLine->setZ( ItemDocument::Z::ConnectorCreateLine );
640 m_connectorLine->show();
641 return false;
642 }
643
644
mouseMoved(const EventInfo & eventInfo)645 bool CMAutoConnector::mouseMoved( const EventInfo &eventInfo )
646 {
647 const QPoint pos = eventInfo.pos;
648
649 int newX = p_icnDocument->gridSnap( pos.x() );
650 int newY = p_icnDocument->gridSnap( pos.y() );
651
652 bool movedFlag = false;
653
654 if ( newX != m_prevPos.x() )
655 {
656 m_prevPos.setX(newX);
657 movedFlag = true;
658 }
659
660 if ( newY != m_prevPos.y() )
661 {
662 m_prevPos.setY(newY);
663 movedFlag = true;
664 }
665
666 m_connectorLine->setPoints( m_eventInfo.pos.x(), m_eventInfo.pos.y(), newX, newY );
667
668 if (movedFlag) {
669 KtlQCanvasItem *startItem = nullptr;
670 if (p_startNode)
671 startItem = p_startNode;
672 else if (p_startConnector)
673 startItem = p_startConnector;
674
675 KtlQCanvasItem *endItem = p_icnDocument->itemAtTop( QPoint( newX, newY ) );
676 if ( CNItem * cni = dynamic_cast<CNItem*>(endItem) )
677 endItem = cni->getClosestNode( QPoint( newX, newY ) );
678
679 bool validLine = p_icnDocument->canConnect( startItem, endItem );
680 m_connectorLine->setPen( validLine ? validConnectionColor() : Qt::black );
681 }
682 return false;
683 }
684
685
mouseReleased(const EventInfo & eventInfo)686 bool CMAutoConnector::mouseReleased( const EventInfo &eventInfo )
687 {
688 const QPoint pos = eventInfo.pos;
689
690 QPoint end = m_connectorLine->endPoint();
691 delete m_connectorLine;
692 m_connectorLine = nullptr;
693
694 KtlQCanvasItem *qcanvasItem = p_icnDocument->itemAtTop(end);
695 if ( !qcanvasItem )
696 return true;
697
698 grabEndStuff( qcanvasItem, pos, false );
699
700 if (p_startConnector)
701 {
702 if (p_endConnector) {
703 if ( !p_icnDocument->createConnector( p_endConnector, p_startConnector, p_icnDocument->gridSnap(pos), startConnectorPoint ) )
704 return true;
705 } else if (p_endNode) {
706 if ( !p_icnDocument->createConnector( p_endNode, p_startConnector, startConnectorPoint ) )
707 return true;
708 } else return true;
709 } else if (p_startNode) {
710 if (p_endConnector)
711 {
712 if ( !p_icnDocument->createConnector( p_startNode, p_endConnector, p_icnDocument->gridSnap(pos) ) )
713 return true;
714 } else if (p_endNode) {
715 if ( !p_icnDocument->createConnector( p_startNode, p_endNode ) )
716 return true;
717 } else return true;
718 } else return true;
719
720 p_itemDocument->requestStateSave();
721 return true;
722 }
723 //END class CMAutoConnector
724
725
726
727 //BEGIN class CMManualConnector
CMManualConnector(ItemDocument * itemDocument,CMManager * cmManager)728 CMManualConnector::CMManualConnector( ItemDocument *itemDocument, CMManager *cmManager )
729 : ConnectorDraw( itemDocument, cmManager )
730 {
731 m_manualConnectorDraw = nullptr;
732 }
733
~CMManualConnector()734 CMManualConnector::~CMManualConnector()
735 {
736 delete m_manualConnectorDraw;
737 }
738
construct(ItemDocument * itemDocument,CMManager * cmManager)739 CanvasManipulator* CMManualConnector::construct( ItemDocument *itemDocument, CMManager *cmManager )
740 {
741 return new CMManualConnector(itemDocument,cmManager);
742 }
743
manipulatorInfo()744 ManipulatorInfo *CMManualConnector::manipulatorInfo()
745 {
746 ManipulatorInfo *eventInfo = new ManipulatorInfo();
747 eventInfo->m_acceptManipulationPtr = CMManualConnector::acceptManipulation;
748 eventInfo->m_createManipulatorPtr = CMManualConnector::construct;
749 return eventInfo;
750 }
751
acceptManipulation(uint,uint cmState,uint itemType,uint)752 bool CMManualConnector::acceptManipulation( uint /*eventState*/, uint cmState, uint itemType, uint /*cnItemType*/ )
753 {
754 return (itemType & (CMManager::it_node | CMManager::it_connector)) && (cmState & CMManager::cms_manual_route);
755 }
756
757
mousePressedInitial(const EventInfo & eventInfo)758 bool CMManualConnector::mousePressedInitial( const EventInfo &eventInfo )
759 {
760 if ( eventInfo.isRightClick ) return true;
761
762 m_eventInfo = eventInfo;
763
764 p_icnDocument->unselectAll();
765
766 QPoint sp;
767
768 if ( (p_startNode = dynamic_cast<Node*>(eventInfo.qcanvasItemClickedOn)) )
769 {
770 sp.setX( (int)p_startNode->x() );
771 sp.setY( (int)p_startNode->y() );
772 if ( p_startNode->numCon( true, false ) > 2 )
773 {
774 p_startConnector = toConnector(p_startNode);
775 p_startNode = nullptr;
776 }
777 }
778 else
779 {
780 p_startConnector = dynamic_cast<Connector*>(eventInfo.qcanvasItemClickedOn);
781 sp = toValidPos( eventInfo.pos, p_startConnector );
782 }
783 startConnectorPoint = sp;
784
785 if (m_manualConnectorDraw)
786 delete m_manualConnectorDraw;
787 m_manualConnectorDraw = new ManualConnectorDraw( p_icnDocument, sp );
788 return false;
789 }
790
791
mousePressedRepeat(const EventInfo & eventInfo)792 bool CMManualConnector::mousePressedRepeat( const EventInfo &eventInfo )
793 {
794 m_eventInfo = eventInfo;
795 if ( eventInfo.isRightClick ) {
796 return true;
797 }
798 m_manualConnectorDraw->mouseClicked( p_icnDocument->gridSnap(m_eventInfo.pos) );
799 return false;
800 }
801
802
mouseMoved(const EventInfo & eventInfo)803 bool CMManualConnector::mouseMoved( const EventInfo &eventInfo )
804 {
805 if ( !m_manualConnectorDraw )
806 return true;
807
808 const QPoint pos = eventInfo.pos;
809
810 int newX = p_icnDocument->gridSnap( pos.x() );
811 int newY = p_icnDocument->gridSnap( pos.y() );
812
813 bool movedFlag = false;
814
815 if ( newX != m_prevPos.x() )
816 {
817 m_prevPos.setX(newX);
818 movedFlag = true;
819 }
820
821 if ( newY != m_prevPos.y() )
822 {
823 m_prevPos.setY(newY);
824 movedFlag = true;
825 }
826
827 if ( movedFlag )
828 {
829 KtlQCanvasItem *startItem = nullptr;
830 if (p_startNode)
831 startItem = p_startNode;
832 else if (p_startConnector)
833 startItem = p_startConnector;
834
835 KtlQCanvasItem * endItem = p_icnDocument->itemAtTop( QPoint( newX, newY ) );
836
837 // If the endItem is a node, we have to finish exactly on the end.
838 if ( Node * node = dynamic_cast<Node*>(endItem) )
839 {
840 if ( node->x() != newX || node->y() != newY )
841 endItem = nullptr;
842 }
843
844 bool validLine = p_icnDocument->canConnect( startItem, endItem );
845
846 m_manualConnectorDraw->setColor( validLine ? validConnectionColor() : Qt::black );
847 m_manualConnectorDraw->mouseMoved( QPoint( newX, newY ) );
848 }
849
850 return false;
851 }
852
853
mouseReleased(const EventInfo & eventInfo)854 bool CMManualConnector::mouseReleased( const EventInfo &eventInfo )
855 {
856 if (!m_manualConnectorDraw) return true;
857
858 QPoint pos = p_icnDocument->gridSnap(eventInfo.pos);
859
860 grabEndStuff( m_manualConnectorDraw->mouseClicked(pos), pos, true );
861
862 if ( !p_endNode && !p_endConnector )
863 return false;
864
865 // Create the points that define the manual route
866 QPointList list = m_manualConnectorDraw->pointList();
867 delete m_manualConnectorDraw;
868 m_manualConnectorDraw = nullptr;
869
870 if (p_startConnector)
871 {
872 if (p_endConnector)
873 {
874 if ( !p_icnDocument->createConnector( p_endConnector, p_startConnector, p_icnDocument->gridSnap(pos), startConnectorPoint, &list ) )
875 return true;
876 } else // if (p_endNode)
877 {
878 if ( !p_icnDocument->createConnector( p_endNode, p_startConnector, startConnectorPoint, &list ) )
879 return true;
880 }
881 } else if (p_startNode) {
882 if (p_endConnector)
883 {
884 if ( !p_icnDocument->createConnector( p_startNode, p_endConnector, p_icnDocument->gridSnap(pos), &list ) )
885 return true;
886 } else // if (p_endNode)
887 {
888 if ( !p_icnDocument->createConnector( p_startNode, p_endNode, &list ) )
889 return true;
890 }
891 } else return true;
892
893 p_itemDocument->requestStateSave();
894 return true;
895 }
896 //END class CMManualConnector
897
898
899 //BEGIN class CMItemMove
CMItemMove(ItemDocument * itemDocument,CMManager * cmManager)900 CMItemMove::CMItemMove( ItemDocument *itemDocument, CMManager *cmManager )
901 : CanvasManipulator( itemDocument, cmManager )
902 {
903 p_flowContainerCandidate = nullptr;
904 m_bItemsSnapToGrid = false;
905 }
906
~CMItemMove()907 CMItemMove::~CMItemMove()
908 {
909 }
910
construct(ItemDocument * itemDocument,CMManager * cmManager)911 CanvasManipulator* CMItemMove::construct( ItemDocument *itemDocument, CMManager *cmManager )
912 {
913 return new CMItemMove(itemDocument,cmManager);
914 }
915
manipulatorInfo()916 ManipulatorInfo *CMItemMove::manipulatorInfo()
917 {
918 ManipulatorInfo *eventInfo = new ManipulatorInfo();
919 eventInfo->m_acceptManipulationPtr = CMItemMove::acceptManipulation;
920 eventInfo->m_createManipulatorPtr = CMItemMove::construct;
921 return eventInfo;
922 }
923
acceptManipulation(uint eventState,uint,uint itemType,uint cnItemType)924 bool CMItemMove::acceptManipulation( uint eventState, uint /*cmState*/, uint itemType, uint cnItemType )
925 {
926 return ((itemType & CMManager::it_canvas_item) || (itemType & CMManager::it_drawpart)) && (cnItemType & CMManager::isi_isMovable) && !(eventState & CMManager::es_right_click);
927 }
928
929
mousePressedInitial(const EventInfo & eventInfo)930 bool CMItemMove::mousePressedInitial( const EventInfo &eventInfo )
931 {
932 m_eventInfo = eventInfo;
933 m_prevPos = eventInfo.pos;
934
935 Item *item = dynamic_cast<Item*>(eventInfo.qcanvasItemClickedOn);
936
937 if (!item) return true;
938
939 if ( !p_selectList->contains(item) )
940 {
941 if (!eventInfo.ctrlPressed)
942 p_itemDocument->unselectAll();
943
944 p_itemDocument->select(item);
945 } else if (m_eventInfo.ctrlPressed)
946 p_itemDocument->unselect(item);
947
948 if ( p_selectList->isEmpty() )
949 return true;
950
951 // We want to allow dragging into FlowContainers if this is a FlowView
952 p_flowContainerCandidate = nullptr;
953 {
954 const ItemList &itemList = p_icnDocument->itemList();
955 const ItemList::const_iterator ciEnd = itemList.end();
956 for ( ItemList::const_iterator it = itemList.begin(); it != ciEnd; ++it )
957 {
958 if ( FlowContainer *flowContainer = dynamic_cast<FlowContainer*>((Item*)*it) )
959 flowContainer->setFullBounds(true);
960 }
961 }
962
963 ItemList itemList = p_cnItemSelectList->items(false);
964 itemList.removeAll((Item*)nullptr);
965
966 m_bItemsSnapToGrid = false;
967 const ItemList::iterator itemListEnd = itemList.end();
968 for ( ItemList::iterator it = itemList.begin(); it != itemListEnd; ++it )
969 {
970 CNItem *cnItem = dynamic_cast<CNItem*>((Item*)*it);
971 if ( !cnItem || !cnItem->canvas() )
972 continue;
973
974 m_bItemsSnapToGrid = true;
975 }
976
977 if ( m_bItemsSnapToGrid )
978 m_prevSnapPoint = this->snapPoint( m_prevPos );
979 else m_prevSnapPoint = m_prevPos;
980
981 ConnectorList fixedConnectors;
982 p_icnDocument->getTranslatable( itemList, &fixedConnectors, &m_translatableConnectors, &m_translatableNodeGroups );
983
984 const ConnectorList::iterator fixedConnectorsEnd = fixedConnectors.end();
985 for ( ConnectorList::iterator it = fixedConnectors.begin(); it != fixedConnectorsEnd; ++it )
986 (*it)->setSemiHidden(true);
987
988 p_flowContainerCandidate = p_icnDocument->flowContainer(eventInfo.pos);
989
990 return false;
991 }
992
993
canvasResized(const QRect &,const QRect &)994 void CMItemMove::canvasResized( const QRect & /*oldSize*/, const QRect & /*newSize*/ )
995 {
996 //QPoint delta = oldSize.topLeft() - newSize.topLeft(); // 2017.10.01 - comment out unused variable
997
998 // scrollCanvasToSelection();
999
1000 // QCursor::setPos( QCursor::pos() + delta );
1001 // m_prevPos += delta;
1002 // m_prevSnapPoint += delta;
1003 }
1004
1005
scrollCanvasToSelection()1006 void CMItemMove::scrollCanvasToSelection()
1007 {
1008 QRect bound;
1009 ItemList itemList = p_cnItemSelectList->items(false);
1010 itemList.removeAll((Item*)nullptr);
1011 const ItemList::iterator itemListEnd = itemList.end();
1012 for ( ItemList::iterator it = itemList.begin(); it != itemListEnd; ++it )
1013 bound |= (*it)->boundingRect();
1014
1015 QPoint scrollToPos = m_prevPos;
1016 if ( m_dx < 0 ) {
1017 // Scrolling left
1018 scrollToPos -= QPoint( bound.left(), 0 );
1019 } else {
1020 // Scrolling right
1021 scrollToPos += QPoint( bound.right(), 0 );
1022 }
1023
1024 if ( m_dy < 0 ) {
1025 // Scrolling up
1026 scrollToPos -= QPoint( 0, bound.top() );
1027 } else {
1028 // Scrolling right
1029 scrollToPos += QPoint( 0, bound.bottom() );
1030 }
1031
1032 ItemView *itemView = dynamic_cast<ItemView*>(p_itemDocument->activeView());
1033 if (itemView)
1034 itemView->scrollToMouse( scrollToPos );
1035 }
1036
1037
mouseMoved(const EventInfo & eventInfo)1038 bool CMItemMove::mouseMoved( const EventInfo &eventInfo )
1039 {
1040 QPoint pos = eventInfo.pos;
1041
1042 QPoint snapPoint = pos;
1043 if ( m_bItemsSnapToGrid )
1044 snapPoint = this->snapPoint( snapPoint );
1045
1046 int dx = snapPoint.x() - m_prevSnapPoint.x();
1047 int dy = snapPoint.y() - m_prevSnapPoint.y();
1048
1049 m_dx = dx;
1050 m_dy = dy;
1051
1052 const ItemList itemList = p_cnItemSelectList->items();
1053 const ItemList::const_iterator end = itemList.end();
1054
1055 for ( ItemList::const_iterator it = itemList.begin(); it != end; ++it )
1056 {
1057 if ( !*it || !(*it)->isMovable() )
1058 continue;
1059
1060 //QRect oldRect = (*it)->boundingRect(); // 2017.10.01 - comment out unused variable
1061 (*it)->moveBy( dx, dy );
1062 //QRect newRect = (*it)->boundingRect();
1063 //QRect merged = oldRect | newRect; // 2017.10.01 - comment out unused variable
1064 }
1065
1066 if ( (dx != 0) || (dy != 0) )
1067 {
1068 const ConnectorList::iterator frEnd = m_translatableConnectors.end();
1069 for ( ConnectorList::iterator it = m_translatableConnectors.begin(); it != frEnd; ++it )
1070 (*it)->translateRoute( dx, dy );
1071
1072 const NodeGroupList::iterator end = m_translatableNodeGroups.end();
1073 for ( NodeGroupList::iterator it = m_translatableNodeGroups.begin(); it != end; ++it )
1074 (*it)->translate( dx, dy );
1075 }
1076
1077 FlowContainer *fc = p_icnDocument->flowContainer(pos);
1078 if ( fc != p_flowContainerCandidate )
1079 {
1080 if ( p_flowContainerCandidate )
1081 {
1082 p_flowContainerCandidate->setSelected(false);
1083 p_flowContainerCandidate = nullptr;
1084 }
1085 }
1086
1087 if (fc)
1088 {
1089 p_flowContainerCandidate = fc;
1090 p_flowContainerCandidate->setSelected(true);
1091 }
1092
1093 p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems );
1094 p_canvas->update();
1095 m_prevPos = pos;
1096 m_prevSnapPoint = snapPoint;
1097
1098 // scrollCanvasToSelection();
1099
1100 return false;
1101 }
1102
1103
mouseReleased(const EventInfo & eventInfo)1104 bool CMItemMove::mouseReleased( const EventInfo &eventInfo )
1105 {
1106 // Is the release event from a right click (which rotates items)?
1107 if ( eventInfo.isRightClick || eventInfo.isMiddleClick )
1108 return false;
1109
1110 QStringList itemIDs;
1111
1112 const ItemList itemList = p_cnItemSelectList->items();
1113 const ItemList::const_iterator ilEnd = itemList.end();
1114 for ( ItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it )
1115 {
1116 if (*it) itemIDs.append( (*it)->id() );
1117 }
1118
1119 //const QPoint pos = eventInfo.pos; // 2017.10.10 - comment out unused variable
1120
1121 // And make sure all connectors are properly shown
1122 const ConnectorList &connectorList = p_icnDocument->connectorList();
1123 const ConnectorList::const_iterator conEnd = connectorList.end();
1124 for ( ConnectorList::const_iterator it = connectorList.begin(); it != conEnd; ++it )
1125 {
1126 (*it)->setSemiHidden(false);
1127 }
1128
1129 if (p_flowContainerCandidate)
1130 {
1131 for ( ItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it )
1132 p_flowContainerCandidate->addChild(*it);
1133
1134 p_flowContainerCandidate->setSelected(false);
1135 p_flowContainerCandidate = nullptr;
1136 } else {
1137 for ( ItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it )
1138 (*it)->setParentItem(nullptr);
1139 }
1140
1141 // And disable the FlowContainers again...
1142 const ItemList &cnItemList = p_icnDocument->itemList();
1143 const ItemList::const_iterator end = cnItemList.end();
1144 for ( ItemList::const_iterator it = cnItemList.begin(); it != end; ++it )
1145 {
1146 if ( FlowContainer *flowContainer = dynamic_cast<FlowContainer*>((Item*)*it) )
1147 flowContainer->setFullBounds(false);
1148 }
1149
1150 if (p_icnDocument) p_icnDocument->requestRerouteInvalidatedConnectors();
1151
1152 if ( m_eventInfo.pos != eventInfo.pos ) p_itemDocument->requestStateSave();
1153
1154 p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems );
1155
1156 return true;
1157 }
1158
1159
mousePressedRepeat(const EventInfo & info)1160 bool CMItemMove::mousePressedRepeat( const EventInfo & info )
1161 {
1162 if ( info.isRightClick )
1163 p_cnItemSelectList->slotRotateCW();
1164 else if ( info.isMiddleClick )
1165 p_cnItemSelectList->flipHorizontally();
1166
1167 return false;
1168 }
1169 //END class CMItemMove
1170
1171
CMItemResize(ItemDocument * itemDocument,CMManager * cmManager)1172 CMItemResize::CMItemResize( ItemDocument *itemDocument, CMManager *cmManager )
1173 : CanvasManipulator( itemDocument, cmManager )
1174 {
1175 }
1176
~CMItemResize()1177 CMItemResize::~CMItemResize()
1178 {
1179 }
1180
construct(ItemDocument * itemDocument,CMManager * cmManager)1181 CanvasManipulator* CMItemResize::construct( ItemDocument *itemDocument, CMManager *cmManager )
1182 {
1183 return new CMItemResize(itemDocument,cmManager);
1184 }
1185
manipulatorInfo()1186 ManipulatorInfo *CMItemResize::manipulatorInfo()
1187 {
1188 ManipulatorInfo *eventInfo = new ManipulatorInfo();
1189 // eventInfo->m_itemType.m_activate = CMManager::it_canvas_item;
1190 eventInfo->m_acceptManipulationPtr = CMItemResize::acceptManipulation;
1191 eventInfo->m_createManipulatorPtr = CMItemResize::construct;
1192 return eventInfo;
1193 }
1194
acceptManipulation(uint eventState,uint,uint itemType,uint)1195 bool CMItemResize::acceptManipulation( uint eventState, uint /*cmState*/, uint itemType, uint /*cnItemType*/ )
1196 {
1197 return (itemType & CMManager::it_resize_handle) && !(eventState & CMManager::es_right_click);
1198 }
1199
1200
mousePressedInitial(const EventInfo & eventInfo)1201 bool CMItemResize::mousePressedInitial( const EventInfo &eventInfo )
1202 {
1203 m_eventInfo = eventInfo;
1204 p_resizeHandle = dynamic_cast<ResizeHandle*>(eventInfo.qcanvasItemClickedOn);
1205 m_rh_dx = p_resizeHandle->x()-eventInfo.pos.x();
1206 m_rh_dy = p_resizeHandle->y()-eventInfo.pos.y();
1207 return false;
1208 }
1209
1210
mouseMoved(const EventInfo & eventInfo)1211 bool CMItemResize::mouseMoved( const EventInfo &eventInfo )
1212 {
1213 int _x = int(m_rh_dx + eventInfo.pos.x());
1214 int _y = int(m_rh_dy + eventInfo.pos.y());
1215
1216 // Shift pressed == snap to grid
1217 if ( eventInfo.shiftPressed )
1218 {
1219 _x = snapToCanvas(_x);
1220 _y = snapToCanvas(_y);
1221 }
1222
1223 p_resizeHandle->moveRH( _x, _y );
1224 return false;
1225 }
1226
1227
mouseReleased(const EventInfo &)1228 bool CMItemResize::mouseReleased( const EventInfo &/*eventInfo*/ )
1229 {
1230 if (p_icnDocument)
1231 p_icnDocument->requestRerouteInvalidatedConnectors();
1232 p_itemDocument->requestStateSave();
1233 return true;
1234 }
1235
1236
CMMechItemMove(ItemDocument * itemDocument,CMManager * cmManager)1237 CMMechItemMove::CMMechItemMove( ItemDocument *itemDocument, CMManager *cmManager )
1238 : CanvasManipulator( itemDocument, cmManager )
1239 {
1240 }
1241
~CMMechItemMove()1242 CMMechItemMove::~CMMechItemMove()
1243 {
1244 }
1245
construct(ItemDocument * itemDocument,CMManager * cmManager)1246 CanvasManipulator* CMMechItemMove::construct( ItemDocument *itemDocument, CMManager *cmManager )
1247 {
1248 return new CMMechItemMove(itemDocument,cmManager);
1249 }
1250
manipulatorInfo()1251 ManipulatorInfo *CMMechItemMove::manipulatorInfo()
1252 {
1253 ManipulatorInfo *eventInfo = new ManipulatorInfo();
1254 // eventInfo->m_itemType.m_activate = CMManager::it_canvas_item;
1255 eventInfo->m_acceptManipulationPtr = CMMechItemMove::acceptManipulation;
1256 eventInfo->m_createManipulatorPtr = CMMechItemMove::construct;
1257 return eventInfo;
1258 }
1259
acceptManipulation(uint eventState,uint,uint itemType,uint)1260 bool CMMechItemMove::acceptManipulation( uint eventState, uint /*cmState*/, uint itemType, uint /*cnItemType*/ )
1261 {
1262 return ((itemType & CMManager::it_mechanics_item) || (itemType & CMManager::it_drawpart)) && !(eventState & CMManager::es_right_click);
1263 }
1264
1265
mousePressedInitial(const EventInfo & eventInfo)1266 bool CMMechItemMove::mousePressedInitial( const EventInfo &eventInfo )
1267 {
1268 m_eventInfo = eventInfo;
1269 m_prevPos = eventInfo.pos;
1270
1271 Item *item = dynamic_cast<Item*>(eventInfo.qcanvasItemClickedOn);
1272 if (!item)
1273 return true;
1274
1275 MechanicsItem *mechItem = dynamic_cast<MechanicsItem*>(eventInfo.qcanvasItemClickedOn);
1276
1277 if (mechItem) m_prevClickedOnSM = mechItem->selectionMode();
1278
1279 if (eventInfo.shiftPressed)
1280 {
1281 p_mechanicsDocument->unselectAll();
1282 p_mechanicsDocument->select(item);
1283 if (mechItem)
1284 {
1285 mechItem->setSelectionMode(MechanicsItem::sm_move);
1286 mechItem->setParentItem(nullptr);
1287 }
1288 } else if ( !p_selectList->contains(mechItem) )
1289 {
1290 if (!eventInfo.ctrlPressed)
1291 p_mechanicsDocument->unselectAll();
1292
1293 p_mechanicsDocument->select(item);
1294
1295 if (mechItem)
1296 mechItem->setSelectionMode(MechanicsItem::sm_move);
1297 } else {
1298 if (mechItem)
1299 mechItem->setSelectionMode(MechanicsItem::sm_move);
1300
1301 if (m_eventInfo.ctrlPressed)
1302 p_mechanicsDocument->unselect(item);
1303 }
1304
1305 if ( p_selectList->isEmpty() )
1306 return true;
1307
1308 p_mechItemSelectList->setSelectionMode( MechanicsItem::sm_move );
1309 p_mechItemSelectList->setRaised(true);
1310 return false;
1311 }
1312
1313
mouseMoved(const EventInfo & eventInfo)1314 bool CMMechItemMove::mouseMoved( const EventInfo &eventInfo )
1315 {
1316 const QPoint pos = eventInfo.pos;
1317
1318 int x = pos.x();
1319 int y = pos.y();
1320
1321 const MechItemList itemList = p_mechItemSelectList->toplevelMechItemList();
1322 const MechItemList::const_iterator ilEnd = itemList.end();
1323 for ( MechItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it )
1324 {
1325 if (*it)
1326 (*it)->moveBy( x - m_prevPos.x(), y - m_prevPos.y() );
1327 }
1328
1329 m_prevPos = QPoint( x, y );
1330
1331 p_canvas->update();
1332 p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems );
1333 return false;
1334 }
1335
1336
mouseReleased(const EventInfo & eventInfo)1337 bool CMMechItemMove::mouseReleased( const EventInfo &eventInfo )
1338 {
1339 const QPoint pos = eventInfo.pos;
1340
1341 int dx = pos.x() - m_eventInfo.pos.x();
1342 int dy = pos.y() - m_eventInfo.pos.y();
1343
1344 p_mechItemSelectList->setRaised(false);
1345
1346 MechanicsItem *mechItem = dynamic_cast<MechanicsItem*>(m_eventInfo.qcanvasItemClickedOn);
1347 if ( dx == 0 && dy == 0 )
1348 {
1349 if ( mechItem && mechItem->isSelected() )
1350 {
1351 if ( m_prevClickedOnSM == MechanicsItem::sm_resize )
1352 mechItem->setSelectionMode( MechanicsItem::sm_rotate );
1353 else
1354 mechItem->setSelectionMode( MechanicsItem::sm_resize );
1355 }
1356 p_itemDocument->requestStateSave();
1357 return true;
1358 }
1359
1360 if ( mechItem && mechItem->isSelected() )
1361 {
1362 if ( m_prevClickedOnSM == MechanicsItem::sm_rotate )
1363 mechItem->setSelectionMode(MechanicsItem::sm_rotate);
1364 else
1365 mechItem->setSelectionMode(MechanicsItem::sm_resize);
1366 }
1367
1368 QStringList itemIDs;
1369
1370 ItemList itemList = p_mechItemSelectList->items();
1371 const ItemList::iterator ilEnd = itemList.end();
1372 for ( ItemList::iterator it = itemList.begin(); it != ilEnd; ++it )
1373 {
1374 if (*it) {
1375 itemIDs.append( (*it)->id() );
1376 }
1377 }
1378
1379 p_mechItemSelectList->setSelectionMode( MechanicsItem::sm_resize );
1380 p_itemDocument->requestStateSave();
1381 p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems );
1382 return true;
1383 }
1384
1385
1386
1387 //BEGIN class SelectRectangle
SelectRectangle(int x,int y,int w,int h,KtlQCanvas * qcanvas)1388 SelectRectangle::SelectRectangle( int x, int y, int w, int h, KtlQCanvas *qcanvas )
1389 : m_x(x), m_y(y)
1390 {
1391 m_topLine = new KtlQCanvasLine(qcanvas);
1392 m_rightLine = new KtlQCanvasLine(qcanvas);
1393 m_bottomLine = new KtlQCanvasLine(qcanvas);
1394 m_leftLine = new KtlQCanvasLine(qcanvas);
1395 setSize( w, h );
1396
1397 KtlQCanvasLine* lines[] = { m_topLine, m_rightLine, m_bottomLine, m_leftLine };
1398 for ( int i=0; i<4; ++ i)
1399 {
1400 lines[i]->setPen( QPen( QColor(190,190,190), 1, Qt::DotLine ) );
1401 lines[i]->setZ( ICNDocument::Z::Select );
1402 lines[i]->show();
1403 }
1404 }
1405
1406
~SelectRectangle()1407 SelectRectangle::~SelectRectangle()
1408 {
1409 delete m_topLine;
1410 delete m_rightLine;
1411 delete m_bottomLine;
1412 delete m_leftLine;
1413 }
1414
1415
setSize(int w,int h)1416 void SelectRectangle::setSize( int w, int h )
1417 {
1418 m_topLine->setPoints( m_x, m_y, m_x+w, m_y );
1419 m_rightLine->setPoints( m_x+w, m_y, m_x+w, m_y+h );
1420 m_bottomLine->setPoints( m_x+w, m_y+h, m_x, m_y+h );
1421 m_leftLine->setPoints( m_x, m_y+h, m_x, m_y );
1422 m_w = w;
1423 m_h = h;
1424 }
1425
1426
collisions()1427 KtlQCanvasItemList SelectRectangle::collisions()
1428 {
1429 KtlQCanvas *canvas = m_topLine->canvas();
1430
1431 return canvas->collisions( QRect( m_x, m_y, m_w, m_h ) );
1432 }
1433 //END class SelectRectangle
1434
1435
1436 //BEGIN class CMSelect
CMSelect(ItemDocument * itemDocument,CMManager * cmManager)1437 CMSelect::CMSelect( ItemDocument *itemDocument, CMManager *cmManager )
1438 : CanvasManipulator( itemDocument, cmManager )
1439 {
1440 m_selectRectangle = nullptr;
1441 }
1442
~CMSelect()1443 CMSelect::~CMSelect()
1444 {
1445 delete m_selectRectangle;
1446 }
1447
construct(ItemDocument * itemDocument,CMManager * cmManager)1448 CanvasManipulator* CMSelect::construct( ItemDocument *itemDocument, CMManager *cmManager )
1449 {
1450 return new CMSelect(itemDocument,cmManager);
1451 }
1452
manipulatorInfo()1453 ManipulatorInfo *CMSelect::manipulatorInfo()
1454 {
1455 ManipulatorInfo *eventInfo = new ManipulatorInfo();
1456 // eventInfo->m_itemType.m_activate = CMManager::it_none;
1457 eventInfo->m_acceptManipulationPtr = CMSelect::acceptManipulation;
1458 eventInfo->m_createManipulatorPtr = CMSelect::construct;
1459 return eventInfo;
1460 }
1461
acceptManipulation(uint,uint,uint itemType,uint)1462 bool CMSelect::acceptManipulation( uint /*eventState*/, uint /*cmState*/, uint itemType, uint /*cnItemType*/ )
1463 {
1464 return (itemType & CMManager::it_none);
1465 }
1466
1467
mousePressedInitial(const EventInfo & eventInfo)1468 bool CMSelect::mousePressedInitial( const EventInfo &eventInfo )
1469 {
1470 m_eventInfo = eventInfo;
1471
1472 if (!eventInfo.ctrlPressed) {
1473 p_itemDocument->unselectAll();
1474 }
1475
1476 m_selectRectangle = new SelectRectangle( eventInfo.pos.x(), eventInfo.pos.y(), 0, 0, p_canvas );
1477 return false;
1478 }
1479
1480
mouseMoved(const EventInfo & eventInfo)1481 bool CMSelect::mouseMoved( const EventInfo &eventInfo )
1482 {
1483 QPoint pos = eventInfo.pos;
1484
1485 m_selectRectangle->setSize( pos.x()-m_eventInfo.pos.x(), pos.y()-m_eventInfo.pos.y() );
1486
1487 if (m_eventInfo.ctrlPressed) {
1488 p_itemDocument->select( m_selectRectangle->collisions() );
1489 } else if (p_selectList) {
1490 p_selectList->setItems( m_selectRectangle->collisions() );
1491 }
1492
1493 if (p_selectList && !p_mechanicsDocument) {
1494 p_selectList->setSelected(true);
1495 }
1496 return false;
1497 }
1498
1499
mouseReleased(const EventInfo &)1500 bool CMSelect::mouseReleased( const EventInfo &/*eventInfo*/ )
1501 {
1502 delete m_selectRectangle;
1503 m_selectRectangle = nullptr;
1504
1505 return true;
1506 }
1507 //END class CMSelect
1508
1509
CMItemDrag(ItemDocument * itemDocument,CMManager * cmManager)1510 CMItemDrag::CMItemDrag( ItemDocument *itemDocument, CMManager *cmManager )
1511 : CanvasManipulator( itemDocument, cmManager )
1512 {
1513 b_dragged = false;
1514 }
1515
~CMItemDrag()1516 CMItemDrag::~CMItemDrag()
1517 {
1518 }
1519
construct(ItemDocument * itemDocument,CMManager * cmManager)1520 CanvasManipulator* CMItemDrag::construct( ItemDocument *itemDocument, CMManager *cmManager )
1521 {
1522 return new CMItemDrag(itemDocument,cmManager);
1523 }
1524
manipulatorInfo()1525 ManipulatorInfo *CMItemDrag::manipulatorInfo()
1526 {
1527 ManipulatorInfo *eventInfo = new ManipulatorInfo();
1528 // eventInfo->m_itemType.m_activate = CMManager::it_canvas_item;
1529 eventInfo->m_acceptManipulationPtr = CMItemDrag::acceptManipulation;
1530 eventInfo->m_createManipulatorPtr = CMItemDrag::construct;
1531 return eventInfo;
1532 }
1533
acceptManipulation(uint,uint,uint itemType,uint cnItemType)1534 bool CMItemDrag::acceptManipulation( uint /*eventState*/, uint /*cmState*/, uint itemType, uint cnItemType )
1535 {
1536 return (itemType & (CMManager::it_canvas_item|CMManager::it_pin)) && !(cnItemType & CMManager::isi_isMovable);
1537 }
1538
1539
mousePressedInitial(const EventInfo & eventInfo)1540 bool CMItemDrag::mousePressedInitial( const EventInfo &eventInfo )
1541 {
1542 m_eventInfo = eventInfo;
1543 b_dragged = false;
1544 return false;
1545 }
1546
1547
mouseMoved(const EventInfo & eventInfo)1548 bool CMItemDrag::mouseMoved( const EventInfo &eventInfo )
1549 {
1550 const QPoint pos = eventInfo.pos;
1551
1552 if ( b_dragged ||
1553 pos.x() > (m_eventInfo.pos.x()+4 ) ||
1554 pos.x() < (m_eventInfo.pos.x()-4) ||
1555 pos.y() > (m_eventInfo.pos.y()+4) ||
1556 pos.y() < (m_eventInfo.pos.y()-4) )
1557 {
1558
1559 b_dragged = true;
1560
1561 if ( PinItem * pi = dynamic_cast<PinItem*>(m_eventInfo.qcanvasItemClickedOn) )
1562 pi->dragged( pos.x() - m_eventInfo.pos.x() );
1563 }
1564 return false;
1565 }
1566
1567
mouseReleased(const EventInfo &)1568 bool CMItemDrag::mouseReleased( const EventInfo &/*eventInfo*/ )
1569 {
1570 if ( !b_dragged )
1571 {
1572 if ( PinItem * pi = dynamic_cast<PinItem*>(m_eventInfo.qcanvasItemClickedOn) )
1573 pi->switchState();
1574 }
1575
1576 p_itemDocument->requestStateSave();
1577 return true;
1578 }
1579
1580
1581 //BEGIN class CanvasEllipseDraw
CanvasEllipseDraw(int x,int y,KtlQCanvas * canvas)1582 CanvasEllipseDraw::CanvasEllipseDraw( int x, int y, KtlQCanvas * canvas )
1583 : KtlQCanvasEllipse( 0, 0, canvas )
1584 {
1585 move( x, y );
1586 }
1587
drawShape(QPainter & p)1588 void CanvasEllipseDraw::drawShape( QPainter & p )
1589 {
1590 p.drawEllipse( int(x()-width()/2), int(y()-height()/2), width(), height() );
1591 }
1592 //END class CanvasEllipseDraw
1593
1594
1595 //BEGIN class CMDraw
CMDraw(ItemDocument * itemDocument,CMManager * cmManager)1596 CMDraw::CMDraw( ItemDocument *itemDocument, CMManager *cmManager )
1597 : CanvasManipulator( itemDocument, cmManager )
1598 {
1599 m_pDrawLine = nullptr;
1600 m_pDrawRectangle = nullptr;
1601 m_pDrawEllipse = nullptr;
1602 }
1603
~CMDraw()1604 CMDraw::~CMDraw()
1605 {
1606 p_cmManager->setDrawAction(-1);
1607 }
1608
construct(ItemDocument * itemDocument,CMManager * cmManager)1609 CanvasManipulator* CMDraw::construct( ItemDocument *itemDocument, CMManager *cmManager )
1610 {
1611 return new CMDraw(itemDocument,cmManager);
1612 }
1613
manipulatorInfo()1614 ManipulatorInfo *CMDraw::manipulatorInfo()
1615 {
1616 ManipulatorInfo *eventInfo = new ManipulatorInfo();
1617 eventInfo->m_acceptManipulationPtr = CMDraw::acceptManipulation;
1618 eventInfo->m_createManipulatorPtr = CMDraw::construct;
1619 return eventInfo;
1620 }
1621
acceptManipulation(uint,uint cmState,uint,uint)1622 bool CMDraw::acceptManipulation( uint /*eventState*/, uint cmState, uint /*itemType*/, uint /*cnItemType*/ )
1623 {
1624 return (cmState & CMManager::cms_draw);
1625 }
1626
mousePressedInitial(const EventInfo & eventInfo)1627 bool CMDraw::mousePressedInitial( const EventInfo &eventInfo )
1628 {
1629 m_eventInfo = eventInfo;
1630
1631 switch ( (DrawPart::DrawAction) p_cmManager->drawAction() )
1632 {
1633 case DrawPart::da_text:
1634 case DrawPart::da_rectangle:
1635 case DrawPart::da_image:
1636 {
1637 m_pDrawRectangle = new KtlQCanvasRectangle( eventInfo.pos.x(), eventInfo.pos.y(), 0, 0, p_canvas );
1638 m_pDrawRectangle->setPen( QPen( QColor(0,0,0), 1 ) );
1639 m_pDrawRectangle->setZ( ICNDocument::Z::ConnectorCreateLine );
1640 m_pDrawRectangle->show();
1641 break;
1642 }
1643 case DrawPart::da_ellipse:
1644 {
1645 m_pDrawEllipse = new CanvasEllipseDraw( eventInfo.pos.x(), eventInfo.pos.y(), p_canvas );
1646 m_pDrawEllipse->setPen( QPen( QColor(0,0,0), 1 ) );
1647 m_pDrawEllipse->setZ( ICNDocument::Z::ConnectorCreateLine );
1648 m_pDrawEllipse->show();
1649 break;
1650 }
1651 case DrawPart::da_line:
1652 case DrawPart::da_arrow:
1653 {
1654 m_pDrawLine = new KtlQCanvasLine(p_canvas);
1655 m_pDrawLine->setPoints( eventInfo.pos.x(), eventInfo.pos.y(), eventInfo.pos.x(), eventInfo.pos.y() );
1656 m_pDrawLine->setPen( QPen( QColor(0,0,0), 1 ) );
1657 m_pDrawLine->setZ( ICNDocument::Z::ConnectorCreateLine );
1658 m_pDrawLine->show();
1659 break;
1660 }
1661 default:
1662 return true;
1663 }
1664
1665 return false;
1666 }
1667
1668
mouseMoved(const EventInfo & eventInfo)1669 bool CMDraw::mouseMoved( const EventInfo &eventInfo )
1670 {
1671 const QPoint pos = eventInfo.pos;
1672
1673 if (m_pDrawRectangle)
1674 m_pDrawRectangle->setSize( pos.x()-m_eventInfo.pos.x(), pos.y()-m_eventInfo.pos.y() );
1675
1676 else if (m_pDrawEllipse) {
1677 // QRect r( m_eventInfo.pos.x(), m_eventInfo.pos.y(), pos.x()-m_eventInfo.pos.x(), pos.y()-m_eventInfo.pos.y() );
1678 // r = r.normalized();
1679 //
1680 // m_pDrawEllipse->setSize( r.width(), r.height() );
1681 // m_pDrawEllipse->move( r.left()+(r.width()/2), r.top()+(r.height()/2) );
1682
1683 m_pDrawEllipse->setSize( 2 * abs(pos.x() - m_eventInfo.pos.x()), 2 * abs(pos.y() - m_eventInfo.pos.y()) );
1684 }
1685
1686 else if (m_pDrawLine)
1687 m_pDrawLine->setPoints( eventInfo.pos.x(), eventInfo.pos.y(), m_pDrawLine->endPoint().x(), m_pDrawLine->endPoint().y() );
1688 else return true;
1689
1690 return false;
1691 }
1692
1693
mouseReleased(const EventInfo &)1694 bool CMDraw::mouseReleased( const EventInfo & /*eventInfo*/ )
1695 {
1696 //const QPoint pos = eventInfo.pos; // 2017.10.01 - comment out unused variable
1697
1698 QRect sizeRect;
1699
1700 if ( m_pDrawRectangle || m_pDrawEllipse )
1701 {
1702 if (m_pDrawRectangle)
1703 {
1704 sizeRect = m_pDrawRectangle->rect();
1705
1706 // We have to manually adjust the size rect so that it matches up with what the user has drawn
1707
1708 sizeRect.setWidth( sizeRect.width()+1 );
1709 sizeRect.setHeight( sizeRect.height()+1 );
1710
1711 sizeRect = sizeRect.normalized();
1712
1713 if ( m_pDrawRectangle->rect().width() < 0 )
1714 sizeRect.moveLeft( sizeRect.left() + 1);
1715
1716 if ( m_pDrawRectangle->rect().height() < 0 )
1717 sizeRect.moveTop( sizeRect.top() + 1);
1718 } else {
1719 int w = m_pDrawEllipse->width()+1;
1720 int h = m_pDrawEllipse->height()+1;
1721 int x = int(m_pDrawEllipse->x()-w/2);
1722 int y = int(m_pDrawEllipse->y()-h/2);
1723 sizeRect = QRect( x, y, w, h ).normalized();
1724 }
1725
1726 delete m_pDrawRectangle;
1727 delete m_pDrawEllipse;
1728 m_pDrawRectangle = nullptr;
1729 m_pDrawEllipse = nullptr;
1730 } else if (m_pDrawLine) {
1731 int sx = m_pDrawLine->startPoint().x();
1732 int sy = m_pDrawLine->startPoint().y();
1733 int ex = m_pDrawLine->endPoint().x();
1734 int ey = m_pDrawLine->endPoint().y();
1735
1736 sizeRect = QRect( ex, ey, sx-ex, sy-ey );
1737
1738 delete m_pDrawLine;
1739 m_pDrawLine = nullptr;
1740 } else return true;
1741
1742 QString id;
1743 switch ( (DrawPart::DrawAction) p_cmManager->drawAction() )
1744 {
1745 case DrawPart::da_rectangle:
1746 id = "dp/rectangle";
1747 break;
1748
1749 case DrawPart::da_image:
1750 id = "dp/image";
1751 break;
1752
1753 case DrawPart::da_ellipse:
1754 id = "dp/ellipse";
1755 break;
1756
1757 case DrawPart::da_text:
1758 id = "dp/canvas_text";
1759
1760 if ( sizeRect.width() < 56 )
1761 sizeRect.setWidth( 56 );
1762
1763 if ( sizeRect.height() < 24 )
1764 sizeRect.setHeight( 24 );
1765
1766 break;
1767
1768 case DrawPart::da_line:
1769 id = "dp/line";
1770 break;
1771
1772 case DrawPart::da_arrow:
1773 id = "dp/arrow";
1774 break;
1775 }
1776
1777 if ( id.isEmpty() ) return true;
1778
1779 Item *item = p_itemDocument->addItem( id, sizeRect.topLeft(), true );
1780
1781 if (!item) return true;
1782
1783 item->move( sizeRect.x(), sizeRect.y() ); // We call this again as p_itemDocument->addItem will move the item if it is slightly off the canvas.
1784
1785 item->setSize( 0, 0, sizeRect.width(), sizeRect.height() );
1786
1787 p_itemDocument->requestStateSave();
1788 return true;
1789 }
1790 //END class CMDraw
1791
1792
1793 //BEGIN class ManualConnectorDraw
ManualConnectorDraw(ICNDocument * _icnDocument,const QPoint & initialPos)1794 ManualConnectorDraw::ManualConnectorDraw( ICNDocument *_icnDocument, const QPoint &initialPos )
1795 {
1796 m_color = Qt::black;
1797
1798 icnDocument = _icnDocument;
1799 m_currentPos = m_previousPos = m_initialPos = initialPos;
1800 p_initialItem = icnDocument->itemAtTop(initialPos);
1801
1802 b_currentVertical = false;
1803 b_orientationDefined = false;
1804
1805 m_connectorLines.append( m_previousCon = new KtlQCanvasLine( icnDocument->canvas() ) );
1806 m_connectorLines.append( m_currentCon = new KtlQCanvasLine( icnDocument->canvas() ) );
1807
1808 m_currentCon->setPoints( initialPos.x(), initialPos.y(), initialPos.x(), initialPos.y() );
1809 m_previousCon->setPoints( initialPos.x(), initialPos.y(), initialPos.x(), initialPos.y() );
1810
1811 m_currentCon->setPen( m_color );
1812 m_previousCon->setPen( m_color );
1813
1814 updateConnectorEnds();
1815
1816 m_currentCon->show();
1817 m_previousCon->show();
1818 }
1819
1820
~ManualConnectorDraw()1821 ManualConnectorDraw::~ManualConnectorDraw()
1822 {
1823 const QList<KtlQCanvasLine*>::iterator end = m_connectorLines.end();
1824 for ( QList<KtlQCanvasLine*>::iterator it = m_connectorLines.begin(); it != end; ++it )
1825 delete *it;
1826
1827 m_connectorLines.clear();
1828 }
1829
setColor(const QColor & color)1830 void ManualConnectorDraw::setColor( const QColor & color )
1831 {
1832 m_color = color;
1833
1834 const QList<KtlQCanvasLine*>::iterator end = m_connectorLines.end();
1835 for ( QList<KtlQCanvasLine*>::iterator it = m_connectorLines.begin(); it != end; ++it )
1836 (*it)->setPen( m_color );
1837 }
1838
mouseMoved(const QPoint & pos)1839 void ManualConnectorDraw::mouseMoved( const QPoint &pos )
1840 {
1841 if ( m_currentPos == pos ) return;
1842
1843 if (!b_orientationDefined)
1844 {
1845 QPoint previousStart = m_previousCon->startPoint();
1846
1847 double distance = std::sqrt( std::pow( (double)(m_currentPos.x()-previousStart.x()), 2. ) +
1848 std::pow( (double)(m_currentPos.y()-previousStart.y()), 2. ) );
1849
1850 if ( distance < 24 )
1851 {
1852 b_currentVertical = ( std::abs( double(m_currentPos.x()-previousStart.x()) ) >= std::abs( double(m_currentPos.y()-previousStart.y()) ) );
1853 }
1854
1855 }
1856
1857 m_previousPos = m_currentPos;
1858 m_currentPos = pos;
1859 updateConnectorEnds();
1860 }
1861
1862
mouseClicked(const QPoint & pos)1863 KtlQCanvasItem* ManualConnectorDraw::mouseClicked( const QPoint &pos )
1864 {
1865 if (b_orientationDefined)
1866 b_currentVertical = !b_currentVertical;
1867 else mouseMoved(pos);
1868
1869 b_orientationDefined = true;
1870
1871 m_currentPos = pos;
1872
1873 KtlQCanvasItem * qcanvasItem = icnDocument->itemAtTop(pos);
1874
1875 if ( qcanvasItem && pos != m_initialPos && qcanvasItem != p_initialItem )
1876 return qcanvasItem;
1877
1878 m_previousCon = m_currentCon;
1879
1880 m_connectorLines.append( m_currentCon = new KtlQCanvasLine( icnDocument->canvas() ) );
1881 m_currentCon->setPoints( pos.x(), pos.y(), pos.x(), pos.y() );
1882 m_currentCon->setPen( m_color );
1883 updateConnectorEnds();
1884 m_currentCon->show();
1885
1886 return nullptr;
1887 }
1888
1889
updateConnectorEnds()1890 void ManualConnectorDraw::updateConnectorEnds()
1891 {
1892 QPoint pivot = m_currentPos;
1893 QPoint previousStart = m_previousCon->startPoint();
1894
1895 if (b_currentVertical)
1896 {
1897 pivot.setY( previousStart.y() );
1898 m_currentCon->setPoints( pivot.x(), pivot.y(), pivot.x(), m_currentPos.y() );
1899 } else {
1900 pivot.setX( previousStart.x() );
1901 m_currentCon->setPoints( pivot.x(), pivot.y(), m_currentPos.x(), pivot.y() );
1902 }
1903
1904 m_previousCon->setPoints( previousStart.x(), previousStart.y(), pivot.x(), pivot.y() );
1905 }
1906
1907
pointList()1908 QPointList ManualConnectorDraw::pointList()
1909 {
1910 QPointList list;
1911 list.append(m_initialPos);
1912
1913 const QList<KtlQCanvasLine*>::iterator end = m_connectorLines.end();
1914 for ( QList<KtlQCanvasLine*>::iterator it = m_connectorLines.begin(); it != end; ++it )
1915 {
1916 list.append( (*it)->endPoint() );
1917 }
1918
1919 return list;
1920 }
1921 //END class ManualConnectorDraw
1922
1923
1924 //BEGIN class ManipulatorInfo
ManipulatorInfo()1925 ManipulatorInfo::ManipulatorInfo()
1926 {
1927 }
1928 //END class ManipulatorInfo
1929