picking up branches/tmp/sh/qt4-port/, merging it with trunk
[duncan/yast2-qt4.git] / src / YQComboBox.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQComboBox.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19
20 #define SEND_SELECTION_CHANGED_EVENT 0
21
22 #include <qstring.h>
23 #include <qlabel.h>
24 #include <qcombobox.h>
25 #include <qlineedit.h>
26 #include <qpixmap.h>
27 #define y2log_component "qt-ui"
28 #include <ycp/y2log.h>
29
30 #include "utf8.h"
31 #include "YQUI.h"
32 #include "YEvent.h"
33 #include "QY2CharValidator.h"
34 #include "YQComboBox.h"
35 #include "YQSignalBlocker.h"
36 #include "YQWidgetCaption.h"
37 #include <QVBoxLayout>
38
39
40 YQComboBox::YQComboBox( YWidget *       parent,
41                         const string &  label,
42                         bool            editable )
43     : QFrame( (QWidget *) parent->widgetRep() )
44     , YComboBox( parent, label, editable )
45     , _validator(0)
46 {
47     QVBoxLayout* layout = new QVBoxLayout( this );
48     setLayout( layout );
49
50     setWidgetRep( this );
51     layout->setSpacing( YQWidgetSpacing );
52     layout->setMargin ( YQWidgetMargin  );
53
54     _caption = new YQWidgetCaption( this, label );
55     YUI_CHECK_NEW( _caption );
56     layout->addWidget( _caption );
57
58     _qt_comboBox = new QComboBox( editable, this );
59     YUI_CHECK_NEW( _caption );
60     layout->addWidget( _qt_comboBox );
61
62     _caption->setBuddy( _qt_comboBox );
63
64 #if SEND_SELECTION_CHANGED_EVENT
65     connect( _qt_comboBox,      SIGNAL( highlighted (int) ),
66              this,              SLOT  ( slotSelected(int) ) );
67 #endif
68
69     connect( _qt_comboBox,      SIGNAL( activated  ( const QString & ) ),
70              this,              SLOT  ( textChanged( const QString & ) ) );
71
72     connect( _qt_comboBox,      SIGNAL( textChanged( const QString & ) ),
73              this,              SLOT  ( textChanged( const QString & ) ) );
74 }
75
76
77 YQComboBox::~YQComboBox()
78 {
79     // NOP
80 }
81
82
83 string YQComboBox::text()
84 {
85     return toUTF8( _qt_comboBox->currentText() );
86 }
87
88
89 void YQComboBox::setText( const string & newValue )
90 {
91     QString text = fromUTF8( newValue );
92
93     if ( isValidText( text ) )
94     {
95         YQSignalBlocker sigBlocker( _qt_comboBox );
96         _qt_comboBox->setCurrentText( text );
97     }
98     else
99     {
100         y2error( "%s \"%s\": Rejecting invalid value \"%s\"",
101                  widgetClass(), debugLabel().c_str(), newValue.c_str() );
102     }
103 }
104
105
106 void YQComboBox::addItem( YItem * item )
107 {
108     YComboBox::addItem( item );
109     QPixmap icon;
110
111     if ( item->hasIconName() )
112     {
113         string iconName = iconFullPath( item );
114         icon = QPixmap( iconName.c_str() );
115
116         if ( icon.isNull() )
117             y2warning( "Can't load icon %s", iconName.c_str() );
118     }
119
120     if ( icon.isNull() )
121         _qt_comboBox->insertItem( fromUTF8( item->label() ) );
122     else
123         _qt_comboBox->insertItem( icon, fromUTF8( item->label() ) );
124
125     if ( item->selected() )
126     {
127         YQSignalBlocker sigBlocker( _qt_comboBox );
128         setText( item->label() );
129     }
130 }
131
132
133 void YQComboBox::deleteAllItems()
134 {
135     YQSignalBlocker sigBlocker( _qt_comboBox );
136
137     _qt_comboBox->clear();
138     YComboBox::deleteAllItems();
139 }
140
141
142 void YQComboBox::setLabel( const string & label )
143 {
144     _caption->setText( label );
145     YComboBox::setLabel( label );
146 }
147
148
149 void YQComboBox::setValidChars( const string & newValidChars )
150 {
151     if ( ! _qt_comboBox->editable() )
152     {
153         y2warning( "Setting ValidChars is useless on a combo box that isn't editable! (%s)",
154                    debugLabel().c_str() );
155         return;
156     }
157
158     if ( _validator )
159     {
160         _validator->setValidChars( fromUTF8( newValidChars ) );
161     }
162     else
163     {
164         _validator = new QY2CharValidator( fromUTF8( newValidChars ), this );
165         _qt_comboBox->setValidator( _validator );
166
167         // No need to delete the validator in the destructor - Qt will take
168         // care of that since it's a QObject with a parent!
169     }
170
171     if ( ! isValidText( _qt_comboBox->currentText() ) )
172     {
173         y2error( "Old value \"%s\" of %s \"%s\" invalid according to ValidChars \"%s\" - deleting",
174                  (const char *) _qt_comboBox->currentText(),
175                  widgetClass(), debugLabel().c_str(),
176                  newValidChars.c_str() );
177         _qt_comboBox->setCurrentText( "" );
178     }
179
180     YComboBox::setValidChars( newValidChars );
181 }
182
183
184 bool YQComboBox::isValidText( const QString & txt ) const
185 {
186     if ( ! _validator )
187         return true;
188
189     int pos = 0;
190     QString text( txt );        // need a non-const QString &
191
192     return _validator->validate( text, pos ) == QValidator::Acceptable;
193 }
194
195
196 void YQComboBox::slotSelected( int i )
197 {
198     if ( notify() )
199     {
200         if ( ! YQUI::ui()->eventPendingFor( this ) )
201         {
202             // Avoid overwriting a (more important) ValueChanged event with a SelectionChanged event
203
204             YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
205         }
206     }
207 }
208
209
210 void YQComboBox::textChanged( const QString & new_text )
211 {
212     if ( notify() )
213         YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ValueChanged ) );
214 }
215
216
217 void YQComboBox::setInputMaxLength( int len )
218 {
219     _qt_comboBox->lineEdit()->setMaxLength( len );
220     YComboBox::setInputMaxLength( len );
221 }
222
223
224 int YQComboBox::preferredWidth()
225 {
226     return sizeHint().width();
227 }
228
229
230 int YQComboBox::preferredHeight()
231 {
232     return sizeHint().height();
233 }
234
235
236 void YQComboBox::setSize( int newWidth, int newHeight )
237 {
238     resize( newWidth, newHeight );
239 }
240
241
242 void YQComboBox::setEnabled( bool enabled )
243 {
244     _caption->setEnabled( enabled );
245     _qt_comboBox->setEnabled( enabled );
246     YWidget::setEnabled( enabled );
247 }
248
249
250 bool YQComboBox::setKeyboardFocus()
251 {
252     _qt_comboBox->setFocus();
253
254     return true;
255 }
256
257
258 #include "YQComboBox.moc"