Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <doc.hxx>
21 : #include <IDocumentContentOperations.hxx>
22 : #include "writerhelper.hxx"
23 : #include <com/sun/star/embed/XClassifiedObject.hpp>
24 : #include <com/sun/star/embed/Aspects.hpp>
25 :
26 : #include <algorithm>
27 : #include <functional>
28 : #include <osl/endian.h>
29 : #include <sot/storage.hxx>
30 : #include <com/sun/star/drawing/XShape.hpp>
31 : #include <hintids.hxx>
32 : #include <svx/svdoole2.hxx>
33 : #include <filter/msfilter/msdffimp.hxx>
34 : #include <sprmids.hxx>
35 : #include <svx/unoapi.hxx>
36 :
37 : #include <sot/exchange.hxx>
38 : #include <swtypes.hxx>
39 : #include <fmtanchr.hxx>
40 : #include <fmtcntnt.hxx>
41 : #include <dcontact.hxx>
42 : #include <frmfmt.hxx>
43 : #include <pam.hxx>
44 : #include <ndgrf.hxx>
45 : #include <docsh.hxx>
46 : #include <mdiexp.hxx>
47 : #include <redline.hxx>
48 : #include <fltshell.hxx>
49 : #include <unodraw.hxx>
50 : #include <shellio.hxx>
51 : #include <ndole.hxx>
52 :
53 : #include <vcl/graphicfilter.hxx>
54 : #include <vcl/wmf.hxx>
55 :
56 : #include "ww8scan.hxx"
57 : #include "ww8par.hxx"
58 : #include "ww8par2.hxx"
59 :
60 : struct OLE_MFP
61 : {
62 : sal_Int16 mm; // 0x6 int
63 : sal_Int16 xExt; // 0x8 int in 1/100 mm
64 : sal_Int16 yExt; // 0xa int in 1/100 mm
65 : sal_Int16 hMF; // 0xc int
66 : };
67 :
68 : using namespace ::com::sun::star;
69 :
70 0 : static bool SwWw8ReadScaling(long& rX, long& rY, tools::SvRef<SotStorage>& rSrc1)
71 : {
72 : // Skalierungsfaktoren holen:
73 : // Informationen in PIC-Stream ( durch ausprobieren )
74 : // 0x0 (l)cb
75 : // 0x08 .. 0x0a Flags ??
76 : // 0x08 Inh: 1 / 0
77 : // 0x09 Inh: 0,8,0x18
78 : // 0x0a Inh: immer 8, MAP_ANISOTROPIC ???
79 : // 0x0b Inh: immer 0
80 : // 0x0c, 0x10 Originalgroesse x,y in 1/100 mm
81 : // 0x14, 0x16 Originalgroesse x,y in tw
82 : // 0x2c, 0x30 Skalierung x,y in Promille
83 : // 0x34, 0x38, 0x3c, 0x40 Crop Left, Top, Right, Bot in tw
84 :
85 : tools::SvRef<SotStorageStream> xSrc3 = rSrc1->OpenSotStream( OUString("\3PIC"),
86 0 : STREAM_STD_READ | StreamMode::NOCREATE);
87 0 : SotStorageStream* pS = xSrc3;
88 0 : pS->SetEndian( SvStreamEndian::LITTLE );
89 0 : pS->Seek( STREAM_SEEK_TO_END );
90 :
91 : OSL_ENSURE( pS->Tell() >= 76, "+OLE-PIC-Stream is shorter than 76 Byte" );
92 :
93 : sal_Int32 nOrgWidth,
94 : nOrgHeight,
95 : nScaleX,
96 : nScaleY,
97 : nCropLeft,
98 : nCropTop,
99 : nCropRight,
100 : nCropBottom;
101 0 : pS->Seek( 0x14 );
102 0 : pS->ReadInt32( nOrgWidth ) // Original Size in 1/100 mm
103 0 : .ReadInt32( nOrgHeight );
104 0 : pS->Seek( 0x2c );
105 0 : pS->ReadInt32( nScaleX ) // Scaling in Promille
106 0 : .ReadInt32( nScaleY )
107 0 : .ReadInt32( nCropLeft ) // Cropping in 1/100 mm
108 0 : .ReadInt32( nCropTop )
109 0 : .ReadInt32( nCropRight )
110 0 : .ReadInt32( nCropBottom );
111 :
112 0 : rX = nOrgWidth - nCropLeft - nCropRight;
113 0 : rY = nOrgHeight - nCropTop - nCropBottom;
114 0 : if (10 > nScaleX || 65536 < nScaleX || 10 > nScaleY || 65536 < nScaleY)
115 : {
116 : OSL_ENSURE( !pS, "+OLE-Scalinginformation in PIC-Stream wrong" );
117 0 : return false;
118 : }
119 : else
120 : {
121 0 : rX = (rX * nScaleX) / 1000;
122 0 : rY = (rY * nScaleY) / 1000;
123 : }
124 0 : return true;
125 : }
126 :
127 0 : static bool SwWw6ReadMetaStream(GDIMetaFile& rWMF, OLE_MFP* pMfp,
128 : tools::SvRef<SotStorage>& rSrc1)
129 : {
130 : tools::SvRef<SotStorageStream> xSrc2 = rSrc1->OpenSotStream( OUString("\3META"),
131 0 : STREAM_STD_READ | StreamMode::NOCREATE);
132 0 : SotStorageStream* pSt = xSrc2;
133 0 : pSt->SetEndian( SvStreamEndian::LITTLE );
134 0 : sal_uLong nRead = pSt->Read( pMfp, sizeof(*pMfp ) );
135 : // Mini-Placable-Header lesen
136 0 : if (nRead != sizeof(*pMfp))
137 0 : return false;
138 :
139 : #if defined OSL_BIGENDIAN
140 : pMfp->mm = OSL_SWAPWORD( pMfp->mm );
141 : pMfp->xExt = OSL_SWAPWORD( pMfp->xExt );
142 : pMfp->yExt = OSL_SWAPWORD( pMfp->yExt );
143 : #endif // OSL_BIGENDIAN
144 :
145 0 : if( pMfp->mm == 94 || pMfp->mm == 99 )
146 : {
147 : OSL_ENSURE( !pSt, "+OLE: Falscher Metafile-Typ" );
148 0 : return false;
149 : }
150 0 : if( pMfp->mm != 8 )
151 : {
152 : OSL_ENSURE( !pSt, "+OLE: Falscher Metafile-Typ ( nicht Anisotropic )" );
153 : }
154 0 : if( !pMfp->xExt || !pMfp->yExt )
155 : {
156 : OSL_ENSURE( !pSt, "+OLE: Groesse von 0 ???" );
157 0 : return false;
158 : }
159 0 : bool bOk = ReadWindowMetafile( *pSt, rWMF, NULL ); // WMF lesen
160 : // *pSt >> aWMF geht nicht ohne placable Header
161 0 : if (!bOk || pSt->GetError() || rWMF.GetActionSize() == 0)
162 : {
163 : OSL_ENSURE( !pSt, "+OLE: Konnte Metafile nicht lesen" );
164 0 : return false;
165 : }
166 :
167 0 : rWMF.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
168 :
169 : // MetaFile auf neue Groesse skalieren und
170 : // neue Groesse am MetaFile setzen
171 0 : Size aOldSiz( rWMF.GetPrefSize() );
172 0 : Size aNewSiz( pMfp->xExt, pMfp->yExt );
173 0 : Fraction aFracX( aNewSiz.Width(), aOldSiz.Width() );
174 0 : Fraction aFracY( aNewSiz.Height(), aOldSiz.Height() );
175 :
176 0 : rWMF.Scale( aFracX, aFracY );
177 0 : rWMF.SetPrefSize( aNewSiz );
178 :
179 0 : return true;
180 : }
181 :
182 0 : static bool SwWw6ReadMacPICTStream(Graphic& rGraph, tools::SvRef<SotStorage>& rSrc1)
183 : {
184 : // 03-META-Stream nicht da. Vielleicht ein 03-PICT ?
185 0 : tools::SvRef<SotStorageStream> xSrc4 = rSrc1->OpenSotStream(OUString("\3PICT"));
186 0 : SotStorageStream* pStp = xSrc4;
187 0 : pStp->SetEndian( SvStreamEndian::LITTLE );
188 : sal_uInt8 aTestA[10]; // Ist der 01Ole-Stream ueberhaupt vorhanden
189 0 : sal_uLong nReadTst = pStp->Read( aTestA, sizeof( aTestA ) );
190 0 : if (nReadTst != sizeof(aTestA))
191 0 : return false;
192 :
193 0 : pStp->Seek( STREAM_SEEK_TO_BEGIN );
194 :
195 : // Mac-Pict steht im 03PICT-StorageStream allerdings ohne die ersten 512
196 : // Bytes, die bei einem MAC-PICT egal sind ( werden nicht ausgewertet )
197 0 : return SwWW8ImplReader::GetPictGrafFromStream(rGraph, *pStp);
198 : }
199 :
200 15 : SwFlyFrameFormat* SwWW8ImplReader::InsertOle(SdrOle2Obj &rObject,
201 : const SfxItemSet &rFlySet, const SfxItemSet &rGrfSet)
202 : {
203 15 : SfxObjectShell *pPersist = m_rDoc.GetPersist();
204 : OSL_ENSURE(pPersist, "No persist, cannot insert objects correctly");
205 15 : if (!pPersist)
206 0 : return 0;
207 :
208 15 : SwFlyFrameFormat *pRet = 0;
209 :
210 15 : SfxItemSet *pMathFlySet = 0;
211 15 : uno::Reference < embed::XClassifiedObject > xClass( rObject.GetObjRef(), uno::UNO_QUERY );
212 15 : if( xClass.is() )
213 : {
214 15 : SvGlobalName aClassName( xClass->getClassID() );
215 15 : if (SotExchange::IsMath(aClassName))
216 : {
217 : /*
218 : StarMath sets it own fixed size, so its counter productive to use the
219 : size word says it is. i.e. Don't attempt to override its size.
220 : */
221 10 : pMathFlySet = new SfxItemSet(rFlySet);
222 10 : pMathFlySet->ClearItem(RES_FRM_SIZE);
223 15 : }
224 : }
225 :
226 : /*
227 : Take complete responsibility of the object away from SdrOle2Obj and to
228 : me here locally. This utility class now owns the object.
229 : */
230 :
231 : // TODO/MBA: is the object inserted multiple times here? Testing!
232 : // And is it a problem that we now use the same naming scheme as in the other apps?
233 30 : sw::hack::DrawingOLEAdaptor aOLEObj(rObject, *pPersist);
234 30 : OUString sNewName;
235 15 : bool bSuccess = aOLEObj.TransferToDoc(sNewName);
236 :
237 : OSL_ENSURE(bSuccess, "Insert OLE failed");
238 15 : if (bSuccess)
239 : {
240 15 : const SfxItemSet *pFlySet = pMathFlySet ? pMathFlySet : &rFlySet;
241 15 : pRet = m_rDoc.getIDocumentContentOperations().InsertOLE(*m_pPaM, sNewName, rObject.GetAspect(), pFlySet, &rGrfSet, 0);
242 : }
243 15 : delete pMathFlySet;
244 30 : return pRet;
245 : }
246 :
247 9 : SwFrameFormat* SwWW8ImplReader::ImportOle(const Graphic* pGrf,
248 : const SfxItemSet* pFlySet, const SfxItemSet *pGrfSet, const Rectangle& aVisArea )
249 : {
250 9 : ::SetProgressState(m_nProgress, m_pDocShell); // Update
251 9 : SwFrameFormat* pFormat = 0;
252 :
253 9 : GrafikCtor();
254 :
255 9 : Graphic aGraph;
256 9 : SdrObject* pRet = ImportOleBase(aGraph, pGrf, pFlySet, aVisArea );
257 :
258 : // create flyset
259 9 : SfxItemSet* pTempSet = 0;
260 9 : if( !pFlySet )
261 : {
262 0 : pTempSet = new SfxItemSet( m_rDoc.GetAttrPool(), RES_FRMATR_BEGIN,
263 0 : RES_FRMATR_END-1);
264 :
265 0 : pFlySet = pTempSet;
266 :
267 : // Abstand/Umrandung raus
268 0 : if (!m_bNewDoc)
269 0 : Reader::ResetFrameFormatAttrs( *pTempSet );
270 :
271 0 : SwFormatAnchor aAnchor( FLY_AS_CHAR );
272 0 : aAnchor.SetAnchor( m_pPaM->GetPoint() );
273 0 : pTempSet->Put( aAnchor );
274 :
275 : const Size aSizeTwip = OutputDevice::LogicToLogic(
276 0 : aGraph.GetPrefSize(), aGraph.GetPrefMapMode(), MAP_TWIP );
277 :
278 : pTempSet->Put( SwFormatFrmSize( ATT_FIX_SIZE, aSizeTwip.Width(),
279 0 : aSizeTwip.Height() ) );
280 0 : pTempSet->Put( SwFormatVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ));
281 :
282 0 : if( m_pSFlyPara )
283 : {
284 : // OLE im Rahmen ? ok, Rahmen auf Bildgroesse vergroessern (
285 : // nur wenn Auto-Breite )
286 0 : m_pSFlyPara->BoxUpWidth( aSizeTwip.Width() );
287 0 : }
288 : }
289 :
290 9 : if (pRet) // Ole-Object wurde eingefuegt
291 : {
292 8 : if (pRet->ISA(SdrOle2Obj))
293 : {
294 4 : pFormat = InsertOle(*static_cast<SdrOle2Obj*>(pRet), *pFlySet, *pGrfSet);
295 4 : SdrObject::Free( pRet ); // das brauchen wir nicht mehr
296 : }
297 : else
298 4 : pFormat = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pRet, *pFlySet );
299 : }
300 1 : else if (
301 1 : GRAPHIC_GDIMETAFILE == aGraph.GetType() ||
302 0 : GRAPHIC_BITMAP == aGraph.GetType()
303 : )
304 : {
305 1 : pFormat = m_rDoc.getIDocumentContentOperations().Insert(*m_pPaM, OUString(), OUString(), &aGraph, pFlySet,
306 1 : pGrfSet, NULL);
307 : }
308 9 : delete pTempSet;
309 9 : return pFormat;
310 : }
311 :
312 0 : bool SwWW8ImplReader::ImportOleWMF(tools::SvRef<SotStorage> xSrc1,GDIMetaFile &rWMF,
313 : long &rX,long &rY)
314 : {
315 0 : bool bOk = false;
316 : OLE_MFP aMfp;
317 0 : if( SwWw6ReadMetaStream( rWMF, &aMfp, xSrc1 ) )
318 : {
319 : /*
320 : take scaling factor as found in PIC and apply it to graphic.
321 : */
322 0 : SwWw8ReadScaling( rX, rY, xSrc1 );
323 0 : Size aFinalSize, aOrigSize;
324 0 : aFinalSize.Width() = rX;
325 0 : aFinalSize.Height() = rY;
326 : aFinalSize = OutputDevice::LogicToLogic(
327 0 : aFinalSize, MAP_TWIP, rWMF.GetPrefMapMode() );
328 0 : aOrigSize = rWMF.GetPrefSize();
329 0 : Fraction aScaleX(aFinalSize.Width(),aOrigSize.Width());
330 0 : Fraction aScaleY(aFinalSize.Height(),aOrigSize.Height());
331 0 : rWMF.Scale( aScaleX, aScaleY );
332 0 : bOk = true;
333 : }
334 0 : return bOk;
335 : }
336 :
337 9 : SdrObject* SwWW8ImplReader::ImportOleBase( Graphic& rGraph,
338 : const Graphic* pGrf, const SfxItemSet* pFlySet, const Rectangle& aVisArea )
339 : {
340 9 : SdrObject* pRet = 0;
341 : OSL_ENSURE( m_pStg, "ohne storage geht hier fast gar nichts!" );
342 :
343 9 : ::SetProgressState( m_nProgress, m_rDoc.GetDocShell() ); // Update
344 :
345 9 : long nX=0, nY=0; // nX, nY is graphic size
346 9 : bool bOleOk = true;
347 :
348 9 : OUString aSrcStgName('_');
349 : // ergibt Name "_4711"
350 9 : aSrcStgName += OUString::number( m_nObjLocFc );
351 :
352 18 : tools::SvRef<SotStorage> xSrc0 = m_pStg->OpenSotStorage(OUString(SL::aObjectPool));
353 : tools::SvRef<SotStorage> xSrc1 = xSrc0->OpenSotStorage( aSrcStgName,
354 18 : STREAM_READWRITE| StreamMode::SHARE_DENYALL );
355 :
356 9 : if (pGrf)
357 : {
358 9 : rGraph = *pGrf;
359 : const Size aSizeTwip = OutputDevice::LogicToLogic(
360 9 : rGraph.GetPrefSize(), rGraph.GetPrefMapMode(), MAP_TWIP );
361 9 : nX = aSizeTwip.Width();
362 9 : nY = aSizeTwip.Height();
363 : }
364 : else
365 : {
366 0 : GDIMetaFile aWMF;
367 :
368 0 : if (ImportOleWMF(xSrc1,aWMF,nX,nY))
369 0 : rGraph = Graphic( aWMF );
370 0 : else if( SwWw6ReadMacPICTStream( rGraph, xSrc1 ) )
371 : {
372 : // 03-META-Stream nicht da. Vielleicht ein 03-PICT ?
373 : const Size aSizeTwip = OutputDevice::LogicToLogic(
374 0 : rGraph.GetPrefSize(), rGraph.GetPrefMapMode(), MAP_TWIP );
375 0 : nX = aSizeTwip.Width();
376 0 : nY = aSizeTwip.Height();
377 : // PICT: kein WMF da -> Grafik statt OLE
378 0 : bOleOk = false;
379 0 : }
380 : } // StorageStreams wieder zu
381 :
382 9 : Rectangle aRect(0, 0, nX, nY);
383 :
384 9 : if (pFlySet)
385 : {
386 9 : if (const SwFormatFrmSize* pSize =
387 9 : static_cast<const SwFormatFrmSize*>(pFlySet->GetItem(RES_FRM_SIZE, false)))
388 : {
389 9 : aRect.SetSize(pSize->GetSize());
390 : }
391 : }
392 :
393 9 : if (!(m_bIsHeader || m_bIsFooter))
394 : {
395 : //Can't put them in headers/footers :-(
396 9 : uno::Reference< drawing::XShape > xRef;
397 : OSL_ENSURE(m_pFormImpl, "Impossible");
398 9 : if (m_pFormImpl && m_pFormImpl->ReadOCXStream(xSrc1, &xRef, false))
399 : {
400 4 : pRet = GetSdrObjectFromXShape(xRef);
401 : OSL_ENSURE(pRet, "Impossible");
402 4 : if (pRet)
403 4 : pRet->SetLogicRect(aRect);
404 4 : return pRet;
405 5 : }
406 : }
407 :
408 5 : if (GRAPHIC_GDIMETAFILE == rGraph.GetType() ||
409 0 : GRAPHIC_BITMAP == rGraph.GetType())
410 : {
411 5 : ::SetProgressState(m_nProgress, m_pDocShell); // Update
412 :
413 5 : if (bOleOk)
414 : {
415 5 : sal_uLong nOldPos = m_pDataStream->Tell();
416 5 : m_pDataStream->Seek(STREAM_SEEK_TO_END);
417 5 : SvStream *pTmpData = 0;
418 5 : if (m_nObjLocFc < m_pDataStream->Tell())
419 : {
420 0 : pTmpData = m_pDataStream;
421 0 : pTmpData->Seek( m_nObjLocFc );
422 : }
423 :
424 5 : sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
425 :
426 : {
427 : tools::SvRef<SotStorageStream> xObjInfoSrc = xSrc1->OpenSotStream(OUString("\3ObjInfo"),
428 5 : STREAM_STD_READ | StreamMode::NOCREATE );
429 5 : if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
430 : {
431 5 : sal_uInt8 nByte = 0;
432 5 : xObjInfoSrc->ReadUChar( nByte );
433 5 : if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
434 1 : nAspect = embed::Aspects::MSOLE_ICON;
435 5 : }
436 : }
437 :
438 5 : ErrCode nError = ERRCODE_NONE;
439 : pRet = SvxMSDffManager::CreateSdrOLEFromStorage(
440 : aSrcStgName, xSrc0, m_pDocShell->GetStorage(), rGraph, aRect, aVisArea, pTmpData, nError,
441 5 : SwMSDffManager::GetFilterFlags(), nAspect );
442 5 : m_pDataStream->Seek( nOldPos );
443 : }
444 : }
445 14 : return pRet;
446 : }
447 :
448 72 : void SwWW8ImplReader::ReadRevMarkAuthorStrTabl( SvStream& rStrm,
449 : sal_Int32 nTablePos, sal_Int32 nTableSiz, SwDoc& rDocOut )
450 : {
451 72 : ::std::vector<OUString> aAuthorNames;
452 72 : WW8ReadSTTBF( !m_bVer67, rStrm, nTablePos, nTableSiz, m_bVer67 ? 2 : 0,
453 144 : m_eStructCharSet, aAuthorNames );
454 :
455 72 : sal_uInt16 nCount = static_cast< sal_uInt16 >(aAuthorNames.size());
456 1454 : for( sal_uInt16 nAuthor = 0; nAuthor < nCount; ++nAuthor )
457 : {
458 : // Store author in doc
459 1382 : sal_uInt16 nSWId = rDocOut.getIDocumentRedlineAccess().InsertRedlineAuthor(aAuthorNames[nAuthor]);
460 : // Store matchpair
461 1382 : m_aAuthorInfos[nAuthor] = nSWId;
462 72 : }
463 72 : }
464 :
465 : /*
466 : Revision Marks ( == Redlining )
467 : */
468 : // insert or delete content (change char attributes resp.)
469 10 : void SwWW8ImplReader::Read_CRevisionMark(RedlineType_t eType,
470 : const sal_uInt8* pData, short nLen )
471 : {
472 : // there *must* be a SprmCIbstRMark[Del] and a SprmCDttmRMark[Del]
473 : // pointing to the very same char position as our SprmCFRMark[Del]
474 10 : if (!m_pPlcxMan)
475 10 : return;
476 : const sal_uInt8* pSprmCIbstRMark;
477 : const sal_uInt8* pSprmCDttmRMark;
478 10 : if( nsRedlineType_t::REDLINE_FORMAT == eType )
479 : {
480 0 : pSprmCIbstRMark = pData+1;
481 0 : pSprmCDttmRMark = pData+3;
482 : }
483 : else
484 : {
485 : /*
486 : It is possible to have a number of date stamps for the created time
487 : of the change, (possibly a word bug) so we must use the "get a full
488 : list" variant of HasCharSprm and take the last one as the true one.
489 : */
490 10 : std::vector<const sal_uInt8 *> aResult;
491 10 : bool bIns = (nsRedlineType_t::REDLINE_INSERT == eType);
492 10 : if( m_bVer67 )
493 : {
494 0 : m_pPlcxMan->HasCharSprm(69, aResult);
495 0 : pSprmCIbstRMark = aResult.empty() ? 0 : aResult.back();
496 0 : aResult.clear();
497 0 : m_pPlcxMan->HasCharSprm(70, aResult);
498 0 : pSprmCDttmRMark = aResult.empty() ? 0 : aResult.back();
499 : }
500 : else
501 : {
502 10 : m_pPlcxMan->HasCharSprm( bIns ? 0x4804 : 0x4863, aResult);
503 10 : pSprmCIbstRMark = aResult.empty() ? 0 : aResult.back();
504 10 : aResult.clear();
505 10 : m_pPlcxMan->HasCharSprm( bIns ? 0x6805 : NS_sprm::LN_CDttmRMarkDel, aResult);
506 10 : pSprmCDttmRMark = aResult.empty() ? 0 : aResult.back();
507 10 : }
508 : }
509 :
510 10 : if (nLen < 0)
511 5 : m_pRedlineStack->close(*m_pPaM->GetPoint(), eType, m_pTableDesc );
512 : else
513 : {
514 : // start of new revision mark, if not there default to first entry
515 5 : sal_uInt16 nWWAutNo = pSprmCIbstRMark ? SVBT16ToShort(pSprmCIbstRMark) : 0;
516 5 : sal_uInt32 nWWDate = pSprmCDttmRMark ? SVBT32ToUInt32(pSprmCDttmRMark): 0;
517 5 : DateTime aStamp(msfilter::util::DTTM2DateTime(nWWDate));
518 5 : sal_uInt16 nAuthorNo = m_aAuthorInfos[nWWAutNo];
519 5 : SwFltRedline aNewAttr(eType, nAuthorNo, aStamp);
520 5 : NewAttr(aNewAttr);
521 : }
522 : }
523 :
524 : // insert new content
525 2 : void SwWW8ImplReader::Read_CFRMark(sal_uInt16 , const sal_uInt8* pData, short nLen)
526 : {
527 2 : Read_CRevisionMark( nsRedlineType_t::REDLINE_INSERT, pData, nLen );
528 2 : }
529 :
530 : // delete old content
531 8 : void SwWW8ImplReader::Read_CFRMarkDel(sal_uInt16 , const sal_uInt8* pData, short nLen)
532 : {
533 8 : Read_CRevisionMark( nsRedlineType_t::REDLINE_DELETE, pData, nLen );
534 8 : }
535 :
536 : // change properties of content ( == char formatting)
537 0 : void SwWW8ImplReader::Read_CPropRMark(sal_uInt16 , const sal_uInt8* pData, short nLen)
538 : {
539 : // complex (len is always 7)
540 : // 1 byte - chp.fPropRMark
541 : // 2 bytes - chp.ibstPropRMark
542 : // 4 bytes - chp.dttmPropRMark;
543 0 : Read_CRevisionMark( nsRedlineType_t::REDLINE_FORMAT, pData, nLen );
544 60 : }
545 :
546 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|