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 {
142 // Adding a child to the widget
143 WidgetElement *pChild = new WidgetElement ( nUid, name, attributes, this, mpImport );
144
145 if ( !mpWidget->addChild( pChild->mpWidget ) )
146 {
147 DBG_ERROR2( "ERROR: cannot add %s to container %s, container full", OUSTRING_CSTR( name ), OUSTRING_CSTR( getLocalName() ) );
148 throw xml::sax::SAXException();
149 }
150
151 PropList aProps;
152 propsFromAttributes( attributes, aProps, mpImport->XMLNS_CONTAINER_UID );
153 mpWidget->setChildProperties( pChild->mpWidget, aProps );
154
155 return pChild;
156 }
157
158 // Support Ivo Hinkelmann's move label/text/title attribute to CONTENT
159 // transex3 hack.
160 void SAL_CALL
characters(OUString const & rChars)161 WidgetElement::characters( OUString const& rChars )
162 {
163 if ( mpWidget && rChars.trim().getLength() )
164 {
165 uno::Reference< awt::XDialog2 > xDialog( mpWidget->getPeer(), uno::UNO_QUERY );
166 uno::Reference< awt::XButton > xButton( mpWidget->getPeer(), uno::UNO_QUERY );
167 if ( xDialog.is() )
168 xDialog->setTitle( rChars );
169 else if ( xButton.is() )
170 mpWidget->setProperty( OUString::createFromAscii( "label" ), rChars );
171 else
172 mpWidget->setProperty( OUString::createFromAscii( "text" ), rChars );
173 }
174 }
175 // ---- ElementBase ----
176
ElementBase(sal_Int32 nUid,OUString const & rLocalName,uno::Reference<xml::input::XAttributes> const & xAttributes,ElementBase * pParent,ImportContext * pImport)177 ElementBase::ElementBase( sal_Int32 nUid, OUString const & rLocalName,
178 uno::Reference< xml::input::XAttributes > const & xAttributes,
179 ElementBase* pParent,
180 ImportContext* pImport )
181 SAL_THROW(())
182 : mpImport( pImport )
183 , mpParent( pParent )
184 , mnUid( nUid )
185 , maLocalName( rLocalName )
186 , mxAttributes( xAttributes )
187 {
188 }
189
190 // ---- ImportContext ----
191
startDocument(uno::Reference<xml::input::XNamespaceMapping> const & xNamespaceMapping)192 void ImportContext::startDocument(
193 uno::Reference< xml::input::XNamespaceMapping > const & xNamespaceMapping )
194 {
195 XMLNS_LAYOUT_UID = xNamespaceMapping->getUidByUri(
196 OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_LAYOUT_URI ) ) );
197 XMLNS_CONTAINER_UID = xNamespaceMapping->getUidByUri(
198 OUString( RTL_CONSTASCII_USTRINGPARAM( XMLNS_CONTAINER_URI ) ) );
199 }
200
ToplevelElement(OUString const & rName,uno::Reference<xml::input::XAttributes> const & xAttributes,ImportContext * pImport)201 ToplevelElement::ToplevelElement (OUString const &rName,
202 uno::Reference <xml::input::XAttributes> const &xAttributes,
203 ImportContext *pImport)
204 SAL_THROW(())
205 : WidgetElement( 0, rName, xAttributes, NULL, pImport )
206 {
207 }
208
~ToplevelElement()209 ToplevelElement::~ToplevelElement()
210 {
211 }
212
startRootElement(sal_Int32 nUid,OUString const & rLocalName,uno::Reference<xml::input::XAttributes> const & xAttributes)213 uno::Reference< xml::input::XElement > ImportContext::startRootElement(
214 sal_Int32 nUid, OUString const & rLocalName,
215 uno::Reference< xml::input::XAttributes > const & xAttributes )
216 {
217 if ( XMLNS_LAYOUT_UID != nUid )
218 throw xml::sax::SAXException(
219 OUString( RTL_CONSTASCII_USTRINGPARAM( "invalid namespace!" ) ),
220 uno::Reference< uno::XInterface >(), uno::Any() );
221 return new ToplevelElement( rLocalName, xAttributes, this );
222 }
223
RadioGroups()224 RadioGroups::RadioGroups()
225 {
226 }
227
addItem(rtl::OUString id,uno::Reference<awt::XRadioButton> xRadio)228 void RadioGroups::addItem( rtl::OUString id, uno::Reference< awt::XRadioButton > xRadio )
229 {
230 if ( ! xRadio.is() )
231 throw uno::RuntimeException();
232
233 uno::Reference< RadioGroup > group;
234 RadioGroupsMap::iterator it = mxRadioGroups.find( id );
235 if ( it == mxRadioGroups.end() )
236 {
237 group = uno::Reference< RadioGroup > ( new RadioGroup() );
238 mxRadioGroups [id] = group;
239 }
240 else
241 group = it->second;
242 group->addItem( xRadio );
243 }
244
RadioGroup()245 RadioGroups::RadioGroup::RadioGroup()
246 {
247 }
248
addItem(uno::Reference<awt::XRadioButton> xRadio)249 void RadioGroups::RadioGroup::addItem( uno::Reference< awt::XRadioButton > xRadio )
250 {
251 if ( ! mxSelectedRadio.is() )
252 {
253 xRadio->setState( true );
254 mxSelectedRadio = xRadio;
255 }
256 else if ( xRadio->getState() )
257 {
258 #if 1
259 xRadio->setState( false );
260 #else // huh, why select last added?
261 mxSelectedRadio->setState( false );
262 mxSelectedRadio = xRadio;
263 #endif
264 }
265
266 // TOO late: actionPerformed is called before itemStateChanged.
267 // If client code (wrongly?) uses actionPerformed, it will see
268 // the previous RadioButtons' state.
269 xRadio->addItemListener( this );
270
271 uno::Reference< awt::XButton > xButton = uno::Reference< awt::XButton > ( xRadio, uno::UNO_QUERY );
272 xButton->addActionListener( this );
273
274 mxRadios.push_back (xRadio);
275 }
276
handleSelected()277 void RadioGroups::RadioGroup::handleSelected ()
278 {
279 for ( RadioButtonsList::iterator it = mxRadios.begin();
280 it != mxRadios.end(); it++ )
281 if ( *it != mxSelectedRadio && (*it)->getState() )
282 {
283 mxSelectedRadio->setState( false );
284 mxSelectedRadio = *it;
285 break;
286 }
287 }
288
289 // awt::XItemListener
itemStateChanged(const awt::ItemEvent & e)290 void RadioGroups::RadioGroup::itemStateChanged( const awt::ItemEvent& e )
291 {
292 // TOO late: actionPerformed is called before itemStateChanged.
293 // If client code (wrongly?) uses actionPerformed, it will see
294 // the previous RadioButtons' state.
295
296 // Need this for initialization, though.
297 if ( e.Selected )
298 handleSelected ();
299 }
300
301 // awt::XActionListener
actionPerformed(const awt::ActionEvent &)302 void RadioGroups::RadioGroup::actionPerformed( const awt::ActionEvent& )
303 {
304 handleSelected ();
305 }
306
307 // lang::XEventListener
disposing(const lang::EventObject &)308 void SAL_CALL RadioGroups::RadioGroup::disposing( const lang::EventObject& )
309 {
310 }
311
312 } // namespace layoutimpl
313