Warning, file /libraries/kproperty/src/KPropertyUtils.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> 0003 Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net> 0004 Copyright (C) 2004-2017 Jarosław Staniek <staniek@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "KPropertyUtils.h" 0023 #include "KPropertyUtils_p.h" 0024 #include "KPropertyEditorDataModel_p.h" 0025 #include "KPropertyEditorView.h" 0026 0027 #include <QPainter> 0028 #include <QPixmap> 0029 #include <QStyle> 0030 #include <QStyleOption> 0031 #include <QStyleOptionHeader> 0032 #include <QMouseEvent> 0033 #include <QVBoxLayout> 0034 #include <QPointer> 0035 #include <QMetaEnum> 0036 0037 #define BRANCHBOX_SIZE 9 0038 0039 //! @internal 0040 static void paintListViewExpander(QPainter* p, QWidget* w, int height, const QPalette& palette, bool isOpen) 0041 { 0042 const int marg = (height - 2 - BRANCHBOX_SIZE) / 2; 0043 int xmarg = marg; 0044 #if 0 0045 //! @todo disabled: kstyles do not paint background yet... reenable in the future... 0046 KStyle* kstyle = dynamic_cast<KStyle*>(widget->style()); 0047 if (kstyle) { 0048 kstyle->drawKStylePrimitive( 0049 KStyle::KPE_ListViewExpander, p, w, QRect(xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE), 0050 cg, isOpen ? 0 : QStyle::Style_On, 0051 QStyleOption::Default); 0052 } 0053 #endif 0054 Q_UNUSED(w); 0055 //draw by hand 0056 p->setPen(KPropertyEditorView::defaultGridLineColor()); 0057 p->drawRect(xmarg, marg, BRANCHBOX_SIZE, BRANCHBOX_SIZE); 0058 p->fillRect(xmarg + 1, marg + 1, BRANCHBOX_SIZE - 2, BRANCHBOX_SIZE - 2, 0059 palette.brush(QPalette::Base)); 0060 p->setPen(palette.color(QPalette::Foreground)); 0061 p->drawLine(xmarg + 2, marg + BRANCHBOX_SIZE / 2, xmarg + BRANCHBOX_SIZE - 3, marg + BRANCHBOX_SIZE / 2); 0062 if (!isOpen) { 0063 p->drawLine(xmarg + BRANCHBOX_SIZE / 2, marg + 2, 0064 xmarg + BRANCHBOX_SIZE / 2, marg + BRANCHBOX_SIZE - 3); 0065 } 0066 } 0067 0068 //! @internal 0069 //! Based on KPopupTitle, see kpopupmenu.cpp 0070 class GroupWidgetBase : public QWidget 0071 { 0072 public: 0073 explicit GroupWidgetBase(QWidget* parent) 0074 : QWidget(parent) 0075 , m_isOpen(true) 0076 , m_mouseDown(false) { 0077 QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Fixed); 0078 sp.setHorizontalStretch(0); 0079 sp.setVerticalStretch(1); 0080 setSizePolicy(sp); 0081 } 0082 0083 void setText(const QString &text) { 0084 m_titleStr = text; 0085 } 0086 0087 void setIcon(const QPixmap &pix) { 0088 m_miniicon = pix; 0089 } 0090 0091 virtual bool isOpen() const { 0092 return m_isOpen; 0093 } 0094 0095 virtual void setOpen(bool set) { 0096 m_isOpen = set; 0097 } 0098 0099 QSize sizeHint() const override { 0100 QSize s(QWidget::sizeHint()); 0101 s.setHeight(fontMetrics().height()*2); 0102 return s; 0103 } 0104 0105 protected: 0106 void paintEvent(QPaintEvent *) override { 0107 QRect r(rect()); 0108 QPainter p(this); 0109 QStyleOptionHeader option; 0110 option.initFrom(this); 0111 option.state = m_mouseDown ? QStyle::State_Sunken : QStyle::State_Raised; 0112 style()->drawControl(QStyle::CE_Header, &option, &p, this); 0113 0114 paintListViewExpander(&p, this, r.height() + 2, palette(), isOpen()); 0115 if (!m_miniicon.isNull()) { 0116 p.drawPixmap(24, (r.height() - m_miniicon.height()) / 2, m_miniicon); 0117 } 0118 0119 if (!m_titleStr.isEmpty()) { 0120 int indent = 16 + (m_miniicon.isNull() ? 0 : (m_miniicon.width() + 4)); 0121 p.setPen(palette().color(QPalette::Text)); 0122 QFont f = p.font(); 0123 f.setBold(true); 0124 p.setFont(f); 0125 p.drawText(indent + 8, 0, width() - (indent + 8), 0126 height(), Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, 0127 m_titleStr); 0128 } 0129 } 0130 0131 bool event(QEvent * e) override { 0132 if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease) { 0133 QMouseEvent* me = static_cast<QMouseEvent*>(e); 0134 if (me->button() == Qt::LeftButton) { 0135 m_mouseDown = e->type() == QEvent::MouseButtonPress; 0136 update(); 0137 } 0138 } 0139 return QWidget::event(e); 0140 } 0141 0142 protected: 0143 QString m_titleStr; 0144 QPixmap m_miniicon; 0145 bool m_isOpen; 0146 bool m_mouseDown; 0147 }; 0148 0149 /* class GroupWidget : public GroupWidgetBase 0150 { 0151 public: 0152 explicit GroupWidget(EditorGroupItem *parentItem) 0153 : GroupWidgetBase(parentItem->listView()->viewport()) 0154 , m_parentItem(parentItem) { 0155 } 0156 0157 virtual bool isOpen() const { 0158 return m_parentItem->isOpen(); 0159 } 0160 0161 protected: 0162 EditorGroupItem *m_parentItem; 0163 };*/ 0164 0165 class Q_DECL_HIDDEN KPropertyGroupWidget::Private 0166 { 0167 public: 0168 Private() {} 0169 QVBoxLayout* lyr; 0170 GroupWidgetBase *groupWidget; 0171 QPointer<QWidget> contents; 0172 }; 0173 0174 KPropertyGroupWidget::KPropertyGroupWidget(const QString& title, QWidget* parent) 0175 : QWidget(parent) 0176 , d(new Private()) 0177 { 0178 QSizePolicy sp(QSizePolicy::Preferred, QSizePolicy::Fixed); 0179 sp.setHorizontalStretch(0); 0180 sp.setVerticalStretch(1); 0181 setSizePolicy(sp); 0182 d->lyr = new QVBoxLayout(this); 0183 d->groupWidget = new GroupWidgetBase(this); 0184 d->groupWidget->setText(title); 0185 d->lyr->addWidget(d->groupWidget); 0186 d->lyr->addSpacing(4); 0187 } 0188 0189 KPropertyGroupWidget::~KPropertyGroupWidget() 0190 { 0191 delete d; 0192 } 0193 0194 void KPropertyGroupWidget::setContents(QWidget* contents) 0195 { 0196 if (d->contents) { 0197 d->contents->hide(); 0198 d->lyr->removeWidget(d->contents); 0199 delete d->contents; 0200 } 0201 d->contents = contents; 0202 if (d->contents) { 0203 d->lyr->addWidget(d->contents); 0204 d->contents->show(); 0205 } 0206 update(); 0207 } 0208 0209 bool KPropertyGroupWidget::event(QEvent * e) 0210 { 0211 if (e->type() == QEvent::MouseButtonPress) { 0212 QMouseEvent* me = static_cast<QMouseEvent*>(e); 0213 if (me->button() == Qt::LeftButton && d->contents && d->groupWidget->rect().contains(me->pos())) { 0214 d->groupWidget->setOpen(!d->groupWidget->isOpen()); 0215 if (d->groupWidget->isOpen()) 0216 d->contents->show(); 0217 else 0218 d->contents->hide(); 0219 d->lyr->invalidate(); 0220 update(); 0221 } 0222 } 0223 return QWidget::event(e); 0224 } 0225 0226 QColor KPropertyUtilsPrivate::contrastColor(const QColor& c) 0227 { 0228 int g = qGray(c.rgb()); 0229 if (g > 110) 0230 return c.dark(300); 0231 else if (g > 80) 0232 return c.light(250); 0233 else if (g > 20) 0234 return c.light(400); 0235 return Qt::lightGray; 0236 } 0237 0238 QColor KPropertyUtilsPrivate::gridLineColor(const QWidget *widget) 0239 { 0240 Q_ASSERT(widget); 0241 KPropertyEditorView *view = nullptr; 0242 if (widget->parentWidget()) { 0243 view = qobject_cast<KPropertyEditorView*>(widget->parentWidget()->parentWidget()); 0244 } 0245 return view ? view->gridLineColor() : QColor(); 0246 } 0247 0248 // ------------------- 0249 0250 KPROPERTYWIDGETS_EXPORT KProperty* KPropertyUtils::propertyForIndex(const QModelIndex &index) 0251 { 0252 const KPropertyEditorDataModel *editorModel 0253 = qobject_cast<const KPropertyEditorDataModel*>(index.model()); 0254 return editorModel ? editorModel->propertyForIndex(index) : nullptr; 0255 } 0256 0257 bool KPropertyUtilsPrivate::shouldUseNativeDialogs() 0258 { 0259 #if defined Q_OS_UNIX && !defined Q_OS_MACOS 0260 const QString xdgSessionDesktop = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP").trimmed()); 0261 return xdgSessionDesktop.isEmpty() 0262 && 0 == xdgSessionDesktop.compare(QStringLiteral("KDE"), Qt::CaseInsensitive); 0263 #else 0264 return true; 0265 #endif 0266 }