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