KProperty

combobox.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
3 Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net>
4 Copyright (C) 2008-2015 Jarosław Staniek <staniek@kde.org>
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
33KPropertyComboBoxEditorOptions::KPropertyComboBoxEditorOptions()
34 : extraValueAllowed(false)
35{
36}
37
38KPropertyComboBoxEditorOptions::KPropertyComboBoxEditorOptions(
39 const KPropertyComboBoxEditorOptions &other)
40{
41 *this = other;
42}
43
44KPropertyComboBoxEditorOptions::~KPropertyComboBoxEditorOptions()
45{
46 delete iconProvider;
47}
48
49KPropertyComboBoxEditorOptions& 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
64class Q_DECL_HIDDEN KPropertyComboBoxEditor::Private
65{
66public:
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
80KPropertyComboBoxEditor::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);
89 setContextMenuPolicy(Qt::NoContextMenu);
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
111KPropertyComboBoxEditor::~KPropertyComboBoxEditor()
112{
113 delete d;
114}
115
116//static
117QString 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
129bool KPropertyComboBoxEditor::listDataKeysAvailable() const
130{
131 return !d->listData.keys().isEmpty();
132}
133
134QVariant 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
150void 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 }
177 }
178}
179
180void 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
202void KPropertyComboBoxEditor::setListData(const KPropertyListData & listData)
203{
204 d->listData = listData;
205 fillValues();
206}
207
208void KPropertyComboBoxEditor::slotValueChanged(int)
209{
210 emit commitData( this );
211}
212
213void KPropertyComboBoxEditor::paintEvent( QPaintEvent * event )
214{
216 KPropertyWidgetsFactory::paintTopGridLine(this);
217}
218
219//-----------------------
220
221KPropertyComboBoxDelegate::KPropertyComboBoxDelegate()
222{
223 options()->setBordersVisible(true);
224}
225
226QString 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
246QString KPropertyComboBoxDelegate::valueToString(const QVariant& value, const QLocale &locale) const
247{
248 Q_UNUSED(locale)
249 return value.toString();
250}
251
252QWidget* 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}
const KPropertyEditorCreatorOptions * options() const
Options for editor creating.
A data container for properties of list type.
QVariantList keys() const
A list containing all possible keys for a property.
QStringList namesAsStringList() const
The list of user-visible translated name elements as strings.
QVariantList names() const
The list of user-visible translated name elements.
The base class representing a single property.
Definition KProperty.h:96
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 ...
QVariant value() const
KPropertyListData * listData() const
bool isValid(QStringView ifopt)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void clear()
bool isEditable() const const
virtual bool event(QEvent *event) override
QString itemText(int index) const const
virtual void paintEvent(QPaintEvent *e) override
void setEditText(const QString &text)
void setItemIcon(int index, const QIcon &icon)
void setItemText(int index, const QString &text)
void setWidget(QWidget *widget)
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
NoContextMenu
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool isNull() const const
bool toBool() const const
QString toString() const const
QWidget * parentWidget() const const
QStyle * style() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:15:40 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.