| /************************************************************** |
| * |
| * 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 <tools/urlobj.hxx> |
| #include <svl/urihelper.hxx> |
| #include <rtl/tencinfo.h> |
| #include <swerror.h> |
| #include <ndtxt.hxx> |
| #include <pam.hxx> |
| #include <shellio.hxx> |
| #include <docsh.hxx> |
| #include <fmtanchr.hxx> |
| #include <frmfmt.hxx> |
| #include <doc.hxx> |
| #include <docary.hxx> |
| #include "ww8glsy.hxx" |
| #include "ww8par.hxx" |
| |
| |
| WW8Glossary::WW8Glossary(SvStorageStreamRef &refStrm, sal_uInt8 nVersion, |
| SvStorage *pStg) |
| : pGlossary(0), rStrm(refStrm), xStg(pStg), nStrings(0) |
| { |
| refStrm->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); |
| WW8Fib aWwFib(*refStrm, nVersion); |
| |
| if (aWwFib.nFibBack >= 0x6A) //Word97 |
| { |
| xTableStream = pStg->OpenSotStream(String::CreateFromAscii( |
| aWwFib.fWhichTblStm ? SL::a1Table : SL::a0Table), STREAM_STD_READ); |
| |
| if (xTableStream.Is() && SVSTREAM_OK == xTableStream->GetError()) |
| { |
| xTableStream->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN); |
| pGlossary = |
| new WW8GlossaryFib(*refStrm, nVersion, *xTableStream, aWwFib); |
| } |
| } |
| } |
| |
| bool WW8Glossary::HasBareGraphicEnd(SwDoc *pDoc,SwNodeIndex &rIdx) |
| { |
| bool bRet=false; |
| for( sal_uInt16 nCnt = pDoc->GetSpzFrmFmts()->Count(); nCnt; ) |
| { |
| SwFrmFmt* pFrmFmt = (*pDoc->GetSpzFrmFmts())[ --nCnt ]; |
| if ( RES_FLYFRMFMT != pFrmFmt->Which() && |
| RES_DRAWFRMFMT != pFrmFmt->Which() ) |
| continue; |
| const SwFmtAnchor& rAnchor = pFrmFmt->GetAnchor(); |
| SwPosition const*const pAPos = rAnchor.GetCntntAnchor(); |
| if (pAPos && |
| ((FLY_AT_PARA == rAnchor.GetAnchorId()) || |
| (FLY_AT_CHAR == rAnchor.GetAnchorId())) && |
| rIdx == pAPos->nNode.GetIndex() ) |
| { |
| bRet=true; |
| break; |
| } |
| } |
| return bRet; |
| } |
| |
| bool WW8Glossary::MakeEntries(SwDoc *pD, SwTextBlocks &rBlocks, |
| bool bSaveRelFile, const std::vector<String>& rStrings, |
| const std::vector<ww::bytes>& rExtra) |
| { |
| // this code will be called after reading all text into the |
| // empty sections |
| const String aOldURL( rBlocks.GetBaseURL() ); |
| bool bRet=false; |
| if( bSaveRelFile ) |
| { |
| rBlocks.SetBaseURL( |
| URIHelper::SmartRel2Abs( |
| INetURLObject(), rBlocks.GetFileName(), |
| URIHelper::GetMaybeFileHdl())); |
| } |
| else |
| rBlocks.SetBaseURL( aEmptyStr ); |
| |
| SwNodeIndex aDocEnd( pD->GetNodes().GetEndOfContent() ); |
| SwNodeIndex aStart( *aDocEnd.GetNode().StartOfSectionNode(), 1 ); |
| |
| // search the first NormalStartNode |
| while( !( aStart.GetNode().IsStartNode() && SwNormalStartNode == |
| aStart.GetNode().GetStartNode()->GetStartNodeType()) && |
| aStart < aDocEnd ) |
| aStart++; |
| |
| if( aStart < aDocEnd ) |
| { |
| SwTxtFmtColl* pColl = pD->GetTxtCollFromPool |
| (RES_POOLCOLL_STANDARD, false); |
| sal_uInt16 nGlosEntry = 0; |
| SwCntntNode* pCNd = 0; |
| do { |
| SwPaM aPam( aStart ); |
| { |
| SwNodeIndex& rIdx = aPam.GetPoint()->nNode; |
| rIdx++; |
| if( 0 == ( pCNd = rIdx.GetNode().GetTxtNode() ) ) |
| { |
| pCNd = pD->GetNodes().MakeTxtNode( rIdx, pColl ); |
| rIdx = *pCNd; |
| } |
| } |
| aPam.GetPoint()->nContent.Assign( pCNd, 0 ); |
| aPam.SetMark(); |
| { |
| SwNodeIndex& rIdx = aPam.GetPoint()->nNode; |
| rIdx = aStart.GetNode().EndOfSectionIndex() - 1; |
| if(( 0 == ( pCNd = rIdx.GetNode().GetCntntNode() ) ) |
| || HasBareGraphicEnd(pD,rIdx)) |
| { |
| rIdx++; |
| pCNd = pD->GetNodes().MakeTxtNode( rIdx, pColl ); |
| rIdx = *pCNd; |
| } |
| } |
| aPam.GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); |
| |
| // now we have the right selection for one entry. Copy this to |
| // the definied TextBlock, but only if it is not an autocorrection |
| // entry (== -1) otherwise the group indicates the group in the |
| // sttbfglsystyle list that this entry belongs to. Unused at the |
| // moment |
| const ww::bytes &rData = rExtra[nGlosEntry]; |
| sal_uInt16 n = SVBT16ToShort( &(rData[2]) ); |
| if(n != 0xFFFF) |
| { |
| rBlocks.ClearDoc(); |
| const String &rLNm = rStrings[nGlosEntry]; |
| |
| String sShortcut = rLNm; |
| |
| // Need to check make sure the shortcut is not already being used |
| xub_StrLen nStart = 0; |
| sal_uInt16 nCurPos = rBlocks.GetIndex( sShortcut ); |
| xub_StrLen nLen = sShortcut.Len(); |
| while( (sal_uInt16)-1 != nCurPos ) |
| { |
| sShortcut.Erase( nLen ) += |
| String::CreateFromInt32( ++nStart ); // add an Number to it |
| nCurPos = rBlocks.GetIndex( sShortcut ); |
| } |
| |
| if( rBlocks.BeginPutDoc( sShortcut, sShortcut )) // Make the shortcut and the name the same |
| |
| { |
| SwDoc* pGlDoc = rBlocks.GetDoc(); |
| SwNodeIndex aIdx( pGlDoc->GetNodes().GetEndOfContent(), |
| -1 ); |
| pCNd = aIdx.GetNode().GetCntntNode(); |
| SwPosition aPos( aIdx, SwIndex( pCNd, pCNd->Len() )); |
| pD->CopyRange( aPam, aPos, false ); |
| rBlocks.PutDoc(); |
| } |
| } |
| aStart = aStart.GetNode().EndOfSectionIndex() + 1; |
| ++nGlosEntry; |
| } while( aStart.GetNode().IsStartNode() && |
| SwNormalStartNode == aStart.GetNode(). |
| GetStartNode()->GetStartNodeType()); |
| bRet=true; |
| } |
| |
| // this code will be called after reading all text into the empty sections |
| |
| rBlocks.SetBaseURL( aOldURL ); |
| return bRet; |
| } |
| |
| |
| bool WW8Glossary::Load( SwTextBlocks &rBlocks, bool bSaveRelFile ) |
| { |
| bool bRet=false; |
| if (pGlossary && pGlossary->IsGlossaryFib() && rBlocks.StartPutMuchBlockEntries()) |
| { |
| //read the names of the autotext entries |
| std::vector<String> aStrings; |
| std::vector<ww::bytes> aData; |
| |
| rtl_TextEncoding eStructCharSet = |
| WW8Fib::GetFIBCharset(pGlossary->chseTables); |
| |
| WW8ReadSTTBF(true, *xTableStream, pGlossary->fcSttbfglsy, |
| pGlossary->lcbSttbfglsy, 0, eStructCharSet, aStrings, &aData ); |
| |
| rStrm->Seek(0); |
| |
| if ( 0 != (nStrings = static_cast< sal_uInt16 >(aStrings.size()))) |
| { |
| SfxObjectShellLock xDocSh(new SwDocShell(SFX_CREATE_MODE_INTERNAL)); |
| if (xDocSh->DoInitNew(0)) |
| { |
| SwDoc *pD = ((SwDocShell*)(&xDocSh))->GetDoc(); |
| SwWW8ImplReader* pRdr = new SwWW8ImplReader(pGlossary->nVersion, |
| xStg, &rStrm, *pD, rBlocks.GetBaseURL(), true); |
| |
| SwNodeIndex aIdx( |
| *pD->GetNodes().GetEndOfContent().StartOfSectionNode(), 1); |
| if( !aIdx.GetNode().IsTxtNode() ) |
| { |
| ASSERT( !this, "wo ist der TextNode?" ); |
| pD->GetNodes().GoNext( &aIdx ); |
| } |
| SwPaM aPamo( aIdx ); |
| aPamo.GetPoint()->nContent.Assign(aIdx.GetNode().GetCntntNode(), |
| 0); |
| pRdr->LoadDoc(aPamo,this); |
| |
| bRet = MakeEntries(pD, rBlocks, bSaveRelFile, aStrings, aData); |
| |
| delete pRdr; |
| } |
| xDocSh->DoClose(); |
| rBlocks.EndPutMuchBlockEntries(); |
| } |
| } |
| return bRet; |
| } |
| |
| |
| bool WW8GlossaryFib::IsGlossaryFib() |
| { |
| // fGlsy will indicate whether this has AutoText or not |
| return fGlsy; |
| } |
| |
| sal_uInt32 WW8GlossaryFib::FindGlossaryFibOffset(SvStream & /* rTableStrm */, |
| SvStream & /* rStrm */, |
| const WW8Fib &rFib) |
| { |
| sal_uInt32 nGlossaryFibOffset = 0; |
| if ( rFib.fDot ) // its a template |
| { |
| if ( rFib.pnNext ) |
| nGlossaryFibOffset = ( rFib.pnNext * 512 ); |
| } |
| return nGlossaryFibOffset; |
| } |
| |
| /* vi:set tabstop=4 shiftwidth=4 expandtab: */ |