kexi

kexisharedactionhost.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl>
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 "kexisharedactionhost.h"
00021 #include "kexisharedactionhost_p.h"
00022 #include "kexiactionproxy.h"
00023 #include "kexidialogbase.h"
00024 
00025 #include <kexiutils/utils.h>
00026 
00027 #include <kiconloader.h>
00028 #include <kdebug.h>
00029 
00030 KexiSharedActionHostPrivate::KexiSharedActionHostPrivate(KexiSharedActionHost *h)
00031 : QObject(0,"KexiSharedActionHostPrivate")
00032 , actionProxies(401)
00033 , actionMapper( this )
00034 , volatileActions(401)
00035 , enablers(401, false)
00036 , host(h)
00037 {
00038     volatileActions.setAutoDelete(true);
00039     connect(&actionMapper, SIGNAL(mapped(const QString &)), this, SLOT(slotAction(const QString &)));
00040 }
00041 
00042 void KexiSharedActionHostPrivate::slotAction(const QString& act_id)
00043 {
00044     QWidget *w = host->focusWindow(); //focusWidget();
00045 //  while (w && !w->inherits("KexiDialogBase") && !w->inherits("KexiDockBase"))
00046 //      w = w->parentWidget();
00047 
00048     KexiActionProxy *proxy = w ? actionProxies[ w ] : 0;
00049 
00050     if (!proxy || !proxy->activateSharedAction(act_id.latin1())) {
00051         //also try to find previous enabler
00052         w = enablers[act_id.latin1()];
00053         if (!w)
00054             return;
00055         proxy = actionProxies[ w ];
00056         if (!proxy)
00057             return;
00058         proxy->activateSharedAction(act_id.latin1());
00059     }
00060 }
00061 
00062 //--------------------------------------------------
00063 
00065 KexiSharedActionHost KexiSharedActionHost_dummy = KexiSharedActionHost(0);
00066 
00068 KexiSharedActionHost* KexiSharedActionHost_defaultHost = &KexiSharedActionHost_dummy;
00069 
00070 KexiSharedActionHost& KexiSharedActionHost::defaultHost()
00071 {
00072     return *KexiSharedActionHost_defaultHost;
00073 }
00074 
00075 void KexiSharedActionHost::setAsDefaultHost()
00076 {
00077     KexiSharedActionHost_defaultHost = this;
00078 }
00079 
00080 //--------------------------------------------------
00081 
00082 KexiSharedActionHost::KexiSharedActionHost(KMainWindow* mainWin)
00083 : d( new KexiSharedActionHostPrivate(this) )
00084 {
00085     d->mainWin = mainWin;
00086 }
00087 
00088 KexiSharedActionHost::~KexiSharedActionHost()
00089 {
00090     if (KexiSharedActionHost_defaultHost == this) {
00091         //default host is destroyed! - restore dummy
00092         KexiSharedActionHost_defaultHost = &KexiSharedActionHost_dummy;
00093     }
00094     delete d;
00095     d=0; 
00096 }
00097 
00098 void KexiSharedActionHost::setActionAvailable(const char *action_name, bool avail)
00099 {
00100     KAction *act = d->mainWin->actionCollection()->action(action_name);
00101     if (act) {
00102         act->setEnabled(avail);
00103     }
00104 }
00105 
00106 void KexiSharedActionHost::updateActionAvailable(const char *action_name, bool avail, QObject *obj)
00107 {
00108 /*test  if (qstrcmp(action_name, "tablepart_toggle_pkey")==0) {
00109         kdDebug() << "tablepart_toggle_pkey" << endl;
00110     }*/
00111     if (!d)
00112         return; //sanity
00113     QWidget *fw = d->mainWin->focusWidget();
00114     while (fw && obj!=fw)
00115         fw = fw->parentWidget();
00116     if (!fw)
00117         return;
00118 
00119     setActionAvailable(action_name, avail);
00120     if (avail) {
00121         d->enablers.replace(action_name, fw);
00122     }
00123     else {
00124         d->enablers.take(action_name);
00125     }
00126 }
00127 
00128 void KexiSharedActionHost::plugActionProxy(KexiActionProxy *proxy)
00129 {
00130 //  kdDebug() << "KexiSharedActionHost::plugActionProxy():" << proxy->receiver()->name() << endl;
00131     d->actionProxies.insert( proxy->receiver(), proxy );
00132 }
00133 
00134 KMainWindow* KexiSharedActionHost::mainWindow() const
00135 {
00136     return d->mainWin;
00137 }
00138 
00139 void KexiSharedActionHost::invalidateSharedActions(QObject *o)
00140 {
00141     if (!d)
00142         return;
00143     bool insideDialogBase = o && (o->inherits("KexiDialogBase") || 0!=KexiUtils::findParent<KexiDialogBase>(o, "KexiDialogBase"));
00144 
00145     KexiActionProxy *p = o ? d->actionProxies[ o ] : 0;
00146     for (KActionPtrList::ConstIterator it=d->sharedActions.constBegin(); it!=d->sharedActions.constEnd(); ++it) {
00147 //          setActionAvailable((*it)->name(),p && p->isAvailable((*it)->name()));
00148         KAction *a = *it;
00149         if (!insideDialogBase && d->mainWin->actionCollection()!=a->parentCollection()) {
00150             //o is not KexiDialogBase or its child:
00151             // only invalidate action if it comes from mainwindow's KActionCollection
00152             // (thus part-actions are untouched when the focus is e.g. in the Property Editor)
00153             continue;
00154         }
00155         const bool avail = p && p->isAvailable(a->name());
00156         KexiVolatileActionData *va = d->volatileActions[ a ];
00157         if (va != 0) {
00158             if (p && p->isSupported(a->name())) {
00159                 QPtrList<KAction> actions_list;
00160                 actions_list.append( a );
00161                 if (!va->plugged) {
00162                     va->plugged=true;
00163     //              d->mainWin->unplugActionList( a->name() );
00164                     d->mainWin->plugActionList( a->name(), actions_list );
00165                 }
00166             }
00167             else {
00168                 if (va->plugged) {
00169                     va->plugged=false;
00170                     d->mainWin->unplugActionList( a->name() );
00171                 }
00172             }
00173         }
00174 //      a->setEnabled(p && p->isAvailable(a->name()));
00175         a->setEnabled(avail);
00176 //      kdDebug() << "Action " << a->name() << (avail ? " enabled." : " disabled.") << endl;
00177     }
00178 }
00179 
00180 KexiActionProxy* KexiSharedActionHost::actionProxyFor(QObject *o) const
00181 {
00182     return d->actionProxies[ o ];
00183 }
00184 
00185 KexiActionProxy* KexiSharedActionHost::takeActionProxyFor(QObject *o)
00186 {
00187     if (d)
00188         return d->actionProxies.take( o );
00189     return 0;
00190 }
00191 
00192 bool KexiSharedActionHost::acceptsSharedActions(QObject *)
00193 {
00194     return false;
00195 }
00196 
00197 QWidget* KexiSharedActionHost::focusWindow()
00198 {
00199     QWidget *fw;
00200     if (dynamic_cast<KMdiMainFrm*>(d->mainWin)) {
00201         fw = dynamic_cast<KMdiMainFrm*>(d->mainWin)->activeWindow();
00202     }
00203     else {
00204         QWidget *aw = qApp->activeWindow();
00205         if (!aw)
00206             aw = d->mainWin;
00207         fw = aw->focusWidget();
00208     }
00209     while (fw && !acceptsSharedActions(fw))
00210         fw = fw->parentWidget();
00211     return fw;
00212 }
00213 
00214 KAction* KexiSharedActionHost::createSharedActionInternal( KAction *action )
00215 {
00216     QObject::connect(action,SIGNAL(activated()), &d->actionMapper, SLOT(map()));
00217     d->actionMapper.setMapping(action, action->name());
00218     d->sharedActions.append( action );
00219     return action;
00220 }
00221 
00222 KActionPtrList KexiSharedActionHost::sharedActions() const
00223 {
00224     return d->sharedActions;
00225 }
00226 
00227 /*class KexiAction : public KAction
00228 {
00229     public:
00230         KexiAction(const QString &text, const QIconSet &pix,
00231             const KShortcut &cut, const QObject *receiver,
00232             const char *slot, KActionCollection *parent, const char *name)
00233          : KAction(text,pix,cut,receiver,slot,parent,name)
00234         {
00235         }
00236 
00237     QPtrDict<QWidget> unplugged;
00238 };*/
00239 
00240 KAction* KexiSharedActionHost::createSharedAction(const QString &text, const QString &pix_name,
00241     const KShortcut &cut, const char *name, KActionCollection* col, const char *subclassName)
00242 {
00243     if (subclassName==0)
00244         return createSharedActionInternal(
00245             new KAction(text, pix_name,
00246             cut, 0/*receiver*/, 0/*slot*/, col ? col : d->mainWin->actionCollection(), name)
00247         );
00248     else if (qstricmp(subclassName,"KToggleAction")==0)
00249         return createSharedActionInternal(
00250             new KToggleAction(text, pix_name,
00251             cut, 0/*receiver*/, 0/*slot*/, col ? col : d->mainWin->actionCollection(), name)
00252         );
00253     else if (qstricmp(subclassName,"KActionMenu")==0)
00254         return createSharedActionInternal(
00255             new KActionMenu(text, pix_name, col ? col : d->mainWin->actionCollection(), name)
00256         );
00257 //TODO: more KAction subclasses
00258 
00259     return 0;
00260 }
00261 
00262 KAction* KexiSharedActionHost::createSharedAction( KStdAction::StdAction id, const char *name,
00263     KActionCollection* col)
00264 {
00265     return createSharedActionInternal(
00266         KStdAction::create( id, name, 0/*receiver*/, 0/*slot*/, col ? col : d->mainWin->actionCollection() )
00267     );
00268 }
00269 
00270 void KexiSharedActionHost::setActionVolatile( KAction *a, bool set )
00271 {
00272     if (!set) {
00273         d->volatileActions.remove( a );
00274         return;
00275     }
00276     if (d->volatileActions[ a ])
00277         return;
00278     d->volatileActions.insert( a, new KexiVolatileActionData() );
00279 }
00280 
00281 #include "kexisharedactionhost_p.moc"
00282 
KDE Home | KDE Accessibility Home | Description of Access Keys