umbrello API Documentation

aligntoolbar.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   This program is free software; you can redistribute it and/or modify  *
00004  *   it under the terms of the GNU General Public License as published by  *
00005  *   the Free Software Foundation; either version 2 of the License, or     *
00006  *   (at your option) any later version.                                   *
00007  *                                                                         *
00008  *   copyright (C) 2004-2007                                               *
00009  *   Umbrello UML Modeller Authors <uml-devel@uml.sf.net>                  *
00010  ***************************************************************************/
00011 
00012 // own header
00013 #include "aligntoolbar.h"
00014 
00015 // system includes
00016 #include <algorithm>
00017 #include <vector>
00018 
00019 // qt includes
00020 #include <qmainwindow.h>
00021 
00022 // kde includes
00023 #include <klocale.h>
00024 #include <kmessagebox.h>
00025 #include <kstandarddirs.h>
00026 
00027 // app includes
00028 #include "uml.h"
00029 #include "umldoc.h"
00030 #include "umlview.h"
00031 #include "umlwidget.h"
00032 #include "umlwidgetlist.h"
00033 
00034 AlignToolBar::AlignToolBar(QMainWindow* parentWindow, const char* )
00035         : KToolBar(parentWindow,Qt::DockRight,false) {
00036     // load images for the buttons
00037     loadPixmaps();
00038 
00039     // create the buttons
00040     insertButton(m_Pixmaps[alac_align_left], alac_align_left, true, i18n("Align Left"));
00041     insertButton(m_Pixmaps[alac_align_right], alac_align_right, true, i18n("Align Right"));
00042     insertButton(m_Pixmaps[alac_align_top], alac_align_top, true, i18n("Align Top"));
00043     insertButton(m_Pixmaps[alac_align_bottom], alac_align_bottom, true, i18n("Align Bottom"));
00044     insertButton(m_Pixmaps[alac_align_vertical_middle], alac_align_vertical_middle, true, i18n("Align Vertical Middle"));
00045     insertButton(m_Pixmaps[alac_align_horizontal_middle], alac_align_horizontal_middle, true, i18n("Align Horizontal Middle"));
00046     insertButton(m_Pixmaps[alac_align_vertical_distribute], alac_align_vertical_distribute, true, i18n("Align Vertical Distribute"));
00047     insertButton(m_Pixmaps[alac_align_horizontal_distribute], alac_align_horizontal_distribute, true, i18n("Align Horizontal Distribute"));
00048 
00049     setOrientation( Qt::Vertical );
00050     setVerticalStretchable( true );
00051 
00052     // gets called whenever a button in the toolbar is clicked
00053     connect( this, SIGNAL( released( int ) ), this, SLOT( slotButtonChanged (int ) ) );
00054 }
00055 
00056 AlignToolBar::~AlignToolBar() {
00057 }
00058 
00059 /* ------ private functions ------ */
00060 
00061 bool AlignToolBar::hasWidgetSmallerX(const UMLWidget* widget1, const UMLWidget* widget2) {
00062     return widget1->getX() < widget2->getX();
00063 }
00064 
00065 bool AlignToolBar::hasWidgetSmallerY(const UMLWidget* widget1, const UMLWidget* widget2) {
00066     return widget1->getY() < widget2->getY();
00067 }
00068 
00069 void AlignToolBar::loadPixmaps() {
00070     KStandardDirs* dirs = KGlobal::dirs();
00071     QString dataDir = dirs->findResourceDir( "data", "umbrello/pics/object.png" );
00072     dataDir += "/umbrello/pics/";
00073 
00074     m_Pixmaps[alac_align_left].load( dataDir + "align_left.png" );
00075     m_Pixmaps[alac_align_right].load( dataDir + "align_right.png" );
00076     m_Pixmaps[alac_align_top].load( dataDir + "align_top.png" );
00077     m_Pixmaps[alac_align_bottom].load( dataDir + "align_bottom.png" );
00078     m_Pixmaps[alac_align_vertical_middle].load( dataDir + "align_vert_middle.png" );
00079     m_Pixmaps[alac_align_horizontal_middle].load( dataDir + "align_hori_middle.png" );
00080     m_Pixmaps[alac_align_vertical_distribute].load( dataDir + "align_vert_distribute.png" );
00081     m_Pixmaps[alac_align_horizontal_distribute].load( dataDir + "align_hori_distribute.png" );
00082 
00083     return;
00084 }
00085 
00086 int AlignToolBar::getSmallestX(const UMLWidgetList &widgetList) {
00087     UMLWidgetListIt it(widgetList);
00088     UMLWidget* widget;
00089 
00090     int smallestX = it.toFirst()->getX();
00091     ++it;
00092 
00093     while ((widget = it.current()) != 0) {
00094         ++it;
00095         if (smallestX > widget->getX())
00096             smallestX = widget->getX();
00097     }
00098 
00099     return smallestX;
00100 }
00101 
00102 int AlignToolBar::getSmallestY(const UMLWidgetList &widgetList) {
00103     UMLWidgetListIt it(widgetList);
00104     UMLWidget* widget;
00105 
00106     int smallestY = it.toFirst()->getY();
00107     ++it;
00108 
00109     while ((widget = it.current()) != 0) {
00110         ++it;
00111         if (smallestY > widget->getY())
00112             smallestY = widget->getY();
00113     }
00114 
00115     return smallestY;
00116 }
00117 
00118 int AlignToolBar::getBiggestX(const UMLWidgetList &widgetList) {
00119     UMLWidgetListIt it(widgetList);
00120     UMLWidget* widget;
00121 
00122     int biggestX = it.toFirst()->getX();
00123     biggestX += it.current()->getWidth();
00124     ++it;
00125 
00126     while ((widget = it.current()) != 0) {
00127         ++it;
00128         if (biggestX < widget->getX() + widget->getWidth())
00129             biggestX = widget->getX() + widget->getWidth();
00130     }
00131 
00132     return biggestX;
00133 }
00134 
00135 int AlignToolBar::getBiggestY(const UMLWidgetList &widgetList) {
00136     UMLWidgetListIt it(widgetList);
00137     UMLWidget* widget;
00138 
00139     int biggestY = it.toFirst()->getY();
00140     biggestY += it.current()->getHeight();
00141     ++it;
00142 
00143     while ((widget = it.current()) != 0) {
00144         ++it;
00145         if (biggestY < widget->getY() + widget->getHeight())
00146             biggestY = widget->getY() + widget->getHeight();
00147     }
00148 
00149     return biggestY;
00150 }
00151 
00152 int AlignToolBar::getHeightsSum(const UMLWidgetList &widgetList) {
00153     UMLWidget* widget;
00154     UMLWidgetListIt it(widgetList);
00155 
00156     int heightsSum = 0;
00157 
00158     it.toFirst();
00159     while ((widget = it.current()) != 0) {
00160         ++it;
00161         heightsSum += widget->getHeight();
00162     }
00163 
00164     return heightsSum;
00165 }
00166 
00167 int AlignToolBar::getWidthsSum(const UMLWidgetList &widgetList) {
00168     UMLWidget* widget;
00169     UMLWidgetListIt it(widgetList);
00170 
00171     int widthsSum = 0;
00172 
00173     it.toFirst();
00174     while ((widget = it.current()) != 0) {
00175         ++it;
00176         widthsSum += widget->getWidth();
00177     }
00178 
00179     return widthsSum;
00180 }
00181 
00182 void AlignToolBar::alignLeft(UMLWidgetList &widgetList) {
00183     int smallestX = getSmallestX(widgetList);
00184 
00185     UMLWidget* widget;
00186     UMLWidgetListIt it(widgetList);
00187 
00188     it.toFirst();
00189     while ((widget = it.current()) != 0) {
00190         ++it;
00191         widget->setX(smallestX);
00192     }
00193 }
00194 
00195 void AlignToolBar::alignRight(UMLWidgetList &widgetList) {
00196     int biggestX = getBiggestX(widgetList);
00197 
00198     UMLWidget* widget;
00199     UMLWidgetListIt it(widgetList);
00200 
00201     it.toFirst();
00202     while ((widget = it.current()) != 0) {
00203         ++it;
00204         widget->setX(biggestX - widget->getWidth());
00205     }
00206 }
00207 
00208 void AlignToolBar::alignTop(UMLWidgetList &widgetList) {
00209     int smallestY = getSmallestY(widgetList);
00210 
00211     UMLWidget* widget;
00212     UMLWidgetListIt it(widgetList);
00213 
00214     it.toFirst();
00215     while ((widget = it.current()) != 0) {
00216         ++it;
00217         widget->setY(smallestY);
00218     }
00219 }
00220 
00221 void AlignToolBar::alignBottom(UMLWidgetList &widgetList) {
00222     int biggestY = getBiggestY(widgetList);
00223 
00224     UMLWidget* widget;
00225     UMLWidgetListIt it(widgetList);
00226 
00227     it.toFirst();
00228     while ((widget = it.current()) != 0) {
00229         ++it;
00230         widget->setY(biggestY - widget->getHeight());
00231     }
00232 }
00233 
00234 void AlignToolBar::alignVerticalMiddle(UMLWidgetList &widgetList) {
00235     int smallestX = getSmallestX(widgetList);
00236     int biggestX = getBiggestX(widgetList);
00237     int middle = int((biggestX - smallestX) / 2) + smallestX;
00238 
00239     UMLWidget* widget;
00240     UMLWidgetListIt it(widgetList);
00241 
00242     it.toFirst();
00243     while ((widget = it.current()) != 0) {
00244         ++it;
00245         widget->setX(middle - int(widget->getWidth() / 2));
00246     }
00247 }
00248 
00249 void AlignToolBar::alignHorizontalMiddle(UMLWidgetList &widgetList) {
00250     int smallestY = getSmallestY(widgetList);
00251     int biggestY = getBiggestY(widgetList);
00252     int middle = int((biggestY - smallestY) / 2) + smallestY;
00253 
00254     UMLWidget* widget;
00255     UMLWidgetListIt it(widgetList);
00256 
00257     it.toFirst();
00258     while ((widget = it.current()) != 0) {
00259         ++it;
00260         widget->setY(middle - int(widget->getHeight() / 2));
00261     }
00262 }
00263 
00264 void AlignToolBar::alignVerticalDistribute(UMLWidgetList &widgetList) {
00265     int smallestY = getSmallestY(widgetList);
00266     int biggestY = getBiggestY(widgetList);
00267     int heightsSum = getHeightsSum(widgetList);
00268     int distance = int(((biggestY - smallestY) - heightsSum) / (widgetList.count()-1.0) + 0.5);
00269 
00270     sortWidgetList(widgetList, hasWidgetSmallerY);
00271 
00272     UMLWidget* widget;
00273     UMLWidgetListIt it(widgetList);
00274 
00275     it = UMLWidgetListIt(widgetList);
00276 
00277     UMLWidget* widgetPrev = it.toFirst();
00278     ++it;
00279     while ((widget = it.current()) != 0) {
00280         ++it;
00281         widget->setY(widgetPrev->getY() + widgetPrev->getHeight() + distance);
00282         widgetPrev = widget;
00283     }
00284 }
00285 
00286 void AlignToolBar::alignHorizontalDistribute(UMLWidgetList &widgetList) {
00287     int smallestX = getSmallestX(widgetList);
00288     int biggestX = getBiggestX(widgetList);
00289     int widthsSum = getWidthsSum(widgetList);
00290     int distance = int(((biggestX - smallestX) - widthsSum) / (widgetList.count()-1.0) + 0.5);
00291 
00292     sortWidgetList(widgetList, hasWidgetSmallerX);
00293 
00294     UMLWidget* widget;
00295     UMLWidgetListIt it(widgetList);
00296 
00297     it = UMLWidgetListIt(widgetList);
00298 
00299     UMLWidget* widgetPrev = it.toFirst();
00300     ++it;
00301     while ((widget = it.current()) != 0) {
00302         ++it;
00303         widget->setX(widgetPrev->getX() + widgetPrev->getWidth() + distance);
00304         widgetPrev = widget;
00305     }
00306 }
00307 
00308 template<typename Compare>
00309 void AlignToolBar::sortWidgetList(UMLWidgetList &widgetList, Compare comp) {
00310     std::vector<UMLWidget*> widgetVector;
00311     UMLWidgetListIt it(widgetList);
00312     while (it.current() != 0) {
00313         widgetVector.push_back(*it);
00314         ++it;
00315     }
00316     sort(widgetVector.begin(), widgetVector.end(), comp);
00317 
00318     widgetList.clear();
00319 
00320     for (std::vector<UMLWidget*>::iterator it=widgetVector.begin(); it != widgetVector.end(); ++it) {
00321         widgetList.append(*it);
00322     }
00323 }
00324 
00325 /* ------ private slots ------ */
00326 
00327 void AlignToolBar::slotButtonChanged(int btn) {
00328     UMLView* view = UMLApp::app()->getCurrentView();
00329     UMLWidgetList widgetList;
00330     UMLWidget* widget;
00331 
00332     // get the list with selected widgets (not associations)
00333     view->getSelectedWidgets(widgetList);
00334     UMLWidgetListIt it(widgetList);
00335 
00336     // at least 2 widgets must be selected
00337     if (widgetList.count() > 1) {
00338         // now perform alignment according to the clicked button
00339         switch (btn) {
00340         case alac_align_left:
00341             alignLeft(widgetList);
00342             break;
00343 
00344         case alac_align_right:
00345             alignRight(widgetList);
00346             break;
00347 
00348         case alac_align_top:
00349             alignTop(widgetList);
00350             break;
00351 
00352         case alac_align_bottom:
00353             alignBottom(widgetList);
00354             break;
00355 
00356         case alac_align_vertical_middle:
00357             alignVerticalMiddle(widgetList);
00358             break;
00359 
00360         case alac_align_horizontal_middle:
00361             alignHorizontalMiddle(widgetList);
00362             break;
00363 
00364         case alac_align_vertical_distribute:
00365             alignVerticalDistribute(widgetList);
00366             break;
00367 
00368         case alac_align_horizontal_distribute:
00369             alignHorizontalDistribute(widgetList);
00370             break;
00371 
00372         } // switch (btn)
00373 
00374         // update associations
00375         it.toFirst();
00376         while ((widget = it.current()) != 0) {
00377             ++it;
00378             widget->updateWidget();
00379         }
00380         UMLApp::app()->getDocument()->setModified();
00381     } else {
00382         KMessageBox::messageBox(0, KMessageBox::Information,
00383                                 i18n("For alignment you have to select at least 2 objects like classes or actors. You can not align associations."),
00384                                 i18n("Information"), i18n("&OK"), QString(""),
00385                                 "showAlignInformation");
00386     } // if (widgetList.count() > 1)
00387 
00388     return;
00389 }
00390 
00391 #include "aligntoolbar.moc"
KDE Logo
This file is part of the documentation for umbrello Version 3.1.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Jun 26 08:07:54 2007 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003