Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include <algorithm>
22 : #include <editeng/eeitem.hxx>
23 : #include <com/sun/star/i18n/WordType.hpp>
24 :
25 : #include <svl/itemset.hxx>
26 : #include <editeng/editeng.hxx>
27 : #include <editeng/editview.hxx>
28 : #include <editeng/unoedhlp.hxx>
29 : #include <editeng/editdata.hxx>
30 : #include <editeng/outliner.hxx>
31 : #include <editeng/editobj.hxx>
32 :
33 : #include <editeng/unofored.hxx>
34 : #include <unofored_internal.hxx>
35 :
36 : using namespace ::com::sun::star;
37 :
38 :
39 :
40 2233 : SvxEditEngineForwarder::SvxEditEngineForwarder( EditEngine& rEngine ) :
41 2233 : rEditEngine( rEngine )
42 : {
43 2233 : }
44 :
45 348 : SvxEditEngineForwarder::~SvxEditEngineForwarder()
46 : {
47 : // the EditEngine may need to be deleted from the outside
48 348 : }
49 :
50 80861 : sal_Int32 SvxEditEngineForwarder::GetParagraphCount() const
51 : {
52 80861 : return rEditEngine.GetParagraphCount();
53 : }
54 :
55 213358 : sal_Int32 SvxEditEngineForwarder::GetTextLen( sal_Int32 nParagraph ) const
56 : {
57 213358 : return rEditEngine.GetTextLen( nParagraph );
58 : }
59 :
60 322 : OUString SvxEditEngineForwarder::GetText( const ESelection& rSel ) const
61 : {
62 322 : return convertLineEnd(rEditEngine.GetText(rSel, LINEEND_LF), GetSystemLineEnd());
63 : }
64 :
65 12187 : SfxItemSet SvxEditEngineForwarder::GetAttribs( const ESelection& rSel, EditEngineAttribs nOnlyHardAttrib ) const
66 : {
67 12187 : if( rSel.nStartPara == rSel.nEndPara )
68 : {
69 12187 : GetAttribsFlags nFlags = GetAttribsFlags::NONE;
70 12187 : switch( nOnlyHardAttrib )
71 : {
72 : case EditEngineAttribs_All:
73 10786 : nFlags = GetAttribsFlags::ALL;
74 10786 : break;
75 : case EditEngineAttribs_HardAndPara:
76 0 : nFlags = GetAttribsFlags::PARAATTRIBS|GetAttribsFlags::CHARATTRIBS;
77 0 : break;
78 : case EditEngineAttribs_OnlyHard:
79 1401 : nFlags = GetAttribsFlags::CHARATTRIBS;
80 1401 : break;
81 : default:
82 : OSL_FAIL("unknown flags for SvxOutlinerForwarder::GetAttribs");
83 : }
84 :
85 12187 : return rEditEngine.GetAttribs( rSel.nStartPara, rSel.nStartPos, rSel.nEndPos, nFlags );
86 : }
87 : else
88 : {
89 0 : return rEditEngine.GetAttribs( rSel, nOnlyHardAttrib );
90 : }
91 : }
92 :
93 1063 : SfxItemSet SvxEditEngineForwarder::GetParaAttribs( sal_Int32 nPara ) const
94 : {
95 1063 : SfxItemSet aSet( rEditEngine.GetParaAttribs( nPara ) );
96 :
97 1063 : sal_uInt16 nWhich = EE_PARA_START;
98 21260 : while( nWhich <= EE_PARA_END )
99 : {
100 19134 : if( aSet.GetItemState( nWhich, true ) != SfxItemState::SET )
101 : {
102 14405 : if( rEditEngine.HasParaAttrib( nPara, nWhich ) )
103 0 : aSet.Put( rEditEngine.GetParaAttrib( nPara, nWhich ) );
104 : }
105 19134 : nWhich++;
106 : }
107 :
108 1063 : return aSet;
109 : }
110 :
111 1053 : void SvxEditEngineForwarder::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
112 : {
113 1053 : rEditEngine.SetParaAttribs( nPara, rSet );
114 1053 : }
115 :
116 0 : void SvxEditEngineForwarder::RemoveAttribs( const ESelection& rSelection, bool bRemoveParaAttribs, sal_uInt16 nWhich )
117 : {
118 0 : rEditEngine.RemoveAttribs( rSelection, bRemoveParaAttribs, nWhich );
119 0 : }
120 :
121 4 : SfxItemPool* SvxEditEngineForwarder::GetPool() const
122 : {
123 4 : return rEditEngine.GetEmptyItemSet().GetPool();
124 : }
125 :
126 877 : void SvxEditEngineForwarder::GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList ) const
127 : {
128 877 : rEditEngine.GetPortions( nPara, rList );
129 877 : }
130 :
131 2994 : void SvxEditEngineForwarder::QuickInsertText( const OUString& rText, const ESelection& rSel )
132 : {
133 2994 : rEditEngine.QuickInsertText( rText, rSel );
134 2994 : }
135 :
136 5 : void SvxEditEngineForwarder::QuickInsertLineBreak( const ESelection& rSel )
137 : {
138 5 : rEditEngine.QuickInsertLineBreak( rSel );
139 5 : }
140 :
141 1469 : void SvxEditEngineForwarder::QuickInsertField( const SvxFieldItem& rFld, const ESelection& rSel )
142 : {
143 1469 : rEditEngine.QuickInsertField( rFld, rSel );
144 1469 : }
145 :
146 708 : void SvxEditEngineForwarder::QuickSetAttribs( const SfxItemSet& rSet, const ESelection& rSel )
147 : {
148 708 : rEditEngine.QuickSetAttribs( rSet, rSel );
149 708 : }
150 :
151 513 : bool SvxEditEngineForwarder::IsValid() const
152 : {
153 : // cannot reliably query EditEngine state
154 : // while in the middle of an update
155 513 : return rEditEngine.GetUpdateMode();
156 : }
157 :
158 464 : OUString SvxEditEngineForwarder::CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, Color*& rpTxtColor, Color*& rpFldColor )
159 : {
160 464 : return rEditEngine.CalcFieldValue( rField, nPara, nPos, rpTxtColor, rpFldColor );
161 : }
162 :
163 0 : void SvxEditEngineForwarder::FieldClicked( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos )
164 : {
165 0 : rEditEngine.FieldClicked( rField, nPara, nPos );
166 0 : }
167 :
168 2053 : SfxItemState GetSvxEditEngineItemState( EditEngine& rEditEngine, const ESelection& rSel, sal_uInt16 nWhich )
169 : {
170 2053 : std::vector<EECharAttrib> aAttribs;
171 :
172 2053 : const SfxPoolItem* pLastItem = NULL;
173 :
174 2053 : SfxItemState eState = SfxItemState::DEFAULT;
175 :
176 : // check all paragraphs inside the selection
177 4106 : for( sal_Int32 nPara = rSel.nStartPara; nPara <= rSel.nEndPara; nPara++ )
178 : {
179 2053 : SfxItemState eParaState = SfxItemState::DEFAULT;
180 :
181 : // calculate start and endpos for this paragraph
182 2053 : sal_Int32 nPos = 0;
183 2053 : if( rSel.nStartPara == nPara )
184 2053 : nPos = rSel.nStartPos;
185 :
186 2053 : sal_Int32 nEndPos = rSel.nEndPos;
187 2053 : if( rSel.nEndPara != nPara )
188 0 : nEndPos = rEditEngine.GetTextLen( nPara );
189 :
190 :
191 : // get list of char attribs
192 2053 : rEditEngine.GetCharAttribs( nPara, aAttribs );
193 :
194 2053 : bool bEmpty = true; // we found no item inside the selection of this paragraph
195 2053 : bool bGaps = false; // we found items but theire gaps between them
196 2053 : sal_Int32 nLastEnd = nPos;
197 :
198 2053 : const SfxPoolItem* pParaItem = NULL;
199 :
200 16043 : for(std::vector<EECharAttrib>::const_iterator i = aAttribs.begin(); i < aAttribs.end(); ++i)
201 : {
202 : DBG_ASSERT(i->pAttr, "GetCharAttribs gives corrupt data");
203 :
204 14009 : const bool bEmptyPortion = i->nStart == i->nEnd;
205 14028 : if((!bEmptyPortion && i->nStart >= nEndPos) ||
206 18 : (bEmptyPortion && i->nStart > nEndPos))
207 19 : break; // break if we are already behind our selection
208 :
209 14162 : if((!bEmptyPortion && i->nEnd <= nPos) ||
210 18 : (bEmptyPortion && i->nEnd < nPos))
211 172 : continue; // or if the attribute ends before our selection
212 :
213 13818 : if(i->pAttr->Which() != nWhich)
214 13161 : continue; // skip if is not the searched item
215 :
216 : // if we already found an item
217 657 : if( pParaItem )
218 : {
219 : // ... and its different to this one than the state is dont care
220 0 : if(*pParaItem != *(i->pAttr))
221 0 : return SfxItemState::DONTCARE;
222 : }
223 : else
224 657 : pParaItem = i->pAttr;
225 :
226 657 : if( bEmpty )
227 657 : bEmpty = false;
228 :
229 657 : if(!bGaps && i->nStart > nLastEnd)
230 0 : bGaps = true;
231 :
232 657 : nLastEnd = i->nEnd;
233 : }
234 :
235 2053 : if( !bEmpty && !bGaps && nLastEnd < ( nEndPos - 1 ) )
236 0 : bGaps = true;
237 :
238 2053 : if( bEmpty )
239 1396 : eParaState = SfxItemState::DEFAULT;
240 657 : else if( bGaps )
241 0 : eParaState = SfxItemState::DONTCARE;
242 : else
243 657 : eParaState = SfxItemState::SET;
244 :
245 : // if we already found an item check if we found the same
246 2053 : if( pLastItem )
247 : {
248 0 : if( (pParaItem == NULL) || (*pLastItem != *pParaItem) )
249 0 : return SfxItemState::DONTCARE;
250 : }
251 : else
252 : {
253 2053 : pLastItem = pParaItem;
254 2053 : eState = eParaState;
255 : }
256 : }
257 :
258 2053 : return eState;
259 : }
260 :
261 2 : SfxItemState SvxEditEngineForwarder::GetItemState( const ESelection& rSel, sal_uInt16 nWhich ) const
262 : {
263 2 : return GetSvxEditEngineItemState( rEditEngine, rSel, nWhich );
264 : }
265 :
266 0 : SfxItemState SvxEditEngineForwarder::GetItemState( sal_Int32 nPara, sal_uInt16 nWhich ) const
267 : {
268 0 : const SfxItemSet& rSet = rEditEngine.GetParaAttribs( nPara );
269 0 : return rSet.GetItemState( nWhich );
270 : }
271 :
272 3 : LanguageType SvxEditEngineForwarder::GetLanguage( sal_Int32 nPara, sal_Int32 nIndex ) const
273 : {
274 3 : return rEditEngine.GetLanguage(nPara, nIndex);
275 : }
276 :
277 423 : sal_Int32 SvxEditEngineForwarder::GetFieldCount( sal_Int32 nPara ) const
278 : {
279 423 : return rEditEngine.GetFieldCount(nPara);
280 : }
281 :
282 30 : EFieldInfo SvxEditEngineForwarder::GetFieldInfo( sal_Int32 nPara, sal_uInt16 nField ) const
283 : {
284 30 : return rEditEngine.GetFieldInfo( nPara, nField );
285 : }
286 :
287 830 : EBulletInfo SvxEditEngineForwarder::GetBulletInfo( sal_Int32 ) const
288 : {
289 830 : return EBulletInfo();
290 : }
291 :
292 21 : Rectangle SvxEditEngineForwarder::GetCharBounds( sal_Int32 nPara, sal_Int32 nIndex ) const
293 : {
294 : // #101701#
295 : // EditEngine's 'internal' methods like GetCharacterBounds()
296 : // don't rotate for vertical text.
297 21 : Size aSize( rEditEngine.CalcTextWidth(), rEditEngine.GetTextHeight() );
298 21 : ::std::swap( aSize.Width(), aSize.Height() );
299 21 : bool bIsVertical( rEditEngine.IsVertical() );
300 :
301 : // #108900# Handle virtual position one-past-the end of the string
302 21 : if( nIndex >= rEditEngine.GetTextLen(nPara) )
303 : {
304 0 : Rectangle aLast;
305 :
306 0 : if( nIndex )
307 : {
308 : // use last character, if possible
309 0 : aLast = rEditEngine.GetCharacterBounds( EPosition(nPara, nIndex-1) );
310 :
311 : // move at end of this last character, make one pixel wide
312 0 : aLast.Move( aLast.Right() - aLast.Left(), 0 );
313 0 : aLast.SetSize( Size(1, aLast.GetHeight()) );
314 :
315 : // take care for CTL
316 0 : aLast = SvxEditSourceHelper::EEToUserSpace( aLast, aSize, bIsVertical );
317 : }
318 : else
319 : {
320 : // #109864# Bounds must lie within the paragraph
321 0 : aLast = GetParaBounds( nPara );
322 :
323 : // #109151# Don't use paragraph height, but line height
324 : // instead. aLast is already CTL-correct
325 0 : if( bIsVertical)
326 0 : aLast.SetSize( Size( rEditEngine.GetLineHeight(nPara,0), 1 ) );
327 : else
328 0 : aLast.SetSize( Size( 1, rEditEngine.GetLineHeight(nPara,0) ) );
329 : }
330 :
331 0 : return aLast;
332 : }
333 : else
334 : {
335 42 : return SvxEditSourceHelper::EEToUserSpace( rEditEngine.GetCharacterBounds( EPosition(nPara, nIndex) ),
336 42 : aSize, bIsVertical );
337 : }
338 : }
339 :
340 118 : Rectangle SvxEditEngineForwarder::GetParaBounds( sal_Int32 nPara ) const
341 : {
342 118 : const Point aPnt = rEditEngine.GetDocPosTopLeft( nPara );
343 : sal_uLong nWidth;
344 : sal_uLong nHeight;
345 : sal_uLong nTextWidth;
346 :
347 118 : if( rEditEngine.IsVertical() )
348 : {
349 : // #101701#
350 : // Hargl. EditEngine's 'external' methods return the rotated
351 : // dimensions, 'internal' methods like GetTextHeight( n )
352 : // don't rotate.
353 0 : nWidth = rEditEngine.GetTextHeight( nPara );
354 0 : nHeight = rEditEngine.GetTextHeight();
355 0 : nTextWidth = rEditEngine.GetTextHeight();
356 :
357 0 : return Rectangle( nTextWidth - aPnt.Y() - nWidth, 0, nTextWidth - aPnt.Y(), nHeight );
358 : }
359 : else
360 : {
361 118 : nWidth = rEditEngine.CalcTextWidth();
362 118 : nHeight = rEditEngine.GetTextHeight( nPara );
363 :
364 118 : return Rectangle( 0, aPnt.Y(), nWidth, aPnt.Y() + nHeight );
365 : }
366 : }
367 :
368 139 : MapMode SvxEditEngineForwarder::GetMapMode() const
369 : {
370 139 : return rEditEngine.GetRefMapMode();
371 : }
372 :
373 0 : OutputDevice* SvxEditEngineForwarder::GetRefDevice() const
374 : {
375 0 : return rEditEngine.GetRefDevice();
376 : }
377 :
378 11 : bool SvxEditEngineForwarder::GetIndexAtPoint( const Point& rPos, sal_Int32& nPara, sal_Int32& nIndex ) const
379 : {
380 11 : Size aSize( rEditEngine.CalcTextWidth(), rEditEngine.GetTextHeight() );
381 11 : ::std::swap( aSize.Width(), aSize.Height() );
382 : Point aEEPos( SvxEditSourceHelper::UserSpaceToEE( rPos,
383 : aSize,
384 11 : rEditEngine.IsVertical() ));
385 :
386 11 : EPosition aDocPos = rEditEngine.FindDocPosition( aEEPos );
387 :
388 11 : nPara = aDocPos.nPara;
389 11 : nIndex = aDocPos.nIndex;
390 :
391 11 : return true;
392 : }
393 :
394 0 : bool SvxEditEngineForwarder::GetWordIndices( sal_Int32 nPara, sal_Int32 nIndex, sal_Int32& nStart, sal_Int32& nEnd ) const
395 : {
396 0 : ESelection aRes = rEditEngine.GetWord( ESelection(nPara, nIndex, nPara, nIndex), com::sun::star::i18n::WordType::DICTIONARY_WORD );
397 :
398 0 : if( aRes.nStartPara == nPara &&
399 0 : aRes.nStartPara == aRes.nEndPara )
400 : {
401 0 : nStart = aRes.nStartPos;
402 0 : nEnd = aRes.nEndPos;
403 :
404 0 : return true;
405 : }
406 :
407 0 : return false;
408 : }
409 :
410 0 : bool SvxEditEngineForwarder::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nPara, sal_Int32 nIndex, bool bInCell ) const
411 : {
412 0 : return SvxEditSourceHelper::GetAttributeRun( nStartIndex, nEndIndex, rEditEngine, nPara, nIndex, bInCell );
413 : }
414 :
415 4 : sal_Int32 SvxEditEngineForwarder::GetLineCount( sal_Int32 nPara ) const
416 : {
417 4 : return rEditEngine.GetLineCount(nPara);
418 : }
419 :
420 4 : sal_Int32 SvxEditEngineForwarder::GetLineLen( sal_Int32 nPara, sal_Int32 nLine ) const
421 : {
422 4 : return rEditEngine.GetLineLen(nPara, nLine);
423 : }
424 :
425 0 : void SvxEditEngineForwarder::GetLineBoundaries( /*out*/sal_Int32 &rStart, /*out*/sal_Int32 &rEnd, sal_Int32 nPara, sal_Int32 nLine ) const
426 : {
427 0 : rEditEngine.GetLineBoundaries(rStart, rEnd, nPara, nLine);
428 0 : }
429 :
430 0 : sal_Int32 SvxEditEngineForwarder::GetLineNumberAtIndex( sal_Int32 nPara, sal_Int32 nIndex ) const
431 : {
432 0 : return rEditEngine.GetLineNumberAtIndex(nPara, nIndex);
433 : }
434 :
435 :
436 0 : bool SvxEditEngineForwarder::QuickFormatDoc( bool )
437 : {
438 0 : rEditEngine.QuickFormatDoc();
439 :
440 0 : return true;
441 : }
442 :
443 0 : bool SvxEditEngineForwarder::Delete( const ESelection& rSelection )
444 : {
445 0 : rEditEngine.QuickDelete( rSelection );
446 0 : rEditEngine.QuickFormatDoc();
447 :
448 0 : return true;
449 : }
450 :
451 0 : bool SvxEditEngineForwarder::InsertText( const OUString& rStr, const ESelection& rSelection )
452 : {
453 0 : rEditEngine.QuickInsertText( rStr, rSelection );
454 0 : rEditEngine.QuickFormatDoc();
455 :
456 0 : return true;
457 : }
458 :
459 0 : sal_Int16 SvxEditEngineForwarder::GetDepth( sal_Int32 ) const
460 : {
461 : // EditEngine does not support outline depth
462 0 : return -1;
463 : }
464 :
465 0 : bool SvxEditEngineForwarder::SetDepth( sal_Int32, sal_Int16 nNewDepth )
466 : {
467 : // EditEngine does not support outline depth
468 0 : return nNewDepth == -1;
469 : }
470 :
471 0 : const SfxItemSet * SvxEditEngineForwarder::GetEmptyItemSetPtr()
472 : {
473 0 : return &rEditEngine.GetEmptyItemSet();
474 : }
475 :
476 0 : void SvxEditEngineForwarder::AppendParagraph()
477 : {
478 0 : rEditEngine.InsertParagraph( rEditEngine.GetParagraphCount(), OUString() );
479 0 : }
480 :
481 0 : sal_Int32 SvxEditEngineForwarder::AppendTextPortion( sal_Int32 nPara, const OUString &rText, const SfxItemSet & /*rSet*/ )
482 : {
483 0 : sal_Int32 nLen = 0;
484 :
485 0 : sal_Int32 nParaCount = rEditEngine.GetParagraphCount();
486 : DBG_ASSERT( nPara < nParaCount, "paragraph index out of bounds" );
487 0 : if (0 <= nPara && nPara < nParaCount)
488 : {
489 0 : nLen = rEditEngine.GetTextLen( nPara );
490 0 : rEditEngine.QuickInsertText( rText, ESelection( nPara, nLen, nPara, nLen ) );
491 : }
492 :
493 0 : return nLen;
494 : }
495 :
496 0 : void SvxEditEngineForwarder::CopyText(const SvxTextForwarder& rSource)
497 : {
498 0 : const SvxEditEngineForwarder* pSourceForwarder = dynamic_cast< const SvxEditEngineForwarder* >( &rSource );
499 0 : if( !pSourceForwarder )
500 0 : return;
501 0 : EditTextObject* pNewTextObject = pSourceForwarder->rEditEngine.CreateTextObject();
502 0 : rEditEngine.SetText( *pNewTextObject );
503 0 : delete pNewTextObject;
504 : }
505 :
506 :
507 :
508 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|