xref: /trunk/main/editeng/source/uno/unoedhlp.cxx (revision 0deba7fbda3d9908785c25a443701a293b6f4e71)
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_editeng.hxx"
26 #include <tools/debug.hxx>
27 
28 #include <editeng/unoedhlp.hxx>
29 #include <editeng/editdata.hxx>
30 #include <editeng/editeng.hxx>
31 //IAccessibility2 Implementation 2009-----
32 #include <svl/itemset.hxx>
33 
34 //-----IAccessibility2 Implementation 2009
35 //------------------------------------------------------------------------
36 
37 TYPEINIT1( SvxEditSourceHint, TextHint );
38 
39 SvxEditSourceHint::SvxEditSourceHint( sal_uLong _nId ) :
40     TextHint( _nId ),
41     mnStart( 0 ),
42     mnEnd( 0 )
43 {
44 }
45 
46 SvxEditSourceHint::SvxEditSourceHint( sal_uLong _nId, sal_uLong nValue, sal_uLong nStart, sal_uLong nEnd ) :
47     TextHint( _nId, nValue ),
48     mnStart( nStart),
49     mnEnd( nEnd )
50 {
51 }
52 
53 sal_uLong SvxEditSourceHint::GetValue() const
54 {
55     return TextHint::GetValue();
56 }
57 
58 sal_uLong SvxEditSourceHint::GetStartValue() const
59 {
60     return mnStart;
61 }
62 
63 sal_uLong SvxEditSourceHint::GetEndValue() const
64 {
65     return mnEnd;
66 }
67 
68 void SvxEditSourceHint::SetValue( sal_uLong n )
69 {
70     TextHint::SetValue( n );
71 }
72 
73 void SvxEditSourceHint::SetStartValue( sal_uLong n )
74 {
75     mnStart = n;
76 }
77 
78 void SvxEditSourceHint::SetEndValue( sal_uLong n )
79 {
80     mnEnd = n;
81 }
82 //IAccessibility2 Implementation 2009-----
83 TYPEINIT1( SvxEditSourceHintEndPara , SvxEditSourceHint );
84 //-----IAccessibility2 Implementation 2009
85 //------------------------------------------------------------------------
86 
87 ::std::auto_ptr<SfxHint> SvxEditSourceHelper::EENotification2Hint( EENotify* aNotify )
88 {
89     if( aNotify )
90     {
91         switch( aNotify->eNotificationType )
92         {
93             case EE_NOTIFY_TEXTMODIFIED:
94                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_MODIFIED, aNotify->nParagraph ) );
95 
96             case EE_NOTIFY_PARAGRAPHINSERTED:
97                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_PARAINSERTED, aNotify->nParagraph ) );
98 
99             case EE_NOTIFY_PARAGRAPHREMOVED:
100                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_PARAREMOVED, aNotify->nParagraph ) );
101 
102             case EE_NOTIFY_PARAGRAPHSMOVED:
103                 return ::std::auto_ptr<SfxHint>( new SvxEditSourceHint( EDITSOURCE_HINT_PARASMOVED, aNotify->nParagraph, aNotify->nParam1, aNotify->nParam2 ) );
104 
105             case EE_NOTIFY_TEXTHEIGHTCHANGED:
106                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_TEXTHEIGHTCHANGED, aNotify->nParagraph ) );
107 
108             case EE_NOTIFY_TEXTVIEWSCROLLED:
109                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_VIEWSCROLLED ) );
110 
111             case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED:
112                 return ::std::auto_ptr<SfxHint>( new SvxEditSourceHint( EDITSOURCE_HINT_SELECTIONCHANGED ) );
113 
114             case EE_NOTIFY_BLOCKNOTIFICATION_START:
115                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_START, 0 ) );
116 
117             case EE_NOTIFY_BLOCKNOTIFICATION_END:
118                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_END, 0 ) );
119 
120             case EE_NOTIFY_INPUT_START:
121                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_INPUT_START, 0 ) );
122 
123             case EE_NOTIFY_INPUT_END:
124                 return ::std::auto_ptr<SfxHint>( new TextHint( TEXT_HINT_INPUT_END, 0 ) );
125     //IAccessibility2 Implementation 2009-----
126             case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED_ENDD_PARA:
127                 return ::std::auto_ptr<SfxHint>( new SvxEditSourceHintEndPara( EDITSOURCE_HINT_SELECTIONCHANGED ) );
128     //-----IAccessibility2 Implementation 2009
129             default:
130                 DBG_ERROR( "SvxEditSourceHelper::EENotification2Hint unknown notification" );
131                 break;
132         }
133     }
134 
135     return ::std::auto_ptr<SfxHint>( new SfxHint() );
136 }
137 sal_Bool SvxEditSourceHelper::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, const EditEngine& rEE, sal_uInt16 nPara, sal_uInt16 nIndex, sal_Bool bInCell )
138 {
139     // IA2 CWS introduced bInCell, but also did many other changes here.
140     // Need to verify implementation with AT (IA2 and ATK)
141     // Old implementation at the end of the method for reference...
142 
143 #if 1 // IA2 CWS
144 
145     //added dummy attributes for the default text
146     EECharAttribArray aCharAttribs, aTempCharAttribs;
147     rEE.GetCharAttribs( nPara, aTempCharAttribs );
148     if ( aTempCharAttribs.Count() )
149     {
150         sal_uInt32 nIndex2 = 0;
151         sal_uInt32 nParaLen = rEE.GetTextLen(nPara);
152         for ( sal_uInt16 nAttr = 0; nAttr < aTempCharAttribs.Count(); nAttr++ )
153         {
154             if ( nIndex2 < aTempCharAttribs[nAttr].nStart )
155             {
156                 EECharAttrib aEEAttr;
157                 aEEAttr.nStart = sal_uInt16(nIndex2);
158                 aEEAttr.nEnd = aTempCharAttribs[nAttr].nStart;
159                 aCharAttribs.Insert( aEEAttr, nAttr );
160             }
161             nIndex2 = aTempCharAttribs[nAttr].nEnd;
162             aCharAttribs.Insert( aTempCharAttribs[nAttr], aCharAttribs.Count() );
163         }
164         if ( nIndex2 != nParaLen )
165         {
166             EECharAttrib aEEAttr;
167             aEEAttr.nStart = sal_uInt16(nIndex2);
168             aEEAttr.nEnd = sal_uInt16(nParaLen);
169             aCharAttribs.Insert( aEEAttr, aCharAttribs.Count() );
170         }
171     }
172     // find closest index in front of nIndex
173     sal_uInt16 nAttr, nCurrIndex;
174     sal_Int32 nClosestStartIndex;
175     sal_Int32 nClosestStartIndex_s, nClosestStartIndex_e;
176     for( nAttr=0, nClosestStartIndex_s=0, nClosestStartIndex_e=0; nAttr<aCharAttribs.Count(); ++nAttr )
177     {
178         nCurrIndex = aCharAttribs[nAttr].nStart;
179 
180         //if( nCurrIndex > nIndex )
181         //    break; // aCharAttribs array is sorted in increasing order for nStart values
182 
183         if( nCurrIndex > nClosestStartIndex_s &&
184             nCurrIndex <= nIndex)
185         {
186             nClosestStartIndex_s = nCurrIndex;
187         }
188         nCurrIndex = aCharAttribs[nAttr].nEnd;
189         if ( nCurrIndex > nClosestStartIndex_e &&
190             nCurrIndex < nIndex )
191         {
192             nClosestStartIndex_e = nCurrIndex;
193         }
194     }
195     nClosestStartIndex = nClosestStartIndex_s > nClosestStartIndex_e ? nClosestStartIndex_s : nClosestStartIndex_e;
196 
197     // find closest index behind of nIndex
198     sal_Int32 nClosestEndIndex;
199     sal_Int32 nClosestEndIndex_s, nClosestEndIndex_e;
200     for( nAttr=0, nClosestEndIndex_s=nClosestEndIndex_e=rEE.GetTextLen(nPara); nAttr<aCharAttribs.Count(); ++nAttr )
201     {
202         nCurrIndex = aCharAttribs[nAttr].nEnd;
203 
204         if( nCurrIndex > nIndex &&
205             nCurrIndex < nClosestEndIndex_e )
206         {
207             nClosestEndIndex_e = nCurrIndex;
208         }
209         nCurrIndex = aCharAttribs[nAttr].nStart;
210         if ( nCurrIndex > nIndex &&
211             nCurrIndex < nClosestEndIndex_s)
212         {
213             nClosestEndIndex_s = nCurrIndex;
214         }
215     }
216     nClosestEndIndex = nClosestEndIndex_s < nClosestEndIndex_e ? nClosestEndIndex_s : nClosestEndIndex_e;
217 
218     nStartIndex = static_cast<sal_uInt16>( nClosestStartIndex );
219     nEndIndex = static_cast<sal_uInt16>( nClosestEndIndex );
220     if ( bInCell )
221     {
222         EPosition aStartPos( nPara, nStartIndex ), aEndPos( nPara, nEndIndex );
223         sal_uInt32 nParaCount = rEE.GetParagraphCount();
224         sal_uInt32 nCrrntParaLen = rEE.GetTextLen(nPara);
225         //need to find closest index in front of nIndex in the previous paragraphs
226         if ( aStartPos.nIndex == 0 )
227         {
228             SfxItemSet aCrrntSet = rEE.GetAttribs( nPara, 0, 1, GETATTRIBS_CHARATTRIBS );
229             for ( sal_Int32 nParaIdx = nPara-1; nParaIdx >= 0; nParaIdx-- )
230             {
231                 sal_uInt32 nLen = rEE.GetTextLen( sal_uInt16(nParaIdx) );
232                 if ( nLen )
233                 {
234                     sal_uInt16 nStartIdx, nEndIdx;
235                     GetAttributeRun( nStartIdx, nEndIdx, rEE, sal_uInt16(nParaIdx), sal_uInt16(nLen), sal_False );
236                     SfxItemSet aSet = rEE.GetAttribs( sal_uInt16(nParaIdx), sal_uInt16(nLen-1), sal_uInt16(nLen), GETATTRIBS_CHARATTRIBS );
237                     if ( aSet == aCrrntSet )
238                     {
239                         aStartPos.nPara = sal_uInt16(nParaIdx);
240                         aStartPos.nIndex = nStartIdx;
241                         if ( aStartPos.nIndex != 0 )
242                         {
243                             break;
244                         }
245                     }
246                 }
247             }
248         }
249         //need find closest index behind nIndex in the following paragrphs
250         if ( aEndPos.nIndex == nCrrntParaLen )
251         {
252             SfxItemSet aCrrntSet = rEE.GetAttribs( nPara, sal_uInt16(nCrrntParaLen-1), sal_uInt16(nCrrntParaLen), GETATTRIBS_CHARATTRIBS );
253             for ( sal_uInt32 nParaIdx = nPara+1; nParaIdx < nParaCount; nParaIdx++ )
254             {
255                 sal_uInt32 nLen = rEE.GetTextLen( sal_uInt16(nParaIdx) );
256                 if ( nLen )
257                 {
258                     sal_uInt16 nStartIdx, nEndIdx;
259                     GetAttributeRun( nStartIdx, nEndIdx, rEE, sal_uInt16(nParaIdx), 0, sal_False );
260                     SfxItemSet aSet = rEE.GetAttribs( sal_uInt16(nParaIdx), 0, 1, GETATTRIBS_CHARATTRIBS );
261                     if ( aSet == aCrrntSet )
262                     {
263                         aEndPos.nPara = sal_uInt16(nParaIdx);
264                         aEndPos.nIndex = nEndIdx;
265                         if ( aEndPos.nIndex != nLen )
266                         {
267                             break;
268                         }
269                     }
270                 }
271             }
272         }
273         nStartIndex = 0;
274         if ( aStartPos.nPara > 0 )
275         {
276             for ( sal_uInt16 i = 0; i < aStartPos.nPara; i++ )
277             {
278                 nStartIndex += rEE.GetTextLen(i)+1;
279             }
280         }
281         nStartIndex += aStartPos.nIndex;
282         nEndIndex = 0;
283         if ( aEndPos.nPara > 0 )
284         {
285             for ( sal_uInt16 i = 0; i < aEndPos.nPara; i++ )
286             {
287                 nEndIndex += rEE.GetTextLen(i)+1;
288             }
289         }
290         nEndIndex += aEndPos.nIndex;
291     }
292 
293     return sal_True;
294 
295 #else // old implementation
296 
297     EECharAttribArray aCharAttribs;
298 
299     rEE.GetCharAttribs( nPara, aCharAttribs );
300 
301     // find closest index in front of nIndex
302     sal_uInt16 nAttr, nCurrIndex;
303     sal_Int32 nClosestStartIndex;
304     for( nAttr=0, nClosestStartIndex=0; nAttr<aCharAttribs.Count(); ++nAttr )
305     {
306         nCurrIndex = aCharAttribs[nAttr].nStart;
307 
308         if( nCurrIndex > nIndex )
309             break; // aCharAttribs array is sorted in increasing order for nStart values
310 
311         if( nCurrIndex > nClosestStartIndex )
312         {
313             nClosestStartIndex = nCurrIndex;
314         }
315     }
316 
317     // find closest index behind of nIndex
318     sal_Int32 nClosestEndIndex;
319     for( nAttr=0, nClosestEndIndex=rEE.GetTextLen(nPara); nAttr<aCharAttribs.Count(); ++nAttr )
320     {
321         nCurrIndex = aCharAttribs[nAttr].nEnd;
322 
323         if( nCurrIndex > nIndex &&
324             nCurrIndex < nClosestEndIndex )
325         {
326             nClosestEndIndex = nCurrIndex;
327         }
328     }
329 
330     nStartIndex = static_cast<sal_uInt16>( nClosestStartIndex );
331     nEndIndex = static_cast<sal_uInt16>( nClosestEndIndex );
332 
333     return sal_True;
334 
335 #endif
336 }
337 
338 Point SvxEditSourceHelper::EEToUserSpace( const Point& rPoint, const Size& rEESize, bool bIsVertical )
339 {
340     return bIsVertical ? Point( -rPoint.Y() + rEESize.Height(), rPoint.X() ) : rPoint;
341 }
342 
343 Point SvxEditSourceHelper::UserSpaceToEE( const Point& rPoint, const Size& rEESize, bool bIsVertical )
344 {
345     return bIsVertical ? Point( rPoint.Y(), -rPoint.X() + rEESize.Height() ) : rPoint;
346 }
347 
348 Rectangle SvxEditSourceHelper::EEToUserSpace( const Rectangle& rRect, const Size& rEESize, bool bIsVertical )
349 {
350     // #106775# Don't touch rect if not vertical
351     return bIsVertical ? Rectangle( EEToUserSpace(rRect.BottomLeft(), rEESize, bIsVertical),
352                                     EEToUserSpace(rRect.TopRight(), rEESize, bIsVertical) ) : rRect;
353 }
354 
355 Rectangle SvxEditSourceHelper::UserSpaceToEE( const Rectangle& rRect, const Size& rEESize, bool bIsVertical )
356 {
357     // #106775# Don't touch rect if not vertical
358     return bIsVertical ? Rectangle( UserSpaceToEE(rRect.TopRight(), rEESize, bIsVertical),
359                                     UserSpaceToEE(rRect.BottomLeft(), rEESize, bIsVertical) ) : rRect;
360 }
361