Line data Source code
1 : /// Including QT Headers
2 : #include <QGraphicsSceneDragDropEvent>
3 : #include <QEvent>
4 : #include <QSettings>
5 : #include <QMimeData>
6 :
7 : #include <QWidget>
8 :
9 : #include <QMenu>
10 : #include <QApplication>
11 : /// Including Schema Editor
12 : #include "dbe/SchemaGraphicsScene.hpp"
13 : #include "dbe/SchemaGraphicNote.hpp"
14 : #include "dbe/SchemaGraphicObject.hpp"
15 : #include "dbe/SchemaGraphicSegmentedArrow.hpp"
16 : #include "dbe/SchemaKernelWrapper.hpp"
17 : #include "dbe/SchemaNoteEditor.hpp"
18 : #include "dbe/SchemaClassEditor.hpp"
19 : #include "dbe/SchemaRelationshipEditor.hpp"
20 :
21 : using namespace dunedaq::oks;
22 :
23 0 : dbse::SchemaGraphicsScene::SchemaGraphicsScene ( QObject * parent )
24 : : QGraphicsScene ( parent ),
25 0 : m_line ( nullptr ),
26 0 : m_context_menu ( nullptr ),
27 0 : CurrentObject ( nullptr ),
28 0 : m_current_arrow ( nullptr ),
29 0 : m_modified(false)
30 : {
31 0 : setSceneRect ( QRectF ( 0, 0, 10000, 10000 ) );
32 :
33 0 : QSettings settings;
34 0 : settings.beginGroup("view defaults");
35 :
36 0 : m_inherited_properties_visible = settings.value("show_inherited", false).toBool();
37 0 : m_highlight_abstract = settings.value("highlight_abstract", false).toBool();
38 0 : m_highlight_active = settings.value("highlight_active", false).toBool();
39 0 : m_show_defaults = settings.value("show_default", false).toBool();
40 :
41 0 : CreateActions();
42 0 : }
43 :
44 0 : dbse::SchemaGraphicsScene::~SchemaGraphicsScene()
45 : {
46 0 : }
47 :
48 0 : void dbse::SchemaGraphicsScene::CreateActions()
49 : {
50 : // Add new class
51 0 : m_add_class = new QAction ( "&Add new class", this );
52 0 : connect ( m_add_class, SIGNAL ( triggered() ), this, SLOT ( new_class_slot() ) );
53 :
54 : // Edit current class
55 0 : m_edit_class = new QAction ( "&Edit class", this );
56 0 : connect ( m_edit_class, SIGNAL ( triggered() ), this, SLOT ( EditClassSlot() ) );
57 :
58 : // Toggle inherited properties of all classes in view
59 0 : m_toggle_indirect_infos = new QAction ( "Show &inherited properties", this );
60 0 : m_toggle_indirect_infos->setCheckable(true);
61 0 : m_toggle_indirect_infos->setChecked(m_inherited_properties_visible);
62 0 : connect ( m_toggle_indirect_infos, SIGNAL ( triggered() ), this, SLOT ( ToggleIndirectInfos() ) );
63 :
64 : // Toggle highlighting of all classes in active schema
65 0 : m_toggle_highlight_active = new QAction ( "&Highlight classes in active schema", this );
66 0 : m_toggle_highlight_active->setCheckable(true);
67 0 : m_toggle_highlight_active->setChecked(m_highlight_active);
68 0 : connect ( m_toggle_highlight_active, SIGNAL ( triggered() ), this, SLOT ( ToggleHighlightActive() ) );
69 :
70 : // Toggle highlighting of all abstract classes in view
71 0 : m_toggle_highlight_abstract = new QAction ( "&Highlight abstract classes in view", this );
72 0 : m_toggle_highlight_abstract->setCheckable(true);
73 0 : m_toggle_highlight_abstract->setChecked(m_highlight_abstract);
74 0 : connect ( m_toggle_highlight_abstract, SIGNAL ( triggered() ), this, SLOT ( ToggleHighlightAbstract() ) );
75 :
76 : // Toggle displaying default values of attributes
77 0 : m_toggle_default = new QAction ( "Show &default values of attributes", this );
78 0 : m_toggle_default->setCheckable(true);
79 0 : m_toggle_default->setChecked(m_show_defaults);
80 0 : connect ( m_toggle_default, SIGNAL ( triggered() ), this, SLOT ( ToggleDefault() ) );
81 :
82 : // Toggle highlighting of current class
83 0 : m_toggle_highlight_class = new QAction ( "&Highlight this class", this );
84 0 : m_toggle_highlight_class->setCheckable(true);
85 0 : connect ( m_toggle_highlight_class, SIGNAL ( triggered() ), this, SLOT ( ToggleHighlightClass() ) );
86 :
87 0 : m_add_note = new QAction ( "&Add note to view", this );
88 0 : connect ( m_add_note, SIGNAL ( triggered() ), this, SLOT ( new_note_slot() ) );
89 :
90 0 : m_edit_note = new QAction ( "&Edit note", this );
91 0 : connect ( m_edit_note, SIGNAL ( triggered() ), this, SLOT ( edit_note_slot() ) );
92 :
93 0 : m_remove_note = new QAction ( "&Remove note", this );
94 0 : connect ( m_remove_note, SIGNAL ( triggered() ), this, SLOT ( remove_note_slot() ) );
95 :
96 : // Show superclasses of the current class
97 0 : m_add_direct_super_classes = new QAction ( "Add direct &superclasses to view", this );
98 0 : connect ( m_add_direct_super_classes, SIGNAL ( triggered() ), this, SLOT ( AddDirectSuperClassesSlot() ) );
99 :
100 : // Show relationship classes of the current clas
101 0 : m_add_direct_relationship_classes = new QAction ( "Add direct &relationship classes to view", this );
102 0 : connect ( m_add_direct_relationship_classes, SIGNAL ( triggered() ), this, SLOT ( AddDirectRelationshipClassesSlot() ) );
103 :
104 : // Show superclasses of the current class
105 0 : m_add_all_super_classes = new QAction ( "Add all &superclasses to view", this );
106 0 : connect ( m_add_all_super_classes, SIGNAL ( triggered() ), this, SLOT ( AddAllSuperClassesSlot() ) );
107 :
108 : // Show subclasses of the current clas
109 0 : m_add_all_sub_classes = new QAction ( "Add all s&ubclasses to view", this );
110 0 : connect ( m_add_all_sub_classes, SIGNAL ( triggered() ), this, SLOT ( AddAllSubClassesSlot() ) );
111 :
112 : // Show indirect relationship classes of the current class
113 0 : m_add_all_relationship_classes = new QAction ( "Add all &relationship classes to view", this );
114 0 : connect ( m_add_all_relationship_classes, SIGNAL ( triggered() ), this, SLOT ( AddAllRelationshipClassesSlot() ) );
115 :
116 : // Remove class
117 0 : m_remove_class = new QAction ( "&Remove Class from view", this );
118 0 : connect ( m_remove_class, SIGNAL ( triggered() ), this, SLOT ( RemoveClassSlot() ) );
119 :
120 : // Remove arrow
121 0 : m_remove_arrow = new QAction ( "&Remove Arrow", this );
122 0 : connect ( m_remove_arrow, SIGNAL ( triggered() ), this, SLOT ( RemoveArrowSlot() ) );
123 :
124 0 : m_save = new QAction("&Save view", this);
125 0 : connect(m_save, SIGNAL(triggered()), this, SLOT(requestSave()));
126 :
127 0 : m_move = new QAction("&Move scene", this);
128 0 : connect(m_move, SIGNAL(triggered()), this, SLOT(moveScene()));
129 0 : }
130 :
131 0 : void dbse::SchemaGraphicsScene::dragEnterEvent ( QGraphicsSceneDragDropEvent * event )
132 : {
133 0 : if ( event->mimeData()->hasFormat ( "application/vnd.text.list" ) )
134 : {
135 0 : event->accept();
136 : }
137 0 : }
138 :
139 0 : void dbse::SchemaGraphicsScene::dragMoveEvent ( QGraphicsSceneDragDropEvent * event )
140 : {
141 0 : if ( event->mimeData()->hasFormat ( "application/vnd.text.list" ) )
142 : {
143 0 : event->accept();
144 : }
145 0 : }
146 :
147 0 : void dbse::SchemaGraphicsScene::dropEvent ( QGraphicsSceneDragDropEvent * event )
148 : {
149 0 : QByteArray encodedData = event->mimeData()->data ( "application/vnd.text.list" );
150 0 : QDataStream stream ( &encodedData, QIODevice::ReadOnly );
151 :
152 0 : if (stream.atEnd()) {
153 0 : return;
154 : }
155 :
156 0 : QStringList schema_classes;
157 0 : while ( !stream.atEnd() )
158 : {
159 0 : QString class_name;
160 0 : stream >> class_name;
161 0 : schema_classes.append ( class_name );
162 0 : }
163 :
164 0 : QList<QPointF> positions;
165 0 : for ( int i = 0; i < schema_classes.size(); ++i )
166 : {
167 0 : positions.push_back ( event->scenePos() );
168 : }
169 :
170 0 : AddItemsToScene ( schema_classes, positions );
171 0 : }
172 :
173 0 : void dbse::SchemaGraphicsScene::contextMenuEvent ( QGraphicsSceneContextMenuEvent * event )
174 : {
175 0 : if ( m_context_menu == nullptr ) {
176 0 : m_context_menu = new QMenu();
177 0 : m_context_menu->addAction ( m_add_class );
178 0 : m_context_menu->addAction ( m_add_note );
179 0 : m_context_menu->addAction ( m_toggle_indirect_infos );
180 0 : m_context_menu->addAction ( m_toggle_highlight_abstract );
181 0 : m_context_menu->addAction ( m_toggle_highlight_active );
182 0 : m_context_menu->addAction ( m_toggle_default );
183 :
184 0 : m_seperator_pos = m_context_menu->actions().size();
185 0 : m_context_menu->addSeparator();
186 :
187 0 : m_class_pos = m_context_menu->actions().size();
188 0 : m_context_menu->addAction ( m_edit_class );
189 0 : m_context_menu->addAction ( m_remove_class );
190 0 : m_context_menu->addAction ( m_toggle_highlight_class );
191 0 : m_context_menu->addSeparator();
192 :
193 0 : m_context_menu->addAction ( m_add_direct_super_classes );
194 0 : m_context_menu->addAction ( m_add_direct_relationship_classes );
195 0 : m_context_menu->addAction ( m_add_all_super_classes );
196 0 : m_context_menu->addAction ( m_add_all_sub_classes );
197 0 : m_context_menu->addAction ( m_add_all_sub_classes );
198 0 : m_context_menu->addAction ( m_add_all_relationship_classes );
199 :
200 0 : m_arrow_pos = m_context_menu->actions().size();
201 0 : m_context_menu->addAction ( m_remove_arrow );
202 :
203 0 : m_note_pos = m_context_menu->actions().size();
204 0 : m_context_menu->addAction ( m_edit_note );
205 0 : m_context_menu->addAction ( m_remove_note );
206 :
207 0 : m_context_menu->addSeparator();
208 0 : m_save_pos = m_context_menu->actions().size();
209 0 : m_context_menu->addAction(m_save);
210 0 : m_context_menu->addAction(m_move);
211 : }
212 :
213 0 : bool active = KernelWrapper::GetInstance().IsActive ( );
214 0 : m_context_menu->actions().at ( 0 )->setVisible ( active );
215 :
216 0 : for (int item=1; item<m_seperator_pos; item++) {
217 0 : m_context_menu->actions().at ( item )->setVisible ( true );
218 : }
219 :
220 : // Set all other items invisible
221 0 : const auto nitems = m_context_menu->actions().size();
222 0 : for (int item=m_seperator_pos; item<nitems; item++) {
223 0 : m_context_menu->actions().at ( item )->setVisible ( false );
224 : }
225 :
226 0 : if (ItemMap.size()>0) {
227 0 : m_context_menu->actions().at(m_save_pos-1)->setVisible(true);
228 0 : m_context_menu->actions().at(m_save_pos+1)->setVisible(true);
229 : }
230 0 : if (m_modified && ItemMap.size()>0) {
231 0 : m_context_menu->actions().at(m_save_pos)->setVisible(true);
232 : }
233 :
234 0 : if ( itemAt ( event->scenePos(), QTransform() ) ) {
235 : // Something under mouse pointer, set additional items visible
236 : // depending on what it is
237 0 : m_context_menu->actions().at ( m_seperator_pos )->setVisible ( true );
238 :
239 0 : auto object = dynamic_cast<SchemaGraphicObject *> (
240 0 : itemAt ( event->scenePos(), QTransform() ) );
241 0 : auto arrow = dynamic_cast<SchemaGraphicSegmentedArrow *> (
242 0 : itemAt ( event->scenePos(), QTransform() ) );
243 0 : auto note = dynamic_cast<SchemaGraphicNote *> (
244 0 : itemAt ( event->scenePos(), QTransform() ) );
245 :
246 0 : if ( object != nullptr) {
247 0 : CurrentObject = object;
248 0 : m_toggle_highlight_class->setChecked(CurrentObject->highlighted());
249 :
250 0 : auto filename =
251 0 : CurrentObject->GetClass()->get_file()->get_full_file_name();
252 0 : bool writable = KernelWrapper::GetInstance().IsFileWritable ( filename );
253 0 : m_context_menu->actions().at ( m_class_pos )->setVisible ( writable );
254 :
255 0 : for (int item=m_class_pos+1; item<m_arrow_pos; item++) {
256 0 : m_context_menu->actions().at ( item )->setVisible ( true );
257 : }
258 0 : }
259 0 : else if ( arrow != nullptr ) {
260 0 : m_context_menu->actions().at ( m_arrow_pos )->setVisible ( true );
261 0 : m_current_arrow = arrow;
262 : }
263 0 : else if ( note != nullptr) {
264 0 : for (int item=m_note_pos; item<nitems; item++) {
265 0 : m_context_menu->actions().at ( item )->setVisible ( true );
266 : }
267 0 : m_current_note = note;
268 : }
269 : }
270 0 : m_current_pos = event->scenePos();
271 0 : m_context_menu->exec ( event->screenPos() );
272 0 : }
273 :
274 0 : QStringList dbse::SchemaGraphicsScene::AddItemsToScene (
275 : QStringList SchemaClasses,
276 : QList<QPointF> Positions )
277 : {
278 0 : QStringList missingItems{};
279 :
280 0 : for ( QString & ClassName : SchemaClasses )
281 : {
282 0 : if ( !ItemMap.contains ( ClassName ) )
283 : {
284 :
285 0 : if ( !KernelWrapper::GetInstance().FindClass ( ClassName.toStdString() ) ) {
286 0 : std::cout << "ERROR: class " << ClassName.toStdString() << " not found" << std::endl;
287 0 : missingItems.append(ClassName);
288 0 : continue;
289 : }
290 :
291 0 : SchemaGraphicObject * Object = new SchemaGraphicObject ( ClassName, this );
292 0 : Object->setPos ( Positions.at ( SchemaClasses.indexOf ( ClassName ) ) );
293 0 : addItem ( Object );
294 : /// Updating item list
295 0 : ItemMap.insert ( ClassName, Object );
296 : }
297 : }
298 :
299 0 : for ( QString & ClassName : ItemMap.keys() )
300 : {
301 0 : OksClass * ClassInfo = KernelWrapper::GetInstance().FindClass ( ClassName.toStdString() );
302 :
303 0 : const std::list<OksRelationship *> * DirectRelationshipList =
304 0 : ClassInfo->direct_relationships();
305 0 : const std::list<std::string *> * DirectSuperClassesList = ClassInfo->direct_super_classes();
306 :
307 0 : std::map<std::string, unsigned int> arrow_count;
308 :
309 : //// PLotting relationships
310 0 : if ( DirectRelationshipList != nullptr )
311 : {
312 0 : for ( OksRelationship * ClassRelationship : * ( DirectRelationshipList ) )
313 : {
314 0 : auto rct = ClassRelationship->get_class_type()->get_name();
315 0 : QString RelationshipClassType = QString::fromStdString (rct);
316 :
317 0 : if ( ItemMap.contains ( RelationshipClassType ) ) //&& !ItemMap[ClassName]->HasArrow (
318 : //ItemMap[RelationshipClassType] ) )
319 : {
320 0 : QString SchemaCardinality =
321 0 : KernelWrapper::GetInstance().GetCardinalityStringRelationship ( ClassRelationship ) + " ";
322 0 : SchemaGraphicSegmentedArrow * NewArrow = new SchemaGraphicSegmentedArrow (
323 0 : ItemMap[ClassName], ItemMap[RelationshipClassType],
324 0 : arrow_count[rct],
325 : false,
326 0 : ClassRelationship->get_is_composite(),
327 0 : QString::fromStdString ( ClassRelationship->get_name() ), SchemaCardinality );
328 0 : ItemMap[ClassName]->AddArrow ( NewArrow );
329 0 : ItemMap[RelationshipClassType]->AddArrow ( NewArrow );
330 0 : addItem ( NewArrow );
331 : //NewArrow->SetLabelScene(this);
332 0 : NewArrow->setZValue ( -1000.0 );
333 0 : NewArrow->UpdatePosition();
334 0 : arrow_count[rct]++;
335 0 : }
336 0 : }
337 : }
338 :
339 : /// Plotting the superclasses
340 0 : if ( DirectSuperClassesList != nullptr )
341 : {
342 0 : for ( std::string * SuperClassNameStd : * ( DirectSuperClassesList ) )
343 : {
344 0 : QString SuperClassName = QString::fromStdString ( *SuperClassNameStd );
345 :
346 0 : if ( ItemMap.contains ( SuperClassName ) ) // && !ItemMap[ClassName]->HasArrow (
347 : // ItemMap[SuperClassName] ) )
348 : {
349 0 : SchemaGraphicSegmentedArrow * NewArrow = new SchemaGraphicSegmentedArrow (
350 0 : ItemMap[ClassName],
351 0 : ItemMap[SuperClassName],
352 0 : arrow_count[*SuperClassNameStd],
353 : true,
354 0 : false, "", "" );
355 0 : ItemMap[ClassName]->AddArrow ( NewArrow );
356 0 : ItemMap[SuperClassName]->AddArrow ( NewArrow );
357 0 : addItem ( NewArrow );
358 : //NewArrow->SetLabelScene(this);
359 0 : NewArrow->setZValue ( -1000.0 );
360 0 : NewArrow->UpdatePosition();
361 0 : arrow_count[*SuperClassNameStd]++;
362 : }
363 0 : }
364 : }
365 0 : }
366 0 : modified(true);
367 0 : return missingItems;
368 0 : }
369 :
370 0 : void dbse::SchemaGraphicsScene::RemoveItemFromScene ( QGraphicsItem* item ) {
371 0 : removeItem ( item );
372 0 : modified(true);
373 0 : }
374 :
375 0 : void dbse::SchemaGraphicsScene::add_notes (QStringList notes,
376 : QList<QPointF> positions ) {
377 0 : for ( int index = 0; index<notes.size(); index++) {
378 0 : auto note = new SchemaGraphicNote (
379 0 : QString("#" + QString::number(m_next_note++)),
380 0 : notes.at(index) );
381 0 : note->setPos ( positions.at ( index ) );
382 0 : m_notes.insert(note);
383 0 : addItem(note);
384 : }
385 :
386 0 : }
387 0 : void dbse::SchemaGraphicsScene::remove_note_object (SchemaGraphicNote* note ) {
388 0 : if (note == nullptr) {
389 : return;
390 : }
391 0 : RemoveItemFromScene (note);
392 : }
393 :
394 0 : void dbse::SchemaGraphicsScene::RemoveClassObject ( SchemaGraphicObject * Object )
395 : {
396 0 : if ( Object == nullptr )
397 : {
398 : return;
399 : }
400 :
401 0 : Object->RemoveArrows();
402 0 : RemoveItemFromScene ( Object );
403 0 : ItemMap.remove ( Object->GetClassName() );
404 : }
405 :
406 0 : void dbse::SchemaGraphicsScene::CleanItemMap()
407 : {
408 0 : ItemMap.clear();
409 0 : }
410 :
411 0 : void dbse::SchemaGraphicsScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent )
412 : {
413 0 : if ( itemAt ( mouseEvent->scenePos(), QTransform() ) ) {
414 : // Save position of item under mouse so we can see if it has been
415 : // moved in mouseReleaseEvent
416 0 : m_mouse_item_pos = itemAt(mouseEvent->scenePos(), QTransform())->pos();
417 : }
418 0 : if ( mouseEvent->button() != Qt::LeftButton )
419 : {
420 : return;
421 : }
422 :
423 0 : if ( mouseEvent->widget()->cursor().shape() == Qt::CrossCursor )
424 : {
425 0 : m_line = new QGraphicsLineItem ( QLineF ( mouseEvent->scenePos(), mouseEvent->scenePos() ) );
426 0 : m_line->setPen ( QPen ( Qt::black, 2 ) );
427 0 : addItem ( m_line );
428 0 : modified(true);
429 0 : return;
430 : }
431 :
432 0 : QGraphicsScene::mousePressEvent ( mouseEvent );
433 : }
434 :
435 0 : void dbse::SchemaGraphicsScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent )
436 : {
437 0 : if ( m_line != nullptr )
438 : {
439 0 : QLineF newLine ( m_line->line().p1(), mouseEvent->scenePos() );
440 0 : m_line->setLine ( newLine );
441 : }
442 : else
443 : {
444 0 : QGraphicsScene::mouseMoveEvent ( mouseEvent );
445 : }
446 0 : }
447 :
448 0 : void dbse::SchemaGraphicsScene::ClearModified() {
449 0 : modified(false);
450 0 : }
451 :
452 0 : void dbse::SchemaGraphicsScene::modified(bool state) {
453 0 : m_modified = state;
454 0 : emit sceneModified(state);
455 0 : }
456 :
457 0 : void dbse::SchemaGraphicsScene::moveScene() {
458 0 : qreal minx = 1e6;
459 0 : qreal miny = 1e6;
460 0 : for (auto obj : ItemMap) {
461 0 : auto pos = obj->pos();
462 0 : if (pos.x() < minx) {
463 : minx = pos.x();
464 : }
465 0 : if (pos.y() < miny) {
466 : miny = pos.y();
467 : }
468 : }
469 0 : qreal xoffset = m_current_pos.x() - minx;
470 0 : qreal yoffset = m_current_pos.y() - miny;
471 0 : for (auto obj : ItemMap) {
472 0 : obj->setX(obj->x()+xoffset);
473 0 : obj->setY(obj->y()+yoffset);
474 0 : obj->update_arrows();
475 : }
476 0 : for (auto obj : m_notes) {
477 0 : obj->setX(obj->x()+xoffset);
478 0 : obj->setY(obj->y()+yoffset);
479 : }
480 0 : update();
481 0 : modified(true);
482 0 : }
483 :
484 0 : void dbse::SchemaGraphicsScene::requestSave() {
485 0 : emit saveRequested();
486 0 : }
487 0 : void dbse::SchemaGraphicsScene::modified_slot() {
488 0 : modified(true);
489 0 : }
490 0 : void dbse::SchemaGraphicsScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent )
491 : {
492 0 : if ( itemAt ( mouseEvent->scenePos(), QTransform() ) ) {
493 0 : auto item = itemAt(mouseEvent->scenePos(), QTransform() );
494 0 : if (!m_mouse_item_pos.isNull()) {
495 0 : if (m_mouse_item_pos != item->pos()) {
496 0 : modified(true);
497 : }
498 0 : m_mouse_item_pos = QPointF();
499 : }
500 : }
501 0 : if ( m_line != nullptr )
502 : {
503 0 : QList<QGraphicsItem *> startItems = items ( m_line->line().p1() );
504 :
505 0 : if ( startItems.count() && startItems.first() == m_line )
506 : {
507 0 : startItems.removeFirst();
508 : }
509 :
510 0 : QList<QGraphicsItem *> endItems = items ( m_line->line().p2() );
511 :
512 0 : if ( endItems.count() && endItems.first() == m_line )
513 : {
514 0 : endItems.removeFirst();
515 : }
516 :
517 0 : RemoveItemFromScene ( m_line );
518 0 : delete m_line;
519 :
520 0 : if ( startItems.count() > 0 && endItems.count() > 0
521 0 : && startItems.first() != endItems.first() )
522 : {
523 :
524 0 : bool Inheritance = KernelWrapper::GetInstance().GetInheritanceMode();
525 0 : SchemaGraphicObject * startItem = qgraphicsitem_cast<SchemaGraphicObject *> (
526 0 : startItems.first() );
527 0 : SchemaGraphicObject * endItem = qgraphicsitem_cast<SchemaGraphicObject *> (
528 0 : endItems.first() );
529 :
530 0 : if ( Inheritance )
531 : {
532 0 : startItem->GetClass()->add_super_class ( endItem->GetClassName().toStdString() );
533 : /// Create arrow
534 0 : SchemaGraphicSegmentedArrow * newArrow = new SchemaGraphicSegmentedArrow (
535 : startItem, endItem,
536 : 0,
537 : Inheritance,
538 0 : true, "", "" );
539 0 : startItem->AddArrow ( newArrow );
540 0 : endItem->AddArrow ( newArrow );
541 0 : newArrow->setZValue ( -1000.0 );
542 0 : addItem ( newArrow );
543 : //newArrow->SetLabelScene(this);
544 0 : newArrow->UpdatePosition();
545 : }
546 : else
547 : {
548 0 : SchemaRelationshipEditor * Editor = new SchemaRelationshipEditor (
549 0 : startItem->GetClass(), endItem->GetClassName() );
550 0 : connect ( Editor, SIGNAL ( MakeGraphConnection ( QString, QString, QString ) ), this,
551 : SLOT ( DrawArrow ( QString, QString, QString ) ) );
552 0 : Editor->show();
553 : }
554 : }
555 0 : }
556 :
557 0 : m_line = nullptr;
558 0 : QGraphicsScene::mouseReleaseEvent ( mouseEvent );
559 0 : }
560 :
561 0 : void dbse::SchemaGraphicsScene::edit_note_slot() {
562 0 : m_current_note->open_editor();
563 0 : }
564 :
565 0 : void dbse::SchemaGraphicsScene::remove_note_slot() {
566 0 : remove_note_object(m_current_note);
567 0 : }
568 :
569 0 : void dbse::SchemaGraphicsScene::add_note_slot(SchemaGraphicNote* note) {
570 0 : m_notes.insert(note);
571 0 : addItem(note);
572 0 : modified(true);
573 0 : }
574 0 : void dbse::SchemaGraphicsScene::cancel_note_slot(SchemaGraphicNote* note) {
575 0 : m_notes.erase(note);
576 0 : delete note;
577 0 : }
578 :
579 0 : void dbse::SchemaGraphicsScene::new_note_slot() {
580 0 : auto note = new SchemaGraphicNote (
581 0 : QString("#") + QString::number(m_next_note++), QString());
582 0 : note->setPos(m_current_pos);
583 0 : auto editor = new SchemaNoteEditor(note);
584 0 : connect(editor, SIGNAL(note_accepted(SchemaGraphicNote*)), this, SLOT(add_note_slot(SchemaGraphicNote*)));
585 0 : connect(editor, SIGNAL(cancelled(SchemaGraphicNote*)), this, SLOT(cancel_note_slot(SchemaGraphicNote*)));
586 0 : editor->show();
587 0 : }
588 :
589 0 : void dbse::SchemaGraphicsScene::add_class_slot(QString class_name) {
590 0 : disconnect(m_addclass_connection);
591 :
592 0 : auto object = new SchemaGraphicObject(class_name, this);
593 0 : object->setPos(m_current_pos);
594 0 : addItem (object);
595 : /// Updating item list
596 0 : ItemMap.insert(class_name, object);
597 0 : }
598 0 : void dbse::SchemaGraphicsScene::new_class_slot() {
599 0 : m_addclass_connection = connect (
600 0 : &KernelWrapper::GetInstance(), SIGNAL ( ClassCreated(QString) ),
601 0 : this, SLOT ( add_class_slot(QString) ) );
602 0 : SchemaClassEditor::createNewClass();
603 0 : }
604 :
605 0 : void dbse::SchemaGraphicsScene::EditClassSlot()
606 : {
607 0 : QString class_name = QString::fromStdString ( CurrentObject->GetClass()->get_name() );
608 0 : SchemaClassEditor::launch(class_name);
609 0 : }
610 :
611 0 : void dbse::SchemaGraphicsScene::ToggleHighlightClass() {
612 0 : CurrentObject->toggle_highlight_class();
613 0 : this->update();
614 0 : }
615 :
616 0 : void dbse::SchemaGraphicsScene::ToggleHighlightActive() {
617 0 : m_highlight_active = !m_highlight_active;
618 0 : this->update();
619 0 : }
620 :
621 0 : void dbse::SchemaGraphicsScene::ToggleHighlightAbstract() {
622 0 : m_highlight_abstract = !m_highlight_abstract;
623 0 : this->update();
624 0 : }
625 :
626 0 : void dbse::SchemaGraphicsScene::ToggleDefault() {
627 0 : m_show_defaults = !m_show_defaults;
628 0 : for ( SchemaGraphicObject * item : ItemMap.values() ) {
629 0 : item->update_arrows();
630 0 : }
631 0 : this->update();
632 0 : }
633 :
634 0 : void dbse::SchemaGraphicsScene::ToggleIndirectInfos() {
635 0 : m_inherited_properties_visible = !m_inherited_properties_visible;
636 :
637 0 : for ( SchemaGraphicObject * item : ItemMap.values() ) {
638 0 : item->update_arrows();
639 0 : }
640 0 : this->update();
641 0 : }
642 :
643 0 : void dbse::SchemaGraphicsScene::AddDirectSuperClassesSlot() {
644 :
645 0 : QString class_name = QString::fromStdString ( CurrentObject->GetClass()->get_name() );
646 0 : OksClass * class_info = KernelWrapper::GetInstance().FindClass ( class_name.toStdString() );
647 :
648 0 : QStringList super_class_list;
649 0 : QList<QPointF> positions;
650 :
651 0 : const std::list<std::string *>* direct_classes = class_info->direct_super_classes();
652 0 : if(direct_classes != nullptr) {
653 0 : for(std::string * cl_name : *direct_classes) {
654 0 : super_class_list.push_back(QString::fromStdString(*cl_name));
655 0 : positions.push_back({0,0});
656 : }
657 : }
658 :
659 0 : this->AddItemsToScene ( super_class_list, positions );
660 :
661 0 : }
662 :
663 0 : void dbse::SchemaGraphicsScene::AddAllSuperClassesSlot() {
664 :
665 0 : QString class_name = QString::fromStdString ( CurrentObject->GetClass()->get_name() );
666 0 : OksClass * class_info = KernelWrapper::GetInstance().FindClass ( class_name.toStdString() );
667 :
668 0 : QStringList super_class_list;
669 0 : QList<QPointF> positions;
670 :
671 0 : const OksClass::FList* all_classes = class_info->all_super_classes();
672 0 : if(all_classes != nullptr) {
673 0 : for(const OksClass* cl : *all_classes) {
674 0 : super_class_list.push_back(QString::fromStdString(cl->get_name()));
675 0 : positions.push_back({0,0});
676 : }
677 : }
678 :
679 :
680 0 : this->AddItemsToScene ( super_class_list, positions );
681 :
682 0 : }
683 :
684 0 : void dbse::SchemaGraphicsScene::AddAllSubClassesSlot() {
685 :
686 0 : QString class_name = QString::fromStdString ( CurrentObject->GetClass()->get_name() );
687 0 : OksClass * class_info = KernelWrapper::GetInstance().FindClass ( class_name.toStdString() );
688 :
689 0 : QStringList sub_class_list;
690 0 : QList<QPointF> positions;
691 :
692 0 : const OksClass::FList* all_classes = class_info->all_sub_classes();
693 0 : if(all_classes != nullptr) {
694 0 : for(const OksClass* cl : *all_classes) {
695 0 : sub_class_list.push_back(QString::fromStdString(cl->get_name()));
696 0 : positions.push_back({0,0});
697 : }
698 : }
699 :
700 0 : this->AddItemsToScene ( sub_class_list, positions );
701 :
702 0 : }
703 :
704 0 : void dbse::SchemaGraphicsScene::AddDirectRelationshipClassesSlot() {
705 :
706 0 : QString class_name = QString::fromStdString ( CurrentObject->GetClass()->get_name() );
707 0 : OksClass * class_info = KernelWrapper::GetInstance().FindClass ( class_name.toStdString() );
708 :
709 0 : QStringList relationship_classes;
710 0 : QList<QPointF> positions;
711 :
712 0 : const std::list<OksRelationship *> * direct_relationship_list = class_info->direct_relationships();
713 0 : if ( direct_relationship_list != nullptr ) {
714 0 : for(const OksRelationship* rl : *direct_relationship_list) {
715 0 : relationship_classes.push_back(QString::fromStdString(rl->get_type()));
716 0 : positions.push_back({0,0});
717 : }
718 :
719 : }
720 :
721 0 : this->AddItemsToScene ( relationship_classes, positions );
722 :
723 0 : }
724 :
725 0 : void dbse::SchemaGraphicsScene::AddAllRelationshipClassesSlot() {
726 :
727 0 : QString class_name = QString::fromStdString ( CurrentObject->GetClass()->get_name() );
728 0 : OksClass * class_info = KernelWrapper::GetInstance().FindClass ( class_name.toStdString() );
729 :
730 0 : QStringList relationship_classes;
731 0 : QList<QPointF> positions;
732 :
733 0 : const std::list<OksRelationship *> * all_relationship_list = class_info->all_relationships();
734 0 : if ( all_relationship_list != nullptr ) {
735 0 : for(const OksRelationship* rl : *all_relationship_list) {
736 0 : relationship_classes.push_back(QString::fromStdString(rl->get_type()));
737 0 : positions.push_back({0,0});
738 : }
739 :
740 : }
741 :
742 0 : this->AddItemsToScene ( relationship_classes, positions );
743 0 : }
744 :
745 0 : void dbse::SchemaGraphicsScene::RemoveClassSlot()
746 : {
747 0 : if ( CurrentObject == nullptr )
748 : {
749 : return;
750 : }
751 :
752 0 : CurrentObject->RemoveArrows();
753 0 : RemoveItemFromScene ( CurrentObject );
754 0 : ItemMap.remove ( CurrentObject->GetClassName() );
755 : }
756 :
757 0 : void dbse::SchemaGraphicsScene::RemoveArrowSlot()
758 : {
759 0 : RemoveItemFromScene ( m_current_arrow );
760 0 : m_current_arrow->GetStartItem()->RemoveArrow ( m_current_arrow );
761 0 : m_current_arrow->GetEndItem()->RemoveArrow ( m_current_arrow );
762 0 : m_current_arrow->RemoveArrow();
763 0 : }
764 :
765 0 : void dbse::SchemaGraphicsScene::DrawArrow ( QString ClassName, QString RelationshipType,
766 : QString RelationshipName )
767 : {
768 0 : if ( !ItemMap.contains ( ClassName ) || !ItemMap.contains ( RelationshipType ) )
769 : {
770 0 : return;
771 : }
772 :
773 0 : SchemaGraphicObject * startItem = ItemMap[ClassName];
774 0 : SchemaGraphicObject * endItem = ItemMap[RelationshipType];
775 :
776 0 : OksClass * SchemaClass = KernelWrapper::GetInstance().FindClass ( ClassName.toStdString() );
777 0 : OksRelationship * SchemaRelationship = SchemaClass->find_direct_relationship (
778 0 : RelationshipName.toStdString() );
779 :
780 0 : if ( SchemaRelationship != nullptr )
781 : {
782 0 : QString RelationshipCardinality =
783 0 : KernelWrapper::GetInstance().GetCardinalityStringRelationship ( SchemaRelationship );
784 0 : SchemaGraphicSegmentedArrow * newArrow = new SchemaGraphicSegmentedArrow (
785 : startItem, endItem,
786 : 0,
787 0 : false, SchemaRelationship->get_is_composite(),
788 0 : QString::fromStdString ( SchemaRelationship->get_name() ), RelationshipCardinality );
789 0 : startItem->AddArrow ( newArrow );
790 0 : endItem->AddArrow ( newArrow );
791 0 : newArrow->setZValue ( -1000.0 );
792 0 : addItem ( newArrow );
793 : //newArrow->SetLabelScene(this);
794 0 : newArrow->UpdatePosition();
795 0 : }
796 : }
|