libyui-qt  2.53.0
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 using std::string;
39 
40 
41 
42 YQMenuButton::YQMenuButton( YWidget * parent,
43  const string & label )
44  : QWidget( (QWidget *) parent->widgetRep() )
45  , YMenuButton( parent, label )
46  , _selectedItem( 0 )
47 {
48  setWidgetRep( this );
49  _qt_button = new QPushButton( fromUTF8( label ), this );
50  // _qt_button->setMinimumSize( 2,2 );
51  _qt_button->move( YQButtonBorder, YQButtonBorder );
52  setMinimumSize( _qt_button->minimumSize()
53  + 2 * QSize( YQButtonBorder, YQButtonBorder ) );
54 }
55 
56 
58 {
59  // NOP
60 }
61 
62 
63 void
64 YQMenuButton::setLabel( const string & label )
65 {
66  _qt_button->setText( fromUTF8( label ) );
67  YMenuButton::setLabel( label );
68 }
69 
70 
71 void
73 {
74  //
75  // Delete any previous menu
76  // (in case the menu items got replaced)
77  //
78 
79  if ( _qt_button->menu() )
80  delete _qt_button->menu();
81 
82  //
83  // Create toplevel menu
84  //
85 
86  QMenu * menu = new QMenu( _qt_button );
87  YUI_CHECK_NEW( menu );
88  _qt_button->setMenu( menu );
89  menu->setProperty( "class", "ymenubutton QMenu" );
90 
91  connect( menu, &pclass(menu)::triggered,
92  this, &pclass(this)::menuEntryActivated );
93 
94  //
95  // Recursively add Qt menu items from the YMenuItems
96  //
97 
98  rebuildMenuTree( menu, itemsBegin(), itemsEnd() );
99 }
100 
101 
102 void
103 YQMenuButton::rebuildMenuTree( QMenu * parentMenu, YItemIterator begin, YItemIterator end )
104 {
105  for ( YItemIterator it = begin; it != end; ++it )
106  {
107  YItem * item = *it;
108  QIcon icon;
109 
110  if ( item->hasIconName() )
111  {
112  icon = YQUI::ui()->loadIcon( item->iconName() );
113  }
114 
115  if ( item->hasChildren() )
116  {
117  QMenu * subMenu;
118 
119  if ( icon.isNull() )
120  subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
121  else
122  subMenu = parentMenu->addMenu( icon, fromUTF8( item->label() ));
123 
124  connect( subMenu, &pclass(subMenu)::triggered,
125  this, &pclass(this)::menuEntryActivated );
126 
127  rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
128  }
129  else // No children - leaf entry
130  {
131  // item->index() is guaranteed to be unique within this YMenuButton's items,
132  // so it can easily be used as unique ID in all Q3PopupMenus that belong
133  // to this YQMenuButton.
134 
135  QAction *act;
136 
137  if ( icon.isNull() )
138  act = parentMenu->addAction( fromUTF8( item->label() ) );
139  else
140  act = parentMenu->addAction( icon, fromUTF8( item->label() ) );
141 
142  _serials[act] = item->index();
143  }
144  }
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 << 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  QTimer::singleShot( 100, this, SLOT( returnNow() ) );
172  }
173  else
174  {
175  yuiError() << "No menu item with serial no. " << serialNo << endl;
176  }
177 }
178 
179 
180 void
182 {
183  if ( _selectedItem )
184  {
185  YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
186  _selectedItem = 0;
187  }
188 }
189 
190 
191 
192 void
194 {
195  _qt_button->setEnabled( enabled );
196  YWidget::setEnabled( enabled );
197 }
198 
199 
201 {
202  return 2*YQButtonBorder + _qt_button->sizeHint().width();
203 }
204 
205 
207 {
208  return 2*YQButtonBorder + _qt_button->sizeHint().height();
209 }
210 
211 
212 void
213 YQMenuButton::setSize( int newWidth, int newHeight )
214 {
215  _qt_button->resize( newWidth - 2 * YQButtonBorder,
216  newHeight - 2 * YQButtonBorder );
217  resize( newWidth, newHeight );
218 }
219 
220 
221 bool
223 {
224  _qt_button->setFocus();
225 
226  return true;
227 }
228 
229 
230 void
231 YQMenuButton::activateItem( YMenuItem * item )
232 {
233  if ( item )
234  YQUI::ui()->sendEvent( new YMenuEvent( item ) );
235 }
virtual void setLabel(const std::string &label)
Change the label on the button.
Definition: YQMenuButton.cc:64
virtual void activateItem(YMenuItem *item)
Activate the item selected in the tree.
YQMenuButton(YWidget *parent, const std::string &label)
Constructor.
Definition: YQMenuButton.cc:42
virtual int preferredHeight()
Preferred height of the widget.
virtual bool setKeyboardFocus()
Accept the keyboard focus.
virtual void setSize(int newWidth, int newHeight)
Set the new size of the widget.
virtual int preferredWidth()
Preferred width of the widget.
virtual void setEnabled(bool enabled)
Set enabled / disabled state.
void returnNow()
Triggered via menuEntryActivated() by zero timer to get back in sync with the Qt event loop.
virtual void rebuildMenuTree()
Rebuild the displayed menu tree from the internally stored YMenuItems.
Definition: YQMenuButton.cc:72
void menuEntryActivated(QAction *menuItem)
Triggered when any menu item is activated.
virtual ~YQMenuButton()
Destructor.
Definition: YQMenuButton.cc:57
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:83
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
QIcon loadIcon(const string &iconName) const
Load an icon.
Definition: YQUI.cc:708