kexi

kexiactionproxy.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "kexiactionproxy.h"
21#include "kexiactionproxy_p.h"
22
23#include <kdebug.h>
24#include <tdeaction.h>
25#include <tdemainwindow.h>
26#include <tdeshortcut.h>
27
28#include <tqwidget.h>
29#include <tqsignal.h>
30#include <tqiconset.h>
31
32TDEAction_setEnabled_Helper::TDEAction_setEnabled_Helper(KexiActionProxy* proxy)
33 : TQObject(0,"TDEAction_setEnabled_Helper")
34 , m_proxy( proxy )
35{
36}
37
38void TDEAction_setEnabled_Helper::slotSetEnabled(bool enabled)
39{
40 if (sender()->inherits("TDEAction")) {
41 const TDEAction *a = static_cast<const TDEAction*>(sender());
42 m_proxy->setAvailable(a->name(), enabled);
43 }
44}
45
46//=======================
47
48KexiSharedActionConnector::KexiSharedActionConnector( KexiActionProxy* proxy, TQObject *obj )
49 : m_proxy(proxy)
50 , m_object(obj)
51{
52}
53
54KexiSharedActionConnector::~KexiSharedActionConnector()
55{
56}
57
58void KexiSharedActionConnector::plugSharedAction(const char *action_name, const char *slot)
59{
60 m_proxy->plugSharedAction(action_name, m_object, slot);
61}
62
63void KexiSharedActionConnector::plugSharedActionToExternalGUI(
64 const char *action_name, KXMLGUIClient *client)
65{
66 m_proxy->plugSharedActionToExternalGUI(action_name, client);
67}
68
69void KexiSharedActionConnector::plugSharedActionsToExternalGUI(
70 const TQValueList<TQCString>& action_names, KXMLGUIClient *client)
71{
72 m_proxy->plugSharedActionsToExternalGUI(action_names, client);
73}
74
75
76//=======================
77
79 : m_host( host ? host : &KexiSharedActionHost::defaultHost() )
80 , m_receiver(receiver)
81 , m_signals(47)
82 , m_actionProxyParent(0)
83 , m_signal_parent( 0, "signal_parent" )
84 , m_TDEAction_setEnabled_helper( new TDEAction_setEnabled_Helper(this) )
85 , m_focusedChild(0)
86{
87 m_signals.setAutoDelete(true);
88 m_sharedActionChildren.setAutoDelete(false);
89 m_alternativeActions.setAutoDelete(true);
90 m_host->plugActionProxy( this );
91}
92
93KexiActionProxy::~KexiActionProxy()
94{
95 TQPtrListIterator<KexiActionProxy> it(m_sharedActionChildren);
96 //detach myself from every child
97 for (;it.current();++it) {
98 it.current()->setActionProxyParent_internal( 0 );
99 }
100 //take me from parent
101 if (m_actionProxyParent)
102 m_actionProxyParent->takeActionProxyChild( this );
103
104 m_host->takeActionProxyFor(m_receiver);
105
107}
108
109void KexiActionProxy::plugSharedAction(const char *action_name, TQObject* receiver, const char *slot)
110{
111 if (!action_name)// || !receiver || !slot)
112 return;
113 TQPair<TQSignal*,bool> *p = m_signals[action_name];
114 if (!p) {
115 p = new TQPair<TQSignal*,bool>( new TQSignal(&m_signal_parent), true );
116 m_signals.insert(action_name, p);
117 }
118 if (receiver && slot)
119 p->first->connect( receiver, slot );
120}
121
122void KexiActionProxy::unplugSharedAction(const char *action_name)
123{
124 TQPair<TQSignal*,bool> *p = m_signals.take(action_name);
125 if (!p)
126 return;
127 delete p->first;
128 delete p;
129}
130
131int KexiActionProxy::plugSharedAction(const char *action_name, TQWidget* w)
132{
133 TDEAction *a = sharedAction(action_name);
134 if (!a) {
135 kdWarning() << "KexiActionProxy::plugSharedAction(): NO SUCH ACTION: " << action_name << endl;
136 return -1;
137 }
138 return a->plug(w);
139}
140
141void KexiActionProxy::unplugSharedAction(const char *action_name, TQWidget* w)
142{
143 TDEAction *a = sharedAction(action_name);
144 if (!a) {
145 kdWarning() << "KexiActionProxy::unplugSharedAction(): NO SUCH ACTION: " << action_name << endl;
146 return;
147 }
148 a->unplug(w);
149}
150
151TDEAction* KexiActionProxy::plugSharedAction(const char *action_name, const TQString& alternativeText, TQWidget* w)
152{
153 TDEAction *a = sharedAction(action_name);
154 if (!a) {
155 kdWarning() << "KexiActionProxy::plugSharedAction(): NO SUCH ACTION: " << action_name << endl;
156 return 0;
157 }
158 TQCString altName = a->name();
159 altName += "_alt";
160 TDEAction *alt_act = new TDEAction(alternativeText, a->iconSet(), a->shortcut(),
161 0, 0, a->parent(), altName);
162 TQObject::connect(alt_act, TQ_SIGNAL(activated()), a, TQ_SLOT(activate()));
163 alt_act->plug(w);
164
165//OK?
166 m_host->updateActionAvailable(action_name, true, m_receiver);
167
168 return alt_act;
169}
170
171void KexiActionProxy::plugSharedActionToExternalGUI(const char *action_name, KXMLGUIClient *client)
172{
173 TDEAction *a = client->action(action_name);
174 if (!a)
175 return;
176 plugSharedAction(a->name(), a, TQ_SLOT(activate()));
177
178 //update availability
179 setAvailable(a->name(), a->isEnabled());
180 //changes will be signaled
181 TQObject::connect(a, TQ_SIGNAL(enabled(bool)), m_TDEAction_setEnabled_helper, TQ_SLOT(slotSetEnabled(bool)));
182}
183
184void KexiActionProxy::plugSharedActionsToExternalGUI(
185 const TQValueList<TQCString>& action_names, KXMLGUIClient *client)
186{
187 for (TQValueList<TQCString>::const_iterator it = action_names.constBegin(); it!=action_names.constEnd(); ++it) {
188 plugSharedActionToExternalGUI(*it, client);
189 }
190}
191
192bool KexiActionProxy::activateSharedAction(const char *action_name, bool alsoCheckInChildren)
193{
194 TQPair<TQSignal*,bool> *p = m_signals[action_name];
195 if (!p || !p->second) {
196 //try in children...
197 if (alsoCheckInChildren) {
198 TQPtrListIterator<KexiActionProxy> it( m_sharedActionChildren );
199 for( ; it.current(); ++it ) {
200 if (it.current()->activateSharedAction( action_name, alsoCheckInChildren ))
201 return true;
202 }
203 }
204 return m_actionProxyParent ? m_actionProxyParent->activateSharedAction(action_name, false) : false; //last chance: parent
205 }
206 //activate in this proxy...
207 p->first->activate();
208 return true;
209}
210
211TDEAction* KexiActionProxy::sharedAction(const char* action_name)
212{
213 return m_host->mainWindow()->actionCollection()->action(action_name);
214}
215
216bool KexiActionProxy::isSupported(const char* action_name) const
217{
218 TQPair<TQSignal*,bool> *p = m_signals[action_name];
219 if (!p) {
220 //not supported explicitly - try in children...
221 if (m_focusedChild)
222 return m_focusedChild->isSupported(action_name);
223 TQPtrListIterator<KexiActionProxy> it( m_sharedActionChildren );
224 for( ; it.current(); ++it ) {
225 if (it.current()->isSupported(action_name))
226 return true;
227 }
228 return false; //not suported
229 }
230 return p != 0;
231}
232
233bool KexiActionProxy::isAvailable(const char* action_name, bool alsoCheckInChildren) const
234{
235 TQPair<TQSignal*,bool> *p = m_signals[action_name];
236 if (!p) {
237 //not supported explicitly - try in children...
238 if (alsoCheckInChildren) {
239 if (m_focusedChild)
240 return m_focusedChild->isAvailable(action_name, alsoCheckInChildren);
241 TQPtrListIterator<KexiActionProxy> it( m_sharedActionChildren );
242 for( ; it.current(); ++it ) {
243 if (it.current()->isSupported(action_name))
244 return it.current()->isAvailable(action_name, alsoCheckInChildren);
245 }
246 }
247 return m_actionProxyParent ? m_actionProxyParent->isAvailable(action_name, false) : false; //last chance: parent
248 }
249 //supported explicitly:
250 return p->second != 0;
251}
252
253void KexiActionProxy::setAvailable(const char* action_name, bool set)
254{
255 TQPair<TQSignal*,bool> *p = m_signals[action_name];
256 if (!p)
257 return;
258 p->second = set;
259 m_host->updateActionAvailable(action_name, set, m_receiver);
260}
261
263{
264 if (!child || child==this)
265 return;
266 child->setActionProxyParent_internal( this );
267 m_sharedActionChildren.append( child );
268}
269
270void KexiActionProxy::takeActionProxyChild( KexiActionProxy* child )
271{
272 if (m_sharedActionChildren.findRef( child ) != -1)
273 m_sharedActionChildren.take();
274}
275
277{
278 m_actionProxyParent = parent;
279}
280
281#include "kexiactionproxy_p.moc"
282
An interface that acts as proxy for shared actions within the application.
void addActionProxyChild(KexiActionProxy *child)
TDEAction_setEnabled_Helper * m_TDEAction_setEnabled_helper
For internal use by plugSharedActionToExternalGUI()
bool isAvailable(const char *action_name, bool alsoCheckInChildren=true) const
virtual TDEAction * sharedAction(const char *action_name)
bool activateSharedAction(const char *action_name, bool alsoCheckInChildren=true)
TQObject m_signal_parent
it's just to have common parent for owned signals
void setActionProxyParent_internal(KexiActionProxy *parent)
For internal use by addActionProxyChild(). parent can be 0.
void plugSharedAction(const char *action_name, TQObject *receiver, const char *slot)
bool isSupported(const char *action_name) const
KexiActionProxy(TQObject *receiver, KexiSharedActionHost *host=0)
Acts as application-wide host that offers shared actions.
void plugActionProxy(KexiActionProxy *proxy)
void updateActionAvailable(const char *action_name, bool avail, TQObject *obj)
TDEMainWindow * mainWindow() const
KexiActionProxy * takeActionProxyFor(TQObject *o)