1 /*
2 # PostgreSQL Database Modeler (pgModeler)
3 #
4 # Copyright 2006-2020 - Raphael Araújo e Silva <raphael@pgmodeler.io>
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation version 3.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # The complete text of GPLv3 is at LICENSE file on source code root directory.
16 # Also, you can get the complete GNU General Public License at <http://www.gnu.org/licenses/>
17 */
18
19 #include "tableobjectview.h"
20
21 const QString TableObjectView::TypeSeparator=QString(" ");
22 const QString TableObjectView::ConstrSeparator=QString(" ");
23 const QString TableObjectView::TextUnique=QString("uq");
24 const QString TableObjectView::TextExclude=QString("ex");
25 const QString TableObjectView::TextCheck=QString("ck");
26 const QString TableObjectView::TextPrimaryKey=QString("pk");
27 const QString TableObjectView::TextForeignKey=QString("fk");
28 const QString TableObjectView::TextNotNull=QString("nn");
29 const QString TableObjectView::ConstrDelimStart=QString("«");
30 const QString TableObjectView::ConstrDelimEnd=QString("»");
31
TableObjectView(TableObject * object)32 TableObjectView::TableObjectView(TableObject *object) : BaseObjectView(object)
33 {
34 descriptor=nullptr;
35 fake_selection=false;
36
37 for(unsigned i=0; i < 3; i++)
38 lables[i]=new QGraphicsSimpleTextItem;
39
40 if(obj_selection)
41 delete obj_selection;
42 }
43
~TableObjectView()44 TableObjectView::~TableObjectView()
45 {
46 delete descriptor;
47
48 for(unsigned i=0; i < 3; i++)
49 delete lables[i];
50
51 delete obj_selection;
52 }
53
configureDescriptor(ConstraintType constr_type)54 void TableObjectView::configureDescriptor(ConstraintType constr_type)
55 {
56 ObjectType obj_type=ObjectType::BaseObject;
57 Column *column=dynamic_cast<Column *>(this->getUnderlyingObject());
58 bool ellipse_desc=false;
59 double factor=(font_config[Attributes::Global].font().pointSizeF()/DefaultFontSize) * BaseObjectView::getScreenDpiFactor();
60 QPen pen;
61
62 //Based upon the source object type the descriptor is allocated
63 if(this->getUnderlyingObject())
64 obj_type=this->getUnderlyingObject()->getObjectType();
65
66 /* Elliptical descriptor is used to columns (with or without not-null constraint),
67 for other object types, polygonal descriptor is usded */
68 ellipse_desc=((column && constr_type==BaseType::Null) || (!TableObject::isTableObject(obj_type)));
69
70 if(descriptor && ((ellipse_desc && !dynamic_cast<QGraphicsEllipseItem *>(descriptor)) ||
71 (!ellipse_desc && dynamic_cast<QGraphicsEllipseItem *>(descriptor))))
72 {
73 delete descriptor;
74 descriptor=nullptr;
75 }
76
77 if(!descriptor)
78 {
79 if(ellipse_desc)
80 descriptor=new QGraphicsEllipseItem;
81 else
82 descriptor=new QGraphicsPolygonItem;
83 }
84
85 if(column)
86 {
87 QString attrib;
88 QPolygonF pol;
89
90 if(constr_type==BaseType::Null)
91 {
92 QGraphicsEllipseItem *desc=dynamic_cast<QGraphicsEllipseItem *>(descriptor);
93
94 desc->setRect(QRectF(QPointF(0,0), QSizeF(9.0 * factor, 9.0 * factor)));
95
96 if(column->isNotNull())
97 attrib=Attributes::NnColumn;
98 else
99 attrib=Attributes::Column;
100
101 desc->setBrush(this->getFillStyle(attrib));
102
103 pen = this->getBorderStyle(attrib);
104 pen.setWidthF(ObjectBorderWidth * 1.15);
105 desc->setPen(pen);
106 }
107 else
108 {
109 QGraphicsPolygonItem *desc=dynamic_cast<QGraphicsPolygonItem *>(descriptor);
110
111 if(constr_type==ConstraintType::PrimaryKey)
112 {
113 attrib=Attributes::PkColumn;
114 pol.append(QPointF(2,0)); pol.append(QPointF(0,2)); pol.append(QPointF(0,7));
115 pol.append(QPointF(2,9)); pol.append(QPointF(3,8)); pol.append(QPointF(3,6));
116 pol.append(QPointF(4,6)); pol.append(QPointF(5,7)); pol.append(QPointF(6,6));
117 pol.append(QPointF(7,5)); pol.append(QPointF(9,7)); pol.append(QPointF(9,3));
118 pol.append(QPointF(3,3)); pol.append(QPointF(3,1));
119 }
120 else if(constr_type==ConstraintType::ForeignKey)
121 {
122 attrib=Attributes::FkColumn;
123 pol.append(QPointF(0,3)); pol.append(QPointF(0,6)); pol.append(QPointF(4,6));
124 pol.append(QPointF(4,9)); pol.append(QPointF(5,9)); pol.append(QPointF(9,5));
125 pol.append(QPointF(9,4)); pol.append(QPointF(5,0)); pol.append(QPointF(4,0));
126 pol.append(QPointF(4,3));
127 }
128 else if(constr_type==ConstraintType::Unique)
129 {
130 attrib=Attributes::UqColumn;
131 pol.append(QPointF(4,0)); pol.append(QPointF(0,4)); pol.append(QPointF(0,5));
132 pol.append(QPointF(4,9)); pol.append(QPointF(5,9)); pol.append(QPointF(9,5));
133 pol.append(QPointF(9,4)); pol.append(QPointF(5,0));
134 }
135
136 if(factor!=1.0)
137 TextPolygonItem::resizePolygon(pol, pol.boundingRect().width() * factor,
138 pol.boundingRect().height() * factor);
139
140 desc->setPolygon(pol);
141 desc->setBrush(this->getFillStyle(attrib));
142
143 pen = this->getBorderStyle(attrib);
144 pen.setWidthF(ObjectBorderWidth * 1.15);
145 desc->setPen(pen);
146 }
147 }
148 else if(obj_type != ObjectType::BaseObject)
149 {
150 TableObject *tab_obj=dynamic_cast<TableObject *>(this->getUnderlyingObject());
151 QGraphicsPolygonItem *desc=dynamic_cast<QGraphicsPolygonItem *>(descriptor);
152 QPolygonF pol;
153
154 pol.append(QPointF(5,0)); pol.append(QPointF(0,5)); pol.append(QPointF(4,9));
155 pol.append(QPointF(9,9)); pol.append(QPointF(9,4));
156
157 if(factor!=1.0)
158 TextPolygonItem::resizePolygon(pol, pol.boundingRect().width() * factor , pol.boundingRect().height() * factor);
159
160 desc->setPolygon(pol);
161 desc->setBrush(this->getFillStyle(tab_obj->getSchemaName()));
162
163 pen = this->getBorderStyle(tab_obj->getSchemaName());
164 pen.setWidthF(ObjectBorderWidth * 1.15);
165 desc->setPen(pen);
166 }
167 else
168 {
169 QGraphicsEllipseItem *desc=dynamic_cast<QGraphicsEllipseItem *>(descriptor);
170
171 desc->setRect(QRectF(QPointF(0,0), QSizeF(9.0 * factor, 9.0 * factor)));
172 desc->setBrush(this->getFillStyle(Attributes::Reference));
173
174 pen = this->getBorderStyle(Attributes::Reference);
175 pen.setWidthF(ObjectBorderWidth * 1.15);
176 desc->setPen(pen);
177 }
178 }
179
configureObject()180 void TableObjectView::configureObject()
181 {
182 if(this->getUnderlyingObject())
183 {
184 QTextCharFormat fmt;
185 double px = 0;
186 QString str_constr, tooltip, atribs_tip;
187 TableObject *tab_obj=dynamic_cast<TableObject *>(this->getUnderlyingObject());
188 Column *column=dynamic_cast<Column *>(tab_obj);
189 ConstraintType constr_type=ConstraintType::Null;
190 bool sql_disabled=false;
191
192 tooltip=tab_obj->getName() + QString(" (") + tab_obj->getTypeName() + QString(")");
193 tooltip+=QString("\nId: %1").arg(tab_obj->getObjectId());
194 sql_disabled=tab_obj->isSQLDisabled();
195 fake_selection=false;
196
197 if(column)
198 {
199 if(column->isAddedByRelationship())
200 tooltip+=tr("\nRelationship: %1").arg(column->getParentRelationship()->getName());
201
202 str_constr=this->getConstraintString(column);
203
204 if(str_constr.indexOf(TextPrimaryKey)>=0)
205 {
206 fmt=font_config[Attributes::PkColumn];
207 constr_type=ConstraintType::PrimaryKey;
208 }
209 else if(str_constr.indexOf(TextForeignKey)>=0)
210 {
211 fmt=font_config[Attributes::FkColumn];
212 constr_type=ConstraintType::ForeignKey;
213 }
214 else if(str_constr.indexOf(TextUnique)>=0)
215 {
216 fmt=font_config[Attributes::UqColumn];
217 constr_type=ConstraintType::Unique;
218 }
219 else if(str_constr.indexOf(TextNotNull)>=0)
220 fmt=font_config[Attributes::NnColumn];
221 else
222 fmt=font_config[Attributes::Column];
223
224 if(column->isAddedByRelationship())
225 fmt=font_config[Attributes::InhColumn];
226 else if(column->isProtected())
227 fmt=font_config[Attributes::ProtColumn];
228
229 if(str_constr.indexOf(TextPrimaryKey)>=0)
230 atribs_tip+=(~ConstraintType(ConstraintType::PrimaryKey)).toLower() + QString(", ");
231
232 if(str_constr.indexOf(TextForeignKey)>=0)
233 atribs_tip+=(~ConstraintType(ConstraintType::ForeignKey)).toLower() + QString(", ");
234
235 if(str_constr.indexOf(TextUnique)>=0)
236 atribs_tip+=(~ConstraintType(ConstraintType::Unique)).toLower() + QString(", ");
237
238 if(str_constr.indexOf(TextExclude)>=0)
239 atribs_tip+=(~ConstraintType(ConstraintType::Exclude)).toLower() + QString(", ");
240
241 if(str_constr.indexOf(TextNotNull)>=0)
242 atribs_tip+=QString("not null");
243 }
244 else
245 {
246 if(tab_obj->isAddedByRelationship())
247 fmt=font_config[Attributes::InhColumn];
248 else if(tab_obj->isProtected())
249 fmt=font_config[Attributes::ProtColumn];
250 else
251 fmt=font_config[tab_obj->getSchemaName()];
252 }
253
254 configureDescriptor(constr_type);
255
256 descriptor->setPos(HorizSpacing, 0);
257 px=HorizSpacing + descriptor->boundingRect().width() + (2 * HorizSpacing);
258
259 //Configuring the labels as follow: [object name] [type] [constraints]
260 lables[0]->setText(compact_view && !tab_obj->getAlias().isEmpty() ? tab_obj->getAlias() : tab_obj->getName());
261
262 //Strikeout the column name when its SQL is disabled
263 QFont font=fmt.font();
264 font.setStrikeOut(sql_disabled);
265 fmt.setFont(font);
266
267 lables[0]->setFont(fmt.font());
268 lables[0]->setBrush(fmt.foreground());
269 lables[0]->setPos(px, 0);
270 px+=lables[0]->boundingRect().width();
271
272 //Configuring the type label
273 fmt=font_config[Attributes::ObjectType];
274
275 if(compact_view)
276 lables[1]->setText("");
277 else
278 {
279 if(column)
280 lables[1]->setText(TypeSeparator + (*column->getType()));
281 else
282 lables[1]->setText(TypeSeparator + tab_obj->getSchemaName());
283 }
284
285 lables[1]->setFont(fmt.font());
286 lables[1]->setBrush(fmt.foreground());
287 lables[1]->setPos(px, 0);
288 px+=lables[1]->boundingRect().width() + (3 * HorizSpacing);
289
290 //Configuring the constraints label
291 fmt=font_config[Attributes::Constraints];
292 if(compact_view)
293 lables[2]->setText("");
294 else if(column)
295 lables[2]->setText(!str_constr.isEmpty() ? str_constr : QString(" "));
296 else
297 {
298 Rule *rule=dynamic_cast<Rule *>(tab_obj);
299 Trigger *trigger=dynamic_cast<Trigger *>(tab_obj);
300 Index *index=dynamic_cast<Index *>(tab_obj);
301 Constraint *constr=dynamic_cast<Constraint *>(tab_obj);
302 Policy *policy = dynamic_cast<Policy *>(tab_obj);
303
304 if(rule)
305 {
306 str_constr+=(~rule->getExecutionType()).mid(0,1);
307 atribs_tip+=(~rule->getExecutionType()).toLower() + QString(", ");
308
309 str_constr+=ConstrSeparator;
310
311 str_constr+=(~rule->getEventType()).mid(3,1);
312 atribs_tip+=(~rule->getEventType()).toLower();
313 str_constr=str_constr.toLower();
314 }
315 else if(trigger)
316 {
317 str_constr+=(~trigger->getFiringType()).mid(0,1);
318 str_constr+=ConstrSeparator;
319
320 atribs_tip+=(~trigger->getFiringType()).toLower() + QString(", ");
321
322 for(unsigned i=EventType::OnInsert; i <= EventType::OnTruncate; i++)
323 {
324 if(trigger->isExecuteOnEvent(EventType(i)))
325 {
326 str_constr+=(~EventType(i)).mid(3,1);
327 atribs_tip+=(~EventType(i)).toLower() + QString(", ");
328 }
329 }
330 str_constr=str_constr.toLower();
331 }
332 else if(index)
333 {
334 if(index->getIndexAttribute(Index::Unique))
335 {
336 str_constr+=QString("u");
337 atribs_tip += QString("unique") + QString(", ");
338 }
339
340 if(index->getIndexAttribute(Index::Concurrent))
341 {
342 str_constr+=QString("c");
343 atribs_tip += QString("concurrent") + QString(", ");
344 }
345
346 if(index->getIndexAttribute(Index::FastUpdate))
347 {
348 str_constr+=QString("f");
349 atribs_tip += QString("fast updated");
350 }
351
352 if(index->getIndexAttribute(Index::Buffering))
353 {
354 str_constr+=QString("b");
355 atribs_tip += QString("buffering");
356 }
357 }
358 else if(constr)
359 {
360 ConstraintType type = constr->getConstraintType();
361
362 if(type == ConstraintType::PrimaryKey)
363 str_constr = TextPrimaryKey;
364 else if(type == ConstraintType::ForeignKey)
365 str_constr = TextForeignKey;
366 else if(type == ConstraintType::Unique)
367 str_constr = TextUnique;
368 else if(type == ConstraintType::Exclude)
369 str_constr = TextExclude;
370 else if(type == ConstraintType::Check)
371 str_constr = TextCheck;
372
373 atribs_tip = (~type).toLower();
374 }
375 else if(policy)
376 {
377 if(policy->isPermissive())
378 {
379 str_constr += QString("p");
380 atribs_tip += QString("permissive");
381 }
382 else
383 {
384 str_constr += QString("r");
385 atribs_tip += QString("restrictive");
386 }
387
388 atribs_tip += QString(", ");
389 str_constr += (~policy->getPolicyCommand()).toLower().at(0);
390 atribs_tip += (~policy->getPolicyCommand()).toLower();
391 }
392
393 if(!str_constr.isEmpty())
394 lables[2]->setText(ConstrDelimStart + QString(" ") +
395 str_constr + QString(" ") +
396 ConstrDelimEnd);
397 else
398 lables[2]->setText("");
399 }
400
401 if(!atribs_tip.isEmpty())
402 {
403 if(atribs_tip.at(atribs_tip.length()-1)==' ')
404 atribs_tip.remove(atribs_tip.length()-2, 2);
405
406 atribs_tip=QString("\n") + ConstrDelimStart +
407 QString(" ") + atribs_tip + QString(" ") + ConstrDelimEnd;
408
409 }
410
411 if(!tab_obj->getComment().isEmpty())
412 atribs_tip += QString("\n---\n%1").arg(tab_obj->getComment());
413
414 lables[2]->setFont(fmt.font());
415 lables[2]->setBrush(fmt.foreground());
416 lables[2]->setPos(px, 0);
417
418 calculateBoundingRect();
419 this->setToolTip(tooltip + atribs_tip);
420 }
421 }
422
configureObject(Reference reference)423 void TableObjectView::configureObject(Reference reference)
424 {
425 QTextCharFormat fmt;
426 double px;
427 QString str_aux;
428
429 configureDescriptor();
430 descriptor->setPos(HorizSpacing, 0);
431 px=descriptor->pos().x() + descriptor->boundingRect().width() + (2 * HorizSpacing);
432
433 if(reference.getReferenceType()==Reference::ReferColumn)
434 {
435 //Configures the name label as: [table].[column]
436 fmt=font_config[Attributes::RefTable];
437
438 if(compact_view && !reference.getReferenceAlias().isEmpty())
439 lables[0]->setText(reference.getReferenceAlias());
440 else
441 lables[0]->setText(reference.getTable()->getName() + ".");
442
443 lables[0]->setFont(fmt.font());
444 lables[0]->setBrush(fmt.foreground());
445 lables[0]->setPos(px, 0);
446 px+=lables[0]->boundingRect().width();
447
448 fmt=font_config[Attributes::RefColumn];
449 if(compact_view && !reference.getReferenceAlias().isEmpty())
450 lables[1]->setText("");
451 else
452 {
453 if(reference.getColumn())
454 lables[1]->setText(reference.getColumn()->getName());
455 else
456 lables[1]->setText("*");
457 }
458
459 lables[1]->setFont(fmt.font());
460 lables[1]->setBrush(fmt.foreground());
461 lables[1]->setPos(px, 0);
462 px+=lables[1]->boundingRect().width();
463 }
464 else
465 {
466 fmt=font_config[Attributes::RefTable];
467 str_aux = compact_view && !reference.getReferenceAlias().isEmpty() ? reference.getReferenceAlias() : "";
468
469 if(str_aux.isEmpty())
470 {
471 str_aux=reference.getExpression().simplified().mid(0,25);
472 if(reference.getExpression().size() > 25) str_aux+=QString("...");
473 str_aux.replace(QString("\n"), QString(" "));
474 }
475
476 lables[0]->setText(str_aux);
477 lables[0]->setFont(fmt.font());
478 lables[0]->setBrush(fmt.foreground());
479 lables[1]->setText("");
480 lables[0]->setPos(px, 0);
481 px+=lables[0]->boundingRect().width();
482 }
483
484 //Configures a label for the alias (if there is one)
485 if(!compact_view &&
486 ((reference.getColumn() && !reference.getColumnAlias().isEmpty()) ||
487 (!reference.getAlias().isEmpty() && reference.getReferenceType()==Reference::ReferExpression)))
488 {
489 if(reference.getReferenceType()==Reference::ReferExpression)
490 str_aux=reference.getAlias();
491 else
492 str_aux=reference.getColumnAlias();
493
494 str_aux=QString(" (") + str_aux + QString(") ");
495 fmt=font_config[Attributes::Alias];
496 lables[2]->setText(str_aux);
497 lables[2]->setFont(fmt.font());
498 lables[2]->setBrush(fmt.foreground());
499 lables[2]->setPos(px, 0);
500 }
501 else
502 lables[2]->setText("");
503
504 calculateBoundingRect();
505 }
506
configureObject(const SimpleColumn & col)507 void TableObjectView::configureObject(const SimpleColumn &col)
508 {
509 QTextCharFormat fmt;
510 double px;
511
512 configureDescriptor();
513 descriptor->setPos(HorizSpacing, 0);
514 px=descriptor->pos().x() + descriptor->boundingRect().width() + (2 * HorizSpacing);
515
516 fmt = font_config[Attributes::Column];
517
518 if(compact_view && !col.alias.isEmpty())
519 lables[0]->setText(col.alias);
520 else
521 lables[0]->setText(col.name);
522
523 lables[0]->setFont(fmt.font());
524 lables[0]->setBrush(fmt.foreground());
525 lables[0]->setPos(px, 0);
526 px+=lables[0]->boundingRect().width() + (4 * HorizSpacing);
527
528 if(!compact_view && !col.type.isEmpty())
529 {
530 fmt=font_config[Attributes::ObjectType];
531 lables[1]->setText(col.type);
532 lables[1]->setFont(fmt.font());
533 lables[1]->setBrush(fmt.foreground());
534 lables[1]->setPos(px, 0);
535 px+=lables[1]->boundingRect().width() + (4 * HorizSpacing);
536 }
537 else
538 lables[1]->setText("");
539
540 lables[2]->setText("");
541 calculateBoundingRect();
542 }
543
setChildObjectXPos(unsigned obj_idx,double px)544 void TableObjectView::setChildObjectXPos(unsigned obj_idx, double px)
545 {
546 if(obj_idx >= 4)
547 throw Exception(ErrorCode::RefObjectInvalidIndex, __PRETTY_FUNCTION__, __FILE__, __LINE__);
548
549 if(obj_idx==0)
550 descriptor->setPos(px, descriptor->pos().y());
551 else
552 lables[obj_idx-1]->setPos(px, lables[obj_idx-1]->pos().y());
553
554 calculateBoundingRect();
555 }
556
calculateBoundingRect()557 void TableObjectView::calculateBoundingRect()
558 {
559 double width = 0, height = 0, curr_w = 0, py = 0;
560
561 width = descriptor->pos().x() + descriptor->boundingRect().width();
562 height = lables[0]->boundingRect().height();
563
564 for(int i = 0; i < 3; i++)
565 {
566 if(lables[i]->text().isEmpty())
567 continue;
568
569 curr_w = lables[i]->pos().x() + lables[i]->boundingRect().width();
570
571 if(width < curr_w)
572 width = lables[i]->pos().x() + lables[i]->boundingRect().width();
573 }
574
575 bounding_rect = QRectF(QPointF(0,0), QSizeF(width + (4 * HorizSpacing), height + VertSpacing * 0.80));
576
577 //Adjusting the Y position of the objects in order to center them on the new bouding rect
578 descriptor->setPos(descriptor->pos().x(),
579 (bounding_rect.height() - descriptor->boundingRect().height() + (VertSpacing * 0.4))/2);
580
581 py = (bounding_rect.height() - lables[0]->boundingRect().height())/2;
582
583 for(unsigned i = 0; i < 3; i++)
584 lables[i]->setPos(lables[i]->pos().x(), py);
585 }
586
getChildObject(unsigned obj_idx)587 QGraphicsItem *TableObjectView::getChildObject(unsigned obj_idx)
588 {
589 if(obj_idx > ConstrAliasLabel)
590 throw Exception(ErrorCode::RefObjectInvalidIndex, __PRETTY_FUNCTION__, __FILE__, __LINE__);
591
592 if(obj_idx == ObjDescriptor)
593 return descriptor;
594 else
595 return lables[obj_idx - 1];
596 }
597
getConstraintString(Column * column)598 QString TableObjectView::getConstraintString(Column *column)
599 {
600 if(column && column->getParentTable())
601 {
602 PhysicalTable *table=dynamic_cast<PhysicalTable *>(column->getParentTable());
603 QString str_constr;
604 Constraint *constr=nullptr;
605 vector<TableObject *>::iterator itr,itr_end;
606 ConstraintType constr_type;
607
608 itr=table->getObjectList(ObjectType::Constraint)->begin();
609 itr_end=table->getObjectList(ObjectType::Constraint)->end();
610
611 while(itr!=itr_end)
612 {
613 constr=dynamic_cast<Constraint *>(*itr);
614 itr++;
615
616 //Check if the column is referecend by the constraint
617 if((constr->getConstraintType()!=ConstraintType::Exclude && constr->isColumnExists(column, Constraint::SourceCols)) ||
618 (constr->getConstraintType()==ConstraintType::Exclude && constr->isColumnReferenced(column, false)))
619 {
620 constr_type=constr->getConstraintType();
621
622 if(constr_type==ConstraintType::PrimaryKey)
623 str_constr=TextPrimaryKey + ConstrSeparator + str_constr;
624
625 if(constr_type==ConstraintType::ForeignKey && str_constr.indexOf(TextForeignKey) < 0)
626 str_constr+=TextForeignKey + ConstrSeparator;
627
628 if(constr_type==ConstraintType::Unique && str_constr.indexOf(TextUnique) < 0)
629 str_constr+=TextUnique + ConstrSeparator;
630
631 if(constr_type==ConstraintType::Exclude && str_constr.indexOf(TextExclude) < 0)
632 str_constr+=TextExclude + ConstrSeparator;
633 }
634 }
635
636 if(column->isNotNull() && !str_constr.contains(TextPrimaryKey))
637 str_constr+=TextNotNull + ConstrSeparator;
638
639 if(!str_constr.isEmpty())
640 str_constr= ConstrDelimStart + ConstrSeparator + str_constr + ConstrDelimEnd;
641
642 return str_constr;
643 }
644 else return "";
645 }
646
setFakeSelection(bool value)647 void TableObjectView::setFakeSelection(bool value)
648 {
649 // Fake selection is used only by instances that own and underlying object (column, constratin, trigger,etc)
650 if(!this->getUnderlyingObject())
651 return;
652
653 fake_selection = value;
654
655 if(value)
656 {
657 configureObjectSelection();
658 sel_order=++BaseObjectView::global_sel_order;
659 }
660 else
661 sel_order = 0;
662
663 update();
664 }
665
hasFakeSelection()666 bool TableObjectView::hasFakeSelection()
667 {
668 return fake_selection;
669 }
670
configureObjectSelection()671 void TableObjectView::configureObjectSelection()
672 {
673 QGraphicsItem *parent = this->parentItem();
674 RoundedRectItem *rect_item=nullptr;
675 QRectF rect = this->boundingRect();
676
677 /* In order to avoid unnecessary memory usage by items that eventually will
678 * get selection we allocate the object selection rectangle only if the object
679 * itself is selected by the user, and it'll be allocated until the object's destruction */
680 if(!obj_selection)
681 obj_selection=new RoundedRectItem;
682
683 rect_item = dynamic_cast<RoundedRectItem *>(obj_selection);
684 rect.setX(0);
685 rect.setY(0);
686 rect.setHeight(rect.height() - VertSpacing);
687
688 // An small hack to capture the width of the table in which the item is child of
689 if(parent->parentItem())
690 rect.setWidth(parent->parentItem()->boundingRect().width() - (2.5 * HorizSpacing));
691 else
692 rect.setWidth(rect.width() - (3.5 * HorizSpacing));
693
694 rect_item->setBorderRadius(2);
695 rect_item->setRect(rect);
696 rect_item->setPos(0, VertSpacing/2);
697 rect_item->setBrush(this->getFillStyle(Attributes::ObjSelection));
698 rect_item->setPen(this->getBorderStyle(Attributes::ObjSelection));
699 }
700
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget * widget)701 void TableObjectView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
702 {
703 painter->save();
704 painter->translate(descriptor->pos());
705 descriptor->paint(painter, option, widget);
706 painter->restore();
707
708 for(int i = 0 ; i < 3; i++)
709 {
710 if(lables[i]->text().isEmpty())
711 continue;
712
713 painter->save();
714 painter->translate(lables[i]->pos());
715 lables[i]->paint(painter, option, widget);
716 painter->restore();
717 }
718
719 if(fake_selection)
720 {
721 painter->translate(obj_selection->pos());
722 obj_selection->paint(painter, option, widget);
723 }
724 }
725
boundingRect() const726 QRectF TableObjectView::boundingRect() const
727 {
728 return bounding_rect;
729 }
730
731