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