1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ControlContainer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "taskpane/ControlContainer.hxx"
36 #include "taskpane/TaskPaneTreeNode.hxx"
38 #include <vcl/window.hxx>
39 #include <vcl/svapp.hxx>
41 namespace sd
{ namespace toolpanel
{
44 ControlContainer::ControlContainer (TreeNode
* pNode
)
46 mnActiveControlIndex((sal_uInt32
)-1),
47 mbMultiSelection(false)
54 ControlContainer::~ControlContainer (void)
56 // Set mpNode to NULL so that no one calls it from now on.
64 void ControlContainer::DeleteChildren (void)
66 // Deleting the children may lead to calls back to the container. To
67 // prevent the container from accessing the just deleted children, the
68 // maControlList member is first cleared (by transferring its content to
69 // a local list) before the children are destroyed.
71 maList
.swap(maControlList
);
72 ControlList::iterator I
;
73 ControlList::iterator
Iend (maList
.end());
74 for (I
=maList
.begin(); I
!=Iend
; ++I
)
78 mpNode
->FireStateChangeEvent(EID_ALL_CHILDREN_REMOVED
);
83 sal_uInt32
ControlContainer::AddControl (::std::auto_ptr
<TreeNode
> pControl
)
85 ::osl::MutexGuard
aGuard (maMutex
);
87 pControl
->GetWindow()->Show();
88 sal_uInt32 nIndex
= maControlList
.size();
89 maControlList
.push_back (pControl
.get());
95 mpNode
->FireStateChangeEvent(EID_CHILD_ADDED
, pControl
.get());
103 void ControlContainer::SetExpansionState (
105 ExpansionState aState
)
107 ::osl::MutexGuard
aGuard (maMutex
);
109 bool bResizeNecessary (false);
111 if (mbMultiSelection
)
113 TreeNode
* pControl
= GetControl(nIndex
);
117 bResizeNecessary
= pControl
->Expand( ! pControl
->IsExpanded());
121 bResizeNecessary
= pControl
->Expand(true);
125 bResizeNecessary
= pControl
->Expand(false);
131 // When bExpansionState is true then the control to expand is the
132 // one with the given index. If bExpansionState is false and the
133 // given index points to the active control then then following
134 // control (in cyclic order) it is expanded. When there is only one
135 // control then that is always expanded.
138 // Ignore a call with an invalid index. (The seperate comparison
139 // with -1 is not strictly necessary but it is here just in
141 if (nIndex
>=GetControlCount() || nIndex
==(sal_uInt32
)-1)
149 bExpand
= ! GetControl(nIndex
)->IsExpanded();
162 // Make the specified control the active one and expand it.
163 mnActiveControlIndex
= nIndex
;
167 if (nIndex
== mnActiveControlIndex
)
169 // We have to determine a new active control since the
170 // current one is about to be collapsed. Choose the
171 // previous one for the last and the next one for all
173 if (mnActiveControlIndex
+1 == GetControlCount())
175 = GetPreviousIndex(mnActiveControlIndex
);
178 = GetNextIndex (mnActiveControlIndex
);
182 // Update the expansion state of all controls.
183 for (UINT32 i
=0; i
<GetControlCount(); i
=GetNextIndex(i
))
185 TreeNode
* pControl
= GetControl(i
);
186 bResizeNecessary
|= pControl
->Expand(i
== mnActiveControlIndex
);
192 if (bResizeNecessary
&& mpNode
!= NULL
)
193 mpNode
->RequestResize();
199 void ControlContainer::SetExpansionState (
201 ExpansionState aState
)
203 SetExpansionState (GetControlIndex(pControl
), aState
);
209 sal_uInt32
ControlContainer::GetControlIndex (TreeNode
* pControlToExpand
) const
212 for (nIndex
=0; nIndex
<GetControlCount(); nIndex
++)
214 TreeNode
* pControl
= GetControl(nIndex
);
215 if (pControl
== pControlToExpand
)
224 sal_uInt32
ControlContainer::GetActiveControlIndex (void) const
226 return mnActiveControlIndex
;
232 void ControlContainer::ListHasChanged (void)
239 sal_uInt32
ControlContainer::GetControlCount (void) const
241 return maControlList
.size();
247 sal_uInt32
ControlContainer::GetVisibleControlCount (void) const
249 sal_uInt32
nCount (0);
252 sal_uInt32
nAllCount (maControlList
.size());
253 for (nIndex
=0; nIndex
<nAllCount
; nIndex
=GetNextIndex(nIndex
,true))
255 if (maControlList
[nIndex
]->GetWindow()->IsVisible())
265 TreeNode
* ControlContainer::GetControl (sal_uInt32 nIndex
) const
267 if (nIndex
<maControlList
.size() && nIndex
!=(sal_uInt32
)-1)
268 return maControlList
[nIndex
];
276 sal_uInt32
ControlContainer::GetPreviousIndex (
281 sal_uInt32
nCandidate (nIndex
);
288 // We have reached the head of the list of controls and must
289 // not cycle to its end.
290 nCandidate
= maControlList
.size();
295 // Cycle to the end of the list.
296 nCandidate
= maControlList
.size() - 1;
299 // Go to the regular predecessor.
302 if (nCandidate
== nIndex
)
304 // Made one full loop and found no valid control.
305 nCandidate
= maControlList
.size();
308 else if (bIncludeHidden
)
310 // Return the candidate index regardless of whether the control
314 else if (maControlList
[nCandidate
]->GetWindow()->IsVisible())
316 // Found a visible control.
320 // The candidate does not meet our constraints so do one more loop.
328 sal_uInt32
ControlContainer::GetNextIndex (
333 sal_uInt32
nCandidate (nIndex
);
337 // Go to the regular successor.
339 if (nCandidate
==maControlList
.size())
343 // We have reached the end of the list of controls and must
344 // not cycle to its head.
349 // Cycle to the head of the list.
354 if (nCandidate
== nIndex
)
356 // Made one full loop and found no valid control.
357 nCandidate
= maControlList
.size();
360 else if (bIncludeHidden
)
362 // Return the candidate index regardless of whether the control
366 else if (maControlList
[nCandidate
]->GetWindow()->IsVisible())
368 // Found a visible control.
372 // The candidate does not meet our constraints so do one more loop.
381 sal_uInt32
ControlContainer::GetFirstIndex (bool bIncludeHidden
)
383 sal_uInt32 nIndex
= 0;
385 if (maControlList
.size() == 0)
387 // The list is empty so there is no first element.
388 nIndex
= maControlList
.size();
390 else if ( ! bIncludeHidden
391 && ! maControlList
[nIndex
]->GetWindow()->IsVisible())
393 // The first element is not visible. Go the next visible one.
394 nIndex
= GetNextIndex (nIndex
, bIncludeHidden
, false);
403 sal_uInt32
ControlContainer::GetLastIndex (bool bIncludeHidden
)
407 if (maControlList
.size() == 0)
409 // The list is empty so there is no last element.
410 nIndex
= maControlList
.size();
414 nIndex
= maControlList
.size() - 1;
415 if ( ! bIncludeHidden
416 && ! maControlList
[nIndex
]->GetWindow()->IsVisible())
418 // The last element is not visible. Go the previous visible one.
419 nIndex
= GetPreviousIndex (nIndex
, bIncludeHidden
, false);
428 void ControlContainer::SetMultiSelection (bool bFlag
)
430 mbMultiSelection
= bFlag
;
436 void ControlContainer::SetVisibilityState (
437 sal_uInt32 nControlIndex
,
438 VisibilityState aState
)
440 TreeNode
* pControl
= GetControl (nControlIndex
);
441 if (pControl
!= NULL
)
448 bShow
= ! pControl
->IsShowing();
458 bool bControlWasExpanded
= pControl
->IsExpanded();
459 if (bShow
!= pControl
->IsShowing())
461 pControl
->Show (bShow
);
465 // If we just turned on the first control then expand it, too.
466 // If we turned on another control collapse it.
467 if (GetVisibleControlCount() == 1)
468 SetExpansionState (nControlIndex
, ES_EXPAND
);
470 SetExpansionState (nControlIndex
, ES_COLLAPSE
);
474 if (GetVisibleControlCount() > 0)
476 if (bControlWasExpanded
)
478 // We turned off an expanded control. Make sure that
479 // one of the still visible ones is expanded.
480 sal_uInt32 nIndex
= GetNextIndex(
484 if (nIndex
== GetControlCount())
485 nIndex
= GetPreviousIndex(
489 SetExpansionState (nIndex
, ES_EXPAND
);
495 mpNode
->RequestResize();
503 } } // end of namespace ::sd::toolpanel