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 :
21 : #include "ViewShellManager.hxx"
22 : #include "ViewShell.hxx"
23 : #include "ViewShellBase.hxx"
24 : #include "Window.hxx"
25 : #include "DrawDocShell.hxx"
26 : #include "FormShellManager.hxx"
27 :
28 : #include <sfx2/dispatch.hxx>
29 : #include <svx/svxids.hrc>
30 : #include <svx/fmshell.hxx>
31 :
32 : #include <boost/unordered_map.hpp>
33 : #include <iterator>
34 :
35 : namespace sd {
36 :
37 : namespace {
38 :
39 : /** The ShellDescriptor class is used to shells together with their ids and
40 : the factory that was used to create the shell.
41 :
42 : The shell pointer may be NULL. In that case the shell is created on
43 : demand by a factory.
44 :
45 : The factory pointer may be NULL. In that case the shell pointer is
46 : given to the ViewShellManager.
47 :
48 : Shell pointer and factory pointer can but should not be NULL at the same
49 : time.
50 : */
51 1017 : class ShellDescriptor {
52 : public:
53 : SfxShell* mpShell;
54 : ShellId mnId;
55 : ViewShellManager::SharedShellFactory mpFactory;
56 : bool mbIsListenerAddedToWindow;
57 :
58 : ShellDescriptor ();
59 : ShellDescriptor (SfxShell* pShell, ShellId nId);
60 : ShellDescriptor (const ShellDescriptor& rDescriptor);
61 : ShellDescriptor& operator= (const ShellDescriptor& rDescriptor);
62 : bool IsMainViewShell (void) const;
63 : ::Window* GetWindow (void) const;
64 : };
65 :
66 :
67 :
68 :
69 : /** This functor can be used to search for a shell in an STL container when the
70 : shell pointer is given.
71 : */
72 : class IsShell : public ::std::unary_function<ShellDescriptor,bool>
73 : {
74 : public:
75 337 : IsShell (const SfxShell* pShell) : mpShell(pShell) {}
76 400 : bool operator() (const ShellDescriptor& rDescriptor)
77 400 : { return rDescriptor.mpShell == mpShell; }
78 : private:
79 : const SfxShell* mpShell;
80 : };
81 :
82 :
83 :
84 :
85 : /** This functor can be used to search for a shell in an STL container when the
86 : id of the shell is given.
87 : */
88 : class IsId : public ::std::unary_function<ShellDescriptor,bool>
89 : {
90 : public:
91 5720 : IsId (ShellId nId) : mnId(nId) {}
92 11164 : bool operator() (const ShellDescriptor& rDescriptor)
93 11164 : { return rDescriptor.mnId == mnId; }
94 : private:
95 : ShellId mnId;
96 : };
97 :
98 : } // end of anonymous namespace
99 :
100 :
101 :
102 :
103 : class ViewShellManager::Implementation
104 : {
105 : public:
106 : Implementation (
107 : ViewShellManager& rManager,
108 : ViewShellBase& rBase);
109 : ~Implementation (void);
110 :
111 : void AddShellFactory (
112 : const SfxShell* pViewShell,
113 : const SharedShellFactory& rpFactory);
114 : void RemoveShellFactory (
115 : const SfxShell* pViewShell,
116 : const SharedShellFactory& rpFactory);
117 : void ActivateViewShell (
118 : ViewShell* pViewShell);
119 : void DeactivateViewShell (const ViewShell& rShell);
120 : void ActivateShell (SfxShell& rShell);
121 : void DeactivateShell (const SfxShell& rShell);
122 : void ActivateShell (const ShellDescriptor& rDescriptor);
123 : void SetFormShell (const ViewShell* pViewShell, FmFormShell* pFormShell, bool bAbove);
124 : void ActivateSubShell (const SfxShell& rParentShell, ShellId nId);
125 : void DeactivateSubShell (const SfxShell& rParentShell, ShellId nId);
126 : void MoveToTop (const SfxShell& rParentShell);
127 : SfxShell* GetShell (ShellId nId) const;
128 : SfxShell* GetTopShell (void) const;
129 : void Shutdown (void);
130 : void InvalidateAllSubShells (const SfxShell* pParentShell);
131 :
132 : /** Remove all shells from the SFX stack above and including the given
133 : shell.
134 : */
135 : void TakeShellsFromStack (const SfxShell* pShell);
136 :
137 : class UpdateLock
138 : {
139 : public:
140 479 : UpdateLock (Implementation& rImpl) : mrImpl(rImpl) {mrImpl.LockUpdate();}
141 479 : ~UpdateLock (void) {mrImpl.UnlockUpdate();};
142 : private:
143 : Implementation& mrImpl;
144 : };
145 :
146 :
147 :
148 : /** Prevent updates of the shell stack. While the sub shell manager is
149 : locked it will update its internal data structures but not alter the
150 : shell stack. Use this method when there are several modifications
151 : to the shell stack to prevent multiple rebuilds of the shell stack
152 : and resulting broadcasts.
153 : */
154 : void LockUpdate (void);
155 :
156 : /** Allow updates of the shell stack. This method has to be called the
157 : same number of times as LockUpdate() to really allow a rebuild of
158 : the shell stack.
159 : */
160 : void UnlockUpdate (void);
161 :
162 : private:
163 : ViewShellBase& mrBase;
164 : mutable ::osl::Mutex maMutex;
165 :
166 3198 : class ShellHash{public: size_t operator()(const SfxShell* p) const { return (size_t)p;} };
167 : typedef ::boost::unordered_multimap<const SfxShell*,SharedShellFactory,ShellHash>
168 : FactoryList;
169 : FactoryList maShellFactories;
170 :
171 : /** List of the active view shells. In order to create gather all shells
172 : to put on the shell stack each view shell in this list is asked for
173 : its sub-shells (typically toolbars).
174 : */
175 : typedef ::std::list<ShellDescriptor> ActiveShellList;
176 : ActiveShellList maActiveViewShells;
177 :
178 : typedef ::std::list<ShellDescriptor> SubShellSubList;
179 : typedef ::boost::unordered_map<const SfxShell*,SubShellSubList,ShellHash> SubShellList;
180 : SubShellList maActiveSubShells;
181 :
182 : /** In this member we remember what shells we have pushed on the shell
183 : stack.
184 : */
185 : typedef ::std::vector<SfxShell*> ShellStack;
186 :
187 : int mnUpdateLockCount;
188 :
189 : /** When this flag is set then the main view shell is always kept at the
190 : top of the shell stack.
191 : */
192 : bool mbKeepMainViewShellOnTop;
193 :
194 : /** The UpdateShellStack() method can be called recursively. This flag
195 : is used to communicate between different levels of invocation: if
196 : the stack has been updated in an inner call the outer call can (has
197 : to) stop and return immediately.
198 : */
199 : bool mbShellStackIsUpToDate;
200 :
201 : SfxShell* mpFormShell;
202 : const ViewShell* mpFormShellParent;
203 : bool mbFormShellAboveParent;
204 :
205 : SfxShell* mpTopShell;
206 :
207 : void GatherActiveShells (ShellStack& rShellList);
208 :
209 : void UpdateShellStack (void);
210 :
211 : void CreateShells (void);
212 :
213 : /** This method rebuilds the stack of shells that are stacked upon the
214 : view shell base.
215 : */
216 : void CreateTargetStack (ShellStack& rStack) const;
217 :
218 : DECL_LINK(WindowEventHandler, VclWindowEvent*);
219 :
220 : #if OSL_DEBUG_LEVEL >= 2
221 : void DumpShellStack (const ShellStack& rStack);
222 : void DumpSfxShellStack (void);
223 : #endif
224 :
225 : /** To be called before a shell is taken fom the SFX shell stack. This
226 : method deactivates an active text editing to avoid problems with
227 : undo managers.
228 : Afterwards the Deactivate() of the shell is called.
229 : */
230 : void Deactivate (SfxShell* pShell);
231 :
232 : ShellDescriptor CreateSubShell (
233 : SfxShell* pShell,
234 : ShellId nShellId,
235 : ::Window* pParentWindow,
236 : FrameView* pFrameView);
237 : void DestroyViewShell (ShellDescriptor& rDescriptor);
238 : void DestroySubShell (
239 : const SfxShell& rViewShell,
240 : const ShellDescriptor& rDescriptor);
241 : };
242 :
243 :
244 :
245 :
246 : //===== ViewShellManager ======================================================
247 :
248 73 : ViewShellManager::ViewShellManager (ViewShellBase& rBase)
249 73 : : mpImpl(new Implementation(*this,rBase)),
250 146 : mbValid(true)
251 : {
252 73 : }
253 :
254 :
255 :
256 :
257 73 : ViewShellManager::~ViewShellManager (void)
258 : {
259 73 : }
260 :
261 :
262 :
263 :
264 205 : void ViewShellManager::AddSubShellFactory (
265 : ViewShell* pViewShell,
266 : const SharedShellFactory& rpFactory)
267 : {
268 205 : if (mbValid)
269 205 : mpImpl->AddShellFactory(pViewShell, rpFactory);
270 205 : }
271 :
272 :
273 :
274 :
275 136 : void ViewShellManager::RemoveSubShellFactory (
276 : ViewShell* pViewShell,
277 : const SharedShellFactory& rpFactory)
278 : {
279 136 : if (mbValid)
280 4 : mpImpl->RemoveShellFactory(pViewShell, rpFactory);
281 136 : }
282 :
283 :
284 :
285 :
286 132 : void ViewShellManager::ActivateViewShell (ViewShell* pViewShell)
287 : {
288 132 : if (mbValid)
289 132 : return mpImpl->ActivateViewShell(pViewShell);
290 : }
291 :
292 :
293 :
294 :
295 132 : void ViewShellManager::DeactivateViewShell (const ViewShell* pShell)
296 : {
297 132 : if (mbValid && pShell!=NULL)
298 0 : mpImpl->DeactivateViewShell(*pShell);
299 132 : }
300 :
301 :
302 :
303 :
304 138 : void ViewShellManager::SetFormShell (
305 : const ViewShell* pParentShell,
306 : FmFormShell* pFormShell,
307 : bool bAbove)
308 : {
309 138 : if (mbValid)
310 138 : mpImpl->SetFormShell(pParentShell,pFormShell,bAbove);
311 138 : }
312 :
313 :
314 :
315 :
316 69 : void ViewShellManager::ActivateSubShell (const ViewShell& rViewShell, ShellId nId)
317 : {
318 69 : if (mbValid)
319 69 : mpImpl->ActivateSubShell(rViewShell,nId);
320 69 : }
321 :
322 :
323 :
324 :
325 0 : void ViewShellManager::DeactivateSubShell (const ViewShell& rViewShell, ShellId nId)
326 : {
327 0 : if (mbValid)
328 0 : mpImpl->DeactivateSubShell(rViewShell,nId);
329 0 : }
330 :
331 :
332 :
333 :
334 74 : void ViewShellManager::InvalidateAllSubShells (ViewShell* pViewShell)
335 : {
336 74 : if (mbValid)
337 74 : mpImpl->InvalidateAllSubShells(pViewShell);
338 74 : }
339 :
340 :
341 :
342 :
343 73 : void ViewShellManager::ActivateShell (SfxShell* pShell)
344 : {
345 73 : if (mbValid && pShell!=NULL)
346 73 : mpImpl->ActivateShell(*pShell);
347 73 : }
348 :
349 :
350 :
351 :
352 0 : void ViewShellManager::DeactivateShell (const SfxShell* pShell)
353 : {
354 0 : if (mbValid && pShell!=NULL)
355 0 : mpImpl->DeactivateShell(*pShell);
356 0 : }
357 :
358 :
359 :
360 :
361 132 : void ViewShellManager::MoveToTop (const ViewShell& rParentShell)
362 : {
363 132 : if (mbValid)
364 132 : mpImpl->MoveToTop(rParentShell);
365 132 : }
366 :
367 :
368 :
369 :
370 2791 : SfxShell* ViewShellManager::GetShell (ShellId nId) const
371 : {
372 2791 : if (mbValid)
373 2791 : return mpImpl->GetShell(nId);
374 : else
375 0 : return NULL;
376 : }
377 :
378 :
379 :
380 :
381 0 : SfxShell* ViewShellManager::GetTopShell (void) const
382 : {
383 0 : if (mbValid)
384 0 : return mpImpl->GetTopShell();
385 : else
386 0 : return NULL;
387 : }
388 :
389 :
390 :
391 :
392 142 : void ViewShellManager::Shutdown (void)
393 : {
394 142 : if (mbValid)
395 : {
396 73 : mpImpl->Shutdown();
397 73 : mbValid = false;
398 : }
399 142 : }
400 :
401 :
402 :
403 1039 : void ViewShellManager::LockUpdate (void)
404 : {
405 1039 : mpImpl->LockUpdate();
406 1039 : }
407 :
408 :
409 :
410 :
411 1039 : void ViewShellManager::UnlockUpdate (void)
412 : {
413 1039 : mpImpl->UnlockUpdate();
414 1039 : }
415 :
416 :
417 :
418 :
419 : //===== ViewShellManager::Implementation ======================================
420 :
421 73 : ViewShellManager::Implementation::Implementation (
422 : ViewShellManager& rManager,
423 : ViewShellBase& rBase)
424 : : mrBase(rBase),
425 : maMutex(),
426 : maShellFactories(),
427 : maActiveViewShells(),
428 : mnUpdateLockCount(0),
429 : mbKeepMainViewShellOnTop(false),
430 : mbShellStackIsUpToDate(true),
431 : mpFormShell(NULL),
432 : mpFormShellParent(NULL),
433 : mbFormShellAboveParent(true),
434 73 : mpTopShell(NULL)
435 : {
436 : (void)rManager;
437 73 : }
438 :
439 :
440 :
441 :
442 146 : ViewShellManager::Implementation::~Implementation (void)
443 : {
444 73 : Shutdown();
445 73 : }
446 :
447 :
448 :
449 :
450 205 : void ViewShellManager::Implementation::AddShellFactory (
451 : const SfxShell* pViewShell,
452 : const SharedShellFactory& rpFactory)
453 : {
454 205 : bool bAlreadyAdded (false);
455 :
456 : // Check that the given factory has not already been added.
457 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
458 205 : maShellFactories.equal_range(pViewShell));
459 274 : for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
460 69 : if (iFactory->second == rpFactory)
461 : {
462 0 : bAlreadyAdded = true;
463 0 : break;
464 : }
465 :
466 : // Add the factory if it is not already present.
467 205 : if ( ! bAlreadyAdded)
468 205 : maShellFactories.insert(FactoryList::value_type(pViewShell, rpFactory));
469 205 : }
470 :
471 :
472 :
473 :
474 4 : void ViewShellManager::Implementation::RemoveShellFactory (
475 : const SfxShell* pViewShell,
476 : const SharedShellFactory& rpFactory)
477 : {
478 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
479 4 : maShellFactories.equal_range(pViewShell));
480 4 : for (FactoryList::iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
481 4 : if (iFactory->second == rpFactory)
482 : {
483 4 : maShellFactories.erase(iFactory);
484 4 : break;
485 : }
486 4 : }
487 :
488 :
489 :
490 :
491 132 : void ViewShellManager::Implementation::ActivateViewShell (ViewShell* pViewShell)
492 : {
493 132 : ::osl::MutexGuard aGuard (maMutex);
494 :
495 264 : ShellDescriptor aResult;
496 132 : aResult.mpShell = pViewShell;
497 :
498 : // Register as window listener so that the shells of the current
499 : // window can be moved to the top of the shell stack.
500 132 : if (aResult.mpShell != NULL)
501 : {
502 132 : ::Window* pWindow = aResult.GetWindow();
503 132 : if (pWindow != NULL)
504 : {
505 : pWindow->AddEventListener(
506 132 : LINK(this, ViewShellManager::Implementation, WindowEventHandler));
507 132 : aResult.mbIsListenerAddedToWindow = true;
508 : }
509 : else
510 : {
511 : DBG_ASSERT(false,
512 : "ViewShellManager::ActivateViewShell: "
513 : "new view shell has no active window");
514 : }
515 : }
516 :
517 264 : ActivateShell(aResult);
518 132 : }
519 :
520 :
521 :
522 :
523 132 : void ViewShellManager::Implementation::DeactivateViewShell (const ViewShell& rShell)
524 : {
525 132 : ::osl::MutexGuard aGuard (maMutex);
526 :
527 : ActiveShellList::iterator iShell (::std::find_if (
528 : maActiveViewShells.begin(),
529 : maActiveViewShells.end(),
530 132 : IsShell(&rShell)));
531 132 : if (iShell != maActiveViewShells.end())
532 : {
533 132 : UpdateLock aLocker (*this);
534 :
535 264 : ShellDescriptor aDescriptor(*iShell);
536 132 : mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
537 132 : maActiveViewShells.erase(iShell);
538 132 : TakeShellsFromStack(aDescriptor.mpShell);
539 :
540 : // Deactivate sub shells.
541 132 : SubShellList::iterator iList (maActiveSubShells.find(&rShell));
542 132 : if (iList != maActiveSubShells.end())
543 : {
544 69 : SubShellSubList& rList (iList->second);
545 207 : while ( ! rList.empty())
546 69 : DeactivateSubShell(rShell, rList.front().mnId);
547 : }
548 :
549 264 : DestroyViewShell(aDescriptor);
550 132 : }
551 132 : }
552 :
553 :
554 :
555 :
556 73 : void ViewShellManager::Implementation::ActivateShell (SfxShell& rShell)
557 : {
558 73 : ::osl::MutexGuard aGuard (maMutex);
559 :
560 : // Create a new shell or recycle on in the cache.
561 146 : ShellDescriptor aDescriptor;
562 73 : aDescriptor.mpShell = &rShell;
563 :
564 146 : ActivateShell(aDescriptor);
565 73 : }
566 :
567 :
568 :
569 :
570 205 : void ViewShellManager::Implementation::ActivateShell (const ShellDescriptor& rDescriptor)
571 : {
572 : // Put shell on top of the active view shells.
573 205 : if (rDescriptor.mpShell != NULL)
574 : {
575 : // Determine where to put the view shell on the stack. By default
576 : // it is put on top of the stack. When the view shell of the center
577 : // pane is to be kept top most and the new view shell is not
578 : // displayed in the center pane then it is inserted at the position
579 : // one below the top.
580 205 : ActiveShellList::iterator iInsertPosition (maActiveViewShells.begin());
581 615 : if (iInsertPosition != maActiveViewShells.end()
582 132 : && mbKeepMainViewShellOnTop
583 0 : && ! rDescriptor.IsMainViewShell()
584 615 : && iInsertPosition->IsMainViewShell())
585 : {
586 0 : ++iInsertPosition;
587 : }
588 : maActiveViewShells.insert(
589 : iInsertPosition,
590 205 : rDescriptor);
591 : }
592 205 : }
593 :
594 :
595 :
596 :
597 73 : void ViewShellManager::Implementation::DeactivateShell (const SfxShell& rShell)
598 : {
599 73 : ::osl::MutexGuard aGuard (maMutex);
600 :
601 : ActiveShellList::iterator iShell (::std::find_if (
602 : maActiveViewShells.begin(),
603 : maActiveViewShells.end(),
604 73 : IsShell(&rShell)));
605 73 : if (iShell != maActiveViewShells.end())
606 : {
607 73 : UpdateLock aLocker (*this);
608 :
609 146 : ShellDescriptor aDescriptor(*iShell);
610 73 : mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
611 73 : maActiveViewShells.erase(iShell);
612 73 : TakeShellsFromStack(aDescriptor.mpShell);
613 :
614 : // Deactivate sub shells.
615 73 : SubShellList::iterator iList (maActiveSubShells.find(&rShell));
616 73 : if (iList != maActiveSubShells.end())
617 : {
618 0 : SubShellSubList& rList (iList->second);
619 0 : while ( ! rList.empty())
620 0 : DeactivateSubShell(rShell, rList.front().mnId);
621 : }
622 :
623 146 : DestroyViewShell(aDescriptor);
624 73 : }
625 73 : }
626 :
627 :
628 :
629 :
630 69 : void ViewShellManager::Implementation::ActivateSubShell (
631 : const SfxShell& rParentShell,
632 : ShellId nId)
633 : {
634 69 : ::osl::MutexGuard aGuard (maMutex);
635 :
636 : // Check that the given view shell is active.
637 : ActiveShellList::iterator iShell (::std::find_if (
638 : maActiveViewShells.begin(),
639 : maActiveViewShells.end(),
640 69 : IsShell(&rParentShell)));
641 69 : if (iShell == maActiveViewShells.end())
642 0 : return;
643 :
644 : // Create the sub shell list if it does not yet exist.
645 69 : SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
646 69 : if (iList == maActiveSubShells.end())
647 : iList = maActiveSubShells.insert(
648 69 : SubShellList::value_type(&rParentShell,SubShellSubList())).first;
649 :
650 : // Do not activate an object bar that is already active. Requesting
651 : // this is not exactly an error but may be an indication of one.
652 69 : SubShellSubList& rList (iList->second);
653 69 : if (::std::find_if(rList.begin(),rList.end(), IsId(nId)) != rList.end())
654 0 : return;
655 :
656 : // Add just the id of the sub shell. The actual shell is created
657 : // later in CreateShells().
658 138 : UpdateLock aLock (*this);
659 138 : rList.push_back(ShellDescriptor(NULL, nId));
660 : }
661 :
662 :
663 :
664 :
665 69 : void ViewShellManager::Implementation::DeactivateSubShell (
666 : const SfxShell& rParentShell,
667 : ShellId nId)
668 : {
669 69 : ::osl::MutexGuard aGuard (maMutex);
670 :
671 : // Check that the given view shell is active.
672 69 : SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
673 69 : if (iList == maActiveSubShells.end())
674 0 : return;
675 :
676 : // Look up the sub shell.
677 69 : SubShellSubList& rList (iList->second);
678 : SubShellSubList::iterator iShell (
679 69 : ::std::find_if(rList.begin(),rList.end(), IsId(nId)));
680 69 : if (iShell == rList.end())
681 0 : return;
682 69 : SfxShell* pShell = iShell->mpShell;
683 69 : if (pShell == NULL)
684 0 : return;
685 :
686 138 : UpdateLock aLock (*this);
687 :
688 138 : ShellDescriptor aDescriptor(*iShell);
689 : // Remove the sub shell from both the internal structure as well as the
690 : // SFX shell stack above and including the sub shell.
691 69 : rList.erase(iShell);
692 69 : TakeShellsFromStack(pShell);
693 :
694 138 : DestroySubShell(rParentShell, aDescriptor);
695 : }
696 :
697 :
698 :
699 :
700 132 : void ViewShellManager::Implementation::MoveToTop (const SfxShell& rShell)
701 : {
702 132 : ::osl::MutexGuard aGuard (maMutex);
703 :
704 : // Check that we have access to a dispatcher. If not, then we are
705 : // (probably) called while the view shell is still being created or
706 : // initialized. Without dispatcher we can not rebuild the shell stack
707 : // to move the requested shell to the top. So return right away instead
708 : // of making a mess without being able to clean up afterwards.
709 132 : if (mrBase.GetDispatcher() == NULL)
710 201 : return;
711 :
712 : ActiveShellList::iterator iShell (::std::find_if (
713 : maActiveViewShells.begin(),
714 : maActiveViewShells.end(),
715 63 : IsShell(&rShell)));
716 63 : bool bMove = true;
717 63 : if (iShell != maActiveViewShells.end())
718 : {
719 : // Is the shell already at the top of the stack? We have to keep
720 : // the case in mind that mbKeepMainViewShellOnTop is true. Shells
721 : // that are not the main view shell are placed on the second-to-top
722 : // position in this case.
723 189 : if (iShell == maActiveViewShells.begin()
724 189 : && (iShell->IsMainViewShell() || ! mbKeepMainViewShellOnTop))
725 : {
726 : // The shell is at the top position and is either a) the main
727 : // view shell or b) another shell but the main view shell is not
728 : // kept at the top position. We do not have to move the shell.
729 0 : bMove = false;
730 : }
731 189 : else if (iShell == ++maActiveViewShells.begin()
732 63 : && ! iShell->IsMainViewShell()
733 189 : && mbKeepMainViewShellOnTop)
734 : {
735 : // The shell is a the second-to-top position, not the main view
736 : // shell and the main view shell is kept at the top position.
737 : // Therefore we do not have to move the shell.
738 0 : bMove = false;
739 : }
740 : }
741 : else
742 : {
743 : // The shell is not on the stack. Therefore it can not be moved.
744 : // We could insert it but we don't. Use ActivateViewShell() for
745 : // that.
746 0 : bMove = false;
747 : }
748 :
749 : // When the shell is not at the right position it is removed from the
750 : // internal list of shells and inserted at the correct position.
751 63 : if (bMove)
752 : {
753 63 : UpdateLock aLock (*this);
754 :
755 126 : ShellDescriptor aDescriptor(*iShell);
756 :
757 63 : TakeShellsFromStack(&rShell);
758 63 : maActiveViewShells.erase(iShell);
759 :
760 : // Find out whether to insert at the top or one below.
761 63 : ActiveShellList::iterator aInsertPosition (maActiveViewShells.begin());
762 63 : if (mbKeepMainViewShellOnTop && ! aDescriptor.IsMainViewShell())
763 : {
764 0 : if (maActiveViewShells.back().IsMainViewShell())
765 0 : ++aInsertPosition;
766 : }
767 :
768 126 : maActiveViewShells.insert(aInsertPosition, aDescriptor);
769 63 : }
770 : }
771 :
772 :
773 :
774 :
775 2791 : SfxShell* ViewShellManager::Implementation::GetShell (ShellId nId) const
776 : {
777 2791 : ::osl::MutexGuard aGuard (maMutex);
778 :
779 2791 : SfxShell* pShell = NULL;
780 :
781 : // First search the active view shells.
782 : ActiveShellList::const_iterator iShell (
783 : ::std::find_if (
784 : maActiveViewShells.begin(),
785 : maActiveViewShells.end(),
786 2791 : IsId(nId)));
787 2791 : if (iShell != maActiveViewShells.end())
788 0 : pShell = iShell->mpShell;
789 : else
790 : {
791 : // Now search the active sub shells of every active view shell.
792 2791 : SubShellList::const_iterator iList;
793 5582 : for (iList=maActiveSubShells.begin(); iList!=maActiveSubShells.end(); ++iList)
794 : {
795 2791 : const SubShellSubList& rList (iList->second);
796 : SubShellSubList::const_iterator iSubShell(
797 2791 : ::std::find_if(rList.begin(),rList.end(), IsId(nId)));
798 2791 : if (iSubShell != rList.end())
799 : {
800 0 : pShell = iSubShell->mpShell;
801 0 : break;
802 : }
803 : }
804 : }
805 :
806 2791 : return pShell;
807 : }
808 :
809 :
810 :
811 :
812 0 : SfxShell* ViewShellManager::Implementation::GetTopShell (void) const
813 : {
814 : OSL_ASSERT(mpTopShell == mrBase.GetSubShell(0));
815 0 : return mpTopShell;
816 : }
817 :
818 :
819 :
820 :
821 1518 : void ViewShellManager::Implementation::LockUpdate (void)
822 : {
823 1518 : mnUpdateLockCount++;
824 1518 : }
825 :
826 :
827 :
828 :
829 1518 : void ViewShellManager::Implementation::UnlockUpdate (void)
830 : {
831 1518 : ::osl::MutexGuard aGuard (maMutex);
832 :
833 1518 : mnUpdateLockCount--;
834 1518 : if (mnUpdateLockCount < 0)
835 : {
836 : // This should not happen.
837 : OSL_ASSERT (mnUpdateLockCount>=0);
838 0 : mnUpdateLockCount = 0;
839 : }
840 1518 : if (mnUpdateLockCount == 0)
841 575 : UpdateShellStack();
842 1518 : }
843 :
844 :
845 :
846 :
847 : /** Update the SFX shell stack (the portion that is visible to us) so that
848 : it matches the internal shell stack. This is done in six steps:
849 : 1. Create the missing view shells and sub shells.
850 : 2. Set up the internal shell stack.
851 : 3. Get the SFX shell stack.
852 : 4. Find the lowest shell in which the two stacks differ.
853 : 5. Remove all shells above and including that shell from the SFX stack.
854 : 6. Push all shells of the internal stack on the SFX shell stack that are
855 : not already present on the later.
856 : */
857 575 : void ViewShellManager::Implementation::UpdateShellStack (void)
858 : {
859 575 : ::osl::MutexGuard aGuard (maMutex);
860 :
861 : // Remember the undo manager from the top-most shell on the stack.
862 575 : SfxShell* pTopMostShell = mrBase.GetSubShell(0);
863 : ::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
864 360 : ? pTopMostShell->GetUndoManager()
865 935 : : NULL;
866 :
867 : // 1. Create the missing shells.
868 575 : CreateShells();
869 :
870 :
871 : // 2. Create the internal target stack.
872 1150 : ShellStack aTargetStack;
873 575 : CreateTargetStack(aTargetStack);
874 :
875 :
876 : // 3. Get SFX shell stack.
877 1150 : ShellStack aSfxShellStack;
878 575 : sal_uInt16 nIndex (0);
879 2177 : while (mrBase.GetSubShell(nIndex)!=NULL)
880 1027 : ++nIndex;
881 575 : aSfxShellStack.reserve(nIndex);
882 2177 : while (nIndex-- > 0)
883 1027 : aSfxShellStack.push_back(mrBase.GetSubShell(nIndex));
884 :
885 :
886 : #if OSL_DEBUG_LEVEL >= 2
887 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": Current SFX Stack");
888 : DumpShellStack(aSfxShellStack);
889 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": Target Stack");
890 : DumpShellStack(aTargetStack);
891 : #endif
892 :
893 :
894 : // 4. Find the lowest shell in which the two stacks differ.
895 575 : ShellStack::iterator iSfxShell (aSfxShellStack.begin());
896 575 : ShellStack::iterator iTargetShell (aTargetStack.begin());
897 6455 : while (iSfxShell != aSfxShellStack.end()
898 2497 : && iTargetShell!=aTargetStack.end()
899 5437 : && (*iSfxShell)==(*iTargetShell))
900 : {
901 895 : ++iSfxShell;
902 895 : ++iTargetShell;
903 : }
904 :
905 :
906 : // 5. Remove all shells above and including the differing shell from the
907 : // SFX stack starting with the shell on top of the stack.
908 707 : for (std::reverse_iterator<ShellStack::const_iterator> i(aSfxShellStack.end()), iLast(iSfxShell);
909 : i != iLast; ++i)
910 : {
911 132 : SfxShell* const pShell = *i;
912 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": removing shell " << pShell << " from stack");
913 132 : mrBase.RemoveSubShell(pShell);
914 : }
915 575 : aSfxShellStack.erase(iSfxShell, aSfxShellStack.end());
916 :
917 :
918 : // 6. Push shells from the given stack onto the SFX stack.
919 575 : mbShellStackIsUpToDate = false;
920 1568 : while (iTargetShell != aTargetStack.end())
921 : {
922 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": pushing shell " << *iTargetShell << " on stack");
923 469 : mrBase.AddSubShell(**iTargetShell);
924 469 : ++iTargetShell;
925 :
926 : // The pushing of the shell on to the shell stack may have lead to
927 : // another invocation of this method. In this case we have to abort
928 : // pushing shells on the stack and return immediately.
929 469 : if (mbShellStackIsUpToDate)
930 51 : break;
931 : }
932 575 : if (mrBase.GetDispatcher() != NULL)
933 429 : mrBase.GetDispatcher()->Flush();
934 :
935 : // Update the pointer to the top-most shell and set its undo manager
936 : // to the one of the previous top-most shell.
937 575 : mpTopShell = mrBase.GetSubShell(0);
938 575 : if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL)
939 0 : mpTopShell->SetUndoManager(pUndoManager);
940 :
941 : // Finally tell an invocation of this method on a higher level that it can (has
942 : // to) abort and return immediately.
943 1150 : mbShellStackIsUpToDate = true;
944 :
945 : #if OSL_DEBUG_LEVEL >= 2
946 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": New current stack");
947 : DumpSfxShellStack();
948 : #endif
949 575 : }
950 :
951 :
952 :
953 :
954 337 : void ViewShellManager::Implementation::TakeShellsFromStack (const SfxShell* pShell)
955 : {
956 337 : ::osl::MutexGuard aGuard (maMutex);
957 :
958 : // Remember the undo manager from the top-most shell on the stack.
959 337 : SfxShell* pTopMostShell = mrBase.GetSubShell(0);
960 : ::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
961 337 : ? pTopMostShell->GetUndoManager()
962 674 : : NULL;
963 :
964 : #if OSL_DEBUG_LEVEL >= 2
965 : SAL_INFO("sd.view", OSL_THIS_FUNC << "TakeShellsFromStack( " << pShell << ")");
966 : DumpSfxShellStack();
967 : #endif
968 :
969 : // 0.Make sure that the given shell is on the stack. This is a
970 : // preparation for the following assertion.
971 337 : for (sal_uInt16 nIndex=0; true; nIndex++)
972 : {
973 337 : SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
974 337 : if (pShellOnStack == NULL)
975 : {
976 : // Set pShell to NULL to indicate the following code that the
977 : // shell is not on the stack.
978 0 : pShell = NULL;
979 0 : break;
980 : }
981 337 : else if (pShellOnStack == pShell)
982 337 : break;
983 0 : }
984 :
985 337 : if (pShell != NULL)
986 : {
987 : // 1. Deactivate our shells on the stack before they are removed so
988 : // that during the Deactivation() calls the stack is still intact.
989 337 : for (sal_uInt16 nIndex=0; true; nIndex++)
990 : {
991 337 : SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
992 337 : Deactivate(pShellOnStack);
993 337 : if (pShellOnStack == pShell)
994 337 : break;
995 0 : }
996 :
997 : // 2. Remove the shells from the stack.
998 : while (true)
999 : {
1000 337 : SfxShell* pShellOnStack = mrBase.GetSubShell(0);
1001 : SAL_INFO("sd.view", OSL_THIS_FUNC << "removing shell " << pShellOnStack << " from stack");
1002 337 : mrBase.RemoveSubShell(pShellOnStack);
1003 337 : if (pShellOnStack == pShell)
1004 337 : break;
1005 : }
1006 :
1007 : // 3. Update the stack.
1008 674 : if (mrBase.GetDispatcher() != NULL)
1009 333 : mrBase.GetDispatcher()->Flush();
1010 :
1011 : // Update the pointer to the top-most shell and set its undo manager
1012 : // to the one of the previous top-most shell.
1013 337 : mpTopShell = mrBase.GetSubShell(0);
1014 337 : if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL)
1015 63 : mpTopShell->SetUndoManager(pUndoManager);
1016 337 : }
1017 :
1018 :
1019 : #if OSL_DEBUG_LEVEL >= 2
1020 : SAL_INFO("sd.view", OSL_THIS_FUNC << "Sfx shell stack is:");
1021 : DumpSfxShellStack();
1022 : #endif
1023 337 : }
1024 :
1025 :
1026 :
1027 :
1028 575 : void ViewShellManager::Implementation::CreateShells (void)
1029 : {
1030 575 : ::osl::MutexGuard aGuard (maMutex);
1031 :
1032 : // Iterate over all view shells.
1033 575 : ActiveShellList::reverse_iterator iShell;
1034 1587 : for (iShell=maActiveViewShells.rbegin(); iShell!=maActiveViewShells.rend(); ++iShell)
1035 : {
1036 : // Get the list of associated sub shells.
1037 1012 : SubShellList::iterator iList (maActiveSubShells.find(iShell->mpShell));
1038 1012 : if (iList != maActiveSubShells.end())
1039 : {
1040 352 : SubShellSubList& rList (iList->second);
1041 :
1042 : // Iterate over all sub shells of the current view shell.
1043 352 : SubShellSubList::iterator iSubShell;
1044 704 : for (iSubShell=rList.begin(); iSubShell!=rList.end(); ++iSubShell)
1045 : {
1046 352 : if (iSubShell->mpShell == NULL)
1047 : {
1048 69 : *iSubShell = CreateSubShell(iShell->mpShell,iSubShell->mnId,NULL,NULL);
1049 : }
1050 : }
1051 : }
1052 575 : }
1053 575 : }
1054 :
1055 :
1056 :
1057 :
1058 575 : void ViewShellManager::Implementation::CreateTargetStack (ShellStack& rStack) const
1059 : {
1060 : // Create a local stack of the shells that are to push on the shell
1061 : // stack. We can thus safly create the required shells wile still
1062 : // having a valid shell stack.
1063 4761 : for (ActiveShellList::const_reverse_iterator iViewShell (maActiveViewShells.rbegin());
1064 3174 : iViewShell != maActiveViewShells.rend();
1065 : ++iViewShell)
1066 : {
1067 : // Possibly place the form shell below the current view shell.
1068 2024 : if ( ! mbFormShellAboveParent
1069 862 : && mpFormShell!=NULL
1070 1874 : && iViewShell->mpShell==mpFormShellParent)
1071 : {
1072 352 : rStack.push_back(mpFormShell);
1073 : }
1074 :
1075 : // Put the view shell itself on the local stack.
1076 1012 : rStack.push_back (iViewShell->mpShell);
1077 :
1078 : // Possibly place the form shell above the current view shell.
1079 1012 : if (mbFormShellAboveParent
1080 150 : && mpFormShell!=NULL
1081 1012 : && iViewShell->mpShell==mpFormShellParent)
1082 : {
1083 0 : rStack.push_back(mpFormShell);
1084 : }
1085 :
1086 : // Add all other sub shells.
1087 1012 : SubShellList::const_iterator iList (maActiveSubShells.find(iViewShell->mpShell));
1088 1012 : if (iList != maActiveSubShells.end())
1089 : {
1090 352 : const SubShellSubList& rList (iList->second);
1091 352 : SubShellSubList::const_reverse_iterator iSubShell;
1092 704 : for (iSubShell=rList.rbegin(); iSubShell!=rList.rend(); ++iSubShell)
1093 352 : if (iSubShell->mpShell != mpFormShell)
1094 0 : rStack.push_back(iSubShell->mpShell);
1095 : }
1096 : }
1097 575 : }
1098 :
1099 :
1100 :
1101 :
1102 1232 : IMPL_LINK(ViewShellManager::Implementation, WindowEventHandler, VclWindowEvent*, pEvent)
1103 : {
1104 616 : if (pEvent != NULL)
1105 : {
1106 : ::Window* pEventWindow
1107 616 : = static_cast<VclWindowEvent*>(pEvent)->GetWindow();
1108 :
1109 616 : switch (pEvent->GetId())
1110 : {
1111 : case VCLEVENT_WINDOW_GETFOCUS:
1112 : {
1113 0 : for (ActiveShellList::iterator aI(maActiveViewShells.begin());
1114 0 : aI!=maActiveViewShells.end();
1115 : aI++)
1116 : {
1117 0 : if (pEventWindow == static_cast< ::Window*>(aI->GetWindow()))
1118 : {
1119 0 : MoveToTop(*aI->mpShell);
1120 0 : break;
1121 : }
1122 : }
1123 : }
1124 0 : break;
1125 :
1126 : case VCLEVENT_WINDOW_LOSEFOCUS:
1127 0 : break;
1128 :
1129 : case VCLEVENT_OBJECT_DYING:
1130 : // Remember that we do not have to remove the window
1131 : // listener for this window.
1132 0 : for (ActiveShellList::iterator
1133 0 : iShell(maActiveViewShells.begin()),
1134 0 : iEnd(maActiveViewShells.end());
1135 : iShell!=iEnd;
1136 : ++iShell)
1137 : {
1138 0 : if (iShell->GetWindow() == pEventWindow)
1139 : {
1140 0 : iShell->mbIsListenerAddedToWindow = false;
1141 0 : break;
1142 : }
1143 : }
1144 0 : break;
1145 : }
1146 : }
1147 616 : return sal_True;
1148 : }
1149 :
1150 :
1151 :
1152 :
1153 69 : ShellDescriptor ViewShellManager::Implementation::CreateSubShell (
1154 : SfxShell* pParentShell,
1155 : ShellId nShellId,
1156 : ::Window* pParentWindow,
1157 : FrameView* pFrameView)
1158 : {
1159 69 : ::osl::MutexGuard aGuard (maMutex);
1160 69 : ShellDescriptor aResult;
1161 :
1162 : // Look up the factories for the parent shell.
1163 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
1164 69 : maShellFactories.equal_range(pParentShell));
1165 :
1166 : // Try all factories to create the shell.
1167 138 : for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
1168 : {
1169 138 : SharedShellFactory pFactory = iFactory->second;
1170 138 : if (pFactory != 0)
1171 138 : aResult.mpShell = pFactory->CreateShell(nShellId, pParentWindow, pFrameView);
1172 :
1173 : // Exit the loop when the shell has been successfully created.
1174 138 : if (aResult.mpShell != NULL)
1175 : {
1176 69 : aResult.mpFactory = pFactory;
1177 69 : aResult.mnId = nShellId;
1178 69 : break;
1179 : }
1180 69 : }
1181 :
1182 69 : return aResult;
1183 : }
1184 :
1185 :
1186 :
1187 :
1188 205 : void ViewShellManager::Implementation::DestroyViewShell (
1189 : ShellDescriptor& rDescriptor)
1190 : {
1191 : OSL_ASSERT(rDescriptor.mpShell != NULL);
1192 :
1193 205 : if (rDescriptor.mbIsListenerAddedToWindow)
1194 : {
1195 132 : rDescriptor.mbIsListenerAddedToWindow = false;
1196 132 : ::Window* pWindow = rDescriptor.GetWindow();
1197 132 : if (pWindow != NULL)
1198 : {
1199 : pWindow->RemoveEventListener(
1200 132 : LINK(this, ViewShellManager::Implementation, WindowEventHandler));
1201 : }
1202 : }
1203 :
1204 : // Destroy the sub shell factories.
1205 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
1206 205 : maShellFactories.equal_range(rDescriptor.mpShell));
1207 205 : if (aRange.first != maShellFactories.end())
1208 132 : maShellFactories.erase(aRange.first, aRange.second);
1209 :
1210 : // Release the shell.
1211 205 : if (rDescriptor.mpFactory.get() != NULL)
1212 0 : rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
1213 205 : }
1214 :
1215 :
1216 :
1217 :
1218 69 : void ViewShellManager::Implementation::DestroySubShell (
1219 : const SfxShell& rParentShell,
1220 : const ShellDescriptor& rDescriptor)
1221 : {
1222 : (void)rParentShell;
1223 : OSL_ASSERT(rDescriptor.mpFactory.get() != NULL);
1224 69 : rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
1225 69 : }
1226 :
1227 :
1228 :
1229 :
1230 74 : void ViewShellManager::Implementation::InvalidateAllSubShells (const SfxShell* pParentShell)
1231 : {
1232 74 : ::osl::MutexGuard aGuard (maMutex);
1233 :
1234 74 : SubShellList::iterator iList (maActiveSubShells.find(pParentShell));
1235 74 : if (iList != maActiveSubShells.end())
1236 : {
1237 1 : SubShellSubList& rList (iList->second);
1238 1 : SubShellSubList::iterator iShell;
1239 2 : for (iShell=rList.begin(); iShell!=rList.end(); ++iShell)
1240 1 : if (iShell->mpShell != NULL)
1241 1 : iShell->mpShell->Invalidate();
1242 74 : }
1243 74 : }
1244 :
1245 :
1246 :
1247 :
1248 146 : void ViewShellManager::Implementation::Shutdown (void)
1249 : {
1250 146 : ::osl::MutexGuard aGuard (maMutex);
1251 :
1252 : // Take stacked shells from stack.
1253 146 : if ( ! maActiveViewShells.empty())
1254 : {
1255 73 : UpdateLock aLock (*this);
1256 :
1257 :
1258 351 : while ( ! maActiveViewShells.empty())
1259 : {
1260 205 : SfxShell* pShell = maActiveViewShells.front().mpShell;
1261 205 : if (pShell != NULL)
1262 : {
1263 205 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
1264 205 : if (pViewShell != NULL)
1265 132 : DeactivateViewShell(*pViewShell);
1266 : else
1267 73 : DeactivateShell(*pShell);
1268 : }
1269 : else
1270 : {
1271 : DBG_ASSERT(false,
1272 : "ViewShellManager::Implementation::Shutdown(): empty active shell descriptor");
1273 0 : maActiveViewShells.pop_front();
1274 : }
1275 73 : }
1276 : }
1277 146 : mrBase.RemoveSubShell (NULL);
1278 :
1279 146 : maShellFactories.clear();
1280 146 : }
1281 :
1282 :
1283 :
1284 :
1285 : #if OSL_DEBUG_LEVEL >= 2
1286 : void ViewShellManager::Implementation::DumpShellStack (const ShellStack& rStack)
1287 : {
1288 : ShellStack::const_reverse_iterator iEntry;
1289 : for (iEntry=rStack.rbegin(); iEntry!=rStack.rend(); ++iEntry)
1290 : if (*iEntry != NULL)
1291 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": " <<
1292 : *iEntry << " : " <<
1293 : OUStringToOString((*iEntry)->GetName(),RTL_TEXTENCODING_UTF8).getStr());
1294 : else
1295 : SAL_INFO("sd.view", OSL_THIS_FUNC << " null");
1296 : }
1297 :
1298 :
1299 :
1300 :
1301 : void ViewShellManager::Implementation::DumpSfxShellStack (void)
1302 : {
1303 : ShellStack aSfxShellStack;
1304 : sal_uInt16 nIndex (0);
1305 : while (mrBase.GetSubShell(nIndex)!=NULL)
1306 : ++nIndex;
1307 : aSfxShellStack.reserve(nIndex);
1308 : while (nIndex-- > 0)
1309 : aSfxShellStack.push_back(mrBase.GetSubShell(nIndex));
1310 : DumpShellStack(aSfxShellStack);
1311 : }
1312 : #endif
1313 :
1314 :
1315 :
1316 337 : void ViewShellManager::Implementation::Deactivate (SfxShell* pShell)
1317 : {
1318 : OSL_ASSERT(pShell!=NULL);
1319 :
1320 : // We have to end a text edit for view shells that are to be taken from
1321 : // the shell stack.
1322 337 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
1323 337 : if (pViewShell != NULL)
1324 : {
1325 195 : sd::View* pView = pViewShell->GetView();
1326 195 : if (pView!=NULL && pView->IsTextEdit())
1327 : {
1328 0 : pView->SdrEndTextEdit();
1329 0 : pView->UnmarkAll();
1330 : pViewShell->GetViewFrame()->GetDispatcher()->Execute(
1331 : SID_OBJECT_SELECT,
1332 0 : SFX_CALLMODE_ASYNCHRON);
1333 : }
1334 : }
1335 :
1336 : // Now we can deactivate the shell.
1337 337 : pShell->Deactivate(true);
1338 337 : }
1339 :
1340 :
1341 :
1342 :
1343 138 : void ViewShellManager::Implementation::SetFormShell (
1344 : const ViewShell* pFormShellParent,
1345 : FmFormShell* pFormShell,
1346 : bool bFormShellAboveParent)
1347 : {
1348 138 : ::osl::MutexGuard aGuard (maMutex);
1349 :
1350 138 : mpFormShellParent = pFormShellParent;
1351 138 : mpFormShell = pFormShell;
1352 138 : mbFormShellAboveParent = bFormShellAboveParent;
1353 138 : }
1354 :
1355 :
1356 :
1357 :
1358 : namespace {
1359 :
1360 274 : ShellDescriptor::ShellDescriptor (void)
1361 : : mpShell(NULL),
1362 : mnId(0),
1363 : mpFactory(),
1364 274 : mbIsListenerAddedToWindow(false)
1365 : {
1366 274 : }
1367 :
1368 :
1369 :
1370 :
1371 69 : ShellDescriptor::ShellDescriptor (
1372 : SfxShell* pShell,
1373 : ShellId nId)
1374 : : mpShell(pShell),
1375 : mnId(nId),
1376 : mpFactory(),
1377 69 : mbIsListenerAddedToWindow(false)
1378 : {
1379 69 : }
1380 :
1381 :
1382 :
1383 :
1384 674 : ShellDescriptor::ShellDescriptor (const ShellDescriptor& rDescriptor)
1385 : : mpShell(rDescriptor.mpShell),
1386 : mnId(rDescriptor.mnId),
1387 : mpFactory(rDescriptor.mpFactory),
1388 674 : mbIsListenerAddedToWindow(rDescriptor.mbIsListenerAddedToWindow)
1389 : {
1390 674 : }
1391 :
1392 :
1393 :
1394 :
1395 69 : ShellDescriptor& ShellDescriptor::operator= (const ShellDescriptor& rDescriptor)
1396 : {
1397 69 : if (this != &rDescriptor)
1398 : {
1399 69 : mpShell = rDescriptor.mpShell;
1400 69 : mnId = rDescriptor.mnId;
1401 69 : mpFactory = rDescriptor.mpFactory;
1402 69 : mbIsListenerAddedToWindow = rDescriptor.mbIsListenerAddedToWindow;
1403 : }
1404 69 : return *this;
1405 : }
1406 :
1407 :
1408 :
1409 :
1410 63 : bool ShellDescriptor::IsMainViewShell (void) const
1411 : {
1412 63 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
1413 63 : if (pViewShell != NULL)
1414 63 : return pViewShell->IsMainViewShell();
1415 : else
1416 0 : return false;
1417 : }
1418 :
1419 :
1420 :
1421 :
1422 264 : ::Window* ShellDescriptor::GetWindow (void) const
1423 : {
1424 264 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
1425 264 : if (pViewShell != NULL)
1426 264 : return pViewShell->GetActiveWindow();
1427 : else
1428 0 : return NULL;
1429 : }
1430 :
1431 :
1432 :
1433 : } // end of anonymous namespace
1434 :
1435 : } // end of namespace sd
1436 :
1437 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|