libyui-qt  2.52.4
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 using std::endl;
37 
38 
39 
41  : QObject ()
42  , YContextMenu( )
43  , _suppressCancelEvent(false )
44  , _parent(0)
45 {
46  yuiWarning() << "YQContextMenu";
47 
48 }
49 
50 YQContextMenu::YQContextMenu( QWidget* parent, const QPoint position )
51  : QObject ()
52  , YContextMenu( )
53  , _position ( position )
54  , _parent(parent)
55 {
56  // NOP
57 }
58 
59 
61 {
62  // NOP
63 }
64 
65 
66 void
68 {
69  QMenu * menu = new QMenu( _parent );
70  YUI_CHECK_NEW( menu );
71  menu->setProperty( "class", "ycontextmenu QMenu" );
72 
73  connect( menu, &pclass(menu)::triggered,
74  this, &pclass(this)::menuEntryActivated );
75 
76  connect( menu, &pclass(menu)::aboutToHide,
77  this, &pclass(this)::slotMenuHidden );
78  //
79  // Recursively add Qt menu items from the YMenuItems
80  //
81 
82  rebuildMenuTree( menu, itemsBegin(), itemsEnd() );
83  menu->popup( _position );
84 }
85 
86 
87 void
88 YQContextMenu::rebuildMenuTree( QMenu * parentMenu, YItemIterator begin, YItemIterator end )
89 {
90  for ( YItemIterator it = begin; it != end; ++it )
91  {
92  YItem * item = *it;
93  QIcon icon;
94 
95  if ( item->hasIconName() )
96  {
97  icon = YQUI::ui()->loadIcon( item->iconName() );
98  }
99 
100  if ( item->hasChildren() )
101  {
102  QMenu * subMenu;
103 
104  if ( icon.isNull() )
105  subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
106  else
107  subMenu = parentMenu->addMenu( QIcon( icon ), fromUTF8( item->label() ));
108 
109  connect( subMenu, &pclass(subMenu)::triggered,
110  this, &pclass(this)::menuEntryActivated );
111 
112  rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
113  }
114  else // No children - leaf entry
115  {
116  // item->index() is guaranteed to be unique within this YContextMenu's items,
117  // so it can easily be used as unique ID in all Q3PopupMenus that belong
118  // to this YQContextMenu.
119 
120  QAction *act;
121 
122  if ( icon.isNull() )
123  act = parentMenu->addAction( fromUTF8( item->label() ) );
124  else
125  act = parentMenu->addAction( QIcon( icon ), fromUTF8( item->label() ) );
126 
127  _serials[act] = item->index();
128  }
129  }
130 }
131 
132 void
134 {
135  // dirty hack
136  // see menuEntryActivated() for details
137  QTimer::singleShot( 150, this, SLOT( slotReturnMenuHidden() ) );
138 }
139 
140 
141 void
143 {
144  if ( ! _suppressCancelEvent )
145  YQUI::ui()->sendEvent( new YCancelEvent() );
146 
147  _suppressCancelEvent = false;
148 }
149 
150 
151 void
153 {
154  int serialNo = -1;
155  if ( _serials.contains( action ) )
156  serialNo = _serials[action];
157 
158  // yuiDebug() << "Selected menu entry #" << menu_item_index << endl;
159  _selectedItem = findMenuItem( serialNo );
160 
161  if ( _selectedItem )
162  {
163  /*
164  * Defer the real returnNow() until all popup related events have been
165  * processed. This took me some hours to figure out; obviously
166  * exit_loop() doesn't have any effect as long as there are still
167  * popups open. So be it - use a zero timer to perform the real
168  * returnNow() later.
169  */
170 
171  /*
172  * the 100 delay is a ugly dirty workaround
173  */
174  _suppressCancelEvent = true;
175  QTimer::singleShot( 100, this, SLOT( returnNow() ) );
176  }
177  else
178  {
179  yuiError() << "No menu item with serial no. " << serialNo << endl;
180  }
181 }
182 
183 
184 void
186 {
187  if ( _selectedItem )
188  {
189  YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
190  _selectedItem = 0;
191  }
192 }
193 
194 
196 {
197  return 42;
198 }
199 
200 
202 {
203  return 42;
204 }
205 
206 
207 void
208 YQContextMenu::setSize( int newWidth, int newHeight )
209 {
210 
211 }
void menuEntryActivated(QAction *menuItem)
Triggered when any menu item is activated.
virtual int preferredWidth()
Preferred width of the widget.
void slotReturnMenuHidden()
Triggered via slotMenuHidden() by zero timer to get back in sync with the Qt event loop...
virtual int preferredHeight()
Preferred height of the widget.
QIcon loadIcon(const string &iconName) const
Load an icon.
Definition: YQUI.cc:708
void slotMenuHidden()
Triggered when the context menu is hidden.
void sendEvent(YEvent *event)
Widget event handlers (slots) call this when an event occured that should be the answer to a UserInpu...
Definition: YQUI.cc:480
virtual void setSize(int newWidth, int newHeight)
Set the new size of the widget.
void returnNow()
Triggered via menuEntryActivated() by zero timer to get back in sync with the Qt event loop...
YQContextMenu()
Constructor.
virtual void rebuildMenuTree()
Change the label on the button.
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:83
virtual ~YQContextMenu()
Destructor.