1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
31 #include "taskpane/ControlContainer.hxx"
33 #include "taskpane/TaskPaneTreeNode.hxx"
35 #include <vcl/window.hxx>
36 #include <vcl/svapp.hxx>
38 namespace sd
{ namespace toolpanel
{
41 ControlContainer::ControlContainer (TreeNode
* pNode
)
43 mnActiveControlIndex((sal_uInt32
)-1),
44 mbMultiSelection(false)
51 ControlContainer::~ControlContainer (void)
53 // Set mpNode to NULL so that no one calls it from now on.
61 void ControlContainer::DeleteChildren (void)
63 // Deleting the children may lead to calls back to the container. To
64 // prevent the container from accessing the just deleted children, the
65 // maControlList member is first cleared (by transferring its content to
66 // a local list) before the children are destroyed.
68 maList
.swap(maControlList
);
69 ControlList::iterator I
;
70 ControlList::iterator
Iend (maList
.end());
71 for (I
=maList
.begin(); I
!=Iend
; ++I
)
75 mpNode
->FireStateChangeEvent(EID_ALL_CHILDREN_REMOVED
);
80 sal_uInt32
ControlContainer::AddControl (::std::auto_ptr
<TreeNode
> pControl
)
82 ::osl::MutexGuard
aGuard (maMutex
);
84 pControl
->GetWindow()->Show();
85 sal_uInt32 nIndex
= maControlList
.size();
86 maControlList
.push_back (pControl
.get());
92 mpNode
->FireStateChangeEvent(EID_CHILD_ADDED
, pControl
.get());
100 void ControlContainer::SetExpansionState (
102 ExpansionState aState
)
104 ::osl::MutexGuard
aGuard (maMutex
);
106 bool bResizeNecessary (false);
108 if (mbMultiSelection
)
110 TreeNode
* pControl
= GetControl(nIndex
);
114 bResizeNecessary
= pControl
->Expand( ! pControl
->IsExpanded());
118 bResizeNecessary
= pControl
->Expand(true);
122 bResizeNecessary
= pControl
->Expand(false);
128 // When bExpansionState is true then the control to expand is the
129 // one with the given index. If bExpansionState is false and the
130 // given index points to the active control then then following
131 // control (in cyclic order) it is expanded. When there is only one
132 // control then that is always expanded.
135 // Ignore a call with an invalid index. (The seperate comparison
136 // with -1 is not strictly necessary but it is here just in
138 if (nIndex
>=GetControlCount() || nIndex
==(sal_uInt32
)-1)
146 bExpand
= ! GetControl(nIndex
)->IsExpanded();
159 // Make the specified control the active one and expand it.
160 mnActiveControlIndex
= nIndex
;
164 if (nIndex
== mnActiveControlIndex
)
166 // We have to determine a new active control since the
167 // current one is about to be collapsed. Choose the
168 // previous one for the last and the next one for all
170 if (mnActiveControlIndex
+1 == GetControlCount())
172 = GetPreviousIndex(mnActiveControlIndex
);
175 = GetNextIndex (mnActiveControlIndex
);
179 // Update the expansion state of all controls.
180 for (sal_uInt32 i
=0; i
<GetControlCount(); i
=GetNextIndex(i
))
182 TreeNode
* pControl
= GetControl(i
);
183 bResizeNecessary
|= pControl
->Expand(i
== mnActiveControlIndex
);
189 if (bResizeNecessary
&& mpNode
!= NULL
)
190 mpNode
->RequestResize();
196 void ControlContainer::SetExpansionState (
198 ExpansionState aState
)
200 SetExpansionState (GetControlIndex(pControl
), aState
);
206 sal_uInt32
ControlContainer::GetControlIndex (TreeNode
* pControlToExpand
) const
209 for (nIndex
=0; nIndex
<GetControlCount(); nIndex
++)
211 TreeNode
* pControl
= GetControl(nIndex
);
212 if (pControl
== pControlToExpand
)
221 void ControlContainer::ListHasChanged (void)
228 sal_uInt32
ControlContainer::GetControlCount (void) const
230 return maControlList
.size();
236 sal_uInt32
ControlContainer::GetVisibleControlCount (void) const
238 sal_uInt32
nCount (0);
241 sal_uInt32
nAllCount (maControlList
.size());
242 for (nIndex
=0; nIndex
<nAllCount
; nIndex
=GetNextIndex(nIndex
,true))
244 if (maControlList
[nIndex
]->GetWindow()->IsVisible())
254 TreeNode
* ControlContainer::GetControl (sal_uInt32 nIndex
) const
256 if (nIndex
<maControlList
.size() && nIndex
!=(sal_uInt32
)-1)
257 return maControlList
[nIndex
];
265 sal_uInt32
ControlContainer::GetPreviousIndex (
270 sal_uInt32
nCandidate (nIndex
);
277 // We have reached the head of the list of controls and must
278 // not cycle to its end.
279 nCandidate
= maControlList
.size();
284 // Cycle to the end of the list.
285 nCandidate
= maControlList
.size() - 1;
288 // Go to the regular predecessor.
291 if (nCandidate
== nIndex
)
293 // Made one full loop and found no valid control.
294 nCandidate
= maControlList
.size();
297 else if (bIncludeHidden
)
299 // Return the candidate index regardless of whether the control
303 else if (maControlList
[nCandidate
]->GetWindow()->IsVisible())
305 // Found a visible control.
309 // The candidate does not meet our constraints so do one more loop.
317 sal_uInt32
ControlContainer::GetNextIndex (
322 sal_uInt32
nCandidate (nIndex
);
326 // Go to the regular successor.
328 if (nCandidate
==maControlList
.size())
332 // We have reached the end of the list of controls and must
333 // not cycle to its head.
338 // Cycle to the head of the list.
343 if (nCandidate
== nIndex
)
345 // Made one full loop and found no valid control.
346 nCandidate
= maControlList
.size();
349 else if (bIncludeHidden
)
351 // Return the candidate index regardless of whether the control
355 else if (maControlList
[nCandidate
]->GetWindow()->IsVisible())
357 // Found a visible control.
361 // The candidate does not meet our constraints so do one more loop.
370 void ControlContainer::SetMultiSelection (bool bFlag
)
372 mbMultiSelection
= bFlag
;
378 void ControlContainer::SetVisibilityState (
379 sal_uInt32 nControlIndex
,
380 VisibilityState aState
)
382 TreeNode
* pControl
= GetControl (nControlIndex
);
383 if (pControl
!= NULL
)
390 bShow
= ! pControl
->IsShowing();
400 bool bControlWasExpanded
= pControl
->IsExpanded();
401 if (bShow
!= pControl
->IsShowing())
403 pControl
->Show (bShow
);
407 // If we just turned on the first control then expand it, too.
408 // If we turned on another control collapse it.
409 if (GetVisibleControlCount() == 1)
410 SetExpansionState (nControlIndex
, ES_EXPAND
);
412 SetExpansionState (nControlIndex
, ES_COLLAPSE
);
416 if (GetVisibleControlCount() > 0)
418 if (bControlWasExpanded
)
420 // We turned off an expanded control. Make sure that
421 // one of the still visible ones is expanded.
422 sal_uInt32 nIndex
= GetNextIndex(
426 if (nIndex
== GetControlCount())
427 nIndex
= GetPreviousIndex(
431 SetExpansionState (nIndex
, ES_EXPAND
);
437 mpNode
->RequestResize();
445 } } // end of namespace ::sd::toolpanel