| /************************************************************** |
| * |
| * 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 <hintids.hxx> |
| |
| #include <stack> |
| |
| #include <tools/errinf.hxx> |
| #include <tools/stream.hxx> |
| #include <svl/itemiter.hxx> |
| #include <svtools/rtftoken.h> |
| #include <svl/intitem.hxx> |
| #include <editeng/fhgtitem.hxx> |
| #include <editeng/ulspitem.hxx> |
| #include <editeng/tstpitem.hxx> |
| #include <editeng/lspcitem.hxx> |
| #include <editeng/lrspitem.hxx> |
| #include <editeng/escpitem.hxx> |
| #include <editeng/fontitem.hxx> |
| #include <editeng/frmdiritem.hxx> |
| #include <editeng/hyznitem.hxx> |
| #include <fmtpdsc.hxx> |
| #include <fmtfld.hxx> |
| #include <fmthdft.hxx> |
| #include <fmtcntnt.hxx> |
| #include <txtftn.hxx> |
| #include <fmtclds.hxx> |
| #include <fmtftn.hxx> |
| #include <fmtfsize.hxx> |
| #include <fmtflcnt.hxx> |
| #include <fmtanchr.hxx> |
| #include <frmatr.hxx> |
| #include <docstat.hxx> |
| #include <swtable.hxx> |
| #include <shellio.hxx> |
| #include <swtypes.hxx> |
| #include <ndtxt.hxx> |
| #include <doc.hxx> |
| #include <docary.hxx> |
| #include <pam.hxx> |
| #include <mdiexp.hxx> // ...Percent() |
| #include <swparrtf.hxx> |
| #include <charfmt.hxx> |
| #include <pagedesc.hxx> |
| #include <ftninfo.hxx> |
| #include <docufld.hxx> |
| #include <flddat.hxx> |
| #include <fltini.hxx> |
| #include <fchrfmt.hxx> |
| #include <paratr.hxx> |
| #include <section.hxx> |
| #include <fmtclbl.hxx> |
| #include <viewsh.hxx> |
| #include <shellres.hxx> |
| #include <hfspacingitem.hxx> |
| #include <tox.hxx> |
| #include <swerror.h> |
| #include <cmdid.h> |
| #include <statstr.hrc> // ResId fuer Statusleiste |
| #include <SwStyleNameMapper.hxx> |
| #include <tblsel.hxx> // SwSelBoxes |
| |
| #include <docsh.hxx> |
| #include <fmtlsplt.hxx> // SwLayoutSplit |
| #include <editeng/keepitem.hxx> |
| #include <svx/svdopath.hxx> |
| #include <svx/svdorect.hxx> |
| |
| |
| #include <fmtsrnd.hxx> |
| #include <fmtfollowtextflow.hxx> |
| #include <svx/svdmodel.hxx> |
| #include <svx/svdpage.hxx> |
| #include <editeng/opaqitem.hxx> |
| #include "svx/svdograf.hxx" |
| #include <svx/xflclit.hxx> |
| #include <svx/xlnwtit.hxx> |
| #include <svx/svdoutl.hxx> |
| #include <editeng/outlobj.hxx> |
| #include <editeng/paperinf.hxx> |
| |
| #include <tools/stream.hxx> |
| #include <basegfx/polygon/b2dpolygon.hxx> |
| #include <basegfx/polygon/b2dpolypolygon.hxx> |
| #include <basegfx/range/b2drange.hxx> |
| #include <vcl/salbtype.hxx> // FRound |
| |
| #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> |
| |
| |
| using namespace ::com::sun::star; |
| |
| |
| // einige Hilfs-Funktionen |
| // char |
| inline const SvxFontHeightItem& GetSize(const SfxItemSet& rSet,sal_Bool bInP=sal_True) |
| { return (const SvxFontHeightItem&)rSet.Get( RES_CHRATR_FONTSIZE,bInP); } |
| inline const SvxLRSpaceItem& GetLRSpace(const SfxItemSet& rSet,sal_Bool bInP=sal_True) |
| { return (const SvxLRSpaceItem&)rSet.Get( RES_LR_SPACE,bInP); } |
| |
| /* */ |
| |
| extern "C" SAL_DLLPUBLIC_EXPORT Reader* SAL_CALL ImportRTF() |
| { |
| return new RtfReader(); |
| } |
| |
| // Aufruf fuer die allg. Reader-Schnittstelle |
| sal_uLong RtfReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String &) |
| { |
| if( !pStrm ) |
| { |
| ASSERT( sal_False, "RTF-Read ohne Stream" ); |
| return ERR_SWG_READ_ERROR; |
| } |
| |
| //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne |
| // Kapitelnummer. Darum hier explizit abschalten |
| // weil das Default jetzt wieder auf AN ist. |
| if( !bInsertMode ) |
| { |
| Reader::SetNoOutlineNum( rDoc ); |
| |
| // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf. |
| Reader::ResetFrmFmts( rDoc ); |
| } |
| |
| sal_uLong nRet = 0; |
| SwDocShell *pDocShell(rDoc.GetDocShell()); |
| DBG_ASSERT(pDocShell, "no SwDocShell"); |
| uno::Reference<document::XDocumentProperties> xDocProps; |
| if (pDocShell) { |
| uno::Reference<document::XDocumentPropertiesSupplier> xDPS( |
| pDocShell->GetModel(), uno::UNO_QUERY_THROW); |
| xDocProps.set(xDPS->getDocumentProperties()); |
| } |
| |
| SvParserRef xParser = new SwRTFParser( &rDoc, xDocProps, |
| rPam, *pStrm, rBaseURL, !bInsertMode ); |
| SvParserState eState = xParser->CallParser(); |
| if( SVPAR_PENDING != eState && SVPAR_ACCEPTED != eState ) |
| { |
| String sErr( String::CreateFromInt32( xParser->GetLineNr() )); |
| sErr += ','; |
| sErr += String::CreateFromInt32( xParser->GetLinePos() ); |
| |
| nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr, |
| ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); |
| } |
| |
| |
| return nRet; |
| } |
| |
| sal_uLong RtfReader::Read(SvStream* pStream, SwDoc& rDoc, const String& rBaseURL, SwPaM& rPam) |
| { |
| pStrm = pStream; |
| return Read(rDoc, rBaseURL, rPam, rBaseURL); |
| } |
| |
| SwRTFParser::SwRTFParser(SwDoc* pD, |
| uno::Reference<document::XDocumentProperties> i_xDocProps, |
| const SwPaM& rCrsr, SvStream& rIn, const String& rBaseURL, |
| int bReadNewDoc) : |
| SvxRTFParser(pD->GetAttrPool(), rIn, i_xDocProps, bReadNewDoc), |
| maParaStyleMapper(*pD), |
| maCharStyleMapper(*pD), |
| maSegments(*this), |
| maInsertedTables(*pD), |
| mpBookmarkStart(0), |
| mpRedlineStack(0), |
| pAuthorInfos(0), |
| pGrfAttrSet(0), |
| pTableNode(0), |
| pOldTblNd(0), |
| pSttNdIdx(0), |
| pRegionEndIdx(0), |
| pDoc(pD), |
| pRelNumRule(new SwRelNumRuleSpaces(*pD, static_cast< sal_Bool >(bReadNewDoc))), |
| pRedlineInsert(0), |
| pRedlineDelete(0), |
| sBaseURL( rBaseURL ), |
| nAktPageDesc(0), |
| nAktFirstPageDesc(0), |
| m_nCurrentBox(0), |
| nInsTblRow(USHRT_MAX), |
| nNewNumSectDef(USHRT_MAX), |
| nRowsToRepeat(0), |
| // --> OD 2008-12-22 #i83368# |
| mbReadCellWhileReadSwFly( false ), |
| // <-- |
| bTrowdRead(0), |
| nReadFlyDepth(0), |
| nZOrder(0) |
| { |
| mbIsFootnote = mbReadNoTbl = bReadSwFly = bSwPageDesc = bStyleTabValid = |
| bInPgDscTbl = bNewNumList = false; |
| bFirstContinue = true; |
| bContainsPara = false; |
| bContainsTablePara = false; |
| bNestedField = false; |
| bForceNewTable = false; |
| |
| pPam = new SwPaM( *rCrsr.GetPoint() ); |
| SetInsPos( SwxPosition( pPam ) ); |
| SetChkStyleAttr( 0 != bReadNewDoc ); |
| SetCalcValue( sal_False ); |
| SetReadDocInfo( sal_True ); |
| |
| // diese sollen zusaetzlich ueber \pard zurueck gesetzt werden |
| sal_uInt16 temp; |
| temp = RES_TXTATR_CHARFMT; AddPlainAttr( temp ); |
| temp = RES_PAGEDESC; AddPardAttr( temp ); |
| temp = RES_BREAK; AddPardAttr( temp ); |
| temp = RES_PARATR_NUMRULE; AddPardAttr( temp ); |
| temp = FN_PARAM_NUM_LEVEL; AddPardAttr( temp ); |
| } |
| |
| // Aufruf des Parsers |
| SvParserState SwRTFParser::CallParser() |
| { |
| mbReadNoTbl = false; |
| bFirstContinue = true; |
| |
| rInput.Seek(STREAM_SEEK_TO_BEGIN); |
| rInput.ResetError(); |
| |
| mpRedlineStack = new sw::util::RedlineStack(*pDoc); |
| |
| return SvxRTFParser::CallParser(); |
| } |
| |
| bool lcl_UsedPara(SwPaM &rPam) |
| { |
| const SwCntntNode* pCNd; |
| const SfxItemSet* pSet; |
| if( rPam.GetPoint()->nContent.GetIndex() || |
| ( 0 != ( pCNd = rPam.GetCntntNode()) && |
| 0 != ( pSet = pCNd->GetpSwAttrSet()) && |
| ( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False ) || |
| SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, sal_False )))) |
| return true; |
| return false; |
| } |
| |
| void SwRTFParser::Continue( int nToken ) |
| { |
| if( bFirstContinue ) |
| { |
| bFirstContinue = sal_False; |
| |
| if (IsNewDoc()) |
| { |
| // |
| // COMPATIBILITY FLAGS START |
| // |
| pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX, true); |
| pDoc->set(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES, true); |
| pDoc->set(IDocumentSettingAccess::TAB_COMPAT, true); |
| pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, true); |
| pDoc->set(IDocumentSettingAccess::USE_HIRES_VIRTUAL_DEVICE, true); |
| pDoc->set(IDocumentSettingAccess::ADD_FLY_OFFSETS, true); |
| pDoc->set(IDocumentSettingAccess::ADD_EXT_LEADING, true); |
| pDoc->set(IDocumentSettingAccess::OLD_NUMBERING, false); |
| pDoc->set(IDocumentSettingAccess::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING, false ); |
| pDoc->set(IDocumentSettingAccess::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK, false); |
| pDoc->set(IDocumentSettingAccess::OLD_LINE_SPACING, false); |
| pDoc->set(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS, true); |
| pDoc->set(IDocumentSettingAccess::USE_FORMER_OBJECT_POS, false); |
| pDoc->set(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING, false); |
| pDoc->set(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION, true); |
| pDoc->set(IDocumentSettingAccess::DO_NOT_RESET_PARA_ATTRS_FOR_NUM_FONT, false); // --> FME 2005-08-11 #i53199# |
| // --> FME 2006-02-10 #131283# |
| pDoc->set(IDocumentSettingAccess::TABLE_ROW_KEEP, true); |
| pDoc->set(IDocumentSettingAccess::IGNORE_TABS_AND_BLANKS_FOR_LINE_CALCULATION, true); |
| |
| // |
| // COMPATIBILITY FLAGS END |
| // |
| } |
| |
| // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt! |
| pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() ); |
| if( !IsNewDoc() ) // in ein Dokument einfuegen ? |
| { |
| const SwPosition* pPos = pPam->GetPoint(); |
| SwTxtNode* pSttNd = pPos->nNode.GetNode().GetTxtNode(); |
| |
| pDoc->SplitNode( *pPos, false ); |
| |
| *pSttNdIdx = pPos->nNode.GetIndex()-1; |
| pDoc->SplitNode( *pPos, false ); |
| |
| SwPaM aInsertionRangePam( *pPos ); |
| |
| pPam->Move( fnMoveBackward ); |
| |
| // #106634# split any redline over the insertion point |
| aInsertionRangePam.SetMark(); |
| *aInsertionRangePam.GetPoint() = *pPam->GetPoint(); |
| aInsertionRangePam.Move( fnMoveBackward ); |
| pDoc->SplitRedline( aInsertionRangePam ); |
| |
| pDoc->SetTxtFmtColl( *pPam, pDoc->GetTxtCollFromPool |
| ( RES_POOLCOLL_STANDARD, false )); |
| |
| // verhinder das einlesen von Tabellen in Fussnoten / Tabellen |
| sal_uLong nNd = pPos->nNode.GetIndex(); |
| mbReadNoTbl = 0 != pSttNd->FindTableNode() || |
| ( nNd < pDoc->GetNodes().GetEndOfInserts().GetIndex() && |
| pDoc->GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd ); |
| } |
| |
| // Laufbalken anzeigen, aber nur bei synchronem Call |
| sal_uLong nCurrPos = rInput.Tell(); |
| rInput.Seek(STREAM_SEEK_TO_END); |
| rInput.ResetError(); |
| ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(), pDoc->GetDocShell()); |
| rInput.Seek( nCurrPos ); |
| rInput.ResetError(); |
| } |
| |
| SvxRTFParser::Continue( nToken ); |
| |
| if( SVPAR_PENDING == GetStatus() ) |
| return ; // weiter gehts beim naechsten mal |
| |
| pRelNumRule->SetNumRelSpaces( *pDoc ); |
| |
| // den Start wieder korrigieren |
| if( !IsNewDoc() && pSttNdIdx->GetIndex() ) |
| { |
| //die Flys muessen zuerst zurecht gerueckt werden, denn sonst wird |
| // ein am 1. Absatz verankerter Fly falsch eingefuegt |
| if( SVPAR_ACCEPTED == eState ) |
| { |
| if( aFlyArr.Count() ) |
| SetFlysInDoc(); |
| pRelNumRule->SetOultineRelSpaces( *pSttNdIdx, pPam->GetPoint()->nNode ); |
| } |
| |
| SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode(); |
| SwNodeIndex aNxtIdx( *pSttNdIdx ); |
| if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx )) |
| { |
| xub_StrLen nStt = pTxtNode->GetTxt().Len(); |
| // wenn der Cursor noch in dem Node steht, dann setze in an das Ende |
| if( pPam->GetPoint()->nNode == aNxtIdx ) |
| { |
| pPam->GetPoint()->nNode = *pSttNdIdx; |
| pPam->GetPoint()->nContent.Assign( pTxtNode, nStt ); |
| } |
| |
| #ifdef DBG_UTIL |
| // !!! sollte nicht moeglich sein, oder ?? |
| ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_True ).nNode.GetIndex(), |
| "Pam.Bound1 steht noch im Node" ); |
| ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_False ).nNode.GetIndex(), |
| "Pam.Bound2 steht noch im Node" ); |
| |
| if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_True ).nNode.GetIndex() ) |
| { |
| xub_StrLen nCntPos = pPam->GetBound( sal_True ).nContent.GetIndex(); |
| pPam->GetBound( sal_True ).nContent.Assign( pTxtNode, |
| pTxtNode->GetTxt().Len() + nCntPos ); |
| } |
| if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_False ).nNode.GetIndex() ) |
| { |
| xub_StrLen nCntPos = pPam->GetBound( sal_False ).nContent.GetIndex(); |
| pPam->GetBound( sal_False ).nContent.Assign( pTxtNode, |
| pTxtNode->GetTxt().Len() + nCntPos ); |
| } |
| #endif |
| // Zeichen Attribute beibehalten! |
| SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode(); |
| if( pTxtNode->GetTxt().Len() ) |
| pDelNd->FmtToTxtAttr( pTxtNode ); |
| else |
| pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() ); |
| pTxtNode->JoinNext(); |
| } |
| } |
| |
| if( SVPAR_ACCEPTED == eState ) |
| { |
| // den letzen Bereich wieder zumachen |
| if( pRegionEndIdx ) |
| { |
| // JP 06.01.00: Task 71411 - the last section in WW are not a |
| // balanced Section. |
| if( !GetVersionNo() ) |
| { |
| SwSectionNode* pSectNd = pRegionEndIdx->GetNode(). |
| StartOfSectionNode()->GetSectionNode(); |
| if( pSectNd ) |
| pSectNd->GetSection().GetFmt()->SetFmtAttr( |
| SwFmtNoBalancedColumns( sal_True ) ); |
| } |
| |
| DelLastNode(); |
| pPam->GetPoint()->nNode = *pRegionEndIdx; |
| pPam->Move( fnMoveForward, fnGoNode ); |
| delete pRegionEndIdx, pRegionEndIdx = 0; |
| } |
| |
| sal_uInt16 nPageDescOffset = pDoc->GetPageDescCnt(); |
| maSegments.InsertSegments(IsNewDoc()); |
| UpdatePageDescs(*pDoc, nPageDescOffset); |
| //$flr folloing garbe collecting code has been moved from the previous procedure |
| // UpdatePageDescs to here in order to fix bug #117882# |
| rtfSections::myrDummyIter aDEnd = maSegments.maDummyPageNos.rend(); |
| for (rtfSections::myrDummyIter aI = maSegments.maDummyPageNos.rbegin(); aI != aDEnd; ++aI) |
| pDoc->DelPageDesc(*aI); |
| |
| if( aFlyArr.Count() ) |
| SetFlysInDoc(); |
| |
| // jetzt noch den letzten ueberfluessigen Absatz loeschen |
| SwPosition* pPos = pPam->GetPoint(); |
| if( !pPos->nContent.GetIndex() ) |
| { |
| SwTxtNode* pAktNd; |
| sal_uLong nNodeIdx = pPos->nNode.GetIndex(); |
| if( IsNewDoc() ) |
| { |
| SwNode* pTmp = pDoc->GetNodes()[ nNodeIdx -1 ]; |
| if( pTmp->IsCntntNode() && !pTmp->FindTableNode() ) |
| { |
| // --> FME 2006-02-15 #131200# Do not delete the paragraph |
| // if it has anchored objects: |
| bool bAnchoredObjs = false; |
| const SwSpzFrmFmts* pFrmFmts = pDoc->GetSpzFrmFmts(); |
| if ( pFrmFmts && pFrmFmts->Count() ) |
| { |
| for ( sal_uInt16 nI = pFrmFmts->Count(); nI; --nI ) |
| { |
| const SwFmtAnchor & rAnchor = (*pFrmFmts)[ nI - 1 ]->GetAnchor(); |
| if ((FLY_AT_PARA == rAnchor.GetAnchorId()) || |
| (FLY_AT_CHAR == rAnchor.GetAnchorId())) |
| { |
| const SwPosition * pObjPos = rAnchor.GetCntntAnchor(); |
| if ( pObjPos && nNodeIdx == pObjPos->nNode.GetIndex() ) |
| { |
| bAnchoredObjs = true; |
| break; |
| } |
| } |
| } |
| } |
| // <-- |
| |
| if ( !bAnchoredObjs ) |
| DelLastNode(); |
| } |
| } |
| else if (0 != (pAktNd = pDoc->GetNodes()[nNodeIdx]->GetTxtNode())) |
| { |
| if( pAktNd->CanJoinNext( &pPos->nNode )) |
| { |
| SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode(); |
| pPos->nContent.Assign( pNextNd, 0 ); |
| pPam->SetMark(); pPam->DeleteMark(); |
| pNextNd->JoinPrev(); |
| } |
| else if( !pAktNd->GetTxt().Len() && |
| pAktNd->StartOfSectionIndex()+2 < |
| pAktNd->EndOfSectionIndex() ) |
| { |
| pPos->nContent.Assign( 0, 0 ); |
| pPam->SetMark(); pPam->DeleteMark(); |
| pDoc->GetNodes().Delete( pPos->nNode, 1 ); |
| pPam->Move( fnMoveBackward ); |
| } |
| } |
| } |
| // nun noch das SplitNode vom Ende aufheben |
| else if( !IsNewDoc() ) |
| { |
| if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein \par, |
| pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node |
| SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode(); |
| SwNodeIndex aPrvIdx( pPos->nNode ); |
| if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) && |
| *pSttNdIdx <= aPrvIdx ) |
| { |
| // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor |
| // usw. sind im pTxtNode angemeldet, so dass der bestehen |
| // bleiben MUSS. |
| |
| // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die |
| // Absatzattribute und die Vorlage uebernehmen! |
| SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode(); |
| pTxtNode->ChgFmtColl( pPrev->GetTxtColl() ); |
| pTxtNode->FmtToTxtAttr( pPrev ); |
| pTxtNode->ResetAllAttr(); |
| |
| if( pPrev->HasSwAttrSet() ) |
| pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() ); |
| |
| if( &pPam->GetBound(sal_True).nNode.GetNode() == pPrev ) |
| pPam->GetBound(sal_True).nContent.Assign( pTxtNode, 0 ); |
| if( &pPam->GetBound(sal_False).nNode.GetNode() == pPrev ) |
| pPam->GetBound(sal_False).nContent.Assign( pTxtNode, 0 ); |
| |
| pTxtNode->JoinPrev(); |
| } |
| } |
| } |
| delete pSttNdIdx, pSttNdIdx = 0; |
| delete pRegionEndIdx, pRegionEndIdx = 0; |
| RemoveUnusedNumRules(); |
| |
| pDoc->SetUpdateExpFldStat(true); |
| pDoc->SetInitDBFields(true); |
| |
| // Laufbalken bei asynchronen Call nicht einschalten !!! |
| ::EndProgress( pDoc->GetDocShell() ); |
| } |
| |
| bool rtfSections::SetCols(SwFrmFmt &rFmt, const rtfSection &rSection, |
| sal_uInt16 nNettoWidth) |
| { |
| //sprmSCcolumns - Anzahl der Spalten - 1 |
| sal_uInt16 nCols = static_cast< sal_uInt16 >(rSection.NoCols()); |
| |
| if (nCols < 2) |
| return false; // keine oder bloedsinnige Spalten |
| |
| SwFmtCol aCol; // Erzeuge SwFmtCol |
| |
| //sprmSDxaColumns - Default-Abstand 1.25 cm |
| sal_uInt16 nColSpace = static_cast< sal_uInt16 >(rSection.StandardColSeperation()); |
| |
| aCol.Init( nCols, nColSpace, nNettoWidth ); |
| |
| // not SFEvenlySpaced |
| if (rSection.maPageInfo.maColumns.size()) |
| { |
| aCol._SetOrtho(false); |
| sal_uInt16 nWishWidth = 0, nHalfPrev = 0; |
| for (sal_uInt16 n=0, i=0; |
| (static_cast<size_t>(n)+1) < rSection.maPageInfo.maColumns.size() && i < nCols; |
| n += 2, ++i) |
| { |
| SwColumn* pCol = aCol.GetColumns()[ i ]; |
| pCol->SetLeft( nHalfPrev ); |
| sal_uInt16 nSp = static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n+1 ]); |
| nHalfPrev = nSp / 2; |
| pCol->SetRight( nSp - nHalfPrev ); |
| pCol->SetWishWidth( static_cast< sal_uInt16 >(rSection.maPageInfo.maColumns[ n ]) + |
| pCol->GetLeft() + pCol->GetRight()); |
| nWishWidth = nWishWidth + pCol->GetWishWidth(); |
| } |
| aCol.SetWishWidth( nWishWidth ); |
| } |
| |
| rFmt.SetFmtAttr(aCol); |
| return true; |
| } |
| |
| void rtfSections::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt, |
| const rtfSection &rSection, bool bIgnoreCols) |
| { |
| // 1. Orientierung |
| rInPageDesc.SetLandscape(rSection.IsLandScape()); |
| |
| // 2. Papiergroesse |
| SwFmtFrmSize aSz(rFmt.GetFrmSize()); |
| aSz.SetWidth(rSection.GetPageWidth()); |
| aSz.SetHeight(rSection.GetPageHeight()); |
| rFmt.SetFmtAttr(aSz); |
| |
| rFmt.SetFmtAttr( |
| SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE)); |
| |
| if (!bIgnoreCols) |
| { |
| SetCols(rFmt, rSection, static_cast< sal_uInt16 >(rSection.GetPageWidth() - |
| rSection.GetPageLeft() - rSection.GetPageRight())); |
| } |
| |
| rFmt.SetFmtAttr(rSection.maPageInfo.maBox); |
| } |
| |
| bool HasHeader(const SwFrmFmt &rFmt) |
| { |
| const SfxPoolItem *pHd; |
| if (SFX_ITEM_SET == rFmt.GetItemState(RES_HEADER, false, &pHd)) |
| return ((const SwFmtHeader *)(pHd))->IsActive(); |
| return false; |
| } |
| |
| bool HasFooter(const SwFrmFmt &rFmt) |
| { |
| const SfxPoolItem *pFt; |
| if (SFX_ITEM_SET == rFmt.GetItemState(RES_FOOTER, false, &pFt)) |
| return ((const SwFmtFooter *)(pFt))->IsActive(); |
| return false; |
| } |
| |
| void rtfSections::GetPageULData(const rtfSection &rSection, bool bFirst, |
| rtfSections::wwULSpaceData& rData) |
| { |
| short nWWUp = static_cast< short >(rSection.maPageInfo.mnMargtsxn); |
| short nWWLo = static_cast< short >(rSection.maPageInfo.mnMargbsxn); |
| short nWWHTop = static_cast< short >(rSection.maPageInfo.mnHeadery); |
| short nWWFBot = static_cast< short >(rSection.maPageInfo.mnFootery); |
| |
| if (bFirst) |
| { |
| if ( |
| rSection.mpTitlePage && HasHeader(rSection.mpTitlePage->GetMaster()) |
| ) |
| { |
| rData.bHasHeader = true; |
| } |
| } |
| else |
| { |
| if (rSection.mpPage && |
| ( |
| HasHeader(rSection.mpPage->GetMaster()) |
| || HasHeader(rSection.mpPage->GetLeft()) |
| ) |
| ) |
| { |
| rData.bHasHeader = true; |
| } |
| } |
| |
| if( rData.bHasHeader ) |
| { |
| rData.nSwUp = nWWHTop; // Header -> umrechnen, see ww8par6.cxx |
| |
| if ( nWWUp > 0 && nWWUp >= nWWHTop ) |
| rData.nSwHLo = nWWUp - nWWHTop; |
| else |
| rData.nSwHLo = 0; |
| |
| if (rData.nSwHLo < cMinHdFtHeight) |
| rData.nSwHLo = cMinHdFtHeight; |
| } |
| else // kein Header -> Up einfach uebernehmen |
| rData.nSwUp = Abs(nWWUp); |
| |
| if (bFirst) |
| { |
| if ( |
| rSection.mpTitlePage && |
| HasFooter(rSection.mpTitlePage->GetMaster()) |
| ) |
| { |
| rData.bHasFooter = true; |
| } |
| } |
| else |
| { |
| if (rSection.mpPage && |
| ( |
| HasFooter(rSection.mpPage->GetMaster()) |
| || HasFooter(rSection.mpPage->GetLeft()) |
| ) |
| ) |
| { |
| rData.bHasFooter = true; |
| } |
| } |
| |
| if( rData.bHasFooter ) |
| { |
| rData.nSwLo = nWWFBot; // Footer -> Umrechnen |
| if ( nWWLo > 0 && nWWLo >= nWWFBot ) |
| rData.nSwFUp = nWWLo - nWWFBot; |
| else |
| rData.nSwFUp = 0; |
| |
| if (rData.nSwFUp < cMinHdFtHeight) |
| rData.nSwFUp = cMinHdFtHeight; |
| } |
| else // kein Footer -> Lo einfach uebernehmen |
| rData.nSwLo = Abs(nWWLo); |
| } |
| |
| void rtfSections::SetPageULSpaceItems(SwFrmFmt &rFmt, |
| rtfSections::wwULSpaceData& rData) |
| { |
| if (rData.bHasHeader) // ... und Header-Lower setzen |
| { |
| //Kopfzeilenhoehe minimal sezten |
| if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt()) |
| { |
| pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo)); |
| SvxULSpaceItem aHdUL(pHdFmt->GetULSpace()); |
| aHdUL.SetLower( rData.nSwHLo - cMinHdFtHeight ); |
| pHdFmt->SetFmtAttr(aHdUL); |
| pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem( |
| RES_HEADER_FOOTER_EAT_SPACING, true)); |
| } |
| } |
| |
| if (rData.bHasFooter) // ... und Footer-Upper setzen |
| { |
| if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt()) |
| { |
| pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp)); |
| SvxULSpaceItem aFtUL(pFtFmt->GetULSpace()); |
| aFtUL.SetUpper( rData.nSwFUp - cMinHdFtHeight ); |
| pFtFmt->SetFmtAttr(aFtUL); |
| pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem( |
| RES_HEADER_FOOTER_EAT_SPACING, true)); |
| } |
| } |
| |
| SvxULSpaceItem aUL(rData.nSwUp, rData.nSwLo, RES_UL_SPACE ); // Page-UL setzen |
| rFmt.SetFmtAttr(aUL); |
| } |
| |
| void rtfSections::SetSegmentToPageDesc(const rtfSection &rSection, |
| bool bTitlePage, bool bIgnoreCols) |
| { |
| SwPageDesc &rPage = bTitlePage ? *rSection.mpTitlePage : *rSection.mpPage; |
| |
| // SetNumberingType(rSection, rPage); |
| |
| SwFrmFmt &rFmt = rPage.GetMaster(); |
| // mrReader.SetDocumentGrid(rFmt, rSection); |
| |
| wwULSpaceData aULData; |
| GetPageULData(rSection, bTitlePage, aULData); |
| SetPageULSpaceItems(rFmt, aULData); |
| |
| SetPage(rPage, rFmt, rSection, bIgnoreCols); |
| |
| UseOnPage ePage = rPage.ReadUseOn(); |
| if(ePage & nsUseOnPage::PD_ALL) |
| { |
| SwFrmFmt &rFmtLeft = rPage.GetLeft(); |
| SetPageULSpaceItems(rFmtLeft, aULData); |
| SetPage(rPage, rFmtLeft, rSection, bIgnoreCols); |
| } |
| |
| } |
| |
| void rtfSections::CopyFrom(const SwPageDesc &rFrom, SwPageDesc &rDest) |
| { |
| UseOnPage ePage = rFrom.ReadUseOn(); |
| rDest.WriteUseOn(ePage); |
| |
| mrReader.pDoc->CopyHeader(rFrom.GetMaster(), rDest.GetMaster()); |
| SwFrmFmt &rDestFmt = rDest.GetMaster(); |
| rDestFmt.SetFmtAttr(rFrom.GetMaster().GetHeader()); |
| mrReader.pDoc->CopyHeader(rFrom.GetLeft(), rDest.GetLeft()); |
| mrReader.pDoc->CopyFooter(rFrom.GetMaster(), rDest.GetMaster()); |
| mrReader.pDoc->CopyFooter(rFrom.GetLeft(), rDest.GetLeft()); |
| } |
| |
| void rtfSections::MoveFrom(SwPageDesc &rFrom, SwPageDesc &rDest) |
| { |
| UseOnPage ePage = rFrom.ReadUseOn(); |
| rDest.WriteUseOn(ePage); |
| |
| SwFrmFmt &rDestMaster = rDest.GetMaster(); |
| SwFrmFmt &rFromMaster = rFrom.GetMaster(); |
| rDestMaster.SetFmtAttr(rFromMaster.GetHeader()); |
| rDestMaster.SetFmtAttr(rFromMaster.GetFooter()); |
| //rFromMaster.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882# |
| //rFromMaster.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882# |
| |
| SwFrmFmt &rDestLeft = rDest.GetLeft(); |
| SwFrmFmt &rFromLeft = rFrom.GetLeft(); |
| rDestLeft.SetFmtAttr(rFromLeft.GetHeader()); |
| rDestLeft.SetFmtAttr(rFromLeft.GetFooter()); |
| //rFromLeft.SetAttr(SwFmtHeader()); //$flr uncommented due to bug fix #117882# |
| //rFromLeft.SetAttr(SwFmtFooter()); //$flr uncommented due to bug fix #117882# |
| } |
| |
| void rtfSections::SetHdFt(rtfSection &rSection) |
| { |
| ASSERT(rSection.mpPage, "makes no sense to call without a main page"); |
| if (rSection.mpPage && rSection.maPageInfo.mpPageHdFt) |
| { |
| if (rSection.maPageInfo.mbPageHdFtUsed) |
| { |
| MoveFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage); |
| rSection.maPageInfo.mbPageHdFtUsed = false; |
| rSection.maPageInfo.mpPageHdFt = rSection.mpPage; |
| } |
| else |
| CopyFrom(*rSection.maPageInfo.mpPageHdFt, *rSection.mpPage); |
| } |
| |
| if (rSection.mpTitlePage && rSection.maPageInfo.mpTitlePageHdFt) |
| { |
| if (rSection.maPageInfo.mbTitlePageHdFtUsed) |
| { |
| MoveFrom(*rSection.maPageInfo.mpTitlePageHdFt, |
| *rSection.mpTitlePage); |
| rSection.maPageInfo.mbTitlePageHdFtUsed = false; |
| rSection.maPageInfo.mpTitlePageHdFt = rSection.mpTitlePage; |
| } |
| else |
| { |
| CopyFrom(*rSection.maPageInfo.mpTitlePageHdFt, |
| *rSection.mpTitlePage); |
| } |
| } |
| } |
| |
| SwSectionFmt *rtfSections::InsertSection(SwPaM& rMyPaM, rtfSection &rSection) |
| { |
| SwSectionData aSectionData(CONTENT_SECTION, |
| mrReader.pDoc->GetUniqueSectionName()); |
| |
| SfxItemSet aSet( mrReader.pDoc->GetAttrPool(), aFrmFmtSetRange ); |
| |
| sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi(); |
| aSet.Put(SvxFrameDirectionItem( |
| nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR)); |
| |
| rSection.mpSection = |
| mrReader.pDoc->InsertSwSection( rMyPaM, aSectionData, 0, &aSet ); |
| ASSERT(rSection.mpSection, "section not inserted!"); |
| if (!rSection.mpSection) |
| return 0; |
| |
| SwPageDesc *pPage = 0; |
| mySegrIter aEnd = maSegments.rend(); |
| for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter) |
| { |
| pPage = aIter->mpPage; |
| if (pPage) |
| break; |
| } |
| |
| ASSERT(pPage, "no page outside this section!"); |
| |
| if (!pPage) |
| pPage = &mrReader.pDoc->_GetPageDesc(0); |
| |
| if (!pPage) |
| return 0; |
| |
| SwFrmFmt& rFmt = pPage->GetMaster(); |
| const SwFmtFrmSize& rSz = rFmt.GetFrmSize(); |
| const SvxLRSpaceItem& rLR = rFmt.GetLRSpace(); |
| SwTwips nWidth = rSz.GetWidth(); |
| long nLeft = rLR.GetTxtLeft(); |
| long nRight = rLR.GetRight(); |
| |
| SwSectionFmt *pFmt = rSection.mpSection->GetFmt(); |
| ASSERT(pFmt, "impossible"); |
| if (!pFmt) |
| return 0; |
| SetCols(*pFmt, rSection, (sal_uInt16)(nWidth - nLeft - nRight) ); |
| |
| return pFmt; |
| } |
| |
| void rtfSections::InsertSegments(bool bNewDoc) |
| { |
| sal_uInt16 nDesc(0); |
| mySegIter aEnd = maSegments.end(); |
| mySegIter aStart = maSegments.begin(); |
| for (mySegIter aIter = aStart; aIter != aEnd; ++aIter) |
| { |
| mySegIter aNext = aIter+1; |
| |
| bool bInsertSection = aIter != aStart ? aIter->IsContinous() : false; |
| |
| if (!bInsertSection) |
| { |
| /* |
| If a cont section follow this section then we won't be |
| creating a page desc with 2+ cols as we cannot host a one |
| col section in a 2+ col pagedesc and make it look like |
| word. But if the current section actually has columns then |
| we are forced to insert a section here as well as a page |
| descriptor. |
| */ |
| |
| /* |
| Note for the future: |
| If we want to import "protected sections" the here is |
| where we would also test for that and force a section |
| insertion if that was true. |
| */ |
| bool bIgnoreCols = false; |
| if (aNext != aEnd && aNext->IsContinous()) |
| { |
| bIgnoreCols = true; |
| if (aIter->NoCols() > 1) |
| bInsertSection = true; |
| } |
| |
| if (aIter->HasTitlePage()) |
| { |
| if (bNewDoc && aIter == aStart) |
| { |
| aIter->mpTitlePage = |
| mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_FIRST); |
| } |
| else |
| { |
| sal_uInt16 nPos = mrReader.pDoc->MakePageDesc( |
| ViewShell::GetShellRes()->GetPageDescName(nDesc) |
| , 0, false); |
| aIter->mpTitlePage = &mrReader.pDoc->_GetPageDesc(nPos); |
| } |
| ASSERT(aIter->mpTitlePage, "no page!"); |
| if (!aIter->mpTitlePage) |
| continue; |
| |
| SetSegmentToPageDesc(*aIter, true, bIgnoreCols); |
| } |
| |
| if (!bNewDoc && aIter == aStart) |
| continue; |
| else if (bNewDoc && aIter == aStart) |
| { |
| aIter->mpPage = |
| mrReader.pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD); |
| } |
| else |
| { |
| sal_uInt16 nPos = mrReader.pDoc->MakePageDesc( |
| ViewShell::GetShellRes()->GetPageDescName(nDesc, |
| false, aIter->HasTitlePage()), |
| aIter->mpTitlePage, false); |
| aIter->mpPage = &mrReader.pDoc->_GetPageDesc(nPos); |
| } |
| ASSERT(aIter->mpPage, "no page!"); |
| if (!aIter->mpPage) |
| continue; |
| |
| SetHdFt(*aIter); |
| |
| if (aIter->mpTitlePage) |
| SetSegmentToPageDesc(*aIter, true, bIgnoreCols); |
| SetSegmentToPageDesc(*aIter, false, bIgnoreCols); |
| |
| SwFmtPageDesc aPgDesc(aIter->HasTitlePage() ? |
| aIter->mpTitlePage : aIter->mpPage); |
| |
| if (aIter->mpTitlePage) |
| aIter->mpTitlePage->SetFollow(aIter->mpPage); |
| |
| if (aIter->PageRestartNo() || |
| ((aIter == aStart) && aIter->PageStartAt() != 1)) |
| aPgDesc.SetNumOffset( static_cast< sal_uInt16 >(aIter->PageStartAt()) ); |
| |
| /* |
| If its a table here, apply the pagebreak to the table |
| properties, otherwise we add it to the para at this |
| position |
| */ |
| if (aIter->maStart.GetNode().IsTableNode()) |
| { |
| SwTable& rTable = |
| aIter->maStart.GetNode().GetTableNode()->GetTable(); |
| SwFrmFmt* pApply = rTable.GetFrmFmt(); |
| ASSERT(pApply, "impossible"); |
| if (pApply) |
| pApply->SetFmtAttr(aPgDesc); |
| } |
| else |
| { |
| SwPosition aPamStart(aIter->maStart); |
| aPamStart.nContent.Assign( |
| aIter->maStart.GetNode().GetCntntNode(), 0); |
| SwPaM aPage(aPamStart); |
| |
| mrReader.pDoc->InsertPoolItem(aPage, aPgDesc, 0); |
| } |
| ++nDesc; |
| } |
| |
| SwTxtNode* pTxtNd = 0; |
| if (bInsertSection) |
| { |
| SwPaM aSectPaM(*mrReader.pPam); |
| SwNodeIndex aAnchor(aSectPaM.GetPoint()->nNode); |
| if (aNext != aEnd) |
| { |
| aAnchor = aNext->maStart; |
| aSectPaM.GetPoint()->nNode = aAnchor; |
| aSectPaM.GetPoint()->nContent.Assign( |
| aNext->maStart.GetNode().GetCntntNode(), 0); |
| aSectPaM.Move(fnMoveBackward); |
| } |
| |
| const SwPosition* pPos = aSectPaM.GetPoint(); |
| SwTxtNode const*const pSttNd = pPos->nNode.GetNode().GetTxtNode(); |
| const SwTableNode* pTableNd = pSttNd ? pSttNd->FindTableNode() : 0; |
| if (pTableNd) |
| { |
| pTxtNd = |
| mrReader.pDoc->GetNodes().MakeTxtNode(aAnchor, |
| mrReader.pDoc->GetTxtCollFromPool( RES_POOLCOLL_TEXT )); |
| |
| aSectPaM.GetPoint()->nNode = SwNodeIndex(*pTxtNd); |
| aSectPaM.GetPoint()->nContent.Assign( |
| aSectPaM.GetCntntNode(), 0); |
| } |
| |
| aSectPaM.SetMark(); |
| |
| aSectPaM.GetPoint()->nNode = aIter->maStart; |
| aSectPaM.GetPoint()->nContent.Assign( |
| aSectPaM.GetCntntNode(), 0); |
| |
| SwSectionFmt *pRet = InsertSection(aSectPaM, *aIter); |
| //The last section if continous is always unbalanced |
| if (aNext == aEnd && pRet) |
| pRet->SetFmtAttr(SwFmtNoBalancedColumns(true)); |
| } |
| |
| if (pTxtNd) |
| { |
| SwNodeIndex aIdx(*pTxtNd); |
| SwPosition aPos(aIdx); |
| SwPaM aTest(aPos); |
| mrReader.pDoc->DelFullPara(aTest); |
| pTxtNd = 0; |
| } |
| } |
| } |
| |
| namespace sw{ |
| namespace util{ |
| |
| InsertedTableClient::InsertedTableClient(SwTableNode & rNode) |
| { |
| rNode.Add(this); |
| } |
| |
| SwTableNode * InsertedTableClient::GetTableNode() |
| { |
| return dynamic_cast<SwTableNode *> (GetRegisteredInNonConst()); |
| } |
| |
| InsertedTablesManager::InsertedTablesManager(const SwDoc &rDoc) |
| : mbHasRoot(rDoc.GetCurrentLayout()) //swmod 080218 |
| { |
| } |
| |
| void InsertedTablesManager::DelAndMakeTblFrms() |
| { |
| if (!mbHasRoot) |
| return; |
| TblMapIter aEnd = maTables.end(); |
| for (TblMapIter aIter = maTables.begin(); aIter != aEnd; ++aIter) |
| { |
| // exitiert schon ein Layout, dann muss an dieser Tabelle die BoxFrames |
| // neu erzeugt |
| SwTableNode *pTable = aIter->first->GetTableNode(); |
| ASSERT(pTable, "Why no expected table"); |
| if (pTable) |
| { |
| SwFrmFmt * pFrmFmt = pTable->GetTable().GetFrmFmt(); |
| |
| if (pFrmFmt != NULL) |
| { |
| SwNodeIndex *pIndex = aIter->second; |
| pTable->DelFrms(); |
| pTable->MakeFrms(pIndex); |
| } |
| } |
| } |
| } |
| |
| void InsertedTablesManager::InsertTable(SwTableNode &rTableNode, SwPaM &rPaM) |
| { |
| if (!mbHasRoot) |
| return; |
| //Associate this tablenode with this after position, replace an //old |
| //node association if necessary |
| |
| InsertedTableClient * pClient = new InsertedTableClient(rTableNode); |
| |
| maTables.insert(TblMap::value_type(pClient, &(rPaM.GetPoint()->nNode))); |
| } |
| } |
| } |
| |
| SwRTFParser::~SwRTFParser() |
| { |
| maInsertedTables.DelAndMakeTblFrms(); |
| mpRedlineStack->closeall(*pPam->GetPoint()); |
| delete mpRedlineStack; |
| |
| delete pSttNdIdx; |
| delete pRegionEndIdx; |
| delete pPam; |
| delete pRelNumRule; |
| |
| if (aFlyArr.Count()) |
| aFlyArr.DeleteAndDestroy( 0, aFlyArr.Count() ); |
| |
| if (pGrfAttrSet) |
| DELETEZ( pGrfAttrSet ); |
| |
| DELETEZ( pAuthorInfos ); |
| } |
| |
| //i19718 |
| void SwRTFParser::ReadShpRslt() |
| { |
| int nToken; |
| while ('}' != (nToken = GetNextToken() ) && IsParserWorking()) |
| { |
| switch(nToken) |
| { |
| case RTF_PAR: |
| break; |
| default: |
| NextToken(nToken); |
| break; |
| } |
| } |
| SkipToken(-1); |
| } |
| |
| void SwRTFParser::ReadShpTxt(String& s) |
| { |
| int nToken; |
| int level=1; |
| s.AppendAscii("{\\rtf"); |
| while (level>0 && IsParserWorking()) |
| { |
| nToken = GetNextToken(); |
| switch(nToken) |
| { |
| case RTF_SN: |
| case RTF_SV: |
| SkipGroup(); |
| break; |
| case RTF_TEXTTOKEN: |
| s.Append(aToken); |
| break; |
| case '{': |
| level++; |
| s.Append(String::CreateFromAscii("{")); |
| break; |
| case '}': |
| level--; |
| s.Append(String::CreateFromAscii("}")); |
| break; |
| default: |
| s.Append(aToken); |
| if (bTokenHasValue) { |
| s.Append(String::CreateFromInt64(nTokenValue)); |
| } |
| s.Append(String::CreateFromAscii(" ")); |
| break; |
| } |
| } |
| SkipToken(-1); |
| } |
| |
| /* |
| * #127429#. Very basic support for the "Buchhalternase". |
| */ |
| void SwRTFParser::ReadDrawingObject() |
| { |
| int nToken; |
| int level; |
| level=1; |
| Rectangle aRect; |
| ::basegfx::B2DPolygon aPolygon; |
| ::basegfx::B2DPoint aPoint; |
| bool bPolygonActive(false); |
| |
| while (level>0 && IsParserWorking()) |
| { |
| nToken = GetNextToken(); |
| switch(nToken) |
| { |
| case '}': |
| level--; |
| break; |
| case '{': |
| level++; |
| break; |
| case RTF_DPX: |
| aRect.setX(nTokenValue); |
| break; |
| case RTF_DPXSIZE: |
| aRect.setWidth(nTokenValue); |
| break; |
| case RTF_DPY: |
| aRect.setY(nTokenValue); |
| break; |
| case RTF_DPYSIZE: |
| aRect.setHeight(nTokenValue); |
| break; |
| case RTF_DPPOLYCOUNT: |
| bPolygonActive = true; |
| break; |
| case RTF_DPPTX: |
| aPoint.setX(nTokenValue); |
| break; |
| case RTF_DPPTY: |
| aPoint.setY(nTokenValue); |
| |
| if(bPolygonActive) |
| { |
| aPolygon.append(aPoint); |
| } |
| |
| break; |
| default: |
| break; |
| } |
| } |
| SkipToken(-1); |
| /* |
| const Point aPointC1( 0, 0 ); |
| const Point aPointC2( 100, 200 ); |
| const Point aPointC3( 300, 400 ); |
| XPolygon aPolygonC(3); |
| aPolygonC[0] = aPointC1; |
| aPolygonC[1] = aPointC2; |
| aPolygonC[2] = aPointC3; |
| */ |
| if(bPolygonActive && aPolygon.count()) |
| { |
| SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aPolygon)); |
| SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1); |
| SwFmtSurround aSur( SURROUND_PARALLEL ); |
| aSur.SetContour( false ); |
| aSur.SetOutside(true); |
| aFlySet.Put( aSur ); |
| SwFmtFollowTextFlow aFollowTextFlow( sal_False ); |
| aFlySet.Put( aFollowTextFlow ); |
| /* |
| sw::util::SetLayer aSetLayer(*pDoc); |
| aSetLayer.SendObjectToHeaven(*pStroke); |
| */ |
| SwFmtAnchor aAnchor( FLY_AT_PARA ); |
| aAnchor.SetAnchor( pPam->GetPoint() ); |
| aFlySet.Put( aAnchor ); |
| |
| /* |
| text::RelOrientation::FRAME, // Absatz inkl. Raender |
| text::RelOrientation::PRINT_AREA, // Absatz ohne Raender |
| text::RelOrientation::CHAR, // an einem Zeichen |
| text::RelOrientation::PAGE_LEFT, // im linken Seitenrand |
| text::RelOrientation::PAGE_RIGHT, // im rechten Seitenrand |
| text::RelOrientation::FRAME_LEFT, // im linken Absatzrand |
| text::RelOrientation::FRAME_RIGHT, // im rechten Absatzrand |
| text::RelOrientation::PAGE_FRAME, // Seite inkl. Raender, bei seitengeb. identisch mit text::RelOrientation::FRAME |
| text::RelOrientation::PAGE_PRINT_AREA, // Seite ohne Raender, bei seitengeb. identisch mit text::RelOrientation::PRTAREA |
| // OD 11.11.2003 #i22341# |
| text::RelOrientation::TEXT_LINE, // vertical relative to top of text line, only for to-character |
| // anchored objects. |
| |
| |
| text::HoriOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an. |
| text::HoriOrientation::RIGHT, //Der Rest ist fuer automatische Ausrichtung. |
| text::HoriOrientation::CENTER, |
| text::HoriOrientation::LEFT, |
| text::HoriOrientation::INSIDE, |
| text::HoriOrientation::OUTSIDE, |
| text::HoriOrientation::FULL, //Spezialwert fuer Tabellen |
| text::HoriOrientation::LEFT_AND_WIDTH //Auch fuer Tabellen |
| */ |
| SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ); |
| aFlySet.Put( aHori ); |
| /* |
| text::VertOrientation::NONE, //Der Wert in nYPos gibt die RelPos direkt an. |
| text::VertOrientation::TOP, //Der Rest ist fuer automatische Ausrichtung. |
| text::VertOrientation::CENTER, |
| text::VertOrientation::BOTTOM, |
| text::VertOrientation::CHAR_TOP, //Ausrichtung _nur_ fuer Zeichengebundene Rahmen |
| text::VertOrientation::CHAR_CENTER, //wie der Name jew. sagt wird der RefPoint des Rahmens |
| text::VertOrientation::CHAR_BOTTOM, //entsprechend auf die Oberkante, Mitte oder Unterkante |
| text::VertOrientation::LINE_TOP, //der Zeile gesetzt. Der Rahmen richtet sich dann |
| text::VertOrientation::LINE_CENTER, //entsprechend aus. |
| text::VertOrientation::LINE_BOTTOM |
| */ |
| SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ); |
| aFlySet.Put( aVert ); |
| |
| pDoc->GetOrCreateDrawModel(); |
| SdrModel* pDrawModel = pDoc->GetDrawModel(); |
| SdrPage* pDrawPg = pDrawModel->GetPage(0); |
| pDrawPg->InsertObject(pStroke, 0); |
| |
| pStroke->SetSnapRect(aRect); |
| |
| /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet ); |
| } |
| } |
| |
| void SwRTFParser::InsertShpObject(SdrObject* pStroke, int _nZOrder) |
| { |
| SfxItemSet aFlySet(pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1); |
| SwFmtSurround aSur( SURROUND_THROUGHT ); |
| aSur.SetContour( false ); |
| aSur.SetOutside(true); |
| aFlySet.Put( aSur ); |
| SwFmtFollowTextFlow aFollowTextFlow( sal_False ); |
| aFlySet.Put( aFollowTextFlow ); |
| |
| SwFmtAnchor aAnchor( FLY_AT_PARA ); |
| aAnchor.SetAnchor( pPam->GetPoint() ); |
| aFlySet.Put( aAnchor ); |
| |
| |
| SwFmtHoriOrient aHori( 0, text::HoriOrientation::NONE, text::RelOrientation::PAGE_FRAME ); |
| aFlySet.Put( aHori ); |
| |
| SwFmtVertOrient aVert( 0, text::VertOrientation::NONE, text::RelOrientation::PAGE_FRAME ); |
| aFlySet.Put( aVert ); |
| |
| aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false)); |
| |
| pDoc->GetOrCreateDrawModel(); |
| SdrModel* pDrawModel = pDoc->GetDrawModel(); |
| SdrPage* pDrawPg = pDrawModel->GetPage(0); |
| pDrawPg->InsertObject(pStroke); |
| pDrawPg->SetObjectOrdNum(pStroke->GetOrdNum(), _nZOrder); |
| /* SwFrmFmt* pRetFrmFmt = */pDoc->InsertDrawObj(*pPam, *pStroke, aFlySet ); |
| } |
| |
| ::basegfx::B2DPoint rotate(const ::basegfx::B2DPoint& rStart, const ::basegfx::B2DPoint& rEnd) |
| { |
| const ::basegfx::B2DVector aVector(rStart - rEnd); |
| return ::basegfx::B2DPoint(aVector.getY() + rEnd.getX(), -aVector.getX() + rEnd.getY()); |
| } |
| |
| |
| void SwRTFParser::ReadShapeObject() |
| { |
| int nToken; |
| int level; |
| level=1; |
| ::basegfx::B2DPoint aPointLeftTop; |
| ::basegfx::B2DPoint aPointRightBottom; |
| String sn; |
| sal_Int32 shapeType=-1; |
| Graphic aGrf; |
| bool bGrfValid=false; |
| bool fFilled=true; |
| Color fillColor(255, 255, 255); |
| bool fLine=true; |
| int lineWidth=9525/360; |
| String shpTxt; |
| bool bshpTxt=false; |
| int txflTextFlow=0; |
| ::rtl::OUString sDescription, sName; |
| |
| |
| while (level>0 && IsParserWorking()) |
| { |
| nToken = GetNextToken(); |
| switch(nToken) |
| { |
| case '}': |
| level--; |
| break; |
| case '{': |
| level++; |
| break; |
| case RTF_SHPLEFT: |
| aPointLeftTop.setX(nTokenValue); |
| break; |
| case RTF_SHPTOP: |
| aPointLeftTop.setY(nTokenValue); |
| break; |
| case RTF_SHPBOTTOM: |
| aPointRightBottom.setY(nTokenValue); |
| break; |
| case RTF_SHPRIGHT: |
| aPointRightBottom.setX(nTokenValue); |
| break; |
| case RTF_SN: |
| nToken = GetNextToken(); |
| ASSERT(nToken==RTF_TEXTTOKEN, "expected name"); |
| sn=aToken; |
| break; |
| case RTF_SV: |
| nToken = GetNextToken(); |
| if (nToken==RTF_TEXTTOKEN) |
| { |
| if (sn.EqualsAscii("shapeType")) |
| { |
| shapeType=aToken.ToInt32(); |
| |
| } else if (sn.EqualsAscii("fFilled")) |
| { |
| fFilled=aToken.ToInt32(); |
| |
| } else if (sn.EqualsAscii("fLine")) |
| { |
| fLine=aToken.ToInt32(); |
| } else if (sn.EqualsAscii("lineWidth")) |
| { |
| lineWidth=aToken.ToInt32()/360; |
| |
| } else if (sn.EqualsAscii("fillColor")) |
| { |
| sal_uInt32 nColor=aToken.ToInt32(); |
| fillColor=Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) ); |
| }else if (sn.EqualsAscii("txflTextFlow")) |
| { |
| txflTextFlow=aToken.ToInt32(); |
| } |
| else if (sn.EqualsAscii("wzDescription")) |
| { |
| sDescription = aToken; |
| } |
| else if(sn.EqualsAscii("wzName")) |
| { |
| sName = aToken; |
| } |
| } |
| break; |
| case RTF_PICT: |
| { |
| SvxRTFPictureType aPicType; |
| bGrfValid=ReadBmpData( aGrf, aPicType ); |
| } |
| break; |
| case RTF_SHPRSLT: |
| if (shapeType!=1 && shapeType!=20 && shapeType!=75) |
| { |
| ReadShpRslt(); |
| } |
| break; |
| case RTF_SHPTXT: |
| ReadShpTxt(shpTxt); |
| bshpTxt=true; |
| break; |
| |
| default: |
| break; |
| } |
| } |
| SkipToken(-1); |
| |
| SdrObject* pSdrObject = 0; |
| switch(shapeType) |
| { |
| case 202: /* Text Box */ |
| case 1: /* Rectangle */ |
| { |
| ::basegfx::B2DRange aRange(aPointLeftTop); |
| aRange.expand(aPointRightBottom); |
| |
| if (txflTextFlow==2) { |
| const ::basegfx::B2DPoint a(rotate(aRange.getMinimum(), aRange.getCenter())); |
| const ::basegfx::B2DPoint b(rotate(aRange.getMaximum(), aRange.getCenter())); |
| |
| aRange.reset(); |
| aRange.expand(a); |
| aRange.expand(b); |
| } |
| |
| const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY())); |
| SdrRectObj* pStroke = new SdrRectObj(aRect); |
| pSdrObject = pStroke; |
| pStroke->SetSnapRect(aRect); |
| pDoc->GetOrCreateDrawModel(); // create model |
| InsertShpObject(pStroke, this->nZOrder++); |
| SfxItemSet aSet(pStroke->GetMergedItemSet()); |
| if (fFilled) |
| { |
| aSet.Put(XFillStyleItem(XFILL_SOLID)); |
| aSet.Put(XFillColorItem( String(), fillColor ) ); |
| } |
| else |
| { |
| aSet.Put(XFillStyleItem(XFILL_NONE)); |
| } |
| if (!fLine) { |
| aSet.Put(XLineStyleItem(XLINE_NONE)); |
| } else { |
| aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width |
| } |
| |
| pStroke->SetMergedItemSet(aSet); |
| if (bshpTxt) { |
| SdrOutliner& rOutliner=pDoc->GetDrawModel()->GetDrawOutliner(pStroke); |
| rOutliner.Clear(); |
| ByteString bs(shpTxt, RTL_TEXTENCODING_ASCII_US); |
| SvMemoryStream aStream((sal_Char*)bs.GetBuffer(), bs.Len(), STREAM_READ); |
| rOutliner.Read(aStream, String::CreateFromAscii(""), EE_FORMAT_RTF); |
| OutlinerParaObject* pParaObject=rOutliner.CreateParaObject(); |
| pStroke->NbcSetOutlinerParaObject(pParaObject); |
| //delete pParaObject; |
| rOutliner.Clear(); |
| } |
| if (txflTextFlow==2) { |
| long nAngle = 90; |
| double a = nAngle*100*nPi180; |
| pStroke->Rotate(pStroke->GetCurrentBoundRect().Center(), nAngle*100, sin(a), cos(a) ); |
| |
| } |
| |
| } |
| break; |
| case 20: /* Line */ |
| { |
| ::basegfx::B2DPolygon aLine; |
| aLine.append(aPointLeftTop); |
| aLine.append(aPointRightBottom); |
| |
| SdrPathObj* pStroke = new SdrPathObj(OBJ_PLIN, ::basegfx::B2DPolyPolygon(aLine)); |
| pSdrObject = pStroke; |
| //pStroke->SetSnapRect(aRect); |
| |
| InsertShpObject(pStroke, this->nZOrder++); |
| SfxItemSet aSet(pStroke->GetMergedItemSet()); |
| if (!fLine) { |
| aSet.Put(XLineStyleItem(XLINE_NONE)); |
| } else { |
| aSet.Put( XLineWidthItem( lineWidth/2 ) ); // lineWidth are in 1000th mm, seems that XLineWidthItem expects 1/2 the line width |
| } |
| |
| pStroke->SetMergedItemSet(aSet); |
| } |
| break; |
| case 75 : /* Picture */ |
| if (bGrfValid) { |
| ::basegfx::B2DRange aRange(aPointLeftTop); |
| aRange.expand(aPointRightBottom); |
| const Rectangle aRect(FRound(aRange.getMinX()), FRound(aRange.getMinY()), FRound(aRange.getMaxX()), FRound(aRange.getMaxY())); |
| |
| SdrRectObj* pStroke = new SdrGrafObj(aGrf); |
| pSdrObject = pStroke; |
| pStroke->SetSnapRect(aRect); |
| |
| InsertShpObject(pStroke, this->nZOrder++); |
| } |
| } |
| if( pSdrObject ) |
| { |
| pSdrObject->SetDescription(sDescription); |
| pSdrObject->SetTitle(sName); |
| } |
| } |
| |
| extern void sw3io_ConvertFromOldField( SwDoc& rDoc, sal_uInt16& rWhich, |
| sal_uInt16& rSubType, sal_uLong &rFmt, |
| sal_uInt16 nVersion ); |
| |
| sal_uInt16 SwRTFParser::ReadRevTbl() |
| { |
| // rStr.Erase( 0 ); |
| int nNumOpenBrakets = 1, nToken; // die erste wurde schon vorher erkannt !! |
| sal_uInt16 nAuthorTableIndex = 0; |
| |
| while( nNumOpenBrakets && IsParserWorking() ) |
| { |
| switch( nToken = GetNextToken() ) |
| { |
| case '}': --nNumOpenBrakets; break; |
| case '{': |
| { |
| if( RTF_IGNOREFLAG != GetNextToken() ) |
| nToken = SkipToken( -1 ); |
| else if( RTF_UNKNOWNCONTROL != GetNextToken() ) |
| nToken = SkipToken( -2 ); |
| else |
| { |
| ReadUnknownData(); |
| nToken = GetNextToken(); |
| if( '}' != nToken ) |
| eState = SVPAR_ERROR; |
| break; |
| } |
| ++nNumOpenBrakets; |
| } |
| break; |
| |
| case RTF_TEXTTOKEN: |
| aToken.EraseTrailingChars(';'); |
| |
| sal_uInt16 nSWId = pDoc->InsertRedlineAuthor(aToken); |
| // Store matchpair |
| if( !pAuthorInfos ) |
| pAuthorInfos = new sw::util::AuthorInfos; |
| sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthorTableIndex, nSWId ); |
| if( 0 == pAuthorInfos->Insert( pAutorInfo ) ) |
| delete pAutorInfo; |
| |
| aRevTbl.push_back(aToken); |
| nAuthorTableIndex++; |
| break; |
| } |
| } |
| SkipToken( -1 ); |
| return nAuthorTableIndex; |
| } |
| |
| void SwRTFParser::NextToken( int nToken ) |
| { |
| sal_uInt16 eDateFmt; |
| |
| switch( nToken ) |
| { |
| case RTF_FOOTNOTE: |
| { |
| //We can only insert a footnote if we're not inside a footnote. e.g. |
| //#i7713# |
| |
| // in insert mode it's also possible to be inside of a footnote! |
| bool bInsertIntoFootnote = false; |
| if( !IsNewDoc() ) |
| { |
| SwStartNode* pSttNode = pPam->GetNode()->StartOfSectionNode(); |
| while(pSttNode && pSttNode->IsSectionNode()) |
| { |
| pSttNode = pSttNode->StartOfSectionNode(); |
| } |
| if( SwFootnoteStartNode == pSttNode->GetStartNodeType() ) |
| bInsertIntoFootnote = true; |
| } |
| if (!mbIsFootnote && !bInsertIntoFootnote) |
| { |
| ReadHeaderFooter( nToken ); |
| SkipToken( -1 ); // Klammer wieder zurueck |
| } |
| } |
| break; |
| case RTF_SWG_PRTDATA: |
| ReadPrtData(); |
| break; |
| case RTF_XE: |
| ReadXEField(); |
| break; |
| case RTF_FIELD: |
| ReadField(); |
| break; |
| case RTF_SHPRSLT: |
| ReadShpRslt(); |
| break; |
| case RTF_DO: |
| ReadDrawingObject(); |
| break; |
| case RTF_SHP: |
| ReadShapeObject(); |
| break; |
| case RTF_SHPPICT: |
| case RTF_PICT: |
| ReadBitmapData(); |
| break; |
| #ifdef READ_OLE_OBJECT |
| case RTF_OBJECT: |
| ReadOLEData(); |
| break; |
| #endif |
| case RTF_TROWD: ReadTable( nToken ); break; |
| case RTF_PGDSCTBL: |
| if( !IsNewDoc() ) |
| SkipPageDescTbl(); |
| else |
| ReadPageDescTbl(); |
| break; |
| case RTF_LISTTABLE: ReadListTable(); break; |
| case RTF_LISTOVERRIDETABLE: ReadListOverrideTable(); break; |
| |
| case RTF_LISTTEXT: |
| GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 )); |
| SkipGroup(); |
| break; |
| |
| case RTF_PN: |
| if( bNewNumList ) |
| SkipGroup(); |
| else |
| { |
| bStyleTabValid = sal_True; |
| if (SwNumRule* pRule = ReadNumSecLevel( nToken )) |
| { |
| GetAttrSet().Put( SwNumRuleItem( pRule->GetName() )); |
| |
| if( SFX_ITEM_SET != GetAttrSet().GetItemState( FN_PARAM_NUM_LEVEL, sal_False )) |
| GetAttrSet().Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 )); |
| } |
| } |
| break; |
| |
| |
| case RTF_BKMKSTART: |
| if(RTF_TEXTTOKEN == GetNextToken()) |
| mpBookmarkStart = new BookmarkPosition(*pPam); |
| else |
| SkipToken(-1); |
| |
| SkipGroup(); |
| break; |
| |
| case RTF_BKMKEND: |
| if(RTF_TEXTTOKEN == GetNextToken()) |
| { |
| const String& sBookmark = aToken; |
| KeyCode aEmptyKeyCode; |
| if (mpBookmarkStart) |
| { |
| BookmarkPosition aBookmarkEnd(*pPam); |
| SwPaM aBookmarkRegion( mpBookmarkStart->maMkNode, mpBookmarkStart->mnMkCntnt, |
| aBookmarkEnd.maMkNode, aBookmarkEnd.mnMkCntnt); |
| if (*mpBookmarkStart == aBookmarkEnd) |
| aBookmarkRegion.DeleteMark(); |
| pDoc->getIDocumentMarkAccess()->makeMark(aBookmarkRegion, sBookmark, IDocumentMarkAccess::BOOKMARK); |
| } |
| delete mpBookmarkStart, mpBookmarkStart = 0; |
| } |
| else |
| SkipToken(-1); |
| |
| SkipGroup(); |
| break; |
| |
| |
| case RTF_PNSECLVL:{ |
| if( bNewNumList) |
| SkipGroup(); |
| else |
| ReadNumSecLevel( nToken ); |
| break; |
| } |
| |
| case RTF_PNTEXT: |
| case RTF_NONSHPPICT: |
| SkipGroup(); |
| break; |
| |
| case RTF_DEFFORMAT: |
| case RTF_DEFTAB: |
| case RTF_DEFLANG: |
| // sind zwar Dok-Controls, werden aber manchmal auch vor der |
| // Font/Style/Color-Tabelle gesetzt! |
| SvxRTFParser::NextToken( nToken ); |
| break; |
| |
| case RTF_PAGE: |
| if (pTableNode==NULL) { //#117410#: A \page command within a table is ignored by Word. |
| if (lcl_UsedPara(*pPam)) |
| InsertPara(); |
| CheckInsNewTblLine(); |
| pDoc->InsertPoolItem(*pPam, |
| SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE, RES_BREAK), 0); |
| } |
| break; |
| |
| case RTF_SECT: |
| ReadSectControls( nToken ); |
| break; |
| case RTF_CELL: |
| // --> OD 2008-12-22 #i83368# |
| mbReadCellWhileReadSwFly = bReadSwFly; |
| // <-- |
| if (CantUseTables()) |
| InsertPara(); |
| else |
| { |
| // Tabelle nicht mehr vorhanden ? |
| if (USHRT_MAX != nInsTblRow && !pTableNode) |
| NewTblLine(); // evt. Line copieren |
| GotoNextBox(); |
| } |
| break; |
| |
| case RTF_ROW: |
| bTrowdRead=false; |
| if (!CantUseTables()) |
| { |
| // aus der Line raus |
| m_nCurrentBox = 0; |
| pTableNode = 0; |
| // noch in der Tabelle drin? |
| SwNodeIndex& rIdx = pPam->GetPoint()->nNode; |
| const SwTableNode* pTblNd = rIdx.GetNode().FindTableNode(); |
| if( pTblNd ) |
| { |
| // search the end of this row |
| const SwStartNode* pBoxStt = |
| rIdx.GetNode().FindTableBoxStartNode(); |
| const SwTableBox* pBox = pTblNd->GetTable().GetTblBox( |
| pBoxStt->GetIndex() ); |
| const SwTableLine* pLn = pBox->GetUpper(); |
| pBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ]; |
| rIdx = *pBox->GetSttNd()->EndOfSectionNode(); |
| pPam->Move( fnMoveForward, fnGoNode ); |
| } |
| nInsTblRow = static_cast< sal_uInt16 >(GetOpenBrakets()); |
| SetPardTokenRead( sal_False ); |
| SwPaM aTmp(*pPam); |
| aTmp.Move( fnMoveBackward, fnGoNode ); |
| } |
| ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() ); |
| break; |
| |
| case RTF_INTBL: |
| if (!CantUseTables()) |
| { |
| if( !pTableNode ) // Tabelle nicht mehr vorhanden ? |
| { |
| if (RTF_TROWD != GetNextToken()) |
| NewTblLine(); // evt. Line copieren |
| SkipToken(-1); |
| } |
| else |
| { |
| // Crsr nicht mehr in der Tabelle ? |
| if( !pPam->GetNode()->FindTableNode() ) |
| { |
| // dann wieder in die letzte Box setzen |
| // (kann durch einlesen von Flys geschehen!) |
| pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode(); |
| pPam->Move( fnMoveBackward ); |
| } |
| } |
| } |
| break; |
| |
| case RTF_REVTBL: |
| ReadRevTbl(); |
| break; |
| |
| case RTF_REVISED: |
| pRedlineInsert = new SwFltRedline(nsRedlineType_t::REDLINE_INSERT, 0, DateTime(Date( 0 ), Time( 0 ))); |
| break; |
| |
| case RTF_DELETED: |
| pRedlineDelete = new SwFltRedline(nsRedlineType_t::REDLINE_DELETE, 0, DateTime(Date( 0 ), Time( 0 ))); |
| break; |
| |
| case RTF_REVAUTH: |
| { |
| sw::util::AuthorInfo aEntry( static_cast< sal_uInt16 >(nTokenValue) ); |
| sal_uInt16 nPos; |
| |
| if(pRedlineInsert) |
| { |
| if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos)) |
| { |
| if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos)) |
| { |
| pRedlineInsert->nAutorNo = pAuthor->nOurId; |
| } |
| } |
| } |
| } |
| break; |
| |
| case RTF_REVAUTHDEL: |
| { |
| sw::util::AuthorInfo aEntry( static_cast< short >(nTokenValue) ); |
| sal_uInt16 nPos; |
| |
| if(pRedlineDelete) |
| { |
| if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos)) |
| { |
| if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos)) |
| { |
| pRedlineDelete->nAutorNo = pAuthor->nOurId; |
| } |
| } |
| } |
| } |
| break; |
| |
| case RTF_REVDTTM: |
| if (pRedlineInsert != NULL) |
| pRedlineInsert->aStamp = sw::ms::DTTM2DateTime(nTokenValue); |
| |
| break; |
| |
| case RTF_REVDTTMDEL: |
| pRedlineDelete->aStamp = sw::ms::DTTM2DateTime(nTokenValue); |
| break; |
| |
| |
| case RTF_FLY_INPARA: |
| // \pard und plain ueberlesen ! |
| if( '}' != GetNextToken() && '}' != GetNextToken() ) |
| { |
| // Zeichengebundener Fly in Fly |
| ReadHeaderFooter( nToken ); |
| SetPardTokenRead( sal_False ); |
| } |
| break; |
| |
| case RTF_PGDSCNO: |
| if( IsNewDoc() && bSwPageDesc && |
| sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() ) |
| { |
| const SwPageDesc* pPgDsc = |
| &const_cast<const SwDoc *>(pDoc) |
| ->GetPageDesc( sal_uInt16(nTokenValue) ); |
| CheckInsNewTblLine(); |
| pDoc->InsertPoolItem(*pPam, SwFmtPageDesc( pPgDsc ), 0); |
| } |
| break; |
| |
| case RTF_COLUM: |
| pDoc->InsertPoolItem(*pPam, |
| SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0); |
| break; |
| |
| case RTF_DXFRTEXT: // werden nur im Zusammenhang mit Flys ausgewertet |
| case RTF_DFRMTXTX: |
| case RTF_DFRMTXTY: |
| break; |
| |
| case RTF_CHDATE: eDateFmt = DF_SHORT; goto SETCHDATEFIELD; |
| case RTF_CHDATEA: eDateFmt = DF_SSYS; goto SETCHDATEFIELD; |
| case RTF_CHDATEL: eDateFmt = DF_LSYS; goto SETCHDATEFIELD; |
| SETCHDATEFIELD: |
| { |
| sal_uInt16 nSubType = DATEFLD, nWhich = RES_DATEFLD; |
| sal_uLong nFormat = eDateFmt; |
| sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 ); |
| |
| SwDateTimeField aDateFld( (SwDateTimeFieldType*) |
| pDoc->GetSysFldType( RES_DATETIMEFLD ), DATEFLD, nFormat); |
| CheckInsNewTblLine(); |
| pDoc->InsertPoolItem(*pPam, SwFmtFld( aDateFld ), 0); |
| } |
| break; |
| |
| case RTF_CHTIME: |
| { |
| sal_uInt16 nSubType = TIMEFLD, nWhich = RES_TIMEFLD; |
| sal_uLong nFormat = TF_SSMM_24; |
| sw3io_ConvertFromOldField( *pDoc, nWhich, nSubType, nFormat, 0x0110 ); |
| SwDateTimeField aTimeFld( (SwDateTimeFieldType*) |
| pDoc->GetSysFldType( RES_DATETIMEFLD ), TIMEFLD, nFormat); |
| CheckInsNewTblLine(); |
| pDoc->InsertPoolItem(*pPam, SwFmtFld( aTimeFld ), 0); |
| } |
| break; |
| |
| case RTF_CHPGN: |
| { |
| SwPageNumberField aPageFld( (SwPageNumberFieldType*) |
| pDoc->GetSysFldType( RES_PAGENUMBERFLD ), |
| PG_RANDOM, SVX_NUM_ARABIC ); |
| CheckInsNewTblLine(); |
| pDoc->InsertPoolItem(*pPam, SwFmtFld(aPageFld), 0); |
| } |
| break; |
| |
| case RTF_CHFTN: |
| bFootnoteAutoNum = sal_True; |
| break; |
| |
| case RTF_NOFPAGES: |
| if( IsNewDoc() && nTokenValue && -1 != nTokenValue ) |
| ((SwDocStat&)pDoc->GetDocStat()).nPage = (sal_uInt16)nTokenValue; |
| break; |
| |
| case RTF_NOFWORDS: |
| if( IsNewDoc() && nTokenValue && -1 != nTokenValue ) |
| ((SwDocStat&)pDoc->GetDocStat()).nWord = (sal_uInt16)nTokenValue; |
| break; |
| case RTF_NOFCHARS: |
| if( IsNewDoc() && nTokenValue && -1 != nTokenValue ) |
| ((SwDocStat&)pDoc->GetDocStat()).nChar = (sal_uInt16)nTokenValue; |
| break; |
| case RTF_LYTPRTMET: |
| if (IsNewDoc()) |
| pDoc->set(IDocumentSettingAccess::USE_VIRTUAL_DEVICE, false); |
| break; |
| case RTF_U: |
| { |
| CheckInsNewTblLine(); |
| if( nTokenValue ) |
| aToken = (sal_Unicode )nTokenValue; |
| pDoc->InsertString( *pPam, aToken ); |
| } |
| break; |
| |
| case RTF_USERPROPS: |
| ReadUserProperties(); // #i28758 For now we don't support user properties |
| break; |
| |
| // RTF_SUBENTRYINDEX |
| |
| default: |
| switch( nToken & ~(0xff | RTF_SWGDEFS) ) |
| { |
| case RTF_DOCFMT: |
| ReadDocControls( nToken ); |
| break; |
| case RTF_SECTFMT: |
| ReadSectControls( nToken ); |
| break; |
| case RTF_APOCTL: |
| if (nReadFlyDepth < 10) |
| { |
| nReadFlyDepth++; |
| ReadFly( nToken ); |
| nReadFlyDepth--; |
| } |
| break; |
| |
| case RTF_BRDRDEF | RTF_TABLEDEF: |
| case RTF_SHADINGDEF | RTF_TABLEDEF: |
| case RTF_TABLEDEF: |
| ReadTable( nToken ); |
| break; |
| |
| case RTF_INFO: |
| ReadInfo(); |
| break; |
| |
| default: |
| if( USHRT_MAX != nInsTblRow && |
| (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() )) |
| nInsTblRow = USHRT_MAX; |
| |
| SvxRTFParser::NextToken( nToken ); |
| break; |
| } |
| } |
| if( USHRT_MAX != nInsTblRow && |
| (nInsTblRow > GetOpenBrakets() || IsPardTokenRead() )) |
| nInsTblRow = USHRT_MAX; |
| } |
| |
| |
| |
| void SwRTFParser::InsertText() |
| { |
| bContainsPara = false; |
| // dann fuege den String ein, ohne das Attribute am Ende |
| // aufgespannt werden. |
| CheckInsNewTblLine(); |
| |
| if(pRedlineInsert) |
| mpRedlineStack->open(*pPam->GetPoint(), *pRedlineInsert); |
| if(pRedlineDelete) |
| mpRedlineStack->open(*pPam->GetPoint(), *pRedlineDelete); |
| |
| pDoc->InsertString( *pPam, aToken ); |
| |
| if(pRedlineDelete) |
| { |
| mpRedlineStack->close(*pPam->GetPoint(), pRedlineDelete->eType); |
| } |
| |
| if(pRedlineInsert) |
| { |
| mpRedlineStack->close(*pPam->GetPoint(), pRedlineInsert->eType); |
| } |
| |
| |
| } |
| |
| |
| void SwRTFParser::InsertPara() |
| { |
| bContainsPara = true; |
| CheckInsNewTblLine(); |
| pDoc->AppendTxtNode(*pPam->GetPoint()); |
| |
| // setze das default Style |
| if( !bStyleTabValid ) |
| MakeStyleTab(); |
| |
| SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 ); |
| if( !pColl ) |
| pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); |
| pDoc->SetTxtFmtColl( *pPam, pColl ); |
| |
| ::SetProgressState( rInput.Tell(), pDoc->GetDocShell() ); |
| } |
| |
| |
| |
| void SwRTFParser::MovePos( int bForward ) |
| { |
| if( bForward ) |
| pPam->Move( fnMoveForward ); |
| else |
| pPam->Move( fnMoveBackward ); |
| } |
| |
| int SwRTFParser::IsEndPara( SvxNodeIdx* pNd, xub_StrLen nCnt ) const |
| { |
| SwCntntNode *pNode = pDoc->GetNodes()[pNd->GetIdx()]->GetCntntNode(); |
| return pNode && pNode->Len() == nCnt; |
| } |
| |
| bool SwRTFParser::UncompressableStackEntry(const SvxRTFItemStackType &rSet) |
| const |
| { |
| /* |
| #i21961# |
| Seeing as CHARFMT sets all the properties of the charfmt itself, its not |
| good enough to just see it as a single property from the point of |
| compressing property sets. If bold and charfmt are in a child, and bold is |
| in the parent, removing bold from the child will not result in the same |
| thing, if the charfmt removes bold itself for example |
| */ |
| bool bRet = false; |
| if (rSet.GetAttrSet().Count()) |
| { |
| |
| if (SFX_ITEM_SET == |
| rSet.GetAttrSet().GetItemState(RES_TXTATR_CHARFMT, sal_False)) |
| { |
| bRet = true; |
| } |
| } |
| return bRet; |
| } |
| |
| void SwRTFParser::SetEndPrevPara( SvxNodeIdx*& rpNodePos, xub_StrLen& rCntPos ) |
| { |
| SwNodeIndex aIdx( pPam->GetPoint()->nNode ); |
| SwCntntNode* pNode = pDoc->GetNodes().GoPrevious( &aIdx ); |
| if( !pNode ) |
| { |
| ASSERT( sal_False, "keinen vorherigen ContentNode gefunden" ); |
| } |
| |
| rpNodePos = new SwNodeIdx( aIdx ); |
| rCntPos = pNode->Len(); |
| } |
| |
| void SwRTFParser::SetAttrInDoc( SvxRTFItemStackType &rSet ) |
| { |
| sal_uLong nSNd = rSet.GetSttNodeIdx(), nENd = rSet.GetEndNodeIdx(); |
| xub_StrLen nSCnt = rSet.GetSttCnt(), nECnt = rSet.GetEndCnt(); |
| |
| SwPaM aPam( *pPam->GetPoint() ); |
| |
| #ifdef DBG_UTIL |
| ASSERT( nSNd <= nENd, "Start groesser als Ende" ); |
| SwNode* pDebugNd = pDoc->GetNodes()[ nSNd ]; |
| ASSERT( pDebugNd->IsCntntNode(), "Start kein ContentNode" ); |
| pDebugNd = pDoc->GetNodes()[ nENd ]; |
| ASSERT( pDebugNd->IsCntntNode(), "Ende kein ContentNode" ); |
| #endif |
| |
| SwCntntNode* pCNd = pDoc->GetNodes()[ nSNd ]->GetCntntNode(); |
| aPam.GetPoint()->nNode = nSNd; |
| aPam.GetPoint()->nContent.Assign( pCNd, nSCnt ); |
| aPam.SetMark(); |
| if( nENd == nSNd ) |
| aPam.GetPoint()->nContent = nECnt; |
| else |
| { |
| aPam.GetPoint()->nNode = nENd; |
| pCNd = aPam.GetCntntNode(); |
| aPam.GetPoint()->nContent.Assign( pCNd, nECnt ); |
| } |
| |
| // setze ueber den Bereich das entsprechende Style |
| if( rSet.StyleNo() ) |
| { |
| // setze jetzt das Style |
| if( !bStyleTabValid ) |
| MakeStyleTab(); |
| SwTxtFmtColl* pColl = aTxtCollTbl.Get( rSet.StyleNo() ); |
| if( pColl ) |
| pDoc->SetTxtFmtColl( aPam, pColl, false ); |
| } |
| |
| const SfxPoolItem* pItem; |
| const SfxPoolItem* pCharFmt; |
| if (rSet.GetAttrSet().Count() ) |
| { |
| |
| // falls eine Zeichenvorlage im Set steht, deren Attribute |
| // aus dem Set loeschen. Sonst sind diese doppelt, was man ja |
| // nicht will. |
| if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( |
| RES_TXTATR_CHARFMT, sal_False, &pCharFmt ) && |
| ((SwFmtCharFmt*)pCharFmt)->GetCharFmt() ) |
| { |
| const String& rName = ((SwFmtCharFmt*)pCharFmt)->GetCharFmt()->GetName(); |
| SvxRTFStyleType* pStyle = GetStyleTbl().First(); |
| do { |
| if( pStyle->bIsCharFmt && pStyle->sName == rName ) |
| { |
| // alle Attribute, die schon vom Style definiert sind, aus dem |
| // akt. AttrSet entfernen |
| SfxItemSet &rAttrSet = rSet.GetAttrSet(), |
| &rStyleSet = pStyle->aAttrSet; |
| SfxItemIter aIter( rAttrSet ); |
| sal_uInt16 nWhich = aIter.GetCurItem()->Which(); |
| while( sal_True ) |
| { |
| const SfxPoolItem* pI; |
| if( SFX_ITEM_SET == rStyleSet.GetItemState( |
| nWhich, sal_False, &pI ) && *pI == *aIter.GetCurItem()) |
| rAttrSet.ClearItem( nWhich ); // loeschen |
| |
| if( aIter.IsAtEnd() ) |
| break; |
| nWhich = aIter.NextItem()->Which(); |
| } |
| break; |
| } |
| } while( 0 != (pStyle = GetStyleTbl().Next()) ); |
| |
| pDoc->InsertPoolItem(aPam, *pCharFmt, 0); |
| rSet.GetAttrSet().ClearItem(RES_TXTATR_CHARFMT); //test hack |
| } |
| if (rSet.GetAttrSet().Count()) |
| { |
| // dann setze ueber diesen Bereich die Attrbiute |
| SetSwgValues(rSet.GetAttrSet()); |
| pDoc->InsertItemSet(aPam, rSet.GetAttrSet(), |
| nsSetAttrMode::SETATTR_DONTCHGNUMRULE); |
| } |
| } |
| |
| if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( |
| FN_PARAM_NUM_LEVEL, sal_False, &pItem )) |
| { |
| // dann ueber den Bereich an den Nodes das NodeNum setzen |
| for( sal_uLong n = nSNd; n <= nENd; ++n ) |
| { |
| SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode(); |
| if( pTxtNd ) |
| { |
| pTxtNd->SetAttrListLevel((sal_uInt8) ((SfxUInt16Item*)pItem)->GetValue()); |
| // Update vom LR-Space abschalten? |
| } |
| } |
| } |
| |
| if( SFX_ITEM_SET == rSet.GetAttrSet().GetItemState( |
| RES_PARATR_NUMRULE, sal_False, &pItem )) |
| { |
| const SwNumRule* pRule = pDoc->FindNumRulePtr( |
| ((SwNumRuleItem*)pItem)->GetValue() ); |
| if( pRule && ( pRule->IsContinusNum() || !bNewNumList )) |
| { |
| // diese Rule hat keinen Level, also muss die Einrueckung |
| // erhalten bleiben! |
| // dann ueber den Bereich an den Nodes das Flag zuruecksetzen |
| for( sal_uLong n = nSNd; n <= nENd; ++n ) |
| { |
| SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode(); |
| if( pTxtNd ) |
| { |
| // Update vom LR-Space abschalten |
| pTxtNd->SetNumLSpace( sal_False ); |
| } |
| } |
| } |
| } |
| |
| bool bNoNum = true; |
| if ( |
| (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(RES_PARATR_NUMRULE)) |
| || (SFX_ITEM_SET == rSet.GetAttrSet().GetItemState(FN_PARAM_NUM_LEVEL)) |
| ) |
| { |
| bNoNum = false; |
| } |
| |
| if (bNoNum) |
| { |
| for( sal_uLong n = nSNd; n <= nENd; ++n ) |
| { |
| SwTxtNode* pTxtNd = pDoc->GetNodes()[ n ]->GetTxtNode(); |
| if( pTxtNd ) |
| { |
| pTxtNd->SetAttr( *GetDfltAttr(RES_PARATR_NUMRULE) ); |
| // reset all list attributes |
| pTxtNd->ResetAttr( RES_PARATR_LIST_LEVEL ); |
| pTxtNd->ResetAttr( RES_PARATR_LIST_ISRESTART ); |
| pTxtNd->ResetAttr( RES_PARATR_LIST_RESTARTVALUE ); |
| pTxtNd->ResetAttr( RES_PARATR_LIST_ISCOUNTED ); |
| pTxtNd->ResetAttr( RES_PARATR_LIST_ID ); |
| } |
| } |
| } |
| } |
| |
| DocPageInformation::DocPageInformation() |
| : maBox( RES_BOX ), |
| mnPaperw(12240), mnPaperh(15840), mnMargl(1800), mnMargr(1800), |
| mnMargt(1440), mnMargb(1440), mnGutter(0), mnPgnStart(1), mbFacingp(false), |
| mbLandscape(false), mbRTLdoc(false) |
| { |
| } |
| |
| SectPageInformation::SectPageInformation(const DocPageInformation &rDoc) |
| : maBox(rDoc.maBox), mpTitlePageHdFt(0), mpPageHdFt(0), |
| mnPgwsxn(rDoc.mnPaperw), mnPghsxn(rDoc.mnPaperh), mnMarglsxn(rDoc.mnMargl), |
| mnMargrsxn(rDoc.mnMargr), mnMargtsxn(rDoc.mnMargt), |
| mnMargbsxn(rDoc.mnMargb), mnGutterxsn(rDoc.mnGutter), mnHeadery(720), |
| mnFootery(720), mnPgnStarts(rDoc.mnPgnStart), mnCols(1), mnColsx(720), |
| mnStextflow(rDoc.mbRTLdoc ? 3 : 0), mnBkc(2), mbLndscpsxn(rDoc.mbLandscape), |
| mbTitlepg(false), mbFacpgsxn(rDoc.mbFacingp), mbRTLsection(rDoc.mbRTLdoc), |
| mbPgnrestart(false), mbTitlePageHdFtUsed(false), mbPageHdFtUsed(false) |
| { |
| }; |
| |
| SectPageInformation::SectPageInformation(const SectPageInformation &rSect) |
| : maColumns(rSect.maColumns), maBox(rSect.maBox), |
| maNumType(rSect.maNumType), mpTitlePageHdFt(rSect.mpTitlePageHdFt), |
| mpPageHdFt(rSect.mpPageHdFt), mnPgwsxn(rSect.mnPgwsxn), |
| mnPghsxn(rSect.mnPghsxn), mnMarglsxn(rSect.mnMarglsxn), |
| mnMargrsxn(rSect.mnMargrsxn), mnMargtsxn(rSect.mnMargtsxn), |
| mnMargbsxn(rSect.mnMargbsxn), mnGutterxsn(rSect.mnGutterxsn), |
| mnHeadery(rSect.mnHeadery), mnFootery(rSect.mnFootery), |
| mnPgnStarts(rSect.mnPgnStarts), mnCols(rSect.mnCols), |
| mnColsx(rSect.mnColsx), mnStextflow(rSect.mnStextflow), mnBkc(rSect.mnBkc), |
| mbLndscpsxn(rSect.mbLndscpsxn), mbTitlepg(rSect.mbTitlepg), |
| mbFacpgsxn(rSect.mbFacpgsxn), mbRTLsection(rSect.mbRTLsection), |
| mbPgnrestart(rSect.mbPgnrestart), |
| mbTitlePageHdFtUsed(rSect.mbTitlePageHdFtUsed), |
| mbPageHdFtUsed(rSect.mbPageHdFtUsed) |
| { |
| }; |
| |
| rtfSection::rtfSection(const SwPosition &rPos, |
| const SectPageInformation &rPageInfo) |
| : maStart(rPos.nNode), maPageInfo(rPageInfo), mpSection(0), mpTitlePage(0), |
| mpPage(0) |
| { |
| } |
| |
| void rtfSections::push_back(const rtfSection &rSect) |
| { |
| if (!maSegments.empty() && (maSegments.back().maStart == rSect.maStart)) |
| maSegments.pop_back(); |
| maSegments.push_back(rSect); |
| } |
| |
| // lese alle Dokument-Controls ein |
| void SwRTFParser::SetPageInformationAsDefault(const DocPageInformation &rInfo) |
| { |
| //If we are at the beginning of the document then start the document with |
| //a segment with these properties. See #i14982# for this requirement |
| rtfSection aSect(*pPam->GetPoint(), SectPageInformation(rInfo)); |
| if (maSegments.empty() || (maSegments.back().maStart == aSect.maStart)) |
| maSegments.push_back(aSect); |
| |
| if (!bSwPageDesc && IsNewDoc()) |
| { |
| SwFmtFrmSize aFrmSize(ATT_FIX_SIZE, rInfo.mnPaperw, rInfo.mnPaperh); |
| |
| SvxLRSpaceItem aLR( static_cast< sal_uInt16 >(rInfo.mnMargl), static_cast< sal_uInt16 >(rInfo.mnMargr), 0, 0, RES_LR_SPACE ); |
| SvxULSpaceItem aUL( static_cast< sal_uInt16 >(rInfo.mnMargt), static_cast< sal_uInt16 >(rInfo.mnMargb), RES_UL_SPACE ); |
| |
| UseOnPage eUseOn; |
| if (rInfo.mbFacingp) |
| eUseOn = UseOnPage(nsUseOnPage::PD_MIRROR | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE); |
| else |
| eUseOn = UseOnPage(nsUseOnPage::PD_ALL | nsUseOnPage::PD_HEADERSHARE | nsUseOnPage::PD_FOOTERSHARE); |
| |
| sal_uInt16 nPgStart = static_cast< sal_uInt16 >(rInfo.mnPgnStart); |
| |
| SvxFrameDirectionItem aFrmDir(rInfo.mbRTLdoc ? |
| FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR); |
| |
| // direkt an der Standartseite drehen |
| SwPageDesc& rPg = pDoc->_GetPageDesc( 0 ); |
| rPg.WriteUseOn( eUseOn ); |
| |
| if (rInfo.mbLandscape) |
| rPg.SetLandscape(true); |
| |
| SwFrmFmt &rFmt1 = rPg.GetMaster(), &rFmt2 = rPg.GetLeft(); |
| |
| rFmt1.SetFmtAttr( aFrmSize ); rFmt2.SetFmtAttr( aFrmSize ); |
| rFmt1.SetFmtAttr( aLR ); rFmt2.SetFmtAttr( aLR ); |
| rFmt1.SetFmtAttr( aUL ); rFmt2.SetFmtAttr( aUL ); |
| rFmt1.SetFmtAttr( aFrmDir ); rFmt2.SetFmtAttr( aFrmDir ); |
| |
| // StartNummer der Seiten setzen |
| if (nPgStart != 1) |
| { |
| SwFmtPageDesc aPgDsc( &rPg ); |
| aPgDsc.SetNumOffset( nPgStart ); |
| pDoc->InsertPoolItem( *pPam, aPgDsc, 0 ); |
| } |
| } |
| } |
| |
| void SwRTFParser::SetBorderLine(SvxBoxItem& rBox, sal_uInt16 nLine) |
| { |
| int bWeiter = true; |
| short nLineThickness = 1; |
| short nPageDistance = 0; |
| sal_uInt8 nCol = 0; |
| short nIdx = 0; |
| |
| int nToken = GetNextToken(); |
| do { |
| switch( nToken ) |
| { |
| case RTF_BRDRS: |
| nIdx = 1; |
| break; |
| |
| case RTF_BRDRDB: |
| nIdx = 3; |
| break; |
| |
| case RTF_BRDRTRIPLE: |
| nIdx = 10; |
| break; |
| |
| case RTF_BRDRTNTHSG: |
| nIdx = 11; |
| break; |
| |
| case RTF_BRDRTHTNSG: |
| nIdx = 12; |
| break; |
| |
| case RTF_BRDRTNTHTNSG: |
| nIdx = 13; |
| break; |
| |
| case RTF_BRDRTNTHMG: |
| nIdx = 14; |
| break; |
| |
| case RTF_BRDRTHTNMG: |
| nIdx = 15; |
| break; |
| |
| case RTF_BRDRTNTHTNMG: |
| nIdx = 16; |
| break; |
| |
| case RTF_BRDRTNTHLG: |
| nIdx = 17; |
| break; |
| |
| case RTF_BRDRTHTNLG: |
| nIdx = 18; |
| break; |
| |
| case RTF_BRDRTNTHTNLG: |
| nIdx = 19; |
| break; |
| |
| case RTF_BRDRWAVY: |
| nIdx = 20; |
| break; |
| |
| case RTF_BRDRWAVYDB: |
| nIdx = 21; |
| break; |
| |
| case RTF_BRDREMBOSS: |
| nIdx = 24; |
| break; |
| |
| case RTF_BRDRENGRAVE: |
| nIdx = 25; |
| break; |
| |
| case RTF_BRSP: |
| nPageDistance = static_cast< short >(nTokenValue); |
| break; |
| |
| case RTF_BRDRDOT: // SO does not have dashed or dotted lines |
| case RTF_BRDRDASH: |
| case RTF_BRDRDASHSM: |
| case RTF_BRDRDASHD: |
| case RTF_BRDRDASHDD: |
| case RTF_BRDRDASHDOTSTR: |
| case RTF_BRDRSH: // shading not supported |
| case RTF_BRDRCF: // colors not supported |
| break; |
| |
| case RTF_BRDRW: |
| nLineThickness = static_cast< short >(nTokenValue); |
| break; |
| default: |
| bWeiter = false; |
| SkipToken(-1); |
| break; |
| } |
| if (bWeiter) |
| nToken = GetNextToken(); |
| } while (bWeiter && IsParserWorking()); |
| |
| GetLineIndex(rBox, nLineThickness, nPageDistance, nCol, nIdx, nLine, nLine, 0); |
| } |
| |
| // lese alle Dokument-Controls ein |
| void SwRTFParser::ReadDocControls( int nToken ) |
| { |
| int bWeiter = true; |
| |
| SwFtnInfo aFtnInfo; |
| SwEndNoteInfo aEndInfo; |
| bool bSetHyph = false; |
| |
| sal_Bool bEndInfoChgd = sal_False, bFtnInfoChgd = sal_False; |
| |
| do { |
| sal_uInt16 nValue = sal_uInt16( nTokenValue ); |
| switch( nToken ) |
| { |
| case RTF_RTLDOC: |
| maPageDefaults.mbRTLdoc = true; |
| break; |
| case RTF_LTRDOC: |
| maPageDefaults.mbRTLdoc = false; |
| break; |
| case RTF_LANDSCAPE: |
| maPageDefaults.mbLandscape = true; |
| break; |
| case RTF_PAPERW: |
| if( 0 < nTokenValue ) |
| maPageDefaults.mnPaperw = nTokenValue; |
| break; |
| case RTF_PAPERH: |
| if( 0 < nTokenValue ) |
| maPageDefaults.mnPaperh = nTokenValue; |
| break; |
| case RTF_MARGL: |
| if( 0 <= nTokenValue ) |
| maPageDefaults.mnMargl = nTokenValue; |
| break; |
| case RTF_MARGR: |
| if( 0 <= nTokenValue ) |
| maPageDefaults.mnMargr = nTokenValue; |
| break; |
| case RTF_MARGT: |
| if( 0 <= nTokenValue ) |
| maPageDefaults.mnMargt = nTokenValue; |
| break; |
| case RTF_MARGB: |
| if( 0 <= nTokenValue ) |
| maPageDefaults.mnMargb = nTokenValue; |
| break; |
| case RTF_FACINGP: |
| maPageDefaults.mbFacingp = true; |
| break; |
| case RTF_PGNSTART: |
| maPageDefaults.mnPgnStart = nTokenValue; |
| break; |
| case RTF_ENDDOC: |
| case RTF_ENDNOTES: |
| aFtnInfo.ePos = FTNPOS_CHAPTER; bFtnInfoChgd = sal_True; |
| break; |
| case RTF_FTNTJ: |
| case RTF_FTNBJ: |
| aFtnInfo.ePos = FTNPOS_PAGE; bFtnInfoChgd = sal_True; |
| break; |
| |
| case RTF_AENDDOC: |
| case RTF_AENDNOTES: |
| case RTF_AFTNTJ: |
| case RTF_AFTNBJ: |
| case RTF_AFTNRESTART: |
| case RTF_AFTNRSTCONT: |
| break; // wir kenn nur am Doc Ende und Doc weite Num.! |
| |
| case RTF_FTNSTART: |
| if( nValue ) |
| { |
| aFtnInfo.nFtnOffset = nValue-1; |
| bFtnInfoChgd = sal_True; |
| } |
| break; |
| case RTF_AFTNSTART: |
| if( nValue ) |
| { |
| aEndInfo.nFtnOffset = nValue-1; |
| bEndInfoChgd = sal_True; |
| } |
| break; |
| case RTF_FTNRSTPG: |
| aFtnInfo.eNum = FTNNUM_PAGE; bFtnInfoChgd = sal_True; |
| break; |
| case RTF_FTNRESTART: |
| aFtnInfo.eNum = FTNNUM_CHAPTER; bFtnInfoChgd = sal_True; |
| break; |
| case RTF_FTNRSTCONT: |
| aFtnInfo.eNum = FTNNUM_DOC; bFtnInfoChgd = sal_True; |
| break; |
| |
| case RTF_FTNNAR: |
| aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bFtnInfoChgd = sal_True; break; |
| case RTF_FTNNALC: |
| aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); bFtnInfoChgd = sal_True; break; |
| case RTF_FTNNAUC: |
| aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); bFtnInfoChgd = sal_True; break; |
| case RTF_FTNNRLC: |
| aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); bFtnInfoChgd = sal_True; break; |
| case RTF_FTNNRUC: |
| aFtnInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); bFtnInfoChgd = sal_True; break; |
| case RTF_FTNNCHI: |
| aFtnInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); bFtnInfoChgd = sal_True; break; |
| |
| case RTF_AFTNNAR: |
| aEndInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC); bEndInfoChgd = sal_True; break; |
| case RTF_AFTNNALC: |
| aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER_N); |
| bEndInfoChgd = sal_True; |
| break; |
| case RTF_AFTNNAUC: |
| aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_UPPER_LETTER_N); |
| bEndInfoChgd = sal_True; |
| break; |
| case RTF_AFTNNRLC: |
| aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER); |
| bEndInfoChgd = sal_True; |
| break; |
| case RTF_AFTNNRUC: |
| aEndInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_UPPER); |
| bEndInfoChgd = sal_True; |
| break; |
| case RTF_AFTNNCHI: |
| aEndInfo.aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL); |
| bEndInfoChgd = sal_True; |
| break; |
| case RTF_HYPHAUTO: |
| if (nTokenValue) |
| bSetHyph = true; |
| //FOO// |
| break; |
| case RTF_PGBRDRT: |
| SetBorderLine(maPageDefaults.maBox, BOX_LINE_TOP); |
| break; |
| |
| case RTF_PGBRDRB: |
| SetBorderLine(maPageDefaults.maBox, BOX_LINE_BOTTOM); |
| break; |
| |
| case RTF_PGBRDRL: |
| SetBorderLine(maPageDefaults.maBox, BOX_LINE_LEFT); |
| break; |
| |
| case RTF_PGBRDRR: |
| SetBorderLine(maPageDefaults.maBox, BOX_LINE_RIGHT); |
| break; |
| |
| case '{': |
| { |
| short nSkip = 0; |
| if( RTF_IGNOREFLAG != GetNextToken() ) |
| nSkip = -1; |
| else if( RTF_DOCFMT != (( nToken = GetNextToken() ) |
| & ~(0xff | RTF_SWGDEFS)) ) |
| nSkip = -2; |
| else |
| { |
| SkipGroup(); // erstmal komplett ueberlesen |
| // ueberlese noch die schliessende Klammer |
| GetNextToken(); |
| } |
| if( nSkip ) |
| { |
| SkipToken( nSkip ); // Ignore wieder zurueck |
| bWeiter = sal_False; |
| } |
| } |
| break; |
| |
| default: |
| if( RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS)) || |
| RTF_UNKNOWNCONTROL == nToken ) |
| SvxRTFParser::NextToken( nToken ); |
| else |
| bWeiter = sal_False; |
| break; |
| } |
| if( bWeiter ) |
| nToken = GetNextToken(); |
| } while( bWeiter && IsParserWorking() ); |
| |
| if (IsNewDoc()) |
| { |
| if( bEndInfoChgd ) |
| pDoc->SetEndNoteInfo( aEndInfo ); |
| if( bFtnInfoChgd ) |
| pDoc->SetFtnInfo( aFtnInfo ); |
| } |
| |
| if (!bSwPageDesc) |
| { |
| SetPageInformationAsDefault(maPageDefaults); |
| |
| MakeStyleTab(); |
| |
| SwTxtFmtColl* pColl = aTxtCollTbl.Get(0); |
| if (!pColl) |
| { |
| pColl = pDoc->GetTxtCollFromPool(RES_POOLCOLL_STANDARD, false ); |
| } |
| |
| ASSERT(pColl, "impossible to have no standard style"); |
| |
| if (pColl) |
| { |
| if ( |
| IsNewDoc() && bSetHyph && |
| SFX_ITEM_SET != pColl->GetItemState(RES_PARATR_HYPHENZONE, |
| false) |
| ) |
| { |
| pColl->SetFmtAttr(SvxHyphenZoneItem(true, RES_PARATR_HYPHENZONE)); |
| } |
| |
| pDoc->SetTxtFmtColl( *pPam, pColl ); |
| } |
| } |
| |
| SkipToken( -1 ); |
| } |
| |
| void SwRTFParser::MakeStyleTab() |
| { |
| // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections |
| if( GetStyleTbl().Count() ) |
| { |
| sal_uInt16 nValidOutlineLevels = 0; |
| if( !IsNewDoc() ) |
| { |
| // search all outlined collections |
| //sal_uInt8 nLvl; |
| const SwTxtFmtColls& rColls = *pDoc->GetTxtFmtColls(); |
| for( sal_uInt16 n = rColls.Count(); n; ) |
| //if( MAXLEVEL > (nLvl = rColls[ --n ]->GetOutlineLevel() ))//#outline level,zhaojianwei |
| // nValidOutlineLevels |= 1 << nLvl; |
| if( rColls[ --n ]->IsAssignedToListLevelOfOutlineStyle()) |
| nValidOutlineLevels |= 1 << rColls[ n ]->GetAssignedOutlineStyleLevel();//<-end,zhaojianwei |
| } |
| |
| SvxRTFStyleType* pStyle = GetStyleTbl().First(); |
| do { |
| sal_uInt16 nNo = sal_uInt16( GetStyleTbl().GetCurKey() ); |
| if( pStyle->bIsCharFmt ) |
| { |
| if( !aCharFmtTbl.Get( nNo ) ) |
| // existiert noch nicht, also anlegen |
| MakeCharStyle( nNo, *pStyle ); |
| } |
| else if( !aTxtCollTbl.Get( nNo ) ) |
| { |
| // existiert noch nicht, also anlegen |
| MakeStyle( nNo, *pStyle ); |
| } |
| |
| } while( 0 != (pStyle = GetStyleTbl().Next()) ); |
| bStyleTabValid = sal_True; |
| } |
| } |
| |
| sal_Bool lcl_SetFmtCol( SwFmt& rFmt, sal_uInt16 nCols, sal_uInt16 nColSpace, |
| const SvUShorts& rColumns ) |
| { |
| sal_Bool bSet = sal_False; |
| if( nCols && USHRT_MAX != nCols ) |
| { |
| SwFmtCol aCol; |
| if( USHRT_MAX == nColSpace ) |
| nColSpace = 720; |
| |
| aCol.Init( nCols, nColSpace, USHRT_MAX ); |
| if( nCols == ( rColumns.Count() / 2 ) ) |
| { |
| aCol._SetOrtho( sal_False ); |
| sal_uInt16 nWishWidth = 0, nHalfPrev = 0; |
| for (sal_uInt16 n = 0, i = 0; (n+1) < rColumns.Count(); n += 2, ++i) |
| { |
| SwColumn* pCol = aCol.GetColumns()[ i ]; |
| pCol->SetLeft( nHalfPrev ); |
| sal_uInt16 nSp = rColumns[ n+1 ]; |
| nHalfPrev = nSp / 2; |
| pCol->SetRight( nSp - nHalfPrev ); |
| pCol->SetWishWidth( rColumns[ n ] + |
| pCol->GetLeft() + pCol->GetRight() ); |
| nWishWidth = nWishWidth + pCol->GetWishWidth(); |
| } |
| aCol.SetWishWidth( nWishWidth ); |
| } |
| rFmt.SetFmtAttr( aCol ); |
| bSet = sal_True; |
| } |
| return bSet; |
| } |
| |
| void SwRTFParser::DoHairyWriterPageDesc(int nToken) |
| { |
| int bWeiter = sal_True; |
| do { |
| if( '{' == nToken ) |
| { |
| switch( nToken = GetNextToken() ) |
| { |
| case RTF_IGNOREFLAG: |
| if( RTF_SECTFMT != (( nToken = GetNextToken() ) |
| & ~(0xff | RTF_SWGDEFS)) ) |
| { |
| SkipToken( -2 ); // Ignore und Token wieder zurueck |
| bWeiter = sal_False; |
| break; |
| } |
| // kein break, Gruppe ueberspringen |
| |
| case RTF_FOOTER: |
| case RTF_HEADER: |
| case RTF_FOOTERR: |
| case RTF_HEADERR: |
| case RTF_FOOTERL: |
| case RTF_HEADERL: |
| case RTF_FOOTERF: |
| case RTF_HEADERF: |
| SkipGroup(); // erstmal komplett ueberlesen |
| // ueberlese noch die schliessende Klammer |
| GetNextToken(); |
| break; |
| |
| default: |
| SkipToken( -1 ); // Ignore wieder zurueck |
| bWeiter = sal_False; |
| break; |
| } |
| } |
| else if( RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) || |
| RTF_UNKNOWNCONTROL == nToken ) |
| SvxRTFParser::NextToken( nToken ); |
| else |
| bWeiter = sal_False; |
| if( bWeiter ) |
| nToken = GetNextToken(); |
| } while( bWeiter && IsParserWorking() ); |
| SkipToken( -1 ); // letztes Token wieder zurueck |
| return; |
| } |
| |
| void SwRTFParser::ReadSectControls( int nToken ) |
| { |
| //this is some hairy stuff to try and retain writer style page descriptors |
| //in rtf, almost certainy a bad idea, but we've inherited it, so here it |
| //stays |
| if (bInPgDscTbl) |
| { |
| DoHairyWriterPageDesc(nToken); |
| return; |
| } |
| |
| ASSERT(!maSegments.empty(), "suspicious to have a section with no " |
| "page info, though probably legal"); |
| if (maSegments.empty()) |
| { |
| maSegments.push_back(rtfSection(*pPam->GetPoint(), |
| SectPageInformation(maPageDefaults))); |
| } |
| |
| SectPageInformation aNewSection(maSegments.back().maPageInfo); |
| |
| bool bNewSection = false; |
| bool bNewSectionHeader = false; |
| const SwFmtHeader* _pKeepHeader = NULL; |
| const SwFmtFooter* _pKeepFooter = NULL; |
| int bWeiter = true; |
| bool bKeepFooter = false; |
| do { |
| sal_uInt16 nValue = sal_uInt16( nTokenValue ); |
| switch( nToken ) |
| { |
| case RTF_SECT: |
| bNewSection = true; |
| bForceNewTable = true; // #117882# |
| break; |
| case RTF_SECTD: { |
| //Reset to page defaults |
| SwPageDesc* oldPageDesc=aNewSection.mpPageHdFt; |
| aNewSection = SectPageInformation(maPageDefaults); |
| aNewSection.mpPageHdFt=oldPageDesc; |
| _pKeepHeader = NULL; |
| _pKeepFooter = NULL; |
| } break; |
| case RTF_PGWSXN: |
| if (0 < nTokenValue) |
| aNewSection.mnPgwsxn = nTokenValue; |
| break; |
| case RTF_PGHSXN: |
| if (0 < nTokenValue) |
| aNewSection.mnPghsxn = nTokenValue; |
| break; |
| case RTF_MARGLSXN: |
| if (0 <= nTokenValue) |
| aNewSection.mnMarglsxn = nTokenValue; |
| break; |
| case RTF_MARGRSXN: |
| if (0 <= nTokenValue) |
| aNewSection.mnMargrsxn = nTokenValue; |
| break; |
| case RTF_MARGTSXN: |
| if (0 <= nTokenValue) |
| aNewSection.mnMargtsxn = nTokenValue; |
| break; |
| case RTF_MARGBSXN: |
| if (0 <= nTokenValue) |
| aNewSection.mnMargbsxn = nTokenValue; |
| break; |
| case RTF_FACPGSXN: |
| aNewSection.mbFacpgsxn = true; |
| break; |
| case RTF_HEADERY: |
| aNewSection.mnHeadery = nTokenValue; |
| break; |
| case RTF_FOOTERY: |
| aNewSection.mnFootery = nTokenValue; |
| break; |
| case RTF_LNDSCPSXN: |
| aNewSection.mbLndscpsxn = true; |
| break; |
| case RTF_PGNSTARTS: |
| aNewSection.mnPgnStarts = nTokenValue; |
| break; |
| case RTF_PGNDEC: |
| aNewSection.maNumType.SetNumberingType(SVX_NUM_ARABIC); |
| break; |
| case RTF_PGNUCRM: |
| aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_UPPER); |
| break; |
| case RTF_PGNLCRM: |
| aNewSection.maNumType.SetNumberingType(SVX_NUM_ROMAN_LOWER); |
| break; |
| case RTF_PGNUCLTR: |
| aNewSection.maNumType.SetNumberingType( |
| SVX_NUM_CHARS_UPPER_LETTER_N); |
| break; |
| case RTF_PGNLCLTR: |
| aNewSection.maNumType.SetNumberingType( |
| SVX_NUM_CHARS_LOWER_LETTER_N); |
| break; |
| case RTF_SBKNONE: |
| aNewSection.mnBkc = 0; |
| break; |
| case RTF_SBKCOL: |
| aNewSection.mnBkc = 1; |
| break; |
| case RTF_PGBRDRT: |
| SetBorderLine(aNewSection.maBox, BOX_LINE_TOP); |
| break; |
| |
| case RTF_PGBRDRB: |
| SetBorderLine(aNewSection.maBox, BOX_LINE_BOTTOM); |
| break; |
| |
| case RTF_PGBRDRL: |
| SetBorderLine(aNewSection.maBox, BOX_LINE_LEFT); |
| break; |
| |
| case RTF_PGBRDRR: |
| SetBorderLine(aNewSection.maBox, BOX_LINE_RIGHT); |
| break; |
| |
| case RTF_PGBRDROPT: |
| case RTF_ENDNHERE: |
| case RTF_BINFSXN: |
| case RTF_BINSXN: |
| case RTF_SBKPAGE: |
| case RTF_SBKEVEN: |
| case RTF_SBKODD: |
| case RTF_LINEBETCOL: |
| case RTF_LINEMOD: |
| case RTF_LINEX: |
| case RTF_LINESTARTS: |
| case RTF_LINERESTART: |
| case RTF_LINEPAGE: |
| case RTF_LINECONT: |
| case RTF_GUTTERSXN: |
| case RTF_PGNCONT: |
| case RTF_PGNRESTART: |
| case RTF_PGNX: |
| case RTF_PGNY: |
| case RTF_VERTALT: |
| case RTF_VERTALB: |
| case RTF_VERTALC: |
| case RTF_VERTALJ: |
| break; |
| case RTF_TITLEPG: |
| aNewSection.mbTitlepg = true; |
| break; |
| case RTF_HEADER: |
| case RTF_HEADERL: |
| case RTF_HEADERR: |
| if (aNewSection.mpPageHdFt!=NULL) |
| { |
| _pKeepHeader = NULL; |
| bKeepFooter = true; // #i82008 |
| _pKeepFooter = &aNewSection.mpPageHdFt->GetMaster().GetFooter(); |
| } |
| case RTF_FOOTER: |
| case RTF_FOOTERL: |
| case RTF_FOOTERR: |
| if (aNewSection.mpPageHdFt!=NULL && !bKeepFooter ) |
| { |
| _pKeepFooter = NULL; |
| _pKeepHeader = &aNewSection.mpPageHdFt->GetMaster().GetHeader(); |
| } |
| bKeepFooter = false; |
| if (!bNewSectionHeader) { //see #117914# topic 2). If a header is redefined in a section |
| bNewSectionHeader=true; // a new header must be created. |
| aNewSection.mpPageHdFt=NULL; |
| } |
| if (!aNewSection.mpPageHdFt) |
| { |
| String aName(RTL_CONSTASCII_STRINGPARAM("rtfHdFt")); |
| aName += String::CreateFromInt32(maSegments.size()); |
| sal_uInt16 nPageNo = pDoc->MakePageDesc(aName); |
| aNewSection.mpPageHdFt = &pDoc->_GetPageDesc(nPageNo); |
| aNewSection.mbPageHdFtUsed = true; |
| maSegments.maDummyPageNos.push_back(nPageNo); |
| } |
| ReadHeaderFooter(nToken, aNewSection.mpPageHdFt); |
| if (_pKeepHeader) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepHeader); |
| if (_pKeepFooter) aNewSection.mpPageHdFt->GetMaster().SetFmtAttr(*_pKeepFooter); |
| break; |
| case RTF_FOOTERF: |
| case RTF_HEADERF: |
| if (!aNewSection.mpTitlePageHdFt) |
| { |
| String aTitle(RTL_CONSTASCII_STRINGPARAM("rtfTitleHdFt")); |
| aTitle += String::CreateFromInt32(maSegments.size()); |
| sal_uInt16 nPageNo = pDoc->MakePageDesc(aTitle); |
| aNewSection.mpTitlePageHdFt = &pDoc->_GetPageDesc(nPageNo); |
| aNewSection.mbTitlePageHdFtUsed = true; |
| maSegments.maDummyPageNos.push_back(nPageNo); |
| } |
| ReadHeaderFooter(nToken, aNewSection.mpTitlePageHdFt); |
| break; |
| case RTF_COLS: |
| aNewSection.mnCols = nTokenValue; |
| break; |
| case RTF_COLSX: |
| aNewSection.mnColsx = nTokenValue; |
| break; |
| case RTF_COLNO: |
| { |
| // next token must be either colw or colsr |
| unsigned long nAktCol = nValue; |
| long nWidth = 0, nSpace = 0; |
| int nColToken = GetNextToken(); |
| if (RTF_COLW == nColToken) |
| { |
| // next token could be colsr (but not required) |
| nWidth = nTokenValue; |
| if( RTF_COLSR == GetNextToken() ) |
| nSpace = nTokenValue; |
| else |
| SkipToken( -1 ); // put back token |
| } |
| else if (RTF_COLSR == nColToken) |
| { |
| // next token must be colw (what sense should it make to have colsr only?!) |
| nSpace = nTokenValue; |
| if( RTF_COLW == GetNextToken() ) |
| nWidth = nTokenValue; |
| else |
| // what should we do if an isolated colsr without colw is found? Doesn't make sense! |
| SkipToken( -1 ); // put back token |
| } |
| else |
| break; |
| |
| if (--nAktCol == (aNewSection.maColumns.size() / 2)) |
| { |
| aNewSection.maColumns.push_back(nWidth); |
| aNewSection.maColumns.push_back(nSpace); |
| } |
| } |
| break; |
| case RTF_STEXTFLOW: |
| aNewSection.mnStextflow = nTokenValue; |
| break; |
| case RTF_RTLSECT: |
| aNewSection.mbRTLsection = true; |
| break; |
| case RTF_LTRSECT: |
| aNewSection.mbRTLsection = false; |
| break; |
| case '{': |
| { |
| short nSkip = 0; |
| if( RTF_IGNOREFLAG != ( nToken = GetNextToken() )) |
| nSkip = -1; |
| else if( RTF_SECTFMT != (( nToken = GetNextToken() ) |
| & ~(0xff | RTF_SWGDEFS)) && |
| ( RTF_DOCFMT != ( nToken & ~(0xff | RTF_SWGDEFS))) ) |
| nSkip = -2; |
| else |
| { |
| // erstmal komplett ueberlesen |
| SkipGroup(); |
| // ueberlese noch die schliessende Klammer |
| GetNextToken(); |
| } |
| if (nSkip) |
| { |
| bWeiter = ((-1 == nSkip) && |
| ( |
| RTF_FOOTER == nToken || RTF_HEADER == nToken || |
| RTF_FOOTERR == nToken || RTF_HEADERR == nToken || |
| RTF_FOOTERL == nToken || RTF_HEADERL == nToken || |
| RTF_FOOTERF == nToken || RTF_HEADERF == nToken |
| )); |
| SkipToken (nSkip); // Ignore wieder zurueck |
| } |
| } |
| break; |
| case RTF_PAPERW: |
| case RTF_PAPERH: |
| case RTF_MARGL: |
| case RTF_MARGR: |
| case RTF_MARGT: |
| case RTF_MARGB: |
| case RTF_FACINGP: |
| ASSERT(!this, "why are these tokens found in this section?"); |
| ReadDocControls( nToken ); |
| break; |
| default: |
| if (RTF_DOCFMT == (nToken & ~(0xff | RTF_SWGDEFS))) |
| ReadDocControls( nToken ); |
| else if (RTF_SECTFMT == (nToken & ~(0xff | RTF_SWGDEFS)) || |
| RTF_UNKNOWNCONTROL == nToken) |
| { |
| SvxRTFParser::NextToken(nToken); |
| } |
| else |
| bWeiter = false; |
| break; |
| } |
| |
| if (bWeiter) |
| nToken = GetNextToken(); |
| } while (bWeiter && IsParserWorking()); |
| |
| if (bNewSection || maSegments.empty()) |
| { |
| AttrGroupEnd(); //#106493# |
| if(!bContainsPara && !bContainsTablePara) //#117881#: bContainsTablePara is set in rtftbl.cxx |
| pDoc->AppendTxtNode(*pPam->GetPoint()); |
| bContainsPara = false; |
| bContainsTablePara = false; |
| maSegments.push_back(rtfSection(*pPam->GetPoint(), aNewSection)); |
| } |
| else //modifying/replacing the current section |
| { |
| SwPaM aPamStart(maSegments.back().maStart); |
| maSegments.pop_back(); |
| maSegments.push_back(rtfSection(*aPamStart.GetPoint(), aNewSection)); |
| } |
| |
| SkipToken(-1); |
| } |
| |
| void SwRTFParser::EnterEnvironment() |
| { |
| } |
| |
| |
| void SwRTFParser::LeaveEnvironment() |
| { |
| if(pRedlineDelete) |
| { |
| delete pRedlineDelete; |
| pRedlineDelete = 0; |
| } |
| |
| if(pRedlineInsert) |
| { |
| delete pRedlineInsert; |
| pRedlineInsert = 0; |
| } |
| } |
| |
| void SwRTFParser::SkipPageDescTbl() |
| { |
| // M.M. #117907# I have to use this glorified SkipGroup because the |
| // SvParser SkipGroup uses nNextCh which is not set correctly <groan> |
| int nNumOpenBrakets = 1; |
| |
| while( nNumOpenBrakets && IsParserWorking() ) |
| { |
| switch( GetNextToken() ) |
| { |
| case '}': |
| { |
| --nNumOpenBrakets; |
| } |
| break; |
| |
| case '{': |
| { |
| nNumOpenBrakets++; |
| } |
| break; |
| } |
| } |
| |
| SkipToken( -1 ); |
| } |
| |
| void SwRTFParser::ReadPageDescTbl() |
| { |
| // dann erzeuge aus der SvxStyle-Tabelle die Swg-Collections, damit |
| // diese auch in den Headers/Footer benutzt werden koennen! |
| MakeStyleTab(); |
| // das default-Style schon gleich am ersten Node setzen |
| SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 ); |
| if( !pColl ) |
| pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); |
| pDoc->SetTxtFmtColl( *pPam, pColl ); |
| |
| int nToken, bSaveChkStyleAttr = IsChkStyleAttr(); |
| int nNumOpenBrakets = 1; // die erste wurde schon vorher erkannt !! |
| |
| SetChkStyleAttr(sal_False); // Attribute nicht gegen die Styles checken |
| |
| bInPgDscTbl = true; |
| sal_uInt16 nPos = 0; |
| SwPageDesc* pPg = 0; |
| SwFrmFmt* pPgFmt = 0; |
| |
| SvxULSpaceItem aUL( RES_UL_SPACE ), aHUL( RES_UL_SPACE ), aFUL( RES_UL_SPACE ); |
| SvxLRSpaceItem aLR( RES_LR_SPACE ), aHLR( RES_LR_SPACE ), aFLR( RES_LR_SPACE ); |
| Size a4 = SvxPaperInfo::GetPaperSize(PAPER_A4); |
| SwFmtFrmSize aSz( ATT_FIX_SIZE, a4.Width(), a4.Height() ); // DIN A4 defaulten |
| SwFmtFrmSize aFSz( ATT_MIN_SIZE ), aHSz( ATT_MIN_SIZE ); |
| |
| SvxFrameDirectionItem aFrmDir(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR); |
| |
| sal_uInt16 nCols = USHRT_MAX, nColSpace = USHRT_MAX, nAktCol = 0; |
| SvUShorts aColumns; |
| ::std::map< const SwPageDesc*, sal_uInt16 > aFollowMap; //store index of following page descriptors |
| |
| while( nNumOpenBrakets && IsParserWorking() ) |
| { |
| switch( nToken = GetNextToken() ) |
| { |
| case '{': |
| ++nNumOpenBrakets; |
| break; |
| case '}': |
| if (1 == --nNumOpenBrakets) |
| { |
| ASSERT(pPgFmt && pPg, "Serious problem here"); |
| if (pPgFmt && pPg) |
| { |
| // PageDesc ist fertig, setze am Doc |
| pPgFmt->SetFmtAttr(aFrmDir); |
| pPgFmt->SetFmtAttr(aLR); |
| pPgFmt->SetFmtAttr(aUL); |
| pPgFmt->SetFmtAttr(aSz); |
| ::lcl_SetFmtCol(*pPgFmt, nCols, nColSpace, aColumns); |
| if (pPgFmt->GetHeader().GetHeaderFmt()) |
| { |
| SwFrmFmt* pHFmt = |
| (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt(); |
| pHFmt->SetFmtAttr(aHUL); |
| pHFmt->SetFmtAttr(aHLR); |
| pHFmt->SetFmtAttr(aHSz); |
| } |
| if (pPgFmt->GetFooter().GetFooterFmt()) |
| { |
| SwFrmFmt* pFFmt = |
| (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt(); |
| pFFmt->SetFmtAttr(aHUL); |
| pFFmt->SetFmtAttr(aHLR); |
| pFFmt->SetFmtAttr(aHSz); |
| } |
| if( nPos < pDoc->GetPageDescCnt() ) |
| pDoc->ChgPageDesc(nPos++, *pPg); |
| } |
| } |
| break; |
| case RTF_PGDSC: |
| if (nPos) // kein && wg MAC |
| { |
| if (nPos != pDoc->MakePageDesc( |
| String::CreateFromInt32(nTokenValue))) |
| { |
| ASSERT( sal_False, "PageDesc an falscher Position" ); |
| } |
| } |
| pPg = &pDoc->_GetPageDesc(nPos); |
| pPg->SetLandscape( sal_False ); |
| pPgFmt = &pPg->GetMaster(); |
| #ifndef CFRONT |
| SETPAGEDESC_DEFAULTS: |
| #endif |
| aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); |
| aLR.SetLeft( 0 ); aLR.SetRight( 0 ); |
| aUL.SetLower( 0 ); aUL.SetUpper( 0 ); |
| aHLR.SetLeft( 0 ); aHLR.SetRight( 0 ); |
| aHUL.SetLower( 0 ); aHUL.SetUpper( 0 ); |
| aFLR.SetLeft( 0 ); aFLR.SetRight( 0 ); |
| aFUL.SetLower( 0 ); aFUL.SetUpper( 0 ); |
| nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0; |
| aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 ); |
| aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 ); |
| break; |
| |
| case RTF_PGDSCUSE: |
| pPg->WriteUseOn( (UseOnPage)nTokenValue ); |
| break; |
| |
| case RTF_PGDSCNXT: |
| // store index of follow in map; will be fixed up later |
| if( nTokenValue ) |
| aFollowMap.insert( ::std::pair<const SwPageDesc*, sal_uInt16>( pPg, nTokenValue )); |
| else |
| pPg->SetFollow( & const_cast<const SwDoc *>(pDoc) |
| ->GetPageDesc( 0 ) ); |
| break; |
| |
| case RTF_FORMULA: /* Zeichen "\|" !!! */ |
| pPgFmt->SetFmtAttr( aLR ); |
| pPgFmt->SetFmtAttr( aUL ); |
| pPgFmt->SetFmtAttr( aSz ); |
| ::lcl_SetFmtCol( *pPgFmt, nCols, nColSpace, aColumns ); |
| if( pPgFmt->GetHeader().GetHeaderFmt() ) |
| { |
| SwFrmFmt* pHFmt = (SwFrmFmt*)pPgFmt->GetHeader().GetHeaderFmt(); |
| pHFmt->SetFmtAttr( aHUL ); |
| pHFmt->SetFmtAttr( aHLR ); |
| pHFmt->SetFmtAttr( aHSz ); |
| } |
| if( pPgFmt->GetFooter().GetFooterFmt() ) |
| { |
| SwFrmFmt* pFFmt = (SwFrmFmt*)pPgFmt->GetFooter().GetFooterFmt(); |
| pFFmt->SetFmtAttr( aHUL ); |
| pFFmt->SetFmtAttr( aHLR ); |
| pFFmt->SetFmtAttr( aHSz ); |
| } |
| |
| pPgFmt = &pPg->GetLeft(); |
| #ifndef CFRONT |
| goto SETPAGEDESC_DEFAULTS; |
| #else |
| aLR.SetLeft( 0 ); aLR.SetRight( 0 ); |
| aUL.SetLower( 0 ); aUL.SetUpper( 0 ); |
| aHLR.SetLeft( 0 ); aHLR.SetRight( 0 ); |
| aHUL.SetLower( 0 ); aHUL.SetUpper( 0 ); |
| aFLR.SetLeft( 0 ); aFLR.SetRight( 0 ); |
| aFUL.SetLower( 0 ); aFUL.SetUpper( 0 ); |
| aSz.SetWidth( a4.Width() ); aSz.SetHeight( a4.Height() ); // DIN A4 default |
| nCols = USHRT_MAX; nColSpace = USHRT_MAX; nAktCol = 0; |
| aFSz.SetHeightSizeType( ATT_MIN_SIZE ); aFSz.SetHeight( 0 ); |
| aHSz.SetHeightSizeType( ATT_MIN_SIZE ); aHSz.SetHeight( 0 ); |
| break; |
| #endif |
| |
| case RTF_RTLSECT: |
| aFrmDir.SetValue(FRMDIR_HORI_RIGHT_TOP); |
| break; |
| |
| case RTF_LTRSECT: |
| aFrmDir.SetValue(FRMDIR_HORI_LEFT_TOP); |
| break; |
| |
| // alt: LI/RI/SA/SB, neu: MARG?SXN |
| case RTF_MARGLSXN: |
| case RTF_LI: aLR.SetLeft( (sal_uInt16)nTokenValue ); break; |
| case RTF_MARGRSXN: |
| case RTF_RI: aLR.SetRight( (sal_uInt16)nTokenValue ); break; |
| case RTF_MARGTSXN: |
| case RTF_SA: aUL.SetUpper( (sal_uInt16)nTokenValue ); break; |
| case RTF_MARGBSXN: |
| case RTF_SB: aUL.SetLower( (sal_uInt16)nTokenValue ); break; |
| case RTF_PGWSXN: aSz.SetWidth( nTokenValue ); break; |
| case RTF_PGHSXN: aSz.SetHeight( nTokenValue ); break; |
| |
| case RTF_HEADERY: aHUL.SetUpper( (sal_uInt16)nTokenValue ); break; |
| case RTF_HEADER_YB: aHUL.SetLower( (sal_uInt16)nTokenValue ); break; |
| case RTF_HEADER_XL: aHLR.SetLeft( (sal_uInt16)nTokenValue ); break; |
| case RTF_HEADER_XR: aHLR.SetRight( (sal_uInt16)nTokenValue ); break; |
| case RTF_FOOTERY: aFUL.SetLower( (sal_uInt16)nTokenValue ); break; |
| case RTF_FOOTER_YT: aFUL.SetUpper( (sal_uInt16)nTokenValue ); break; |
| case RTF_FOOTER_XL: aFLR.SetLeft( (sal_uInt16)nTokenValue ); break; |
| case RTF_FOOTER_XR: aFLR.SetRight( (sal_uInt16)nTokenValue ); break; |
| |
| case RTF_HEADER_YH: |
| if( 0 > nTokenValue ) |
| { |
| aHSz.SetHeightSizeType( ATT_FIX_SIZE ); |
| nTokenValue = -nTokenValue; |
| } |
| aHSz.SetHeight( (sal_uInt16)nTokenValue ); |
| break; |
| |
| case RTF_FOOTER_YH: |
| if( 0 > nTokenValue ) |
| { |
| aFSz.SetHeightSizeType( ATT_FIX_SIZE ); |
| nTokenValue = -nTokenValue; |
| } |
| aFSz.SetHeight( (sal_uInt16)nTokenValue ); |
| break; |
| |
| |
| case RTF_LNDSCPSXN: pPg->SetLandscape( sal_True ); break; |
| |
| case RTF_COLS: nCols = (sal_uInt16)nTokenValue; break; |
| case RTF_COLSX: nColSpace = (sal_uInt16)nTokenValue; break; |
| |
| case RTF_COLNO: |
| nAktCol = (sal_uInt16)nTokenValue; |
| if( RTF_COLW == GetNextToken() ) |
| { |
| sal_uInt16 nWidth = sal_uInt16( nTokenValue ), nSpace = 0; |
| if( RTF_COLSR == GetNextToken() ) |
| nSpace = sal_uInt16( nTokenValue ); |
| else |
| SkipToken( -1 ); // wieder zurueck |
| |
| if( --nAktCol == ( aColumns.Count() / 2 ) ) |
| { |
| aColumns.Insert( nWidth, aColumns.Count() ); |
| aColumns.Insert( nSpace, aColumns.Count() ); |
| } |
| } |
| break; |
| |
| case RTF_PAGEBB: |
| { |
| pPgFmt->SetFmtAttr( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK ) ); |
| } |
| break; |
| |
| case RTF_HEADER: |
| case RTF_HEADERL: |
| case RTF_HEADERR: |
| case RTF_FOOTER: |
| case RTF_FOOTERL: |
| case RTF_FOOTERR: |
| case RTF_FOOTERF: |
| case RTF_HEADERF: |
| ReadHeaderFooter(nToken, pPg); |
| --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen! |
| break; |
| case RTF_TEXTTOKEN: |
| if (!DelCharAtEnd(aToken, ';' ).Len()) |
| break; |
| ASSERT(pPg, "Unexpected missing pPg"); |
| if (pPg) |
| { |
| pPg->SetName(aToken); |
| |
| // sollte es eine Vorlage aus dem Pool sein ?? |
| sal_uInt16 n = SwStyleNameMapper::GetPoolIdFromUIName(aToken, |
| nsSwGetPoolIdFromName::GET_POOLID_PAGEDESC); |
| if (USHRT_MAX != n) |
| { |
| // dann setze bei der Neuen die entsp. PoolId |
| pPg->SetPoolFmtId(n); |
| } |
| } |
| break; |
| case RTF_BRDBOX: |
| if (3 == nNumOpenBrakets) |
| { |
| ReadBorderAttr(SkipToken(-2), |
| (SfxItemSet&)pPgFmt->GetAttrSet()); |
| --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen! |
| } |
| break; |
| case RTF_SHADOW: |
| if( 3 == nNumOpenBrakets ) |
| { |
| ReadAttr( SkipToken( -2 ), (SfxItemSet*)&pPgFmt->GetAttrSet() ); |
| --nNumOpenBrakets; // Klammer wird im ReadAttr ueberlesen! |
| } |
| break; |
| |
| |
| default: |
| if( (nToken & ~0xff ) == RTF_SHADINGDEF ) |
| ReadBackgroundAttr( nToken, (SfxItemSet&)pPgFmt->GetAttrSet() ); |
| break; |
| } |
| } |
| |
| |
| // setze jetzt noch bei allen die entsprechenden Follows !! |
| // Die, die ueber die Tabelle eingelesen wurden und einen |
| // Follow definiert haben, ist dieser als Tabposition im |
| // Follow schon gesetzt. |
| for( nPos = 0; nPos < pDoc->GetPageDescCnt(); ++nPos ) |
| { |
| SwPageDesc* pPgDsc = &pDoc->_GetPageDesc( nPos ); |
| std::map< const SwPageDesc*, sal_uInt16 >::const_iterator aIter = |
| aFollowMap.find( pPgDsc ); |
| if (aIter != aFollowMap.end()) |
| { |
| if ((*aIter).second < pDoc->GetPageDescCnt()) |
| pPgDsc->SetFollow(& const_cast<const SwDoc *>(pDoc)->GetPageDesc((*aIter).second)); |
| } |
| } |
| |
| SetChkStyleAttr( bSaveChkStyleAttr ); |
| |
| bInPgDscTbl = false; |
| nAktPageDesc = 0; |
| nAktFirstPageDesc = 0; |
| bSwPageDesc = true; |
| SkipToken( -1 ); |
| } |
| |
| // -------------- Methoden -------------------- |
| |
| /* |
| void SwRTFParser::ReadUnknownData() |
| { |
| SvRTFParser::ReadUnknownData(); |
| } |
| |
| void SwRTFParser::ReadOLEData() |
| { |
| SvRTFParser::ReadOLEData(); |
| } |
| */ |
| |
| void SwRTFParser::ReadPrtData() |
| { |
| while( IsParserWorking() ) |
| { |
| int nToken = GetNextToken(); |
| if( (RTF_TEXTTOKEN != nToken) && ('}' == nToken) ) |
| break; |
| } |
| |
| SkipToken( -1 ); // schliessende Klammer wieder zurueck!! |
| } |
| |
| static const SwNodeIndex* SetHeader(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld) |
| { |
| ASSERT(pHdFtFmt, "Impossible, no header"); |
| const SwFrmFmt* pExisting = bReuseOld ? |
| pHdFtFmt->GetHeader().GetHeaderFmt() : 0; |
| if (!pExisting) |
| { |
| //No existing header, create a new one |
| pHdFtFmt->SetFmtAttr(SwFmtHeader(sal_True)); |
| pExisting = pHdFtFmt->GetHeader().GetHeaderFmt(); |
| } |
| return pExisting->GetCntnt().GetCntntIdx(); |
| } |
| |
| static const SwNodeIndex* SetFooter(SwFrmFmt* pHdFtFmt, sal_Bool bReuseOld) |
| { |
| ASSERT(pHdFtFmt, "Impossible, no footer"); |
| const SwFrmFmt* pExisting = bReuseOld ? |
| pHdFtFmt->GetFooter().GetFooterFmt() : 0; |
| if (!pExisting) |
| { |
| //No exist footer, create a new one |
| pHdFtFmt->SetFmtAttr(SwFmtFooter(sal_True)); |
| pExisting = pHdFtFmt->GetFooter().GetFooterFmt(); |
| } |
| return pExisting->GetCntnt().GetCntntIdx(); |
| } |
| |
| |
| void SwRTFParser::ReadHeaderFooter( int nToken, SwPageDesc* pPageDesc ) |
| { |
| ASSERT( RTF_FOOTNOTE == nToken || |
| RTF_FLY_INPARA == nToken || |
| pPageDesc, "PageDesc is missing" ); |
| |
| bool bContainsParaCache = bContainsPara; |
| // backup all important data |
| SwPosition aSavePos( *pPam->GetPoint() ); |
| SvxRTFItemStack aSaveStack(GetAttrStack()); |
| GetAttrStack().clear(); |
| |
| // save the fly array - after read, all flys may be set into |
| // the header/footer |
| SwFlySaveArr aSaveArray( 255 < aFlyArr.Count() ? aFlyArr.Count() : 255 ); |
| aSaveArray.Insert( &aFlyArr, 0 ); |
| aFlyArr.Remove( 0, aFlyArr.Count() ); |
| sal_Bool bSetFlyInDoc = sal_True; |
| |
| const SwNodeIndex* pSttIdx = 0; |
| SwFrmFmt* pHdFtFmt = 0; |
| SwTxtAttr* pTxtAttr = 0; |
| int bDelFirstChar = sal_False; |
| bool bOldIsFootnote = mbIsFootnote; |
| sal_Bool bOldGrpStt = sal::static_int_cast< sal_Bool, int >(IsNewGroup()); |
| |
| int nNumOpenBrakets = GetOpenBrakets() - 1; |
| |
| switch( nToken ) |
| { |
| case RTF_FOOTNOTE: |
| { |
| bool bIsEndNote = RTF_FTNALT == GetNextToken(); |
| if (!bIsEndNote) |
| SkipToken(-1); |
| |
| SwTxtNode* pTxtNd = pPam->GetNode()->GetTxtNode(); |
| SwFmtFtn aFtnNote(bIsEndNote); |
| xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex(); |
| |
| if (nPos && !bFootnoteAutoNum) |
| { |
| pPam->GetPoint()->nContent--; |
| nPos--; |
| aFtnNote.SetNumStr( pTxtNd->GetTxt().GetChar( nPos ) ); |
| ((String&)pTxtNd->GetTxt()).SetChar( nPos, CH_TXTATR_INWORD ); |
| bDelFirstChar = sal_True; |
| } |
| |
| pTxtAttr = pTxtNd->InsertItem( aFtnNote, nPos, nPos, |
| bDelFirstChar ? nsSetAttrMode::SETATTR_NOTXTATRCHR : 0 ); |
| |
| ASSERT( pTxtAttr, "konnte die Fussnote nicht einfuegen/finden" ); |
| |
| if( pTxtAttr ) |
| pSttIdx = ((SwTxtFtn*)pTxtAttr)->GetStartNode(); |
| mbIsFootnote = true; |
| |
| // wurde an der Position ein Escapement aufgespannt, so entferne |
| // das jetzt. Fussnoten sind bei uns immer hochgestellt. |
| SvxRTFItemStackTypePtr pTmp = aSaveStack.empty() ? 0 : aSaveStack.back(); |
| if( pTmp && pTmp->GetSttNodeIdx() == |
| pPam->GetPoint()->nNode.GetIndex() && |
| pTmp->GetSttCnt() == nPos ) |
| pTmp->GetAttrSet().ClearItem( RES_CHRATR_ESCAPEMENT ); |
| } |
| break; |
| |
| case RTF_FLY_INPARA: |
| { |
| xub_StrLen nPos = pPam->GetPoint()->nContent.GetIndex(); |
| SfxItemSet aSet( pDoc->GetAttrPool(), RES_FRMATR_BEGIN, |
| RES_FRMATR_END-1 ); |
| aSet.Put( SwFmtAnchor( FLY_AS_CHAR )); |
| pHdFtFmt = pDoc->MakeFlySection( FLY_AS_CHAR, |
| pPam->GetPoint(), &aSet ); |
| |
| pTxtAttr = pPam->GetNode()->GetTxtNode()->GetTxtAttrForCharAt( |
| nPos, RES_TXTATR_FLYCNT ); |
| ASSERT( pTxtAttr, "konnte den Fly nicht einfuegen/finden" ); |
| |
| pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx(); |
| bSetFlyInDoc = sal_False; |
| } |
| break; |
| |
| case RTF_HEADERF: |
| case RTF_HEADER: |
| pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_HEADERSHARE) ); |
| pHdFtFmt = &pPageDesc->GetMaster(); |
| pSttIdx = SetHeader( pHdFtFmt, sal_False ); |
| break; |
| |
| case RTF_HEADERL: |
| // we cannot have left or right, must have always both |
| pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL)); |
| SetHeader( pPageDesc->GetRightFmt(), sal_True ); |
| pHdFtFmt = pPageDesc->GetLeftFmt(); |
| pSttIdx = SetHeader(pHdFtFmt, sal_False ); |
| break; |
| |
| case RTF_HEADERR: |
| // we cannot have left or right, must have always both |
| pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_HEADERSHARE) | nsUseOnPage::PD_ALL)); |
| SetHeader( pPageDesc->GetLeftFmt(), sal_True ); |
| pHdFtFmt = pPageDesc->GetRightFmt(); |
| pSttIdx = SetHeader(pHdFtFmt, sal_False ); |
| break; |
| |
| case RTF_FOOTERF: |
| case RTF_FOOTER: |
| pPageDesc->WriteUseOn( (UseOnPage)(pPageDesc->ReadUseOn() | nsUseOnPage::PD_FOOTERSHARE) ); |
| pHdFtFmt = &pPageDesc->GetMaster(); |
| pSttIdx = SetFooter(pHdFtFmt, sal_False ); |
| break; |
| |
| case RTF_FOOTERL: |
| // we cannot have left or right, must have always both |
| pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL)); |
| SetFooter( pPageDesc->GetRightFmt(), sal_True ); |
| pHdFtFmt = pPageDesc->GetLeftFmt(); |
| pSttIdx = SetFooter(pHdFtFmt, sal_False ); |
| break; |
| |
| case RTF_FOOTERR: |
| // we cannot have left or right, must have always both |
| pPageDesc->WriteUseOn( (UseOnPage)((pPageDesc->ReadUseOn() & ~nsUseOnPage::PD_FOOTERSHARE) | nsUseOnPage::PD_ALL)); |
| SetFooter( pPageDesc->GetLeftFmt(), sal_True ); |
| pHdFtFmt = pPageDesc->GetRightFmt(); |
| pSttIdx = SetFooter(pHdFtFmt, sal_False ); |
| break; |
| } |
| |
| sal_uInt16 nOldFlyArrCnt = aFlyArr.Count(); |
| if( !pSttIdx ) |
| SkipGroup(); |
| else |
| { |
| // es ist auf jedenfall jetzt ein TextNode im Kopf/Fusszeilen-Bereich |
| // vorhanden. Dieser muss jetzt nur noch gefunden und der neue Cursor |
| // dort hinein gesetzt werden. |
| SwCntntNode *pNode = pDoc->GetNodes()[ pSttIdx->GetIndex()+1 ]-> |
| GetCntntNode(); |
| |
| // immer ans Ende der Section einfuegen !! |
| pPam->GetPoint()->nNode = *pNode->EndOfSectionNode(); |
| pPam->Move( fnMoveBackward ); |
| |
| SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 ); |
| if( !pColl ) |
| pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); |
| pDoc->SetTxtFmtColl( *pPam, pColl ); |
| |
| SetNewGroup( sal_True ); |
| |
| while( !( nNumOpenBrakets == GetOpenBrakets() && !GetStackPos()) && IsParserWorking() ) |
| { |
| switch( nToken = GetNextToken() ) |
| { |
| case RTF_U: |
| if( bDelFirstChar ) |
| { |
| bDelFirstChar = sal_False; |
| nToken = 0; |
| } |
| break; |
| |
| case RTF_TEXTTOKEN: |
| if( bDelFirstChar ) |
| { |
| if( !aToken.Erase( 0, 1 ).Len() ) |
| nToken = 0; |
| bDelFirstChar = sal_False; |
| } |
| break; |
| } |
| if( nToken ) |
| NextToken( nToken ); |
| } |
| |
| SetAllAttrOfStk(); |
| if( aFlyArr.Count() && bSetFlyInDoc ) |
| SetFlysInDoc(); |
| |
| // sollte der letze Node leer sein, dann loesche ihn |
| // (\par heisst ja Absatzende und nicht neuer Absatz!) |
| DelLastNode(); |
| } |
| |
| // vom FlyFmt noch die richtigen Attribute setzen |
| if( pTxtAttr && RES_TXTATR_FLYCNT == pTxtAttr->Which() ) |
| { |
| // is add a new fly ? |
| if( nOldFlyArrCnt < aFlyArr.Count() ) |
| { |
| SwFlySave* pFlySave = aFlyArr[ aFlyArr.Count()-1 ]; |
| pFlySave->aFlySet.ClearItem( RES_ANCHOR ); |
| pHdFtFmt->SetFmtAttr( pFlySave->aFlySet ); |
| aFlyArr.DeleteAndDestroy( aFlyArr.Count() - 1 ); |
| } |
| else |
| { |
| // no, so remove the created textattribute |
| SwFrmFmt* pFlyFmt = pTxtAttr->GetFlyCnt().GetFrmFmt(); |
| // remove the pam from the flynode |
| *pPam->GetPoint() = aSavePos; |
| pDoc->DelLayoutFmt( pFlyFmt ); |
| } |
| } |
| |
| bFootnoteAutoNum = sal_False; // default auf aus! |
| |
| // und alles wieder zurueck |
| *pPam->GetPoint() = aSavePos; |
| if (mbIsFootnote) |
| SetNewGroup( bOldGrpStt ); // Status wieder zurueck |
| else |
| SetNewGroup( sal_False ); // { - Klammer war kein Group-Start! |
| mbIsFootnote = bOldIsFootnote; |
| GetAttrStack() = aSaveStack; |
| |
| aFlyArr.Insert( &aSaveArray, 0 ); |
| aSaveArray.Remove( 0, aSaveArray.Count() ); |
| bContainsPara = bContainsParaCache; |
| } |
| |
| void SwRTFParser::SetSwgValues( SfxItemSet& rSet ) |
| { |
| const SfxPoolItem* pItem; |
| // Escapement korrigieren |
| if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ESCAPEMENT, sal_False, &pItem )) |
| { |
| /* prozentuale Veraenderung errechnen ! |
| * Formel : (FontSize * 1/20 ) pts Escapement * 2 |
| * ----------------------- = ---------------- |
| * 100% x |
| */ |
| |
| // die richtige |
| long nEsc = ((SvxEscapementItem*)pItem)->GetEsc(); |
| |
| // automatische Ausrichtung wurde schon richtig berechnet |
| if( DFLT_ESC_AUTO_SUPER != nEsc && DFLT_ESC_AUTO_SUB != nEsc ) |
| { |
| const SvxFontHeightItem& rFH = GetSize( rSet ); |
| nEsc *= 1000L; |
| if(rFH.GetHeight()) nEsc /= long(rFH.GetHeight()); // #i77256# |
| |
| SvxEscapementItem aEsc( (short) nEsc, |
| ((SvxEscapementItem*)pItem)->GetProp(), RES_CHRATR_ESCAPEMENT); |
| rSet.Put( aEsc ); |
| } |
| } |
| |
| // TabStops anpassen |
| if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_TABSTOP, sal_False, &pItem )) |
| { |
| const SvxLRSpaceItem& rLR = GetLRSpace( rSet ); |
| SvxTabStopItem aTStop( *(SvxTabStopItem*)pItem ); |
| |
| long nOffset = rLR.GetTxtLeft(); |
| if( nOffset ) |
| { |
| // Tabs anpassen !! |
| SvxTabStop* pTabs = (SvxTabStop*)aTStop.GetStart(); |
| for( sal_uInt16 n = aTStop.Count(); n; --n, ++pTabs) |
| if( SVX_TAB_ADJUST_DEFAULT != pTabs->GetAdjustment() ) |
| pTabs->GetTabPos() -= nOffset; |
| |
| // negativer Einzug, dann auf 0 Pos einen Tab setzen |
| if( rLR.GetTxtFirstLineOfst() < 0 ) |
| aTStop.Insert( SvxTabStop() ); |
| } |
| |
| if( !aTStop.Count() ) |
| { |
| const SvxTabStopItem& rDflt = (const SvxTabStopItem&)rSet. |
| GetPool()->GetDefaultItem(RES_PARATR_TABSTOP); |
| if( rDflt.Count() ) |
| aTStop.Insert( &rDflt, 0 ); |
| } |
| rSet.Put( aTStop ); |
| } |
| else if( SFX_ITEM_SET == rSet.GetItemState( RES_LR_SPACE, sal_False, &pItem ) |
| && ((SvxLRSpaceItem*)pItem)->GetTxtFirstLineOfst() < 0 ) |
| { |
| // negativer Einzug, dann auf 0 Pos einen Tab setzen |
| rSet.Put( SvxTabStopItem( 1, 0, SVX_TAB_ADJUST_DEFAULT, RES_PARATR_TABSTOP )); |
| } |
| |
| // NumRules anpassen |
| if( !bStyleTabValid && |
| SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_NUMRULE, sal_False, &pItem )) |
| { |
| // dann steht im Namen nur ein Verweis in das ListArray |
| SwNumRule* pRule = GetNumRuleOfListNo( ((SwNumRuleItem*)pItem)-> |
| GetValue().ToInt32() ); |
| if( pRule ) |
| rSet.Put( SwNumRuleItem( pRule->GetName() )); |
| else |
| rSet.ClearItem( RES_PARATR_NUMRULE ); |
| |
| } |
| |
| |
| /* |
| ???????????????????????????????????????????????????????????????????? |
| ?? muss die LineSpacing Hoehe 200Twip betragen ?? |
| ?? in rtfitem.hxx wird es auf 0 defaultet. Wenn ja, dann muss hier |
| ?? ein neues Item gesetzt werden!!!! |
| ???????????????????????????????????????????????????????????????????? |
| |
| // LineSpacing korrigieren |
| if( SFX_ITEM_SET == rSet.GetItemState( RES_PARATR_LINESPACING, sal_False, &pItem )) |
| { |
| const SvxLineSpacingItem* pLS = (const SvxLineSpacingItem*)pItem; |
| SvxLineSpacingItem aNew; |
| |
| aNew.SetInterLineSpace( pLS->GetInterLineSpace() ); |
| aNew.GetLineSpaceRule() = pLS->GetLineSpaceRule(); |
| aNew.SetPropLineSpace( pLS->GetPropLineSpace() ); |
| aNew.GetInterLineSpaceRule() = pLS->GetInterLineSpaceRule(); |
| |
| rSet.Put( aNew ); |
| } |
| ?????????????????????????????????????????????????????????????????? */ |
| |
| } |
| |
| |
| SwTxtFmtColl* SwRTFParser::MakeColl(const String& rName, sal_uInt16 nPos, |
| sal_uInt8 nOutlineLevel, bool& rbCollExist) |
| { |
| if( sal_uInt8(-1) == nOutlineLevel ) |
| //nOutlineLevel = NO_NUMBERING; |
| nOutlineLevel = MAXLEVEL;//#outline level,zhaojianwei |
| |
| rbCollExist = false; |
| SwTxtFmtColl* pColl; |
| String aNm( rName ); |
| if( !aNm.Len() ) |
| { |
| ASSERT(!this, "not a bug, but I (cmc) want to see an example of this"); |
| if( !nPos ) |
| { |
| pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); |
| if ( nOutlineLevel < MAXLEVEL ) |
| pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel ); |
| else |
| pColl->DeleteAssignmentToListLevelOfOutlineStyle(); |
| return pColl; |
| } |
| |
| // erzeuge einen Namen |
| aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" )); |
| aNm += String::CreateFromInt32( nPos ); |
| aNm += ')'; |
| } |
| ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName); |
| sw::util::ParaStyleMapper::StyleResult aResult = |
| maParaStyleMapper.GetStyle(rName, eSti); |
| pColl = aResult.first; |
| rbCollExist = aResult.second; |
| if (IsNewDoc() && rbCollExist) |
| { |
| // --> OD 2007-01-25 #i73790# - method renamed |
| pColl->ResetAllFmtAttr(); |
| // <-- |
| rbCollExist = false; |
| } |
| |
| if (!rbCollExist) |
| { |
| //pColl->SetOutlineLevel( nOutlineLevel ); //#outline level,removed by zhaojianwei |
| if(nOutlineLevel < MAXLEVEL) //->add by zhaojianwei |
| pColl->AssignToListLevelOfOutlineStyle( nOutlineLevel ); |
| else |
| pColl->DeleteAssignmentToListLevelOfOutlineStyle(); //<-end,zhaojianwei |
| } |
| |
| return pColl; |
| } |
| |
| SwCharFmt* SwRTFParser::MakeCharFmt(const String& rName, sal_uInt16 nPos, |
| int& rbCollExist) |
| { |
| rbCollExist = sal_False; |
| SwCharFmt* pFmt; |
| String aNm( rName ); |
| if( !aNm.Len() ) |
| { |
| ASSERT(!this, "not a bug, but I (cmc) want to see an example of this"); |
| aNm.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "NoName(" )); |
| aNm += String::CreateFromInt32( nPos ); |
| aNm += ')'; |
| } |
| |
| ww::sti eSti = ww::GetCanonicalStiFromEnglishName(rName); |
| sw::util::CharStyleMapper::StyleResult aResult = |
| maCharStyleMapper.GetStyle(rName, eSti); |
| pFmt = aResult.first; |
| rbCollExist = aResult.second; |
| if (IsNewDoc() && rbCollExist) |
| { |
| // --> OD 2007-01-25 #i73790# - method renamed |
| pFmt->ResetAllFmtAttr(); |
| // <-- |
| rbCollExist = false; |
| } |
| return pFmt; |
| } |
| |
| void SwRTFParser::SetStyleAttr( SfxItemSet& rCollSet, |
| const SfxItemSet& rStyleSet, |
| const SfxItemSet& rDerivedSet ) |
| { |
| rCollSet.Put( rStyleSet ); |
| if( rDerivedSet.Count() ) |
| { |
| // suche alle Attribute, die neu gesetzt werden: |
| const SfxPoolItem* pItem; |
| SfxItemIter aIter( rDerivedSet ); |
| sal_uInt16 nWhich = aIter.GetCurItem()->Which(); |
| while( sal_True ) |
| { |
| switch( rStyleSet.GetItemState( nWhich, sal_False, &pItem ) ) |
| { |
| case SFX_ITEM_DEFAULT: |
| // auf default zuruecksetzen |
| if( RES_FRMATR_END > nWhich ) |
| rCollSet.Put( rCollSet.GetPool()->GetDefaultItem( nWhich )); |
| break; |
| case SFX_ITEM_SET: |
| if( *pItem == *aIter.GetCurItem() ) // gleiches Attribut? |
| // definition kommt aus dem Parent |
| rCollSet.ClearItem( nWhich ); // loeschen |
| break; |
| } |
| |
| if( aIter.IsAtEnd() ) |
| break; |
| nWhich = aIter.NextItem()->Which(); |
| } |
| } |
| // und jetzt noch auf unsere Werte abgleichen |
| SetSwgValues( rCollSet ); |
| } |
| |
| SwTxtFmtColl* SwRTFParser::MakeStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle) |
| { |
| bool bCollExist; |
| SwTxtFmtColl* pColl = MakeColl( rStyle.sName, sal_uInt16(nNo), |
| rStyle.nOutlineNo, bCollExist); |
| aTxtCollTbl.Insert( nNo, pColl ); |
| |
| // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen |
| if( bCollExist ) |
| return pColl; |
| |
| sal_uInt16 nStyleNo = rStyle.nBasedOn; |
| if( rStyle.bBasedOnIsSet && nStyleNo != nNo ) |
| { |
| SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo ); |
| SwTxtFmtColl* pDerivedColl = aTxtCollTbl.Get( nStyleNo ); |
| if( !pDerivedColl ) // noch nicht vorhanden, also anlegen |
| { |
| // ist die ueberhaupt als Style vorhanden ? |
| pDerivedColl = pDerivedStyle |
| ? MakeStyle( nStyleNo, *pDerivedStyle ) |
| : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); |
| } |
| |
| if( pColl == pDerivedColl ) |
| ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet ); |
| else |
| { |
| pColl->SetDerivedFrom( pDerivedColl ); |
| |
| // setze die richtigen Attribute |
| const SfxItemSet* pDerivedSet; |
| if( pDerivedStyle ) |
| pDerivedSet = &pDerivedStyle->aAttrSet; |
| else |
| pDerivedSet = &pDerivedColl->GetAttrSet(); |
| |
| SetStyleAttr( (SfxItemSet&)pColl->GetAttrSet(), |
| rStyle.aAttrSet, *pDerivedSet ); |
| } |
| } |
| else |
| ((SfxItemSet&)pColl->GetAttrSet()).Put( rStyle.aAttrSet ); |
| |
| |
| nStyleNo = rStyle.nNext; |
| if( nStyleNo != nNo ) |
| { |
| SwTxtFmtColl* pNext = aTxtCollTbl.Get( nStyleNo ); |
| if( !pNext ) // noch nicht vorhanden, also anlegen |
| { |
| // ist die ueberhaupt als Style vorhanden ? |
| SvxRTFStyleType* pMkStyle = GetStyleTbl().Get( nStyleNo ); |
| pNext = pMkStyle |
| ? MakeStyle( nStyleNo, *pMkStyle ) |
| : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false ); |
| } |
| pColl->SetNextTxtFmtColl( *pNext ); |
| } |
| return pColl; |
| } |
| |
| SwCharFmt* SwRTFParser::MakeCharStyle( sal_uInt16 nNo, const SvxRTFStyleType& rStyle ) |
| { |
| int bCollExist; |
| SwCharFmt* pFmt = MakeCharFmt( rStyle.sName, sal_uInt16(nNo), bCollExist ); |
| aCharFmtTbl.Insert( nNo, pFmt ); |
| |
| // in bestehendes Dok einfuegen, dann keine Ableitung usw. setzen |
| if( bCollExist ) |
| return pFmt; |
| |
| sal_uInt16 nStyleNo = rStyle.nBasedOn; |
| if( rStyle.bBasedOnIsSet && nStyleNo != nNo ) |
| { |
| SvxRTFStyleType* pDerivedStyle = GetStyleTbl().Get( nStyleNo ); |
| SwCharFmt* pDerivedFmt = aCharFmtTbl.Get( nStyleNo ); |
| if( !pDerivedFmt ) // noch nicht vorhanden, also anlegen |
| { |
| // ist die ueberhaupt als Style vorhanden ? |
| pDerivedFmt = pDerivedStyle |
| ? MakeCharStyle( nStyleNo, *pDerivedStyle ) |
| : pDoc->GetDfltCharFmt(); |
| } |
| |
| if( pFmt == pDerivedFmt ) |
| ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet ); |
| else |
| { |
| pFmt->SetDerivedFrom( pDerivedFmt ); |
| |
| // setze die richtigen Attribute |
| const SfxItemSet* pDerivedSet; |
| if( pDerivedStyle ) |
| pDerivedSet = &pDerivedStyle->aAttrSet; |
| else |
| pDerivedSet = &pDerivedFmt->GetAttrSet(); |
| |
| SetStyleAttr( (SfxItemSet&)pFmt->GetAttrSet(), |
| rStyle.aAttrSet, *pDerivedSet ); |
| } |
| } |
| else |
| ((SfxItemSet&)pFmt->GetAttrSet()).Put( rStyle.aAttrSet ); |
| |
| return pFmt; |
| } |
| |
| // loesche den letzten Node (Tabelle/Fly/Ftn/..) |
| void SwRTFParser::DelLastNode() |
| { |
| // sollte der letze Node leer sein, dann loesche ihn |
| // (\par heisst ja Absatzende und nicht neuer Absatz!) |
| |
| if( !pPam->GetPoint()->nContent.GetIndex() ) |
| { |
| sal_uLong nNodeIdx = pPam->GetPoint()->nNode.GetIndex(); |
| SwCntntNode* pCNd = pDoc->GetNodes()[ nNodeIdx ]->GetCntntNode(); |
| // paragraphs with page break information are not empty! see #117914# topic 1) |
| if(const SfxPoolItem* pItem=&(pCNd->GetAttr( RES_PAGEDESC, sal_False))) |
| { |
| SwFmtPageDesc* pPageDescItem = ((SwFmtPageDesc*)pItem); |
| if (pPageDescItem->GetPageDesc()!=NULL) |
| return; |
| } |
| |
| if( pCNd && pCNd->StartOfSectionIndex()+2 < |
| pCNd->EndOfSectionIndex() ) |
| { |
| if( !GetAttrStack().empty() ) |
| { |
| // Attribut Stack-Eintraege, muessen ans Ende des vorherigen |
| // Nodes verschoben werden. |
| sal_Bool bMove = sal_False; |
| for( size_t n = GetAttrStack().size(); n; ) |
| { |
| SvxRTFItemStackType* pStkEntry = (SvxRTFItemStackType*) |
| GetAttrStack()[ --n ]; |
| if( nNodeIdx == pStkEntry->GetSttNode().GetIdx() ) |
| { |
| if( !bMove ) |
| { |
| pPam->Move( fnMoveBackward ); |
| bMove = sal_True; |
| } |
| pStkEntry->SetStartPos( SwxPosition( pPam ) ); |
| } |
| } |
| if( bMove ) |
| pPam->Move( fnMoveForward ); |
| } |
| pPam->GetPoint()->nContent.Assign( 0, 0 ); |
| pPam->SetMark(); |
| pPam->DeleteMark(); |
| |
| pDoc->GetNodes().Delete( pPam->GetPoint()->nNode ); |
| } |
| } |
| } |
| |
| // fuer Tokens, die im ReadAttr nicht ausgewertet werden |
| void SwRTFParser::UnknownAttrToken( int nToken, SfxItemSet* pSet ) |
| { |
| switch( nToken ) |
| { |
| case RTF_INTBL: |
| { |
| if( !pTableNode ) // Tabelle nicht mehr vorhanden ? |
| NewTblLine(); // evt. Line copieren |
| else |
| { |
| static int _do=0; //$flr See #117881# for explanation. |
| // Crsr nicht mehr in der Tabelle ? |
| if( !pPam->GetNode()->FindTableNode() && _do ) |
| { |
| sal_uLong nOldPos = pPam->GetPoint()->nNode.GetIndex(); |
| |
| // dann wieder in die letzte Box setzen |
| // (kann durch einlesen von Flys geschehen!) |
| pPam->GetPoint()->nNode = *pTableNode->EndOfSectionNode(); |
| pPam->Move( fnMoveBackward ); |
| |
| // alle Attribute, die schon auf den nachfolgen zeigen |
| // auf die neue Box umsetzen !! |
| SvxRTFItemStack& rAttrStk = GetAttrStack(); |
| const SvxRTFItemStackType* pStk; |
| for( size_t n = 0; n < rAttrStk.size(); ++n ) |
| if( ( pStk = rAttrStk[ n ])->GetSttNodeIdx() == nOldPos && |
| !pStk->GetSttCnt() ) |
| ((SvxRTFItemStackType*)pStk)->SetStartPos( SwxPosition( pPam ) ); |
| } |
| } |
| } |
| break; |
| |
| case RTF_PAGEBB: |
| { |
| pSet->Put( SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE, RES_BREAK )); |
| } |
| break; |
| |
| case RTF_PGBRK: |
| { |
| pSet->Put( SvxFmtBreakItem( 1 == nTokenValue ? |
| SVX_BREAK_PAGE_BOTH : SVX_BREAK_PAGE_AFTER, RES_BREAK )); |
| } |
| break; |
| |
| case RTF_PGDSCNO: |
| if( IsNewDoc() && bSwPageDesc && |
| sal_uInt16(nTokenValue) < pDoc->GetPageDescCnt() ) |
| { |
| const SwPageDesc* pPgDsc = &const_cast<const SwDoc *>(pDoc) |
| ->GetPageDesc( (sal_uInt16)nTokenValue ); |
| pDoc->InsertPoolItem( *pPam, SwFmtPageDesc( pPgDsc ), 0); |
| } |
| break; |
| case RTF_CS: |
| { |
| SwCharFmt* pFmt = aCharFmtTbl.Get( nTokenValue ); |
| if( pFmt ) |
| pSet->Put( SwFmtCharFmt( pFmt )); |
| } |
| break; |
| |
| case RTF_LS: |
| if( -1 != nTokenValue ) |
| { |
| if( bStyleTabValid ) |
| { |
| // dann ist auch die ListTabelle gueltig, also suche die |
| // enstprechende NumRule |
| SwNumRule* pRule = GetNumRuleOfListNo( nTokenValue ); |
| if( pRule ) |
| pSet->Put( SwNumRuleItem( pRule->GetName() )); |
| |
| if( SFX_ITEM_SET != pSet->GetItemState( FN_PARAM_NUM_LEVEL, sal_False )) |
| pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, 0 )); |
| } |
| else |
| { |
| // wir sind in der Style-Definitions - Phase. Der Name |
| // wird dann spaeter umgesetzt |
| //#117891# pSet->Put( SwNumRuleItem( String::CreateFromInt32( nTokenValue ))); |
| } |
| |
| } |
| break; |
| |
| case RTF_ILVL: |
| case RTF_SOUTLVL: |
| { |
| sal_uInt8 nLevel = MAXLEVEL <= nTokenValue ? MAXLEVEL - 1 |
| : sal_uInt8( nTokenValue ); |
| pSet->Put( SfxUInt16Item( FN_PARAM_NUM_LEVEL, nLevel )); |
| } |
| break; |
| |
| /* |
| case RTF_SBYS: |
| case RTF_EXPND: |
| case RTF_KEEP: |
| case RTF_KEEPN: |
| */ |
| |
| } |
| } |
| |
| void SwRTFParser::ReadInfo( const sal_Char* pChkForVerNo ) |
| { |
| sal_Char __READONLY_DATA aChkForVerNo[] = "StarWriter"; |
| |
| // falls nicht schon was vorgegeben wurde, setzen wir unseren Namen |
| // rein. Wenn das im Kommentar match, wird im Parser die VersionNummer |
| // gelesen und gesetzt |
| if( !pChkForVerNo ) |
| pChkForVerNo = aChkForVerNo; |
| |
| SvxRTFParser::ReadInfo( pChkForVerNo ); |
| } |
| |
| void SwRTFParser::ReadUserProperties() |
| { |
| // For now we don't support user properties but at least the parser is here. |
| // At the moment it just swallows the tokens to prevent them being displayed |
| int nNumOpenBrakets = 1, nToken; |
| |
| while( nNumOpenBrakets && IsParserWorking() ) |
| { |
| switch( nToken = GetNextToken() ) |
| { |
| case '}': |
| --nNumOpenBrakets; |
| break; |
| case '{': |
| { |
| if( RTF_IGNOREFLAG != GetNextToken() ) |
| nToken = SkipToken( -1 ); |
| else if( RTF_UNKNOWNCONTROL != GetNextToken() ) |
| nToken = SkipToken( -2 ); |
| else |
| { |
| // gleich herausfiltern |
| ReadUnknownData(); |
| nToken = GetNextToken(); |
| if( '}' != nToken ) |
| eState = SVPAR_ERROR; |
| break; |
| } |
| ++nNumOpenBrakets; |
| } |
| break; |
| |
| case RTF_PROPNAME: |
| SkipGroup(); |
| break; |
| |
| case RTF_PROPTYPE: |
| break; |
| |
| case RTF_STATICVAL: |
| SkipGroup(); |
| break; |
| |
| // default: |
| } |
| } |
| |
| SkipToken( -1 ); |
| } |
| |
| |
| #ifdef USED |
| void SwRTFParser::SaveState( int nToken ) |
| { |
| SvxRTFParser::SaveState( nToken ); |
| } |
| |
| void SwRTFParser::RestoreState() |
| { |
| SvxRTFParser::RestoreState(); |
| } |
| #endif |
| |
| /**/ |
| |
| BookmarkPosition::BookmarkPosition(const SwPaM &rPaM) |
| : maMkNode(rPaM.GetMark()->nNode), |
| mnMkCntnt(rPaM.GetMark()->nContent.GetIndex()) |
| { |
| } |
| |
| BookmarkPosition::BookmarkPosition(const BookmarkPosition &rEntry) |
| : maMkNode(rEntry.maMkNode), mnMkCntnt(rEntry.mnMkCntnt) |
| { |
| } |
| |
| bool BookmarkPosition::operator==(const BookmarkPosition rhs) |
| { |
| return(maMkNode.GetIndex() == rhs.maMkNode.GetIndex() && mnMkCntnt == rhs.mnMkCntnt); |
| } |
| |
| sal_uLong SwNodeIdx::GetIdx() const |
| { |
| return aIdx.GetIndex(); |
| } |
| |
| SvxNodeIdx* SwNodeIdx::Clone() const |
| { |
| return new SwNodeIdx( aIdx ); |
| } |
| |
| SvxPosition* SwxPosition::Clone() const |
| { |
| return new SwxPosition( pPam ); |
| } |
| |
| SvxNodeIdx* SwxPosition::MakeNodeIdx() const |
| { |
| return new SwNodeIdx( pPam->GetPoint()->nNode ); |
| } |
| |
| sal_uLong SwxPosition::GetNodeIdx() const |
| { |
| return pPam->GetPoint()->nNode.GetIndex(); |
| } |
| |
| xub_StrLen SwxPosition::GetCntIdx() const |
| { |
| return pPam->GetPoint()->nContent.GetIndex(); |
| } |
| |
| /* vi:set tabstop=4 shiftwidth=4 expandtab: */ |