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 .
21 #include <editeng/unoedhlp.hxx>
22 #include <editeng/editdata.hxx>
23 #include <editeng/editeng.hxx>
24 #include <svl/itemset.hxx>
26 #include <osl/diagnose.h>
29 SvxEditSourceHint::SvxEditSourceHint( SfxHintId _nId
) :
36 SvxEditSourceHint::SvxEditSourceHint( SfxHintId _nId
, sal_uLong nValue
, sal_Int32 nStart
, sal_Int32 nEnd
) :
37 TextHint( _nId
, nValue
),
44 std::unique_ptr
<SfxHint
> SvxEditSourceHelper::EENotification2Hint( EENotify
const * aNotify
)
48 switch( aNotify
->eNotificationType
)
50 case EE_NOTIFY_TEXTMODIFIED
:
51 return std::unique_ptr
<SfxHint
>( new TextHint( SfxHintId::TextModified
, aNotify
->nParagraph
) );
53 case EE_NOTIFY_PARAGRAPHINSERTED
:
54 return std::unique_ptr
<SfxHint
>( new TextHint( SfxHintId::TextParaInserted
, aNotify
->nParagraph
) );
56 case EE_NOTIFY_PARAGRAPHREMOVED
:
57 return std::unique_ptr
<SfxHint
>( new TextHint( SfxHintId::TextParaRemoved
, aNotify
->nParagraph
) );
59 case EE_NOTIFY_PARAGRAPHSMOVED
:
60 return std::unique_ptr
<SfxHint
>( new SvxEditSourceHint( SfxHintId::EditSourceParasMoved
, aNotify
->nParagraph
, aNotify
->nParam1
, aNotify
->nParam2
) );
62 case EE_NOTIFY_TextHeightChanged
:
63 return std::unique_ptr
<SfxHint
>( new TextHint( SfxHintId::TextHeightChanged
, aNotify
->nParagraph
) );
65 case EE_NOTIFY_TEXTVIEWSCROLLED
:
66 return std::unique_ptr
<SfxHint
>( new TextHint( SfxHintId::TextViewScrolled
) );
68 case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED
:
69 return std::unique_ptr
<SfxHint
>( new SvxEditSourceHint( SfxHintId::EditSourceSelectionChanged
) );
71 case EE_NOTIFY_PROCESSNOTIFICATIONS
:
72 return std::unique_ptr
<SfxHint
>( new TextHint( SfxHintId::TextProcessNotifications
));
74 case EE_NOTIFY_TEXTVIEWSELECTIONCHANGED_ENDD_PARA
:
75 return std::unique_ptr
<SfxHint
>( new SvxEditSourceHintEndPara
);
77 OSL_FAIL( "SvxEditSourceHelper::EENotification2Hint unknown notification" );
82 return std::make_unique
<SfxHint
>( );
85 void SvxEditSourceHelper::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, const EditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nIndex
, bool bInCell
)
87 // IA2 CWS introduced bInCell, but also did many other changes here.
88 // Need to verify implementation with AT (IA2 and ATK)
89 // Old implementation at the end of the method for reference...
91 //added dummy attributes for the default text
92 std::vector
<EECharAttrib
> aCharAttribs
, aTempCharAttribs
;
93 rEE
.GetCharAttribs( nPara
, aTempCharAttribs
);
95 if (!aTempCharAttribs
.empty())
97 sal_Int32 nIndex2
= 0;
98 sal_Int32 nParaLen
= rEE
.GetTextLen(nPara
);
99 for (size_t nAttr
= 0; nAttr
< aTempCharAttribs
.size(); ++nAttr
)
101 if (nIndex2
< aTempCharAttribs
[nAttr
].nStart
)
103 EECharAttrib aEEAttr
;
104 aEEAttr
.nStart
= nIndex2
;
105 aEEAttr
.nEnd
= aTempCharAttribs
[nAttr
].nStart
;
106 aCharAttribs
.insert(aCharAttribs
.begin() + nAttr
, aEEAttr
);
108 nIndex2
= aTempCharAttribs
[nAttr
].nEnd
;
109 aCharAttribs
.push_back(aTempCharAttribs
[nAttr
]);
111 if ( nIndex2
!= nParaLen
)
113 EECharAttrib aEEAttr
;
114 aEEAttr
.nStart
= nIndex2
;
115 aEEAttr
.nEnd
= nParaLen
;
116 aCharAttribs
.push_back(aEEAttr
);
119 // find closest index in front of nIndex
120 sal_Int32 nCurrIndex
;
121 sal_Int32 nClosestStartIndex_s
= 0, nClosestStartIndex_e
= 0;
122 for (auto const& charAttrib
: aCharAttribs
)
124 nCurrIndex
= charAttrib
.nStart
;
126 if( nCurrIndex
> nClosestStartIndex_s
&&
127 nCurrIndex
<= nIndex
)
129 nClosestStartIndex_s
= nCurrIndex
;
131 nCurrIndex
= charAttrib
.nEnd
;
132 if ( nCurrIndex
> nClosestStartIndex_e
&&
133 nCurrIndex
< nIndex
)
135 nClosestStartIndex_e
= nCurrIndex
;
138 sal_Int32 nClosestStartIndex
= std::max(nClosestStartIndex_s
, nClosestStartIndex_e
);
140 // find closest index behind of nIndex
141 sal_Int32 nClosestEndIndex_s
, nClosestEndIndex_e
;
142 nClosestEndIndex_s
= nClosestEndIndex_e
= rEE
.GetTextLen(nPara
);
143 for (auto const& charAttrib
: aCharAttribs
)
145 nCurrIndex
= charAttrib
.nEnd
;
147 if( nCurrIndex
> nIndex
&&
148 nCurrIndex
< nClosestEndIndex_e
)
150 nClosestEndIndex_e
= nCurrIndex
;
152 nCurrIndex
= charAttrib
.nStart
;
153 if ( nCurrIndex
> nIndex
&&
154 nCurrIndex
< nClosestEndIndex_s
)
156 nClosestEndIndex_s
= nCurrIndex
;
159 sal_Int32 nClosestEndIndex
= std::min(nClosestEndIndex_s
, nClosestEndIndex_e
);
161 nStartIndex
= nClosestStartIndex
;
162 nEndIndex
= nClosestEndIndex
;
166 EPosition
aStartPos( nPara
, nStartIndex
), aEndPos( nPara
, nEndIndex
);
167 sal_Int32 nParaCount
= rEE
.GetParagraphCount();
168 sal_Int32 nCrrntParaLen
= rEE
.GetTextLen(nPara
);
169 //need to find closest index in front of nIndex in the previous paragraphs
170 if ( aStartPos
.nIndex
== 0 )
172 SfxItemSet aCrrntSet
= rEE
.GetAttribs( nPara
, 0, 1, GetAttribsFlags::CHARATTRIBS
);
173 for ( sal_Int32 nParaIdx
= nPara
-1; nParaIdx
>= 0; nParaIdx
-- )
175 sal_uInt32 nLen
= rEE
.GetTextLen(nParaIdx
);
178 sal_Int32 nStartIdx
, nEndIdx
;
179 GetAttributeRun( nStartIdx
, nEndIdx
, rEE
, nParaIdx
, nLen
);
180 SfxItemSet aSet
= rEE
.GetAttribs( nParaIdx
, nLen
-1, nLen
, GetAttribsFlags::CHARATTRIBS
);
181 if ( aSet
== aCrrntSet
)
183 aStartPos
.nPara
= nParaIdx
;
184 aStartPos
.nIndex
= nStartIdx
;
185 if ( aStartPos
.nIndex
!= 0 )
193 //need find closest index behind nIndex in the following paragraphs
194 if ( aEndPos
.nIndex
== nCrrntParaLen
)
196 SfxItemSet aCrrntSet
= rEE
.GetAttribs( nPara
, nCrrntParaLen
-1, nCrrntParaLen
, GetAttribsFlags::CHARATTRIBS
);
197 for ( sal_Int32 nParaIdx
= nPara
+1; nParaIdx
< nParaCount
; nParaIdx
++ )
199 sal_Int32 nLen
= rEE
.GetTextLen( nParaIdx
);
202 sal_Int32 nStartIdx
, nEndIdx
;
203 GetAttributeRun( nStartIdx
, nEndIdx
, rEE
, nParaIdx
, 0 );
204 SfxItemSet aSet
= rEE
.GetAttribs( nParaIdx
, 0, 1, GetAttribsFlags::CHARATTRIBS
);
205 if ( aSet
== aCrrntSet
)
207 aEndPos
.nPara
= nParaIdx
;
208 aEndPos
.nIndex
= nEndIdx
;
209 if ( aEndPos
.nIndex
!= nLen
)
218 if ( aStartPos
.nPara
> 0 )
220 for ( sal_Int32 i
= 0; i
< aStartPos
.nPara
; i
++ )
222 nStartIndex
+= rEE
.GetTextLen(i
)+1;
225 nStartIndex
+= aStartPos
.nIndex
;
227 if ( aEndPos
.nPara
> 0 )
229 for ( sal_Int32 i
= 0; i
< aEndPos
.nPara
; i
++ )
231 nEndIndex
+= rEE
.GetTextLen(i
)+1;
234 nEndIndex
+= aEndPos
.nIndex
;
238 Point
SvxEditSourceHelper::EEToUserSpace( const Point
& rPoint
, const Size
& rEESize
, bool bIsVertical
)
240 return bIsVertical
? Point( -rPoint
.Y() + rEESize
.Height(), rPoint
.X() ) : rPoint
;
243 Point
SvxEditSourceHelper::UserSpaceToEE( const Point
& rPoint
, const Size
& rEESize
, bool bIsVertical
)
245 return bIsVertical
? Point( rPoint
.Y(), -rPoint
.X() + rEESize
.Height() ) : rPoint
;
248 tools::Rectangle
SvxEditSourceHelper::EEToUserSpace( const tools::Rectangle
& rRect
, const Size
& rEESize
, bool bIsVertical
)
250 return bIsVertical
? tools::Rectangle( EEToUserSpace(rRect
.BottomLeft(), rEESize
, bIsVertical
),
251 EEToUserSpace(rRect
.TopRight(), rEESize
, bIsVertical
) ) : rRect
;
254 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */