| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ |
| |
| #include <iostream> |
| |
| #include <com/sun/star/embed/ElementModes.hpp> |
| #include <com/sun/star/embed/XStorage.hpp> |
| #include <unotools/ucbstreamhelper.hxx> |
| |
| #include <algorithm> |
| |
| #include <map> |
| #include <set> |
| |
| #include <hintids.hxx> |
| #include <string.h> // memcpy() |
| #include <osl/endian.h> |
| #include <docsh.hxx> |
| |
| #define _SVSTDARR_BOOLS |
| #include <svl/svstdarr.hxx> |
| |
| #include <unotools/fltrcfg.hxx> |
| #include <vcl/salbtype.hxx> |
| #include <sot/storage.hxx> |
| #include <svl/zformat.hxx> |
| #include <sfx2/docinf.hxx> |
| #include <editeng/tstpitem.hxx> |
| #include <svx/svdmodel.hxx> |
| #include <svx/svdpage.hxx> |
| #include <editeng/hyznitem.hxx> |
| #include <editeng/langitem.hxx> |
| #include <filter/msfilter/msoleexp.hxx> |
| #include <filter/msfilter/msocximex.hxx> |
| #include <editeng/lrspitem.hxx> |
| #include <editeng/ulspitem.hxx> |
| #include <editeng/boxitem.hxx> |
| #include <editeng/brshitem.hxx> |
| #include <swtypes.hxx> |
| #include <swrect.hxx> |
| #include <swtblfmt.hxx> |
| #include <txatbase.hxx> |
| #include <fmtcntnt.hxx> |
| #include <fmtpdsc.hxx> |
| #include <fmtrowsplt.hxx> |
| #include <frmatr.hxx> |
| #include <doc.hxx> |
| #include <docary.hxx> |
| #include <pam.hxx> |
| #include <ndtxt.hxx> |
| #include <shellio.hxx> |
| #include <docstat.hxx> |
| #include <pagedesc.hxx> |
| #include <IMark.hxx> |
| #include <swtable.hxx> |
| #include <wrtww8.hxx> |
| #include <ww8par.hxx> |
| #include <fltini.hxx> |
| #include <swmodule.hxx> |
| #include <section.hxx> |
| #include <swfltopt.hxx> |
| #include <fmtinfmt.hxx> |
| #include <txtinet.hxx> |
| #include <fmturl.hxx> |
| #include <fesh.hxx> |
| #include <svtools/imap.hxx> |
| #include <svtools/imapobj.hxx> |
| #include <tools/urlobj.hxx> |
| #include <mdiexp.hxx> // Progress |
| #include <statstr.hrc> // ResId fuer Statusleiste |
| #include <fmtline.hxx> |
| #include <fmtfsize.hxx> |
| #include <comphelper/extract.hxx> |
| #include <comphelper/stlunosequence.hxx> |
| #include <writerfilter/doctok/sprmids.hxx> |
| |
| #include "writerhelper.hxx" |
| #include "writerwordglue.hxx" |
| #include "ww8attributeoutput.hxx" |
| |
| #include <IDocumentMarkAccess.hxx> |
| #include <xmloff/odffields.hxx> |
| |
| #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> |
| #include <com/sun/star/document/XDocumentProperties.hpp> |
| |
| #include "dbgoutsw.hxx" |
| |
| #include <sfx2/docfile.hxx> |
| #include <sfx2/request.hxx> |
| #include <sfx2/frame.hxx> |
| #include <svl/stritem.hxx> |
| #include <unotools/tempfile.hxx> |
| #include <filter/msfilter/mscodec.hxx> |
| #include <filter/msfilter/svxmsbas.hxx> |
| #include <osl/time.h> |
| #include <rtl/random.h> |
| #include "WW8Sttbf.hxx" |
| #include <editeng/charrotateitem.hxx> |
| #include "WW8FibData.hxx" |
| #include "numrule.hxx" |
| |
| #include <boost/scoped_ptr.hpp> |
| |
| |
| using namespace sw::util; |
| using namespace sw::types; |
| |
| /** FKP - Formatted disK Page |
| */ |
| class WW8_WrFkp |
| { |
| sal_uInt8* pFkp; // gesamter Fkp ( zuerst nur FCs und Sprms ) |
| sal_uInt8* pOfs; // Pointer auf Offset-Bereich, spaeter nach pFkp kopiert |
| ePLCFT ePlc; |
| short nStartGrp; // ab hier grpprls |
| short nOldStartGrp; |
| sal_uInt8 nItemSize; |
| sal_uInt8 nIMax; // Anzahl der Eintrags-Paare |
| sal_uInt8 nOldVarLen; |
| sal_uInt8 nMark; |
| bool bCombined; // true : Einfuegen verboten |
| |
| sal_uInt8 SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms ); |
| public: |
| WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8); |
| ~WW8_WrFkp(); |
| bool Append( WW8_FC nEndFc, sal_uInt16 nVarLen = 0, const sal_uInt8* pSprms = 0 ); |
| bool Combine(); |
| void Write( SvStream& rStrm, SwWW8WrGrf& rGrf ); |
| |
| bool IsEqualPos(WW8_FC nEndFc) const |
| { return !bCombined && nIMax && nEndFc == ((sal_Int32*)pFkp)[nIMax]; } |
| void MergeToNew( short& rVarLen, sal_uInt8 *& pNewSprms ); |
| bool IsEmptySprm() const |
| { return !bCombined && nIMax && !nOldVarLen; } |
| void SetNewEnd( WW8_FC nEnd ) |
| { ((sal_Int32*)pFkp)[nIMax] = nEnd; } |
| |
| #ifdef __WW8_NEEDS_COPY |
| WW8_FC GetStartFc() const; |
| WW8_FC GetEndFc() const; |
| #else |
| WW8_FC GetStartFc() const { return ((sal_Int32*)pFkp)[0]; }; |
| WW8_FC GetEndFc() const { return ((sal_Int32*)pFkp)[nIMax]; }; |
| #endif // defined __WW8_NEEDS_COPY |
| |
| sal_uInt8 *CopyLastSprms(sal_uInt8 &rLen, bool bVer8); |
| }; |
| |
| |
| // ------------------------------------------------------------------------- |
| // class WW8_WrPc sammelt alle Piece-Eintraege fuer ein Piece |
| // ------------------------------------------------------------------------- |
| |
| class WW8_WrPc |
| { |
| WW8_CP nStartCp; // Start ZeichenPosition vom Text |
| WW8_FC nStartFc; // Start File Position vom Text |
| sal_uInt16 nStatus; // Absatzende im Piece ? |
| |
| public: |
| WW8_WrPc(WW8_FC nSFc, WW8_CP nSCp ) |
| : nStartCp( nSCp ), nStartFc( nSFc ), nStatus( 0x0040 ) |
| {} |
| |
| void SetStatus() { nStatus = 0x0050; } |
| sal_uInt16 GetStatus() const { return nStatus; } |
| WW8_CP GetStartCp() const { return nStartCp; } |
| WW8_FC GetStartFc() const { return nStartFc; } |
| }; |
| |
| typedef std::map<String,long> BKMKNames; |
| typedef BKMKNames::iterator BKMKNmItr; |
| typedef std::pair<bool,String> BKMK; |
| typedef std::pair<long,BKMK> BKMKCP; |
| typedef std::multimap<long,BKMKCP*> BKMKCPs; |
| typedef BKMKCPs::iterator CPItr; |
| |
| class WW8_WrtBookmarks |
| { |
| private: |
| BKMKCPs aSttCps,aEndCps; |
| BKMKNames maSwBkmkNms; |
| WW8_WrtBookmarks(const WW8_WrtBookmarks&); |
| WW8_WrtBookmarks& operator=(const WW8_WrtBookmarks&); |
| |
| public: |
| WW8_WrtBookmarks(); |
| ~WW8_WrtBookmarks(); |
| void Append( WW8_CP nStartCp, const String& rNm, const ::sw::mark::IMark* pBkmk=NULL ); |
| void Write( WW8Export& rWrt ); |
| void MoveFieldMarks(sal_uLong nFrom,sal_uLong nTo); |
| }; |
| |
| WW8_WrtBookmarks::WW8_WrtBookmarks() |
| {} |
| |
| WW8_WrtBookmarks::~WW8_WrtBookmarks() |
| { |
| CPItr aEnd = aSttCps.end(); |
| for (CPItr aItr = aSttCps.begin();aItr!=aEnd;aItr++) |
| { |
| if (aItr->second) |
| { |
| delete aItr->second; |
| aItr->second = NULL; |
| } |
| } |
| } |
| |
| void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm, const ::sw::mark::IMark*) |
| { |
| std::pair<BKMKNmItr,bool> aResult = maSwBkmkNms.insert(std::pair<String,long>(rNm,0L)); |
| if (aResult.second) |
| { |
| BKMK aBK(false,rNm); |
| BKMKCP* pBKCP = new BKMKCP((long)nStartCp,aBK); |
| aSttCps.insert(std::pair<long,BKMKCP*>(nStartCp,pBKCP)); |
| aResult.first->second = (long)nStartCp; |
| } |
| else |
| { |
| std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(aResult.first->second); |
| for (CPItr aItr = aRange.first;aItr != aRange.second;aItr++) |
| { |
| if (aItr->second && aItr->second->second.second == rNm) |
| { |
| if (aItr->second->second.first) |
| nStartCp--; |
| aItr->second->first = (long)nStartCp; |
| break; |
| } |
| } |
| } |
| } |
| |
| void WW8_WrtBookmarks::Write( WW8Export& rWrt) |
| { |
| if (!aSttCps.size()) |
| return; |
| CPItr aItr; |
| long n; |
| std::vector<String> aNames; |
| SvMemoryStream aTempStrm1(65535,65535); |
| SvMemoryStream aTempStrm2(65535,65535); |
| for (aItr = aSttCps.begin();aItr!=aSttCps.end();aItr++) |
| { |
| if (aItr->second) |
| { |
| aEndCps.insert(std::pair<long,BKMKCP*>(aItr->second->first,aItr->second)); |
| aNames.push_back(aItr->second->second.second); |
| SwWW8Writer::WriteLong( aTempStrm1, aItr->first); |
| } |
| } |
| |
| aTempStrm1.Seek(0L); |
| for (aItr = aEndCps.begin(), n = 0;aItr != aEndCps.end();aItr++,n++) |
| { |
| if (aItr->second) |
| { |
| aItr->second->first = n; |
| SwWW8Writer::WriteLong( aTempStrm2, aItr->first); |
| } |
| } |
| |
| aTempStrm2.Seek(0L); |
| rWrt.WriteAsStringTable(aNames, rWrt.pFib->fcSttbfbkmk,rWrt.pFib->lcbSttbfbkmk); |
| SvStream& rStrm = rWrt.bWrtWW8 ? *rWrt.pTableStrm : rWrt.Strm(); |
| rWrt.pFib->fcPlcfbkf = rStrm.Tell(); |
| rStrm<<aTempStrm1; |
| SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx); |
| for (aItr = aSttCps.begin();aItr!=aSttCps.end();aItr++) |
| { |
| if (aItr->second) |
| { |
| SwWW8Writer::WriteLong(rStrm, aItr->second->first); |
| } |
| } |
| rWrt.pFib->lcbPlcfbkf = rStrm.Tell() - rWrt.pFib->fcPlcfbkf; |
| rWrt.pFib->fcPlcfbkl = rStrm.Tell(); |
| rStrm<<aTempStrm2; |
| SwWW8Writer::WriteLong(rStrm, rWrt.pFib->ccpText + rWrt.pFib->ccpTxbx); |
| rWrt.pFib->lcbPlcfbkl = rStrm.Tell() - rWrt.pFib->fcPlcfbkl; |
| } |
| |
| void WW8_WrtBookmarks::MoveFieldMarks(sal_uLong nFrom,sal_uLong nTo) |
| { |
| std::pair<CPItr,CPItr> aRange = aSttCps.equal_range(nFrom); |
| CPItr aItr = aRange.first; |
| while (aItr != aRange.second) |
| { |
| if (aItr->second) |
| { |
| if (aItr->second->first == (long)nFrom) |
| { |
| aItr->second->second.first = true; |
| aItr->second->first = nTo; |
| } |
| aSttCps.insert(std::pair<long,BKMKCP*>(nTo,aItr->second)); |
| aItr->second = NULL; |
| aRange = aSttCps.equal_range(nFrom); |
| aItr = aRange.first; |
| continue; |
| } |
| aItr++; |
| } |
| } |
| |
| #define ANZ_DEFAULT_STYLES 16 |
| |
| // die Namen der StorageStreams |
| #define sMainStream CREATE_CONST_ASC("WordDocument") |
| #define sCompObj CREATE_CONST_ASC("\1CompObj") |
| |
| |
| SV_IMPL_VARARR( WW8Bytes, sal_uInt8 ) |
| SV_IMPL_PTRARR( WW8_WrFkpPtrs, WW8_FkpPtr ) |
| |
| typedef WW8_WrPc* WW8_WrPcPtr; |
| SV_DECL_PTRARR_DEL( WW8_WrPcPtrs, WW8_WrPcPtr, 4, 4 ) |
| SV_IMPL_PTRARR( WW8_WrPcPtrs, WW8_WrPcPtr ) |
| |
| static void WriteDop( WW8Export& rWrt ) |
| { |
| WW8Dop& rDop = *rWrt.pDop; |
| |
| // i#78951#, store the value of unknown compatability options |
| rDop.SetCompatabilityOptions( rWrt.pDoc->Getn32DummyCompatabilityOptions1()); |
| rDop.SetCompatabilityOptions2( rWrt.pDoc->Getn32DummyCompatabilityOptions2()); |
| |
| rDop.fNoLeading = !rWrt.pDoc->get(IDocumentSettingAccess::ADD_EXT_LEADING); |
| rDop.fUsePrinterMetrics = !rWrt.pDoc->get(IDocumentSettingAccess::USE_VIRTUAL_DEVICE); |
| |
| // default TabStop schreiben |
| const SvxTabStopItem& rTabStop = |
| DefaultItemGet<SvxTabStopItem>(*rWrt.pDoc, RES_PARATR_TABSTOP); |
| rDop.dxaTab = (sal_uInt16)rTabStop[0].GetTabPos(); |
| |
| |
| // Werte aus der DocStatistik (werden aufjedenfall fuer die |
| // DocStat-Felder benoetigt!) |
| rDop.fWCFtnEdn = true; // because they are included in StarWriter |
| |
| const SwDocStat& rDStat = rWrt.pDoc->GetDocStat(); |
| rDop.cWords = rDStat.nWord; |
| rDop.cCh = rDStat.nChar; |
| rDop.cPg = static_cast< sal_Int16 >(rDStat.nPage); |
| rDop.cParas = rDStat.nPara; |
| rDop.cLines = rDStat.nPara; |
| |
| SwDocShell *pDocShell(rWrt.pDoc->GetDocShell()); |
| DBG_ASSERT(pDocShell, "no SwDocShell"); |
| uno::Reference<document::XDocumentProperties> xDocProps; |
| uno::Reference<beans::XPropertySet> xProps; |
| if (pDocShell) { |
| uno::Reference<lang::XComponent> xModelComp(pDocShell->GetModel(), |
| uno::UNO_QUERY); |
| xProps = uno::Reference<beans::XPropertySet>(xModelComp, |
| uno::UNO_QUERY); |
| uno::Reference<document::XDocumentPropertiesSupplier> xDPS( |
| xModelComp, uno::UNO_QUERY_THROW); |
| xDocProps = xDPS->getDocumentProperties(); |
| DBG_ASSERT(xDocProps.is(), "DocumentProperties is null"); |
| |
| rDop.lKeyProtDoc = pDocShell->GetModifyPasswordHash(); |
| } |
| |
| if ((rWrt.pSepx && rWrt.pSepx->DocumentIsProtected()) || |
| rDop.lKeyProtDoc != 0) |
| { |
| rDop.fProtEnabled = 1; |
| } |
| else |
| { |
| rDop.fProtEnabled = 0; |
| } |
| |
| if (!xDocProps.is()) { |
| rDop.dttmCreated = rDop.dttmRevised = rDop.dttmLastPrint = 0x45FBAC69; |
| } else { |
| ::util::DateTime uDT = xDocProps->getCreationDate(); |
| Date aD(uDT.Day, uDT.Month, uDT.Year); |
| Time aT(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); |
| rDop.dttmCreated = sw::ms::DateTime2DTTM(DateTime(aD,aT)); |
| uDT = xDocProps->getModificationDate(); |
| Date aD2(uDT.Day, uDT.Month, uDT.Year); |
| Time aT2(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); |
| rDop.dttmRevised = sw::ms::DateTime2DTTM(DateTime(aD2,aT2)); |
| uDT = xDocProps->getPrintDate(); |
| Date aD3(uDT.Day, uDT.Month, uDT.Year); |
| Time aT3(uDT.Hours, uDT.Minutes, uDT.Seconds, uDT.HundredthSeconds); |
| rDop.dttmLastPrint = sw::ms::DateTime2DTTM(DateTime(aD3,aT3)); |
| |
| } |
| |
| // auch damit werden die DocStat-Felder in Kopf-/Fusszeilen nicht korrekt |
| // berechnet. |
| // ( we do not have this fields! ) |
| |
| // und noch fuer die Header und Footers |
| rDop.cWordsFtnEnd = rDStat.nWord; |
| rDop.cChFtnEdn = rDStat.nChar; |
| rDop.cPgFtnEdn = (sal_Int16)rDStat.nPage; |
| rDop.cParasFtnEdn = rDStat.nPara; |
| rDop.cLinesFtnEdn = rDStat.nPara; |
| |
| rDop.fDontUseHTMLAutoSpacing = (rWrt.pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX) != 0); |
| |
| rDop.fExpShRtn = !rWrt.pDoc->get(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK); // #i56856# |
| |
| rDop.Write( *rWrt.pTableStrm, *rWrt.pFib ); |
| } |
| |
| const sal_Unicode *WW8DopTypography::GetJapanNotBeginLevel1() |
| { |
| static const sal_Unicode aJapanNotBeginLevel1[nMaxFollowing] = |
| //Japanese Level 1 |
| { |
| 0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, |
| 0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032, |
| 0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d, |
| 0x300f, 0x3011, 0x3015, 0x309b, 0x309c, 0x309d, 0x309e, 0x30fb, |
| 0x30fd, 0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, |
| 0xff1b, 0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65, |
| 0xff9e, 0xff9f, 0xffe0 |
| }; |
| return &aJapanNotBeginLevel1[0]; |
| } |
| |
| const sal_Unicode *WW8DopTypography::GetJapanNotEndLevel1() |
| { |
| static const sal_Unicode aJapanNotEndLevel1[nMaxLeading] = |
| //Japanese Level 1 |
| { |
| 0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018, |
| 0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04, |
| 0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5 |
| }; |
| return &aJapanNotEndLevel1[0]; |
| } |
| |
| int lcl_CmpBeginEndChars( const rtl::OUString& rSWStr, |
| const sal_Unicode* pMSStr, int nMSStrByteLen ) |
| { |
| nMSStrByteLen /= sizeof( sal_Unicode ); |
| if( nMSStrByteLen > rSWStr.getLength() ) |
| nMSStrByteLen = rSWStr.getLength()+1; |
| nMSStrByteLen *= sizeof( sal_Unicode ); |
| |
| return memcmp( rSWStr.getStr(), pMSStr, nMSStrByteLen ); |
| } |
| |
| /* |
| Converts the OOo Asian Typography into a best fit match for Microsoft |
| Asian typography. This structure is actually dumped to disk within the |
| Dop Writer. Assumption is that rTypo is cleared to 0 on entry |
| */ |
| void WW8Export::ExportDopTypography(WW8DopTypography &rTypo) |
| { |
| static const sal_Unicode aLangNotBegin[4][WW8DopTypography::nMaxFollowing]= |
| { |
| //Japanese Level 1 |
| { |
| 0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, |
| 0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2030, 0x2032, |
| 0x2033, 0x2103, 0x3001, 0x3002, 0x3005, 0x3009, 0x300b, 0x300d, |
| 0x300f, 0x3011, 0x3015, 0x3041, 0x3043, 0x3045, 0x3047, 0x3049, |
| 0x3063, 0x3083, 0x3085, 0x3087, 0x308e, 0x309b, 0x309c, 0x309d, |
| 0x309e, 0x30a1, 0x30a3, 0x30a5, 0x30a7, 0x30a9, 0x30c3, 0x30e3, |
| 0x30e5, 0x30e7, 0x30ee, 0x30f5, 0x30f6, 0x30fb, 0x30fc, 0x30fd, |
| 0x30fe, 0xff01, 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, |
| 0xff1f, 0xff3d, 0xff5d, 0xff61, 0xff63, 0xff64, 0xff65, 0xff67, |
| 0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, |
| 0xff70, 0xff9e, 0xff9f, 0xffe0 |
| }, |
| //Simplified Chinese |
| { |
| 0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d, |
| 0x007d, 0x00a8, 0x00b7, 0x02c7, 0x02c9, 0x2015, 0x2016, 0x2019, |
| 0x201d, 0x2026, 0x2236, 0x3001, 0x3002, 0x3003, 0x3005, 0x3009, |
| 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x3017, 0xff01, 0xff02, |
| 0xff07, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d, |
| 0xff40, 0xff5c, 0xff5d, 0xff5e, 0xffe0 |
| }, |
| //Korean |
| { |
| 0x0021, 0x0025, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, |
| 0x005d, 0x007d, 0x00a2, 0x00b0, 0x2019, 0x201d, 0x2032, 0x2033, |
| 0x2103, 0x3009, 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0xff01, |
| 0xff05, 0xff09, 0xff0c, 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff3d, |
| 0xff5d, 0xffe0 |
| }, |
| //Traditional Chinese |
| { |
| 0x0021, 0x0029, 0x002c, 0x002e, 0x003a, 0x003b, 0x003f, 0x005d, |
| 0x007d, 0x00a2, 0x00b7, 0x2013, 0x2014, 0x2019, 0x201d, 0x2022, |
| 0x2025, 0x2026, 0x2027, 0x2032, 0x2574, 0x3001, 0x3002, 0x3009, |
| 0x300b, 0x300d, 0x300f, 0x3011, 0x3015, 0x301e, 0xfe30, 0xfe31, |
| 0xfe33, 0xfe34, 0xfe36, 0xfe38, 0xfe3a, 0xfe3c, 0xfe3e, 0xfe40, |
| 0xfe42, 0xfe44, 0xfe4f, 0xfe50, 0xfe51, 0xfe52, 0xfe54, 0xfe55, |
| 0xfe56, 0xfe57, 0xfe5a, 0xfe5c, 0xfe5e, 0xff01, 0xff09, 0xff0c, |
| 0xff0e, 0xff1a, 0xff1b, 0xff1f, 0xff5c, 0xff5d, 0xff64 |
| }, |
| }; |
| |
| static const sal_Unicode aLangNotEnd[4][WW8DopTypography::nMaxLeading] = |
| { |
| //Japanese Level 1 |
| { |
| 0x0024, 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018, |
| 0x201c, 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04, |
| 0xff08, 0xff3b, 0xff5b, 0xff62, 0xffe1, 0xffe5 |
| }, |
| //Simplified Chinese |
| { |
| 0x0028, 0x005b, 0x007b, 0x00b7, 0x2018, 0x201c, 0x3008, 0x300a, |
| 0x300c, 0x300e, 0x3010, 0x3014, 0x3016, 0xff08, 0xff0e, 0xff3b, |
| 0xff5b, 0xffe1, 0xffe5 |
| }, |
| //Korean |
| { |
| 0x0028, 0x005b, 0x005c, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c, |
| 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0xff04, 0xff08, |
| 0xff3b, 0xff5b, 0xffe6 |
| }, |
| //Traditional Chinese |
| { |
| 0x0028, 0x005b, 0x007b, 0x00a3, 0x00a5, 0x2018, 0x201c, 0x2035, |
| 0x3008, 0x300a, 0x300c, 0x300e, 0x3010, 0x3014, 0x301d, 0xfe35, |
| 0xfe37, 0xfe39, 0xfe3b, 0xfe3d, 0xfe3f, 0xfe41, 0xfe43, 0xfe59, |
| 0xfe5b, 0xfe5d, 0xff08, 0xff5b |
| }, |
| }; |
| |
| const i18n::ForbiddenCharacters *pForbidden = 0; |
| const i18n::ForbiddenCharacters *pUseMe = 0; |
| sal_uInt8 nUseReserved=0; |
| int nNoNeeded=0; |
| /* |
| Now we have some minor difficult issues, to wit... |
| a. MicroSoft Office can only store one set of begin and end characters in |
| a given document, not one per language. |
| b. StarOffice has only a concept of one set of begin and end characters for |
| a given language, i.e. not the two levels of kinsoku in japanese |
| |
| What is unknown as yet is if our default begin and end chars for |
| japanese, chinese tradition, chinese simplified and korean are different |
| in Word and Writer. I already suspect that they are different between |
| different version of word itself. |
| |
| So what have come up with is to simply see if any of the four languages |
| in OOo have been changed away from OUR defaults, and if one has then |
| export that. If more than one has in the future we may hack in something |
| which examines our document properties to see which language is used the |
| most and choose that, for now we choose the first and throw an ASSERT. |
| */ |
| |
| /*Our default Japanese Level is 2, this is a special MS hack to set this*/ |
| rTypo.reserved2 = 1; |
| |
| for (rTypo.reserved1=8;rTypo.reserved1>0;rTypo.reserved1-=2) |
| { |
| if (0 != (pForbidden = pDoc->getForbiddenCharacters(rTypo.GetConvertedLang(), |
| false))) |
| { |
| int nIdx = (rTypo.reserved1-2)/2; |
| if( lcl_CmpBeginEndChars( pForbidden->endLine, |
| aLangNotEnd[ nIdx ], sizeof(aLangNotEnd[ nIdx ]) ) || |
| lcl_CmpBeginEndChars( pForbidden->beginLine, |
| aLangNotBegin[ nIdx ], sizeof(aLangNotBegin[ nIdx ]) ) ) |
| { |
| //One exception for Japanese, if it matches a level 1 we |
| //can use one extra flag for that, rather than use a custom |
| if (rTypo.GetConvertedLang() == LANGUAGE_JAPANESE) |
| { |
| if ( |
| !lcl_CmpBeginEndChars |
| ( |
| pForbidden->endLine, |
| rTypo.GetJapanNotEndLevel1(), |
| rTypo.nMaxLeading * sizeof(sal_Unicode) |
| ) |
| && |
| !lcl_CmpBeginEndChars |
| ( |
| pForbidden->beginLine, |
| rTypo.GetJapanNotBeginLevel1(), |
| rTypo.nMaxFollowing * sizeof(sal_Unicode) |
| ) |
| ) |
| { |
| rTypo.reserved2 = 0; |
| continue; |
| } |
| } |
| |
| if (!pUseMe) |
| { |
| pUseMe = pForbidden; |
| nUseReserved = rTypo.reserved1; |
| rTypo.iLevelOfKinsoku = 2; |
| } |
| nNoNeeded++; |
| } |
| } |
| } |
| |
| ASSERT( nNoNeeded<=1, "Example of unexportable forbidden chars" ); |
| rTypo.reserved1=nUseReserved; |
| if (rTypo.iLevelOfKinsoku) |
| { |
| rTypo.cchFollowingPunct = msword_cast<sal_Int16> |
| (pUseMe->beginLine.getLength()); |
| if (rTypo.cchFollowingPunct > WW8DopTypography::nMaxFollowing - 1) |
| rTypo.cchFollowingPunct = WW8DopTypography::nMaxFollowing - 1; |
| |
| rTypo.cchLeadingPunct = msword_cast<sal_Int16> |
| (pUseMe->endLine.getLength()); |
| if (rTypo.cchLeadingPunct > WW8DopTypography::nMaxLeading - 1) |
| rTypo.cchLeadingPunct = WW8DopTypography::nMaxLeading -1; |
| |
| memcpy(rTypo.rgxchFPunct,pUseMe->beginLine.getStr(), |
| (rTypo.cchFollowingPunct+1)*2); |
| |
| memcpy(rTypo.rgxchLPunct,pUseMe->endLine.getStr(), |
| (rTypo.cchLeadingPunct+1)*2); |
| } |
| |
| const IDocumentSettingAccess* pIDocumentSettingAccess = GetWriter().getIDocumentSettingAccess(); |
| |
| rTypo.fKerningPunct = pIDocumentSettingAccess->get(IDocumentSettingAccess::KERN_ASIAN_PUNCTUATION); |
| rTypo.iJustification = pDoc->getCharacterCompressionType(); |
| } |
| |
| // HasItem ist fuer die Zusammenfassung der Doppel-Attribute |
| // Underline / WordLineMode und Box / Shadow. |
| // Es kann nur etwas gefunden werden, wenn diese Methode innerhalb |
| // der aufgerufenen Methoden WW8_SwAttrIter::OutAttr() und |
| // WW8Export::OutputItemSet() benutzt wird. |
| const SfxPoolItem* MSWordExportBase::HasItem( sal_uInt16 nWhich ) const |
| { |
| const SfxPoolItem* pItem=0; |
| if (pISet) |
| { |
| // if write a EditEngine text, then the WhichIds are greater as |
| // ourer own Ids. So the Id have to translate from our into the |
| // EditEngine Range |
| nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich); |
| if (nWhich && SFX_ITEM_SET != pISet->GetItemState(nWhich, true, &pItem)) |
| pItem = 0; |
| } |
| else if( pChpIter ) |
| pItem = pChpIter->HasTextItem( nWhich ); |
| else |
| { |
| ASSERT( !this, "Wo ist mein ItemSet / pChpIter ?" ); |
| pItem = 0; |
| } |
| return pItem; |
| } |
| |
| const SfxPoolItem& MSWordExportBase::GetItem(sal_uInt16 nWhich) const |
| { |
| const SfxPoolItem* pItem; |
| if (pISet) |
| { |
| // if write a EditEngine text, then the WhichIds are greater as |
| // ourer own Ids. So the Id have to translate from our into the |
| // EditEngine Range |
| nWhich = sw::hack::GetSetWhichFromSwDocWhich(*pISet, *pDoc, nWhich); |
| ASSERT(nWhich != 0, "All broken, Impossible"); |
| pItem = &pISet->Get(nWhich, true); |
| } |
| else if( pChpIter ) |
| pItem = &pChpIter->GetItem( nWhich ); |
| else |
| { |
| ASSERT( !this, "Wo ist mein ItemSet / pChpIter ?" ); |
| pItem = 0; |
| } |
| return *pItem; |
| } |
| |
| //------------------------------------------------------------------------------ |
| |
| WW8_WrPlc1::WW8_WrPlc1( sal_uInt16 nStructSz ) |
| : aPos( 16, 16 ), nStructSiz( nStructSz ) |
| { |
| nDataLen = 16 * nStructSz; |
| pData = new sal_uInt8[ nDataLen ]; |
| } |
| |
| WW8_WrPlc1::~WW8_WrPlc1() |
| { |
| delete[] pData; |
| } |
| |
| WW8_CP WW8_WrPlc1::Prev() const |
| { |
| sal_uInt16 nLen = aPos.Count(); |
| ASSERT(nLen,"Prev called on empty list"); |
| return nLen ? aPos[nLen-1] : 0; |
| } |
| |
| void WW8_WrPlc1::Append( WW8_CP nCp, const void* pNewData ) |
| { |
| sal_uLong nInsPos = aPos.Count() * nStructSiz; |
| aPos.Insert( nCp, aPos.Count() ); |
| if( nDataLen < nInsPos + nStructSiz ) |
| { |
| sal_uInt8* pNew = new sal_uInt8[ 2 * nDataLen ]; |
| memmove( pNew, pData, nDataLen ); |
| delete[] pData; |
| pData = pNew; |
| nDataLen *= 2; |
| } |
| memcpy( pData + nInsPos, pNewData, nStructSiz ); |
| } |
| |
| void WW8_WrPlc1::Finish( sal_uLong nLastCp, sal_uLong nSttCp ) |
| { |
| if( aPos.Count() ) |
| { |
| aPos.Insert( nLastCp, aPos.Count() ); |
| if( nSttCp ) |
| for( sal_uInt16 n = 0; n < aPos.Count(); ++n ) |
| aPos[ n ] -= nSttCp; |
| } |
| } |
| |
| |
| void WW8_WrPlc1::Write( SvStream& rStrm ) |
| { |
| sal_uInt16 i; |
| for( i = 0; i < aPos.Count(); ++i ) |
| SwWW8Writer::WriteLong( rStrm, aPos[i] ); |
| if( i ) |
| rStrm.Write( pData, (i-1) * nStructSiz ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| // Klasse WW8_WrPlcFld fuer Felder |
| //------------------------------------------------------------------------------ |
| |
| |
| bool WW8_WrPlcFld::Write( WW8Export& rWrt ) |
| { |
| if( WW8_WrPlc1::Count() <= 1 ) |
| return false; |
| |
| WW8_FC *pfc; |
| sal_Int32 *plc; |
| switch (nTxtTyp) |
| { |
| case TXT_MAINTEXT: |
| pfc = &rWrt.pFib->fcPlcffldMom; |
| plc = &rWrt.pFib->lcbPlcffldMom; |
| break; |
| case TXT_HDFT: |
| pfc = &rWrt.pFib->fcPlcffldHdr; |
| plc = &rWrt.pFib->lcbPlcffldHdr; |
| break; |
| |
| case TXT_FTN: |
| pfc = &rWrt.pFib->fcPlcffldFtn; |
| plc = &rWrt.pFib->lcbPlcffldFtn; |
| break; |
| |
| case TXT_EDN: |
| pfc = &rWrt.pFib->fcPlcffldEdn; |
| plc = &rWrt.pFib->lcbPlcffldEdn; |
| break; |
| |
| case TXT_ATN: |
| pfc = &rWrt.pFib->fcPlcffldAtn; |
| plc = &rWrt.pFib->lcbPlcffldAtn; |
| break; |
| |
| case TXT_TXTBOX: |
| pfc = &rWrt.pFib->fcPlcffldTxbx; |
| plc = &rWrt.pFib->lcbPlcffldTxbx; |
| break; |
| |
| case TXT_HFTXTBOX: |
| pfc = &rWrt.pFib->fcPlcffldHdrTxbx; |
| plc = &rWrt.pFib->lcbPlcffldHdrTxbx; |
| break; |
| |
| default: |
| pfc = plc = 0; |
| break; |
| } |
| |
| if( pfc && plc ) |
| { |
| sal_uLong nFcStart = rWrt.pTableStrm->Tell(); |
| WW8_WrPlc1::Write( *rWrt.pTableStrm ); |
| *pfc = nFcStart; |
| *plc = rWrt.pTableStrm->Tell() - nFcStart; |
| } |
| return true; |
| } |
| |
| bool WW8_WrMagicTable::Write( WW8Export& rWrt ) |
| { |
| if( WW8_WrPlc1::Count() <= 1 ) |
| return false; |
| sal_uLong nFcStart = rWrt.pTableStrm->Tell(); |
| WW8_WrPlc1::Write( *rWrt.pTableStrm ); |
| rWrt.pFib->fcPlcfTch = nFcStart; |
| rWrt.pFib->lcbPlcfTch = rWrt.pTableStrm->Tell() - nFcStart; |
| return true; |
| } |
| |
| void WW8_WrMagicTable::Append( WW8_CP nCp, sal_uLong nData) |
| { |
| SVBT32 nLittle; |
| /* |
| Tell the undocumented table hack that everything between here and the last |
| table position is nontable text, don't do it if the previous position is |
| the same as this one, as that would be a region of 0 length |
| */ |
| if ((!Count()) || (Prev() != nCp)) |
| { |
| UInt32ToSVBT32(nData,nLittle); |
| WW8_WrPlc1::Append(nCp, nLittle); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| |
| void SwWW8Writer::FillCount( SvStream& rStrm, sal_uLong nCount ) |
| { |
| static const sal_uInt32 aNulls[16] = |
| { |
| 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // 64 Byte |
| }; |
| |
| while (nCount > 64) |
| { |
| rStrm.Write( aNulls, 64 ); // in 64-Byte-Schritten |
| nCount -= 64; |
| } |
| rStrm.Write( aNulls, nCount ); // Rest ( 0 .. 64 Bytes ) schreiben |
| } |
| |
| sal_uLong SwWW8Writer::FillUntil( SvStream& rStrm, sal_uLong nEndPos ) |
| { |
| sal_uLong nCurPos = rStrm.Tell(); |
| if( !nEndPos ) // nEndPos == 0 -> next Page |
| nEndPos = (nCurPos + 0x1ff) & ~0x1ffUL; |
| |
| if( nEndPos > nCurPos ) |
| SwWW8Writer::FillCount( rStrm, nEndPos - nCurPos ); |
| #ifdef DBG_UTIL |
| else |
| ASSERT( nEndPos == nCurPos, "Falsches FillUntil()" ); |
| #endif |
| return rStrm.Tell(); |
| } |
| |
| |
| //-------------------------------------------------------------------------- |
| /* */ |
| |
| WW8_WrPlcPn::WW8_WrPlcPn( WW8Export& rWr, ePLCFT ePl, WW8_FC nStartFc ) |
| : rWrt(rWr), nFkpStartPage(0), ePlc(ePl), nMark(0) |
| { |
| WW8_FkpPtr pF = new WW8_WrFkp( ePlc, nStartFc, rWrt.bWrtWW8 ); |
| aFkps.Insert( pF, aFkps.Count() ); |
| } |
| |
| WW8_WrPlcPn::~WW8_WrPlcPn() |
| { |
| aFkps.DeleteAndDestroy( 0, aFkps.Count() ); |
| } |
| |
| sal_uInt8 *WW8_WrPlcPn::CopyLastSprms(sal_uInt8 &rLen) |
| { |
| WW8_FkpPtr pF = aFkps.GetObject(aFkps.Count() - 1); |
| return pF->CopyLastSprms(rLen, rWrt.bWrtWW8); |
| } |
| |
| void WW8_WrPlcPn::AppendFkpEntry(WW8_FC nEndFc,short nVarLen,const sal_uInt8* pSprms) |
| { |
| WW8_FkpPtr pF = aFkps.GetObject( aFkps.Count() - 1 ); |
| |
| // big sprm? build the sprmPHugePapx |
| sal_uInt8* pNewSprms = (sal_uInt8*)pSprms; |
| sal_uInt8 aHugePapx[ 8 ]; |
| if( rWrt.bWrtWW8 && PAP == ePlc && 488 < nVarLen ) |
| { |
| sal_uInt8* p = aHugePapx; |
| *p++ = *pSprms++; // set style Id |
| *p++ = *pSprms++; |
| nVarLen -= 2; |
| |
| long nDataPos = rWrt.pDataStrm->Tell(); |
| SwWW8Writer::WriteShort( *rWrt.pDataStrm, nVarLen ); |
| rWrt.pDataStrm->Write( pSprms, nVarLen ); |
| |
| Set_UInt16( p, 0x6646 ); // set SprmCode |
| Set_UInt32( p, nDataPos ); // set startpos (FC) in the datastream |
| nVarLen = static_cast< short >(p - aHugePapx); |
| pSprms = pNewSprms = aHugePapx; |
| } |
| // if append at the same FC-EndPos and there are sprms, then get the old |
| // sprms and erase it; they will append now with the new sprms |
| else if( nVarLen && pF->IsEqualPos( nEndFc )) |
| pF->MergeToNew( nVarLen, pNewSprms ); |
| // has the prev EndFC an empty sprm and the current is empty too, then |
| // expand only the old EndFc to the new EndFc |
| else if( !nVarLen && pF->IsEmptySprm() ) |
| { |
| pF->SetNewEnd( nEndFc ); |
| return ; |
| } |
| |
| bool bOk = pF->Append(nEndFc, nVarLen, pNewSprms); |
| if( !bOk ) |
| { |
| pF->Combine(); |
| pF = new WW8_WrFkp( ePlc, pF->GetEndFc(), rWrt.bWrtWW8 );// Anfang neuer Fkp |
| // == Ende alter Fkp |
| aFkps.Insert( pF, aFkps.Count() ); |
| if( !pF->Append( nEndFc, nVarLen, pNewSprms ) ) |
| { |
| ASSERT( !this, "Sprm liess sich nicht einfuegen" ); |
| } |
| } |
| if( pNewSprms != pSprms ) //Merge to new has created a new block |
| delete[] pNewSprms; |
| } |
| |
| void WW8_WrPlcPn::WriteFkps() |
| { |
| nFkpStartPage = (sal_uInt16) ( SwWW8Writer::FillUntil( rWrt.Strm() ) >> 9 ); |
| |
| for( sal_uInt16 i = 0; i < aFkps.Count(); i++ ) |
| aFkps.GetObject( i )->Write( rWrt.Strm(), *rWrt.pGrf ); |
| |
| if( CHP == ePlc ) |
| { |
| rWrt.pFib->pnChpFirst = nFkpStartPage; |
| rWrt.pFib->cpnBteChp = aFkps.Count(); |
| } |
| else |
| { |
| rWrt.pFib->pnPapFirst = nFkpStartPage; |
| rWrt.pFib->cpnBtePap = aFkps.Count(); |
| } |
| } |
| |
| void WW8_WrPlcPn::WritePlc() |
| { |
| sal_uLong nFcStart = rWrt.pTableStrm->Tell(); |
| sal_uInt16 i; |
| |
| for( i = 0; i < aFkps.Count(); i++ ) |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, |
| aFkps.GetObject( i )->GetStartFc() ); |
| |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, |
| aFkps.GetObject( i - 1 )->GetEndFc() ); |
| |
| // fuer jedes FKP die Page ausgeben |
| if( rWrt.bWrtWW8) // fuer WW97 Long-Ausgabe |
| for ( i = 0; i < aFkps.Count(); i++) |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, i + nFkpStartPage ); |
| else // fuer WW95 Short-Ausgabe |
| for ( i = 0; i < aFkps.Count(); i++) |
| SwWW8Writer::WriteShort( *rWrt.pTableStrm, i + nFkpStartPage ); |
| |
| if( CHP == ePlc ) |
| { |
| rWrt.pFib->fcPlcfbteChpx = nFcStart; |
| rWrt.pFib->lcbPlcfbteChpx = rWrt.pTableStrm->Tell() - nFcStart; |
| } |
| else |
| { |
| rWrt.pFib->fcPlcfbtePapx = nFcStart; |
| rWrt.pFib->lcbPlcfbtePapx = rWrt.pTableStrm->Tell() - nFcStart; |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| /* */ |
| |
| WW8_WrFkp::WW8_WrFkp(ePLCFT ePl, WW8_FC nStartFc, bool bWrtWW8) |
| : ePlc(ePl), nStartGrp(511), nOldStartGrp(511), |
| nItemSize( ( CHP == ePl ) ? 1 : ( bWrtWW8 ? 13 : 7 )), |
| nIMax(0), nOldVarLen(0), nMark(0), bCombined(false) |
| { |
| pFkp = (sal_uInt8*)new sal_Int32[128]; // 512 Byte |
| pOfs = (sal_uInt8*)new sal_Int32[128]; // 512 Byte |
| memset( pFkp, 0, 4 * 128 ); |
| memset( pOfs, 0, 4 * 128 ); |
| ( (sal_Int32*)pFkp )[0] = nStartFc; // 0. FC-Eintrag auf nStartFc |
| } |
| |
| WW8_WrFkp::~WW8_WrFkp() |
| { |
| delete[] (sal_Int32 *)pFkp; |
| delete[] (sal_Int32 *)pOfs; |
| } |
| |
| sal_uInt8 WW8_WrFkp::SearchSameSprm( sal_uInt16 nVarLen, const sal_uInt8* pSprms ) |
| { |
| if( 3 < nVarLen ) |
| { |
| // if the sprms contained picture-references then never equal! |
| for( sal_uInt8 n = static_cast< sal_uInt8 >(nVarLen - 1); 3 < n; --n ) |
| if( pSprms[ n ] == GRF_MAGIC_3 && |
| pSprms[ n-1 ] == GRF_MAGIC_2 && |
| pSprms[ n-2 ] == GRF_MAGIC_1 ) |
| return 0; |
| } |
| |
| short i; |
| for( i = 0; i < nIMax; i++ ) |
| { |
| sal_uInt8 nStart = pOfs[i * nItemSize]; |
| if( nStart ) |
| { // Hat Sprms |
| const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 ); |
| if( ( CHP == ePlc |
| ? (*p++ == nVarLen) |
| : (((sal_uInt16)*p++ << 1 ) == (( nVarLen+1) & 0xfffe)) ) |
| && !memcmp( p, pSprms, nVarLen ) ) |
| return nStart; // gefunden |
| } |
| } |
| return 0; // nicht gefunden |
| } |
| |
| sal_uInt8 *WW8_WrFkp::CopyLastSprms(sal_uInt8 &rLen, bool bVer8) |
| { |
| rLen=0; |
| sal_uInt8 *pStart=0,*pRet=0; |
| |
| if (!bCombined) |
| pStart = pOfs; |
| else |
| pStart = pFkp + ( nIMax + 1 ) * 4; |
| |
| sal_uInt8 nStart = *(pStart + (nIMax-1) * nItemSize); |
| |
| const sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 ); |
| |
| if (!*p && bVer8) |
| p++; |
| |
| if (*p) |
| { |
| rLen = *p++; |
| if (PAP == ePlc) |
| rLen *= 2; |
| pRet = new sal_uInt8[rLen]; |
| memcpy(pRet,p,rLen); |
| } |
| return pRet; |
| } |
| |
| bool WW8_WrFkp::Append( WW8_FC nEndFc, sal_uInt16 nVarLen, const sal_uInt8* pSprms ) |
| { |
| ASSERT( !nVarLen || pSprms, "Item-Pointer fehlt" ); |
| ASSERT( nVarLen < ( ( ePlc == PAP ) ? 497U : 502U ), "Sprms zu lang !" ); |
| |
| if( bCombined ) |
| { |
| ASSERT( !this, "Fkp::Append: Fkp is already combined" ); |
| return false; |
| } |
| sal_Int32 n = ((sal_Int32*)pFkp)[nIMax]; // letzter Eintrag |
| if( nEndFc <= n ) |
| { |
| ASSERT( nEndFc >= n, "+Fkp: FC rueckwaerts" ); |
| ASSERT( !nVarLen || !pSprms || nEndFc != n, |
| "+Fkp: selber FC mehrfach benutzt" ); |
| // selber FC ohne Sprm wird ohne zu mosern ignoriert. |
| |
| return true; // ignorieren, keinen neuen Fkp anlegen |
| } |
| |
| sal_uInt8 nOldP = ( nVarLen ) ? SearchSameSprm( nVarLen, pSprms ) : 0; |
| // Kombinieren gleicher Eintraege |
| short nOffset=0, nPos = nStartGrp; |
| if (nVarLen && !nOldP) |
| { |
| nPos = PAP == ePlc |
| ? ( 13 == nItemSize // HACK: PAP und bWrtWW8 !! |
| ? (nStartGrp & 0xFFFE ) - nVarLen - 1 |
| : (nStartGrp - (((nVarLen + 1) & 0xFFFE)+1)) & 0xFFFE ) |
| : ((nStartGrp - nVarLen - 1) & 0xFFFE); |
| if( nPos < 0 ) |
| return false; // Passt absolut nicht |
| nOffset = nPos; // Offset merken (kann auch ungerade sein!) |
| nPos &= 0xFFFE; // Pos fuer Sprms ( gerade Pos ) |
| } |
| |
| if( (sal_uInt16)nPos <= ( nIMax + 2U ) * 4U + ( nIMax + 1U ) * nItemSize ) |
| // Passt hinter CPs und Offsets ? |
| return false; // Nein |
| |
| ((sal_Int32*)pFkp)[nIMax + 1] = nEndFc; // FC eintragen |
| |
| nOldVarLen = (sal_uInt8)nVarLen; |
| if( nVarLen && !nOldP ) |
| { // echt eintragen |
| nOldStartGrp = nStartGrp; |
| |
| nStartGrp = nPos; |
| pOfs[nIMax * nItemSize] = (sal_uInt8)( nStartGrp >> 1 ); |
| // ( DatenAnfg >> 1 ) eintragen |
| sal_uInt8 nCnt = static_cast< sal_uInt8 >(CHP == ePlc |
| ? ( nVarLen < 256 ) ? (sal_uInt8) nVarLen : 255 |
| : ( ( nVarLen + 1 ) >> 1 )); |
| |
| pFkp[ nOffset ] = nCnt; // DatenLaenge eintragen |
| memcpy( pFkp + nOffset + 1, pSprms, nVarLen ); // Sprms speichern |
| } |
| else |
| { |
| // nicht echt eintragen ( keine Sprms oder Wiederholung ) |
| // DatenAnfg 0 ( keine Daten ) oder Wiederholung |
| pOfs[nIMax * nItemSize] = nOldP; |
| } |
| nIMax++; |
| return true; |
| } |
| |
| bool WW8_WrFkp::Combine() |
| { |
| if( bCombined ) |
| return false; |
| if( nIMax ) |
| memcpy( pFkp + ( nIMax + 1 ) * 4, pOfs, nIMax * nItemSize ); |
| delete[] pOfs; |
| pOfs = 0; |
| ((sal_uInt8*)pFkp)[511] = nIMax; |
| bCombined = true; |
| |
| #if defined OSL_BIGENDIAN // Hier werden nur die FCs gedreht, die |
| sal_uInt16 i; // Sprms muessen an anderer Stelle gedreht |
| // werden |
| sal_uInt32* p; |
| for( i = 0, p = (sal_uInt32*)pFkp; i <= nIMax; i++, p++ ) |
| *p = SWAPLONG( *p ); |
| #endif // ifdef OSL_BIGENDIAN |
| |
| return true; |
| } |
| |
| void WW8_WrFkp::Write( SvStream& rStrm, SwWW8WrGrf& rGrf ) |
| { |
| Combine(); // Falls noch nicht Combined |
| |
| sal_uInt8* p; // Suche Magic fuer nPicLocFc |
| sal_uInt8* pEnd = pFkp + nStartGrp; |
| for( p = pFkp + 511 - 4; p >= pEnd; p-- ) |
| { |
| if( *p != GRF_MAGIC_1 ) // Suche nach Signatur 0x12 0x34 0x56 0xXX |
| continue; |
| if( *(p+1) != GRF_MAGIC_2 ) |
| continue; |
| if( *(p+2) != GRF_MAGIC_3 ) |
| continue; |
| |
| SVBT32 nPos; // Signatur gefunden |
| UInt32ToSVBT32( rGrf.GetFPos(), nPos ); // FilePos der Grafik |
| memcpy( p, nPos, 4 ); // Patche FilePos ueber Signatur |
| } |
| rStrm.Write( pFkp, 512 ); |
| } |
| |
| void WW8_WrFkp::MergeToNew( short& rVarLen, sal_uInt8 *& rpNewSprms ) |
| { |
| sal_uInt8 nStart = pOfs[ (nIMax-1) * nItemSize ]; |
| if( nStart ) |
| { // Hat Sprms |
| sal_uInt8* p = pFkp + ( (sal_uInt16)nStart << 1 ); |
| |
| // old and new equal? Then copy only one into the new sprms |
| if( nOldVarLen == rVarLen && !memcmp( p+1, rpNewSprms, nOldVarLen )) |
| { |
| sal_uInt8* pNew = new sal_uInt8[ nOldVarLen ]; |
| memcpy( pNew, p+1, nOldVarLen ); |
| rpNewSprms = pNew; |
| } |
| else |
| { |
| sal_uInt8* pNew = new sal_uInt8[ nOldVarLen + rVarLen ]; |
| memcpy( pNew, p+1, nOldVarLen ); |
| memcpy( pNew + nOldVarLen, rpNewSprms, rVarLen ); |
| |
| rpNewSprms = pNew; |
| rVarLen = rVarLen + nOldVarLen; |
| } |
| --nIMax; |
| // if this sprms dont used from others, remove it |
| bool bFnd = false; |
| for (sal_uInt16 n = 0; n < nIMax; ++n) |
| { |
| if (nStart == pOfs[n * nItemSize]) |
| { |
| bFnd = true; |
| break; |
| } |
| } |
| if (!bFnd) |
| { |
| nStartGrp = nOldStartGrp; |
| memset( p, 0, nOldVarLen+1 ); |
| } |
| } |
| } |
| |
| #ifdef __WW8_NEEDS_COPY |
| |
| WW8_FC WW8_WrFkp::GetStartFc() const |
| { |
| // wenn bCombined, dann ist das Array ab pFkp schon Bytemaessig auf LittleEndian |
| // umgedreht, d.h. zum Herausholen der Anfangs- und Endpositionen muss |
| // zurueckgedreht werden. |
| if( bCombined ) |
| return SVBT32ToUInt32( pFkp ); // 0. Element |
| return ((sal_Int32*)pFkp)[0]; |
| } |
| |
| WW8_FC WW8_WrFkp::GetEndFc() const |
| { |
| if( bCombined ) |
| return SVBT32ToUInt32( &(pFkp[nIMax*4]) ); // nIMax-tes SVBT32-Element |
| return ((sal_Int32*)pFkp)[nIMax]; |
| } |
| |
| #endif // defined __WW8_NEEDS_COPY |
| |
| |
| |
| //-------------------------------------------------------------------------- |
| // Methoden fuer Piece-Table-Verwaltung |
| //-------------------------------------------------------------------------- |
| |
| WW8_WrPct::WW8_WrPct(WW8_FC nfcMin, bool bSaveUniCode) |
| : pPcts(new WW8_WrPcPtrs), nOldFc(nfcMin), bIsUni(bSaveUniCode) |
| { |
| AppendPc( nOldFc, bIsUni ); |
| } |
| |
| WW8_WrPct::~WW8_WrPct() |
| { |
| delete pPcts; |
| } |
| |
| // Piece fuellen und neues Piece erzeugen |
| void WW8_WrPct::AppendPc(WW8_FC nStartFc, bool bIsUnicode) |
| { |
| WW8_CP nStartCp = nStartFc - nOldFc; // Textbeginn abziehen |
| if ( !nStartCp ) |
| { |
| if ( 0 != pPcts->Count() ) |
| { |
| ASSERT( 1 == pPcts->Count(), "Leeres Piece !!"); |
| pPcts->DeleteAndDestroy( pPcts->Count() - 1 , 1); |
| } |
| } |
| |
| nOldFc = nStartFc; // StartFc als alten merken |
| |
| if( bIsUni ) |
| nStartCp >>= 1; // Bei Unicode Anzahl der Zeichen / 2 |
| |
| |
| if ( !bIsUnicode ) |
| { |
| nStartFc <<= 1; // Adresse * 2 |
| nStartFc |= 0x40000000; // Vorletztes Bit setzen fuer !Unicode |
| } |
| |
| if( pPcts->Count() ) |
| nStartCp += pPcts->GetObject( pPcts->Count()- 1 )->GetStartCp(); |
| |
| WW8_WrPcPtr pPc = new WW8_WrPc( nStartFc, nStartCp ); |
| pPcts->Insert( pPc, pPcts->Count() ); |
| |
| bIsUni = bIsUnicode; |
| } |
| |
| |
| void WW8_WrPct::WritePc( WW8Export& rWrt ) |
| { |
| sal_uLong nPctStart; |
| sal_uLong nOldPos, nEndPos; |
| sal_uInt16 i; |
| |
| nPctStart = rWrt.pTableStrm->Tell(); // Beginn Piece-Table |
| *rWrt.pTableStrm << ( char )0x02; // Statusbyte PCT |
| nOldPos = nPctStart + 1; // Position merken |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, 0 ); // Laenge folgt |
| for( i = 0; i < pPcts->Count(); ++i ) // Bereiche |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, |
| pPcts->GetObject( i )->GetStartCp() ); |
| |
| |
| // die letzte Pos noch errechnen |
| sal_uLong nStartCp = rWrt.pFib->fcMac - nOldFc; |
| if( bIsUni ) |
| nStartCp >>= 1; // Bei Unicode Anzahl der Zeichen / 2 |
| nStartCp += pPcts->GetObject( i-1 )->GetStartCp(); |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, nStartCp ); |
| |
| // Pieceverweise |
| for ( i = 0; i < pPcts->Count(); ++i ) |
| { |
| WW8_WrPcPtr pPc = pPcts->GetObject( i ); |
| |
| SwWW8Writer::WriteShort( *rWrt.pTableStrm, pPc->GetStatus()); |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, pPc->GetStartFc()); |
| SwWW8Writer::WriteShort( *rWrt.pTableStrm, 0); // PRM=0 |
| } |
| |
| // Eintraege im FIB |
| rWrt.pFib->fcClx = nPctStart; |
| nEndPos = rWrt.pTableStrm->Tell(); |
| rWrt.pFib->lcbClx = nEndPos - nPctStart; |
| |
| // und noch die Laenge eintragen |
| SwWW8Writer::WriteLong( *rWrt.pTableStrm, nOldPos, |
| nEndPos - nPctStart-5 ); |
| |
| } |
| |
| void WW8_WrPct::SetParaBreak() |
| { |
| ASSERT( pPcts->Count(),"SetParaBreak : aPcts.Count = 0" ); |
| pPcts->GetObject( pPcts->Count() - 1)->SetStatus(); |
| } |
| |
| WW8_CP WW8_WrPct::Fc2Cp( sal_uLong nFc ) const |
| { |
| ASSERT( nFc >= (sal_uLong)nOldFc, "FilePos liegt vorm letzten Piece" ); |
| ASSERT( pPcts->Count(), "Fc2Cp noch kein Piece vorhanden" ); |
| |
| nFc -= nOldFc; |
| if( bIsUni ) |
| nFc /= 2; |
| return nFc + pPcts->GetObject( pPcts->Count() - 1 )->GetStartCp(); |
| } |
| |
| void WW8Export::AppendBookmarks( const SwTxtNode& rNd, |
| xub_StrLen nAktPos, xub_StrLen nLen ) |
| { |
| SvPtrarr aArr( 8, 8 ); |
| sal_uInt16 nCntnt; |
| xub_StrLen nAktEnd = nAktPos + nLen; |
| if( GetWriter().GetBookmarks( rNd, nAktPos, nAktEnd, aArr )) |
| { |
| sal_uLong nNd = rNd.GetIndex(), nSttCP = Fc2Cp( Strm().Tell() ); |
| for( sal_uInt16 n = 0; n < aArr.Count(); ++n ) |
| { |
| ::sw::mark::IMark& rBkmk = *(::sw::mark::IMark*)aArr[ n ]; |
| if(dynamic_cast< ::sw::mark::IFieldmark *>(&rBkmk)) |
| continue; |
| |
| const SwPosition* pPos = &rBkmk.GetMarkPos(); |
| const SwPosition* pOPos = 0; |
| if(rBkmk.IsExpanded()) |
| pOPos = &rBkmk.GetOtherMarkPos(); |
| if( pOPos && pOPos->nNode == pPos->nNode && |
| pOPos->nContent < pPos->nContent ) |
| { |
| pPos = pOPos; |
| pOPos = &rBkmk.GetMarkPos(); |
| } |
| |
| if( !pOPos || ( nNd == pPos->nNode.GetIndex() && |
| ( nCntnt = pPos->nContent.GetIndex() ) >= nAktPos && |
| nCntnt < nAktEnd ) ) |
| { |
| sal_uLong nCp = nSttCP + pPos->nContent.GetIndex() - nAktPos; |
| pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk); |
| } |
| if( pOPos && nNd == pOPos->nNode.GetIndex() && |
| ( nCntnt = pOPos->nContent.GetIndex() ) >= nAktPos && |
| nCntnt < nAktEnd ) |
| { |
| sal_uLong nCp = nSttCP + pOPos->nContent.GetIndex() - nAktPos; |
| pBkmks->Append(nCp, BookmarkToWord(rBkmk.GetName()), &rBkmk); |
| } |
| } |
| } |
| } |
| |
| void WW8Export::MoveFieldMarks(sal_uLong nFrom, sal_uLong nTo) |
| { |
| pBkmks->MoveFieldMarks(nFrom, nTo); |
| } |
| |
| void WW8Export::AppendBookmark( const rtl::OUString& rName, bool bSkip ) |
| { |
| sal_uLong nSttCP = Fc2Cp( Strm().Tell() ) + ( bSkip? 1: 0 ); |
| pBkmks->Append( nSttCP, rName ); |
| } |
| |
| //For i120928,collect all the graphics of bullets applied to paragraphs |
| int WW8Export::CollectGrfsOfBullets() const |
| { |
| m_vecBulletPic.clear(); |
| |
| if ( pDoc ) |
| { |
| sal_uInt16 nCountRule = pDoc->GetNumRuleTbl().Count(); |
| for (sal_uInt16 n = 0; n < nCountRule; ++n) |
| { |
| const SwNumRule &rRule = *(pDoc->GetNumRuleTbl().GetObject(n)); |
| sal_uInt16 nLevels = rRule.IsContinusNum() ? 1 : 9; |
| for (sal_uInt16 nLvl = 0; nLvl < nLevels; ++nLvl) |
| { |
| const SwNumFmt &rFmt = rRule.Get(nLvl); |
| if (SVX_NUM_BITMAP != rFmt.GetNumberingType()) |
| { |
| continue; |
| } |
| const Graphic *pGrf = rFmt.GetBrush()? rFmt.GetBrush()->GetGraphic():0; |
| if ( pGrf ) |
| { |
| bool bHas = false; |
| for (sal_uInt16 i = 0; i < m_vecBulletPic.size(); ++i) |
| { |
| if (m_vecBulletPic[i]->GetChecksum() == pGrf->GetChecksum()) |
| { |
| bHas = true; |
| break; |
| } |
| } |
| if (!bHas) |
| { |
| m_vecBulletPic.push_back(pGrf); |
| } |
| } |
| } |
| } |
| } |
| |
| return m_vecBulletPic.size(); |
| } |
| //Export Graphic of Bullets |
| void WW8Export::ExportGrfBullet(const SwTxtNode& rNd) |
| { |
| int nCount = CollectGrfsOfBullets(); |
| if (nCount > 0) |
| { |
| SwPosition aPos(rNd); |
| String aPicBullets = String::CreateFromAscii("_PictureBullets"); |
| AppendBookmark(aPicBullets); |
| for (int i = 0; i < nCount; i++) |
| { |
| sw::Frame aFrame(*(m_vecBulletPic[i]), aPos); |
| OutGrfBullets(aFrame); |
| } |
| AppendBookmark(aPicBullets); |
| } |
| } |
| |
| static sal_uInt8 nAttrMagicIdx = 0; |
| void WW8Export::OutGrfBullets(const sw::Frame & rFrame) |
| { |
| if ( !pGrf || !pChpPlc || !pO ) |
| return; |
| |
| pGrf->Insert(rFrame); |
| pChpPlc->AppendFkpEntry( Strm().Tell(), pO->Count(), pO->GetData() ); |
| pO->Remove( 0, pO->Count() ); |
| //if links... |
| WriteChar( (char)1 ); |
| |
| sal_uInt8 aArr[ 22 ]; |
| sal_uInt8* pArr = aArr; |
| |
| // sprmCFSpec |
| if( bWrtWW8 ) |
| Set_UInt16( pArr, 0x855 ); |
| else |
| Set_UInt8( pArr, 117 ); |
| Set_UInt8( pArr, 1 ); |
| |
| Set_UInt16( pArr, 0x083c ); |
| Set_UInt8( pArr, 0x81 ); |
| |
| // sprmCPicLocation |
| if( bWrtWW8 ) |
| Set_UInt16( pArr, 0x6a03 ); |
| else |
| { |
| Set_UInt8( pArr, 68 ); |
| Set_UInt8( pArr, 4 ); |
| } |
| Set_UInt32( pArr, GRF_MAGIC_321 ); |
| |
| //extern nAttrMagicIdx; |
| --pArr; |
| Set_UInt8( pArr, nAttrMagicIdx++ ); |
| pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr ); |
| } |
| //Achieve the index position |
| int WW8Export::GetGrfIndex(const SvxBrushItem& rBrush) |
| { |
| int nIndex = -1; |
| if ( rBrush.GetGraphic() ) |
| { |
| for (sal_uInt16 i = 0; i < m_vecBulletPic.size(); ++i) |
| { |
| if (m_vecBulletPic[i]->GetChecksum() == rBrush.GetGraphic()->GetChecksum()) |
| { |
| nIndex = i; |
| break; |
| } |
| } |
| } |
| |
| return nIndex; |
| } |
| |
| void MSWordExportBase::AppendWordBookmark( const String& rName ) |
| { |
| AppendBookmark( BookmarkToWord( rName ) ); |
| } |
| |
| |
| //-------------------------------------------------------------------------- |
| /* */ |
| |
| void WW8_WrtRedlineAuthor::Write( Writer& rWrt ) |
| { |
| WW8Export & rWW8Wrt = *(((SwWW8Writer&)rWrt).m_pExport); |
| rWW8Wrt.WriteAsStringTable(maAuthors, rWW8Wrt.pFib->fcSttbfRMark, |
| rWW8Wrt.pFib->lcbSttbfRMark, rWW8Wrt.bWrtWW8 ? 0 : 2); |
| } |
| |
| sal_uInt16 WW8Export::AddRedlineAuthor( sal_uInt16 nId ) |
| { |
| if( !pRedlAuthors ) |
| { |
| pRedlAuthors = new WW8_WrtRedlineAuthor; |
| pRedlAuthors->AddName(CREATE_CONST_ASC("Unknown")); |
| } |
| return pRedlAuthors->AddName( SW_MOD()->GetRedlineAuthor( nId ) ); |
| } |
| |
| //-------------------------------------------------------------------------- |
| /* */ |
| |
| void WW8Export::WriteAsStringTable(const std::vector<String>& rStrings, |
| sal_Int32& rfcSttbf, sal_Int32& rlcbSttbf, sal_uInt16 nExtraLen) |
| { |
| sal_uInt16 n, nCount = static_cast< sal_uInt16 >(rStrings.size()); |
| if( nCount ) |
| { |
| // we have some Redlines found in the document -> the |
| // Author Name Stringtable |
| SvStream& rStrm = bWrtWW8 ? *pTableStrm : Strm(); |
| rfcSttbf = rStrm.Tell(); |
| if( bWrtWW8 ) |
| { |
| SwWW8Writer::WriteShort( rStrm, -1 ); |
| SwWW8Writer::WriteLong( rStrm, nCount ); |
| for( n = 0; n < nCount; ++n ) |
| { |
| const String& rNm = rStrings[n]; |
| SwWW8Writer::WriteShort( rStrm, rNm.Len() ); |
| SwWW8Writer::WriteString16(rStrm, rNm, false); |
| if( nExtraLen ) |
| SwWW8Writer::FillCount(rStrm, nExtraLen); |
| } |
| } |
| else |
| { |
| SwWW8Writer::WriteShort( rStrm, 0 ); |
| for( n = 0; n < nCount; ++n ) |
| { |
| const String aNm(rStrings[n].Copy(0, 255)); |
| rStrm << (sal_uInt8)aNm.Len(); |
| SwWW8Writer::WriteString8(rStrm, aNm, false, |
| RTL_TEXTENCODING_MS_1252); |
| if (nExtraLen) |
| SwWW8Writer::FillCount(rStrm, nExtraLen); |
| } |
| } |
| rlcbSttbf = rStrm.Tell() - rfcSttbf; |
| if( !bWrtWW8 ) |
| SwWW8Writer::WriteShort( rStrm, rfcSttbf, (sal_uInt16)rlcbSttbf ); |
| } |
| } |
| |
| // WriteShort() traegt an FilePos nPos den Wert nVal ein und seekt auf die |
| // alte FilePos zurueck. Benutzt zum Nachtragen von Laengen. |
| void SwWW8Writer::WriteShort( SvStream& rStrm, sal_uLong nPos, sal_Int16 nVal ) |
| { |
| sal_uLong nOldPos = rStrm.Tell(); // Pos merken |
| rStrm.Seek( nPos ); |
| SwWW8Writer::WriteShort( rStrm, nVal ); |
| rStrm.Seek( nOldPos ); |
| } |
| |
| void SwWW8Writer::WriteLong( SvStream& rStrm, sal_uLong nPos, sal_Int32 nVal ) |
| { |
| sal_uLong nOldPos = rStrm.Tell(); // Pos merken |
| rStrm.Seek( nPos ); |
| SwWW8Writer::WriteLong( rStrm, nVal ); |
| rStrm.Seek( nOldPos ); |
| } |
| |
| void SwWW8Writer::InsUInt16(ww::bytes &rO, sal_uInt16 n) |
| { |
| SVBT16 nL; |
| ShortToSVBT16( n, nL ); |
| rO.push_back(nL[0]); |
| rO.push_back(nL[1]); |
| } |
| |
| void SwWW8Writer::InsUInt32(ww::bytes &rO, sal_uInt32 n) |
| { |
| SVBT32 nL; |
| UInt32ToSVBT32( n, nL ); |
| rO.push_back(nL[0]); |
| rO.push_back(nL[1]); |
| rO.push_back(nL[2]); |
| rO.push_back(nL[3]); |
| } |
| |
| void SwWW8Writer::InsAsString16(ww::bytes &rO, const String& rStr) |
| { |
| const sal_Unicode* pStr = rStr.GetBuffer(); |
| for( xub_StrLen n = 0, nLen = rStr.Len(); n < nLen; ++n, ++pStr ) |
| SwWW8Writer::InsUInt16( rO, *pStr ); |
| } |
| |
| void SwWW8Writer::InsAsString8(ww::bytes &rO, const String& rStr, |
| rtl_TextEncoding eCodeSet) |
| { |
| ByteString sTmp(rStr, eCodeSet); |
| const sal_Char *pStart = sTmp.GetBuffer(); |
| const sal_Char *pEnd = pStart + sTmp.Len(); |
| rO.reserve(rO.size() + sTmp.Len()); |
| |
| std::copy(pStart, pEnd, std::inserter(rO, rO.end())); |
| } |
| |
| #ifdef __WW8_NEEDS_COPY |
| |
| void SwWW8Writer::InsUInt16( WW8Bytes& rO, sal_uInt16 n ) |
| { |
| SVBT16 nL; |
| ShortToSVBT16( n, nL ); |
| rO.Insert( nL, 2, rO.Count() ); |
| } |
| void SwWW8Writer::InsUInt32( WW8Bytes& rO, sal_uInt32 n ) |
| { |
| SVBT32 nL; |
| UInt32ToSVBT32( n, nL ); |
| rO.Insert( nL, 4, rO.Count() ); |
| } |
| |
| #else |
| |
| void SwWW8Writer::InsUInt16( WW8Bytes& rO, sal_uInt16 n ) |
| { |
| rO.Insert( (sal_uInt8*)&n, 2, rO.Count() ); |
| } |
| void SwWW8Writer::InsUInt32( WW8Bytes& rO, sal_uInt32 n ) |
| { |
| rO.Insert( (sal_uInt8*)&n, 4, rO.Count() ); |
| } |
| |
| #endif // defined __WW8_NEEDS_COPY |
| |
| void SwWW8Writer::InsAsString16( WW8Bytes& rO, const String& rStr ) |
| { |
| const sal_Unicode* pStr = rStr.GetBuffer(); |
| for( xub_StrLen n = 0, nLen = rStr.Len(); n < nLen; ++n, ++pStr ) |
| SwWW8Writer::InsUInt16( rO, *pStr ); |
| } |
| |
| void SwWW8Writer::InsAsString8( WW8Bytes& rO, const String& rStr, |
| rtl_TextEncoding eCodeSet ) |
| { |
| ByteString sTmp( rStr, eCodeSet ); |
| rO.Insert( (sal_uInt8*)sTmp.GetBuffer(), sTmp.Len(), rO.Count() ); |
| } |
| |
| void SwWW8Writer::WriteString16(SvStream& rStrm, const String& rStr, |
| bool bAddZero) |
| { |
| ww::bytes aBytes; |
| SwWW8Writer::InsAsString16(aBytes, rStr); |
| if (bAddZero) |
| SwWW8Writer::InsUInt16(aBytes, 0); |
| //vectors are guaranteed to have contiguous memory, so we can do |
| //this while migrating away from WW8Bytes. Meyers Effective STL, item 16 |
| if (!aBytes.empty()) |
| rStrm.Write(&aBytes[0], aBytes.size()); |
| } |
| |
| void SwWW8Writer::WriteString_xstz(SvStream& rStrm, const String& rStr, bool bAddZero) |
| { |
| ww::bytes aBytes; |
| SwWW8Writer::InsUInt16(aBytes, rStr.Len()); |
| SwWW8Writer::InsAsString16(aBytes, rStr); |
| if (bAddZero) |
| SwWW8Writer::InsUInt16(aBytes, 0); |
| rStrm.Write(&aBytes[0], aBytes.size()); |
| } |
| |
| |
| void SwWW8Writer::WriteString8(SvStream& rStrm, const String& rStr, |
| bool bAddZero, rtl_TextEncoding eCodeSet) |
| { |
| ww::bytes aBytes; |
| SwWW8Writer::InsAsString8(aBytes, rStr, eCodeSet); |
| if (bAddZero) |
| aBytes.push_back(0); |
| //vectors are guaranteed to have contiguous memory, so we can do |
| ////this while migrating away from WW8Bytes. Meyers Effective STL, item 16 |
| if (!aBytes.empty()) |
| rStrm.Write(&aBytes[0], aBytes.size()); |
| } |
| |
| void WW8Export::WriteStringAsPara( const String& rTxt, sal_uInt16 nStyleId ) |
| { |
| if( rTxt.Len() ) |
| OutSwString( rTxt, 0, rTxt.Len(), IsUnicode(), RTL_TEXTENCODING_MS_1252 ); |
| WriteCR(); // CR danach |
| |
| WW8Bytes aArr( 10, 10 ); |
| SwWW8Writer::InsUInt16( aArr, nStyleId ); |
| if( bOutTable ) |
| { // Tab-Attr |
| // sprmPFInTable |
| if( bWrtWW8 ) |
| SwWW8Writer::InsUInt16( aArr, NS_sprm::LN_PFInTable ); |
| else |
| aArr.Insert( 24, aArr.Count() ); |
| aArr.Insert( 1, aArr.Count() ); |
| } |
| |
| sal_uLong nPos = Strm().Tell(); |
| pPapPlc->AppendFkpEntry( nPos, aArr.Count(), aArr.GetData() ); |
| pChpPlc->AppendFkpEntry( nPos ); |
| } |
| |
| void MSWordExportBase::WriteSpecialText( sal_uLong nStart, sal_uLong nEnd, sal_uInt8 nTTyp ) |
| { |
| sal_uInt8 nOldTyp = nTxtTyp; |
| nTxtTyp = nTTyp; |
| SwPaM* pOldPam = pCurPam; //!! Einfaches Umsetzen des PaM ohne |
| SwPaM* pOldEnd = pOrigPam; // Wiederherstellen muesste es auch tun |
| bool bOldPageDescs = bOutPageDescs; |
| bOutPageDescs = false; |
| // bOutKF wird in WriteKF1 gemerkt / gesetzt |
| pCurPam = Writer::NewSwPaM( *pDoc, nStart, nEnd ); |
| |
| // Tabelle in Sonderbereichen erkennen |
| if ( ( nStart != pCurPam->GetMark()->nNode.GetIndex() ) && |
| pDoc->GetNodes()[ nStart ]->IsTableNode() ) |
| { |
| pCurPam->GetMark()->nNode = nStart; |
| } |
| |
| pOrigPam = pCurPam; |
| pCurPam->Exchange(); |
| |
| WriteText(); |
| |
| bOutPageDescs = bOldPageDescs; |
| delete pCurPam; // Pam wieder loeschen |
| pCurPam = pOldPam; |
| pOrigPam = pOldEnd; |
| nTxtTyp = nOldTyp; |
| } |
| |
| void WW8Export::OutSwString(const String& rStr, xub_StrLen nStt, |
| xub_StrLen nLen, bool bUnicode, rtl_TextEncoding eChrSet) |
| |
| { |
| #ifdef DEBUG |
| ::std::clog << "<OutSwString>" << ::std::endl; |
| #endif |
| |
| if( nLen ) |
| { |
| if ( bUnicode != pPiece->IsUnicode() ) |
| pPiece->AppendPc ( Strm().Tell(), bUnicode ); |
| |
| if( nStt || nLen != rStr.Len() ) |
| { |
| String sOut( rStr.Copy( nStt, nLen ) ); |
| |
| #ifdef DEBUG |
| ::std::clog << ::rtl::OUStringToOString(sOut, RTL_TEXTENCODING_ASCII_US).getStr() << ::std::endl; |
| #endif |
| |
| if (bUnicode) |
| SwWW8Writer::WriteString16(Strm(), sOut, false); |
| else |
| SwWW8Writer::WriteString8(Strm(), sOut, false, eChrSet); |
| } |
| else |
| { |
| #ifdef DEBUG |
| ::std::clog << ::rtl::OUStringToOString(rStr, RTL_TEXTENCODING_ASCII_US).getStr() << ::std::endl; |
| #endif |
| |
| if (bUnicode) |
| SwWW8Writer::WriteString16(Strm(), rStr, false); |
| else |
| SwWW8Writer::WriteString8(Strm(), rStr, false, eChrSet); |
| } |
| } |
| |
| #ifdef DEBUG |
| ::std::clog << "</OutSwString>" << ::std::endl; |
| #endif |
| } |
| |
| void WW8Export::WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) |
| { |
| if (pTableTextNodeInfoInner.get() != NULL && pTableTextNodeInfoInner->getDepth() == 1 && pTableTextNodeInfoInner->isEndOfCell()) |
| WriteChar('\007'); |
| else |
| WriteChar( '\015' ); |
| |
| pPiece->SetParaBreak(); |
| } |
| |
| void WW8Export::WriteChar( sal_Unicode c ) |
| { |
| if( pPiece->IsUnicode() ) |
| Strm() << c; |
| else |
| Strm() << (sal_uInt8)c; |
| } |
| |
| void MSWordExportBase::SaveData( sal_uLong nStt, sal_uLong nEnd ) |
| { |
| MSWordSaveData aData; |
| |
| // WW8Export only stuff - zeroed here not to issue warnings |
| aData.pOOld = NULL; |
| aData.mpTableAtOld = NULL; |
| aData.mnTableStdAtLenOld = 0; |
| |
| // Common stuff |
| aData.pOldPam = pCurPam; |
| aData.pOldEnd = pOrigPam; |
| aData.pOldFlyFmt = mpParentFrame; |
| aData.pOldPageDesc = pAktPageDesc; |
| |
| aData.pOldFlyOffset = pFlyOffset; |
| aData.eOldAnchorType = eNewAnchorType; |
| |
| aData.bOldOutTable = bOutTable; |
| aData.bOldFlyFrmAttrs = bOutFlyFrmAttrs; |
| aData.bOldStartTOX = bStartTOX; |
| aData.bOldInWriteTOX = bInWriteTOX; |
| |
| pCurPam = Writer::NewSwPaM( *pDoc, nStt, nEnd ); |
| |
| // Recognize tables in special cases |
| if ( nStt != pCurPam->GetMark()->nNode.GetIndex() && |
| pDoc->GetNodes()[ nStt ]->IsTableNode() ) |
| { |
| pCurPam->GetMark()->nNode = nStt; |
| } |
| |
| pOrigPam = pCurPam; |
| pCurPam->Exchange(); |
| |
| bOutTable = false; |
| // Caution: bIsInTable should not be set here |
| bOutFlyFrmAttrs = false; |
| // pAttrSet = 0; |
| bStartTOX = false; |
| bInWriteTOX = false; |
| |
| maSaveData.push( aData ); |
| } |
| |
| void MSWordExportBase::RestoreData() |
| { |
| MSWordSaveData &rData = maSaveData.top(); |
| |
| delete pCurPam; |
| pCurPam = rData.pOldPam; |
| pOrigPam = rData.pOldEnd; |
| |
| bOutTable = rData.bOldOutTable; |
| bOutFlyFrmAttrs = rData.bOldFlyFrmAttrs; |
| bStartTOX = rData.bOldStartTOX; |
| bInWriteTOX = rData.bOldInWriteTOX; |
| |
| mpParentFrame = rData.pOldFlyFmt; |
| pAktPageDesc = rData.pOldPageDesc; |
| |
| eNewAnchorType = rData.eOldAnchorType; |
| pFlyOffset = rData.pOldFlyOffset; |
| |
| maSaveData.pop(); |
| } |
| |
| void WW8Export::SaveData( sal_uLong nStt, sal_uLong nEnd ) |
| { |
| MSWordExportBase::SaveData( nStt, nEnd ); |
| |
| MSWordSaveData &rData = maSaveData.top(); |
| |
| if ( pO->Count() ) |
| { |
| rData.pOOld = pO; |
| pO = new WW8Bytes( 128, 128 ); |
| } |
| else |
| rData.pOOld = 0; // reuse pO |
| |
| rData.mpTableAtOld = mpTableAt; |
| mpTableAt = NULL; |
| rData.mnTableStdAtLenOld = mnTableStdAtLen; |
| mnTableStdAtLen = 0; |
| |
| rData.bOldWriteAll = GetWriter().bWriteAll; |
| GetWriter().bWriteAll = true; |
| } |
| |
| void WW8Export::RestoreData() |
| { |
| MSWordSaveData &rData = maSaveData.top(); |
| |
| GetWriter().bWriteAll = rData.bOldWriteAll; |
| |
| ASSERT( !pO->Count(), "pO is not empty in WW8Export::RestoreData()" ); |
| if ( rData.pOOld ) |
| { |
| delete pO; |
| pO = rData.pOOld; |
| } |
| |
| ASSERT( !mpTableAt || !mpTableAt->Count(), "mpTableAt is not empty in WW8Export::RestoreData()" ); |
| if ( mpTableAt ) |
| delete mpTableAt; |
| mpTableAt = rData.mpTableAtOld; |
| mnTableStdAtLen = rData.mnTableStdAtLenOld; |
| |
| MSWordExportBase::RestoreData(); |
| } |
| |
| void WW8AttributeOutput::TableInfoCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth(); |
| |
| if ( nDepth > 0 ) |
| { |
| /* Cell */ |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable ); |
| m_rWW8Export.pO->Insert( (sal_uInt8)0x1, m_rWW8Export.pO->Count() ); |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth ); |
| m_rWW8Export.InsUInt32( nDepth ); |
| |
| if ( nDepth > 1 && pTableTextNodeInfoInner->isEndOfCell() ) |
| { |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PCell ); |
| m_rWW8Export.pO->Insert( (sal_uInt8)0x1, m_rWW8Export.pO->Count() ); |
| } |
| } |
| } |
| |
| void WW8AttributeOutput::TableInfoRow( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| sal_uInt32 nDepth = pTableTextNodeInfoInner->getDepth(); |
| |
| if ( nDepth > 0 ) |
| { |
| /* Row */ |
| if ( pTableTextNodeInfoInner->isEndOfLine() ) |
| { |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PFInTable ); |
| m_rWW8Export.pO->Insert( (sal_uInt8)0x1, m_rWW8Export.pO->Count() ); |
| |
| if ( nDepth == 1 ) |
| { |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PFTtp ); |
| m_rWW8Export.pO->Insert( (sal_uInt8)0x1, m_rWW8Export.pO->Count() ); |
| } |
| |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PTableDepth ); |
| m_rWW8Export.InsUInt32( nDepth ); |
| |
| if ( nDepth > 1 ) |
| { |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PCell ); |
| m_rWW8Export.pO->Insert( (sal_uInt8)0x1, m_rWW8Export.pO->Count() ); |
| m_rWW8Export.InsUInt16( NS_sprm::LN_PRow ); |
| m_rWW8Export.pO->Insert( (sal_uInt8)0x1, m_rWW8Export.pO->Count() ); |
| } |
| |
| TableDefinition( pTableTextNodeInfoInner ); |
| TableHeight( pTableTextNodeInfoInner ); |
| TableBackgrounds( pTableTextNodeInfoInner ); |
| TableDefaultBorders( pTableTextNodeInfoInner ); |
| TableCanSplit( pTableTextNodeInfoInner ); |
| TableBidi( pTableTextNodeInfoInner ); |
| TableVerticalCell( pTableTextNodeInfoInner ); |
| TableOrientation( pTableTextNodeInfoInner ); |
| TableSpacing( pTableTextNodeInfoInner ); |
| } |
| } |
| } |
| |
| static sal_uInt16 lcl_TCFlags(SwDoc &rDoc, const SwTableBox * pBox, const sal_Int32 nRowSpan) |
| { |
| sal_uInt16 nFlags = 0; |
| |
| if (nRowSpan > 1) |
| nFlags |= (3 << 5); |
| else if (nRowSpan < 0) |
| nFlags |= (1 << 5); |
| |
| if (pBox != NULL) |
| { |
| const SwFrmFmt * pFmt = pBox->GetFrmFmt(); |
| switch (pFmt->GetVertOrient().GetVertOrient()) |
| { |
| case text::VertOrientation::CENTER: |
| nFlags |= (1 << 7); |
| break; |
| case text::VertOrientation::BOTTOM: |
| nFlags |= (2 << 7); |
| break; |
| default: |
| break; |
| } |
| const SwStartNode * pSttNd = pBox->GetSttNd(); |
| if(pSttNd) |
| { |
| SwNodeIndex aIdx( *pSttNd ); |
| const SwCntntNode * pCNd = pSttNd->GetNodes().GoNext( &aIdx ); |
| if( pCNd && pCNd->IsTxtNode()) |
| { |
| SfxItemSet aCoreSet(rDoc.GetAttrPool(), RES_CHRATR_ROTATE, RES_CHRATR_ROTATE); |
| ((SwTxtNode*)pCNd)->GetAttr( aCoreSet, 0, ((SwTxtNode*)pCNd)->GetTxt().Len()); |
| const SvxCharRotateItem * pRotate = NULL; |
| const SfxPoolItem * pRotItem; |
| if ( SFX_ITEM_SET == aCoreSet.GetItemState(RES_CHRATR_ROTATE, sal_True, &pRotItem)) |
| { |
| pRotate = (SvxCharRotateItem*)pRotItem; |
| if(pRotate && pRotate->GetValue() == 900) |
| { |
| nFlags = nFlags | 0x0004 | 0x0008; |
| } |
| else if(pRotate && pRotate->GetValue() == 2700 ) |
| { |
| nFlags = nFlags | 0x0004 | 0x0010; |
| } |
| } |
| } |
| } |
| } |
| |
| return nFlags; |
| } |
| |
| void WW8AttributeOutput::TableVerticalCell( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwTableLine * pTabLine = pTabBox->GetUpper(); |
| const SwTableBoxes & rTblBoxes = pTabLine->GetTabBoxes(); |
| |
| const sal_uInt16 nBoxes = rTblBoxes.Count(); |
| for ( sal_uInt16 n = 0; n < nBoxes; n++ ) |
| { |
| const SwTableBox * pTabBox1 = rTblBoxes[n]; |
| const SwFrmFmt * pFrmFmt = pTabBox1->GetFrmFmt(); |
| |
| if ( FRMDIR_VERT_TOP_RIGHT == m_rWW8Export.TrueFrameDirection( *pFrmFmt ) ) |
| { |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TTextFlow ); |
| m_rWW8Export.pO->Insert( sal_uInt8(n), m_rWW8Export.pO->Count() ); //start range |
| m_rWW8Export.pO->Insert( sal_uInt8(n + 1), m_rWW8Export.pO->Count() ); //end range |
| m_rWW8Export.InsUInt16( 5 ); //Equals vertical writing |
| } |
| } |
| } |
| |
| void WW8AttributeOutput::TableCanSplit( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwTableLine * pTabLine = pTabBox->GetUpper(); |
| const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt(); |
| |
| /* |
| By default the row can be split in word, and now in writer we have a |
| feature equivalent to this, Word stores 1 for fCantSplit if the row |
| cannot be split, we set true if we can split it. An example is #i4569# |
| */ |
| |
| const SwFmtRowSplit& rSplittable = pLineFmt->GetRowSplit(); |
| sal_uInt8 nCantSplit = (!rSplittable.GetValue()) ? 1 : 0; |
| if ( m_rWW8Export.bWrtWW8 ) |
| { |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit ); |
| m_rWW8Export.pO->Insert( nCantSplit, m_rWW8Export.pO->Count() ); |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TFCantSplit90 ); // also write fCantSplit90 |
| } |
| else |
| { |
| m_rWW8Export.pO->Insert( 185, m_rWW8Export.pO->Count() ); |
| } |
| m_rWW8Export.pO->Insert( nCantSplit, m_rWW8Export.pO->Count() ); |
| } |
| |
| void WW8AttributeOutput::TableBidi( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTable * pTable = pTableTextNodeInfoInner->getTable(); |
| const SwFrmFmt * pFrmFmt = pTable->GetFrmFmt(); |
| |
| if ( m_rWW8Export.bWrtWW8 ) |
| { |
| if ( m_rWW8Export.TrueFrameDirection(*pFrmFmt) == FRMDIR_HORI_RIGHT_TOP ) |
| { |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TFBiDi ); |
| m_rWW8Export.InsUInt16( 1 ); |
| } |
| } |
| } |
| |
| void WW8AttributeOutput::TableHeight( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwTableLine * pTabLine = pTabBox->GetUpper(); |
| const SwFrmFmt * pLineFmt = pTabLine->GetFrmFmt(); |
| |
| #if 0 |
| const SwTable * pTable = pTableTextNodeInfo->getTable(); |
| bool bNewTableModel = pTable->IsNewModel(); |
| bool bFixRowHeight = false; |
| const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes(); |
| if (! bNewModel) |
| { |
| sal_uInt32 nBoxes = rTabBoxes.Count(); |
| |
| for (sal_uInt32 n = 0; n < nBoxes; n++) |
| { |
| SwTableBox * pBox1 = rTabBoxes[n]; |
| if (pBox1->getRowspan() != 1) |
| { |
| bFixRowHeight = true; |
| break; |
| } |
| } |
| } |
| #endif |
| |
| // Zeilenhoehe ausgeben sprmTDyaRowHeight |
| long nHeight = 0; |
| const SwFmtFrmSize& rLSz = pLineFmt->GetFrmSize(); |
| if ( ATT_VAR_SIZE != rLSz.GetHeightSizeType() && rLSz.GetHeight() ) |
| { |
| if ( ATT_MIN_SIZE == rLSz.GetHeightSizeType() ) |
| nHeight = rLSz.GetHeight(); |
| else |
| nHeight = -rLSz.GetHeight(); |
| } |
| |
| if ( nHeight ) |
| { |
| if ( m_rWW8Export.bWrtWW8 ) |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TDyaRowHeight ); |
| else |
| m_rWW8Export.pO->Insert( 189, m_rWW8Export.pO->Count() ); |
| m_rWW8Export.InsUInt16( (sal_uInt16)nHeight ); |
| } |
| |
| } |
| |
| void WW8AttributeOutput::TableOrientation( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTable * pTable = pTableTextNodeInfoInner->getTable(); |
| |
| const SwFrmFmt *pFmt = pTable->GetFrmFmt(); |
| ASSERT(pFmt,"Impossible"); |
| if (!pFmt) |
| return; |
| |
| const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient(); |
| const SwFmtVertOrient &rVert = pFmt->GetVertOrient(); |
| |
| if ( |
| (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() || |
| text::RelOrientation::FRAME == rHori.GetRelationOrient()) |
| && |
| (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() || |
| text::RelOrientation::FRAME == rVert.GetRelationOrient()) |
| ) |
| { |
| sal_Int16 eHOri = rHori.GetHoriOrient(); |
| switch (eHOri) |
| { |
| case text::HoriOrientation::CENTER: |
| case text::HoriOrientation::RIGHT: |
| if ( m_rWW8Export.bWrtWW8 ) |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TJc ); |
| else |
| m_rWW8Export.pO->Insert( 182, m_rWW8Export.pO->Count() ); |
| m_rWW8Export.InsUInt16( text::HoriOrientation::RIGHT == eHOri ? 2 : 1 ); |
| break; |
| default: |
| break; |
| } |
| } |
| } |
| |
| void WW8AttributeOutput::TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) |
| { |
| const SwTable * pTable = pTableTextNodeInfoInner->getTable(); |
| const SwTableFmt * pTableFmt = pTable->GetTableFmt(); |
| |
| if (pTableFmt != NULL) |
| { |
| const SvxULSpaceItem & rUL = pTableFmt->GetULSpace(); |
| |
| if (rUL.GetUpper() > 0) |
| { |
| sal_uInt8 nPadding = 2; |
| sal_uInt8 nPcVert = 0; |
| sal_uInt8 nPcHorz = 0; |
| |
| sal_uInt8 nTPc = (nPadding << 4) | (nPcVert << 2) | nPcHorz; |
| |
| m_rWW8Export.InsUInt16(NS_sprm::LN_TPc); |
| m_rWW8Export.pO->Insert( nTPc, m_rWW8Export.pO->Count() ); |
| |
| m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaAbs); |
| m_rWW8Export.InsUInt16(rUL.GetUpper()); |
| |
| m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromText); |
| m_rWW8Export.InsUInt16(rUL.GetUpper()); |
| } |
| |
| if (rUL.GetLower() > 0) |
| { |
| m_rWW8Export.InsUInt16(NS_sprm::LN_TDyaFromTextBottom); |
| m_rWW8Export.InsUInt16(rUL.GetLower()); |
| } |
| } |
| } |
| |
| void WW8AttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTable * pTable = pTableTextNodeInfoInner->getTable(); |
| |
| if ( pTable->GetRowsToRepeat() > pTableTextNodeInfoInner->getRow() ) |
| { |
| if( m_rWW8Export.bWrtWW8 ) |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TTableHeader ); |
| else |
| m_rWW8Export.pO->Insert( 186, m_rWW8Export.pO->Count() ); |
| m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() ); |
| } |
| |
| ww8::TableBoxVectorPtr pTableBoxes = pTableTextNodeInfoInner->getTableBoxesOfRow(); |
| // number of cell written |
| const sal_uInt16 nBoxes = |
| pTableBoxes->size() > ww8::MAXTABLECELLS |
| ? ww8::MAXTABLECELLS |
| : static_cast< sal_uInt16 >(pTableBoxes->size()); |
| |
| // sprm header |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTable ); |
| const sal_uInt16 nSprmSize = 2 + (nBoxes + 1) * 2 + nBoxes * 20; |
| m_rWW8Export.InsUInt16( nSprmSize ); // length |
| |
| // number of boxes |
| m_rWW8Export.pO->Insert( static_cast<sal_uInt8>(nBoxes), m_rWW8Export.pO->Count() ); |
| |
| /* cellxs */ |
| /* |
| ALWAYS relative when text::HoriOrientation::NONE (nPageSize + ( nPageSize / 10 )) < nTblSz, |
| in that case the cell width's and table width's are not real. The table |
| width is maxed and cells relative, so we need the frame (generally page) |
| width that the table is in to work out the true widths. |
| */ |
| //const bool bNewTableModel = pTbl->IsNewModel(); |
| const SwFrmFmt *pFmt = pTable->GetFrmFmt(); |
| ASSERT(pFmt,"Impossible"); |
| if (!pFmt) |
| return; |
| |
| const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient(); |
| const SwFmtVertOrient &rVert = pFmt->GetVertOrient(); |
| |
| sal_uInt16 nTblOffset = 0; |
| |
| if ( |
| (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() || |
| text::RelOrientation::FRAME == rHori.GetRelationOrient()) |
| && |
| (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() || |
| text::RelOrientation::FRAME == rVert.GetRelationOrient()) |
| ) |
| { |
| sal_Int16 eHOri = rHori.GetHoriOrient(); |
| switch ( eHOri ) |
| { |
| case text::HoriOrientation::CENTER: |
| case text::HoriOrientation::RIGHT: |
| break; |
| |
| default: |
| nTblOffset = static_cast< sal_uInt16 >(rHori.GetPos()); |
| const SvxLRSpaceItem& rLRSp = pFmt->GetLRSpace(); |
| nTblOffset += static_cast< sal_uInt16 >(rLRSp.GetLeft()); |
| break; |
| } |
| } |
| |
| m_rWW8Export.InsUInt16( nTblOffset ); |
| |
| ww8::GridColsPtr pGridCols = GetGridCols( pTableTextNodeInfoInner ); |
| for ( ww8::GridCols::const_iterator it = pGridCols->begin(), |
| end = pGridCols->end(); it != end; ++it ) |
| { |
| m_rWW8Export.InsUInt16( static_cast<sal_uInt16>( *it ) + nTblOffset ); |
| } |
| |
| /* TCs */ |
| ww8::RowSpansPtr pRowSpans = pTableTextNodeInfoInner->getRowSpansOfRow(); |
| ww8::RowSpans::const_iterator aItRowSpans = pRowSpans->begin(); |
| ww8::TableBoxVector::const_iterator aIt; |
| ww8::TableBoxVector::const_iterator aItEnd = pTableBoxes->end(); |
| |
| #ifdef DEBUG |
| size_t nRowSpans = pRowSpans->size(); |
| size_t nTableBoxes = pTableBoxes->size(); |
| (void) nRowSpans; |
| (void) nTableBoxes; |
| #endif |
| |
| for( aIt = pTableBoxes->begin(); aIt != aItEnd; ++aIt, ++aItRowSpans) |
| { |
| #ifdef DEBUG |
| sal_uInt16 npOCount = m_rWW8Export.pO->Count(); |
| #endif |
| |
| const SwTableBox * pTabBox1 = *aIt; |
| const SwFrmFmt * pBoxFmt = NULL; |
| if (pTabBox1 != NULL) |
| pBoxFmt = pTabBox1->GetFrmFmt(); |
| |
| if ( m_rWW8Export.bWrtWW8 ) |
| { |
| sal_uInt16 nFlags = |
| lcl_TCFlags(*m_rWW8Export.pDoc, pTabBox1, *aItRowSpans); |
| m_rWW8Export.InsUInt16( nFlags ); |
| } |
| |
| static sal_uInt8 aNullBytes[] = { 0x0, 0x0 }; |
| |
| m_rWW8Export.pO->Insert( aNullBytes, 2, m_rWW8Export.pO->Count() ); // dummy |
| if (pBoxFmt != NULL) |
| { |
| const SvxBoxItem & rBoxItem = pBoxFmt->GetBox(); |
| |
| m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, &rBoxItem ); // 8/16 Byte |
| } |
| else |
| m_rWW8Export.Out_SwFmtTableBox( *m_rWW8Export.pO, NULL); // 8/16 Byte |
| |
| #ifdef DEBUG |
| ::std::clog << "<tclength>" << m_rWW8Export.pO->Count() - npOCount << "</tclength>" |
| << ::std::endl; |
| #endif |
| } |
| } |
| |
| ww8::GridColsPtr AttributeOutputBase::GetGridCols( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| return pTableTextNodeInfoInner->getGridColsOfRow(*this); |
| } |
| |
| void AttributeOutputBase::GetTablePageSize( ww8::WW8TableNodeInfoInner * pTableTextNodeInfoInner, sal_uInt32& rPageSize, bool& rRelBoxSize ) |
| { |
| sal_uInt32 nPageSize = 0; |
| |
| const SwNode *pTxtNd = pTableTextNodeInfoInner->getNode( ); |
| const SwTable *pTable = pTableTextNodeInfoInner->getTable( ); |
| |
| const SwFrmFmt *pFmt = pTable->GetFrmFmt(); |
| ASSERT(pFmt,"Impossible"); |
| if (!pFmt) |
| return; |
| |
| const SwFmtFrmSize &rSize = pFmt->GetFrmSize(); |
| int nWidthPercent = rSize.GetWidthPercent(); |
| bool bManualAligned = pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::NONE; |
| if ( (pFmt->GetHoriOrient().GetHoriOrient() == text::HoriOrientation::FULL) || bManualAligned ) |
| nWidthPercent = 100; |
| bool bRelBoxSize = nWidthPercent != 0; |
| unsigned long nTblSz = static_cast<unsigned long>(rSize.GetWidth()); |
| if (nTblSz > USHRT_MAX/2 && !bRelBoxSize) |
| { |
| ASSERT(bRelBoxSize, "huge table width but not relative, suspicious"); |
| bRelBoxSize = true; |
| } |
| |
| if ( bRelBoxSize ) |
| { |
| Point aPt; |
| SwRect aRect( pFmt->FindLayoutRect( false, &aPt ) ); |
| if ( aRect.IsEmpty() ) |
| { |
| // dann besorge mal die Seitenbreite ohne Raender !! |
| const SwFrmFmt* pParentFmt = |
| GetExport().mpParentFrame ? |
| &(GetExport().mpParentFrame->GetFrmFmt()) : |
| const_cast<const SwDoc *>(GetExport().pDoc)->GetPageDesc(0).GetPageFmtOfNode(*pTxtNd, false); |
| aRect = pParentFmt->FindLayoutRect(true); |
| if ( 0 == ( nPageSize = aRect.Width() ) ) |
| { |
| const SvxLRSpaceItem& rLR = pParentFmt->GetLRSpace(); |
| nPageSize = pParentFmt->GetFrmSize().GetWidth() - rLR.GetLeft() |
| - rLR.GetRight(); |
| } |
| } |
| else |
| { |
| nPageSize = aRect.Width(); |
| if ( bManualAligned ) |
| { |
| // #i37571# For manually aligned tables |
| const SvxLRSpaceItem &rLR = pFmt->GetLRSpace(); |
| nPageSize -= (rLR.GetLeft() + rLR.GetRight()); |
| } |
| |
| } |
| |
| ASSERT(nWidthPercent, "Impossible"); |
| if (nWidthPercent) |
| { |
| nPageSize *= nWidthPercent; |
| nPageSize /= 100; |
| } |
| } |
| |
| rPageSize = nPageSize; |
| rRelBoxSize = bRelBoxSize; |
| } |
| |
| void WW8AttributeOutput::TableDefaultBorders( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwFrmFmt * pFrmFmt = pTabBox->GetFrmFmt(); |
| |
| //Set Default, just taken from the first cell of the first |
| //row |
| static sal_uInt16 aBorders[] = |
| { |
| BOX_LINE_TOP, BOX_LINE_LEFT, |
| BOX_LINE_BOTTOM, BOX_LINE_RIGHT |
| }; |
| |
| for ( int i = 0; i < 4; ++i ) |
| { |
| SwWW8Writer::InsUInt16( *m_rWW8Export.pO, 0xD634 ); |
| m_rWW8Export.pO->Insert( sal_uInt8(6), m_rWW8Export.pO->Count() ); |
| m_rWW8Export.pO->Insert( sal_uInt8(0), m_rWW8Export.pO->Count() ); |
| m_rWW8Export.pO->Insert( sal_uInt8(1), m_rWW8Export.pO->Count() ); |
| m_rWW8Export.pO->Insert( sal_uInt8(1 << i), m_rWW8Export.pO->Count() ); |
| m_rWW8Export.pO->Insert( sal_uInt8(3), m_rWW8Export.pO->Count() ); |
| |
| SwWW8Writer::InsUInt16( *m_rWW8Export.pO, |
| pFrmFmt->GetBox().GetDistance( aBorders[i] ) ); |
| } |
| } |
| |
| void WW8AttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) |
| { |
| const SwTableBox * pTabBox = pTableTextNodeInfoInner->getTableBox(); |
| const SwTableLine * pTabLine = pTabBox->GetUpper(); |
| const SwTableBoxes & rTabBoxes = pTabLine->GetTabBoxes(); |
| |
| const sal_uInt16 nBoxes = rTabBoxes.Count(); |
| if ( m_rWW8Export.bWrtWW8 ) |
| m_rWW8Export.InsUInt16( NS_sprm::LN_TDefTableShd ); |
| else |
| m_rWW8Export.pO->Insert( (sal_uInt8)191, m_rWW8Export.pO->Count() ); |
| m_rWW8Export.pO->Insert( (sal_uInt8)(nBoxes * 2), m_rWW8Export.pO->Count() ); // Len |
| |
| for ( sal_uInt8 n = 0; n < nBoxes; n++ ) |
| { |
| const SwTableBox * pBox1 = rTabBoxes[n]; |
| const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt(); |
| const SfxPoolItem * pI = NULL; |
| Color aColor; |
| |
| if ( SFX_ITEM_ON == pFrmFmt->GetAttrSet().GetItemState( RES_BACKGROUND, false, &pI ) ) |
| { |
| aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor(); |
| } |
| else |
| aColor = COL_AUTO; |
| |
| WW8_SHD aShd; |
| m_rWW8Export.TransBrush( aColor, aShd ); |
| m_rWW8Export.InsUInt16( aShd.GetValue() ); |
| } |
| |
| if ( m_rWW8Export.bWrtWW8 ) |
| { |
| const sal_uInt16 aSprmIds[] = { NS_sprm::LN_TCellShd, NS_sprm::LN_TCellShadow }; |
| sal_uInt16 nBoxes0 = rTabBoxes.Count(); |
| if (nBoxes0 > 21) |
| nBoxes0 = 21; |
| |
| for ( sal_uInt32 m = 0; m < 2; m++ ) |
| { |
| m_rWW8Export.InsUInt16( aSprmIds[m] ); |
| m_rWW8Export.pO->Insert( |
| static_cast< sal_uInt8 >( nBoxes0 * 10 ), |
| m_rWW8Export.pO->Count() ); |
| |
| for ( sal_uInt16 n = 0; n < nBoxes0; n++ ) |
| { |
| const SwTableBox * pBox1 = rTabBoxes[n]; |
| const SwFrmFmt * pFrmFmt = pBox1->GetFrmFmt(); |
| const SfxPoolItem * pI = NULL; |
| Color aColor; |
| |
| if ( SFX_ITEM_ON == |
| pFrmFmt->GetAttrSet(). |
| GetItemState( RES_BACKGROUND, false, &pI ) ) |
| { |
| aColor = dynamic_cast<const SvxBrushItem *>(pI)->GetColor(); |
| } |
| else |
| aColor = COL_AUTO; |
| |
| WW8SHDLong aSHD; |
| aSHD.setCvFore( 0xFF000000 ); |
| |
| sal_uInt32 nBgColor = aColor.GetColor(); |
| if ( nBgColor == COL_AUTO ) |
| aSHD.setCvBack( 0xFF000000 ); |
| else |
| aSHD.setCvBack( wwUtility::RGBToBGR( nBgColor ) ); |
| |
| aSHD.Write( m_rWW8Export ); |
| } |
| } |
| } |
| } |
| |
| void WW8Export::SectionBreaksAndFrames( const SwTxtNode& rNode ) |
| { |
| // output page/section breaks |
| OutputSectionBreaks( rNode.GetpSwAttrSet(), rNode ); |
| |
| // all textframes anchored as character for the winword 7- format |
| if ( !bWrtWW8 && !IsInTable() ) |
| OutWW6FlyFrmsInCntnt( rNode ); |
| } |
| |
| #ifdef DEBUG |
| struct SwNodeHash |
| { |
| size_t operator()(SwNode * pNode) const { return reinterpret_cast<size_t>(pNode); } |
| }; |
| |
| typedef ::std::hash_set<SwNode *, SwNodeHash> SwNodeHashSet; |
| typedef ::std::deque<SwNode *> SwNodeDeque; |
| #endif |
| |
| void MSWordExportBase::WriteText() |
| { |
| // whoever has need of the missing function should go and implement it! |
| // This piece of code always breaks builds... |
| //#ifdef DEBUG |
| // ::std::clog << "<WriteText>" << ::std::endl; |
| // ::std::clog << dbg_out(pCurPam->GetDoc()->GetNodes()) << ::std::endl; |
| // |
| // SwNodeHashSet aNodeSet; |
| // SwNodeDeque aNodeDeque; |
| //#endif |
| |
| while( pCurPam->GetPoint()->nNode < pCurPam->GetMark()->nNode || |
| ( pCurPam->GetPoint()->nNode == pCurPam->GetMark()->nNode && |
| pCurPam->GetPoint()->nContent.GetIndex() <= pCurPam->GetMark()->nContent.GetIndex() ) ) |
| { |
| SwNode * pNd = pCurPam->GetNode(); |
| |
| // whoever has need of the missing function should go and implement it! |
| // This piece of code always breaks builds... |
| #if 0 |
| #ifdef DEBUG |
| if (aNodeSet.find(pNd) == aNodeSet.end()) |
| { |
| aNodeSet.insert(pNd); |
| aNodeDeque.push_back(pNd); |
| } |
| else |
| { |
| ::std::clog << "<already-done>" << dbg_out(*pNd) << "</already-done>" << ::std::endl; |
| } |
| #endif |
| #endif |
| |
| if ( pNd->IsTxtNode() ) |
| SectionBreaksAndFrames( *pNd->GetTxtNode() ); |
| |
| // output the various types of nodes |
| if ( pNd->IsCntntNode() ) |
| { |
| SwCntntNode* pCNd = (SwCntntNode*)pNd; |
| |
| const SwPageDesc* pTemp = pCNd->GetSwAttrSet().GetPageDesc().GetPageDesc(); |
| if ( pTemp ) |
| pAktPageDesc = pTemp; |
| |
| pCurPam->GetPoint()->nContent.Assign( pCNd, 0 ); |
| OutputContentNode( *pCNd ); |
| } |
| else if ( pNd->IsTableNode() ) |
| { |
| mpTableInfo->processSwTable( &pNd->GetTableNode()->GetTable() ); |
| } |
| else if ( pNd->IsSectionNode() && TXT_MAINTEXT == nTxtTyp ) |
| OutputSectionNode( *pNd->GetSectionNode() ); |
| else if ( TXT_MAINTEXT == nTxtTyp && pNd->IsEndNode() && |
| pNd->StartOfSectionNode()->IsSectionNode() ) |
| { |
| const SwSection& rSect = pNd->StartOfSectionNode()->GetSectionNode() |
| ->GetSection(); |
| if ( bStartTOX && TOX_CONTENT_SECTION == rSect.GetType() ) |
| bStartTOX = false; |
| |
| SwNodeIndex aIdx( *pNd, 1 ); |
| if ( aIdx.GetNode().IsEndNode() && aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) |
| ; |
| else if ( aIdx.GetNode().IsSectionNode() ) |
| ; |
| else if ( !IsInTable() |
| && (rSect.GetType() != TOX_CONTENT_SECTION && rSect.GetType() != TOX_HEADER_SECTION )) //No sections in table |
| { |
| //#120140# Do not need to insert a page/section break after a section end. Check this case first |
| sal_Bool bNeedExportBreakHere = sal_True; |
| if ( aIdx.GetNode().IsTxtNode() ) |
| { |
| SwTxtNode *pTempNext = aIdx.GetNode().GetTxtNode(); |
| if ( pTempNext ) |
| { |
| const SfxPoolItem * pTempItem = NULL; |
| if (pTempNext->GetpSwAttrSet() && SFX_ITEM_SET == pTempNext->GetpSwAttrSet()->GetItemState(RES_PAGEDESC, false, &pTempItem) |
| && pTempItem && ((SwFmtPageDesc*)pTempItem)->GetRegisteredIn()) |
| { |
| //Next node has a new page style which means this node is a section end. Do not insert another page/section break here |
| bNeedExportBreakHere = sal_False; |
| } |
| } |
| } |
| if (bNeedExportBreakHere) //#120140# End of check |
| { |
| ReplaceCr( (char)0xc ); // Indikator fuer Page/Section-Break |
| |
| const SwSectionFmt* pParentFmt = rSect.GetFmt()->GetParent(); |
| if ( !pParentFmt ) |
| pParentFmt = (SwSectionFmt*)0xFFFFFFFF; |
| |
| sal_uLong nRstLnNum; |
| if ( aIdx.GetNode().IsCntntNode() ) |
| nRstLnNum = ((SwCntntNode&)aIdx.GetNode()).GetSwAttrSet(). |
| GetLineNumber().GetStartValue(); |
| else |
| nRstLnNum = 0; |
| |
| AppendSection( pAktPageDesc, pParentFmt, nRstLnNum ); |
| } |
| } |
| } |
| else if ( pNd->IsStartNode() ) |
| { |
| OutputStartNode( *pNd->GetStartNode() ); |
| } |
| else if ( pNd->IsEndNode() ) |
| { |
| OutputEndNode( *pNd->GetEndNode() ); |
| } |
| |
| if ( pNd == &pNd->GetNodes().GetEndOfContent() ) |
| break; |
| |
| SwNode * pCurrentNode = &pCurPam->GetPoint()->nNode.GetNode(); |
| const SwNode * pNextNode = mpTableInfo->getNextNode(pCurrentNode); |
| |
| if (pNextNode != NULL) |
| pCurPam->GetPoint()->nNode = SwNodeIndex(*pNextNode); |
| else |
| pCurPam->GetPoint()->nNode++; |
| |
| sal_uLong nPos = pCurPam->GetPoint()->nNode.GetIndex(); |
| ::SetProgressState( nPos, pCurPam->GetDoc()->GetDocShell() ); |
| } |
| |
| #ifdef DEBUG |
| ::std::clog << "</WriteText>" << ::std::endl; |
| #endif |
| } |
| |
| void WW8Export::WriteMainText() |
| { |
| #ifdef DEBUG |
| ::std::clog << "<WriteMainText>" << ::std::endl; |
| #endif |
| |
| pFib->fcMin = Strm().Tell(); |
| |
| pCurPam->GetPoint()->nNode = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode()->GetIndex(); |
| |
| WriteText(); |
| |
| if( 0 == Strm().Tell() - pFib->fcMin ) // kein Text ? |
| WriteCR(); // dann CR ans Ende ( sonst mault WW ) |
| |
| pFib->ccpText = Fc2Cp( Strm().Tell() ); |
| pFldMain->Finish( pFib->ccpText, 0 ); |
| |
| // ccpText beinhaltet Ftn- und KF-Texte |
| // deshalb wird pFib->ccpText evtl. noch geupdated |
| // save the StyleId of the last paragraph. Because WW97 take the style |
| // from the last CR, that will be write after footer/Header/fontnotes/ |
| // annotation usw. |
| const SwTxtNode* pLastNd = pCurPam->GetMark()->nNode.GetNode().GetTxtNode(); |
| if( pLastNd ) |
| nLastFmtId = GetId( (SwTxtFmtColl&)pLastNd->GetAnyFmtColl() ); |
| |
| #ifdef DEBUG |
| ::std::clog << "</WriteMainText>" << ::std::endl; |
| #endif |
| } |
| |
| bool MSWordExportBase::IsInTable() const |
| { |
| bool bResult = false; |
| |
| if (pCurPam != NULL) |
| { |
| SwNode * pNode = pCurPam->GetNode(); |
| |
| if (pNode != NULL && mpTableInfo.get() != NULL) |
| { |
| ww8::WW8TableNodeInfo::Pointer_t pTableNodeInfo = mpTableInfo->getTableNodeInfo(pNode); |
| |
| if (pTableNodeInfo.get() != NULL && pTableNodeInfo->getDepth() > 0) |
| { |
| bResult = true; |
| } |
| } |
| } |
| |
| return bResult; |
| } |
| |
| typedef ww8::WW8Sttb< ww8::WW8Struct > WW8SttbAssoc; |
| |
| void WW8Export::WriteFkpPlcUsw() |
| { |
| if( !bWrtWW8 ) |
| { |
| static const sal_uInt8 aSpec[2] = |
| { |
| 117, 1 |
| }; |
| |
| pChpPlc->AppendFkpEntry( Strm().Tell() ); // Sepx mit fSpecial |
| pSepx->WriteSepx( Strm() ); // Slcx.Sepx |
| pGrf->Write(); // Grafiken |
| pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aSpec ), aSpec ); |
| |
| pChpPlc->WriteFkps(); // Fkp.Chpx |
| pPapPlc->WriteFkps(); // Fkp.Papx |
| pStyles->OutputStylesTable(); // Styles |
| pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc |
| pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc |
| pAtn->WritePlc( *this ); // Annotation-Ref & Text Plc |
| pSepx->WritePlcSed( *this ); // Slcx.PlcSed |
| pSepx->WritePlcHdd( *this ); // Slcx.PlcHdd |
| pChpPlc->WritePlc(); // Plcx.Chpx |
| pPapPlc->WritePlc(); // Plcx.Papx |
| maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs |
| if( pRedlAuthors ) |
| pRedlAuthors->Write( GetWriter() ); // sttbfRMark (RedlineAuthors) |
| pFldMain->Write( *this ); // Fields ( Main Text ) |
| pFldHdFt->Write( *this ); // Fields ( Header/Footer ) |
| pFldFtn->Write( *this ); // Fields ( FootNotes ) |
| pFldEdn->Write( *this ); // Fields ( EndNotes ) |
| pFldAtn->Write( *this ); // Fields ( Annotations ) |
| pBkmks->Write( *this ); // Bookmarks - sttbfBkmk/ |
| // plcfBkmkf/plcfBkmkl |
| WriteDop( *this ); // Document-Properties |
| |
| } |
| else |
| { |
| // Grafiken in den Data-Tream |
| pGrf->Write(); // Grafiken |
| |
| // Ausgabe in WordDocument-Stream |
| pChpPlc->WriteFkps(); // Fkp.Chpx |
| pPapPlc->WriteFkps(); // Fkp.Papx |
| pSepx->WriteSepx( Strm() ); // Sepx |
| |
| // Ausagbe in Table-Stream |
| pStyles->OutputStylesTable(); // fuer WW8 StyleTab |
| pFtn->WritePlc( *this ); // Footnote-Ref & Text Plc |
| pEdn->WritePlc( *this ); // Endnote-Ref & Text Plc |
| pTxtBxs->WritePlc( *this ); // Textbox Text Plc |
| pHFTxtBxs->WritePlc( *this ); // Head/Foot-Textbox Text Plc |
| pAtn->WritePlc( *this ); // Annotation-Ref & Text Plc |
| |
| pSepx->WritePlcSed( *this ); // Slcx.PlcSed |
| pSepx->WritePlcHdd( *this ); // Slcx.PlcHdd |
| |
| pChpPlc->WritePlc(); // Plcx.Chpx |
| pPapPlc->WritePlc(); // Plcx.Papx |
| |
| if( pRedlAuthors ) |
| pRedlAuthors->Write( GetWriter() ); // sttbfRMark (RedlineAuthors) |
| pFldMain->Write( *this ); // Fields ( Main Text ) |
| pFldHdFt->Write( *this ); // Fields ( Header/Footer ) |
| pFldFtn->Write( *this ); // Fields ( FootNotes ) |
| pFldEdn->Write( *this ); // Fields ( EndNotes ) |
| pFldAtn->Write( *this ); // Fields ( Annotations ) |
| pFldTxtBxs->Write( *this ); // Fields ( Textboxes ) |
| pFldHFTxtBxs->Write( *this ); // Fields ( Head/Foot-Textboxes ) |
| |
| if (pEscher || pDoc->ContainsMSVBasic()) |
| { |
| /* |
| #82587# Everytime MS 2000 creates an escher stream there is always |
| an ObjectPool dir (even if empty). It turns out that if a copy of |
| MS 2000 is used to open a document that contains escher graphics |
| exported from StarOffice without this empty dir then *if* that |
| copy of MS Office has never been used to open a MSOffice document |
| that has escher graphics (and an ObjectPool dir of course) and |
| that copy of office has not been used to draw escher graphics then |
| our exported graphics do not appear. Once you do open a ms |
| document with escher graphics or draw an escher graphic with that |
| copy of word, then all documents from staroffice that contain |
| escher work from then on. Tricky to track down, some sort of late |
| binding trickery in MS where solely for first time initialization |
| the existence of an ObjectPool dir is necessary for triggering |
| some magic. cmc |
| */ |
| /* |
| #10570# Similiarly having msvbasic storage seems to also trigger |
| creating this stream |
| */ |
| GetWriter().GetStorage().OpenSotStorage(CREATE_CONST_ASC(SL::aObjectPool), |
| STREAM_READWRITE | STREAM_SHARE_DENYALL); |
| } |
| |
| // dggInfo - escher stream |
| WriteEscher(); |
| |
| pSdrObjs->WritePlc( *this ); |
| pHFSdrObjs->WritePlc( *this ); |
| // spamom - office drawing table |
| // spahdr - header office drawing table |
| |
| pBkmks->Write( *this ); // Bookmarks - sttbfBkmk/ |
| // plcfBkmkf/plcfBkmkl |
| |
| WriteNumbering(); |
| |
| RestoreMacroCmds(); |
| |
| pMagicTable->Write( *this ); |
| |
| pPiece->WritePc( *this ); // Piece-Table |
| maFontHelper.WriteFontTable(pTableStrm, *pFib); // FFNs |
| |
| //Convert OOo asian typography into MS typography structure |
| ExportDopTypography(pDop->doptypography); |
| |
| WriteDop( *this ); // Document-Properties |
| |
| // Write SttbfAssoc |
| WW8SttbAssoc * pSttbfAssoc = dynamic_cast<WW8SttbAssoc *> |
| (pDoc->getExternalData(::sw::STTBF_ASSOC).get()); |
| // --> OD 2009-10-19 #i106057# |
| if ( pSttbfAssoc ) |
| // <-- |
| { |
| ::std::vector<String> aStrings; |
| |
| ::ww8::StringVector_t & aSttbStrings = pSttbfAssoc->getStrings(); |
| ::ww8::StringVector_t::const_iterator aItEnd = aSttbStrings.end(); |
| for (::ww8::StringVector_t::const_iterator aIt = aSttbStrings.begin(); |
| aIt != aItEnd; aIt++) |
| { |
| String aStr(aIt->getStr()); |
| aStrings.push_back(aStr); |
| } |
| |
| WriteAsStringTable(aStrings, pFib->fcSttbfAssoc, |
| pFib->lcbSttbfAssoc); |
| } |
| } |
| Strm().Seek( 0 ); |
| |
| // Reclaim stored FIB data from document. |
| ::ww8::WW8FibData * pFibData = dynamic_cast<ww8::WW8FibData *> |
| (pDoc->getExternalData(::sw::FIB).get()); |
| |
| if ( pFibData ) |
| // <-- |
| { |
| pFib->fReadOnlyRecommended = |
| pFibData->getReadOnlyRecommended() ? 1 : 0; |
| pFib->fWriteReservation = |
| pFibData->getWriteReservation() ? 1 : 0; |
| } |
| |
| pFib->Write( Strm() ); // FIB |
| } |
| |
| void WW8Export::StoreDoc1() |
| { |
| bool bNeedsFinalPara = false; |
| // Start of Text ( Mangel ueber ) |
| SwWW8Writer::FillUntil( Strm(), pFib->fcMin ); |
| |
| WriteMainText(); // HauptText |
| sal_uInt8 nSprmsLen; |
| sal_uInt8 *pLastSprms = pPapPlc->CopyLastSprms(nSprmsLen); |
| |
| bNeedsFinalPara |= pFtn->WriteTxt( *this ); // Footnote-Text |
| bNeedsFinalPara |= pSepx->WriteKFTxt( *this ); // K/F-Text |
| bNeedsFinalPara |= pAtn->WriteTxt( *this ); // Annotation-Text |
| bNeedsFinalPara |= pEdn->WriteTxt( *this ); // EndNote-Text |
| |
| // create the escher streams |
| if( bWrtWW8 ) |
| CreateEscher(); |
| |
| bNeedsFinalPara |= pTxtBxs->WriteTxt( *this ); //Textbox Text Plc |
| bNeedsFinalPara |= pHFTxtBxs->WriteTxt( *this );//Head/Foot-Textbox Text Plc |
| |
| if (bNeedsFinalPara) |
| { |
| WriteCR(); |
| pPapPlc->AppendFkpEntry(Strm().Tell(), nSprmsLen, pLastSprms); |
| } |
| delete[] pLastSprms; |
| |
| pSepx->Finish( Fc2Cp( Strm().Tell() ));// Text + Ftn + HdFt als Section-Ende |
| pMagicTable->Finish( Fc2Cp( Strm().Tell() ),0); |
| |
| pFib->fcMac = Strm().Tell(); // Ende aller Texte |
| |
| WriteFkpPlcUsw(); // FKP, PLC, ..... |
| } |
| |
| void MSWordExportBase::AddLinkTarget(const String& rURL) |
| { |
| if( !rURL.Len() || rURL.GetChar(0) != INET_MARK_TOKEN ) |
| return; |
| |
| String aURL( BookmarkToWriter( rURL.Copy( 1 ) ) ); |
| xub_StrLen nPos = aURL.SearchBackward( cMarkSeperator ); |
| |
| if( nPos < 2 ) |
| return; |
| |
| String sCmp( aURL.Copy( nPos+1 ) ); |
| sCmp.EraseAllChars(); |
| if( !sCmp.Len() ) |
| return; |
| |
| sCmp.ToLowerAscii(); |
| |
| if( sCmp.EqualsAscii( pMarkToOutline ) ) |
| { |
| SwPosition aPos( *pCurPam->GetPoint() ); |
| String aOutline( BookmarkToWriter(aURL.Copy( 0, nPos )) ); |
| // If we can find the outline this bookmark refers to |
| // save the name of the bookmark and the |
| // node index number of where it points to |
| if( pDoc->GotoOutline( aPos, aOutline ) ) |
| { |
| sal_uLong nIdx = aPos.nNode.GetIndex(); |
| aPair aImplicitBookmark; |
| aImplicitBookmark.first = aOutline; |
| aImplicitBookmark.second = nIdx; |
| maImplicitBookmarks.push_back(aImplicitBookmark); |
| } |
| } |
| } |
| |
| void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc) |
| { |
| const SwFmtINetFmt* pINetFmt; |
| const SwTxtINetFmt* pTxtAttr; |
| const SwTxtNode* pTxtNd; |
| |
| sal_uInt32 n, nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT ); |
| for( n = 0; n < nMaxItems; ++n ) |
| { |
| if( 0 != (pINetFmt = (SwFmtINetFmt*)rDoc.GetAttrPool().GetItem2( |
| RES_TXTATR_INETFMT, n ) ) && |
| 0 != ( pTxtAttr = pINetFmt->GetTxtINetFmt()) && |
| 0 != ( pTxtNd = pTxtAttr->GetpTxtNode() ) && |
| pTxtNd->GetNodes().IsDocNodes() ) |
| { |
| AddLinkTarget( pINetFmt->GetValue() ); |
| } |
| } |
| |
| const SwFmtURL *pURL; |
| nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_URL ); |
| for( n = 0; n < nMaxItems; ++n ) |
| { |
| if( 0 != (pURL = (SwFmtURL*)rDoc.GetAttrPool().GetItem2( |
| RES_URL, n ) ) ) |
| { |
| AddLinkTarget( pURL->GetURL() ); |
| const ImageMap *pIMap = pURL->GetMap(); |
| if( pIMap ) |
| { |
| for( sal_uInt16 i=0; i<pIMap->GetIMapObjectCount(); i++ ) |
| { |
| const IMapObject* pObj = pIMap->GetIMapObject( i ); |
| if( pObj ) |
| { |
| AddLinkTarget( pObj->GetURL() ); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| namespace |
| { |
| const sal_uLong WW_BLOCKSIZE = 0x200; |
| |
| void EncryptRC4(msfilter::MSCodec_Std97& rCtx, SvStream &rIn, SvStream &rOut) |
| { |
| rIn.Seek(STREAM_SEEK_TO_END); |
| sal_uLong nLen = rIn.Tell(); |
| rIn.Seek(0); |
| |
| sal_uInt8 in[WW_BLOCKSIZE]; |
| for (sal_uLong nI = 0, nBlock = 0; nI < nLen; nI += WW_BLOCKSIZE, ++nBlock) |
| { |
| sal_uLong nBS = (nLen - nI > WW_BLOCKSIZE) ? WW_BLOCKSIZE : nLen - nI; |
| rIn.Read(in, nBS); |
| rCtx.InitCipher(nBlock); |
| rCtx.Encode(in, nBS, in, nBS); |
| rOut.Write(in, nBS); |
| } |
| } |
| } |
| |
| void MSWordExportBase::ExportDocument( bool bWriteAll ) |
| { |
| nCharFmtStart = ANZ_DEFAULT_STYLES; |
| nFmtCollStart = nCharFmtStart + pDoc->GetCharFmts()->Count() - 1; |
| |
| bStyDef = bBreakBefore = bOutKF = |
| bOutFlyFrmAttrs = bOutPageDescs = bOutTable = bOutFirstPage = |
| bOutGrf = bInWriteEscher = bStartTOX = |
| bInWriteTOX = false; |
| |
| bFtnAtTxtEnd = bEndAtTxtEnd = true; |
| |
| mpParentFrame = 0; |
| pFlyOffset = 0; |
| eNewAnchorType = FLY_AT_PAGE; |
| nTxtTyp = TXT_MAINTEXT; |
| nStyleBeforeFly = nLastFmtId = 0; |
| pStyAttr = 0; |
| pCurrentStyle = NULL; |
| pOutFmtNode = 0; |
| pEscher = 0; |
| pRedlAuthors = 0; |
| if ( aTOXArr.Count() ) |
| aTOXArr.Remove( 0, aTOXArr.Count() ); |
| |
| // update layout as it is needed for the export - e.g. for the export of tables |
| boost::scoped_ptr< ViewShell > pTemporaryViewShell( 0 ); |
| { |
| ViewShell* pViewShell = NULL; |
| pDoc->GetEditShell( &pViewShell ); |
| if ( pViewShell == NULL ) |
| { |
| pTemporaryViewShell.reset( new ViewShell( *pDoc, 0 ) ); |
| pViewShell = pTemporaryViewShell.get(); |
| } |
| if ( pViewShell != NULL ) |
| { |
| pViewShell->CalcLayout(); |
| } |
| } |
| |
| if ( !pOLEExp ) |
| { |
| sal_uInt32 nSvxMSDffOLEConvFlags = 0; |
| const SvtFilterOptions* pOpt = SvtFilterOptions::Get(); |
| if ( pOpt->IsMath2MathType() ) |
| nSvxMSDffOLEConvFlags |= OLE_STARMATH_2_MATHTYPE; |
| if ( pOpt->IsWriter2WinWord() ) |
| nSvxMSDffOLEConvFlags |= OLE_STARWRITER_2_WINWORD; |
| if ( pOpt->IsCalc2Excel() ) |
| nSvxMSDffOLEConvFlags |= OLE_STARCALC_2_EXCEL; |
| if ( pOpt->IsImpress2PowerPoint() ) |
| nSvxMSDffOLEConvFlags |= OLE_STARIMPRESS_2_POWERPOINT; |
| |
| pOLEExp = new SvxMSExportOLEObjects( nSvxMSDffOLEConvFlags ); |
| } |
| |
| if ( !pOleMap) |
| pOleMap = new WW8OleMaps; |
| |
| if ( !pOCXExp ) |
| pOCXExp = new SwMSConvertControls( pDoc->GetDocShell(), pCurPam ); |
| |
| // Collect anchored objects before changing the redline mode. |
| maFrames = GetFrames( *pDoc, bWriteAll? NULL : pOrigPam ); |
| |
| mnRedlineMode = pDoc->GetRedlineMode(); |
| if ( pDoc->GetRedlineTbl().Count() ) |
| { |
| pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode | nsRedlineMode_t::REDLINE_SHOW_DELETE | |
| nsRedlineMode_t::REDLINE_SHOW_INSERT) ); |
| } |
| |
| maFontHelper.InitFontTable( HackIsWW8OrHigher(), *pDoc ); |
| GatherChapterFields(); |
| |
| CollectOutlineBookmarks(*pDoc); |
| |
| // make unique OrdNums (Z-Order) for all drawing-/fly Objects |
| if ( pDoc->GetDrawModel() ) |
| pDoc->GetDrawModel()->GetPage( 0 )->RecalcObjOrdNums(); |
| |
| ExportDocument_Impl(); |
| |
| if ( mnRedlineMode != pDoc->GetRedlineMode() ) |
| pDoc->SetRedlineMode( (RedlineMode_t)(mnRedlineMode) ); |
| } |
| |
| bool SwWW8Writer::InitStd97CodecUpdateMedium( ::msfilter::MSCodec_Std97& rCodec ) |
| { |
| uno::Sequence< beans::NamedValue > aEncryptionData; |
| |
| if ( mpMedium ) |
| { |
| SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False ); |
| if ( pEncryptionDataItem && ( pEncryptionDataItem->GetValue() >>= aEncryptionData ) && !rCodec.InitCodec( aEncryptionData ) ) |
| { |
| OSL_ENSURE( false, "Unexpected EncryptionData!" ); |
| aEncryptionData.realloc( 0 ); |
| } |
| |
| if ( !aEncryptionData.getLength() ) |
| { |
| // try to generate the encryption data based on password |
| SFX_ITEMSET_ARG( mpMedium->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False ); |
| if ( pPasswordItem && pPasswordItem->GetValue().Len() && pPasswordItem->GetValue().Len() <= 15 ) |
| { |
| // Generate random number with a seed of time as salt. |
| TimeValue aTime; |
| osl_getSystemTime( &aTime ); |
| rtlRandomPool aRandomPool = rtl_random_createPool (); |
| rtl_random_addBytes ( aRandomPool, &aTime, 8 ); |
| |
| sal_uInt8 pDocId[ 16 ]; |
| rtl_random_getBytes( aRandomPool, pDocId, 16 ); |
| |
| rtl_random_destroyPool( aRandomPool ); |
| |
| sal_Unicode aPassword[16]; |
| memset( aPassword, 0, sizeof( aPassword ) ); |
| for ( xub_StrLen nChar = 0; nChar < pPasswordItem->GetValue().Len(); ++nChar ) |
| aPassword[nChar] = pPasswordItem->GetValue().GetChar(nChar); |
| |
| rCodec.InitKey( aPassword, pDocId ); |
| aEncryptionData = rCodec.GetEncryptionData(); |
| |
| mpMedium->GetItemSet()->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) ); |
| } |
| } |
| |
| if ( aEncryptionData.getLength() ) |
| mpMedium->GetItemSet()->ClearItem( SID_PASSWORD ); |
| } |
| |
| // nonempty encryption data means hier that the codec was successfuly initialized |
| return ( aEncryptionData.getLength() != 0 ); |
| } |
| |
| void WW8Export::ExportDocument_Impl() |
| { |
| PrepareStorage(); |
| |
| pFib = new WW8Fib( bWrtWW8 ? 8 : 6 ); |
| |
| SvStorageStreamRef xWwStrm( GetWriter().GetStorage().OpenSotStream( aMainStg ) ); |
| SvStorageStreamRef xTableStrm( xWwStrm ), xDataStrm( xWwStrm ); |
| xWwStrm->SetBufferSize( 32768 ); |
| |
| if( bWrtWW8 ) |
| { |
| pFib->fWhichTblStm = 1; |
| xTableStrm = GetWriter().GetStorage().OpenSotStream(CREATE_CONST_ASC(SL::a1Table), |
| STREAM_STD_WRITE ); |
| xDataStrm = GetWriter().GetStorage().OpenSotStream(CREATE_CONST_ASC(SL::aData), |
| STREAM_STD_WRITE ); |
| |
| xDataStrm->SetBufferSize( 32768 ); // fuer Grafiken |
| xTableStrm->SetBufferSize( 16384 ); // fuer die Font-/Style-Table, usw. |
| |
| xTableStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); |
| xDataStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); |
| } |
| |
| GetWriter().SetStream( & *xWwStrm ); |
| pTableStrm = &xTableStrm; |
| pDataStrm = &xDataStrm; |
| |
| Strm().SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); |
| |
| utl::TempFile aTempMain; |
| aTempMain.EnableKillingFile(); |
| utl::TempFile aTempTable; |
| aTempTable.EnableKillingFile(); |
| utl::TempFile aTempData; |
| aTempData.EnableKillingFile(); |
| |
| msfilter::MSCodec_Std97 aCtx; |
| bool bEncrypt = m_pWriter ? m_pWriter->InitStd97CodecUpdateMedium( aCtx ) : false; |
| if ( bEncrypt ) |
| { |
| GetWriter().SetStream( |
| aTempMain.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ) ); |
| |
| pTableStrm = aTempTable.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); |
| |
| pDataStrm = aTempData.GetStream( STREAM_READWRITE | STREAM_SHARE_DENYWRITE ); |
| |
| sal_uInt8 aRC4EncryptionHeader[ 52 ] = {0}; |
| pTableStrm->Write( aRC4EncryptionHeader, 52 ); |
| } |
| |
| // Default: "Standard" |
| pSepx = new WW8_WrPlcSepx( *this ); // Sections/headers/footers |
| |
| pFtn = new WW8_WrPlcFtnEdn( TXT_FTN ); // Footnotes |
| pEdn = new WW8_WrPlcFtnEdn( TXT_EDN ); // Endnotes |
| pAtn = new WW8_WrPlcAnnotations; // PostIts |
| pTxtBxs = new WW8_WrPlcTxtBoxes( TXT_TXTBOX ); |
| pHFTxtBxs = new WW8_WrPlcTxtBoxes( TXT_HFTXTBOX ); |
| |
| pSdrObjs = new MainTxtPlcDrawObj; // Draw-/Fly-Objects for main text |
| pHFSdrObjs = new HdFtPlcDrawObj; // Draw-/Fly-Objects for header/footer |
| |
| pBkmks = new WW8_WrtBookmarks; // Bookmarks |
| GetWriter().CreateBookmarkTbl(); |
| |
| pPapPlc = new WW8_WrPlcPn( *this, PAP, pFib->fcMin ); |
| pChpPlc = new WW8_WrPlcPn( *this, CHP, pFib->fcMin ); |
| pO = new WW8Bytes( 128, 128 ); |
| pStyles = new MSWordStyles( *this ); |
| pFldMain = new WW8_WrPlcFld( 2, TXT_MAINTEXT ); |
| pFldHdFt = new WW8_WrPlcFld( 2, TXT_HDFT ); |
| pFldFtn = new WW8_WrPlcFld( 2, TXT_FTN ); |
| pFldEdn = new WW8_WrPlcFld( 2, TXT_EDN ); |
| pFldAtn = new WW8_WrPlcFld( 2, TXT_ATN ); |
| pFldTxtBxs = new WW8_WrPlcFld( 2, TXT_TXTBOX ); |
| pFldHFTxtBxs = new WW8_WrPlcFld( 2, TXT_HFTXTBOX ); |
| |
| pMagicTable = new WW8_WrMagicTable; |
| |
| pGrf = new SwWW8WrGrf( *this ); |
| pPiece = new WW8_WrPct( pFib->fcMin, bWrtWW8 ); |
| pDop = new WW8Dop; |
| |
| |
| pDop->fRevMarking = 0 != ( nsRedlineMode_t::REDLINE_ON & mnRedlineMode ); |
| pDop->fRMView = 0 != ( nsRedlineMode_t::REDLINE_SHOW_DELETE & mnRedlineMode ); |
| pDop->fRMPrint = pDop->fRMView; |
| |
| // set AutoHyphenation flag if found in default para style |
| const SfxPoolItem* pItem; |
| SwTxtFmtColl* pStdTxtFmtColl = |
| pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false); |
| if (pStdTxtFmtColl && SFX_ITEM_SET == pStdTxtFmtColl->GetItemState( |
| RES_PARATR_HYPHENZONE, false, &pItem)) |
| { |
| pDop->fAutoHyphen = ((const SvxHyphenZoneItem*)pItem)->IsHyphen(); |
| } |
| |
| StoreDoc1(); |
| |
| if ( bEncrypt ) |
| { |
| SvStream *pStrmTemp, *pTableStrmTemp, *pDataStrmTemp; |
| pStrmTemp = &xWwStrm; |
| pTableStrmTemp = &xTableStrm; |
| pDataStrmTemp = &xDataStrm; |
| |
| if ( pDataStrmTemp && pDataStrmTemp != pStrmTemp) |
| EncryptRC4(aCtx, *pDataStrm, *pDataStrmTemp); |
| |
| EncryptRC4(aCtx, *pTableStrm, *pTableStrmTemp); |
| |
| // Write Unencrypted Header 52 bytes to the start of the table stream |
| // EncryptionVersionInfo (4 bytes): A Version structure where Version.vMajor MUST be 0x0001, and Version.vMinor MUST be 0x0001. |
| pTableStrmTemp->Seek( 0 ); |
| sal_uInt32 nEncType = 0x10001; |
| *pTableStrmTemp << nEncType; |
| |
| sal_uInt8 pDocId[16]; |
| aCtx.GetDocId( pDocId ); |
| |
| sal_uInt8 pSaltData[16]; |
| sal_uInt8 pSaltDigest[16]; |
| aCtx.GetEncryptKey( pDocId, pSaltData, pSaltDigest ); |
| |
| pTableStrmTemp->Write( pDocId, 16 ); |
| pTableStrmTemp->Write( pSaltData, 16 ); |
| pTableStrmTemp->Write( pSaltDigest, 16 ); |
| |
| EncryptRC4(aCtx, GetWriter().Strm(), *pStrmTemp); |
| |
| // Write Unencrypted Fib 68 bytes to the start of the workdocument stream |
| pFib->fEncrypted = 1; // fEncrypted indicates the document is encrypted. |
| pFib->fObfuscated = 0; // Must be 0 for RC4. |
| pFib->nHash = 0x34; // encrypt header bytes count of table stream. |
| pFib->nKey = 0; // lkey2 must be 0 for RC4. |
| |
| pStrmTemp->Seek( 0 ); |
| pFib->WriteHeader( *pStrmTemp ); |
| } |
| |
| if (pUsedNumTbl) // all used NumRules |
| { |
| // clear the part of the list array that was copied from the document |
| // - it's an auto delete array, so the rest of the array which are |
| // duplicated lists that were added during the export will be deleted. |
| pUsedNumTbl->Remove(0, pUsedNumTbl->Count()-nUniqueList); |
| delete pUsedNumTbl; |
| } |
| |
| DELETEZ( pGrf ); |
| DELETEZ( pMagicTable ); |
| DELETEZ( pFldFtn ); |
| DELETEZ( pFldTxtBxs ); |
| DELETEZ( pFldHFTxtBxs ); |
| DELETEZ( pFldAtn ); |
| DELETEZ( pFldEdn ); |
| DELETEZ( pFldHdFt ); |
| DELETEZ( pFldMain ); |
| DELETEZ( pStyles ); |
| DELETEZ( pO ); |
| DELETEZ( pChpPlc ); |
| DELETEZ( pPapPlc ); |
| DELETEZ( pSepx ); |
| |
| delete pRedlAuthors; |
| delete pSdrObjs; |
| delete pHFSdrObjs; |
| delete pTxtBxs; |
| delete pHFTxtBxs; |
| delete pAtn; |
| delete pEdn; |
| delete pFtn; |
| delete pBkmks; |
| delete pPiece; |
| delete pDop; |
| delete pFib; |
| GetWriter().SetStream( 0 ); |
| |
| |
| xWwStrm->SetBufferSize( 0 ); |
| if( bWrtWW8 ) |
| { |
| xTableStrm->SetBufferSize( 0 ); |
| xDataStrm->SetBufferSize( 0 ); |
| if( 0 == pDataStrm->Seek( STREAM_SEEK_TO_END )) |
| { |
| xDataStrm.Clear(); |
| pDataStrm = 0; |
| GetWriter().GetStorage().Remove(CREATE_CONST_ASC(SL::aData)); |
| } |
| } |
| } |
| |
| |
| void WW8Export::PrepareStorage() |
| { |
| sal_uLong nLen; |
| const sal_uInt8* pData; |
| const char* pName; |
| sal_uInt32 nId1; |
| |
| if (bWrtWW8) |
| { |
| static const char aUserName[] = "Microsoft Word-Document"; |
| static const sal_uInt8 aCompObj[] = |
| { |
| 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0x06, 0x09, 0x02, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x46, 0x18, 0x00, 0x00, 0x00, |
| 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, |
| 0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x2D, 0x44, |
| 0x6F, 0x6B, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x00, |
| 0x0A, 0x00, 0x00, 0x00, 0x4D, 0x53, 0x57, 0x6F, |
| 0x72, 0x64, 0x44, 0x6F, 0x63, 0x00, 0x10, 0x00, |
| 0x00, 0x00, 0x57, 0x6F, 0x72, 0x64, 0x2E, 0x44, |
| 0x6F, 0x63, 0x75, 0x6D, 0x65, 0x6E, 0x74, 0x2E, |
| 0x38, 0x00, 0xF4, 0x39, 0xB2, 0x71, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 0x00, 0x00 |
| }; |
| |
| pName = aUserName; |
| pData = aCompObj; |
| nLen = sizeof( aCompObj ); |
| nId1 = 0x00020906L; |
| } |
| else |
| { |
| static const char aUserName[] = "Microsoft Word 6.0 Document"; |
| static const sal_uInt8 aCompObj[] = |
| { |
| 0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, |
| 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x09, 0x02, 0x00, |
| 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x46, 0x1C, 0x00, 0x00, 0x00, |
| 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, |
| 0x74, 0x20, 0x57, 0x6F, 0x72, 0x64, 0x20, 0x36, |
| 0x2E, 0x30, 0x2D, 0x44, 0x6F, 0x6B, 0x75, 0x6D, |
| 0x65, 0x6E, 0x74, 0x00, 0x0A, 0x00, 0x00, 0x00, |
| 0x4D, 0x53, 0x57, 0x6F, 0x72, 0x64, 0x44, 0x6F, |
| 0x63, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x6F, |
| 0x72, 0x64, 0x2E, 0x44, 0x6F, 0x63, 0x75, 0x6D, |
| 0x65, 0x6E, 0x74, 0x2E, 0x36, 0x00, 0x00, 0x00, |
| 0x00, 0x00 |
| }; |
| |
| pName = aUserName; |
| pData = aCompObj; |
| nLen = sizeof( aCompObj ); |
| nId1 = 0x00020900L; |
| } |
| |
| SvGlobalName aGName( nId1, 0x0000, 0x0000, 0xc0, 0x00, 0x00, 0x00, |
| 0x00, 0x00, 0x00, 0x46 ); |
| GetWriter().GetStorage().SetClass( aGName, 0, String::CreateFromAscii( pName )); |
| SvStorageStreamRef xStor( GetWriter().GetStorage().OpenSotStream(sCompObj) ); |
| xStor->Write( pData, nLen ); |
| |
| SwDocShell* pDocShell = pDoc->GetDocShell (); |
| DBG_ASSERT(pDocShell, "no SwDocShell"); |
| |
| if (pDocShell) { |
| uno::Reference<document::XDocumentPropertiesSupplier> xDPS( |
| pDocShell->GetModel(), uno::UNO_QUERY_THROW); |
| uno::Reference<document::XDocumentProperties> xDocProps( |
| xDPS->getDocumentProperties()); |
| DBG_ASSERT(xDocProps.is(), "DocumentProperties is null"); |
| |
| if (xDocProps.is()) |
| { |
| if ( SvtFilterOptions::Get()->IsEnableWordPreview() ) |
| { |
| ::boost::shared_ptr<GDIMetaFile> pMetaFile = |
| pDocShell->GetPreviewMetaFile (sal_False); |
| uno::Sequence<sal_uInt8> metaFile( |
| sfx2::convertMetaFile(pMetaFile.get())); |
| sfx2::SaveOlePropertySet(xDocProps, &GetWriter().GetStorage(), &metaFile); |
| } |
| else |
| sfx2::SaveOlePropertySet( xDocProps, &GetWriter().GetStorage() ); |
| } |
| } |
| } |
| |
| sal_uLong SwWW8Writer::WriteStorage() |
| { |
| long nMaxNode = pDoc->GetNodes().Count(); |
| ::StartProgress( STR_STATSTR_W4WWRITE, 0, nMaxNode, pDoc->GetDocShell() ); |
| |
| // Tabelle am Doc.-Anfang beachten |
| { |
| SwTableNode * pTNd = pCurPam->GetNode()->FindTableNode(); |
| if( pTNd && bWriteAll ) |
| // mit dem TabellenNode anfangen !! |
| pCurPam->GetPoint()->nNode = *pTNd; |
| } |
| |
| // Do the actual export |
| { |
| WW8Export aExport( this, pDoc, pCurPam, pOrigPam, m_bWrtWW8 ); |
| m_pExport = &aExport; |
| aExport.ExportDocument( bWriteAll ); |
| m_pExport = NULL; |
| } |
| |
| ::EndProgress( pDoc->GetDocShell() ); |
| return 0; |
| } |
| |
| sal_uLong SwWW8Writer::WriteMedium( SfxMedium& ) |
| { |
| return WriteStorage(); |
| } |
| |
| sal_uLong SwWW8Writer::Write( SwPaM& rPaM, SfxMedium& rMed, |
| const String* pFileName ) |
| { |
| mpMedium = &rMed; |
| sal_uLong nRet = StgWriter::Write( rPaM, rMed, pFileName ); |
| mpMedium = NULL; |
| return nRet; |
| } |
| |
| MSWordExportBase::MSWordExportBase( SwDoc *pDocument, SwPaM *pCurrentPam, SwPaM *pOriginalPam ) |
| : aMainStg(sMainStream), pISet(0), pUsedNumTbl(0), mpTopNodeOfHdFtPage(0), |
| pBmpPal(0), pOLEExp(0), pOCXExp(0), pOleMap(0), |
| mpTableInfo(new ww8::WW8TableInfo()), nUniqueList(0), |
| mnHdFtIndex(0), pAktPageDesc(0), pPapPlc(0), pChpPlc(0), pChpIter(0), |
| pStyles( NULL ), |
| bHasHdr(false), bHasFtr(false), bSubstituteBullets(true), |
| mbExportModeRTF( false ), |
| mbOutOutlineOnly( false ), |
| pDoc( pDocument ), |
| pCurPam( pCurrentPam ), |
| pOrigPam( pOriginalPam ) |
| { |
| } |
| |
| MSWordExportBase::~MSWordExportBase() |
| { |
| delete pBmpPal; |
| delete pOLEExp; |
| delete pOCXExp; |
| delete pOleMap; |
| } |
| |
| WW8Export::WW8Export( |
| SwWW8Writer *pWriter, |
| SwDoc *pDocument, |
| SwPaM *pCurrentPam, |
| SwPaM *pOriginalPam, |
| bool bIsWW8 ) |
| : MSWordExportBase( pDocument, pCurrentPam, pOriginalPam ), |
| pO( NULL ), |
| mpTableAt( NULL ), |
| mnTableStdAtLen( 0 ), |
| pSepx( NULL ), |
| bWrtWW8( bIsWW8 ), |
| m_pWriter( pWriter ), |
| m_pAttrOutput( new WW8AttributeOutput( *this ) ) |
| { |
| } |
| |
| WW8Export::~WW8Export() |
| { |
| delete m_pAttrOutput, m_pAttrOutput = NULL; |
| } |
| |
| AttributeOutputBase& WW8Export::AttrOutput() const |
| { |
| return *m_pAttrOutput; |
| } |
| |
| MSWordSections& WW8Export::Sections() const |
| { |
| return *pSepx; |
| } |
| |
| SwWW8Writer::SwWW8Writer(const String& rFltName, const String& rBaseURL) |
| : StgWriter(), |
| m_bWrtWW8( rFltName.EqualsAscii( FILTER_WW8 ) ), |
| m_pExport( NULL ), |
| mpMedium( 0 ) |
| { |
| SetBaseURL( rBaseURL ); |
| } |
| |
| SwWW8Writer::~SwWW8Writer() |
| { |
| } |
| |
| extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL SaveOrDelMSVBAStorage_ww8( SfxObjectShell& rDoc, SotStorage& rStor, sal_Bool bSaveInto, const String& rStorageName ) |
| { |
| SvxImportMSVBasic aTmp( rDoc, rStor ); |
| return aTmp.SaveOrDelMSVBAStorage( bSaveInto, rStorageName ); |
| } |
| |
| extern "C" SAL_DLLPUBLIC_EXPORT void SAL_CALL ExportDOC( const String& rFltName, const String& rBaseURL, WriterRef& xRet ) |
| { |
| xRet = new SwWW8Writer( rFltName, rBaseURL ); |
| } |
| |
| |
| extern "C" SAL_DLLPUBLIC_EXPORT sal_uLong SAL_CALL GetSaveWarningOfMSVBAStorage_ww8( SfxObjectShell &rDocS ) |
| { |
| return SvxImportMSVBasic::GetSaveWarningOfMSVBAStorage( rDocS ); |
| } |
| |
| bool WW8_WrPlcFtnEdn::WriteTxt( WW8Export& rWrt ) |
| { |
| bool bRet = false; |
| if (TXT_FTN == nTyp) |
| { |
| bRet = WriteGenericTxt( rWrt, TXT_FTN, rWrt.pFib->ccpFtn ); |
| rWrt.pFldFtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ), |
| rWrt.pFib->ccpText ); |
| } |
| else |
| { |
| bRet = WriteGenericTxt( rWrt, TXT_EDN, rWrt.pFib->ccpEdn ); |
| rWrt.pFldEdn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ), |
| rWrt.pFib->ccpText + rWrt.pFib->ccpFtn |
| + rWrt.pFib->ccpHdr + rWrt.pFib->ccpAtn ); |
| } |
| return bRet; |
| } |
| |
| void WW8_WrPlcFtnEdn::WritePlc( WW8Export& rWrt ) const |
| { |
| if( TXT_FTN == nTyp ) |
| { |
| WriteGenericPlc( rWrt, TXT_FTN, rWrt.pFib->fcPlcffndTxt, |
| rWrt.pFib->lcbPlcffndTxt, rWrt.pFib->fcPlcffndRef, |
| rWrt.pFib->lcbPlcffndRef ); |
| } |
| else |
| { |
| WriteGenericPlc( rWrt, TXT_EDN, rWrt.pFib->fcPlcfendTxt, |
| rWrt.pFib->lcbPlcfendTxt, rWrt.pFib->fcPlcfendRef, |
| rWrt.pFib->lcbPlcfendRef ); |
| } |
| } |
| |
| |
| bool WW8_WrPlcAnnotations::WriteTxt( WW8Export& rWrt ) |
| { |
| bool bRet = WriteGenericTxt( rWrt, TXT_ATN, rWrt.pFib->ccpAtn ); |
| rWrt.pFldAtn->Finish( rWrt.Fc2Cp( rWrt.Strm().Tell() ), |
| rWrt.pFib->ccpText + rWrt.pFib->ccpFtn |
| + rWrt.pFib->ccpHdr ); |
| return bRet; |
| } |
| |
| void WW8_WrPlcAnnotations::WritePlc( WW8Export& rWrt ) const |
| { |
| WriteGenericPlc( rWrt, TXT_ATN, rWrt.pFib->fcPlcfandTxt, |
| rWrt.pFib->lcbPlcfandTxt, rWrt.pFib->fcPlcfandRef, |
| rWrt.pFib->lcbPlcfandRef ); |
| } |
| |
| void WW8_WrPlcTxtBoxes::WritePlc( WW8Export& rWrt ) const |
| { |
| if( TXT_TXTBOX == nTyp ) |
| { |
| WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcftxbxBkd, |
| rWrt.pFib->lcbPlcftxbxBkd, rWrt.pFib->fcPlcftxbxTxt, |
| rWrt.pFib->lcbPlcftxbxTxt ); |
| } |
| else |
| { |
| WriteGenericPlc( rWrt, nTyp, rWrt.pFib->fcPlcfHdrtxbxBkd, |
| rWrt.pFib->lcbPlcfHdrtxbxBkd, rWrt.pFib->fcPlcfHdrtxbxTxt, |
| rWrt.pFib->lcbPlcfHdrtxbxTxt ); |
| } |
| } |
| |
| void WW8Export::RestoreMacroCmds() |
| { |
| pFib->fcCmds = pTableStrm->Tell(); |
| |
| uno::Reference < embed::XStorage > xSrcRoot(pDoc->GetDocShell()->GetStorage()); |
| try |
| { |
| uno::Reference < io::XStream > xSrcStream = |
| xSrcRoot->openStreamElement( CREATE_CONST_ASC(SL::aMSMacroCmds), embed::ElementModes::READ ); |
| SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xSrcStream ); |
| |
| if ( pStream && SVSTREAM_OK == pStream->GetError()) |
| { |
| pStream->Seek(STREAM_SEEK_TO_END); |
| pFib->lcbCmds = pStream->Tell(); |
| pStream->Seek(0); |
| |
| sal_uInt8 *pBuffer = new sal_uInt8[pFib->lcbCmds]; |
| pStream->Read(pBuffer, pFib->lcbCmds); |
| pTableStrm->Write(pBuffer, pFib->lcbCmds); |
| delete[] pBuffer; |
| |
| } |
| |
| delete pStream; |
| } |
| catch ( uno::Exception& ) |
| { |
| } |
| |
| // set len to FIB |
| pFib->lcbCmds = pTableStrm->Tell() - pFib->fcCmds; |
| } |
| |
| void WW8SHDLong::Write( WW8Export& rExport ) |
| { |
| rExport.InsUInt32( m_cvFore ); |
| rExport.InsUInt32( m_cvBack ); |
| rExport.InsUInt16( m_ipat ); |
| } |
| |
| void WW8Export::WriteFormData( const ::sw::mark::IFieldmark& rFieldmark ) |
| { |
| ASSERT( bWrtWW8, "No 95 export yet" ); |
| if ( !bWrtWW8 ) |
| return; |
| |
| const ::sw::mark::IFieldmark* pFieldmark = &rFieldmark; |
| const ::sw::mark::ICheckboxFieldmark* pAsCheckbox = dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >( pFieldmark ); |
| |
| |
| ASSERT(rFieldmark.GetFieldname().equalsAscii( ODF_FORMTEXT ) || rFieldmark.GetFieldname().equalsAscii( ODF_FORMDROPDOWN ) || rFieldmark.GetFieldname().equalsAscii( ODF_FORMCHECKBOX ), "Unknown field type!!!"); |
| if ( ! ( rFieldmark.GetFieldname().equalsAscii( ODF_FORMTEXT ) || |
| rFieldmark.GetFieldname().equalsAscii( ODF_FORMDROPDOWN ) || |
| rFieldmark.GetFieldname().equalsAscii( ODF_FORMCHECKBOX ) ) ) |
| return; |
| |
| int type = 0; // TextFieldmark |
| if ( pAsCheckbox ) |
| type = 1; |
| if ( rFieldmark.GetFieldname().equalsAscii( ODF_FORMDROPDOWN ) ) |
| type=2; |
| |
| ::sw::mark::IFieldmark::parameter_map_t::const_iterator pNameParameter = rFieldmark.GetParameters()->find(::rtl::OUString::createFromAscii("name")); |
| ::rtl::OUString ffname; |
| if(pNameParameter != rFieldmark.GetParameters()->end()) |
| pNameParameter->second >>= ffname; |
| |
| sal_uLong nDataStt = pDataStrm->Tell(); |
| pChpPlc->AppendFkpEntry(Strm().Tell()); |
| |
| WriteChar(0x01); |
| static sal_uInt8 aArr1[] = |
| { |
| 0x03, 0x6a, 0,0,0,0, // sprmCPicLocation |
| |
| 0x06, 0x08, 0x01, // sprmCFData |
| 0x55, 0x08, 0x01, // sprmCFSpec |
| 0x02, 0x08, 0x01 // sprmCFFldVanish |
| }; |
| sal_uInt8* pDataAdr = aArr1 + 2; |
| Set_UInt32(pDataAdr, nDataStt); |
| |
| pChpPlc->AppendFkpEntry( Strm().Tell(), sizeof( aArr1 ), aArr1 ); |
| |
| sal_uInt8 aFldHeader[] = |
| { |
| 0xFF, 0xFF, 0xFF, 0xFF, // Unicode Marker... |
| 0, 0, 0, 0,// 0, 0, 0, 0 |
| }; |
| |
| aFldHeader[4] |= (type & 0x03); |
| sal_Int32 ffres = 0; // rFieldmark.GetFFRes(); |
| if ( pAsCheckbox && pAsCheckbox->IsChecked() ) |
| ffres = 1; |
| else if ( type == 2 ) |
| { |
| ::sw::mark::IFieldmark::parameter_map_t::const_iterator pResParameter = rFieldmark.GetParameters()->find(::rtl::OUString::createFromAscii(ODF_FORMDROPDOWN)); |
| if(pResParameter != rFieldmark.GetParameters()->end()) |
| pResParameter->second >>= ffres; |
| else |
| ffres = 0; |
| } |
| aFldHeader[4] |= ( (ffres<<2) & 0x7C ); |
| |
| std::vector< ::rtl::OUString > aListItems; |
| if (type==2) |
| { |
| aFldHeader[5] |= 0x80; // ffhaslistbox |
| const ::sw::mark::IFieldmark::parameter_map_t* const pParameters = rFieldmark.GetParameters(); |
| ::sw::mark::IFieldmark::parameter_map_t::const_iterator pListEntries = pParameters->find(::rtl::OUString::createFromAscii(ODF_FORMDROPDOWN_LISTENTRY)); |
| if(pListEntries != pParameters->end()) |
| { |
| uno::Sequence< ::rtl::OUString > vListEntries; |
| pListEntries->second >>= vListEntries; |
| copy(::comphelper::stl_begin(vListEntries), ::comphelper::stl_end(vListEntries), back_inserter(aListItems)); |
| } |
| } |
| |
| const ::rtl::OUString ffdeftext; |
| const ::rtl::OUString ffformat; |
| const ::rtl::OUString ffhelptext; |
| const ::rtl::OUString ffstattext; |
| const ::rtl::OUString ffentrymcr; |
| const ::rtl::OUString ffexitmcr; |
| |
| |
| const sal_uInt8 aFldData[] = |
| { |
| 0x44,0, // the start of "next" data |
| 0,0,0,0,0,0,0,0,0,0, // PIC-Structure! /10 |
| 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // | /16 |
| 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // | /16 |
| 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // | /16 |
| 0,0,0,0, // / /4 |
| }; |
| sal_uInt32 slen = sizeof(sal_uInt32) |
| + sizeof(aFldData) |
| + sizeof( aFldHeader ) |
| + 2*ffname.getLength() + 4 |
| + 2*ffdeftext.getLength() + 4 |
| + 2*ffformat.getLength() + 4 |
| + 2*ffhelptext.getLength() + 4 |
| + 2*ffstattext.getLength() + 4 |
| + 2*ffentrymcr.getLength() + 4 |
| + 2*ffexitmcr.getLength() + 4; |
| if ( type==2 ) { |
| slen += 2; // for 0xFF, 0xFF |
| slen += 4; // for num of list items |
| const int items = aListItems.size(); |
| for( int i = 0; i < items; i++ ) { |
| rtl::OUString item = aListItems[i]; |
| slen += 2 * item.getLength() + 2; |
| } |
| } |
| |
| *pDataStrm << slen; |
| |
| int len = sizeof( aFldData ); |
| OSL_ENSURE( len == 0x44-sizeof(sal_uInt32), "SwWW8Writer::WriteFormData(..) - wrong aFldData length" ); |
| pDataStrm->Write( aFldData, len ); |
| |
| len = sizeof( aFldHeader ); |
| OSL_ENSURE( len == 8, "SwWW8Writer::WriteFormData(..) - wrong aFldHeader length" ); |
| |
| pDataStrm->Write( aFldHeader, len ); |
| |
| SwWW8Writer::WriteString_xstz( *pDataStrm, ffname, true ); // Form field name |
| |
| if ( type == 0 ) |
| SwWW8Writer::WriteString_xstz( *pDataStrm, ffdeftext, true ); |
| else |
| pDataStrm->WriteNumber( (sal_uInt16)0 ); |
| |
| SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffformat ), true ); |
| SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffhelptext ), true ); |
| SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffstattext ), true ); |
| SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffentrymcr ), true ); |
| SwWW8Writer::WriteString_xstz( *pDataStrm, String( ffexitmcr ), true ); |
| if (type==2) { |
| *pDataStrm<<(sal_uInt16)0xFFFF; |
| const int items=aListItems.size(); |
| *pDataStrm<<(sal_uInt32)items; |
| for(int i=0;i<items;i++) { |
| rtl::OUString item=aListItems[i]; |
| SwWW8Writer::WriteString_xstz( *pDataStrm, item, false ); |
| } |
| } |
| } |
| |
| void WW8Export::WriteHyperlinkData( const sw::mark::IFieldmark& /*rFieldmark*/ ) |
| { |
| //@TODO implement me !!! |
| } |
| |
| void WW8AttributeOutput::TableNodeInfoInner( ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner ) |
| { |
| SVBT16 nStyle; |
| ShortToSVBT16( m_rWW8Export.nStyleBeforeFly, nStyle ); |
| |
| #ifdef DEBUG |
| ::std::clog << "<OutWW8_TableNodeInfoInner>" << pNodeInfoInner->toString(); |
| #endif |
| |
| m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren |
| |
| sal_uInt32 nShadowsBefore = pNodeInfoInner->getShadowsBefore(); |
| if (nShadowsBefore > 0) |
| { |
| ww8::WW8TableNodeInfoInner::Pointer_t |
| pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL)); |
| |
| pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth()); |
| pTmpNodeInfoInner->setEndOfCell(true); |
| |
| for (sal_uInt32 n = 0; n < nShadowsBefore; ++n) |
| { |
| m_rWW8Export.WriteCR(pTmpNodeInfoInner); |
| |
| m_rWW8Export.pO->Insert( (sal_uInt8*)&nStyle, 2, |
| m_rWW8Export.pO->Count() ); // Style # |
| TableInfoCell(pTmpNodeInfoInner); |
| m_rWW8Export.pPapPlc->AppendFkpEntry |
| ( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), |
| m_rWW8Export.pO->GetData() ); |
| |
| m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren |
| } |
| } |
| |
| if (pNodeInfoInner->isEndOfCell()) |
| { |
| #ifdef DEBUG |
| ::std::clog << "<endOfCell/>" << ::std::endl; |
| #endif |
| m_rWW8Export.WriteCR(pNodeInfoInner); |
| |
| m_rWW8Export.pO->Insert( (sal_uInt8*)&nStyle, 2, m_rWW8Export.pO->Count() ); // Style # |
| TableInfoCell(pNodeInfoInner); |
| m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), |
| m_rWW8Export.pO->GetData() ); |
| |
| m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren |
| } |
| |
| sal_uInt32 nShadowsAfter = pNodeInfoInner->getShadowsAfter(); |
| if (nShadowsAfter > 0) |
| { |
| ww8::WW8TableNodeInfoInner::Pointer_t |
| pTmpNodeInfoInner(new ww8::WW8TableNodeInfoInner(NULL)); |
| |
| pTmpNodeInfoInner->setDepth(pNodeInfoInner->getDepth()); |
| pTmpNodeInfoInner->setEndOfCell(true); |
| |
| for (sal_uInt32 n = 0; n < nShadowsAfter; ++n) |
| { |
| m_rWW8Export.WriteCR(pTmpNodeInfoInner); |
| |
| m_rWW8Export.pO->Insert( (sal_uInt8*)&nStyle, 2, m_rWW8Export.pO->Count() ); // Style # |
| TableInfoCell(pTmpNodeInfoInner); |
| m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), |
| m_rWW8Export.pO->GetData() ); |
| |
| m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren |
| } |
| } |
| |
| if (pNodeInfoInner->isEndOfLine()) |
| { |
| #ifdef DEBUG |
| ::std::clog << "<endOfLine/>" << ::std::endl; |
| #endif |
| TableRowEnd(pNodeInfoInner->getDepth()); |
| |
| ShortToSVBT16(0, nStyle); |
| m_rWW8Export.pO->Insert( (sal_uInt8*)&nStyle, 2, m_rWW8Export.pO->Count() ); // Style # |
| TableInfoRow(pNodeInfoInner); |
| m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), |
| m_rWW8Export.pO->GetData() ); |
| |
| m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() ); // leeren |
| } |
| #ifdef DEBUG |
| ::std::clog << "</OutWW8_TableNodeInfoInner>" << ::std::endl; |
| #endif |
| } |
| |
| void MSWordExportBase::OutputStartNode( const SwStartNode & rNode) |
| { |
| #if 0 |
| #ifdef DEBUG |
| ::std::clog << "<OutWW8_SwStartNode>" << dbg_out(&rNode) << ::std::endl; |
| #endif |
| #endif |
| |
| ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = |
| mpTableInfo->getTableNodeInfo( &rNode ); |
| |
| if (pNodeInfo.get() != NULL) |
| { |
| #ifdef DEBUG |
| ::std::clog << pNodeInfo->toString() << ::std::endl; |
| #endif |
| |
| const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners(); |
| ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aIt(aInners.rbegin()); |
| ww8::WW8TableNodeInfo::Inners_t::const_reverse_iterator aEnd(aInners.rend()); |
| while (aIt != aEnd) |
| { |
| ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second; |
| |
| AttrOutput().TableNodeInfoInner(pInner); |
| aIt++; |
| } |
| } |
| #ifdef DEBUG |
| ::std::clog << "</OutWW8_SwStartNode>" << ::std::endl; |
| #endif |
| } |
| |
| void MSWordExportBase::OutputEndNode( const SwEndNode &rNode ) |
| { |
| #ifdef DEBUG |
| // whoever has need of the missing function should go and implement it! |
| // This piece of code always breaks builds... |
| // ::std::clog << "<OutWW8_SwEndNode>" << dbg_out(&rNode) << ::std::endl; |
| #endif |
| |
| ww8::WW8TableNodeInfo::Pointer_t pNodeInfo = mpTableInfo->getTableNodeInfo( &rNode ); |
| |
| if (pNodeInfo.get() != NULL) |
| { |
| #ifdef DEBUG |
| ::std::clog << pNodeInfo->toString() << ::std::endl; |
| #endif |
| |
| const ww8::WW8TableNodeInfo::Inners_t aInners = pNodeInfo->getInners(); |
| ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt(aInners.begin()); |
| ww8::WW8TableNodeInfo::Inners_t::const_iterator aEnd(aInners.end()); |
| while (aIt != aEnd) |
| { |
| ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second; |
| AttrOutput().TableNodeInfoInner(pInner); |
| aIt++; |
| } |
| } |
| #ifdef DEBUG |
| ::std::clog << "</OutWW8_SwEndNode>" << ::std::endl; |
| #endif |
| } |
| |
| const NfKeywordTable & MSWordExportBase::GetNfKeywordTable() |
| { |
| if (pKeyMap.get() == NULL) |
| { |
| pKeyMap.reset(new NfKeywordTable); |
| NfKeywordTable & rKeywordTable = *pKeyMap; |
| rKeywordTable[NF_KEY_D] = ::rtl::OUString::createFromAscii("d"); |
| rKeywordTable[NF_KEY_DD] = ::rtl::OUString::createFromAscii("dd"); |
| rKeywordTable[NF_KEY_DDD] = ::rtl::OUString::createFromAscii("ddd"); |
| rKeywordTable[NF_KEY_DDDD] = ::rtl::OUString::createFromAscii("dddd"); |
| rKeywordTable[NF_KEY_M] = ::rtl::OUString::createFromAscii("M"); |
| rKeywordTable[NF_KEY_MM] = ::rtl::OUString::createFromAscii("MM"); |
| rKeywordTable[NF_KEY_MMM] = ::rtl::OUString::createFromAscii("MMM"); |
| rKeywordTable[NF_KEY_MMMM] = ::rtl::OUString::createFromAscii("MMMM"); |
| rKeywordTable[NF_KEY_NN] = ::rtl::OUString::createFromAscii("ddd"); |
| rKeywordTable[NF_KEY_NNN] = ::rtl::OUString::createFromAscii("dddd"); |
| rKeywordTable[NF_KEY_NNNN] = ::rtl::OUString::createFromAscii("dddd"); |
| rKeywordTable[NF_KEY_YY] = ::rtl::OUString::createFromAscii("yy"); |
| rKeywordTable[NF_KEY_YYYY] = ::rtl::OUString::createFromAscii("yyyy"); |
| rKeywordTable[NF_KEY_H] = ::rtl::OUString::createFromAscii("H"); |
| rKeywordTable[NF_KEY_HH] = ::rtl::OUString::createFromAscii("HH"); |
| rKeywordTable[NF_KEY_MI] = ::rtl::OUString::createFromAscii("m"); |
| rKeywordTable[NF_KEY_MMI] = ::rtl::OUString::createFromAscii("mm"); |
| rKeywordTable[NF_KEY_S] = ::rtl::OUString::createFromAscii("s"); |
| rKeywordTable[NF_KEY_SS] = ::rtl::OUString::createFromAscii("ss"); |
| rKeywordTable[NF_KEY_AMPM] = ::rtl::OUString::createFromAscii("AM/PM"); |
| } |
| |
| return *pKeyMap; |
| } |
| |
| /* vi:set tabstop=4 shiftwidth=4 expandtab: */ |