KProperty

KPropertyUtils.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) 2004-2017 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 "KPropertyUtils.h"
23#include "KPropertyUtils_p.h"
24#include "KPropertyEditorDataModel_p.h"
25#include "KPropertyEditorView.h"
26
27#include <QPainter>
28#include <QPixmap>
29#include <QStyle>
30#include <QStyleOption>
31#include <QStyleOptionHeader>
32#include <QMouseEvent>
33#include <QVBoxLayout>
34#include <QPointer>
35#include <QMetaEnum>
36
37#define BRANCHBOX_SIZE 9
38
39//! @internal
40static void paintListViewExpander(QPainter* p, QWidget* w, int height, const QPalette& palette, bool isOpen)
41{
42 const int marg = (height - 2 - BRANCHBOX_SIZE) / 2;
43 int xmarg = marg;
44#if 0
45//! @todo disabled: kstyles do not paint background yet... reenable in the future...
46 KStyle* kstyle = dynamic_cast<KStyle*>(widget->style());
47 if (kstyle) {
48 kstyle->drawKStylePrimitive(
49 KStyle::KPE_ListViewExpander, p, w, QRect(xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE),
50 cg, isOpen ? 0 : QStyle::Style_On,
51 QStyleOption::Default);
52 }
53#endif
54 Q_UNUSED(w);
55 //draw by hand
57 p->drawRect(xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE);
58 p->fillRect(xmarg + 1, marg + 1, BRANCHBOX_SIZE - 2, BRANCHBOX_SIZE - 2,
59 palette.brush(QPalette::Base));
61 p->drawLine(xmarg + 2, marg + BRANCHBOX_SIZE / 2, xmarg + BRANCHBOX_SIZE - 3, marg + BRANCHBOX_SIZE / 2);
62 if (!isOpen) {
63 p->drawLine(xmarg + BRANCHBOX_SIZE / 2, marg + 2,
64 xmarg + BRANCHBOX_SIZE / 2, marg + BRANCHBOX_SIZE - 3);
65 }
66}
67
68//! @internal
69//! Based on KPopupTitle, see kpopupmenu.cpp
70class GroupWidgetBase : public QWidget
71{
72public:
73 explicit GroupWidgetBase(QWidget* parent)
75 , m_isOpen(true)
76 , m_mouseDown(false) {
78 sp.setHorizontalStretch(0);
79 sp.setVerticalStretch(1);
80 setSizePolicy(sp);
81 }
82
83 void setText(const QString &text) {
84 m_titleStr = text;
85 }
86
87 void setIcon(const QPixmap &pix) {
88 m_miniicon = pix;
89 }
90
91 virtual bool isOpen() const {
92 return m_isOpen;
93 }
94
95 virtual void setOpen(bool set) {
96 m_isOpen = set;
97 }
98
99 QSize sizeHint() const override {
101 s.setHeight(fontMetrics().height()*2);
102 return s;
103 }
104
105protected:
106 void paintEvent(QPaintEvent *) override {
107 QRect r(rect());
108 QPainter p(this);
109 QStyleOptionHeader option;
110 option.initFrom(this);
111 option.state = m_mouseDown ? QStyle::State_Sunken : QStyle::State_Raised;
112 style()->drawControl(QStyle::CE_Header, &option, &p, this);
113
114 paintListViewExpander(&p, this, r.height() + 2, palette(), isOpen());
115 if (!m_miniicon.isNull()) {
116 p.drawPixmap(24, (r.height() - m_miniicon.height()) / 2, m_miniicon);
117 }
118
119 if (!m_titleStr.isEmpty()) {
120 int indent = 16 + (m_miniicon.isNull() ? 0 : (m_miniicon.width() + 4));
121 p.setPen(palette().color(QPalette::Text));
122 QFont f = p.font();
123 f.setBold(true);
124 p.setFont(f);
125 p.drawText(indent + 8, 0, width() - (indent + 8),
127 m_titleStr);
128 }
129 }
130
131 bool event(QEvent * e) override {
133 QMouseEvent* me = static_cast<QMouseEvent*>(e);
134 if (me->button() == Qt::LeftButton) {
135 m_mouseDown = e->type() == QEvent::MouseButtonPress;
136 update();
137 }
138 }
139 return QWidget::event(e);
140 }
141
142protected:
143 QString m_titleStr;
144 QPixmap m_miniicon;
145 bool m_isOpen;
146 bool m_mouseDown;
147};
148
149/* class GroupWidget : public GroupWidgetBase
150 {
151 public:
152 explicit GroupWidget(EditorGroupItem *parentItem)
153 : GroupWidgetBase(parentItem->listView()->viewport())
154 , m_parentItem(parentItem) {
155 }
156
157 virtual bool isOpen() const {
158 return m_parentItem->isOpen();
159 }
160
161 protected:
162 EditorGroupItem *m_parentItem;
163 };*/
164
165class Q_DECL_HIDDEN KPropertyGroupWidget::Private
166{
167public:
168 Private() {}
169 QVBoxLayout* lyr;
170 GroupWidgetBase *groupWidget;
171 QPointer<QWidget> contents;
172};
173
174KPropertyGroupWidget::KPropertyGroupWidget(const QString& title, QWidget* parent)
175 : QWidget(parent)
176 , d(new Private())
177{
179 sp.setHorizontalStretch(0);
180 sp.setVerticalStretch(1);
181 setSizePolicy(sp);
182 d->lyr = new QVBoxLayout(this);
183 d->groupWidget = new GroupWidgetBase(this);
184 d->groupWidget->setText(title);
185 d->lyr->addWidget(d->groupWidget);
186 d->lyr->addSpacing(4);
187}
188
189KPropertyGroupWidget::~KPropertyGroupWidget()
190{
191 delete d;
192}
193
194void KPropertyGroupWidget::setContents(QWidget* contents)
195{
196 if (d->contents) {
197 d->contents->hide();
198 d->lyr->removeWidget(d->contents);
199 delete d->contents;
200 }
201 d->contents = contents;
202 if (d->contents) {
203 d->lyr->addWidget(d->contents);
204 d->contents->show();
205 }
206 update();
207}
208
209bool KPropertyGroupWidget::event(QEvent * e)
210{
211 if (e->type() == QEvent::MouseButtonPress) {
212 QMouseEvent* me = static_cast<QMouseEvent*>(e);
213 if (me->button() == Qt::LeftButton && d->contents && d->groupWidget->rect().contains(me->pos())) {
214 d->groupWidget->setOpen(!d->groupWidget->isOpen());
215 if (d->groupWidget->isOpen())
216 d->contents->show();
217 else
218 d->contents->hide();
219 d->lyr->invalidate();
220 update();
221 }
222 }
223 return QWidget::event(e);
224}
225
226QColor KPropertyUtilsPrivate::contrastColor(const QColor& c)
227{
228 int g = qGray(c.rgb());
229 if (g > 110)
230 return c.dark(300);
231 else if (g > 80)
232 return c.light(250);
233 else if (g > 20)
234 return c.light(400);
235 return Qt::lightGray;
236}
237
238QColor KPropertyUtilsPrivate::gridLineColor(const QWidget *widget)
239{
240 Q_ASSERT(widget);
241 KPropertyEditorView *view = nullptr;
242 if (widget->parentWidget()) {
243 view = qobject_cast<KPropertyEditorView*>(widget->parentWidget()->parentWidget());
244 }
245 return view ? view->gridLineColor() : QColor();
246}
247
248// -------------------
249
250KPROPERTYWIDGETS_EXPORT KProperty* KPropertyUtils::propertyForIndex(const QModelIndex &index)
251{
252 const KPropertyEditorDataModel *editorModel
253 = qobject_cast<const KPropertyEditorDataModel*>(index.model());
254 return editorModel ? editorModel->propertyForIndex(index) : nullptr;
255}
256
257bool KPropertyUtilsPrivate::shouldUseNativeDialogs()
258{
259#if defined Q_OS_UNIX && !defined Q_OS_MACOS
260 const QString xdgSessionDesktop = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP").trimmed());
261 return xdgSessionDesktop.isEmpty()
262 && 0 == xdgSessionDesktop.compare(QStringLiteral("KDE"), Qt::CaseInsensitive);
263#else
264 return true;
265#endif
266}
A widget for editing properties.
static QColor defaultGridLineColor()
A container widget that can be used to split information into hideable sections for a property editor...
The base class representing a single property.
Definition KProperty.h:96
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
virtual void invalidate() override
QColor dark(int factor) const const
QColor light(int factor) const const
QRgb rgb() const const
MouseButtonPress
QEvent::Type type() const const
void setBold(bool enable)
void removeWidget(QWidget *widget)
const QAbstractItemModel * model() const const
Qt::MouseButton button() const const
QPoint pos() const const
QObject * parent() const const
void drawLine(const QLineF &line)
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
void drawRect(const QRectF &rectangle)
void drawText(const QPointF &position, const QString &text)
void fillRect(const QRectF &rectangle, const QBrush &brush)
const QFont & font() const const
void setFont(const QFont &font)
void setPen(const QColor &color)
const QBrush & brush(QPalette::ColorGroup group, QPalette::ColorRole role) const const
const QColor & color(QPalette::ColorGroup group, QPalette::ColorRole role) const const
int height() const const
bool isNull() const const
int width() const const
int compare(const QString &other, Qt::CaseSensitivity cs) const const
QString fromLatin1(const char *str, int size)
bool isEmpty() const const
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const=0
void initFrom(const QWidget *widget)
AlignLeft
CaseInsensitive
lightGray
LeftButton
TextSingleLine
virtual bool event(QEvent *event) override
QFontMetrics fontMetrics() const const
QWidget * parentWidget() const const
void setSizePolicy(QSizePolicy)
QStyle * style() const const
void update()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:41:55 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.