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