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 <awt/vclxbutton.hxx>
25 #include <tools/debug.hxx>
26 #include <toolkit/awt/vclxwindows.hxx>
27 #include <vcl/button.hxx>
28 
29 #include "dialogbuttonhbox.hxx"
30 #include "flow.hxx"
31 #include "proplist.hxx"
32 
33 #if TEST_LAYOUT && !defined( DBG_UTIL )
34 #undef DBG_ERROR
35 #define DBG_ERROR OSL_TRACE
36 #undef DBG_ERROR1
37 #define DBG_ERROR1 OSL_TRACE
38 #undef DBG_ERROR2
39 #define DBG_ERROR2 OSL_TRACE
40 #endif /* TEST_LAYOUT && !DBG_UTIL */
41 
42 namespace layoutimpl
43 {
44 
45 using namespace css;
46 
47 //FIXME: how to set platform-dependant variables?
48 DialogButtonHBox::Ordering const DialogButtonHBox::DEFAULT_ORDERING =
49 #if defined( MACOSX )
50     DialogButtonHBox::MACOS;
51 #elif defined( SAL_W32 )
52 DialogButtonHBox::WINDOWS;
53 #elif defined( ENABLE_KDE )
54 DialogButtonHBox::KDE;
55 #else /* !MACOSX && !SAL_W32 && !ENABLE_KDE */
56 DialogButtonHBox::GNOME;
57 #endif /* !MACOSX && !SAL_W32 && !ENABLE_KDE */
58 
DialogButtonHBox()59 DialogButtonHBox::DialogButtonHBox()
60     : HBox()
61     , mnOrdering( DEFAULT_ORDERING )
62     , mFlow()
63     , mpAction( 0 )
64     , mpAffirmative( 0 )
65     , mpAlternate( 0 )
66     , mpApply( 0 )
67     , mpCancel( 0 )
68     , mpFlow( createChild( uno::Reference< awt::XLayoutConstrains > ( &mFlow ) ) )
69     , mpHelp( 0 )
70     , mpReset( 0 )
71 {
72     mbHomogeneous = true;
73 }
74 
75 void
setOrdering(rtl::OUString const & ordering)76 DialogButtonHBox::setOrdering( rtl::OUString const& ordering )
77 {
78     if ( ordering.equalsIgnoreAsciiCaseAscii( "GNOME" ) )
79         mnOrdering = GNOME;
80     else if ( ordering.equalsIgnoreAsciiCaseAscii( "KDE" ) )
81         mnOrdering = KDE;
82     else if ( ordering.equalsIgnoreAsciiCaseAscii( "MacOS" ) )
83         mnOrdering = MACOS;
84     else if ( ordering.equalsIgnoreAsciiCaseAscii( "Windows" ) )
85         mnOrdering = WINDOWS;
86     else
87     {
88         DBG_ERROR1( "DialogButtonHBox: no such ordering: %s", OUSTRING_CSTR( ordering ) );
89     }
90 }
91 
92 void
addChild(uno::Reference<awt::XLayoutConstrains> const & xChild)93 DialogButtonHBox::addChild( uno::Reference< awt::XLayoutConstrains > const& xChild )
94     throw ( uno::RuntimeException, awt::MaxChildrenException )
95 {
96     if ( !xChild.is() )
97         return;
98 
99     ChildData *p = createChild( xChild );
100 
101 #define IS_BUTTON(t) dynamic_cast<VCLX##t##Button *>( xChild.get () )
102 
103     /* Sort Retry as Action */
104     if ( !mpAction && IS_BUTTON( Retry ) )
105         mpAction = p;
106     else if ( !mpAffirmative && IS_BUTTON( OK ) )
107         mpAffirmative = p;
108     else if ( !mpAffirmative && IS_BUTTON( Yes ) )
109         mpAffirmative = p;
110     else if ( !mpAlternate && IS_BUTTON( No ) )
111         mpAlternate = p;
112     /* Sort Ignore as Alternate */
113     else if ( !mpAlternate && IS_BUTTON( Ignore ) )
114         mpAlternate = p;
115     else if ( !mpApply && IS_BUTTON( Apply ) )
116         mpApply = p;
117     else if ( !mpCancel && IS_BUTTON( Cancel ) )
118         mpCancel = p;
119     /* Let the user overwrite Flow */
120     else if ( /* !mpFlow && */ dynamic_cast<Flow *>( xChild.get () ) )
121         mpFlow = p;
122     else if ( !mpHelp && IS_BUTTON( Help ) )
123         mpHelp = p;
124     else if ( !mpReset && IS_BUTTON( Reset ) )
125         mpReset = p;
126     else
127         maOther.push_back( p );
128     orderChildren();
129     setChildParent( xChild );
130     queueResize();
131 }
132 
133 void
orderChildren()134 DialogButtonHBox::orderChildren()
135 {
136     if ( mnOrdering == WINDOWS )
137         windowsOrdering();
138     else if ( mnOrdering == MACOS )
139         macosOrdering();
140     else if ( mnOrdering == KDE )
141         kdeOrdering();
142     else if ( 1 || mnOrdering == GNOME )
143         gnomeOrdering();
144 }
145 
146 void SAL_CALL
removeChild(uno::Reference<awt::XLayoutConstrains> const & xChild)147 DialogButtonHBox::removeChild( uno::Reference< awt::XLayoutConstrains > const& xChild )
148     throw ( uno::RuntimeException)
149 {
150     if ( !xChild.is ())
151         return;
152 
153     Box_Base::ChildData *p = 0;
154 
155     if ( mpAction && mpAction->mxChild == xChild )
156         p = mpAction;
157     else if ( mpAffirmative && mpAffirmative->mxChild == xChild )
158         p = mpAffirmative;
159     else if ( mpAlternate && mpAlternate->mxChild == xChild )
160         p = mpAlternate;
161     else if ( mpApply && mpApply->mxChild == xChild )
162         p = mpApply;
163     else if ( mpCancel && mpCancel->mxChild == xChild )
164         p = mpCancel;
165     else if ( mpFlow && mpFlow->mxChild == xChild )
166         p = mpFlow;
167     else if ( mpReset && mpReset->mxChild == xChild )
168         p = mpReset;
169     else if ( mpHelp && mpHelp->mxChild == xChild )
170         p = mpHelp;
171     else
172         p = removeChildData( maOther, xChild );
173 
174     if ( p )
175     {
176         delete p;
177         unsetChildParent( xChild );
178         orderChildren();
179         queueResize();
180     }
181     else
182     {
183         DBG_ERROR( "DialogButtonHBox: removeChild: no such child" );
184     }
185 }
186 
187 void
gnomeOrdering()188 DialogButtonHBox::gnomeOrdering()
189 {
190     std::list< Box_Base::ChildData * > ordered;
191     if ( mpHelp )
192         ordered.push_back( mpHelp );
193     if ( mpReset )
194         ordered.push_back( mpReset );
195     if ( mpFlow && ( mpHelp || mpReset ) )
196         ordered.push_back( mpFlow );
197     ordered.insert( ordered.end(), maOther.begin(), maOther.end() );
198     if ( mpAction )
199         ordered.push_back( mpAction );
200     if ( mpApply )
201         ordered.push_back( mpApply );
202     if ( mpAlternate )
203         ordered.push_back( mpAlternate );
204     if ( mpCancel )
205         ordered.push_back( mpCancel );
206     if ( mpAffirmative )
207         ordered.push_back( mpAffirmative );
208     maChildren = ordered;
209 }
210 
211 void
kdeOrdering()212 DialogButtonHBox::kdeOrdering()
213 {
214     std::list< Box_Base::ChildData * > ordered;
215     if ( mpHelp )
216         ordered.push_back( mpHelp );
217     if ( mpReset )
218         ordered.push_back( mpReset );
219     if ( mpFlow && ( mpHelp || mpReset ) )
220         ordered.push_back( mpFlow );
221     ordered.insert( ordered.end(), maOther.begin(), maOther.end() );
222     if ( mpAction )
223         ordered.push_back( mpAction );
224     if ( mpAffirmative )
225         ordered.push_back( mpAffirmative );
226     if ( mpApply )
227         ordered.push_back( mpApply );
228     if ( mpAlternate )
229         ordered.push_back( mpAlternate );
230     if ( mpCancel )
231         ordered.push_back( mpCancel );
232     maChildren = ordered;
233 }
234 
235 void
macosOrdering()236 DialogButtonHBox::macosOrdering()
237 {
238     std::list< Box_Base::ChildData * > ordered;
239     if ( mpHelp )
240         ordered.push_back( mpHelp );
241     if ( mpReset )
242         ordered.push_back( mpReset );
243     if ( mpApply )
244         ordered.push_back( mpApply );
245     if ( mpAction )
246         ordered.push_back( mpAction );
247     ordered.insert( ordered.end(), maOther.begin(), maOther.end() );
248     if ( mpFlow ) // Always flow? && ( maOther.size () || mpHelp || mpReset || mpAction ) )
249         ordered.push_back( mpFlow );
250     if ( mpAlternate )
251         ordered.push_back( mpAlternate );
252     if ( mpFlow && mpAlternate )
253         ordered.push_back( mpFlow );
254     if ( mpCancel )
255         ordered.push_back( mpCancel );
256     if ( mpAffirmative )
257         ordered.push_back( mpAffirmative );
258     maChildren = ordered;
259 }
260 
261 void
windowsOrdering()262 DialogButtonHBox::windowsOrdering()
263 {
264     std::list< Box_Base::ChildData * > ordered;
265     if ( mpReset )
266         ordered.push_back( mpReset );
267     if ( mpReset && mpFlow )
268         ordered.push_back( mpFlow );
269     if ( mpAffirmative )
270         ordered.push_back( mpAffirmative );
271     if ( mpAlternate )
272         ordered.push_back( mpAlternate );
273     if ( mpAction )
274         ordered.push_back( mpAction );
275     if ( mpCancel )
276         ordered.push_back( mpCancel );
277     if ( mpApply )
278         ordered.push_back( mpApply );
279     ordered.insert( ordered.end(), maOther.begin(), maOther.end() );
280     if ( mpHelp )
281         ordered.push_back( mpHelp );
282     maChildren = ordered;
283 }
284 
285 } // namespace layoutimpl
286