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 
27 #include <com/sun/star/util/DateTime.hpp>
28 #include <com/sun/star/text/XTextTable.hpp>
29 
30 #include <rtl/ustrbuf.hxx>
31 #include <vos/mutex.hxx>
32 #include <vcl/svapp.hxx>
33 
34 #include <pagedesc.hxx>
35 #include "poolfmt.hxx"
36 #include <redline.hxx>
37 #include <section.hxx>
38 #include <unoprnms.hxx>
39 #include <unomid.h>
40 #include <unotextrange.hxx>
41 #include <unotextcursor.hxx>
42 #include <unoparagraph.hxx>
43 #include <unocoll.hxx>
44 #include <unomap.hxx>
45 #include <unocrsr.hxx>
46 #include <unoredline.hxx>
47 #include <doc.hxx>
48 #include <docary.hxx>
49 
50 
51 using namespace ::com::sun::star;
52 using ::rtl::OUString;
53 using ::rtl::OUStringBuffer;
54 
55 
56 
SwXRedlineText(SwDoc * _pDoc,SwNodeIndex aIndex)57 SwXRedlineText::SwXRedlineText(SwDoc* _pDoc, SwNodeIndex aIndex) :
58 	SwXText(_pDoc, CURSOR_REDLINE),
59 	aNodeIndex(aIndex)
60 {
61 }
62 
GetStartNode() const63 const SwStartNode* SwXRedlineText::GetStartNode() const
64 {
65 	return aNodeIndex.GetNode().GetStartNode();
66 }
67 
queryInterface(const uno::Type & rType)68 uno::Any SwXRedlineText::queryInterface( const uno::Type& rType )
69 	throw(uno::RuntimeException)
70 {
71 	uno::Any aRet;
72 
73 	if (::getCppuType((uno::Reference<container::XEnumerationAccess> *)0) == rType)
74 	{
75 		uno::Reference<container::XEnumerationAccess> aAccess = this;
76 		aRet <<= aAccess;
77 	}
78 	else
79 	{
80 		// delegate to SwXText and OWeakObject
81 		aRet = SwXText::queryInterface(rType);
82 		if(!aRet.hasValue())
83 		{
84 			aRet = OWeakObject::queryInterface(rType);
85 		}
86 	}
87 
88 	return aRet;
89 }
90 
getTypes()91 uno::Sequence<uno::Type> SwXRedlineText::getTypes()
92 	throw(uno::RuntimeException)
93 {
94 	// SwXText::getTypes()
95 	uno::Sequence<uno::Type> aTypes = SwXText::getTypes();
96 
97 	// add container::XEnumerationAccess
98 	sal_Int32 nLength = aTypes.getLength();
99 	aTypes.realloc(nLength + 1);
100 	aTypes[nLength] = ::getCppuType((uno::Reference<container::XEnumerationAccess> *)0);
101 
102 	return aTypes;
103 }
104 
getImplementationId()105 uno::Sequence<sal_Int8> SwXRedlineText::getImplementationId()
106 	throw(uno::RuntimeException)
107 {
108     vos::OGuard aGuard(Application::GetSolarMutex());
109     static uno::Sequence< sal_Int8 > aId( 16 );
110     static sal_Bool bInit = sal_False;
111     if(!bInit)
112     {
113         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
114         bInit = sal_True;
115     }
116     return aId;
117 }
118 
createTextCursor(void)119 uno::Reference<text::XTextCursor> SwXRedlineText::createTextCursor(void)
120 	throw( uno::RuntimeException )
121 {
122 	vos::OGuard aGuard(Application::GetSolarMutex());
123 
124 	SwPosition aPos(aNodeIndex);
125     SwXTextCursor *const pXCursor =
126         new SwXTextCursor(*GetDoc(), this, CURSOR_REDLINE, aPos);
127     SwUnoCrsr *const pUnoCursor = pXCursor->GetCursor();
128 	pUnoCursor->Move(fnMoveForward, fnGoNode);
129 
130     // #101929# prevent a newly created text cursor from running inside a table
131     // because table cells have their own XText.
132     // Patterned after SwXTextFrame::createTextCursor(void).
133 
134     // skip all tables at the beginning
135     SwTableNode* pTableNode = pUnoCursor->GetNode()->FindTableNode();
136     SwCntntNode* pContentNode = NULL;
137     bool bTable = pTableNode != NULL;
138     while( pTableNode != NULL )
139     {
140         pUnoCursor->GetPoint()->nNode = *(pTableNode->EndOfSectionNode());
141         pContentNode = GetDoc()->GetNodes().GoNext(&pUnoCursor->GetPoint()->nNode);
142         pTableNode = pContentNode->FindTableNode();
143     }
144     if( pContentNode != NULL )
145         pUnoCursor->GetPoint()->nContent.Assign( pContentNode, 0 );
146     if( bTable && pUnoCursor->GetNode()->FindSttNodeByType( SwNormalStartNode )
147                                                             != GetStartNode() )
148     {
149         // We have gone too far and have left our own redline. This means that
150         // no content node outside of a table could be found, and therefore we
151         // except.
152         uno::RuntimeException aExcept;
153         aExcept.Message = OUString( RTL_CONSTASCII_USTRINGPARAM(
154             "No content node found that is inside this change section "
155             "but outside of a table" ) );
156         throw aExcept;
157     }
158 
159     return static_cast<text::XWordCursor*>(pXCursor);
160 }
161 
createTextCursorByRange(const uno::Reference<text::XTextRange> & aTextRange)162 uno::Reference<text::XTextCursor> SwXRedlineText::createTextCursorByRange(
163 	const uno::Reference<text::XTextRange> & aTextRange)
164 		throw( uno::RuntimeException )
165 {
166 	uno::Reference<text::XTextCursor> xCursor = createTextCursor();
167 	xCursor->gotoRange(aTextRange->getStart(), sal_False);
168 	xCursor->gotoRange(aTextRange->getEnd(), sal_True);
169 	return xCursor;
170 }
171 
createEnumeration(void)172 uno::Reference<container::XEnumeration> SwXRedlineText::createEnumeration(void)
173 	throw( uno::RuntimeException )
174 {
175 	vos::OGuard aGuard(Application::GetSolarMutex());
176 	SwPaM aPam(aNodeIndex);
177 	aPam.Move(fnMoveForward, fnGoNode);
178     ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
179         GetDoc()->CreateUnoCrsr(*aPam.Start(), sal_False));
180     return new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_REDLINE);
181 }
182 
getElementType()183 uno::Type SwXRedlineText::getElementType(  ) throw(uno::RuntimeException)
184 {
185 	return ::getCppuType((uno::Reference<text::XTextRange>*)0);
186 }
187 
hasElements()188 sal_Bool SwXRedlineText::hasElements(  ) throw(uno::RuntimeException)
189 {
190 	return sal_True; 	// we always have a content index
191 }
192 
SwXRedlinePortion(const SwRedline * pRed,const SwUnoCrsr * pPortionCrsr,uno::Reference<text::XText> xParent,sal_Bool bStart)193 SwXRedlinePortion::SwXRedlinePortion(	const SwRedline* pRed,
194 						const SwUnoCrsr* pPortionCrsr,
195 						uno::Reference< text::XText >  xParent, sal_Bool bStart) :
196 	SwXTextPortion(pPortionCrsr, xParent, bStart ? PORTION_REDLINE_START : PORTION_REDLINE_END),
197 //	SwXText(pPortionCrsr->GetDoc(), CURSOR_REDLINE),
198 //	SwXRedlineText(pPortionCrsr->GetDoc(), *pRed->GetContentIdx()),
199 	pRedline(pRed)
200 {
201 	SetCollapsed(!pRedline->HasMark());
202 }
203 
~SwXRedlinePortion()204 SwXRedlinePortion::~SwXRedlinePortion()
205 {
206 }
207 
lcl_DateTimeToUno(const DateTime & rDT)208 static util::DateTime lcl_DateTimeToUno(const DateTime& rDT)
209 {
210 	util::DateTime aRetDT;
211 	aRetDT.Year = rDT.GetYear();
212 	aRetDT.Month= rDT.GetMonth();
213 	aRetDT.Day  	= rDT.GetDay();
214 	aRetDT.Hours	= rDT.GetHour();
215 	aRetDT.Minutes = rDT.GetMin();
216 	aRetDT.Seconds = rDT.GetSec();
217 	aRetDT.HundredthSeconds = rDT.Get100Sec();
218 	return aRetDT;
219 }
220 
221 // ---------------------------------------------------------------------------
lcl_RedlineTypeToOUString(RedlineType_t eType)222 static OUString lcl_RedlineTypeToOUString(RedlineType_t eType)
223 {
224 	OUString sRet;
225 	switch(eType & nsRedlineType_t::REDLINE_NO_FLAG_MASK)
226 	{
227 		case nsRedlineType_t::REDLINE_INSERT: sRet = C2U("Insert"); break;
228 		case nsRedlineType_t::REDLINE_DELETE: sRet = C2U("Delete"); break;
229 		case nsRedlineType_t::REDLINE_FORMAT: sRet = C2U("Format"); break;
230 		case nsRedlineType_t::REDLINE_TABLE:  sRet = C2U("TextTable"); break;
231 		case nsRedlineType_t::REDLINE_FMTCOLL:sRet = C2U("Style"); break;
232 	}
233 	return sRet;
234 }
235 
236 // ---------------------------------------------------------------------------
lcl_GetSuccessorProperties(const SwRedline & rRedline)237 static uno::Sequence<beans::PropertyValue> lcl_GetSuccessorProperties(const SwRedline& rRedline)
238 {
239 	uno::Sequence<beans::PropertyValue> aValues(4);
240 
241 	const SwRedlineData* pNext = rRedline.GetRedlineData().Next();
242 	if(pNext)
243 	{
244 		beans::PropertyValue* pValues = aValues.getArray();
245 		pValues[0].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_AUTHOR));
246 		// GetAuthorString(n) walks the SwRedlineData* chain;
247 		// here we always need element 1
248 		pValues[0].Value <<= OUString(rRedline.GetAuthorString(1));
249 		pValues[1].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_DATE_TIME));
250 		pValues[1].Value <<= lcl_DateTimeToUno(pNext->GetTimeStamp());
251 		pValues[2].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_COMMENT));
252 		pValues[2].Value <<= OUString(pNext->GetComment());
253 		pValues[3].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_TYPE));
254 		pValues[3].Value <<= lcl_RedlineTypeToOUString(pNext->GetType());
255 	}
256 	return aValues;
257 }
258 // ---------------------------------------------------------------------------
getPropertyValue(const OUString & rPropertyName)259 uno::Any SwXRedlinePortion::getPropertyValue( const OUString& rPropertyName )
260 		throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
261 {
262 	vos::OGuard aGuard(Application::GetSolarMutex());
263 	Validate();
264 	uno::Any aRet;
265 	if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_TEXT)))
266 	{
267 		SwNodeIndex* pNodeIdx = pRedline->GetContentIdx();
268 		if(pNodeIdx )
269 		{
270 			if ( 1 < ( pNodeIdx->GetNode().EndOfSectionIndex() - pNodeIdx->GetNode().GetIndex() ) )
271 			{
272                 SwUnoCrsr* pUnoCrsr = GetCursor();
273 				uno::Reference<text::XText> xRet = new SwXRedlineText(pUnoCrsr->GetDoc(), *pNodeIdx);
274 				aRet <<= xRet;
275 			}
276 			else {
277 				DBG_ASSERT(0, "Empty section in redline portion! (end node immediately follows start node)");
278             }
279 		}
280 	}
281 	else
282 	{
283 		aRet = GetPropertyValue( rPropertyName, *pRedline);
284 		if(!aRet.hasValue() &&
285 		   ! rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_SUCCESSOR_DATA)))
286 			aRet = SwXTextPortion::getPropertyValue(rPropertyName);
287 	}
288 	return aRet;
289 }
290 
Validate()291 void SwXRedlinePortion::Validate() throw( uno::RuntimeException )
292 {
293     SwUnoCrsr* pUnoCrsr = GetCursor();
294 	if(!pUnoCrsr)
295 		throw uno::RuntimeException();
296 	//search for the redline
297 	SwDoc* pDoc = pUnoCrsr->GetDoc();
298 	const SwRedlineTbl& rRedTbl = pDoc->GetRedlineTbl();
299 	sal_Bool bFound = sal_False;
300 	for(sal_uInt16 nRed = 0; nRed < rRedTbl.Count() && !bFound; nRed++)
301 		bFound = pRedline == rRedTbl[nRed];
302 	if(!bFound)
303 		throw uno::RuntimeException();
304 }
305 
getImplementationId()306 uno::Sequence< sal_Int8 > SAL_CALL SwXRedlinePortion::getImplementationId(  ) throw(uno::RuntimeException)
307 {
308     vos::OGuard aGuard(Application::GetSolarMutex());
309     static uno::Sequence< sal_Int8 > aId( 16 );
310     static sal_Bool bInit = sal_False;
311     if(!bInit)
312     {
313         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
314         bInit = sal_True;
315     }
316     return aId;
317 }
318 
GetPropertyValue(const OUString & rPropertyName,const SwRedline & rRedline)319 uno::Any  SwXRedlinePortion::GetPropertyValue( const OUString& rPropertyName, const SwRedline& rRedline ) throw()
320 {
321 	uno::Any aRet;
322 	if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_AUTHOR)))
323 		aRet <<= OUString(rRedline.GetAuthorString());
324 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_DATE_TIME)))
325 	{
326 		aRet <<= lcl_DateTimeToUno(rRedline.GetTimeStamp());
327 	}
328 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_COMMENT)))
329 		aRet <<= OUString(rRedline.GetComment());
330 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_TYPE)))
331 	{
332 		aRet <<= lcl_RedlineTypeToOUString(rRedline.GetType());
333 	}
334 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_SUCCESSOR_DATA)))
335 	{
336 		if(rRedline.GetRedlineData().Next())
337 			aRet <<= lcl_GetSuccessorProperties(rRedline);
338 	}
339 	else if (rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_IDENTIFIER)))
340 	{
341 		OUStringBuffer sBuf;
342 		sBuf.append( sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(&rRedline) ) );
343 		aRet <<= sBuf.makeStringAndClear();
344 	}
345 	else if (rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_IS_IN_HEADER_FOOTER)))
346 	{
347 		sal_Bool bRet =
348 			rRedline.GetDoc()->IsInHeaderFooter( rRedline.GetPoint()->nNode );
349 		aRet.setValue(&bRet, ::getBooleanCppuType());
350 	}
351 	else if (rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_MERGE_LAST_PARA)))
352     {
353         sal_Bool bRet = !rRedline.IsDelLastPara();
354         aRet.setValue( &bRet, ::getBooleanCppuType() );
355     }
356 	return aRet;
357 }
358 
CreateRedlineProperties(const SwRedline & rRedline,sal_Bool bIsStart)359 uno::Sequence< beans::PropertyValue > SwXRedlinePortion::CreateRedlineProperties(
360     const SwRedline& rRedline, sal_Bool bIsStart ) throw()
361 {
362     uno::Sequence< beans::PropertyValue > aRet(11);
363 	const SwRedlineData* pNext = rRedline.GetRedlineData().Next();
364 	beans::PropertyValue* pRet = aRet.getArray();
365 
366 	OUStringBuffer sRedlineIdBuf;
367 	sRedlineIdBuf.append( sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(&rRedline) ) );
368 
369     sal_Int32 nPropIdx  = 0;
370     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_AUTHOR));
371     pRet[nPropIdx++].Value <<= OUString(rRedline.GetAuthorString());
372     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_DATE_TIME));
373     pRet[nPropIdx++].Value <<= lcl_DateTimeToUno(rRedline.GetTimeStamp());
374     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_COMMENT));
375     pRet[nPropIdx++].Value <<= OUString(rRedline.GetComment());
376     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_TYPE));
377     pRet[nPropIdx++].Value <<= lcl_RedlineTypeToOUString(rRedline.GetType());
378     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_IDENTIFIER));
379     pRet[nPropIdx++].Value <<= sRedlineIdBuf.makeStringAndClear();
380     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_IS_COLLAPSED));
381     sal_Bool bTmp = !rRedline.HasMark();
382     pRet[nPropIdx++].Value.setValue(&bTmp, ::getBooleanCppuType()) ;
383 
384     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_IS_START));
385     pRet[nPropIdx++].Value.setValue(&bIsStart, ::getBooleanCppuType()) ;
386 
387     bTmp = !rRedline.IsDelLastPara();
388     pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_MERGE_LAST_PARA));
389     pRet[nPropIdx++].Value.setValue(&bTmp, ::getBooleanCppuType()) ;
390 
391     SwNodeIndex* pNodeIdx = rRedline.GetContentIdx();
392     if(pNodeIdx )
393     {
394         if ( 1 < ( pNodeIdx->GetNode().EndOfSectionIndex() - pNodeIdx->GetNode().GetIndex() ) )
395         {
396             uno::Reference<text::XText> xRet = new SwXRedlineText(rRedline.GetDoc(), *pNodeIdx);
397             pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_TEXT));
398             pRet[nPropIdx++].Value <<= xRet;
399         }
400         else {
401             DBG_ASSERT(0, "Empty section in redline portion! (end node immediately follows start node)");
402         }
403     }
404 	if(pNext)
405 	{
406         pRet[nPropIdx].Name = C2U(SW_PROP_NAME_STR(UNO_NAME_REDLINE_SUCCESSOR_DATA));
407         pRet[nPropIdx++].Value <<= lcl_GetSuccessorProperties(rRedline);
408 	}
409     aRet.realloc(nPropIdx);
410 	return aRet;
411 }
412 
413 TYPEINIT1(SwXRedline, SwClient);
SwXRedline(SwRedline & rRedline,SwDoc & rDoc)414 SwXRedline::SwXRedline(SwRedline& rRedline, SwDoc& rDoc) :
415 	SwXText(&rDoc, CURSOR_REDLINE),
416 	pDoc(&rDoc),
417 	pRedline(&rRedline)
418 {
419 	pDoc->GetPageDescFromPool(RES_POOLPAGE_STANDARD)->Add(this);
420 }
421 
~SwXRedline()422 SwXRedline::~SwXRedline()
423 {
424 }
425 
getPropertySetInfo()426 uno::Reference< beans::XPropertySetInfo > SwXRedline::getPropertySetInfo(  ) throw(uno::RuntimeException)
427 {
428 	static uno::Reference< beans::XPropertySetInfo >  xRef =
429         aSwMapProvider.GetPropertySet(PROPERTY_MAP_REDLINE)->getPropertySetInfo();
430 	return xRef;
431 }
432 
setPropertyValue(const OUString & rPropertyName,const uno::Any & aValue)433 void SwXRedline::setPropertyValue( const OUString& rPropertyName, const uno::Any& aValue )
434 	throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException,
435 		lang::WrappedTargetException, uno::RuntimeException)
436 {
437 	vos::OGuard aGuard(Application::GetSolarMutex());
438 	if(!pDoc)
439 		throw uno::RuntimeException();
440 	if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_AUTHOR)))
441 	{
442 		DBG_ERROR("currently not available");
443 	}
444 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_DATE_TIME)))
445 	{
446 		DBG_ERROR("currently not available");
447 //		util::DateTime aDT;
448 //		if(aValue >>= aDT)
449 //				pRedline->SetTimeStamp(lcl_DateTimeFromUno(aDT));
450 	}
451 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_COMMENT)))
452 	{
453 		OUString sTmp; aValue >>= sTmp;
454 		pRedline->SetComment(sTmp);
455 	}
456 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_TYPE)))
457 	{
458 		DBG_ERROR("currently not available");
459 		OUString sTmp; aValue >>= sTmp;
460 		if(!sTmp.getLength())
461 			throw lang::IllegalArgumentException();
462 //		pRedline->SetType(lcl_OUStringToRedlineType(sTmp));
463 	}
464 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_SUCCESSOR_DATA)))
465 	{
466 		DBG_ERROR("currently not available");
467 /*		SwRedlineData* pNext = pRedline->GetRedlineData().Next();
468 		uno::Sequence<beans::PropertyValue> aValues;
469 		if(!(aValue =>> aValues) || !pNext)
470 			throw lang::IllegalArgumentException();
471 
472 		const beans::PropertyValue* pValues = aValues.getConstArray();
473 		for(sal_Int32 nValue = 0; nValue < aValues.getLength(); nValue++)
474 		{
475 			if(pValues[nValue].Name.equalsAscii(UNO_NAME_REDLINE_AUTHOR.pName)
476 			{
477 				DBG_ERROR("currently not available");
478 			}
479 			else if(pValues[nValue].Name.equalsAscii(UNO_NAME_REDLINE_DATE_TIME.pName))
480 			{
481 				util::DateTime aDT;
482 				if(pValues[nValue].Value >>= aDT)
483 					pNext->SetTimeStamp(lcl_DateTimeFromUno(aDT));
484 			}
485 			else if(pValues[nValue].Name.equalsAscii(UNO_NAME_REDLINE_COMMENT.pName))
486 			{
487 				OUString sTmp; pValues[nValue].Value >>= sTmp;
488 				pNext->SetComment(sTmp);
489 			}
490 			else if(pValues[nValue].Name.equalsAscii(UNO_NAME_REDLINE_TYPE.pName))
491 			{
492 				OUString sTmp; pValues[nValue].Value >>= sTmp;
493 				pNext->SetType(lcl_OUStringToRedlineType(sTmp);
494 			}
495 		}
496 */	}
497 	else
498 	{
499 		throw lang::IllegalArgumentException();
500 	}
501 }
502 
getPropertyValue(const OUString & rPropertyName)503 uno::Any SwXRedline::getPropertyValue( const OUString& rPropertyName )
504 	throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
505 {
506 	vos::OGuard aGuard(Application::GetSolarMutex());
507 	if(!pDoc)
508 		throw uno::RuntimeException();
509 	uno::Any aRet;
510 	sal_Bool bStart = rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_START));
511 	if(bStart ||
512 		rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_END)))
513 	{
514 		uno::Reference<XInterface> xRet;
515 		SwNode* pNode = pRedline->GetNode();
516 		if(!bStart && pRedline->HasMark())
517 			pNode = pRedline->GetNode(sal_False);
518 		switch(pNode->GetNodeType())
519 		{
520 			case ND_SECTIONNODE:
521 			{
522 				SwSectionNode* pSectNode = pNode->GetSectionNode();
523 				DBG_ASSERT(pSectNode, "No section node!");
524 				xRet = SwXTextSections::GetObject( *pSectNode->GetSection().GetFmt() );
525 			}
526 			break;
527 			case ND_TABLENODE :
528 			{
529 				SwTableNode* pTblNode = pNode->GetTableNode();
530 				DBG_ASSERT(pTblNode, "No table node!");
531 				SwTable& rTbl = pTblNode->GetTable();
532 				SwFrmFmt* pTblFmt = rTbl.GetFrmFmt();
533 				xRet = SwXTextTables::GetObject( *pTblFmt );
534 			}
535 			break;
536 			case ND_TEXTNODE :
537 			{
538 				SwPosition* pPoint = 0;
539 				if(bStart || !pRedline->HasMark())
540 					pPoint = pRedline->GetPoint();
541 				else
542 					pPoint = pRedline->GetMark();
543                 const uno::Reference<text::XTextRange> xRange =
544                     SwXTextRange::CreateXTextRange(*pDoc, *pPoint, 0);
545 				xRet = xRange.get();
546 			}
547 			break;
548 			default:
549 				DBG_ERROR("illegal node type");
550 		}
551 		aRet <<= xRet;
552 	}
553 	else if(rPropertyName.equalsAsciiL(SW_PROP_NAME(UNO_NAME_REDLINE_TEXT)))
554 	{
555 		SwNodeIndex* pNodeIdx = pRedline->GetContentIdx();
556 		if( pNodeIdx )
557 		{
558 			if ( 1 < ( pNodeIdx->GetNode().EndOfSectionIndex() - pNodeIdx->GetNode().GetIndex() ) )
559 			{
560 				uno::Reference<text::XText> xRet = new SwXRedlineText(pDoc, *pNodeIdx);
561 				aRet <<= xRet;
562 			}
563 			else {
564 				DBG_ASSERT(0, "Empty section in redline portion! (end node immediately follows start node)");
565             }
566 		}
567 	}
568 	else
569 		aRet = SwXRedlinePortion::GetPropertyValue(rPropertyName, *pRedline);
570 	return aRet;
571 }
572 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)573 void SwXRedline::addPropertyChangeListener(
574 	const OUString& /*aPropertyName*/,
575     const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/ )
576 		throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
577 {
578 }
579 
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)580 void SwXRedline::removePropertyChangeListener(
581     const OUString& /*aPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
582 		throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
583 {
584 }
585 
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)586 void SwXRedline::addVetoableChangeListener(
587     const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
588         throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
589 {
590 }
591 
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)592 void SwXRedline::removeVetoableChangeListener(
593     const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
594 		throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
595 {
596 }
597 
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)598 void SwXRedline::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
599 {
600 	ClientModify(this, pOld, pNew);
601 	if(!GetRegisteredIn())
602   	{
603 		pDoc = 0;
604 		pRedline = 0;
605 	}
606 }
607 
createEnumeration(void)608 uno::Reference< container::XEnumeration >  SwXRedline::createEnumeration(void) throw( uno::RuntimeException )
609 {
610 	vos::OGuard aGuard(Application::GetSolarMutex());
611 	uno::Reference< container::XEnumeration > xRet;
612 	if(!pDoc)
613 		throw uno::RuntimeException();
614 
615 	SwNodeIndex* pNodeIndex = pRedline->GetContentIdx();
616 	if(pNodeIndex)
617 	{
618 		SwPaM aPam(*pNodeIndex);
619 		aPam.Move(fnMoveForward, fnGoNode);
620         ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
621             GetDoc()->CreateUnoCrsr(*aPam.Start(), sal_False));
622         xRet = new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_REDLINE);
623 	}
624 	return xRet;
625 }
626 
getElementType()627 uno::Type SwXRedline::getElementType(  ) throw(uno::RuntimeException)
628 {
629 	return ::getCppuType((uno::Reference<text::XTextRange>*)0);
630 }
631 
hasElements()632 sal_Bool SwXRedline::hasElements(  ) throw(uno::RuntimeException)
633 {
634 	if(!pDoc)
635 		throw uno::RuntimeException();
636 	return 0 != pRedline->GetContentIdx();
637 }
638 
createTextCursor(void)639 uno::Reference< text::XTextCursor >  SwXRedline::createTextCursor(void) throw( uno::RuntimeException )
640 {
641 	vos::OGuard aGuard(Application::GetSolarMutex());
642 	if(!pDoc)
643 		throw uno::RuntimeException();
644 
645 	uno::Reference< text::XTextCursor >  	xRet;
646 	SwNodeIndex* pNodeIndex = pRedline->GetContentIdx();
647 	if(pNodeIndex)
648 	{
649 		SwPosition aPos(*pNodeIndex);
650         SwXTextCursor *const pXCursor =
651             new SwXTextCursor(*pDoc, this, CURSOR_REDLINE, aPos);
652         SwUnoCrsr *const pUnoCrsr = pXCursor->GetCursor();
653 		pUnoCrsr->Move(fnMoveForward, fnGoNode);
654 
655 		//steht hier eine Tabelle?
656 		SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
657 		SwCntntNode* pCont = 0;
658 		while( pTblNode )
659 		{
660 			pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode();
661 			pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode);
662 			pTblNode = pCont->FindTableNode();
663 		}
664 		if(pCont)
665 			pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
666         xRet = static_cast<text::XWordCursor*>(pXCursor);
667 	}
668 	else
669 	{
670 		throw uno::RuntimeException();
671 	}
672 	return xRet;
673 }
674 
createTextCursorByRange(const uno::Reference<text::XTextRange> &)675 uno::Reference< text::XTextCursor >  SwXRedline::createTextCursorByRange(
676     const uno::Reference< text::XTextRange > & /*aTextPosition*/)
677 		throw( uno::RuntimeException )
678 {
679 	throw uno::RuntimeException();
680 }
681 
queryInterface(const uno::Type & rType)682 uno::Any SwXRedline::queryInterface( const uno::Type& rType )
683 	throw(uno::RuntimeException)
684 {
685 	uno::Any aRet = SwXText::queryInterface(rType);
686 	if(!aRet.hasValue())
687 	{
688 		aRet = SwXRedlineBaseClass::queryInterface(rType);
689 	}
690 	return aRet;
691 }
692 
getTypes()693 uno::Sequence<uno::Type> SwXRedline::getTypes()
694 	throw(uno::RuntimeException)
695 {
696 	uno::Sequence<uno::Type> aTypes = SwXText::getTypes();
697 	uno::Sequence<uno::Type> aBaseTypes = SwXRedlineBaseClass::getTypes();
698 	const uno::Type* pBaseTypes = aBaseTypes.getConstArray();
699 	sal_Int32 nCurType = aTypes.getLength();
700 	aTypes.realloc(aTypes.getLength() + aBaseTypes.getLength());
701 	uno::Type* pTypes = aTypes.getArray();
702 	for(sal_Int32 nType = 0; nType < aBaseTypes.getLength(); nType++)
703 		pTypes[nCurType++] = pBaseTypes[nType];
704 	return aTypes;
705 }
706 
getImplementationId()707 uno::Sequence<sal_Int8> SwXRedline::getImplementationId()
708 	throw(uno::RuntimeException)
709 {
710     vos::OGuard aGuard(Application::GetSolarMutex());
711     static uno::Sequence< sal_Int8 > aId( 16 );
712     static sal_Bool bInit = sal_False;
713     if(!bInit)
714     {
715         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
716         bInit = sal_True;
717     }
718     return aId;
719 }
720 
721