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