You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
392 lines
11 KiB
C++
392 lines
11 KiB
C++
/***************************************************************************
|
|
* *
|
|
* 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) 2004-2007 *
|
|
* Umbrello UML Modeller Authors <uml-devel@uml.sf.net> *
|
|
***************************************************************************/
|
|
|
|
// own header
|
|
#include "aligntoolbar.h"
|
|
|
|
// system includes
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
// qt includes
|
|
#include <tqmainwindow.h>
|
|
|
|
// kde includes
|
|
#include <tdelocale.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kstandarddirs.h>
|
|
|
|
// app includes
|
|
#include "uml.h"
|
|
#include "umldoc.h"
|
|
#include "umlview.h"
|
|
#include "umlwidget.h"
|
|
#include "umlwidgetlist.h"
|
|
|
|
AlignToolBar::AlignToolBar(TQMainWindow* parentWindow, const char* )
|
|
: TDEToolBar(parentWindow,TQt::DockRight,false) {
|
|
// load images for the buttons
|
|
loadPixmaps();
|
|
|
|
// create the buttons
|
|
insertButton(m_Pixmaps[alac_align_left], alac_align_left, true, i18n("Align Left"));
|
|
insertButton(m_Pixmaps[alac_align_right], alac_align_right, true, i18n("Align Right"));
|
|
insertButton(m_Pixmaps[alac_align_top], alac_align_top, true, i18n("Align Top"));
|
|
insertButton(m_Pixmaps[alac_align_bottom], alac_align_bottom, true, i18n("Align Bottom"));
|
|
insertButton(m_Pixmaps[alac_align_vertical_middle], alac_align_vertical_middle, true, i18n("AlignQt::Vertical Middle"));
|
|
insertButton(m_Pixmaps[alac_align_horizontal_middle], alac_align_horizontal_middle, true, i18n("AlignQt::Horizontal Middle"));
|
|
insertButton(m_Pixmaps[alac_align_vertical_distribute], alac_align_vertical_distribute, true, i18n("AlignQt::Vertical Distribute"));
|
|
insertButton(m_Pixmaps[alac_align_horizontal_distribute], alac_align_horizontal_distribute, true, i18n("AlignQt::Horizontal Distribute"));
|
|
|
|
setOrientation( Qt::Vertical );
|
|
setVerticalStretchable( true );
|
|
|
|
// gets called whenever a button in the toolbar is clicked
|
|
connect( this, TQT_SIGNAL( released( int ) ), this, TQT_SLOT( slotButtonChanged (int ) ) );
|
|
}
|
|
|
|
AlignToolBar::~AlignToolBar() {
|
|
}
|
|
|
|
/* ------ private functions ------ */
|
|
|
|
bool AlignToolBar::hasWidgetSmallerX(const UMLWidget* widget1, const UMLWidget* widget2) {
|
|
return widget1->getX() < widget2->getX();
|
|
}
|
|
|
|
bool AlignToolBar::hasWidgetSmallerY(const UMLWidget* widget1, const UMLWidget* widget2) {
|
|
return widget1->getY() < widget2->getY();
|
|
}
|
|
|
|
void AlignToolBar::loadPixmaps() {
|
|
TDEStandardDirs* dirs = TDEGlobal::dirs();
|
|
TQString dataDir = dirs->findResourceDir( "data", "umbrello/pics/object.png" );
|
|
dataDir += "/umbrello/pics/";
|
|
|
|
m_Pixmaps[alac_align_left].load( dataDir + "align_left.png" );
|
|
m_Pixmaps[alac_align_right].load( dataDir + "align_right.png" );
|
|
m_Pixmaps[alac_align_top].load( dataDir + "align_top.png" );
|
|
m_Pixmaps[alac_align_bottom].load( dataDir + "align_bottom.png" );
|
|
m_Pixmaps[alac_align_vertical_middle].load( dataDir + "align_vert_middle.png" );
|
|
m_Pixmaps[alac_align_horizontal_middle].load( dataDir + "align_hori_middle.png" );
|
|
m_Pixmaps[alac_align_vertical_distribute].load( dataDir + "align_vert_distribute.png" );
|
|
m_Pixmaps[alac_align_horizontal_distribute].load( dataDir + "align_hori_distribute.png" );
|
|
|
|
return;
|
|
}
|
|
|
|
int AlignToolBar::getSmallestX(const UMLWidgetList &widgetList) {
|
|
UMLWidgetListIt it(widgetList);
|
|
UMLWidget* widget;
|
|
|
|
int smallestX = it.toFirst()->getX();
|
|
++it;
|
|
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
if (smallestX > widget->getX())
|
|
smallestX = widget->getX();
|
|
}
|
|
|
|
return smallestX;
|
|
}
|
|
|
|
int AlignToolBar::getSmallestY(const UMLWidgetList &widgetList) {
|
|
UMLWidgetListIt it(widgetList);
|
|
UMLWidget* widget;
|
|
|
|
int smallestY = it.toFirst()->getY();
|
|
++it;
|
|
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
if (smallestY > widget->getY())
|
|
smallestY = widget->getY();
|
|
}
|
|
|
|
return smallestY;
|
|
}
|
|
|
|
int AlignToolBar::getBiggestX(const UMLWidgetList &widgetList) {
|
|
UMLWidgetListIt it(widgetList);
|
|
UMLWidget* widget;
|
|
|
|
int biggestX = it.toFirst()->getX();
|
|
biggestX += it.current()->getWidth();
|
|
++it;
|
|
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
if (biggestX < widget->getX() + widget->getWidth())
|
|
biggestX = widget->getX() + widget->getWidth();
|
|
}
|
|
|
|
return biggestX;
|
|
}
|
|
|
|
int AlignToolBar::getBiggestY(const UMLWidgetList &widgetList) {
|
|
UMLWidgetListIt it(widgetList);
|
|
UMLWidget* widget;
|
|
|
|
int biggestY = it.toFirst()->getY();
|
|
biggestY += it.current()->getHeight();
|
|
++it;
|
|
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
if (biggestY < widget->getY() + widget->getHeight())
|
|
biggestY = widget->getY() + widget->getHeight();
|
|
}
|
|
|
|
return biggestY;
|
|
}
|
|
|
|
int AlignToolBar::getHeightsSum(const UMLWidgetList &widgetList) {
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
int heightsSum = 0;
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
heightsSum += widget->getHeight();
|
|
}
|
|
|
|
return heightsSum;
|
|
}
|
|
|
|
int AlignToolBar::getWidthsSum(const UMLWidgetList &widgetList) {
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
int widthsSum = 0;
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widthsSum += widget->getWidth();
|
|
}
|
|
|
|
return widthsSum;
|
|
}
|
|
|
|
void AlignToolBar::alignLeft(UMLWidgetList &widgetList) {
|
|
int smallestX = getSmallestX(widgetList);
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setX(smallestX);
|
|
}
|
|
}
|
|
|
|
void AlignToolBar::alignRight(UMLWidgetList &widgetList) {
|
|
int biggestX = getBiggestX(widgetList);
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setX(biggestX - widget->getWidth());
|
|
}
|
|
}
|
|
|
|
void AlignToolBar::alignTop(UMLWidgetList &widgetList) {
|
|
int smallestY = getSmallestY(widgetList);
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setY(smallestY);
|
|
}
|
|
}
|
|
|
|
void AlignToolBar::alignBottom(UMLWidgetList &widgetList) {
|
|
int biggestY = getBiggestY(widgetList);
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setY(biggestY - widget->getHeight());
|
|
}
|
|
}
|
|
|
|
void AlignToolBar::alignVerticalMiddle(UMLWidgetList &widgetList) {
|
|
int smallestX = getSmallestX(widgetList);
|
|
int biggestX = getBiggestX(widgetList);
|
|
int middle = int((biggestX - smallestX) / 2) + smallestX;
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setX(middle - int(widget->getWidth() / 2));
|
|
}
|
|
}
|
|
|
|
void AlignToolBar::alignHorizontalMiddle(UMLWidgetList &widgetList) {
|
|
int smallestY = getSmallestY(widgetList);
|
|
int biggestY = getBiggestY(widgetList);
|
|
int middle = int((biggestY - smallestY) / 2) + smallestY;
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setY(middle - int(widget->getHeight() / 2));
|
|
}
|
|
}
|
|
|
|
void AlignToolBar::alignVerticalDistribute(UMLWidgetList &widgetList) {
|
|
int smallestY = getSmallestY(widgetList);
|
|
int biggestY = getBiggestY(widgetList);
|
|
int heightsSum = getHeightsSum(widgetList);
|
|
int distance = int(((biggestY - smallestY) - heightsSum) / (widgetList.count()-1.0) + 0.5);
|
|
|
|
sortWidgetList(widgetList, hasWidgetSmallerY);
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it = UMLWidgetListIt(widgetList);
|
|
|
|
UMLWidget* widgetPrev = it.toFirst();
|
|
++it;
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setY(widgetPrev->getY() + widgetPrev->getHeight() + distance);
|
|
widgetPrev = widget;
|
|
}
|
|
}
|
|
|
|
void AlignToolBar::alignHorizontalDistribute(UMLWidgetList &widgetList) {
|
|
int smallestX = getSmallestX(widgetList);
|
|
int biggestX = getBiggestX(widgetList);
|
|
int widthsSum = getWidthsSum(widgetList);
|
|
int distance = int(((biggestX - smallestX) - widthsSum) / (widgetList.count()-1.0) + 0.5);
|
|
|
|
sortWidgetList(widgetList, hasWidgetSmallerX);
|
|
|
|
UMLWidget* widget;
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
it = UMLWidgetListIt(widgetList);
|
|
|
|
UMLWidget* widgetPrev = it.toFirst();
|
|
++it;
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->setX(widgetPrev->getX() + widgetPrev->getWidth() + distance);
|
|
widgetPrev = widget;
|
|
}
|
|
}
|
|
|
|
template<typename Compare>
|
|
void AlignToolBar::sortWidgetList(UMLWidgetList &widgetList, Compare comp) {
|
|
std::vector<UMLWidget*> widgetVector;
|
|
UMLWidgetListIt it(widgetList);
|
|
while (it.current() != 0) {
|
|
widgetVector.push_back(*it);
|
|
++it;
|
|
}
|
|
sort(widgetVector.begin(), widgetVector.end(), comp);
|
|
|
|
widgetList.clear();
|
|
|
|
for (std::vector<UMLWidget*>::iterator it=widgetVector.begin(); it != widgetVector.end(); ++it) {
|
|
widgetList.append(*it);
|
|
}
|
|
}
|
|
|
|
/* ------ private slots ------ */
|
|
|
|
void AlignToolBar::slotButtonChanged(int btn) {
|
|
UMLView* view = UMLApp::app()->getCurrentView();
|
|
UMLWidgetList widgetList;
|
|
UMLWidget* widget;
|
|
|
|
// get the list with selected widgets (not associations)
|
|
view->getSelectedWidgets(widgetList);
|
|
UMLWidgetListIt it(widgetList);
|
|
|
|
// at least 2 widgets must be selected
|
|
if (widgetList.count() > 1) {
|
|
// now perform alignment according to the clicked button
|
|
switch (btn) {
|
|
case alac_align_left:
|
|
alignLeft(widgetList);
|
|
break;
|
|
|
|
case alac_align_right:
|
|
alignRight(widgetList);
|
|
break;
|
|
|
|
case alac_align_top:
|
|
alignTop(widgetList);
|
|
break;
|
|
|
|
case alac_align_bottom:
|
|
alignBottom(widgetList);
|
|
break;
|
|
|
|
case alac_align_vertical_middle:
|
|
alignVerticalMiddle(widgetList);
|
|
break;
|
|
|
|
case alac_align_horizontal_middle:
|
|
alignHorizontalMiddle(widgetList);
|
|
break;
|
|
|
|
case alac_align_vertical_distribute:
|
|
alignVerticalDistribute(widgetList);
|
|
break;
|
|
|
|
case alac_align_horizontal_distribute:
|
|
alignHorizontalDistribute(widgetList);
|
|
break;
|
|
|
|
} // switch (btn)
|
|
|
|
// update associations
|
|
it.toFirst();
|
|
while ((widget = it.current()) != 0) {
|
|
++it;
|
|
widget->updateWidget();
|
|
}
|
|
UMLApp::app()->getDocument()->setModified();
|
|
} else {
|
|
KMessageBox::messageBox(0, KMessageBox::Information,
|
|
i18n("For alignment you have to select at least 2 objects like classes or actors. You can not align associations."),
|
|
i18n("Information"), i18n("&OK"), TQString(""),
|
|
"showAlignInformation");
|
|
} // if (widgetList.count() > 1)
|
|
|
|
return;
|
|
}
|
|
|
|
#include "aligntoolbar.moc"
|