libyui-qt  2.43.5
/usr/src/RPM/BUILD/libyui-qt-2.43.5/src/YQMenuButton.cc
00001 /*
00002   Copyright (C) 2000-2012 Novell, Inc
00003   This library is free software; you can redistribute it and/or modify
00004   it under the terms of the GNU Lesser General Public License as
00005   published by the Free Software Foundation; either version 2.1 of the
00006   License, or (at your option) version 3.0 of the License. This library
00007   is distributed in the hope that it will be useful, but WITHOUT ANY
00008   WARRANTY; without even the implied warranty of MERCHANTABILITY or
00009   FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00010   License for more details. You should have received a copy of the GNU
00011   Lesser General Public License along with this library; if not, write
00012   to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
00013   Floor, Boston, MA 02110-1301 USA
00014 */
00015 
00016 
00017 /*-/
00018 
00019   File:       YQMenuButton.cc
00020 
00021   Author:     Stefan Hundhammer <sh@suse.de>
00022 
00023 /-*/
00024 
00025 
00026 #include <qpushbutton.h>
00027 #include <QMenu>
00028 #include <qsize.h>
00029 #include <qtimer.h>
00030 #define YUILogComponent "qt-ui"
00031 #include <yui/YUILog.h>
00032 
00033 #include "utf8.h"
00034 #include "YQUI.h"
00035 #include "YQMenuButton.h"
00036 #include <yui/YEvent.h>
00037 
00038 
00039 
00040 YQMenuButton::YQMenuButton( YWidget *           parent,
00041                             const std::string & label )
00042     : QWidget( (QWidget *) parent->widgetRep() )
00043     , YMenuButton( parent, label )
00044     , _selectedItem( 0 )
00045 {
00046     setWidgetRep( this );
00047     _qt_button = new QPushButton( fromUTF8( label ), this );
00048     // _qt_button->setMinimumSize( 2,2 );
00049     _qt_button->move( YQButtonBorder, YQButtonBorder );
00050     setMinimumSize( _qt_button->minimumSize()
00051                     + 2 * QSize( YQButtonBorder, YQButtonBorder ) );
00052 }
00053 
00054 
00055 YQMenuButton::~YQMenuButton()
00056 {
00057     // NOP
00058 }
00059 
00060 
00061 void
00062 YQMenuButton::setLabel( const std::string & label )
00063 {
00064     _qt_button->setText( fromUTF8( label ) );
00065     YMenuButton::setLabel( label );
00066 }
00067 
00068 
00069 void
00070 YQMenuButton::rebuildMenuTree()
00071 {
00072     //
00073     // Delete any previous menu
00074     // (in case the menu items got replaced)
00075     //
00076 
00077     if ( _qt_button->menu() )
00078         delete _qt_button->menu();
00079 
00080     //
00081     // Create toplevel menu
00082     //
00083 
00084     QMenu * menu = new QMenu( _qt_button );
00085     YUI_CHECK_NEW( menu );
00086     _qt_button->setMenu( menu );
00087     menu->setProperty( "class", "ymenubutton QMenu" );
00088 
00089     connect( menu,      SIGNAL( triggered         ( QAction * ) ),
00090              this,      SLOT  ( menuEntryActivated( QAction * ) ) );
00091 
00092     //
00093     // Recursively add Qt menu items from the YMenuItems
00094     //
00095 
00096     rebuildMenuTree( menu, itemsBegin(), itemsEnd() );
00097 }
00098 
00099 
00100 void
00101 YQMenuButton::rebuildMenuTree( QMenu * parentMenu, YItemIterator begin, YItemIterator end )
00102 {
00103     for ( YItemIterator it = begin; it != end; ++it )
00104     {
00105         YItem * item = *it;
00106         QPixmap icon;
00107 
00108         if ( item->hasIconName() )
00109         {
00110             std::string iconName = iconFullPath( item );
00111             icon = QPixmap( iconName.c_str() );
00112 
00113             if ( icon.isNull() )
00114                 yuiWarning() << "Can't load icon " << iconName << std::endl;
00115         }
00116 
00117         if ( item->hasChildren() )
00118         {
00119             QMenu * subMenu;
00120 
00121             if ( icon.isNull() )
00122                 subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
00123             else
00124                 subMenu = parentMenu->addMenu( QIcon( icon ), fromUTF8( item->label() ));
00125 
00126             connect( subMenu,   SIGNAL( triggered         ( QAction * ) ),
00127                      this,      SLOT  ( menuEntryActivated( QAction * ) ) );
00128 
00129             rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
00130         }
00131         else // No children - leaf entry
00132         {
00133             // item->index() is guaranteed to be unique within this YMenuButton's items,
00134             // so it can easily be used as unique ID in all Q3PopupMenus that belong
00135             // to this YQMenuButton.
00136 
00137             QAction *act;
00138 
00139             if ( icon.isNull() )
00140                 act = parentMenu->addAction( fromUTF8( item->label() ) );
00141             else
00142                 act = parentMenu->addAction( QIcon( icon ), fromUTF8( item->label() ) );
00143 
00144             _serials[act] = item->index();
00145         }
00146     }
00147 }
00148 
00149 
00150 void
00151 YQMenuButton::menuEntryActivated( QAction* action )
00152 {
00153     int serialNo = -1;
00154     if ( _serials.contains( action ) )
00155         serialNo = _serials[action];
00156 
00157     // yuiDebug() << "Selected menu entry #" << menu_item_index << std::endl;
00158     _selectedItem = findMenuItem( serialNo );
00159 
00160     if ( _selectedItem )
00161     {
00162         /*
00163          * Defer the real returnNow() until all popup related events have been
00164          * processed. This took me some hours to figure out; obviously
00165          * exit_loop() doesn't have any effect as long as there are still
00166          * popups open. So be it - use a zero timer to perform the real
00167          * returnNow() later.
00168          */
00169 
00170         /*
00171          * the 100 delay is a ugly dirty workaround
00172          */
00173         QTimer::singleShot( 100, this, SLOT( returnNow() ) );
00174     }
00175     else
00176     {
00177         yuiError() << "No menu item with serial no. " << serialNo << std::endl;
00178     }
00179 }
00180 
00181 
00182 void
00183 YQMenuButton::returnNow()
00184 {
00185     if ( _selectedItem )
00186     {
00187         YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
00188         _selectedItem = 0;
00189     }
00190 }
00191 
00192 
00193 
00194 void
00195 YQMenuButton::setEnabled( bool enabled )
00196 {
00197     _qt_button->setEnabled( enabled );
00198     YWidget::setEnabled( enabled );
00199 }
00200 
00201 
00202 int YQMenuButton::preferredWidth()
00203 {
00204     return 2*YQButtonBorder + _qt_button->sizeHint().width();
00205 }
00206 
00207 
00208 int YQMenuButton::preferredHeight()
00209 {
00210     return 2*YQButtonBorder + _qt_button->sizeHint().height();
00211 }
00212 
00213 
00214 void
00215 YQMenuButton::setSize( int newWidth, int newHeight )
00216 {
00217     _qt_button->resize( newWidth  - 2 * YQButtonBorder,
00218                             newHeight - 2 * YQButtonBorder );
00219     resize( newWidth, newHeight );
00220 }
00221 
00222 
00223 bool
00224 YQMenuButton::setKeyboardFocus()
00225 {
00226     _qt_button->setFocus();
00227 
00228     return true;
00229 }
00230 
00231 
00232 #include "YQMenuButton.moc"
 All Classes Functions Variables