xref: /trunk/main/toolkit/source/layout/core/import.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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