/*************************************************************************** * * * 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 * ***************************************************************************/ // own header #include "aligntoolbar.h" // system includes #include #include // qt includes #include // kde includes #include #include #include // 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 void AlignToolBar::sortWidgetList(UMLWidgetList &widgetList, Compare comp) { std::vector widgetVector; UMLWidgetListIt it(widgetList); while (it.current() != 0) { widgetVector.push_back(*it); ++it; } sort(widgetVector.begin(), widgetVector.end(), comp); widgetList.clear(); for (std::vector::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"