libyui-qt
2.43.5
|
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"