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