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( SfxSlotMode 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 103764 : SfxControllerItem* SfxControllerItem::GetItemLink()
52 : {
53 103764 : return pNext == this ? 0 : pNext;
54 : }
55 :
56 :
57 : // returns sal_True if this binding is really bound to a function
58 :
59 368216 : bool SfxControllerItem::IsBound() const
60 : {
61 368216 : return pNext != this;
62 : }
63 :
64 :
65 : // registeres with the id at the bindings
66 :
67 63994 : void SfxControllerItem::Bind( sal_uInt16 nNewId, SfxBindings *pBindinx )
68 : {
69 : DBG_ASSERT(pBindings || pBindinx, "No Bindings");
70 :
71 63994 : if ( IsBound() ) {
72 : DBG_ASSERT(pBindings, "No Bindings");
73 0 : pBindings->Release(*this);
74 : }
75 :
76 63994 : nId = nNewId;
77 63994 : pNext = 0;
78 :
79 63994 : if (pBindinx)
80 63994 : pBindings = pBindinx;
81 63994 : pBindings->Register(*this);
82 63994 : }
83 :
84 80218 : void SfxControllerItem::BindInternal_Impl( sal_uInt16 nNewId, SfxBindings *pBindinx )
85 : {
86 : DBG_ASSERT(pBindings || pBindinx, "No Bindings");
87 :
88 80218 : if ( IsBound() ) {
89 : DBG_ASSERT(pBindings, "No Bindings");
90 0 : pBindings->Release(*this);
91 : }
92 :
93 80218 : nId = nNewId;
94 80218 : pNext = 0;
95 :
96 80218 : if (pBindinx)
97 80218 : pBindings = pBindinx;
98 80218 : pBindings->RegisterInternal_Impl(*this);
99 80218 : }
100 :
101 :
102 :
103 :
104 163431 : 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 163431 : pBindings->Release(*this);
123 163431 : pNext = this;
124 163431 : }
125 :
126 :
127 :
128 27646 : 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 27646 : pBindings->Register(*this);
147 27646 : }
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 92376 : SfxControllerItem* SfxControllerItem::ChangeItemLink( SfxControllerItem* pNewLink )
183 : {
184 92376 : SfxControllerItem* pOldLink = pNext;
185 92376 : pNext = pNewLink;
186 92376 : return pOldLink == this ? 0 : pOldLink;
187 : }
188 :
189 :
190 : // changes the id of unbound functions (e.g. for sub-menu-ids)
191 :
192 80409 : void SfxControllerItem::SetId( sal_uInt16 nItemId )
193 : {
194 : DBG_ASSERT( !IsBound(), "changing id of bound binding" );
195 80409 : nId = nItemId;
196 80409 : }
197 :
198 :
199 :
200 : // creates a atomic item for a controller without registration.
201 :
202 80410 : SfxControllerItem::SfxControllerItem():
203 : nId(0),
204 : pNext(this),
205 80410 : pBindings(0)
206 : {
207 80410 : }
208 :
209 :
210 : // creates a representation of the function nId and registeres it
211 :
212 63994 : SfxControllerItem::SfxControllerItem( sal_uInt16 nID, SfxBindings &rBindings ):
213 : nId(nID),
214 : pNext(this),
215 63994 : pBindings(&rBindings)
216 : {
217 63994 : Bind(nId, &rBindings);
218 63994 : }
219 :
220 :
221 : // unregisters the item in the bindings
222 :
223 136777 : SfxControllerItem::~SfxControllerItem()
224 : {
225 136777 : dispose();
226 136777 : }
227 :
228 143960 : void SfxControllerItem::dispose()
229 : {
230 143960 : if ( IsBound() )
231 8370 : pBindings->Release(*this);
232 143960 : }
233 :
234 4 : void SfxControllerItem::StateChanged
235 : (
236 : sal_uInt16, // <SID> of the triggering slot
237 : SfxItemState, // <SfxItemState> of 'pState'
238 : const SfxPoolItem* // Slot-Status, NULL or IsInvalidItem()
239 : )
240 :
241 : /* [Description]
242 :
243 : This virtual method is called by the SFx to inform the <SfxControllerItem>s
244 : is about that state of the slots 'NSID' has changed. The new value and the
245 : value determined by this status is given as 'pState' or 'eState'.
246 :
247 : The status of a slot may change, for example when the MDI window is
248 : switched or when the slot was invalidated explicitly with
249 : <SfxBindings::Invalidate()>.
250 :
251 : Achtung! Die Methode wird nicht gerufen, wenn der Slot ung"ultig wurde,
252 : danach jedoch wieder denselben Wert angenommen hat.
253 :
254 : Beware! The method is not called when the slot is invalid, however
255 : has again assumed the same value.
256 :
257 : This base class need not be called, further interim steps however
258 : (eg <SfxToolboxControl> ) should be called.
259 : */
260 :
261 : {
262 4 : }
263 :
264 :
265 :
266 0 : void SfxStatusForwarder::StateChanged
267 : (
268 : sal_uInt16 nSID, // <SID> of the triggering slot
269 : SfxItemState eState, // <SfxItemState> of 'pState'
270 : const SfxPoolItem* pState // Slot-Status, NULL or IsInvalidItem()
271 : )
272 :
273 : {
274 0 : pMaster->StateChanged( nSID, eState, pState );
275 0 : }
276 :
277 :
278 :
279 0 : SfxStatusForwarder::SfxStatusForwarder(
280 : sal_uInt16 nSlotId,
281 : SfxControllerItem& rMaster ):
282 0 : SfxControllerItem( nSlotId, rMaster.GetBindings() ),
283 0 : pMaster( &rMaster )
284 : {
285 0 : }
286 :
287 :
288 :
289 421 : SfxItemState SfxControllerItem::GetItemState
290 : (
291 : const SfxPoolItem* pState /* Pointer to <SfxPoolItem>, which
292 : Status should be queried. */
293 : )
294 :
295 : /* [Description]
296 :
297 : Static method to determine the status of the SfxPoolItem-Pointers, to be
298 : used in the method <SfxControllerItem::StateChanged(const SfxPoolItem*)>
299 :
300 : [Return value]
301 :
302 : SfxItemState SfxItemState::UNKNOWN
303 : Enabled, but no further status information available.
304 : Typical for <Slot>s, which anyway are sometimes
305 : disabled, but otherwise do not change their appearance.
306 :
307 : SfxItemState::DISABLED
308 : Disabled and no further status information available.
309 : All other values that may appear should be reset to
310 : default.
311 :
312 : SfxItemState::DONTCARE
313 : Enabled but there were only ambiguous values available
314 : (i.e. non that can be queried).
315 :
316 : SfxItemState::DEFAULT
317 : Enabled and with available values, which are queried
318 : by 'pState'. The Type is thus clearly defined in the
319 : entire Program and specified through the Slot.
320 : */
321 :
322 : {
323 : return !pState
324 : ? SfxItemState::DISABLED
325 421 : : IsInvalidItem(pState)
326 : ? SfxItemState::DONTCARE
327 421 : : pState->ISA(SfxVoidItem) && !pState->Which()
328 : ? SfxItemState::UNKNOWN
329 1263 : : SfxItemState::DEFAULT;
330 : }
331 :
332 :
333 :
334 1364 : SfxMapUnit SfxControllerItem::GetCoreMetric() const
335 :
336 : /* [Description]
337 :
338 : Gets the measurement unit from the competent pool, in which the Status
339 : item exist.
340 : */
341 :
342 : {
343 1364 : SfxStateCache *pCache = pBindings->GetStateCache( nId );
344 1364 : SfxDispatcher *pDispat = pBindings->GetDispatcher_Impl();
345 :
346 1364 : if ( !pDispat )
347 : {
348 0 : SfxViewFrame* pViewFrame = SfxViewFrame::Current();
349 0 : if ( !pViewFrame )
350 0 : SfxViewFrame::GetFirst();
351 0 : if ( pViewFrame )
352 0 : pDispat = pViewFrame->GetDispatcher();
353 : }
354 :
355 1364 : if ( pDispat && pCache )
356 : {
357 1364 : const SfxSlotServer *pServer = pCache->GetSlotServer( *pDispat );
358 1364 : if ( pServer )
359 : {
360 1364 : SfxShell *pSh = pDispat->GetShell( pServer->GetShellLevel() );
361 1364 : SfxItemPool &rPool = pSh->GetPool();
362 1364 : sal_uInt16 nWhich = rPool.GetWhich( nId );
363 :
364 : // invalidate slot and its message|slot server as 'global' information
365 : // about the validated message|slot server is not made available
366 1364 : pCache->Invalidate( true );
367 :
368 1364 : return rPool.GetMetric( nWhich );
369 : }
370 : }
371 :
372 : DBG_WARNING( "W1: Can not find ItemPool!" );
373 0 : return SFX_MAPUNIT_100TH_MM;
374 : }
375 :
376 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|