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 void KPushButton::setIcon( const QIcon &qicon ) 00262 { 00263 d->item.setIcon(KIcon(qicon)); 00264 } 00265 00266 void KPushButton::setDragEnabled( bool enable ) 00267 { 00268 d->m_dragEnabled = enable; 00269 } 00270 00271 void KPushButton::mousePressEvent( QMouseEvent *e ) 00272 { 00273 if ( d->m_dragEnabled ) 00274 d->startPos = e->pos(); 00275 QPushButton::mousePressEvent( e ); 00276 } 00277 00278 void KPushButton::mouseMoveEvent( QMouseEvent *e ) 00279 { 00280 if ( !d->m_dragEnabled ) 00281 { 00282 QPushButton::mouseMoveEvent( e ); 00283 return; 00284 } 00285 00286 if ( (e->buttons() & Qt::LeftButton) && 00287 (e->pos() - d->startPos).manhattanLength() > 00288 KGlobalSettings::dndEventDelay() ) 00289 { 00290 startDrag(); 00291 setDown( false ); 00292 } 00293 } 00294 00295 QDrag * KPushButton::dragObject() 00296 { 00297 return 0; 00298 } 00299 00300 void KPushButton::startDrag() 00301 { 00302 QDrag *d = dragObject(); 00303 if ( d ) 00304 d->start(); 00305 } 00306 00307 void KPushButton::setDelayedMenu(QMenu *delayedMenu) 00308 { 00309 d->delayedMenu=delayedMenu; 00310 } 00311 00312 QMenu* KPushButton::delayedMenu() 00313 { 00314 return d->delayedMenu; 00315 } 00316 00317 KAuth::Action *KPushButton::authAction() const 00318 { 00319 return d->authAction; 00320 } 00321 00322 void KPushButton::setAuthAction(const QString &actionName) 00323 { 00324 if (actionName.isEmpty()) { 00325 setAuthAction(0); 00326 } else { 00327 setAuthAction(new KAuth::Action(actionName)); 00328 } 00329 } 00330 00331 void KPushButton::setAuthAction(KAuth::Action *action) 00332 { 00333 if (d->authAction == action) { 00334 return; 00335 } 00336 00337 if (d->authAction) { 00338 disconnect(d->authAction->watcher(), SIGNAL(statusChanged(int)), 00339 this, SLOT(authStatusChanged(int))); 00340 //delete d->authAction; 00341 d->authAction = 0; 00342 if (!d->oldIcon.isNull()) { 00343 setIcon(d->oldIcon); 00344 d->oldIcon = KIcon(); 00345 } 00346 } 00347 00348 if (action != 0) { 00349 d->authAction = action; 00350 00351 // Set the parent widget 00352 d->authAction->setParentWidget(this); 00353 00354 connect(d->authAction->watcher(), SIGNAL(statusChanged(int)), 00355 this, SLOT(authStatusChanged(int))); 00356 d->authStatusChanged(d->authAction->status()); 00357 } 00358 } 00359 00360 QSize KPushButton::sizeHint() const 00361 { 00362 const bool tempSetMenu = !menu() && d->delayedMenu; 00363 if (tempSetMenu) 00364 const_cast<KPushButton *>(this)->setMenu(d->delayedMenu); 00365 const QSize sz = QPushButton::sizeHint(); 00366 if (tempSetMenu) 00367 const_cast<KPushButton *>(this)->setMenu(0); 00368 return sz; 00369 } 00370 00371 void KPushButton::paintEvent( QPaintEvent * ) 00372 { 00373 QStylePainter p(this); 00374 QStyleOptionButton option; 00375 initStyleOption(&option); 00376 00377 if (d->delayedMenu) 00378 option.features |= QStyleOptionButton::HasMenu; 00379 00380 p.drawControl(QStyle::CE_PushButton, option); 00381 } 00382 00383 #include "kpushbutton.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:53:05 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:53:05 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.