xref: /trunk/main/sw/source/filter/basflt/fltini.cxx (revision 870262e3)
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_sw.hxx"
26 #define _SVSTDARR_STRINGS
27 
28 #include <string.h>
29 #include <stdio.h>                      // sscanf
30 #include <hintids.hxx>
31 #include <i18npool/lang.h>
32 #include <i18npool/mslangid.hxx>
33 #include <vcl/msgbox.hxx>
34 #include <svtools/parhtml.hxx>
35 #include <svl/svstdarr.hxx>
36 #include <sot/storage.hxx>
37 #include <sot/clsids.hxx>
38 #include <sfx2/app.hxx>
39 #include <sfx2/docfilt.hxx>
40 #include <sfx2/fcontnr.hxx>
41 #include <sfx2/docfile.hxx>
42 #include <editeng/lrspitem.hxx>
43 #include <editeng/tstpitem.hxx>
44 #include <doc.hxx>
45 #include <docary.hxx>
46 #include <pam.hxx>
47 #include <shellio.hxx>
48 #include <errhdl.hxx>
49 #include <docsh.hxx>
50 #include <wdocsh.hxx>
51 #include <fltini.hxx>
52 #include <hints.hxx>
53 #include <frmatr.hxx>
54 #include <fmtfsize.hxx>
55 #include <swtable.hxx>
56 #include <fmtcntnt.hxx>
57 #include <editeng/boxitem.hxx>
58 #include <frmatr.hxx>
59 #include <frmfmt.hxx>
60 #include <numrule.hxx>
61 #include <ndtxt.hxx>
62 #include <swfltopt.hxx>
63 #include <swerror.h>
64 #include <osl/module.hxx>
65 #include <comphelper/processfactory.hxx>
66 #include <comphelper/componentcontext.hxx>
67 #include <com/sun/star/beans/XPropertySet.hpp>
68 #include <com/sun/star/util/XMacroExpander.hpp>
69 #include <rtl/uri.hxx>
70 #include <tools/svlibrary.hxx>
71 
72 using namespace utl;
73 using rtl::OUString;
74 using namespace com::sun::star::uno;
75 using namespace com::sun::star;
76 
77 SwRead ReadAscii = 0, /*ReadSwg = 0, ReadSw3 = 0,*/
78                 ReadHTML = 0, ReadXML = 0;
79 
80 Reader* GetRTFReader();
81 Reader* GetWW8Reader();
82 
83 // Note: if editing, please don't forget to modify also the enum
84 // ReaderWriterEnum and aFilterDetect in shellio.hxx
85 SwReaderWriterEntry aReaderWriter[] =
86 {
87     SwReaderWriterEntry( &::GetRTFReader, &::GetRTFWriter,  sal_True  ),
88     SwReaderWriterEntry( 0,               &::GetASCWriter,  sal_False ),
89     SwReaderWriterEntry( &::GetWW8Reader, &::GetWW8Writer,  sal_True  ),
90     SwReaderWriterEntry( &::GetWW8Reader, &::GetWW8Writer,  sal_True  ),
91     SwReaderWriterEntry( &::GetRTFReader, &::GetRTFWriter,  sal_True  ),
92     SwReaderWriterEntry( 0,               &::GetHTMLWriter, sal_True  ),
93     SwReaderWriterEntry( 0,               0,                sal_True  ),
94     SwReaderWriterEntry( &::GetWW8Reader, 0,                sal_True  ),
95     SwReaderWriterEntry( 0,               &::GetXMLWriter,  sal_True  ),
96     SwReaderWriterEntry( 0,               &::GetASCWriter,  sal_True  ),
97     SwReaderWriterEntry( 0,               &::GetASCWriter,  sal_True  )
98 };
99 
GetReader()100 Reader* SwReaderWriterEntry::GetReader()
101 {
102     if ( pReader )
103         return pReader;
104     else if ( fnGetReader )
105     {
106         pReader = (*fnGetReader)();
107         return pReader;
108     }
109     return NULL;
110 }
111 
GetWriter(const String & rNm,const String & rBaseURL,WriterRef & xWrt) const112 void SwReaderWriterEntry::GetWriter( const String& rNm, const String& rBaseURL, WriterRef& xWrt ) const
113 {
114     if ( fnGetWriter )
115         (*fnGetWriter)( rNm, rBaseURL, xWrt );
116     else
117         xWrt = WriterRef(0);
118 }
119 
120 /*SwRead SwGetReaderSw3() // SW_DLLPUBLIC
121 {
122         return ReadSw3;
123 }
124 */
SwGetReaderXML()125 SwRead SwGetReaderXML() // SW_DLLPUBLIC
126 {
127         return ReadXML;
128 }
129 
IsDocShellRegistered()130 bool IsDocShellRegistered()
131 {
132     return 0 != SwDocShell::_GetInterface();
133 }
134 
_SetFltPtr(sal_uInt16 rPos,SwRead pReader)135 inline void _SetFltPtr( sal_uInt16 rPos, SwRead pReader )
136 {
137         aReaderWriter[ rPos ].pReader = pReader;
138 }
139 
_InitFilter()140 void _InitFilter()
141 {
142     _SetFltPtr( READER_WRITER_BAS, (ReadAscii = new AsciiReader) );
143     _SetFltPtr( READER_WRITER_HTML, (ReadHTML = new HTMLReader) );
144     _SetFltPtr( READER_WRITER_WW1, new WW1Reader );
145     _SetFltPtr( READER_WRITER_XML, (ReadXML = new XMLReader)  );
146 
147 #ifdef NEW_WW97_EXPORT
148     aReaderWriter[ READER_WRITER_WW1 ].fnGetWriter =  &::GetWW8Writer;
149     aReaderWriter[ READER_WRITER_WW5 ].fnGetWriter = &::GetWW8Writer;
150 #endif
151 
152     _SetFltPtr( READER_WRITER_TEXT_DLG, ReadAscii );
153     _SetFltPtr( READER_WRITER_TEXT, ReadAscii );
154 }
155 
_FinitFilter()156 void _FinitFilter()
157 {
158         // die Reader vernichten
159         for( sal_uInt16 n = 0; n < MAXFILTER; ++n )
160         {
161                 SwReaderWriterEntry& rEntry = aReaderWriter[n];
162                 if( rEntry.bDelReader && rEntry.pReader )
163                         delete rEntry.pReader, rEntry.pReader = NULL;
164         }
165 }
166 
167 
168 /*  */
169 
170 namespace SwReaderWriter {
171 
GetReader(ReaderWriterEnum eReader)172 Reader* GetReader( ReaderWriterEnum eReader )
173 {
174     return aReaderWriter[eReader].GetReader();
175 }
176 
GetWriter(const String & rFltName,const String & rBaseURL,WriterRef & xRet)177 void GetWriter( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
178 {
179         for( sal_uInt16 n = 0; n < MAXFILTER; ++n )
180                 if( aFilterDetect[n].IsFilter( rFltName ) )
181                 {
182             aReaderWriter[n].GetWriter( rFltName, rBaseURL, xRet );
183                         break;
184                 }
185 }
186 
GetReader(const String & rFltName)187 SwRead GetReader( const String& rFltName )
188 {
189         SwRead pRead = 0;
190         for( sal_uInt16 n = 0; n < MAXFILTER; ++n )
191                 if( aFilterDetect[n].IsFilter( rFltName ) )
192                 {
193                         pRead = aReaderWriter[n].GetReader();
194                         // fuer einige Reader noch eine Sonderbehandlung:
195                         if ( pRead )
196                                 pRead->SetFltName( rFltName );
197                         break;
198                 }
199         return pRead;
200 }
201 
202 } // namespace SwReaderWriter
203 
204 /*  */
205 
206 /////////////// die Storage Reader/Writer ////////////////////////////////
207 
208 /*void GetSw3Writer( const String&, const String& rBaseURL, WriterRef& xRet )
209 {
210     DBG_ERROR( "Shouldn't happen!");
211         xRet = new Sw3Writer;
212 }
213 */
214 
OpenMainStream(SvStorageStreamRef & rRef,sal_uInt16 & rBuffSize)215 sal_uLong StgReader::OpenMainStream( SvStorageStreamRef& rRef, sal_uInt16& rBuffSize )
216 {
217         sal_uLong nRet = ERR_SWG_READ_ERROR;
218         ASSERT( pStg, "wo ist mein Storage?" );
219         const SfxFilter* pFltr = SwIoSystem::GetFilterOfFormat( aFltName );
220         if( pFltr )
221         {
222         rRef = pStg->OpenSotStream( SwIoSystem::GetSubStorageName( *pFltr ),
223                                                                         STREAM_READ | STREAM_SHARE_DENYALL );
224 
225                 if( rRef.Is() )
226                 {
227                         if( SVSTREAM_OK == rRef->GetError() )
228                         {
229                                 sal_uInt16 nOld = rRef->GetBufferSize();
230                                 rRef->SetBufferSize( rBuffSize );
231                                 rBuffSize = nOld;
232                                 nRet = 0;
233                         }
234                         else
235                                 nRet = rRef->GetError();
236                 }
237         }
238         return nRet;
239 }
240 
241 /*  */
242 /*
243 sal_uLong Sw3Reader::Read( SwDoc &rDoc, SwPaM &rPam, const String & )
244 {
245         sal_uLong nRet;
246         if( pStg && pIO )
247         {
248                 // sal_True: Vorlagen ueberschreiben
249                 pIO->SetReadOptions( aOpt,sal_True );
250                 if( !bInsertMode )
251                 {
252                         // Im Laden-Modus darf der PaM-Content-Teil nicht
253                         // in den Textbereich zeigen (Nodes koennen geloescht werden)
254                         rPam.GetBound( sal_True ).nContent.Assign( 0, 0 );
255                         rPam.GetBound( sal_False ).nContent.Assign( 0, 0 );
256                 }
257                 nRet = pIO->Load( pStg, bInsertMode ? &rPam : 0 );
258                 aOpt.ResetAllFmtsOnly();
259                 pIO->SetReadOptions( aOpt, sal_True );
260         }
261         else
262         {
263                 ASSERT( sal_False, "Sw3-Read without storage and/or IO system" );
264                 nRet = ERR_SWG_READ_ERROR;
265         }
266         return nRet;
267 }
268 
269         // read the sections of the document, which is equal to the medium.
270         // returns the count of it
271 sal_uInt16 Sw3Reader::GetSectionList( SfxMedium& rMedium,
272                                                                         SvStrings& rStrings ) const
273 {
274         SvStorageRef aStg( rMedium.GetStorage() );
275         const SfxFilter* pFlt = rMedium.GetFilter();
276         ASSERT( pFlt && pFlt->GetVersion(),
277                                                                 "Kein Filter oder Filter ohne FF-Version" );
278         if( pFlt && pFlt->GetVersion() )
279                 aStg->SetVersion( (long)pFlt->GetVersion() );
280 
281         if( pIO )
282                 pIO->GetSectionList( &aStg, rStrings );
283         return rStrings.Count();
284     return 0;
285 }
286 */
287 
288 /*sal_uLong Sw3Writer::WriteStorage()
289 {
290     sal_uLong nRet;
291         if( pIO )
292         {
293                 // der gleiche Storage -> Save, sonst SaveAs aufrufen
294                 if( !bSaveAs )
295                         nRet = pIO->Save( pOrigPam, bWriteAll );
296                 else
297                         nRet = pIO->SaveAs( pStg, pOrigPam, bWriteAll );
298 
299                 pIO = 0;                // nach dem Schreiben ist der Pointer ungueltig !!
300         }
301         else
302         {
303                 ASSERT( sal_False, "Sw3-Writer without IO-System" )
304                 nRet = ERR_SWG_WRITE_ERROR;
305     }
306     return nRet;
307 }
308 
309 sal_uLong Sw3Writer::WriteMedium( SfxMedium& )
310 {
311     DBG_ERROR( "Shouldn't be used currently!");
312         return WriteStorage();
313 }
314 
315 sal_Bool Sw3Writer::IsSw3Writer() const { return sal_True; }
316 */
317 
SetPasswd(const String &)318 void Writer::SetPasswd( const String& ) {}
319 
320 
SetVersion(const String &,long)321 void Writer::SetVersion( const String&, long ) {}
322 
323 
IsStgWriter() const324 sal_Bool Writer::IsStgWriter() const { return sal_False; }
325 //sal_Bool Writer::IsSw3Writer() const { return sal_False; }
326 
IsStgWriter() const327 sal_Bool StgWriter::IsStgWriter() const { return sal_True; }
328 
329 /*  */
330 
331 
332 
NeedsPasswd(const Reader &)333 sal_Bool SwReader::NeedsPasswd( const Reader& /*rOptions*/ )
334 {
335         sal_Bool bRes = sal_False;
336     return bRes;
337 }
338 
339 
CheckPasswd(const String &,const Reader &)340 sal_Bool SwReader::CheckPasswd( const String& /*rPasswd*/, const Reader& /*rOptions*/ )
341 {
342     return sal_True;
343 }
344 
345 
346 /*  */
347 
348 //-----------------------------------------------------------------------
349 // Filter Flags lesen, wird von WW8 / W4W / EXCEL / LOTUS benutzt.
350 //-----------------------------------------------------------------------
351 
352 /*
353 <FilterFlags>
354         <Excel_Lotus>
355                 <MinRow cfg:type="long">0</MinRow>
356                 <MaxRow cfg:type="long">0</MaxRow>
357                 <MinCol cfg:type="long">0</MinCol>
358                 <MaxCol cfg:type="long">0</MaxCol>
359         </Excel_Lotus>
360         <W4W>
361                 <W4WHD cfg:type="long">0</W4WHD>
362                 <W4WFT cfg:type="long">0</W4WFT>
363                 <W4W000 cfg:type="long">0</W4W000>
364         </W4W>
365         <WinWord>
366                 <WW1F cfg:type="long">0</WW1F>
367                 <WW cfg:type="long">0</WW>
368                 <WW8 cfg:type="long">0</WW8>
369                 <WWF cfg:type="long">0</WWF>
370                 <WWFA0 cfg:type="long">0</WWFA0>
371                 <WWFA1 cfg:type="long">0</WWFA1>
372                 <WWFA2 cfg:type="long">0</WWFA2>
373                 <WWFB0 cfg:type="long">0</WWFB0>
374                 <WWFB1 cfg:type="long">0</WWFB1>
375                 <WWFB2 cfg:type="long">0</WWFB2>
376                 <WWFLX cfg:type="long">0</WWFLX>
377                 <WWFLY cfg:type="long">0</WWFLY>
378                 <WWFT cfg:type="long">0</WWFT>
379                 <WWWR cfg:type="long">0</WWWR>
380         </WinWord>
381         <Writer>
382                 <SW3Imp cfg:type="long">0</SW3Imp>
383         </Writer>
384 </FilterFlags>
385 */
386 
387 #define FILTER_OPTION_ROOT              String::CreateFromAscii( \
388                                 RTL_CONSTASCII_STRINGPARAM( "Office.Writer/FilterFlags" ) )
389 
SwFilterOptions(sal_uInt16 nCnt,const sal_Char ** ppNames,sal_uInt32 * pValues)390 SwFilterOptions::SwFilterOptions( sal_uInt16 nCnt, const sal_Char** ppNames,
391                                                                 sal_uInt32* pValues )
392         : ConfigItem( FILTER_OPTION_ROOT )
393 {
394         GetValues( nCnt, ppNames, pValues );
395 }
396 
GetValues(sal_uInt16 nCnt,const sal_Char ** ppNames,sal_uInt32 * pValues)397 void SwFilterOptions::GetValues( sal_uInt16 nCnt, const sal_Char** ppNames,
398                                                                         sal_uInt32* pValues )
399 {
400         Sequence<OUString> aNames( nCnt );
401         OUString* pNames = aNames.getArray();
402         sal_uInt16 n;
403 
404         for( n = 0; n < nCnt; ++n )
405                 pNames[ n ] = OUString::createFromAscii( ppNames[ n ] );
406         Sequence<Any> aValues = GetProperties( aNames );
407 
408         if( nCnt == aValues.getLength() )
409         {
410                 const Any* pAnyValues = aValues.getConstArray();
411                 for( n = 0; n < nCnt; ++n )
412                         pValues[ n ] = pAnyValues[ n ].hasValue()
413                                                         ? *(sal_uInt32*)pAnyValues[ n ].getValue()
414                                                         : 0;
415         }
416         else
417                 for( n = 0; n < nCnt; ++n )
418                         pValues[ n ] = 0;
419 }
420 
Commit()421 void SwFilterOptions::Commit() {}
Notify(const::com::sun::star::uno::Sequence<rtl::OUString> &)422 void SwFilterOptions::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& ) {}
423 
424 /*  */
425 
426 
SetFltName(const String & rFltNm)427 void StgReader::SetFltName( const String& rFltNm )
428 {
429         if( SW_STORAGE_READER & GetReaderType() )
430                 aFltName = rFltNm;
431 }
432 
433 
434 /*  */
435 
SwRelNumRuleSpaces(SwDoc & rDoc,sal_Bool bNDoc)436 SwRelNumRuleSpaces::SwRelNumRuleSpaces( SwDoc& rDoc, sal_Bool bNDoc )
437         : bNewDoc( bNDoc )
438 {
439         pNumRuleTbl = new SwNumRuleTbl( 8, 8 );
440         if( !bNDoc )
441                 pNumRuleTbl->Insert( &rDoc.GetNumRuleTbl(), 0 );
442 }
443 
~SwRelNumRuleSpaces()444 SwRelNumRuleSpaces::~SwRelNumRuleSpaces()
445 {
446         if( pNumRuleTbl )
447         {
448                 pNumRuleTbl->Remove( 0, pNumRuleTbl->Count() );
449                 delete pNumRuleTbl;
450         }
451 }
452 
SetNumRelSpaces(SwDoc & rDoc)453 void SwRelNumRuleSpaces::SetNumRelSpaces( SwDoc& rDoc )
454 {
455         const SwNumRuleTbl* pRuleTbl = NULL;
456 
457         if( !bNewDoc )
458         {
459                 // jetzt alle schon vorhanden NumRules aus dem Array entfernen,
460                 // damit nur die neuen angepasst werden
461                 SwNumRuleTbl aNumRuleTbl;
462                 aNumRuleTbl.Insert( pNumRuleTbl, 0 );
463                 pNumRuleTbl->Remove( 0, pNumRuleTbl->Count() );
464                 const SwNumRuleTbl& rRuleTbl = rDoc.GetNumRuleTbl();
465                 SwNumRule* pRule;
466 
467                 for( sal_uInt16 n = 0; n < rRuleTbl.Count(); ++n )
468                         if( USHRT_MAX == aNumRuleTbl.GetPos( ( pRule = rRuleTbl[ n ] )))
469                                 // war noch nicht vorhanden, also neu
470                                 pNumRuleTbl->Insert( pRule, pNumRuleTbl->Count() );
471 
472                 aNumRuleTbl.Remove( 0, aNumRuleTbl.Count() );
473 
474         pRuleTbl = pNumRuleTbl;
475         }
476     else
477     {
478         pRuleTbl = &rDoc.GetNumRuleTbl();
479     }
480 
481         if( pRuleTbl )
482         {
483                 for( sal_uInt16 n = pRuleTbl->Count(); n; )
484                 {
485                         SwNumRule* pRule = (*pRuleTbl)[ --n ];
486                         // Rule noch gueltig und am Doc vorhanden?
487                         if( USHRT_MAX != rDoc.GetNumRuleTbl().GetPos( pRule ))
488                         {
489                 // --> OD 2008-02-19 #refactorlists#
490 //                SwNumRuleInfo aUpd( pRule->GetName() );
491 //                aUpd.MakeList( rDoc );
492 
493 //                // bei allen nmumerierten Absaetzen vom linken Rand
494 //                // den absoluten Wert des NumFormates abziehen
495 //                for( sal_uLong nUpdPos = 0; nUpdPos < aUpd.GetList().Count();
496 //                    ++nUpdPos )
497 //                {
498 //                    SwTxtNode* pNd = aUpd.GetList().GetObject( nUpdPos );
499 //                    SetNumLSpace( *pNd, *pRule );
500 //                }
501                 SwNumRule::tTxtNodeList aTxtNodeList;
502                 pRule->GetTxtNodeList( aTxtNodeList );
503                 for ( SwNumRule::tTxtNodeList::iterator aIter = aTxtNodeList.begin();
504                       aIter != aTxtNodeList.end(); ++aIter )
505                 {
506                     SwTxtNode* pNd = *aIter;
507                     SetNumLSpace( *pNd, *pRule );
508                 }
509                 // <--
510                         }
511                 }
512         }
513 
514         if( pNumRuleTbl )
515         {
516                 pNumRuleTbl->Remove( 0, pNumRuleTbl->Count() );
517                 delete pNumRuleTbl, pNumRuleTbl = 0;
518         }
519 
520         if( bNewDoc )
521         {
522                 SetOultineRelSpaces( SwNodeIndex( rDoc.GetNodes() ),
523                                                         SwNodeIndex( rDoc.GetNodes().GetEndOfContent()));
524         }
525 }
526 
SetOultineRelSpaces(const SwNodeIndex & rStt,const SwNodeIndex & rEnd)527 void SwRelNumRuleSpaces::SetOultineRelSpaces( const SwNodeIndex& rStt,
528                                                                                         const SwNodeIndex& rEnd )
529 {
530         SwDoc* pDoc = rStt.GetNode().GetDoc();
531         const SwOutlineNodes& rOutlNds = pDoc->GetNodes().GetOutLineNds();
532         if( rOutlNds.Count() )
533         {
534                 sal_uInt16 nPos;
535                 rOutlNds.Seek_Entry( &rStt.GetNode(), &nPos );
536                 for( ; nPos < rOutlNds.Count() &&
537                                 rOutlNds[ nPos ]->GetIndex() < rEnd.GetIndex(); ++nPos )
538                 {
539                         SwTxtNode* pNd = rOutlNds[ nPos ]->GetTxtNode();
540                         if( pNd->IsOutline() && !pNd->GetNumRule() )
541                                 SetNumLSpace( *pNd, *pDoc->GetOutlineNumRule() );
542                 }
543         }
544 }
545 
SetNumLSpace(SwTxtNode & rNd,const SwNumRule & rRule)546 void SwRelNumRuleSpaces::SetNumLSpace( SwTxtNode& rNd, const SwNumRule& rRule )
547 {
548         sal_Bool bOutlineRule = OUTLINE_RULE == rRule.GetRuleType();
549     // --> OD 2005-11-18 #128056#
550     // correction of refactoring done by cws swnumtree:
551     // - assure a correct level for retrieving numbering format.
552 //    sal_uInt8 nLvl = rNd.GetLevel();
553     sal_uInt8 nLvl = 0;
554     if ( rNd.GetActualListLevel() >= 0 && rNd.GetActualListLevel() < MAXLEVEL )
555     {
556         nLvl = static_cast< sal_uInt8 >(rNd.GetActualListLevel());
557     }
558     // <--
559         const SwNumFmt& rFmt = rRule.Get( nLvl );
560         const SvxLRSpaceItem& rLR = rNd.GetSwAttrSet().GetLRSpace();
561 
562         SvxLRSpaceItem aLR( rLR );
563         aLR.SetTxtFirstLineOfst( 0 );
564 
565         // sagt der Node, das die Numerierung den Wert vorgibt?
566         if( !bOutlineRule && rNd.IsSetNumLSpace() )
567                 aLR.SetTxtLeft( 0 );
568         else
569         {
570                 long nLeft = rFmt.GetAbsLSpace(), nParaLeft = rLR.GetTxtLeft();
571                 if( 0 < rLR.GetTxtFirstLineOfst() )
572                         nParaLeft += rLR.GetTxtFirstLineOfst();
573                 else if( nParaLeft >= nLeft )
574                         // #82963#/#82962#: set correct paragraph indent
575                         nParaLeft -= nLeft;
576                 else
577                         //#83154#, Don't think any of the older #80856# bugfix code is
578                         //relevant anymore.
579                         nParaLeft = rLR.GetTxtLeft()+rLR.GetTxtFirstLineOfst();
580                 aLR.SetTxtLeft( nParaLeft );
581         }
582 
583         if( aLR.GetTxtLeft() != rLR.GetTxtLeft() )
584         {
585                 //bevor rLR geloescht wird!
586                 long nOffset = rLR.GetTxtLeft() - aLR.GetTxtLeft();
587         rNd.SetAttr( aLR );
588 
589                 // Tabs anpassen !!
590                 const SfxPoolItem* pItem;
591                 if( SFX_ITEM_SET == rNd.GetSwAttrSet().GetItemState(
592                                 RES_PARATR_TABSTOP, sal_True, &pItem ))
593                 {
594                         SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem );
595                         for( sal_uInt16 n = 0; n < aTStop.Count(); ++n )
596                         {
597                                 SvxTabStop& rTab = (SvxTabStop&)aTStop[ n ];
598                                 if( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() )
599                                 {
600                                         if( !rTab.GetTabPos() )
601                                         {
602                                                 aTStop.Remove( n );
603                                                 --n;
604                                         }
605                                         else
606                                                 rTab.GetTabPos() += nOffset;
607                                 }
608                         }
609             rNd.SetAttr( aTStop );
610                 }
611         }
612 }
613 
614 /*  */
615 
616 
CalculateFlySize(SfxItemSet & rFlySet,const SwNodeIndex & rAnchor,SwTwips nPageWidth)617 void CalculateFlySize(SfxItemSet& rFlySet, const SwNodeIndex& rAnchor,
618         SwTwips nPageWidth)
619 {
620         const SfxPoolItem* pItem = 0;
621         if( SFX_ITEM_SET != rFlySet.GetItemState( RES_FRM_SIZE, sal_True, &pItem ) ||
622                 MINFLY > ((SwFmtFrmSize*)pItem)->GetWidth() )
623         {
624                 SwFmtFrmSize aSz((SwFmtFrmSize&)rFlySet.Get(RES_FRM_SIZE, sal_True));
625                 if (pItem)
626                         aSz = (SwFmtFrmSize&)(*pItem);
627 
628                 SwTwips nWidth;
629                 // dann die Breite des Flys selbst bestimmen. Ist eine Tabelle
630                 // defininiert, dann benutze deren Breite, sonst die Breite der
631                 // Seite
632                 const SwTableNode* pTblNd = rAnchor.GetNode().FindTableNode();
633                 if( pTblNd )
634                         nWidth = pTblNd->GetTable().GetFrmFmt()->GetFrmSize().GetWidth();
635                 else
636                         nWidth = nPageWidth;
637 
638                 const SwNodeIndex* pSttNd = ((SwFmtCntnt&)rFlySet.Get( RES_CNTNT )).
639                                                                         GetCntntIdx();
640                 if( pSttNd )
641                 {
642                         sal_Bool bOnlyOneNode = sal_True;
643                         sal_uLong nMinFrm = 0;
644                         sal_uLong nMaxFrm = 0;
645                         SwTxtNode* pFirstTxtNd = 0;
646                         SwNodeIndex aIdx( *pSttNd, 1 );
647                         SwNodeIndex aEnd( *pSttNd->GetNode().EndOfSectionNode() );
648                         while( aIdx < aEnd )
649                         {
650                                 SwTxtNode *pTxtNd = aIdx.GetNode().GetTxtNode();
651                                 if( pTxtNd )
652                                 {
653                                         if( !pFirstTxtNd )
654                                                 pFirstTxtNd = pTxtNd;
655                                         else if( pFirstTxtNd != pTxtNd )
656                                         {
657                                                 // forget it
658                                                 bOnlyOneNode = sal_False;
659                                                 break;
660                                         }
661 
662                                         sal_uLong nAbsMinCnts;
663                                         pTxtNd->GetMinMaxSize( aIdx.GetIndex(), nMinFrm,
664                                                                                         nMaxFrm, nAbsMinCnts );
665                                 }
666                                 aIdx++;
667                         }
668 
669                         if( bOnlyOneNode )
670                         {
671                                 if( nMinFrm < MINLAY && pFirstTxtNd )
672                                 {
673                                         // if the first node dont contained any content, then
674                                         // insert one char in it calc again and delete once again
675                                         SwIndex aNdIdx( pFirstTxtNd );
676                     pFirstTxtNd->InsertText( String::CreateFromAscii(
677                             RTL_CONSTASCII_STRINGPARAM( "MM" )), aNdIdx );
678                                         sal_uLong nAbsMinCnts;
679                                         pFirstTxtNd->GetMinMaxSize( pFirstTxtNd->GetIndex(),
680                                                                                         nMinFrm, nMaxFrm, nAbsMinCnts );
681                                         aNdIdx -= 2;
682                     pFirstTxtNd->EraseText( aNdIdx, 2 );
683                 }
684 
685                                 // Umrandung und Abstand zum Inhalt beachten
686                                 const SvxBoxItem& rBoxItem = (SvxBoxItem&)rFlySet.Get( RES_BOX );
687                                 sal_uInt16 nLine = BOX_LINE_LEFT;
688                                 for( int i = 0; i < 2; ++i )
689                                 {
690                                         const SvxBorderLine* pLn = rBoxItem.GetLine( nLine );
691                                         if( pLn )
692                                         {
693                                                 sal_uInt16 nWidthTmp = pLn->GetOutWidth() + pLn->GetInWidth();
694                         nWidthTmp = nWidthTmp + rBoxItem.GetDistance( nLine );
695                                                 nMinFrm += nWidthTmp;
696                                                 nMaxFrm += nWidthTmp;
697                                         }
698                                         nLine = BOX_LINE_RIGHT;
699                                 }
700 
701                                 // Mindestbreite fuer Inhalt einhalten
702                                 if( nMinFrm < MINLAY )
703                                         nMinFrm = MINLAY;
704                                 if( nMaxFrm < MINLAY )
705                                         nMaxFrm = MINLAY;
706 
707                                 if( nWidth > (sal_uInt16)nMaxFrm )
708                                         nWidth = nMaxFrm;
709                                 else if( nWidth > (sal_uInt16)nMinFrm )
710                                         nWidth = nMinFrm;
711                         }
712                 }
713 
714                 if( MINFLY > nWidth )
715                         nWidth = MINFLY;
716 
717                 aSz.SetWidth( nWidth );
718                 if( MINFLY > aSz.GetHeight() )
719                         aSz.SetHeight( MINFLY );
720                 rFlySet.Put( aSz );
721         }
722         else if( MINFLY > ((SwFmtFrmSize*)pItem)->GetHeight() )
723         {
724                 SwFmtFrmSize aSz( *(SwFmtFrmSize*)pItem );
725                 aSz.SetHeight( MINFLY );
726                 rFlySet.Put( aSz );
727         }
728 }
729 
730 /*  */
731 struct CharSetNameMap
732 {
733     rtl_TextEncoding eCode;
734     const sal_Char* pName;
735 };
736 
GetCharSetNameMap()737 const CharSetNameMap *GetCharSetNameMap()
738 {
739     static const CharSetNameMap aMapArr[] =
740     {
741 #   define IMPLENTRY(X) { RTL_TEXTENCODING_##X, "" #X "" }
742         IMPLENTRY(DONTKNOW),
743         IMPLENTRY(MS_1252),
744         IMPLENTRY(APPLE_ROMAN),
745         IMPLENTRY(IBM_437),
746         IMPLENTRY(IBM_850),
747         IMPLENTRY(IBM_860),
748         IMPLENTRY(IBM_861),
749         IMPLENTRY(IBM_863),
750         IMPLENTRY(IBM_865),
751         IMPLENTRY(SYMBOL),
752         IMPLENTRY(ASCII_US),
753         IMPLENTRY(ISO_8859_1),
754         IMPLENTRY(ISO_8859_2),
755         IMPLENTRY(ISO_8859_3),
756         IMPLENTRY(ISO_8859_4),
757         IMPLENTRY(ISO_8859_5),
758         IMPLENTRY(ISO_8859_6),
759         IMPLENTRY(ISO_8859_7),
760         IMPLENTRY(ISO_8859_8),
761         IMPLENTRY(ISO_8859_9),
762         IMPLENTRY(ISO_8859_14),
763         IMPLENTRY(ISO_8859_15),
764         IMPLENTRY(IBM_737),
765         IMPLENTRY(IBM_775),
766         IMPLENTRY(IBM_852),
767         IMPLENTRY(IBM_855),
768         IMPLENTRY(IBM_857),
769         IMPLENTRY(IBM_862),
770         IMPLENTRY(IBM_864),
771         IMPLENTRY(IBM_866),
772         IMPLENTRY(IBM_869),
773         IMPLENTRY(MS_874),
774         IMPLENTRY(MS_1250),
775         IMPLENTRY(MS_1251),
776         IMPLENTRY(MS_1253),
777         IMPLENTRY(MS_1254),
778         IMPLENTRY(MS_1255),
779         IMPLENTRY(MS_1256),
780         IMPLENTRY(MS_1257),
781         IMPLENTRY(MS_1258),
782         IMPLENTRY(APPLE_ARABIC),
783         IMPLENTRY(APPLE_CENTEURO),
784         IMPLENTRY(APPLE_CROATIAN),
785         IMPLENTRY(APPLE_CYRILLIC),
786         IMPLENTRY(APPLE_DEVANAGARI),
787         IMPLENTRY(APPLE_FARSI),
788         IMPLENTRY(APPLE_GREEK),
789         IMPLENTRY(APPLE_GUJARATI),
790         IMPLENTRY(APPLE_GURMUKHI),
791         IMPLENTRY(APPLE_HEBREW),
792         IMPLENTRY(APPLE_ICELAND),
793         IMPLENTRY(APPLE_ROMANIAN),
794         IMPLENTRY(APPLE_THAI),
795         IMPLENTRY(APPLE_TURKISH),
796         IMPLENTRY(APPLE_UKRAINIAN),
797         IMPLENTRY(APPLE_CHINSIMP),
798         IMPLENTRY(APPLE_CHINTRAD),
799         IMPLENTRY(APPLE_JAPANESE),
800         IMPLENTRY(APPLE_KOREAN),
801         IMPLENTRY(MS_932),
802         IMPLENTRY(MS_936),
803         IMPLENTRY(MS_949),
804         IMPLENTRY(MS_950),
805         IMPLENTRY(SHIFT_JIS),
806         IMPLENTRY(GB_2312),
807         IMPLENTRY(GBT_12345),
808         IMPLENTRY(GBK),
809         IMPLENTRY(BIG5),
810         IMPLENTRY(EUC_JP),
811         IMPLENTRY(EUC_CN),
812         IMPLENTRY(EUC_TW),
813         IMPLENTRY(ISO_2022_JP),
814         IMPLENTRY(ISO_2022_CN),
815         IMPLENTRY(KOI8_R),
816         IMPLENTRY(KOI8_U),
817         IMPLENTRY(UTF7),
818         IMPLENTRY(UTF8),
819         IMPLENTRY(ISO_8859_10),
820         IMPLENTRY(ISO_8859_13),
821         IMPLENTRY(EUC_KR),
822         IMPLENTRY(ISO_2022_KR),
823         IMPLENTRY(JIS_X_0201),
824         IMPLENTRY(JIS_X_0208),
825         IMPLENTRY(JIS_X_0212),
826         IMPLENTRY(MS_1361),
827         IMPLENTRY(GB_18030),
828         IMPLENTRY(BIG5_HKSCS),
829         IMPLENTRY(TIS_620),
830         IMPLENTRY(PT154),
831         IMPLENTRY(UCS4),
832         IMPLENTRY(UCS2),
833         IMPLENTRY(UNICODE),
834         {0,0}       //Last
835     };
836     return &aMapArr[0];
837 }
838 /*
839  Get a rtl_TextEncoding from its name
840  */
CharSetFromName(const String & rChrSetStr)841 rtl_TextEncoding CharSetFromName(const String& rChrSetStr)
842 {
843     const CharSetNameMap *pStart = GetCharSetNameMap();
844     rtl_TextEncoding nRet = pStart->eCode;
845 
846     for(const CharSetNameMap *pMap = pStart; pMap->pName; ++pMap)
847     {
848         if(rChrSetStr.EqualsIgnoreCaseAscii(pMap->pName))
849         {
850             nRet = pMap->eCode;
851             break;
852         }
853     }
854 
855     ASSERT(nRet != pStart->eCode, "TXT: That was an unknown language!");
856 
857         return nRet;
858 }
859 
860 
861 /*
862  Get the String name of an rtl_TextEncoding
863  */
NameFromCharSet(rtl_TextEncoding nChrSet)864 String NameFromCharSet(rtl_TextEncoding nChrSet)
865 {
866     const CharSetNameMap *pStart = GetCharSetNameMap();
867     const char *pRet = pStart->pName;
868 
869     for(const CharSetNameMap *pMap = pStart; pMap->pName; ++pMap)
870     {
871         if (nChrSet == pMap->eCode)
872         {
873             pRet = pMap->pName;
874             break;
875         }
876     }
877 
878     ASSERT(pRet != pStart->pName, "TXT: That was an unknown language!");
879 
880     return String::CreateFromAscii(pRet);
881 }
882 
883 // for the automatic conversion (mail/news/...)
884 // The user data contains the options for the ascii import/export filter.
885 // The format is:
886 //      1. CharSet - as ascii chars
887 //      2. LineEnd - as CR/LR/CRLF
888 //      3. Fontname
889 //      4. Language
890 // the delimetercharacter is ","
891 //
892 
ReadUserData(const String & rStr)893 void SwAsciiOptions::ReadUserData( const String& rStr )
894 {
895         xub_StrLen nToken = 0;
896         sal_uInt16 nCnt = 0;
897         String sToken;
898         do {
899                 if( 0 != (sToken = rStr.GetToken( 0, ',', nToken )).Len() )
900                 {
901                         switch( nCnt )
902                         {
903                         case 0:         // CharSet
904                 eCharSet = CharSetFromName(sToken);
905                                 break;
906                         case 1:         // LineEnd
907                                 if( sToken.EqualsIgnoreCaseAscii( "CRLF" ))
908                                         eCRLF_Flag = LINEEND_CRLF;
909                                 else if( sToken.EqualsIgnoreCaseAscii( "LF" ))
910                                         eCRLF_Flag = LINEEND_LF;
911                                 else
912                                         eCRLF_Flag = LINEEND_CR;
913                                 break;
914                         case 2:         // fontname
915                                 sFont = sToken;
916                                 break;
917                         case 3:         // Language
918                 nLanguage = MsLangId::convertIsoStringToLanguage( sToken );
919                                 break;
920                         }
921                 }
922                 ++nCnt;
923         } while( STRING_NOTFOUND != nToken );
924 }
925 
WriteUserData(String & rStr)926 void SwAsciiOptions::WriteUserData( String& rStr )
927 {
928         // 1. charset
929         rStr = NameFromCharSet(eCharSet);
930         rStr += ',';
931 
932         // 2. LineEnd
933         switch(eCRLF_Flag)
934         {
935         case LINEEND_CRLF:
936             rStr.AppendAscii( "CRLF" );
937             break;
938         case LINEEND_CR:
939             rStr.AppendAscii(  "CR" );
940             break;
941         case LINEEND_LF:
942             rStr.AppendAscii(  "LF" );
943             break;
944         }
945         rStr += ',';
946 
947         // 3. Fontname
948         rStr += sFont;
949         rStr += ',';
950 
951         // 4. Language
952         if (nLanguage)
953         {
954         rtl::OUString sTmp = MsLangId::convertLanguageToIsoString( nLanguage );
955         rStr += (String)sTmp;
956         }
957         rStr += ',';
958 }
959 
thisModule()960 extern "C" { static void SAL_CALL thisModule() {} }
961 
GetMswordLibSymbol(const char * pSymbol)962 static oslGenericFunction GetMswordLibSymbol( const char *pSymbol )
963 {
964     static ::osl::Module aModule;
965         static sal_Bool bLoaded = sal_False;
966     static ::rtl::OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( SVLIBRARY( "msword" ) ) );
967         if (!bLoaded)
968                 bLoaded = SvLibrary::LoadModule( aModule, aLibName, &thisModule );
969         if (bLoaded)
970         return aModule.getFunctionSymbol( ::rtl::OUString::createFromAscii( pSymbol ) );
971     return NULL;
972 }
973 
GetRTFReader()974 Reader* GetRTFReader()
975 {
976     FnGetReader pFunction = reinterpret_cast<FnGetReader>( GetMswordLibSymbol( "ImportRTF" ) );
977 
978     if ( pFunction )
979         return (*pFunction)();
980 
981     return NULL;
982 }
983 
GetRTFWriter(const String & rFltName,const String & rBaseURL,WriterRef & xRet)984 void GetRTFWriter( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
985 {
986     FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( GetMswordLibSymbol( "ExportRTF" ) );
987 
988     if ( pFunction )
989         (*pFunction)( rFltName, rBaseURL, xRet );
990     else
991         xRet = WriterRef(0);
992 }
993 
GetWW8Reader()994 Reader* GetWW8Reader()
995 {
996     FnGetReader pFunction = reinterpret_cast<FnGetReader>( GetMswordLibSymbol( "ImportDOC" ) );
997 
998     if ( pFunction )
999         return (*pFunction)();
1000 
1001     return NULL;
1002 }
1003 
GetWW8Writer(const String & rFltName,const String & rBaseURL,WriterRef & xRet)1004 void GetWW8Writer( const String& rFltName, const String& rBaseURL, WriterRef& xRet )
1005 {
1006     FnGetWriter pFunction = reinterpret_cast<FnGetWriter>( GetMswordLibSymbol( "ExportDOC" ) );
1007 
1008     if ( pFunction )
1009         (*pFunction)( rFltName, rBaseURL, xRet );
1010     else
1011         xRet = WriterRef(0);
1012 }
1013 
1014 typedef sal_uLong ( __LOADONCALLAPI *SaveOrDel )( SfxObjectShell&, SotStorage&, sal_Bool, const String& );
1015 typedef sal_uLong ( __LOADONCALLAPI *GetSaveWarning )( SfxObjectShell& );
1016 
SaveOrDelMSVBAStorage(SfxObjectShell & rDoc,SotStorage & rStor,sal_Bool bSaveInto,const String & rStorageName)1017 sal_uLong SaveOrDelMSVBAStorage( SfxObjectShell& rDoc, SotStorage& rStor, sal_Bool bSaveInto, const String& rStorageName )
1018 {
1019     SaveOrDel pFunction = reinterpret_cast<SaveOrDel>( GetMswordLibSymbol( "SaveOrDelMSVBAStorage_ww8" ) );
1020     if( pFunction )
1021                 return pFunction( rDoc, rStor, bSaveInto, rStorageName );
1022         return ERRCODE_NONE;
1023 }
1024 
GetSaveWarningOfMSVBAStorage(SfxObjectShell & rDocS)1025 sal_uLong GetSaveWarningOfMSVBAStorage( SfxObjectShell &rDocS )
1026 {
1027     GetSaveWarning pFunction = reinterpret_cast<GetSaveWarning>( GetMswordLibSymbol( "GetSaveWarningOfMSVBAStorage_ww8" ) );
1028     if( pFunction )
1029                         return pFunction( rDocS );
1030         return ERRCODE_NONE;
1031 }
1032 
1033 
1034