xref: /trunk/main/starmath/source/mathmlexport.cxx (revision d107581f)
1*d107581fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*d107581fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*d107581fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*d107581fSAndrew Rist  * distributed with this work for additional information
6*d107581fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*d107581fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*d107581fSAndrew Rist  * "License"); you may not use this file except in compliance
9*d107581fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*d107581fSAndrew Rist  *
11*d107581fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*d107581fSAndrew Rist  *
13*d107581fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*d107581fSAndrew Rist  * software distributed under the License is distributed on an
15*d107581fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*d107581fSAndrew Rist  * KIND, either express or implied.  See the License for the
17*d107581fSAndrew Rist  * specific language governing permissions and limitations
18*d107581fSAndrew Rist  * under the License.
19*d107581fSAndrew Rist  *
20*d107581fSAndrew Rist  *************************************************************/
21*d107581fSAndrew Rist 
22*d107581fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_starmath.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir /*
28cdf0e10cSrcweir  Warning: The SvXMLElementExport helper class creates the beginning and
29cdf0e10cSrcweir  closing tags of xml elements in its constructor and destructor, so theres
30cdf0e10cSrcweir  hidden stuff going on, on occasion the ordering of these classes declarations
31cdf0e10cSrcweir  may be significant
32cdf0e10cSrcweir */
33cdf0e10cSrcweir 
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <com/sun/star/xml/sax/XErrorHandler.hpp>
36cdf0e10cSrcweir #include <com/sun/star/xml/sax/XEntityResolver.hpp>
37cdf0e10cSrcweir #include <com/sun/star/xml/sax/InputSource.hpp>
38cdf0e10cSrcweir #include <com/sun/star/xml/sax/XDTDHandler.hpp>
39cdf0e10cSrcweir #include <com/sun/star/xml/sax/XParser.hpp>
40cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataSource.hpp>
41cdf0e10cSrcweir #include <com/sun/star/io/XActiveDataControl.hpp>
42cdf0e10cSrcweir #include <com/sun/star/document/XDocumentProperties.hpp>
43cdf0e10cSrcweir #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
44cdf0e10cSrcweir #include <com/sun/star/packages/zip/ZipIOException.hpp>
45cdf0e10cSrcweir #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
46cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
47cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
48cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp>
49cdf0e10cSrcweir #include <com/sun/star/uno/Any.h>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #include <rtl/math.hxx>
52cdf0e10cSrcweir #include <sfx2/frame.hxx>
53cdf0e10cSrcweir #include <sfx2/docfile.hxx>
54cdf0e10cSrcweir #include <tools/debug.hxx>
55cdf0e10cSrcweir #include <tools/urlobj.hxx>
56cdf0e10cSrcweir #include <svtools/sfxecode.hxx>
57cdf0e10cSrcweir #include <unotools/saveopt.hxx>
58cdf0e10cSrcweir #include <svl/stritem.hxx>
59cdf0e10cSrcweir #include <svl/itemprop.hxx>
60cdf0e10cSrcweir #include <unotools/processfactory.hxx>
61cdf0e10cSrcweir #include <unotools/streamwrap.hxx>
62cdf0e10cSrcweir #include <xmloff/xmlnmspe.hxx>
63cdf0e10cSrcweir #include <xmloff/xmltoken.hxx>
64cdf0e10cSrcweir #include <xmloff/nmspmap.hxx>
65cdf0e10cSrcweir #include <xmloff/attrlist.hxx>
66cdf0e10cSrcweir #include <xmloff/xmluconv.hxx>
67cdf0e10cSrcweir #include <xmloff/xmlmetai.hxx>
68cdf0e10cSrcweir #include <osl/mutex.hxx>
69cdf0e10cSrcweir #include <comphelper/genericpropertyset.hxx>
70cdf0e10cSrcweir 
71cdf0e10cSrcweir #include <memory>
72cdf0e10cSrcweir 
73cdf0e10cSrcweir #include "mathmlexport.hxx"
74cdf0e10cSrcweir #include <starmath.hrc>
75cdf0e10cSrcweir #include <unomodel.hxx>
76cdf0e10cSrcweir #include <document.hxx>
77cdf0e10cSrcweir #include <utility.hxx>
78cdf0e10cSrcweir #include <config.hxx>
79cdf0e10cSrcweir 
80cdf0e10cSrcweir using namespace ::com::sun::star::beans;
81cdf0e10cSrcweir using namespace ::com::sun::star::container;
82cdf0e10cSrcweir using namespace ::com::sun::star::document;
83cdf0e10cSrcweir using namespace ::com::sun::star::lang;
84cdf0e10cSrcweir using namespace ::com::sun::star::uno;
85cdf0e10cSrcweir using namespace ::com::sun::star;
86cdf0e10cSrcweir using namespace ::xmloff::token;
87cdf0e10cSrcweir 
88cdf0e10cSrcweir using ::rtl::OUString;
89cdf0e10cSrcweir using ::rtl::OUStringBuffer;
90cdf0e10cSrcweir 
91cdf0e10cSrcweir #define EXPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLExportFilter")
92cdf0e10cSrcweir 
93cdf0e10cSrcweir #undef WANTEXCEPT
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 
96cdf0e10cSrcweir ////////////////////////////////////////////////////////////
97cdf0e10cSrcweir 
98cdf0e10cSrcweir sal_Bool SmXMLExportWrapper::Export(SfxMedium &rMedium)
99cdf0e10cSrcweir {
100cdf0e10cSrcweir     sal_Bool bRet=sal_True;
101cdf0e10cSrcweir     uno::Reference<lang::XMultiServiceFactory>
102cdf0e10cSrcweir         xServiceFactory(utl::getProcessServiceFactory());
103cdf0e10cSrcweir     DBG_ASSERT(xServiceFactory.is(),"got no service manager");
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     //Get model
106cdf0e10cSrcweir     uno::Reference< lang::XComponent > xModelComp(xModel, uno::UNO_QUERY );
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     sal_Bool bEmbedded = sal_False;
109cdf0e10cSrcweir     uno::Reference <lang::XUnoTunnel> xTunnel;
110cdf0e10cSrcweir     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
111cdf0e10cSrcweir     SmModel *pModel = reinterpret_cast<SmModel *>
112cdf0e10cSrcweir         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
113cdf0e10cSrcweir 
114cdf0e10cSrcweir     SmDocShell *pDocShell = pModel ?
115cdf0e10cSrcweir             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
116cdf0e10cSrcweir     if ( pDocShell &&
117cdf0e10cSrcweir         SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
118cdf0e10cSrcweir         bEmbedded = sal_True;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     uno::Reference<task::XStatusIndicator> xStatusIndicator;
121cdf0e10cSrcweir     if (!bEmbedded)
122cdf0e10cSrcweir     {
123cdf0e10cSrcweir         if (pDocShell /*&& pDocShell->GetMedium()*/)
124cdf0e10cSrcweir         {
125cdf0e10cSrcweir             DBG_ASSERT( pDocShell->GetMedium() == &rMedium,
126cdf0e10cSrcweir                     "different SfxMedium found" );
127cdf0e10cSrcweir 
128cdf0e10cSrcweir             SfxItemSet* pSet = rMedium.GetItemSet();
129cdf0e10cSrcweir             if (pSet)
130cdf0e10cSrcweir             {
131cdf0e10cSrcweir                 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
132cdf0e10cSrcweir                     pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
133cdf0e10cSrcweir                 if (pItem)
134cdf0e10cSrcweir                     pItem->GetValue() >>= xStatusIndicator;
135cdf0e10cSrcweir             }
136cdf0e10cSrcweir         }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir         // set progress range and start status indicator
139cdf0e10cSrcweir         if (xStatusIndicator.is())
140cdf0e10cSrcweir         {
141cdf0e10cSrcweir             sal_Int32 nProgressRange = bFlat ? 1 : 3;
142cdf0e10cSrcweir             xStatusIndicator->start(String(SmResId(STR_STATSTR_WRITING)),
143cdf0e10cSrcweir                 nProgressRange);
144cdf0e10cSrcweir         }
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir 
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     // create XPropertySet with three properties for status indicator
149cdf0e10cSrcweir     comphelper::PropertyMapEntry aInfoMap[] =
150cdf0e10cSrcweir     {
151cdf0e10cSrcweir         { "UsePrettyPrinting", sizeof("UsePrettyPrinting")-1, 0,
152cdf0e10cSrcweir               &::getBooleanCppuType(),
153cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0},
154cdf0e10cSrcweir         { "BaseURI", sizeof("BaseURI")-1, 0,
155cdf0e10cSrcweir               &::getCppuType( (OUString *)0 ),
156cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0 },
157cdf0e10cSrcweir         { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
158cdf0e10cSrcweir               &::getCppuType( (OUString *)0 ),
159cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0 },
160cdf0e10cSrcweir         { "StreamName", sizeof("StreamName")-1, 0,
161cdf0e10cSrcweir               &::getCppuType( (OUString *)0 ),
162cdf0e10cSrcweir               beans::PropertyAttribute::MAYBEVOID, 0 },
163cdf0e10cSrcweir         { NULL, 0, 0, NULL, 0, 0 }
164cdf0e10cSrcweir     };
165cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xInfoSet(
166cdf0e10cSrcweir                 comphelper::GenericPropertySet_CreateInstance(
167cdf0e10cSrcweir                             new comphelper::PropertySetInfo( aInfoMap ) ) );
168cdf0e10cSrcweir 
169cdf0e10cSrcweir     SvtSaveOptions aSaveOpt;
170cdf0e10cSrcweir     OUString sUsePrettyPrinting(RTL_CONSTASCII_USTRINGPARAM("UsePrettyPrinting"));
171cdf0e10cSrcweir     sal_Bool bUsePrettyPrinting( bFlat || aSaveOpt.IsPrettyPrinting() );
172cdf0e10cSrcweir     Any aAny;
173cdf0e10cSrcweir     aAny.setValue( &bUsePrettyPrinting, ::getBooleanCppuType() );
174cdf0e10cSrcweir     xInfoSet->setPropertyValue( sUsePrettyPrinting, aAny );
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     // Set base URI
177cdf0e10cSrcweir     OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
178cdf0e10cSrcweir     xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL( true ) ) );
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     sal_Int32 nSteps=0;
181cdf0e10cSrcweir     if (xStatusIndicator.is())
182cdf0e10cSrcweir             xStatusIndicator->setValue(nSteps++);
183cdf0e10cSrcweir     if (!bFlat) //Storage (Package) of Stream
184cdf0e10cSrcweir     {
185cdf0e10cSrcweir         uno::Reference < embed::XStorage > xStg = rMedium.GetOutputStorage();
186cdf0e10cSrcweir         sal_Bool bOASIS = ( SotStorage::GetVersion( xStg ) > SOFFICE_FILEFORMAT_60 );
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         // TODO/LATER: handle the case of embedded links gracefully
189cdf0e10cSrcweir         if ( bEmbedded ) //&& !pStg->IsRoot() )
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir             OUString aName;
192cdf0e10cSrcweir             if ( rMedium.GetItemSet() )
193cdf0e10cSrcweir             {
194cdf0e10cSrcweir                 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
195cdf0e10cSrcweir                     rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
196cdf0e10cSrcweir                 if ( pDocHierarchItem )
197cdf0e10cSrcweir                     aName = pDocHierarchItem->GetValue();
198cdf0e10cSrcweir             }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir             if ( aName.getLength() )
201cdf0e10cSrcweir             {
202cdf0e10cSrcweir                 sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
203cdf0e10cSrcweir                 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
204cdf0e10cSrcweir             }
205cdf0e10cSrcweir         }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir         if ( !bEmbedded )
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir             if (xStatusIndicator.is())
210cdf0e10cSrcweir                 xStatusIndicator->setValue(nSteps++);
211cdf0e10cSrcweir 
212cdf0e10cSrcweir             bRet = WriteThroughComponent(
213cdf0e10cSrcweir                     xStg, xModelComp, "meta.xml", xServiceFactory, xInfoSet,
214cdf0e10cSrcweir                     (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaExporter"
215cdf0e10cSrcweir                             : "com.sun.star.comp.Math.XMLMetaExporter"),
216cdf0e10cSrcweir                     sal_False);
217cdf0e10cSrcweir         }
218cdf0e10cSrcweir         if ( bRet )
219cdf0e10cSrcweir         {
220cdf0e10cSrcweir            if (xStatusIndicator.is())
221cdf0e10cSrcweir                 xStatusIndicator->setValue(nSteps++);
222cdf0e10cSrcweir 
223cdf0e10cSrcweir             bRet = WriteThroughComponent(
224cdf0e10cSrcweir                     xStg, xModelComp, "content.xml", xServiceFactory, xInfoSet,
225cdf0e10cSrcweir                     "com.sun.star.comp.Math.XMLContentExporter");
226cdf0e10cSrcweir         }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir         if ( bRet )
229cdf0e10cSrcweir         {
230cdf0e10cSrcweir             if (xStatusIndicator.is())
231cdf0e10cSrcweir                 xStatusIndicator->setValue(nSteps++);
232cdf0e10cSrcweir 
233cdf0e10cSrcweir             bRet = WriteThroughComponent(
234cdf0e10cSrcweir                     xStg, xModelComp, "settings.xml", xServiceFactory, xInfoSet,
235cdf0e10cSrcweir                     (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsExporter"
236cdf0e10cSrcweir                             : "com.sun.star.comp.Math.XMLSettingsExporter") );
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir     else
240cdf0e10cSrcweir     {
241cdf0e10cSrcweir         SvStream *pStream = rMedium.GetOutStream();
242cdf0e10cSrcweir         uno::Reference<io::XOutputStream> xOut(
243cdf0e10cSrcweir             new utl::OOutputStreamWrapper(*pStream) );
244cdf0e10cSrcweir 
245cdf0e10cSrcweir         if (xStatusIndicator.is())
246cdf0e10cSrcweir             xStatusIndicator->setValue(nSteps++);
247cdf0e10cSrcweir 
248cdf0e10cSrcweir         bRet = WriteThroughComponent(
249cdf0e10cSrcweir             xOut, xModelComp, xServiceFactory, xInfoSet,
250cdf0e10cSrcweir             "com.sun.star.comp.Math.XMLContentExporter");
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir 
253cdf0e10cSrcweir     if (xStatusIndicator.is())
254cdf0e10cSrcweir         xStatusIndicator->end();
255cdf0e10cSrcweir 
256cdf0e10cSrcweir     return bRet;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir 
260cdf0e10cSrcweir /// export through an XML exporter component (output stream version)
261cdf0e10cSrcweir sal_Bool SmXMLExportWrapper::WriteThroughComponent(
262cdf0e10cSrcweir     Reference<io::XOutputStream> xOutputStream,
263cdf0e10cSrcweir     Reference<XComponent> xComponent,
264cdf0e10cSrcweir     Reference<lang::XMultiServiceFactory> & rFactory,
265cdf0e10cSrcweir     Reference<beans::XPropertySet> & rPropSet,
266cdf0e10cSrcweir     const sal_Char* pComponentName )
267cdf0e10cSrcweir {
268cdf0e10cSrcweir     DBG_ASSERT(xOutputStream.is(), "I really need an output stream!");
269cdf0e10cSrcweir     DBG_ASSERT(xComponent.is(), "Need component!");
270cdf0e10cSrcweir     DBG_ASSERT(NULL != pComponentName, "Need component name!");
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     // get component
273cdf0e10cSrcweir     Reference< io::XActiveDataSource > xSaxWriter(
274cdf0e10cSrcweir         rFactory->createInstance(
275cdf0e10cSrcweir             OUString::createFromAscii("com.sun.star.xml.sax.Writer") ),
276cdf0e10cSrcweir         UNO_QUERY );
277cdf0e10cSrcweir     DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
278cdf0e10cSrcweir     if (!xSaxWriter.is())
279cdf0e10cSrcweir         return sal_False;
280cdf0e10cSrcweir 
281cdf0e10cSrcweir     // connect XML writer to output stream
282cdf0e10cSrcweir     xSaxWriter->setOutputStream( xOutputStream );
283cdf0e10cSrcweir 
284cdf0e10cSrcweir     // prepare arguments (prepend doc handler to given arguments)
285cdf0e10cSrcweir     Reference<xml::sax::XDocumentHandler> xDocHandler( xSaxWriter,UNO_QUERY);
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     Sequence<Any> aArgs( 2 );
288cdf0e10cSrcweir     aArgs[0] <<= xDocHandler;
289cdf0e10cSrcweir     aArgs[1] <<= rPropSet;
290cdf0e10cSrcweir 
291cdf0e10cSrcweir     // get filter component
292cdf0e10cSrcweir     Reference< document::XExporter > xExporter(
293cdf0e10cSrcweir         rFactory->createInstanceWithArguments(
294cdf0e10cSrcweir             OUString::createFromAscii(pComponentName), aArgs), UNO_QUERY);
295cdf0e10cSrcweir     DBG_ASSERT( xExporter.is(),
296cdf0e10cSrcweir             "can't instantiate export filter component" );
297cdf0e10cSrcweir     if ( !xExporter.is() )
298cdf0e10cSrcweir         return sal_False;
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     // connect model and filter
302cdf0e10cSrcweir     xExporter->setSourceDocument( xComponent );
303cdf0e10cSrcweir 
304cdf0e10cSrcweir     // filter!
305cdf0e10cSrcweir     Reference < XFilter > xFilter( xExporter, UNO_QUERY );
306cdf0e10cSrcweir     uno::Sequence< PropertyValue > aProps(0);
307cdf0e10cSrcweir     xFilter->filter( aProps );
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     uno::Reference<lang::XUnoTunnel> xFilterTunnel;
310cdf0e10cSrcweir     xFilterTunnel = uno::Reference<lang::XUnoTunnel>
311cdf0e10cSrcweir         ( xFilter, uno::UNO_QUERY );
312cdf0e10cSrcweir     SmXMLExport *pFilter = reinterpret_cast< SmXMLExport * >(
313cdf0e10cSrcweir                 sal::static_int_cast< sal_uIntPtr >(
314cdf0e10cSrcweir                 xFilterTunnel->getSomething( SmXMLExport::getUnoTunnelId() )));
315cdf0e10cSrcweir     return pFilter ? pFilter->GetSuccess() : sal_True;
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir 
319cdf0e10cSrcweir /// export through an XML exporter component (storage version)
320cdf0e10cSrcweir sal_Bool SmXMLExportWrapper::WriteThroughComponent(
321cdf0e10cSrcweir     const Reference < embed::XStorage >& xStorage,
322cdf0e10cSrcweir     Reference<XComponent> xComponent,
323cdf0e10cSrcweir     const sal_Char* pStreamName,
324cdf0e10cSrcweir     Reference<lang::XMultiServiceFactory> & rFactory,
325cdf0e10cSrcweir     Reference<beans::XPropertySet> & rPropSet,
326cdf0e10cSrcweir     const sal_Char* pComponentName,
327cdf0e10cSrcweir     sal_Bool bCompress
328cdf0e10cSrcweir     )
329cdf0e10cSrcweir {
330cdf0e10cSrcweir     DBG_ASSERT(xStorage.is(), "Need storage!");
331cdf0e10cSrcweir     DBG_ASSERT(NULL != pStreamName, "Need stream name!");
332cdf0e10cSrcweir 
333cdf0e10cSrcweir     // open stream
334cdf0e10cSrcweir     Reference < io::XStream > xStream;
335cdf0e10cSrcweir     OUString sStreamName = OUString::createFromAscii(pStreamName);
336cdf0e10cSrcweir     try
337cdf0e10cSrcweir     {
338cdf0e10cSrcweir         xStream = xStorage->openStreamElement( sStreamName,
339cdf0e10cSrcweir             embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
340cdf0e10cSrcweir     }
341cdf0e10cSrcweir     catch ( uno::Exception& )
342cdf0e10cSrcweir     {
343cdf0e10cSrcweir         DBG_ERROR( "Can't create output stream in package!" );
344cdf0e10cSrcweir         return sal_False;
345cdf0e10cSrcweir     }
346cdf0e10cSrcweir 
347cdf0e10cSrcweir     String aPropName( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("MediaType") ) );
348cdf0e10cSrcweir     OUString aMime( RTL_CONSTASCII_USTRINGPARAM("text/xml") );
349cdf0e10cSrcweir     uno::Any aAny;
350cdf0e10cSrcweir     aAny <<= aMime;
351cdf0e10cSrcweir 
352cdf0e10cSrcweir     uno::Reference < beans::XPropertySet > xSet( xStream, uno::UNO_QUERY );
353cdf0e10cSrcweir     xSet->setPropertyValue( aPropName, aAny );
354cdf0e10cSrcweir 
355cdf0e10cSrcweir     if ( !bCompress )
356cdf0e10cSrcweir     {
357cdf0e10cSrcweir         aPropName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM("Compressed") );
358cdf0e10cSrcweir         sal_Bool bFalse = sal_False;
359cdf0e10cSrcweir         aAny.setValue( &bFalse, ::getBooleanCppuType() );
360cdf0e10cSrcweir         xSet->setPropertyValue( aPropName, aAny );
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir     // even plain stream must be encrypted in encrypted document
364cdf0e10cSrcweir     OUString aTmpPropName( RTL_CONSTASCII_USTRINGPARAM("UseCommonStoragePasswordEncryption") );
365cdf0e10cSrcweir     sal_Bool bTrue = sal_True;
366cdf0e10cSrcweir     aAny.setValue( &bTrue, ::getBooleanCppuType() );
367cdf0e10cSrcweir     xSet->setPropertyValue( aTmpPropName, aAny );
368cdf0e10cSrcweir 
369cdf0e10cSrcweir     // set Base URL
370cdf0e10cSrcweir     if ( rPropSet.is() )
371cdf0e10cSrcweir     {
372cdf0e10cSrcweir         OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
373cdf0e10cSrcweir         rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
374cdf0e10cSrcweir     }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir     // write the stuff
377cdf0e10cSrcweir     sal_Bool bRet = WriteThroughComponent( xStream->getOutputStream(), xComponent, rFactory,
378cdf0e10cSrcweir         rPropSet, pComponentName );
379cdf0e10cSrcweir 
380cdf0e10cSrcweir     // stream is closed by SAX parser
381cdf0e10cSrcweir     //if ( bRet )
382cdf0e10cSrcweir     //    xStream->getOutputStream()->closeOutput();
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     return bRet;
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir ////////////////////////////////////////////////////////////
388cdf0e10cSrcweir 
389cdf0e10cSrcweir // #110680#
390cdf0e10cSrcweir SmXMLExport::SmXMLExport(
391cdf0e10cSrcweir     const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
392cdf0e10cSrcweir     sal_uInt16 nExportFlags)
393cdf0e10cSrcweir :   SvXMLExport( xServiceFactory, MAP_INCH, XML_MATH, nExportFlags ) ,
394cdf0e10cSrcweir     pTree(0) ,
395cdf0e10cSrcweir     bSuccess(sal_False)
396cdf0e10cSrcweir {
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir sal_Int64 SAL_CALL SmXMLExport::getSomething(
400cdf0e10cSrcweir     const uno::Sequence< sal_Int8 >& rId )
401cdf0e10cSrcweir throw(uno::RuntimeException)
402cdf0e10cSrcweir {
403cdf0e10cSrcweir     if ( rId.getLength() == 16 &&
404cdf0e10cSrcweir         0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
405cdf0e10cSrcweir         rId.getConstArray(), 16 ) )
406cdf0e10cSrcweir     return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
407cdf0e10cSrcweir 
408cdf0e10cSrcweir     return SvXMLExport::getSomething( rId );
409cdf0e10cSrcweir }
410cdf0e10cSrcweir 
411cdf0e10cSrcweir const uno::Sequence< sal_Int8 > & SmXMLExport::getUnoTunnelId() throw()
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     static uno::Sequence< sal_Int8 > * pSeq = 0;
414cdf0e10cSrcweir     if ( !pSeq )
415cdf0e10cSrcweir     {
416cdf0e10cSrcweir         osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
417cdf0e10cSrcweir         if ( !pSeq )
418cdf0e10cSrcweir         {
419cdf0e10cSrcweir             static uno::Sequence< sal_Int8 > aSeq( 16 );
420cdf0e10cSrcweir             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
421cdf0e10cSrcweir             pSeq = &aSeq;
422cdf0e10cSrcweir         }
423cdf0e10cSrcweir     }
424cdf0e10cSrcweir     return *pSeq;
425cdf0e10cSrcweir }
426cdf0e10cSrcweir 
427cdf0e10cSrcweir OUString SAL_CALL SmXMLExport_getImplementationName() throw()
428cdf0e10cSrcweir {
429cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLExporter" ) );
430cdf0e10cSrcweir }
431cdf0e10cSrcweir 
432cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExport_getSupportedServiceNames()
433cdf0e10cSrcweir         throw()
434cdf0e10cSrcweir {
435cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
436cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
437cdf0e10cSrcweir     return aSeq;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExport_createInstance(
441cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
442cdf0e10cSrcweir     throw( uno::Exception )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir     // #110680#
445cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_ALL );
446cdf0e10cSrcweir     // EXPORT_OASIS is required here allthough there is no differrence between
447cdf0e10cSrcweir     // OOo and OASIS, because without the flag, a transformation to OOo would
448cdf0e10cSrcweir     // be chained in.
449cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_ALL );
450cdf0e10cSrcweir }
451cdf0e10cSrcweir 
452cdf0e10cSrcweir ////////////////////////////////////////////////////////////
453cdf0e10cSrcweir 
454cdf0e10cSrcweir OUString SAL_CALL SmXMLExportMetaOOO_getImplementationName() throw()
455cdf0e10cSrcweir {
456cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLMetaExporter" ) );
457cdf0e10cSrcweir }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportMetaOOO_getSupportedServiceNames()
460cdf0e10cSrcweir     throw()
461cdf0e10cSrcweir {
462cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
463cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
464cdf0e10cSrcweir     return aSeq;
465cdf0e10cSrcweir }
466cdf0e10cSrcweir 
467cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMetaOOO_createInstance(
468cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
469cdf0e10cSrcweir throw( uno::Exception )
470cdf0e10cSrcweir {
471cdf0e10cSrcweir     // #110680#
472cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
473cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_META );
474cdf0e10cSrcweir }
475cdf0e10cSrcweir 
476cdf0e10cSrcweir ////////////////////////////////////////////////////////////
477cdf0e10cSrcweir 
478cdf0e10cSrcweir OUString SAL_CALL SmXMLExportMeta_getImplementationName() throw()
479cdf0e10cSrcweir {
480cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaExporter" ) );
481cdf0e10cSrcweir }
482cdf0e10cSrcweir 
483cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportMeta_getSupportedServiceNames()
484cdf0e10cSrcweir throw()
485cdf0e10cSrcweir {
486cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
487cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
488cdf0e10cSrcweir     return aSeq;
489cdf0e10cSrcweir }
490cdf0e10cSrcweir 
491cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportMeta_createInstance(
492cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
493cdf0e10cSrcweir throw( uno::Exception )
494cdf0e10cSrcweir {
495cdf0e10cSrcweir     // #110680#
496cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_META );
497cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_META );
498cdf0e10cSrcweir }
499cdf0e10cSrcweir 
500cdf0e10cSrcweir ////////////////////////////////////////////////////////////
501cdf0e10cSrcweir 
502cdf0e10cSrcweir OUString SAL_CALL SmXMLExportSettingsOOO_getImplementationName() throw()
503cdf0e10cSrcweir {
504cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLSettingsExporter" ) );
505cdf0e10cSrcweir }
506cdf0e10cSrcweir 
507cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportSettingsOOO_getSupportedServiceNames()
508cdf0e10cSrcweir throw()
509cdf0e10cSrcweir {
510cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
511cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
512cdf0e10cSrcweir     return aSeq;
513cdf0e10cSrcweir }
514cdf0e10cSrcweir 
515cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettingsOOO_createInstance(
516cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
517cdf0e10cSrcweir throw( uno::Exception )
518cdf0e10cSrcweir {
519cdf0e10cSrcweir     // #110680#
520cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
521cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_SETTINGS );
522cdf0e10cSrcweir }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir ////////////////////////////////////////////////////////////
525cdf0e10cSrcweir 
526cdf0e10cSrcweir OUString SAL_CALL SmXMLExportSettings_getImplementationName() throw()
527cdf0e10cSrcweir {
528cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsExporter" ) );
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
531cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportSettings_getSupportedServiceNames()
532cdf0e10cSrcweir throw()
533cdf0e10cSrcweir {
534cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
535cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
536cdf0e10cSrcweir     return aSeq;
537cdf0e10cSrcweir }
538cdf0e10cSrcweir 
539cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportSettings_createInstance(
540cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
541cdf0e10cSrcweir throw( uno::Exception )
542cdf0e10cSrcweir {
543cdf0e10cSrcweir     // #110680#
544cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_SETTINGS );
545cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_SETTINGS );
546cdf0e10cSrcweir }
547cdf0e10cSrcweir 
548cdf0e10cSrcweir ////////////////////////////////////////////////////////////
549cdf0e10cSrcweir 
550cdf0e10cSrcweir OUString SAL_CALL SmXMLExportContent_getImplementationName() throw()
551cdf0e10cSrcweir {
552cdf0e10cSrcweir     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLContentExporter" ) );
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir uno::Sequence< OUString > SAL_CALL SmXMLExportContent_getSupportedServiceNames()
556cdf0e10cSrcweir         throw()
557cdf0e10cSrcweir {
558cdf0e10cSrcweir     const OUString aServiceName( EXPORT_SVC_NAME );
559cdf0e10cSrcweir     const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
560cdf0e10cSrcweir     return aSeq;
561cdf0e10cSrcweir }
562cdf0e10cSrcweir 
563cdf0e10cSrcweir uno::Reference< uno::XInterface > SAL_CALL SmXMLExportContent_createInstance(
564cdf0e10cSrcweir     const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
565cdf0e10cSrcweir throw( uno::Exception )
566cdf0e10cSrcweir {
567cdf0e10cSrcweir     // #110680#
568cdf0e10cSrcweir     // return (cppu::OWeakObject*)new SmXMLExport( EXPORT_CONTENT );
569cdf0e10cSrcweir     // The EXPORT_OASIS flag is only required to avoid that a transformer is
570cdf0e10cSrcweir     // chanied in
571cdf0e10cSrcweir     return (cppu::OWeakObject*)new SmXMLExport( rSMgr, EXPORT_OASIS|EXPORT_CONTENT );
572cdf0e10cSrcweir }
573cdf0e10cSrcweir 
574cdf0e10cSrcweir ////////////////////////////////////////////////////////////
575cdf0e10cSrcweir 
576cdf0e10cSrcweir // XServiceInfo
577cdf0e10cSrcweir // override empty method from parent class
578cdf0e10cSrcweir rtl::OUString SAL_CALL SmXMLExport::getImplementationName()
579cdf0e10cSrcweir throw(uno::RuntimeException)
580cdf0e10cSrcweir {
581cdf0e10cSrcweir     OUString aTxt;
582cdf0e10cSrcweir     switch( getExportFlags() )
583cdf0e10cSrcweir     {
584cdf0e10cSrcweir         case EXPORT_META:
585cdf0e10cSrcweir             aTxt = SmXMLExportMeta_getImplementationName();
586cdf0e10cSrcweir             break;
587cdf0e10cSrcweir         case EXPORT_SETTINGS:
588cdf0e10cSrcweir             aTxt = SmXMLExportSettings_getImplementationName();
589cdf0e10cSrcweir             break;
590cdf0e10cSrcweir         case EXPORT_CONTENT:
591cdf0e10cSrcweir             aTxt = SmXMLExportContent_getImplementationName();
592cdf0e10cSrcweir             break;
593cdf0e10cSrcweir         case EXPORT_ALL:
594cdf0e10cSrcweir         default:
595cdf0e10cSrcweir             aTxt = SmXMLExport_getImplementationName();
596cdf0e10cSrcweir             break;
597cdf0e10cSrcweir     }
598cdf0e10cSrcweir     return aTxt;
599cdf0e10cSrcweir }
600cdf0e10cSrcweir 
601cdf0e10cSrcweir sal_uInt32 SmXMLExport::exportDoc(enum XMLTokenEnum eClass)
602cdf0e10cSrcweir {
603cdf0e10cSrcweir     if ( (getExportFlags() & EXPORT_CONTENT) == 0 )
604cdf0e10cSrcweir     {
605cdf0e10cSrcweir         SvXMLExport::exportDoc( eClass );
606cdf0e10cSrcweir     }
607cdf0e10cSrcweir     else
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         uno::Reference <frame::XModel> xModel = GetModel();
610cdf0e10cSrcweir         uno::Reference <lang::XUnoTunnel> xTunnel;
611cdf0e10cSrcweir         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
612cdf0e10cSrcweir         SmModel *pModel = reinterpret_cast<SmModel *>
613cdf0e10cSrcweir             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
614cdf0e10cSrcweir 
615cdf0e10cSrcweir         if (pModel)
616cdf0e10cSrcweir         {
617cdf0e10cSrcweir             SmDocShell *pDocShell =
618cdf0e10cSrcweir                 static_cast<SmDocShell*>(pModel->GetObjectShell());
619cdf0e10cSrcweir             pTree = pDocShell->GetFormulaTree();
620cdf0e10cSrcweir             aText = pDocShell->GetText();
621cdf0e10cSrcweir         }
622cdf0e10cSrcweir 
623cdf0e10cSrcweir         GetDocHandler()->startDocument();
624cdf0e10cSrcweir 
625cdf0e10cSrcweir         /*Add xmlns line*/
626cdf0e10cSrcweir         SvXMLAttributeList &rList = GetAttrList();
627cdf0e10cSrcweir 
628cdf0e10cSrcweir         // make use of a default namespace
629cdf0e10cSrcweir         ResetNamespaceMap();    // Math doesn't need namespaces from xmloff, since it now uses default namespaces (because that is common with current MathML usage in the web)
630cdf0e10cSrcweir         _GetNamespaceMap().Add( OUString::createFromAscii(""), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
631cdf0e10cSrcweir 
632cdf0e10cSrcweir         rList.AddAttribute(GetNamespaceMap().GetAttrNameByKey(XML_NAMESPACE_MATH_IDX),
633cdf0e10cSrcweir                 GetNamespaceMap().GetNameByKey( XML_NAMESPACE_MATH_IDX));
634cdf0e10cSrcweir 
635cdf0e10cSrcweir         //I think we need something like ImplExportEntities();
636cdf0e10cSrcweir         _ExportContent();
637cdf0e10cSrcweir         GetDocHandler()->endDocument();
638cdf0e10cSrcweir     }
639cdf0e10cSrcweir 
640cdf0e10cSrcweir     bSuccess=sal_True;
641cdf0e10cSrcweir     return 0;
642cdf0e10cSrcweir }
643cdf0e10cSrcweir 
644cdf0e10cSrcweir void SmXMLExport::_ExportContent()
645cdf0e10cSrcweir {
646cdf0e10cSrcweir     SvXMLElementExport aEquation(*this, XML_NAMESPACE_MATH, XML_MATH, sal_True, sal_True);
647cdf0e10cSrcweir     SvXMLElementExport *pSemantics=0;
648cdf0e10cSrcweir 
649cdf0e10cSrcweir     if (aText.Len())
650cdf0e10cSrcweir     {
651cdf0e10cSrcweir         pSemantics = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
652cdf0e10cSrcweir             XML_SEMANTICS, sal_True, sal_True);
653cdf0e10cSrcweir     }
654cdf0e10cSrcweir 
655cdf0e10cSrcweir     ExportNodes(pTree, 0);
656cdf0e10cSrcweir 
657cdf0e10cSrcweir     if (aText.Len())
658cdf0e10cSrcweir     {
659cdf0e10cSrcweir         // Convert symbol names
660cdf0e10cSrcweir         uno::Reference <frame::XModel> xModel = GetModel();
661cdf0e10cSrcweir         uno::Reference <lang::XUnoTunnel> xTunnel;
662cdf0e10cSrcweir         xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
663cdf0e10cSrcweir         SmModel *pModel = reinterpret_cast<SmModel *>
664cdf0e10cSrcweir             (xTunnel->getSomething(SmModel::getUnoTunnelId()));
665cdf0e10cSrcweir         SmDocShell *pDocShell = pModel ?
666cdf0e10cSrcweir             static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
667cdf0e10cSrcweir         DBG_ASSERT( pDocShell, "doc shell missing" );
668cdf0e10cSrcweir         if (pDocShell)
669cdf0e10cSrcweir         {
670cdf0e10cSrcweir             SmParser &rParser = pDocShell->GetParser();
671cdf0e10cSrcweir             sal_Bool bVal = rParser.IsExportSymbolNames();
672cdf0e10cSrcweir             rParser.SetExportSymbolNames( sal_True );
673cdf0e10cSrcweir             SmNode *pTmpTree = rParser.Parse( aText );
674cdf0e10cSrcweir             aText = rParser.GetText();
675cdf0e10cSrcweir             delete pTmpTree;
676cdf0e10cSrcweir             rParser.SetExportSymbolNames( bVal );
677cdf0e10cSrcweir         }
678cdf0e10cSrcweir 
679cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_ENCODING,
680cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
681cdf0e10cSrcweir         SvXMLElementExport aAnnotation(*this, XML_NAMESPACE_MATH,
682cdf0e10cSrcweir             XML_ANNOTATION, sal_True, sal_False);
683cdf0e10cSrcweir         GetDocHandler()->characters(OUString( aText ));
684cdf0e10cSrcweir     }
685cdf0e10cSrcweir     delete pSemantics;
686cdf0e10cSrcweir }
687cdf0e10cSrcweir 
688cdf0e10cSrcweir void SmXMLExport::GetViewSettings( Sequence < PropertyValue >& aProps)
689cdf0e10cSrcweir {
690cdf0e10cSrcweir     uno::Reference <frame::XModel> xModel = GetModel();
691cdf0e10cSrcweir     if ( !xModel.is() )
692cdf0e10cSrcweir         return;
693cdf0e10cSrcweir 
694cdf0e10cSrcweir     uno::Reference <lang::XUnoTunnel> xTunnel;
695cdf0e10cSrcweir     xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
696cdf0e10cSrcweir     SmModel *pModel = reinterpret_cast<SmModel *>
697cdf0e10cSrcweir         (xTunnel->getSomething(SmModel::getUnoTunnelId()));
698cdf0e10cSrcweir 
699cdf0e10cSrcweir     if ( !pModel )
700cdf0e10cSrcweir         return;
701cdf0e10cSrcweir 
702cdf0e10cSrcweir     SmDocShell *pDocShell =
703cdf0e10cSrcweir         static_cast<SmDocShell*>(pModel->GetObjectShell());
704cdf0e10cSrcweir     if ( !pDocShell )
705cdf0e10cSrcweir         return;
706cdf0e10cSrcweir 
707cdf0e10cSrcweir     aProps.realloc( 4 );
708cdf0e10cSrcweir     PropertyValue *pValue = aProps.getArray();
709cdf0e10cSrcweir     sal_Int32 nIndex = 0;
710cdf0e10cSrcweir 
711cdf0e10cSrcweir     Rectangle aRect( pDocShell->GetVisArea() );
712cdf0e10cSrcweir 
713cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaTop") );
714cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.Top();
715cdf0e10cSrcweir 
716cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaLeft") );
717cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.Left();
718cdf0e10cSrcweir 
719cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaWidth") );
720cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.GetWidth();
721cdf0e10cSrcweir 
722cdf0e10cSrcweir     pValue[nIndex].Name = OUString( RTL_CONSTASCII_USTRINGPARAM ( "ViewAreaHeight") );
723cdf0e10cSrcweir     pValue[nIndex++].Value <<= aRect.GetHeight();
724cdf0e10cSrcweir }
725cdf0e10cSrcweir 
726cdf0e10cSrcweir void SmXMLExport::GetConfigurationSettings( Sequence < PropertyValue > & rProps)
727cdf0e10cSrcweir {
728cdf0e10cSrcweir     Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
729cdf0e10cSrcweir     if ( xProps.is() )
730cdf0e10cSrcweir     {
731cdf0e10cSrcweir         Reference< XPropertySetInfo > xPropertySetInfo = xProps->getPropertySetInfo();
732cdf0e10cSrcweir         if (xPropertySetInfo.is())
733cdf0e10cSrcweir         {
734cdf0e10cSrcweir             Sequence< Property > aProps = xPropertySetInfo->getProperties();
735cdf0e10cSrcweir             sal_Int32 nCount(aProps.getLength());
736cdf0e10cSrcweir             if (nCount > 0)
737cdf0e10cSrcweir             {
738cdf0e10cSrcweir                 rProps.realloc(nCount);
739cdf0e10cSrcweir                 PropertyValue* pProps = rProps.getArray();
740cdf0e10cSrcweir                 if (pProps)
741cdf0e10cSrcweir                 {
742cdf0e10cSrcweir                     SmConfig *pConfig = SM_MOD()->GetConfig();
743cdf0e10cSrcweir                     const bool bUsedSymbolsOnly = pConfig ? pConfig->IsSaveOnlyUsedSymbols() : false;
744cdf0e10cSrcweir 
745cdf0e10cSrcweir                     const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
746cdf0e10cSrcweir                     const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
747cdf0e10cSrcweir                     const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
748cdf0e10cSrcweir                     const OUString sRuntimeUID ( RTL_CONSTASCII_USTRINGPARAM ( "RuntimeUID" ) );
749cdf0e10cSrcweir                     for (sal_Int32 i = 0; i < nCount; i++, pProps++)
750cdf0e10cSrcweir                     {
751cdf0e10cSrcweir                         const OUString &rPropName = aProps[i].Name;
752cdf0e10cSrcweir                         if (rPropName != sFormula &&
753cdf0e10cSrcweir                             rPropName != sBasicLibraries &&
754cdf0e10cSrcweir                             rPropName != sDialogLibraries &&
755cdf0e10cSrcweir                             rPropName != sRuntimeUID)
756cdf0e10cSrcweir                         {
757cdf0e10cSrcweir                             pProps->Name = rPropName;
758cdf0e10cSrcweir 
759cdf0e10cSrcweir                             rtl::OUString aActualName( rPropName );
760cdf0e10cSrcweir 
761cdf0e10cSrcweir                             // handle 'save used symbols only'
762cdf0e10cSrcweir                             if (bUsedSymbolsOnly && rPropName.equalsAscii("Symbols"))
763cdf0e10cSrcweir                                 aActualName = OUString( RTL_CONSTASCII_USTRINGPARAM ( "UserDefinedSymbolsInUse" ) );
764cdf0e10cSrcweir 
765cdf0e10cSrcweir                             pProps->Value = xProps->getPropertyValue( aActualName );
766cdf0e10cSrcweir                         }
767cdf0e10cSrcweir                     }
768cdf0e10cSrcweir                 }
769cdf0e10cSrcweir             }
770cdf0e10cSrcweir         }
771cdf0e10cSrcweir     }
772cdf0e10cSrcweir }
773cdf0e10cSrcweir 
774cdf0e10cSrcweir void SmXMLExport::ExportLine(const SmNode *pNode, int nLevel)
775cdf0e10cSrcweir {
776cdf0e10cSrcweir     ExportExpression(pNode, nLevel);
777cdf0e10cSrcweir }
778cdf0e10cSrcweir 
779cdf0e10cSrcweir void SmXMLExport::ExportBinaryHorizontal(const SmNode *pNode, int nLevel)
780cdf0e10cSrcweir {
781cdf0e10cSrcweir     ExportExpression(pNode, nLevel);
782cdf0e10cSrcweir }
783cdf0e10cSrcweir 
784cdf0e10cSrcweir void SmXMLExport::ExportUnaryHorizontal(const SmNode *pNode, int nLevel)
785cdf0e10cSrcweir {
786cdf0e10cSrcweir     ExportExpression(pNode, nLevel);
787cdf0e10cSrcweir }
788cdf0e10cSrcweir 
789cdf0e10cSrcweir void SmXMLExport::ExportExpression(const SmNode *pNode, int nLevel)
790cdf0e10cSrcweir {
791cdf0e10cSrcweir     SvXMLElementExport *pRow=0;
792cdf0e10cSrcweir     sal_uLong  nSize = pNode->GetNumSubNodes();
793cdf0e10cSrcweir 
794cdf0e10cSrcweir     // #i115443: nodes of type expression always need to be grouped with mrow statement
795cdf0e10cSrcweir     if (nSize > 1 || (pNode && pNode->GetType() == NEXPRESSION))
796cdf0e10cSrcweir         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW, sal_True, sal_True);
797cdf0e10cSrcweir 
798cdf0e10cSrcweir     //if (nSize)
799cdf0e10cSrcweir     //{
800cdf0e10cSrcweir         for (sal_uInt16 i = 0; i < nSize; i++)
801cdf0e10cSrcweir             if (const SmNode *pTemp = pNode->GetSubNode(i))
802cdf0e10cSrcweir                 ExportNodes(pTemp, nLevel+1);
803cdf0e10cSrcweir     //}
804cdf0e10cSrcweir #if 0
805cdf0e10cSrcweir     else
806cdf0e10cSrcweir     {
807cdf0e10cSrcweir         //This saves us from situations like "a newline" where the
808cdf0e10cSrcweir         //lack of a term following the newline would otherwise create
809cdf0e10cSrcweir         //a incorrect token like <mtr/>
810cdf0e10cSrcweir         SvXMLElementExport aDummy(*this, XML_NAMESPACE_MATH, XML_MI, sal_True, sal_False);
811cdf0e10cSrcweir         sal_Unicode nArse[2] = {'\n','\0'};
812cdf0e10cSrcweir         GetDocHandler()->characters(nArse);
813cdf0e10cSrcweir     }
814cdf0e10cSrcweir #endif
815cdf0e10cSrcweir 
816cdf0e10cSrcweir     delete pRow;
817cdf0e10cSrcweir }
818cdf0e10cSrcweir 
819cdf0e10cSrcweir void SmXMLExport::ExportBinaryVertical(const SmNode *pNode, int nLevel)
820cdf0e10cSrcweir {
821cdf0e10cSrcweir     DBG_ASSERT(pNode->GetNumSubNodes()==3,"Bad Fraction");
822cdf0e10cSrcweir     SvXMLElementExport aFraction(*this, XML_NAMESPACE_MATH, XML_MFRAC, sal_True, sal_True);
823cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(0), nLevel);
824cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(2), nLevel);
825cdf0e10cSrcweir }
826cdf0e10cSrcweir 
827cdf0e10cSrcweir void SmXMLExport::ExportTable(const SmNode *pNode, int nLevel)
828cdf0e10cSrcweir {
829cdf0e10cSrcweir     SvXMLElementExport *pTable=0;
830cdf0e10cSrcweir 
831cdf0e10cSrcweir     sal_uInt16 nSize = pNode->GetNumSubNodes();
832cdf0e10cSrcweir 
833cdf0e10cSrcweir     //If the list ends in newline then the last entry has
834cdf0e10cSrcweir     //no subnodes, the newline is superfulous so we just drop
835cdf0e10cSrcweir     //the last node, inclusion would create a bad MathML
836cdf0e10cSrcweir     //table
837cdf0e10cSrcweir     if (nSize >= 1 && pNode->GetSubNode(nSize-1)->GetNumSubNodes() == 0)
838cdf0e10cSrcweir         --nSize;
839cdf0e10cSrcweir 
840cdf0e10cSrcweir     // try to avoid creating a mtable element when the formula consists only
841cdf0e10cSrcweir     // of a single output line
842cdf0e10cSrcweir     if (nLevel || (nSize >1))
843cdf0e10cSrcweir         pTable = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
844cdf0e10cSrcweir 
845cdf0e10cSrcweir     for (sal_uInt16 i = 0; i < nSize; i++)
846cdf0e10cSrcweir         if (const SmNode *pTemp = pNode->GetSubNode(i))
847cdf0e10cSrcweir         {
848cdf0e10cSrcweir             SvXMLElementExport *pRow=0;
849cdf0e10cSrcweir             SvXMLElementExport *pCell=0;
850cdf0e10cSrcweir             if (pTable)
851cdf0e10cSrcweir             {
852cdf0e10cSrcweir                 pRow  = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
853cdf0e10cSrcweir                 pCell = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
854cdf0e10cSrcweir             }
855cdf0e10cSrcweir             ExportNodes(pTemp, nLevel+1);
856cdf0e10cSrcweir             delete pCell;
857cdf0e10cSrcweir             delete pRow;
858cdf0e10cSrcweir         }
859cdf0e10cSrcweir 
860cdf0e10cSrcweir     delete pTable;
861cdf0e10cSrcweir }
862cdf0e10cSrcweir 
863cdf0e10cSrcweir void SmXMLExport::ExportMath(const SmNode *pNode, int /*nLevel*/)
864cdf0e10cSrcweir {
865cdf0e10cSrcweir     const SmMathSymbolNode *pTemp = static_cast<const SmMathSymbolNode *>(pNode);
866cdf0e10cSrcweir     SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO, sal_True, sal_False);
867cdf0e10cSrcweir     sal_Unicode nArse[2];
868cdf0e10cSrcweir     nArse[0] = pTemp->GetText().GetChar(0);
869cdf0e10cSrcweir     sal_Unicode cTmp = ConvertMathToMathML( nArse[0] );
870cdf0e10cSrcweir     if (cTmp != 0)
871cdf0e10cSrcweir         nArse[0] = cTmp;
872cdf0e10cSrcweir     DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
873cdf0e10cSrcweir     nArse[1] = 0;
874cdf0e10cSrcweir     GetDocHandler()->characters(nArse);
875cdf0e10cSrcweir }
876cdf0e10cSrcweir 
877cdf0e10cSrcweir void SmXMLExport::ExportText(const SmNode *pNode, int /*nLevel*/)
878cdf0e10cSrcweir {
879cdf0e10cSrcweir     SvXMLElementExport *pText;
880cdf0e10cSrcweir     const SmTextNode *pTemp = static_cast<const SmTextNode *>(pNode);
881cdf0e10cSrcweir     switch (pNode->GetToken().eType)
882cdf0e10cSrcweir     {
883cdf0e10cSrcweir         default:
884cdf0e10cSrcweir         case TIDENT:
885cdf0e10cSrcweir         {
886cdf0e10cSrcweir             //Note that we change the fontstyle to italic for strings that
887cdf0e10cSrcweir             //are italic and longer than a single character.
888cdf0e10cSrcweir             sal_Bool bIsItalic = IsItalic( pTemp->GetFont() );
889cdf0e10cSrcweir             if ((pTemp->GetText().Len() > 1) && bIsItalic)
890cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_ITALIC);
891cdf0e10cSrcweir             else if ((pTemp->GetText().Len() == 1) && !bIsItalic)
892cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, XML_NORMAL);
893cdf0e10cSrcweir             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI,sal_True,sal_False);
894cdf0e10cSrcweir             break;
895cdf0e10cSrcweir         }
896cdf0e10cSrcweir         case TNUMBER:
897cdf0e10cSrcweir             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MN,sal_True,sal_False);
898cdf0e10cSrcweir             break;
899cdf0e10cSrcweir         case TTEXT:
900cdf0e10cSrcweir             pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MTEXT,sal_True,sal_False);
901cdf0e10cSrcweir             break;
902cdf0e10cSrcweir         }
903cdf0e10cSrcweir     GetDocHandler()->characters(OUString(pTemp->GetText().GetBuffer()));
904cdf0e10cSrcweir     delete pText;
905cdf0e10cSrcweir }
906cdf0e10cSrcweir 
907cdf0e10cSrcweir void SmXMLExport::ExportBlank(const SmNode * /*pNode*/, int /*nLevel*/)
908cdf0e10cSrcweir {
909cdf0e10cSrcweir     //!! exports an empty <mi> tag since for example "~_~" is allowed in
910cdf0e10cSrcweir     //!! Math (so it has no sense at all) but must not result in an empty
911cdf0e10cSrcweir     //!! <msub> tag in MathML !!
912cdf0e10cSrcweir 
913cdf0e10cSrcweir     SvXMLElementExport *pText;
914cdf0e10cSrcweir     //const SmBlankNode *pTemp = static_cast<const SmBlankNode *>(pNode);
915cdf0e10cSrcweir 
916cdf0e10cSrcweir     pText = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MI, sal_True, sal_False);
917cdf0e10cSrcweir 
918cdf0e10cSrcweir     GetDocHandler()->characters( OUString() );
919cdf0e10cSrcweir     delete pText;
920cdf0e10cSrcweir }
921cdf0e10cSrcweir 
922cdf0e10cSrcweir void SmXMLExport::ExportSubSupScript(const SmNode *pNode, int nLevel)
923cdf0e10cSrcweir {
924cdf0e10cSrcweir     const SmNode *pSub  = 0;
925cdf0e10cSrcweir     const SmNode *pSup  = 0;
926cdf0e10cSrcweir     const SmNode *pCSub = 0;
927cdf0e10cSrcweir     const SmNode *pCSup = 0;
928cdf0e10cSrcweir     const SmNode *pLSub = 0;
929cdf0e10cSrcweir     const SmNode *pLSup = 0;
930cdf0e10cSrcweir     SvXMLElementExport *pThing = 0, *pThing2 = 0;
931cdf0e10cSrcweir 
932cdf0e10cSrcweir     //if we have prescripts at all then we must use the tensor notation
933cdf0e10cSrcweir 
934cdf0e10cSrcweir     //This is one of those excellent locations where scope is vital to
935cdf0e10cSrcweir     //arrange the construction and destruction of the element helper
936cdf0e10cSrcweir     //classes correctly
937cdf0e10cSrcweir     pLSub = pNode->GetSubNode(LSUB+1);
938cdf0e10cSrcweir     pLSup = pNode->GetSubNode(LSUP+1);
939cdf0e10cSrcweir     if (pLSub || pLSup)
940cdf0e10cSrcweir     {
941cdf0e10cSrcweir         SvXMLElementExport aMultiScripts(*this, XML_NAMESPACE_MATH,
942cdf0e10cSrcweir             XML_MMULTISCRIPTS, sal_True, sal_True);
943cdf0e10cSrcweir 
944cdf0e10cSrcweir 
945cdf0e10cSrcweir         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
946cdf0e10cSrcweir             && NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
947cdf0e10cSrcweir         {
948cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
949cdf0e10cSrcweir                 XML_MUNDEROVER, sal_True,sal_True);
950cdf0e10cSrcweir         }
951cdf0e10cSrcweir         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
952cdf0e10cSrcweir         {
953cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
954cdf0e10cSrcweir                 XML_MUNDER, sal_True,sal_True);
955cdf0e10cSrcweir         }
956cdf0e10cSrcweir         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
957cdf0e10cSrcweir         {
958cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
959cdf0e10cSrcweir                 XML_MOVER, sal_True,sal_True);
960cdf0e10cSrcweir         }
961cdf0e10cSrcweir 
962cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
963cdf0e10cSrcweir 
964cdf0e10cSrcweir         if (pCSub)
965cdf0e10cSrcweir             ExportNodes(pCSub, nLevel+1);
966cdf0e10cSrcweir         if (pCSup)
967cdf0e10cSrcweir             ExportNodes(pCSup, nLevel+1);
968cdf0e10cSrcweir         delete pThing2;
969cdf0e10cSrcweir 
970cdf0e10cSrcweir         pSub = pNode->GetSubNode(RSUB+1);
971cdf0e10cSrcweir         pSup = pNode->GetSubNode(RSUP+1);
972cdf0e10cSrcweir         if (pSub || pSup)
973cdf0e10cSrcweir         {
974cdf0e10cSrcweir             if (pSub)
975cdf0e10cSrcweir                 ExportNodes(pSub, nLevel+1);
976cdf0e10cSrcweir             else
977cdf0e10cSrcweir             {
978cdf0e10cSrcweir                 SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
979cdf0e10cSrcweir             }
980cdf0e10cSrcweir             if (pSup)
981cdf0e10cSrcweir                 ExportNodes(pSup, nLevel+1);
982cdf0e10cSrcweir             else
983cdf0e10cSrcweir             {
984cdf0e10cSrcweir                 SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,sal_True,sal_True);
985cdf0e10cSrcweir             }
986cdf0e10cSrcweir         }
987cdf0e10cSrcweir 
988cdf0e10cSrcweir         //Seperator element between suffix and prefix sub/sup pairs
989cdf0e10cSrcweir         {
990cdf0e10cSrcweir             SvXMLElementExport aPrescripts(*this, XML_NAMESPACE_MATH,
991cdf0e10cSrcweir                 XML_MPRESCRIPTS, sal_True,sal_True);
992cdf0e10cSrcweir         }
993cdf0e10cSrcweir 
994cdf0e10cSrcweir         if (pLSub)
995cdf0e10cSrcweir             ExportNodes(pLSub, nLevel+1);
996cdf0e10cSrcweir         else
997cdf0e10cSrcweir         {
998cdf0e10cSrcweir             SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
999cdf0e10cSrcweir                 sal_True,sal_True);
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir         }
1002cdf0e10cSrcweir         if (pLSup)
1003cdf0e10cSrcweir             ExportNodes(pLSup, nLevel+1);
1004cdf0e10cSrcweir         else
1005cdf0e10cSrcweir         {
1006cdf0e10cSrcweir             SvXMLElementExport aNone(*this, XML_NAMESPACE_MATH, XML_NONE,
1007cdf0e10cSrcweir                 sal_True,sal_True);
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir         }
1010cdf0e10cSrcweir     }
1011cdf0e10cSrcweir     else
1012cdf0e10cSrcweir     {
1013cdf0e10cSrcweir         if (NULL != (pSub = pNode->GetSubNode(RSUB+1)) &&
1014cdf0e10cSrcweir             NULL != (pSup = pNode->GetSubNode(RSUP+1)))
1015cdf0e10cSrcweir         {
1016cdf0e10cSrcweir             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1017cdf0e10cSrcweir                 XML_MSUBSUP, sal_True,sal_True);
1018cdf0e10cSrcweir         }
1019cdf0e10cSrcweir         else if (NULL != (pSub = pNode->GetSubNode(RSUB+1)))
1020cdf0e10cSrcweir         {
1021cdf0e10cSrcweir             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUB,
1022cdf0e10cSrcweir                 sal_True,sal_True);
1023cdf0e10cSrcweir         }
1024cdf0e10cSrcweir         else if (NULL != (pSup = pNode->GetSubNode(RSUP+1)))
1025cdf0e10cSrcweir         {
1026cdf0e10cSrcweir             pThing = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MSUP,
1027cdf0e10cSrcweir                 sal_True,sal_True);
1028cdf0e10cSrcweir         }
1029cdf0e10cSrcweir 
1030cdf0e10cSrcweir         if (NULL != (pCSub = pNode->GetSubNode(CSUB+1))
1031cdf0e10cSrcweir             && NULL != (pCSup=pNode->GetSubNode(CSUP+1)))
1032cdf0e10cSrcweir         {
1033cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1034cdf0e10cSrcweir                 XML_MUNDEROVER, sal_True,sal_True);
1035cdf0e10cSrcweir         }
1036cdf0e10cSrcweir         else if (NULL != (pCSub = pNode->GetSubNode(CSUB+1)))
1037cdf0e10cSrcweir         {
1038cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1039cdf0e10cSrcweir                 XML_MUNDER, sal_True,sal_True);
1040cdf0e10cSrcweir         }
1041cdf0e10cSrcweir         else if (NULL != (pCSup = pNode->GetSubNode(CSUP+1)))
1042cdf0e10cSrcweir         {
1043cdf0e10cSrcweir             pThing2 = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1044cdf0e10cSrcweir                 XML_MOVER, sal_True,sal_True);
1045cdf0e10cSrcweir         }
1046cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);    //Main Term
1047cdf0e10cSrcweir 
1048cdf0e10cSrcweir         if (pCSub)
1049cdf0e10cSrcweir             ExportNodes(pCSub, nLevel+1);
1050cdf0e10cSrcweir         if (pCSup)
1051cdf0e10cSrcweir             ExportNodes(pCSup, nLevel+1);
1052cdf0e10cSrcweir         delete pThing2;
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir         if (pSub)
1055cdf0e10cSrcweir             ExportNodes(pSub, nLevel+1);
1056cdf0e10cSrcweir         if (pSup)
1057cdf0e10cSrcweir             ExportNodes(pSup, nLevel+1);
1058cdf0e10cSrcweir         delete pThing;
1059cdf0e10cSrcweir     }
1060cdf0e10cSrcweir }
1061cdf0e10cSrcweir 
1062cdf0e10cSrcweir void SmXMLExport::ExportBrace(const SmNode *pNode, int nLevel)
1063cdf0e10cSrcweir {
1064cdf0e10cSrcweir     const SmNode *pTemp;
1065cdf0e10cSrcweir     const SmNode *pLeft=pNode->GetSubNode(0);
1066cdf0e10cSrcweir     const SmNode *pRight=pNode->GetSubNode(2);
1067cdf0e10cSrcweir     SvXMLElementExport *pFences=0,*pRow=0;
1068cdf0e10cSrcweir     if ( ((pLeft) && (pLeft->GetToken().eType != TNONE)) &&
1069cdf0e10cSrcweir         ((pRight) && (pRight->GetToken().eType != TNONE)) &&
1070cdf0e10cSrcweir         (pNode->GetScaleMode() == SCALE_HEIGHT))
1071cdf0e10cSrcweir     {
1072cdf0e10cSrcweir         sal_Unicode nArse[2];
1073cdf0e10cSrcweir         nArse[1] = 0;
1074cdf0e10cSrcweir         nArse[0] = static_cast<
1075cdf0e10cSrcweir             const SmMathSymbolNode* >(pLeft)->GetText().GetChar(0);
1076cdf0e10cSrcweir         DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
1077cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_OPEN,nArse);
1078cdf0e10cSrcweir         nArse[0] = static_cast<
1079cdf0e10cSrcweir             const SmMathSymbolNode* >(pRight)->GetText().GetChar(0);
1080cdf0e10cSrcweir         DBG_ASSERT(nArse[0] != 0xffff,"Non existant symbol");
1081cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_CLOSE,nArse);
1082cdf0e10cSrcweir         pFences = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MFENCED,
1083cdf0e10cSrcweir             sal_True,sal_True);
1084cdf0e10cSrcweir     }
1085cdf0e10cSrcweir     else if (pLeft && (pLeft->GetToken().eType != TNONE))
1086cdf0e10cSrcweir     {
1087cdf0e10cSrcweir         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
1088cdf0e10cSrcweir             sal_True, sal_True);
1089cdf0e10cSrcweir         if (pNode->GetScaleMode() == SCALE_HEIGHT)
1090cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
1091cdf0e10cSrcweir         else
1092cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
1093cdf0e10cSrcweir         ExportNodes(pLeft, nLevel+1);
1094cdf0e10cSrcweir     }
1095cdf0e10cSrcweir     else
1096cdf0e10cSrcweir         pRow = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MROW,
1097cdf0e10cSrcweir             sal_True, sal_True);
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir     if (NULL != (pTemp = pNode->GetSubNode(1)))
1100cdf0e10cSrcweir         ExportNodes(pTemp, nLevel+1);
1101cdf0e10cSrcweir     if (pFences)
1102cdf0e10cSrcweir         delete pFences;
1103cdf0e10cSrcweir     else if (pRight && (pRight->GetToken().eType != TNONE))
1104cdf0e10cSrcweir     {
1105cdf0e10cSrcweir         if (pNode->GetScaleMode() == SCALE_HEIGHT)
1106cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_TRUE);
1107cdf0e10cSrcweir         else
1108cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
1109cdf0e10cSrcweir         ExportNodes(pRight, nLevel+1);
1110cdf0e10cSrcweir     }
1111cdf0e10cSrcweir     delete pRow;
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir 
1114cdf0e10cSrcweir void SmXMLExport::ExportRoot(const SmNode *pNode, int nLevel)
1115cdf0e10cSrcweir {
1116cdf0e10cSrcweir     if (pNode->GetSubNode(0))
1117cdf0e10cSrcweir     {
1118cdf0e10cSrcweir         SvXMLElementExport aRoot(*this, XML_NAMESPACE_MATH, XML_MROOT,sal_True,
1119cdf0e10cSrcweir             sal_True);
1120cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(2), nLevel+1);
1121cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);
1122cdf0e10cSrcweir     }
1123cdf0e10cSrcweir     else
1124cdf0e10cSrcweir     {
1125cdf0e10cSrcweir         SvXMLElementExport aSqrt(*this, XML_NAMESPACE_MATH, XML_MSQRT,sal_True,
1126cdf0e10cSrcweir             sal_True);
1127cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(2), nLevel+1);
1128cdf0e10cSrcweir     }
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir 
1131cdf0e10cSrcweir void SmXMLExport::ExportOperator(const SmNode *pNode, int nLevel)
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir     /*we need to either use content or font and size attributes
1134cdf0e10cSrcweir      *here*/
1135cdf0e10cSrcweir #if 0
1136cdf0e10cSrcweir     {
1137cdf0e10cSrcweir     SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
1138cdf0e10cSrcweir         sal_True,sal_False);
1139cdf0e10cSrcweir     SmTextNode *pTemp = (SmTextNode *)pNode->GetSubNode(0);
1140cdf0e10cSrcweir     GetDocHandler()->characters(pTemp->GetText());
1141cdf0e10cSrcweir     }
1142cdf0e10cSrcweir #endif
1143cdf0e10cSrcweir     SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MROW,
1144cdf0e10cSrcweir         sal_True, sal_True);
1145cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(0), nLevel+1);
1146cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(1), nLevel+1);
1147cdf0e10cSrcweir }
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir void SmXMLExport::ExportAttributes(const SmNode *pNode, int nLevel)
1150cdf0e10cSrcweir {
1151cdf0e10cSrcweir     SvXMLElementExport *pElement=0;
1152cdf0e10cSrcweir 
1153cdf0e10cSrcweir     if (pNode->GetToken().eType == TUNDERLINE)
1154cdf0e10cSrcweir     {
1155cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_ACCENTUNDER,
1156cdf0e10cSrcweir             XML_TRUE);
1157cdf0e10cSrcweir         pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MUNDER,
1158cdf0e10cSrcweir             sal_True,sal_True);
1159cdf0e10cSrcweir     }
1160cdf0e10cSrcweir     else if (pNode->GetToken().eType != TOVERSTRIKE)
1161cdf0e10cSrcweir     {
1162cdf0e10cSrcweir         AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT,
1163cdf0e10cSrcweir             XML_TRUE);
1164cdf0e10cSrcweir         pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH, XML_MOVER,
1165cdf0e10cSrcweir             sal_True,sal_True);
1166cdf0e10cSrcweir     }
1167cdf0e10cSrcweir 
1168cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(1), nLevel+1);
1169cdf0e10cSrcweir     switch (pNode->GetToken().eType)
1170cdf0e10cSrcweir     {
1171cdf0e10cSrcweir         case TOVERLINE:
1172cdf0e10cSrcweir             {
1173cdf0e10cSrcweir             //proper entity support required
1174cdf0e10cSrcweir             SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
1175cdf0e10cSrcweir                 sal_True,sal_True);
1176cdf0e10cSrcweir #if 0
1177cdf0e10cSrcweir             GetDocHandler()->characters(
1178cdf0e10cSrcweir                 OUString(RTL_CONSTASCII_USTRINGPARAM("&overbar;")));
1179cdf0e10cSrcweir #else
1180cdf0e10cSrcweir             sal_Unicode nArse[2] = {0xAF,0x00};
1181cdf0e10cSrcweir #endif
1182cdf0e10cSrcweir             GetDocHandler()->characters(nArse);
1183cdf0e10cSrcweir             }
1184cdf0e10cSrcweir             break;
1185cdf0e10cSrcweir         case TUNDERLINE:
1186cdf0e10cSrcweir             {
1187cdf0e10cSrcweir             //proper entity support required
1188cdf0e10cSrcweir             SvXMLElementExport aMath(*this, XML_NAMESPACE_MATH, XML_MO,
1189cdf0e10cSrcweir                 sal_True,sal_True);
1190cdf0e10cSrcweir #if 0
1191cdf0e10cSrcweir             GetDocHandler()->characters(
1192cdf0e10cSrcweir                 OUString(RTL_CONSTASCII_USTRINGPARAM("&underbar;")));
1193cdf0e10cSrcweir #else
1194cdf0e10cSrcweir             sal_Unicode nArse[2] = {0x0332,0x00};
1195cdf0e10cSrcweir #endif
1196cdf0e10cSrcweir             GetDocHandler()->characters(nArse);
1197cdf0e10cSrcweir             }
1198cdf0e10cSrcweir             break;
1199cdf0e10cSrcweir         case TOVERSTRIKE:
1200cdf0e10cSrcweir             break;
1201cdf0e10cSrcweir         default:
1202cdf0e10cSrcweir             ExportNodes(pNode->GetSubNode(0), nLevel+1);
1203cdf0e10cSrcweir             break;
1204cdf0e10cSrcweir     }
1205cdf0e10cSrcweir     delete pElement;
1206cdf0e10cSrcweir }
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir static bool lcl_HasEffectOnMathvariant( const SmTokenType eType )
1209cdf0e10cSrcweir {
1210cdf0e10cSrcweir     return  eType == TBOLD || eType == TNBOLD ||
1211cdf0e10cSrcweir             eType == TITALIC || eType == TNBOLD ||
1212cdf0e10cSrcweir             eType == TSANS || eType == TSERIF || eType == TFIXED;
1213cdf0e10cSrcweir }
1214cdf0e10cSrcweir 
1215cdf0e10cSrcweir void SmXMLExport::ExportFont(const SmNode *pNode, int nLevel)
1216cdf0e10cSrcweir {
1217cdf0e10cSrcweir     SvXMLElementExport *pElement = 0;
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir     //
1220cdf0e10cSrcweir     // gather the mathvariant attribut relevant data from all
1221cdf0e10cSrcweir     // successively following SmFontNodes...
1222cdf0e10cSrcweir     //
1223cdf0e10cSrcweir     int nBold   = -1;   // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1224cdf0e10cSrcweir     int nItalic = -1;   // for the following variables: -1 = yet undefined; 0 = false; 1 = true;
1225cdf0e10cSrcweir     int nSansSerifFixed   = -1;
1226cdf0e10cSrcweir     SmTokenType eNodeType = TUNKNOWN;
1227cdf0e10cSrcweir     while (lcl_HasEffectOnMathvariant( (eNodeType = pNode->GetToken().eType) ))
1228cdf0e10cSrcweir     {
1229cdf0e10cSrcweir         switch (eNodeType)
1230cdf0e10cSrcweir         {
1231cdf0e10cSrcweir             case TBOLD      : nBold   = 1; break;
1232cdf0e10cSrcweir             case TNBOLD     : nBold   = 0; break;
1233cdf0e10cSrcweir             case TITALIC    : nItalic = 1; break;
1234cdf0e10cSrcweir             case TNITALIC   : nItalic = 0; break;
1235cdf0e10cSrcweir             case TSANS      : nSansSerifFixed  = 0; break;
1236cdf0e10cSrcweir             case TSERIF     : nSansSerifFixed  = 1; break;
1237cdf0e10cSrcweir             case TFIXED     : nSansSerifFixed  = 2; break;
1238cdf0e10cSrcweir             default:
1239cdf0e10cSrcweir                 DBG_ASSERT( 0, "unexpected case" );
1240cdf0e10cSrcweir         }
1241cdf0e10cSrcweir         // According to the parser every node that is to be evaluated heres
1242cdf0e10cSrcweir         // has a single non-zero subnode at index 1!! Thus we only need to check
1243cdf0e10cSrcweir         // that single node for follow-up nodes that have an effect on the attribute.
1244cdf0e10cSrcweir         if (pNode->GetNumSubNodes() > 1 && pNode->GetSubNode(1) &&
1245cdf0e10cSrcweir             lcl_HasEffectOnMathvariant( pNode->GetSubNode(1)->GetToken().eType))
1246cdf0e10cSrcweir         {
1247cdf0e10cSrcweir             pNode = pNode->GetSubNode(1);
1248cdf0e10cSrcweir         }
1249cdf0e10cSrcweir         else
1250cdf0e10cSrcweir             break;
1251cdf0e10cSrcweir     }
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir     switch (pNode->GetToken().eType)
1254cdf0e10cSrcweir     {
1255cdf0e10cSrcweir         //wrap a phantom element around everything*/
1256cdf0e10cSrcweir         case TPHANTOM:
1257cdf0e10cSrcweir             pElement = new SvXMLElementExport(*this, XML_NAMESPACE_MATH,
1258cdf0e10cSrcweir                 XML_MPHANTOM, sal_True,sal_True);
1259cdf0e10cSrcweir             break;
1260cdf0e10cSrcweir         case TBLACK:
1261cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLACK);
1262cdf0e10cSrcweir             break;
1263cdf0e10cSrcweir         case TWHITE:
1264cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_WHITE);
1265cdf0e10cSrcweir             break;
1266cdf0e10cSrcweir         case TRED:
1267cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_RED);
1268cdf0e10cSrcweir             break;
1269cdf0e10cSrcweir         case TGREEN:
1270cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_GREEN);
1271cdf0e10cSrcweir             break;
1272cdf0e10cSrcweir         case TBLUE:
1273cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_BLUE);
1274cdf0e10cSrcweir             break;
1275cdf0e10cSrcweir         case TCYAN:
1276cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_AQUA);
1277cdf0e10cSrcweir             break;
1278cdf0e10cSrcweir         case TMAGENTA:
1279cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_FUCHSIA);
1280cdf0e10cSrcweir             break;
1281cdf0e10cSrcweir         case TYELLOW:
1282cdf0e10cSrcweir             AddAttribute(XML_NAMESPACE_MATH, XML_COLOR, XML_YELLOW);
1283cdf0e10cSrcweir             break;
1284cdf0e10cSrcweir         case TSIZE:
1285cdf0e10cSrcweir             {
1286cdf0e10cSrcweir                 const SmFontNode *pFontNode = static_cast<const SmFontNode *>(pNode);
1287cdf0e10cSrcweir                 const Fraction &aFrac = pFontNode->GetSizeParameter();
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir                 OUStringBuffer sStrBuf;
1290cdf0e10cSrcweir                 switch(pFontNode->GetSizeType())
1291cdf0e10cSrcweir                 {
1292cdf0e10cSrcweir                     case FNTSIZ_MULTIPLY:
1293cdf0e10cSrcweir                         SvXMLUnitConverter::convertDouble(sStrBuf,
1294cdf0e10cSrcweir                             static_cast<double>(aFrac*Fraction(100.00)));
1295cdf0e10cSrcweir                         sStrBuf.append(static_cast<sal_Unicode>('%'));
1296cdf0e10cSrcweir                         break;
1297cdf0e10cSrcweir                     case FNTSIZ_DIVIDE:
1298cdf0e10cSrcweir                         SvXMLUnitConverter::convertDouble(sStrBuf,
1299cdf0e10cSrcweir                             static_cast<double>(Fraction(100.00)/aFrac));
1300cdf0e10cSrcweir                         sStrBuf.append(static_cast<sal_Unicode>('%'));
1301cdf0e10cSrcweir                         break;
1302cdf0e10cSrcweir                     case FNTSIZ_ABSOLUT:
1303cdf0e10cSrcweir                         SvXMLUnitConverter::convertDouble(sStrBuf,
1304cdf0e10cSrcweir                             static_cast<double>(aFrac));
1305cdf0e10cSrcweir                         sStrBuf.append(
1306cdf0e10cSrcweir                             GetXMLToken(XML_UNIT_PT));
1307cdf0e10cSrcweir                         break;
1308cdf0e10cSrcweir                     default:
1309cdf0e10cSrcweir                         {
1310cdf0e10cSrcweir                             //The problem here is that the wheels fall off because
1311cdf0e10cSrcweir                             //font size is stored in 100th's of a mm not pts, and
1312cdf0e10cSrcweir                             //rounding errors take their toll on the original
1313cdf0e10cSrcweir                             //value specified in points.
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir                             //Must fix StarMath to retain the original pt values
1316cdf0e10cSrcweir                             Fraction aTemp = Sm100th_mmToPts(pFontNode->GetFont().
1317cdf0e10cSrcweir                                 GetSize().Height());
1318cdf0e10cSrcweir 
1319cdf0e10cSrcweir                             if (pFontNode->GetSizeType() == FNTSIZ_MINUS)
1320cdf0e10cSrcweir                                 aTemp-=aFrac;
1321cdf0e10cSrcweir                             else
1322cdf0e10cSrcweir                                 aTemp+=aFrac;
1323cdf0e10cSrcweir 
1324cdf0e10cSrcweir                             double mytest = static_cast<double>(aTemp);
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir                             mytest = ::rtl::math::round(mytest,1);
1327cdf0e10cSrcweir                             SvXMLUnitConverter::convertDouble(sStrBuf,mytest);
1328cdf0e10cSrcweir                             sStrBuf.append(GetXMLToken(XML_UNIT_PT));
1329cdf0e10cSrcweir                         }
1330cdf0e10cSrcweir                         break;
1331cdf0e10cSrcweir                 }
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir                 OUString sStr(sStrBuf.makeStringAndClear());
1334cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHSIZE, sStr);
1335cdf0e10cSrcweir             }
1336cdf0e10cSrcweir             break;
1337cdf0e10cSrcweir         case TBOLD:
1338cdf0e10cSrcweir         case TITALIC:
1339cdf0e10cSrcweir         case TNBOLD:
1340cdf0e10cSrcweir         case TNITALIC:
1341cdf0e10cSrcweir         case TFIXED:
1342cdf0e10cSrcweir         case TSANS:
1343cdf0e10cSrcweir         case TSERIF:
1344cdf0e10cSrcweir             {
1345cdf0e10cSrcweir                 // nBold:   -1 = yet undefined; 0 = false; 1 = true;
1346cdf0e10cSrcweir                 // nItalic: -1 = yet undefined; 0 = false; 1 = true;
1347cdf0e10cSrcweir                 // nSansSerifFixed: -1 = undefined; 0 = sans; 1 = serif; 2 = fixed;
1348cdf0e10cSrcweir                 const sal_Char *pText = "normal";
1349cdf0e10cSrcweir                 if (nSansSerifFixed == -1 || nSansSerifFixed == 1)
1350cdf0e10cSrcweir                 {
1351cdf0e10cSrcweir                     pText = "normal";
1352cdf0e10cSrcweir                     if (nBold == 1 && nItalic != 1)
1353cdf0e10cSrcweir                         pText = "bold";
1354cdf0e10cSrcweir                     else if (nBold != 1 && nItalic == 1)
1355cdf0e10cSrcweir                         pText = "italic";
1356cdf0e10cSrcweir                     else if (nBold == 1 && nItalic == 1)
1357cdf0e10cSrcweir                         pText = "bold-italic";
1358cdf0e10cSrcweir                 }
1359cdf0e10cSrcweir                 else if (nSansSerifFixed == 0)
1360cdf0e10cSrcweir                 {
1361cdf0e10cSrcweir                     pText = "sans-serif";
1362cdf0e10cSrcweir                     if (nBold == 1 && nItalic != 1)
1363cdf0e10cSrcweir                         pText = "bold-sans-serif";
1364cdf0e10cSrcweir                     else if (nBold != 1 && nItalic == 1)
1365cdf0e10cSrcweir                         pText = "sans-serif-italic";
1366cdf0e10cSrcweir                     else if (nBold == 1 && nItalic == 1)
1367cdf0e10cSrcweir                         pText = "sans-serif-bold-italic";
1368cdf0e10cSrcweir                 }
1369cdf0e10cSrcweir                 else if (nSansSerifFixed == 2)
1370cdf0e10cSrcweir                     pText = "monospace";    // no modifiers allowed for monospace ...
1371cdf0e10cSrcweir                 else
1372cdf0e10cSrcweir                 {
1373cdf0e10cSrcweir                     DBG_ASSERT( 0, "unexpected case" );
1374cdf0e10cSrcweir                 }
1375cdf0e10cSrcweir                 AddAttribute(XML_NAMESPACE_MATH, XML_MATHVARIANT, A2OU(pText));
1376cdf0e10cSrcweir             }
1377cdf0e10cSrcweir             break;
1378cdf0e10cSrcweir         default:
1379cdf0e10cSrcweir             break;
1380cdf0e10cSrcweir 
1381cdf0e10cSrcweir     }
1382cdf0e10cSrcweir #if 0
1383cdf0e10cSrcweir     if (pNode->GetNumSubNodes() > 1) //or in the future is a node that
1384cdf0e10cSrcweir                                      //cannot take the currently supported
1385cdf0e10cSrcweir                                      //properties
1386cdf0e10cSrcweir #endif
1387cdf0e10cSrcweir     //for now we will just always export with a style and not worry about
1388cdf0e10cSrcweir     //anyone else for the moment.
1389cdf0e10cSrcweir     {
1390cdf0e10cSrcweir         //wrap a style around it
1391cdf0e10cSrcweir         SvXMLElementExport aStyle(*this, XML_NAMESPACE_MATH, XML_MSTYLE, sal_True,sal_True);
1392cdf0e10cSrcweir         ExportExpression(pNode, nLevel);
1393cdf0e10cSrcweir     }
1394cdf0e10cSrcweir #if 0
1395cdf0e10cSrcweir     else
1396cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel+1);
1397cdf0e10cSrcweir #endif
1398cdf0e10cSrcweir 
1399cdf0e10cSrcweir     delete pElement;
1400cdf0e10cSrcweir }
1401cdf0e10cSrcweir 
1402cdf0e10cSrcweir 
1403cdf0e10cSrcweir void SmXMLExport::ExportVerticalBrace(const SmNode *pNode, int nLevel)
1404cdf0e10cSrcweir {
1405cdf0e10cSrcweir     //Place the overbrace value OVER a vertical brace and then place that
1406cdf0e10cSrcweir     //expression OVER the overbrace value, If someone can find a
1407cdf0e10cSrcweir     //dedicated term in MathML to handle this overbrace/underbrace concept
1408cdf0e10cSrcweir     //let me know. C.
1409cdf0e10cSrcweir     XMLTokenEnum which;
1410cdf0e10cSrcweir 
1411cdf0e10cSrcweir     switch (pNode->GetToken().eType)
1412cdf0e10cSrcweir     {
1413cdf0e10cSrcweir         case TOVERBRACE:
1414cdf0e10cSrcweir         default:
1415cdf0e10cSrcweir             which = XML_MOVER;
1416cdf0e10cSrcweir             break;
1417cdf0e10cSrcweir         case TUNDERBRACE:
1418cdf0e10cSrcweir             which = XML_MUNDER;
1419cdf0e10cSrcweir             break;
1420cdf0e10cSrcweir     }
1421cdf0e10cSrcweir 
1422cdf0e10cSrcweir     DBG_ASSERT(pNode->GetNumSubNodes()==3,"Bad Vertical Brace");
1423cdf0e10cSrcweir     SvXMLElementExport aOver1(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
1424cdf0e10cSrcweir     {//Scoping
1425cdf0e10cSrcweir         // using accents will draw the over-/underbraces too close to the base
1426cdf0e10cSrcweir         // see http://www.w3.org/TR/MathML2/chapter3.html#id.3.4.5.2
1427cdf0e10cSrcweir         // also XML_ACCENT is illegal with XML_MUNDER. Thus no XML_ACCENT attribut here!
1428cdf0e10cSrcweir //        AddAttribute(XML_NAMESPACE_MATH, XML_ACCENT, XML_sal_True);
1429cdf0e10cSrcweir         SvXMLElementExport aOver2(*this, XML_NAMESPACE_MATH,which, sal_True, sal_True);
1430cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(0), nLevel);
1431cdf0e10cSrcweir         ExportNodes(pNode->GetSubNode(1), nLevel);
1432cdf0e10cSrcweir     }
1433cdf0e10cSrcweir     ExportNodes(pNode->GetSubNode(2), nLevel);
1434cdf0e10cSrcweir }
1435cdf0e10cSrcweir 
1436cdf0e10cSrcweir void SmXMLExport::ExportMatrix(const SmNode *pNode, int nLevel)
1437cdf0e10cSrcweir {
1438cdf0e10cSrcweir     SvXMLElementExport aTable(*this, XML_NAMESPACE_MATH, XML_MTABLE, sal_True, sal_True);
1439cdf0e10cSrcweir     const SmMatrixNode *pMatrix = static_cast<const SmMatrixNode *>(pNode);
1440cdf0e10cSrcweir     sal_uInt16 i=0;
1441cdf0e10cSrcweir     for (sal_uLong y = 0; y < pMatrix->GetNumRows(); y++)
1442cdf0e10cSrcweir     {
1443cdf0e10cSrcweir         SvXMLElementExport aRow(*this, XML_NAMESPACE_MATH, XML_MTR, sal_True, sal_True);
1444cdf0e10cSrcweir         for (sal_uLong x = 0; x < pMatrix->GetNumCols(); x++)
1445cdf0e10cSrcweir             if (const SmNode *pTemp = pNode->GetSubNode(i++))
1446cdf0e10cSrcweir             {
1447cdf0e10cSrcweir                 SvXMLElementExport aCell(*this, XML_NAMESPACE_MATH, XML_MTD, sal_True, sal_True);
1448cdf0e10cSrcweir                 ExportNodes(pTemp, nLevel+1);
1449cdf0e10cSrcweir             }
1450cdf0e10cSrcweir     }
1451cdf0e10cSrcweir }
1452cdf0e10cSrcweir 
1453cdf0e10cSrcweir void SmXMLExport::ExportNodes(const SmNode *pNode, int nLevel)
1454cdf0e10cSrcweir {
1455cdf0e10cSrcweir     if (!pNode)
1456cdf0e10cSrcweir         return;
1457cdf0e10cSrcweir     switch(pNode->GetType())
1458cdf0e10cSrcweir     {
1459cdf0e10cSrcweir         case NTABLE:
1460cdf0e10cSrcweir             ExportTable(pNode, nLevel);
1461cdf0e10cSrcweir             break;
1462cdf0e10cSrcweir         case NALIGN:
1463cdf0e10cSrcweir         case NBRACEBODY:
1464cdf0e10cSrcweir         case NEXPRESSION:
1465cdf0e10cSrcweir             ExportExpression(pNode, nLevel);
1466cdf0e10cSrcweir             break;
1467cdf0e10cSrcweir         case NLINE:
1468cdf0e10cSrcweir             ExportLine(pNode, nLevel);
1469cdf0e10cSrcweir             break;
1470cdf0e10cSrcweir         case NTEXT:
1471cdf0e10cSrcweir             ExportText(pNode, nLevel);
1472cdf0e10cSrcweir             break;
1473cdf0e10cSrcweir         case NSPECIAL: //NSPECIAL requires some sort of Entity preservation in the XML engine.
1474cdf0e10cSrcweir         case NGLYPH_SPECIAL:
1475cdf0e10cSrcweir         case NMATH:
1476cdf0e10cSrcweir             {
1477cdf0e10cSrcweir                 sal_Unicode cTmp = 0;
1478cdf0e10cSrcweir                 const SmTextNode *pTemp = static_cast< const SmTextNode * >(pNode);
1479cdf0e10cSrcweir                 if (pTemp->GetText().Len() > 0)
1480cdf0e10cSrcweir                     cTmp = ConvertMathToMathML( pTemp->GetText().GetChar(0) );
1481cdf0e10cSrcweir                 if (cTmp == 0)
1482cdf0e10cSrcweir                 {
1483cdf0e10cSrcweir                     // no conversion to MathML implemented -> export it as text
1484cdf0e10cSrcweir                     // thus at least it will not vanish into nothing
1485cdf0e10cSrcweir                     ExportText(pNode, nLevel);
1486cdf0e10cSrcweir                 }
1487cdf0e10cSrcweir                 else
1488cdf0e10cSrcweir                 {
1489cdf0e10cSrcweir                     //To fully handle generic MathML we need to implement the full
1490cdf0e10cSrcweir                     //operator dictionary, we will generate MathML with explicit
1491cdf0e10cSrcweir                     //stretchiness for now.
1492cdf0e10cSrcweir                     sal_Int16 nLength = GetAttrList().getLength();
1493cdf0e10cSrcweir                     sal_Bool bAddStretch=sal_True;
1494cdf0e10cSrcweir                     for ( sal_Int16 i = 0; i < nLength; i++ )
1495cdf0e10cSrcweir                     {
1496cdf0e10cSrcweir                         OUString sLocalName;
1497cdf0e10cSrcweir                         sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName(
1498cdf0e10cSrcweir                             GetAttrList().getNameByIndex(i), &sLocalName );
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir                         if ( ( XML_NAMESPACE_MATH == nPrefix ) &&
1501cdf0e10cSrcweir                             IsXMLToken(sLocalName, XML_STRETCHY) )
1502cdf0e10cSrcweir                         {
1503cdf0e10cSrcweir                             bAddStretch = sal_False;
1504cdf0e10cSrcweir                             break;
1505cdf0e10cSrcweir                         }
1506cdf0e10cSrcweir                     }
1507cdf0e10cSrcweir                     if (bAddStretch)
1508cdf0e10cSrcweir                     {
1509cdf0e10cSrcweir                         AddAttribute(XML_NAMESPACE_MATH, XML_STRETCHY, XML_FALSE);
1510cdf0e10cSrcweir                     }
1511cdf0e10cSrcweir                     ExportMath(pNode, nLevel);
1512cdf0e10cSrcweir                 }
1513cdf0e10cSrcweir             }
1514cdf0e10cSrcweir             break;
1515cdf0e10cSrcweir         case NPLACE:
1516cdf0e10cSrcweir             ExportMath(pNode, nLevel);
1517cdf0e10cSrcweir             break;
1518cdf0e10cSrcweir         case NBINHOR:
1519cdf0e10cSrcweir             ExportBinaryHorizontal(pNode, nLevel);
1520cdf0e10cSrcweir             break;
1521cdf0e10cSrcweir         case NUNHOR:
1522cdf0e10cSrcweir             ExportUnaryHorizontal(pNode, nLevel);
1523cdf0e10cSrcweir             break;
1524cdf0e10cSrcweir         case NBRACE:
1525cdf0e10cSrcweir             ExportBrace(pNode, nLevel);
1526cdf0e10cSrcweir             break;
1527cdf0e10cSrcweir         case NBINVER:
1528cdf0e10cSrcweir             ExportBinaryVertical(pNode, nLevel);
1529cdf0e10cSrcweir             break;
1530cdf0e10cSrcweir         case NSUBSUP:
1531cdf0e10cSrcweir             ExportSubSupScript(pNode, nLevel);
1532cdf0e10cSrcweir             break;
1533cdf0e10cSrcweir         case NROOT:
1534cdf0e10cSrcweir             ExportRoot(pNode, nLevel);
1535cdf0e10cSrcweir             break;
1536cdf0e10cSrcweir         case NOPER:
1537cdf0e10cSrcweir             ExportOperator(pNode, nLevel);
1538cdf0e10cSrcweir             break;
1539cdf0e10cSrcweir         case NATTRIBUT:
1540cdf0e10cSrcweir             ExportAttributes(pNode, nLevel);
1541cdf0e10cSrcweir             break;
1542cdf0e10cSrcweir         case NFONT:
1543cdf0e10cSrcweir             ExportFont(pNode, nLevel);
1544cdf0e10cSrcweir             break;
1545cdf0e10cSrcweir         case NVERTICAL_BRACE:
1546cdf0e10cSrcweir             ExportVerticalBrace(pNode, nLevel);
1547cdf0e10cSrcweir             break;
1548cdf0e10cSrcweir         case NMATRIX:
1549cdf0e10cSrcweir             ExportMatrix(pNode, nLevel);
1550cdf0e10cSrcweir             break;
1551cdf0e10cSrcweir         case NBLANK:
1552cdf0e10cSrcweir             ExportBlank(pNode, nLevel);
1553cdf0e10cSrcweir             break;
1554cdf0e10cSrcweir        default:
1555cdf0e10cSrcweir             DBG_ASSERT( 0, "Warning: failed to export a node?" );
1556cdf0e10cSrcweir             break;
1557cdf0e10cSrcweir 
1558cdf0e10cSrcweir #if 0
1559cdf0e10cSrcweir         default:
1560cdf0e10cSrcweir             {
1561cdf0e10cSrcweir             sal_uLong  nSize = pNode->GetNumSubNodes();
1562cdf0e10cSrcweir             for (sal_uLong i = 0; i < nSize; i++)
1563cdf0e10cSrcweir                 if (SmNode *pTemp = pNode->GetSubNode(i))
1564cdf0e10cSrcweir                     ExportNodes(pTemp, nLevel+1);
1565cdf0e10cSrcweir             }
1566cdf0e10cSrcweir             break;
1567cdf0e10cSrcweir #endif
1568cdf0e10cSrcweir     }
1569cdf0e10cSrcweir }
1570cdf0e10cSrcweir 
1571cdf0e10cSrcweir ////////////////////////////////////////////////////////////
1572cdf0e10cSrcweir 
1573