KDEUI
kpushbutton.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kpushbutton.h" 00021 #include <QStyleOptionToolButton> 00022 #include <QStylePainter> 00023 00024 #include <QtGui/QDrag> 00025 #include <QtGui/QActionEvent> 00026 #include <QtGui/QMenu> 00027 #include <QtCore/QPointer> 00028 #include <QtGui/QStyle> 00029 #include <QtCore/QTimer> 00030 00031 #include <config.h> 00032 00033 #include <kconfig.h> 00034 #include <kglobal.h> 00035 #include <kglobalsettings.h> 00036 #include <kguiitem.h> 00037 #include <kicon.h> 00038 00039 #include "auth/kauthaction.h" 00040 #include "auth/kauthactionwatcher.h" 00041 00042 static bool s_useIcons = false; 00043 00044 class KPushButton::KPushButtonPrivate 00045 { 00046 public: 00047 KPushButtonPrivate(KPushButton *_parent) : parent(_parent), m_dragEnabled( false ), authAction(0) 00048 { 00049 } 00050 00051 KPushButton *parent; 00052 00053 KGuiItem item; 00054 KStandardGuiItem::StandardItem itemType; 00055 QPointer<QMenu> delayedMenu; 00056 QTimer * delayedMenuTimer; 00057 bool m_dragEnabled; 00058 QPoint startPos; 00059 KAuth::Action *authAction; 00060 // TODO: Remove whenever QIcon overlays will get fixed 00061 KIcon oldIcon; 00062 00063 void slotSettingsChanged( int ); 00064 void slotPressedInternal(); 00065 void slotClickedInternal(); 00066 void authStatusChanged(int status); 00067 void slotDelayedMenuTimeout(); 00068 void readSettings(); 00069 }; 00070 00071 void KPushButton::KPushButtonPrivate::slotSettingsChanged( int /* category */ ) 00072 { 00073 readSettings(); 00074 parent->setIcon( item.icon() ); 00075 } 00076 00077 void KPushButton::KPushButtonPrivate::slotPressedInternal() 00078 { 00079 if (!delayedMenu.isNull()) { 00080 if (delayedMenuTimer==0) { 00081 delayedMenuTimer=new QTimer(parent); 00082 delayedMenuTimer->setSingleShot(true); 00083 connect(delayedMenuTimer,SIGNAL(timeout()),parent,SLOT(slotDelayedMenuTimeout())); 00084 } 00085 const int delay=parent->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, parent); 00086 delayedMenuTimer->start((delay<=0) ? 150:delay); 00087 } 00088 } 00089 00090 void KPushButton::KPushButtonPrivate::slotClickedInternal() 00091 { 00092 if (delayedMenuTimer) 00093 delayedMenuTimer->stop(); 00094 00095 if (authAction) { 00096 KAuth::Action::AuthStatus s = authAction->earlyAuthorize(); 00097 switch(s) { 00098 case KAuth::Action::Denied: 00099 parent->setEnabled(false); 00100 break; 00101 case KAuth::Action::Authorized: 00102 emit parent->authorized(authAction); 00103 break; 00104 default: 00105 break; 00106 } 00107 } 00108 } 00109 00110 void KPushButton::KPushButtonPrivate::slotDelayedMenuTimeout() { 00111 delayedMenuTimer->stop(); 00112 if (!delayedMenu.isNull()) { 00113 parent->setMenu(delayedMenu); 00114 parent->showMenu(); 00115 parent->setMenu(0); 00116 } 00117 } 00118 00119 void KPushButton::KPushButtonPrivate::authStatusChanged(int status) 00120 { 00121 KAuth::Action::AuthStatus s = (KAuth::Action::AuthStatus)status; 00122 00123 switch(s) { 00124 case KAuth::Action::Authorized: 00125 parent->setEnabled(true); 00126 if(!oldIcon.isNull()) { 00127 parent->setIcon(oldIcon); 00128 oldIcon = KIcon(); 00129 } 00130 break; 00131 case KAuth::Action::AuthRequired: 00132 parent->setEnabled(true); 00133 oldIcon = KIcon(parent->icon()); 00134 parent->setIcon(KIcon("dialog-password")); 00135 break; 00136 default: 00137 parent->setEnabled(false); 00138 if(!oldIcon.isNull()) { 00139 parent->setIcon(oldIcon); 00140 oldIcon = KIcon(); 00141 } 00142 } 00143 } 00144 00145 void KPushButton::KPushButtonPrivate::readSettings() 00146 { 00147 s_useIcons = KGlobalSettings::showIconsOnPushButtons(); 00148 } 00149 00150 00151 00152 KPushButton::KPushButton( QWidget *parent ) 00153 : QPushButton( parent ), d( new KPushButtonPrivate(this) ) 00154 { 00155 init( KGuiItem( "" ) ); 00156 } 00157 00158 KPushButton::KPushButton( const QString &text, QWidget *parent ) 00159 : QPushButton( parent ), d( new KPushButtonPrivate(this) ) 00160 { 00161 init( KGuiItem( text ) ); 00162 } 00163 00164 KPushButton::KPushButton( const KIcon &icon, const QString &text, 00165 QWidget *parent ) 00166 : QPushButton( text, parent ), d( new KPushButtonPrivate(this) ) 00167 { 00168 init( KGuiItem( text, icon ) ); 00169 } 00170 00171 KPushButton::KPushButton( const KGuiItem &item, QWidget *parent ) 00172 : QPushButton( parent ), d( new KPushButtonPrivate(this) ) 00173 { 00174 init( item ); 00175 } 00176 00177 KPushButton::~KPushButton() 00178 { 00179 delete d; 00180 } 00181 00182 void KPushButton::init( const KGuiItem &item ) 00183 { 00184 d->item = item; 00185 d->itemType = (KStandardGuiItem::StandardItem) 0; 00186 d->delayedMenuTimer=0; 00187 00188 connect(this,SIGNAL(pressed()), this, SLOT(slotPressedInternal())); 00189 connect(this,SIGNAL(clicked()), this, SLOT(slotClickedInternal())); 00190 // call QPushButton's implementation since we don't need to 00191 // set the GUI items text or check the state of the icon set 00192 QPushButton::setText( d->item.text() ); 00193 00194 static bool initialized = false; 00195 if ( !initialized ) { 00196 d->readSettings(); 00197 initialized = true; 00198 } 00199 00200 setIcon( d->item.icon() ); 00201 00202 setToolTip( item.toolTip() ); 00203 00204 setWhatsThis(item.whatsThis()); 00205 00206 connect( KGlobalSettings::self(), SIGNAL( settingsChanged(int) ), 00207 SLOT( slotSettingsChanged(int) ) ); 00208 } 00209 00210 bool KPushButton::isDragEnabled() const 00211 { 00212 return d->m_dragEnabled; 00213 } 00214 00215 void KPushButton::setGuiItem( const KGuiItem& item ) 00216 { 00217 d->item = item; 00218 00219 // call QPushButton's implementation since we don't need to 00220 // set the GUI items text or check the state of the icon set 00221 QPushButton::setText( d->item.text() ); 00222 setIcon( d->item.icon() ); 00223 setToolTip( d->item.toolTip() ); 00224 setEnabled( d->item.isEnabled() ); 00225 setWhatsThis( d->item.whatsThis() ); 00226 } 00227 00228 void KPushButton::setGuiItem( KStandardGuiItem::StandardItem item ) 00229 { 00230 setGuiItem( KStandardGuiItem::guiItem(item) ); 00231 d->itemType = item; 00232 } 00233 00234 KStandardGuiItem::StandardItem KPushButton::guiItem() const 00235 { 00236 return d->itemType; 00237 } 00238 00239 void KPushButton::setText( const QString &text ) 00240 { 00241 QPushButton::setText(text); 00242 00243 // we need to re-evaluate the icon set when the text 00244 // is removed, or when it is supplied 00245 if (text.isEmpty() != d->item.text().isEmpty()) 00246 setIcon(d->item.icon()); 00247 00248 d->item.setText(text); 00249 } 00250 00251 void KPushButton::setIcon( const KIcon &icon ) 00252 { 00253 d->item.setIcon(icon); 00254 00255 if ( s_useIcons || text().isEmpty() ) 00256 QPushButton::setIcon( icon ); 00257 else 00258 QPushButton::setIcon( QIcon() ); 00259 } 00260 00261 #ifndef KDE_NO_DEPRECATED 00262 void KPushButton::setIcon( const QIcon &qicon ) 00263 { 00264 d->item.setIcon(KIcon(qicon)); 00265 } 00266 #endif 00267 00268 void KPushButton::setDragEnabled( bool enable ) 00269 { 00270 d->m_dragEnabled = enable; 00271 } 00272 00273 void KPushButton::mousePressEvent( QMouseEvent *e ) 00274 { 00275 if ( d->m_dragEnabled ) 00276 d->startPos = e->pos(); 00277 QPushButton::mousePressEvent( e ); 00278 } 00279 00280 void KPushButton::mouseMoveEvent( QMouseEvent *e ) 00281 { 00282 if ( !d->m_dragEnabled ) 00283 { 00284 QPushButton::mouseMoveEvent( e ); 00285 return; 00286 } 00287 00288 if ( (e->buttons() & Qt::LeftButton) && 00289 (e->pos() - d->startPos).manhattanLength() > 00290 KGlobalSettings::dndEventDelay() ) 00291 { 00292 startDrag(); 00293 setDown( false ); 00294 } 00295 } 00296 00297 QDrag * KPushButton::dragObject() 00298 { 00299 return 0; 00300 } 00301 00302 void KPushButton::startDrag() 00303 { 00304 QDrag *d = dragObject(); 00305 if ( d ) 00306 d->start(); 00307 } 00308 00309 void KPushButton::setDelayedMenu(QMenu *delayedMenu) 00310 { 00311 d->delayedMenu=delayedMenu; 00312 } 00313 00314 QMenu* KPushButton::delayedMenu() 00315 { 00316 return d->delayedMenu; 00317 } 00318 00319 KAuth::Action *KPushButton::authAction() const 00320 { 00321 return d->authAction; 00322 } 00323 00324 void KPushButton::setAuthAction(const QString &actionName) 00325 { 00326 if (actionName.isEmpty()) { 00327 setAuthAction(0); 00328 } else { 00329 setAuthAction(new KAuth::Action(actionName)); 00330 } 00331 } 00332 00333 void KPushButton::setAuthAction(KAuth::Action *action) 00334 { 00335 if (d->authAction == action) { 00336 return; 00337 } 00338 00339 if (d->authAction) { 00340 disconnect(d->authAction->watcher(), SIGNAL(statusChanged(int)), 00341 this, SLOT(authStatusChanged(int))); 00342 //delete d->authAction; 00343 d->authAction = 0; 00344 if (!d->oldIcon.isNull()) { 00345 setIcon(d->oldIcon); 00346 d->oldIcon = KIcon(); 00347 } 00348 } 00349 00350 if (action != 0) { 00351 d->authAction = action; 00352 00353 // Set the parent widget 00354 d->authAction->setParentWidget(this); 00355 00356 connect(d->authAction->watcher(), SIGNAL(statusChanged(int)), 00357 this, SLOT(authStatusChanged(int))); 00358 d->authStatusChanged(d->authAction->status()); 00359 } 00360 } 00361 00362 QSize KPushButton::sizeHint() const 00363 { 00364 const bool tempSetMenu = !menu() && d->delayedMenu; 00365 if (tempSetMenu) 00366 const_cast<KPushButton *>(this)->setMenu(d->delayedMenu); 00367 const QSize sz = QPushButton::sizeHint(); 00368 if (tempSetMenu) 00369 const_cast<KPushButton *>(this)->setMenu(0); 00370 return sz; 00371 } 00372 00373 void KPushButton::paintEvent( QPaintEvent * ) 00374 { 00375 QStylePainter p(this); 00376 QStyleOptionButton option; 00377 initStyleOption(&option); 00378 00379 if (d->delayedMenu) 00380 option.features |= QStyleOptionButton::HasMenu; 00381 00382 p.drawControl(QStyle::CE_PushButton, option); 00383 } 00384 00385 #include "kpushbutton.moc"
KDE 4.6 API Reference