8
8
* Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
9
9
***************************************************************************/
12
11
#include "umlwidget.h"
14
#include "associationwidget.h"
15
#include "classifier.h"
16
#include "classpropdlg.h"
18
#include "debug_utils.h"
19
#include "floatingtextwidget.h"
20
#include "idchangelog.h"
21
#include "listpopupmenu.h"
22
#include "settingsdlg.h"
25
#include "umlobject.h"
27
#include "umlwidgetcontroller.h"
31
#include <kcolordialog.h>
32
#include <kfontdialog.h>
34
#include <kmessagebox.h>
14
37
#include <QtCore/QPointer>
15
38
#include <QtGui/QPainter>
16
39
#include <QtGui/QColor>
17
40
#include <QtGui/QMouseEvent>
19
#include <kcolordialog.h>
20
#include <kfontdialog.h>
22
#include <kmessagebox.h>
24
#include "debug_utils.h"
25
#include "umlwidgetcontroller.h"
26
#include "umlobject.h"
27
#include "classifier.h"
32
#include "umlclassifierlistitemlist.h"
33
#include "listpopupmenu.h"
34
#include "associationwidget.h"
35
#include "settingsdlg.h"
36
#include "codedocument.h"
37
#include "floatingtextwidget.h"
38
#include "docwindow.h"
39
#include "classpropdlg.h"
40
#include "idchangelog.h"
43
42
using namespace Uml;
55
54
UMLWidget::UMLWidget(UMLScene * scene, WidgetType type, UMLObject * o, UMLWidgetController *widgetController)
56
55
: WidgetBase(scene, type),
57
UMLSceneRectItem(scene->canvas())
58
setCanvas(scene->canvas());
59
59
if (widgetController) {
60
60
m_widgetController = widgetController;
80
80
UMLWidget::UMLWidget(UMLScene *scene, WidgetType type, Uml::IDType id, UMLWidgetController *widgetController)
81
81
: WidgetBase(scene, type),
82
UMLSceneRectItem(scene->canvas())
84
setCanvas(scene->canvas());
84
85
if (widgetController) {
85
86
m_widgetController = widgetController;
125
126
m_instanceName = other.m_instanceName;
126
127
m_instanceName = other.m_instanceName;
127
128
m_showStereotype = other.m_showStereotype;
130
131
UMLSceneRectItem::setSize(other.width(), other.height());
132
133
// assign volatile (non-saved) members
264
264
width = maxSize.width();
265
265
if (height > maxSize.height())
266
266
height = maxSize.height();
268
if (fixedAspectRatio()) {
269
UMLSceneSize size = UMLSceneRectItem::size();
270
float aspectRatio = (float)size.height()/size.width();
271
height = width * aspectRatio;
322
329
connect(m_scene, SIGNAL(sigRemovePopupMenu()), this, SLOT(slotRemovePopupMenu()));
323
330
connect(m_scene, SIGNAL(sigClearAllSelected()), this, SLOT(slotClearAllSelected()));
325
connect(m_scene, SIGNAL(sigColorChanged(Uml::IDType)), this, SLOT(slotColorChanged(Uml::IDType)));
332
connect(m_scene, SIGNAL(sigFillColorChanged(Uml::IDType)), this, SLOT(slotFillColorChanged(Uml::IDType)));
333
connect(m_scene, SIGNAL(sigLineColorChanged(Uml::IDType)), this, SLOT(slotLineColorChanged(Uml::IDType)));
334
connect(m_scene, SIGNAL(sigTextColorChanged(Uml::IDType)), this, SLOT(slotTextColorChanged(Uml::IDType)));
326
335
connect(m_scene, SIGNAL(sigLineWidthChanged(Uml::IDType)), this, SLOT(slotLineWidthChanged(Uml::IDType)));
328
337
m_pObject = NULL;
337
346
void UMLWidget::slotMenuSelection(QAction* action)
340
const WidgetBase::WidgetType wt = m_Type;
349
const WidgetBase::WidgetType wt = m_baseType;
341
350
UMLWidget* widget = 0; // use for select the first object properties (fill, line color)
343
352
ListPopupMenu::MenuType sel = m_pMenu->getMenuType(action);
345
354
case ListPopupMenu::mt_Rename:
346
355
m_doc->renameUMLObject(m_pObject);
347
// adjustAssocs( getX(), getY() );//adjust assoc lines
356
// adjustAssocs( x(), y() ); // adjust assoc lines
350
359
case ListPopupMenu::mt_Delete:
428
437
case ListPopupMenu::mt_Change_Font:
429
438
case ListPopupMenu::mt_Change_Font_Selection: {
430
439
QFont font = UMLWidget::font();
431
if (KFontDialog::getFont(font, KFontChooser::NoDisplayFlags, m_scene)) {
440
if (KFontDialog::getFont(font, KFontChooser::NoDisplayFlags, m_scene->view())) {
432
441
UMLApp::app()->executeCommand(new CmdChangeFontSelection(m_doc, m_scene, font));
492
502
* @param sceneID The id of the object behind the widget.
494
void UMLWidget::slotColorChanged(Uml::IDType viewID)
504
void UMLWidget::slotFillColorChanged(Uml::IDType viewID)
496
506
//only change if on the diagram concerned
497
if (m_scene->getID() != viewID) {
507
if (m_scene->ID() != viewID) {
500
510
if (m_usesDiagramFillColor) {
501
511
m_FillColor = m_scene->fillColor();
513
if (m_usesDiagramUseFillColor) {
514
m_useFillColor = m_scene->useFillColor();
520
* Captures a text color change signal.
522
* @param sceneID The id of the object behind the widget.
524
void UMLWidget::slotTextColorChanged(Uml::IDType viewID)
526
//only change if on the diagram concerned
527
if (m_scene->ID() != viewID)
529
setTextColor( m_scene->textColor() );
535
* Captures a line color change signal.
537
* @param sceneID The id of the object behind the widget.
539
void UMLWidget::slotLineColorChanged(Uml::IDType viewID)
541
//only change if on the diagram concerned
542
if (m_scene->ID() != viewID)
503
545
if (m_usesDiagramLineColor) {
504
546
m_LineColor = m_scene->lineColor();
506
if (m_usesDiagramUseFillColor) {
507
m_useFillColor = m_scene->useFillColor();
547
setLineColor( m_LineColor );
552
592
* Overrides the method from WidgetBase.
594
void UMLWidget::setTextColorcmd(const QColor &color)
596
WidgetBase::setTextColor(color);
601
* Overrides the method from WidgetBase.
603
void UMLWidget::setTextColor(const QColor &color)
605
UMLApp::app()->executeCommand(new CmdChangeTextColor(this, color));
610
* Overrides the method from WidgetBase.
554
612
void UMLWidget::setLineColorcmd(const QColor &color)
556
614
WidgetBase::setLineColor(color);
613
671
p->fillRect(offsetX + w - s, offsetY, s, s, brush);
615
673
// Draw the resize anchor in the lower right corner.
674
// Don't draw it if the widget is so small that the
675
// resize anchor would cover up most of the widget.
676
if (m_resizable && w * h > (s*3) * (s*3)) {
617
677
brush.setColor(Qt::red);
618
678
const int right = offsetX + w;
619
679
const int bottom = offsetY + h;
634
694
bool UMLWidget::activate(IDChangeLog* /*ChangeLog = 0 */)
636
if (widgetHasUMLObject(m_Type) && m_pObject == NULL) {
696
if (widgetHasUMLObject(m_baseType) && m_pObject == NULL) {
637
697
m_pObject = m_doc->findObjectById(m_nId);
638
698
if (m_pObject == NULL) {
639
699
uError() << "cannot find UMLObject with id=" << ID2STR(m_nId);
644
setSize(getWidth(), getHeight());
704
setSize(width(), height());
645
705
m_activated = true;
646
706
updateComponentSize();
647
707
if (m_scene->getPaste()) {
648
708
FloatingTextWidget * ft = 0;
649
709
QPoint point = m_scene->getPastePoint();
650
int x = point.x() + getX();
651
int y = point.y() + getY();
710
int x = point.x() + this->x();
711
int y = point.y() + this->y();
652
712
x = x < 0 ? 0 : x;
653
713
y = y < 0 ? 0 : y;
654
714
if (m_scene->type() == Uml::DiagramType::Sequence) {
655
715
switch (baseType()) {
656
716
case WidgetBase::wt_Object:
657
717
case WidgetBase::wt_Precondition :
662
722
case WidgetBase::wt_Message:
780
839
foreach(AssociationWidget* assocwidget , m_Assocs) {
782
if (!assocwidget->getSelected())
841
if (!assocwidget->isSelected())
783
842
assocwidget->saveIdealTextPositions();
786
845
foreach(AssociationWidget* assocwidget , m_Assocs) {
787
if (!assocwidget->getSelected())
846
if (!assocwidget->isSelected())
788
847
assocwidget->widgetMoved(this, x, y);
797
856
// will already be selected so make sure docWindow updates the doc
798
857
// back it the widget
799
DocWindow *docwindow = UMLApp::app()->docWindow();
800
docwindow->updateDocumentation(false);
858
umlScene()->updateDocumentation(false);
801
859
QPointer<ClassPropDlg> dlg = new ClassPropDlg((QWidget*)UMLApp::app(), this);
803
861
if (dlg->exec()) {
804
docwindow->showDocumentation(umlObject() , true);
862
umlScene()->showDocumentation(umlObject() , true);
805
863
m_doc->setModified(true);
807
865
dlg->close(); //wipe from memory
830
888
m_menuIsEmbedded = false;
831
889
//if in a multi- selection to a specific m_pMenu for that
832
890
// NEW: ask UMLView to count ONLY the widgets and not their floatingtextwidgets
833
int count = m_scene->getSelectCount(true);
891
int count = m_scene->selectedCount(true);
834
892
//a MessageWidget when selected will select its text widget and vice versa
835
893
//so take that into account for popup menu.
846
904
unique = m_scene->checkUniqueSelection();
848
906
// create the right click context menu
849
m_pMenu = new ListPopupMenu(m_scene, this, multi, unique);
907
m_pMenu = new ListPopupMenu(m_scene->view(), this, multi, unique);
851
909
// disable the "view code" menu for simple code generators
852
910
if (UMLApp::app()->isSimpleCodeGeneratorActive())
998
1056
void UMLWidget::setSelected(bool _select)
1000
const WidgetBase::WidgetType wt = m_Type;
1058
const WidgetBase::WidgetType wt = m_baseType;
1002
if (m_scene->getSelectCount() == 0) {
1060
if (m_scene->selectedCount() == 0) {
1003
1061
if (widgetHasUMLObject(wt)) {
1004
1062
m_scene->showDocumentation(m_pObject, false);
1019
1077
m_selected = _select;
1021
const QPoint pos(getX(), getY());
1079
const QPoint pos(x(), y());
1022
1080
UMLWidget *bkgnd = m_scene->widgetAt(pos);
1023
1081
if (bkgnd && bkgnd != this && _select) {
1024
uDebug() << "setting Z to " << bkgnd->getZ() + 1 << ", SelectState: " << _select;
1025
setZ(bkgnd->getZ() + 1);
1082
uDebug() << "setting Z to " << bkgnd->z() + 1 << ", SelectState: " << _select;
1083
setZ(bkgnd->z() + 1);
1052
1110
//remove signals from old view - was probably 0 anyway
1053
1111
disconnect(m_scene, SIGNAL(sigRemovePopupMenu()), this, SLOT(slotRemovePopupMenu()));
1054
1112
disconnect(m_scene, SIGNAL(sigClearAllSelected()), this, SLOT(slotClearAllSelected()));
1055
disconnect(m_scene, SIGNAL(sigColorChanged(Uml::IDType)), this, SLOT(slotColorChanged(Uml::IDType)));
1113
disconnect(m_scene, SIGNAL(sigFillColorChanged(Uml::IDType)), this, SLOT(slotFillColorChanged(Uml::IDType)));
1114
disconnect(m_scene, SIGNAL(sigTextColorChanged(Uml::IDType)), this, SLOT(slotTextColorChanged(Uml::IDType)));
1056
1115
disconnect(m_scene, SIGNAL(sigLineWidthChanged(Uml::IDType)), this, SLOT(slotLineWidthChanged(Uml::IDType)));
1058
1117
connect(m_scene, SIGNAL(sigRemovePopupMenu()), this, SLOT(slotRemovePopupMenu()));
1059
1118
connect(m_scene, SIGNAL(sigClearAllSelected()), this, SLOT(slotClearAllSelected()));
1060
connect(m_scene, SIGNAL(sigColorChanged(Uml::IDType)), this, SLOT(slotColorChanged(Uml::IDType)));
1119
connect(m_scene, SIGNAL(sigFillColorChanged(Uml::IDType)), this, SLOT(slotFillColorChanged(Uml::IDType)));
1120
connect(m_scene, SIGNAL(sigTextColorChanged(Uml::IDType)), this, SLOT(slotTextColorChanged(Uml::IDType)));
1061
1121
connect(m_scene, SIGNAL(sigLineWidthChanged(Uml::IDType)), this, SLOT(slotLineWidthChanged(Uml::IDType)));
1125
* Gets the x-coordinate.
1127
UMLSceneValue UMLWidget::x() const {
1128
return UMLSceneRectItem::x();
1131
* Gets the y-coordinate.
1133
UMLSceneValue UMLWidget::y() const {
1134
return UMLSceneRectItem::y();
1137
* Gets the z-coordinate.
1139
UMLSceneValue UMLWidget::z() const {
1140
return UMLSceneRectItem::z();
1065
1144
* Sets the x-coordinate.
1066
1145
* Currently, the only class that reimplements this method is
1067
1146
* ObjectWidget.
1069
1148
* @param x The x-coordinate to be set.
1071
void UMLWidget::setX(int x)
1150
void UMLWidget::setX(UMLSceneValue x)
1073
1152
if (!m_ignoreSnapToGrid) {
1074
1153
x = m_scene->snappedX(x);
1191
1269
* Sets the size.
1192
* If m_scene->getSnapComponentSizeToGrid() is true, then
1270
* If m_scene->snapComponentSizeToGrid() is true, then
1193
1271
* set the next larger size that snaps to the grid.
1195
1273
void UMLWidget::setSize(int width, int height)
1197
1275
// snap to the next larger size that is a multiple of the grid
1198
1276
if (!m_ignoreSnapComponentSizeToGrid
1199
&& m_scene->getSnapComponentSizeToGrid()) {
1277
&& m_scene->snapComponentSizeToGrid()) {
1200
1278
// integer divisions
1201
int numX = width / m_scene->getSnapX();
1202
int numY = height / m_scene->getSnapY();
1279
int numX = width / m_scene->snapX();
1280
int numY = height / m_scene->snapY();
1203
1281
// snap to the next larger valid value
1204
if (width > numX * m_scene->getSnapX())
1205
width = (numX + 1) * m_scene->getSnapX();
1206
if (height > numY * m_scene->getSnapY())
1207
height = (numY + 1) * m_scene->getSnapY();
1282
if (width > numX * m_scene->snapX())
1283
width = (numX + 1) * m_scene->snapX();
1284
if (height > numY * m_scene->snapY())
1285
height = (numY + 1) * m_scene->snapY();
1210
1288
UMLSceneRectItem::setSize(width, height);
1229
1307
void UMLWidget::clipSize()
1231
int width = getWidth();
1232
int height = getHeight();
1233
constrain(width, height);
1234
setSize(width, height);
1309
int clipWidth = width();
1310
int clipHeight = height();
1311
constrain(clipWidth, clipHeight);
1312
setSize(clipWidth, clipHeight);
1316
* Template Method, override this to set the default font metric.
1237
1318
void UMLWidget::setDefaultFontMetrics(UMLWidget::FontType fontType)
1239
1320
setupFontType(m_Font, fontType);
1294
1378
setFontMetrics(fontType, painter.fontMetrics());
1382
* Returns the font metric used by this object for Text
1383
* which uses bold/italic fonts.
1297
1385
QFontMetrics &UMLWidget::getFontMetrics(UMLWidget::FontType fontType)
1299
1387
if (m_pFontMetrics[fontType] == 0) {
1360
1451
* Set the status of whether to show Stereotype.
1362
* @param _status True if stereotype shall be shown.
1453
* @param flag True if stereotype shall be shown.
1364
void UMLWidget::setShowStereotype(bool _status)
1455
void UMLWidget::setShowStereotype(bool flag)
1366
m_showStereotype = _status;
1457
m_showStereotype = flag;
1367
1458
updateComponentSize();
1396
1487
WidgetBase::saveToXMI(qDoc, qElement);
1397
1488
qElement.setAttribute("xmi.id", ID2STR(id()));
1398
1489
qElement.setAttribute("font", m_Font.toString());
1399
qElement.setAttribute("x", getX());
1400
qElement.setAttribute("y", getY());
1401
qElement.setAttribute("width", getWidth());
1402
qElement.setAttribute("height", getHeight());
1490
qElement.setAttribute("x", x());
1491
qElement.setAttribute("y", y());
1492
qElement.setAttribute("width", width());
1493
qElement.setAttribute("height", height());
1403
1494
qElement.setAttribute("isinstance", m_isInstance);
1404
1495
if (!m_instanceName.isEmpty())
1405
1496
qElement.setAttribute("instancename", m_instanceName);