libyui-qt  2.49.11
YQMenuButton.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: YQMenuButton.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 
26 #include <qpushbutton.h>
27 #include <QMenu>
28 #include <qsize.h>
29 #include <qtimer.h>
30 #define YUILogComponent "qt-ui"
31 #include <yui/YUILog.h>
32 
33 #include "utf8.h"
34 #include "YQUI.h"
35 #include "YQMenuButton.h"
36 #include <yui/YEvent.h>
37 
38 
39 
40 YQMenuButton::YQMenuButton( YWidget * parent,
41  const std::string & label )
42  : QWidget( (QWidget *) parent->widgetRep() )
43  , YMenuButton( parent, label )
44  , _selectedItem( 0 )
45 {
46  setWidgetRep( this );
47  _qt_button = new QPushButton( fromUTF8( label ), this );
48  // _qt_button->setMinimumSize( 2,2 );
49  _qt_button->move( YQButtonBorder, YQButtonBorder );
50  setMinimumSize( _qt_button->minimumSize()
51  + 2 * QSize( YQButtonBorder, YQButtonBorder ) );
52 }
53 
54 
56 {
57  // NOP
58 }
59 
60 
61 void
62 YQMenuButton::setLabel( const std::string & label )
63 {
64  _qt_button->setText( fromUTF8( label ) );
65  YMenuButton::setLabel( label );
66 }
67 
68 
69 void
71 {
72  //
73  // Delete any previous menu
74  // (in case the menu items got replaced)
75  //
76 
77  if ( _qt_button->menu() )
78  delete _qt_button->menu();
79 
80  //
81  // Create toplevel menu
82  //
83 
84  QMenu * menu = new QMenu( _qt_button );
85  YUI_CHECK_NEW( menu );
86  _qt_button->setMenu( menu );
87  menu->setProperty( "class", "ymenubutton QMenu" );
88 
89  connect( menu, &pclass(menu)::triggered,
90  this, &pclass(this)::menuEntryActivated );
91 
92  //
93  // Recursively add Qt menu items from the YMenuItems
94  //
95 
96  rebuildMenuTree( menu, itemsBegin(), itemsEnd() );
97 }
98 
99 
100 void
101 YQMenuButton::rebuildMenuTree( QMenu * parentMenu, YItemIterator begin, YItemIterator end )
102 {
103  for ( YItemIterator it = begin; it != end; ++it )
104  {
105  YItem * item = *it;
106  QIcon icon;
107 
108  if ( item->hasIconName() )
109  {
110  icon = YQUI::ui()->loadIcon( item->iconName() );
111  }
112 
113  if ( item->hasChildren() )
114  {
115  QMenu * subMenu;
116 
117  if ( icon.isNull() )
118  subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
119  else
120  subMenu = parentMenu->addMenu( icon, fromUTF8( item->label() ));
121 
122  connect( subMenu, &pclass(subMenu)::triggered,
123  this, &pclass(this)::menuEntryActivated );
124 
125  rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
126  }
127  else // No children - leaf entry
128  {
129  // item->index() is guaranteed to be unique within this YMenuButton's items,
130  // so it can easily be used as unique ID in all Q3PopupMenus that belong
131  // to this YQMenuButton.
132 
133  QAction *act;
134 
135  if ( icon.isNull() )
136  act = parentMenu->addAction( fromUTF8( item->label() ) );
137  else
138  act = parentMenu->addAction( icon, fromUTF8( item->label() ) );
139 
140  _serials[act] = item->index();
141  }
142  }
143 }
144 
145 
146 void
148 {
149  int serialNo = -1;
150  if ( _serials.contains( action ) )
151  serialNo = _serials[action];
152 
153  // yuiDebug() << "Selected menu entry #" << menu_item_index << std::endl;
154  _selectedItem = findMenuItem( serialNo );
155 
156  if ( _selectedItem )
157  {
158  /*
159  * Defer the real returnNow() until all popup related events have been
160  * processed. This took me some hours to figure out; obviously
161  * exit_loop() doesn't have any effect as long as there are still
162  * popups open. So be it - use a zero timer to perform the real
163  * returnNow() later.
164  */
165 
166  /*
167  * the 100 delay is a ugly dirty workaround
168  */
169  QTimer::singleShot( 100, this, SLOT( returnNow() ) );
170  }
171  else
172  {
173  yuiError() << "No menu item with serial no. " << serialNo << std::endl;
174  }
175 }
176 
177 
178 void
180 {
181  if ( _selectedItem )
182  {
183  YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
184  _selectedItem = 0;
185  }
186 }
187 
188 
189 
190 void
192 {
193  _qt_button->setEnabled( enabled );
194  YWidget::setEnabled( enabled );
195 }
196 
197 
199 {
200  return 2*YQButtonBorder + _qt_button->sizeHint().width();
201 }
202 
203 
205 {
206  return 2*YQButtonBorder + _qt_button->sizeHint().height();
207 }
208 
209 
210 void
211 YQMenuButton::setSize( int newWidth, int newHeight )
212 {
213  _qt_button->resize( newWidth - 2 * YQButtonBorder,
214  newHeight - 2 * YQButtonBorder );
215  resize( newWidth, newHeight );
216 }
217 
218 
219 bool
221 {
222  _qt_button->setFocus();
223 
224  return true;
225 }
226 
227 
228 
virtual void setSize(int newWidth, int newHeight)
Set the new size of the widget.
virtual bool setKeyboardFocus()
Accept the keyboard focus.
void menuEntryActivated(QAction *menuItem)
Triggered when any menu item is activated.
virtual void setLabel(const std::string &label)
Change the label on the button.
Definition: YQMenuButton.cc:62
void returnNow()
Triggered via menuEntryActivated() by zero timer to get back in sync with the Qt event loop.
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 int preferredWidth()
Preferred width of the widget.
virtual ~YQMenuButton()
Destructor.
Definition: YQMenuButton.cc:55
virtual void rebuildMenuTree()
Rebuild the displayed menu tree from the internally stored YMenuItems.
Definition: YQMenuButton.cc:70
virtual void setEnabled(bool enabled)
Set enabled / disabled state.
virtual int preferredHeight()
Preferred height of the widget.
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:81
YQMenuButton(YWidget *parent, const std::string &label)
Constructor.
Definition: YQMenuButton.cc:40