KProperty

KPropertyUtils.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) 2004-2017 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 "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 
40 static 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  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));
60  p->setPen(palette.color(QPalette::Foreground));
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 
70 class GroupWidgetBase : public QWidget
71 {
72 public:
73  explicit GroupWidgetBase(QWidget* parent)
74  : 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 
105 protected:
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 
142 protected:
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 
165 class Q_DECL_HIDDEN KPropertyGroupWidget::Private
166 {
167 public:
168  Private() {}
169  QVBoxLayout* lyr;
170  GroupWidgetBase *groupWidget;
171  QPointer<QWidget> contents;
172 };
173 
174 KPropertyGroupWidget::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 
189 KPropertyGroupWidget::~KPropertyGroupWidget()
190 {
191  delete d;
192 }
193 
194 void 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 
209 bool 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 
226 QColor 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 
238 QColor 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 
250 KPROPERTYWIDGETS_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 
257 bool 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 }
MouseButtonPress
QEvent::Type type() const const
const QPalette & palette() const const
void fillRect(const QRectF &rectangle, const QBrush &brush)
QColor light(int factor) const const
const QFont & font() const const
QStyle * style() const const
const QColor & color(QPalette::ColorGroup group, QPalette::ColorRole role) const const
LeftButton
void drawLine(const QLineF &line)
void update()
AlignLeft
QColor dark(int factor) const const
void initFrom(const QWidget *widget)
int width() const const
void setBold(bool enable)
void drawRect(const QRectF &rectangle)
void setFont(const QFont &font)
virtual void paintEvent(QPaintEvent *event)
const QBrush & brush(QPalette::ColorGroup group, QPalette::ColorRole role) const const
QRgb rgb() const const
void setPen(const QColor &color)
Qt::MouseButton button() const const
CaseInsensitive
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
bool isEmpty() const const
void drawText(const QPointF &position, const QString &text)
QColor gridLineColor() const
void setSizePolicy(QSizePolicy)
QRect rect() const const
A widget for editing properties.
virtual QSize sizeHint() const const
The base class representing a single property.
Definition: KProperty.h:95
A container widget that can be used to split information into hideable sections for a property editor...
const QAbstractItemModel * model() const const
QFontMetrics fontMetrics() const const
QWidget * parentWidget() const const
virtual void drawControl(QStyle::ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const const =0
TextSingleLine
void update(Part *part, const QByteArray &data, qint64 dataSize)
QString fromLatin1(const char *str, int size)
void show()
QPoint pos() const const
lightGray
int compare(const QString &other, Qt::CaseSensitivity cs) const const
static QColor defaultGridLineColor()
virtual bool event(QEvent *event) override
int height() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Aug 9 2020 23:10:57 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.