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 0 : 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 0 : IsShell (const SfxShell* pShell) : mpShell(pShell) {}
76 0 : bool operator() (const ShellDescriptor& rDescriptor)
77 0 : { 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 0 : IsId (ShellId nId) : mnId(nId) {}
92 0 : bool operator() (const ShellDescriptor& rDescriptor)
93 0 : { 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 0 : UpdateLock (Implementation& rImpl) : mrImpl(rImpl) {mrImpl.LockUpdate();}
141 0 : ~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 0 : 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 0 : ViewShellManager::ViewShellManager (ViewShellBase& rBase)
249 0 : : mpImpl(new Implementation(*this,rBase)),
250 0 : mbValid(true)
251 : {
252 0 : }
253 :
254 :
255 :
256 :
257 0 : ViewShellManager::~ViewShellManager (void)
258 : {
259 0 : }
260 :
261 :
262 :
263 :
264 0 : void ViewShellManager::AddSubShellFactory (
265 : ViewShell* pViewShell,
266 : const SharedShellFactory& rpFactory)
267 : {
268 0 : if (mbValid)
269 0 : mpImpl->AddShellFactory(pViewShell, rpFactory);
270 0 : }
271 :
272 :
273 :
274 :
275 0 : void ViewShellManager::RemoveSubShellFactory (
276 : ViewShell* pViewShell,
277 : const SharedShellFactory& rpFactory)
278 : {
279 0 : if (mbValid)
280 0 : mpImpl->RemoveShellFactory(pViewShell, rpFactory);
281 0 : }
282 :
283 :
284 :
285 :
286 0 : void ViewShellManager::ActivateViewShell (ViewShell* pViewShell)
287 : {
288 0 : if (mbValid)
289 0 : return mpImpl->ActivateViewShell(pViewShell);
290 : }
291 :
292 :
293 :
294 :
295 0 : void ViewShellManager::DeactivateViewShell (const ViewShell* pShell)
296 : {
297 0 : if (mbValid && pShell!=NULL)
298 0 : mpImpl->DeactivateViewShell(*pShell);
299 0 : }
300 :
301 :
302 :
303 :
304 0 : void ViewShellManager::SetFormShell (
305 : const ViewShell* pParentShell,
306 : FmFormShell* pFormShell,
307 : bool bAbove)
308 : {
309 0 : if (mbValid)
310 0 : mpImpl->SetFormShell(pParentShell,pFormShell,bAbove);
311 0 : }
312 :
313 :
314 :
315 :
316 0 : void ViewShellManager::ActivateSubShell (const ViewShell& rViewShell, ShellId nId)
317 : {
318 0 : if (mbValid)
319 0 : mpImpl->ActivateSubShell(rViewShell,nId);
320 0 : }
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 0 : void ViewShellManager::InvalidateAllSubShells (ViewShell* pViewShell)
335 : {
336 0 : if (mbValid)
337 0 : mpImpl->InvalidateAllSubShells(pViewShell);
338 0 : }
339 :
340 :
341 :
342 :
343 0 : void ViewShellManager::ActivateShell (SfxShell* pShell)
344 : {
345 0 : if (mbValid && pShell!=NULL)
346 0 : mpImpl->ActivateShell(*pShell);
347 0 : }
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 0 : void ViewShellManager::MoveToTop (const ViewShell& rParentShell)
362 : {
363 0 : if (mbValid)
364 0 : mpImpl->MoveToTop(rParentShell);
365 0 : }
366 :
367 :
368 :
369 :
370 0 : SfxShell* ViewShellManager::GetShell (ShellId nId) const
371 : {
372 0 : if (mbValid)
373 0 : 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 0 : void ViewShellManager::Shutdown (void)
393 : {
394 0 : if (mbValid)
395 : {
396 0 : mpImpl->Shutdown();
397 0 : mbValid = false;
398 : }
399 0 : }
400 :
401 :
402 :
403 0 : void ViewShellManager::LockUpdate (void)
404 : {
405 0 : mpImpl->LockUpdate();
406 0 : }
407 :
408 :
409 :
410 :
411 0 : void ViewShellManager::UnlockUpdate (void)
412 : {
413 0 : mpImpl->UnlockUpdate();
414 0 : }
415 :
416 :
417 :
418 :
419 : //===== ViewShellManager::Implementation ======================================
420 :
421 0 : 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 0 : mpTopShell(NULL)
435 : {
436 : (void)rManager;
437 0 : }
438 :
439 :
440 :
441 :
442 0 : ViewShellManager::Implementation::~Implementation (void)
443 : {
444 0 : Shutdown();
445 0 : }
446 :
447 :
448 :
449 :
450 0 : void ViewShellManager::Implementation::AddShellFactory (
451 : const SfxShell* pViewShell,
452 : const SharedShellFactory& rpFactory)
453 : {
454 0 : bool bAlreadyAdded (false);
455 :
456 : // Check that the given factory has not already been added.
457 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
458 0 : maShellFactories.equal_range(pViewShell));
459 0 : for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
460 0 : 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 0 : if ( ! bAlreadyAdded)
468 0 : maShellFactories.insert(FactoryList::value_type(pViewShell, rpFactory));
469 0 : }
470 :
471 :
472 :
473 :
474 0 : void ViewShellManager::Implementation::RemoveShellFactory (
475 : const SfxShell* pViewShell,
476 : const SharedShellFactory& rpFactory)
477 : {
478 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
479 0 : maShellFactories.equal_range(pViewShell));
480 0 : for (FactoryList::iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
481 0 : if (iFactory->second == rpFactory)
482 : {
483 0 : maShellFactories.erase(iFactory);
484 0 : break;
485 : }
486 0 : }
487 :
488 :
489 :
490 :
491 0 : void ViewShellManager::Implementation::ActivateViewShell (ViewShell* pViewShell)
492 : {
493 0 : ::osl::MutexGuard aGuard (maMutex);
494 :
495 0 : ShellDescriptor aResult;
496 0 : 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 0 : if (aResult.mpShell != NULL)
501 : {
502 0 : ::Window* pWindow = aResult.GetWindow();
503 0 : if (pWindow != NULL)
504 : {
505 : pWindow->AddEventListener(
506 0 : LINK(this, ViewShellManager::Implementation, WindowEventHandler));
507 0 : 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 0 : ActivateShell(aResult);
518 0 : }
519 :
520 :
521 :
522 :
523 0 : void ViewShellManager::Implementation::DeactivateViewShell (const ViewShell& rShell)
524 : {
525 0 : ::osl::MutexGuard aGuard (maMutex);
526 :
527 : ActiveShellList::iterator iShell (::std::find_if (
528 : maActiveViewShells.begin(),
529 : maActiveViewShells.end(),
530 0 : IsShell(&rShell)));
531 0 : if (iShell != maActiveViewShells.end())
532 : {
533 0 : UpdateLock aLocker (*this);
534 :
535 0 : ShellDescriptor aDescriptor(*iShell);
536 0 : mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
537 0 : maActiveViewShells.erase(iShell);
538 0 : TakeShellsFromStack(aDescriptor.mpShell);
539 :
540 : // Deactivate sub shells.
541 0 : SubShellList::iterator iList (maActiveSubShells.find(&rShell));
542 0 : if (iList != maActiveSubShells.end())
543 : {
544 0 : SubShellSubList& rList (iList->second);
545 0 : while ( ! rList.empty())
546 0 : DeactivateSubShell(rShell, rList.front().mnId);
547 : }
548 :
549 0 : DestroyViewShell(aDescriptor);
550 0 : }
551 0 : }
552 :
553 :
554 :
555 :
556 0 : void ViewShellManager::Implementation::ActivateShell (SfxShell& rShell)
557 : {
558 0 : ::osl::MutexGuard aGuard (maMutex);
559 :
560 : // Create a new shell or recycle on in the cache.
561 0 : ShellDescriptor aDescriptor;
562 0 : aDescriptor.mpShell = &rShell;
563 :
564 0 : ActivateShell(aDescriptor);
565 0 : }
566 :
567 :
568 :
569 :
570 0 : void ViewShellManager::Implementation::ActivateShell (const ShellDescriptor& rDescriptor)
571 : {
572 : // Put shell on top of the active view shells.
573 0 : 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 0 : ActiveShellList::iterator iInsertPosition (maActiveViewShells.begin());
581 0 : if (iInsertPosition != maActiveViewShells.end()
582 0 : && mbKeepMainViewShellOnTop
583 0 : && ! rDescriptor.IsMainViewShell()
584 0 : && iInsertPosition->IsMainViewShell())
585 : {
586 0 : ++iInsertPosition;
587 : }
588 : maActiveViewShells.insert(
589 : iInsertPosition,
590 0 : rDescriptor);
591 : }
592 0 : }
593 :
594 :
595 :
596 :
597 0 : void ViewShellManager::Implementation::DeactivateShell (const SfxShell& rShell)
598 : {
599 0 : ::osl::MutexGuard aGuard (maMutex);
600 :
601 : ActiveShellList::iterator iShell (::std::find_if (
602 : maActiveViewShells.begin(),
603 : maActiveViewShells.end(),
604 0 : IsShell(&rShell)));
605 0 : if (iShell != maActiveViewShells.end())
606 : {
607 0 : UpdateLock aLocker (*this);
608 :
609 0 : ShellDescriptor aDescriptor(*iShell);
610 0 : mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
611 0 : maActiveViewShells.erase(iShell);
612 0 : TakeShellsFromStack(aDescriptor.mpShell);
613 :
614 : // Deactivate sub shells.
615 0 : SubShellList::iterator iList (maActiveSubShells.find(&rShell));
616 0 : 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 0 : DestroyViewShell(aDescriptor);
624 0 : }
625 0 : }
626 :
627 :
628 :
629 :
630 0 : void ViewShellManager::Implementation::ActivateSubShell (
631 : const SfxShell& rParentShell,
632 : ShellId nId)
633 : {
634 0 : ::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 0 : IsShell(&rParentShell)));
641 0 : if (iShell == maActiveViewShells.end())
642 0 : return;
643 :
644 : // Create the sub shell list if it does not yet exist.
645 0 : SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
646 0 : if (iList == maActiveSubShells.end())
647 : iList = maActiveSubShells.insert(
648 0 : 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 0 : SubShellSubList& rList (iList->second);
653 0 : 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 0 : UpdateLock aLock (*this);
659 0 : rList.push_back(ShellDescriptor(NULL, nId));
660 : }
661 :
662 :
663 :
664 :
665 0 : void ViewShellManager::Implementation::DeactivateSubShell (
666 : const SfxShell& rParentShell,
667 : ShellId nId)
668 : {
669 0 : ::osl::MutexGuard aGuard (maMutex);
670 :
671 : // Check that the given view shell is active.
672 0 : SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
673 0 : if (iList == maActiveSubShells.end())
674 0 : return;
675 :
676 : // Look up the sub shell.
677 0 : SubShellSubList& rList (iList->second);
678 : SubShellSubList::iterator iShell (
679 0 : ::std::find_if(rList.begin(),rList.end(), IsId(nId)));
680 0 : if (iShell == rList.end())
681 0 : return;
682 0 : SfxShell* pShell = iShell->mpShell;
683 0 : if (pShell == NULL)
684 0 : return;
685 :
686 0 : UpdateLock aLock (*this);
687 :
688 0 : 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 0 : rList.erase(iShell);
692 0 : TakeShellsFromStack(pShell);
693 :
694 0 : DestroySubShell(rParentShell, aDescriptor);
695 : }
696 :
697 :
698 :
699 :
700 0 : void ViewShellManager::Implementation::MoveToTop (const SfxShell& rShell)
701 : {
702 0 : ::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 0 : if (mrBase.GetDispatcher() == NULL)
710 0 : return;
711 :
712 : ActiveShellList::iterator iShell (::std::find_if (
713 : maActiveViewShells.begin(),
714 : maActiveViewShells.end(),
715 0 : IsShell(&rShell)));
716 0 : bool bMove = true;
717 0 : 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 0 : if (iShell == maActiveViewShells.begin()
724 0 : && (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 0 : else if (iShell == ++maActiveViewShells.begin()
732 0 : && ! iShell->IsMainViewShell()
733 0 : && 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 0 : if (bMove)
752 : {
753 0 : UpdateLock aLock (*this);
754 :
755 0 : ShellDescriptor aDescriptor(*iShell);
756 :
757 0 : TakeShellsFromStack(&rShell);
758 0 : maActiveViewShells.erase(iShell);
759 :
760 : // Find out whether to insert at the top or one below.
761 0 : ActiveShellList::iterator aInsertPosition (maActiveViewShells.begin());
762 0 : if (mbKeepMainViewShellOnTop && ! aDescriptor.IsMainViewShell())
763 : {
764 0 : if (maActiveViewShells.back().IsMainViewShell())
765 0 : ++aInsertPosition;
766 : }
767 :
768 0 : maActiveViewShells.insert(aInsertPosition, aDescriptor);
769 0 : }
770 : }
771 :
772 :
773 :
774 :
775 0 : SfxShell* ViewShellManager::Implementation::GetShell (ShellId nId) const
776 : {
777 0 : ::osl::MutexGuard aGuard (maMutex);
778 :
779 0 : 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 0 : IsId(nId)));
787 0 : 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 0 : SubShellList::const_iterator iList;
793 0 : for (iList=maActiveSubShells.begin(); iList!=maActiveSubShells.end(); ++iList)
794 : {
795 0 : const SubShellSubList& rList (iList->second);
796 : SubShellSubList::const_iterator iSubShell(
797 0 : ::std::find_if(rList.begin(),rList.end(), IsId(nId)));
798 0 : if (iSubShell != rList.end())
799 : {
800 0 : pShell = iSubShell->mpShell;
801 0 : break;
802 : }
803 : }
804 : }
805 :
806 0 : 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 0 : void ViewShellManager::Implementation::LockUpdate (void)
822 : {
823 0 : mnUpdateLockCount++;
824 0 : }
825 :
826 :
827 :
828 :
829 0 : void ViewShellManager::Implementation::UnlockUpdate (void)
830 : {
831 0 : ::osl::MutexGuard aGuard (maMutex);
832 :
833 0 : mnUpdateLockCount--;
834 0 : if (mnUpdateLockCount < 0)
835 : {
836 : // This should not happen.
837 : OSL_ASSERT (mnUpdateLockCount>=0);
838 0 : mnUpdateLockCount = 0;
839 : }
840 0 : if (mnUpdateLockCount == 0)
841 0 : UpdateShellStack();
842 0 : }
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 0 : void ViewShellManager::Implementation::UpdateShellStack (void)
858 : {
859 0 : ::osl::MutexGuard aGuard (maMutex);
860 :
861 : // Remember the undo manager from the top-most shell on the stack.
862 0 : SfxShell* pTopMostShell = mrBase.GetSubShell(0);
863 : ::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
864 0 : ? pTopMostShell->GetUndoManager()
865 0 : : NULL;
866 :
867 : // 1. Create the missing shells.
868 0 : CreateShells();
869 :
870 :
871 : // 2. Create the internal target stack.
872 0 : ShellStack aTargetStack;
873 0 : CreateTargetStack(aTargetStack);
874 :
875 :
876 : // 3. Get SFX shell stack.
877 0 : ShellStack aSfxShellStack;
878 0 : sal_uInt16 nIndex (0);
879 0 : while (mrBase.GetSubShell(nIndex)!=NULL)
880 0 : ++nIndex;
881 0 : aSfxShellStack.reserve(nIndex);
882 0 : while (nIndex-- > 0)
883 0 : 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 0 : ShellStack::iterator iSfxShell (aSfxShellStack.begin());
896 0 : ShellStack::iterator iTargetShell (aTargetStack.begin());
897 0 : while (iSfxShell != aSfxShellStack.end()
898 0 : && iTargetShell!=aTargetStack.end()
899 0 : && (*iSfxShell)==(*iTargetShell))
900 : {
901 0 : ++iSfxShell;
902 0 : ++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 0 : for (std::reverse_iterator<ShellStack::const_iterator> i(aSfxShellStack.end()), iLast(iSfxShell);
909 : i != iLast; ++i)
910 : {
911 0 : SfxShell* const pShell = *i;
912 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": removing shell " << pShell << " from stack");
913 0 : mrBase.RemoveSubShell(pShell);
914 : }
915 0 : aSfxShellStack.erase(iSfxShell, aSfxShellStack.end());
916 :
917 :
918 : // 6. Push shells from the given stack onto the SFX stack.
919 0 : mbShellStackIsUpToDate = false;
920 0 : while (iTargetShell != aTargetStack.end())
921 : {
922 : SAL_INFO("sd.view", OSL_THIS_FUNC << ": pushing shell " << *iTargetShell << " on stack");
923 0 : mrBase.AddSubShell(**iTargetShell);
924 0 : ++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 0 : if (mbShellStackIsUpToDate)
930 0 : break;
931 : }
932 0 : if (mrBase.GetDispatcher() != NULL)
933 0 : 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 0 : mpTopShell = mrBase.GetSubShell(0);
938 0 : 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 0 : 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 0 : }
950 :
951 :
952 :
953 :
954 0 : void ViewShellManager::Implementation::TakeShellsFromStack (const SfxShell* pShell)
955 : {
956 0 : ::osl::MutexGuard aGuard (maMutex);
957 :
958 : // Remember the undo manager from the top-most shell on the stack.
959 0 : SfxShell* pTopMostShell = mrBase.GetSubShell(0);
960 : ::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
961 0 : ? pTopMostShell->GetUndoManager()
962 0 : : 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 0 : for (sal_uInt16 nIndex=0; true; nIndex++)
972 : {
973 0 : SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
974 0 : 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 0 : else if (pShellOnStack == pShell)
982 0 : break;
983 0 : }
984 :
985 0 : 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 0 : for (sal_uInt16 nIndex=0; true; nIndex++)
990 : {
991 0 : SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
992 0 : Deactivate(pShellOnStack);
993 0 : if (pShellOnStack == pShell)
994 0 : break;
995 0 : }
996 :
997 : // 2. Remove the shells from the stack.
998 : while (true)
999 : {
1000 0 : SfxShell* pShellOnStack = mrBase.GetSubShell(0);
1001 : SAL_INFO("sd.view", OSL_THIS_FUNC << "removing shell " << pShellOnStack << " from stack");
1002 0 : mrBase.RemoveSubShell(pShellOnStack);
1003 0 : if (pShellOnStack == pShell)
1004 0 : break;
1005 : }
1006 :
1007 : // 3. Update the stack.
1008 0 : if (mrBase.GetDispatcher() != NULL)
1009 0 : 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 0 : mpTopShell = mrBase.GetSubShell(0);
1014 0 : if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL)
1015 0 : mpTopShell->SetUndoManager(pUndoManager);
1016 0 : }
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 0 : }
1024 :
1025 :
1026 :
1027 :
1028 0 : void ViewShellManager::Implementation::CreateShells (void)
1029 : {
1030 0 : ::osl::MutexGuard aGuard (maMutex);
1031 :
1032 : // Iterate over all view shells.
1033 0 : ActiveShellList::reverse_iterator iShell;
1034 0 : for (iShell=maActiveViewShells.rbegin(); iShell!=maActiveViewShells.rend(); ++iShell)
1035 : {
1036 : // Get the list of associated sub shells.
1037 0 : SubShellList::iterator iList (maActiveSubShells.find(iShell->mpShell));
1038 0 : if (iList != maActiveSubShells.end())
1039 : {
1040 0 : SubShellSubList& rList (iList->second);
1041 :
1042 : // Iterate over all sub shells of the current view shell.
1043 0 : SubShellSubList::iterator iSubShell;
1044 0 : for (iSubShell=rList.begin(); iSubShell!=rList.end(); ++iSubShell)
1045 : {
1046 0 : if (iSubShell->mpShell == NULL)
1047 : {
1048 0 : *iSubShell = CreateSubShell(iShell->mpShell,iSubShell->mnId,NULL,NULL);
1049 : }
1050 : }
1051 : }
1052 0 : }
1053 0 : }
1054 :
1055 :
1056 :
1057 :
1058 0 : 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 0 : for (ActiveShellList::const_reverse_iterator iViewShell (maActiveViewShells.rbegin());
1064 0 : iViewShell != maActiveViewShells.rend();
1065 : ++iViewShell)
1066 : {
1067 : // Possibly place the form shell below the current view shell.
1068 0 : if ( ! mbFormShellAboveParent
1069 0 : && mpFormShell!=NULL
1070 0 : && iViewShell->mpShell==mpFormShellParent)
1071 : {
1072 0 : rStack.push_back(mpFormShell);
1073 : }
1074 :
1075 : // Put the view shell itself on the local stack.
1076 0 : rStack.push_back (iViewShell->mpShell);
1077 :
1078 : // Possibly place the form shell above the current view shell.
1079 0 : if (mbFormShellAboveParent
1080 0 : && mpFormShell!=NULL
1081 0 : && iViewShell->mpShell==mpFormShellParent)
1082 : {
1083 0 : rStack.push_back(mpFormShell);
1084 : }
1085 :
1086 : // Add all other sub shells.
1087 0 : SubShellList::const_iterator iList (maActiveSubShells.find(iViewShell->mpShell));
1088 0 : if (iList != maActiveSubShells.end())
1089 : {
1090 0 : const SubShellSubList& rList (iList->second);
1091 0 : SubShellSubList::const_reverse_iterator iSubShell;
1092 0 : for (iSubShell=rList.rbegin(); iSubShell!=rList.rend(); ++iSubShell)
1093 0 : if (iSubShell->mpShell != mpFormShell)
1094 0 : rStack.push_back(iSubShell->mpShell);
1095 : }
1096 : }
1097 0 : }
1098 :
1099 :
1100 :
1101 :
1102 0 : IMPL_LINK(ViewShellManager::Implementation, WindowEventHandler, VclWindowEvent*, pEvent)
1103 : {
1104 0 : if (pEvent != NULL)
1105 : {
1106 : ::Window* pEventWindow
1107 0 : = static_cast<VclWindowEvent*>(pEvent)->GetWindow();
1108 :
1109 0 : 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 0 : return sal_True;
1148 : }
1149 :
1150 :
1151 :
1152 :
1153 0 : ShellDescriptor ViewShellManager::Implementation::CreateSubShell (
1154 : SfxShell* pParentShell,
1155 : ShellId nShellId,
1156 : ::Window* pParentWindow,
1157 : FrameView* pFrameView)
1158 : {
1159 0 : ::osl::MutexGuard aGuard (maMutex);
1160 0 : ShellDescriptor aResult;
1161 :
1162 : // Look up the factories for the parent shell.
1163 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
1164 0 : maShellFactories.equal_range(pParentShell));
1165 :
1166 : // Try all factories to create the shell.
1167 0 : for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
1168 : {
1169 0 : SharedShellFactory pFactory = iFactory->second;
1170 0 : if (pFactory != 0)
1171 0 : aResult.mpShell = pFactory->CreateShell(nShellId, pParentWindow, pFrameView);
1172 :
1173 : // Exit the loop when the shell has been successfully created.
1174 0 : if (aResult.mpShell != NULL)
1175 : {
1176 0 : aResult.mpFactory = pFactory;
1177 0 : aResult.mnId = nShellId;
1178 0 : break;
1179 : }
1180 0 : }
1181 :
1182 0 : return aResult;
1183 : }
1184 :
1185 :
1186 :
1187 :
1188 0 : void ViewShellManager::Implementation::DestroyViewShell (
1189 : ShellDescriptor& rDescriptor)
1190 : {
1191 : OSL_ASSERT(rDescriptor.mpShell != NULL);
1192 :
1193 0 : if (rDescriptor.mbIsListenerAddedToWindow)
1194 : {
1195 0 : rDescriptor.mbIsListenerAddedToWindow = false;
1196 0 : ::Window* pWindow = rDescriptor.GetWindow();
1197 0 : if (pWindow != NULL)
1198 : {
1199 : pWindow->RemoveEventListener(
1200 0 : LINK(this, ViewShellManager::Implementation, WindowEventHandler));
1201 : }
1202 : }
1203 :
1204 : // Destroy the sub shell factories.
1205 : ::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
1206 0 : maShellFactories.equal_range(rDescriptor.mpShell));
1207 0 : if (aRange.first != maShellFactories.end())
1208 0 : maShellFactories.erase(aRange.first, aRange.second);
1209 :
1210 : // Release the shell.
1211 0 : if (rDescriptor.mpFactory.get() != NULL)
1212 0 : rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
1213 0 : }
1214 :
1215 :
1216 :
1217 :
1218 0 : void ViewShellManager::Implementation::DestroySubShell (
1219 : const SfxShell& rParentShell,
1220 : const ShellDescriptor& rDescriptor)
1221 : {
1222 : (void)rParentShell;
1223 : OSL_ASSERT(rDescriptor.mpFactory.get() != NULL);
1224 0 : rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
1225 0 : }
1226 :
1227 :
1228 :
1229 :
1230 0 : void ViewShellManager::Implementation::InvalidateAllSubShells (const SfxShell* pParentShell)
1231 : {
1232 0 : ::osl::MutexGuard aGuard (maMutex);
1233 :
1234 0 : SubShellList::iterator iList (maActiveSubShells.find(pParentShell));
1235 0 : if (iList != maActiveSubShells.end())
1236 : {
1237 0 : SubShellSubList& rList (iList->second);
1238 0 : SubShellSubList::iterator iShell;
1239 0 : for (iShell=rList.begin(); iShell!=rList.end(); ++iShell)
1240 0 : if (iShell->mpShell != NULL)
1241 0 : iShell->mpShell->Invalidate();
1242 0 : }
1243 0 : }
1244 :
1245 :
1246 :
1247 :
1248 0 : void ViewShellManager::Implementation::Shutdown (void)
1249 : {
1250 0 : ::osl::MutexGuard aGuard (maMutex);
1251 :
1252 : // Take stacked shells from stack.
1253 0 : if ( ! maActiveViewShells.empty())
1254 : {
1255 0 : UpdateLock aLock (*this);
1256 :
1257 :
1258 0 : while ( ! maActiveViewShells.empty())
1259 : {
1260 0 : SfxShell* pShell = maActiveViewShells.front().mpShell;
1261 0 : if (pShell != NULL)
1262 : {
1263 0 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
1264 0 : if (pViewShell != NULL)
1265 0 : DeactivateViewShell(*pViewShell);
1266 : else
1267 0 : 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 0 : }
1276 : }
1277 0 : mrBase.RemoveSubShell (NULL);
1278 :
1279 0 : maShellFactories.clear();
1280 0 : }
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 0 : 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 0 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
1323 0 : if (pViewShell != NULL)
1324 : {
1325 0 : sd::View* pView = pViewShell->GetView();
1326 0 : 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 0 : pShell->Deactivate(true);
1338 0 : }
1339 :
1340 :
1341 :
1342 :
1343 0 : void ViewShellManager::Implementation::SetFormShell (
1344 : const ViewShell* pFormShellParent,
1345 : FmFormShell* pFormShell,
1346 : bool bFormShellAboveParent)
1347 : {
1348 0 : ::osl::MutexGuard aGuard (maMutex);
1349 :
1350 0 : mpFormShellParent = pFormShellParent;
1351 0 : mpFormShell = pFormShell;
1352 0 : mbFormShellAboveParent = bFormShellAboveParent;
1353 0 : }
1354 :
1355 :
1356 :
1357 :
1358 : namespace {
1359 :
1360 0 : ShellDescriptor::ShellDescriptor (void)
1361 : : mpShell(NULL),
1362 : mnId(0),
1363 : mpFactory(),
1364 0 : mbIsListenerAddedToWindow(false)
1365 : {
1366 0 : }
1367 :
1368 :
1369 :
1370 :
1371 0 : ShellDescriptor::ShellDescriptor (
1372 : SfxShell* pShell,
1373 : ShellId nId)
1374 : : mpShell(pShell),
1375 : mnId(nId),
1376 : mpFactory(),
1377 0 : mbIsListenerAddedToWindow(false)
1378 : {
1379 0 : }
1380 :
1381 :
1382 :
1383 :
1384 0 : ShellDescriptor::ShellDescriptor (const ShellDescriptor& rDescriptor)
1385 : : mpShell(rDescriptor.mpShell),
1386 : mnId(rDescriptor.mnId),
1387 : mpFactory(rDescriptor.mpFactory),
1388 0 : mbIsListenerAddedToWindow(rDescriptor.mbIsListenerAddedToWindow)
1389 : {
1390 0 : }
1391 :
1392 :
1393 :
1394 :
1395 0 : ShellDescriptor& ShellDescriptor::operator= (const ShellDescriptor& rDescriptor)
1396 : {
1397 0 : if (this != &rDescriptor)
1398 : {
1399 0 : mpShell = rDescriptor.mpShell;
1400 0 : mnId = rDescriptor.mnId;
1401 0 : mpFactory = rDescriptor.mpFactory;
1402 0 : mbIsListenerAddedToWindow = rDescriptor.mbIsListenerAddedToWindow;
1403 : }
1404 0 : return *this;
1405 : }
1406 :
1407 :
1408 :
1409 :
1410 0 : bool ShellDescriptor::IsMainViewShell (void) const
1411 : {
1412 0 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
1413 0 : if (pViewShell != NULL)
1414 0 : return pViewShell->IsMainViewShell();
1415 : else
1416 0 : return false;
1417 : }
1418 :
1419 :
1420 :
1421 :
1422 0 : ::Window* ShellDescriptor::GetWindow (void) const
1423 : {
1424 0 : ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
1425 0 : if (pViewShell != NULL)
1426 0 : 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: */
|