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 "import.hxx"
25
26 #include <com/sun/star/awt/XButton.hpp>
27 #include <com/sun/star/awt/XDialog2.hpp>
28 #include <vcl/image.hxx>
29 #include <tools/debug.hxx>
30 #include <layout/layout.hxx>
31
32 #include "root.hxx"
33 #include "helper.hxx"
34 #include "dialogbuttonhbox.hxx"
35
36
37 #define XMLNS_LAYOUT_URI "http://openoffice.org/2007/layout"
38 #define XMLNS_CONTAINER_URI "http://openoffice.org/2007/layout/container"
39
40 namespace layoutimpl
41 {
42 using namespace css;
43
44 using ::rtl::OUString;
45
~ElementBase()46 ElementBase::~ElementBase()
47 SAL_THROW( () )
48 {
49 //delete mpImport;
50 //mpImport = 0;
51 }
52
53 //** parser
WidgetElement(sal_Int32 nUid,const OUString & rName,uno::Reference<xml::input::XAttributes> const & attributes,ElementBase * pParent,ImportContext * pImport)54 WidgetElement::WidgetElement ( sal_Int32 nUid, const OUString &rName,
55 uno::Reference <xml::input::XAttributes> const &attributes,
56 ElementBase *pParent,
57 ImportContext *pImport)
58 SAL_THROW (())
59 : ElementBase( nUid, rName, attributes, pParent, pImport )
60 {
61 OUString name = rName.toAsciiLowerCase();
62
63 PropList aProps;
64 propsFromAttributes( attributes, aProps, pImport->XMLNS_LAYOUT_UID );
65
66 OUString aId;
67 findAndRemove( "id", aProps, aId );
68 OUString aLang;
69 findAndRemove( "xml-lang", aProps, aLang );
70
71 {
72 //DEBUG
73 uno::Reference< awt::XLayoutConstrains > xParent;
74 if ( pParent )
75 xParent = ((WidgetElement *) pParent)->mpWidget->getPeer();
76
77
78 mpWidget = pImport->mrRoot.create( aId, name,
79 getAttributeProps( aProps ), uno::Reference< awt::XLayoutContainer >( xParent, uno::UNO_QUERY ) );
80
81 }
82
83 // TODO: handle with non-existing widgets
84
85 mpWidget->setProperties( aProps );
86
87 uno::Reference< awt::XDialog2 > xDialog( mpWidget->getPeer(), uno::UNO_QUERY );
88 if ( xDialog.is() )
89 {
90 OUString aTitle;
91 if ( findAndRemove( "title", aProps, aTitle ) )
92 {
93 OSL_TRACE("Setting title: %s", OUSTRING_CSTR( aTitle ) );
94 xDialog->setTitle( aTitle );
95 }
96 OUString aHelpId;
97 if ( findAndRemove( "help-id", aProps, aHelpId ) )
98 {
99 OSL_TRACE("Setting help-id: %s", OUSTRING_CSTR( aHelpId ) );
100 xDialog->setHelpId( aHelpId );
101 }
102 } // DEBUG:
103 else if ( pParent == NULL )
104 {
105 DBG_ERROR( "Fatal error: top node isn't a dialog" );
106 }
107
108 OUString aOrdering;
109 if ( findAndRemove( "ordering", aProps, aOrdering ) )
110 if ( DialogButtonHBox *b = dynamic_cast<DialogButtonHBox *> ( mpWidget->getPeer().get() ) )
111 b->setOrdering ( aOrdering );
112
113 bool bSetRadioGroup;
114 OUString aRadioGroup;
115 bSetRadioGroup = findAndRemove( "radiogroup", aProps, aRadioGroup );
116
117 mpWidget->setProperties( aProps );
118
119 // we need to add radio buttons to the group after their properties are
120 // set, so we can check if they should be the one selected by default or not.
121 // And the state changed event isn't fired when changing properties.
122
123 uno::Reference< awt::XRadioButton > xRadio( mpWidget->getPeer(), uno::UNO_QUERY );
124 if ( xRadio.is() )
125 {
126 if (!bSetRadioGroup)
127 aRadioGroup = OUString::createFromAscii ("default");
128 pImport->mxRadioGroups.addItem( aRadioGroup, xRadio );
129 }
130 }
131
~WidgetElement()132 WidgetElement::~WidgetElement()
133 {
134 //delete mpWidget;
135 //mpWidget = 0;
136 }
137
138 uno::Reference <xml::input::XElement>
startChildElement(sal_Int32 nUid,OUString const & name,uno::Reference<xml::input::XAttributes> const & attributes)139 WidgetElement::startChildElement ( sal_Int32 nUid, OUString const &name,
140 uno::Reference <xml::input::XAttributes> const &attributes )
141 throw( xml::sax::SAXException, uno::RuntimeException )
142 {
143 // Adding a child to the widget
144 WidgetElement *pChild = new WidgetElement ( nUid, name, attributes, this, mpImport );
145
146 if ( !mpWidget->addChild( pChild->mpWidget ) )
147 {
148 DBG_ERROR2( "ERROR: cannot add %s to container %s, container full", OUSTRING_CSTR( name ), OUSTRING_CSTR( getLocalName() ) );
149 throw xml::sax::SAXException();
150 }
151
152 PropList aProps;
153 propsFromAttributes( attributes, aProps, mpImport->XMLNS_CONTAINER_UID );
154 mpWidget->setChildProperties( pChild->mpWidget, aProps );
155
156 return pChild;
157 }
158
159 // Support Ivo Hinkelmann's move label/text/title attribute to CONTENT
160 // transex3 hack.
161 void SAL_CALL
characters(OUString const & rChars)162 WidgetElement::characters( OUString const& rChars )
163 throw (xml::sax::SAXException, uno::RuntimeException)
164 {
165 if ( mpWidget && rChars.trim().getLength() )
166 {
167 uno::Reference< awt::XDialog2 > xDialog( mpWidget->getPeer(), uno::UNO_QUERY );
168 uno::Reference< awt::XButton > xButton( mpWidget->getPeer(), uno::UNO_QUERY );
169 if ( xDialog.is() )
170 xDialog->setTitle( rChars );
171 else if ( xButton.is() )
172 mpWidget->setProperty( OUString::createFromAscii( "label" ), rChars );
173 else
174 mpWidget->setProperty( OUString::createFromAscii( "text" ), rChars );
175 }
176 }
177 // ---- ElementBase ----
178
ElementBase(sal_Int32 nUid,OUString const & rLocalName,uno::Reference<xml::input::XAttributes> const & xAttributes,ElementBase * pParent,ImportContext * pImport)179 ElementBase::ElementBase( sal_Int32 nUid, OUString const & rLocalName,
180 uno::Reference< xml::input::XAttributes > const & xAttributes,
181 ElementBase* pParent,
182 ImportContext* pImport )
183 SAL_THROW(())
184 : mpImport( pImport )
185 , mpParent( pParent )
186 , mnUid( nUid )
187 , maLocalName( rLocalName )
188 , mxAttributes( xAttributes )
189 {
190 }
191
192 // ---- ImportContext ----
193
startDocument(uno::Reference<xml::input::XNamespaceMapping> const & xNamespaceMapping)194 void ImportContext::startDocument(
195 uno::Reference< xml::input::XNamespaceMapping > const & xNamespaceMapping )
196 throw (xml::sax::SAXException, uno::RuntimeException)
197 {
198 XMLNS_LAYOUT_UID = xNamespaceMapping->getUidByUri(
199 OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_LAYOUT_URI ) ) );
200 XMLNS_CONTAINER_UID = xNamespaceMapping->getUidByUri(
201 OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_CONTAINER_URI ) ) );
202 }
203
ToplevelElement(OUString const & rName,uno::Reference<xml::input::XAttributes> const & xAttributes,ImportContext * pImport)204 ToplevelElement::ToplevelElement (OUString const &rName,
205 uno::Reference <xml::input::XAttributes> const &xAttributes,
206 ImportContext *pImport)
207 SAL_THROW(())
208 : WidgetElement( 0, rName, xAttributes, NULL, pImport )
209 {
210 }
211
~ToplevelElement()212 ToplevelElement::~ToplevelElement()
213 {
214 }
215
startRootElement(sal_Int32 nUid,OUString const & rLocalName,uno::Reference<xml::input::XAttributes> const & xAttributes)216 uno::Reference< xml::input::XElement > ImportContext::startRootElement(
217 sal_Int32 nUid, OUString const & rLocalName,
218 uno::Reference< xml::input::XAttributes > const & xAttributes )
219 throw (xml::sax::SAXException, uno::RuntimeException)
220 {
221 if ( XMLNS_LAYOUT_UID != nUid )
222 throw xml::sax::SAXException(
223 OUString( RTL_CONSTASCII_USTRINGPARAM( "invalid namespace!" ) ),
224 uno::Reference< uno::XInterface >(), uno::Any() );
225 return new ToplevelElement( rLocalName, xAttributes, this );
226 }
227
RadioGroups()228 RadioGroups::RadioGroups()
229 {
230 }
231
addItem(rtl::OUString id,uno::Reference<awt::XRadioButton> xRadio)232 void RadioGroups::addItem( rtl::OUString id, uno::Reference< awt::XRadioButton > xRadio )
233 throw (uno::RuntimeException)
234 {
235 if ( ! xRadio.is() )
236 throw uno::RuntimeException();
237
238 uno::Reference< RadioGroup > group;
239 RadioGroupsMap::iterator it = mxRadioGroups.find( id );
240 if ( it == mxRadioGroups.end() )
241 {
242 group = uno::Reference< RadioGroup > ( new RadioGroup() );
243 mxRadioGroups [id] = group;
244 }
245 else
246 group = it->second;
247 group->addItem( xRadio );
248 }
249
RadioGroup()250 RadioGroups::RadioGroup::RadioGroup()
251 {
252 }
253
addItem(uno::Reference<awt::XRadioButton> xRadio)254 void RadioGroups::RadioGroup::addItem( uno::Reference< awt::XRadioButton > xRadio )
255 {
256 if ( ! mxSelectedRadio.is() )
257 {
258 xRadio->setState( true );
259 mxSelectedRadio = xRadio;
260 }
261 else if ( xRadio->getState() )
262 {
263 #if 1
264 xRadio->setState( false );
265 #else // huh, why select last added?
266 mxSelectedRadio->setState( false );
267 mxSelectedRadio = xRadio;
268 #endif
269 }
270
271 // TOO late: actionPerformed is called before itemStateChanged.
272 // If client code (wrongly?) uses actionPerformed, it will see
273 // the previous RadioButtons' state.
274 xRadio->addItemListener( this );
275
276 uno::Reference< awt::XButton > xButton = uno::Reference< awt::XButton > ( xRadio, uno::UNO_QUERY );
277 xButton->addActionListener( this );
278
279 mxRadios.push_back (xRadio);
280 }
281
handleSelected()282 void RadioGroups::RadioGroup::handleSelected ()
283 throw (uno::RuntimeException)
284 {
285 for ( RadioButtonsList::iterator it = mxRadios.begin();
286 it != mxRadios.end(); it++ )
287 if ( *it != mxSelectedRadio && (*it)->getState() )
288 {
289 mxSelectedRadio->setState( false );
290 mxSelectedRadio = *it;
291 break;
292 }
293 }
294
295 // awt::XItemListener
itemStateChanged(const awt::ItemEvent & e)296 void RadioGroups::RadioGroup::itemStateChanged( const awt::ItemEvent& e )
297 throw (uno::RuntimeException)
298 {
299 // TOO late: actionPerformed is called before itemStateChanged.
300 // If client code (wrongly?) uses actionPerformed, it will see
301 // the previous RadioButtons' state.
302
303 // Need this for initialization, though.
304 if ( e.Selected )
305 handleSelected ();
306 }
307
308 // awt::XActionListener
actionPerformed(const awt::ActionEvent &)309 void RadioGroups::RadioGroup::actionPerformed( const awt::ActionEvent& )
310 throw (uno::RuntimeException)
311 {
312 handleSelected ();
313 }
314
315 // lang::XEventListener
disposing(const lang::EventObject &)316 void SAL_CALL RadioGroups::RadioGroup::disposing( const lang::EventObject& )
317 throw (uno::RuntimeException)
318 {
319 }
320
321 } // namespace layoutimpl
322