[Uml-devel] branches/work/soc-umbrello/umbrello
Gopala Krishna A
krishna.ggk at gmail.com
Sat Aug 30 10:30:10 UTC 2008
SVN commit 854790 by gopala:
* Implemented better delayed initialzation mechanism for
MessageWidget. The delayed initialzation for MessageWidget now
happens when the scene is set for the first time on widget.
* Create FloatingTextWidget in constructor (technically in init() ) so
that prompt for FloatingTextWidget's text works fine now. The
MessageText can now be set and displayed as before.
* Implemented Operation submenu for the context menu of MessageWidget.
* Extended delayed intialization functionality to include code of
MessageWidget::activate(). The latter method is removed now.
M +75 -96 messagewidget.cpp
M +13 -0 messagewidget.h
--- branches/work/soc-umbrello/umbrello/messagewidget.cpp #854789:854790
@@ -103,9 +103,16 @@
setIgnoreSnapToGrid(true);
setIgnoreSnapComponentSizeToGrid(true);
m_objectWidgets[Uml::A] = m_objectWidgets[Uml::B] = 0;
- m_floatingTextWidget = 0;
- QTimer::singleShot(10, this, SLOT(slotDelayedInit()));
- uDebug() << "Created";
+
+ Uml::Text_Role tr = Uml::tr_Seq_Message;
+ m_floatingTextWidget = new FloatingTextWidget( tr );
+ m_floatingTextWidget->setFont(font());
+ m_floatingTextWidget->setLink(this);
+ m_floatingTextWidget->hide(); // Hide initially until a text is set
+
+ m_isMsgSceneSetBefore = false;
+ // Some delayed initialization is done when a new UMLScene is set
+ // on this widget for the first time. (see slotDelayedInit)
}
/// Destructor. Inform Object widgets about destruction.
@@ -163,6 +170,7 @@
setUMLObject(op);
if (umlObject() && m_floatingTextWidget)
connect(umlObject(), SIGNAL(modified()), m_floatingTextWidget, SLOT(setMessageText()));
+ m_floatingTextWidget->setMessageText();
}
/**
@@ -192,10 +200,11 @@
*/
void MessageWidget::setMessageText(FloatingTextWidget *ft)
{
- if (ft == NULL)
+ if (!ft)
return;
QString displayText = m_sequenceNumber + ": " + LinkWidget::getOperationText(umlScene());
ft->setText(displayText);
+ show();
setTextPosition();
}
@@ -437,6 +446,21 @@
return qMin(heightA, heightB);
}
+/**
+ * Reimplemented from NewUMLRectWidget::setupContextMenuActions to add
+ * a submenu to change the text of the FloatingTextWidget of this
+ * message widget.
+ */
+void MessageWidget::setupContextMenuActions(ListPopupMenu &menu)
+{
+ //TODO: Investigate the constructor parameters.
+ ListPopupMenu* floatingtextSubMenu = new ListPopupMenu(&menu, m_floatingTextWidget, 0, 0);
+ floatingtextSubMenu->setTitle( i18n( "Operation" ) );
+
+ menu.addMenu( floatingtextSubMenu );
+ // The floatingtextSubMenu is destroyed automatically when menu is destroyed.
+}
+
bool MessageWidget::loadFromXMI(QDomElement& qElement)
{
if ( !NewUMLRectWidget::loadFromXMI(qElement) ) {
@@ -591,6 +615,20 @@
m_objectWidgets[Uml::B]->adjustSequentialLineEnd();
}
}
+ else if (change == ItemSceneHasChanged) {
+ if (!m_isMsgSceneSetBefore) {
+ m_isMsgSceneSetBefore = true;
+ // Use timer to disambiguate situation where virtual
+ // functions might not call be called
+ // appropriately.
+
+ // Also, set the timeout to higher value than the one
+ // used in NewUMLWidget::itemChange so that the base's
+ // delayed initialization is done before.
+
+ QTimer::singleShot(100, this, SLOT(slotDelayedInit()));
+ }
+ }
}
return NewUMLRectWidget::itemChange(change, value);
}
@@ -861,105 +899,46 @@
void MessageWidget::slotDelayedInit()
{
- ObjectWidget *objA = m_objectWidgets[Uml::A];
- ObjectWidget *objB = m_objectWidgets[Uml::B];
+ // Get reference to pointers.
+ ObjectWidget *&objA = m_objectWidgets[Uml::A];
+ ObjectWidget *&objB = m_objectWidgets[Uml::B];
- if (objA) {
- objA->messageAdded(this);
- handleObjectMove(objA);
- objA->adjustSequentialLineEnd();
+ updateResizability();
+
+ if (!objA || !objB) {
+ return;
}
- if (objB && objB != objA) {
+ UMLClassifier *c = dynamic_cast<UMLClassifier*>(objB->umlObject());
+ UMLOperation *op = 0;
+ if (c && !m_customOperation.isEmpty()) {
+ Uml::IDType opId = STR2ID(m_customOperation);
+ op = dynamic_cast<UMLOperation*>( c->findChildObjectById(opId, true) );
+ if (op) {
+ // If the UMLOperation is set, m_customOperation isn't used anyway.
+ // Just setting it empty for the sake of sanity.
+ m_customOperation.clear();
+ }
+ }
+
+ if (op) {
+ setOperation(op); // This requires a valid m_floatingTextWidget.
+ }
+
+ if (objA == objB) {
+ m_floatingTextWidget->setTextRole(Uml::tr_Seq_Message_Self);
+ }
+ setLinkAndTextPos();
+
+ objA->messageAdded(this);
+ handleObjectMove(objA);
+ objA->adjustSequentialLineEnd();
+
+ if (objB != objA) {
objB->messageAdded(this);
handleObjectMove(objB);
objB->adjustSequentialLineEnd();
}
}
-// bool MessageWidget::activate(IDChangeLog * /*Log = 0*/) {
-// umlScene()->resetPastePoint();
-// // NewUMLRectWidget::activate(Log); CHECK: I don't think we need this ?
-// if (m_objectWidgets[Uml::A] == NULL) {
-// NewUMLRectWidget *pWA = umlScene()->findWidget(m_widgetAId);
-// if (pWA == NULL) {
-// uDebug() << "role A object " << ID2STR(m_widgetAId) << " not found" << endl;
-// return false;
-// }
-// m_objectWidgets[Uml::A] = dynamic_cast<ObjectWidget*>(pWA);
-// if (m_objectWidgets[Uml::A] == NULL) {
-// uDebug() << "role A widget " << ID2STR(m_widgetAId)
-// << " is not an ObjectWidget" << endl;
-// return false;
-// }
-// }
-// if (m_objectWidgets[Uml::B] == NULL) {
-// NewUMLRectWidget *pWB = umlScene()->findWidget(m_widgetBId);
-// if (pWB == NULL) {
-// uDebug() << "role B object " << ID2STR(m_widgetBId) << " not found" << endl;
-// return false;
-// }
-// m_objectWidgets[Uml::B] = dynamic_cast<ObjectWidget*>(pWB);
-// if (m_objectWidgets[Uml::B] == NULL) {
-// uDebug() << "role B widget " << ID2STR(m_widgetBId)
-// << " is not an ObjectWidget" << endl;
-// return false;
-// }
-// }
-// updateResizability();
-
-// UMLClassifier *c = dynamic_cast<UMLClassifier*>(m_objectWidgets[Uml::B]->getUMLObject());
-// UMLOperation *op = NULL;
-// if (c && !m_customOperation.isEmpty()) {
-// Uml::IDType opId = STR2ID(m_customOperation);
-// op = dynamic_cast<UMLOperation*>( c->findChildObjectById(opId, true) );
-// if (op) {
-// // If the UMLOperation is set, m_customOperation isn't used anyway.
-// // Just setting it empty for the sake of sanity.
-// m_customOperation.clear();
-// }
-// }
-
-// if( !m_floatingTextWidget ) {
-// Uml::Text_Role tr = Uml::tr_Seq_Message;
-// if (m_objectWidgets[Uml::A] == m_objectWidgets[Uml::B])
-// tr = Uml::tr_Seq_Message_Self;
-// m_floatingTextWidget = new FloatingTextWidget( tr );
-// m_floatingTextWidget->setFont(font());
-// }
-// if (op)
-// setOperation(op); // This requires a valid m_floatingTextWidget.
-// setLinkAndTextPos();
-// m_floatingTextWidget->setText("");
-// m_floatingTextWidget->setActivated();
-// QString messageText = m_floatingTextWidget->text();
-// m_floatingTextWidget->setVisible( messageText.length() > 1 );
-
-// connect(m_objectWidgets[Uml::A], SIGNAL(sigWidgetMoved(Uml::IDType)), this, SLOT(slotWidgetMoved(Uml::IDType)));
-// connect(m_objectWidgets[Uml::B], SIGNAL(sigWidgetMoved(Uml::IDType)), this, SLOT(slotWidgetMoved(Uml::IDType)));
-
-// connect(this, SIGNAL(sigMessageMoved()), m_objectWidgets[Uml::A], SLOT(slotMessageMoved()) );
-// connect(this, SIGNAL(sigMessageMoved()), m_objectWidgets[Uml::B], SLOT(slotMessageMoved()) );
-// m_objectWidgets[Uml::A]->messageAdded(this);
-// m_objectWidgets[Uml::B]->messageAdded(this);
-// calculateDimensions();
-
-// emit sigMessageMoved();
-// return true;
-// }
-
-
-// ListPopupMenu* MessageWidget::setupPopupMenu() {
-
-// NewUMLRectWidget::setupPopupMenu( ); // will setup the menu in m_pMenu
-// ListPopupMenu* floatingtextSubMenu = m_floatingTextWidget->setupPopupMenu();
-// floatingtextSubMenu->setTitle( i18n( "Operation" ) );
-
-// m_pMenu->addMenu( floatingtextSubMenu );
-
-// return m_pMenu;
-// }
-
-
-
#include "messagewidget.moc"
--- branches/work/soc-umbrello/umbrello/messagewidget.h #854789:854790
@@ -137,6 +137,8 @@
qreal minY() const;
qreal maxY() const;
+ virtual void setupContextMenuActions(ListPopupMenu &menu);
+
virtual bool loadFromXMI( QDomElement & qElement );
virtual void saveToXMI( QDomDocument & qDoc, QDomElement & qElement );
@@ -176,6 +178,17 @@
*/
QPointF m_clickedPoint;
+ /**
+ * A state variable to keep track of initialization which has to
+ * happen only once when the scene is set for the first time.
+ *
+ * @note There is an identicle variable in NewUMLWidget called
+ * m_isSceneSetBefore. But we can't use it as that variable
+ * is for base intialization and hence that is delibarately
+ * made private.
+ */
+ bool m_isMsgSceneSetBefore;
+
/// Whether the message is synchronous or asynchronous
Uml::Sequence_Message_Type m_sequenceMessageType;
More information about the umbrello-devel
mailing list