/*************************************************************************** * Copyright (C) 2004-2005 by David Saxton * * david@bluehaze.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "cnitemgroup.h" #include "canvasitemparts.h" #include "dptext.h" #include "canvasmanipulator.h" #include "connector.h" #include "flowcontainer.h" #include "icndocument.h" #include "itemview.h" #include "mechanicsdocument.h" #include "mechanicsgroup.h" #include "mechanicsitem.h" #include "node.h" #include "nodegroup.h" #include "picitem.h" #include "resizeoverlay.h" #include #include #include #include #include #include CMManager::CMManager( ItemDocument *itemDocument ) : TQObject() { b_allowItemScroll = true; p_lastMouseOverResizeHandle = 0l; m_canvasManipulator = 0l; p_itemDocument = itemDocument; m_cmState = 0; p_lastMouseOverItem = 0l; p_lastItemClicked = 0l; m_drawAction = -1; m_allowItemScrollTmr = new TQTimer(this); connect( m_allowItemScrollTmr, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotAllowItemScroll()) ); TDEGlobal::config()->setGroup("General"); slotSetManualRoute( TDEGlobal::config()->readBoolEntry( "ManualRouting", false ) ); } CMManager::~CMManager() { delete m_allowItemScrollTmr; m_allowItemScrollTmr = 0l; delete m_canvasManipulator; m_canvasManipulator = 0l; const ManipulatorInfoList::iterator end = m_manipulatorInfoList.end(); for ( ManipulatorInfoList::iterator it = m_manipulatorInfoList.begin(); it != end; ++it ) { delete *it; } m_manipulatorInfoList.clear(); } void CMManager::addManipulatorInfo( ManipulatorInfo *eventInfo ) { if ( eventInfo && !m_manipulatorInfoList.contains(eventInfo) ) { m_manipulatorInfoList.prepend(eventInfo); } } void CMManager::cancelCurrentManipulation() { delete m_canvasManipulator; m_canvasManipulator = 0l; setRepeatedAddId(); } void CMManager::mousePressEvent( EventInfo eventInfo ) { if (m_canvasManipulator) { if (m_canvasManipulator->mousePressedRepeat(eventInfo)) { delete m_canvasManipulator; m_canvasManipulator = 0l; } return; } uint eventState=0; if (eventInfo.isRightClick) eventState |= CMManager::es_right_click; if (eventInfo.ctrlPressed) eventState |= CMManager::es_ctrl_pressed; uint itemType=0; uint cnItemType=0; switch ( eventInfo.itemRtti ) { case ItemDocument::RTTI::None: itemType = CMManager::it_none; break; case ItemDocument::RTTI::Node: itemType = CMManager::it_node; break; case ItemDocument::RTTI::Connector: itemType = CMManager::it_connector; break; case ItemDocument::RTTI::Pin: itemType = CMManager::it_pin; break; case ItemDocument::RTTI::ResizeHandle: itemType = CMManager::it_resize_handle; break; case ItemDocument::RTTI::DrawPart: { itemType = CMManager::it_drawpart; DrawPart *drawPartClickedOn = dynamic_cast(eventInfo.qcanvasItemClickedOn); if ( drawPartClickedOn->mousePressEvent(eventInfo) ) { p_lastItemClicked = drawPartClickedOn; return; } if ( drawPartClickedOn->isMovable() ) cnItemType |= CMManager::isi_isMovable; break; } case ItemDocument::RTTI::Widget: { Widget *widget = dynamic_cast(eventInfo.qcanvasItemClickedOn); if (widget) eventInfo.qcanvasItemClickedOn = widget->parent(); } case ItemDocument::RTTI::CNItem: { itemType = CMManager::it_canvas_item; CNItem *cnItemClickedOn = dynamic_cast(eventInfo.qcanvasItemClickedOn); if ( cnItemClickedOn->mousePressEvent(eventInfo) ) { p_lastItemClicked = cnItemClickedOn; return; } if ( cnItemClickedOn->isMovable() ) cnItemType |= CMManager::isi_isMovable; break; } case ItemDocument::RTTI::MechanicsItem: { itemType = CMManager::it_mechanics_item; MechanicsItem *p_mechanicsItemClickedOn = dynamic_cast(eventInfo.qcanvasItemClickedOn); if ( p_mechanicsItemClickedOn->mousePressEvent(eventInfo) ) { p_lastItemClicked = p_mechanicsItemClickedOn; return; } break; } } // uint highestScore=0; // ManipulatorInfo *best=0l; const ManipulatorInfoList::iterator end = m_manipulatorInfoList.end(); for ( ManipulatorInfoList::iterator it = m_manipulatorInfoList.begin(); it != end && !m_canvasManipulator; ++it ) { if ( (*it)->m_acceptManipulationPtr( eventState, m_cmState, itemType, cnItemType ) ) { m_canvasManipulator = (*it)->m_createManipulatorPtr( p_itemDocument, this ); } } if (m_canvasManipulator) { if (m_canvasManipulator->mousePressedInitial(eventInfo)) { delete m_canvasManipulator; m_canvasManipulator = 0l; } } } void CMManager::mouseDoubleClickEvent( const EventInfo &eventInfo ) { Item *item = dynamic_cast(eventInfo.qcanvasItemClickedOn); if (item) { item->mouseDoubleClickEvent(eventInfo); return; } Widget *widget = dynamic_cast(eventInfo.qcanvasItemClickedOn); if (widget) { widget->parent()->mouseDoubleClickEvent(eventInfo); return; } } void CMManager::mouseMoveEvent( const EventInfo &eventInfo ) { if (m_canvasManipulator) { if (m_canvasManipulator->mouseMoved(eventInfo)) { kdDebug() << k_funcinfo << "About to delete" << endl; delete m_canvasManipulator; kdDebug() << k_funcinfo << "Deleted" << endl; m_canvasManipulator = 0l; kdDebug() << k_funcinfo << "Nullified" << endl; } ItemView *itemView = dynamic_cast(p_itemDocument->activeView()); if (itemView) itemView->scrollToMouse(eventInfo.pos); return; } //BEGIN TQCanvasItem *qcnItem = p_itemDocument->itemAtTop(eventInfo.pos); Item *item; Widget *widget = dynamic_cast(qcnItem); if (widget) item = widget->parent(); else item = dynamic_cast(qcnItem); if ( p_lastMouseOverItem != (TQGuardedPtr)item ) { TQEvent event(TQEvent::Leave); if (p_lastMouseOverItem) p_lastMouseOverItem->leaveEvent(); if (item) item->enterEvent(); p_lastMouseOverItem = item; } // If we clicked on an item, then continue to pass mouse events to that item until we release the mouse... if (p_lastItemClicked) { p_lastItemClicked->mouseMoveEvent(eventInfo); } else if (item) { item->mouseMoveEvent(eventInfo); } //END updateCurrentResizeHandle( dynamic_cast(qcnItem) ); } void CMManager::updateCurrentResizeHandle( ResizeHandle * resizeHandle ) { if ( p_lastMouseOverResizeHandle != (TQGuardedPtr)resizeHandle ) { if (p_lastMouseOverResizeHandle) p_lastMouseOverResizeHandle->setHover(false); p_lastMouseOverResizeHandle = resizeHandle; if (resizeHandle) resizeHandle->setHover(true); } } void CMManager::mouseReleaseEvent( const EventInfo &eventInfo ) { // If it returns true, then it has finished its editing operation if ( m_canvasManipulator && m_canvasManipulator->mouseReleased(eventInfo) ) { delete m_canvasManipulator; m_canvasManipulator = 0l; } if (p_lastItemClicked) { p_lastItemClicked->mouseReleaseEvent(eventInfo); p_lastItemClicked=0l; } updateCurrentResizeHandle( dynamic_cast( p_itemDocument->itemAtTop(eventInfo.pos) ) ); } void CMManager::wheelEvent( const EventInfo &eventInfo ) { bool accepted = false; if (b_allowItemScroll) { TQCanvasItem *qcnItem = p_itemDocument->itemAtTop(eventInfo.pos); Item *item; Widget *widget = dynamic_cast(qcnItem); if (widget) item = widget->parent(); else item = dynamic_cast(qcnItem); if (item) accepted = item->wheelEvent(eventInfo); } if (!accepted) { // Only allow scrolling of items if we have not just been scrolling the canvas b_allowItemScroll = false; m_allowItemScrollTmr->stop(); m_allowItemScrollTmr->start(500,true); ItemView *itemView = dynamic_cast(p_itemDocument->activeView()); if (itemView) { itemView->cvbEditor()->setPassEventsToView(false); itemView->cvbEditor()->contentsWheelEvent( eventInfo.wheelEvent( 0, 0 ) ); itemView->cvbEditor()->setPassEventsToView(true); } } } void CMManager::setDrawAction( int drawAction ) { if ( m_drawAction == drawAction ) return; m_drawAction = drawAction; setCMState( cms_draw, (m_drawAction != -1) ); } void CMManager::slotSetManualRoute( bool manualRoute ) { TDEGlobal::config()->setGroup("General"); TDEGlobal::config()->writeEntry( "ManualRouting", manualRoute ); setCMState( cms_manual_route, manualRoute ); } void CMManager::setCMState( CMState type, bool state ) { // Set or clear the correct bit state ? (m_cmState|=type) : (m_cmState&=(~type)); if ( type == CMManager::cms_manual_route ) emit manualRoutingChanged(state); } void CMManager::setRepeatedAddId( const TQString & repeatedId ) { m_repeatedItemId = repeatedId; } CanvasManipulator::CanvasManipulator( ItemDocument *itemDocument, CMManager *cmManager ) { p_itemDocument = itemDocument; p_icnDocument = dynamic_cast(itemDocument); p_mechanicsDocument = dynamic_cast(itemDocument); p_canvas = p_itemDocument->canvas(); // b_connectorsAllowedRouting = true; p_selectList = p_itemDocument->selectList(); p_cnItemSelectList = dynamic_cast(p_selectList); p_mechItemSelectList = dynamic_cast(p_selectList); p_cnItemClickedOn = 0l; p_cmManager = cmManager; } CanvasManipulator::~CanvasManipulator() { } CMRepeatedItemAdd::CMRepeatedItemAdd( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { } CMRepeatedItemAdd::~CMRepeatedItemAdd() { } CanvasManipulator* CMRepeatedItemAdd::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMRepeatedItemAdd(itemDocument,cmManager); } ManipulatorInfo *CMRepeatedItemAdd::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); eventInfo->m_acceptManipulationPtr = CMRepeatedItemAdd::acceptManipulation; eventInfo->m_createManipulatorPtr = CMRepeatedItemAdd::construct; return eventInfo; } bool CMRepeatedItemAdd::acceptManipulation( uint /*eventState*/, uint cmState, uint /*itemType*/, uint /*cnItemType*/ ) { return (cmState & CMManager::cms_repeated_add); } bool CMRepeatedItemAdd::mousePressedRepeat( const EventInfo &eventInfo ) { return mousePressedInitial(eventInfo); } bool CMRepeatedItemAdd::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; if (eventInfo.isRightClick) { p_cmManager->setCMState( CMManager::cms_repeated_add, false ); return true; } p_icnDocument->addItem( p_cmManager->repeatedItemId(), eventInfo.pos, true ); p_itemDocument->requestStateSave(); return false; } bool CMRepeatedItemAdd::mouseMoved( const EventInfo &/*eventInfo*/ ) { return false; } bool CMRepeatedItemAdd::mouseReleased( const EventInfo &/*eventInfo*/ ) { return false; } CMRightClick::CMRightClick( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { } CMRightClick::~CMRightClick() { } CanvasManipulator* CMRightClick::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMRightClick(itemDocument,cmManager); } ManipulatorInfo *CMRightClick::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); // eventInfo->m_eventState.m_activate = CMManager::es_right_click; eventInfo->m_acceptManipulationPtr = CMRightClick::acceptManipulation; eventInfo->m_createManipulatorPtr = CMRightClick::construct; return eventInfo; } bool CMRightClick::acceptManipulation( uint eventState, uint /*cmState*/, uint /*itemType*/, uint /*cnItemType*/ ) { return eventState & CMManager::es_right_click; } bool CMRightClick::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; p_itemDocument->canvasRightClick( eventInfo.globalPos, eventInfo.qcanvasItemClickedOn ); return true; } bool CMRightClick::mouseMoved( const EventInfo &/*eventInfo*/ ) { return true; } bool CMRightClick::mouseReleased( const EventInfo &/*eventInfo*/ ) { return true; } //BEGIN class ConnectorDraw ConnectorDraw::ConnectorDraw( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { p_startNode = 0l; p_startConnector = 0l; p_endNode = 0l; p_endConnector = 0l; } ConnectorDraw::~ConnectorDraw() { } TQColor ConnectorDraw::validConnectionColor() { return TQColor( 255, 166, 0 ); } static double qpoint_distance( const TQPoint & p1, const TQPoint & p2 ) { double dx = p1.x() - p2.x(); double dy = p1.y() - p2.y(); return std::sqrt( dx*dx + dy*dy ); } TQPoint ConnectorDraw::toValidPos( const TQPoint & clickPos, Connector * clickedConnector ) const { if ( !clickedConnector ) return clickPos; const TQPointList pointList = clickedConnector->connectorPoints(); TQPointList::const_iterator end = pointList.end(); double dl[] = { 0.5, 8.5, 11.5, 18.0, 23.0 }; // various distances rounded up of (0,0) cells, (0,1), etc for ( unsigned i = 0; i < 5; ++i ) { for ( TQPointList::const_iterator it = pointList.begin(); it != end; ++it ) { if ( qpoint_distance( *it, clickPos ) <= dl[i] ) return *it; } } return clickPos; } Connector * ConnectorDraw::toConnector( Node * node ) { if ( !node || node->numCon( true, false ) < 3 ) return 0l; const ConnectorList inList = node->inputConnectorList(); if ( !inList.isEmpty() ) return *inList.begin(); const ConnectorList outList = node->outputConnectorList(); if ( !outList.isEmpty() ) return *outList.begin(); return 0l; } void ConnectorDraw::grabEndStuff( TQCanvasItem * endItem, const TQPoint & pos, bool posIsExact ) { if (!endItem) return; CNItem * cnItem = dynamic_cast(endItem); if ( cnItem && !posIsExact ) p_endNode = cnItem->getClosestNode(pos); else p_endNode = dynamic_cast(endItem); if ( p_endNode && p_endNode->numCon( true, false ) > 2 ) { p_endConnector = toConnector(p_endNode); p_endNode = 0l; } // If the endItem is a node, we have to finish exactly on the end when posIsExact is true if ( posIsExact && p_endNode && (p_endNode->x() != pos.x() || p_endNode->y() != pos.y()) ) p_endNode = 0l; if (!p_endConnector) p_endConnector = dynamic_cast(endItem); } //END class ConnectorDraw //BEGIN class CMAutoConnector CMAutoConnector::CMAutoConnector( ItemDocument *itemDocument, CMManager *cmManager ) : ConnectorDraw( itemDocument, cmManager ) { m_connectorLine = 0l; p_startNode = 0l; p_startConnector = 0l; } CMAutoConnector::~CMAutoConnector() { delete m_connectorLine; m_connectorLine = 0l; } CanvasManipulator* CMAutoConnector::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMAutoConnector(itemDocument,cmManager); } ManipulatorInfo *CMAutoConnector::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); eventInfo->m_acceptManipulationPtr = CMAutoConnector::acceptManipulation; eventInfo->m_createManipulatorPtr = CMAutoConnector::construct; return eventInfo; } bool CMAutoConnector::acceptManipulation( uint /*eventState*/, uint cmState, uint itemType, uint /*cnItemType*/ ) { return (itemType & (CMManager::it_node | CMManager::it_connector)) && !(cmState & CMManager::cms_manual_route); } bool CMAutoConnector::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; p_startNode = dynamic_cast(eventInfo.qcanvasItemClickedOn); if (p_startNode) { m_eventInfo.pos = m_prevPos = p_icnDocument->gridSnap( TQPoint( (int)p_startNode->x(), (int)p_startNode->y() ) ); if (p_startNode->numCon( true, false ) > 2) { p_startConnector = toConnector(p_startNode); p_startNode = 0l; } } else if (p_startConnector = dynamic_cast(eventInfo.qcanvasItemClickedOn) ) { // startConnectorPoint = m_eventInfo.pos = m_prevPos = p_icnDocument->gridSnap(m_eventInfo.pos); startConnectorPoint = m_eventInfo.pos = m_prevPos = toValidPos( m_eventInfo.pos, p_startConnector ); } else return true; p_icnDocument->unselectAll(); delete m_connectorLine; m_connectorLine = new TQCanvasLine(p_canvas); m_connectorLine->setPen( TQColor(0,0,0) ); m_connectorLine->setZ( ItemDocument::Z::ConnectorCreateLine ); m_connectorLine->show(); return false; } bool CMAutoConnector::mouseMoved( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; int newX = p_icnDocument->gridSnap( pos.x() ); int newY = p_icnDocument->gridSnap( pos.y() ); bool movedFlag = false; if ( newX != m_prevPos.x() ) { m_prevPos.setX(newX); movedFlag = true; } if ( newY != m_prevPos.y() ) { m_prevPos.setY(newY); movedFlag = true; } m_connectorLine->setPoints( m_eventInfo.pos.x(), m_eventInfo.pos.y(), newX, newY ); if (movedFlag) { TQCanvasItem *startItem = 0l; if (p_startNode) startItem = p_startNode; else if (p_startConnector) startItem = p_startConnector; TQCanvasItem *endItem = p_icnDocument->itemAtTop( TQPoint( newX, newY ) ); if ( endItem && endItem->rtti() == ItemDocument::RTTI::CNItem ) endItem = (static_cast(endItem))->getClosestNode( TQPoint( newX, newY ) ); bool validLine = p_icnDocument->canConnect( startItem, endItem ); m_connectorLine->setPen( validLine ? validConnectionColor() : TQt::black ); } return false; } bool CMAutoConnector::mouseReleased( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; TQPoint end = m_connectorLine->endPoint(); delete m_connectorLine; m_connectorLine = 0l; TQCanvasItem *qcanvasItem = p_icnDocument->itemAtTop(end); if ( !qcanvasItem ) return true; grabEndStuff( qcanvasItem, pos, false ); if (p_startConnector) { if (p_endConnector) { if ( !p_icnDocument->createConnector( p_endConnector, p_startConnector, p_icnDocument->gridSnap(pos), startConnectorPoint ) ) return true; } else if (p_endNode) { if ( !p_icnDocument->createConnector( p_endNode, p_startConnector, startConnectorPoint ) ) return true; } else return true; } else if (p_startNode) { if (p_endConnector) { if ( !p_icnDocument->createConnector( p_startNode, p_endConnector, p_icnDocument->gridSnap(pos) ) ) return true; } else if (p_endNode) { if ( !p_icnDocument->createConnector( p_startNode, p_endNode ) ) return true; } else return true; } else return true; p_itemDocument->requestStateSave(); return true; } //END class CMAutoConnector //BEGIN class CMManualConnector CMManualConnector::CMManualConnector( ItemDocument *itemDocument, CMManager *cmManager ) : ConnectorDraw( itemDocument, cmManager ) { m_manualConnectorDraw = 0l; } CMManualConnector::~CMManualConnector() { delete m_manualConnectorDraw; m_manualConnectorDraw = 0l; } CanvasManipulator* CMManualConnector::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMManualConnector(itemDocument,cmManager); } ManipulatorInfo *CMManualConnector::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); eventInfo->m_acceptManipulationPtr = CMManualConnector::acceptManipulation; eventInfo->m_createManipulatorPtr = CMManualConnector::construct; return eventInfo; } bool CMManualConnector::acceptManipulation( uint /*eventState*/, uint cmState, uint itemType, uint /*cnItemType*/ ) { return (itemType & (CMManager::it_node | CMManager::it_connector)) && (cmState & CMManager::cms_manual_route); } bool CMManualConnector::mousePressedInitial( const EventInfo &eventInfo ) { if ( eventInfo.isRightClick ) { return true; } m_eventInfo = eventInfo; p_icnDocument->unselectAll(); TQPoint sp; if ( eventInfo.itemRtti == ItemDocument::RTTI::Node ) { p_startNode = static_cast(eventInfo.qcanvasItemClickedOn); sp.setX( (int)p_startNode->x() ); sp.setY( (int)p_startNode->y() ); if ( p_startNode->numCon( true, false ) > 2 ) { p_startConnector = toConnector(p_startNode); p_startNode = 0l; } } else { p_startConnector = dynamic_cast(eventInfo.qcanvasItemClickedOn); sp = toValidPos( eventInfo.pos, p_startConnector ); } startConnectorPoint = sp; if (m_manualConnectorDraw) delete m_manualConnectorDraw; m_manualConnectorDraw = new ManualConnectorDraw( p_icnDocument, sp ); return false; } bool CMManualConnector::mousePressedRepeat( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; if ( eventInfo.isRightClick ) { return true; } m_manualConnectorDraw->mouseClicked( p_icnDocument->gridSnap(m_eventInfo.pos) ); return false; } bool CMManualConnector::mouseMoved( const EventInfo &eventInfo ) { if ( !m_manualConnectorDraw ) return true; const TQPoint pos = eventInfo.pos; int newX = p_icnDocument->gridSnap( pos.x() ); int newY = p_icnDocument->gridSnap( pos.y() ); bool movedFlag = false; if ( newX != m_prevPos.x() ) { m_prevPos.setX(newX); movedFlag = true; } if ( newY != m_prevPos.y() ) { m_prevPos.setY(newY); movedFlag = true; } if ( movedFlag ) { TQCanvasItem *startItem = 0l; if (p_startNode) startItem = p_startNode; else if (p_startConnector) startItem = p_startConnector; TQCanvasItem * endItem = p_icnDocument->itemAtTop( TQPoint( newX, newY ) ); // If the endItem is a node, we have to finish exactly on the end. if ( Node * node = dynamic_cast(endItem) ) { if ( node->x() != newX || node->y() != newY ) endItem = 0l; } bool validLine = p_icnDocument->canConnect( startItem, endItem ); m_manualConnectorDraw->setColor( validLine ? validConnectionColor() : TQt::black ); m_manualConnectorDraw->mouseMoved( TQPoint( newX, newY ) ); } return false; } bool CMManualConnector::mouseReleased( const EventInfo &eventInfo ) { if (!m_manualConnectorDraw) { return true; } TQPoint pos = p_icnDocument->gridSnap(eventInfo.pos); grabEndStuff( m_manualConnectorDraw->mouseClicked(pos), pos, true ); if ( !p_endNode && !p_endConnector ) return false; // Create the points that define the manual route TQPointList list = m_manualConnectorDraw->pointList(); delete m_manualConnectorDraw; m_manualConnectorDraw = 0l; if (p_startConnector) { if (p_endConnector) { if ( !p_icnDocument->createConnector( p_endConnector, p_startConnector, p_icnDocument->gridSnap(pos), startConnectorPoint, &list ) ) return true; } else // if (p_endNode) { if ( !p_icnDocument->createConnector( p_endNode, p_startConnector, startConnectorPoint, &list ) ) return true; } } else if (p_startNode) { if (p_endConnector) { if ( !p_icnDocument->createConnector( p_startNode, p_endConnector, p_icnDocument->gridSnap(pos), &list ) ) return true; } else // if (p_endNode) { if ( !p_icnDocument->createConnector( p_startNode, p_endNode, &list ) ) return true; } } else return true; p_itemDocument->requestStateSave(); return true; } //END class CMManualConnector CMItemMove::CMItemMove( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { p_flowContainerCandidate = 0l; } CMItemMove::~CMItemMove() { } CanvasManipulator* CMItemMove::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMItemMove(itemDocument,cmManager); } ManipulatorInfo *CMItemMove::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); eventInfo->m_acceptManipulationPtr = CMItemMove::acceptManipulation; eventInfo->m_createManipulatorPtr = CMItemMove::construct; return eventInfo; } bool CMItemMove::acceptManipulation( uint eventState, uint /*cmState*/, uint itemType, uint cnItemType ) { return ((itemType & CMManager::it_canvas_item) || (itemType & CMManager::it_drawpart)) && (cnItemType & CMManager::isi_isMovable) && !(eventState & CMManager::es_right_click); } bool CMItemMove::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; m_prevPos = eventInfo.pos; Item *item = dynamic_cast(eventInfo.qcanvasItemClickedOn); if (!item) return true; if ( !p_selectList->contains(item) ) { if (!eventInfo.ctrlPressed) p_itemDocument->unselectAll(); p_itemDocument->select(item); } else if (m_eventInfo.ctrlPressed) p_itemDocument->unselect(item); if ( p_selectList->isEmpty() ) return true; // We want to allow dragging into FlowContainers if this is a FlowView p_flowContainerCandidate = 0l; { const ItemList &itemList = p_icnDocument->itemList(); const ItemList::const_iterator ciEnd = itemList.end(); for ( ItemList::const_iterator it = itemList.begin(); it != ciEnd; ++it ) { if ( FlowContainer *flowContainer = dynamic_cast((Item*)*it) ) flowContainer->setFullBounds(true); } } ItemList itemList = p_cnItemSelectList->items(false); itemList.remove((Item*)0l); const ItemList::iterator itemListEnd = itemList.end(); for ( ItemList::iterator it = itemList.begin(); it != itemListEnd; ++it ) { CNItem *cnItem = dynamic_cast((Item*)*it); if ( !cnItem || !cnItem->canvas() ) continue; cnItem->setInitialPos(m_eventInfo.pos); } ConnectorList fixedConnectors; p_icnDocument->getTranslatable( itemList, &fixedConnectors, &m_translatableConnectors, &m_translatableNodeGroups ); const ConnectorList::iterator fixedConnectorsEnd = fixedConnectors.end(); for ( ConnectorList::iterator it = fixedConnectors.begin(); it != fixedConnectorsEnd; ++it ) (*it)->setSemiHidden(true); p_flowContainerCandidate = p_icnDocument->flowContainer(eventInfo.pos); return false; } bool CMItemMove::mouseMoved( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; int x = pos.x(); int y = pos.y(); const ItemList itemList = p_cnItemSelectList->items(); const ItemList::const_iterator end = itemList.end(); int dx=0, dy=0; for ( ItemList::const_iterator it = itemList.begin(); it != end; ++it ) { if ( !*it || !(*it)->isMovable() ) continue; const TQRect oldRect = (*it)->boundingRect(); (*it)->setChanged(); if ( CNItem *cnItem = dynamic_cast((Item*)*it) ) { dx = -int((*it)->x()); dy = -int((*it)->y()); cnItem->snap( x, y ); dx += int((*it)->x()); dy += int((*it)->y()); } else (*it)->moveBy( eventInfo.pos.x()-m_prevPos.x(), eventInfo.pos.y()-m_prevPos.y() ); TQRect newRect = (*it)->boundingRect(); TQRect merged = oldRect | newRect; } if ( (dx != 0) || (dy != 0) ) { const ConnectorList::iterator frEnd = m_translatableConnectors.end(); for ( ConnectorList::iterator it = m_translatableConnectors.begin(); it != frEnd; ++it ) (*it)->translateRoute( dx, dy ); const NodeGroupList::iterator end = m_translatableNodeGroups.end(); for ( NodeGroupList::iterator it = m_translatableNodeGroups.begin(); it != end; ++it ) (*it)->translate( dx, dy ); } FlowContainer *fc = p_icnDocument->flowContainer(pos); if ( fc != p_flowContainerCandidate ) { if ( p_flowContainerCandidate ) { p_flowContainerCandidate->setSelected(false); p_flowContainerCandidate = 0l; } } if (fc) { p_flowContainerCandidate = fc; p_flowContainerCandidate->setSelected(true); } p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems ); p_canvas->update(); m_prevPos = eventInfo.pos; return false; } bool CMItemMove::mouseReleased( const EventInfo &eventInfo ) { TQStringList itemIDs; const ItemList itemList = p_cnItemSelectList->items(); const ItemList::const_iterator ilEnd = itemList.end(); for ( ItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it ) { if (*it) itemIDs.append( (*it)->id() ); } const TQPoint pos = eventInfo.pos; // And make sure all connectors are properly shown const ConnectorList &connectorList = p_icnDocument->connectorList(); const ConnectorList::const_iterator conEnd = connectorList.end(); for ( ConnectorList::const_iterator it = connectorList.begin(); it != conEnd; ++it ) { (*it)->setSemiHidden(false); } if (p_flowContainerCandidate) { for ( ItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it ) p_flowContainerCandidate->addChild(*it); p_flowContainerCandidate->setSelected(false); p_flowContainerCandidate = 0l; } else { for ( ItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it ) (*it)->setParentItem(0l); } // And disable the FlowContainers again... const ItemList &cnItemList = p_icnDocument->itemList(); const ItemList::const_iterator end = cnItemList.end(); for ( ItemList::const_iterator it = cnItemList.begin(); it != end; ++it ) { if ( FlowContainer *flowContainer = dynamic_cast((Item*)*it) ) flowContainer->setFullBounds(false); } if (p_icnDocument) p_icnDocument->requestRerouteInvalidatedConnectors(); if ( m_eventInfo.pos != eventInfo.pos ) p_itemDocument->requestStateSave(); p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems ); return true; } CMItemResize::CMItemResize( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { } CMItemResize::~CMItemResize() { } CanvasManipulator* CMItemResize::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMItemResize(itemDocument,cmManager); } ManipulatorInfo *CMItemResize::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); // eventInfo->m_itemType.m_activate = CMManager::it_canvas_item; eventInfo->m_acceptManipulationPtr = CMItemResize::acceptManipulation; eventInfo->m_createManipulatorPtr = CMItemResize::construct; return eventInfo; } bool CMItemResize::acceptManipulation( uint eventState, uint /*cmState*/, uint itemType, uint /*cnItemType*/ ) { return (itemType & CMManager::it_resize_handle) && !(eventState & CMManager::es_right_click); } bool CMItemResize::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; p_resizeHandle = dynamic_cast(eventInfo.qcanvasItemClickedOn); m_rh_dx = p_resizeHandle->x()-eventInfo.pos.x(); m_rh_dy = p_resizeHandle->y()-eventInfo.pos.y(); return false; } bool CMItemResize::mouseMoved( const EventInfo &eventInfo ) { int _x = int(m_rh_dx + eventInfo.pos.x()); int _y = int(m_rh_dy + eventInfo.pos.y()); // Shift pressed == snap to grid if ( eventInfo.shiftPressed ) { _x = int(_x/8)*8+4; _y = int(_y/8)*8+4; } p_resizeHandle->moveRH( _x, _y ); return false; } bool CMItemResize::mouseReleased( const EventInfo &/*eventInfo*/ ) { if (p_icnDocument) p_icnDocument->requestRerouteInvalidatedConnectors(); p_itemDocument->requestStateSave(); return true; } CMMechItemMove::CMMechItemMove( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { } CMMechItemMove::~CMMechItemMove() { } CanvasManipulator* CMMechItemMove::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMMechItemMove(itemDocument,cmManager); } ManipulatorInfo *CMMechItemMove::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); // eventInfo->m_itemType.m_activate = CMManager::it_canvas_item; eventInfo->m_acceptManipulationPtr = CMMechItemMove::acceptManipulation; eventInfo->m_createManipulatorPtr = CMMechItemMove::construct; return eventInfo; } bool CMMechItemMove::acceptManipulation( uint eventState, uint /*cmState*/, uint itemType, uint /*cnItemType*/ ) { return ((itemType & CMManager::it_mechanics_item) || (itemType & CMManager::it_drawpart)) && !(eventState & CMManager::es_right_click); } bool CMMechItemMove::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; m_prevPos = eventInfo.pos; Item *item = dynamic_cast(eventInfo.qcanvasItemClickedOn); if (!item) return true; MechanicsItem *mechItem = dynamic_cast(eventInfo.qcanvasItemClickedOn); if (mechItem) m_prevClickedOnSM = mechItem->selectionMode(); if (eventInfo.shiftPressed) { p_mechanicsDocument->unselectAll(); p_mechanicsDocument->select(item); if (mechItem) { mechItem->setSelectionMode(MechanicsItem::sm_move); mechItem->setParentItem(0l); } } else if ( !p_selectList->contains(mechItem) ) { if (!eventInfo.ctrlPressed) p_mechanicsDocument->unselectAll(); p_mechanicsDocument->select(item); if (mechItem) mechItem->setSelectionMode(MechanicsItem::sm_move); } else { if (mechItem) mechItem->setSelectionMode(MechanicsItem::sm_move); if (m_eventInfo.ctrlPressed) p_mechanicsDocument->unselect(item); } if ( p_selectList->isEmpty() ) return true; p_mechItemSelectList->setSelectionMode( MechanicsItem::sm_move ); p_mechItemSelectList->setRaised(true); return false; } bool CMMechItemMove::mouseMoved( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; int x = pos.x(); int y = pos.y(); const MechItemList itemList = p_mechItemSelectList->toplevelMechItemList(); const MechItemList::const_iterator ilEnd = itemList.end(); for ( MechItemList::const_iterator it = itemList.begin(); it != ilEnd; ++it ) { if (*it) (*it)->moveBy( x - m_prevPos.x(), y - m_prevPos.y() ); } m_prevPos = TQPoint( x, y ); p_canvas->update(); p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems ); return false; } bool CMMechItemMove::mouseReleased( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; int dx = pos.x() - m_eventInfo.pos.x(); int dy = pos.y() - m_eventInfo.pos.y(); p_mechItemSelectList->setRaised(false); MechanicsItem *mechItem = dynamic_cast(m_eventInfo.qcanvasItemClickedOn); if ( dx == 0 && dy == 0 ) { if ( mechItem && mechItem->isSelected() ) { if ( m_prevClickedOnSM == MechanicsItem::sm_resize ) mechItem->setSelectionMode( MechanicsItem::sm_rotate ); else mechItem->setSelectionMode( MechanicsItem::sm_resize ); } p_itemDocument->requestStateSave(); return true; } if ( mechItem && mechItem->isSelected() ) { if ( m_prevClickedOnSM == MechanicsItem::sm_rotate ) mechItem->setSelectionMode(MechanicsItem::sm_rotate); else mechItem->setSelectionMode(MechanicsItem::sm_resize); } TQStringList itemIDs; ItemList itemList = p_mechItemSelectList->items(); const ItemList::iterator ilEnd = itemList.end(); for ( ItemList::iterator it = itemList.begin(); it != ilEnd; ++it ) { if (*it) { itemIDs.append( (*it)->id() ); } } p_mechItemSelectList->setSelectionMode( MechanicsItem::sm_resize ); p_itemDocument->requestStateSave(); p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems ); return true; } //BEGIN class SelectRectangle SelectRectangle::SelectRectangle( int x, int y, int w, int h, TQCanvas *qcanvas ) : m_x(x), m_y(y) { m_topLine = new TQCanvasLine(qcanvas); m_rightLine = new TQCanvasLine(qcanvas); m_bottomLine = new TQCanvasLine(qcanvas); m_leftLine = new TQCanvasLine(qcanvas); setSize( w, h ); TQCanvasLine* lines[] = { m_topLine, m_rightLine, m_bottomLine, m_leftLine }; for ( int i=0; i<4; ++ i) { lines[i]->setPen( TQPen( TQColor(190,190,190), 1, TQt::DotLine ) ); lines[i]->setZ( ICNDocument::Z::Select ); lines[i]->show(); } } SelectRectangle::~SelectRectangle() { delete m_topLine; delete m_rightLine; delete m_bottomLine; delete m_leftLine; } void SelectRectangle::setSize( int w, int h ) { m_topLine->setPoints( m_x, m_y, m_x+w, m_y ); m_rightLine->setPoints( m_x+w, m_y, m_x+w, m_y+h ); m_bottomLine->setPoints( m_x+w, m_y+h, m_x, m_y+h ); m_leftLine->setPoints( m_x, m_y+h, m_x, m_y ); m_w = w; m_h = h; } TQCanvasItemList SelectRectangle::collisions() { TQCanvas *canvas = m_topLine->canvas(); return canvas->collisions( TQRect( m_x, m_y, m_w, m_h ) ); } //END class SelectRectangle //BEGIN class CMSelect CMSelect::CMSelect( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { m_selectRectangle = 0l; } CMSelect::~CMSelect() { delete m_selectRectangle; m_selectRectangle = 0l; } CanvasManipulator* CMSelect::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMSelect(itemDocument,cmManager); } ManipulatorInfo *CMSelect::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); // eventInfo->m_itemType.m_activate = CMManager::it_none; eventInfo->m_acceptManipulationPtr = CMSelect::acceptManipulation; eventInfo->m_createManipulatorPtr = CMSelect::construct; return eventInfo; } bool CMSelect::acceptManipulation( uint /*eventState*/, uint /*cmState*/, uint itemType, uint /*cnItemType*/ ) { return (itemType & CMManager::it_none); } bool CMSelect::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; if (!eventInfo.ctrlPressed) { p_itemDocument->unselectAll(); } m_selectRectangle = new SelectRectangle( eventInfo.pos.x(), eventInfo.pos.y(), 0, 0, p_canvas ); return false; } bool CMSelect::mouseMoved( const EventInfo &eventInfo ) { TQPoint pos = eventInfo.pos; m_selectRectangle->setSize( pos.x()-m_eventInfo.pos.x(), pos.y()-m_eventInfo.pos.y() ); if (m_eventInfo.ctrlPressed) { p_itemDocument->select( m_selectRectangle->collisions() ); } else if (p_selectList) { p_selectList->setItems( m_selectRectangle->collisions() ); } if (p_selectList && !p_mechanicsDocument) { p_selectList->setSelected(true); } return false; } bool CMSelect::mouseReleased( const EventInfo &/*eventInfo*/ ) { delete m_selectRectangle; m_selectRectangle = 0l; return true; } //END class CMSelect CMItemDrag::CMItemDrag( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { b_dragged = false; } CMItemDrag::~CMItemDrag() { } CanvasManipulator* CMItemDrag::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMItemDrag(itemDocument,cmManager); } ManipulatorInfo *CMItemDrag::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); // eventInfo->m_itemType.m_activate = CMManager::it_canvas_item; eventInfo->m_acceptManipulationPtr = CMItemDrag::acceptManipulation; eventInfo->m_createManipulatorPtr = CMItemDrag::construct; return eventInfo; } bool CMItemDrag::acceptManipulation( uint /*eventState*/, uint /*cmState*/, uint itemType, uint cnItemType ) { return (itemType & (CMManager::it_canvas_item|CMManager::it_pin)) && !(cnItemType & CMManager::isi_isMovable); } bool CMItemDrag::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; b_dragged = false; return false; } bool CMItemDrag::mouseMoved( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; if ( b_dragged || pos.x() > (m_eventInfo.pos.x()+4 ) || pos.x() < (m_eventInfo.pos.x()-4) || pos.y() > (m_eventInfo.pos.y()+4) || pos.y() < (m_eventInfo.pos.y()-4) ) { b_dragged = true; if ( m_eventInfo.itemRtti == ItemDocument::RTTI::Pin ) ((PinItem*)m_eventInfo.qcanvasItemClickedOn)->dragged( pos.x() - m_eventInfo.pos.x() ); } return false; } bool CMItemDrag::mouseReleased( const EventInfo &/*eventInfo*/ ) { if ( !b_dragged && m_eventInfo.itemRtti == ItemDocument::RTTI::Pin ) (static_cast(m_eventInfo.qcanvasItemClickedOn))->switchState(); p_itemDocument->requestStateSave(); return true; } //BEGIN class CanvasEllipseDraw CanvasEllipseDraw::CanvasEllipseDraw( int x, int y, TQCanvas * canvas ) : TQCanvasEllipse( 0, 0, canvas ) { move( x, y ); } void CanvasEllipseDraw::drawShape( TQPainter & p ) { p.drawEllipse( int(x()-width()/2), int(y()-height()/2), width(), height() ); } //END class CanvasEllipseDraw //BEGIN class CMDraw CMDraw::CMDraw( ItemDocument *itemDocument, CMManager *cmManager ) : CanvasManipulator( itemDocument, cmManager ) { m_pDrawLine = 0l; m_pDrawRectangle = 0l; m_pDrawEllipse = 0l; } CMDraw::~CMDraw() { p_cmManager->setDrawAction(-1); } CanvasManipulator* CMDraw::construct( ItemDocument *itemDocument, CMManager *cmManager ) { return new CMDraw(itemDocument,cmManager); } ManipulatorInfo *CMDraw::manipulatorInfo() { ManipulatorInfo *eventInfo = new ManipulatorInfo(); eventInfo->m_acceptManipulationPtr = CMDraw::acceptManipulation; eventInfo->m_createManipulatorPtr = CMDraw::construct; return eventInfo; } bool CMDraw::acceptManipulation( uint /*eventState*/, uint cmState, uint /*itemType*/, uint /*cnItemType*/ ) { return (cmState & CMManager::cms_draw); } bool CMDraw::mousePressedInitial( const EventInfo &eventInfo ) { m_eventInfo = eventInfo; switch ( (DrawPart::DrawAction) p_cmManager->drawAction() ) { case DrawPart::da_text: case DrawPart::da_rectangle: { m_pDrawRectangle = new TQCanvasRectangle( eventInfo.pos.x(), eventInfo.pos.y(), 0, 0, p_canvas ); m_pDrawRectangle->setPen( TQPen( TQColor(0,0,0), 1 ) ); m_pDrawRectangle->setZ( ICNDocument::Z::Select ); m_pDrawRectangle->show(); break; } case DrawPart::da_ellipse: { m_pDrawEllipse = new CanvasEllipseDraw( eventInfo.pos.x(), eventInfo.pos.y(), p_canvas ); m_pDrawEllipse->setPen( TQPen( TQColor(0,0,0), 1 ) ); m_pDrawEllipse->setZ( ICNDocument::Z::Select ); m_pDrawEllipse->show(); break; } case DrawPart::da_line: case DrawPart::da_arrow: { m_pDrawLine = new TQCanvasLine(p_canvas); m_pDrawLine->setPoints( eventInfo.pos.x(), eventInfo.pos.y(), eventInfo.pos.x(), eventInfo.pos.y() ); m_pDrawLine->setPen( TQPen( TQColor(0,0,0), 1 ) ); m_pDrawLine->setZ( ICNDocument::Z::Select ); m_pDrawLine->show(); break; } default: return true; } return false; } bool CMDraw::mouseMoved( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; if (m_pDrawRectangle) m_pDrawRectangle->setSize( pos.x()-m_eventInfo.pos.x(), pos.y()-m_eventInfo.pos.y() ); else if (m_pDrawEllipse) { // TQRect r( m_eventInfo.pos.x(), m_eventInfo.pos.y(), pos.x()-m_eventInfo.pos.x(), pos.y()-m_eventInfo.pos.y() ); // r = r.normalize(); // // m_pDrawEllipse->setSize( r.width(), r.height() ); // m_pDrawEllipse->move( r.left()+(r.width()/2), r.top()+(r.height()/2) ); m_pDrawEllipse->setSize( 2*TQABS(pos.x()-m_eventInfo.pos.x()), 2*TQABS(pos.y()-m_eventInfo.pos.y()) ); } else if (m_pDrawLine) m_pDrawLine->setPoints( eventInfo.pos.x(), eventInfo.pos.y(), m_pDrawLine->endPoint().x(), m_pDrawLine->endPoint().y() ); else return true; return false; } bool CMDraw::mouseReleased( const EventInfo &eventInfo ) { const TQPoint pos = eventInfo.pos; TQRect sizeRect; if ( m_pDrawRectangle || m_pDrawEllipse ) { if (m_pDrawRectangle) { sizeRect = m_pDrawRectangle->rect(); // We have to manually adjust the size rect so that it matches up with what the user has drawn sizeRect.setWidth( sizeRect.width()+1 ); sizeRect.setHeight( sizeRect.height()+1 ); sizeRect = sizeRect.normalize(); if ( m_pDrawRectangle->rect().width() < 0 ) sizeRect.moveLeft( sizeRect.left() + 1); if ( m_pDrawRectangle->rect().height() < 0 ) sizeRect.moveTop( sizeRect.top() + 1); } else { int w = m_pDrawEllipse->width()+1; int h = m_pDrawEllipse->height()+1; int x = int(m_pDrawEllipse->x()-w/2); int y = int(m_pDrawEllipse->y()-h/2); sizeRect = TQRect( x, y, w, h ).normalize(); } delete m_pDrawRectangle; delete m_pDrawEllipse; m_pDrawRectangle = 0l; m_pDrawEllipse = 0l; } else if (m_pDrawLine) { int sx = m_pDrawLine->startPoint().x(); int sy = m_pDrawLine->startPoint().y(); int ex = m_pDrawLine->endPoint().x(); int ey = m_pDrawLine->endPoint().y(); sizeRect = TQRect( ex, ey, sx-ex, sy-ey ); delete m_pDrawLine; m_pDrawLine = 0l; } else return true; TQString id; switch ( (DrawPart::DrawAction) p_cmManager->drawAction() ) { case DrawPart::da_rectangle: id = "dp/rectangle"; break; case DrawPart::da_ellipse: id = "dp/ellipse"; break; case DrawPart::da_text: id = "dp/canvas_text"; if ( sizeRect.width() < 56 ) sizeRect.setWidth( 56 ); if ( sizeRect.height() < 24 ) sizeRect.setHeight( 24 ); break; case DrawPart::da_line: id = "dp/line"; break; case DrawPart::da_arrow: id = "dp/arrow"; break; } if ( id.isEmpty() ) return true; Item * item = p_itemDocument->addItem( id, sizeRect.topLeft(), true ); if (!item) return true; 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. item->setSize( 0, 0, sizeRect.width(), sizeRect.height() ); p_itemDocument->requestStateSave(); return true; } //END class CMDraw //BEGIN class ManualConnectorDraw ManualConnectorDraw::ManualConnectorDraw( ICNDocument *_icnDocument, const TQPoint &initialPos ) { m_color = TQt::black; icnDocument = _icnDocument; m_currentPos = m_previousPos = m_initialPos = initialPos; p_initialItem = icnDocument->itemAtTop(initialPos); b_currentVertical = false; b_orientationDefined = false; m_connectorLines.append( m_previousCon = new TQCanvasLine( icnDocument->canvas() ) ); m_connectorLines.append( m_currentCon = new TQCanvasLine( icnDocument->canvas() ) ); m_currentCon->setPoints( initialPos.x(), initialPos.y(), initialPos.x(), initialPos.y() ); m_previousCon->setPoints( initialPos.x(), initialPos.y(), initialPos.x(), initialPos.y() ); m_currentCon->setPen( m_color ); m_previousCon->setPen( m_color ); updateConnectorEnds(); m_currentCon->show(); m_previousCon->show(); } ManualConnectorDraw::~ManualConnectorDraw() { const TQValueList::iterator end = m_connectorLines.end(); for ( TQValueList::iterator it = m_connectorLines.begin(); it != end; ++it ) delete *it; m_connectorLines.clear(); } void ManualConnectorDraw::setColor( const TQColor & color ) { m_color = color; const TQValueList::iterator end = m_connectorLines.end(); for ( TQValueList::iterator it = m_connectorLines.begin(); it != end; ++it ) (*it)->setPen( m_color ); } void ManualConnectorDraw::mouseMoved( const TQPoint &pos ) { if ( m_currentPos == pos ) return; if (!b_orientationDefined) { TQPoint previousStart = m_previousCon->startPoint(); double distance = std::sqrt( std::pow( (double)(m_currentPos.x()-previousStart.x()), 2. ) + std::pow( (double)(m_currentPos.y()-previousStart.y()), 2. ) ); if ( distance < 24 ) { b_currentVertical = ( std::abs( double(m_currentPos.x()-previousStart.x()) ) >= std::abs( double(m_currentPos.y()-previousStart.y()) ) ); } } m_previousPos = m_currentPos; m_currentPos = pos; updateConnectorEnds(); } TQCanvasItem* ManualConnectorDraw::mouseClicked( const TQPoint &pos ) { if (b_orientationDefined) b_currentVertical = !b_currentVertical; else mouseMoved(pos); b_orientationDefined = true; m_currentPos = pos; TQCanvasItem * qcanvasItem = icnDocument->itemAtTop(pos); if ( qcanvasItem && pos != m_initialPos && qcanvasItem != p_initialItem ) return qcanvasItem; m_previousCon = m_currentCon; m_connectorLines.append( m_currentCon = new TQCanvasLine( icnDocument->canvas() ) ); m_currentCon->setPoints( pos.x(), pos.y(), pos.x(), pos.y() ); m_currentCon->setPen( m_color ); updateConnectorEnds(); m_currentCon->show(); return 0L; } void ManualConnectorDraw::updateConnectorEnds() { TQPoint pivot = m_currentPos; TQPoint previousStart = m_previousCon->startPoint(); if (b_currentVertical) { pivot.setY( previousStart.y() ); m_currentCon->setPoints( pivot.x(), pivot.y(), pivot.x(), m_currentPos.y() ); } else { pivot.setX( previousStart.x() ); m_currentCon->setPoints( pivot.x(), pivot.y(), m_currentPos.x(), pivot.y() ); } m_previousCon->setPoints( previousStart.x(), previousStart.y(), pivot.x(), pivot.y() ); } TQPointList ManualConnectorDraw::pointList() { TQPointList list; list.append(m_initialPos); const TQValueList::iterator end = m_connectorLines.end(); for ( TQValueList::iterator it = m_connectorLines.begin(); it != end; ++it ) { list.append( (*it)->endPoint() ); } return list; } //END class ManualConnectorDraw //BEGIN class ManipulatorInfo ManipulatorInfo::ManipulatorInfo() { } //END class ManipulatorInfo #include "canvasmanipulator.moc"