kexi

kexisharedactionhost.cpp
1/* This file is part of the KDE project
2 Copyright (C) 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 "kexisharedactionhost.h"
21#include "kexisharedactionhost_p.h"
22#include "kexiactionproxy.h"
23#include "kexidialogbase.h"
24
25#include <kexiutils/utils.h>
26
27#include <kiconloader.h>
28#include <kguiitem.h>
29#include <kdebug.h>
30
31KexiSharedActionHostPrivate::KexiSharedActionHostPrivate(KexiSharedActionHost *h)
32: TQObject(0,"KexiSharedActionHostPrivate")
33, actionProxies(401)
34, actionMapper( this )
35, volatileActions(401)
36, enablers(401, false)
37, host(h)
38{
39 volatileActions.setAutoDelete(true);
40 connect(&actionMapper, TQ_SIGNAL(mapped(const TQString &)), this, TQ_SLOT(slotAction(const TQString &)));
41}
42
43void KexiSharedActionHostPrivate::slotAction(const TQString& act_id)
44{
45 TQWidget *w = host->focusWindow(); //focusWidget();
46// while (w && !w->inherits("KexiDialogBase") && !w->inherits("KexiDockBase"))
47// w = w->parentWidget();
48
49 KexiActionProxy *proxy = w ? actionProxies[ w ] : 0;
50
51 if (!proxy || !proxy->activateSharedAction(act_id.latin1())) {
52 //also try to find previous enabler
53 w = enablers[act_id.latin1()];
54 if (!w)
55 return;
56 proxy = actionProxies[ w ];
57 if (!proxy)
58 return;
59 proxy->activateSharedAction(act_id.latin1());
60 }
61}
62
63//--------------------------------------------------
64
66KexiSharedActionHost KexiSharedActionHost_dummy = KexiSharedActionHost(0);
67
69KexiSharedActionHost* KexiSharedActionHost_defaultHost = &KexiSharedActionHost_dummy;
70
72{
73 return *KexiSharedActionHost_defaultHost;
74}
75
77{
78 KexiSharedActionHost_defaultHost = this;
79}
80
81//--------------------------------------------------
82
84: d( new KexiSharedActionHostPrivate(this) )
85{
86 d->mainWin = mainWin;
87}
88
90{
91 if (KexiSharedActionHost_defaultHost == this) {
92 //default host is destroyed! - restore dummy
93 KexiSharedActionHost_defaultHost = &KexiSharedActionHost_dummy;
94 }
95 delete d;
96 d=0;
97}
98
99void KexiSharedActionHost::setActionAvailable(const char *action_name, bool avail)
100{
101 TDEAction *act = d->mainWin->actionCollection()->action(action_name);
102 if (act) {
103 act->setEnabled(avail);
104 }
105}
106
107void KexiSharedActionHost::updateActionAvailable(const char *action_name, bool avail, TQObject *obj)
108{
109/*test if (qstrcmp(action_name, "tablepart_toggle_pkey")==0) {
110 kdDebug() << "tablepart_toggle_pkey" << endl;
111 }*/
112 if (!d)
113 return; //sanity
114 TQWidget *fw = d->mainWin->focusWidget();
115 while (fw && obj!=fw)
116 fw = fw->parentWidget();
117 if (!fw)
118 return;
119
120 setActionAvailable(action_name, avail);
121 if (avail) {
122 d->enablers.replace(action_name, fw);
123 }
124 else {
125 d->enablers.take(action_name);
126 }
127}
128
129void KexiSharedActionHost::plugActionProxy(KexiActionProxy *proxy)
130{
131// kdDebug() << "KexiSharedActionHost::plugActionProxy():" << proxy->receiver()->name() << endl;
132 d->actionProxies.insert( proxy->receiver(), proxy );
133}
134
136{
137 return d->mainWin;
138}
139
141{
142 if (!d)
143 return;
144 bool insideDialogBase = o && (o->inherits("KexiDialogBase") || 0!=KexiUtils::findParent<KexiDialogBase>(o, "KexiDialogBase"));
145
146 KexiActionProxy *p = o ? d->actionProxies[ o ] : 0;
147 for (TDEActionPtrList::ConstIterator it=d->sharedActions.constBegin(); it!=d->sharedActions.constEnd(); ++it) {
148// setActionAvailable((*it)->name(),p && p->isAvailable((*it)->name()));
149 TDEAction *a = *it;
150 if (!insideDialogBase && d->mainWin->actionCollection()!=a->parentCollection()) {
151 //o is not KexiDialogBase or its child:
152 // only invalidate action if it comes from mainwindow's TDEActionCollection
153 // (thus part-actions are untouched when the focus is e.g. in the Property Editor)
154 continue;
155 }
156 const bool avail = p && p->isAvailable(a->name());
157 KexiVolatileActionData *va = d->volatileActions[ a ];
158 if (va != 0) {
159 if (p && p->isSupported(a->name())) {
160 TQPtrList<TDEAction> actions_list;
161 actions_list.append( a );
162 if (!va->plugged) {
163 va->plugged=true;
164 // d->mainWin->unplugActionList( a->name() );
165 d->mainWin->plugActionList( a->name(), actions_list );
166 }
167 }
168 else {
169 if (va->plugged) {
170 va->plugged=false;
171 d->mainWin->unplugActionList( a->name() );
172 }
173 }
174 }
175// a->setEnabled(p && p->isAvailable(a->name()));
176 a->setEnabled(avail);
177// kdDebug() << "Action " << a->name() << (avail ? " enabled." : " disabled.") << endl;
178 }
179}
180
181KexiActionProxy* KexiSharedActionHost::actionProxyFor(TQObject *o) const
182{
183 return d->actionProxies[ o ];
184}
185
186KexiActionProxy* KexiSharedActionHost::takeActionProxyFor(TQObject *o)
187{
188 if (d)
189 return d->actionProxies.take( o );
190 return 0;
191}
192
194{
195 return false;
196}
197
199{
200 TQWidget *fw;
201 if (dynamic_cast<KMdiMainFrm*>(d->mainWin)) {
202 fw = dynamic_cast<KMdiMainFrm*>(d->mainWin)->activeWindow();
203 }
204 else {
205 TQWidget *aw = tqApp->activeWindow();
206 if (!aw)
207 aw = d->mainWin;
208 fw = aw->focusWidget();
209 }
210 while (fw && !acceptsSharedActions(fw))
211 fw = fw->parentWidget();
212 return fw;
213}
214
215TDEAction* KexiSharedActionHost::createSharedActionInternal( TDEAction *action )
216{
217 TQObject::connect(action,TQ_SIGNAL(activated()), &d->actionMapper, TQ_SLOT(map()));
218 d->actionMapper.setMapping(action, action->name());
219 d->sharedActions.append( action );
220 return action;
221}
222
224{
225 return d->sharedActions;
226}
227
228/*class KexiAction : public TDEAction
229{
230 public:
231 KexiAction(const TQString &text, const TQIconSet &pix,
232 const TDEShortcut &cut, const TQObject *receiver,
233 const char *slot, TDEActionCollection *parent, const char *name)
234 : TDEAction(text,pix,cut,receiver,slot,parent,name)
235 {
236 }
237
238 TQPtrDict<TQWidget> unplugged;
239};*/
240
241TDEAction* KexiSharedActionHost::createSharedAction(const TQString &text, const TQString &pix_name,
242 const TDEShortcut &cut, const char *name, TDEActionCollection* col, const char *subclassName)
243{
244 if (subclassName==0)
245 return createSharedActionInternal(
246 new TDEAction(text, pix_name,
247 cut, 0/*receiver*/, 0/*slot*/, col ? col : d->mainWin->actionCollection(), name)
248 );
249 else if (tqstricmp(subclassName,"TDEToggleAction")==0)
250 return createSharedActionInternal(
251 new TDEToggleAction(text, pix_name,
252 cut, 0/*receiver*/, 0/*slot*/, col ? col : d->mainWin->actionCollection(), name)
253 );
254 else if (tqstricmp(subclassName,"TDEActionMenu")==0)
255 return createSharedActionInternal(
256 new TDEActionMenu(text, pix_name, col ? col : d->mainWin->actionCollection(), name)
257 );
258//TODO: more TDEAction subclasses
259
260 return 0;
261}
262
263TDEAction* KexiSharedActionHost::createSharedAction( KStdAction::StdAction id, const char *name,
264 TDEActionCollection* col)
265{
266 return createSharedActionInternal(
267 KStdAction::create( id, name, 0/*receiver*/, 0/*slot*/, col ? col : d->mainWin->actionCollection() )
268 );
269}
270
271TDEAction* KexiSharedActionHost::createSharedAction(const KGuiItem& guiItem, const TDEShortcut &cut,
272 const char *name, TDEActionCollection* col)
273{
274 return createSharedActionInternal(
275 new TDEAction(guiItem, cut, 0/*receiver*/, 0/*slot*/,
276 col ? col : d->mainWin->actionCollection(), name));
277}
278
279void KexiSharedActionHost::setActionVolatile( TDEAction *a, bool set )
280{
281 if (!set) {
282 d->volatileActions.remove( a );
283 return;
284 }
285 if (d->volatileActions[ a ])
286 return;
287 d->volatileActions.insert( a, new KexiVolatileActionData() );
288}
289
290#include "kexisharedactionhost_p.moc"
291
An interface that acts as proxy for shared actions within the application.
bool isAvailable(const char *action_name, bool alsoCheckInChildren=true) const
bool activateSharedAction(const char *action_name, bool alsoCheckInChildren=true)
bool isSupported(const char *action_name) const
Acts as application-wide host that offers shared actions.
void setActionVolatile(TDEAction *a, bool set)
KexiActionProxy * actionProxyFor(TQObject *o) const
void plugActionProxy(KexiActionProxy *proxy)
void updateActionAvailable(const char *action_name, bool avail, TQObject *obj)
virtual bool acceptsSharedActions(TQObject *o)
TDEMainWindow * mainWindow() const
virtual void invalidateSharedActions(TQObject *o)
static KexiSharedActionHost & defaultHost()
KexiSharedActionHost(TDEMainWindow *mainWin)
TDEActionPtrList sharedActions() const
TDEAction * createSharedAction(const TQString &text, const TQString &pix_name, const TDEShortcut &cut, const char *name, TDEActionCollection *col=0, const char *subclassName=0)
KexiActionProxy * takeActionProxyFor(TQObject *o)
type * findParent(TQObject *o, const char *className)