1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "box.hxx"
25 
26 #include <tools/debug.hxx>
27 #include <sal/macros.h>
28 
29 #include <com/sun/star/awt/XWindow2.hpp>
30 
31 // fixed point precision for distributing error
32 #define FIXED_PT 16
33 
34 namespace layoutimpl
35 {
36 
37 using namespace css;
38 
ChildData(uno::Reference<awt::XLayoutConstrains> const & xChild)39 Box_Base::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild )
40     : mxChild( xChild )
41     , mxProps()
42     , maRequisition()
43 {
44 }
45 
isVisible(uno::Reference<awt::XLayoutConstrains> xWidget)46 static bool isVisible( uno::Reference< awt::XLayoutConstrains > xWidget )
47 {
48     if ( !xWidget.is() )
49     {
50         DBG_ERROR( "FIXME: invalid child !" );
51         return true;
52     }
53 
54     uno::Reference< awt::XWindow2 > xWindow( xWidget, uno::UNO_QUERY );
55     if ( xWindow.is() && !xWindow->isVisible() )
56         return false;
57 
58     uno::Reference< awt::XLayoutContainer > xContainer( xWidget, uno::UNO_QUERY );
59     if ( xContainer.is() )
60     {
61         uno::Sequence< uno::Reference< awt::XLayoutConstrains > > aChildren
62             = xContainer->getChildren();
63 
64         if (!aChildren.getLength ())
65             if (Container *c = dynamic_cast <Container*> (xWidget.get ()))
66                 return c->emptyVisible ();
67 
68         for ( int i = 0; i < aChildren.getLength(); i++ )
69             if ( isVisible( aChildren[i] ) )
70                 return true;
71         return false; // this would kill flow without workaround above
72     }
73 
74     return true;
75 }
76 
isVisible()77 bool Box_Base::ChildData::isVisible()
78 {
79     // FIXME: call the 'isVisible' method on it ?
80     return layoutimpl::isVisible( mxChild );
81 }
82 
83 void
AddChild(uno::Reference<awt::XLayoutConstrains> const & xChild)84 Box_Base::AddChild (uno::Reference <awt::XLayoutConstrains> const& xChild)
85 {
86     ChildData *pData = createChild (xChild);
87     maChildren.push_back (pData);
88     queueResize ();
89 }
90 
91 void SAL_CALL
addChild(uno::Reference<awt::XLayoutConstrains> const & xChild)92 Box_Base::addChild (uno::Reference <awt::XLayoutConstrains> const& xChild)
93     throw (uno::RuntimeException, awt::MaxChildrenException)
94 {
95     if (xChild.is ())
96     {
97         AddChild (xChild);
98         setChildParent (xChild);
99     }
100 }
101 
102 Box_Base::ChildData*
removeChildData(std::list<ChildData * > & lst,css::uno::Reference<css::awt::XLayoutConstrains> const & xChild)103 Box_Base::removeChildData( std::list< ChildData* >& lst, css::uno::Reference< css::awt::XLayoutConstrains > const& xChild )
104 {
105     for ( std::list< ChildData* >::iterator it = lst.begin();
106           it != lst.end(); it++ )
107     {
108         if ( (*it)->mxChild == xChild )
109         {
110             ChildData* pRet = *it;
111             lst.erase( it );
112             return pRet;
113         }
114     }
115     return 0;
116 }
117 
118 void SAL_CALL
removeChild(const uno::Reference<awt::XLayoutConstrains> & xChild)119 Box_Base::removeChild( const uno::Reference< awt::XLayoutConstrains >& xChild )
120     throw (uno::RuntimeException)
121 {
122     if ( ChildData* p = removeChildData( maChildren, xChild ) )
123     {
124         delete p;
125         unsetChildParent( xChild );
126         queueResize();
127     }
128     else
129     {
130         DBG_ERROR( "Box_Base: removeChild: no such child" );
131     }
132 }
133 
134 uno::Sequence< uno::Reference < awt::XLayoutConstrains > > SAL_CALL
getChildren()135 Box_Base::getChildren()
136     throw (uno::RuntimeException)
137 {
138     uno::Sequence< uno::Reference< awt::XLayoutConstrains > > children( maChildren.size() );
139     unsigned int index = 0;
140     for ( std::list< ChildData* >::iterator it = maChildren.begin();
141           it != maChildren.end(); it++, index++ )
142         children[index] = ( *it )->mxChild;
143 
144     return children;
145 }
146 
147 uno::Reference< beans::XPropertySet > SAL_CALL
getChildProperties(const uno::Reference<awt::XLayoutConstrains> & xChild)148 Box_Base::getChildProperties( const uno::Reference< awt::XLayoutConstrains >& xChild )
149     throw (uno::RuntimeException)
150 {
151 
152     for ( std::list< ChildData * >::iterator it = maChildren.begin();
153           it != maChildren.end(); it++)
154     {
155         if ( ( *it )->mxChild == xChild )
156         {
157             if ( !( *it )->mxProps.is() )
158             {
159                 PropHelper *pProps = createChildProps( *it );
160                 pProps->setChangeListener( this );
161                 ( *it )->mxProps = pProps;
162             }
163             return (*it)->mxProps;
164         }
165     }
166     return uno::Reference< beans::XPropertySet >();
167 }
168 
169 } // namespace layoutimpl
170