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