You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1905 lines
48 KiB
1905 lines
48 KiB
15 years ago
|
/***************************************************************************
|
||
|
* 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 <cmath>
|
||
|
|
||
|
#include <kconfig.h>
|
||
|
#include <kdebug.h>
|
||
|
#include <kglobal.h>
|
||
|
|
||
|
#include <qpainter.h>
|
||
|
#include <qtimer.h>
|
||
|
|
||
|
|
||
|
CMManager::CMManager( ItemDocument *itemDocument )
|
||
|
: QObject()
|
||
|
{
|
||
|
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 QTimer(this);
|
||
|
connect( m_allowItemScrollTmr, SIGNAL(timeout()), this, SLOT(slotAllowItemScroll()) );
|
||
|
|
||
|
KGlobal::config()->setGroup("General");
|
||
|
slotSetManualRoute( KGlobal::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<DrawPart*>(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<Widget*>(eventInfo.qcanvasItemClickedOn);
|
||
|
if (widget)
|
||
|
eventInfo.qcanvasItemClickedOn = widget->parent();
|
||
|
}
|
||
|
case ItemDocument::RTTI::CNItem:
|
||
|
{
|
||
|
itemType = CMManager::it_canvas_item;
|
||
|
CNItem *cnItemClickedOn = dynamic_cast<CNItem*>(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<MechanicsItem*>(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<Item*>(eventInfo.qcanvasItemClickedOn);
|
||
|
if (item)
|
||
|
{
|
||
|
item->mouseDoubleClickEvent(eventInfo);
|
||
|
return;
|
||
|
}
|
||
|
Widget *widget = dynamic_cast<Widget*>(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<ItemView*>(p_itemDocument->activeView());
|
||
|
if (itemView)
|
||
|
itemView->scrollToMouse(eventInfo.pos);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//BEGIN
|
||
|
QCanvasItem *qcnItem = p_itemDocument->itemAtTop(eventInfo.pos);
|
||
|
Item *item;
|
||
|
Widget *widget = dynamic_cast<Widget*>(qcnItem);
|
||
|
if (widget)
|
||
|
item = widget->parent();
|
||
|
else
|
||
|
item = dynamic_cast<Item*>(qcnItem);
|
||
|
|
||
|
if ( p_lastMouseOverItem != (QGuardedPtr<Item>)item )
|
||
|
{
|
||
|
QEvent event(QEvent::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<ResizeHandle*>(qcnItem) );
|
||
|
}
|
||
|
|
||
|
|
||
|
void CMManager::updateCurrentResizeHandle( ResizeHandle * resizeHandle )
|
||
|
{
|
||
|
if ( p_lastMouseOverResizeHandle != (QGuardedPtr<ResizeHandle>)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<ResizeHandle*>( p_itemDocument->itemAtTop(eventInfo.pos) ) );
|
||
|
}
|
||
|
|
||
|
|
||
|
void CMManager::wheelEvent( const EventInfo &eventInfo )
|
||
|
{
|
||
|
bool accepted = false;
|
||
|
if (b_allowItemScroll)
|
||
|
{
|
||
|
QCanvasItem *qcnItem = p_itemDocument->itemAtTop(eventInfo.pos);
|
||
|
Item *item;
|
||
|
Widget *widget = dynamic_cast<Widget*>(qcnItem);
|
||
|
if (widget)
|
||
|
item = widget->parent();
|
||
|
else
|
||
|
item = dynamic_cast<Item*>(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<ItemView*>(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 )
|
||
|
{
|
||
|
KGlobal::config()->setGroup("General");
|
||
|
KGlobal::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 QString & repeatedId )
|
||
|
{
|
||
|
m_repeatedItemId = repeatedId;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
CanvasManipulator::CanvasManipulator( ItemDocument *itemDocument, CMManager *cmManager )
|
||
|
{
|
||
|
p_itemDocument = itemDocument;
|
||
|
p_icnDocument = dynamic_cast<ICNDocument*>(itemDocument);
|
||
|
p_mechanicsDocument = dynamic_cast<MechanicsDocument*>(itemDocument);
|
||
|
p_canvas = p_itemDocument->canvas();
|
||
|
// b_connectorsAllowedRouting = true;
|
||
|
p_selectList = p_itemDocument->selectList();
|
||
|
p_cnItemSelectList = dynamic_cast<CNItemGroup*>(p_selectList);
|
||
|
p_mechItemSelectList = dynamic_cast<MechanicsGroup*>(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()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
QColor ConnectorDraw::validConnectionColor()
|
||
|
{
|
||
|
return QColor( 255, 166, 0 );
|
||
|
}
|
||
|
|
||
|
|
||
|
static double qpoint_distance( const QPoint & p1, const QPoint & p2 )
|
||
|
{
|
||
|
double dx = p1.x() - p2.x();
|
||
|
double dy = p1.y() - p2.y();
|
||
|
|
||
|
return std::sqrt( dx*dx + dy*dy );
|
||
|
}
|
||
|
|
||
|
|
||
|
QPoint ConnectorDraw::toValidPos( const QPoint & clickPos, Connector * clickedConnector ) const
|
||
|
{
|
||
|
if ( !clickedConnector )
|
||
|
return clickPos;
|
||
|
|
||
|
const QPointList pointList = clickedConnector->connectorPoints();
|
||
|
|
||
|
QPointList::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 ( QPointList::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( QCanvasItem * endItem, const QPoint & pos, bool posIsExact )
|
||
|
{
|
||
|
if (!endItem)
|
||
|
return;
|
||
|
|
||
|
CNItem * cnItem = dynamic_cast<CNItem*>(endItem);
|
||
|
if ( cnItem && !posIsExact )
|
||
|
p_endNode = cnItem->getClosestNode(pos);
|
||
|
else
|
||
|
p_endNode = dynamic_cast<Node*>(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<Connector*>(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<Node*>(eventInfo.qcanvasItemClickedOn);
|
||
|
|
||
|
if (p_startNode)
|
||
|
{
|
||
|
m_eventInfo.pos = m_prevPos = p_icnDocument->gridSnap( QPoint( (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<Connector*>(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 QCanvasLine(p_canvas);
|
||
|
m_connectorLine->setPen( QColor(0,0,0) );
|
||
|
m_connectorLine->setZ( ItemDocument::Z::ConnectorCreateLine );
|
||
|
m_connectorLine->show();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CMAutoConnector::mouseMoved( const EventInfo &eventInfo )
|
||
|
{
|
||
|
const QPoint 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)
|
||
|
{
|
||
|
QCanvasItem *startItem = 0l;
|
||
|
if (p_startNode)
|
||
|
startItem = p_startNode;
|
||
|
else if (p_startConnector)
|
||
|
startItem = p_startConnector;
|
||
|
|
||
|
QCanvasItem *endItem = p_icnDocument->itemAtTop( QPoint( newX, newY ) );
|
||
|
if ( endItem && endItem->rtti() == ItemDocument::RTTI::CNItem )
|
||
|
endItem = (static_cast<CNItem*>(endItem))->getClosestNode( QPoint( newX, newY ) );
|
||
|
|
||
|
bool validLine = p_icnDocument->canConnect( startItem, endItem );
|
||
|
m_connectorLine->setPen( validLine ? validConnectionColor() : Qt::black );
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CMAutoConnector::mouseReleased( const EventInfo &eventInfo )
|
||
|
{
|
||
|
const QPoint pos = eventInfo.pos;
|
||
|
|
||
|
QPoint end = m_connectorLine->endPoint();
|
||
|
delete m_connectorLine;
|
||
|
m_connectorLine = 0l;
|
||
|
|
||
|
QCanvasItem *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();
|
||
|
|
||
|
QPoint sp;
|
||
|
|
||
|
if ( eventInfo.itemRtti == ItemDocument::RTTI::Node )
|
||
|
{
|
||
|
p_startNode = static_cast<Node*>(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<Connector*>(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 QPoint 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 )
|
||
|
{
|
||
|
QCanvasItem *startItem = 0l;
|
||
|
if (p_startNode)
|
||
|
startItem = p_startNode;
|
||
|
else if (p_startConnector)
|
||
|
startItem = p_startConnector;
|
||
|
|
||
|
QCanvasItem * endItem = p_icnDocument->itemAtTop( QPoint( newX, newY ) );
|
||
|
|
||
|
// If the endItem is a node, we have to finish exactly on the end.
|
||
|
if ( Node * node = dynamic_cast<Node*>(endItem) )
|
||
|
{
|
||
|
if ( node->x() != newX || node->y() != newY )
|
||
|
endItem = 0l;
|
||
|
}
|
||
|
|
||
|
bool validLine = p_icnDocument->canConnect( startItem, endItem );
|
||
|
|
||
|
m_manualConnectorDraw->setColor( validLine ? validConnectionColor() : Qt::black );
|
||
|
m_manualConnectorDraw->mouseMoved( QPoint( newX, newY ) );
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CMManualConnector::mouseReleased( const EventInfo &eventInfo )
|
||
|
{
|
||
|
if (!m_manualConnectorDraw) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
QPoint 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
|
||
|
QPointList 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<Item*>(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<FlowContainer*>((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<CNItem*>((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 QPoint 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 QRect oldRect = (*it)->boundingRect();
|
||
|
(*it)->setChanged();
|
||
|
|
||
|
if ( CNItem *cnItem = dynamic_cast<CNItem*>((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() );
|
||
|
|
||
|
QRect newRect = (*it)->boundingRect();
|
||
|
QRect 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 )
|
||
|
{
|
||
|
QStringList 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 QPoint 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<FlowContainer*>((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<ResizeHandle*>(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<Item*>(eventInfo.qcanvasItemClickedOn);
|
||
|
if (!item)
|
||
|
return true;
|
||
|
|
||
|
MechanicsItem *mechItem = dynamic_cast<MechanicsItem*>(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 QPoint 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 = QPoint( x, y );
|
||
|
|
||
|
p_canvas->update();
|
||
|
p_itemDocument->requestEvent( ItemDocument::ItemDocumentEvent::ResizeCanvasToItems );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CMMechItemMove::mouseReleased( const EventInfo &eventInfo )
|
||
|
{
|
||
|
const QPoint 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<MechanicsItem*>(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);
|
||
|
}
|
||
|
|
||
|
QStringList 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, QCanvas *qcanvas )
|
||
|
: m_x(x), m_y(y)
|
||
|
{
|
||
|
m_topLine = new QCanvasLine(qcanvas);
|
||
|
m_rightLine = new QCanvasLine(qcanvas);
|
||
|
m_bottomLine = new QCanvasLine(qcanvas);
|
||
|
m_leftLine = new QCanvasLine(qcanvas);
|
||
|
setSize( w, h );
|
||
|
|
||
|
QCanvasLine* lines[] = { m_topLine, m_rightLine, m_bottomLine, m_leftLine };
|
||
|
for ( int i=0; i<4; ++ i)
|
||
|
{
|
||
|
lines[i]->setPen( QPen( QColor(190,190,190), 1, Qt::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;
|
||
|
}
|
||
|
|
||
|
|
||
|
QCanvasItemList SelectRectangle::collisions()
|
||
|
{
|
||
|
QCanvas *canvas = m_topLine->canvas();
|
||
|
|
||
|
return canvas->collisions( QRect( 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 )
|
||
|
{
|
||
|
QPoint 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 QPoint 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<PinItem*>(m_eventInfo.qcanvasItemClickedOn))->switchState();
|
||
|
|
||
|
p_itemDocument->requestStateSave();
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
//BEGIN class CanvasEllipseDraw
|
||
|
CanvasEllipseDraw::CanvasEllipseDraw( int x, int y, QCanvas * canvas )
|
||
|
: QCanvasEllipse( 0, 0, canvas )
|
||
|
{
|
||
|
move( x, y );
|
||
|
}
|
||
|
|
||
|
|
||
|
void CanvasEllipseDraw::drawShape( QPainter & 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 QCanvasRectangle( eventInfo.pos.x(), eventInfo.pos.y(), 0, 0, p_canvas );
|
||
|
m_pDrawRectangle->setPen( QPen( QColor(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( QPen( QColor(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 QCanvasLine(p_canvas);
|
||
|
m_pDrawLine->setPoints( eventInfo.pos.x(), eventInfo.pos.y(), eventInfo.pos.x(), eventInfo.pos.y() );
|
||
|
m_pDrawLine->setPen( QPen( QColor(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 QPoint 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)
|
||
|
{
|
||
|
// QRect 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*QABS(pos.x()-m_eventInfo.pos.x()), 2*QABS(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 QPoint pos = eventInfo.pos;
|
||
|
|
||
|
QRect 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 = QRect( 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 = QRect( ex, ey, sx-ex, sy-ey );
|
||
|
|
||
|
delete m_pDrawLine;
|
||
|
m_pDrawLine = 0l;
|
||
|
}
|
||
|
else
|
||
|
return true;
|
||
|
|
||
|
QString 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 QPoint &initialPos )
|
||
|
{
|
||
|
m_color = Qt::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 QCanvasLine( icnDocument->canvas() ) );
|
||
|
m_connectorLines.append( m_currentCon = new QCanvasLine( 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 QValueList<QCanvasLine*>::iterator end = m_connectorLines.end();
|
||
|
for ( QValueList<QCanvasLine*>::iterator it = m_connectorLines.begin(); it != end; ++it )
|
||
|
delete *it;
|
||
|
|
||
|
m_connectorLines.clear();
|
||
|
}
|
||
|
|
||
|
|
||
|
void ManualConnectorDraw::setColor( const QColor & color )
|
||
|
{
|
||
|
m_color = color;
|
||
|
|
||
|
const QValueList<QCanvasLine*>::iterator end = m_connectorLines.end();
|
||
|
for ( QValueList<QCanvasLine*>::iterator it = m_connectorLines.begin(); it != end; ++it )
|
||
|
(*it)->setPen( m_color );
|
||
|
}
|
||
|
|
||
|
|
||
|
void ManualConnectorDraw::mouseMoved( const QPoint &pos )
|
||
|
{
|
||
|
if ( m_currentPos == pos ) return;
|
||
|
|
||
|
if (!b_orientationDefined)
|
||
|
{
|
||
|
QPoint 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();
|
||
|
}
|
||
|
|
||
|
|
||
|
QCanvasItem* ManualConnectorDraw::mouseClicked( const QPoint &pos )
|
||
|
{
|
||
|
if (b_orientationDefined)
|
||
|
b_currentVertical = !b_currentVertical;
|
||
|
|
||
|
else
|
||
|
mouseMoved(pos);
|
||
|
|
||
|
b_orientationDefined = true;
|
||
|
|
||
|
m_currentPos = pos;
|
||
|
|
||
|
QCanvasItem * qcanvasItem = icnDocument->itemAtTop(pos);
|
||
|
|
||
|
if ( qcanvasItem && pos != m_initialPos && qcanvasItem != p_initialItem )
|
||
|
return qcanvasItem;
|
||
|
|
||
|
m_previousCon = m_currentCon;
|
||
|
|
||
|
m_connectorLines.append( m_currentCon = new QCanvasLine( 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()
|
||
|
{
|
||
|
QPoint pivot = m_currentPos;
|
||
|
QPoint 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() );
|
||
|
}
|
||
|
|
||
|
|
||
|
QPointList ManualConnectorDraw::pointList()
|
||
|
{
|
||
|
QPointList list;
|
||
|
list.append(m_initialPos);
|
||
|
|
||
|
const QValueList<QCanvasLine*>::iterator end = m_connectorLines.end();
|
||
|
for ( QValueList<QCanvasLine*>::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"
|