DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
SchemaGraphicObject.cpp
Go to the documentation of this file.
1
2#include <QApplication>
3#include <QCursor>
4#include <QEvent>
5#include <QGraphicsScene>
6#include <QGraphicsSceneHoverEvent>
7#include <QGraphicsView>
8#include <QPainter>
9#include <QToolTip>
11#include"oks/method.hpp"
18
19using namespace dunedaq::oks;
20
22 QGraphicsObject * parent )
23 : QGraphicsObject ( parent ),
24 m_inherited_properties_visible(true),
25 LineOffsetX ( 0 ),
26 LineOffsetY ( 0 )
27{
28 setAcceptHoverEvents(true);
29 m_font = QFont( "Helvetica [Cronyx]", 9);
30 m_bold_font = QFont( "Helvetica [Cronyx]", 9, QFont::DemiBold);
31 m_default_color = QColor ( 0x1e1b18 );
32 m_highlight_color = QColor ( 0x14aaff );
33 m_opaque_color = QColor ( 0x5d5b59 );
34
35 setFlag ( ItemIsMovable );
36 setFlag ( ItemSendsGeometryChanges, true );
37 setFlag ( ItemSendsScenePositionChanges, true );
38
40 connect ( &KernelWrapper::GetInstance(), SIGNAL ( ClassUpdated ( QString ) ), this,
41 SLOT ( UpdateObject ( QString ) ) );
42 connect ( &KernelWrapper::GetInstance(), SIGNAL ( ClassRemoved ( QString ) ), this,
43 SLOT ( RemoveObject ( QString ) ) );
45 m_class_info = KernelWrapper::GetInstance().FindClass ( ClassName.toStdString() );
46 m_class_object_name = ClassName;
47
49 GetInfo();
50}
51
55
56
57
58void dbse::SchemaGraphicObject::hoverEnterEvent ( QGraphicsSceneHoverEvent* he) {
59 // std::cout << "hover event at scenePos" << he->scenePos().x() << "," << he->scenePos().y()
60 // << ", pos=" << he->pos().x() << "," << he->pos().y() << "\n";
61
62 auto text = m_class_info->get_name();
63 auto desc = m_class_info->get_description();
64 if (!desc.empty()) {
65 text += "\n" + desc;
66 }
67 text += "\n-----------";
68
69 std::string attr_descriptions;
70 auto attributes = m_class_info->direct_attributes();
71 if (attributes != nullptr) {
72 for (auto attr: *attributes) {
73 if (!attr->get_description().empty()) {
74 attr_descriptions += "\n " + attr->get_name() + ": " +
75 attr->get_description();
76 }
77 }
78 }
79 std::string rel_descriptions;
80 auto relationships = m_class_info->direct_relationships();
81 if (relationships != nullptr) {
82 for (auto rel: *relationships) {
83 if (!rel->get_description().empty()) {
84 rel_descriptions += "\n " + rel->get_name() + ": " +
85 rel->get_description();
86 }
87 }
88 }
89 std::string method_descriptions;
90 auto methods = m_class_info->direct_methods();
91 if (methods != nullptr) {
92 for (auto method: *methods) {
93 if (!method->get_description().empty()) {
94 method_descriptions += "\n " + method->get_name() + ": " +
95 method->get_description();
96 }
97 }
98 }
99
100 std::string sep="\n-----";
101 if (!attr_descriptions.empty()) {
102 text += "\nAttributes:" + attr_descriptions;
103 if (!(rel_descriptions.empty() && method_descriptions.empty())) {
104 text += sep;
105 }
106 }
107 if (!rel_descriptions.empty()) {
108 text += "\nRelationships:" + rel_descriptions;
109 if (!method_descriptions.empty()) {
110 text += sep;
111 }
112 }
113 if (method_descriptions != "") {
114 text += "\nMethods:" + method_descriptions;
115 }
116 //std::cout << "text=<" << text << ">\n"; std::cout.flush();
117 QToolTip::showText( he->screenPos(),
118 QString::fromStdString(text),
119 nullptr, QRect(), 10000);
120 he->ignore();
121}
122void dbse::SchemaGraphicObject::hoverLeaveEvent ( QGraphicsSceneHoverEvent* he) {
123 // std::cout << "hover leave\n";
124 QToolTip::hideText();
125 he->ignore();
126}
127
128void dbse::SchemaGraphicObject::mouseDoubleClickEvent ( QGraphicsSceneMouseEvent* ) {
129 // std::cout << "Open class editor\n";
130 bool WidgetFound = false;
131 QString ClassName = QString::fromStdString ( m_class_info->get_name() );
132
133 for ( QWidget * Editor : QApplication::allWidgets() )
134 {
135 SchemaClassEditor * Widget = dynamic_cast<SchemaClassEditor *> ( Editor );
136
137 if ( Widget != nullptr )
138 {
139 if ( ( Widget->objectName() ).compare ( ClassName ) == 0 )
140 {
141 Widget->raise();
142 Widget->setVisible ( true );
143 Widget->activateWindow();
144 WidgetFound = true;
145 }
146 }
147 }
148
149 if ( !WidgetFound )
150 {
151 SchemaClassEditor * Editor = new SchemaClassEditor ( m_class_info );
152 Editor->show();
153 }
154
155}
156
157
159{
160 return m_class_info;
161}
162
164{
165 return m_class_object_name;
166}
167
169{
170 m_class_attributes.clear();
171 m_class_relationhips.clear();
172 m_class_methods.clear();
173
174 std::list<OksAttribute *> direct_attributes = {};
175 if (m_class_info->direct_attributes()) {
176 direct_attributes = *m_class_info->direct_attributes();
177 }
178 std::list<OksMethod *> direct_methods = {};
179 if (m_class_info->direct_methods()) direct_methods = *m_class_info->direct_methods();
180
181 std::list<OksRelationship *> direct_relationships = {};
182 if (m_class_info->direct_relationships()) direct_relationships = *m_class_info->direct_relationships();
183
184 std::list<OksAttribute *> all_attributes = {};
185 if (m_class_info->all_attributes()) all_attributes = *m_class_info->all_attributes();
186
187 std::list<OksMethod *> all_methods = {};
188 if (m_class_info->all_methods()) all_methods = *m_class_info->all_methods();
189
190 std::list<OksRelationship *> all_relationships = {};
191 if (m_class_info->all_relationships()) all_relationships = *m_class_info->all_relationships();
192
193 // Prepare indirect relationship list
194 std::list<OksAttribute *> indirect_attributes = all_attributes;
195 std::list<OksMethod *> indirect_methods = all_methods;
196 std::list<OksRelationship *> indirect_relationships = all_relationships;
197
198 for ( OksAttribute * attribute : direct_attributes ) {
199 indirect_attributes.remove(attribute);
200 }
201
202 for ( OksMethod * method : direct_methods ) {
203 indirect_methods.remove(method);
204 }
205
206 for ( OksRelationship * relationship : direct_relationships ) {
207 indirect_relationships.remove(relationship);
208 }
209
210 std::map<OksRelationship::CardinalityConstraint, std::string> m = {
214 };
215
217 for ( OksAttribute * attribute : direct_attributes )
218 {
219 QString AttributeString (
220 QString::fromStdString ( attribute->get_name() ) + " : "
221 + QString::fromStdString ( attribute->get_type() ) + (attribute->get_is_multi_values() ? "[]" : "") );
222 m_class_attributes.append ( AttributeString );
223 }
224
226 for ( OksRelationship * relationship : direct_relationships )
227 {
228 QString relationship_string ( QString::fromStdString ( relationship->get_name() ) + " : "
229 + QString::fromStdString ( relationship->get_type() ) + " - "
230 + QString::fromStdString ( m[ relationship->get_low_cardinality_constraint() ] ) + ":"
231 + QString::fromStdString ( m[ relationship->get_high_cardinality_constraint() ] ) );
232 m_class_relationhips.append ( relationship_string );
233 }
234
236 for ( OksMethod * Method : direct_methods )
237 {
238 QString MethodString ( QString::fromStdString ( Method->get_name() ) + "()" );
239 m_class_methods.append ( MethodString );
240 }
241
242 if (m_inherited_properties_visible) {
244 for ( OksAttribute * attribute : indirect_attributes )
245 {
246 QString attribute_string (
247 QString::fromStdString ( attribute->get_name() ) + " : "
248 + QString::fromStdString ( attribute->get_type() ) );
249 m_class_inherited_attributes.append ( attribute_string );
250 }
251
253 for ( OksRelationship * relationship : indirect_relationships )
254 {
255 QString relationship_string ( QString::fromStdString ( relationship->get_name() ) + " : "
256 + QString::fromStdString ( relationship->get_type() ) + " - "
257 + QString::fromStdString ( m[ relationship->get_low_cardinality_constraint() ] ) + ":"
258 + QString::fromStdString ( m[ relationship->get_high_cardinality_constraint() ] ) );
259 m_class_inherited_relationhips.append ( relationship_string );
260 }
261
263 for ( OksMethod * method : indirect_methods )
264 {
265 QString method_string ( QString::fromStdString ( method->get_name() ) + "()" );
266 m_class_inherited_methods.append ( method_string );
267 }
268
269 }
270
271}
272
274{
275 double SpaceX = 3;
276 double TotalBoundingHeight = 0;
277 double TotalBoundingWidth = 0;
278
279 QFontMetrics FontMetrics ( m_font );
280
281 TotalBoundingHeight += SpaceX * 5;
282 TotalBoundingHeight += FontMetrics.boundingRect ( m_class_object_name ).height();
283 TotalBoundingWidth += FontMetrics.boundingRect ( m_class_object_name ).width();
284
285 for ( auto & AttributeName : m_class_attributes )
286 {
287 TotalBoundingHeight += FontMetrics.boundingRect ( AttributeName ).height();
288
289 if ( FontMetrics.boundingRect ( AttributeName ).width() > TotalBoundingWidth )
290 TotalBoundingWidth =
291 FontMetrics.boundingRect ( AttributeName ).width();
292 }
293
294 if (m_inherited_properties_visible) {
295 for ( auto & AttributeName : m_class_inherited_attributes )
296 {
297 TotalBoundingHeight += FontMetrics.boundingRect ( AttributeName ).height();
298
299 if ( FontMetrics.boundingRect ( AttributeName ).width() > TotalBoundingWidth )
300 TotalBoundingWidth =
301 FontMetrics.boundingRect ( AttributeName ).width();
302 }
303 }
304
305 for ( auto & relationship_name : m_class_relationhips )
306 {
307 TotalBoundingHeight += FontMetrics.boundingRect ( relationship_name ).height();
308
309 if ( FontMetrics.boundingRect ( relationship_name ).width() > TotalBoundingWidth )
310 TotalBoundingWidth =
311 FontMetrics.boundingRect ( relationship_name ).width();
312 }
313
314 if (m_inherited_properties_visible) {
315 for ( auto & relationship_name : m_class_inherited_relationhips )
316 {
317 TotalBoundingHeight += FontMetrics.boundingRect ( relationship_name ).height();
318
319 if ( FontMetrics.boundingRect ( relationship_name ).width() > TotalBoundingWidth )
320 TotalBoundingWidth =
321 FontMetrics.boundingRect ( relationship_name ).width();
322 }
323 }
324
325 for ( auto & MethodName : m_class_methods )
326 {
327 TotalBoundingHeight += FontMetrics.boundingRect ( MethodName ).height();
328
329 if ( FontMetrics.boundingRect ( MethodName ).width() > TotalBoundingWidth )
330 TotalBoundingWidth =
331 FontMetrics.boundingRect ( MethodName ).width();
332 }
333
334 if (m_inherited_properties_visible) {
335 for ( auto & MethodName : m_class_inherited_methods )
336 {
337 TotalBoundingHeight += FontMetrics.boundingRect ( MethodName ).height();
338
339 if ( FontMetrics.boundingRect ( MethodName ).width() > TotalBoundingWidth )
340 TotalBoundingWidth =
341 FontMetrics.boundingRect ( MethodName ).width();
342 }
343 }
344
345 TotalBoundingWidth += 15;
346 return QRectF ( 0, 0, TotalBoundingWidth, TotalBoundingHeight );
347}
348
350{
351 QPainterPath path;
352 path.addRect ( boundingRect() );
353 return path;
354}
355
356void dbse::SchemaGraphicObject::paint ( QPainter * painter,
357 const QStyleOptionGraphicsItem * option,
358 QWidget * widget )
359{
360 Q_UNUSED ( widget )
361 Q_UNUSED ( option )
362
363 double SpaceX = 3;
364 double SpaceY = 3;
365
366 QColor colour;
367 if (m_highlight_active && (m_class_info->get_file()->get_full_file_name()
369 colour = m_highlight_color;
370 }
371 else {
372 colour = m_default_color;
373 }
374
375 const QPen bounding_box_pen = QPen(colour, 2.5);
376 const QPen inner_line_pen = QPen(colour, 1.5);
377
378 painter->setFont ( m_font );
379 painter->setPen ( bounding_box_pen );
380 painter->drawRect ( boundingRect() );
381 // painter->setPen ( m_default_color );
382
383 QFontMetrics FontMetrics = painter->fontMetrics();
384 QRectF ClassNameBoundingRect = FontMetrics.boundingRect ( m_class_object_name );
385 QRectF ObjectBoundingRect = boundingRect();
386
387 double HeightOffset = ClassNameBoundingRect.height() + SpaceY;
388 int ClassNamePosition = ( ObjectBoundingRect.width() - ClassNameBoundingRect.width() ) / 2;
389 painter->setFont ( m_font );
390 painter->drawText ( ClassNamePosition, ClassNameBoundingRect.height(), m_class_object_name );
391 painter->setFont ( m_font );
392 painter->drawLine ( 0, HeightOffset, ObjectBoundingRect.width(), HeightOffset );
393
394 for ( QString & AttributeName : m_class_attributes )
395 {
396 QRectF AttributeBoundingRect = FontMetrics.boundingRect ( AttributeName );
397 HeightOffset += AttributeBoundingRect.height();
398 painter->drawText ( SpaceX, HeightOffset, AttributeName );
399 }
400
401 if (m_inherited_properties_visible) {
402 painter->setPen ( m_opaque_color );
403 for ( QString & AttributeName : m_class_inherited_attributes )
404 {
405 QRectF AttributeBoundingRect = FontMetrics.boundingRect ( AttributeName );
406 HeightOffset += AttributeBoundingRect.height();
407 painter->drawText ( SpaceX, HeightOffset, AttributeName );
408 }
409 painter->setPen ( colour );
410 }
411
412 HeightOffset += SpaceY;
413 painter->setPen ( inner_line_pen );
414 painter->drawLine ( 0, HeightOffset, ObjectBoundingRect.width(), HeightOffset );
415
416 for ( QString & relationship_name : m_class_relationhips )
417 {
418 QRectF relationship_bounding_rect = FontMetrics.boundingRect ( relationship_name );
419 HeightOffset += relationship_bounding_rect.height();
420 painter->drawText ( SpaceX, HeightOffset, relationship_name );
421 }
422
423 if (m_inherited_properties_visible) {
424 painter->setPen ( m_opaque_color );
425 for ( QString & relationship_name : m_class_inherited_relationhips )
426 {
427 QRectF relationship_bounding_rect = FontMetrics.boundingRect ( relationship_name );
428 HeightOffset += relationship_bounding_rect.height();
429 painter->drawText ( SpaceX, HeightOffset, relationship_name );
430 }
431 painter->setPen ( colour );
432 }
433
434
435 HeightOffset += SpaceY;
436 painter->setPen ( inner_line_pen );
437 painter->drawLine ( 0, HeightOffset, ObjectBoundingRect.width(), HeightOffset );
438
439 for ( QString & MethodName : m_class_methods )
440 {
441 QRectF AttributeBoundingRect = FontMetrics.boundingRect ( MethodName );
442 HeightOffset += AttributeBoundingRect.height();
443 painter->drawText ( SpaceX, HeightOffset, MethodName );
444 }
445
446 if (m_inherited_properties_visible) {
447 painter->setPen ( m_opaque_color );
448 for ( QString & MethodName : m_class_inherited_methods )
449 {
450 QRectF AttributeBoundingRect = FontMetrics.boundingRect ( MethodName );
451 HeightOffset += AttributeBoundingRect.height();
452 painter->drawText ( SpaceX, HeightOffset, MethodName );
453 }
454 painter->setPen ( colour );
455 }
456}
457
459{
460 m_arrows.append ( Arrow );
461}
462
464{
465 int index = m_arrows.indexOf ( Arrow );
466
467 if ( index != -1 )
468 {
469 m_arrows.removeAt ( index );
470 }
471}
472
474{
475 foreach ( SchemaGraphicSegmentedArrow * arrow, m_arrows )
476 {
477 arrow->GetStartItem()->RemoveArrow ( arrow );
478 arrow->GetEndItem()->RemoveArrow ( arrow );
479 scene()->removeItem ( arrow );
480 }
481}
482
484{
485 if ( m_arrows.isEmpty() )
486 {
487 return false;
488 }
489
490 for ( SchemaGraphicSegmentedArrow * Arrow : m_arrows )
491 {
492 SchemaGraphicObject * ArrowSource = Arrow->GetStartItem();
493 SchemaGraphicObject * ArrowDest = Arrow->GetEndItem();
494
495 if ( ( ArrowSource == this ) && ( ArrowDest == Dest ) )
496 {
497 return true;
498 }
499 }
500
501 return false;
502}
503
505
506 m_inherited_properties_visible = visible;
507 for ( SchemaGraphicSegmentedArrow * arrow : m_arrows )
508 {
509 arrow->UpdatePosition();
510 }
511}
512
514{
515 m_highlight_active = highlight;
516}
517
518
519QVariant dbse::SchemaGraphicObject::itemChange ( GraphicsItemChange change,
520 const QVariant & value )
521{
522 if ( change == ItemPositionChange )
523 for ( SchemaGraphicSegmentedArrow * arrow : m_arrows )
524 {
525 arrow->UpdatePosition();
526 }
527
528 return value;
529}
530
532{
533 if ( Name != m_class_object_name )
534 {
535 return;
536 }
537
539 GetInfo();
541 SchemaGraphicsScene * Scene = dynamic_cast<SchemaGraphicsScene *> ( scene() );
542
543 if ( Scene )
544 {
545 QStringList ClassesList;
546 ClassesList.append ( Name );
547
548 QList<QPointF> ClassesPositions;
549 QPointF ClassPosition ( this->scenePos() );
550 ClassesPositions.append ( ClassPosition );
551
552 Scene->RemoveClassObject ( this );
553 Scene->AddItemsToScene ( QStringList ( m_class_object_name ), ClassesPositions );
554 }
555
557 update();
558}
559
561{
562 if ( Name != m_class_object_name )
563 {
564 return;
565 }
566
568 SchemaGraphicsScene * Scene = dynamic_cast<SchemaGraphicsScene *> ( scene() );
569
570 if ( Scene )
571 {
572 Scene->RemoveClassObject ( this );
573 }
574}
std::string GetActiveSchema() const
static KernelWrapper & GetInstance()
dunedaq::oks::OksClass * FindClass(std::string ClassName) const
void AddArrow(SchemaGraphicSegmentedArrow *Arrow)
Arrow API.
void set_highlight_active(bool highlight)
QPainterPath shape() const override
void hoverLeaveEvent(QGraphicsSceneHoverEvent *ev)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
void RemoveArrow(SchemaGraphicSegmentedArrow *Arrow)
void hoverEnterEvent(QGraphicsSceneHoverEvent *ev)
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
SchemaGraphicObject(QString &ClassName, QGraphicsObject *parent=nullptr)
dunedaq::oks::OksClass * GetClass() const
QRectF boundingRect() const override
dunedaq::oks::OksClass * m_class_info
bool HasArrow(SchemaGraphicObject *Dest) const
void set_inherited_properties_visibility(bool visible)
Graphic API.
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *ev)
QStringList AddItemsToScene(QStringList SchemaClasses, QList< QPointF > Positions)
void RemoveClassObject(SchemaGraphicObject *Object)
OKS attribute class.
The OKS class.
Definition class.hpp:200
const std::list< OksMethod * > * direct_methods() const noexcept
Definition class.hpp:702
OKS method class.
Definition method.hpp:153