libyui-qt  2.53.0
YQComboBox.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: YQComboBox.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 
26 #define SEND_SELECTION_CHANGED_EVENT 0
27 
28 #include <qstring.h>
29 #include <qlabel.h>
30 #include <qcombobox.h>
31 #include <qlineedit.h>
32 #define YUILogComponent "qt-ui"
33 #include <yui/YUILog.h>
34 
35 #include "utf8.h"
36 #include "YQUI.h"
37 #include <yui/YEvent.h>
38 #include "QY2CharValidator.h"
39 #include "YQComboBox.h"
40 #include "YQSignalBlocker.h"
41 #include "YQWidgetCaption.h"
42 #include <QVBoxLayout>
43 #include <QDebug>
44 
45 using std::string;
46 using std::endl;
47 
48 
49 
50 YQComboBox::YQComboBox( YWidget * parent,
51  const string & label,
52  bool editable )
53  : QFrame( (QWidget *) parent->widgetRep() )
54  , YComboBox( parent, label, editable )
55  , _validator(0)
56 {
57  QVBoxLayout* layout = new QVBoxLayout( this );
58  setLayout( layout );
59 
60  setWidgetRep( this );
61  layout->setSpacing( YQWidgetSpacing );
62  layout->setMargin ( YQWidgetMargin );
63 
64  _caption = new YQWidgetCaption( this, label );
65  YUI_CHECK_NEW( _caption );
66  layout->addWidget( _caption );
67 
68  _qt_comboBox = new QComboBox(this);
69  _qt_comboBox->setEditable(editable);
70  YUI_CHECK_NEW( _caption );
71  layout->addWidget( _qt_comboBox );
72 
73  _caption->setBuddy( _qt_comboBox );
74 
75 #if SEND_SELECTION_CHANGED_EVENT
76  connect( _qt_comboBox, &pclass(_qt_comboBox)::highlighted,
77  this, &pclass(this)::slotSelected );
78 #endif
79 
80 #if (QT_VERSION < QT_VERSION_CHECK( 5, 15, 0 ))
81 
82  // The Trolls introduced a bunch of SOURCE CODE INCOMPATIBILITIES in a MINOR RELEASE!
83  // With Qt 5.15, they deprecated a ton of functions, causing a ton of warnings.
84  // For us, this means a build failure because we always compile with -Werror,
85  // promoting all warnings to errors.
86  //
87  // Seriously, Trolls, WTF?!?
88  //
89  // And now we have to live with ugly stuff like this #if QT_VERSION. Thanks a lot.
90  //
91  // -- 2020-05-20 HuHa
92 
93  connect( _qt_comboBox, static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::activated),
94  this, &pclass(this)::textChanged );
95 #else
96  connect( _qt_comboBox, static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::textActivated),
97  this, &pclass(this)::textChanged );
98 #endif
99 
100  connect( _qt_comboBox, &pclass(_qt_comboBox)::editTextChanged,
101  this, &pclass(this)::textChanged );
102 }
103 
104 
106 {
107  // NOP
108 }
109 
110 
112 {
113  return toUTF8( _qt_comboBox->currentText() );
114 }
115 
116 
117 void YQComboBox::setText( const string & newValue )
118 {
119  QString text = fromUTF8( newValue );
120 
121  if ( isValidText( text ) )
122  {
123  YQSignalBlocker sigBlocker( _qt_comboBox );
124  int index = _qt_comboBox->findText( text );
125  if ( index < 0 )
126  _qt_comboBox->setEditText( text );
127  else
128  {
129  _qt_comboBox->setCurrentIndex( index );
130  _qt_comboBox->setItemText(index, text );
131  }
132  }
133  else
134  {
135  yuiError() << this << ": Rejecting invalid value \"" << newValue << "\"" << endl;
136  }
137 }
138 
139 
140 void YQComboBox::addItem( YItem * item )
141 {
142  YComboBox::addItem( item );
143  QIcon icon;
144 
145  if ( item->hasIconName() )
146  {
147  icon = YQUI::ui()->loadIcon( item->iconName() );
148  }
149 
150  if ( icon.isNull() )
151  _qt_comboBox->addItem( fromUTF8( item->label() ) );
152  else
153  _qt_comboBox->addItem( icon, fromUTF8( item->label() ) );
154 
155  if ( item->selected() )
156  {
157  YQSignalBlocker sigBlocker( _qt_comboBox );
158  setText( item->label() );
159  }
160 }
161 
162 
164 {
165  YQSignalBlocker sigBlocker( _qt_comboBox );
166 
167  _qt_comboBox->clear();
168  YComboBox::deleteAllItems();
169 }
170 
171 
172 void YQComboBox::setLabel( const string & label )
173 {
174  _caption->setText( label );
175  YComboBox::setLabel( label );
176 }
177 
178 
179 void YQComboBox::setValidChars( const string & newValidChars )
180 {
181  if ( ! _qt_comboBox->isEditable() )
182  {
183  yuiWarning() << this << ": Setting ValidChars is useless on a combo box that isn't editable!" << endl;
184  return;
185  }
186 
187  if ( _validator )
188  {
189  _validator->setValidChars( fromUTF8( newValidChars ) );
190  }
191  else
192  {
193  _validator = new QY2CharValidator( fromUTF8( newValidChars ), this );
194  _qt_comboBox->setValidator( _validator );
195 
196  // No need to delete the validator in the destructor - Qt will take
197  // care of that since it's a QObject with a parent!
198  }
199 
200  if ( ! isValidText( _qt_comboBox->currentText() ) )
201  {
202  yuiError() << this << ": Old value \"" << _qt_comboBox->currentText()
203  << " \" invalid according to new ValidChars \""<< newValidChars << "\" - deleting"
204  << endl;
205  _qt_comboBox->setItemText(_qt_comboBox->currentIndex(), "");
206  }
207 
208  YComboBox::setValidChars( newValidChars );
209 }
210 
211 
212 bool YQComboBox::isValidText( const QString & txt ) const
213 {
214  if ( ! _validator )
215  return true;
216 
217  int pos = 0;
218  QString text( txt ); // need a non-const QString &
219 
220  return _validator->validate( text, pos ) == QValidator::Acceptable;
221 }
222 
223 
225 {
226  if ( notify() )
227  {
228  if ( ! YQUI::ui()->eventPendingFor( this ) )
229  {
230  // Avoid overwriting a (more important) ValueChanged event with a SelectionChanged event
231 
232  YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::SelectionChanged ) );
233  }
234  }
235 }
236 
237 
238 void YQComboBox::textChanged( QString )
239 {
240  if ( notify() )
241  YQUI::ui()->sendEvent( new YWidgetEvent( this, YEvent::ValueChanged ) );
242 }
243 
244 
246 {
247  _qt_comboBox->lineEdit()->setMaxLength( len );
248  YComboBox::setInputMaxLength( len );
249 }
250 
251 
253 {
254  return sizeHint().width();
255 }
256 
257 
259 {
260  return sizeHint().height();
261 }
262 
263 
264 void YQComboBox::setSize( int newWidth, int newHeight )
265 {
266  resize( newWidth, newHeight );
267 }
268 
269 
270 void YQComboBox::setEnabled( bool enabled )
271 {
272  _caption->setEnabled( enabled );
273  _qt_comboBox->setEnabled( enabled );
274  YWidget::setEnabled( enabled );
275 }
276 
277 
279 {
280  _qt_comboBox->setFocus();
281 
282  return true;
283 }
284 
YQSignalBlocker
Helper class to block Qt signals for QWidgets or QObjects as long as this object exists.
Definition: YQSignalBlocker.h:37
QY2CharValidator
Definition: QY2CharValidator.h:35
YQComboBox::deleteAllItems
virtual void deleteAllItems()
Delete all items.
Definition: YQComboBox.cc:163
YQComboBox::slotSelected
void slotSelected(int i)
Tells the ui that an item has been selected.
Definition: YQComboBox.cc:224
YQUI::sendEvent
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
YQComboBox::addItem
virtual void addItem(YItem *item)
Add one item.
Definition: YQComboBox.cc:140
YQComboBox::preferredHeight
virtual int preferredHeight()
Preferred height of the widget.
Definition: YQComboBox.cc:258
QY2CharValidator::setValidChars
void setValidChars(const QString &newValidChars)
Set the valid input characters.
Definition: QY2CharValidator.h:66
YQComboBox::setKeyboardFocus
virtual bool setKeyboardFocus()
Accept the keyboard focus.
Definition: YQComboBox.cc:278
YQComboBox::isValidText
bool isValidText(const QString &txt) const
Returns 'true' if the given text is valid according to the current setting of ValidChars.
Definition: YQComboBox.cc:212
YQComboBox::preferredWidth
virtual int preferredWidth()
Preferred width of the widget.
Definition: YQComboBox.cc:252
YQComboBox::setValidChars
virtual void setValidChars(const std::string &validChars)
Change the valid input characters.
Definition: YQComboBox.cc:179
YQComboBox::setSize
virtual void setSize(int newWidth, int newHeight)
Set the new size of the widget.
Definition: YQComboBox.cc:264
YQComboBox::setInputMaxLength
virtual void setInputMaxLength(int numberOfChars)
Specify the amount of characters which can be inserted.
Definition: YQComboBox.cc:245
YQWidgetCaption::setText
virtual void setText(const std::string &newText)
Change the text and handle visibility: If the new text is empty, hide this widget.
Definition: YQWidgetCaption.cc:59
QY2CharValidator::validate
virtual State validate(QString &input, int &pos) const
Check user input.
Definition: QY2CharValidator.cc:51
YQUI::ui
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:83
YQComboBox::setText
virtual void setText(const std::string &newText)
Set this ComboBox's current value as text.
Definition: YQComboBox.cc:117
YQComboBox::setLabel
virtual void setLabel(const std::string &label)
Change the label text.
Definition: YQComboBox.cc:172
YQComboBox::textChanged
void textChanged(QString)
Tells the ui that the user has edited the text ( if the 'editable' option is set ).
Definition: YQComboBox.cc:238
YQWidgetCaption
Helper class for captions (labels) above a widget: Takes care of hiding itself when its text is empty...
Definition: YQWidgetCaption.h:39
YQComboBox::setEnabled
virtual void setEnabled(bool enabled)
Set enabled / disabled state.
Definition: YQComboBox.cc:270
YQComboBox::text
virtual std::string text()
Return this ComboBox's current value as text.
Definition: YQComboBox.cc:111
YQComboBox::~YQComboBox
~YQComboBox()
Destructor.
Definition: YQComboBox.cc:105
YQComboBox::YQComboBox
YQComboBox(YWidget *parent, const std::string &label, bool editable)
Constructor.
Definition: YQComboBox.cc:50
YQUI::loadIcon
QIcon loadIcon(const string &iconName) const
Load an icon.
Definition: YQUI.cc:708