libyui-qt  2.47.1.1
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  QPixmap icon;
107 
108  if ( item->hasIconName() )
109  {
110  std::string iconName = iconFullPath( item );
111  icon = QPixmap( iconName.c_str() );
112 
113  if ( icon.isNull() )
114  yuiWarning() << "Can't load icon " << iconName << std::endl;
115  }
116 
117  if ( item->hasChildren() )
118  {
119  QMenu * subMenu;
120 
121  if ( icon.isNull() )
122  subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
123  else
124  subMenu = parentMenu->addMenu( QIcon( icon ), fromUTF8( item->label() ));
125 
126  connect( subMenu, &pclass(subMenu)::triggered,
127  this, &pclass(this)::menuEntryActivated );
128 
129  rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
130  }
131  else // No children - leaf entry
132  {
133  // item->index() is guaranteed to be unique within this YMenuButton's items,
134  // so it can easily be used as unique ID in all Q3PopupMenus that belong
135  // to this YQMenuButton.
136 
137  QAction *act;
138 
139  if ( icon.isNull() )
140  act = parentMenu->addAction( fromUTF8( item->label() ) );
141  else
142  act = parentMenu->addAction( QIcon( icon ), fromUTF8( item->label() ) );
143 
144  _serials[act] = item->index();
145  }
146  }
147 }
148 
149 
150 void
152 {
153  int serialNo = -1;
154  if ( _serials.contains( action ) )
155  serialNo = _serials[action];
156 
157  // yuiDebug() << "Selected menu entry #" << menu_item_index << std::endl;
158  _selectedItem = findMenuItem( serialNo );
159 
160  if ( _selectedItem )
161  {
162  /*
163  * Defer the real returnNow() until all popup related events have been
164  * processed. This took me some hours to figure out; obviously
165  * exit_loop() doesn't have any effect as long as there are still
166  * popups open. So be it - use a zero timer to perform the real
167  * returnNow() later.
168  */
169 
170  /*
171  * the 100 delay is a ugly dirty workaround
172  */
173  QTimer::singleShot( 100, this, SLOT( returnNow() ) );
174  }
175  else
176  {
177  yuiError() << "No menu item with serial no. " << serialNo << std::endl;
178  }
179 }
180 
181 
182 void
184 {
185  if ( _selectedItem )
186  {
187  YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
188  _selectedItem = 0;
189  }
190 }
191 
192 
193 
194 void
196 {
197  _qt_button->setEnabled( enabled );
198  YWidget::setEnabled( enabled );
199 }
200 
201 
203 {
204  return 2*YQButtonBorder + _qt_button->sizeHint().width();
205 }
206 
207 
209 {
210  return 2*YQButtonBorder + _qt_button->sizeHint().height();
211 }
212 
213 
214 void
215 YQMenuButton::setSize( int newWidth, int newHeight )
216 {
217  _qt_button->resize( newWidth - 2 * YQButtonBorder,
218  newHeight - 2 * YQButtonBorder );
219  resize( newWidth, newHeight );
220 }
221 
222 
223 bool
225 {
226  _qt_button->setFocus();
227 
228  return true;
229 }
230 
231 
232 #include "YQMenuButton.moc"
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:494
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:80
YQMenuButton(YWidget *parent, const std::string &label)
Constructor.
Definition: YQMenuButton.cc:40