1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "taskpane/ControlContainer.hxx"
23 #include "taskpane/TaskPaneTreeNode.hxx"
25 #include <vcl/window.hxx>
26 #include <vcl/svapp.hxx>
28 namespace sd
{ namespace toolpanel
{
31 ControlContainer::ControlContainer (TreeNode
* pNode
)
33 mnActiveControlIndex((sal_uInt32
)-1),
34 mbMultiSelection(false)
41 ControlContainer::~ControlContainer (void)
43 // Set mpNode to NULL so that no one calls it from now on.
51 void ControlContainer::DeleteChildren (void)
53 // Deleting the children may lead to calls back to the container. To
54 // prevent the container from accessing the just deleted children, the
55 // maControlList member is first cleared (by transferring its content to
56 // a local list) before the children are destroyed.
58 maList
.swap(maControlList
);
59 ControlList::iterator I
;
60 ControlList::iterator
Iend (maList
.end());
61 for (I
=maList
.begin(); I
!=Iend
; ++I
)
65 mpNode
->FireStateChangeEvent(EID_ALL_CHILDREN_REMOVED
);
70 sal_uInt32
ControlContainer::AddControl (::std::auto_ptr
<TreeNode
> pControl
)
72 ::osl::MutexGuard
aGuard (maMutex
);
74 pControl
->GetWindow()->Show();
75 sal_uInt32 nIndex
= maControlList
.size();
76 maControlList
.push_back (pControl
.get());
82 mpNode
->FireStateChangeEvent(EID_CHILD_ADDED
, pControl
.get());
90 void ControlContainer::SetExpansionState (
92 ExpansionState aState
)
94 ::osl::MutexGuard
aGuard (maMutex
);
96 bool bResizeNecessary (false);
100 TreeNode
* pControl
= GetControl(nIndex
);
104 bResizeNecessary
= pControl
->Expand( ! pControl
->IsExpanded());
108 bResizeNecessary
= pControl
->Expand(true);
112 bResizeNecessary
= pControl
->Expand(false);
118 // When bExpansionState is true then the control to expand is the
119 // one with the given index. If bExpansionState is false and the
120 // given index points to the active control then then following
121 // control (in cyclic order) it is expanded. When there is only one
122 // control then that is always expanded.
125 // Ignore a call with an invalid index. (The separate comparison
126 // with -1 is not strictly necessary but it is here just in
128 if (nIndex
>=GetControlCount() || nIndex
==(sal_uInt32
)-1)
136 bExpand
= ! GetControl(nIndex
)->IsExpanded();
149 // Make the specified control the active one and expand it.
150 mnActiveControlIndex
= nIndex
;
154 if (nIndex
== mnActiveControlIndex
)
156 // We have to determine a new active control since the
157 // current one is about to be collapsed. Choose the
158 // previous one for the last and the next one for all
160 if (mnActiveControlIndex
+1 == GetControlCount())
162 = GetPreviousIndex(mnActiveControlIndex
);
165 = GetNextIndex (mnActiveControlIndex
);
169 // Update the expansion state of all controls.
170 for (sal_uInt32 i
=0; i
<GetControlCount(); i
=GetNextIndex(i
))
172 TreeNode
* pControl
= GetControl(i
);
173 bResizeNecessary
|= pControl
->Expand(i
== mnActiveControlIndex
);
179 if (bResizeNecessary
&& mpNode
!= NULL
)
180 mpNode
->RequestResize();
186 void ControlContainer::SetExpansionState (
188 ExpansionState aState
)
190 SetExpansionState (GetControlIndex(pControl
), aState
);
196 sal_uInt32
ControlContainer::GetControlIndex (TreeNode
* pControlToExpand
) const
199 for (nIndex
=0; nIndex
<GetControlCount(); nIndex
++)
201 TreeNode
* pControl
= GetControl(nIndex
);
202 if (pControl
== pControlToExpand
)
211 void ControlContainer::ListHasChanged (void)
218 sal_uInt32
ControlContainer::GetControlCount (void) const
220 return maControlList
.size();
226 sal_uInt32
ControlContainer::GetVisibleControlCount (void) const
228 sal_uInt32
nCount (0);
231 sal_uInt32
nAllCount (maControlList
.size());
232 for (nIndex
=0; nIndex
<nAllCount
; nIndex
=GetNextIndex(nIndex
,true))
234 if (maControlList
[nIndex
]->GetWindow()->IsVisible())
244 TreeNode
* ControlContainer::GetControl (sal_uInt32 nIndex
) const
246 if (nIndex
<maControlList
.size() && nIndex
!=(sal_uInt32
)-1)
247 return maControlList
[nIndex
];
255 sal_uInt32
ControlContainer::GetPreviousIndex (
260 sal_uInt32
nCandidate (nIndex
);
267 // We have reached the head of the list of controls and must
268 // not cycle to its end.
269 nCandidate
= maControlList
.size();
274 // Cycle to the end of the list.
275 nCandidate
= maControlList
.size() - 1;
278 // Go to the regular predecessor.
281 if (nCandidate
== nIndex
)
283 // Made one full loop and found no valid control.
284 nCandidate
= maControlList
.size();
287 else if (bIncludeHidden
)
289 // Return the candidate index regardless of whether the control
293 else if (maControlList
[nCandidate
]->GetWindow()->IsVisible())
295 // Found a visible control.
299 // The candidate does not meet our constraints so do one more loop.
307 sal_uInt32
ControlContainer::GetNextIndex (
312 sal_uInt32
nCandidate (nIndex
);
316 // Go to the regular successor.
318 if (nCandidate
==maControlList
.size())
322 // We have reached the end of the list of controls and must
323 // not cycle to its head.
328 // Cycle to the head of the list.
333 if (nCandidate
== nIndex
)
335 // Made one full loop and found no valid control.
336 nCandidate
= maControlList
.size();
339 else if (bIncludeHidden
)
341 // Return the candidate index regardless of whether the control
345 else if (maControlList
[nCandidate
]->GetWindow()->IsVisible())
347 // Found a visible control.
351 // The candidate does not meet our constraints so do one more loop.
360 void ControlContainer::SetMultiSelection (bool bFlag
)
362 mbMultiSelection
= bFlag
;
368 void ControlContainer::SetVisibilityState (
369 sal_uInt32 nControlIndex
,
370 VisibilityState aState
)
372 TreeNode
* pControl
= GetControl (nControlIndex
);
373 if (pControl
!= NULL
)
380 bShow
= ! pControl
->IsShowing();
390 bool bControlWasExpanded
= pControl
->IsExpanded();
391 if (bShow
!= pControl
->IsShowing())
393 pControl
->Show (bShow
);
397 // If we just turned on the first control then expand it, too.
398 // If we turned on another control collapse it.
399 if (GetVisibleControlCount() == 1)
400 SetExpansionState (nControlIndex
, ES_EXPAND
);
402 SetExpansionState (nControlIndex
, ES_COLLAPSE
);
406 if (GetVisibleControlCount() > 0)
408 if (bControlWasExpanded
)
410 // We turned off an expanded control. Make sure that
411 // one of the still visible ones is expanded.
412 sal_uInt32 nIndex
= GetNextIndex(
416 if (nIndex
== GetControlCount())
417 nIndex
= GetPreviousIndex(
421 SetExpansionState (nIndex
, ES_EXPAND
);
427 mpNode
->RequestResize();
435 } } // end of namespace ::sd::toolpanel
437 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */