libyui-qt  2.43.5
/usr/src/RPM/BUILD/libyui-qt-2.43.5/src/YQContextMenu.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:       YQContextMenu.cc
00020 
00021   Author:     Thomas Goettlicher <tgoettlicher@suse.de>
00022 
00023 /-*/
00024 
00025 
00026 #include <QMenu>
00027 #include <qtimer.h>
00028 #define YUILogComponent "qt-ui"
00029 #include <yui/YUILog.h>
00030 
00031 #include "utf8.h"
00032 #include "YQUI.h"
00033 #include "YQContextMenu.h"
00034 #include <yui/YEvent.h>
00035 
00036 
00037 YQContextMenu::YQContextMenu()
00038     : QObject ()
00039     , YContextMenu( )
00040     , _suppressCancelEvent(false )
00041 {
00042      yuiWarning() << "YQContextMenu";
00043 
00044 }
00045 
00046 YQContextMenu::YQContextMenu( const QPoint position )
00047     : QObject ()
00048     , YContextMenu(  )
00049     , _position ( position )
00050 {
00051     // NOP
00052 }
00053 
00054 
00055 YQContextMenu::~YQContextMenu()
00056 {
00057     // NOP
00058 }
00059 
00060 
00061 void
00062 YQContextMenu::rebuildMenuTree()
00063 {
00064     QMenu * menu = new QMenu( 0 );
00065     YUI_CHECK_NEW( menu );
00066     menu->setProperty( "class", "ycontextmenu QMenu" );
00067 
00068     connect( menu,      SIGNAL( triggered         ( QAction * ) ),
00069              this,      SLOT  ( menuEntryActivated( QAction * ) ) );
00070 
00071     connect( menu,      SIGNAL( aboutToHide      () ),
00072              this,      SLOT  ( slotMenuHidden   () ) );
00073     //
00074     // Recursively add Qt menu items from the YMenuItems
00075     //
00076 
00077     rebuildMenuTree( menu, itemsBegin(), itemsEnd() );
00078     menu->popup( _position );
00079 }
00080 
00081 
00082 void
00083 YQContextMenu::rebuildMenuTree( QMenu * parentMenu, YItemIterator begin, YItemIterator end )
00084 {
00085     for ( YItemIterator it = begin; it != end; ++it )
00086     {
00087         YItem * item = *it;
00088         QPixmap icon;
00089 
00090         if ( item->hasIconName() )
00091         {
00092             std::string iconName = iconFullPath( item );
00093             icon = QPixmap( iconName.c_str() );
00094 
00095             if ( icon.isNull() )
00096                 yuiWarning() << "Can't load icon " << iconName << std::endl;
00097         }
00098 
00099         if ( item->hasChildren() )
00100         {
00101             QMenu * subMenu;
00102 
00103             if ( icon.isNull() )
00104                 subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
00105             else
00106                 subMenu = parentMenu->addMenu( QIcon( icon ), fromUTF8( item->label() ));
00107 
00108             connect( subMenu,   SIGNAL( triggered         ( QAction * ) ),
00109                      this,      SLOT  ( menuEntryActivated( QAction * ) ) );
00110 
00111             rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
00112         }
00113         else // No children - leaf entry
00114         {
00115             // item->index() is guaranteed to be unique within this YContextMenu's items,
00116             // so it can easily be used as unique ID in all Q3PopupMenus that belong
00117             // to this YQContextMenu.
00118 
00119             QAction *act;
00120 
00121             if ( icon.isNull() )
00122                 act = parentMenu->addAction( fromUTF8( item->label() ) );
00123             else
00124                 act = parentMenu->addAction( QIcon( icon ), fromUTF8( item->label() ) );
00125 
00126             _serials[act] = item->index();
00127         }
00128     }
00129 }
00130 
00131 void
00132 YQContextMenu::slotMenuHidden()
00133 {
00134         // dirty hack
00135         // see menuEntryActivated() for details
00136         QTimer::singleShot( 150, this, SLOT( slotReturnMenuHidden() ) );
00137 }
00138 
00139 
00140 void
00141 YQContextMenu::slotReturnMenuHidden()
00142 {
00143     if ( ! _suppressCancelEvent )
00144         YQUI::ui()->sendEvent( new YCancelEvent() );
00145 
00146     _suppressCancelEvent = false;
00147 }
00148 
00149 
00150 void
00151 YQContextMenu::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         _suppressCancelEvent = true;
00174         QTimer::singleShot( 100, this, SLOT( returnNow() ) );
00175     }
00176     else
00177     {
00178         yuiError() << "No menu item with serial no. " << serialNo << std::endl;
00179     }
00180 }
00181 
00182 
00183 void
00184 YQContextMenu::returnNow()
00185 {
00186     if ( _selectedItem )
00187     {
00188         YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
00189         _selectedItem = 0;
00190     }
00191 }
00192 
00193 
00194 int YQContextMenu::preferredWidth()
00195 {
00196         return 42;
00197 }
00198 
00199 
00200 int YQContextMenu::preferredHeight()
00201 {
00202         return 42;
00203 }
00204 
00205 
00206 void
00207 YQContextMenu::setSize( int newWidth, int newHeight )
00208 {
00209 
00210 }
00211 
00212 
00213 #include "YQContextMenu.moc"
 All Classes Functions Variables