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 #include "precompiled_sw.hxx"
25 
26 #include <parachangetrackinginfo.hxx>
27 
28 #include <errhdl.hxx>
29 #include <wrong.hxx>
30 #include <com/sun/star/text/TextMarkupType.hpp>
31 
32 #include <txtfrm.hxx>
33 #include <ndtxt.hxx>
34 #include <IDocumentRedlineAccess.hxx>
35 #include <docary.hxx>
36 #include <redline.hxx>
37 
38 namespace css = com::sun::star;
39 
40 namespace {
initChangeTrackTextMarkupLists(const SwTxtFrm & rTxtFrm,SwWrongList * & opChangeTrackInsertionTextMarkupList,SwWrongList * & opChangeTrackDeletionTextMarkupList,SwWrongList * & opChangeTrackFormatChangeTextMarkupList)41     void initChangeTrackTextMarkupLists( const SwTxtFrm& rTxtFrm,
42                                          SwWrongList*& opChangeTrackInsertionTextMarkupList,
43                                          SwWrongList*& opChangeTrackDeletionTextMarkupList,
44                                          SwWrongList*& opChangeTrackFormatChangeTextMarkupList )
45     {
46         opChangeTrackInsertionTextMarkupList = new SwWrongList( WRONGLIST_CHANGETRACKING );
47         opChangeTrackDeletionTextMarkupList = new SwWrongList( WRONGLIST_CHANGETRACKING );
48         opChangeTrackFormatChangeTextMarkupList = new SwWrongList( WRONGLIST_CHANGETRACKING );
49 
50         if ( !rTxtFrm.GetTxtNode() )
51         {
52             ASSERT( false,
53                     "<initChangeTrackTextMarkupLists(..) - missing <SwTxtNode> instance!" );
54             return;
55         }
56         const SwTxtNode& rTxtNode( *(rTxtFrm.GetTxtNode()) );
57 
58         const IDocumentRedlineAccess* pIDocChangeTrack( rTxtNode.getIDocumentRedlineAccess() );
59         if ( !pIDocChangeTrack )
60         {
61             ASSERT( false,
62                     "<initChangeTrackTextMarkupLists(..) - missing <IDocumentRedlineAccess> instance!" );
63             return;
64         }
65 
66         if ( !IDocumentRedlineAccess::IsShowChanges( pIDocChangeTrack->GetRedlineMode() ) ||
67              pIDocChangeTrack->GetRedlineTbl().Count() == 0 )
68         {
69             // nothing to do --> empty change track text markup lists.
70             return;
71         }
72 
73         const sal_uInt16 nIdxOfFirstRedlineForTxtNode =
74                     pIDocChangeTrack->GetRedlinePos( rTxtNode, USHRT_MAX );
75         if ( nIdxOfFirstRedlineForTxtNode == USHRT_MAX )
76         {
77             // nothing to do --> empty change track text markup lists.
78             return;
79         }
80 
81         const xub_StrLen nTxtFrmTextStartPos = rTxtFrm.IsFollow()
82                                                ? rTxtFrm.GetOfst()
83                                                : 0;
84         const xub_StrLen nTxtFrmTextEndPos = rTxtFrm.HasFollow()
85                                              ? rTxtFrm.GetFollow()->GetOfst()
86                                              : rTxtFrm.GetTxt().Len();
87 
88         // iteration over the redlines which overlap with the text node.
89         const SwRedlineTbl& rRedlineTbl = pIDocChangeTrack->GetRedlineTbl();
90         const sal_uInt16 nRedlineCount( rRedlineTbl.Count() );
91         for ( sal_uInt16 nActRedline = nIdxOfFirstRedlineForTxtNode;
92               nActRedline < nRedlineCount;
93               ++nActRedline)
94         {
95             const SwRedline* pActRedline = rRedlineTbl[ nActRedline ];
96             if ( pActRedline->Start()->nNode > rTxtNode.GetIndex() )
97             {
98                 break;
99             }
100 
101             xub_StrLen nTxtNodeChangeTrackStart( STRING_LEN );
102             xub_StrLen nTxtNodeChangeTrackEnd( STRING_LEN );
103             pActRedline->CalcStartEnd( rTxtNode.GetIndex(),
104                                        nTxtNodeChangeTrackStart,
105                                        nTxtNodeChangeTrackEnd );
106             if ( nTxtNodeChangeTrackStart > nTxtFrmTextEndPos ||
107                  nTxtNodeChangeTrackEnd < nTxtFrmTextStartPos )
108             {
109                 // Consider only redlines which overlap with the text frame's text.
110                 continue;
111             }
112 
113             SwWrongList* pMarkupList( 0 );
114             switch ( pActRedline->GetType() )
115             {
116                 case nsRedlineType_t::REDLINE_INSERT:
117                 {
118                     pMarkupList = opChangeTrackInsertionTextMarkupList;
119                 }
120                 break;
121                 case nsRedlineType_t::REDLINE_DELETE:
122                 {
123                     pMarkupList = opChangeTrackDeletionTextMarkupList;
124                 }
125                 break;
126                 case nsRedlineType_t::REDLINE_FORMAT:
127                 {
128                     pMarkupList = opChangeTrackFormatChangeTextMarkupList;
129                 }
130                 break;
131                 default:
132                 {
133                     // other types are not considered
134                 }
135             }
136             if ( pMarkupList )
137             {
138                 const xub_StrLen nTxtFrmChangeTrackStart =
139                                     nTxtNodeChangeTrackStart <= nTxtFrmTextStartPos
140                                     ? nTxtFrmTextStartPos
141                                     : nTxtNodeChangeTrackStart;
142 
143                 const xub_StrLen nTxtFrmChangeTrackEnd =
144                                     nTxtNodeChangeTrackEnd >= nTxtFrmTextEndPos
145                                     ? nTxtFrmTextEndPos
146                                     : nTxtNodeChangeTrackEnd;
147 
148                 pMarkupList->Insert( rtl::OUString(), 0,
149                                      nTxtFrmChangeTrackStart,
150                                      nTxtFrmChangeTrackEnd - nTxtFrmChangeTrackStart,
151                                      pMarkupList->Count() );
152             }
153         } // eof iteration over the redlines which overlap with the text node
154     }
155 } // eof anonymous namespace
156 
SwParaChangeTrackingInfo(const SwTxtFrm & rTxtFrm)157 SwParaChangeTrackingInfo::SwParaChangeTrackingInfo( const SwTxtFrm& rTxtFrm )
158     : mrTxtFrm( rTxtFrm )
159     , mpChangeTrackInsertionTextMarkupList( 0 )
160     , mpChangeTrackDeletionTextMarkupList( 0 )
161     , mpChangeTrackFormatChangeTextMarkupList( 0 )
162 {
163 }
164 
165 
~SwParaChangeTrackingInfo()166 SwParaChangeTrackingInfo::~SwParaChangeTrackingInfo()
167 {
168     reset();
169 }
170 
reset()171 void SwParaChangeTrackingInfo::reset()
172 {
173     delete mpChangeTrackInsertionTextMarkupList;
174     mpChangeTrackInsertionTextMarkupList = 0;
175 
176     delete mpChangeTrackDeletionTextMarkupList;
177     mpChangeTrackDeletionTextMarkupList = 0;
178 
179     delete mpChangeTrackFormatChangeTextMarkupList;
180     mpChangeTrackFormatChangeTextMarkupList = 0;
181 }
182 
getChangeTrackingTextMarkupList(const sal_Int32 nTextMarkupType)183 const SwWrongList* SwParaChangeTrackingInfo::getChangeTrackingTextMarkupList( const sal_Int32 nTextMarkupType )
184 {
185     SwWrongList* pChangeTrackingTextMarkupList = 0;
186 
187     if ( mpChangeTrackInsertionTextMarkupList == 0 )
188     {
189         ASSERT( mpChangeTrackDeletionTextMarkupList == 0,
190                 "<SwParaChangeTrackingInfo::getChangeTrackingTextMarkupList(..) - <mpChangeTrackDeletionTextMarkupList> expected to be NULL." );
191         ASSERT( mpChangeTrackFormatChangeTextMarkupList == 0,
192                 "<SwParaChangeTrackingInfo::getChangeTrackingTextMarkupList(..) - <mpChangeTrackFormatChangeTextMarkupList> expected to be NULL." );
193         initChangeTrackTextMarkupLists( mrTxtFrm,
194                                         mpChangeTrackInsertionTextMarkupList,
195                                         mpChangeTrackDeletionTextMarkupList,
196                                         mpChangeTrackFormatChangeTextMarkupList );
197     }
198 
199     switch ( nTextMarkupType )
200     {
201         case css::text::TextMarkupType::TRACK_CHANGE_INSERTION:
202         {
203             pChangeTrackingTextMarkupList = mpChangeTrackInsertionTextMarkupList;
204         }
205         break;
206         case css::text::TextMarkupType::TRACK_CHANGE_DELETION:
207         {
208             pChangeTrackingTextMarkupList = mpChangeTrackDeletionTextMarkupList;
209         }
210         break;
211         case css::text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
212         {
213             pChangeTrackingTextMarkupList = mpChangeTrackFormatChangeTextMarkupList;
214         }
215         break;
216         default:
217         {
218             ASSERT( false,
219                     "<SwParaChangeTrackingInfo::getChangeTrackingTextMarkupList(..)> - misusage - unexpected text markup type for change tracking." );
220         }
221     }
222 
223     return pChangeTrackingTextMarkupList;
224 }
225