File indexing completed on 2024-04-14 14:20:24
0001 /* This file is part of the KDE libraries 0002 Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@kde.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kpushbutton.h" 0021 #include <QStyleOptionToolButton> 0022 #include <QStylePainter> 0023 0024 #include <QDrag> 0025 #include <QActionEvent> 0026 #include <QMenu> 0027 #include <QPointer> 0028 #include <QStyle> 0029 #include <QTimer> 0030 #include <QApplication> 0031 0032 #include <kguiitem.h> 0033 0034 #include <kauth/objectdecorator.h> 0035 0036 class Q_DECL_HIDDEN KPushButton::KPushButtonPrivate 0037 { 0038 public: 0039 KPushButtonPrivate(KPushButton *_parent) : parent(_parent), m_dragEnabled(false), decorator(nullptr) 0040 { 0041 } 0042 0043 KPushButton *parent; 0044 0045 KStandardGuiItem::StandardItem itemType; 0046 QPointer<QMenu> delayedMenu; 0047 QTimer *delayedMenuTimer; 0048 bool m_dragEnabled; 0049 QPoint startPos; 0050 KAuth::ObjectDecorator *decorator; 0051 0052 void slotPressedInternal(); 0053 void slotClickedInternal(); 0054 void authStatusChanged(KAuth::Action::AuthStatus status); 0055 void slotDelayedMenuTimeout(); 0056 }; 0057 0058 void KPushButton::KPushButtonPrivate::slotPressedInternal() 0059 { 0060 if (!delayedMenu.isNull()) { 0061 if (delayedMenuTimer == nullptr) { 0062 delayedMenuTimer = new QTimer(parent); 0063 delayedMenuTimer->setSingleShot(true); 0064 connect(delayedMenuTimer, SIGNAL(timeout()), parent, SLOT(slotDelayedMenuTimeout())); 0065 } 0066 const int delay = parent->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, nullptr, parent); 0067 delayedMenuTimer->start((delay <= 0) ? 150 : delay); 0068 } 0069 } 0070 0071 void KPushButton::KPushButtonPrivate::slotClickedInternal() 0072 { 0073 if (delayedMenuTimer) { 0074 delayedMenuTimer->stop(); 0075 } 0076 } 0077 0078 void KPushButton::KPushButtonPrivate::slotDelayedMenuTimeout() 0079 { 0080 delayedMenuTimer->stop(); 0081 if (!delayedMenu.isNull()) { 0082 parent->setMenu(delayedMenu); 0083 parent->showMenu(); 0084 parent->setMenu(nullptr); 0085 } 0086 } 0087 0088 KPushButton::KPushButton(QWidget *parent) 0089 : QPushButton(parent), d(new KPushButtonPrivate(this)) 0090 { 0091 initWidget(KGuiItem("")); 0092 } 0093 0094 KPushButton::KPushButton(const QString &text, QWidget *parent) 0095 : QPushButton(parent), d(new KPushButtonPrivate(this)) 0096 { 0097 initWidget(KGuiItem(text)); 0098 } 0099 0100 KPushButton::KPushButton(const QIcon &icon, const QString &text, 0101 QWidget *parent) 0102 : QPushButton(text, parent), d(new KPushButtonPrivate(this)) 0103 { 0104 initWidget(KGuiItem(text, icon)); 0105 } 0106 0107 KPushButton::KPushButton(const KGuiItem &item, QWidget *parent) 0108 : QPushButton(parent), d(new KPushButtonPrivate(this)) 0109 { 0110 initWidget(item); 0111 } 0112 0113 KPushButton::~KPushButton() 0114 { 0115 delete d; 0116 } 0117 0118 void KPushButton::initWidget(const KGuiItem &item) 0119 { 0120 d->decorator = new KAuth::ObjectDecorator(this); 0121 connect(d->decorator, SIGNAL(authorized(KAuth::Action)), 0122 this, SIGNAL(authorized(KAuth::Action))); 0123 0124 d->itemType = (KStandardGuiItem::StandardItem) 0; 0125 d->delayedMenuTimer = nullptr; 0126 0127 connect(this, SIGNAL(pressed()), this, SLOT(slotPressedInternal())); 0128 connect(this, SIGNAL(clicked()), this, SLOT(slotClickedInternal())); 0129 KGuiItem::assign(this, item); 0130 } 0131 0132 bool KPushButton::isDragEnabled() const 0133 { 0134 return d->m_dragEnabled; 0135 } 0136 0137 void KPushButton::setGuiItem(const KGuiItem &item) 0138 { 0139 KGuiItem::assign(this, item); 0140 } 0141 0142 void KPushButton::setGuiItem(KStandardGuiItem::StandardItem item) 0143 { 0144 setGuiItem(KStandardGuiItem::guiItem(item)); 0145 d->itemType = item; 0146 } 0147 0148 KStandardGuiItem::StandardItem KPushButton::guiItem() const 0149 { 0150 return d->itemType; 0151 } 0152 0153 void KPushButton::setText(const QString &text) 0154 { 0155 QPushButton::setText(text); 0156 } 0157 0158 void KPushButton::setIcon(const QIcon &icon) 0159 { 0160 const bool useIcons = style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons, nullptr, this); 0161 if (useIcons || text().isEmpty()) { 0162 QPushButton::setIcon(icon); 0163 } else { 0164 QPushButton::setIcon(QIcon()); 0165 } 0166 } 0167 0168 void KPushButton::setDragEnabled(bool enable) 0169 { 0170 d->m_dragEnabled = enable; 0171 } 0172 0173 void KPushButton::mousePressEvent(QMouseEvent *e) 0174 { 0175 if (d->m_dragEnabled) { 0176 d->startPos = e->pos(); 0177 } 0178 QPushButton::mousePressEvent(e); 0179 } 0180 0181 void KPushButton::mouseMoveEvent(QMouseEvent *e) 0182 { 0183 if (!d->m_dragEnabled) { 0184 QPushButton::mouseMoveEvent(e); 0185 return; 0186 } 0187 0188 if ((e->buttons() & Qt::LeftButton) && 0189 (e->pos() - d->startPos).manhattanLength() > 0190 QApplication::startDragDistance()) { 0191 startDrag(); 0192 setDown(false); 0193 } 0194 } 0195 0196 QDrag *KPushButton::dragObject() 0197 { 0198 return nullptr; 0199 } 0200 0201 void KPushButton::startDrag() 0202 { 0203 QDrag *d = dragObject(); 0204 if (d) { 0205 d->start(); 0206 } 0207 } 0208 0209 void KPushButton::setDelayedMenu(QMenu *delayedMenu) 0210 { 0211 d->delayedMenu = delayedMenu; 0212 } 0213 0214 QMenu *KPushButton::delayedMenu() 0215 { 0216 return d->delayedMenu; 0217 } 0218 0219 KAuth::Action KPushButton::authAction() const 0220 { 0221 return d->decorator->authAction(); 0222 } 0223 0224 void KPushButton::setAuthAction(const QString &actionName) 0225 { 0226 d->decorator->setAuthAction(actionName); 0227 } 0228 0229 void KPushButton::setAuthAction(const KAuth::Action &action) 0230 { 0231 d->decorator->setAuthAction(action); 0232 } 0233 0234 QSize KPushButton::sizeHint() const 0235 { 0236 const bool tempSetMenu = !menu() && d->delayedMenu; 0237 if (tempSetMenu) { 0238 const_cast<KPushButton *>(this)->setMenu(d->delayedMenu); 0239 } 0240 const QSize sz = QPushButton::sizeHint(); 0241 if (tempSetMenu) { 0242 const_cast<KPushButton *>(this)->setMenu(nullptr); 0243 } 0244 return sz; 0245 } 0246 0247 void KPushButton::paintEvent(QPaintEvent *) 0248 { 0249 QStylePainter p(this); 0250 QStyleOptionButton option; 0251 initStyleOption(&option); 0252 0253 if (d->delayedMenu) { 0254 option.features |= QStyleOptionButton::HasMenu; 0255 } 0256 0257 p.drawControl(QStyle::CE_PushButton, option); 0258 } 0259 0260 #include "moc_kpushbutton.cpp"