Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS dbe source for the DUNE DAQ project.
3 : // Fork baseline commit: dbe-02-12-17 (2022-05-12).
4 : // Renamed since fork: no.
5 :
6 : #include "dbe/config_ui_info.hpp"
7 : #include "dbe/config_api_info.hpp"
8 : #include "dbe/config_api_commands.hpp"
9 : #include "dbe/confaccessor.hpp"
10 : #include "dbe/treenode.hpp"
11 :
12 : #include <QGraphicsSceneMouseEvent>
13 : #include <QPainter>
14 : #include <QBitmap>
15 : #include <QGraphicsScene>
16 : #include <QGraphicsObject>
17 : #include <QMimeData>
18 : #include <QComboBox>
19 : #include <QHBoxLayout>
20 : #include <QPushButton>
21 : #include <QMessageBox>
22 : #include <QApplication>
23 : #include <QLabel>
24 : #include <QDrag>
25 :
26 : //------------------------------------------------------------------------------------------
27 0 : dbe::GraphicalObject::GraphicalObject ( bool Used, QString ObjectName,
28 0 : GraphicalClass GraphInfo, QGraphicsObject * parent )
29 : : QGraphicsObject ( parent ),
30 0 : GraphicalInfo ( GraphInfo ),
31 0 : IconItem ( nullptr ),
32 0 : TextItem ( nullptr ),
33 0 : DatabaseClassName ( GraphInfo.DatabaseClassName ),
34 0 : DatabaseUidName ( ObjectName ),
35 0 : IsExpanded ( false ),
36 0 : IsFetched ( false ),
37 0 : expandedX ( 0 ),
38 0 : expandedY ( 0 )
39 : {
40 0 : setAcceptDrops ( true );
41 0 : setFlag ( ItemIsMovable );
42 :
43 0 : QPixmap Icon;
44 :
45 0 : if ( Used )
46 : {
47 0 : if ( !GraphInfo.UsedPixmapFile.isEmpty() ) Icon = QPixmap (
48 0 : ":/Images/" + GraphInfo.UsedPixmapFile );
49 : else
50 : {
51 0 : Icon = QPixmap ( ":/Images/" + GraphInfo.GenericPixmapFile );
52 : }
53 : }
54 : else
55 : {
56 0 : Icon = QPixmap ( ":/Images/" + GraphInfo.GenericPixmapFile );
57 : }
58 :
59 0 : QBitmap IconMask = Icon.createHeuristicMask();
60 0 : Icon.setMask ( IconMask );
61 :
62 0 : IconItem = new QGraphicsPixmapItem ( Icon );
63 0 : TextItem = new QGraphicsTextItem ( ObjectName );
64 0 : }
65 : //------------------------------------------------------------------------------------------
66 :
67 : //------------------------------------------------------------------------------------------
68 0 : dbe::GraphicalObject::~GraphicalObject()
69 : {
70 0 : delete IconItem;
71 0 : delete TextItem;
72 0 : }
73 : //------------------------------------------------------------------------------------------
74 :
75 : //------------------------------------------------------------------------------------------
76 0 : QRectF dbe::GraphicalObject::boundingRect() const
77 : {
78 0 : QRectF Boundarie;
79 0 : Boundarie.setHeight (
80 0 : IconItem->boundingRect().height() + TextItem->boundingRect().height() );
81 :
82 0 : if ( IconItem->boundingRect().width() > TextItem->boundingRect().width() ) Boundarie
83 0 : .setWidth ( IconItem->boundingRect().width() );
84 : else
85 : {
86 0 : Boundarie.setWidth ( TextItem->boundingRect().width() );
87 : }
88 :
89 0 : return Boundarie;
90 : }
91 : //------------------------------------------------------------------------------------------
92 :
93 : //------------------------------------------------------------------------------------------
94 0 : void dbe::GraphicalObject::paint ( QPainter * painter,
95 : const QStyleOptionGraphicsItem * option,
96 : QWidget * widget )
97 : {
98 0 : Q_UNUSED ( option )
99 0 : Q_UNUSED ( widget )
100 :
101 0 : QFontMetrics Metric ( QFont ( "Helvetica", 10 ) );
102 0 : painter->setFont ( QFont ( "Helvetica", 10 ) );
103 0 : painter->drawPixmap ( IconItem->boundingRect(), IconItem->pixmap(),
104 0 : IconItem->boundingRect() );
105 0 : painter->drawText (
106 0 : IconItem->boundingRect().bottomLeft() + QPointF (
107 0 : 0, Metric.boundingRect ( DatabaseUidName ).height() ),
108 0 : DatabaseUidName );
109 0 : }
110 : //------------------------------------------------------------------------------------------
111 :
112 : //------------------------------------------------------------------------------------------
113 0 : QPainterPath dbe::GraphicalObject::shape() const
114 : {
115 0 : QPainterPath Path;
116 0 : Path.addRect ( IconItem->boundingRect() );
117 0 : return Path;
118 0 : }
119 : //------------------------------------------------------------------------------------------
120 :
121 : //------------------------------------------------------------------------------------------
122 0 : void dbe::GraphicalObject::mouseDoubleClickEvent ( QGraphicsSceneMouseEvent * event )
123 : {
124 0 : if ( !IsFetched )
125 : {
126 0 : AddGraphicChildren();
127 : }
128 :
129 0 : if ( !IsExpanded )
130 : {
131 0 : ShowGraphicsChildren();
132 : }
133 : else
134 : {
135 0 : HideGraphicsChildren();
136 : }
137 :
138 0 : update();
139 0 : QGraphicsItem::mouseDoubleClickEvent ( event );
140 0 : }
141 : //------------------------------------------------------------------------------------------
142 :
143 : //------------------------------------------------------------------------------------------
144 0 : void dbe::GraphicalObject::mousePressEvent ( QGraphicsSceneMouseEvent * event )
145 : {
146 0 : if ( event->button() == Qt::LeftButton )
147 : {
148 0 : StartDrag = event->pos();
149 : }
150 0 : }
151 : //------------------------------------------------------------------------------------------
152 :
153 : //------------------------------------------------------------------------------------------
154 0 : void dbe::GraphicalObject::mouseMoveEvent ( QGraphicsSceneMouseEvent * event )
155 : {
156 0 : if ( ! ( event->buttons() & Qt::LeftButton ) )
157 : {
158 0 : return;
159 : }
160 :
161 0 : if ( ( event->pos() - StartDrag ).manhattanLength() < QApplication::startDragDistance() )
162 : {
163 : return;
164 : }
165 :
166 0 : QDrag * drag = new QDrag ( event->widget() );
167 0 : QPixmap Icon = IconItem->pixmap();
168 :
169 0 : QStringList DataList;
170 0 : QMimeData * mimeData = new QMimeData;
171 0 : QByteArray ItemData;
172 0 : QDataStream DataStream ( &ItemData, QIODevice::WriteOnly );
173 :
174 0 : DataList.append ( QString ( DatabaseUidName ) );
175 0 : DataList.append ( QString ( DatabaseClassName ) );
176 0 : DataStream << DataList;
177 0 : mimeData->setData ( "application/vnd.text.list", ItemData );
178 :
179 0 : drag->setMimeData ( mimeData );
180 0 : drag->setPixmap ( Icon );
181 :
182 0 : Qt::DropAction dropAction = drag->exec();
183 0 : Q_UNUSED ( dropAction )
184 0 : }
185 : //------------------------------------------------------------------------------------------
186 :
187 : //------------------------------------------------------------------------------------------
188 0 : void dbe::GraphicalObject::dropEvent ( QGraphicsSceneDragDropEvent * event )
189 : {
190 0 : QByteArray encodedData = event->mimeData()->data ( "application/vnd.text.list" );
191 0 : QDataStream stream ( &encodedData, QIODevice::ReadOnly );
192 0 : QList<QStringList> NewItems;
193 :
194 0 : while ( !stream.atEnd() )
195 : {
196 0 : QStringList Text;
197 0 : stream >> Text;
198 0 : NewItems << Text;
199 0 : }
200 :
201 0 : QStringList ObjectList;
202 :
203 0 : for ( QStringList & i : NewItems )
204 : {
205 0 : ObjectList.append ( i.at ( 0 ) );
206 : }
207 :
208 0 : for ( int i = 0; i < NewItems.size(); ++i )
209 : {
210 0 : if ( NewItems.at ( 0 ).at ( 1 ) != NewItems.at ( i ).at ( 1 ) )
211 : {
212 : return;
213 : }
214 : }
215 :
216 0 : QStringList PossibleRelationships;
217 0 : QString ClassName = NewItems.at ( 0 ).at ( 1 );
218 :
219 0 : dunedaq::conffwk::class_t ClassInfoReceiverObject =
220 0 : dbe::config::api::info::onclass::definition ( DatabaseClassName.toStdString(), false );
221 0 : std::vector<dunedaq::conffwk::relationship_t> RelationshipList = ClassInfoReceiverObject
222 0 : .p_relationships;
223 :
224 0 : for ( dunedaq::conffwk::relationship_t & i : RelationshipList )
225 : {
226 0 : if ( i.p_type == ClassName.toStdString() ) PossibleRelationships.append (
227 0 : QString::fromStdString ( i.p_name ) );
228 :
229 0 : dunedaq::conffwk::class_t ClassInfoDroppedObject =
230 : dbe::config::api::info::onclass::definition ( i.p_type,
231 0 : false );
232 0 : std::vector<std::string> RelationshipListDropped = ClassInfoDroppedObject.p_subclasses;
233 :
234 0 : for ( std::string & j : RelationshipListDropped )
235 : {
236 0 : if ( j == ClassName.toStdString() ) PossibleRelationships.append (
237 0 : QString::fromStdString ( i.p_name ) );
238 : }
239 0 : }
240 :
241 0 : QString SelectedRelationship;
242 :
243 0 : if ( PossibleRelationships.size() == 0 )
244 : {
245 0 : return;
246 : }
247 0 : else if ( PossibleRelationships.size() == 1 ) SelectedRelationship = PossibleRelationships
248 0 : .at ( 0 );
249 : else
250 : {
251 0 : QDialog * NewDialog = new QDialog();
252 0 : QHBoxLayout * NewLayout = new QHBoxLayout();
253 0 : QPushButton * OkButton = new QPushButton ( "Ok" );
254 0 : QComboBox * NewCombo = new QComboBox();
255 0 : QLabel * NewLabel = new QLabel ( "Choose relationship : " );
256 0 : NewCombo->addItems ( PossibleRelationships );
257 0 : NewLayout->addWidget ( NewLabel );
258 0 : NewLayout->addWidget ( NewCombo );
259 0 : NewLayout->addWidget ( OkButton );
260 0 : NewDialog->setLayout ( NewLayout );
261 0 : NewDialog->adjustSize();
262 0 : connect ( OkButton, SIGNAL ( clicked() ), NewDialog, SLOT ( accept() ),
263 : Qt::UniqueConnection );
264 :
265 0 : int Status = NewDialog->exec();
266 :
267 0 : if ( Status == QDialog::Accepted )
268 : {
269 0 : SelectedRelationship = NewCombo->currentText();
270 : }
271 : }
272 :
273 0 : treenode * NodeObject = confaccessor::gethandler()->getnode ( DatabaseClassName,
274 0 : DatabaseUidName );
275 :
276 0 : if ( NodeObject )
277 : {
278 0 : for ( treenode * Child : NodeObject->GetChildren() )
279 : {
280 0 : if ( dynamic_cast<RelationshipNode *> ( Child ) )
281 : {
282 0 : RelationshipNode * NodeRelationship = dynamic_cast<RelationshipNode *> ( Child );
283 0 : dunedaq::conffwk::relationship_t RelationshipData =
284 0 : NodeRelationship->relation_t();
285 :
286 0 : if ( RelationshipData.p_name == SelectedRelationship.toStdString() )
287 : {
288 0 : if ( ( RelationshipData.p_cardinality == dunedaq::conffwk::zero_or_many ) || ( RelationshipData
289 : .p_cardinality
290 : == dunedaq::conffwk::one_or_many ) )
291 : {
292 0 : std::vector<std::string> RelationshipValues;
293 :
294 0 : for ( treenode * RelationshipChildren : NodeRelationship->GetChildren() )
295 0 : RelationshipValues.push_back (
296 0 : RelationshipChildren->GetData ( 0 ).toString().toStdString() );
297 :
298 0 : for ( QStringList & Item : NewItems )
299 0 : if ( std::find ( RelationshipValues.begin(), RelationshipValues.end(),
300 0 : Item.at ( 0 ).toStdString() )
301 0 : == RelationshipValues.end() ) RelationshipValues.push_back (
302 0 : Item.at ( 0 ).toStdString() );
303 :
304 0 : tref Object = NodeObject->GetObject();
305 0 : dbe::config::api::commands::modobj ( Object, RelationshipData,
306 : RelationshipValues );
307 0 : }
308 : else
309 : {
310 0 : QString SelectedObject;
311 :
312 0 : if ( NewItems.size() > 1 )
313 : {
314 0 : QDialog * NewDialog = new QDialog();
315 0 : QHBoxLayout * NewLayout = new QHBoxLayout();
316 0 : QPushButton * OkButton = new QPushButton ( "Ok" );
317 0 : QComboBox * NewCombo = new QComboBox();
318 0 : QLabel * NewLabel = new QLabel ( "Choose Object : " );
319 0 : NewCombo->addItems ( ObjectList );
320 0 : NewLayout->addWidget ( NewLabel );
321 0 : NewLayout->addWidget ( NewCombo );
322 0 : NewLayout->addWidget ( OkButton );
323 0 : NewDialog->setLayout ( NewLayout );
324 0 : NewDialog->adjustSize();
325 0 : connect ( OkButton, SIGNAL ( clicked() ), NewDialog, SLOT ( accept() ),
326 : Qt::UniqueConnection );
327 :
328 0 : int Status = NewDialog->exec();
329 :
330 0 : if ( Status == QDialog::Accepted )
331 : {
332 0 : SelectedObject = NewCombo->currentText();
333 : }
334 : }
335 : else
336 : {
337 0 : SelectedObject = NewItems.at ( 0 ).at ( 0 );
338 : }
339 :
340 0 : tref Object = NodeObject->GetObject();
341 0 : dbe::config::api::commands::modobj ( Object, RelationshipData,
342 : { SelectedObject.toStdString() } );
343 :
344 0 : }
345 : }
346 0 : }
347 0 : }
348 : }
349 0 : }
350 : //------------------------------------------------------------------------------------------
351 :
352 : //------------------------------------------------------------------------------------------
353 0 : void dbe::GraphicalObject::AddGraphicChildren()
354 : {
355 0 : double dx = 0;
356 0 : double dy = 0;
357 :
358 0 : treenode * NodeObject = confaccessor::gethandler()->getnode ( DatabaseClassName,
359 0 : DatabaseUidName );
360 :
361 0 : if ( NodeObject )
362 : {
363 0 : for ( treenode * ChildNode : NodeObject->GetChildren() )
364 : {
365 0 : RelationshipNode * NodeRelationship = dynamic_cast<RelationshipNode *> ( ChildNode );
366 :
367 0 : if ( NodeRelationship && NodeRelationship->GetHasStructure() )
368 : {
369 0 : dunedaq::conffwk::relationship_t RelationshipData =
370 0 : NodeRelationship->relation_t();
371 0 : GraphicalRelationship * RelationshipChildNode = new GraphicalRelationship (
372 0 : DatabaseUidName, DatabaseClassName, RelationshipData );
373 0 : RelationshipChildNode->setParentItem ( this );
374 0 : RelationshipChildNode->AddGraphicChildren();
375 :
376 0 : QPointF coord = RelationshipChildNode->mapFromParent ( boundingRect().bottomRight() );
377 0 : RelationshipChildNode->setX ( coord.x() + dx );
378 0 : RelationshipChildNode->setY ( coord.y() + dy );
379 :
380 0 : for ( QGraphicsItem * GraphicItem : RelationshipChildNode->childItems() )
381 : {
382 0 : dy += GraphicItem->boundingRect().height();
383 0 : }
384 0 : }
385 0 : }
386 : }
387 :
388 0 : IsFetched = true;
389 0 : }
390 : //------------------------------------------------------------------------------------------
391 :
392 : //------------------------------------------------------------------------------------------
393 0 : void dbe::GraphicalObject::ShowGraphicsChildren()
394 : {
395 0 : for ( QGraphicsItem * i : this->childItems() )
396 : {
397 0 : i->show();
398 0 : }
399 :
400 0 : double ThisOffsetX = 0;
401 0 : double ThisOffsetY = 0;
402 0 : GetOffsetX ( this, ThisOffsetX );
403 0 : GetOffsetY ( this, ThisOffsetY );
404 0 : QPointF ThisItemBottom = this->mapToScene ( this->boundingRect().bottomRight() );
405 :
406 0 : if ( !this->childItems().isEmpty() )
407 : {
408 0 : ThisOffsetX -= ThisItemBottom.x();
409 0 : ThisOffsetY -= ThisItemBottom.y();
410 : }
411 :
412 : /// First change items with the same parent
413 0 : QGraphicsItem * AuxiliaryItem = this;
414 :
415 0 : while ( AuxiliaryItem->parentItem() != nullptr )
416 : {
417 0 : for ( int i = AuxiliaryItem->parentItem()->childItems().indexOf ( AuxiliaryItem ) + 1;
418 0 : i < AuxiliaryItem->parentItem()->childItems().size(); ++i )
419 : {
420 0 : QGraphicsItem * Child = AuxiliaryItem->parentItem()->childItems().at ( i );
421 0 : Child->setY ( Child->y() + ThisOffsetY );
422 : }
423 :
424 0 : AuxiliaryItem = AuxiliaryItem->parentItem();
425 : }
426 :
427 : /// Now that the items with the same parent are in their final position
428 : /// calculate the OffsetX/OffsetY of this item top level parent item
429 0 : double ThisTopLevelOffsetX = 0;
430 0 : double ThisTopLevelOffsetY = 0;
431 0 : GetOffsetX ( this->topLevelItem(), ThisTopLevelOffsetX );
432 0 : GetOffsetY ( this->topLevelItem(), ThisTopLevelOffsetY );
433 0 : QPointF ThisTopLevelItemBottom = this->topLevelItem()->mapToScene (
434 0 : this->topLevelItem()->boundingRect().bottomRight() );
435 :
436 0 : if ( !this->topLevelItem()->childItems().isEmpty() )
437 : {
438 0 : ThisTopLevelOffsetX -= ThisTopLevelItemBottom.x();
439 0 : ThisTopLevelOffsetY -= ThisTopLevelItemBottom.y();
440 : }
441 :
442 : /// Now get all the items in the scene
443 0 : QList<QGraphicsItem *> TopLevelItems = scene()->items();
444 : /// Now get the highest y in the same line as this top level item
445 0 : GraphicalObject * ThisTopLevelItem = dynamic_cast<GraphicalObject *>
446 0 : ( this->topLevelItem() );
447 0 : double LineHighestOffsetY = 0;
448 :
449 0 : for ( QGraphicsItem * Item : TopLevelItems )
450 : {
451 : /// Get only top levels items at the same line as this top level item
452 : /// and not equal as this top level item
453 0 : if ( Item->parentItem() == nullptr && ThisTopLevelItem->y() == Item->y()
454 0 : && ThisTopLevelItem != Item )
455 : {
456 0 : GraphicalObject * ItemObject = dynamic_cast<GraphicalObject *> ( Item );
457 :
458 0 : if ( ItemObject && LineHighestOffsetY < ItemObject->GetExpandedY() ) LineHighestOffsetY =
459 0 : ItemObject->GetExpandedY();
460 : }
461 : }
462 :
463 : /// Now i have the highest offset on the line, distance from the line bottom line
464 : /// Iterating over the top level items to add proper offsetX/offsetY
465 0 : for ( QGraphicsItem * Item : TopLevelItems )
466 : {
467 0 : if ( ThisTopLevelItem != Item && Item->parentItem() == nullptr )
468 : {
469 0 : if ( ThisTopLevelItem->y() < Item->y() && ThisTopLevelOffsetY > LineHighestOffsetY )
470 : {
471 0 : if ( LineHighestOffsetY == 0 )
472 : {
473 0 : Item->setY ( Item->y() + ThisOffsetY );
474 : }
475 : else
476 : {
477 0 : if ( ThisTopLevelOffsetY - LineHighestOffsetY < ThisTopLevelOffsetY
478 0 : - ThisTopLevelItem->GetExpandedY() ) Item->setY (
479 0 : Item->y() + ThisTopLevelOffsetY - LineHighestOffsetY );
480 0 : else Item->setY (
481 0 : Item->y() + ThisTopLevelOffsetY - ThisTopLevelItem->GetExpandedY() );
482 : }
483 : }
484 : }
485 :
486 0 : if ( ThisTopLevelItem->y() == Item->y() && ThisTopLevelItem->x() < Item->x()
487 0 : && Item->parentItem() == nullptr )
488 : {
489 0 : if ( ThisTopLevelOffsetX > ThisTopLevelItem->GetExpandedX() )
490 : {
491 0 : if ( ThisTopLevelItem->GetExpandedX() == 0 )
492 : {
493 0 : Item->setX ( Item->x() + ThisOffsetX );
494 : }
495 : else
496 : {
497 0 : Item->setX ( Item->x() + ThisTopLevelOffsetX - ThisTopLevelItem->GetExpandedX() );
498 : }
499 : }
500 : }
501 : }
502 :
503 0 : ThisTopLevelItem->SetExpandedX ( ThisTopLevelOffsetX );
504 0 : ThisTopLevelItem->SetExpandedY ( ThisTopLevelOffsetY );
505 0 : IsExpanded = true;
506 0 : }
507 : //------------------------------------------------------------------------------------------
508 :
509 : //------------------------------------------------------------------------------------------
510 0 : void dbe::GraphicalObject::HideGraphicsChildren()
511 : {
512 0 : double ThisOffsetX = 0;
513 0 : double ThisOffsetY = 0;
514 0 : GetOffsetX ( this, ThisOffsetX );
515 0 : GetOffsetY ( this, ThisOffsetY );
516 0 : QPointF ThisItemBottom = this->mapToScene ( this->boundingRect().bottomRight() );
517 :
518 0 : if ( !this->childItems().isEmpty() )
519 : {
520 0 : ThisOffsetX -= ThisItemBottom.x();
521 0 : ThisOffsetY -= ThisItemBottom.y();
522 : }
523 :
524 : /// First change items with the same parent
525 0 : QGraphicsItem * AuxiliaryItem = this;
526 :
527 0 : while ( AuxiliaryItem->parentItem() != nullptr )
528 : {
529 0 : for ( int i = AuxiliaryItem->parentItem()->childItems().indexOf ( AuxiliaryItem ) + 1;
530 0 : i < AuxiliaryItem->parentItem()->childItems().size(); ++i )
531 : {
532 0 : QGraphicsItem * Child = AuxiliaryItem->parentItem()->childItems().at ( i );
533 0 : Child->setY ( Child->y() - ThisOffsetY );
534 : }
535 :
536 0 : AuxiliaryItem = AuxiliaryItem->parentItem();
537 : }
538 :
539 : /// Now that the items with the same parent are in their final position
540 : /// calculate the OffsetX/OffsetY of this item top level parent item
541 : /// THIS FOR IS EXTREMELY IMPORTANT -> DO NOT TOUCH IT
542 : /// IF YOU TOUCH IT I WILL HUNT YOU FOREVER....AND ONE DAY I WILL CATCH YOU
543 0 : for ( QGraphicsItem * i : this->childItems() )
544 : {
545 0 : i->hide();
546 0 : }
547 :
548 0 : double ThisTopLevelOffsetX = 0;
549 0 : double ThisTopLevelOffsetY = 0;
550 0 : GetOffsetX ( this->topLevelItem(), ThisTopLevelOffsetX );
551 0 : GetOffsetY ( this->topLevelItem(), ThisTopLevelOffsetY );
552 0 : QPointF ThisTopLevelItemBottom = this->topLevelItem()->mapToScene (
553 0 : this->topLevelItem()->boundingRect().bottomRight() );
554 :
555 0 : if ( !this->topLevelItem()->childItems().isEmpty()
556 0 : && this->topLevelItem()->childItems().at (
557 0 : 0 )->isVisible() )
558 : {
559 0 : ThisTopLevelOffsetX -= ThisTopLevelItemBottom.x();
560 0 : ThisTopLevelOffsetY -= ThisTopLevelItemBottom.y();
561 : }
562 :
563 : /// Now get all the items in the scene
564 0 : QList<QGraphicsItem *> TopLevelItems = scene()->items();
565 : /// Now get the highest y in the same line as this top level item
566 0 : GraphicalObject * ThisTopLevelItem = dynamic_cast<GraphicalObject *>
567 0 : ( this->topLevelItem() );
568 0 : double LineHighestOffsetY = 0;
569 :
570 0 : for ( QGraphicsItem * Item : TopLevelItems )
571 : {
572 : /// Get only top levels items at the same line as this top level item
573 : /// and not equal as this top level item
574 0 : if ( Item->parentItem() == nullptr && ThisTopLevelItem->y() == Item->y()
575 0 : && ThisTopLevelItem != Item )
576 : {
577 0 : GraphicalObject * ItemObject = dynamic_cast<GraphicalObject *> ( Item );
578 :
579 0 : if ( ItemObject && LineHighestOffsetY < ItemObject->GetExpandedY() ) LineHighestOffsetY =
580 0 : ItemObject->GetExpandedY();
581 : }
582 : }
583 :
584 : /// Now i have the highest offset on the line, distance from the line bottom line
585 : /// Iterating over the top level items to add proper offsetX/offsetY
586 0 : for ( QGraphicsItem * Item : TopLevelItems )
587 : {
588 0 : if ( ThisTopLevelItem != Item && Item->parentItem() == nullptr )
589 : {
590 0 : if ( ThisTopLevelItem->y() < Item->y() && ThisTopLevelItem->GetExpandedY()
591 : > LineHighestOffsetY )
592 : {
593 0 : if ( LineHighestOffsetY == 0 )
594 : {
595 0 : Item->setY ( Item->y() - ThisOffsetY );
596 : }
597 : else
598 : {
599 0 : if ( ThisTopLevelOffsetY >= LineHighestOffsetY && ThisTopLevelOffsetY
600 0 : < ThisTopLevelItem->GetExpandedY() ) Item->setY (
601 0 : Item->y() - abs ( ThisTopLevelOffsetY - ThisTopLevelItem->GetExpandedY() ) );
602 :
603 0 : if ( ThisTopLevelItem->GetExpandedY() > LineHighestOffsetY && ThisTopLevelOffsetY
604 0 : < LineHighestOffsetY ) Item->setY (
605 0 : Item->y() - abs ( ThisTopLevelItem->GetExpandedY() - LineHighestOffsetY ) );
606 : }
607 : }
608 : }
609 :
610 0 : if ( ThisTopLevelItem->y() == Item->y() && ThisTopLevelItem->x() < Item->x()
611 0 : && Item->parentItem() == nullptr )
612 : {
613 0 : if ( ThisTopLevelOffsetX < ThisTopLevelItem->GetExpandedX() )
614 : {
615 0 : Item->setX ( Item->x() - abs ( ThisTopLevelOffsetX - ThisTopLevelItem->GetExpandedX() ) );
616 : }
617 : }
618 : }
619 :
620 0 : ThisTopLevelItem->SetExpandedX ( ThisTopLevelOffsetX );
621 0 : ThisTopLevelItem->SetExpandedY ( ThisTopLevelOffsetY );
622 0 : IsExpanded = false;
623 0 : }
624 : //------------------------------------------------------------------------------------------
625 :
626 : //------------------------------------------------------------------------------------------
627 0 : void dbe::GraphicalObject::GetOffsetX ( QGraphicsItem * Item, double & Offset )
628 : {
629 0 : for ( QGraphicsItem * ChildItem : Item->childItems() )
630 : {
631 0 : if ( ChildItem->isVisible() )
632 : {
633 0 : QPointF ChildItemBottom = ChildItem->mapToScene (
634 0 : ChildItem->boundingRect().bottomRight() );
635 :
636 0 : if ( Offset < ChildItemBottom.x() )
637 : {
638 0 : Offset = ChildItemBottom.x();
639 : }
640 : }
641 :
642 0 : GetOffsetX ( ChildItem, Offset );
643 0 : }
644 0 : }
645 : //------------------------------------------------------------------------------------------
646 :
647 : //------------------------------------------------------------------------------------------
648 0 : void dbe::GraphicalObject::GetOffsetY ( QGraphicsItem * Item, double & Offset )
649 : {
650 0 : for ( QGraphicsItem * ChildItem : Item->childItems() )
651 : {
652 0 : if ( ChildItem->isVisible() )
653 : {
654 0 : QPointF ChildItemBottom = ChildItem->mapToScene (
655 0 : ChildItem->boundingRect().bottomRight() );
656 :
657 0 : if ( Offset < ChildItemBottom.y() )
658 : {
659 0 : Offset = ChildItemBottom.y();
660 : }
661 : }
662 :
663 0 : GetOffsetY ( ChildItem, Offset );
664 0 : }
665 0 : }
666 : //------------------------------------------------------------------------------------------
667 :
668 : //------------------------------------------------------------------------------------------
669 0 : void dbe::GraphicalObject::LocateTopMostItem ( QGraphicsItem * Auxiliary )
670 : {
671 0 : while ( Auxiliary->parentItem() != nullptr )
672 : {
673 0 : Auxiliary = Auxiliary->parentItem();
674 : }
675 0 : }
676 : //------------------------------------------------------------------------------------------
677 :
678 : //------------------------------------------------------------------------------------------
679 0 : QString dbe::GraphicalObject::GetDatabaseClassName() const
680 : {
681 0 : return DatabaseClassName;
682 : }
683 : //------------------------------------------------------------------------------------------
684 :
685 : //------------------------------------------------------------------------------------------
686 0 : QString dbe::GraphicalObject::GetDatabaseUidName() const
687 : {
688 0 : return DatabaseUidName;
689 : }
690 : //------------------------------------------------------------------------------------------
691 :
692 : //------------------------------------------------------------------------------------------
693 0 : double dbe::GraphicalObject::GetExpandedX() const
694 : {
695 0 : return expandedX;
696 : }
697 : //------------------------------------------------------------------------------------------
698 :
699 : //------------------------------------------------------------------------------------------
700 0 : double dbe::GraphicalObject::GetExpandedY() const
701 : {
702 0 : return expandedY;
703 : }
704 : //------------------------------------------------------------------------------------------
705 :
706 : //------------------------------------------------------------------------------------------
707 0 : void dbe::GraphicalObject::SetExpandedX ( double dx )
708 : {
709 0 : expandedX = dx;
710 0 : }
711 : //------------------------------------------------------------------------------------------
712 :
713 : //------------------------------------------------------------------------------------------
714 0 : void dbe::GraphicalObject::SetExpandedY ( double dy )
715 : {
716 0 : expandedY = dy;
717 0 : }
718 : //------------------------------------------------------------------------------------------
719 :
720 : //------------------------------------------------------------------------------------------
721 0 : dbe::GraphicalRelationship::GraphicalRelationship ( QString ObjectName, QString ClassName,
722 : dunedaq::conffwk::relationship_t & Data,
723 0 : QGraphicsObject * parent )
724 : : QGraphicsObject ( parent ),
725 0 : DatabaseClassName ( ClassName ),
726 0 : DatabaseUidName ( ObjectName ),
727 0 : RelationshipData ( Data ),
728 0 : TextItem ( nullptr )
729 : {
730 0 : TextItem = new QGraphicsTextItem ( QString ( Data.p_name.c_str() ) );
731 0 : }
732 : //------------------------------------------------------------------------------------------
733 :
734 : //------------------------------------------------------------------------------------------
735 0 : dbe::GraphicalRelationship::~GraphicalRelationship()
736 : {
737 0 : delete TextItem;
738 0 : }
739 : //------------------------------------------------------------------------------------------
740 :
741 : //------------------------------------------------------------------------------------------
742 0 : QRectF dbe::GraphicalRelationship::boundingRect() const
743 : {
744 0 : return TextItem->boundingRect();
745 : }
746 : //------------------------------------------------------------------------------------------
747 :
748 : //------------------------------------------------------------------------------------------
749 0 : void dbe::GraphicalRelationship::paint ( QPainter * painter,
750 : const QStyleOptionGraphicsItem * option,
751 : QWidget * widget )
752 : {
753 0 : painter->setFont ( QFont ( "Helvetica", 10 ) );
754 0 : TextItem->paint ( painter, option, widget );
755 0 : }
756 : //------------------------------------------------------------------------------------------
757 :
758 : //------------------------------------------------------------------------------------------
759 0 : QPainterPath dbe::GraphicalRelationship::shape() const
760 : {
761 0 : QPainterPath path;
762 0 : path.addRect ( TextItem->boundingRect() );
763 0 : return path;
764 0 : }
765 : //------------------------------------------------------------------------------------------
766 :
767 : //------------------------------------------------------------------------------------------
768 0 : void dbe::GraphicalRelationship::mouseDoubleClickEvent ( QGraphicsSceneMouseEvent * event )
769 : {
770 0 : Q_UNUSED ( event )
771 0 : }
772 : //------------------------------------------------------------------------------------------
773 :
774 : //------------------------------------------------------------------------------------------
775 0 : void dbe::GraphicalRelationship::mousePressEvent ( QGraphicsSceneMouseEvent * event )
776 : {
777 0 : Q_UNUSED ( event )
778 0 : }
779 : //------------------------------------------------------------------------------------------
780 :
781 : //------------------------------------------------------------------------------------------
782 0 : void dbe::GraphicalRelationship::mouseMoveEvent ( QGraphicsSceneMouseEvent * event )
783 : {
784 0 : Q_UNUSED ( event )
785 0 : }
786 : //------------------------------------------------------------------------------------------
787 :
788 : //------------------------------------------------------------------------------------------
789 0 : void dbe::GraphicalRelationship::AddGraphicChildren()
790 : {
791 0 : double OffsetY = 0;
792 0 : double OffsetX = 10;
793 :
794 0 : treenode * NodeObject = confaccessor::gethandler()->getnode ( DatabaseClassName,
795 0 : DatabaseUidName );
796 :
797 0 : if ( NodeObject )
798 : {
799 0 : for ( treenode * ChildNode : NodeObject->GetChildren() )
800 : {
801 0 : if ( ChildNode->GetData ( 0 ).toString() == QString ( RelationshipData.p_name.c_str() ) )
802 : {
803 0 : for ( treenode * ChildChildNode : ChildNode->GetChildren() )
804 : {
805 0 : ObjectNode * ChildChildNodeObject = dynamic_cast<ObjectNode *> ( ChildChildNode );
806 :
807 0 : if ( ChildChildNodeObject )
808 : {
809 0 : std::string cname = ChildChildNodeObject->GetObject().class_name();
810 0 : GraphicalClass Dummy = confaccessor::guiconfig()->graphical ( cname );
811 0 : GraphicalObject * ObjectNodeGraphical = new GraphicalObject (
812 0 : true, ChildChildNode->GetData ( 0 ).toString(), Dummy );
813 0 : ObjectNodeGraphical->setParentItem ( this );
814 :
815 0 : QPointF coord = ObjectNodeGraphical->mapFromParent ( boundingRect().topRight() );
816 0 : ObjectNodeGraphical->setX ( coord.x() + OffsetX );
817 0 : ObjectNodeGraphical->setY ( coord.y() + OffsetY );
818 0 : OffsetY += ObjectNodeGraphical->boundingRect().height();
819 0 : }
820 0 : }
821 :
822 0 : break;
823 : }
824 0 : }
825 : }
826 0 : }
827 : //------------------------------------------------------------------------------------------
|