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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_starmath.hxx"
26
27 /*todo: Change characters and tcharacters to accumulate the characters together
28 into one string, xml parser hands them to us line by line rather than all in
29 one go*/
30
31 #include <com/sun/star/xml/sax/XErrorHandler.hpp>
32 #include <com/sun/star/xml/sax/XEntityResolver.hpp>
33 #include <com/sun/star/xml/sax/InputSource.hpp>
34 #include <com/sun/star/xml/sax/XDTDHandler.hpp>
35 #include <com/sun/star/xml/sax/XParser.hpp>
36 #include <com/sun/star/io/XActiveDataSource.hpp>
37 #include <com/sun/star/io/XActiveDataControl.hpp>
38 #include <com/sun/star/document/XDocumentProperties.hpp>
39 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
40 #include <com/sun/star/packages/zip/ZipIOException.hpp>
41 #include <com/sun/star/task/XStatusIndicatorFactory.hpp>
42 #include <com/sun/star/beans/PropertyAttribute.hpp>
43 #include <com/sun/star/container/XNameAccess.hpp>
44 #include <com/sun/star/embed/ElementModes.hpp>
45 #include <com/sun/star/uno/Any.h>
46
47 #include <rtl/math.hxx>
48 #include <sfx2/frame.hxx>
49 #include <sfx2/docfile.hxx>
50 #include <tools/debug.hxx>
51 #include <tools/urlobj.hxx>
52 #include <svtools/sfxecode.hxx>
53 #include <unotools/saveopt.hxx>
54 #include <svl/stritem.hxx>
55 #include <svl/itemprop.hxx>
56 #include <unotools/processfactory.hxx>
57 #include <unotools/streamwrap.hxx>
58 #include <xmloff/xmlnmspe.hxx>
59 #include <xmloff/xmltoken.hxx>
60 #include <xmloff/nmspmap.hxx>
61 #include <xmloff/attrlist.hxx>
62 #include <xmloff/xmluconv.hxx>
63 #include <xmloff/xmlmetai.hxx>
64 #include <osl/mutex.hxx>
65 #include <comphelper/genericpropertyset.hxx>
66
67 #include <memory>
68
69 #include "mathmlimport.hxx"
70 #include <starmath.hrc>
71 #include <unomodel.hxx>
72 #include <document.hxx>
73 #include <utility.hxx>
74
75 using namespace ::com::sun::star::beans;
76 using namespace ::com::sun::star::container;
77 using namespace ::com::sun::star::document;
78 using namespace ::com::sun::star::lang;
79 using namespace ::com::sun::star::uno;
80 using namespace ::com::sun::star;
81 using namespace ::xmloff::token;
82
83 using ::rtl::OUString;
84 using ::rtl::OUStringBuffer;
85
86 #define IMPORT_SVC_NAME RTL_CONSTASCII_USTRINGPARAM("com.sun.star.xml.XMLImportFilter")
87
88 #undef WANTEXCEPT
89
90 ////////////////////////////////////////////////////////////
91
Import(SfxMedium & rMedium)92 sal_uLong SmXMLImportWrapper::Import(SfxMedium &rMedium)
93 {
94 sal_uLong nError = ERRCODE_SFX_DOLOADFAILED;
95
96 uno::Reference<lang::XMultiServiceFactory> xServiceFactory(
97 utl::getProcessServiceFactory());
98 DBG_ASSERT(xServiceFactory.is(), "XMLReader::Read: got no service manager");
99 if ( !xServiceFactory.is() )
100 return nError;
101
102 //Make a model component from our SmModel
103 uno::Reference< lang::XComponent > xModelComp( xModel, uno::UNO_QUERY );
104 DBG_ASSERT( xModelComp.is(), "XMLReader::Read: got no model" );
105
106 // try to get an XStatusIndicator from the Medium
107 uno::Reference<task::XStatusIndicator> xStatusIndicator;
108
109 sal_Bool bEmbedded = sal_False;
110 uno::Reference <lang::XUnoTunnel> xTunnel;
111 xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
112 SmModel *pModel = reinterpret_cast<SmModel *>
113 (xTunnel->getSomething(SmModel::getUnoTunnelId()));
114
115 SmDocShell *pDocShell = pModel ?
116 static_cast<SmDocShell*>(pModel->GetObjectShell()) : 0;
117 if (pDocShell)
118 {
119 // if (pDocShell->GetMedium())
120 {
121 DBG_ASSERT( pDocShell->GetMedium() == &rMedium,
122 "different SfxMedium found" );
123
124 SfxItemSet* pSet = rMedium.GetItemSet();
125 if (pSet)
126 {
127 const SfxUnoAnyItem* pItem = static_cast<const SfxUnoAnyItem*>(
128 pSet->GetItem(SID_PROGRESS_STATUSBAR_CONTROL) );
129 if (pItem)
130 pItem->GetValue() >>= xStatusIndicator;
131 }
132 }
133
134 if ( SFX_CREATE_MODE_EMBEDDED == pDocShell->GetCreateMode() )
135 bEmbedded = sal_True;
136 }
137
138 comphelper::PropertyMapEntry aInfoMap[] =
139 {
140 { "PrivateData", sizeof("PrivateData")-1, 0,
141 &::getCppuType( (Reference<XInterface> *)0 ),
142 beans::PropertyAttribute::MAYBEVOID, 0 },
143 { "BaseURI", sizeof("BaseURI")-1, 0,
144 &::getCppuType( (OUString *)0 ),
145 beans::PropertyAttribute::MAYBEVOID, 0 },
146 { "StreamRelPath", sizeof("StreamRelPath")-1, 0,
147 &::getCppuType( (OUString *)0 ),
148 beans::PropertyAttribute::MAYBEVOID, 0 },
149 { "StreamName", sizeof("StreamName")-1, 0,
150 &::getCppuType( (OUString *)0 ),
151 beans::PropertyAttribute::MAYBEVOID, 0 },
152 { NULL, 0, 0, NULL, 0, 0 }
153 };
154 uno::Reference< beans::XPropertySet > xInfoSet(
155 comphelper::GenericPropertySet_CreateInstance(
156 new comphelper::PropertySetInfo( aInfoMap ) ) );
157
158 // Set base URI
159 OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("BaseURI") );
160 xInfoSet->setPropertyValue( sPropName, makeAny( rMedium.GetBaseURL() ) );
161
162 sal_Int32 nSteps=3;
163 if ( !(rMedium.IsStorage()))
164 nSteps = 1;
165
166 sal_Int32 nProgressRange(nSteps);
167 if (xStatusIndicator.is())
168 {
169 xStatusIndicator->start(String(SmResId(STR_STATSTR_READING)),
170 nProgressRange);
171 }
172
173 nSteps=0;
174 if (xStatusIndicator.is())
175 xStatusIndicator->setValue(nSteps++);
176
177 if ( rMedium.IsStorage())
178 {
179 // TODO/LATER: handle the case of embedded links gracefully
180 if ( bEmbedded ) // && !rMedium.GetStorage()->IsRoot() )
181 {
182 OUString aName( RTL_CONSTASCII_USTRINGPARAM( "dummyObjName" ) );
183 if ( rMedium.GetItemSet() )
184 {
185 const SfxStringItem* pDocHierarchItem = static_cast<const SfxStringItem*>(
186 rMedium.GetItemSet()->GetItem(SID_DOC_HIERARCHICALNAME) );
187 if ( pDocHierarchItem )
188 aName = pDocHierarchItem->GetValue();
189 }
190
191 if ( aName.getLength() )
192 {
193 sPropName = OUString(RTL_CONSTASCII_USTRINGPARAM("StreamRelPath"));
194 xInfoSet->setPropertyValue( sPropName, makeAny( aName ) );
195 }
196 }
197
198 sal_Bool bOASIS = ( SotStorage::GetVersion( rMedium.GetStorage() ) > SOFFICE_FILEFORMAT_60 );
199 if (xStatusIndicator.is())
200 xStatusIndicator->setValue(nSteps++);
201
202 sal_uLong nWarn = ReadThroughComponent(
203 rMedium.GetStorage(), xModelComp, "meta.xml", "Meta.xml",
204 xServiceFactory, xInfoSet,
205 (bOASIS ? "com.sun.star.comp.Math.XMLOasisMetaImporter"
206 : "com.sun.star.comp.Math.XMLMetaImporter") );
207
208 if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
209 {
210 if (xStatusIndicator.is())
211 xStatusIndicator->setValue(nSteps++);
212
213 nWarn = ReadThroughComponent(
214 rMedium.GetStorage(), xModelComp, "settings.xml", 0,
215 xServiceFactory, xInfoSet,
216 (bOASIS ? "com.sun.star.comp.Math.XMLOasisSettingsImporter"
217 : "com.sun.star.comp.Math.XMLSettingsImporter" ) );
218
219 if ( nWarn != ERRCODE_IO_BROKENPACKAGE )
220 {
221 if (xStatusIndicator.is())
222 xStatusIndicator->setValue(nSteps++);
223
224 nError = ReadThroughComponent(
225 rMedium.GetStorage(), xModelComp, "content.xml", "Content.xml",
226 xServiceFactory, xInfoSet, "com.sun.star.comp.Math.XMLImporter" );
227 }
228 else
229 nError = ERRCODE_IO_BROKENPACKAGE;
230 }
231 else
232 nError = ERRCODE_IO_BROKENPACKAGE;
233 }
234 else
235 {
236 Reference<io::XInputStream> xInputStream =
237 new utl::OInputStreamWrapper(rMedium.GetInStream());
238
239 if (xStatusIndicator.is())
240 xStatusIndicator->setValue(nSteps++);
241
242 nError = ReadThroughComponent( xInputStream, xModelComp,
243 xServiceFactory, xInfoSet, "com.sun.star.comp.Math.XMLImporter", sal_False );
244 }
245
246 if (xStatusIndicator.is())
247 xStatusIndicator->end();
248 return nError;
249 }
250
251
252 /// read a component (file + filter version)
ReadThroughComponent(Reference<io::XInputStream> xInputStream,Reference<XComponent> xModelComponent,Reference<lang::XMultiServiceFactory> & rFactory,Reference<beans::XPropertySet> & rPropSet,const sal_Char * pFilterName,sal_Bool bEncrypted)253 sal_uLong SmXMLImportWrapper::ReadThroughComponent(
254 Reference<io::XInputStream> xInputStream,
255 Reference<XComponent> xModelComponent,
256 Reference<lang::XMultiServiceFactory> & rFactory,
257 Reference<beans::XPropertySet> & rPropSet,
258 const sal_Char* pFilterName,
259 sal_Bool bEncrypted )
260 {
261 sal_uLong nError = ERRCODE_SFX_DOLOADFAILED;
262 DBG_ASSERT(xInputStream.is(), "input stream missing");
263 DBG_ASSERT(xModelComponent.is(), "document missing");
264 DBG_ASSERT(rFactory.is(), "factory missing");
265 DBG_ASSERT(NULL != pFilterName,"I need a service name for the component!");
266
267 // prepare ParserInputSrouce
268 xml::sax::InputSource aParserInput;
269 aParserInput.aInputStream = xInputStream;
270
271 // get parser
272 Reference< xml::sax::XParser > xParser(
273 rFactory->createInstance(
274 OUString::createFromAscii("com.sun.star.xml.sax.Parser") ),
275 UNO_QUERY );
276 DBG_ASSERT( xParser.is(), "Can't create parser" );
277 if ( !xParser.is() )
278 return nError;
279
280 Sequence<Any> aArgs( 1 );
281 aArgs[0] <<= rPropSet;
282
283 // get filter
284 Reference< xml::sax::XDocumentHandler > xFilter(
285 rFactory->createInstanceWithArguments(
286 OUString::createFromAscii(pFilterName), aArgs ),
287 UNO_QUERY );
288 DBG_ASSERT( xFilter.is(), "Can't instantiate filter component." );
289 if ( !xFilter.is() )
290 return nError;
291
292 // connect parser and filter
293 xParser->setDocumentHandler( xFilter );
294
295 // connect model and filter
296 Reference < XImporter > xImporter( xFilter, UNO_QUERY );
297 xImporter->setTargetDocument( xModelComponent );
298
299 // finally, parser the stream
300 try
301 {
302 xParser->parseStream( aParserInput );
303
304 uno::Reference<lang::XUnoTunnel> xFilterTunnel;
305 xFilterTunnel = uno::Reference<lang::XUnoTunnel>
306 ( xFilter, uno::UNO_QUERY );
307 SmXMLImport *pFilter = reinterpret_cast< SmXMLImport * >(
308 sal::static_int_cast< sal_uIntPtr >(
309 xFilterTunnel->getSomething( SmXMLImport::getUnoTunnelId() )));
310 if ( pFilter && pFilter->GetSuccess() )
311 nError = 0;
312 }
313 catch( xml::sax::SAXParseException& r )
314 {
315 // sax parser sends wrapped exceptions,
316 // try to find the original one
317 xml::sax::SAXException aSaxEx = *(xml::sax::SAXException*)(&r);
318 sal_Bool bTryChild = sal_True;
319
320 while( bTryChild )
321 {
322 xml::sax::SAXException aTmp;
323 if ( aSaxEx.WrappedException >>= aTmp )
324 aSaxEx = aTmp;
325 else
326 bTryChild = sal_False;
327 }
328
329 packages::zip::ZipIOException aBrokenPackage;
330 if ( aSaxEx.WrappedException >>= aBrokenPackage )
331 return ERRCODE_IO_BROKENPACKAGE;
332
333 if ( bEncrypted )
334 nError = ERRCODE_SFX_WRONGPASSWORD;
335 }
336 catch( xml::sax::SAXException& r )
337 {
338 packages::zip::ZipIOException aBrokenPackage;
339 if ( r.WrappedException >>= aBrokenPackage )
340 return ERRCODE_IO_BROKENPACKAGE;
341
342 if ( bEncrypted )
343 nError = ERRCODE_SFX_WRONGPASSWORD;
344 }
345 catch( packages::zip::ZipIOException& )
346 {
347 nError = ERRCODE_IO_BROKENPACKAGE;
348 }
349 catch( io::IOException& )
350 {
351 }
352
353 return nError;
354 }
355
356
ReadThroughComponent(const uno::Reference<embed::XStorage> & xStorage,Reference<XComponent> xModelComponent,const sal_Char * pStreamName,const sal_Char * pCompatibilityStreamName,Reference<lang::XMultiServiceFactory> & rFactory,Reference<beans::XPropertySet> & rPropSet,const sal_Char * pFilterName)357 sal_uLong SmXMLImportWrapper::ReadThroughComponent(
358 const uno::Reference< embed::XStorage >& xStorage,
359 Reference<XComponent> xModelComponent,
360 const sal_Char* pStreamName,
361 const sal_Char* pCompatibilityStreamName,
362 Reference<lang::XMultiServiceFactory> & rFactory,
363 Reference<beans::XPropertySet> & rPropSet,
364 const sal_Char* pFilterName )
365 {
366 DBG_ASSERT(xStorage.is(), "Need storage!");
367 DBG_ASSERT(NULL != pStreamName, "Please, please, give me a name!");
368
369 // open stream (and set parser input)
370 OUString sStreamName = OUString::createFromAscii(pStreamName);
371 uno::Reference < container::XNameAccess > xAccess( xStorage, uno::UNO_QUERY );
372 if ( !xAccess->hasByName(sStreamName) || !xStorage->isStreamElement(sStreamName) )
373 {
374 // stream name not found! Then try the compatibility name.
375 // do we even have an alternative name?
376 if ( pCompatibilityStreamName )
377 sStreamName = OUString::createFromAscii(pCompatibilityStreamName);
378 }
379
380 // get input stream
381 try
382 {
383 uno::Reference < io::XStream > xEventsStream = xStorage->openStreamElement( sStreamName, embed::ElementModes::READ );
384
385 // determine if stream is encrypted or not
386 uno::Reference < beans::XPropertySet > xProps( xEventsStream, uno::UNO_QUERY );
387 Any aAny = xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Encrypted") ) );
388 sal_Bool bEncrypted = sal_False;
389 if ( aAny.getValueType() == ::getBooleanCppuType() )
390 aAny >>= bEncrypted;
391
392 // set Base URL
393 if ( rPropSet.is() )
394 {
395 OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamName") );
396 rPropSet->setPropertyValue( sPropName, makeAny( sStreamName ) );
397 }
398
399
400 Reference < io::XInputStream > xStream = xEventsStream->getInputStream();
401 return ReadThroughComponent( xStream, xModelComponent, rFactory, rPropSet, pFilterName, bEncrypted );
402 }
403 catch ( packages::WrongPasswordException& )
404 {
405 return ERRCODE_SFX_WRONGPASSWORD;
406 }
407 catch( packages::zip::ZipIOException& )
408 {
409 return ERRCODE_IO_BROKENPACKAGE;
410 }
411 catch ( uno::Exception& )
412 {
413 }
414
415 return ERRCODE_SFX_DOLOADFAILED;
416 }
417
418 ////////////////////////////////////////////////////////////
419
SmXMLImport(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> xServiceFactory,sal_uInt16 nImportFlags)420 SmXMLImport::SmXMLImport(
421 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceFactory,
422 sal_uInt16 nImportFlags)
423 : SvXMLImport( xServiceFactory, nImportFlags ),
424 pPresLayoutElemTokenMap(0),
425 pPresLayoutAttrTokenMap(0),
426 pFencedAttrTokenMap(0),
427 pOperatorAttrTokenMap(0),
428 pAnnotationAttrTokenMap(0),
429 pPresElemTokenMap(0),
430 pPresScriptEmptyElemTokenMap(0),
431 pPresTableElemTokenMap(0),
432 pColorTokenMap(0),
433 bSuccess(sal_False)
434 {
435 }
436
getUnoTunnelId()437 const uno::Sequence< sal_Int8 > & SmXMLImport::getUnoTunnelId() throw()
438 {
439 static uno::Sequence< sal_Int8 > * pSeq = 0;
440 if ( !pSeq )
441 {
442 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
443 if ( !pSeq )
444 {
445 static uno::Sequence< sal_Int8 > aSeq( 16 );
446 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
447 pSeq = &aSeq;
448 }
449 }
450 return *pSeq;
451 }
452
SmXMLImport_getImplementationName()453 OUString SAL_CALL SmXMLImport_getImplementationName() throw()
454 {
455 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLImporter" ) );
456 }
457
SmXMLImport_getSupportedServiceNames()458 uno::Sequence< OUString > SAL_CALL SmXMLImport_getSupportedServiceNames()
459 throw()
460 {
461 const OUString aServiceName( IMPORT_SVC_NAME );
462 const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
463 return aSeq;
464 }
465
SmXMLImport_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)466 uno::Reference< uno::XInterface > SAL_CALL SmXMLImport_createInstance(
467 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
468 {
469 // #110680#
470 // return (cppu::OWeakObject*)new SmXMLImport(IMPORT_ALL);
471 return (cppu::OWeakObject*)new SmXMLImport(rSMgr, IMPORT_ALL);
472 }
473
474 ////////////////////////////////////////////////////////////
475
SmXMLImportMeta_getImplementationName()476 OUString SAL_CALL SmXMLImportMeta_getImplementationName() throw()
477 {
478 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisMetaImporter" ) );
479 }
480
SmXMLImportMeta_getSupportedServiceNames()481 uno::Sequence< OUString > SAL_CALL SmXMLImportMeta_getSupportedServiceNames()
482 throw()
483 {
484 const OUString aServiceName( IMPORT_SVC_NAME );
485 const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
486 return aSeq;
487 }
488
SmXMLImportMeta_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)489 uno::Reference< uno::XInterface > SAL_CALL SmXMLImportMeta_createInstance(
490 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
491 {
492 // #110680#
493 // return (cppu::OWeakObject*)new SmXMLImport( IMPORT_META );
494 return (cppu::OWeakObject*)new SmXMLImport( rSMgr, IMPORT_META );
495 }
496
497 ////////////////////////////////////////////////////////////
498
SmXMLImportSettings_getImplementationName()499 OUString SAL_CALL SmXMLImportSettings_getImplementationName() throw()
500 {
501 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Math.XMLOasisSettingsImporter" ) );
502 }
503
SmXMLImportSettings_getSupportedServiceNames()504 uno::Sequence< OUString > SAL_CALL SmXMLImportSettings_getSupportedServiceNames()
505 throw()
506 {
507 const OUString aServiceName( IMPORT_SVC_NAME );
508 const uno::Sequence< OUString > aSeq( &aServiceName, 1 );
509 return aSeq;
510 }
511
SmXMLImportSettings_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)512 uno::Reference< uno::XInterface > SAL_CALL SmXMLImportSettings_createInstance(
513 const uno::Reference< lang::XMultiServiceFactory > & rSMgr)
514 {
515 // #110680#
516 // return (cppu::OWeakObject*)new SmXMLImport( IMPORT_SETTINGS );
517 return (cppu::OWeakObject*)new SmXMLImport( rSMgr, IMPORT_SETTINGS );
518 }
519
520 ////////////////////////////////////////////////////////////
521
522 // XServiceInfo
523 // override empty method from parent class
getImplementationName()524 rtl::OUString SAL_CALL SmXMLImport::getImplementationName()
525 {
526 OUString aTxt;
527 switch( getImportFlags() )
528 {
529 case IMPORT_META:
530 aTxt = SmXMLImportMeta_getImplementationName();
531 break;
532 case IMPORT_SETTINGS:
533 aTxt = SmXMLImportSettings_getImplementationName();
534 break;
535 case IMPORT_ALL:
536 default:
537 aTxt = SmXMLImport_getImplementationName();
538 break;
539 }
540 return aTxt;
541 }
542
543
getSomething(const uno::Sequence<sal_Int8> & rId)544 sal_Int64 SAL_CALL SmXMLImport::getSomething(
545 const uno::Sequence< sal_Int8 >&rId )
546 {
547 if ( rId.getLength() == 16 &&
548 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
549 rId.getConstArray(), 16 ) )
550 return sal::static_int_cast< sal_Int64 >(reinterpret_cast< sal_uIntPtr >(this));
551
552 return SvXMLImport::getSomething( rId );
553 }
554
endDocument(void)555 void SmXMLImport::endDocument(void)
556 {
557 //Set the resulted tree into the SmDocShell where it belongs
558 SmNode *pTree;
559 if (NULL != (pTree = GetTree()))
560 {
561 uno::Reference <frame::XModel> xModel = GetModel();
562 uno::Reference <lang::XUnoTunnel> xTunnel;
563 xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
564 SmModel *pModel = reinterpret_cast<SmModel *>
565 (xTunnel->getSomething(SmModel::getUnoTunnelId()));
566
567 if (pModel)
568 {
569 SmDocShell *pDocShell =
570 static_cast<SmDocShell*>(pModel->GetObjectShell());
571 pDocShell->SetFormulaTree(pTree);
572 if (0 == aText.Len()) //If we picked up no annotation text
573 {
574 // Get text from imported formula
575 pTree->CreateTextFromNode(aText);
576 aText.EraseTrailingChars();
577 }
578
579 // Convert symbol names
580 SmParser &rParser = pDocShell->GetParser();
581 sal_Bool bVal = rParser.IsImportSymbolNames();
582 rParser.SetImportSymbolNames( sal_True );
583 SmNode *pTmpTree = rParser.Parse( aText );
584 aText = rParser.GetText();
585 delete pTmpTree;
586 rParser.SetImportSymbolNames( bVal );
587
588 pDocShell->SetText( aText );
589 }
590 DBG_ASSERT(pModel,"So there *was* a uno problem after all");
591
592 bSuccess = sal_True;
593 }
594
595 SvXMLImport::endDocument();
596 }
597
598 ////////////////////////////////////////////////////////////
599
600 class SmXMLImportContext: public SvXMLImportContext
601 {
602 public:
SmXMLImportContext(SmXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLName)603 SmXMLImportContext( SmXMLImport &rImport, sal_uInt16 nPrfx,
604 const OUString& rLName)
605 : SvXMLImportContext(rImport, nPrfx, rLName) {}
606
GetSmImport() const607 const SmXMLImport& GetSmImport() const
608 {
609 return (const SmXMLImport&)GetImport();
610 }
611
GetSmImport()612 SmXMLImport& GetSmImport()
613 {
614 return (SmXMLImport&)GetImport();
615 }
616
617 virtual void TCharacters(const OUString & /*rChars*/);
618 virtual void Characters(const OUString &rChars);
619 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 /*nPrefix*/, const OUString& /*rLocalName*/, const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/);
620 };
621
TCharacters(const OUString &)622 void SmXMLImportContext::TCharacters(const OUString & /*rChars*/)
623 {
624 }
625
Characters(const OUString & rChars)626 void SmXMLImportContext::Characters(const OUString &rChars)
627 {
628 /*
629 Whitespace occurring within the content of token elements is "trimmed"
630 from the ends (i.e. all whitespace at the beginning and end of the
631 content is removed), and "collapsed" internally (i.e. each sequence of
632 1 or more whitespace characters is replaced with one blank character).
633 */
634 //collapsing not done yet!
635 const OUString &rChars2 = rChars.trim();
636 if (rChars2.getLength())
637 TCharacters(rChars2/*.collapse()*/);
638 }
639
CreateChildContext(sal_uInt16,const OUString &,const uno::Reference<xml::sax::XAttributeList> &)640 SvXMLImportContext * SmXMLImportContext::CreateChildContext(sal_uInt16 /*nPrefix*/,
641 const OUString& /*rLocalName*/,
642 const uno::Reference< xml::sax::XAttributeList > & /*xAttrList*/)
643 {
644 return 0;
645 }
646
647 ////////////////////////////////////////////////////////////
648
649 struct SmXMLContext_Helper
650 {
651 sal_Int8 nIsBold;
652 sal_Int8 nIsItalic;
653 double nFontSize;
654 sal_Bool bFontNodeNeeded;
655 OUString sFontFamily;
656 OUString sColor;
657
658 SmXMLImportContext rContext;
659
SmXMLContext_HelperSmXMLContext_Helper660 SmXMLContext_Helper(SmXMLImportContext &rImport) :
661 nIsBold(-1), nIsItalic(-1), nFontSize(0.0), rContext(rImport) {}
662
663 void RetrieveAttrs(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
664 void ApplyAttrs();
665 };
666
RetrieveAttrs(const uno::Reference<xml::sax::XAttributeList> & xAttrList)667 void SmXMLContext_Helper::RetrieveAttrs(const uno::Reference<
668 xml::sax::XAttributeList > & xAttrList )
669 {
670 sal_Int8 nOldIsBold=nIsBold;
671 sal_Int8 nOldIsItalic=nIsItalic;
672 double nOldFontSize=nFontSize;
673 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
674 OUString sOldFontFamily = sFontFamily;
675 for (sal_Int16 i=0;i<nAttrCount;i++)
676 {
677 OUString sAttrName = xAttrList->getNameByIndex(i);
678 OUString aLocalName;
679 sal_uInt16 nPrefix = rContext.GetSmImport().GetNamespaceMap().
680 GetKeyByAttrName(sAttrName,&aLocalName);
681 OUString sValue = xAttrList->getValueByIndex(i);
682 const SvXMLTokenMap &rAttrTokenMap =
683 rContext.GetSmImport().GetPresLayoutAttrTokenMap();
684 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
685 {
686 case XML_TOK_FONTWEIGHT:
687 nIsBold = sValue.equals(GetXMLToken(XML_BOLD));
688 break;
689 case XML_TOK_FONTSTYLE:
690 nIsItalic = sValue.equals(GetXMLToken(XML_ITALIC));
691 break;
692 case XML_TOK_FONTSIZE:
693 SvXMLUnitConverter::convertDouble(nFontSize,sValue);
694 rContext.GetSmImport().GetMM100UnitConverter().
695 setXMLMeasureUnit(MAP_POINT);
696 if (-1 == sValue.indexOf(GetXMLToken(XML_UNIT_PT)))
697 {
698 if (-1 == sValue.indexOf('%'))
699 nFontSize=0.0;
700 else
701 {
702 rContext.GetSmImport().GetMM100UnitConverter().
703 setXMLMeasureUnit(MAP_RELATIVE);
704 }
705 }
706 break;
707 case XML_TOK_FONTFAMILY:
708 sFontFamily = sValue;
709 break;
710 case XML_TOK_COLOR:
711 sColor = sValue;
712 break;
713 case XML_TOK_MATHCOLOR:
714 sColor = sValue;
715 break;
716 default:
717 break;
718 }
719 }
720
721 if ((nOldIsBold!=nIsBold) || (nOldIsItalic!=nIsItalic) ||
722 (nOldFontSize!=nFontSize) || (sOldFontFamily!=sFontFamily)
723 || sColor.getLength())
724 bFontNodeNeeded=sal_True;
725 else
726 bFontNodeNeeded=sal_False;
727 }
728
ApplyAttrs()729 void SmXMLContext_Helper::ApplyAttrs()
730 {
731 SmNodeStack &rNodeStack = rContext.GetSmImport().GetNodeStack();
732
733 if (bFontNodeNeeded)
734 {
735 SmToken aToken;
736 aToken.cMathChar = '\0';
737 aToken.nGroup = 0;
738 aToken.nLevel = 5;
739
740 if (nIsBold != -1)
741 {
742 if (nIsBold)
743 aToken.eType = TBOLD;
744 else
745 aToken.eType = TNBOLD;
746 SmStructureNode *pFontNode = static_cast<SmStructureNode *>
747 (new SmFontNode(aToken));
748 pFontNode->SetSubNodes(0,rNodeStack.Pop());
749 rNodeStack.Push(pFontNode);
750 }
751 if (nIsItalic != -1)
752 {
753 if (nIsItalic)
754 aToken.eType = TITALIC;
755 else
756 aToken.eType = TNITALIC;
757 SmStructureNode *pFontNode = static_cast<SmStructureNode *>
758 (new SmFontNode(aToken));
759 pFontNode->SetSubNodes(0,rNodeStack.Pop());
760 rNodeStack.Push(pFontNode);
761 }
762 if (nFontSize != 0.0)
763 {
764 aToken.eType = TSIZE;
765 SmFontNode *pFontNode = new SmFontNode(aToken);
766
767 if (MAP_RELATIVE == rContext.GetSmImport().GetMM100UnitConverter().
768 getXMLMeasureUnit())
769 {
770 if (nFontSize < 100.00)
771 pFontNode->SetSizeParameter(Fraction(100.00/nFontSize),
772 FNTSIZ_DIVIDE);
773 else
774 pFontNode->SetSizeParameter(Fraction(nFontSize/100.00),
775 FNTSIZ_MULTIPLY);
776 }
777 else
778 pFontNode->SetSizeParameter(Fraction(nFontSize),FNTSIZ_ABSOLUT);
779
780 pFontNode->SetSubNodes(0,rNodeStack.Pop());
781 rNodeStack.Push(pFontNode);
782 }
783 if (sFontFamily.getLength())
784 {
785 if (sFontFamily.equalsIgnoreAsciiCase(GetXMLToken(XML_FIXED)))
786 aToken.eType = TFIXED;
787 else if (sFontFamily.equalsIgnoreAsciiCase(OUString(
788 RTL_CONSTASCII_USTRINGPARAM("sans"))))
789 aToken.eType = TSANS;
790 else if (sFontFamily.equalsIgnoreAsciiCase(OUString(
791 RTL_CONSTASCII_USTRINGPARAM("serif"))))
792 aToken.eType = TSERIF;
793 else //Just give up, we need to extend our font mechanism to be
794 //more general
795 return;
796
797 aToken.aText = sFontFamily;
798 SmFontNode *pFontNode = new SmFontNode(aToken);
799 pFontNode->SetSubNodes(0,rNodeStack.Pop());
800 rNodeStack.Push(pFontNode);
801 }
802 if (sColor.getLength())
803 {
804 //Again we can only handle a small set of colours in
805 //StarMath for now.
806 const SvXMLTokenMap& rTokenMap =
807 rContext.GetSmImport().GetColorTokenMap();
808 aToken.eType = static_cast<SmTokenType>(rTokenMap.Get(
809 XML_NAMESPACE_MATH, sColor));
810 if (aToken.eType != -1)
811 {
812 SmFontNode *pFontNode = new SmFontNode(aToken);
813 pFontNode->SetSubNodes(0,rNodeStack.Pop());
814 rNodeStack.Push(pFontNode);
815 }
816 }
817
818 }
819 }
820
821 ////////////////////////////////////////////////////////////
822
823 class SmXMLDocContext_Impl : public SmXMLImportContext
824 {
825 public:
SmXMLDocContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLName)826 SmXMLDocContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
827 const OUString& rLName)
828 : SmXMLImportContext(rImport,nPrfx,rLName) {}
829
830 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList);
831
832 void EndElement();
833 };
834
835 ////////////////////////////////////////////////////////////
836
837 /*avert thy gaze from the proginator*/
838 class SmXMLRowContext_Impl : public SmXMLDocContext_Impl
839 {
840 protected:
841 sal_uLong nElementCount;
842
843 public:
SmXMLRowContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)844 SmXMLRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
845 const OUString& rLName)
846 : SmXMLDocContext_Impl(rImport,nPrefix,rLName)
847 { nElementCount = GetSmImport().GetNodeStack().Count(); }
848
849 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList);
850
851 SvXMLImportContext *StrictCreateChildContext(sal_uInt16 nPrefix,
852 const OUString& rLocalName,
853 const uno::Reference< xml::sax::XAttributeList > &xAttrList);
854
855 void EndElement();
856 };
857
858 ////////////////////////////////////////////////////////////
859
860 class SmXMLFracContext_Impl : public SmXMLRowContext_Impl
861 {
862 public:
SmXMLFracContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)863 SmXMLFracContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
864 const OUString& rLName)
865 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
866
867 void EndElement();
868 };
869
870 ////////////////////////////////////////////////////////////
871
872 class SmXMLSqrtContext_Impl : public SmXMLRowContext_Impl
873 {
874 public:
SmXMLSqrtContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)875 SmXMLSqrtContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
876 const OUString& rLName)
877 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
878
879 void EndElement();
880 };
881
882 ////////////////////////////////////////////////////////////
883
884 class SmXMLRootContext_Impl : public SmXMLRowContext_Impl
885 {
886 public:
SmXMLRootContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)887 SmXMLRootContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
888 const OUString& rLName)
889 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
890
891 void EndElement();
892 };
893
894 ////////////////////////////////////////////////////////////
895
896 class SmXMLStyleContext_Impl : public SmXMLRowContext_Impl
897 {
898 protected:
899 SmXMLContext_Helper aStyleHelper;
900
901 public:
902 /*Right now the style tag is completely ignored*/
SmXMLStyleContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)903 SmXMLStyleContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
904 const OUString& rLName) : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
905 aStyleHelper(*this) {}
906
907 void EndElement();
908 void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
909 };
910
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)911 void SmXMLStyleContext_Impl::StartElement(const uno::Reference<
912 xml::sax::XAttributeList > & xAttrList )
913 {
914 #if 1
915 aStyleHelper.RetrieveAttrs(xAttrList);
916 #else
917 sal_Int8 nOldIsBold=nIsBold;
918 sal_Int8 nOldIsItalic=nIsItalic;
919 double nOldFontSize=nFontSize;
920 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
921 OUString sOldFontFamily = sFontFamily;
922 for (sal_Int16 i=0;i<nAttrCount;i++)
923 {
924 OUString sAttrName = xAttrList->getNameByIndex(i);
925 OUString aLocalName;
926 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
927 GetKeyByAttrName(sAttrName,&aLocalName);
928 OUString sValue = xAttrList->getValueByIndex(i);
929 const SvXMLTokenMap &rAttrTokenMap =
930 GetSmImport().GetPresLayoutAttrTokenMap();
931 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
932 {
933 case XML_TOK_FONTWEIGHT:
934 nIsBold = sValue.equals(GetXMLToken(XML_BOLD));
935 break;
936 case XML_TOK_FONTSTYLE:
937 nIsItalic = sValue.equals(GetXMLToken(XML_ITALIC));
938 break;
939 case XML_TOK_FONTSIZE:
940 SvXMLUnitConverter::convertDouble(nFontSize,sValue);
941 GetSmImport().GetMM100UnitConverter().
942 setXMLMeasureUnit(MAP_POINT);
943 if (-1 == sValue.indexOf(GetXMLToken(XML_UNIT_PT)))
944 if (-1 == sValue.indexOf('%'))
945 nFontSize=0.0;
946 else
947 {
948 GetSmImport().GetMM100UnitConverter().
949 setXMLMeasureUnit(MAP_RELATIVE);
950 }
951 break;
952 case XML_TOK_FONTFAMILY:
953 sFontFamily = sValue;
954 break;
955 case XML_TOK_COLOR:
956 sColor = sValue;
957 break;
958 case XML_TOK_MATHCOLOR:
959 sColor = sValue;
960 break;
961 default:
962 break;
963 }
964 }
965
966 if ((nOldIsBold!=nIsBold) || (nOldIsItalic!=nIsItalic) ||
967 (nOldFontSize!=nFontSize) || (sOldFontFamily!=sFontFamily)
968 || sColor.getLength())
969 bFontNodeNeeded=sal_True;
970 else
971 bFontNodeNeeded=sal_False;
972 #endif
973 }
974
975
EndElement()976 void SmXMLStyleContext_Impl::EndElement()
977 {
978 /*
979 <mstyle> accepts any number of arguments; if this number is not 1, its
980 contents are treated as a single "inferred <mrow>" containing its
981 arguments
982 */
983 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
984 if (rNodeStack.Count() - nElementCount > 1)
985 SmXMLRowContext_Impl::EndElement();
986 #if 1
987 aStyleHelper.ApplyAttrs();
988 #else
989 if (bFontNodeNeeded)
990 {
991 SmToken aToken;
992 aToken.cMathChar = '\0';
993 aToken.nGroup = 0;
994 aToken.nLevel = 5;
995
996 if (nIsBold != -1)
997 {
998 if (nIsBold)
999 aToken.eType = TBOLD;
1000 else
1001 aToken.eType = TNBOLD;
1002 SmStructureNode *pFontNode = static_cast<SmStructureNode *>
1003 (new SmFontNode(aToken));
1004 pFontNode->SetSubNodes(0,rNodeStack.Pop());
1005 rNodeStack.Push(pFontNode);
1006 }
1007 if (nIsItalic != -1)
1008 {
1009 if (nIsItalic)
1010 aToken.eType = TITALIC;
1011 else
1012 aToken.eType = TNITALIC;
1013 SmStructureNode *pFontNode = static_cast<SmStructureNode *>
1014 (new SmFontNode(aToken));
1015 pFontNode->SetSubNodes(0,rNodeStack.Pop());
1016 rNodeStack.Push(pFontNode);
1017 }
1018 if (nFontSize != 0.0)
1019 {
1020 aToken.eType = TSIZE;
1021 SmFontNode *pFontNode = new SmFontNode(aToken);
1022
1023 if (MAP_RELATIVE == GetSmImport().GetMM100UnitConverter().
1024 getXMLMeasureUnit())
1025 {
1026 if (nFontSize < 100.00)
1027 pFontNode->SetSizeParameter(Fraction(100.00/nFontSize),
1028 FNTSIZ_DIVIDE);
1029 else
1030 pFontNode->SetSizeParameter(Fraction(nFontSize/100.00),
1031 FNTSIZ_MULTIPLY);
1032 }
1033 else
1034 pFontNode->SetSizeParameter(Fraction(nFontSize),FNTSIZ_ABSOLUT);
1035
1036 pFontNode->SetSubNodes(0,rNodeStack.Pop());
1037 rNodeStack.Push(pFontNode);
1038 }
1039 if (sFontFamily.getLength())
1040 {
1041 if (sFontFamily.equalsIgnoreCase(GetXMLToken(XML_FIXED)))
1042 aToken.eType = TFIXED;
1043 else if (sFontFamily.equalsIgnoreCase(OUString(
1044 RTL_CONSTASCII_USTRINGPARAM("sans"))))
1045 aToken.eType = TSANS;
1046 else if (sFontFamily.equalsIgnoreCase(OUString(
1047 RTL_CONSTASCII_USTRINGPARAM("serif"))))
1048 aToken.eType = TSERIF;
1049 else //Just give up, we need to extend our font mechanism to be
1050 //more general
1051 return;
1052
1053 aToken.aText = sFontFamily;
1054 SmFontNode *pFontNode = new SmFontNode(aToken);
1055 pFontNode->SetSubNodes(0,rNodeStack.Pop());
1056 rNodeStack.Push(pFontNode);
1057 }
1058 if (sColor.getLength())
1059 {
1060 //Again we can only handle a small set of colours in
1061 //StarMath for now.
1062 const SvXMLTokenMap& rTokenMap =
1063 GetSmImport().GetColorTokenMap();
1064 aToken.eType = static_cast<SmTokenType>(rTokenMap.Get(
1065 XML_NAMESPACE_MATH, sColor));
1066 if (aToken.eType != -1)
1067 {
1068 SmFontNode *pFontNode = new SmFontNode(aToken);
1069 pFontNode->SetSubNodes(0,rNodeStack.Pop());
1070 rNodeStack.Push(pFontNode);
1071 }
1072 }
1073
1074 }
1075 #endif
1076 }
1077
1078 ////////////////////////////////////////////////////////////
1079
1080 class SmXMLPaddedContext_Impl : public SmXMLRowContext_Impl
1081 {
1082 public:
1083 /*Right now the style tag is completely ignored*/
SmXMLPaddedContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1084 SmXMLPaddedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1085 const OUString& rLName)
1086 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1087
1088 void EndElement();
1089 };
1090
EndElement()1091 void SmXMLPaddedContext_Impl::EndElement()
1092 {
1093 /*
1094 <mpadded> accepts any number of arguments; if this number is not 1, its
1095 contents are treated as a single "inferred <mrow>" containing its
1096 arguments
1097 */
1098 if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
1099 SmXMLRowContext_Impl::EndElement();
1100 }
1101
1102 ////////////////////////////////////////////////////////////
1103
1104 class SmXMLPhantomContext_Impl : public SmXMLRowContext_Impl
1105 {
1106 public:
1107 /*Right now the style tag is completely ignored*/
SmXMLPhantomContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1108 SmXMLPhantomContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1109 const OUString& rLName)
1110 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1111
1112 void EndElement();
1113 };
1114
EndElement()1115 void SmXMLPhantomContext_Impl::EndElement()
1116 {
1117 /*
1118 <mphantom> accepts any number of arguments; if this number is not 1, its
1119 contents are treated as a single "inferred <mrow>" containing its
1120 arguments
1121 */
1122 if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
1123 SmXMLRowContext_Impl::EndElement();
1124
1125 SmToken aToken;
1126 aToken.cMathChar = '\0';
1127 aToken.nGroup = 0;
1128 aToken.nLevel = 5;
1129 aToken.eType = TPHANTOM;
1130
1131 SmStructureNode *pPhantom = static_cast<SmStructureNode *>
1132 (new SmFontNode(aToken));
1133 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1134 pPhantom->SetSubNodes(0,rNodeStack.Pop());
1135 rNodeStack.Push(pPhantom);
1136 }
1137
1138 ////////////////////////////////////////////////////////////
1139
1140 class SmXMLFencedContext_Impl : public SmXMLRowContext_Impl
1141 {
1142 protected:
1143 sal_Unicode cBegin;
1144 sal_Unicode cEnd;
1145
1146 public:
SmXMLFencedContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1147 SmXMLFencedContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1148 const OUString& rLName)
1149 : SmXMLRowContext_Impl(rImport,nPrefix,rLName),
1150 cBegin('('), cEnd(')') {}
1151
1152 void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList );
1153 void EndElement();
1154 };
1155
1156
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)1157 void SmXMLFencedContext_Impl::StartElement(const uno::Reference<
1158 xml::sax::XAttributeList > & xAttrList )
1159 {
1160 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1161 for (sal_Int16 i=0;i<nAttrCount;i++)
1162 {
1163 OUString sAttrName = xAttrList->getNameByIndex(i);
1164 OUString aLocalName;
1165 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
1166 GetKeyByAttrName(sAttrName,&aLocalName);
1167 OUString sValue = xAttrList->getValueByIndex(i);
1168 const SvXMLTokenMap &rAttrTokenMap =
1169 GetSmImport().GetFencedAttrTokenMap();
1170 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
1171 {
1172 //temp, starmath cannot handle multichar brackets (I think)
1173 case XML_TOK_OPEN:
1174 cBegin = sValue[0];
1175 break;
1176 case XML_TOK_CLOSE:
1177 cEnd = sValue[0];
1178 break;
1179 default:
1180 /*Go to superclass*/
1181 break;
1182 }
1183 }
1184 }
1185
1186
EndElement()1187 void SmXMLFencedContext_Impl::EndElement()
1188 {
1189 SmToken aToken;
1190 aToken.cMathChar = '\0';
1191 aToken.nGroup = 0;
1192 aToken.aText = ',';
1193 aToken.eType = TLEFT;
1194 aToken.nLevel = 5;
1195
1196 aToken.eType = TLPARENT;
1197 aToken.cMathChar = cBegin;
1198 SmStructureNode *pSNode = new SmBraceNode(aToken);
1199 SmNode *pLeft = new SmMathSymbolNode(aToken);
1200
1201 aToken.cMathChar = cEnd;
1202 aToken.eType = TRPARENT;
1203 SmNode *pRight = new SmMathSymbolNode(aToken);
1204
1205 SmNodeArray aRelationArray;
1206 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1207
1208 aToken.cMathChar = '\0';
1209 aToken.aText = ',';
1210 aToken.eType = TIDENT;
1211
1212 sal_uLong i = rNodeStack.Count() - nElementCount;
1213 if (rNodeStack.Count() - nElementCount > 1)
1214 i += rNodeStack.Count() - 1 - nElementCount;
1215 aRelationArray.resize(i);
1216 while (rNodeStack.Count() > nElementCount)
1217 {
1218 aRelationArray[--i] = rNodeStack.Pop();
1219 if (i > 1 && rNodeStack.Count() > 1)
1220 aRelationArray[--i] = new SmGlyphSpecialNode(aToken);
1221 }
1222
1223 SmToken aDummy;
1224 SmStructureNode *pBody = new SmExpressionNode(aDummy);
1225 pBody->SetSubNodes(aRelationArray);
1226
1227
1228 pSNode->SetSubNodes(pLeft,pBody,pRight);
1229 pSNode->SetScaleMode(SCALE_HEIGHT);
1230 GetSmImport().GetNodeStack().Push(pSNode);
1231 }
1232
1233
1234 ////////////////////////////////////////////////////////////
1235
1236 class SmXMLErrorContext_Impl : public SmXMLRowContext_Impl
1237 {
1238 public:
SmXMLErrorContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1239 SmXMLErrorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1240 const OUString& rLName)
1241 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1242
1243 void EndElement();
1244 };
1245
EndElement()1246 void SmXMLErrorContext_Impl::EndElement()
1247 {
1248 /*Right now the error tag is completely ignored, what
1249 can I do with it in starmath, ?, maybe we need a
1250 report window ourselves, do a test for validity of
1251 the xml input, use merrors, and then generate
1252 the markup inside the merror with a big red colour
1253 of something. For now just throw them all away.
1254 */
1255 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1256 while (rNodeStack.Count() > nElementCount)
1257 {
1258 SmNode *pNode = rNodeStack.Pop();
1259 delete pNode;
1260 }
1261 }
1262
1263 ////////////////////////////////////////////////////////////
1264
1265 class SmXMLNumberContext_Impl : public SmXMLImportContext
1266 {
1267 protected:
1268 SmToken aToken;
1269
1270 public:
SmXMLNumberContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1271 SmXMLNumberContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1272 const OUString& rLName)
1273 : SmXMLImportContext(rImport,nPrefix,rLName)
1274 {
1275 aToken.cMathChar = '\0';
1276 aToken.nGroup = 0;
1277 aToken.nLevel = 5;
1278 aToken.eType = TNUMBER;
1279 }
1280
1281 virtual void TCharacters(const OUString &rChars);
1282
1283 void EndElement();
1284 };
1285
TCharacters(const OUString & rChars)1286 void SmXMLNumberContext_Impl::TCharacters(const OUString &rChars)
1287 {
1288 aToken.aText = rChars;
1289 }
1290
EndElement()1291 void SmXMLNumberContext_Impl::EndElement()
1292 {
1293 GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_NUMBER));
1294 }
1295
1296 ////////////////////////////////////////////////////////////
1297
1298 class SmXMLAnnotationContext_Impl : public SmXMLImportContext
1299 {
1300 sal_Bool bIsStarMath;
1301
1302 public:
SmXMLAnnotationContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1303 SmXMLAnnotationContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1304 const OUString& rLName)
1305 : SmXMLImportContext(rImport,nPrefix,rLName), bIsStarMath(sal_False) {}
1306
1307 virtual void Characters(const OUString &rChars);
1308
1309 void StartElement(const uno::Reference<xml::sax::XAttributeList > & xAttrList );
1310 };
1311
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)1312 void SmXMLAnnotationContext_Impl::StartElement(const uno::Reference<
1313 xml::sax::XAttributeList > & xAttrList )
1314 {
1315 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1316 for (sal_Int16 i=0;i<nAttrCount;i++)
1317 {
1318 OUString sAttrName = xAttrList->getNameByIndex(i);
1319 OUString aLocalName;
1320 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
1321 GetKeyByAttrName(sAttrName,&aLocalName);
1322
1323 OUString sValue = xAttrList->getValueByIndex(i);
1324 const SvXMLTokenMap &rAttrTokenMap =
1325 GetSmImport().GetAnnotationAttrTokenMap();
1326 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
1327 {
1328 case XML_TOK_ENCODING:
1329 bIsStarMath= sValue.equals(
1330 OUString(RTL_CONSTASCII_USTRINGPARAM("StarMath 5.0")));
1331 break;
1332 default:
1333 break;
1334 }
1335 }
1336 }
1337
Characters(const OUString & rChars)1338 void SmXMLAnnotationContext_Impl::Characters(const OUString &rChars)
1339 {
1340 if (bIsStarMath)
1341 GetSmImport().GetText().Append(String(rChars));
1342 }
1343
1344 ////////////////////////////////////////////////////////////
1345
1346 class SmXMLTextContext_Impl : public SmXMLImportContext
1347 {
1348 protected:
1349 SmToken aToken;
1350
1351 public:
SmXMLTextContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1352 SmXMLTextContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1353 const OUString& rLName)
1354 : SmXMLImportContext(rImport,nPrefix,rLName)
1355 {
1356 aToken.cMathChar = '\0';
1357 aToken.nGroup = 0;
1358 aToken.nLevel = 5;
1359 aToken.eType = TTEXT;
1360 }
1361
1362 virtual void TCharacters(const OUString &rChars);
1363
1364 void EndElement();
1365 };
1366
TCharacters(const OUString & rChars)1367 void SmXMLTextContext_Impl::TCharacters(const OUString &rChars)
1368 {
1369 aToken.aText = rChars;
1370 }
1371
EndElement()1372 void SmXMLTextContext_Impl::EndElement()
1373 {
1374 GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_TEXT));
1375 }
1376
1377 ////////////////////////////////////////////////////////////
1378
1379 class SmXMLStringContext_Impl : public SmXMLImportContext
1380 {
1381 protected:
1382 SmToken aToken;
1383
1384 public:
SmXMLStringContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1385 SmXMLStringContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1386 const OUString& rLName)
1387 : SmXMLImportContext(rImport,nPrefix,rLName)
1388 {
1389 aToken.cMathChar = '\0';
1390 aToken.nGroup = 0;
1391 aToken.nLevel = 5;
1392 aToken.eType = TTEXT;
1393 }
1394
1395 virtual void TCharacters(const OUString &rChars);
1396
1397 void EndElement();
1398 };
1399
TCharacters(const OUString & rChars)1400 void SmXMLStringContext_Impl::TCharacters(const OUString &rChars)
1401 {
1402 /*
1403 The content of <ms> elements should be rendered with visible "escaping" of
1404 certain characters in the content, including at least "double quote"
1405 itself, and preferably whitespace other than individual blanks. The intent
1406 is for the viewer to see that the expression is a string literal, and to
1407 see exactly which characters form its content. For example, <ms>double
1408 quote is "</ms> might be rendered as "double quote is \"".
1409
1410 Obviously this isn't fully done here.
1411 */
1412 aToken.aText.Erase();
1413 aToken.aText += '\"';
1414 aToken.aText += String(rChars);
1415 aToken.aText += '\"';
1416 }
1417
EndElement()1418 void SmXMLStringContext_Impl::EndElement()
1419 {
1420 GetSmImport().GetNodeStack().Push(new SmTextNode(aToken,FNT_FIXED));
1421 }
1422
1423 ////////////////////////////////////////////////////////////
1424
1425 class SmXMLIdentifierContext_Impl : public SmXMLImportContext
1426 {
1427 protected:
1428 SmXMLContext_Helper aStyleHelper;
1429 SmToken aToken;
1430
1431 public:
SmXMLIdentifierContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1432 SmXMLIdentifierContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1433 const OUString& rLName)
1434 : SmXMLImportContext(rImport,nPrefix,rLName),aStyleHelper(*this)
1435 {
1436 aToken.cMathChar = '\0';
1437 aToken.nGroup = 0;
1438 aToken.nLevel = 5;
1439 aToken.eType = TIDENT;
1440 }
1441
1442 void TCharacters(const OUString &rChars);
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)1443 void StartElement(const uno::Reference< xml::sax::XAttributeList > & xAttrList )
1444 {
1445 aStyleHelper.RetrieveAttrs(xAttrList);
1446 };
1447 void EndElement();
1448 };
1449
EndElement()1450 void SmXMLIdentifierContext_Impl::EndElement()
1451 {
1452 SmTextNode *pNode = 0;
1453 //we will handle identifier italic/normal here instead of with a standalone
1454 //font node
1455 if (((aStyleHelper.nIsItalic == -1) && (aToken.aText.Len() > 1))
1456 || ((aStyleHelper.nIsItalic == 0) && (aToken.aText.Len() == 1)))
1457 {
1458 pNode = new SmTextNode(aToken,FNT_FUNCTION);
1459 pNode->GetFont().SetItalic(ITALIC_NONE);
1460 aStyleHelper.nIsItalic = -1;
1461 }
1462 else
1463 pNode = new SmTextNode(aToken,FNT_VARIABLE);
1464 if (aStyleHelper.bFontNodeNeeded && aStyleHelper.nIsItalic != -1)
1465 {
1466 if (aStyleHelper.nIsItalic)
1467 pNode->GetFont().SetItalic(ITALIC_NORMAL);
1468 else
1469 pNode->GetFont().SetItalic(ITALIC_NONE);
1470 }
1471
1472 if ((-1!=aStyleHelper.nIsBold) || (0.0!=aStyleHelper.nFontSize) ||
1473 (aStyleHelper.sFontFamily.getLength()) ||
1474 aStyleHelper.sColor.getLength())
1475 aStyleHelper.bFontNodeNeeded=sal_True;
1476 else
1477 aStyleHelper.bFontNodeNeeded=sal_False;
1478 if (aStyleHelper.bFontNodeNeeded)
1479 aStyleHelper.ApplyAttrs();
1480 GetSmImport().GetNodeStack().Push(pNode);
1481 }
1482
TCharacters(const OUString & rChars)1483 void SmXMLIdentifierContext_Impl::TCharacters(const OUString &rChars)
1484 {
1485 aToken.aText = rChars;
1486 }
1487
1488 ////////////////////////////////////////////////////////////
1489
1490 class SmXMLOperatorContext_Impl : public SmXMLImportContext
1491 {
1492 sal_Bool bIsStretchy;
1493
1494 protected:
1495 SmToken aToken;
1496
1497 public:
SmXMLOperatorContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1498 SmXMLOperatorContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1499 const OUString& rLName)
1500 : SmXMLImportContext(rImport,nPrefix,rLName), bIsStretchy(sal_False)
1501 {
1502 aToken.nGroup = 0;
1503 aToken.eType = TSPECIAL;
1504 aToken.nLevel = 5;
1505 }
1506
1507 void TCharacters(const OUString &rChars);
1508 void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
1509 void EndElement();
1510 };
1511
TCharacters(const OUString & rChars)1512 void SmXMLOperatorContext_Impl::TCharacters(const OUString &rChars)
1513 {
1514 aToken.cMathChar = rChars[0];
1515 }
1516
EndElement()1517 void SmXMLOperatorContext_Impl::EndElement()
1518 {
1519 SmMathSymbolNode *pNode = new SmMathSymbolNode(aToken);
1520 //For stretchy scaling the scaling must be retrieved from this node
1521 //and applied to the expression itself so as to get the expression
1522 //to scale the operator to the height of the expression itself
1523 if (bIsStretchy)
1524 pNode->SetScaleMode(SCALE_HEIGHT);
1525 GetSmImport().GetNodeStack().Push(pNode);
1526 }
1527
1528
1529
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)1530 void SmXMLOperatorContext_Impl::StartElement(const uno::Reference<
1531 xml::sax::XAttributeList > & xAttrList )
1532 {
1533 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1534 for (sal_Int16 i=0;i<nAttrCount;i++)
1535 {
1536 OUString sAttrName = xAttrList->getNameByIndex(i);
1537 OUString aLocalName;
1538 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
1539 GetKeyByAttrName(sAttrName,&aLocalName);
1540
1541 OUString sValue = xAttrList->getValueByIndex(i);
1542 const SvXMLTokenMap &rAttrTokenMap =
1543 GetSmImport().GetOperatorAttrTokenMap();
1544 switch(rAttrTokenMap.Get(nPrefix,aLocalName))
1545 {
1546 case XML_TOK_STRETCHY:
1547 bIsStretchy = sValue.equals(
1548 GetXMLToken(XML_TRUE));
1549 break;
1550 default:
1551 break;
1552 }
1553 }
1554 }
1555
1556
1557 ////////////////////////////////////////////////////////////
1558
1559 class SmXMLSpaceContext_Impl : public SmXMLImportContext
1560 {
1561 public:
SmXMLSpaceContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1562 SmXMLSpaceContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1563 const OUString& rLName)
1564 : SmXMLImportContext(rImport,nPrefix,rLName) {}
1565
1566 void StartElement(const uno::Reference< xml::sax::XAttributeList >& xAttrList );
1567 };
1568
StartElement(const uno::Reference<xml::sax::XAttributeList> &)1569 void SmXMLSpaceContext_Impl::StartElement(
1570 const uno::Reference<xml::sax::XAttributeList > & /*xAttrList*/ )
1571 {
1572 SmToken aToken;
1573 aToken.cMathChar = '\0';
1574 aToken.nGroup = 0;
1575 aToken.eType = TBLANK;
1576 aToken.nLevel = 5;
1577 SmBlankNode *pBlank = new SmBlankNode(aToken);
1578 pBlank->IncreaseBy(aToken);
1579 GetSmImport().GetNodeStack().Push(pBlank);
1580 }
1581
1582 ////////////////////////////////////////////////////////////
1583
1584 class SmXMLSubContext_Impl : public SmXMLRowContext_Impl
1585 {
1586 protected:
1587 void GenericEndElement(SmTokenType eType,SmSubSup aSubSup);
1588
1589 public:
SmXMLSubContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1590 SmXMLSubContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1591 const OUString& rLName)
1592 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1593
EndElement()1594 void EndElement()
1595 {
1596 GenericEndElement(TRSUB,RSUB);
1597 }
1598 };
1599
1600
GenericEndElement(SmTokenType eType,SmSubSup eSubSup)1601 void SmXMLSubContext_Impl::GenericEndElement(SmTokenType eType, SmSubSup eSubSup)
1602 {
1603 /*The <msub> element requires exactly 2 arguments.*/
1604 const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
1605 DBG_ASSERT( bNodeCheck, "Sub has not two arguments" );
1606 if (!bNodeCheck)
1607 return;
1608
1609 SmToken aToken;
1610 aToken.cMathChar = '\0';
1611 aToken.nGroup = 0;
1612 aToken.nLevel = 0;
1613 aToken.eType = eType;
1614 SmSubSupNode *pNode = new SmSubSupNode(aToken);
1615 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1616
1617 // initialize subnodes array
1618 SmNodeArray aSubNodes;
1619 aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
1620 for (sal_uLong i = 1; i < aSubNodes.size(); i++)
1621 aSubNodes[i] = NULL;
1622
1623 aSubNodes[eSubSup+1] = rNodeStack.Pop();
1624 aSubNodes[0] = rNodeStack.Pop();
1625 pNode->SetSubNodes(aSubNodes);
1626 rNodeStack.Push(pNode);
1627 }
1628
1629 ////////////////////////////////////////////////////////////
1630
1631 class SmXMLSupContext_Impl : public SmXMLSubContext_Impl
1632 {
1633 public:
SmXMLSupContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1634 SmXMLSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1635 const OUString& rLName)
1636 : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
1637
EndElement()1638 void EndElement()
1639 {
1640 GenericEndElement(TRSUP,RSUP);
1641 }
1642 };
1643
1644 ////////////////////////////////////////////////////////////
1645
1646 class SmXMLSubSupContext_Impl : public SmXMLRowContext_Impl
1647 {
1648 protected:
1649 void GenericEndElement(SmTokenType eType, SmSubSup aSub,SmSubSup aSup);
1650
1651 public:
SmXMLSubSupContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1652 SmXMLSubSupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1653 const OUString& rLName)
1654 : SmXMLRowContext_Impl(rImport,nPrefix,rLName) {}
1655
EndElement()1656 void EndElement()
1657 {
1658 GenericEndElement(TRSUB,RSUB,RSUP);
1659 }
1660 };
1661
GenericEndElement(SmTokenType eType,SmSubSup aSub,SmSubSup aSup)1662 void SmXMLSubSupContext_Impl::GenericEndElement(SmTokenType eType,
1663 SmSubSup aSub,SmSubSup aSup)
1664 {
1665 /*The <msub> element requires exactly 3 arguments.*/
1666 const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 3;
1667 DBG_ASSERT( bNodeCheck, "SubSup has not three arguments" );
1668 if (!bNodeCheck)
1669 return;
1670
1671 SmToken aToken;
1672 aToken.cMathChar = '\0';
1673 aToken.nGroup = 0;
1674 aToken.nLevel = 0;
1675 aToken.eType = eType;
1676 SmSubSupNode *pNode = new SmSubSupNode(aToken);
1677 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1678
1679 // initialize subnodes array
1680 SmNodeArray aSubNodes;
1681 aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
1682 for (sal_uLong i = 1; i < aSubNodes.size(); i++)
1683 aSubNodes[i] = NULL;
1684
1685 aSubNodes[aSup+1] = rNodeStack.Pop();
1686 aSubNodes[aSub+1] = rNodeStack.Pop();
1687 aSubNodes[0] = rNodeStack.Pop();
1688 pNode->SetSubNodes(aSubNodes);
1689 rNodeStack.Push(pNode);
1690 }
1691
1692 ////////////////////////////////////////////////////////////
1693
1694 class SmXMLUnderContext_Impl : public SmXMLSubContext_Impl
1695 {
1696 protected:
1697 sal_Int16 nAttrCount;
1698
1699 public:
SmXMLUnderContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1700 SmXMLUnderContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1701 const OUString& rLName)
1702 : SmXMLSubContext_Impl(rImport,nPrefix,rLName) {}
1703
1704 void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
1705 void EndElement();
1706 void HandleAccent();
1707 };
1708
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)1709 void SmXMLUnderContext_Impl::StartElement(const uno::Reference<
1710 xml::sax::XAttributeList > & xAttrList )
1711 {
1712 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1713 }
1714
HandleAccent()1715 void SmXMLUnderContext_Impl::HandleAccent()
1716 {
1717 const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
1718 DBG_ASSERT( bNodeCheck, "Sub has not two arguments" );
1719 if (!bNodeCheck)
1720 return;
1721
1722 /*Just one special case for the underline thing*/
1723 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1724 SmNode *pTest = rNodeStack.Pop();
1725 SmToken aToken;
1726 aToken.cMathChar = '\0';
1727 aToken.nGroup = 0;
1728 aToken.nLevel = 0;
1729 aToken.eType = TUNDERLINE;
1730
1731
1732 SmNodeArray aSubNodes;
1733 aSubNodes.resize(2);
1734
1735 SmStructureNode *pNode = new SmAttributNode(aToken);
1736 if ((pTest->GetToken().cMathChar & 0x0FFF) == 0x0332)
1737 {
1738 aSubNodes[0] = new SmRectangleNode(aToken);
1739 delete pTest;
1740 }
1741 else
1742 aSubNodes[0] = pTest;
1743
1744 aSubNodes[1] = rNodeStack.Pop();
1745 pNode->SetSubNodes(aSubNodes);
1746 pNode->SetScaleMode(SCALE_WIDTH);
1747 rNodeStack.Push(pNode);
1748 }
1749
1750
EndElement()1751 void SmXMLUnderContext_Impl::EndElement()
1752 {
1753 if (!nAttrCount)
1754 GenericEndElement(TCSUB,CSUB);
1755 else
1756 HandleAccent();
1757 #if 0
1758 //UnderBrace trick
1759 SmStructureNode *pNode = rNodeStack.Pop();
1760 if (pNode->GetSubNode(1)->GetToken().cMathChar == (0x0332|0xf000))
1761 if (pNode->GetSubNode(0)->GetToken().cMathChar == (0x0332|0xf000))
1762 #endif
1763 }
1764
1765 ////////////////////////////////////////////////////////////
1766
1767 class SmXMLOverContext_Impl : public SmXMLSubContext_Impl
1768 {
1769 protected:
1770 sal_Int16 nAttrCount;
1771
1772 public:
SmXMLOverContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1773 SmXMLOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1774 const OUString& rLName)
1775 : SmXMLSubContext_Impl(rImport,nPrefix,rLName), nAttrCount(0) {}
1776
1777 void EndElement();
1778 void StartElement(const uno::Reference< xml::sax::XAttributeList > &xAttrList );
1779 void HandleAccent();
1780 };
1781
1782
StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)1783 void SmXMLOverContext_Impl::StartElement(const uno::Reference<
1784 xml::sax::XAttributeList > & xAttrList )
1785 {
1786 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1787 }
1788
1789
EndElement()1790 void SmXMLOverContext_Impl::EndElement()
1791 {
1792 if (!nAttrCount)
1793 GenericEndElement(TCSUP,CSUP);
1794 else
1795 HandleAccent();
1796 }
1797
1798
HandleAccent()1799 void SmXMLOverContext_Impl::HandleAccent()
1800 {
1801 const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
1802 DBG_ASSERT( bNodeCheck, "Sub has not two arguments" );
1803 if (!bNodeCheck)
1804 return;
1805
1806 SmToken aToken;
1807 aToken.cMathChar = '\0';
1808 aToken.nGroup = 0;
1809 aToken.nLevel = 0;
1810 aToken.eType = TACUTE;
1811
1812 SmAttributNode *pNode = new SmAttributNode(aToken);
1813 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
1814
1815 SmNodeArray aSubNodes;
1816 aSubNodes.resize(2);
1817 aSubNodes[0] = rNodeStack.Pop();
1818 aSubNodes[1] = rNodeStack.Pop();
1819 pNode->SetSubNodes(aSubNodes);
1820 pNode->SetScaleMode(SCALE_WIDTH);
1821 rNodeStack.Push(pNode);
1822
1823 }
1824
1825 ////////////////////////////////////////////////////////////
1826
1827 class SmXMLUnderOverContext_Impl : public SmXMLSubSupContext_Impl
1828 {
1829 public:
SmXMLUnderOverContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1830 SmXMLUnderOverContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1831 const OUString& rLName)
1832 : SmXMLSubSupContext_Impl(rImport,nPrefix,rLName) {}
1833
EndElement()1834 void EndElement()
1835 {
1836 GenericEndElement(TCSUB,CSUB,CSUP);
1837 }
1838 };
1839
1840 ////////////////////////////////////////////////////////////
1841
1842 class SmXMLMultiScriptsContext_Impl : public SmXMLSubSupContext_Impl
1843 {
1844 sal_Bool bHasPrescripts;
1845
1846 public:
SmXMLMultiScriptsContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1847 SmXMLMultiScriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1848 const OUString& rLName) :
1849 SmXMLSubSupContext_Impl(rImport,nPrefix,rLName),
1850 bHasPrescripts(sal_False) {}
1851
1852 void EndElement();
1853 void MiddleElement();
1854 SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
1855 const OUString& rLocalName,
1856 const uno::Reference< xml::sax::XAttributeList > &xAttrList);
1857 };
1858
1859 ////////////////////////////////////////////////////////////
1860
1861 class SmXMLNoneContext_Impl : public SmXMLImportContext
1862 {
1863 public:
SmXMLNoneContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1864 SmXMLNoneContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1865 const OUString& rLName)
1866 : SmXMLImportContext(rImport,nPrefix,rLName) {}
1867
1868 void EndElement();
1869 };
1870
1871
EndElement(void)1872 void SmXMLNoneContext_Impl::EndElement(void)
1873 {
1874 SmToken aToken;
1875 aToken.cMathChar = '\0';
1876 aToken.nGroup = 0;
1877 aToken.aText.Erase();
1878 aToken.nLevel = 5;
1879 aToken.eType = TIDENT;
1880 GetSmImport().GetNodeStack().Push(
1881 new SmTextNode(aToken,FNT_VARIABLE));
1882 }
1883
1884 ////////////////////////////////////////////////////////////
1885
1886 class SmXMLPrescriptsContext_Impl : public SmXMLImportContext
1887 {
1888 public:
SmXMLPrescriptsContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1889 SmXMLPrescriptsContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1890 const OUString& rLName)
1891 : SmXMLImportContext(rImport,nPrefix,rLName) {}
1892 };
1893
1894 ////////////////////////////////////////////////////////////
1895
1896 class SmXMLTableRowContext_Impl : public SmXMLRowContext_Impl
1897 {
1898 public:
SmXMLTableRowContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1899 SmXMLTableRowContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1900 const OUString& rLName) :
1901 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1902 {}
1903
1904 SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
1905 const OUString& rLocalName,
1906 const uno::Reference< xml::sax::XAttributeList > &xAttrList);
1907 };
1908
1909
1910 ////////////////////////////////////////////////////////////
1911
1912 class SmXMLTableContext_Impl : public SmXMLTableRowContext_Impl
1913 {
1914 public:
SmXMLTableContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1915 SmXMLTableContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1916 const OUString& rLName) :
1917 SmXMLTableRowContext_Impl(rImport,nPrefix,rLName)
1918 {}
1919
1920 void EndElement();
1921 SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix,
1922 const OUString& rLocalName,
1923 const uno::Reference< xml::sax::XAttributeList > &xAttrList);
1924 };
1925
1926
1927 ////////////////////////////////////////////////////////////
1928
1929 class SmXMLTableCellContext_Impl : public SmXMLRowContext_Impl
1930 {
1931 public:
SmXMLTableCellContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1932 SmXMLTableCellContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1933 const OUString& rLName) :
1934 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1935 {}
1936 };
1937
1938 ////////////////////////////////////////////////////////////
1939
1940 class SmXMLAlignGroupContext_Impl : public SmXMLRowContext_Impl
1941 {
1942 public:
SmXMLAlignGroupContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1943 SmXMLAlignGroupContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1944 const OUString& rLName) :
1945 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1946 {}
1947
1948 /*Don't do anything with alignment for now*/
EndElement()1949 void EndElement()
1950 {
1951 }
1952 };
1953
1954 ////////////////////////////////////////////////////////////
1955
1956 class SmXMLActionContext_Impl : public SmXMLRowContext_Impl
1957 {
1958 public:
SmXMLActionContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrefix,const OUString & rLName)1959 SmXMLActionContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
1960 const OUString& rLName) :
1961 SmXMLRowContext_Impl(rImport,nPrefix,rLName)
1962 {}
1963
1964 void EndElement();
1965 };
1966
1967 ////////////////////////////////////////////////////////////
1968
1969 // NB: virtually inherit so we can multiply inherit properly
1970 // in SmXMLFlatDocContext_Impl
1971 class SmXMLOfficeContext_Impl : public virtual SvXMLImportContext
1972 {
1973 public:
SmXMLOfficeContext_Impl(SmXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLName)1974 SmXMLOfficeContext_Impl( SmXMLImport &rImport, sal_uInt16 nPrfx,
1975 const OUString& rLName)
1976 : SvXMLImportContext(rImport,nPrfx,rLName) {}
1977
1978 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 nPrefix, const OUString& rLocalName, const uno::Reference< xml::sax::XAttributeList > &xAttrList);
1979 };
1980
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)1981 SvXMLImportContext *SmXMLOfficeContext_Impl::CreateChildContext(sal_uInt16 nPrefix,
1982 const OUString& rLocalName,
1983 const uno::Reference< xml::sax::XAttributeList > &xAttrList)
1984 {
1985 SvXMLImportContext *pContext = 0;
1986 if ( XML_NAMESPACE_OFFICE == nPrefix &&
1987 rLocalName == GetXMLToken(XML_META) )
1988 {
1989 DBG_WARNING("XML_TOK_DOC_META: should not have come here, maybe document is invalid?");
1990 }
1991 else if ( XML_NAMESPACE_OFFICE == nPrefix &&
1992 rLocalName == GetXMLToken(XML_SETTINGS) )
1993 {
1994 pContext = new XMLDocumentSettingsContext( GetImport(),
1995 XML_NAMESPACE_OFFICE, rLocalName,
1996 xAttrList );
1997 }
1998 else
1999 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
2000
2001 return pContext;
2002 }
2003
2004 ////////////////////////////////////////////////////////////
2005
2006 // context for flat file xml format
2007 class SmXMLFlatDocContext_Impl
2008 : public SmXMLOfficeContext_Impl, public SvXMLMetaDocumentContext
2009 {
2010 public:
2011 SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
2012 sal_uInt16 i_nPrefix, const OUString & i_rLName,
2013 const uno::Reference<document::XDocumentProperties>& i_xDocProps,
2014 const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder);
2015
2016 virtual ~SmXMLFlatDocContext_Impl();
2017
2018 virtual SvXMLImportContext *CreateChildContext(sal_uInt16 i_nPrefix, const OUString& i_rLocalName, const uno::Reference<xml::sax::XAttributeList>& i_xAttrList);
2019 };
2020
SmXMLFlatDocContext_Impl(SmXMLImport & i_rImport,sal_uInt16 i_nPrefix,const OUString & i_rLName,const uno::Reference<document::XDocumentProperties> & i_xDocProps,const uno::Reference<xml::sax::XDocumentHandler> & i_xDocBuilder)2021 SmXMLFlatDocContext_Impl::SmXMLFlatDocContext_Impl( SmXMLImport& i_rImport,
2022 sal_uInt16 i_nPrefix, const OUString & i_rLName,
2023 const uno::Reference<document::XDocumentProperties>& i_xDocProps,
2024 const uno::Reference<xml::sax::XDocumentHandler>& i_xDocBuilder) :
2025 SvXMLImportContext(i_rImport, i_nPrefix, i_rLName),
2026 SmXMLOfficeContext_Impl(i_rImport, i_nPrefix, i_rLName),
2027 SvXMLMetaDocumentContext(i_rImport, i_nPrefix, i_rLName,
2028 i_xDocProps, i_xDocBuilder)
2029 {
2030 }
2031
~SmXMLFlatDocContext_Impl()2032 SmXMLFlatDocContext_Impl::~SmXMLFlatDocContext_Impl()
2033 {
2034 }
2035
CreateChildContext(sal_uInt16 i_nPrefix,const OUString & i_rLocalName,const uno::Reference<xml::sax::XAttributeList> & i_xAttrList)2036 SvXMLImportContext *SmXMLFlatDocContext_Impl::CreateChildContext(
2037 sal_uInt16 i_nPrefix, const OUString& i_rLocalName,
2038 const uno::Reference<xml::sax::XAttributeList>& i_xAttrList)
2039 {
2040 // behave like meta base class iff we encounter office:meta
2041 if ( XML_NAMESPACE_OFFICE == i_nPrefix &&
2042 i_rLocalName == GetXMLToken(XML_META) )
2043 {
2044 return SvXMLMetaDocumentContext::CreateChildContext(
2045 i_nPrefix, i_rLocalName, i_xAttrList );
2046 }
2047 else
2048 {
2049 return SmXMLOfficeContext_Impl::CreateChildContext(
2050 i_nPrefix, i_rLocalName, i_xAttrList );
2051 }
2052 }
2053
2054 ////////////////////////////////////////////////////////////
2055
2056 static __FAR_DATA SvXMLTokenMapEntry aPresLayoutElemTokenMap[] =
2057 {
2058 { XML_NAMESPACE_MATH, XML_SEMANTICS, XML_TOK_SEMANTICS },
2059 { XML_NAMESPACE_MATH, XML_MATH, XML_TOK_MATH },
2060 { XML_NAMESPACE_MATH, XML_MSTYLE, XML_TOK_MSTYLE },
2061 { XML_NAMESPACE_MATH, XML_MERROR, XML_TOK_MERROR },
2062 { XML_NAMESPACE_MATH, XML_MPHANTOM, XML_TOK_MPHANTOM },
2063 { XML_NAMESPACE_MATH, XML_MROW, XML_TOK_MROW },
2064 { XML_NAMESPACE_MATH, XML_MFRAC, XML_TOK_MFRAC },
2065 { XML_NAMESPACE_MATH, XML_MSQRT, XML_TOK_MSQRT },
2066 { XML_NAMESPACE_MATH, XML_MROOT, XML_TOK_MROOT },
2067 { XML_NAMESPACE_MATH, XML_MSUB, XML_TOK_MSUB },
2068 { XML_NAMESPACE_MATH, XML_MSUP, XML_TOK_MSUP },
2069 { XML_NAMESPACE_MATH, XML_MSUBSUP, XML_TOK_MSUBSUP },
2070 { XML_NAMESPACE_MATH, XML_MUNDER, XML_TOK_MUNDER },
2071 { XML_NAMESPACE_MATH, XML_MOVER, XML_TOK_MOVER },
2072 { XML_NAMESPACE_MATH, XML_MUNDEROVER, XML_TOK_MUNDEROVER },
2073 { XML_NAMESPACE_MATH, XML_MMULTISCRIPTS, XML_TOK_MMULTISCRIPTS },
2074 { XML_NAMESPACE_MATH, XML_MTABLE, XML_TOK_MTABLE },
2075 { XML_NAMESPACE_MATH, XML_MACTION, XML_TOK_MACTION },
2076 { XML_NAMESPACE_MATH, XML_MFENCED, XML_TOK_MFENCED },
2077 { XML_NAMESPACE_MATH, XML_MPADDED, XML_TOK_MPADDED },
2078 XML_TOKEN_MAP_END
2079 };
2080
2081 static __FAR_DATA SvXMLTokenMapEntry aPresLayoutAttrTokenMap[] =
2082 {
2083 { XML_NAMESPACE_MATH, XML_FONTWEIGHT, XML_TOK_FONTWEIGHT },
2084 { XML_NAMESPACE_MATH, XML_FONTSTYLE, XML_TOK_FONTSTYLE },
2085 { XML_NAMESPACE_MATH, XML_FONTSIZE, XML_TOK_FONTSIZE },
2086 { XML_NAMESPACE_MATH, XML_FONTFAMILY, XML_TOK_FONTFAMILY },
2087 { XML_NAMESPACE_MATH, XML_COLOR, XML_TOK_COLOR },
2088 { XML_NAMESPACE_MATH, XML_MATHCOLOR, XML_TOK_MATHCOLOR },
2089 XML_TOKEN_MAP_END
2090 };
2091
2092 static __FAR_DATA SvXMLTokenMapEntry aFencedAttrTokenMap[] =
2093 {
2094 { XML_NAMESPACE_MATH, XML_OPEN, XML_TOK_OPEN },
2095 { XML_NAMESPACE_MATH, XML_CLOSE, XML_TOK_CLOSE },
2096 XML_TOKEN_MAP_END
2097 };
2098
2099 static __FAR_DATA SvXMLTokenMapEntry aOperatorAttrTokenMap[] =
2100 {
2101 { XML_NAMESPACE_MATH, XML_STRETCHY, XML_TOK_STRETCHY },
2102 XML_TOKEN_MAP_END
2103 };
2104
2105 static __FAR_DATA SvXMLTokenMapEntry aAnnotationAttrTokenMap[] =
2106 {
2107 { XML_NAMESPACE_MATH, XML_ENCODING, XML_TOK_ENCODING },
2108 XML_TOKEN_MAP_END
2109 };
2110
2111
2112 static __FAR_DATA SvXMLTokenMapEntry aPresElemTokenMap[] =
2113 {
2114 { XML_NAMESPACE_MATH, XML_ANNOTATION, XML_TOK_ANNOTATION },
2115 { XML_NAMESPACE_MATH, XML_MI, XML_TOK_MI },
2116 { XML_NAMESPACE_MATH, XML_MN, XML_TOK_MN },
2117 { XML_NAMESPACE_MATH, XML_MO, XML_TOK_MO },
2118 { XML_NAMESPACE_MATH, XML_MTEXT, XML_TOK_MTEXT },
2119 { XML_NAMESPACE_MATH, XML_MSPACE,XML_TOK_MSPACE },
2120 { XML_NAMESPACE_MATH, XML_MS, XML_TOK_MS },
2121 { XML_NAMESPACE_MATH, XML_MALIGNGROUP, XML_TOK_MALIGNGROUP },
2122 XML_TOKEN_MAP_END
2123 };
2124
2125 static __FAR_DATA SvXMLTokenMapEntry aPresScriptEmptyElemTokenMap[] =
2126 {
2127 { XML_NAMESPACE_MATH, XML_MPRESCRIPTS, XML_TOK_MPRESCRIPTS },
2128 { XML_NAMESPACE_MATH, XML_NONE, XML_TOK_NONE },
2129 XML_TOKEN_MAP_END
2130 };
2131
2132 static __FAR_DATA SvXMLTokenMapEntry aPresTableElemTokenMap[] =
2133 {
2134 { XML_NAMESPACE_MATH, XML_MTR, XML_TOK_MTR },
2135 { XML_NAMESPACE_MATH, XML_MTD, XML_TOK_MTD },
2136 XML_TOKEN_MAP_END
2137 };
2138
2139 static __FAR_DATA SvXMLTokenMapEntry aColorTokenMap[] =
2140 {
2141 { XML_NAMESPACE_MATH, XML_BLACK, TBLACK},
2142 { XML_NAMESPACE_MATH, XML_WHITE, TWHITE},
2143 { XML_NAMESPACE_MATH, XML_RED, TRED},
2144 { XML_NAMESPACE_MATH, XML_GREEN, TGREEN},
2145 { XML_NAMESPACE_MATH, XML_BLUE, TBLUE},
2146 { XML_NAMESPACE_MATH, XML_AQUA, TAQUA},
2147 { XML_NAMESPACE_MATH, XML_FUCHSIA, TFUCHSIA},
2148 { XML_NAMESPACE_MATH, XML_YELLOW, TYELLOW},
2149 { XML_NAMESPACE_MATH, XML_NAVY, TNAVY},
2150 { XML_NAMESPACE_MATH, XML_TEAL, TTEAL},
2151 { XML_NAMESPACE_MATH, XML_MAROON, TMAROON},
2152 { XML_NAMESPACE_MATH, XML_PURPLE, TPURPLE},
2153 { XML_NAMESPACE_MATH, XML_OLIVE, TOLIVE},
2154 { XML_NAMESPACE_MATH, XML_GRAY, TGRAY},
2155 { XML_NAMESPACE_MATH, XML_SILVER, TSILVER},
2156 { XML_NAMESPACE_MATH, XML_LIME, TLIME},
2157 XML_TOKEN_MAP_END
2158 };
2159
2160 ////////////////////////////////////////////////////////////
2161
GetPresLayoutElemTokenMap()2162 const SvXMLTokenMap& SmXMLImport::GetPresLayoutElemTokenMap()
2163 {
2164 if (!pPresLayoutElemTokenMap)
2165 pPresLayoutElemTokenMap = new SvXMLTokenMap(aPresLayoutElemTokenMap);
2166 return *pPresLayoutElemTokenMap;
2167 }
2168
GetPresLayoutAttrTokenMap()2169 const SvXMLTokenMap& SmXMLImport::GetPresLayoutAttrTokenMap()
2170 {
2171 if (!pPresLayoutAttrTokenMap)
2172 pPresLayoutAttrTokenMap = new SvXMLTokenMap(aPresLayoutAttrTokenMap);
2173 return *pPresLayoutAttrTokenMap;
2174 }
2175
2176
GetFencedAttrTokenMap()2177 const SvXMLTokenMap& SmXMLImport::GetFencedAttrTokenMap()
2178 {
2179 if (!pFencedAttrTokenMap)
2180 pFencedAttrTokenMap = new SvXMLTokenMap(aFencedAttrTokenMap);
2181 return *pFencedAttrTokenMap;
2182 }
2183
GetOperatorAttrTokenMap()2184 const SvXMLTokenMap& SmXMLImport::GetOperatorAttrTokenMap()
2185 {
2186 if (!pOperatorAttrTokenMap)
2187 pOperatorAttrTokenMap = new SvXMLTokenMap(aOperatorAttrTokenMap);
2188 return *pOperatorAttrTokenMap;
2189 }
2190
GetAnnotationAttrTokenMap()2191 const SvXMLTokenMap& SmXMLImport::GetAnnotationAttrTokenMap()
2192 {
2193 if (!pAnnotationAttrTokenMap)
2194 pAnnotationAttrTokenMap = new SvXMLTokenMap(aAnnotationAttrTokenMap);
2195 return *pAnnotationAttrTokenMap;
2196 }
2197
GetPresElemTokenMap()2198 const SvXMLTokenMap& SmXMLImport::GetPresElemTokenMap()
2199 {
2200 if (!pPresElemTokenMap)
2201 pPresElemTokenMap = new SvXMLTokenMap(aPresElemTokenMap);
2202 return *pPresElemTokenMap;
2203 }
2204
GetPresScriptEmptyElemTokenMap()2205 const SvXMLTokenMap& SmXMLImport::GetPresScriptEmptyElemTokenMap()
2206 {
2207 if (!pPresScriptEmptyElemTokenMap)
2208 pPresScriptEmptyElemTokenMap = new
2209 SvXMLTokenMap(aPresScriptEmptyElemTokenMap);
2210 return *pPresScriptEmptyElemTokenMap;
2211 }
2212
GetPresTableElemTokenMap()2213 const SvXMLTokenMap& SmXMLImport::GetPresTableElemTokenMap()
2214 {
2215 if (!pPresTableElemTokenMap)
2216 pPresTableElemTokenMap = new SvXMLTokenMap(aPresTableElemTokenMap);
2217 return *pPresTableElemTokenMap;
2218 }
2219
GetColorTokenMap()2220 const SvXMLTokenMap& SmXMLImport::GetColorTokenMap()
2221 {
2222 if (!pColorTokenMap)
2223 pColorTokenMap = new SvXMLTokenMap(aColorTokenMap);
2224 return *pColorTokenMap;
2225 }
2226
2227 ////////////////////////////////////////////////////////////
2228
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)2229 SvXMLImportContext *SmXMLDocContext_Impl::CreateChildContext(
2230 sal_uInt16 nPrefix,
2231 const OUString& rLocalName,
2232 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2233 {
2234 SvXMLImportContext* pContext = 0L;
2235
2236 const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresLayoutElemTokenMap();
2237
2238 //sal_uInt32 nTest = rTokenMap.Get(nPrefix, rLocalName);
2239
2240 switch(rTokenMap.Get(nPrefix, rLocalName))
2241 {
2242 //Consider semantics a dummy except for any starmath annotations
2243 case XML_TOK_SEMANTICS:
2244 pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
2245 xAttrList);
2246 break;
2247 /*General Layout Schemata*/
2248 case XML_TOK_MROW:
2249 pContext = GetSmImport().CreateRowContext(nPrefix,rLocalName,
2250 xAttrList);
2251 break;
2252 case XML_TOK_MFRAC:
2253 pContext = GetSmImport().CreateFracContext(nPrefix,rLocalName,
2254 xAttrList);
2255 break;
2256 case XML_TOK_MSQRT:
2257 pContext = GetSmImport().CreateSqrtContext(nPrefix,rLocalName,
2258 xAttrList);
2259 break;
2260 case XML_TOK_MROOT:
2261 pContext = GetSmImport().CreateRootContext(nPrefix,rLocalName,
2262 xAttrList);
2263 break;
2264 case XML_TOK_MSTYLE:
2265 pContext = GetSmImport().CreateStyleContext(nPrefix,rLocalName,
2266 xAttrList);
2267 break;
2268 case XML_TOK_MERROR:
2269 pContext = GetSmImport().CreateErrorContext(nPrefix,rLocalName,
2270 xAttrList);
2271 break;
2272 case XML_TOK_MPADDED:
2273 pContext = GetSmImport().CreatePaddedContext(nPrefix,rLocalName,
2274 xAttrList);
2275 break;
2276 case XML_TOK_MPHANTOM:
2277 pContext = GetSmImport().CreatePhantomContext(nPrefix,rLocalName,
2278 xAttrList);
2279 break;
2280 case XML_TOK_MFENCED:
2281 pContext = GetSmImport().CreateFencedContext(nPrefix,rLocalName,
2282 xAttrList);
2283 break;
2284 /*Script and Limit Schemata*/
2285 case XML_TOK_MSUB:
2286 pContext = GetSmImport().CreateSubContext(nPrefix,rLocalName,
2287 xAttrList);
2288 break;
2289 case XML_TOK_MSUP:
2290 pContext = GetSmImport().CreateSupContext(nPrefix,rLocalName,
2291 xAttrList);
2292 break;
2293 case XML_TOK_MSUBSUP:
2294 pContext = GetSmImport().CreateSubSupContext(nPrefix,rLocalName,
2295 xAttrList);
2296 break;
2297 case XML_TOK_MUNDER:
2298 pContext = GetSmImport().CreateUnderContext(nPrefix,rLocalName,
2299 xAttrList);
2300 break;
2301 case XML_TOK_MOVER:
2302 pContext = GetSmImport().CreateOverContext(nPrefix,rLocalName,
2303 xAttrList);
2304 break;
2305 case XML_TOK_MUNDEROVER:
2306 pContext = GetSmImport().CreateUnderOverContext(nPrefix,rLocalName,
2307 xAttrList);
2308 break;
2309 case XML_TOK_MMULTISCRIPTS:
2310 pContext = GetSmImport().CreateMultiScriptsContext(nPrefix,
2311 rLocalName, xAttrList);
2312 break;
2313 case XML_TOK_MTABLE:
2314 pContext = GetSmImport().CreateTableContext(nPrefix,
2315 rLocalName, xAttrList);
2316 break;
2317 case XML_TOK_MACTION:
2318 pContext = GetSmImport().CreateActionContext(nPrefix,
2319 rLocalName, xAttrList);
2320 break;
2321 default:
2322 /*Basically theres an implicit mrow around certain bare
2323 *elements, use a RowContext to see if this is one of
2324 *those ones*/
2325 SmXMLRowContext_Impl aTempContext(GetSmImport(),nPrefix,
2326 GetXMLToken(XML_MROW));
2327
2328 pContext = aTempContext.StrictCreateChildContext(nPrefix,
2329 rLocalName, xAttrList);
2330 break;
2331 }
2332 return pContext;
2333 }
2334
EndElement()2335 void SmXMLDocContext_Impl::EndElement()
2336 {
2337 SmNodeArray ContextArray;
2338 ContextArray.resize(1);
2339 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2340
2341 for (sal_uLong i=0;i< 1;i++)
2342 ContextArray[i] = rNodeStack.Pop();
2343
2344 SmToken aDummy;
2345 SmStructureNode *pSNode = new SmLineNode(aDummy);
2346 pSNode->SetSubNodes(ContextArray);
2347 rNodeStack.Push(pSNode);
2348
2349 SmNodeArray LineArray;
2350 sal_uLong n = rNodeStack.Count();
2351 LineArray.resize(n);
2352 for (sal_uLong j = 0; j < n; j++)
2353 LineArray[n - (j + 1)] = rNodeStack.Pop();
2354 SmStructureNode *pSNode2 = new SmTableNode(aDummy);
2355 pSNode2->SetSubNodes(LineArray);
2356 rNodeStack.Push(pSNode2);
2357 }
2358
EndElement()2359 void SmXMLFracContext_Impl::EndElement()
2360 {
2361 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2362 const bool bNodeCheck = rNodeStack.Count() - nElementCount == 2;
2363 DBG_ASSERT( bNodeCheck, "Fraction (mfrac) tag is missing component" );
2364 if (!bNodeCheck)
2365 return;
2366
2367 SmToken aToken;
2368 aToken.cMathChar = '\0';
2369 aToken.nGroup = 0;
2370 aToken.nLevel = 0;
2371 aToken.eType = TOVER;
2372 SmStructureNode *pSNode = new SmBinVerNode(aToken);
2373 SmNode *pOper = new SmRectangleNode(aToken);
2374 SmNode *pSecond = rNodeStack.Pop();
2375 SmNode *pFirst = rNodeStack.Pop();
2376 pSNode->SetSubNodes(pFirst,pOper,pSecond);
2377 rNodeStack.Push(pSNode);
2378 }
2379
EndElement()2380 void SmXMLRootContext_Impl::EndElement()
2381 {
2382 /*The <mroot> element requires exactly 2 arguments.*/
2383 const bool bNodeCheck = GetSmImport().GetNodeStack().Count() - nElementCount == 2;
2384 DBG_ASSERT( bNodeCheck, "Root tag is missing component" );
2385 if (!bNodeCheck)
2386 return;
2387
2388 SmToken aToken;
2389 aToken.cMathChar = MS_SQRT; //Temporary: alert, based on StarSymbol font
2390 aToken.nGroup = 0;
2391 aToken.nLevel = 0;
2392 aToken.eType = TNROOT;
2393 SmStructureNode *pSNode = new SmRootNode(aToken);
2394 SmNode *pOper = new SmRootSymbolNode(aToken);
2395 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2396 SmNode *pIndex = rNodeStack.Pop();
2397 SmNode *pBase = rNodeStack.Pop();
2398 pSNode->SetSubNodes(pIndex,pOper,pBase);
2399 rNodeStack.Push(pSNode);
2400 }
2401
EndElement()2402 void SmXMLSqrtContext_Impl::EndElement()
2403 {
2404 /*
2405 <msqrt> accepts any number of arguments; if this number is not 1, its
2406 contents are treated as a single "inferred <mrow>" containing its
2407 arguments
2408 */
2409 if (GetSmImport().GetNodeStack().Count() - nElementCount > 1)
2410 SmXMLRowContext_Impl::EndElement();
2411
2412 SmToken aToken;
2413 aToken.cMathChar = MS_SQRT; //Temporary: alert, based on StarSymbol font
2414 aToken.nGroup = 0;
2415 aToken.nLevel = 0;
2416 aToken.eType = TSQRT;
2417 SmStructureNode *pSNode = new SmRootNode(aToken);
2418 SmNode *pOper = new SmRootSymbolNode(aToken);
2419 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2420 pSNode->SetSubNodes(0,pOper,rNodeStack.Pop());
2421 rNodeStack.Push(pSNode);
2422 }
2423
EndElement()2424 void SmXMLRowContext_Impl::EndElement()
2425 {
2426 SmNodeArray aRelationArray;
2427 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2428 sal_uLong nSize = rNodeStack.Count()-nElementCount;
2429
2430 if (nSize > 0)
2431 {
2432 aRelationArray.resize(nSize);
2433 for (sal_uLong j=rNodeStack.Count()-nElementCount;j > 0;j--)
2434 aRelationArray[j-1] = rNodeStack.Pop();
2435
2436
2437 //If the first or last element is an operator with stretchyness
2438 //set then we must create a brace node here from those elements,
2439 //removing the stretchness from the operators and applying it to
2440 //ourselves, and creating the appropriate dummy StarMath none bracket
2441 //to balance the arrangement
2442 if (((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
2443 && (aRelationArray[0]->GetType() == NMATH))
2444 || ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
2445 && (aRelationArray[nSize-1]->GetType() == NMATH)))
2446 {
2447 SmToken aToken;
2448 aToken.cMathChar = '\0';
2449 aToken.nGroup = 0;
2450 aToken.nLevel = 5;
2451
2452 int nLeft=0,nRight=0;
2453 if ((aRelationArray[0]->GetScaleMode() == SCALE_HEIGHT)
2454 && (aRelationArray[0]->GetType() == NMATH))
2455 {
2456 aToken = aRelationArray[0]->GetToken();
2457 nLeft=1;
2458 }
2459 else
2460 aToken.cMathChar = '\0';
2461
2462 aToken.eType = TLPARENT;
2463 SmNode *pLeft = new SmMathSymbolNode(aToken);
2464
2465 if ((aRelationArray[nSize-1]->GetScaleMode() == SCALE_HEIGHT)
2466 && (aRelationArray[nSize-1]->GetType() == NMATH))
2467 {
2468 aToken = aRelationArray[nSize-1]->GetToken();
2469 nRight=1;
2470 }
2471 else
2472 aToken.cMathChar = '\0';
2473
2474 aToken.eType = TRPARENT;
2475 SmNode *pRight = new SmMathSymbolNode(aToken);
2476
2477 SmNodeArray aRelationArray2;
2478
2479 //!! nSize-nLeft-nRight may be < 0 !!
2480 int nRelArrSize = nSize-nLeft-nRight;
2481 if (nRelArrSize > 0)
2482 {
2483 aRelationArray2.resize(nRelArrSize);
2484 for (int i=0;i < nRelArrSize;i++)
2485 aRelationArray2[i] = aRelationArray[i+nLeft];
2486 }
2487
2488 SmToken aDummy;
2489 SmStructureNode *pSNode = new SmBraceNode(aToken);
2490 SmStructureNode *pBody = new SmExpressionNode(aDummy);
2491 pBody->SetSubNodes(aRelationArray2);
2492
2493 pSNode->SetSubNodes(pLeft,pBody,pRight);
2494 pSNode->SetScaleMode(SCALE_HEIGHT);
2495 rNodeStack.Push(pSNode);
2496 return;
2497 }
2498 }
2499 else //Multiple newlines result in empty row elements
2500 {
2501 aRelationArray.resize(1);
2502 SmToken aToken;
2503 aToken.cMathChar = '\0';
2504 aToken.nGroup = 0;
2505 aToken.nLevel = 5;
2506 aToken.eType = TNEWLINE;
2507 aRelationArray[0] = new SmLineNode(aToken);
2508 }
2509
2510 SmToken aDummy;
2511 SmStructureNode *pSNode = new SmExpressionNode(aDummy);
2512 pSNode->SetSubNodes(aRelationArray);
2513 rNodeStack.Push(pSNode);
2514 }
2515
2516
StrictCreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)2517 SvXMLImportContext *SmXMLRowContext_Impl::StrictCreateChildContext(
2518 sal_uInt16 nPrefix,
2519 const OUString& rLocalName,
2520 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2521 {
2522 SvXMLImportContext* pContext = 0L;
2523
2524 const SvXMLTokenMap& rTokenMap = GetSmImport().GetPresElemTokenMap();
2525 switch(rTokenMap.Get(nPrefix, rLocalName))
2526 {
2527 /*Note that these should accept malignmark subelements, but do not*/
2528 case XML_TOK_MN:
2529 pContext = GetSmImport().CreateNumberContext(nPrefix,rLocalName,
2530 xAttrList);
2531 break;
2532 case XML_TOK_MI:
2533 pContext = GetSmImport().CreateIdentifierContext(nPrefix,rLocalName,
2534 xAttrList);
2535 break;
2536 case XML_TOK_MO:
2537 pContext = GetSmImport().CreateOperatorContext(nPrefix,rLocalName,
2538 xAttrList);
2539 break;
2540 case XML_TOK_MTEXT:
2541 pContext = GetSmImport().CreateTextContext(nPrefix,rLocalName,
2542 xAttrList);
2543 break;
2544 case XML_TOK_MSPACE:
2545 pContext = GetSmImport().CreateSpaceContext(nPrefix,rLocalName,
2546 xAttrList);
2547 break;
2548 case XML_TOK_MS:
2549 pContext = GetSmImport().CreateStringContext(nPrefix,rLocalName,
2550 xAttrList);
2551 break;
2552
2553 /*Note: The maligngroup should only be seen when the row
2554 * (or descendants) are in a table*/
2555 case XML_TOK_MALIGNGROUP:
2556 pContext = GetSmImport().CreateAlignGroupContext(nPrefix,rLocalName,
2557 xAttrList);
2558 break;
2559
2560 case XML_TOK_ANNOTATION:
2561 pContext = GetSmImport().CreateAnnotationContext(nPrefix,rLocalName,
2562 xAttrList);
2563 break;
2564
2565 default:
2566 break;
2567 }
2568 return pContext;
2569 }
2570
2571
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)2572 SvXMLImportContext *SmXMLRowContext_Impl::CreateChildContext(
2573 sal_uInt16 nPrefix,
2574 const OUString& rLocalName,
2575 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2576 {
2577 SvXMLImportContext* pContext = StrictCreateChildContext(nPrefix,
2578 rLocalName, xAttrList);
2579
2580 if (!pContext)
2581 {
2582 //Hmm, unrecognized for this level, check to see if its
2583 //an element that can have an implicit schema around it
2584 pContext = SmXMLDocContext_Impl::CreateChildContext(nPrefix,
2585 rLocalName,xAttrList);
2586 }
2587 return pContext;
2588 }
2589
2590
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)2591 SvXMLImportContext *SmXMLMultiScriptsContext_Impl::CreateChildContext(
2592 sal_uInt16 nPrefix,
2593 const OUString& rLocalName,
2594 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2595 {
2596 SvXMLImportContext* pContext = 0L;
2597
2598 const SvXMLTokenMap& rTokenMap = GetSmImport().
2599 GetPresScriptEmptyElemTokenMap();
2600 switch(rTokenMap.Get(nPrefix, rLocalName))
2601 {
2602 case XML_TOK_MPRESCRIPTS:
2603 MiddleElement();
2604 pContext = GetSmImport().CreatePrescriptsContext(nPrefix,
2605 rLocalName, xAttrList);
2606 break;
2607 case XML_TOK_NONE:
2608 pContext = GetSmImport().CreateNoneContext(nPrefix,rLocalName,
2609 xAttrList);
2610 break;
2611 default:
2612 pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
2613 rLocalName,xAttrList);
2614 break;
2615 }
2616 return pContext;
2617 }
2618
MiddleElement()2619 void SmXMLMultiScriptsContext_Impl::MiddleElement()
2620 {
2621 bHasPrescripts=sal_True;
2622
2623 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2624 DBG_ASSERT( rNodeStack.Count() - nElementCount > 0, "Sub has no arguments" );
2625 if (rNodeStack.Count()-nElementCount > 1)
2626 {
2627 SmToken aToken;
2628 aToken.cMathChar = '\0';
2629 aToken.nGroup = 0;
2630 aToken.nLevel = 0;
2631 aToken.eType = TRSUB;
2632 sal_uLong nFinalCount = rNodeStack.Count()-nElementCount-1;
2633
2634 SmNodeStack aReverseStack;
2635 while (rNodeStack.Count()-nElementCount)
2636 {
2637 SmNode *pThing = rNodeStack.Pop();
2638 aReverseStack.Push(pThing);
2639 }
2640
2641 for (sal_uLong nCount=0;nCount < nFinalCount;nCount+=2)
2642 {
2643 SmSubSupNode *pNode = new SmSubSupNode(aToken);
2644
2645 // initialize subnodes array
2646 SmNodeArray aSubNodes;
2647 aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
2648 for (sal_uLong i = 1; i < aSubNodes.size(); i++)
2649 aSubNodes[i] = NULL;
2650
2651 /*On each loop the base and its sub sup pair becomes the
2652 base for the next loop to which the next sub sup pair is
2653 attached, i.e. wheels within wheels*/
2654 //if (nCount == 0)
2655 aSubNodes[0] = aReverseStack.Pop();
2656
2657 SmNode *pScriptNode = aReverseStack.Pop();
2658
2659 if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
2660 (pScriptNode->GetToken().aText.Len())))
2661 aSubNodes[RSUB+1] = pScriptNode;
2662 pScriptNode = aReverseStack.Pop();
2663 if (pScriptNode && ((pScriptNode->GetToken().eType != TIDENT) ||
2664 (pScriptNode->GetToken().aText.Len())))
2665 aSubNodes[RSUP+1] = pScriptNode;
2666
2667 pNode->SetSubNodes(aSubNodes);
2668 aReverseStack.Push(pNode);
2669 }
2670 rNodeStack.Push(aReverseStack.Pop());
2671 }
2672 }
2673
2674
EndElement()2675 void SmXMLTableContext_Impl::EndElement()
2676 {
2677 SmNodeArray aExpressionArray;
2678 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2679 SmNodeStack aReverseStack;
2680 aExpressionArray.resize(rNodeStack.Count()-nElementCount);
2681
2682 sal_uLong nRows = rNodeStack.Count()-nElementCount;
2683 sal_uInt16 nCols = 0;
2684
2685 SmStructureNode *pArray;
2686 for (sal_uLong i=rNodeStack.Count()-nElementCount;i > 0;i--)
2687 {
2688 pArray = (SmStructureNode *)rNodeStack.Pop();
2689 if (pArray->GetNumSubNodes() == 0)
2690 {
2691 //This is a little tricky, it is possible that there was
2692 //be elements that were not inside a <mtd> pair, in which
2693 //case they will not be in a row, i.e. they will not have
2694 //SubNodes, so we have to wait until here before we can
2695 //resolve the situation. Implicitsurrounding tags are
2696 //surprisingly difficult to get right within this
2697 //architecture
2698
2699 SmNodeArray aRelationArray;
2700 aRelationArray.resize(1);
2701 aRelationArray[0] = pArray;
2702 SmToken aDummy;
2703 pArray = new SmExpressionNode(aDummy);
2704 pArray->SetSubNodes(aRelationArray);
2705 }
2706
2707 if (pArray->GetNumSubNodes() > nCols)
2708 nCols = pArray->GetNumSubNodes();
2709 aReverseStack.Push(pArray);
2710 }
2711 aExpressionArray.resize(nCols*nRows);
2712 sal_uLong j=0;
2713 while (aReverseStack.Count())
2714 {
2715 pArray = (SmStructureNode *)aReverseStack.Pop();
2716 for (sal_uInt16 i=0;i<pArray->GetNumSubNodes();i++)
2717 aExpressionArray[j++] = pArray->GetSubNode(i);
2718 }
2719
2720 SmToken aToken;
2721 aToken.cMathChar = '\0';
2722 aToken.nGroup = TRGROUP;
2723 aToken.nLevel = 0;
2724 aToken.eType = TMATRIX;
2725 SmMatrixNode *pSNode = new SmMatrixNode(aToken);
2726 pSNode->SetSubNodes(aExpressionArray);
2727 pSNode->SetRowCol(static_cast<sal_uInt16>(nRows),nCols);
2728 rNodeStack.Push(pSNode);
2729 }
2730
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)2731 SvXMLImportContext *SmXMLTableRowContext_Impl::CreateChildContext(
2732 sal_uInt16 nPrefix,
2733 const OUString& rLocalName,
2734 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2735 {
2736 SvXMLImportContext* pContext = 0L;
2737
2738 const SvXMLTokenMap& rTokenMap = GetSmImport().
2739 GetPresTableElemTokenMap();
2740 switch(rTokenMap.Get(nPrefix, rLocalName))
2741 {
2742 case XML_TOK_MTD:
2743 pContext = GetSmImport().CreateTableCellContext(nPrefix,
2744 rLocalName, xAttrList);
2745 break;
2746 default:
2747 pContext = SmXMLRowContext_Impl::CreateChildContext(nPrefix,
2748 rLocalName,xAttrList);
2749 break;
2750 }
2751 return pContext;
2752 }
2753
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)2754 SvXMLImportContext *SmXMLTableContext_Impl::CreateChildContext(
2755 sal_uInt16 nPrefix,
2756 const OUString& rLocalName,
2757 const uno::Reference<xml::sax::XAttributeList>& xAttrList)
2758 {
2759 SvXMLImportContext* pContext = 0L;
2760
2761 const SvXMLTokenMap& rTokenMap = GetSmImport().
2762 GetPresTableElemTokenMap();
2763 switch(rTokenMap.Get(nPrefix, rLocalName))
2764 {
2765 case XML_TOK_MTR:
2766 pContext = GetSmImport().CreateTableRowContext(nPrefix,rLocalName,
2767 xAttrList);
2768 break;
2769 default:
2770 pContext = SmXMLTableRowContext_Impl::CreateChildContext(nPrefix,
2771 rLocalName,xAttrList);
2772 break;
2773 }
2774 return pContext;
2775 }
2776
EndElement()2777 void SmXMLMultiScriptsContext_Impl::EndElement()
2778 {
2779 if (!bHasPrescripts)
2780 MiddleElement();
2781
2782 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2783 if (rNodeStack.Count()-nElementCount > 1)
2784 {
2785 SmToken aToken;
2786 aToken.cMathChar = '\0';
2787 aToken.nGroup = 0;
2788 aToken.nLevel = 0;
2789 aToken.eType = TLSUB;
2790 sal_uLong nFinalCount = rNodeStack.Count()-nElementCount-1;
2791
2792 SmNodeStack aReverseStack;
2793 while (rNodeStack.Count()-nElementCount)
2794 aReverseStack.Push(rNodeStack.Pop());
2795 for (sal_uLong nCount=0;nCount < nFinalCount;nCount+=2)
2796 {
2797 SmSubSupNode *pNode = new SmSubSupNode(aToken);
2798
2799 // initialize subnodes array
2800 SmNodeArray aSubNodes;
2801 aSubNodes.resize(1 + SUBSUP_NUM_ENTRIES);
2802 for (sal_uLong i = 1; i < aSubNodes.size(); i++)
2803 aSubNodes[i] = NULL;
2804
2805 /*On each loop the base and its sub sup pair becomes the
2806 base for the next loop to which the next sub sup pair is
2807 attached, i.e. wheels within wheels*/
2808 //if (nCount == 0)
2809 aSubNodes[0] = aReverseStack.Pop();
2810
2811 SmNode *pScriptNode = aReverseStack.Pop();
2812 if (pScriptNode->GetToken().aText.Len())
2813 aSubNodes[LSUB+1] = pScriptNode;
2814 pScriptNode = aReverseStack.Pop();
2815 if (pScriptNode->GetToken().aText.Len())
2816 aSubNodes[LSUP+1] = pScriptNode;
2817
2818 pNode->SetSubNodes(aSubNodes);
2819 aReverseStack.Push(pNode);
2820 }
2821 rNodeStack.Push(aReverseStack.Pop());
2822 }
2823
2824 }
EndElement()2825 void SmXMLActionContext_Impl::EndElement()
2826 {
2827 /*For now we will just assume that the
2828 selected attribute is one, and then just display
2829 that expression alone, i.e. remove all expect the
2830 first pushed one*/
2831
2832 SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
2833 for (sal_uLong i=rNodeStack.Count()-nElementCount;i > 1;i--)
2834 {
2835 delete rNodeStack.Pop();
2836 }
2837 }
2838
CreateContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2839 SvXMLImportContext *SmXMLImport::CreateContext(sal_uInt16 nPrefix,
2840 const OUString &rLocalName,
2841 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2842 {
2843 if ( XML_NAMESPACE_OFFICE == nPrefix )
2844 {
2845 if ( (IsXMLToken(rLocalName, XML_DOCUMENT) ||
2846 IsXMLToken(rLocalName, XML_DOCUMENT_META)))
2847 {
2848 uno::Reference<xml::sax::XDocumentHandler> xDocBuilder(
2849 mxServiceFactory->createInstance(
2850 ::rtl::OUString::createFromAscii(
2851 "com.sun.star.xml.dom.SAXDocumentBuilder")),
2852 uno::UNO_QUERY_THROW);
2853 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
2854 GetModel(), uno::UNO_QUERY_THROW);
2855 return IsXMLToken(rLocalName, XML_DOCUMENT_META)
2856 ? new SvXMLMetaDocumentContext(*this,
2857 XML_NAMESPACE_OFFICE, rLocalName,
2858 xDPS->getDocumentProperties(), xDocBuilder)
2859 // flat OpenDocument file format -- this has not been tested...
2860 : new SmXMLFlatDocContext_Impl( *this, nPrefix, rLocalName,
2861 xDPS->getDocumentProperties(), xDocBuilder);
2862 }
2863 else
2864 {
2865 return new SmXMLOfficeContext_Impl( *this,nPrefix,rLocalName);
2866 }
2867 }
2868 else
2869 return new SmXMLDocContext_Impl(*this,nPrefix,rLocalName);
2870 }
2871
CreateRowContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2872 SvXMLImportContext *SmXMLImport::CreateRowContext(sal_uInt16 nPrefix,
2873 const OUString &rLocalName,
2874 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2875 {
2876 return new SmXMLRowContext_Impl(*this,nPrefix,rLocalName);
2877 }
2878
CreateTextContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2879 SvXMLImportContext *SmXMLImport::CreateTextContext(sal_uInt16 nPrefix,
2880 const OUString &rLocalName,
2881 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2882 {
2883 return new SmXMLTextContext_Impl(*this,nPrefix,rLocalName);
2884 }
2885
CreateAnnotationContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2886 SvXMLImportContext *SmXMLImport::CreateAnnotationContext(sal_uInt16 nPrefix,
2887 const OUString &rLocalName,
2888 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2889 {
2890 return new SmXMLAnnotationContext_Impl(*this,nPrefix,rLocalName);
2891 }
2892
CreateStringContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2893 SvXMLImportContext *SmXMLImport::CreateStringContext(sal_uInt16 nPrefix,
2894 const OUString &rLocalName,
2895 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2896 {
2897 return new SmXMLStringContext_Impl(*this,nPrefix,rLocalName);
2898 }
2899
CreateNumberContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2900 SvXMLImportContext *SmXMLImport::CreateNumberContext(sal_uInt16 nPrefix,
2901 const OUString &rLocalName,
2902 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2903 {
2904 return new SmXMLNumberContext_Impl(*this,nPrefix,rLocalName);
2905 }
2906
CreateIdentifierContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2907 SvXMLImportContext *SmXMLImport::CreateIdentifierContext(sal_uInt16 nPrefix,
2908 const OUString &rLocalName,
2909 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2910 {
2911 return new SmXMLIdentifierContext_Impl(*this,nPrefix,rLocalName);
2912 }
2913
CreateOperatorContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2914 SvXMLImportContext *SmXMLImport::CreateOperatorContext(sal_uInt16 nPrefix,
2915 const OUString &rLocalName,
2916 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2917 {
2918 return new SmXMLOperatorContext_Impl(*this,nPrefix,rLocalName);
2919 }
2920
CreateSpaceContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2921 SvXMLImportContext *SmXMLImport::CreateSpaceContext(sal_uInt16 nPrefix,
2922 const OUString &rLocalName,
2923 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2924 {
2925 return new SmXMLSpaceContext_Impl(*this,nPrefix,rLocalName);
2926 }
2927
2928
CreateFracContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2929 SvXMLImportContext *SmXMLImport::CreateFracContext(sal_uInt16 nPrefix,
2930 const OUString &rLocalName,
2931 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2932 {
2933 return new SmXMLFracContext_Impl(*this,nPrefix,rLocalName);
2934 }
2935
CreateSqrtContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2936 SvXMLImportContext *SmXMLImport::CreateSqrtContext(sal_uInt16 nPrefix,
2937 const OUString &rLocalName,
2938 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2939 {
2940 return new SmXMLSqrtContext_Impl(*this,nPrefix,rLocalName);
2941 }
2942
CreateRootContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2943 SvXMLImportContext *SmXMLImport::CreateRootContext(sal_uInt16 nPrefix,
2944 const OUString &rLocalName,
2945 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2946 {
2947 return new SmXMLRootContext_Impl(*this,nPrefix,rLocalName);
2948 }
2949
CreateStyleContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2950 SvXMLImportContext *SmXMLImport::CreateStyleContext(sal_uInt16 nPrefix,
2951 const OUString &rLocalName,
2952 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2953 {
2954 return new SmXMLStyleContext_Impl(*this,nPrefix,rLocalName);
2955 }
2956
CreatePaddedContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2957 SvXMLImportContext *SmXMLImport::CreatePaddedContext(sal_uInt16 nPrefix,
2958 const OUString &rLocalName,
2959 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2960 {
2961 return new SmXMLPaddedContext_Impl(*this,nPrefix,rLocalName);
2962 }
2963
CreatePhantomContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2964 SvXMLImportContext *SmXMLImport::CreatePhantomContext(sal_uInt16 nPrefix,
2965 const OUString &rLocalName,
2966 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2967 {
2968 return new SmXMLPhantomContext_Impl(*this,nPrefix,rLocalName);
2969 }
2970
CreateFencedContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2971 SvXMLImportContext *SmXMLImport::CreateFencedContext(sal_uInt16 nPrefix,
2972 const OUString &rLocalName,
2973 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2974 {
2975 return new SmXMLFencedContext_Impl(*this,nPrefix,rLocalName);
2976 }
2977
CreateErrorContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2978 SvXMLImportContext *SmXMLImport::CreateErrorContext(sal_uInt16 nPrefix,
2979 const OUString &rLocalName,
2980 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2981 {
2982 return new SmXMLErrorContext_Impl(*this,nPrefix,rLocalName);
2983 }
2984
CreateSubContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2985 SvXMLImportContext *SmXMLImport::CreateSubContext(sal_uInt16 nPrefix,
2986 const OUString &rLocalName,
2987 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2988 {
2989 return new SmXMLSubContext_Impl(*this,nPrefix,rLocalName);
2990 }
2991
CreateSubSupContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2992 SvXMLImportContext *SmXMLImport::CreateSubSupContext(sal_uInt16 nPrefix,
2993 const OUString &rLocalName,
2994 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
2995 {
2996 return new SmXMLSubSupContext_Impl(*this,nPrefix,rLocalName);
2997 }
2998
CreateSupContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)2999 SvXMLImportContext *SmXMLImport::CreateSupContext(sal_uInt16 nPrefix,
3000 const OUString &rLocalName,
3001 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3002 {
3003 return new SmXMLSupContext_Impl(*this,nPrefix,rLocalName);
3004 }
3005
CreateUnderContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3006 SvXMLImportContext *SmXMLImport::CreateUnderContext(sal_uInt16 nPrefix,
3007 const OUString &rLocalName,
3008 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3009 {
3010 return new SmXMLUnderContext_Impl(*this,nPrefix,rLocalName);
3011 }
3012
CreateOverContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3013 SvXMLImportContext *SmXMLImport::CreateOverContext(sal_uInt16 nPrefix,
3014 const OUString &rLocalName,
3015 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3016 {
3017 return new SmXMLOverContext_Impl(*this,nPrefix,rLocalName);
3018 }
3019
CreateUnderOverContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3020 SvXMLImportContext *SmXMLImport::CreateUnderOverContext(sal_uInt16 nPrefix,
3021 const OUString &rLocalName,
3022 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3023 {
3024 return new SmXMLUnderOverContext_Impl(*this,nPrefix,rLocalName);
3025 }
3026
CreateMultiScriptsContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3027 SvXMLImportContext *SmXMLImport::CreateMultiScriptsContext(sal_uInt16 nPrefix,
3028 const OUString &rLocalName,
3029 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3030 {
3031 return new SmXMLMultiScriptsContext_Impl(*this,nPrefix,rLocalName);
3032 }
3033
CreateTableContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3034 SvXMLImportContext *SmXMLImport::CreateTableContext(sal_uInt16 nPrefix,
3035 const OUString &rLocalName,
3036 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3037 {
3038 return new SmXMLTableContext_Impl(*this,nPrefix,rLocalName);
3039 }
CreateTableRowContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3040 SvXMLImportContext *SmXMLImport::CreateTableRowContext(sal_uInt16 nPrefix,
3041 const OUString &rLocalName,
3042 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3043 {
3044 return new SmXMLTableRowContext_Impl(*this,nPrefix,rLocalName);
3045 }
CreateTableCellContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3046 SvXMLImportContext *SmXMLImport::CreateTableCellContext(sal_uInt16 nPrefix,
3047 const OUString &rLocalName,
3048 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3049 {
3050 return new SmXMLTableCellContext_Impl(*this,nPrefix,rLocalName);
3051 }
3052
CreateNoneContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3053 SvXMLImportContext *SmXMLImport::CreateNoneContext(sal_uInt16 nPrefix,
3054 const OUString &rLocalName,
3055 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3056 {
3057 return new SmXMLNoneContext_Impl(*this,nPrefix,rLocalName);
3058 }
3059
CreatePrescriptsContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3060 SvXMLImportContext *SmXMLImport::CreatePrescriptsContext(sal_uInt16 nPrefix,
3061 const OUString &rLocalName,
3062 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3063 {
3064 return new SmXMLPrescriptsContext_Impl(*this,nPrefix,rLocalName);
3065 }
3066
CreateAlignGroupContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3067 SvXMLImportContext *SmXMLImport::CreateAlignGroupContext(sal_uInt16 nPrefix,
3068 const OUString &rLocalName,
3069 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3070 {
3071 return new SmXMLAlignGroupContext_Impl(*this,nPrefix,rLocalName);
3072 }
3073
CreateActionContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> &)3074 SvXMLImportContext *SmXMLImport::CreateActionContext(sal_uInt16 nPrefix,
3075 const OUString &rLocalName,
3076 const uno::Reference <xml::sax::XAttributeList> & /*xAttrList*/)
3077 {
3078 return new SmXMLActionContext_Impl(*this,nPrefix,rLocalName);
3079 }
3080
~SmXMLImport()3081 SmXMLImport::~SmXMLImport() throw ()
3082 {
3083 delete pPresLayoutElemTokenMap;
3084 delete pPresElemTokenMap;
3085 delete pPresScriptEmptyElemTokenMap;
3086 delete pPresTableElemTokenMap;
3087 delete pPresLayoutAttrTokenMap;
3088 delete pFencedAttrTokenMap;
3089 delete pColorTokenMap;
3090 delete pOperatorAttrTokenMap;
3091 delete pAnnotationAttrTokenMap;
3092 }
3093
SetViewSettings(const Sequence<PropertyValue> & aViewProps)3094 void SmXMLImport::SetViewSettings(const Sequence<PropertyValue>& aViewProps)
3095 {
3096 uno::Reference <frame::XModel> xModel = GetModel();
3097 if ( !xModel.is() )
3098 return;
3099
3100 uno::Reference <lang::XUnoTunnel> xTunnel;
3101 xTunnel = uno::Reference <lang::XUnoTunnel> (xModel,uno::UNO_QUERY);
3102 SmModel *pModel = reinterpret_cast<SmModel *>
3103 (xTunnel->getSomething(SmModel::getUnoTunnelId()));
3104
3105 if ( !pModel )
3106 return;
3107
3108 SmDocShell *pDocShell =
3109 static_cast<SmDocShell*>(pModel->GetObjectShell());
3110 if ( !pDocShell )
3111 return;
3112
3113 Rectangle aRect( pDocShell->GetVisArea() );
3114
3115 sal_Int32 nCount = aViewProps.getLength();
3116 const PropertyValue *pValue = aViewProps.getConstArray();
3117
3118 long nTmp = 0;
3119 //sal_Bool bShowDeletes = sal_False, bShowInserts = sal_False, bShowFooter = sal_False, bShowHeader = sal_False;
3120
3121 for (sal_Int32 i = 0; i < nCount ; i++)
3122 {
3123 if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaTop" ) ) )
3124 {
3125 pValue->Value >>= nTmp;
3126 aRect.setY( nTmp );
3127 }
3128 else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaLeft" ) ) )
3129 {
3130 pValue->Value >>= nTmp;
3131 aRect.setX( nTmp );
3132 }
3133 else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaWidth" ) ) )
3134 {
3135 pValue->Value >>= nTmp;
3136 Size aSize( aRect.GetSize() );
3137 aSize.Width() = nTmp;
3138 aRect.SetSize( aSize );
3139 }
3140 else if (pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( "ViewAreaHeight" ) ) )
3141 {
3142 pValue->Value >>= nTmp;
3143 Size aSize( aRect.GetSize() );
3144 aSize.Height() = nTmp;
3145 aRect.SetSize( aSize );
3146 }
3147 pValue++;
3148 }
3149
3150 pDocShell->SetVisArea ( aRect );
3151 }
3152
SetConfigurationSettings(const Sequence<PropertyValue> & aConfProps)3153 void SmXMLImport::SetConfigurationSettings(const Sequence<PropertyValue>& aConfProps)
3154 {
3155 uno::Reference < XPropertySet > xProps ( GetModel(), UNO_QUERY );
3156 if ( xProps.is() )
3157 {
3158 Reference < XPropertySetInfo > xInfo ( xProps->getPropertySetInfo() );
3159 if (xInfo.is() )
3160 {
3161 sal_Int32 nCount = aConfProps.getLength();
3162 const PropertyValue* pValues = aConfProps.getConstArray();
3163
3164 const OUString sFormula ( RTL_CONSTASCII_USTRINGPARAM ( "Formula" ) );
3165 const OUString sBasicLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "BasicLibraries" ) );
3166 const OUString sDialogLibraries ( RTL_CONSTASCII_USTRINGPARAM ( "DialogLibraries" ) );
3167 while ( nCount-- )
3168 {
3169 if (pValues->Name != sFormula &&
3170 pValues->Name != sBasicLibraries &&
3171 pValues->Name != sDialogLibraries)
3172 {
3173 try
3174 {
3175 if ( xInfo->hasPropertyByName( pValues->Name ) )
3176 xProps->setPropertyValue( pValues->Name, pValues->Value );
3177 }
3178 catch (beans::PropertyVetoException &e)
3179 {
3180 (void) e;
3181 // dealing with read-only properties here. Nothing to do...
3182 }
3183 catch( Exception& e)
3184 {
3185 (void) e;
3186 DBG_ERROR( "SmXMLImport::SetConfigurationSettings: Exception!" );
3187 }
3188 }
3189
3190 pValues++;
3191 }
3192 }
3193 }
3194 }
3195
3196
3197 ////////////////////////////////////////////////////////////
3198