kexi

kexiactionproxy.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003-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 "kexiactionproxy.h"
00021 #include "kexiactionproxy_p.h"
00022 
00023 #include <kdebug.h>
00024 #include <kaction.h>
00025 #include <kmainwindow.h>
00026 #include <kshortcut.h>
00027 
00028 #include <qwidget.h>
00029 #include <qsignal.h>
00030 #include <qiconset.h>
00031 
00032 KAction_setEnabled_Helper::KAction_setEnabled_Helper(KexiActionProxy* proxy)
00033  : QObject(0,"KAction_setEnabled_Helper")
00034  , m_proxy( proxy )
00035 {
00036 }
00037 
00038 void KAction_setEnabled_Helper::slotSetEnabled(bool enabled)
00039 {
00040     if (sender()->inherits("KAction")) {
00041         const KAction *a = static_cast<const KAction*>(sender());
00042         m_proxy->setAvailable(a->name(), enabled);
00043     }
00044 }
00045 
00046 //=======================
00047 
00048 KexiSharedActionConnector::KexiSharedActionConnector( KexiActionProxy* proxy, QObject *obj ) 
00049  : m_proxy(proxy)
00050  , m_object(obj)
00051 {
00052 }
00053 
00054 KexiSharedActionConnector::~KexiSharedActionConnector()
00055 {
00056 }
00057 
00058 void KexiSharedActionConnector::plugSharedAction(const char *action_name, const char *slot)
00059 {
00060     m_proxy->plugSharedAction(action_name, m_object, slot);
00061 }
00062 
00063 void KexiSharedActionConnector::plugSharedActionToExternalGUI(
00064     const char *action_name, KXMLGUIClient *client) 
00065 {
00066     m_proxy->plugSharedActionToExternalGUI(action_name, client);
00067 }
00068 
00069 void KexiSharedActionConnector::plugSharedActionsToExternalGUI(
00070     const QValueList<QCString>& action_names, KXMLGUIClient *client)
00071 {
00072     m_proxy->plugSharedActionsToExternalGUI(action_names, client);
00073 }
00074 
00075 
00076 //=======================
00077 
00078 KexiActionProxy::KexiActionProxy(QObject *receiver, KexiSharedActionHost *host)
00079  : m_host( host ? host : &KexiSharedActionHost::defaultHost() )
00080  , m_receiver(receiver)
00081  , m_signals(47)
00082  , m_actionProxyParent(0)
00083  , m_signal_parent( 0, "signal_parent" )
00084  , m_KAction_setEnabled_helper( new KAction_setEnabled_Helper(this) )
00085  , m_focusedChild(0)
00086 {
00087     m_signals.setAutoDelete(true);
00088     m_sharedActionChildren.setAutoDelete(false);
00089     m_alternativeActions.setAutoDelete(true);
00090     m_host->plugActionProxy( this );
00091 }
00092 
00093 KexiActionProxy::~KexiActionProxy()
00094 {
00095     QPtrListIterator<KexiActionProxy> it(m_sharedActionChildren);
00096     //detach myself from every child
00097     for (;it.current();++it) {
00098         it.current()->setActionProxyParent_internal( 0 );
00099     }
00100     //take me from parent
00101     if (m_actionProxyParent)
00102         m_actionProxyParent->takeActionProxyChild( this );
00103 
00104     m_host->takeActionProxyFor(m_receiver);
00105 
00106     delete m_KAction_setEnabled_helper;
00107 }
00108 
00109 void KexiActionProxy::plugSharedAction(const char *action_name, QObject* receiver, const char *slot)
00110 {
00111     if (!action_name)// || !receiver || !slot)
00112         return;
00113     QPair<QSignal*,bool> *p = m_signals[action_name];
00114     if (!p) {
00115         p = new QPair<QSignal*,bool>( new QSignal(&m_signal_parent), true );
00116         m_signals.insert(action_name, p);
00117     }
00118     if (receiver && slot)
00119         p->first->connect( receiver, slot );
00120 }
00121 
00122 void KexiActionProxy::unplugSharedAction(const char *action_name)
00123 {
00124     QPair<QSignal*,bool> *p = m_signals.take(action_name);
00125     if (!p)
00126         return;
00127     delete p->first;
00128     delete p;
00129 }
00130 
00131 int KexiActionProxy::plugSharedAction(const char *action_name, QWidget* w)
00132 {
00133     KAction *a = sharedAction(action_name);
00134     if (!a) {
00135         kdWarning() << "KexiActionProxy::plugSharedAction(): NO SUCH ACTION: " << action_name << endl;
00136         return -1;
00137     }
00138     return a->plug(w);
00139 }
00140 
00141 void KexiActionProxy::unplugSharedAction(const char *action_name, QWidget* w)
00142 {
00143     KAction *a = sharedAction(action_name);
00144     if (!a) {
00145         kdWarning() << "KexiActionProxy::unplugSharedAction(): NO SUCH ACTION: " << action_name << endl;
00146         return;
00147     }
00148     a->unplug(w);
00149 }
00150 
00151 KAction* KexiActionProxy::plugSharedAction(const char *action_name, const QString& alternativeText, QWidget* w)
00152 {
00153     KAction *a = sharedAction(action_name);
00154     if (!a) {
00155         kdWarning() << "KexiActionProxy::plugSharedAction(): NO SUCH ACTION: " << action_name << endl;
00156         return 0;
00157     }
00158     QCString altName = a->name();
00159     altName += "_alt";
00160     KAction *alt_act = new KAction(alternativeText, a->iconSet(), a->shortcut(), 
00161         0, 0, a->parent(), altName);
00162     QObject::connect(alt_act, SIGNAL(activated()), a, SLOT(activate()));
00163     alt_act->plug(w);
00164 
00165 //OK?
00166     m_host->updateActionAvailable(action_name, true, m_receiver);
00167 
00168     return alt_act;
00169 }
00170 
00171 void KexiActionProxy::plugSharedActionToExternalGUI(const char *action_name, KXMLGUIClient *client)
00172 {
00173     KAction *a = client->action(action_name);
00174     if (!a)
00175         return;
00176     plugSharedAction(a->name(), a, SLOT(activate()));
00177 
00178     //update availability
00179     setAvailable(a->name(), a->isEnabled());
00180     //changes will be signaled
00181     QObject::connect(a, SIGNAL(enabled(bool)), m_KAction_setEnabled_helper, SLOT(slotSetEnabled(bool)));
00182 }
00183 
00184 void KexiActionProxy::plugSharedActionsToExternalGUI(
00185     const QValueList<QCString>& action_names, KXMLGUIClient *client)
00186 {
00187     for (QValueList<QCString>::const_iterator it = action_names.constBegin(); it!=action_names.constEnd(); ++it) {
00188         plugSharedActionToExternalGUI(*it, client);
00189     }
00190 }
00191 
00192 bool KexiActionProxy::activateSharedAction(const char *action_name, bool alsoCheckInChildren)
00193 {
00194     QPair<QSignal*,bool> *p = m_signals[action_name];
00195     if (!p || !p->second) {
00196         //try in children...
00197         if (alsoCheckInChildren) {
00198             QPtrListIterator<KexiActionProxy> it( m_sharedActionChildren );
00199             for( ; it.current(); ++it ) {
00200                 if (it.current()->activateSharedAction( action_name, alsoCheckInChildren ))
00201                     return true;
00202             }
00203         }
00204         return m_actionProxyParent ? m_actionProxyParent->activateSharedAction(action_name, false) : false; //last chance: parent
00205     }
00206     //activate in this proxy...
00207     p->first->activate();
00208     return true;
00209 }
00210 
00211 KAction* KexiActionProxy::sharedAction(const char* action_name)
00212 {
00213     return m_host->mainWindow()->actionCollection()->action(action_name);
00214 }
00215 
00216 bool KexiActionProxy::isSupported(const char* action_name) const
00217 {
00218     QPair<QSignal*,bool> *p = m_signals[action_name];
00219     if (!p) {
00220         //not supported explicitly - try in children...
00221         if (m_focusedChild)
00222             return m_focusedChild->isSupported(action_name);
00223         QPtrListIterator<KexiActionProxy> it( m_sharedActionChildren );
00224         for( ; it.current(); ++it ) {
00225             if (it.current()->isSupported(action_name))
00226                 return true;
00227         }
00228         return false; //not suported
00229     }
00230     return p != 0;
00231 }
00232 
00233 bool KexiActionProxy::isAvailable(const char* action_name, bool alsoCheckInChildren) const
00234 {
00235     QPair<QSignal*,bool> *p = m_signals[action_name];
00236     if (!p) {
00237         //not supported explicitly - try in children...
00238         if (alsoCheckInChildren) {
00239             if (m_focusedChild)
00240                 return m_focusedChild->isAvailable(action_name, alsoCheckInChildren);
00241             QPtrListIterator<KexiActionProxy> it( m_sharedActionChildren );
00242             for( ; it.current(); ++it ) {
00243                 if (it.current()->isSupported(action_name))
00244                     return it.current()->isAvailable(action_name, alsoCheckInChildren);
00245             }
00246         }
00247         return m_actionProxyParent ? m_actionProxyParent->isAvailable(action_name, false) : false; //last chance: parent
00248     }
00249     //supported explicitly:
00250     return p->second != 0;
00251 }
00252 
00253 void KexiActionProxy::setAvailable(const char* action_name, bool set)
00254 {
00255     QPair<QSignal*,bool> *p = m_signals[action_name];
00256     if (!p)
00257         return;
00258     p->second = set;
00259     m_host->updateActionAvailable(action_name, set, m_receiver);
00260 }
00261 
00262 void KexiActionProxy::addActionProxyChild( KexiActionProxy* child )
00263 {
00264     if (!child || child==this)
00265         return;
00266     child->setActionProxyParent_internal( this );
00267     m_sharedActionChildren.append( child );
00268 }
00269 
00270 void KexiActionProxy::takeActionProxyChild( KexiActionProxy* child )
00271 {
00272     if (m_sharedActionChildren.findRef( child ) != -1)
00273         m_sharedActionChildren.take();
00274 }
00275 
00276 void KexiActionProxy::setActionProxyParent_internal( KexiActionProxy* parent )
00277 {
00278     m_actionProxyParent = parent;
00279 }
00280 
00281 #include "kexiactionproxy_p.moc"
00282 
KDE Home | KDE Accessibility Home | Description of Access Keys