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