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