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#include "dbe/SchemaStyle.hpp"
19
20using namespace dunedaq::oks;
21
24 QGraphicsObject * parent )
25 : QGraphicsObject ( parent ),
26 m_scene(scene),
27 LineOffsetX ( 0 ),
28 LineOffsetY ( 0 )
29{
30 setAcceptHoverEvents(true);
31
32 setFlag ( ItemIsMovable );
33 setFlag ( ItemSendsGeometryChanges, true );
34 setFlag ( ItemSendsScenePositionChanges, true );
35
37 connect ( &KernelWrapper::GetInstance(), SIGNAL ( ClassUpdated ( QString ) ), this,
38 SLOT ( UpdateObject ( QString ) ) );
39 connect ( &KernelWrapper::GetInstance(), SIGNAL ( ClassRemoved ( QString ) ), this,
40 SLOT ( RemoveObject ( QString ) ) );
42 m_class_info = KernelWrapper::GetInstance().FindClass ( ClassName.toStdString() );
43 m_class_object_name = ClassName;
44
46 GetInfo();
47
48 set_font();
49}
50
54
55
56
57void dbse::SchemaGraphicObject::hoverEnterEvent ( QGraphicsSceneHoverEvent* he) {
58 // std::cout << "hover event at scenePos" << he->scenePos().x() << "," << he->scenePos().y()
59 // << ", pos=" << he->pos().x() << "," << he->pos().y() << "\n";
60
61 auto text = m_class_info->get_name();
62 auto desc = m_class_info->get_description();
63 if (!desc.empty()) {
64 text += "\n" + desc;
65 }
66 text += "\n-----------";
67
68 std::string attr_descriptions;
69 auto attributes = m_class_info->direct_attributes();
70 if (attributes != nullptr) {
71 for (auto attr: *attributes) {
72 if (!attr->get_description().empty()) {
73 attr_descriptions += "\n " + attr->get_name() + ": " +
74 attr->get_description();
75 }
76 }
77 }
78 std::string rel_descriptions;
79 auto relationships = m_class_info->direct_relationships();
80 if (relationships != nullptr) {
81 for (auto rel: *relationships) {
82 if (!rel->get_description().empty()) {
83 rel_descriptions += "\n " + rel->get_name() + ": " +
84 rel->get_description();
85 }
86 }
87 }
88 std::string method_descriptions;
89 auto methods = m_class_info->direct_methods();
90 if (methods != nullptr) {
91 for (auto method: *methods) {
92 if (!method->get_description().empty()) {
93 method_descriptions += "\n " + method->get_name() + ": " +
94 method->get_description();
95 }
96 }
97 }
98
99 std::string sep="\n-----";
100 if (!attr_descriptions.empty()) {
101 text += "\nAttributes:" + attr_descriptions;
102 if (!(rel_descriptions.empty() && method_descriptions.empty())) {
103 text += sep;
104 }
105 }
106 if (!rel_descriptions.empty()) {
107 text += "\nRelationships:" + rel_descriptions;
108 if (!method_descriptions.empty()) {
109 text += sep;
110 }
111 }
112 if (method_descriptions != "") {
113 text += "\nMethods:" + method_descriptions;
114 }
115 //std::cout << "text=<" << text << ">\n"; std::cout.flush();
116 QToolTip::showText( he->screenPos(),
117 QString::fromStdString(text),
118 nullptr, QRect(), 10000);
119 he->ignore();
120}
121void dbse::SchemaGraphicObject::hoverLeaveEvent ( QGraphicsSceneHoverEvent* he) {
122 // std::cout << "hover leave\n";
123 QToolTip::hideText();
124 he->ignore();
125}
126
127void dbse::SchemaGraphicObject::mouseDoubleClickEvent ( QGraphicsSceneMouseEvent* ) {
128 QString class_name = QString::fromStdString ( m_class_info->get_name() );
129 SchemaClassEditor::launch(class_name);
130}
131
133{
134 return m_class_info;
135}
136
138{
139 return m_class_object_name;
140}
141
143{
144 m_class_attributes.clear();
145 m_class_relationhips.clear();
146 m_class_methods.clear();
147
148 std::list<OksAttribute *> direct_attributes = {};
149 if (m_class_info->direct_attributes()) {
150 direct_attributes = *m_class_info->direct_attributes();
151 }
152 std::list<OksMethod *> direct_methods = {};
153 if (m_class_info->direct_methods()) direct_methods = *m_class_info->direct_methods();
154
155 std::list<OksRelationship *> direct_relationships = {};
156 if (m_class_info->direct_relationships()) direct_relationships = *m_class_info->direct_relationships();
157
158 std::list<OksAttribute *> all_attributes = {};
159 if (m_class_info->all_attributes()) all_attributes = *m_class_info->all_attributes();
160
161 std::list<OksMethod *> all_methods = {};
162 if (m_class_info->all_methods()) all_methods = *m_class_info->all_methods();
163
164 std::list<OksRelationship *> all_relationships = {};
165 if (m_class_info->all_relationships()) all_relationships = *m_class_info->all_relationships();
166
167 // Prepare indirect relationship list
168 std::list<OksAttribute *> indirect_attributes = all_attributes;
169 std::list<OksMethod *> indirect_methods = all_methods;
170 std::list<OksRelationship *> indirect_relationships = all_relationships;
171
172 for ( OksAttribute * attribute : direct_attributes ) {
173 indirect_attributes.remove(attribute);
174 }
175
176 for ( OksMethod * method : direct_methods ) {
177 indirect_methods.remove(method);
178 }
179
180 for ( OksRelationship * relationship : direct_relationships ) {
181 indirect_relationships.remove(relationship);
182 }
183
184 std::map<OksRelationship::CardinalityConstraint, std::string> m = {
188 };
189
191 for ( OksAttribute * attribute : direct_attributes )
192 {
193 QString AttributeString (
194 QString::fromStdString ( attribute->get_name() ) + " : "
195 + QString::fromStdString ( attribute->get_type() ) + (attribute->get_is_multi_values() ? "[]" : "") );
196 m_class_attributes.append ( AttributeString );
197
198 QString value;
199 if (!attribute->get_init_value().empty()) {
200 value = QString::fromStdString (" = " + attribute->get_init_value());
201 }
202 m_class_attribute_values.append (value);
203 }
204
206 for ( OksRelationship * relationship : direct_relationships )
207 {
208 QString relationship_string ( QString::fromStdString ( relationship->get_name() ) + " : "
209 + QString::fromStdString ( relationship->get_type() ) + " - "
210 + QString::fromStdString ( m[ relationship->get_low_cardinality_constraint() ] ) + ":"
211 + QString::fromStdString ( m[ relationship->get_high_cardinality_constraint() ] ) );
212 m_class_relationhips.append ( relationship_string );
213 }
214
216 for ( OksMethod * Method : direct_methods )
217 {
218 QString MethodString ( QString::fromStdString ( Method->get_name() ) + "()" );
219 m_class_methods.append ( MethodString );
220 }
221
223 for ( OksAttribute * attribute : indirect_attributes )
224 {
225 QString attribute_string (
226 QString::fromStdString ( attribute->get_name() ) + " : "
227 + QString::fromStdString ( attribute->get_type() ) );
228 m_class_inherited_attributes.append ( attribute_string );
229 }
230
232 for ( OksRelationship * relationship : indirect_relationships )
233 {
234 QString relationship_string ( QString::fromStdString ( relationship->get_name() ) + " : "
235 + QString::fromStdString ( relationship->get_type() ) + " - "
236 + QString::fromStdString ( m[ relationship->get_low_cardinality_constraint() ] ) + ":"
237 + QString::fromStdString ( m[ relationship->get_high_cardinality_constraint() ] ) );
238 m_class_inherited_relationhips.append ( relationship_string );
239 }
240
242 for ( OksMethod * method : indirect_methods )
243 {
244 QString method_string ( QString::fromStdString ( method->get_name() ) + "()" );
245 m_class_inherited_methods.append ( method_string );
246 }
247}
248
250{
251 double SpaceX = 3;
252 double TotalBoundingHeight = 0;
253 double TotalBoundingWidth = 0;
254
255 QFontMetrics FontMetrics ( m_font );
256
257 TotalBoundingHeight += SpaceX * 5;
258 TotalBoundingHeight += FontMetrics.boundingRect ( m_class_object_name ).height();
259 TotalBoundingWidth += FontMetrics.boundingRect ( m_class_object_name ).width();
260
261
262 for ( int entry=0; entry<m_class_attributes.size(); entry++)
263 {
264 QString attribute_name = m_class_attributes[entry];
265 if (m_scene->show_defaults()) {
266 attribute_name.append(m_class_attribute_values[entry]);
267 }
268 TotalBoundingHeight += FontMetrics.boundingRect ( attribute_name ).height();
269
270 if ( FontMetrics.boundingRect (attribute_name).width() > TotalBoundingWidth )
271 {
272 TotalBoundingWidth =
273 FontMetrics.boundingRect (attribute_name).width();
274 }
275 }
276
277 if (m_scene->inherited_properties_visible()) {
278 for ( auto & AttributeName : m_class_inherited_attributes )
279 {
280 TotalBoundingHeight += FontMetrics.boundingRect ( AttributeName ).height();
281
282 if ( FontMetrics.boundingRect ( AttributeName ).width() > TotalBoundingWidth )
283 TotalBoundingWidth =
284 FontMetrics.boundingRect ( AttributeName ).width();
285 }
286 }
287
288 for ( auto & relationship_name : m_class_relationhips )
289 {
290 TotalBoundingHeight += FontMetrics.boundingRect ( relationship_name ).height();
291
292 if ( FontMetrics.boundingRect ( relationship_name ).width() > TotalBoundingWidth )
293 TotalBoundingWidth =
294 FontMetrics.boundingRect ( relationship_name ).width();
295 }
296
297 if (m_scene->inherited_properties_visible()) {
298 for ( auto & relationship_name : m_class_inherited_relationhips )
299 {
300 TotalBoundingHeight += FontMetrics.boundingRect ( relationship_name ).height();
301
302 if ( FontMetrics.boundingRect ( relationship_name ).width() > TotalBoundingWidth )
303 TotalBoundingWidth =
304 FontMetrics.boundingRect ( relationship_name ).width();
305 }
306 }
307
308 for ( auto & MethodName : m_class_methods )
309 {
310 TotalBoundingHeight += FontMetrics.boundingRect ( MethodName ).height();
311
312 if ( FontMetrics.boundingRect ( MethodName ).width() > TotalBoundingWidth )
313 TotalBoundingWidth =
314 FontMetrics.boundingRect ( MethodName ).width();
315 }
316
317 if (m_scene->inherited_properties_visible()) {
318 for ( auto & MethodName : m_class_inherited_methods )
319 {
320 TotalBoundingHeight += FontMetrics.boundingRect ( MethodName ).height();
321
322 if ( FontMetrics.boundingRect ( MethodName ).width() > TotalBoundingWidth )
323 TotalBoundingWidth =
324 FontMetrics.boundingRect ( MethodName ).width();
325 }
326 }
327
328 TotalBoundingWidth += 15;
329 return QRectF ( 0, 0, TotalBoundingWidth, TotalBoundingHeight );
330}
331
333{
334 QPainterPath path;
335 path.addRect ( boundingRect() );
336 return path;
337}
338
339void dbse::SchemaGraphicObject::paint ( QPainter * painter,
340 const QStyleOptionGraphicsItem * option,
341 QWidget * widget )
342{
343 Q_UNUSED ( widget )
344 Q_UNUSED ( option )
345
346 double SpaceX = 3;
347 double SpaceY = 3;
348
349
350 QColor colour;
351 QColor background;
352 if (m_highlight_class) {
353 colour = SchemaStyle::get_color("foreground", "highlight");
354 background = SchemaStyle::get_color("background", "highlight");
355 }
356 else if (m_scene->highlight_active() &&
357 (m_class_info->get_file()->get_full_file_name()
359 colour = SchemaStyle::get_color("foreground", "active_file");
360 background = SchemaStyle::get_color("background", "active_file");
361 }
362 else {
363 colour = SchemaStyle::get_color("foreground", "default");
364 background = SchemaStyle::get_color("background", "default");
365 }
366
367 set_font();
368
369 const QPen bounding_box_pen = QPen(colour, 2.5);
370 const QPen inner_line_pen = QPen(colour, 1.5);
371
372 painter->setFont ( m_font );
373 painter->setPen ( bounding_box_pen );
374 painter->setBackground(background);
375 //painter->setBackgroundMode(Qt::OpaqueMode);
376 painter->drawRect ( boundingRect() );
377
378 const QFontMetrics FontMetrics = painter->fontMetrics();
379 const QRectF ClassNameBoundingRect = FontMetrics.boundingRect ( m_class_object_name );
380 const QRectF ObjectBoundingRect = boundingRect();
381
382 double HeightOffset = ClassNameBoundingRect.height() + SpaceY;
383 const auto ClassNamePosition = QPointF(
384 (ObjectBoundingRect.width() - ClassNameBoundingRect.width() ) / 2,
385 ClassNameBoundingRect.height());
386 painter->drawText ( ClassNamePosition, m_class_object_name );
387 painter->drawLine ( 0, HeightOffset, ObjectBoundingRect.width(), HeightOffset );
388
389 for ( int entry=0; entry<m_class_attributes.size(); entry++)
390 {
391 QString attribute_name = m_class_attributes[entry];
392 if (m_scene->show_defaults()) {
393 attribute_name.append(m_class_attribute_values[entry]);
394 }
395 const QRectF AttributeBoundingRect = FontMetrics.boundingRect (attribute_name);
396 HeightOffset += AttributeBoundingRect.height();
397 painter->drawText ( QPointF(SpaceX, HeightOffset), attribute_name );
398 }
399
400 if (m_scene->inherited_properties_visible()) {
401 painter->setPen ( SchemaStyle::get_color("foreground", "inherited") );
402 for ( QString & AttributeName : m_class_inherited_attributes )
403 {
404 const QRectF AttributeBoundingRect = FontMetrics.boundingRect ( AttributeName );
405 HeightOffset += AttributeBoundingRect.height();
406 painter->drawText ( QPointF(SpaceX, HeightOffset), AttributeName );
407 }
408 painter->setPen ( colour );
409 }
410
411 HeightOffset += SpaceY;
412 painter->setPen ( inner_line_pen );
413 painter->drawLine ( 0, HeightOffset, ObjectBoundingRect.width(), HeightOffset );
414
415 for (const QString & relationship_name : m_class_relationhips )
416 {
417 const QRectF relationship_bounding_rect = FontMetrics.boundingRect ( relationship_name );
418 HeightOffset += relationship_bounding_rect.height();
419 painter->drawText ( QPointF(SpaceX, HeightOffset), relationship_name );
420 }
421
422 if (m_scene->inherited_properties_visible()) {
423 painter->setPen ( SchemaStyle::get_color("foreground", "inherited") );
424 for ( const QString & relationship_name : m_class_inherited_relationhips )
425 {
426 const QRectF relationship_bounding_rect = FontMetrics.boundingRect ( relationship_name );
427 HeightOffset += relationship_bounding_rect.height();
428 painter->drawText ( QPointF(SpaceX, HeightOffset), relationship_name );
429 }
430 painter->setPen ( colour );
431 }
432
433
434 HeightOffset += SpaceY;
435 painter->setPen ( inner_line_pen );
436 painter->drawLine ( 0, HeightOffset, ObjectBoundingRect.width(), HeightOffset );
437
438 for ( const QString & MethodName : m_class_methods )
439 {
440 const QRectF AttributeBoundingRect = FontMetrics.boundingRect ( MethodName );
441 HeightOffset += AttributeBoundingRect.height();
442 painter->drawText ( QPointF(SpaceX, HeightOffset), MethodName );
443 }
444
445 if (m_scene->inherited_properties_visible()) {
446 painter->setPen ( SchemaStyle::get_color("foreground", "inherited") );
447 for ( const QString & MethodName : m_class_inherited_methods )
448 {
449 const QRectF AttributeBoundingRect = FontMetrics.boundingRect ( MethodName );
450 HeightOffset += AttributeBoundingRect.height();
451 painter->drawText (QPointF(SpaceX, HeightOffset), MethodName );
452 }
453 painter->setPen ( colour );
454 }
455}
456
458{
459 m_arrows.append ( Arrow );
460}
461
463{
464 const int index = m_arrows.indexOf ( Arrow );
465
466 if ( index != -1 )
467 {
468 m_arrows.removeAt ( index );
469 }
470}
471
473{
474 for ( SchemaGraphicSegmentedArrow * arrow : m_arrows )
475 {
476 arrow->GetStartItem()->RemoveArrow ( arrow );
477 arrow->GetEndItem()->RemoveArrow ( arrow );
478 scene()->removeItem ( arrow );
479 }
480}
481
483{
484 if ( m_arrows.isEmpty() )
485 {
486 return false;
487 }
488
489 for ( SchemaGraphicSegmentedArrow * Arrow : m_arrows )
490 {
491 SchemaGraphicObject * ArrowSource = Arrow->GetStartItem();
492 SchemaGraphicObject * ArrowDest = Arrow->GetEndItem();
493
494 if ( ( ArrowSource == this ) && ( ArrowDest == Dest ) )
495 {
496 return true;
497 }
498 }
499
500 return false;
501}
502
504{
505 for ( SchemaGraphicSegmentedArrow * arrow : m_arrows )
506 {
507 arrow->UpdatePosition();
508 }
509}
510
512{
513 if (m_highlight_class) {
514 m_font = SchemaStyle::get_font("highlight");
515 }
516 else {
517 m_font = SchemaStyle::get_font("default");
518 }
519 if (m_class_info->get_is_abstract() && m_scene->highlight_abstract()) {
520 // Use selected font but with style from abstract class font
521 m_font.setStyle(SchemaStyle::get_font("abstract").style());
522 }
523}
525{
526 m_highlight_class = !m_highlight_class;
527 set_font();
528 update_arrows();
529}
530
531
532QVariant dbse::SchemaGraphicObject::itemChange ( GraphicsItemChange change,
533 const QVariant & value )
534{
535 if ( change == ItemPositionChange )
536 for ( SchemaGraphicSegmentedArrow * arrow : m_arrows )
537 {
538 arrow->UpdatePosition();
539 }
540
541 return value;
542}
543
545{
546 if ( Name != m_class_object_name )
547 {
548 return;
549 }
550
552 GetInfo();
554 SchemaGraphicsScene * Scene = dynamic_cast<SchemaGraphicsScene *> ( scene() );
555
556 if ( Scene )
557 {
558 QStringList ClassesList;
559 ClassesList.append ( Name );
560
561 QList<QPointF> ClassesPositions;
562 QPointF ClassPosition ( this->scenePos() );
563 ClassesPositions.append ( ClassPosition );
564
565 Scene->RemoveClassObject ( this );
566 Scene->AddItemsToScene ( QStringList ( m_class_object_name ), ClassesPositions );
567 }
568
570 update();
571}
572
574{
575 if ( Name != m_class_object_name )
576 {
577 return;
578 }
579
581 SchemaGraphicsScene * Scene = dynamic_cast<SchemaGraphicsScene *> ( scene() );
582
583 if ( Scene )
584 {
585 Scene->RemoveClassObject ( this );
586 }
587}
std::string GetActiveSchema() const
static KernelWrapper & GetInstance()
dunedaq::oks::OksClass * FindClass(std::string ClassName) const
static void launch(QString class_name)
void AddArrow(SchemaGraphicSegmentedArrow *Arrow)
Arrow API.
QPainterPath shape() const override
void hoverLeaveEvent(QGraphicsSceneHoverEvent *ev)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
void RemoveArrow(SchemaGraphicSegmentedArrow *Arrow)
SchemaGraphicObject(QString &ClassName, SchemaGraphicsScene *scene, QGraphicsObject *parent=nullptr)
void hoverEnterEvent(QGraphicsSceneHoverEvent *ev)
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
void toggle_highlight_class()
Graphic API.
dunedaq::oks::OksClass * GetClass() const
QRectF boundingRect() const override
dunedaq::oks::OksClass * m_class_info
bool HasArrow(SchemaGraphicObject *Dest) const
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
static QColor get_color(const QString &item, const QString &group)
static QFont get_font(const QString &group)