Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <svl/itempool.hxx>
21 :
22 : #include <sfx2/ctrlitem.hxx>
23 : #include <sfx2/bindings.hxx>
24 : #include <sfx2/dispatch.hxx>
25 : #include <sfx2/msgpool.hxx>
26 : #include "statcach.hxx"
27 : #include <sfx2/viewfrm.hxx>
28 :
29 : #ifdef DBG_UTIL
30 :
31 : void SfxControllerItem::CheckConfigure_Impl( sal_uIntPtr nType )
32 : {
33 : // Real Slot? (i.e. no Separator etc.)
34 : if ( !nId )
35 : return;
36 :
37 : // is the ID configurable at all in 'nType'?
38 : const SfxSlot *pSlot = SFX_SLOTPOOL().GetSlot(nId);
39 : DBG_ASSERTWARNING( pSlot, "SfxControllerItem: binding not existing slot" );
40 : SAL_WARN_IF(
41 : pSlot && !pSlot->IsMode(nType), "sfx.control",
42 : "SfxControllerItem: slot without ...Config-flag at SID "
43 : << pSlot->GetSlotId());
44 : }
45 :
46 : #endif
47 :
48 :
49 : // returns the next registered SfxControllerItem with the same id
50 :
51 0 : SfxControllerItem* SfxControllerItem::GetItemLink()
52 : {
53 0 : return pNext == this ? 0 : pNext;
54 : }
55 :
56 :
57 : // returns sal_True if this binding is really bound to a function
58 :
59 0 : bool SfxControllerItem::IsBound() const
60 : {
61 0 : return pNext != this;
62 : }
63 :
64 :
65 : // registeres with the id at the bindings
66 :
67 0 : void SfxControllerItem::Bind( sal_uInt16 nNewId, SfxBindings *pBindinx )
68 : {
69 : DBG_ASSERT(pBindings || pBindinx, "No Bindings");
70 :
71 0 : if ( IsBound() ) {
72 : DBG_ASSERT(pBindings, "No Bindings");
73 0 : pBindings->Release(*this);
74 : }
75 :
76 0 : nId = nNewId;
77 0 : pNext = 0;
78 :
79 0 : if (pBindinx)
80 0 : pBindings = pBindinx;
81 0 : pBindings->Register(*this);
82 0 : }
83 :
84 0 : void SfxControllerItem::BindInternal_Impl( sal_uInt16 nNewId, SfxBindings *pBindinx )
85 : {
86 : DBG_ASSERT(pBindings || pBindinx, "No Bindings");
87 :
88 0 : if ( IsBound() ) {
89 : DBG_ASSERT(pBindings, "No Bindings");
90 0 : pBindings->Release(*this);
91 : }
92 :
93 0 : nId = nNewId;
94 0 : pNext = 0;
95 :
96 0 : if (pBindinx)
97 0 : pBindings = pBindinx;
98 0 : pBindings->RegisterInternal_Impl(*this);
99 0 : }
100 :
101 :
102 :
103 :
104 0 : void SfxControllerItem::UnBind()
105 :
106 : /* [Description]
107 :
108 : Unbinds the connection of this SfxControllerItems with the SfxBindings
109 : instance with which it to time is bound. From this time on it does not
110 : receive any status notifications (<SfxControllerItem::StateChented()>)
111 : anymore.
112 :
113 : [Cross-reference]
114 :
115 : <SfxControllerItem::ReBind()>
116 : <SfxControllerItem::ClearCache()>
117 : */
118 : {
119 : DBG_ASSERT(pBindings, "No Bindings");
120 : DBG_ASSERT( IsBound(), "unbindings unbound SfxControllerItem" );
121 :
122 0 : pBindings->Release(*this);
123 0 : pNext = this;
124 0 : }
125 :
126 :
127 :
128 0 : void SfxControllerItem::ReBind()
129 :
130 : /* [Description]
131 :
132 : Binds this SfxControllerItem with the SfxBindings instance again,
133 : with which it was last bound. From this time on it does receive status
134 : notifications (<SfxControllerItem::StateChented()>) again.
135 :
136 : [Cross-reference]
137 :
138 : <SfxControllerItem::UnBind()>
139 : <SfxControllerItem::ClearCache()>
140 : */
141 :
142 : {
143 : DBG_ASSERT(pBindings, "No Bindings");
144 : DBG_ASSERT( !IsBound(), "bindings rebound SfxControllerItem" );
145 :
146 0 : pBindings->Register(*this);
147 0 : }
148 :
149 :
150 :
151 0 : void SfxControllerItem::ClearCache()
152 :
153 : /* [Description]
154 :
155 : Clears the cache status for this SfxControllerItem. That is by the next
156 : status update is the <SfxPoolItem> sent in any case, even if the same was
157 : sent before. This is needed if a controller can be switched on and note
158 : that status themselves.
159 :
160 : [Example]
161 :
162 : The combined controller for adjusting the surface type and the concrete
163 : expression (blue color, or hatching X) can be changed in type, but is then
164 : notified of the next selection again, even if it the same data.
165 :
166 : [Cross-reference]
167 :
168 : <SfxControllerItem::UnBind()>
169 : <SfxControllerItem::ReBind()>
170 : */
171 :
172 :
173 : {
174 : DBG_ASSERT(pBindings, "No Bindings");
175 :
176 0 : pBindings->ClearCache_Impl( GetId() );
177 0 : }
178 :
179 :
180 : // replaces the successor in the list of bindings of the same id
181 :
182 0 : SfxControllerItem* SfxControllerItem::ChangeItemLink( SfxControllerItem* pNewLink )
183 : {
184 0 : SfxControllerItem* pOldLink = pNext;
185 0 : pNext = pNewLink;
186 0 : return pOldLink == this ? 0 : pOldLink;
187 : }
188 :
189 :
190 : // changes the id of unbound functions (e.g. for sub-menu-ids)
191 :
192 0 : void SfxControllerItem::SetId( sal_uInt16 nItemId )
193 : {
194 : DBG_ASSERT( !IsBound(), "changing id of bound binding" );
195 0 : nId = nItemId;
196 0 : }
197 :
198 :
199 :
200 : // creates a atomic item for a controller without registration.
201 :
202 0 : SfxControllerItem::SfxControllerItem():
203 : nId(0),
204 : pNext(this),
205 0 : pBindings(0)
206 : {
207 0 : }
208 :
209 :
210 : // creates a representation of the function nId and registeres it
211 :
212 0 : SfxControllerItem::SfxControllerItem( sal_uInt16 nID, SfxBindings &rBindings ):
213 : nId(nID),
214 : pNext(this),
215 0 : pBindings(&rBindings)
216 : {
217 0 : Bind(nId, &rBindings);
218 0 : }
219 :
220 :
221 : // unregisteres the item in the bindings
222 :
223 0 : SfxControllerItem::~SfxControllerItem()
224 : {
225 0 : if ( IsBound() )
226 0 : pBindings->Release(*this);
227 0 : }
228 :
229 :
230 :
231 0 : void SfxControllerItem::StateChanged
232 : (
233 : sal_uInt16, // <SID> of the triggering slot
234 : SfxItemState, // <SfxItemState> of 'pState'
235 : const SfxPoolItem* // Slot-Status, NULL or IsInvalidItem()
236 : )
237 :
238 : /* [Description]
239 :
240 : This virtual method is called by the SFx to inform the <SfxControllerItem>s
241 : is about that state of the slots 'NSID' has changed. The new value and the
242 : value determined by this status is given as 'pState' or 'eState'.
243 :
244 : The status of a slot may change, for example when the MDI window is
245 : switched or when the slot was invalidated explicitly with
246 : <SfxBindings::Invalidate()>.
247 :
248 : Achtung! Die Methode wird nicht gerufen, wenn der Slot ung"ultig wurde,
249 : danach jedoch wieder denselben Wert angenommen hat.
250 :
251 : Beware! The method is not called when the slot is invalid, however
252 : has again assumed the same value.
253 :
254 : This base class need not be called, further interim steps however
255 : (eg <SfxToolboxControl> ) should be called.
256 : */
257 :
258 : {
259 0 : }
260 :
261 :
262 :
263 0 : void SfxControllerItem::DeleteFloatingWindow()
264 : {
265 0 : }
266 :
267 :
268 :
269 0 : void SfxStatusForwarder::StateChanged
270 : (
271 : sal_uInt16 nSID, // <SID> of the triggering slot
272 : SfxItemState eState, // <SfxItemState> of 'pState'
273 : const SfxPoolItem* pState // Slot-Status, NULL or IsInvalidItem()
274 : )
275 :
276 : {
277 0 : pMaster->StateChanged( nSID, eState, pState );
278 0 : }
279 :
280 :
281 :
282 0 : SfxStatusForwarder::SfxStatusForwarder(
283 : sal_uInt16 nSlotId,
284 : SfxControllerItem& rMaster ):
285 0 : SfxControllerItem( nSlotId, rMaster.GetBindings() ),
286 0 : pMaster( &rMaster )
287 : {
288 0 : }
289 :
290 :
291 :
292 0 : SfxItemState SfxControllerItem::GetItemState
293 : (
294 : const SfxPoolItem* pState /* Pointer to <SfxPoolItem>, which
295 : Status should be queried. */
296 : )
297 :
298 : /* [Description]
299 :
300 : Static method to determine the status of the SfxPoolItem-Pointers, to be
301 : used in the method <SfxControllerItem::StateChanged(const SfxPoolItem*)>
302 :
303 : [Return value]
304 :
305 : SfxItemState SFX_ITEM_UNKNOWN
306 : Enabled, but no further status information available.
307 : Typical for <Slot>s, which anyway are sometimes
308 : disabled, but otherwise do not change their appearance.
309 :
310 : SFX_ITEM_DISABLED
311 : Disabled and no further status information available.
312 : All other values that may appear should be reset to
313 : default.
314 :
315 : SFX_ITEM_DONTCARE
316 : Enabled but there were only ambiguous values available
317 : (i.e. non that can be queried).
318 :
319 : SFX_ITEM_AVAILABLE
320 : Enabled and with available values, which are queried
321 : by 'pState'. The Type is thus clearly defined in the
322 : entire Program and specified through the Slot.
323 : */
324 :
325 : {
326 : return !pState
327 : ? SFX_ITEM_DISABLED
328 0 : : IsInvalidItem(pState)
329 : ? SFX_ITEM_DONTCARE
330 0 : : pState->ISA(SfxVoidItem) && !pState->Which()
331 : ? SFX_ITEM_UNKNOWN
332 0 : : SFX_ITEM_AVAILABLE;
333 : }
334 :
335 :
336 :
337 0 : SfxMapUnit SfxControllerItem::GetCoreMetric() const
338 :
339 : /* [Description]
340 :
341 : Gets the measurement unit from the competent pool, in which the Status
342 : item exist.
343 : */
344 :
345 : {
346 0 : SfxStateCache *pCache = pBindings->GetStateCache( nId );
347 0 : SfxDispatcher *pDispat = pBindings->GetDispatcher_Impl();
348 :
349 0 : if ( !pDispat )
350 : {
351 0 : SfxViewFrame* pViewFrame = SfxViewFrame::Current();
352 0 : if ( !pViewFrame )
353 0 : SfxViewFrame::GetFirst();
354 0 : if ( pViewFrame )
355 0 : pDispat = pViewFrame->GetDispatcher();
356 : }
357 :
358 0 : if ( pDispat && pCache )
359 : {
360 0 : const SfxSlotServer *pServer = pCache->GetSlotServer( *pDispat );
361 0 : if ( pServer )
362 : {
363 0 : SfxShell *pSh = pDispat->GetShell( pServer->GetShellLevel() );
364 0 : SfxItemPool &rPool = pSh->GetPool();
365 0 : sal_uInt16 nWhich = rPool.GetWhich( nId );
366 :
367 : // invalidate slot and its message|slot server as 'global' information
368 : // about the validated message|slot server is not made available
369 0 : pCache->Invalidate( true );
370 :
371 0 : return rPool.GetMetric( nWhich );
372 : }
373 : }
374 :
375 : DBG_WARNING( "W1: Can not find ItemPool!" );
376 0 : return SFX_MAPUNIT_100TH_MM;
377 : }
378 :
379 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|