• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

kaction.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002     Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
00003               (C) 1999 Simon Hausmann <hausmann@kde.org>
00004               (C) 2000 Nicolas Hadacek <haadcek@kde.org>
00005               (C) 2000 Kurt Granroth <granroth@kde.org>
00006               (C) 2000 Michael Koch <koch@kde.org>
00007               (C) 2001 Holger Freyther <freyther@kde.org>
00008               (C) 2002 Ellis Whitehead <ellis@kde.org>
00009               (C) 2002 Joseph Wenninger <jowenn@kde.org>
00010               (C) 2005-2006 Hamish Rodda <rodda@kde.org>
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Library General Public
00014     License version 2 as published by the Free Software Foundation.
00015 
00016     This library is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019     Library General Public License for more details.
00020 
00021     You should have received a copy of the GNU Library General Public License
00022     along with this library; see the file COPYING.LIB.  If not, write to
00023     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00024     Boston, MA 02110-1301, USA.
00025 */
00026 
00027 #include "kaction.h"
00028 #include "kaction_p.h"
00029 #include "kglobalaccel_p.h"
00030 #include "klocale.h"
00031 #include "kmessagebox.h"
00032 #include "kauthaction.h"
00033 #include "kauthactionwatcher.h"
00034 
00035 #include <QtGui/QApplication>
00036 #include <QtGui/QHBoxLayout>
00037 #include <QtGui/QShortcutEvent>
00038 #include <QtGui/QToolBar>
00039 
00040 #include <kdebug.h>
00041 
00042 #include "kguiitem.h"
00043 #include "kicon.h"
00044 
00045 //---------------------------------------------------------------------
00046 // KActionPrivate
00047 //---------------------------------------------------------------------
00048 
00049 void KActionPrivate::init(KAction *q_ptr)
00050 {
00051   q = q_ptr;
00052   globalShortcutEnabled = false;
00053   neverSetGlobalShortcut = true;
00054 
00055   QObject::connect(q, SIGNAL(triggered(bool)), q, SLOT(slotTriggered()));
00056 
00057   q->setProperty("isShortcutConfigurable", true);
00058 }
00059 
00060 void KActionPrivate::setActiveGlobalShortcutNoEnable(const KShortcut &cut)
00061 {
00062     globalShortcut = cut;
00063     emit q->globalShortcutChanged(cut.primary());
00064 }
00065 
00066 
00067 void KActionPrivate::slotTriggered()
00068 {
00069 #ifdef KDE3_SUPPORT
00070   emit q->activated();
00071 #endif
00072   emit q->triggered(QApplication::mouseButtons(), QApplication::keyboardModifiers());
00073 
00074   if (authAction) {
00075       KAuth::Action::AuthStatus s = authAction->earlyAuthorize();
00076       switch(s) {
00077       case KAuth::Action::Denied:
00078           q->setEnabled(false);
00079           break;
00080       case KAuth::Action::Authorized:
00081           emit q->authorized(authAction);
00082           break;
00083       default:
00084           break;
00085       }
00086   }
00087 }
00088 
00089 void KActionPrivate::authStatusChanged(int status)
00090 {
00091     KAuth::Action::AuthStatus s = (KAuth::Action::AuthStatus)status;
00092 
00093     switch(s) {
00094         case KAuth::Action::Authorized:
00095             q->setEnabled(true);
00096             if(!oldIcon.isNull()) {
00097                 q->setIcon(oldIcon);
00098                 oldIcon = KIcon();
00099             }
00100             break;
00101         case KAuth::Action::AuthRequired:
00102             q->setEnabled(true);
00103             oldIcon = KIcon(q->icon());
00104             q->setIcon(KIcon("dialog-password"));
00105             break;
00106         default:
00107             q->setEnabled(false);
00108             if(!oldIcon.isNull()) {
00109                 q->setIcon(oldIcon);
00110                 oldIcon = KIcon();
00111             }
00112     }
00113 }
00114 
00115 bool KAction::event(QEvent *event)
00116 {
00117     if (event->type() == QEvent::Shortcut) {
00118         QShortcutEvent *se = static_cast<QShortcutEvent*>(event);
00119         if(se->isAmbiguous()) {
00120             KMessageBox::information(
00121                     NULL,  // No widget to be seen around here
00122                     i18n( "The key sequence '%1' is ambiguous. Use 'Configure Shortcuts'\n"
00123                           "from the 'Settings' menu to solve the ambiguity.\n"
00124                           "No action will be triggered.",
00125                                 se->key().toString()),
00126                     i18n("Ambiguous shortcut detected"));
00127             return true;
00128         }
00129     }
00130 
00131     return QAction::event(event);
00132 }
00133 
00134 
00135 //---------------------------------------------------------------------
00136 // KAction
00137 //---------------------------------------------------------------------
00138 
00139 KAction::KAction(QObject *parent)
00140   : QWidgetAction(parent), d(new KActionPrivate)
00141 {
00142   d->init(this);
00143 }
00144 
00145 KAction::KAction(const QString &text, QObject *parent)
00146   : QWidgetAction(parent), d(new KActionPrivate)
00147 {
00148   d->init(this);
00149   setText(text);
00150 }
00151 
00152 KAction::KAction(const KIcon &icon, const QString &text, QObject *parent)
00153   : QWidgetAction(parent), d(new KActionPrivate)
00154 {
00155   d->init(this);
00156   setIcon(icon);
00157   setText(text);
00158 }
00159 
00160 KAction::~KAction()
00161 {
00162     if (d->globalShortcutEnabled) {
00163         // - remove the action from KGlobalAccel
00164         d->globalShortcutEnabled = false;
00165         KGlobalAccel::self()->d->remove(this, KGlobalAccelPrivate::SetInactive);
00166     }
00167 
00168     KGestureMap::self()->removeGesture(d->shapeGesture, this);
00169     KGestureMap::self()->removeGesture(d->rockerGesture, this);
00170     delete d;
00171 }
00172 
00173 bool KAction::isShortcutConfigurable() const
00174 {
00175     return property("isShortcutConfigurable").toBool();
00176 }
00177 
00178 void KAction::setShortcutConfigurable( bool b )
00179 {
00180     setProperty("isShortcutConfigurable", b);
00181 }
00182 
00183 KShortcut KAction::shortcut(ShortcutTypes type) const
00184 {
00185   Q_ASSERT(type);
00186 
00187   if (type == DefaultShortcut) {
00188       QKeySequence primary = property("defaultPrimaryShortcut").value<QKeySequence>();
00189       QKeySequence secondary = property("defaultAlternateShortcut").value<QKeySequence>();
00190       return KShortcut(primary, secondary);
00191   }
00192 
00193   QKeySequence primary = shortcuts().value(0);
00194   QKeySequence secondary = shortcuts().value(1);
00195   return KShortcut(primary, secondary);
00196 }
00197 
00198 void KAction::setShortcut( const KShortcut & shortcut, ShortcutTypes type )
00199 {
00200   Q_ASSERT(type);
00201 
00202   if (type & DefaultShortcut) {
00203       setProperty("defaultPrimaryShortcut", shortcut.primary());
00204       setProperty("defaultAlternateShortcut", shortcut.alternate());
00205   }
00206 
00207   if (type & ActiveShortcut) {
00208       QAction::setShortcuts(shortcut);
00209   }
00210 }
00211 
00212 void KAction::setShortcut( const QKeySequence & keySeq, ShortcutTypes type )
00213 {
00214   Q_ASSERT(type);
00215 
00216   if (type & DefaultShortcut)
00217       setProperty("defaultPrimaryShortcut", keySeq);
00218 
00219   if (type & ActiveShortcut) {
00220       QAction::setShortcut(keySeq);
00221   }
00222 }
00223 
00224 void KAction::setShortcuts(const QList<QKeySequence>& shortcuts, ShortcutTypes type)
00225 {
00226   setShortcut(KShortcut(shortcuts), type);
00227 }
00228 
00229 const KShortcut & KAction::globalShortcut(ShortcutTypes type) const
00230 {
00231   Q_ASSERT(type);
00232 
00233   if (type == DefaultShortcut)
00234     return d->defaultGlobalShortcut;
00235 
00236   return d->globalShortcut;
00237 }
00238 
00239 void KAction::setGlobalShortcut( const KShortcut & shortcut, ShortcutTypes type,
00240                                  GlobalShortcutLoading load )
00241 {
00242   Q_ASSERT(type);
00243   bool changed = false;
00244 
00245   // protect against garbage keycode -1 that Qt sometimes produces for exotic keys;
00246   // at the moment (~mid 2008) Multimedia PlayPause is one of those keys.
00247   int shortcutKeys[8];
00248   for (int i = 0; i < 4; i++) {
00249     shortcutKeys[i] = shortcut.primary()[i];
00250     shortcutKeys[i + 4] = shortcut.alternate()[i];
00251   }
00252   for (int i = 0; i < 8; i++) {
00253     if (shortcutKeys[i] == -1) {
00254       kWarning(283) << "Encountered garbage keycode (keycode = -1) in input, not doing anything.";
00255       return;
00256     }
00257   }
00258 
00259   if (!d->globalShortcutEnabled) {
00260     changed = true;
00261     if (objectName().isEmpty() || objectName().startsWith(QLatin1String("unnamed-"))) {
00262       kWarning(283) << "Attempt to set global shortcut for action without objectName()."
00263                        " Read the setGlobalShortcut() documentation.";
00264       return;
00265     }
00266     d->globalShortcutEnabled = true;
00267     KGlobalAccel::self()->d->doRegister(this);
00268   }
00269 
00270   if ((type & DefaultShortcut) && d->defaultGlobalShortcut != shortcut) {
00271     d->defaultGlobalShortcut = shortcut;
00272     changed = true;
00273   }
00274 
00275   if ((type & ActiveShortcut) && d->globalShortcut != shortcut) {
00276     d->globalShortcut = shortcut;
00277     changed = true;
00278   }
00279 
00280   //We want to have updateGlobalShortcuts called on a new action in any case so that
00281   //it will be registered properly. In the case of the first setShortcut() call getting an
00282   //empty shortcut parameter this would not happen...
00283   if (changed || d->neverSetGlobalShortcut) {
00284     KGlobalAccel::self()->d->updateGlobalShortcut(this, type | load);
00285     d->neverSetGlobalShortcut = false;
00286   }
00287 }
00288 
00289 #ifndef KDE_NO_DEPRECATED
00290 bool KAction::globalShortcutAllowed() const
00291 {
00292   return d->globalShortcutEnabled;
00293 }
00294 #endif
00295 
00296 bool KAction::isGlobalShortcutEnabled() const
00297 {
00298   return d->globalShortcutEnabled;
00299 }
00300 
00301 #ifndef KDE_NO_DEPRECATED
00302 void KAction::setGlobalShortcutAllowed( bool allowed, GlobalShortcutLoading /* load */ )
00303 {
00304   if (allowed) {
00305       //### no-op
00306   } else {
00307       forgetGlobalShortcut();
00308   }
00309 }
00310 #endif
00311 
00312 void KAction::forgetGlobalShortcut()
00313 {
00314     d->globalShortcut = KShortcut();
00315     d->defaultGlobalShortcut = KShortcut();
00316     if (d->globalShortcutEnabled) {
00317         d->globalShortcutEnabled = false;
00318         d->neverSetGlobalShortcut = true;   //it's a fresh start :)
00319         KGlobalAccel::self()->d->remove(this, KGlobalAccelPrivate::UnRegister);
00320     }
00321 }
00322 
00323 KShapeGesture KAction::shapeGesture( ShortcutTypes type ) const
00324 {
00325   Q_ASSERT(type);
00326   if ( type & DefaultShortcut )
00327     return d->defaultShapeGesture;
00328 
00329   return d->shapeGesture;
00330 }
00331 
00332 KRockerGesture KAction::rockerGesture( ShortcutTypes type ) const
00333 {
00334   Q_ASSERT(type);
00335   if ( type & DefaultShortcut )
00336     return d->defaultRockerGesture;
00337 
00338   return d->rockerGesture;
00339 }
00340 
00341 void KAction::setShapeGesture( const KShapeGesture& gest,  ShortcutTypes type )
00342 {
00343   Q_ASSERT(type);
00344 
00345   if( type & DefaultShortcut )
00346     d->defaultShapeGesture = gest;
00347 
00348   if ( type & ActiveShortcut ) {
00349     if ( KGestureMap::self()->findAction( gest ) ) {
00350       kDebug(283) << "New mouse gesture already in use, won't change gesture.";
00351       return;
00352     }
00353     KGestureMap::self()->removeGesture( d->shapeGesture, this );
00354     KGestureMap::self()->addGesture( gest, this );
00355     d->shapeGesture = gest;
00356   }
00357 }
00358 
00359 void KAction::setRockerGesture( const KRockerGesture& gest,  ShortcutTypes type )
00360 {
00361   Q_ASSERT(type);
00362 
00363   if( type & DefaultShortcut )
00364     d->defaultRockerGesture = gest;
00365 
00366   if ( type & ActiveShortcut ) {
00367     if ( KGestureMap::self()->findAction( gest ) ) {
00368       kDebug(283) << "New mouse gesture already in use, won't change gesture.";
00369       return;
00370     }
00371     KGestureMap::self()->removeGesture( d->rockerGesture, this );
00372     KGestureMap::self()->addGesture( gest, this );
00373     d->rockerGesture = gest;
00374   }
00375 }
00376 
00377 void KAction::setHelpText(const QString& text)
00378 {
00379     setStatusTip(text);
00380     setToolTip(text);
00381     if (whatsThis().isEmpty())
00382         setWhatsThis(text);
00383 }
00384 
00385 KAuth::Action *KAction::authAction() const
00386 {
00387     return d->authAction;
00388 }
00389 
00390 void KAction::setAuthAction(const QString &actionName)
00391 {
00392     if (actionName.isEmpty()) {
00393         setAuthAction(0);
00394     } else {
00395         setAuthAction(new KAuth::Action(actionName));
00396     }
00397 }
00398 
00399 void KAction::setAuthAction(KAuth::Action *action)
00400 {
00401     if (d->authAction == action) {
00402         return;
00403     }
00404 
00405     if (d->authAction) {
00406         disconnect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
00407                 this, SLOT(authStatusChanged(int)));
00408         //delete d->authAction;
00409         d->authAction = 0;
00410         if (!d->oldIcon.isNull()) {
00411             setIcon(d->oldIcon);
00412             d->oldIcon = KIcon();
00413         }
00414     }
00415 
00416     if (action != 0) {
00417         d->authAction = action;
00418 
00419         // Set the parent widget
00420         d->authAction->setParentWidget(parentWidget());
00421 
00422         connect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
00423                 this, SLOT(authStatusChanged(int)));
00424         d->authStatusChanged(d->authAction->status());
00425     }
00426 }
00427 
00428 /* vim: et sw=2 ts=2
00429  */
00430 
00431 #include "kaction.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal