diff options
Diffstat (limited to 'kexi/core/kexiactionproxy.cpp')
-rw-r--r-- | kexi/core/kexiactionproxy.cpp | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/kexi/core/kexiactionproxy.cpp b/kexi/core/kexiactionproxy.cpp new file mode 100644 index 00000000..0dbcf637 --- /dev/null +++ b/kexi/core/kexiactionproxy.cpp @@ -0,0 +1,282 @@ +/* This file is part of the KDE project + Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "kexiactionproxy.h" +#include "kexiactionproxy_p.h" + +#include <kdebug.h> +#include <kaction.h> +#include <kmainwindow.h> +#include <kshortcut.h> + +#include <qwidget.h> +#include <qsignal.h> +#include <qiconset.h> + +KAction_setEnabled_Helper::KAction_setEnabled_Helper(KexiActionProxy* proxy) + : QObject(0,"KAction_setEnabled_Helper") + , m_proxy( proxy ) +{ +} + +void KAction_setEnabled_Helper::slotSetEnabled(bool enabled) +{ + if (sender()->inherits("KAction")) { + const KAction *a = static_cast<const KAction*>(sender()); + m_proxy->setAvailable(a->name(), enabled); + } +} + +//======================= + +KexiSharedActionConnector::KexiSharedActionConnector( KexiActionProxy* proxy, QObject *obj ) + : m_proxy(proxy) + , m_object(obj) +{ +} + +KexiSharedActionConnector::~KexiSharedActionConnector() +{ +} + +void KexiSharedActionConnector::plugSharedAction(const char *action_name, const char *slot) +{ + m_proxy->plugSharedAction(action_name, m_object, slot); +} + +void KexiSharedActionConnector::plugSharedActionToExternalGUI( + const char *action_name, KXMLGUIClient *client) +{ + m_proxy->plugSharedActionToExternalGUI(action_name, client); +} + +void KexiSharedActionConnector::plugSharedActionsToExternalGUI( + const QValueList<QCString>& action_names, KXMLGUIClient *client) +{ + m_proxy->plugSharedActionsToExternalGUI(action_names, client); +} + + +//======================= + +KexiActionProxy::KexiActionProxy(QObject *receiver, KexiSharedActionHost *host) + : m_host( host ? host : &KexiSharedActionHost::defaultHost() ) + , m_receiver(receiver) + , m_signals(47) + , m_actionProxyParent(0) + , m_signal_parent( 0, "signal_parent" ) + , m_KAction_setEnabled_helper( new KAction_setEnabled_Helper(this) ) + , m_focusedChild(0) +{ + m_signals.setAutoDelete(true); + m_sharedActionChildren.setAutoDelete(false); + m_alternativeActions.setAutoDelete(true); + m_host->plugActionProxy( this ); +} + +KexiActionProxy::~KexiActionProxy() +{ + QPtrListIterator<KexiActionProxy> it(m_sharedActionChildren); + //detach myself from every child + for (;it.current();++it) { + it.current()->setActionProxyParent_internal( 0 ); + } + //take me from parent + if (m_actionProxyParent) + m_actionProxyParent->takeActionProxyChild( this ); + + m_host->takeActionProxyFor(m_receiver); + + delete m_KAction_setEnabled_helper; +} + +void KexiActionProxy::plugSharedAction(const char *action_name, QObject* receiver, const char *slot) +{ + if (!action_name)// || !receiver || !slot) + return; + QPair<QSignal*,bool> *p = m_signals[action_name]; + if (!p) { + p = new QPair<QSignal*,bool>( new QSignal(&m_signal_parent), true ); + m_signals.insert(action_name, p); + } + if (receiver && slot) + p->first->connect( receiver, slot ); +} + +void KexiActionProxy::unplugSharedAction(const char *action_name) +{ + QPair<QSignal*,bool> *p = m_signals.take(action_name); + if (!p) + return; + delete p->first; + delete p; +} + +int KexiActionProxy::plugSharedAction(const char *action_name, QWidget* w) +{ + KAction *a = sharedAction(action_name); + if (!a) { + kdWarning() << "KexiActionProxy::plugSharedAction(): NO SUCH ACTION: " << action_name << endl; + return -1; + } + return a->plug(w); +} + +void KexiActionProxy::unplugSharedAction(const char *action_name, QWidget* w) +{ + KAction *a = sharedAction(action_name); + if (!a) { + kdWarning() << "KexiActionProxy::unplugSharedAction(): NO SUCH ACTION: " << action_name << endl; + return; + } + a->unplug(w); +} + +KAction* KexiActionProxy::plugSharedAction(const char *action_name, const QString& alternativeText, QWidget* w) +{ + KAction *a = sharedAction(action_name); + if (!a) { + kdWarning() << "KexiActionProxy::plugSharedAction(): NO SUCH ACTION: " << action_name << endl; + return 0; + } + QCString altName = a->name(); + altName += "_alt"; + KAction *alt_act = new KAction(alternativeText, a->iconSet(), a->shortcut(), + 0, 0, a->parent(), altName); + QObject::connect(alt_act, SIGNAL(activated()), a, SLOT(activate())); + alt_act->plug(w); + +//OK? + m_host->updateActionAvailable(action_name, true, m_receiver); + + return alt_act; +} + +void KexiActionProxy::plugSharedActionToExternalGUI(const char *action_name, KXMLGUIClient *client) +{ + KAction *a = client->action(action_name); + if (!a) + return; + plugSharedAction(a->name(), a, SLOT(activate())); + + //update availability + setAvailable(a->name(), a->isEnabled()); + //changes will be signaled + QObject::connect(a, SIGNAL(enabled(bool)), m_KAction_setEnabled_helper, SLOT(slotSetEnabled(bool))); +} + +void KexiActionProxy::plugSharedActionsToExternalGUI( + const QValueList<QCString>& action_names, KXMLGUIClient *client) +{ + for (QValueList<QCString>::const_iterator it = action_names.constBegin(); it!=action_names.constEnd(); ++it) { + plugSharedActionToExternalGUI(*it, client); + } +} + +bool KexiActionProxy::activateSharedAction(const char *action_name, bool alsoCheckInChildren) +{ + QPair<QSignal*,bool> *p = m_signals[action_name]; + if (!p || !p->second) { + //try in children... + if (alsoCheckInChildren) { + QPtrListIterator<KexiActionProxy> it( m_sharedActionChildren ); + for( ; it.current(); ++it ) { + if (it.current()->activateSharedAction( action_name, alsoCheckInChildren )) + return true; + } + } + return m_actionProxyParent ? m_actionProxyParent->activateSharedAction(action_name, false) : false; //last chance: parent + } + //activate in this proxy... + p->first->activate(); + return true; +} + +KAction* KexiActionProxy::sharedAction(const char* action_name) +{ + return m_host->mainWindow()->actionCollection()->action(action_name); +} + +bool KexiActionProxy::isSupported(const char* action_name) const +{ + QPair<QSignal*,bool> *p = m_signals[action_name]; + if (!p) { + //not supported explicitly - try in children... + if (m_focusedChild) + return m_focusedChild->isSupported(action_name); + QPtrListIterator<KexiActionProxy> it( m_sharedActionChildren ); + for( ; it.current(); ++it ) { + if (it.current()->isSupported(action_name)) + return true; + } + return false; //not suported + } + return p != 0; +} + +bool KexiActionProxy::isAvailable(const char* action_name, bool alsoCheckInChildren) const +{ + QPair<QSignal*,bool> *p = m_signals[action_name]; + if (!p) { + //not supported explicitly - try in children... + if (alsoCheckInChildren) { + if (m_focusedChild) + return m_focusedChild->isAvailable(action_name, alsoCheckInChildren); + QPtrListIterator<KexiActionProxy> it( m_sharedActionChildren ); + for( ; it.current(); ++it ) { + if (it.current()->isSupported(action_name)) + return it.current()->isAvailable(action_name, alsoCheckInChildren); + } + } + return m_actionProxyParent ? m_actionProxyParent->isAvailable(action_name, false) : false; //last chance: parent + } + //supported explicitly: + return p->second != 0; +} + +void KexiActionProxy::setAvailable(const char* action_name, bool set) +{ + QPair<QSignal*,bool> *p = m_signals[action_name]; + if (!p) + return; + p->second = set; + m_host->updateActionAvailable(action_name, set, m_receiver); +} + +void KexiActionProxy::addActionProxyChild( KexiActionProxy* child ) +{ + if (!child || child==this) + return; + child->setActionProxyParent_internal( this ); + m_sharedActionChildren.append( child ); +} + +void KexiActionProxy::takeActionProxyChild( KexiActionProxy* child ) +{ + if (m_sharedActionChildren.findRef( child ) != -1) + m_sharedActionChildren.take(); +} + +void KexiActionProxy::setActionProxyParent_internal( KexiActionProxy* parent ) +{ + m_actionProxyParent = parent; +} + +#include "kexiactionproxy_p.moc" + |