]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/YQMenuButton.cc
clicking packages work! so the package selector is now
[duncan/yast2-qt4.git] / src / YQMenuButton.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQMenuButton.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19
20 #include <qpushbutton.h>
21 #include <QMenu>
22 #include <qsize.h>
23 #include <qtimer.h>
24 #define y2log_component "qt-ui"
25 #include <ycp/y2log.h>
26
27 #include "utf8.h"
28 #include "YQUI.h"
29 #include "YQMenuButton.h"
30 #include "YEvent.h"
31
32
33
34 YQMenuButton::YQMenuButton( YWidget *           parent,
35                             const string &      label )
36     : QWidget( (QWidget *) parent->widgetRep() )
37     , YMenuButton( parent, label )
38     , _selectedItem( 0 )
39 {
40     setWidgetRep( this );
41     _qt_button = new QPushButton( fromUTF8( label ), this );
42     // _qt_button->setMinimumSize( 2,2 );
43     _qt_button->move( YQButtonBorder, YQButtonBorder );
44     setMinimumSize( _qt_button->minimumSize()
45                     + 2 * QSize( YQButtonBorder, YQButtonBorder ) );
46 }
47
48
49 YQMenuButton::~YQMenuButton()
50 {
51     // NOP
52 }
53
54
55 void
56 YQMenuButton::setLabel( const string & label )
57 {
58     _qt_button->setText( fromUTF8( label ) );
59     YMenuButton::setLabel( label );
60 }
61
62
63 void
64 YQMenuButton::rebuildMenuTree()
65 {
66     //
67     // Delete any previous menu
68     // (in case the menu items got replaced)
69     //
70
71     if ( _qt_button->menu() )
72         delete _qt_button->menu();
73
74     //
75     // Create toplevel menu
76     //
77
78     QMenu * menu = new QMenu( _qt_button );
79     YUI_CHECK_NEW( menu );
80     _qt_button->setMenu( menu );
81
82     connect( menu,      SIGNAL( triggered         ( QAction* ) ),
83              this,      SLOT  ( menuEntryActivated( QAction* ) ) );
84
85     //
86     // Recursively add Qt menu items from the YMenuItems
87     //
88
89     rebuildMenuTree( menu, itemsBegin(), itemsEnd() );
90 }
91
92
93 void
94 YQMenuButton::rebuildMenuTree( QMenu * parentMenu, YItemIterator begin, YItemIterator end )
95 {
96     for ( YItemIterator it = begin; it != end; ++it )
97     {
98         YMenuItem * item = dynamic_cast<YMenuItem *> (*it);
99         YUI_CHECK_PTR( item );
100
101         QPixmap icon;
102
103         if ( item->hasIconName() )
104         {
105             string iconName = iconFullPath( item );
106             icon = QPixmap( iconName.c_str() );
107
108             if ( icon.isNull() )
109                 y2warning( "Can't load icon %s", iconName.c_str() );
110         }
111
112         if ( item->hasChildren() )
113         {
114             QMenu * subMenu;
115
116             if ( icon.isNull() )
117                 subMenu = parentMenu->addMenu( fromUTF8( item->label() ));
118             else
119                 subMenu = parentMenu->addMenu( QIcon( icon ), fromUTF8( item->label() ));
120
121             connect( subMenu,   SIGNAL( triggered         ( QAction* ) ),
122                      this,      SLOT  ( menuEntryActivated( QAction* ) ) );
123
124             rebuildMenuTree( subMenu, item->childrenBegin(), item->childrenEnd() );
125         }
126         else // No children - leaf entry
127         {
128             // item->index() is guaranteed to be unique within this YMenuButton's items,
129             // so it can easily be used as unique ID in all Q3PopupMenus that belong
130             // to this YQMenuButton.
131
132             QAction *act;
133             if ( icon.isNull() )
134                 act = parentMenu->addAction( fromUTF8( item->label() ) );
135             else
136                 act = parentMenu->addAction( QIcon( icon ), fromUTF8( item->label() ) );
137             _serials[act] = item->index();
138         }
139     }
140 }
141
142
143 void
144 YQMenuButton::menuEntryActivated( QAction* action )
145 {
146     int serialNo = -1;
147     if ( _serials.contains( action ) )
148         serialNo = _serials[action];
149
150     // y2debug( "Selected menu entry #%d", menu_item_index );
151     _selectedItem = findMenuItem( serialNo );
152
153     if ( _selectedItem )
154     {
155         /*
156          * Defer the real returnNow() until all popup related events have been
157          * processed. This took me some hours to figure out; obviously
158          * exit_loop() doesn't have any effect as long as there are still
159          * popups open. So be it - use a zero timer to perform the real
160          * returnNow() later.
161          */
162
163         /*
164          * the 100 delay is a ugly dirty workaround
165          */
166         QTimer::singleShot( 100, this, SLOT( returnNow() ) );
167     }
168     else
169     {
170         y2error( "No menu item with serial no. %d", serialNo );
171     }
172 }
173
174
175 void
176 YQMenuButton::returnNow()
177 {
178     if ( _selectedItem )
179     {
180         YQUI::ui()->sendEvent( new YMenuEvent( _selectedItem ) );
181         _selectedItem = 0;
182     }
183 }
184
185
186
187 void
188 YQMenuButton::setEnabled( bool enabled )
189 {
190     _qt_button->setEnabled( enabled );
191     YWidget::setEnabled( enabled );
192 }
193
194
195 int YQMenuButton::preferredWidth()
196 {
197     return 2*YQButtonBorder + _qt_button->sizeHint().width();
198 }
199
200
201 int YQMenuButton::preferredHeight()
202 {
203     return 2*YQButtonBorder + _qt_button->sizeHint().height();
204 }
205
206
207 void
208 YQMenuButton::setSize( int newWidth, int newHeight )
209 {
210     _qt_button->resize( newWidth  - 2 * YQButtonBorder,
211                             newHeight - 2 * YQButtonBorder );
212     resize( newWidth, newHeight );
213 }
214
215
216 bool
217 YQMenuButton::setKeyboardFocus()
218 {
219     _qt_button->setFocus();
220
221     return true;
222 }
223
224
225 #include "YQMenuButton.moc"