libyui-qt  2.46.13
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  QPixmap icon;
91 
92  if ( item->hasIconName() )
93  {
94  std::string iconName = iconFullPath( item );
95  icon = QPixmap( iconName.c_str() );
96 
97  if ( icon.isNull() )
98  yuiWarning() << "Can't load icon " << iconName << std::endl;
99  }
100 
101  if ( item->hasChildren() )
102  {
103  QMenu * subMenu;
104 
105  if ( icon.isNull() )
106  subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
107  else
108  subMenu = parentMenu->addMenu( QIcon( icon ), fromUTF8( item->label() ));
109 
110  connect( subMenu, &pclass(subMenu)::triggered,
111  this, &pclass(this)::menuEntryActivated );
112 
113  rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
114  }
115  else // No children - leaf entry
116  {
117  // item->index() is guaranteed to be unique within this YContextMenu's items,
118  // so it can easily be used as unique ID in all Q3PopupMenus that belong
119  // to this YQContextMenu.
120 
121  QAction *act;
122 
123  if ( icon.isNull() )
124  act = parentMenu->addAction( fromUTF8( item->label() ) );
125  else
126  act = parentMenu->addAction( QIcon( icon ), fromUTF8( item->label() ) );
127 
128  _serials[act] = item->index();
129  }
130  }
131 }
132 
133 void
135 {
136  // dirty hack
137  // see menuEntryActivated() for details
138  QTimer::singleShot( 150, this, SLOT( slotReturnMenuHidden() ) );
139 }
140 
141 
142 void
144 {
145  if ( ! _suppressCancelEvent )
146  YQUI::ui()->sendEvent( new YCancelEvent() );
147 
148  _suppressCancelEvent = false;
149 }
150 
151 
152 void
154 {
155  int serialNo = -1;
156  if ( _serials.contains( action ) )
157  serialNo = _serials[action];
158 
159  // yuiDebug() << "Selected menu entry #" << menu_item_index << std::endl;
160  _selectedItem = findMenuItem( serialNo );
161 
162  if ( _selectedItem )
163  {
164  /*
165  * Defer the real returnNow() until all popup related events have been
166  * processed. This took me some hours to figure out; obviously
167  * exit_loop() doesn't have any effect as long as there are still
168  * popups open. So be it - use a zero timer to perform the real
169  * returnNow() later.
170  */
171 
172  /*
173  * the 100 delay is a ugly dirty workaround
174  */
175  _suppressCancelEvent = true;
176  QTimer::singleShot( 100, this, SLOT( returnNow() ) );
177  }
178  else
179  {
180  yuiError() << "No menu item with serial no. " << serialNo << std::endl;
181  }
182 }
183 
184 
185 void
187 {
188  if ( _selectedItem )
189  {
190  YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
191  _selectedItem = 0;
192  }
193 }
194 
195 
197 {
198  return 42;
199 }
200 
201 
203 {
204  return 42;
205 }
206 
207 
208 void
209 YQContextMenu::setSize( int newWidth, int newHeight )
210 {
211 
212 }
213 
214 
215 #include "YQContextMenu.moc"
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:486
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.