libyui-qt  2.43.3
 All Classes Functions Variables
YQContextMenu.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YQContextMenu.cc
20 
21  Author: Thomas Goettlicher <tgoettlicher@suse.de>
22 
23 /-*/
24 
25 
26 #include <QMenu>
27 #include <qtimer.h>
28 #define YUILogComponent "qt-ui"
29 #include <yui/YUILog.h>
30 
31 #include "utf8.h"
32 #include "YQUI.h"
33 #include "YQContextMenu.h"
34 #include <yui/YEvent.h>
35 
36 
38  : QObject ()
39  , YContextMenu( )
40  , _suppressCancelEvent(false )
41 {
42  yuiWarning() << "YQContextMenu";
43 
44 }
45 
46 YQContextMenu::YQContextMenu( const QPoint position )
47  : QObject ()
48  , YContextMenu( )
49  , _position ( position )
50 {
51  // NOP
52 }
53 
54 
56 {
57  // NOP
58 }
59 
60 
61 void
63 {
64  QMenu * menu = new QMenu( 0 );
65  YUI_CHECK_NEW( menu );
66  menu->setProperty( "class", "ycontextmenu QMenu" );
67 
68  connect( menu, SIGNAL( triggered ( QAction * ) ),
69  this, SLOT ( menuEntryActivated( QAction * ) ) );
70 
71  connect( menu, SIGNAL( aboutToHide () ),
72  this, SLOT ( slotMenuHidden () ) );
73  //
74  // Recursively add Qt menu items from the YMenuItems
75  //
76 
77  rebuildMenuTree( menu, itemsBegin(), itemsEnd() );
78  menu->popup( _position );
79 }
80 
81 
82 void
83 YQContextMenu::rebuildMenuTree( QMenu * parentMenu, YItemIterator begin, YItemIterator end )
84 {
85  for ( YItemIterator it = begin; it != end; ++it )
86  {
87  YItem * item = *it;
88  QPixmap icon;
89 
90  if ( item->hasIconName() )
91  {
92  std::string iconName = iconFullPath( item );
93  icon = QPixmap( iconName.c_str() );
94 
95  if ( icon.isNull() )
96  yuiWarning() << "Can't load icon " << iconName << std::endl;
97  }
98 
99  if ( item->hasChildren() )
100  {
101  QMenu * subMenu;
102 
103  if ( icon.isNull() )
104  subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
105  else
106  subMenu = parentMenu->addMenu( QIcon( icon ), fromUTF8( item->label() ));
107 
108  connect( subMenu, SIGNAL( triggered ( QAction * ) ),
109  this, SLOT ( menuEntryActivated( QAction * ) ) );
110 
111  rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
112  }
113  else // No children - leaf entry
114  {
115  // item->index() is guaranteed to be unique within this YContextMenu's items,
116  // so it can easily be used as unique ID in all Q3PopupMenus that belong
117  // to this YQContextMenu.
118 
119  QAction *act;
120 
121  if ( icon.isNull() )
122  act = parentMenu->addAction( fromUTF8( item->label() ) );
123  else
124  act = parentMenu->addAction( QIcon( icon ), fromUTF8( item->label() ) );
125 
126  _serials[act] = item->index();
127  }
128  }
129 }
130 
131 void
133 {
134  // dirty hack
135  // see menuEntryActivated() for details
136  QTimer::singleShot( 150, this, SLOT( slotReturnMenuHidden() ) );
137 }
138 
139 
140 void
142 {
143  if ( ! _suppressCancelEvent )
144  YQUI::ui()->sendEvent( new YCancelEvent() );
145 
146  _suppressCancelEvent = false;
147 }
148 
149 
150 void
152 {
153  int serialNo = -1;
154  if ( _serials.contains( action ) )
155  serialNo = _serials[action];
156 
157  // yuiDebug() << "Selected menu entry #" << menu_item_index << std::endl;
158  _selectedItem = findMenuItem( serialNo );
159 
160  if ( _selectedItem )
161  {
162  /*
163  * Defer the real returnNow() until all popup related events have been
164  * processed. This took me some hours to figure out; obviously
165  * exit_loop() doesn't have any effect as long as there are still
166  * popups open. So be it - use a zero timer to perform the real
167  * returnNow() later.
168  */
169 
170  /*
171  * the 100 delay is a ugly dirty workaround
172  */
173  _suppressCancelEvent = true;
174  QTimer::singleShot( 100, this, SLOT( returnNow() ) );
175  }
176  else
177  {
178  yuiError() << "No menu item with serial no. " << serialNo << std::endl;
179  }
180 }
181 
182 
183 void
185 {
186  if ( _selectedItem )
187  {
188  YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
189  _selectedItem = 0;
190  }
191 }
192 
193 
195 {
196  return 42;
197 }
198 
199 
201 {
202  return 42;
203 }
204 
205 
206 void
207 YQContextMenu::setSize( int newWidth, int newHeight )
208 {
209 
210 }
211 
212 
213 #include "YQContextMenu.moc"