00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "cnitemgroup.h"
00012 #include "component.h"
00013 #include "connector.h"
00014 #include "flowpart.h"
00015 #include "icndocument.h"
00016 #include "node.h"
00017 #include "nodegroup.h"
00018
00019 CNItemGroup::CNItemGroup( ICNDocument *icnDocument, const char *name)
00020 : ItemGroup( icnDocument, name )
00021 {
00022 p_icnDocument = icnDocument;
00023 m_connectorCount = 0;
00024 m_nodeCount = 0;
00025 m_currentLevel = -1;
00026 }
00027
00028 CNItemGroup::~CNItemGroup()
00029 {
00030 }
00031
00032 bool CNItemGroup::addItem( Item *item )
00033 {
00034
00035
00036
00037
00038
00039 if ( !item || !item->canvas() || m_itemList.contains(item) || !item->isMovable() )
00040 return false;
00041
00042 if ( m_currentLevel != -1 && item->level() > m_currentLevel )
00043 return false;
00044
00045 if ( item && m_currentLevel > item->level() )
00046 removeAllItems();
00047
00048 registerItem(item);
00049 m_currentLevel = item->level();
00050 setActiveItem(item);
00051 item->setSelected(true);
00052 updateInfo();
00053 emit itemAdded(item);
00054 return true;
00055 }
00056
00057 bool CNItemGroup::addNode( Node *node )
00058 {
00059 if ( !node || m_nodeList.contains(node) || node->isChildNode() )
00060 return false;
00061 m_nodeList.prepend(node);
00062 node->setSelected(true);
00063 updateInfo();
00064 emit nodeAdded(node);
00065 return true;
00066 }
00067
00068 bool CNItemGroup::addConnector( Connector *con )
00069 {
00070 if ( !con || m_connectorList.contains(con) )
00071 return false;
00072 m_connectorList.prepend(con);
00073 con->setSelected(true);
00074 updateInfo();
00075 emit connectorAdded(con);
00076 return true;
00077 }
00078
00079 bool CNItemGroup::addQCanvasItem( QCanvasItem *qcanvasItem )
00080 {
00081 if (!qcanvasItem) return false;
00082
00083 Item *item = dynamic_cast<Item*>(qcanvasItem);
00084
00085 if (item) return addItem(item);
00086
00087 Node *node = dynamic_cast<Node*>(qcanvasItem);
00088 if (node) return addNode(node);
00089
00090 Connector *connector = dynamic_cast<Connector*>(qcanvasItem);
00091 if (!connector) {
00092 ConnectorLine *connectorLine = dynamic_cast<ConnectorLine*>(qcanvasItem);
00093 if (connectorLine)
00094 connector = connectorLine->parent();
00095 }
00096
00097 if (connector) return addConnector(connector);
00098
00099 return false;
00100 }
00101
00102 void CNItemGroup::setItems( QCanvasItemList list )
00103 {
00104 ItemList itemRemoveList = m_itemList;
00105 ConnectorList connectorRemoveList = m_connectorList;
00106 NodeList nodeRemoveList = m_nodeList;
00107
00108 const QCanvasItemList::const_iterator end = list.end();
00109 for ( QCanvasItemList::const_iterator it = list.begin(); it != end; ++it )
00110 {
00111 switch ( *it ? (*it)->rtti() : 0 ) {
00112 case ItemDocument::RTTI::CNItem:
00113 case ItemDocument::RTTI::DrawPart:
00114 {
00115 itemRemoveList.remove( dynamic_cast<Item*>(*it) );
00116 break;
00117 }
00118 case ItemDocument::RTTI::Node:
00119 {
00120 nodeRemoveList.remove( dynamic_cast<Node*>(*it) );
00121 break;
00122 }
00123 case ItemDocument::RTTI::Connector:
00124 {
00125 connectorRemoveList.remove( dynamic_cast<Connector*>(*it) );
00126 break;
00127 }
00128 case ItemDocument::RTTI::ConnectorLine:
00129 {
00130 connectorRemoveList.remove( (dynamic_cast<ConnectorLine*>(*it))->parent() );
00131 break;
00132 }
00133 default:
00134 break;
00135 }
00136 }
00137
00138 {
00139 const ItemList::const_iterator end = itemRemoveList.end();
00140 for ( ItemList::const_iterator it = itemRemoveList.begin(); it != end; ++it )
00141 {
00142 removeItem(*it);
00143 (*it)->setSelected(false);
00144 }
00145 }
00146
00147 {
00148 const NodeList::const_iterator end = nodeRemoveList.end();
00149 for ( NodeList::const_iterator it = nodeRemoveList.begin(); it != end; ++it )
00150 {
00151 removeNode(*it);
00152 (*it)->setSelected(false);
00153 }
00154 }
00155
00156 {
00157 const ConnectorList::const_iterator end = connectorRemoveList.end();
00158 for ( ConnectorList::const_iterator it = connectorRemoveList.begin(); it != end; ++it )
00159 {
00160 removeConnector(*it);
00161 (*it)->setSelected(false);
00162 }
00163 }
00164
00165 {
00166 const QCanvasItemList::const_iterator end = list.end();
00167 for ( QCanvasItemList::const_iterator it = list.begin(); it != end; ++it )
00168 {
00169
00170
00171 addQCanvasItem(*it);
00172 }
00173 }
00174 }
00175
00176 void CNItemGroup::removeItem( Item *item )
00177 {
00178 if(!item || !m_itemList.contains(item) ) return;
00179
00180 unregisterItem(item);
00181 if(m_activeItem == item ) getActiveItem();
00182
00183 item->setSelected(false);
00184 updateInfo();
00185 emit itemRemoved(item);
00186 }
00187
00188 void CNItemGroup::removeNode( Node *node )
00189 {
00190 if(!node || !m_nodeList.contains(node)) return;
00191
00192 m_nodeList.remove(node);
00193 node->setSelected(false);
00194 updateInfo();
00195 emit nodeRemoved(node);
00196 }
00197
00198 void CNItemGroup::removeConnector( Connector *con )
00199 {
00200 if ( !con || !m_connectorList.contains(con) ) return;
00201 m_connectorList.remove(con);
00202 con->setSelected(false);
00203 updateInfo();
00204 emit connectorRemoved(con);
00205 }
00206
00207 void CNItemGroup::removeQCanvasItem( QCanvasItem *qcanvasItem )
00208 {
00209 if (!qcanvasItem) return;
00210
00211 Item *item = dynamic_cast<Item*>(qcanvasItem);
00212 if(item) return removeItem(item);
00213
00214 Node *node = dynamic_cast<Node*>(qcanvasItem);
00215 if(node) return removeNode(node);
00216
00217 Connector *connector = dynamic_cast<Connector*>(qcanvasItem);
00218 if (!connector) {
00219 ConnectorLine *connectorLine = dynamic_cast<ConnectorLine*>(qcanvasItem);
00220 if (connectorLine)
00221 connector = connectorLine->parent();
00222 }
00223
00224 if(connector) return removeConnector(connector);
00225 }
00226
00227 NodeList CNItemGroup::nodes( bool excludeParented ) const
00228 {
00229 NodeList nodeList = m_nodeList;
00230 if (excludeParented) return nodeList;
00231
00232 NodeGroupList translatableNodeGroups;
00233 p_icnDocument->getTranslatable( items(false), 0, 0, &translatableNodeGroups );
00234
00235 NodeGroupList::iterator end = translatableNodeGroups.end();
00236 for ( NodeGroupList::iterator it = translatableNodeGroups.begin(); it != end; ++it )
00237 {
00238 const NodeList internal = (*it)->internalNodeList();
00239 NodeList::const_iterator internalEnd = internal.end();
00240 for ( NodeList::const_iterator intIt = internal.begin(); intIt != internalEnd; ++intIt ) {
00241 if ( *intIt && !nodeList.contains(*intIt) )
00242 nodeList << *intIt;
00243 }
00244 }
00245
00246 return nodeList;
00247 }
00248
00249 ConnectorList CNItemGroup::connectors( bool excludeParented ) const
00250 {
00251 ConnectorList connectorList = m_connectorList;
00252 if(excludeParented) return connectorList;
00253
00254 ConnectorList translatableConnectors;
00255 NodeGroupList translatableNodeGroups;
00256 p_icnDocument->getTranslatable( items(false), 0, &translatableConnectors, &translatableNodeGroups );
00257
00258 ConnectorList::iterator tcEnd = translatableConnectors.end();
00259 for ( ConnectorList::iterator it = translatableConnectors.begin(); it != tcEnd; ++it ) {
00260 if ( *it && !connectorList.contains(*it) )
00261 connectorList << *it;
00262 }
00263
00264 NodeGroupList::iterator end = translatableNodeGroups.end();
00265 for ( NodeGroupList::iterator it = translatableNodeGroups.begin(); it != end; ++it ) {
00266 const NodeList internal = (*it)->internalNodeList();
00267 NodeList::const_iterator internalEnd = internal.end();
00268 for ( NodeList::const_iterator intIt = internal.begin(); intIt != internalEnd; ++intIt ) {
00269 const ConnectorList connected = (*intIt)->inputConnectorList() + (*intIt)->outputConnectorList();
00270 ConnectorList::const_iterator connectedEnd = connected.end();
00271 for ( ConnectorList::const_iterator conIt = connected.begin(); conIt != connectedEnd; ++conIt ) {
00272 if ( *conIt && !connectorList.contains(*conIt) )
00273 connectorList << *conIt;
00274 }
00275 }
00276 }
00277
00278 return connectorList;
00279 }
00280
00281 bool CNItemGroup::contains( QCanvasItem *qcanvasItem ) const
00282 {
00283 if (!qcanvasItem) return false;
00284
00285 const ItemList::const_iterator ciEnd = m_itemList.end();
00286 for ( ItemList::const_iterator it = m_itemList.begin(); it != ciEnd; ++it )
00287 {
00288 if ( *it == qcanvasItem ) return true;
00289 }
00290
00291 const ConnectorList::const_iterator conEnd = m_connectorList.end();
00292 for ( ConnectorList::const_iterator it = m_connectorList.begin(); it != conEnd; ++it )
00293 {
00294 if ( *it == qcanvasItem )
00295 return true;
00296 }
00297
00298 const NodeList::const_iterator nodeEnd = m_nodeList.end();
00299 for ( NodeList::const_iterator it = m_nodeList.begin(); it != nodeEnd; ++it )
00300 {
00301 if ( *it == qcanvasItem )
00302 return true;
00303 }
00304
00305 return false;
00306 }
00307
00308 void CNItemGroup::setSelected( bool sel )
00309 {
00310 const ItemList::iterator ciEnd = m_itemList.end();
00311 for ( ItemList::iterator it = m_itemList.begin(); it != ciEnd; ++it )
00312 {
00313 if (*it && (*it)->isSelected() != sel )
00314 (*it)->setSelected(sel);
00315 }
00316
00317 const ConnectorList::iterator conEnd = m_connectorList.end();
00318 for ( ConnectorList::iterator it = m_connectorList.begin(); it != conEnd; ++it )
00319 {
00320 if ( *it && (*it)->isSelected() != sel )
00321 (*it)->setSelected(sel);
00322 }
00323
00324 const NodeList::iterator nodeEnd = m_nodeList.end();
00325 for ( NodeList::iterator it = m_nodeList.begin(); it != nodeEnd; ++it )
00326 {
00327 if ( *it && (*it)->isSelected() != sel )
00328 (*it)->setSelected(sel);
00329 }
00330 }
00331
00332 bool CNItemGroup::canRotate() const
00333 {
00334 const ItemList::const_iterator end = m_itemList.end();
00335 for ( ItemList::const_iterator it = m_itemList.begin(); it != end; ++it )
00336 {
00337 CNItem *cnItem = dynamic_cast<CNItem*>((Item*)*it);
00338 if ( cnItem && cnItem->canRotate() )
00339 return true;
00340 }
00341 return false;
00342 }
00343
00344 bool CNItemGroup::canFlip() const
00345 {
00346 const ItemList::const_iterator end = m_itemList.end();
00347 for ( ItemList::const_iterator it = m_itemList.begin(); it != end; ++it )
00348 {
00349 CNItem *cnItem = dynamic_cast<CNItem*>((Item*)*it);
00350 if ( cnItem && cnItem->canFlip() )
00351 return true;
00352 }
00353 return false;
00354 }
00355
00356 void CNItemGroup::slotRotateCW()
00357 {
00358 const ItemList::iterator end = m_itemList.end();
00359 for ( ItemList::iterator it = m_itemList.begin(); it != end; ++it )
00360 {
00361 Component *component = dynamic_cast<Component*>((Item*)*it);
00362 if ( component && component->isMovable() && component->canRotate() )
00363 {
00364 int oldAngle = component->angleDegrees();
00365 component->setAngleDegrees((oldAngle+90)%360);
00366 }
00367 }
00368 p_icnDocument->requestStateSave();
00369 }
00370
00371 void CNItemGroup::slotRotateCCW()
00372 {
00373 const ItemList::iterator end = m_itemList.end();
00374 for ( ItemList::iterator it = m_itemList.begin(); it != end; ++it )
00375 {
00376 Component *component = dynamic_cast<Component*>((Item*)*it);
00377 if ( component && component->isMovable() && component->canRotate() )
00378 {
00379 int oldAngle = component->angleDegrees();
00380 component->setAngleDegrees((oldAngle+270)%360);
00381 }
00382 }
00383 p_icnDocument->requestStateSave();
00384 }
00385
00386 void CNItemGroup::slotFlip()
00387 {
00388 const ItemList::iterator end = m_itemList.end();
00389 for ( ItemList::iterator it = m_itemList.begin(); it != end; ++it )
00390 {
00391 Component *component = dynamic_cast<Component*>((Item*)*it);
00392 if ( component && component->isMovable() && component->canFlip() )
00393 {
00394 bool oldFlipped = component->flipped();
00395 component->setFlipped(!oldFlipped);
00396 }
00397 }
00398 p_icnDocument->requestStateSave();
00399 }
00400
00401
00402 void CNItemGroup::setOrientationAngle( int _angle )
00403 {
00404 const ItemList::iterator end = m_itemList.end();
00405 for ( ItemList::iterator it = m_itemList.begin(); it != end; ++it )
00406 {
00407 Component *component = dynamic_cast<Component*>((Item*)*it);
00408 if ( component && component->isMovable() && component->canRotate() )
00409 {
00410 int oldAngle = component->angleDegrees();
00411 if ( oldAngle != _angle )
00412 {
00413 component->setAngleDegrees(_angle);
00414 }
00415 }
00416 }
00417 p_icnDocument->requestStateSave();
00418 }
00419
00420
00421 void CNItemGroup::setComponentOrientation( int angleDegrees, bool flipped )
00422 {
00423 bool flipping = flipped;
00424 bool rotating = (((angleDegrees%360)+360)%360) != 0;
00425
00426 const ItemList::iterator end = m_itemList.end();
00427 for ( ItemList::iterator it = m_itemList.begin(); it != end; ++it )
00428 {
00429 Component *component = dynamic_cast<Component*>((Item*)*it);
00430 if ( component && component->isMovable() && (!flipping || component->canFlip()) && (!rotating || component->canRotate()) )
00431 {
00432 int oldAngle = component->angleDegrees();
00433 int oldFlipped = component->flipped();
00434 if ( (oldAngle != angleDegrees) || (oldFlipped != flipped) )
00435 {
00436 if ( component->canFlip() )
00437 component->setFlipped(flipped);
00438 if ( component->canRotate() )
00439 component->setAngleDegrees(angleDegrees);
00440 }
00441 }
00442 }
00443 p_icnDocument->requestStateSave();
00444 }
00445
00446
00447 void CNItemGroup::setFlowPartOrientation( unsigned orientation )
00448 {
00449 const ItemList::iterator end = m_itemList.end();
00450 for ( ItemList::iterator it = m_itemList.begin(); it != end; ++it )
00451 {
00452 FlowPart * flowPart = dynamic_cast<FlowPart*>((Item*)*it);
00453 if ( flowPart && flowPart->isMovable() )
00454 flowPart->setOrientation(orientation);
00455 }
00456 p_icnDocument->requestStateSave();
00457 }
00458
00459 void CNItemGroup::mergeGroup( ItemGroup *itemGroup )
00460 {
00461 CNItemGroup *group = dynamic_cast<CNItemGroup*>(itemGroup);
00462 if (!group) return;
00463
00464 const ItemList items = group->items();
00465 const ConnectorList connectors = group->connectors();
00466 const NodeList nodes = group->nodes();
00467
00468 const ItemList::const_iterator ciEnd = items.end();
00469 for ( ItemList::const_iterator it = items.begin(); it != ciEnd; ++it )
00470 {
00471 addItem(*it);
00472 }
00473 const ConnectorList::const_iterator conEnd = connectors.end();
00474 for ( ConnectorList::const_iterator it = connectors.begin(); it != conEnd; ++it )
00475 {
00476 addConnector(*it);
00477 }
00478 const NodeList::const_iterator nodeEnd = nodes.end();
00479 for ( NodeList::const_iterator it = nodes.begin(); it != nodeEnd; ++it )
00480 {
00481 addNode(*it);
00482 }
00483 }
00484
00485 void CNItemGroup::removeAllItems()
00486 {
00487 while ( !m_itemList.isEmpty() )
00488 removeItem(*m_itemList.begin());
00489
00490 while ( !m_connectorList.isEmpty() )
00491 removeConnector(*m_connectorList.begin());
00492
00493 while ( !m_nodeList.isEmpty() )
00494 removeNode(*m_nodeList.begin());
00495 }
00496
00497 void CNItemGroup::deleteAllItems()
00498 {
00499 const ItemList::iterator ciEnd = m_itemList.end();
00500 for ( ItemList::iterator it = m_itemList.begin(); it != ciEnd; ++it )
00501 {
00502 if(*it) (*it)->removeItem();
00503 }
00504 const NodeList::iterator nodeEnd = m_nodeList.end();
00505 for ( NodeList::iterator it = m_nodeList.begin(); it != nodeEnd; ++it )
00506 {
00507 if(*it && !(*it)->isChildNode() ) (*it)->removeNode();
00508
00509 }
00510 const ConnectorList::iterator conEnd = m_connectorList.end();
00511 for ( ConnectorList::iterator it = m_connectorList.begin(); it != conEnd; ++it )
00512 {
00513 if(*it) (*it)->removeConnector();
00514 }
00515
00516
00517 removeAllItems();
00518 }
00519
00520 void CNItemGroup::updateInfo()
00521 {
00522 m_connectorCount = m_connectorList.count();
00523 m_nodeCount = m_nodeList.count();
00524
00525 if(m_itemList.isEmpty() ) m_currentLevel = -1;
00526 }
00527
00528 void CNItemGroup::getActiveItem()
00529 {
00530 if(m_itemList.isEmpty() ) setActiveItem(0);
00531 else setActiveItem( *m_itemList.begin() );
00532 }
00533
00534 void CNItemGroup::setActiveItem( Item *item )
00535 {
00536 if ( item == m_activeItem ) return;
00537 m_activeItem = item;
00538 }
00539
00540 QStringList CNItemGroup::itemIDs()
00541 {
00542 QStringList list;
00543 ItemList::iterator end = m_itemList.end();
00544 for ( ItemList::iterator it = m_itemList.begin(); it != end; ++it )
00545 {
00546 if (*it) {
00547 list += (*it)->id();
00548 }
00549 }
00550 return list;
00551 }
00552
00553 #include "cnitemgroup.moc"
00554