• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • 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/QShortcutEvent>
00037 
00038 #include <kdebug.h>
00039 
00040 #include "kguiitem.h"
00041 #include "kicon.h"
00042 
00043 //---------------------------------------------------------------------
00044 // KActionPrivate
00045 //---------------------------------------------------------------------
00046 
00047 void KActionPrivate::init(KAction *q_ptr)
00048 {
00049   q = q_ptr;
00050   globalShortcutEnabled = false;
00051   neverSetGlobalShortcut = true;
00052 
00053   QObject::connect(q, SIGNAL(triggered(bool)), q, SLOT(slotTriggered()));
00054 
00055   q->setProperty("isShortcutConfigurable", true);
00056 }
00057 
00058 void KActionPrivate::setActiveGlobalShortcutNoEnable(const KShortcut &cut)
00059 {
00060     globalShortcut = cut;
00061     emit q->globalShortcutChanged(cut.primary());
00062 }
00063 
00064 
00065 void KActionPrivate::slotTriggered()
00066 {
00067 #ifdef KDE3_SUPPORT
00068   emit q->activated();
00069 #endif
00070   emit q->triggered(QApplication::mouseButtons(), QApplication::keyboardModifiers());
00071 
00072   if (authAction) {
00073       KAuth::Action::AuthStatus s = authAction->authorize();
00074       switch(s) {
00075       case KAuth::Action::Denied:
00076           q->setEnabled(false);
00077           break;
00078       case KAuth::Action::Authorized:
00079           emit q->authorized(authAction);
00080           break;
00081       default:
00082           break;
00083       }
00084   }
00085 }
00086 
00087 void KActionPrivate::authStatusChanged(int status)
00088 {
00089     KAuth::Action::AuthStatus s = (KAuth::Action::AuthStatus)status;
00090 
00091     switch(s) {
00092         case KAuth::Action::Authorized:
00093             q->setEnabled(true);
00094             if(!oldIcon.isNull()) {
00095                 q->setIcon(oldIcon);
00096                 oldIcon = KIcon();
00097             }
00098             break;
00099         case KAuth::Action::AuthRequired:
00100             q->setEnabled(true);
00101             oldIcon = KIcon(q->icon());
00102             q->setIcon(KIcon("dialog-password"));
00103             break;
00104         default:
00105             q->setEnabled(false);
00106             if(!oldIcon.isNull()) {
00107                 q->setIcon(oldIcon);
00108                 oldIcon = KIcon();
00109             }
00110     }
00111 }
00112 
00113 bool KAction::event(QEvent *event)
00114 {
00115     if (event->type() == QEvent::Shortcut) {
00116         QShortcutEvent *se = static_cast<QShortcutEvent*>(event);
00117         if(se->isAmbiguous()) {
00118             KMessageBox::information(
00119                     NULL,  // No widget to be seen around here
00120                     i18n( "The key sequence '%1' is ambiguous. Use 'Configure Shortcuts'\n"
00121                           "from the 'Settings' menu to solve the ambiguity.\n"
00122                           "No action will be triggered.",
00123                                 se->key().toString()),
00124                     i18n("Ambiguous shortcut detected"));
00125             return true;
00126         }
00127     }
00128 
00129     return QAction::event(event);
00130 }
00131 
00132 
00133 //---------------------------------------------------------------------
00134 // KAction
00135 //---------------------------------------------------------------------
00136 
00137 KAction::KAction(QObject *parent)
00138   : QWidgetAction(parent), d(new KActionPrivate)
00139 {
00140   d->init(this);
00141 }
00142 
00143 KAction::KAction(const QString &text, QObject *parent)
00144   : QWidgetAction(parent), d(new KActionPrivate)
00145 {
00146   d->init(this);
00147   setText(text);
00148 }
00149 
00150 KAction::KAction(const KIcon &icon, const QString &text, QObject *parent)
00151   : QWidgetAction(parent), d(new KActionPrivate)
00152 {
00153   d->init(this);
00154   setIcon(icon);
00155   setText(text);
00156 }
00157 
00158 KAction::~KAction()
00159 {
00160     if (d->globalShortcutEnabled) {
00161         // - remove the action from KGlobalAccel
00162         d->globalShortcutEnabled = false;
00163         KGlobalAccel::self()->d->remove(this, KGlobalAccelPrivate::SetInactive);
00164     }
00165 
00166     KGestureMap::self()->removeGesture(d->shapeGesture, this);
00167     KGestureMap::self()->removeGesture(d->rockerGesture, this);
00168     delete d;
00169 }
00170 
00171 bool KAction::isShortcutConfigurable() const
00172 {
00173     return property("isShortcutConfigurable").toBool();
00174 }
00175 
00176 void KAction::setShortcutConfigurable( bool b )
00177 {
00178     setProperty("isShortcutConfigurable", b);
00179 }
00180 
00181 KShortcut KAction::shortcut(ShortcutTypes type) const
00182 {
00183   Q_ASSERT(type);
00184 
00185   if (type == DefaultShortcut) {
00186       QKeySequence primary = property("defaultPrimaryShortcut").value<QKeySequence>();
00187       QKeySequence secondary = property("defaultAlternateShortcut").value<QKeySequence>();
00188       return KShortcut(primary, secondary);
00189   }
00190 
00191   QKeySequence primary = shortcuts().value(0);
00192   QKeySequence secondary = shortcuts().value(1);
00193   return KShortcut(primary, secondary);
00194 }
00195 
00196 void KAction::setShortcut( const KShortcut & shortcut, ShortcutTypes type )
00197 {
00198   Q_ASSERT(type);
00199 
00200   if (type & DefaultShortcut) {
00201       setProperty("defaultPrimaryShortcut", shortcut.primary());
00202       setProperty("defaultAlternateShortcut", shortcut.alternate());
00203   }
00204 
00205   if (type & ActiveShortcut) {
00206       QAction::setShortcuts(shortcut);
00207   }
00208 }
00209 
00210 void KAction::setShortcut( const QKeySequence & keySeq, ShortcutTypes type )
00211 {
00212   Q_ASSERT(type);
00213 
00214   if (type & DefaultShortcut)
00215       setProperty("defaultPrimaryShortcut", keySeq);
00216 
00217   if (type & ActiveShortcut) {
00218       QAction::setShortcut(keySeq);
00219   }
00220 }
00221 
00222 void KAction::setShortcuts(const QList<QKeySequence>& shortcuts, ShortcutTypes type)
00223 {
00224   setShortcut(KShortcut(shortcuts), type);
00225 }
00226 
00227 const KShortcut & KAction::globalShortcut(ShortcutTypes type) const
00228 {
00229   Q_ASSERT(type);
00230 
00231   if (type == DefaultShortcut)
00232     return d->defaultGlobalShortcut;
00233 
00234   return d->globalShortcut;
00235 }
00236 
00237 void KAction::setGlobalShortcut( const KShortcut & shortcut, ShortcutTypes type,
00238                                  GlobalShortcutLoading load )
00239 {
00240   Q_ASSERT(type);
00241   bool changed = false;
00242 
00243   // protect against garbage keycode -1 that Qt sometimes produces for exotic keys;
00244   // at the moment (~mid 2008) Multimedia PlayPause is one of those keys.
00245   int shortcutKeys[8];
00246   for (int i = 0; i < 4; i++) {
00247     shortcutKeys[i] = shortcut.primary()[i];
00248     shortcutKeys[i + 4] = shortcut.alternate()[i];
00249   }
00250   for (int i = 0; i < 8; i++) {
00251     if (shortcutKeys[i] == -1) {
00252       kWarning(283) << "Encountered garbage keycode (keycode = -1) in input, not doing anything.";
00253       return;
00254     }
00255   }
00256 
00257   if (!d->globalShortcutEnabled) {
00258     changed = true;
00259     if (objectName().isEmpty() || objectName().startsWith(QLatin1String("unnamed-"))) {
00260       kWarning(283) << "Attempt to set global shortcut for action without objectName()."
00261                        " Read the setGlobalShortcut() documentation.";
00262       return;
00263     }
00264     d->globalShortcutEnabled = true;
00265     KGlobalAccel::self()->d->doRegister(this);
00266   }
00267 
00268   if ((type & DefaultShortcut) && d->defaultGlobalShortcut != shortcut) {
00269     d->defaultGlobalShortcut = shortcut;
00270     changed = true;
00271   }
00272 
00273   if ((type & ActiveShortcut) && d->globalShortcut != shortcut) {
00274     d->globalShortcut = shortcut;
00275     changed = true;
00276   }
00277 
00278   //We want to have updateGlobalShortcuts called on a new action in any case so that
00279   //it will be registered properly. In the case of the first setShortcut() call getting an
00280   //empty shortcut parameter this would not happen...
00281   if (changed || d->neverSetGlobalShortcut) {
00282     KGlobalAccel::self()->d->updateGlobalShortcut(this, type | load);
00283     d->neverSetGlobalShortcut = false;
00284   }
00285 }
00286 
00287 bool KAction::globalShortcutAllowed() const
00288 {
00289   return d->globalShortcutEnabled;
00290 }
00291 
00292 bool KAction::isGlobalShortcutEnabled() const
00293 {
00294   return d->globalShortcutEnabled;
00295 }
00296 
00297 void KAction::setGlobalShortcutAllowed( bool allowed, GlobalShortcutLoading /* load */ )
00298 {
00299   if (allowed) {
00300       //### no-op
00301   } else {
00302       forgetGlobalShortcut();
00303   }
00304 }
00305 
00306 void KAction::forgetGlobalShortcut()
00307 {
00308     d->globalShortcut = KShortcut();
00309     d->defaultGlobalShortcut = KShortcut();
00310     if (d->globalShortcutEnabled) {
00311         d->globalShortcutEnabled = false;
00312         d->neverSetGlobalShortcut = true;   //it's a fresh start :)
00313         KGlobalAccel::self()->d->remove(this, KGlobalAccelPrivate::UnRegister);
00314     }
00315 }
00316 
00317 KShapeGesture KAction::shapeGesture( ShortcutTypes type ) const
00318 {
00319   Q_ASSERT(type);
00320   if ( type & DefaultShortcut )
00321     return d->defaultShapeGesture;
00322 
00323   return d->shapeGesture;
00324 }
00325 
00326 KRockerGesture KAction::rockerGesture( ShortcutTypes type ) const
00327 {
00328   Q_ASSERT(type);
00329   if ( type & DefaultShortcut )
00330     return d->defaultRockerGesture;
00331 
00332   return d->rockerGesture;
00333 }
00334 
00335 void KAction::setShapeGesture( const KShapeGesture& gest,  ShortcutTypes type )
00336 {
00337   Q_ASSERT(type);
00338 
00339   if( type & DefaultShortcut )
00340     d->defaultShapeGesture = gest;
00341 
00342   if ( type & ActiveShortcut ) {
00343     if ( KGestureMap::self()->findAction( gest ) ) {
00344       kDebug(283) << "New mouse gesture already in use, won't change gesture.";
00345       return;
00346     }
00347     KGestureMap::self()->removeGesture( d->shapeGesture, this );
00348     KGestureMap::self()->addGesture( gest, this );
00349     d->shapeGesture = gest;
00350   }
00351 }
00352 
00353 void KAction::setRockerGesture( const KRockerGesture& gest,  ShortcutTypes type )
00354 {
00355   Q_ASSERT(type);
00356 
00357   if( type & DefaultShortcut )
00358     d->defaultRockerGesture = gest;
00359 
00360   if ( type & ActiveShortcut ) {
00361     if ( KGestureMap::self()->findAction( gest ) ) {
00362       kDebug(283) << "New mouse gesture already in use, won't change gesture.";
00363       return;
00364     }
00365     KGestureMap::self()->removeGesture( d->rockerGesture, this );
00366     KGestureMap::self()->addGesture( gest, this );
00367     d->rockerGesture = gest;
00368   }
00369 }
00370 
00371 void KAction::setHelpText(const QString& text)
00372 {
00373     setStatusTip(text);
00374     setToolTip(text);
00375     if (whatsThis().isEmpty())
00376         setWhatsThis(text);
00377 }
00378 
00379 KAuth::Action *KAction::authAction() const
00380 {
00381     return d->authAction;
00382 }
00383 
00384 void KAction::setAuthAction(const QString &actionName)
00385 {
00386     if (actionName.isEmpty()) {
00387         setAuthAction(0);
00388     } else {
00389         setAuthAction(new KAuth::Action(actionName));
00390     }
00391 }
00392 
00393 void KAction::setAuthAction(KAuth::Action *action)
00394 {
00395     if (d->authAction == action) {
00396         return;
00397     }
00398   
00399     if (d->authAction) {
00400         disconnect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
00401                 this, SLOT(authStatusChanged(int)));
00402         //delete d->authAction;
00403         d->authAction = 0;
00404         if (!d->oldIcon.isNull()) {
00405             setIcon(d->oldIcon);
00406             d->oldIcon = KIcon();
00407         }
00408     }
00409 
00410     if (action != 0) {
00411         d->authAction = action;
00412         connect(d->authAction->watcher(), SIGNAL(statusChanged(int)),
00413                 this, SLOT(authStatusChanged(int)));
00414         d->authStatusChanged(d->authAction->status());
00415     }
00416 }
00417 
00418 /* vim: et sw=2 ts=2
00419  */
00420 
00421 #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
  • KUtils
  • Nepomuk
  • Plasma
  •     Sodep
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.9-20090814
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