Commit 69f447eb authored by Oliver Kellogg's avatar Oliver Kellogg
Browse files

merge master@8f5cdde

parents f1e73f10 8f5cdde1
......@@ -352,6 +352,7 @@ set(libwidgets_SRCS
widgets/objectnodewidget.cpp
widgets/objectwidget.cpp
widgets/packagewidget.cpp
widgets/pinportbase.cpp
widgets/pinwidget.cpp
widgets/portwidget.cpp
widgets/preconditionwidget.cpp
......
......@@ -27,7 +27,7 @@
#include "model_utils.h"
#include "objectnodewidget.h"
#include "objectwidget.h"
#include "portwidget.h"
#include "pinportbase.h"
#include "preconditionwidget.h"
#include "signalwidget.h"
#include "statewidget.h"
......@@ -389,8 +389,8 @@ void ListPopupMenu::insertSingleSelectionMenu(WidgetBase* object)
insert(mt_Rename);
insert(mt_NameAsTooltip, i18n("Name as Tooltip"), CHECKABLE);
{
PortWidget *portW = static_cast<PortWidget*>(object);
FloatingTextWidget *ft = portW->floatingTextWidget();
PinPortBase *pW = static_cast<PinPortBase*>(object);
FloatingTextWidget *ft = pW->floatingTextWidget();
if (ft == NULL)
m_actions[mt_NameAsTooltip]->setChecked(true);
}
......@@ -535,6 +535,13 @@ void ListPopupMenu::insertSingleSelectionMenu(WidgetBase* object)
insert(mt_Clear, Icon_Utils::SmallIcon(Icon_Utils::it_Clear), i18nc("clear precondition", "Clear"));
addSeparator();
insert(mt_Rename, i18n("Change Text..."));
if (type == WidgetBase::wt_Pin) {
insert(mt_NameAsTooltip, i18n("Name as Tooltip"), CHECKABLE);
PinPortBase *pW = static_cast<PinPortBase*>(object);
FloatingTextWidget *ft = pW->floatingTextWidget();
if (ft == NULL)
m_actions[mt_NameAsTooltip]->setChecked(true);
}
insert(mt_Delete);
insert(mt_Change_Font);
break;
......
......@@ -432,9 +432,9 @@ bool UMLDoc::openDocument(const KUrl& url, const char* format /* =0 */)
// check if the xmi file is a compressed archive like tar.bzip2 or tar.gz
QString filetype = m_doc_url.fileName();
QString mimetype = "";
if (filetype.indexOf(QRegExp("\\.tgz$")) != -1) {
if (filetype.endsWith(".tgz") || filetype.endsWith(".tar.gz")) {
mimetype = "application/x-gzip";
} else if (filetype.indexOf(QRegExp("\\.tar.bz2$")) != -1) {
} else if (filetype.endsWith(".tar.bz2")) {
mimetype = "application/x-bzip";
}
......@@ -1319,8 +1319,7 @@ QString UMLDoc::createDiagramName(Uml::DiagramType::Enum type, bool askForName /
*
* @param folder the folder in which tp create the diagram.
* @param type the type of diagram to create
* @param name if true shows a dialog box asking for name,
* else uses a default name
* @param name the name for the diagram to create
* @param id optional ID of new diagram
* @return pointer to the UMLView of the new diagram
*/
......
......@@ -790,7 +790,8 @@ UMLListViewItem *UMLListView::findFolderForDiagram(Uml::DiagramType::Enum dt)
*/
void UMLListView::slotDiagramCreated(Uml::ID::Type id)
{
if (m_doc->loading()) {
if (findItem(id)) {
uDebug() << "list view item " << Uml::ID::toString(id) << " already exists";
return;
}
UMLView *v = m_doc->findView(id);
......@@ -1107,8 +1108,8 @@ void UMLListView::slotDiagramRenamed(Uml::ID::Type id)
}
/**
* Sets the document his is associated with. This is important as
* this is required as to setup the callbacks.
* Sets the document this is associated with. This is important as
* this is required as to set up the callbacks.
*
* @param doc The document to associate with this class.
*/
......
......@@ -25,7 +25,7 @@
#include "classoptionspage.h"
#include "cmds.h"
#include "componentwidget.h"
#include "portwidget.h"
#include "pinportbase.h"
#include "datatypewidget.h"
#include "debug_utils.h"
#include "docwindow.h"
......@@ -540,8 +540,9 @@ void UMLScene::print(QPrinter *pPrinter, QPainter & pPainter)
void UMLScene::setupNewWidget(UMLWidget *w, bool setPosition)
{
if (setPosition) {
if (w->baseType() == WidgetBase::wt_Port) {
PortWidget *pw = static_cast<PortWidget*>(w);
if (w->baseType() == WidgetBase::wt_Pin ||
w->baseType() == WidgetBase::wt_Port) {
PinPortBase *pw = static_cast<PinPortBase*>(w);
pw->attachToOwningComponent();
} else if (w->baseType() != WidgetBase::wt_Object) {
// ObjectWidget's position is handled by the widget
......
......@@ -27,6 +27,6 @@ inline QByteArray umbrelloVersion()
}
// Update this version when changing the XMI file format
#define XMI_FILE_VERSION "1.6.7"
#define XMI_FILE_VERSION "1.6.8"
#endif
......@@ -297,6 +297,15 @@ void ActivityWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *op
UMLWidget::paint(painter, option, widget);
}
/**
* Overridden from UMLWidget due to emission of signal sigActMoved()
*/
void ActivityWidget::moveWidgetBy(qreal diffX, qreal diffY)
{
UMLWidget::moveWidgetBy(diffX, diffY);
emit sigActMoved(diffX, diffY);
}
/**
* Loads the widget from the "activitywidget" XMI element.
*/
......
......@@ -64,12 +64,24 @@ public:
virtual void showPropertiesDialog();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual void moveWidgetBy(qreal diffX, qreal diffY);
virtual bool loadFromXMI(QDomElement & qElement);
virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
void constrain(qreal& width, qreal& height);
signals:
/**
* Emitted when the activity widget is moved.
* Provides the delta X and delta Y amount by which the widget was moved
* relative to the previous position.
* Slots into PinWidget::slotActMoved()
* @param diffX The difference between previous and new X value.
* @param diffY The difference between previous and new Y value.
*/
void sigActMoved(qreal diffX, qreal diffY);
public Q_SLOTS:
virtual void slotMenuSelection(QAction* action);
......
......@@ -45,6 +45,8 @@ signals:
* Provides the delta X and delta Y amount by which the widget was moved
* relative to the previous position.
* Slots into PortWidget::slotCompMoved()
* @param diffX The difference between previous and new X value.
* @param diffY The difference between previous and new Y value.
*/
void sigCompMoved(qreal diffX, qreal diffY);
......
/***************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2014 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
// own header
#include "pinportbase.h"
// app includes
#include "port.h"
#include "package.h"
#include "debug_utils.h"
#include "umldoc.h"
#include "umlscene.h"
#include "umlview.h"
#include "floatingtextwidget.h"
// qt includes
#include <QPainter>
#include <QToolTip>
// sys includes
#include <cmath>
PinPortBase::PinPortBase(UMLScene *scene, WidgetType type, UMLObject *o)
: UMLWidget(scene, type, o)
{
init();
}
PinPortBase::PinPortBase(UMLScene *scene, WidgetType type, UMLWidget *a, Uml::ID::Type id)
: UMLWidget(scene, type, id)
{
init(a);
}
/**
* Standard destructor.
*/
PinPortBase::~PinPortBase()
{
}
/**
* Perfoms initializations which are common to PinWidget and PortWidget.
*/
void PinPortBase::init(UMLWidget *owner)
{
m_ignoreSnapToGrid = true;
m_ignoreSnapComponentSizeToGrid = true;
m_resizable = false;
m_pOw = owner;
m_pName = NULL;
m_motionConnected = false;
const int edgeLength = 15; // old: (m_baseType == wt_Pin ? 10 : 15);
const QSizeF FixedSize(edgeLength, edgeLength);
setMinimumSize(FixedSize);
setMaximumSize(FixedSize);
setSize(FixedSize);
}
UMLWidget* PinPortBase::ownerWidget()
{
return m_pOw;
}
/**
* Overrides method from UMLWidget in order to set a tooltip.
* The tooltip is set to the name().
* The reason for using a tooltip for the name is that the size of this
* widget is not large enough to accomodate the average name.
*/
void PinPortBase::updateWidget()
{
QString strName = name();
uDebug() << " port name is " << strName;
if (m_pName) {
m_pName->setText(strName);
} else {
setToolTip(strName);
}
}
/**
* Overrides method from UMLWidget to set the name.
*/
void PinPortBase::setName(const QString &strName)
{
UMLWidget::setName(strName);
updateGeometry();
if (m_pName) {
m_pName->setText(strName);
}
}
/**
* Overridden from UMLWidget.
* Moves the widget to a new position using the difference between the
* current position and the new position.
* Movement is constrained such that the port is always attached to its
* owner widget.
*
* @param diffX The difference between current X position and new X position.
* @param diffY The difference between current Y position and new Y position.
*/
void PinPortBase::moveWidgetBy(qreal diffX, qreal diffY)
{
UMLWidget* owner = ownerWidget();
qreal newX = x() + diffX;
qreal newY = y() + diffY;
uDebug() << "PinPortBase::moveWidgetBy " << diffX << "," << diffY;
if (owner == NULL) {
uError() << "PinPortBase::moveWidgetBy: ownerWidget() returns NULL";
setX(newX);
setY(newY);
return;
}
const qreal deltaTop = fabs(y() + height() - owner->y());
const qreal deltaBottom = fabs(owner->y() + owner->height() - y());
const qreal deltaLeft = fabs(x() + width() - owner->x());
const qreal deltaRight = fabs(owner->x() + owner->width() - x());
bool didAnyMovement = false;
if (deltaTop < 1.0 || deltaBottom < 1.0) {
if (newX < owner->x() - width())
newX = owner->x() - width();
else if (newX > owner->x() + owner->width())
newX = owner->x() + owner->width();
setX(newX);
didAnyMovement = true;
}
if (deltaLeft < 1.0 || deltaRight < 1.0) {
if (newY < owner->y() - height())
newY = owner->y() - height();
else if (newY > owner->y() + owner->height())
newY = owner->y() + owner->height();
setY(newY);
didAnyMovement = true;
}
if (!didAnyMovement) {
uDebug() << "constraint failed for (" << diffX << ", " << diffY << ")";
setX(newX);
setY(newY);
}
}
/**
* Align this widget's position such that it is attached at one of the
* sides of its owner's widget.
*/
void PinPortBase::attachToOwner() {
UMLWidget *owner = ownerWidget();
const QPointF scenePos = m_scene->pos();
if (owner == NULL) {
uError() << "PinPortBase::attachToOwner: ownerWidget() returns NULL";
setX(scenePos.x());
setY(scenePos.y());
return;
}
bool xIsWithinOwner = false;
if (scenePos.x() < owner->x() - width()) {
setX(owner->x() - width());
} else if (scenePos.x() <= owner->x() + owner->width()) {
setX(scenePos.x());
xIsWithinOwner = true;
} else {
setX(owner->x() + owner->width());
}
if (scenePos.y() < owner->y() - height()) {
setY(owner->y() - height());
} else if (scenePos.y() <= owner->y() + owner->height()) {
if (xIsWithinOwner) {
if (scenePos.y() <= owner->y() + owner->height() / 2.0)
setY(owner->y() - height());
else
setY(owner->y() + owner->height());
} else {
setY(scenePos.y());
}
} else {
setY(owner->y() + owner->height());
}
if (m_motionConnected) {
uDebug() << "connectOwnerMotion was already done";
} else {
connectOwnerMotion();
m_motionConnected = true;
}
}
/**
* Overrides standard method.
*/
void PinPortBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
setPenFromSettings(painter);
if (UMLWidget::useFillColor()) {
painter->setBrush(UMLWidget::fillColor());
} else {
painter->setBrush(m_scene->activeView()->viewport()->palette().color(QPalette::Background));
}
int w = width();
int h = height();
painter->drawRect(0, 0, w, h);
UMLWidget::paint(painter, option, widget);
}
void PinPortBase::slotOwnerMoved(qreal diffX, qreal diffY)
{
setX(x() + diffX);
setY(y() + diffY);
}
/**
* Captures any popup menu signals for menus it created.
*/
void PinPortBase::slotMenuSelection(QAction* action)
{
ListPopupMenu::MenuType sel = ListPopupMenu::typeFromAction(action);
switch(sel) {
case ListPopupMenu::mt_NameAsTooltip:
if (m_pName) {
action->setChecked(true);
delete m_pName;
m_pName = NULL;
setToolTip(name());
} else {
action->setChecked(false);
m_pName = new FloatingTextWidget(m_scene, Uml::TextRole::Floating, name());
m_pName->setParentItem(this);
m_pName->setText(name()); // to get geometry update
m_pName->activate();
UMLWidget* owner = ownerWidget();
if (owner == NULL) {
uError() << "PinPortBase::slotMenuSelection: ownerWidget() returns NULL";
setX(x());
setY(y());
} else {
const qreal w = width();
const qreal h = height();
if (x() < owner->x())
m_pName->setX(-m_pName->width());
else if (x() >= owner->x() + owner->width())
m_pName->setX(w);
else
m_pName->setX(-m_pName->width() / 2.0 + w / 2.0);
if (y() < owner->y())
m_pName->setY(-m_pName->height() - 2);
else if (y() >= owner->y() + owner->height())
m_pName->setY(h);
else
m_pName->setY(-m_pName->height() / 2.0 + h / 2.0);
}
m_pName->update();
setToolTip(QString());
QToolTip::hideText();
}
break;
default:
UMLWidget::slotMenuSelection(action);
}
}
FloatingTextWidget *PinPortBase::floatingTextWidget() {
return m_pName;
}
void PinPortBase::setFloatingTextWidget(FloatingTextWidget *ft) {
m_pName = ft;
if (m_pName)
m_pName->setParentItem(this);
}
/**
* Override method from UMLWidget in order to additionally check m_pName.
*
* @param p Point to be checked.
*
* @return 'this' if UMLWidget::onWidget(p) returns non NULL;
* m_pName if m_pName is non NULL and m_pName->onWidget(p) returns non NULL;
* else NULL.
*/
UMLWidget* PinPortBase::onWidget(const QPointF &p)
{
if (UMLWidget::onWidget(p) != NULL)
return this;
if (m_pName) {
uDebug() << "floatingtext: " << m_pName->text();
return m_pName->onWidget(p);
}
return NULL;
}
/**
* Reimplement function from UMLWidget
*/
UMLWidget* PinPortBase::widgetWithID(Uml::ID::Type id)
{
if (UMLWidget::widgetWithID(id))
return this;
if (m_pName && m_pName->widgetWithID(id))
return m_pName;
return NULL;
}
/**
* Saves the widget to the "pinwidget" or "portwidget" XMI element.
*/
void PinPortBase::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
{
QDomElement element = qDoc.createElement(m_baseType == wt_Pin ? "pinwidget" : "portwidget");
element.setAttribute("widgetaid", Uml::ID::toString(ownerWidget()->id()));
UMLWidget::saveToXMI(qDoc, element);
if (m_pName && !m_pName->text().isEmpty()) {
m_pName->saveToXMI(qDoc, element);
}
qElement.appendChild(element);
}
/**
* Loads from a "pinwidget" or from a "portwidget" XMI element.
*/
bool PinPortBase::loadFromXMI(QDomElement & qElement)
{
if (!UMLWidget::loadFromXMI(qElement))
return false;
QString widgetaid = qElement.attribute("widgetaid", "-1");
Uml::ID::Type aId = Uml::ID::fromString(widgetaid);
UMLWidget *owner = m_scene->findWidget(aId);
if (owner == NULL) {
DEBUG(DBG_SRC) << "owner object " << Uml::ID::toString(aId) << " not found";
return false;
}
m_pOw = owner;
// Optional child element: floatingtext
QDomNode node = qElement.firstChild();
QDomElement element = node.toElement();
if (!element.isNull()) {
QString tag = element.tagName();
if (tag == "floatingtext") {
m_pName = new FloatingTextWidget(m_scene, Uml::TextRole::Floating,
name(), Uml::ID::Reserved);
if (!m_pName->loadFromXMI(element)) {
// Most likely cause: The FloatingTextWidget is empty.
delete m_pName;
m_pName = NULL;
} else {
m_pName->setParentItem(this);
m_pName->activate();
m_pName->update();
}
} else {
uError() << "unknown tag " << tag;
}
}
if (m_motionConnected) {
uDebug() << "connectOwnerMotion was already done";
} else {
connectOwnerMotion();
m_motionConnected = true;
}
return true;
}
#include "pinportbase.moc"
/***************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2014 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
#ifndef PINPORTBASE_H
#define PINPORTBASE_H
#include "umlwidget.h"
class FloatingTextWidget;
/**
* @short Abstract base class for PinWidget and PortWidget
* @author Oliver Kellogg
* @see UMLWidget
* Bugs and comments to umbrello-devel@kde.org or http://bugs.kde.org
*/
class PinPortBase : public UMLWidget
{
Q_OBJECT
public:
PinPortBase(UMLScene *scene, WidgetType type, UMLObject *o);
PinPortBase(UMLScene *scene, WidgetType type, UMLWidget *a, Uml::ID::Type id = Uml::ID::None);
virtual ~PinPortBase();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
virtual UMLWidget* ownerWidget();
virtual void connectOwnerMotion() = 0;
void setName(const QString &strName);
void updateWidget();
void moveWidgetBy(qreal diffX, qreal diffY);
void attachToOwner();
UMLWidget* onWidget(const QPointF& p);
UMLWidget* widgetWithID(Uml::ID::Type id);
FloatingTextWidget *floatingTextWidget();
void setFloatingTextWidget(FloatingTextWidget *ft);
void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
bool loadFromXMI(QDomElement& qElement);
public slots:
void slotOwnerMoved(qreal diffX, qreal diffY);
virtual void slotMenuSelection(QAction* action);
protected:
void init(UMLWidget *owner = 0);
UMLWidget* m_pOw;
FloatingTextWidget *m_pName;