KProperty

combobox.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2004 Cedric Pasteur <[email protected]>
3  Copyright (C) 2004 Alexander Dymo <[email protected]>
4  Copyright (C) 2008-2015 Jarosław Staniek <[email protected]>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20 */
21 
22 #include "combobox.h"
23 #include "KPropertyEditorView.h"
24 #include "KPropertyListData.h"
25 #include "KPropertyUtils.h"
26 #include "KPropertyUtils_p.h"
27 #include "KPropertyWidgetsFactory.h"
28 #include "kproperty_debug.h"
29 
30 #include <QCompleter>
31 #include <QGuiApplication>
32 
33 KPropertyComboBoxEditorOptions::KPropertyComboBoxEditorOptions()
34  : extraValueAllowed(false)
35 {
36 }
37 
38 KPropertyComboBoxEditorOptions::KPropertyComboBoxEditorOptions(
39  const KPropertyComboBoxEditorOptions &other)
40 {
41  *this = other;
42 }
43 
44 KPropertyComboBoxEditorOptions::~KPropertyComboBoxEditorOptions()
45 {
46  delete iconProvider;
47 }
48 
49 KPropertyComboBoxEditorOptions& KPropertyComboBoxEditorOptions::operator=(const KPropertyComboBoxEditorOptions &other)
50 {
51  if (this != &other) {
52  if (other.iconProvider) {
53  iconProvider = other.iconProvider->clone();
54  } else {
55  delete iconProvider;
56  iconProvider = nullptr;
57  }
58  extraValueAllowed = other.extraValueAllowed;
59  }
60  return *this;
61 }
62 
63 
64 class Q_DECL_HIDDEN KPropertyComboBoxEditor::Private
65 {
66 public:
67  Private()
68  {
69  }
70  ~Private()
71  {
72  delete completer;
73  }
74  KPropertyListData listData;
75  bool setValueEnabled = true;
76  KPropertyComboBoxEditorOptions options;
77  QCompleter *completer = nullptr;
78 };
79 
80 KPropertyComboBoxEditor::KPropertyComboBoxEditor(const KPropertyListData &listData,
81  const KPropertyComboBoxEditorOptions &options,
82  QWidget *parent)
83  : QComboBox(parent), d(new Private)
84 {
85  d->options = options;
86  setEditable(d->options.extraValueAllowed);
87  setInsertPolicy(QComboBox::NoInsert);
88  setAutoCompletion(true);
90  setListData(listData);
91  connect(this, SIGNAL(activated(int)), this, SLOT(slotValueChanged(int)));
92 
93  int paddingTop = 2;
94  int paddingLeft = 3;
95  const QString style(parent->style()->objectName());
96  if (!KPropertyUtilsPrivate::gridLineColor(this).isValid()) {
97  setFrame(false);
98  paddingTop = 0;
99  }
100  if (style == QLatin1String("windowsvista") || style == QLatin1String("fusion")) {
101  paddingLeft = 2;
102  }
103 
104  //Set the stylesheet to a plain style
105  QString styleSheet = QString::fromLatin1("QComboBox { \
106  %1 \
107  padding-top: %2px; padding-left: %3px; }").arg(borderSheet(this)).arg(paddingTop).arg(paddingLeft);
108  setStyleSheet(styleSheet);
109 }
110 
111 KPropertyComboBoxEditor::~KPropertyComboBoxEditor()
112 {
113  delete d;
114 }
115 
116 //static
117 QString KPropertyComboBoxEditor::borderSheet(const QWidget *widget)
118 {
119  Q_ASSERT(widget);
120  const QString style(widget->parentWidget() ? widget->parentWidget()->style()->objectName() : QString());
121  if (style == QLatin1String("windowsvista") // a hack
122  || style == QLatin1String("fusion"))
123  {
124  return QString();
125  }
126  return QLatin1String("border: 0px; ");
127 }
128 
129 bool KPropertyComboBoxEditor::listDataKeysAvailable() const
130 {
131  return !d->listData.keys().isEmpty();
132 }
133 
134 QVariant KPropertyComboBoxEditor::value() const
135 {
136  if (!listDataKeysAvailable())
137  return QVariant();
138 
139  const int idx = currentIndex();
140  if (idx < 0 || idx >= d->listData.keys().count()
141  || d->listData.names()[idx].toString() != currentText().trimmed())
142  {
143  if (!d->options.extraValueAllowed || currentText().isEmpty())
144  return QVariant();
145  return currentText().trimmed(); //trimmed 4 safety
146  }
147  return d->listData.keys()[idx];
148 }
149 
150 void KPropertyComboBoxEditor::setValue(const QVariant &value)
151 {
152  if (!d->setValueEnabled)
153  return;
154  const int idx = d->listData.keys().isEmpty() ? -1 : d->listData.keys().indexOf(value);
155 // kprDebug() << "**********" << idx << "" << value.toString();
156  if (idx >= 0 && idx < count()) {
157  setCurrentIndex(idx);
158  }
159  else {
160  if (idx < 0) {
161  if (d->options.extraValueAllowed) {
162  setCurrentIndex(-1);
163  setEditText(value.toString());
164  }
165  kprWarning() << "NO SUCH KEY:" << value.toString()
166  << "property=" << objectName();
167  } else {
169  for (int i = 0; i < count(); i++)
170  list += itemText(i);
171  kprWarning() << "NO SUCH INDEX WITHIN COMBOBOX:" << idx
172  << "count=" << count() << "value=" << value.toString()
173  << "property=" << objectName() << "\nActual combobox contents"
174  << list;
175  }
176  setItemText(currentIndex(), QString());
177  }
178 }
179 
180 void KPropertyComboBoxEditor::fillValues()
181 {
182  delete d->completer;
183  clear();
184  if (!listDataKeysAvailable())
185  return;
186 
187  int index = 0;
188  for (const QString &itemName : d->listData.namesAsStringList()) {
189  addItem(itemName);
190  if (d->options.iconProvider) {
191  QIcon icon = d->options.iconProvider->icon(index);
192  setItemIcon(index, icon);
193  }
194  index++;
195  }
196  if (isEditable()) {
197  d->completer = new QCompleter(d->listData.namesAsStringList());
198  d->completer->setWidget(this);
199  }
200 }
201 
202 void KPropertyComboBoxEditor::setListData(const KPropertyListData & listData)
203 {
204  d->listData = listData;
205  fillValues();
206 }
207 
208 void KPropertyComboBoxEditor::slotValueChanged(int)
209 {
210  emit commitData( this );
211 }
212 
213 void KPropertyComboBoxEditor::paintEvent( QPaintEvent * event )
214 {
215  QComboBox::paintEvent(event);
216  KPropertyWidgetsFactory::paintTopGridLine(this);
217 }
218 
219 //-----------------------
220 
221 KPropertyComboBoxDelegate::KPropertyComboBoxDelegate()
222 {
223  options()->setBordersVisible(true);
224 }
225 
226 QString KPropertyComboBoxDelegate::propertyValueToString(const KProperty* property, const QLocale &locale) const
227 {
228  Q_UNUSED(locale)
229  KPropertyListData *listData = property->listData();
230  if (!listData)
231  return property->value().toString();
232  if (property->value().isNull())
233  return QString();
234  //kprDebug() << "property->value()==" << property->value();
235  const int idx = listData->keys().indexOf(property->value());
236  //kprDebug() << "idx==" << idx;
237  if (idx == -1) {
238  if (!property->option("extraValueAllowed").toBool())
239  return QString();
240  else
241  return property->value().toString();
242  }
243  return property->listData()->names()[idx].toString();
244 }
245 
246 QString KPropertyComboBoxDelegate::valueToString(const QVariant& value, const QLocale &locale) const
247 {
248  Q_UNUSED(locale)
249  return value.toString();
250 }
251 
252 QWidget* KPropertyComboBoxDelegate::createEditor( int type, QWidget *parent,
253  const QStyleOptionViewItem & option, const QModelIndex & index ) const
254 {
255  Q_UNUSED(type);
256  Q_UNUSED(option);
257 
258  KProperty *property = KPropertyUtils::propertyForIndex(index);
259  if (!property) {
260  return nullptr;
261  }
262  KPropertyComboBoxEditorOptions options;
263  options.extraValueAllowed = property->option("extraValueAllowed", false).toBool();
264  KPropertyComboBoxEditor *cb = new KPropertyComboBoxEditor(*property->listData(), options, parent);
265  return cb;
266 }
QString styleSheet() const const
QStyle * style() const const
QVariant option(const char *name, const QVariant &defaultValue=QVariant()) const
Returns value of given option Option is set if returned value is not null. If there is no option for ...
Definition: KProperty.cpp:564
NoContextMenu
QVariant property(const char *name) const const
QLocale locale() const const
KPropertyListData * listData() const
Definition: KProperty.cpp:451
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
The base class representing a single property.
Definition: KProperty.h:95
virtual void paintEvent(QPaintEvent *e) override
QWidget * parentWidget() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
bool toBool() const const
QString fromLatin1(const char *str, int size)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QString toString() const const
virtual bool event(QEvent *event) override
A data container for properties of list type.
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Aug 5 2020 23:01:02 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.