1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <editeng/unoedhlp.hxx>
21 #include <editeng/editdata.hxx>
22 #include <editeng/editeng.hxx>
23 #include <svl/itemset.hxx>
25 #include <osl/diagnose.h>
28 SvxEditSourceHint::SvxEditSourceHint( sal_uLong _nId
) :
35 SvxEditSourceHint::SvxEditSourceHint( sal_uLong _nId
, sal_uLong nValue
, sal_Int32 nStart
, sal_Int32 nEnd
) :
36 TextHint( _nId
, nValue
),
42 sal_uLong
SvxEditSourceHint::GetValue() const
44 return TextHint::GetValue();
48 ::std::unique_ptr
<SfxHint
> SvxEditSourceHelper::EENotification2Hint( EENotify
* aNotify
)
52 switch( aNotify
->eNotificationType
)
54 case EE_NOTIFY_TEXTMODIFIED
:
55 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_MODIFIED
, aNotify
->nParagraph
) );
57 case EE_NOTIFY_PARAGRAPHINSERTED
:
58 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_PARAINSERTED
, aNotify
->nParagraph
) );
60 case EE_NOTIFY_PARAGRAPHREMOVED
:
61 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_PARAREMOVED
, aNotify
->nParagraph
) );
63 case EE_NOTIFY_PARAGRAPHSMOVED
:
64 return ::std::unique_ptr
<SfxHint
>( new SvxEditSourceHint( EDITSOURCE_HINT_PARASMOVED
, aNotify
->nParagraph
, aNotify
->nParam1
, aNotify
->nParam2
) );
66 case EE_NOTIFY_TEXTHEIGHTCHANGED
:
67 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_TEXTHEIGHTCHANGED
, aNotify
->nParagraph
) );
69 case EE_NOTIFY_TEXTVIEWSCROLLED
:
70 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_VIEWSCROLLED
) );
72 case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED
:
73 return ::std::unique_ptr
<SfxHint
>( new SvxEditSourceHint( EDITSOURCE_HINT_SELECTIONCHANGED
) );
75 case EE_NOTIFY_BLOCKNOTIFICATION_START
:
76 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_START
, 0 ) );
78 case EE_NOTIFY_BLOCKNOTIFICATION_END
:
79 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_BLOCKNOTIFICATION_END
, 0 ) );
81 case EE_NOTIFY_INPUT_START
:
82 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_INPUT_START
, 0 ) );
84 case EE_NOTIFY_INPUT_END
:
85 return ::std::unique_ptr
<SfxHint
>( new TextHint( TEXT_HINT_INPUT_END
, 0 ) );
86 case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED_ENDD_PARA
:
87 return ::std::unique_ptr
<SfxHint
>( new SvxEditSourceHintEndPara( EDITSOURCE_HINT_SELECTIONCHANGED
) );
89 OSL_FAIL( "SvxEditSourceHelper::EENotification2Hint unknown notification" );
94 return ::std::unique_ptr
<SfxHint
>( new SfxHint() );
97 bool SvxEditSourceHelper::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, const EditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
)
99 // IA2 CWS introduced bInCell, but also did many other changes here.
100 // Need to verify implementation with AT (IA2 and ATK)
101 // Old implementation at the end of the method for reference...
103 //added dummy attributes for the default text
104 std::vector
<EECharAttrib
> aCharAttribs
, aTempCharAttribs
;
105 rEE
.GetCharAttribs( nPara
, aTempCharAttribs
);
107 if (!aTempCharAttribs
.empty())
109 sal_Int32 nIndex2
= 0;
110 sal_Int32 nParaLen
= rEE
.GetTextLen(nPara
);
111 for (size_t nAttr
= 0; nAttr
< aTempCharAttribs
.size(); ++nAttr
)
113 if (nIndex2
< aTempCharAttribs
[nAttr
].nStart
)
115 EECharAttrib aEEAttr
;
116 aEEAttr
.nStart
= nIndex2
;
117 aEEAttr
.nEnd
= aTempCharAttribs
[nAttr
].nStart
;
118 aCharAttribs
.insert(aCharAttribs
.begin() + nAttr
, aEEAttr
);
120 nIndex2
= aTempCharAttribs
[nAttr
].nEnd
;
121 aCharAttribs
.push_back(aTempCharAttribs
[nAttr
]);
123 if ( nIndex2
!= nParaLen
)
125 EECharAttrib aEEAttr
;
126 aEEAttr
.nStart
= nIndex2
;
127 aEEAttr
.nEnd
= nParaLen
;
128 aCharAttribs
.push_back(aEEAttr
);
131 // find closest index in front of nIndex
132 sal_Int32 nCurrIndex
;
133 sal_Int32 nClosestStartIndex_s
= 0, nClosestStartIndex_e
= 0;
134 for(std::vector
<EECharAttrib
>::iterator i
= aCharAttribs
.begin(); i
< aCharAttribs
.end(); ++i
)
136 nCurrIndex
= i
->nStart
;
138 if( nCurrIndex
> nClosestStartIndex_s
&&
139 nCurrIndex
<= nIndex
)
141 nClosestStartIndex_s
= nCurrIndex
;
143 nCurrIndex
= i
->nEnd
;
144 if ( nCurrIndex
> nClosestStartIndex_e
&&
145 nCurrIndex
< nIndex
)
147 nClosestStartIndex_e
= nCurrIndex
;
150 sal_Int32 nClosestStartIndex
= nClosestStartIndex_s
> nClosestStartIndex_e
? nClosestStartIndex_s
: nClosestStartIndex_e
;
152 // find closest index behind of nIndex
153 sal_Int32 nClosestEndIndex_s
, nClosestEndIndex_e
;
154 nClosestEndIndex_s
= nClosestEndIndex_e
= rEE
.GetTextLen(nPara
);
155 for(std::vector
<EECharAttrib
>::iterator i
= aCharAttribs
.begin(); i
< aCharAttribs
.end(); ++i
)
157 nCurrIndex
= i
->nEnd
;
159 if( nCurrIndex
> nIndex
&&
160 nCurrIndex
< nClosestEndIndex_e
)
162 nClosestEndIndex_e
= nCurrIndex
;
164 nCurrIndex
= i
->nStart
;
165 if ( nCurrIndex
> nIndex
&&
166 nCurrIndex
< nClosestEndIndex_s
)
168 nClosestEndIndex_s
= nCurrIndex
;
171 sal_Int32 nClosestEndIndex
= nClosestEndIndex_s
< nClosestEndIndex_e
? nClosestEndIndex_s
: nClosestEndIndex_e
;
173 nStartIndex
= nClosestStartIndex
;
174 nEndIndex
= nClosestEndIndex
;
178 EPosition
aStartPos( nPara
, nStartIndex
), aEndPos( nPara
, nEndIndex
);
179 sal_Int32 nParaCount
= rEE
.GetParagraphCount();
180 sal_Int32 nCrrntParaLen
= rEE
.GetTextLen(nPara
);
181 //need to find closest index in front of nIndex in the previous paragraphs
182 if ( aStartPos
.nIndex
== 0 )
184 SfxItemSet aCrrntSet
= rEE
.GetAttribs( nPara
, 0, 1, GetAttribsFlags::CHARATTRIBS
);
185 for ( sal_Int32 nParaIdx
= nPara
-1; nParaIdx
>= 0; nParaIdx
-- )
187 sal_uInt32 nLen
= rEE
.GetTextLen(nParaIdx
);
190 sal_Int32 nStartIdx
, nEndIdx
;
191 GetAttributeRun( nStartIdx
, nEndIdx
, rEE
, nParaIdx
, nLen
, false );
192 SfxItemSet aSet
= rEE
.GetAttribs( nParaIdx
, nLen
-1, nLen
, GetAttribsFlags::CHARATTRIBS
);
193 if ( aSet
== aCrrntSet
)
195 aStartPos
.nPara
= nParaIdx
;
196 aStartPos
.nIndex
= nStartIdx
;
197 if ( aStartPos
.nIndex
!= 0 )
205 //need find closest index behind nIndex in the following paragrphs
206 if ( aEndPos
.nIndex
== nCrrntParaLen
)
208 SfxItemSet aCrrntSet
= rEE
.GetAttribs( nPara
, nCrrntParaLen
-1, nCrrntParaLen
, GetAttribsFlags::CHARATTRIBS
);
209 for ( sal_Int32 nParaIdx
= nPara
+1; nParaIdx
< nParaCount
; nParaIdx
++ )
211 sal_Int32 nLen
= rEE
.GetTextLen( nParaIdx
);
214 sal_Int32 nStartIdx
, nEndIdx
;
215 GetAttributeRun( nStartIdx
, nEndIdx
, rEE
, nParaIdx
, 0, false );
216 SfxItemSet aSet
= rEE
.GetAttribs( nParaIdx
, 0, 1, GetAttribsFlags::CHARATTRIBS
);
217 if ( aSet
== aCrrntSet
)
219 aEndPos
.nPara
= nParaIdx
;
220 aEndPos
.nIndex
= nEndIdx
;
221 if ( aEndPos
.nIndex
!= nLen
)
230 if ( aStartPos
.nPara
> 0 )
232 for ( sal_Int32 i
= 0; i
< aStartPos
.nPara
; i
++ )
234 nStartIndex
+= rEE
.GetTextLen(i
)+1;
237 nStartIndex
+= aStartPos
.nIndex
;
239 if ( aEndPos
.nPara
> 0 )
241 for ( sal_Int32 i
= 0; i
< aEndPos
.nPara
; i
++ )
243 nEndIndex
+= rEE
.GetTextLen(i
)+1;
246 nEndIndex
+= aEndPos
.nIndex
;
252 Point
SvxEditSourceHelper::EEToUserSpace( const Point
& rPoint
, const Size
& rEESize
, bool bIsVertical
)
254 return bIsVertical
? Point( -rPoint
.Y() + rEESize
.Height(), rPoint
.X() ) : rPoint
;
257 Point
SvxEditSourceHelper::UserSpaceToEE( const Point
& rPoint
, const Size
& rEESize
, bool bIsVertical
)
259 return bIsVertical
? Point( rPoint
.Y(), -rPoint
.X() + rEESize
.Height() ) : rPoint
;
262 Rectangle
SvxEditSourceHelper::EEToUserSpace( const Rectangle
& rRect
, const Size
& rEESize
, bool bIsVertical
)
264 return bIsVertical
? Rectangle( EEToUserSpace(rRect
.BottomLeft(), rEESize
, bIsVertical
),
265 EEToUserSpace(rRect
.TopRight(), rEESize
, bIsVertical
) ) : rRect
;
268 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */