LibreOffice Module editeng (master) 1
impedit4.cxx
Go to the documentation of this file.
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 <svl/srchitem.hxx>
22#include <editeng/lspcitem.hxx>
24#include <editeng/tstpitem.hxx>
25
26#include "eertfpar.hxx"
27#include <editeng/editeng.hxx>
28#include "impedit.hxx"
29#include <editeng/editview.hxx>
30#include "eehtml.hxx"
31#include "editobj2.hxx"
32#include <i18nlangtag/lang.h>
33#include <sal/log.hxx>
34#include <o3tl/safeint.hxx>
35#include <osl/diagnose.h>
36#include <osl/thread.h>
37
38#include <editxml.hxx>
39
42#include <editeng/colritem.hxx>
45#include <editeng/fhgtitem.hxx>
46#include <editeng/fontitem.hxx>
47#include <editeng/kernitem.hxx>
48#include <editeng/lrspitem.hxx>
49#include <editeng/postitem.hxx>
50#include <editeng/shdditem.hxx>
51#include <editeng/udlnitem.hxx>
52#include <editeng/ulspitem.hxx>
53#include <editeng/wghtitem.hxx>
54#include <editeng/langitem.hxx>
58#include "textconv.hxx"
59#include <rtl/tencinfo.h>
60#include <svtools/rtfout.hxx>
61#include <tools/stream.hxx>
62#include <edtspell.hxx>
63#include <editeng/unolingu.hxx>
64#include <com/sun/star/linguistic2/XThesaurus.hpp>
65#include <com/sun/star/i18n/ScriptType.hpp>
66#include <com/sun/star/i18n/WordType.hpp>
70#include <vcl/help.hxx>
71#include <vcl/metric.hxx>
72#include <svtools/rtfkeywd.hxx>
73#include <editeng/edtdlg.hxx>
74
75#include <cstddef>
76#include <memory>
77#include <unordered_map>
78#include <vector>
79
80using namespace ::com::sun::star;
81using namespace ::com::sun::star::uno;
82using namespace ::com::sun::star::beans;
83using namespace ::com::sun::star::linguistic2;
84
85
86EditPaM ImpEditEngine::Read(SvStream& rInput, const OUString& rBaseURL, EETextFormat eFormat, const EditSelection& rSel, SvKeyValueIterator* pHTTPHeaderAttrs)
87{
88 bool _bUpdate = SetUpdateLayout( false );
89 EditPaM aPaM;
90 if ( eFormat == EETextFormat::Text )
91 aPaM = ReadText( rInput, rSel );
92 else if ( eFormat == EETextFormat::Rtf )
93 aPaM = ReadRTF( rInput, rSel );
94 else if ( eFormat == EETextFormat::Xml )
95 aPaM = ReadXML( rInput, rSel );
96 else if ( eFormat == EETextFormat::Html )
97 aPaM = ReadHTML( rInput, rBaseURL, rSel, pHTTPHeaderAttrs );
98 else
99 {
100 OSL_FAIL( "Read: Unknown Format" );
101 }
102
103 FormatFullDoc(); // perhaps a simple format is enough?
104 SetUpdateLayout( _bUpdate );
105
106 return aPaM;
107}
108
110{
111 if ( aSel.HasRange() )
112 aSel = ImpDeleteSelection( aSel );
113 EditPaM aPaM = aSel.Max();
114
115 OUString aTmpStr;
116 bool bDone = rInput.ReadByteStringLine( aTmpStr, rInput.GetStreamCharSet() );
117 while ( bDone )
118 {
119 aPaM = ImpInsertText( EditSelection( aPaM, aPaM ), aTmpStr );
120 aPaM = ImpInsertParaBreak( aPaM );
121 bDone = rInput.ReadByteStringLine( aTmpStr, rInput.GetStreamCharSet() );
122 }
123 return aPaM;
124}
125
127{
128 if ( aSel.HasRange() )
129 aSel = ImpDeleteSelection( aSel );
130
131 ESelection aESel = CreateESel( aSel );
132
133 return ::SvxReadXML( *GetEditEnginePtr(), rInput, aESel );
134}
135
137{
138 if ( aSel.HasRange() )
139 aSel = ImpDeleteSelection( aSel );
140
141 // The SvRTF parser expects the Which-mapping passed on in the pool, not
142 // dependent on a secondary.
143 SfxItemPool* pPool = &aEditDoc.GetItemPool();
144 while (pPool->GetSecondaryPool() && pPool->GetName() != "EditEngineItemPool")
145 {
146 pPool = pPool->GetSecondaryPool();
147 }
148
149 DBG_ASSERT(pPool && pPool->GetName() == "EditEngineItemPool",
150 "ReadRTF: no EditEnginePool!");
151
152 EditRTFParserRef xPrsr = new EditRTFParser(rInput, aSel, *pPool, pEditEngine);
153 SvParserState eState = xPrsr->CallParser();
154 if ( ( eState != SvParserState::Accepted ) && ( !rInput.GetError() ) )
155 {
157 return aSel.Min();
158 }
159 return xPrsr->GetCurPaM();
160}
161
162EditPaM ImpEditEngine::ReadHTML( SvStream& rInput, const OUString& rBaseURL, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs )
163{
164 if ( aSel.HasRange() )
165 aSel = ImpDeleteSelection( aSel );
166
167 EditHTMLParserRef xPrsr = new EditHTMLParser( rInput, rBaseURL, pHTTPHeaderAttrs );
168 SvParserState eState = xPrsr->CallParser(pEditEngine, aSel.Max());
169 if ( ( eState != SvParserState::Accepted ) && ( !rInput.GetError() ) )
170 {
172 return aSel.Min();
173 }
174 return xPrsr->GetCurSelection().Max();
175}
176
177void ImpEditEngine::Write(SvStream& rOutput, EETextFormat eFormat, const EditSelection& rSel)
178{
179 if ( !rOutput.IsWritable() )
181
182 if ( rOutput.GetError() )
183 return;
184
185 if ( eFormat == EETextFormat::Text )
186 WriteText( rOutput, rSel );
187 else if ( eFormat == EETextFormat::Rtf )
188 WriteRTF( rOutput, rSel );
189 else if ( eFormat == EETextFormat::Xml )
190 WriteXML( rOutput, rSel );
191 else if ( eFormat == EETextFormat::Html )
192 ;
193 else
194 {
195 OSL_FAIL( "Write: Unknown Format" );
196 }
197}
198
200{
201 sal_Int32 nStartNode, nEndNode;
202 bool bRange = aSel.HasRange();
203 if ( bRange )
204 {
205 aSel.Adjust( aEditDoc );
206 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
207 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
208 }
209 else
210 {
211 nStartNode = 0;
212 nEndNode = aEditDoc.Count()-1;
213 }
214
215 // iterate over the paragraphs ...
216 for ( sal_Int32 nNode = nStartNode; nNode <= nEndNode; nNode++ )
217 {
218 ContentNode* pNode = aEditDoc.GetObject( nNode );
219 DBG_ASSERT( pNode, "Node not found: Search&Replace" );
220
221 sal_Int32 nStartPos = 0;
222 sal_Int32 nEndPos = pNode->Len();
223 if ( bRange )
224 {
225 if ( nNode == nStartNode )
226 nStartPos = aSel.Min().GetIndex();
227 if ( nNode == nEndNode ) // can also be == nStart!
228 nEndPos = aSel.Max().GetIndex();
229 }
230 OUString aTmpStr = EditDoc::GetParaAsString( pNode, nStartPos, nEndPos );
231 rOutput.WriteByteStringLine( aTmpStr, rOutput.GetStreamCharSet() );
232 }
233
234 return rOutput.GetError();
235}
236
237bool ImpEditEngine::WriteItemListAsRTF( ItemList& rLst, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos,
238 std::vector<std::unique_ptr<SvxFontItem>>& rFontTable, SvxColorList& rColorList )
239{
240 const SfxPoolItem* pAttrItem = rLst.First();
241 while ( pAttrItem )
242 {
243 WriteItemAsRTF( *pAttrItem, rOutput, nPara, nPos,rFontTable, rColorList );
244 pAttrItem = rLst.Next();
245 }
246 return rLst.Count() != 0;
247}
248
249static void lcl_FindValidAttribs( ItemList& rLst, ContentNode* pNode, sal_Int32 nIndex, sal_uInt16 nScriptType )
250{
251 std::size_t nAttr = 0;
252 EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
253 while ( pAttr && ( pAttr->GetStart() <= nIndex ) )
254 {
255 // Start is checked in while ...
256 if ( pAttr->GetEnd() > nIndex )
257 {
258 if ( IsScriptItemValid( pAttr->GetItem()->Which(), nScriptType ) )
259 rLst.Insert( pAttr->GetItem() );
260 }
261 nAttr++;
262 pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
263 }
264}
265
267{
268 ESelection aESel = CreateESel(rSel);
269
270 SvxWriteXML( *GetEditEnginePtr(), rOutput, aESel );
271}
272
274{
275 assert( IsUpdateLayout() && "WriteRTF for UpdateMode = sal_False!" );
277 if ( !IsFormatted() )
278 FormatDoc();
279
280 sal_Int32 nStartNode, nEndNode;
281 aSel.Adjust( aEditDoc );
282
283 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
284 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
285
286 // RTF header ...
287 rOutput.WriteChar( '{' ) ;
288
290
292 rtl_TextEncoding eDestEnc = RTL_TEXTENCODING_MS_1252;
293
294 // Generate and write out Font table ...
295 std::vector<std::unique_ptr<SvxFontItem>> aFontTable;
296 // default font must be up front, so DEF font in RTF
297 aFontTable.emplace_back( new SvxFontItem( aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO ) ) );
298 aFontTable.emplace_back( new SvxFontItem( aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO_CJK ) ) );
299 aFontTable.emplace_back( new SvxFontItem( aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO_CTL ) ) );
300 for ( sal_uInt16 nScriptType = 0; nScriptType < 3; nScriptType++ )
301 {
302 sal_uInt16 nWhich = EE_CHAR_FONTINFO;
303 if ( nScriptType == 1 )
304 nWhich = EE_CHAR_FONTINFO_CJK;
305 else if ( nScriptType == 2 )
306 nWhich = EE_CHAR_FONTINFO_CTL;
307
308 for (const SfxPoolItem* pItem : aEditDoc.GetItemPool().GetItemSurrogates(nWhich))
309 {
310 SvxFontItem const*const pFontItem = static_cast<const SvxFontItem*>(pItem);
311 bool bAlreadyExist = false;
312 size_t nTestMax = nScriptType ? aFontTable.size() : 1;
313 for ( size_t nTest = 0; !bAlreadyExist && ( nTest < nTestMax ); nTest++ )
314 {
315 bAlreadyExist = *aFontTable[ nTest ] == *pFontItem;
316 }
317
318 if ( !bAlreadyExist )
319 aFontTable.emplace_back( new SvxFontItem( *pFontItem ) );
320 }
321 }
322
323 rOutput << endl;
325 for ( std::vector<SvxFontItem*>::size_type j = 0; j < aFontTable.size(); j++ )
326 {
327 SvxFontItem* pFontItem = aFontTable[ j ].get();
328 rOutput.WriteChar( '{' );
330 rOutput.WriteNumberAsString( j );
331 switch ( pFontItem->GetFamily() )
332 {
334 break;
336 break;
338 break;
340 break;
342 break;
344 break;
345 default:
346 break;
347 }
349 sal_uInt16 nVal = 0;
350 switch( pFontItem->GetPitch() )
351 {
352 case PITCH_FIXED: nVal = 1; break;
353 case PITCH_VARIABLE: nVal = 2; break;
354 default:
355 break;
356 }
357 rOutput.WriteNumberAsString( nVal );
358
359 rtl_TextEncoding eChrSet = pFontItem->GetCharSet();
360 // tdf#47679 OpenSymbol is not encoded in Symbol Encoding
361 // and anyway we always attempt to write as eDestEnc
362 // of RTL_TEXTENCODING_MS_1252 and pay no attention
363 // on export what encoding we claim to use for these
364 // fonts.
365 if (IsOpenSymbol(pFontItem->GetFamilyName()))
366 {
367 SAL_WARN_IF(eChrSet == RTL_TEXTENCODING_SYMBOL, "editeng", "OpenSymbol should not have charset of RTL_TEXTENCODING_SYMBOL in new documents");
368 eChrSet = RTL_TEXTENCODING_UTF8;
369 }
370 DBG_ASSERT( eChrSet != 9, "SystemCharSet?!" );
371 if( RTL_TEXTENCODING_DONTKNOW == eChrSet )
372 eChrSet = osl_getThreadTextEncoding();
374 rOutput.WriteNumberAsString( rtl_getBestWindowsCharsetFromTextEncoding( eChrSet ) );
375
376 rOutput.WriteChar( ' ' );
377 RTFOutFuncs::Out_String( rOutput, pFontItem->GetFamilyName(), eDestEnc );
378 rOutput.WriteOString( ";}" );
379 }
380 rOutput.WriteChar( '}' );
381 rOutput << endl;
382
383 // Write out ColorList ...
384 SvxColorList aColorList;
385 // COL_AUTO should be the default color, always put it first
386 aColorList.emplace_back(COL_AUTO);
388 if (rDefault.GetValue() != COL_AUTO) // is the default always AUTO?
389 {
390 aColorList.push_back(rDefault.GetValue());
391 }
393 {
394 auto pColorItem(dynamic_cast<SvxColorItem const*>(pItem));
395 if (pColorItem && pColorItem->GetValue() != COL_AUTO) // may be null!
396 {
397 aColorList.push_back(pColorItem->GetValue());
398 }
399 }
400
402 for ( SvxColorList::size_type j = 0; j < aColorList.size(); j++ )
403 {
404 Color const color = aColorList[j];
405 if (color != COL_AUTO) // auto is represented by "empty" element
406 {
408 rOutput.WriteNumberAsString( color.GetRed() );
410 rOutput.WriteNumberAsString( color.GetGreen() );
412 rOutput.WriteNumberAsString( color.GetBlue() );
413 }
414 rOutput.WriteChar( ';' );
415 }
416 rOutput.WriteChar( '}' );
417 rOutput << endl;
418
419 std::unordered_map<SfxStyleSheetBase*, sal_uInt32> aStyleSheetToIdMap;
420 // StyleSheets...
421 if ( GetStyleSheetPool() )
422 {
423 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(GetStyleSheetPool(),
424 SfxStyleFamily::All);
425 // fill aStyleSheetToIdMap
426 sal_uInt32 nId = 1;
427 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
428 pStyle = aSSSIterator->Next() )
429 {
430 aStyleSheetToIdMap[pStyle] = nId;
431 nId++;
432 }
433
434 if ( aSSSIterator->Count() )
435 {
436
437 sal_uInt32 nStyle = 0;
439
440 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
441 pStyle = aSSSIterator->Next() )
442 {
443
444 rOutput << endl;
446 sal_uInt32 nNumber = nStyle + 1;
447 rOutput.WriteNumberAsString( nNumber );
448
449 // Attribute, also from Parent!
450 for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
451 {
452 if ( pStyle->GetItemSet().GetItemState( nParAttr ) == SfxItemState::SET )
453 {
454 const SfxPoolItem& rItem = pStyle->GetItemSet().Get( nParAttr );
455 WriteItemAsRTF( rItem, rOutput, 0, 0, aFontTable, aColorList );
456 }
457 }
458
459 // Parent ... (only if necessary)
460 if ( !pStyle->GetParent().isEmpty() && ( pStyle->GetParent() != pStyle->GetName() ) )
461 {
462 SfxStyleSheet* pParent = static_cast<SfxStyleSheet*>(GetStyleSheetPool()->Find( pStyle->GetParent(), pStyle->GetFamily() ));
463 DBG_ASSERT( pParent, "Parent not found!" );
465 nNumber = aStyleSheetToIdMap.find(pParent)->second;
466 rOutput.WriteNumberAsString( nNumber );
467 }
468
469 // Next Style... (more)
470 // we assume that we have only SfxStyleSheet in the pool
471 SfxStyleSheet* pNext = static_cast<SfxStyleSheet*>(pStyle);
472 if ( !pStyle->GetFollow().isEmpty() && ( pStyle->GetFollow() != pStyle->GetName() ) )
473 pNext = static_cast<SfxStyleSheet*>(GetStyleSheetPool()->Find( pStyle->GetFollow(), pStyle->GetFamily() ));
474
475 DBG_ASSERT( pNext, "Next not found!" );
477 nNumber = aStyleSheetToIdMap.find(pNext)->second;
478 rOutput.WriteNumberAsString( nNumber );
479
480 // Name of the template...
481 rOutput.WriteOString( " " );
482 RTFOutFuncs::Out_String( rOutput, pStyle->GetName(), eDestEnc );
483 rOutput.WriteOString( ";}" );
484 nStyle++;
485 }
486 rOutput.WriteChar( '}' );
487 rOutput << endl;
488 }
489 }
490
491 // Write the pool defaults in advance ...
492 rOutput.WriteChar( '{' ).WriteOString( OOO_STRING_SVTOOLS_RTF_IGNORE ).WriteOString( "\\EditEnginePoolDefaults" );
493 for ( sal_uInt16 nPoolDefItem = EE_PARA_START; nPoolDefItem <= EE_CHAR_END; nPoolDefItem++)
494 {
495 const SfxPoolItem& rItem = aEditDoc.GetItemPool().GetDefaultItem( nPoolDefItem );
496 WriteItemAsRTF( rItem, rOutput, 0, 0, aFontTable, aColorList );
497 }
498 rOutput.WriteChar( '}' ) << endl;
499
500 // DefTab:
501 MapMode aTwpMode( MapUnit::MapTwip );
502 sal_uInt16 nDefTabTwps = static_cast<sal_uInt16>(GetRefDevice()->LogicToLogic(
503 Point( aEditDoc.GetDefTab(), 0 ),
504 &GetRefMapMode(), &aTwpMode ).X());
506 rOutput.WriteNumberAsString( nDefTabTwps );
507 rOutput << endl;
508
509 // iterate over the paragraphs ...
510 rOutput.WriteChar( '{' ) << endl;
511 for ( sal_Int32 nNode = nStartNode; nNode <= nEndNode; nNode++ )
512 {
513 ContentNode* pNode = aEditDoc.GetObject( nNode );
514 DBG_ASSERT( pNode, "Node not found: Search&Replace" );
515
516 // The paragraph attributes in advance ...
517 bool bAttr = false;
518
519 // Template?
520 if ( pNode->GetStyleSheet() )
521 {
522 // Number of template
524 sal_uInt32 nNumber = aStyleSheetToIdMap.find(pNode->GetStyleSheet())->second;
525 rOutput.WriteNumberAsString( nNumber );
526
527 // All Attribute
528 // Attribute, also from Parent!
529 for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
530 {
531 if ( pNode->GetStyleSheet()->GetItemSet().GetItemState( nParAttr ) == SfxItemState::SET )
532 {
533 const SfxPoolItem& rItem = pNode->GetStyleSheet()->GetItemSet().Get( nParAttr );
534 WriteItemAsRTF( rItem, rOutput, nNode, 0, aFontTable, aColorList );
535 bAttr = true;
536 }
537 }
538 }
539
540 for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
541 {
542 // Now where stylesheet processing, only hard paragraph attributes!
543 if ( pNode->GetContentAttribs().GetItems().GetItemState( nParAttr ) == SfxItemState::SET )
544 {
545 const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItems().Get( nParAttr );
546 WriteItemAsRTF( rItem, rOutput, nNode, 0, aFontTable, aColorList );
547 bAttr = true;
548 }
549 }
550 if ( bAttr )
551 rOutput.WriteChar( ' ' ); // Separator
552
553 ItemList aAttribItems;
554 ParaPortion* pParaPortion = FindParaPortion( pNode );
555 DBG_ASSERT( pParaPortion, "Portion not found: WriteRTF" );
556
557 sal_Int32 nIndex = 0;
558 sal_Int32 nStartPos = 0;
559 sal_Int32 nEndPos = pNode->Len();
560 sal_Int32 nStartPortion = 0;
561 sal_Int32 nEndPortion = pParaPortion->GetTextPortions().Count() - 1;
562 bool bFinishPortion = false;
563 sal_Int32 nPortionStart;
564
565 if ( nNode == nStartNode )
566 {
567 nStartPos = aSel.Min().GetIndex();
568 nStartPortion = pParaPortion->GetTextPortions().FindPortion( nStartPos, nPortionStart );
569 if ( nStartPos != 0 )
570 {
571 aAttribItems.Clear();
572 lcl_FindValidAttribs( aAttribItems, pNode, nStartPos, GetI18NScriptType( EditPaM( pNode, 0 ) ) );
573 if ( aAttribItems.Count() )
574 {
575 // These attributes may not apply to the entire paragraph:
576 rOutput.WriteChar( '{' );
577 WriteItemListAsRTF( aAttribItems, rOutput, nNode, nStartPos, aFontTable, aColorList );
578 bFinishPortion = true;
579 }
580 aAttribItems.Clear();
581 }
582 }
583 if ( nNode == nEndNode ) // can also be == nStart!
584 {
585 nEndPos = aSel.Max().GetIndex();
586 nEndPortion = pParaPortion->GetTextPortions().FindPortion( nEndPos, nPortionStart );
587 }
588
589 const EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature(nIndex);
590 // start at 0, so the index is right ...
591 for ( sal_Int32 n = 0; n <= nEndPortion; n++ )
592 {
593 const TextPortion& rTextPortion = pParaPortion->GetTextPortions()[n];
594 if ( n < nStartPortion )
595 {
596 nIndex = nIndex + rTextPortion.GetLen();
597 continue;
598 }
599
600 if ( pNextFeature && ( pNextFeature->GetStart() == nIndex ) && ( pNextFeature->GetItem()->Which() != EE_FEATURE_FIELD ) )
601 {
602 WriteItemAsRTF( *pNextFeature->GetItem(), rOutput, nNode, nIndex, aFontTable, aColorList );
603 pNextFeature = pNode->GetCharAttribs().FindFeature( pNextFeature->GetStart() + 1 );
604 }
605 else
606 {
607 aAttribItems.Clear();
608 sal_uInt16 nScriptTypeI18N = GetI18NScriptType( EditPaM( pNode, nIndex+1 ) );
609 SvtScriptType nScriptType = SvtLanguageOptions::FromI18NToSvtScriptType(nScriptTypeI18N);
610 if ( !n || IsScriptChange( EditPaM( pNode, nIndex ) ) )
611 {
612 SfxItemSet aAttribs = GetAttribs( nNode, nIndex+1, nIndex+1 );
613 aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_FONTINFO, nScriptType ) ) );
614 aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType ) ) );
615 aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_WEIGHT, nScriptType ) ) );
616 aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_ITALIC, nScriptType ) ) );
617 aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType ) ) );
618 }
619 // Insert hard attribs AFTER CJK attribs...
620 lcl_FindValidAttribs( aAttribItems, pNode, nIndex, nScriptTypeI18N );
621
622 rOutput.WriteChar( '{' );
623 if ( WriteItemListAsRTF( aAttribItems, rOutput, nNode, nIndex, aFontTable, aColorList ) )
624 rOutput.WriteChar( ' ' );
625
626 sal_Int32 nS = nIndex;
627 sal_Int32 nE = nIndex + rTextPortion.GetLen();
628 if ( n == nStartPortion )
629 nS = nStartPos;
630 if ( n == nEndPortion )
631 nE = nEndPos;
632
633 OUString aRTFStr = EditDoc::GetParaAsString( pNode, nS, nE);
634 RTFOutFuncs::Out_String( rOutput, aRTFStr, eDestEnc );
635 rOutput.WriteChar( '}' );
636 }
637 if ( bFinishPortion )
638 {
639 rOutput.WriteChar( '}' );
640 bFinishPortion = false;
641 }
642
643 nIndex = nIndex + rTextPortion.GetLen();
644 }
645
647 rOutput << endl;
648 }
649 // RTF-trailer ...
650 rOutput.WriteOString( "}}" ); // 1xparentheses paragraphs, 1xparentheses RTF document
651
652 aFontTable.clear();
653
654 return rOutput.GetError();
655}
656
657
658void ImpEditEngine::WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_Int32 nPara, sal_Int32 nPos,
659 std::vector<std::unique_ptr<SvxFontItem>>& rFontTable, SvxColorList& rColorList )
660{
661 sal_uInt16 nWhich = rItem.Which();
662 switch ( nWhich )
663 {
665 {
666 const SvxFrameDirectionItem& rWritingMode = static_cast<const SvxFrameDirectionItem&>(rItem);
667 if ( rWritingMode.GetValue() == SvxFrameDirection::Horizontal_RL_TB )
668 rOutput.WriteOString( "\\rtlpar" );
669 else
670 rOutput.WriteOString( "\\ltrpar" );
671 }
672 break;
674 {
675 sal_Int32 nLevel = static_cast<const SfxInt16Item&>(rItem).GetValue();
676 if( nLevel >= 0 )
677 {
678 rOutput.WriteOString( "\\level" );
679 rOutput.WriteNumberAsString( nLevel );
680 }
681 }
682 break;
684 case EE_PARA_LRSPACE:
685 {
687 sal_Int32 nTxtFirst = static_cast<const SvxLRSpaceItem&>(rItem).GetTextFirstLineOffset();
688 nTxtFirst = LogicToTwips( nTxtFirst );
689 rOutput.WriteNumberAsString( nTxtFirst );
691 sal_uInt32 nTxtLeft = static_cast< sal_uInt32 >(static_cast<const SvxLRSpaceItem&>(rItem).GetTextLeft());
692 nTxtLeft = static_cast<sal_uInt32>(LogicToTwips( nTxtLeft ));
693 rOutput.WriteNumberAsString( nTxtLeft );
695 sal_uInt32 nTxtRight = static_cast<const SvxLRSpaceItem&>(rItem).GetRight();
696 nTxtRight = LogicToTwips( nTxtRight);
697 rOutput.WriteNumberAsString( nTxtRight );
698 }
699 break;
700 case EE_PARA_ULSPACE:
701 {
703 sal_uInt32 nUpper = static_cast<const SvxULSpaceItem&>(rItem).GetUpper();
704 nUpper = static_cast<sal_uInt32>(LogicToTwips( nUpper ));
705 rOutput.WriteNumberAsString( nUpper );
707 sal_uInt32 nLower = static_cast<const SvxULSpaceItem&>(rItem).GetLower();
708 nLower = LogicToTwips( nLower );
709 rOutput.WriteNumberAsString( nLower );
710 }
711 break;
712 case EE_PARA_SBL:
713 {
715 sal_Int32 nVal = static_cast<const SvxLineSpacingItem&>(rItem).GetLineHeight();
716 char cMult = '0';
717 if ( static_cast<const SvxLineSpacingItem&>(rItem).GetInterLineSpaceRule() == SvxInterLineSpaceRule::Prop )
718 {
719 // From where do I get the value now?
720 // The SwRTF parser is based on a 240 Font!
721 nVal = static_cast<const SvxLineSpacingItem&>(rItem).GetPropLineSpace();
722 nVal *= 240;
723 nVal /= 100;
724 cMult = '1';
725 }
726 rOutput.WriteNumberAsString( nVal );
728 }
729 break;
730 case EE_PARA_JUST:
731 {
732 SvxAdjust eJustification = static_cast<const SvxAdjustItem&>(rItem).GetAdjust();
733 switch ( eJustification )
734 {
736 break;
738 break;
739 default: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_QL );
740 break;
741 }
742 }
743 break;
744 case EE_PARA_TABS:
745 {
746 const SvxTabStopItem& rTabs = static_cast<const SvxTabStopItem&>(rItem);
747 for ( sal_uInt16 i = 0; i < rTabs.Count(); i++ )
748 {
749 const SvxTabStop& rTab = rTabs[i];
751 rOutput.WriteNumberAsString( LogicToTwips( rTab.GetTabPos() ) );
752 }
753 }
754 break;
755 case EE_CHAR_COLOR:
756 {
757 SvxColorList::const_iterator const iter = std::find(
758 rColorList.begin(), rColorList.end(),
759 static_cast<SvxColorItem const&>(rItem).GetValue());
760 assert(iter != rColorList.end());
761 sal_uInt32 const n = iter - rColorList.begin();
763 rOutput.WriteNumberAsString( n );
764 }
765 break;
766 case EE_CHAR_FONTINFO:
769 {
770 sal_uInt32 n = 0;
771 for (size_t i = 0; i < rFontTable.size(); ++i)
772 {
773 if (*rFontTable[i] == rItem)
774 {
775 n = i;
776 break;
777 }
778 }
779
781 rOutput.WriteNumberAsString( n );
782 }
783 break;
787 {
789 sal_Int32 nHeight = static_cast<const SvxFontHeightItem&>(rItem).GetHeight();
790 nHeight = LogicToTwips( nHeight );
791 // Twips => HalfPoints
792 nHeight /= 10;
793 rOutput.WriteNumberAsString( nHeight );
794 }
795 break;
796 case EE_CHAR_WEIGHT:
799 {
800 FontWeight e = static_cast<const SvxWeightItem&>(rItem).GetWeight();
801 switch ( e )
802 {
803 case WEIGHT_BOLD: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_B ); break;
804 default: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_B ).WriteChar( '0' ); break;
805 }
806 }
807 break;
809 {
810 // Must underlined if in WordLineMode, but the information is
811 // missing here
812 FontLineStyle e = static_cast<const SvxUnderlineItem&>(rItem).GetLineStyle();
813 switch ( e )
814 {
819 default:
820 break;
821 }
822 }
823 break;
824 case EE_CHAR_OVERLINE:
825 {
826 FontLineStyle e = static_cast<const SvxOverlineItem&>(rItem).GetLineStyle();
827 switch ( e )
828 {
833 default:
834 break;
835 }
836 }
837 break;
839 {
840 FontStrikeout e = static_cast<const SvxCrossedOutItem&>(rItem).GetStrikeout();
841 switch ( e )
842 {
843 case STRIKEOUT_SINGLE:
846 default:
847 break;
848 }
849 }
850 break;
851 case EE_CHAR_ITALIC:
854 {
855 FontItalic e = static_cast<const SvxPostureItem&>(rItem).GetPosture();
856 switch ( e )
857 {
858 case ITALIC_OBLIQUE:
860 case ITALIC_NONE: rOutput.WriteOString( OOO_STRING_SVTOOLS_RTF_I ).WriteChar( '0' ); break;
861 default:
862 break;
863 }
864 }
865 break;
866 case EE_CHAR_OUTLINE:
867 {
869 if ( !static_cast<const SvxContourItem&>(rItem).GetValue() )
870 rOutput.WriteChar( '0' );
871 }
872 break;
873 case EE_CHAR_RELIEF:
874 {
875 FontRelief nRelief = static_cast<const SvxCharReliefItem&>(rItem).GetValue();
876 if ( nRelief == FontRelief::Embossed )
878 if ( nRelief == FontRelief::Engraved )
880 }
881 break;
883 {
884 FontEmphasisMark nMark = static_cast<const SvxEmphasisMarkItem&>(rItem).GetEmphasisMark();
885 if ( nMark == FontEmphasisMark::NONE )
887 else if ( nMark == (FontEmphasisMark::Accent | FontEmphasisMark::PosAbove) )
889 else
891 }
892 break;
893 case EE_CHAR_SHADOW:
894 {
896 if ( !static_cast<const SvxShadowedItem&>(rItem).GetValue() )
897 rOutput.WriteChar( '0' );
898 }
899 break;
900 case EE_FEATURE_TAB:
901 {
903 }
904 break;
906 {
908 }
909 break;
910 case EE_CHAR_KERNING:
911 {
914 static_cast<const SvxKerningItem&>(rItem).GetValue() ) );
915 }
916 break;
918 {
920 rOutput.WriteNumberAsString( static_cast<const SvxAutoKernItem&>(rItem).GetValue() ? 1 : 0 );
921 }
922 break;
924 {
925 SvxFont aFont;
926 ContentNode* pNode = aEditDoc.GetObject( nPara );
927 SeekCursor( pNode, nPos, aFont );
928 MapMode aPntMode( MapUnit::MapPoint );
929 tools::Long nFontHeight = GetRefDevice()->LogicToLogic(
930 aFont.GetFontSize(), &GetRefMapMode(), &aPntMode ).Height();
931 nFontHeight *=2; // Half Points
932 sal_uInt16 const nProp = static_cast<const SvxEscapementItem&>(rItem).GetProportionalHeight();
933 sal_uInt16 nProp100 = nProp*100; // For SWG-Token Prop in 100th percent.
934 short nEsc = static_cast<const SvxEscapementItem&>(rItem).GetEsc();
935 const FontMetric& rFontMetric = GetRefDevice()->GetFontMetric();
936 double fFontHeight = rFontMetric.GetAscent() + rFontMetric.GetDescent();
937 double fAutoAscent = .8;
938 double fAutoDescent = .2;
939 if ( fFontHeight )
940 {
941 fAutoAscent = rFontMetric.GetAscent() / fFontHeight;
942 fAutoDescent = rFontMetric.GetDescent() / fFontHeight;
943 }
944 if ( nEsc == DFLT_ESC_AUTO_SUPER )
945 {
946 nEsc = fAutoAscent * (100 - nProp);
947 nProp100++; // A 1 afterwards means 'automatic'.
948 }
949 else if ( nEsc == DFLT_ESC_AUTO_SUB )
950 {
951 nEsc = fAutoDescent * -(100 - nProp);
952 nProp100++;
953 }
954 // SWG:
955 if ( nEsc )
956 {
957 rOutput.WriteOString( "{\\*\\updnprop" ).WriteNumberAsString(
958 nProp100 ).WriteChar( '}' );
959 }
960 tools::Long nUpDown = nFontHeight * std::abs( nEsc ) / 100;
961 if ( nEsc < 0 )
963 else if ( nEsc > 0 )
965 rOutput.WriteNumberAsString(nUpDown);
966 }
967 break;
968 }
969}
970
971std::unique_ptr<EditTextObject> ImpEditEngine::GetEmptyTextObject()
972{
973 EditSelection aEmptySel;
974 aEmptySel.Min() = aEditDoc.GetStartPaM();
975 aEmptySel.Max() = aEditDoc.GetStartPaM();
976
977 return CreateTextObject( aEmptySel );
978}
979
980std::unique_ptr<EditTextObject> ImpEditEngine::CreateTextObject()
981{
982 EditSelection aCompleteSelection;
983 aCompleteSelection.Min() = aEditDoc.GetStartPaM();
984 aCompleteSelection.Max() = aEditDoc.GetEndPaM();
985
986 return CreateTextObject( aCompleteSelection );
987}
988
989std::unique_ptr<EditTextObject> ImpEditEngine::CreateTextObject(const EditSelection& rSel)
990{
992}
993
994std::unique_ptr<EditTextObject> ImpEditEngine::CreateTextObject( EditSelection aSel, SfxItemPool* pPool, bool bAllowBigObjects, sal_Int32 nBigObjectStart )
995{
996 sal_Int32 nStartNode, nEndNode;
997 sal_Int32 nTextPortions = 0;
998
999 aSel.Adjust( aEditDoc );
1000 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
1001 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
1002
1003 bool bOnlyFullParagraphs = !( aSel.Min().GetIndex() ||
1004 ( aSel.Max().GetIndex() < aSel.Max().GetNode()->Len() ) );
1005
1006 // Templates are not saved!
1007 // (Only the name and family, template itself must be in App!)
1008
1009 const MapUnit eMapUnit = aEditDoc.GetItemPool().GetMetric(DEF_METRIC);
1010 auto pTxtObj(std::make_unique<EditTextObjectImpl>(pPool, eMapUnit, GetVertical(), GetRotation(),
1011 GetItemScriptType(aSel)));
1012
1013 // iterate over the paragraphs ...
1014 sal_Int32 nNode;
1015 for ( nNode = nStartNode; nNode <= nEndNode; nNode++ )
1016 {
1017 ContentNode* pNode = aEditDoc.GetObject( nNode );
1018 DBG_ASSERT( pNode, "Node not found: Search&Replace" );
1019
1020 if ( bOnlyFullParagraphs )
1021 {
1022 const ParaPortion* pParaPortion = GetParaPortions()[nNode];
1023 nTextPortions += pParaPortion->GetTextPortions().Count();
1024 }
1025
1026 sal_Int32 nStartPos = 0;
1027 sal_Int32 nEndPos = pNode->Len();
1028
1029 bool bEmptyPara = nEndPos == 0;
1030
1031 if ( ( nNode == nStartNode ) && !bOnlyFullParagraphs )
1032 nStartPos = aSel.Min().GetIndex();
1033 if ( ( nNode == nEndNode ) && !bOnlyFullParagraphs )
1034 nEndPos = aSel.Max().GetIndex();
1035
1036
1037 ContentInfo *pC = pTxtObj->CreateAndInsertContent();
1038
1039 // The paragraph attributes ...
1040 pC->GetParaAttribs().Set( pNode->GetContentAttribs().GetItems() );
1041
1042 // The StyleSheet...
1043 if ( pNode->GetStyleSheet() )
1044 {
1045 pC->SetStyle(pNode->GetStyleSheet()->GetName());
1046 pC->SetFamily(pNode->GetStyleSheet()->GetFamily());
1047 }
1048
1049 // The Text...
1050 pC->SetText(pNode->Copy(nStartPos, nEndPos-nStartPos));
1051 auto& rCAttriblist = pC->GetCharAttribs();
1052
1053 // and the Attribute...
1054 std::size_t nAttr = 0;
1055 EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
1056 rCAttriblist.reserve(rCAttriblist.size() + pNode->GetCharAttribs().GetAttribs().size());
1057 while ( pAttr )
1058 {
1059 // In a blank paragraph keep the attributes!
1060 if ( bEmptyPara ||
1061 ( ( pAttr->GetEnd() > nStartPos ) && ( pAttr->GetStart() < nEndPos ) ) )
1062 {
1063 XEditAttribute aX = pTxtObj->CreateAttrib(*pAttr->GetItem(), pAttr->GetStart(), pAttr->GetEnd());
1064 // Possibly Correct ...
1065 if ( ( nNode == nStartNode ) && ( nStartPos != 0 ) )
1066 {
1067 aX.GetStart() = ( aX.GetStart() > nStartPos ) ? aX.GetStart()-nStartPos : 0;
1068 aX.GetEnd() = aX.GetEnd() - nStartPos;
1069
1070 }
1071 if ( nNode == nEndNode )
1072 {
1073 if ( aX.GetEnd() > (nEndPos-nStartPos) )
1074 aX.GetEnd() = nEndPos-nStartPos;
1075 }
1076 DBG_ASSERT( aX.GetEnd() <= (nEndPos-nStartPos), "CreateTextObject: Attribute too long!" );
1077 if ( !aX.GetLen() && !bEmptyPara )
1078 pTxtObj->DestroyAttrib(aX);
1079 else
1080 rCAttriblist.push_back(std::move(aX));
1081 }
1082 nAttr++;
1083 pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
1084 }
1085
1086 // If possible online spelling
1087 if ( bAllowBigObjects && bOnlyFullParagraphs && pNode->GetWrongList() )
1088 pC->SetWrongList( pNode->GetWrongList()->Clone() );
1089
1090 }
1091
1092 // Remember the portions info in case of large text objects:
1093 // sleeper set up when Olli paragraphs not hacked!
1094 if ( bAllowBigObjects && bOnlyFullParagraphs && IsFormatted() && IsUpdateLayout() && ( nTextPortions >= nBigObjectStart ) )
1095 {
1097 pTxtObj->SetPortionInfo(std::unique_ptr<XParaPortionList>(pXList));
1098 for ( nNode = nStartNode; nNode <= nEndNode; nNode++ )
1099 {
1100 const ParaPortion* pParaPortion = GetParaPortions()[nNode];
1101 XParaPortion* pX = new XParaPortion;
1102 pXList->push_back(pX);
1103
1104 pX->nHeight = pParaPortion->GetHeight();
1105 pX->nFirstLineOffset = pParaPortion->GetFirstLineOffset();
1106
1107 // The TextPortions
1108 sal_uInt16 nCount = pParaPortion->GetTextPortions().Count();
1109 sal_uInt16 n;
1110 for ( n = 0; n < nCount; n++ )
1111 {
1112 const TextPortion& rTextPortion = pParaPortion->GetTextPortions()[n];
1113 TextPortion* pNew = new TextPortion( rTextPortion );
1114 pX->aTextPortions.Append(pNew);
1115 }
1116
1117 // The lines
1118 nCount = pParaPortion->GetLines().Count();
1119 for ( n = 0; n < nCount; n++ )
1120 {
1121 const EditLine& rLine = pParaPortion->GetLines()[n];
1122 EditLine* pNew = rLine.Clone();
1123 pX->aLines.Append(pNew);
1124 }
1125#ifdef DBG_UTIL
1126 sal_uInt16 nTest;
1127 int nTPLen = 0, nTxtLen = 0;
1128 for ( nTest = pParaPortion->GetTextPortions().Count(); nTest; )
1129 nTPLen += pParaPortion->GetTextPortions()[--nTest].GetLen();
1130 for ( nTest = pParaPortion->GetLines().Count(); nTest; )
1131 nTxtLen += pParaPortion->GetLines()[--nTest].GetLen();
1132 DBG_ASSERT( ( nTPLen == pParaPortion->GetNode()->Len() ) && ( nTxtLen == pParaPortion->GetNode()->Len() ), "CreateBinTextObject: ParaPortion not completely formatted!" );
1133#endif
1134 }
1135 }
1136 return pTxtObj;
1137}
1138
1139void ImpEditEngine::SetText( const EditTextObject& rTextObject )
1140{
1141 // Since setting a text object is not undo-able!
1143 bool _bUpdate = IsUpdateLayout();
1144 bool _bUndo = IsUndoEnabled();
1145
1146 SetText( OUString() );
1147 EditPaM aPaM = aEditDoc.GetStartPaM();
1148
1149 SetUpdateLayout( false );
1150 EnableUndo( false );
1151
1152 InsertText( rTextObject, EditSelection( aPaM, aPaM ) );
1153 SetVertical(rTextObject.GetVertical());
1154 SetRotation(rTextObject.GetRotation());
1155
1156 DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "From where comes the Undo in SetText ?!" );
1157 SetUpdateLayout( _bUpdate );
1158 EnableUndo( _bUndo );
1159}
1160
1162{
1163 aSel.Adjust( aEditDoc );
1164 if ( aSel.HasRange() )
1165 aSel = ImpDeleteSelection( aSel );
1166 EditSelection aNewSel = InsertTextObject( rTextObject, aSel.Max() );
1167 return aNewSel;
1168}
1169
1171{
1172 // Optimize: No getPos undFindParaportion, instead calculate index!
1173 EditSelection aSel( aPaM, aPaM );
1174 DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "InsertBibTextObject: Selection broken!(1)" );
1175
1176 bool bUsePortionInfo = false;
1177 const EditTextObjectImpl& rTextObjectImpl = toImpl(rTextObject);
1178 XParaPortionList* pPortionInfo = rTextObjectImpl.GetPortionInfo();
1179
1180 if ( pPortionInfo && ( static_cast<tools::Long>(pPortionInfo->GetPaperWidth()) == GetColumnWidth(aPaperSize) )
1181 && pPortionInfo->GetRefMapMode() == GetRefDevice()->GetMapMode()
1182 && pPortionInfo->getFontScaleX() == mfFontScaleX
1183 && pPortionInfo->getFontScaleY() == mfFontScaleY
1184 && pPortionInfo->getSpacingScaleX() == mfSpacingScaleX
1185 && pPortionInfo->getSpacingScaleY() == mfSpacingScaleY)
1186 {
1187 if ( (pPortionInfo->GetRefDevPtr() == GetRefDevice()) ||
1188 (pPortionInfo->RefDevIsVirtual() && GetRefDevice()->IsVirtual()) )
1189 bUsePortionInfo = true;
1190 }
1191
1192 bool bConvertMetricOfItems = false;
1193 MapUnit eSourceUnit = MapUnit(), eDestUnit = MapUnit();
1194 if (rTextObjectImpl.HasMetric())
1195 {
1196 eSourceUnit = rTextObjectImpl.GetMetric();
1197 eDestUnit = aEditDoc.GetItemPool().GetMetric( DEF_METRIC );
1198 if ( eSourceUnit != eDestUnit )
1199 bConvertMetricOfItems = true;
1200 }
1201
1202 // Before, paragraph count was of type sal_uInt16 so if nContents exceeded
1203 // 0xFFFF this wouldn't have worked anyway, given that nPara is used to
1204 // number paragraphs and is fearlessly incremented.
1205 sal_Int32 nContents = static_cast<sal_Int32>(rTextObjectImpl.GetContents().size());
1206 SAL_WARN_IF( nContents < 0, "editeng", "ImpEditEngine::InsertTextObject - contents overflow " << nContents);
1207 sal_Int32 nPara = aEditDoc.GetPos( aPaM.GetNode() );
1208
1209 for (sal_Int32 n = 0; n < nContents; ++n, ++nPara)
1210 {
1211 const ContentInfo* pC = rTextObjectImpl.GetContents()[n].get();
1212 bool bNewContent = aPaM.GetNode()->Len() == 0;
1213 const sal_Int32 nStartPos = aPaM.GetIndex();
1214
1215 aPaM = ImpFastInsertText( aPaM, pC->GetText() );
1216
1217 ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
1218 DBG_ASSERT( pPortion, "Blind Portion in FastInsertText" );
1219 pPortion->MarkInvalid( nStartPos, pC->GetText().getLength() );
1220
1221 // Character attributes ...
1222 bool bAllreadyHasAttribs = aPaM.GetNode()->GetCharAttribs().Count() != 0;
1223 size_t nNewAttribs = pC->GetCharAttribs().size();
1224 if ( nNewAttribs )
1225 {
1226 bool bUpdateFields = false;
1227 for (size_t nAttr = 0; nAttr < nNewAttribs; ++nAttr)
1228 {
1229 const XEditAttribute& rX = pC->GetCharAttribs()[nAttr];
1230 // Can happen when paragraphs > 16K, it is simply wrapped.
1231 //TODO! Still true, still needed?
1232 if ( rX.GetEnd() <= aPaM.GetNode()->Len() )
1233 {
1234 if ( !bAllreadyHasAttribs || rX.IsFeature() )
1235 {
1236 // Normal attributes then go faster ...
1237 // Features shall not be inserted through
1238 // EditDoc:: InsertAttrib, using FastInsertText they are
1239 // already in the flow
1240 DBG_ASSERT( rX.GetEnd() <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribute too large!" );
1241 EditCharAttrib* pAttr;
1242 if ( !bConvertMetricOfItems )
1243 pAttr = MakeCharAttrib( aEditDoc.GetItemPool(), *(rX.GetItem()), rX.GetStart()+nStartPos, rX.GetEnd()+nStartPos );
1244 else
1245 {
1246 std::unique_ptr<SfxPoolItem> pNew(rX.GetItem()->Clone());
1247 ConvertItem( pNew, eSourceUnit, eDestUnit );
1248 pAttr = MakeCharAttrib( aEditDoc.GetItemPool(), *pNew, rX.GetStart()+nStartPos, rX.GetEnd()+nStartPos );
1249 }
1250 DBG_ASSERT( pAttr->GetEnd() <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribute does not fit! (1)" );
1251 aPaM.GetNode()->GetCharAttribs().InsertAttrib( pAttr );
1252 if ( pAttr->Which() == EE_FEATURE_FIELD )
1253 bUpdateFields = true;
1254 }
1255 else
1256 {
1257 DBG_ASSERT( rX.GetEnd()+nStartPos <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribute does not fit! (2)" );
1258 // Tabs and other Features can not be inserted through InsertAttrib:
1259 aEditDoc.InsertAttrib( aPaM.GetNode(), rX.GetStart()+nStartPos, rX.GetEnd()+nStartPos, *rX.GetItem() );
1260 }
1261 }
1262 }
1263 if ( bUpdateFields )
1264 UpdateFields();
1265
1266 // Otherwise, quick format => no attributes!
1267 pPortion->MarkSelectionInvalid( nStartPos );
1268 }
1269
1270#if OSL_DEBUG_LEVEL > 0 && !defined NDEBUG
1272#endif
1273
1274 bool bParaAttribs = false;
1275 if ( bNewContent || ( ( n > 0 ) && ( n < (nContents-1) ) ) )
1276 {
1277 // only style and ParaAttribs when new paragraph, or
1278 // completely internal ...
1279 bParaAttribs = pC->GetParaAttribs().Count() != 0;
1280 if ( GetStyleSheetPool() && pC->GetStyle().getLength() )
1281 {
1282 SfxStyleSheet* pStyle = static_cast<SfxStyleSheet*>(GetStyleSheetPool()->Find( pC->GetStyle(), pC->GetFamily() ));
1283 DBG_ASSERT( pStyle, "InsertBinTextObject - Style not found!" );
1284 SetStyleSheet( nPara, pStyle );
1285 }
1286 if ( !bConvertMetricOfItems )
1288 else
1289 {
1290 SfxItemSet aAttribs( GetEmptyItemSet() );
1291 ConvertAndPutItems( aAttribs, pC->GetParaAttribs(), &eSourceUnit, &eDestUnit );
1292 SetParaAttribs( aEditDoc.GetPos( aPaM.GetNode() ), aAttribs );
1293 }
1294 if ( bNewContent && bUsePortionInfo )
1295 {
1296 const XParaPortion& rXP = (*pPortionInfo)[n];
1297 ParaPortion* pParaPortion = GetParaPortions()[ nPara ];
1298 DBG_ASSERT( pParaPortion, "InsertBinTextObject: ParaPortion?" );
1299 pParaPortion->nHeight = rXP.nHeight;
1300 pParaPortion->nFirstLineOffset = rXP.nFirstLineOffset;
1301 pParaPortion->bForceRepaint = true;
1302 pParaPortion->SetValid(); // Do not format
1303
1304 // The Text Portions
1305 pParaPortion->GetTextPortions().Reset();
1306 sal_uInt16 nCount = rXP.aTextPortions.Count();
1307 for ( sal_uInt16 _n = 0; _n < nCount; _n++ )
1308 {
1309 const TextPortion& rTextPortion = rXP.aTextPortions[_n];
1310 TextPortion* pNew = new TextPortion( rTextPortion );
1311 pParaPortion->GetTextPortions().Append(pNew);
1312 }
1313
1314 // The lines
1315 pParaPortion->GetLines().Reset();
1316 nCount = rXP.aLines.Count();
1317 for ( sal_uInt16 m = 0; m < nCount; m++ )
1318 {
1319 const EditLine& rLine = rXP.aLines[m];
1320 EditLine* pNew = rLine.Clone();
1321 pNew->SetInvalid(); // Paint again!
1322 pParaPortion->GetLines().Append(pNew);
1323 }
1324#ifdef DBG_UTIL
1325 sal_uInt16 nTest;
1326 int nTPLen = 0, nTxtLen = 0;
1327 for ( nTest = pParaPortion->GetTextPortions().Count(); nTest; )
1328 nTPLen += pParaPortion->GetTextPortions()[--nTest].GetLen();
1329 for ( nTest = pParaPortion->GetLines().Count(); nTest; )
1330 nTxtLen += pParaPortion->GetLines()[--nTest].GetLen();
1331 DBG_ASSERT( ( nTPLen == pParaPortion->GetNode()->Len() ) && ( nTxtLen == pParaPortion->GetNode()->Len() ), "InsertTextObject: ParaPortion not completely formatted!" );
1332#endif
1333 }
1334 }
1335 if ( !bParaAttribs ) // DefFont is not calculated for FastInsertParagraph
1336 {
1338 if ( aStatus.UseCharAttribs() )
1339 aPaM.GetNode()->CreateDefFont();
1340 }
1341
1342 if ( bNewContent && GetStatus().DoOnlineSpelling() && pC->GetWrongList() )
1343 {
1344 aPaM.GetNode()->SetWrongList( pC->GetWrongList()->Clone() );
1345 }
1346
1347 // Wrap when followed by other ...
1348 if ( n < ( nContents-1) )
1349 {
1350 if ( bNewContent )
1351 aPaM = ImpFastInsertParagraph( nPara+1 );
1352 else
1353 aPaM = ImpInsertParaBreak( aPaM, false );
1354 }
1355 }
1356
1357 aSel.Max() = aPaM;
1358 DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "InsertBibTextObject: Selection broken!(1)" );
1359 return aSel;
1360}
1361
1362void ImpEditEngine::GetAllMisspellRanges( std::vector<editeng::MisspellRanges>& rRanges ) const
1363{
1364 std::vector<editeng::MisspellRanges> aRanges;
1365 const EditDoc& rDoc = GetEditDoc();
1366 for (sal_Int32 i = 0, n = rDoc.Count(); i < n; ++i)
1367 {
1368 const ContentNode* pNode = rDoc.GetObject(i);
1369 const WrongList* pWrongList = pNode->GetWrongList();
1370 if (!pWrongList)
1371 continue;
1372
1373 aRanges.emplace_back(i, std::vector(pWrongList->GetRanges()));
1374 }
1375
1376 aRanges.swap(rRanges);
1377}
1378
1379void ImpEditEngine::SetAllMisspellRanges( const std::vector<editeng::MisspellRanges>& rRanges )
1380{
1381 EditDoc& rDoc = GetEditDoc();
1382 for (auto const& rParaRanges : rRanges)
1383 {
1384 ContentNode* pNode = rDoc.GetObject(rParaRanges.mnParagraph);
1385 if (!pNode)
1386 continue;
1387
1388 pNode->CreateWrongList();
1389 WrongList* pWrongList = pNode->GetWrongList();
1390 pWrongList->SetRanges(std::vector(rParaRanges.maRanges));
1391 }
1392}
1393
1394editeng::LanguageSpan ImpEditEngine::GetLanguage( const EditPaM& rPaM, sal_Int32* pEndPos ) const
1395{
1396 short nScriptTypeI18N = GetI18NScriptType( rPaM, pEndPos ); // pEndPos will be valid now, pointing to ScriptChange or NodeLen
1397 SvtScriptType nScriptType = SvtLanguageOptions::FromI18NToSvtScriptType(nScriptTypeI18N);
1398 sal_uInt16 nLangId = GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType );
1399 const SvxLanguageItem* pLangItem = &static_cast<const SvxLanguageItem&>(rPaM.GetNode()->GetContentAttribs().GetItem( nLangId ));
1400 const EditCharAttrib* pAttr = rPaM.GetNode()->GetCharAttribs().FindAttrib( nLangId, rPaM.GetIndex() );
1401
1403
1404 if ( pAttr )
1405 {
1406 pLangItem = static_cast<const SvxLanguageItem*>(pAttr->GetItem());
1407 aLang.nStart = pAttr->GetStart();
1408 aLang.nEnd = pAttr->GetEnd();
1409 }
1410
1411 if ( pEndPos && pAttr && ( pAttr->GetEnd() < *pEndPos ) )
1412 *pEndPos = pAttr->GetEnd();
1413
1414 aLang.nLang = pLangItem->GetLanguage();
1415
1416 return aLang;
1417}
1418
1419css::lang::Locale ImpEditEngine::GetLocale( const EditPaM& rPaM ) const
1420{
1421 return LanguageTag( GetLanguage( rPaM ).nLang ).getLocale();
1422}
1423
1424Reference< XSpellChecker1 > const & ImpEditEngine::GetSpeller()
1425{
1426 if ( !xSpeller.is() )
1428 return xSpeller;
1429}
1430
1431
1432void ImpEditEngine::CreateSpellInfo( bool bMultipleDocs )
1433{
1434 if (!pSpellInfo)
1435 pSpellInfo.reset( new SpellInfo );
1436 else
1437 *pSpellInfo = SpellInfo(); // reset to default values
1438
1439 pSpellInfo->bMultipleDoc = bMultipleDocs;
1440 // always spell draw objects completely, starting at the top.
1441 // (spelling in only a selection or not starting with the top requires
1442 // further changes elsewhere to work properly)
1443 pSpellInfo->aSpellStart = EPaM();
1445}
1446
1447
1448EESpellState ImpEditEngine::Spell(EditView* pEditView, weld::Widget* pDialogParent, bool bMultipleDoc)
1449{
1450 SAL_WARN_IF( !xSpeller.is(), "editeng", "No Spell checker set!" );
1451
1452 if ( !xSpeller.is() )
1454
1456
1457 // In MultipleDoc always from the front / rear ...
1458 if ( bMultipleDoc )
1459 {
1460 pEditView->pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
1461 }
1462
1463 EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
1464 CreateSpellInfo( bMultipleDoc );
1465
1466 bool bIsStart = false;
1467 if ( bMultipleDoc )
1468 bIsStart = true; // Accessible from the front or from behind ...
1469 else if ( CreateEPaM( aEditDoc.GetStartPaM() ) == pSpellInfo->aSpellStart )
1470 bIsStart = true;
1471
1472 {
1473 EditSpellWrapper aWrp(pDialogParent, bIsStart, pEditView );
1474 aWrp.SpellDocument();
1475 }
1476
1477 if ( !bMultipleDoc )
1478 {
1479 pEditView->pImpEditView->DrawSelectionXOR();
1480 if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
1481 aCurSel.Max().SetIndex( aCurSel.Max().GetNode()->Len() );
1482 aCurSel.Min() = aCurSel.Max();
1483 pEditView->pImpEditView->SetEditSelection( aCurSel );
1484 pEditView->pImpEditView->DrawSelectionXOR();
1485 pEditView->ShowCursor( true, false );
1486 }
1487 EESpellState eState = pSpellInfo->eState;
1488 pSpellInfo.reset();
1489 return eState;
1490}
1491
1492
1494{
1495 bool bHasConvTxt = false;
1496
1497 sal_Int32 nParas = pEditEngine->GetParagraphCount();
1498 for (sal_Int32 k = 0; k < nParas; ++k)
1499 {
1500 std::vector<sal_Int32> aPortions;
1501 pEditEngine->GetPortions( k, aPortions );
1502 for ( size_t nPos = 0; nPos < aPortions.size(); ++nPos )
1503 {
1504 sal_Int32 nEnd = aPortions[ nPos ];
1505 sal_Int32 nStart = nPos > 0 ? aPortions[ nPos - 1 ] : 0;
1506
1507 // if the paragraph is not empty we need to increase the index
1508 // by one since the attribute of the character left to the
1509 // specified position is evaluated.
1510 if (nEnd > nStart) // empty para?
1511 ++nStart;
1512 LanguageType nLangFound = pEditEngine->GetLanguage( k, nStart ).nLang;
1513#ifdef DEBUG
1514 lang::Locale aLocale( LanguageTag::convertToLocale( nLangFound ) );
1515#endif
1516 bHasConvTxt = (nSrcLang == nLangFound) ||
1519 if (bHasConvTxt)
1520 return bHasConvTxt;
1521 }
1522 }
1523
1524 return bHasConvTxt;
1525}
1526
1527void ImpEditEngine::Convert( EditView* pEditView, weld::Widget* pDialogParent,
1528 LanguageType nSrcLang, LanguageType nDestLang, const vcl::Font *pDestFont,
1529 sal_Int32 nOptions, bool bIsInteractive, bool bMultipleDoc )
1530{
1531 // modified version of ImpEditEngine::Spell
1532
1533 // In MultipleDoc always from the front / rear ...
1534 if ( bMultipleDoc )
1535 pEditView->pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
1536
1537
1538 // initialize pConvInfo
1539 EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
1540 aCurSel.Adjust( aEditDoc );
1541 pConvInfo.reset(new ConvInfo);
1542 pConvInfo->bMultipleDoc = bMultipleDoc;
1543 pConvInfo->aConvStart = CreateEPaM( aCurSel.Min() );
1544
1545 // if it is not just a selection and we are about to begin
1546 // with the current conversion for the very first time
1547 // we need to find the start of the current (initial)
1548 // convertible unit in order for the text conversion to give
1549 // the correct result for that. Since it is easier to obtain
1550 // the start of the word we use that though.
1551 if (!aCurSel.HasRange() && ImplGetBreakIterator().is())
1552 {
1553 EditPaM aWordStartPaM( SelectWord( aCurSel, i18n::WordType::DICTIONARY_WORD ).Min() );
1554
1555 // since #118246 / #117803 still occurs if the cursor is placed
1556 // between the two chinese characters to be converted (because both
1557 // of them are words on their own!) using the word boundary here does
1558 // not work. Thus since chinese conversion is not interactive we start
1559 // at the begin of the paragraph to solve the problem, i.e. have the
1560 // TextConversion service get those characters together in the same call.
1561 pConvInfo->aConvStart.nIndex = editeng::HangulHanjaConversion::IsChinese( nSrcLang )
1562 ? 0 : aWordStartPaM.GetIndex();
1563 }
1564
1565 pConvInfo->aConvContinue = pConvInfo->aConvStart;
1566
1567 bool bIsStart = false;
1568 if ( bMultipleDoc )
1569 bIsStart = true; // Accessible from the front or from behind ...
1570 else if ( CreateEPaM( aEditDoc.GetStartPaM() ) == pConvInfo->aConvStart )
1571 bIsStart = true;
1572
1573 TextConvWrapper aWrp( pDialogParent,
1574 ::comphelper::getProcessComponentContext(),
1575 LanguageTag::convertToLocale( nSrcLang ),
1576 LanguageTag::convertToLocale( nDestLang ),
1577 pDestFont,
1578 nOptions, bIsInteractive,
1579 bIsStart, pEditView );
1580
1581
1587 //
1588 // disallow formatting, updating the view, ... while
1589 // non-interactively converting the document. (saves time)
1590 //if (!bIsInteractive)
1591 // SetUpdateMode( sal_False );
1592
1593 aWrp.Convert();
1594
1595 //if (!bIsInteractive)
1596 //SetUpdateMode( sal_True, 0, sal_True );
1597
1598 if ( !bMultipleDoc )
1599 {
1600 pEditView->pImpEditView->DrawSelectionXOR();
1601 if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
1602 aCurSel.Max().SetIndex( aCurSel.Max().GetNode()->Len() );
1603 aCurSel.Min() = aCurSel.Max();
1604 pEditView->pImpEditView->SetEditSelection( aCurSel );
1605 pEditView->pImpEditView->DrawSelectionXOR();
1606 pEditView->ShowCursor( true, false );
1607 }
1608 pConvInfo.reset();
1609}
1610
1611
1613 const ESelection &rESel,
1614 LanguageType nLang, sal_uInt16 nLangWhichId,
1615 const vcl::Font *pFont, sal_uInt16 nFontWhichId )
1616{
1617 ESelection aOldSel = pActiveView->GetSelection();
1618 pActiveView->SetSelection( rESel );
1619
1620 // set new language attribute
1622 aNewSet.Put( SvxLanguageItem( nLang, nLangWhichId ) );
1623
1624 // new font to be set?
1625 DBG_ASSERT( pFont, "target font missing?" );
1626 if (pFont)
1627 {
1628 // set new font attribute
1629 SvxFontItem aFontItem = static_cast<const SvxFontItem&>( aNewSet.Get( nFontWhichId ) );
1630 aFontItem.SetFamilyName( pFont->GetFamilyName());
1631 aFontItem.SetFamily( pFont->GetFamilyType());
1632 aFontItem.SetStyleName( pFont->GetStyleName());
1633 aFontItem.SetPitch( pFont->GetPitch());
1634 aFontItem.SetCharSet( pFont->GetCharSet() );
1635 aNewSet.Put( aFontItem );
1636 }
1637
1638 // apply new attributes
1639 pActiveView->SetAttribs( aNewSet );
1640
1641 pActiveView->SetSelection( aOldSel );
1642}
1643
1644
1645void ImpEditEngine::ImpConvert( OUString &rConvTxt, LanguageType &rConvTxtLang,
1646 EditView* pEditView, LanguageType nSrcLang, const ESelection &rConvRange,
1647 bool bAllowImplicitChangesForNotConvertibleText,
1648 LanguageType nTargetLang, const vcl::Font *pTargetFont )
1649{
1650 // modified version of ImpEditEngine::ImpSpell
1651
1652 // looks for next convertible text portion to be passed on to the wrapper
1653
1654 OUString aRes;
1655 LanguageType nResLang = LANGUAGE_NONE;
1656
1657 EditPaM aPos( CreateEditPaM( pConvInfo->aConvContinue ) );
1658 EditSelection aCurSel( aPos, aPos );
1659
1660 OUString aWord;
1661
1662 while (aRes.isEmpty())
1663 {
1664 // empty paragraph found that needs to have language and font set?
1665 if (bAllowImplicitChangesForNotConvertibleText &&
1666 pEditEngine->GetText( pConvInfo->aConvContinue.nPara ).isEmpty())
1667 {
1668 sal_Int32 nPara = pConvInfo->aConvContinue.nPara;
1669 ESelection aESel( nPara, 0, nPara, 0 );
1670 // see comment for below same function call
1671 SetLanguageAndFont( aESel,
1672 nTargetLang, EE_CHAR_LANGUAGE_CJK,
1673 pTargetFont, EE_CHAR_FONTINFO_CJK );
1674 }
1675
1676
1677 if (pConvInfo->aConvContinue.nPara == pConvInfo->aConvTo.nPara &&
1678 pConvInfo->aConvContinue.nIndex >= pConvInfo->aConvTo.nIndex)
1679 break;
1680
1681 sal_Int32 nAttribStart = -1;
1682 sal_Int32 nAttribEnd = -1;
1683 sal_Int32 nCurPos = -1;
1684 EPaM aCurStart = CreateEPaM( aCurSel.Min() );
1685 std::vector<sal_Int32> aPortions;
1686 pEditEngine->GetPortions( aCurStart.nPara, aPortions );
1687 for ( size_t nPos = 0; nPos < aPortions.size(); ++nPos )
1688 {
1689 const sal_Int32 nEnd = aPortions[ nPos ];
1690 const sal_Int32 nStart = nPos > 0 ? aPortions[ nPos - 1 ] : 0;
1691
1692 // the language attribute is obtained from the left character
1693 // (like usually all other attributes)
1694 // thus we usually have to add 1 in order to get the language
1695 // of the text right to the cursor position
1696 const sal_Int32 nLangIdx = nEnd > nStart ? nStart + 1 : nStart;
1697 LanguageType nLangFound = pEditEngine->GetLanguage( aCurStart.nPara, nLangIdx ).nLang;
1698#ifdef DEBUG
1699 lang::Locale aLocale( LanguageTag::convertToLocale( nLangFound ) );
1700#endif
1701 bool bLangOk = (nLangFound == nSrcLang) ||
1704
1705 if (nAttribEnd>=0) // start already found?
1706 {
1707 DBG_ASSERT(nEnd >= aCurStart.nIndex, "error while scanning attributes (a)" );
1708 DBG_ASSERT(nEnd >= nAttribEnd, "error while scanning attributes (b)" );
1709 if (/*nEnd >= aCurStart.nIndex &&*/ nLangFound == nResLang)
1710 nAttribEnd = nEnd;
1711 else // language attrib has changed
1712 break;
1713 }
1714 if (nAttribStart<0 && // start not yet found?
1715 nEnd > aCurStart.nIndex && bLangOk)
1716 {
1717 nAttribStart = nStart;
1718 nAttribEnd = nEnd;
1719 nResLang = nLangFound;
1720 }
1726 if (nAttribStart >= 0 && nAttribStart < aCurStart.nIndex)
1727 {
1728 nAttribStart = aCurStart.nIndex;
1729 }
1730
1731 // check script type to the right of the start of the current portion
1732 EditPaM aPaM( CreateEditPaM( EPaM(aCurStart.nPara, nLangIdx) ) );
1733 bool bIsAsianScript = (i18n::ScriptType::ASIAN == GetI18NScriptType( aPaM ));
1734 // not yet processed text part with for conversion
1735 // not suitable language found that needs to be changed?
1736 if (bAllowImplicitChangesForNotConvertibleText &&
1737 !bLangOk && !bIsAsianScript && nEnd > aCurStart.nIndex)
1738 {
1739 ESelection aESel( aCurStart.nPara, nStart, aCurStart.nPara, nEnd );
1740 // set language and font to target language and font of conversion
1743 // This is in order for every *new* text entered at *any* position to
1744 // have the correct language and font attributes set.
1745 SetLanguageAndFont( aESel,
1746 nTargetLang, EE_CHAR_LANGUAGE_CJK,
1747 pTargetFont, EE_CHAR_FONTINFO_CJK );
1748 }
1749
1750 nCurPos = nEnd;
1751 }
1752
1753 if (nAttribStart>=0 && nAttribEnd>=0)
1754 {
1755 aCurSel.Min().SetIndex( nAttribStart );
1756 aCurSel.Max().SetIndex( nAttribEnd );
1757 }
1758 else if (nCurPos>=0)
1759 {
1760 // set selection to end of scanned text
1761 // (used to set the position where to continue from later on)
1762 aCurSel.Min().SetIndex( nCurPos );
1763 aCurSel.Max().SetIndex( nCurPos );
1764 }
1765
1766 if ( !pConvInfo->bConvToEnd )
1767 {
1768 EPaM aEPaM( CreateEPaM( aCurSel.Min() ) );
1769 if ( !( aEPaM < pConvInfo->aConvTo ) )
1770 break;
1771 }
1772
1773 // clip selected word to the converted area
1774 // (main use when conversion starts/ends **within** a word)
1775 EditPaM aPaM( CreateEditPaM( pConvInfo->aConvStart ) );
1776 if (pConvInfo->bConvToEnd &&
1777 aCurSel.Min().GetNode() == aPaM.GetNode() &&
1778 aCurSel.Min().GetIndex() < aPaM.GetIndex())
1779 aCurSel.Min().SetIndex( aPaM.GetIndex() );
1780 aPaM = CreateEditPaM( pConvInfo->aConvContinue );
1781 if (aCurSel.Min().GetNode() == aPaM.GetNode() &&
1782 aCurSel.Min().GetIndex() < aPaM.GetIndex())
1783 aCurSel.Min().SetIndex( aPaM.GetIndex() );
1784 aPaM = CreateEditPaM( pConvInfo->aConvTo );
1785 if ((!pConvInfo->bConvToEnd || rConvRange.HasRange())&&
1786 aCurSel.Max().GetNode() == aPaM.GetNode() &&
1787 aCurSel.Max().GetIndex() > aPaM.GetIndex())
1788 aCurSel.Max().SetIndex( aPaM.GetIndex() );
1789
1790 aWord = GetSelected( aCurSel );
1791
1792 if ( !aWord.isEmpty() /* && bLangOk */)
1793 aRes = aWord;
1794
1795 // move to next word/paragraph if necessary
1796 if ( aRes.isEmpty() )
1797 aCurSel = WordRight( aCurSel.Min(), css::i18n::WordType::DICTIONARY_WORD );
1798
1799 pConvInfo->aConvContinue = CreateEPaM( aCurSel.Max() );
1800 }
1801
1802 pEditView->pImpEditView->DrawSelectionXOR();
1803 pEditView->pImpEditView->SetEditSelection( aCurSel );
1804 pEditView->pImpEditView->DrawSelectionXOR();
1805 pEditView->ShowCursor( true, false );
1806
1807 rConvTxt = aRes;
1808 if ( !rConvTxt.isEmpty() )
1809 rConvTxtLang = nResLang;
1810}
1811
1812
1813Reference< XSpellAlternatives > ImpEditEngine::ImpSpell( EditView* pEditView )
1814{
1815 DBG_ASSERT( xSpeller.is(), "No spell checker set!" );
1816
1817 ContentNode* pLastNode = aEditDoc.GetObject( aEditDoc.Count()-1 );
1818 EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
1819 aCurSel.Min() = aCurSel.Max();
1820
1821 Reference< XSpellAlternatives > xSpellAlt;
1822 Sequence< PropertyValue > aEmptySeq;
1823 while (!xSpellAlt.is())
1824 {
1825 // Known (most likely) bug: If SpellToCurrent, the current has to be
1826 // corrected at each replacement, otherwise it may not fit exactly in
1827 // the end ...
1828 if ( pSpellInfo->bSpellToEnd || pSpellInfo->bMultipleDoc )
1829 {
1830 if ( aCurSel.Max().GetNode() == pLastNode )
1831 {
1832 if ( aCurSel.Max().GetIndex() >= pLastNode->Len() )
1833 break;
1834 }
1835 }
1836 else if ( !pSpellInfo->bSpellToEnd )
1837 {
1838 EPaM aEPaM( CreateEPaM( aCurSel.Max() ) );
1839 if ( !( aEPaM < pSpellInfo->aSpellTo ) )
1840 break;
1841 }
1842
1843 aCurSel = SelectWord( aCurSel, css::i18n::WordType::DICTIONARY_WORD );
1844 OUString aWord = GetSelected( aCurSel );
1845
1846 // If afterwards a dot, this must be handed over!
1847 // If an abbreviation ...
1848 if ( !aWord.isEmpty() && ( aCurSel.Max().GetIndex() < aCurSel.Max().GetNode()->Len() ) )
1849 {
1850 sal_Unicode cNext = aCurSel.Max().GetNode()->GetChar( aCurSel.Max().GetIndex() );
1851 if ( cNext == '.' )
1852 {
1853 aCurSel.Max().SetIndex( aCurSel.Max().GetIndex()+1 );
1854 aWord += OUStringChar(cNext);
1855 }
1856 }
1857
1858 if ( !aWord.isEmpty() )
1859 {
1860 LanguageType eLang = GetLanguage( aCurSel.Max() ).nLang;
1862 xSpellAlt = xSpeller->spell( aWord, static_cast<sal_uInt16>(eLang), aEmptySeq );
1863 }
1864
1865 if ( !xSpellAlt.is() )
1866 aCurSel = WordRight( aCurSel.Min(), css::i18n::WordType::DICTIONARY_WORD );
1867 else
1869 }
1870
1871 pEditView->pImpEditView->DrawSelectionXOR();
1872 pEditView->pImpEditView->SetEditSelection( aCurSel );
1873 pEditView->pImpEditView->DrawSelectionXOR();
1874 pEditView->ShowCursor( true, false );
1875 return xSpellAlt;
1876}
1877
1878Reference< XSpellAlternatives > ImpEditEngine::ImpFindNextError(EditSelection& rSelection)
1879{
1880 EditSelection aCurSel( rSelection.Min() );
1881
1882 Reference< XSpellAlternatives > xSpellAlt;
1883 Sequence< PropertyValue > aEmptySeq;
1884 while (!xSpellAlt.is())
1885 {
1886 //check if the end of the selection has been reached
1887 {
1888 EPaM aEPaM( CreateEPaM( aCurSel.Max() ) );
1889 if ( !( aEPaM < CreateEPaM( rSelection.Max()) ) )
1890 break;
1891 }
1892
1893 aCurSel = SelectWord( aCurSel, css::i18n::WordType::DICTIONARY_WORD );
1894 OUString aWord = GetSelected( aCurSel );
1895
1896 // If afterwards a dot, this must be handed over!
1897 // If an abbreviation ...
1898 if ( !aWord.isEmpty() && ( aCurSel.Max().GetIndex() < aCurSel.Max().GetNode()->Len() ) )
1899 {
1900 sal_Unicode cNext = aCurSel.Max().GetNode()->GetChar( aCurSel.Max().GetIndex() );
1901 if ( cNext == '.' )
1902 {
1903 aCurSel.Max().SetIndex( aCurSel.Max().GetIndex()+1 );
1904 aWord += OUStringChar(cNext);
1905 }
1906 }
1907
1908 if ( !aWord.isEmpty() )
1909 xSpellAlt = xSpeller->spell( aWord, static_cast<sal_uInt16>(GetLanguage( aCurSel.Max() ).nLang), aEmptySeq );
1910
1911 if ( !xSpellAlt.is() )
1912 aCurSel = WordRight( aCurSel.Min(), css::i18n::WordType::DICTIONARY_WORD );
1913 else
1914 {
1916 rSelection = aCurSel;
1917 }
1918 }
1919 return xSpellAlt;
1920}
1921
1923 svx::SpellPortions& rToFill )
1924{
1925 bool bRet = false;
1926 EditSelection aCurSel( rEditView.pImpEditView->GetEditSelection() );
1927 if(!pSpellInfo)
1928 CreateSpellInfo( true );
1929 pSpellInfo->aCurSentenceStart = aCurSel.Min();
1930 DBG_ASSERT( xSpeller.is(), "No spell checker set!" );
1931 pSpellInfo->aLastSpellPortions.clear();
1932 pSpellInfo->aLastSpellContentSelections.clear();
1933 rToFill.clear();
1934 //if no selection previously exists the range is extended to the end of the object
1935 if (!aCurSel.HasRange())
1936 {
1937 ContentNode* pLastNode = aEditDoc.GetObject( aEditDoc.Count()-1);
1938 aCurSel.Max() = EditPaM(pLastNode, pLastNode->Len());
1939 }
1940 // check for next error in aCurSel and set aCurSel to that one if any was found
1941 Reference< XSpellAlternatives > xAlt = ImpFindNextError(aCurSel);
1942 if (xAlt.is())
1943 {
1944 bRet = true;
1945 //find the sentence boundaries
1946 EditSelection aSentencePaM = SelectSentence(aCurSel);
1947 //make sure that the sentence is never smaller than the error range!
1948 if(aSentencePaM.Max().GetIndex() < aCurSel.Max().GetIndex())
1949 aSentencePaM.Max() = aCurSel.Max();
1950 //add the portion preceding the error
1951 EditSelection aStartSelection(aSentencePaM.Min(), aCurSel.Min());
1952 if(aStartSelection.HasRange())
1953 AddPortionIterated(rEditView, aStartSelection, nullptr, rToFill);
1954 //add the error portion
1955 AddPortionIterated(rEditView, aCurSel, xAlt, rToFill);
1956 //find the end of the sentence
1957 //search for all errors in the rest of the sentence and add all the portions
1958 do
1959 {
1960 EditSelection aNextSel(aCurSel.Max(), aSentencePaM.Max());
1961 xAlt = ImpFindNextError(aNextSel);
1962 if(xAlt.is())
1963 {
1964 //add the part between the previous and the current error
1965 AddPortionIterated(rEditView, EditSelection(aCurSel.Max(), aNextSel.Min()), nullptr, rToFill);
1966 //add the current error
1967 AddPortionIterated(rEditView, aNextSel, xAlt, rToFill);
1968 }
1969 else
1970 AddPortionIterated(rEditView, EditSelection(aCurSel.Max(), aSentencePaM.Max()), xAlt, rToFill);
1971 aCurSel = aNextSel;
1972 }
1973 while( xAlt.is() );
1974
1975 //set the selection to the end of the current sentence
1976 rEditView.pImpEditView->SetEditSelection(aSentencePaM.Max());
1977 }
1978 return bRet;
1979}
1980
1981// Adds one portion to the SpellPortions
1983 const EditSelection& rSel,
1984 const uno::Reference< XSpellAlternatives >& xAlt,
1985 svx::SpellPortions& rToFill,
1986 bool bIsField)
1987{
1988 if(!rSel.HasRange())
1989 return;
1990
1991 svx::SpellPortion aPortion;
1992 aPortion.sText = GetSelected( rSel );
1993 aPortion.eLanguage = GetLanguage( rSel.Min() ).nLang;
1994 aPortion.xAlternatives = xAlt;
1995 aPortion.bIsField = bIsField;
1996 rToFill.push_back(aPortion);
1997
1998 //save the spelled portions for later use
1999 pSpellInfo->aLastSpellPortions.push_back(aPortion);
2000 pSpellInfo->aLastSpellContentSelections.push_back(rSel);
2001}
2002
2003// Adds one or more portions of text to the SpellPortions depending on language changes
2005 EditView const & rEditView,
2006 const EditSelection& rSel,
2007 const Reference< XSpellAlternatives >& xAlt,
2008 svx::SpellPortions& rToFill)
2009{
2010 if (!rSel.HasRange())
2011 return;
2012
2013 if(xAlt.is())
2014 {
2015 AddPortion(rSel, xAlt, rToFill, false);
2016 }
2017 else
2018 {
2019 //iterate and search for language attribute changes
2020 //save the start and end positions
2021 bool bTest = rSel.Min().GetIndex() <= rSel.Max().GetIndex();
2022 EditPaM aStart(bTest ? rSel.Min() : rSel.Max());
2023 EditPaM aEnd(bTest ? rSel.Max() : rSel.Min());
2024 //iterate over the text to find changes in language
2025 //set the mark equal to the point
2026 EditPaM aCursor(aStart);
2027 rEditView.pImpEditView->SetEditSelection( aCursor );
2028 LanguageType eStartLanguage = GetLanguage( aCursor ).nLang;
2029 //search for a field attribute at the beginning - only the end position
2030 //of this field is kept to end a portion at that position
2031 const EditCharAttrib* pFieldAttr = aCursor.GetNode()->GetCharAttribs().
2032 FindFeature( aCursor.GetIndex() );
2033 bool bIsField = pFieldAttr &&
2034 pFieldAttr->GetStart() == aCursor.GetIndex() &&
2035 pFieldAttr->GetStart() != pFieldAttr->GetEnd() &&
2036 pFieldAttr->Which() == EE_FEATURE_FIELD;
2037 sal_Int32 nEndField = bIsField ? pFieldAttr->GetEnd() : -1;
2038 do
2039 {
2040 aCursor = CursorRight( aCursor);
2041 //determine whether a field and has been reached
2042 bool bIsEndField = nEndField == aCursor.GetIndex();
2043 //search for a new field attribute
2044 const EditCharAttrib* _pFieldAttr = aCursor.GetNode()->GetCharAttribs().
2045 FindFeature( aCursor.GetIndex() );
2046 bIsField = _pFieldAttr &&
2047 _pFieldAttr->GetStart() == aCursor.GetIndex() &&
2048 _pFieldAttr->GetStart() != _pFieldAttr->GetEnd() &&
2049 _pFieldAttr->Which() == EE_FEATURE_FIELD;
2050 //on every new field move the end position
2051 if (bIsField)
2052 nEndField = _pFieldAttr->GetEnd();
2053
2054 LanguageType eCurLanguage = GetLanguage( aCursor ).nLang;
2055 if(eCurLanguage != eStartLanguage || bIsField || bIsEndField)
2056 {
2057 eStartLanguage = eCurLanguage;
2058 //go one step back - the cursor currently selects the first character
2059 //with a different language
2060 //create a selection from start to the current Cursor
2061 EditSelection aSelection(aStart, aCursor);
2062 AddPortion(aSelection, xAlt, rToFill, bIsEndField);
2063 aStart = aCursor;
2064 }
2065 }
2066 while(aCursor.GetIndex() < aEnd.GetIndex());
2067 EditSelection aSelection(aStart, aCursor);
2068 AddPortion(aSelection, xAlt, rToFill, bIsField);
2069 }
2070}
2071
2073 const svx::SpellPortions& rNewPortions,
2074 bool bRecheck )
2075{
2076 // Note: rNewPortions.size() == 0 is valid and happens when the whole
2077 // sentence got removed in the dialog
2078
2079 DBG_ASSERT(pSpellInfo, "pSpellInfo not initialized");
2080 if (!pSpellInfo || pSpellInfo->aLastSpellPortions.empty()) // no portions -> no text to be changed
2081 return;
2082
2083 // get current paragraph length to calculate later on how the sentence length changed,
2084 // in order to place the cursor at the end of the sentence again
2085 EditSelection aOldSel( rEditView.pImpEditView->GetEditSelection() );
2086 sal_Int32 nOldLen = aOldSel.Max().GetNode()->Len();
2087
2089 if(pSpellInfo->aLastSpellPortions.size() == rNewPortions.size())
2090 {
2091 DBG_ASSERT( !rNewPortions.empty(), "rNewPortions should not be empty here" );
2092 DBG_ASSERT( pSpellInfo->aLastSpellPortions.size() == pSpellInfo->aLastSpellContentSelections.size(),
2093 "aLastSpellPortions and aLastSpellContentSelections size mismatch" );
2094
2095 //the simple case: the same number of elements on both sides
2096 //each changed element has to be applied to the corresponding source element
2097 svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.end();
2098 svx::SpellPortions::const_iterator aCurrentOldPortion = pSpellInfo->aLastSpellPortions.end();
2099 SpellContentSelections::const_iterator aCurrentOldPosition = pSpellInfo->aLastSpellContentSelections.end();
2100 bool bSetToEnd = false;
2101 do
2102 {
2103 --aCurrentNewPortion;
2104 --aCurrentOldPortion;
2105 --aCurrentOldPosition;
2106 //set the cursor to the end of the sentence - necessary to
2107 //resume there at the next step
2108 if(!bSetToEnd)
2109 {
2110 bSetToEnd = true;
2111 rEditView.pImpEditView->SetEditSelection( aCurrentOldPosition->Max() );
2112 }
2113
2114 SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( aCurrentNewPortion->eLanguage );
2115 sal_uInt16 nLangWhichId = EE_CHAR_LANGUAGE;
2116 switch(nScriptType)
2117 {
2118 case SvtScriptType::ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
2119 case SvtScriptType::COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
2120 default: break;
2121 }
2122 if(aCurrentNewPortion->sText != aCurrentOldPortion->sText)
2123 {
2124 //change text and apply language
2125 SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId );
2126 aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
2127 SetAttribs( *aCurrentOldPosition, aSet );
2128 ImpInsertText( *aCurrentOldPosition, aCurrentNewPortion->sText );
2129 }
2130 else if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
2131 {
2132 //apply language
2133 SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
2134 aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
2135 SetAttribs( *aCurrentOldPosition, aSet );
2136 }
2137 }
2138 while(aCurrentNewPortion != rNewPortions.begin());
2139 }
2140 else
2141 {
2142 DBG_ASSERT( !pSpellInfo->aLastSpellContentSelections.empty(), "aLastSpellContentSelections should not be empty here" );
2143
2144 //select the complete sentence
2145 SpellContentSelections::const_iterator aCurrentEndPosition = pSpellInfo->aLastSpellContentSelections.end();
2146 --aCurrentEndPosition;
2147 SpellContentSelections::const_iterator aCurrentStartPosition = pSpellInfo->aLastSpellContentSelections.begin();
2148 EditSelection aAllSentence(aCurrentStartPosition->Min(), aCurrentEndPosition->Max());
2149
2150 //delete the sentence completely
2151 ImpDeleteSelection( aAllSentence );
2152 EditPaM aCurrentPaM = aAllSentence.Min();
2153 for(const auto& rCurrentNewPortion : rNewPortions)
2154 {
2155 //set the language attribute
2156 LanguageType eCurLanguage = GetLanguage( aCurrentPaM ).nLang;
2157 if(eCurLanguage != rCurrentNewPortion.eLanguage)
2158 {
2159 SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( rCurrentNewPortion.eLanguage );
2160 sal_uInt16 nLangWhichId = EE_CHAR_LANGUAGE;
2161 switch(nScriptType)
2162 {
2163 case SvtScriptType::ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
2164 case SvtScriptType::COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
2165 default: break;
2166 }
2167 SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
2168 aSet.Put(SvxLanguageItem(rCurrentNewPortion.eLanguage, nLangWhichId));
2169 SetAttribs( aCurrentPaM, aSet );
2170 }
2171 //insert the new string and set the cursor to the end of the inserted string
2172 aCurrentPaM = ImpInsertText( aCurrentPaM , rCurrentNewPortion.sText );
2173 }
2174 }
2175 UndoActionEnd();
2176
2177 EditPaM aNext;
2178 if (bRecheck)
2179 aNext = pSpellInfo->aCurSentenceStart;
2180 else
2181 {
2182 // restore cursor position to the end of the modified sentence.
2183 // (This will define the continuation position for spell/grammar checking)
2184 // First: check if the sentence/para length changed
2185 const sal_Int32 nDelta = rEditView.pImpEditView->GetEditSelection().Max().GetNode()->Len() - nOldLen;
2186 const sal_Int32 nEndOfSentence = aOldSel.Max().GetIndex() + nDelta;
2187 aNext = EditPaM( aOldSel.Max().GetNode(), nEndOfSentence );
2188 }
2189 rEditView.pImpEditView->SetEditSelection( aNext );
2190
2191 if (IsUpdateLayout())
2193 aEditDoc.SetModified(true);
2194}
2195
2197{
2198 if( pSpellInfo && !pSpellInfo->aLastSpellContentSelections.empty() )
2199 {
2200 rEditView.pImpEditView->SetEditSelection( pSpellInfo->aLastSpellContentSelections.begin()->Min() );
2201 }
2202}
2203
2204
2205void ImpEditEngine::DoOnlineSpelling( ContentNode* pThisNodeOnly, bool bSpellAtCursorPos, bool bInterruptible )
2206{
2207 /*
2208 It will iterate over all the paragraphs, paragraphs with only
2209 invalidated wrong list will be checked ...
2210
2211 All the words are checked in the invalidated region. Is a word wrong,
2212 but not in the wrong list, or vice versa, the range of the word will be
2213 invalidated
2214 (no Invalidate, but if only transitions wrong from right =>, simple Paint,
2215 even out properly with VDev on transitions from wrong => right)
2216 */
2217
2218 if ( !xSpeller.is() )
2219 return;
2220
2221 EditPaM aCursorPos;
2222 if( pActiveView && !bSpellAtCursorPos )
2223 {
2224 aCursorPos = pActiveView->pImpEditView->GetEditSelection().Max();
2225 }
2226
2227 bool bRestartTimer = false;
2228
2229 ContentNode* pLastNode = aEditDoc.GetObject( aEditDoc.Count() - 1 );
2230 sal_Int32 nNodes = GetEditDoc().Count();
2231 sal_Int32 nInvalids = 0;
2232 Sequence< PropertyValue > aEmptySeq;
2233 for ( sal_Int32 n = 0; n < nNodes; n++ )
2234 {
2235 ContentNode* pNode = GetEditDoc().GetObject( n );
2236 if ( pThisNodeOnly )
2237 pNode = pThisNodeOnly;
2238
2239 pNode->EnsureWrongList();
2240 if (!pNode->GetWrongList()->IsValid())
2241 {
2242 WrongList* pWrongList = pNode->GetWrongList();
2243 const size_t nInvStart = pWrongList->GetInvalidStart();
2244 const size_t nInvEnd = pWrongList->GetInvalidEnd();
2245
2246 sal_Int32 nPaintFrom = -1;
2247 sal_Int32 nPaintTo = 0;
2248 bool bSimpleRepaint = true;
2249
2250 pWrongList->SetValid();
2251
2252 EditPaM aPaM( pNode, nInvStart );
2253 EditSelection aSel( aPaM, aPaM );
2254 while ( aSel.Max().GetNode() == pNode )
2255 {
2256 if ( ( o3tl::make_unsigned(aSel.Min().GetIndex()) > nInvEnd )
2257 || ( ( aSel.Max().GetNode() == pLastNode ) && ( aSel.Max().GetIndex() >= pLastNode->Len() ) ) )
2258 break; // Document end or end of invalid region
2259
2260 aSel = SelectWord( aSel, i18n::WordType::DICTIONARY_WORD );
2261 // If afterwards a dot, this must be handed over!
2262 // If an abbreviation ...
2263 bool bDottAdded = false;
2264 if ( aSel.Max().GetIndex() < aSel.Max().GetNode()->Len() )
2265 {
2266 sal_Unicode cNext = aSel.Max().GetNode()->GetChar( aSel.Max().GetIndex() );
2267 if ( cNext == '.' )
2268 {
2269 aSel.Max().SetIndex( aSel.Max().GetIndex()+1 );
2270 bDottAdded = true;
2271 }
2272 }
2273 OUString aWord = GetSelected(aSel);
2274
2275 bool bChanged = false;
2276 if (!aWord.isEmpty())
2277 {
2278 const sal_Int32 nWStart = aSel.Min().GetIndex();
2279 const sal_Int32 nWEnd = aSel.Max().GetIndex();
2280 if ( !xSpeller->isValid( aWord, static_cast<sal_uInt16>(GetLanguage( EditPaM( aSel.Min().GetNode(), nWStart+1 ) ).nLang), aEmptySeq ) )
2281 {
2282 // Check if already marked correctly...
2283 const sal_Int32 nXEnd = bDottAdded ? nWEnd -1 : nWEnd;
2284 if ( !pWrongList->HasWrong( nWStart, nXEnd ) )
2285 {
2286 // Mark Word as wrong...
2287 // But only when not at Cursor-Position...
2288 bool bCursorPos = false;
2289 if ( aCursorPos.GetNode() == pNode )
2290 {
2291 if ( ( nWStart <= aCursorPos.GetIndex() ) && nWEnd >= aCursorPos.GetIndex() )
2292 bCursorPos = true;
2293 }
2294 if ( bCursorPos )
2295 {
2296 // Then continue to mark as invalid ...
2297 pWrongList->ResetInvalidRange(nWStart, nWEnd);
2298 bRestartTimer = true;
2299 }
2300 else
2301 {
2302 // It may be that the Wrongs in the list are not
2303 // spanning exactly over words because the
2304 // WordDelimiters during expansion are not
2305 // evaluated.
2306 pWrongList->InsertWrong(nWStart, nXEnd);
2307 bChanged = true;
2308 }
2309 }
2310 }
2311 else
2312 {
2313 // Check if not marked as wrong
2314 if ( pWrongList->HasAnyWrong( nWStart, nWEnd ) )
2315 {
2316 pWrongList->ClearWrongs( nWStart, nWEnd, pNode );
2317 bSimpleRepaint = false;
2318 bChanged = true;
2319 }
2320 }
2321 if ( bChanged )
2322 {
2323 if ( nPaintFrom<0 )
2324 nPaintFrom = nWStart;
2325 nPaintTo = nWEnd;
2326 }
2327 }
2328
2329 EditPaM aLastEnd( aSel.Max() );
2330 aSel = WordRight( aSel.Max(), i18n::WordType::DICTIONARY_WORD );
2331 if ( bChanged && ( aSel.Min().GetNode() == pNode ) &&
2332 ( aSel.Min().GetIndex()-aLastEnd.GetIndex() > 1 ) )
2333 {
2334 // If two words are separated by more than one blank, it
2335 // can happen that when splitting a Wrongs the start of
2336 // the second word is before the actually word
2337 pWrongList->ClearWrongs( aLastEnd.GetIndex(), aSel.Min().GetIndex(), pNode );
2338 }
2339 }
2340
2341 // Invalidate?
2342 if ( nPaintFrom>=0 )
2343 {
2345 CallStatusHdl();
2346
2347 if (!aEditViews.empty())
2348 {
2349 // For SimpleRepaint one was painted over a range without
2350 // reaching VDEV, but then one would have to intersect, c
2351 // clipping, ... over all views. Probably not worthwhile.
2352 EditPaM aStartPaM( pNode, nPaintFrom );
2353 EditPaM aEndPaM( pNode, nPaintTo );
2354 tools::Rectangle aStartCursor( PaMtoEditCursor( aStartPaM ) );
2355 tools::Rectangle aEndCursor( PaMtoEditCursor( aEndPaM ) );
2356 DBG_ASSERT( aInvalidRect.IsEmpty(), "InvalidRect set!" );
2357 aInvalidRect.SetLeft( 0 );
2359 aInvalidRect.SetTop( aStartCursor.Top() );
2360 aInvalidRect.SetBottom( aEndCursor.Bottom() );
2362 {
2363 // Then no output through VDev.
2364 UpdateViews();
2365 }
2366 else if ( bSimpleRepaint )
2367 {
2368 for (EditView* pView : aEditViews)
2369 {
2370 tools::Rectangle aClipRect( aInvalidRect );
2371 aClipRect.Intersection( pView->GetVisArea() );
2372 if ( !aClipRect.IsEmpty() )
2373 {
2374 // convert to window coordinates...
2375 aClipRect.SetPos( pView->pImpEditView->GetWindowPos( aClipRect.TopLeft() ) );
2376 pView->pImpEditView->InvalidateAtWindow(aClipRect);
2377 }
2378 }
2379 }
2380 else
2381 {
2383 }
2385 }
2386 }
2387 // After two corrected nodes give up the control...
2388 nInvalids++;
2389 if ( bInterruptible && ( nInvalids >= 2 ) )
2390 {
2391 bRestartTimer = true;
2392 break;
2393 }
2394 }
2395
2396 if ( pThisNodeOnly )
2397 break;
2398 }
2399 if ( bRestartTimer )
2401}
2402
2403
2405{
2406 DBG_ASSERT( xSpeller.is(), "No spell checker set!" );
2407
2408 ContentNode* pLastNode = aEditDoc.GetObject( aEditDoc.Count() - 1 );
2409 EditSelection aCurSel( aEditDoc.GetStartPaM() );
2410
2411 OUString aWord;
2412 Reference< XSpellAlternatives > xSpellAlt;
2413 Sequence< PropertyValue > aEmptySeq;
2414 while ( !xSpellAlt.is() )
2415 {
2416 if ( ( aCurSel.Max().GetNode() == pLastNode ) &&
2417 ( aCurSel.Max().GetIndex() >= pLastNode->Len() ) )
2418 {
2419 return EESpellState::Ok;
2420 }
2421
2422 aCurSel = SelectWord( aCurSel, css::i18n::WordType::DICTIONARY_WORD );
2423 aWord = GetSelected( aCurSel );
2424 if ( !aWord.isEmpty() )
2425 {
2426 LanguageType eLang = GetLanguage( aCurSel.Max() ).nLang;
2428 xSpellAlt = xSpeller->spell( aWord, static_cast<sal_uInt16>(eLang), aEmptySeq );
2429 }
2430 aCurSel = WordRight( aCurSel.Max(), css::i18n::WordType::DICTIONARY_WORD );
2431 }
2432
2434}
2435
2437{
2439}
2440
2442{
2443 EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
2444 if ( !aCurSel.HasRange() )
2445 aCurSel = SelectWord( aCurSel, css::i18n::WordType::DICTIONARY_WORD );
2446 OUString aWord( GetSelected( aCurSel ) );
2447
2448 Reference< XThesaurus > xThes( LinguMgr::GetThesaurus() );
2449 if (!xThes.is())
2451
2453 ScopedVclPtr<AbstractThesaurusDialog> xDlg(pFact->CreateThesaurusDialog(pDialogParent, xThes,
2454 aWord, GetLanguage( aCurSel.Max() ).nLang ));
2455 if (xDlg->Execute() == RET_OK)
2456 {
2457 // Replace Word...
2458 pEditView->pImpEditView->DrawSelectionXOR();
2459 pEditView->pImpEditView->SetEditSelection( aCurSel );
2460 pEditView->pImpEditView->DrawSelectionXOR();
2461 pEditView->InsertText(xDlg->GetWord());
2462 pEditView->ShowCursor(true, false);
2463 }
2464
2465 return EESpellState::Ok;
2466}
2467
2468sal_Int32 ImpEditEngine::StartSearchAndReplace( EditView* pEditView, const SvxSearchItem& rSearchItem )
2469{
2470 sal_Int32 nFound = 0;
2471
2472 EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
2473
2474 // FIND_ALL is not possible without multiple selection.
2475 if ( ( rSearchItem.GetCommand() == SvxSearchCmd::FIND ) ||
2476 ( rSearchItem.GetCommand() == SvxSearchCmd::FIND_ALL ) )
2477 {
2478 if ( Search( rSearchItem, pEditView ) )
2479 nFound++;
2480 }
2481 else if ( rSearchItem.GetCommand() == SvxSearchCmd::REPLACE )
2482 {
2483 // The word is selected if the user not altered the selection
2484 // in between:
2485 if ( aCurSel.HasRange() )
2486 {
2487 pEditView->InsertText( rSearchItem.GetReplaceString() );
2488 nFound = 1;
2489 }
2490 else
2491 if( Search( rSearchItem, pEditView ) )
2492 nFound = 1;
2493 }
2494 else if ( rSearchItem.GetCommand() == SvxSearchCmd::REPLACE_ALL )
2495 {
2496 // The Writer replaces all front beginning to end ...
2497 SvxSearchItem aTmpItem( rSearchItem );
2498 aTmpItem.SetBackward( false );
2499
2500 pEditView->pImpEditView->DrawSelectionXOR();
2501
2502 aCurSel.Adjust( aEditDoc );
2503 EditPaM aStartPaM = aTmpItem.GetSelection() ? aCurSel.Min() : aEditDoc.GetStartPaM();
2504 EditSelection aFoundSel( aCurSel.Max() );
2505 bool bFound = ImpSearch( aTmpItem, aCurSel, aStartPaM, aFoundSel );
2506 if ( bFound )
2508 while ( bFound )
2509 {
2510 nFound++;
2511 aStartPaM = ImpInsertText( aFoundSel, rSearchItem.GetReplaceString() );
2512 bFound = ImpSearch( aTmpItem, aCurSel, aStartPaM, aFoundSel );
2513 }
2514 if ( nFound )
2515 {
2516 EditPaM aNewPaM( aFoundSel.Max() );
2517 if ( aNewPaM.GetIndex() > aNewPaM.GetNode()->Len() )
2518 aNewPaM.SetIndex( aNewPaM.GetNode()->Len() );
2519 pEditView->pImpEditView->SetEditSelection( aNewPaM );
2520 FormatAndLayout( pEditView );
2521 UndoActionEnd();
2522 }
2523 else
2524 {
2525 pEditView->pImpEditView->DrawSelectionXOR();
2526 pEditView->ShowCursor( true, false );
2527 }
2528 }
2529 return nFound;
2530}
2531
2532bool ImpEditEngine::Search( const SvxSearchItem& rSearchItem, EditView* pEditView )
2533{
2534 EditSelection aSel( pEditView->pImpEditView->GetEditSelection() );
2535 aSel.Adjust( aEditDoc );
2536 EditPaM aStartPaM( aSel.Max() );
2537 if ( rSearchItem.GetSelection() && !rSearchItem.GetBackward() )
2538 aStartPaM = aSel.Min();
2539
2540 EditSelection aFoundSel;
2541 bool bFound = ImpSearch( rSearchItem, aSel, aStartPaM, aFoundSel );
2542 if ( bFound && ( aFoundSel == aSel ) ) // For backwards-search
2543 {
2544 aStartPaM = aSel.Min();
2545 bFound = ImpSearch( rSearchItem, aSel, aStartPaM, aFoundSel );
2546 }
2547
2548 pEditView->pImpEditView->DrawSelectionXOR();
2549 if ( bFound )
2550 {
2551 // First, set the minimum, so the whole word is in the visible range.
2552 pEditView->pImpEditView->SetEditSelection( aFoundSel.Min() );
2553 pEditView->ShowCursor( true, false );
2554 pEditView->pImpEditView->SetEditSelection( aFoundSel );
2555 }
2556 else
2557 pEditView->pImpEditView->SetEditSelection( aSel.Max() );
2558
2559 pEditView->pImpEditView->DrawSelectionXOR();
2560 pEditView->ShowCursor( true, false );
2561 return bFound;
2562}
2563
2565 const EditSelection& rSearchSelection, const EditPaM& rStartPos, EditSelection& rFoundSel )
2566{
2567 i18nutil::SearchOptions2 aSearchOptions( rSearchItem.GetSearchOptions() );
2568 aSearchOptions.Locale = GetLocale( rStartPos );
2569
2570 bool bBack = rSearchItem.GetBackward();
2571 bool bSearchInSelection = rSearchItem.GetSelection();
2572 sal_Int32 nStartNode = aEditDoc.GetPos( rStartPos.GetNode() );
2573 sal_Int32 nEndNode;
2574 if ( bSearchInSelection )
2575 {
2576 nEndNode = aEditDoc.GetPos( bBack ? rSearchSelection.Min().GetNode() : rSearchSelection.Max().GetNode() );
2577 }
2578 else
2579 {
2580 nEndNode = bBack ? 0 : aEditDoc.Count()-1;
2581 }
2582
2583 utl::TextSearch aSearcher( aSearchOptions );
2584
2585 // iterate over the paragraphs ...
2586 for ( sal_Int32 nNode = nStartNode;
2587 bBack ? ( nNode >= nEndNode ) : ( nNode <= nEndNode) ;
2588 bBack ? nNode-- : nNode++ )
2589 {
2590 // For backwards-search if nEndNode = 0:
2591 if ( nNode < 0 )
2592 return false;
2593
2594 ContentNode* pNode = aEditDoc.GetObject( nNode );
2595
2596 sal_Int32 nStartPos = 0;
2597 sal_Int32 nEndPos = pNode->GetExpandedLen();
2598 if ( nNode == nStartNode )
2599 {
2600 if ( bBack )
2601 nEndPos = rStartPos.GetIndex();
2602 else
2603 nStartPos = rStartPos.GetIndex();
2604 }
2605 if ( ( nNode == nEndNode ) && bSearchInSelection )
2606 {
2607 if ( bBack )
2608 nStartPos = rSearchSelection.Min().GetIndex();
2609 else
2610 nEndPos = rSearchSelection.Max().GetIndex();
2611 }
2612
2613 // Searching ...
2614 OUString aParaStr( pNode->GetExpandedText() );
2615 bool bFound = false;
2616 if ( bBack )
2617 {
2618 sal_Int32 nTemp;
2619 nTemp = nStartPos;
2620 nStartPos = nEndPos;
2621 nEndPos = nTemp;
2622
2623 bFound = aSearcher.SearchBackward( aParaStr, &nStartPos, &nEndPos);
2624 }
2625 else
2626 {
2627 bFound = aSearcher.SearchForward( aParaStr, &nStartPos, &nEndPos);
2628 }
2629 if ( bFound )
2630 {
2631 pNode->UnExpandPositions( nStartPos, nEndPos );
2632
2633 rFoundSel.Min().SetNode( pNode );
2634 rFoundSel.Min().SetIndex( nStartPos );
2635 rFoundSel.Max().SetNode( pNode );
2636 rFoundSel.Max().SetIndex( nEndPos );
2637 return true;
2638 }
2639 }
2640 return false;
2641}
2642
2643bool ImpEditEngine::HasText( const SvxSearchItem& rSearchItem )
2644{
2645 SvxSearchItem aTmpItem( rSearchItem );
2646 aTmpItem.SetBackward( false );
2647 aTmpItem.SetSelection( false );
2648
2649 EditPaM aStartPaM( aEditDoc.GetStartPaM() );
2650 EditSelection aDummySel( aStartPaM );
2651 EditSelection aFoundSel;
2652 return ImpSearch( aTmpItem, aDummySel, aStartPaM, aFoundSel );
2653}
2654
2655void ImpEditEngine::SetAutoCompleteText(const OUString& rStr, bool bClearTipWindow)
2656{
2657 aAutoCompleteText = rStr;
2658 if ( bClearTipWindow && pActiveView )
2660}
2661
2662namespace
2663{
2664 struct eeTransliterationChgData
2665 {
2666 sal_Int32 nStart;
2667 sal_Int32 nLen;
2668 EditSelection aSelection;
2669 OUString aNewText;
2670 uno::Sequence< sal_Int32 > aOffsets;
2671 };
2672}
2673
2675{
2676 uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
2677 if (!_xBI.is())
2678 return rSelection;
2679
2680 EditSelection aSel( rSelection );
2681 aSel.Adjust( aEditDoc );
2682
2683 if ( !aSel.HasRange() )
2684 {
2685 /* Cursor is inside of a word */
2686 if (nTransliterationMode == TransliterationFlags::SENTENCE_CASE)
2687 aSel = SelectSentence( aSel );
2688 else
2689 aSel = SelectWord( aSel );
2690 }
2691
2692 // tdf#107176: if there's still no range, just return aSel
2693 if ( !aSel.HasRange() )
2694 return aSel;
2695
2696 EditSelection aNewSel( aSel );
2697
2698 const sal_Int32 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
2699 const sal_Int32 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
2700
2701 bool bChanges = false;
2702 bool bLenChanged = false;
2703 std::unique_ptr<EditUndoTransliteration> pUndo;
2704
2705 utl::TransliterationWrapper aTransliterationWrapper( ::comphelper::getProcessComponentContext(), nTransliterationMode );
2706 bool bConsiderLanguage = aTransliterationWrapper.needLanguageForTheMode();
2707
2708 for ( sal_Int32 nNode = nStartNode; nNode <= nEndNode; nNode++ )
2709 {
2710 ContentNode* pNode = aEditDoc.GetObject( nNode );
2711 const OUString& aNodeStr = pNode->GetString();
2712 const sal_Int32 nStartPos = nNode==nStartNode ? aSel.Min().GetIndex() : 0;
2713 const sal_Int32 nEndPos = nNode==nEndNode ? aSel.Max().GetIndex() : aNodeStr.getLength(); // can also be == nStart!
2714
2715 sal_Int32 nCurrentStart = nStartPos;
2716 sal_Int32 nCurrentEnd = nEndPos;
2717 LanguageType nLanguage = LANGUAGE_SYSTEM;
2718
2719 // since we don't use Hiragana/Katakana or half-width/full-width transliterations here
2720 // it is fine to use ANYWORD_IGNOREWHITESPACES. (ANY_WORD btw is broken and will
2721 // occasionally miss words in consecutive sentences). Also with ANYWORD_IGNOREWHITESPACES
2722 // text like 'just-in-time' will be converted to 'Just-In-Time' which seems to be the
2723 // proper thing to do.
2724 const sal_Int16 nWordType = i18n::WordType::ANYWORD_IGNOREWHITESPACES;
2725
2732 std::vector< eeTransliterationChgData > aChanges;
2733 eeTransliterationChgData aChgData;
2734
2735 if (nTransliterationMode == TransliterationFlags::TITLE_CASE)
2736 {
2737 // for 'capitalize every word' we need to iterate over each word
2738
2739 i18n::Boundary aSttBndry;
2740 i18n::Boundary aEndBndry;
2741 aSttBndry = _xBI->getWordBoundary(
2742 aNodeStr, nStartPos,
2743 GetLocale( EditPaM( pNode, nStartPos + 1 ) ),
2744 nWordType, true /*prefer forward direction*/);
2745 aEndBndry = _xBI->getWordBoundary(
2746 aNodeStr, nEndPos,
2747 GetLocale( EditPaM( pNode, nEndPos + 1 ) ),
2748 nWordType, false /*prefer backward direction*/);
2749
2750 // prevent backtracking to the previous word if selection is at word boundary
2751 if (aSttBndry.endPos <= nStartPos)
2752 {
2753 aSttBndry = _xBI->nextWord(
2754 aNodeStr, aSttBndry.endPos,
2755 GetLocale( EditPaM( pNode, aSttBndry.endPos + 1 ) ),
2756 nWordType);
2757 }
2758 // prevent advancing to the next word if selection is at word boundary
2759 if (aEndBndry.startPos >= nEndPos)
2760 {
2761 aEndBndry = _xBI->previousWord(
2762 aNodeStr, aEndBndry.startPos,
2763 GetLocale( EditPaM( pNode, aEndBndry.startPos + 1 ) ),
2764 nWordType);
2765 }
2766
2767 /* Nothing to do if user selection lies entirely outside of word start and end boundary computed above.
2768 * Skip this node, because otherwise the below logic for constraining to the selection will fail */
2769 if (aSttBndry.startPos >= aSel.Max().GetIndex() || aEndBndry.endPos <= aSel.Min().GetIndex()) {
2770 continue;
2771 }
2772
2773 // prevent going outside of the user's selection, which may
2774 // start or end in the middle of a word
2775 if (nNode == nStartNode) {
2776 aSttBndry.startPos = std::max(aSttBndry.startPos, aSel.Min().GetIndex());
2777 aSttBndry.endPos = std::min(aSttBndry.endPos, aSel.Max().GetIndex());
2778 aEndBndry.startPos = std::max(aEndBndry.startPos, aSttBndry.startPos);
2779 aEndBndry.endPos = std::min(aEndBndry.endPos, aSel.Max().GetIndex());
2780 }
2781
2782 i18n::Boundary aCurWordBndry( aSttBndry );
2783 while (aCurWordBndry.endPos && aCurWordBndry.startPos <= aEndBndry.startPos)
2784 {
2785 nCurrentStart = aCurWordBndry.startPos;
2786 nCurrentEnd = aCurWordBndry.endPos;
2787 sal_Int32 nLen = nCurrentEnd - nCurrentStart;
2788 DBG_ASSERT( nLen > 0, "invalid word length of 0" );
2789
2790 Sequence< sal_Int32 > aOffsets;
2791 OUString aNewText( aTransliterationWrapper.transliterate(aNodeStr,
2792 GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ).nLang,
2793 nCurrentStart, nLen, &aOffsets ));
2794
2795 if (aNodeStr != aNewText)
2796 {
2797 aChgData.nStart = nCurrentStart;
2798 aChgData.nLen = nLen;
2799 aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) );
2800 aChgData.aNewText = aNewText;
2801 aChgData.aOffsets = aOffsets;
2802 aChanges.push_back( aChgData );
2803 }
2804#if OSL_DEBUG_LEVEL > 1
2805 OUString aSelTxt ( GetSelected( aChgData.aSelection ) );
2806 (void) aSelTxt;
2807#endif
2808
2809 aCurWordBndry = _xBI->nextWord(aNodeStr, nCurrentStart,
2810 GetLocale( EditPaM( pNode, nCurrentStart + 1 ) ),
2811 nWordType);
2812 }
2813 DBG_ASSERT( nCurrentEnd >= aEndBndry.endPos, "failed to reach end of transliteration" );
2814 }
2815 else if (nTransliterationMode == TransliterationFlags::SENTENCE_CASE)
2816 {
2817 // for 'sentence case' we need to iterate sentence by sentence
2818
2819 sal_Int32 nLastStart = _xBI->beginOfSentence(
2820 aNodeStr, nEndPos,
2821 GetLocale( EditPaM( pNode, nEndPos + 1 ) ) );
2822 sal_Int32 nLastEnd = _xBI->endOfSentence(
2823 aNodeStr, nLastStart,
2824 GetLocale( EditPaM( pNode, nLastStart + 1 ) ) );
2825
2826 // extend nCurrentStart, nCurrentEnd to the current sentence boundaries
2827 nCurrentStart = _xBI->beginOfSentence(
2828 aNodeStr, nStartPos,
2829 GetLocale( EditPaM( pNode, nStartPos + 1 ) ) );
2830 nCurrentEnd = _xBI->endOfSentence(
2831 aNodeStr, nCurrentStart,
2832 GetLocale( EditPaM( pNode, nCurrentStart + 1 ) ) );
2833
2834 // prevent backtracking to the previous sentence if selection starts at end of a sentence
2835 if (nCurrentEnd <= nStartPos)
2836 {
2837 // now nCurrentStart is probably located on a non-letter word. (unless we
2838 // are in Asian text with no spaces...)
2839 // Thus to get the real sentence start we should locate the next real word,
2840 // that is one found by DICTIONARY_WORD
2841 i18n::Boundary aBndry = _xBI->nextWord( aNodeStr, nCurrentEnd,
2842 GetLocale( EditPaM( pNode, nCurrentEnd + 1 ) ),
2843 i18n::WordType::DICTIONARY_WORD);
2844
2845 // now get new current sentence boundaries
2846 nCurrentStart = _xBI->beginOfSentence(
2847 aNodeStr, aBndry.startPos,
2848 GetLocale( EditPaM( pNode, aBndry.startPos + 1 ) ) );
2849 nCurrentEnd = _xBI->endOfSentence(
2850 aNodeStr, nCurrentStart,
2851 GetLocale( EditPaM( pNode, nCurrentStart + 1 ) ) );
2852 }
2853 // prevent advancing to the next sentence if selection ends at start of a sentence
2854 if (nLastStart >= nEndPos)
2855 {
2856 // now nCurrentStart is probably located on a non-letter word. (unless we
2857 // are in Asian text with no spaces...)
2858 // Thus to get the real sentence start we should locate the previous real word,
2859 // that is one found by DICTIONARY_WORD
2860 i18n::Boundary aBndry = _xBI->previousWord( aNodeStr, nLastStart,
2861 GetLocale( EditPaM( pNode, nLastStart + 1 ) ),
2862 i18n::WordType::DICTIONARY_WORD);
2863 nLastEnd = _xBI->endOfSentence(
2864 aNodeStr, aBndry.startPos,
2865 GetLocale( EditPaM( pNode, aBndry.startPos + 1 ) ) );
2866 if (nCurrentEnd > nLastEnd)
2867 nCurrentEnd = nLastEnd;
2868 }
2869
2870 // prevent making any change outside of the user's selection
2871 nCurrentStart = std::max(aSel.Min().GetIndex(), nCurrentStart);
2872 nCurrentEnd = std::min(aSel.Max().GetIndex(), nCurrentEnd);
2873 nLastStart = std::max(aSel.Min().GetIndex(), nLastStart);
2874 nLastEnd = std::min(aSel.Max().GetIndex(), nLastEnd);
2875
2876 while (nCurrentStart < nLastEnd)
2877 {
2878 const sal_Int32 nLen = nCurrentEnd - nCurrentStart;
2879 DBG_ASSERT( nLen > 0, "invalid word length of 0" );
2880
2881 Sequence< sal_Int32 > aOffsets;
2882 OUString aNewText( aTransliterationWrapper.transliterate( aNodeStr,
2883 GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ).nLang,
2884 nCurrentStart, nLen, &aOffsets ));
2885
2886 if (aNodeStr != aNewText)
2887 {
2888 aChgData.nStart = nCurrentStart;
2889 aChgData.nLen = nLen;
2890 aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) );
2891 aChgData.aNewText = aNewText;
2892 aChgData.aOffsets = aOffsets;
2893 aChanges.push_back( aChgData );
2894 }
2895
2896 i18n::Boundary aFirstWordBndry = _xBI->nextWord(
2897 aNodeStr, nCurrentEnd,
2898 GetLocale( EditPaM( pNode, nCurrentEnd + 1 ) ),
2899 nWordType);
2900 nCurrentStart = aFirstWordBndry.startPos;
2901 nCurrentEnd = _xBI->endOfSentence(
2902 aNodeStr, nCurrentStart,
2903 GetLocale( EditPaM( pNode, nCurrentStart + 1 ) ) );
2904 }
2905 DBG_ASSERT( nCurrentEnd >= nLastEnd, "failed to reach end of transliteration" );
2906 }
2907 else
2908 {
2909 do
2910 {
2911 if ( bConsiderLanguage )
2912 {
2913 nLanguage = GetLanguage( EditPaM( pNode, nCurrentStart+1 ), &nCurrentEnd ).nLang;
2914 if ( nCurrentEnd > nEndPos )
2915 nCurrentEnd = nEndPos;
2916 }
2917
2918 const sal_Int32 nLen = nCurrentEnd - nCurrentStart;
2919
2920 Sequence< sal_Int32 > aOffsets;
2921 OUString aNewText( aTransliterationWrapper.transliterate( aNodeStr, nLanguage, nCurrentStart, nLen, &aOffsets ) );
2922
2923 if (aNodeStr != aNewText)
2924 {
2925 aChgData.nStart = nCurrentStart;
2926 aChgData.nLen = nLen;
2927 aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) );
2928 aChgData.aNewText = aNewText;
2929 aChgData.aOffsets = aOffsets;
2930 aChanges.push_back( aChgData );
2931 }
2932
2933 nCurrentStart = nCurrentEnd;
2934 } while( nCurrentEnd < nEndPos );
2935 }
2936
2937 if (!aChanges.empty())
2938 {
2939 // Create a single UndoAction on Demand for all the changes ...
2940 if ( !pUndo && IsUndoEnabled() && !IsInUndo() )
2941 {
2942 // adjust selection to include all changes
2943 for (const eeTransliterationChgData & aChange : aChanges)
2944 {
2945 const EditSelection &rSel = aChange.aSelection;
2946 if (aSel.Min().GetNode() == rSel.Min().GetNode() &&
2947 aSel.Min().GetIndex() > rSel.Min().GetIndex())
2948 aSel.Min().SetIndex( rSel.Min().GetIndex() );
2949 if (aSel.Max().GetNode() == rSel.Max().GetNode() &&
2950 aSel.Max().GetIndex() < rSel.Max().GetIndex())
2951 aSel.Max().SetIndex( rSel.Max().GetIndex() );
2952 }
2953 aNewSel = aSel;
2954
2955 ESelection aESel( CreateESel( aSel ) );
2956 pUndo.reset(new EditUndoTransliteration(pEditEngine, aESel, nTransliterationMode));
2957
2958 const bool bSingleNode = aSel.Min().GetNode()== aSel.Max().GetNode();
2959 const bool bHasAttribs = aSel.Min().GetNode()->GetCharAttribs().HasAttrib( aSel.Min().GetIndex(), aSel.Max().GetIndex() );
2960 if (bSingleNode && !bHasAttribs)
2961 pUndo->SetText( aSel.Min().GetNode()->Copy( aSel.Min().GetIndex(), aSel.Max().GetIndex()-aSel.Min().GetIndex() ) );
2962 else
2963 pUndo->SetText( CreateTextObject( aSel, nullptr ) );
2964 }
2965
2966 // now apply the changes from end to start to leave the offsets of the
2967 // yet unchanged text parts remain the same.
2968 for (size_t i = 0; i < aChanges.size(); ++i)
2969 {
2970 eeTransliterationChgData& rData = aChanges[ aChanges.size() - 1 - i ];
2971
2972 bChanges = true;
2973 if (rData.nLen != rData.aNewText.getLength())
2974 bLenChanged = true;
2975
2976 // Change text without losing the attributes
2977 const sal_Int32 nDiffs =
2978 ReplaceTextOnly( rData.aSelection.Min().GetNode(),
2979 rData.nStart, rData.aNewText, rData.aOffsets );
2980
2981 // adjust selection in end node to possibly changed size
2982 if (aSel.Max().GetNode() == rData.aSelection.Max().GetNode())
2983 aNewSel.Max().SetIndex( aNewSel.Max().GetIndex() + nDiffs );
2984
2985 sal_Int32 nSelNode = aEditDoc.GetPos( rData.aSelection.Min().GetNode() );
2986 ParaPortion* pParaPortion = GetParaPortions()[nSelNode];
2987 pParaPortion->MarkSelectionInvalid( rData.nStart );
2988 }
2989 }
2990 }
2991
2992 if ( pUndo )
2993 {
2994 ESelection aESel( CreateESel( aNewSel ) );
2995 pUndo->SetNewSelection( aESel );
2996 InsertUndo( std::move(pUndo) );
2997 }
2998
2999 if ( bChanges )
3000 {
3001 TextModified();
3002 SetModifyFlag( true );
3003 if ( bLenChanged )
3005 if (IsUpdateLayout())
3007 }
3008
3009 return aNewSel;
3010}
3011
3012
3014 ContentNode* pNode,
3015 sal_Int32 nCurrentStart,
3016 std::u16string_view rNewText,
3017 const uno::Sequence< sal_Int32 >& rOffsets )
3018{
3019 // Change text without losing the attributes
3020 sal_Int32 nCharsAfterTransliteration = rOffsets.getLength();
3021 const sal_Int32* pOffsets = rOffsets.getConstArray();
3022 short nDiffs = 0;
3023 for ( sal_Int32 n = 0; n < nCharsAfterTransliteration; n++ )
3024 {
3025 sal_Int32 nCurrentPos = nCurrentStart+n;
3026 sal_Int32 nDiff = (nCurrentPos-nDiffs) - pOffsets[n];
3027
3028 if ( !nDiff )
3029 {
3030 DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" );
3031 pNode->SetChar( nCurrentPos, rNewText[n] );
3032 }
3033 else if ( nDiff < 0 )
3034 {
3035 // Replace first char, delete the rest...
3036 DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" );
3037 pNode->SetChar( nCurrentPos, rNewText[n] );
3038
3039 DBG_ASSERT( (nCurrentPos+1) < pNode->Len(), "TransliterateText - String smaller than expected!" );
3040 GetEditDoc().RemoveChars( EditPaM( pNode, nCurrentPos+1 ), -nDiff);
3041 }
3042 else
3043 {
3044 DBG_ASSERT( nDiff == 1, "TransliterateText - Diff other than expected! But should work..." );
3045 GetEditDoc().InsertText( EditPaM( pNode, nCurrentPos ), OUStringChar(rNewText[n]) );
3046
3047 }
3048 nDiffs = sal::static_int_cast< short >(nDiffs + nDiff);
3049 }
3050
3051 return nDiffs;
3052}
3053
3054
3056{
3057 if ( n != nAsianCompressionMode )
3058 {
3060 if ( ImplHasText() )
3061 {
3062 FormatFullDoc();
3063 UpdateViews();
3064 }
3065 }
3066}
3067
3069{
3070 if ( b != bKernAsianPunctuation )
3071 {
3073 if ( ImplHasText() )
3074 {
3075 FormatFullDoc();
3076 UpdateViews();
3077 }
3078 }
3079}
3080
3081void ImpEditEngine::SetAddExtLeading( bool bExtLeading )
3082{
3083 if ( IsAddExtLeading() != bExtLeading )
3084 {
3085 bAddExtLeading = bExtLeading;
3086 if ( ImplHasText() )
3087 {
3088 FormatFullDoc();
3089 UpdateViews();
3090 }
3091 }
3092};
3093
3094
3096{
3097 return ( ( GetEditDoc().Count() > 1 ) || GetEditDoc().GetObject(0)->Len() );
3098}
3099
3100sal_Int32 ImpEditEngine::LogicToTwips(sal_Int32 n)
3101{
3102 Size aSz(n, 0);
3103 MapMode aTwipsMode( MapUnit::MapTwip );
3104 aSz = pRefDev->LogicToLogic( aSz, nullptr, &aTwipsMode );
3105 return aSz.Width();
3106}
3107
3108double ImpEditEngine::roundToNearestPt(double fInput) const
3109{
3111 {
3112 double fInputPt = o3tl::convert(fInput, o3tl::Length::mm100, o3tl::Length::pt);
3113 auto nInputRounded = basegfx::fround(fInputPt);
3114 return o3tl::convert(double(nInputRounded), o3tl::Length::pt, o3tl::Length::mm100);
3115 }
3116 else
3117 {
3118 return fInput;
3119 }
3120}
3121
3122/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
CharCompressType
AttribsType & GetAttribs()
Definition: editdoc.hxx:222
const EditCharAttrib * FindFeature(sal_Int32 nPos) const
Definition: editdoc.cxx:2975
static void DbgCheckAttribs(CharAttribList const &rAttribs)
Definition: editdoc.cxx:3014
bool HasAttrib(sal_Int32 nStartPos, sal_Int32 nEndPos) const
Definition: editdoc.cxx:2887
void InsertAttrib(EditCharAttrib *pAttrib)
Definition: editdoc.cxx:2760
sal_Int32 Count() const
Definition: editdoc.cxx:2840
SvxFont & GetDefFont()
Definition: editdoc.hxx:215
const EditCharAttrib * FindAttrib(sal_uInt16 nWhich, sal_Int32 nPos) const
Definition: editdoc.cxx:2845
SfxItemSet & GetItems()
Definition: editdoc.hxx:166
const SfxPoolItem & GetItem(sal_uInt16 nWhich) const
Definition: editdoc.cxx:1862
OUString GetText() const
Definition: editobj.cxx:135
SfxStyleFamily GetFamily() const
Definition: editobj2.hxx:152
const SfxItemSet & GetParaAttribs() const
Definition: editobj2.hxx:157
void SetStyle(const OUString &rStyle)
Definition: editobj2.hxx:154
const WrongList * GetWrongList() const
Definition: editobj.cxx:167
const std::vector< XEditAttribute > & GetCharAttribs() const
Definition: editobj2.hxx:148
void SetFamily(const SfxStyleFamily &rFamily)
Definition: editobj2.hxx:155
void SetText(const OUString &rStr)
Definition: editobj.cxx:141
void SetWrongList(WrongList *p)
Definition: editobj.cxx:172
const OUString & GetStyle() const
Definition: editobj2.hxx:151
void EnsureWrongList()
Definition: editdoc.cxx:1771
void SetChar(sal_Int32 nPos, sal_Unicode c)
Definition: editdoc.cxx:1731
CharAttribList & GetCharAttribs()
Definition: editdoc.hxx:256
sal_Unicode GetChar(sal_Int32 nPos) const
Definition: editdoc.cxx:1766
const OUString & GetString() const
Definition: editdoc.hxx:281
ContentAttribs & GetContentAttribs()
Definition: editdoc.hxx:254
WrongList * GetWrongList()
Definition: editdoc.cxx:1777
void CreateDefFont()
Definition: editdoc.cxx:1579
void UnExpandPositions(sal_Int32 &rStartPos, sal_Int32 &rEndPos)
re-write offsets in the expanded text to string offsets
Definition: editdoc.cxx:1725
OUString Copy(sal_Int32 nPos) const
Definition: editdoc.cxx:1756
OUString GetExpandedText(sal_Int32 nStartPos=0, sal_Int32 nEndPos=-1) const
return content including expanded fields
Definition: editdoc.cxx:1639
void SetWrongList(WrongList *p)
Definition: editdoc.cxx:1787
sal_Int32 GetExpandedLen() const
return length including expanded fields
Definition: editdoc.cxx:1620
SfxStyleSheet * GetStyleSheet()
Definition: editdoc.hxx:266
sal_Int32 Len() const
Definition: editdoc.cxx:1615
void CreateWrongList()
Definition: editdoc.cxx:1792
virtual VclPtr< AbstractThesaurusDialog > CreateThesaurusDialog(weld::Widget *, css::uno::Reference< css::linguistic2::XThesaurus > xThesaurus, const OUString &rWord, LanguageType nLanguage)=0
static EditAbstractDialogFactory * Create()
Definition: edtdlg.cxx:22
sal_Int32 & GetStart()
Definition: editattr.hxx:87
const SfxPoolItem * GetItem() const
Definition: editattr.hxx:85
sal_uInt16 Which() const
Definition: editattr.hxx:84
sal_Int32 & GetEnd()
Definition: editattr.hxx:88
EditPaM GetEndPaM() const
Definition: editdoc.cxx:2204
void SetModified(bool b)
Definition: editdoc.cxx:2240
void InsertAttrib(const SfxPoolItem &rItem, ContentNode *pNode, sal_Int32 nStart, sal_Int32 nEnd)
Definition: editdoc.cxx:2552
const SvxFont & GetDefFont() const
Definition: editdoc.hxx:780
sal_Int32 GetPos(const ContentNode *pNode) const
Definition: editdoc.cxx:2086
void RemoveChars(EditPaM aPaM, sal_Int32 nChars)
Definition: editdoc.cxx:2366
SfxItemPool & GetItemPool()
Definition: editdoc.hxx:812
OUString GetParaAsString(sal_Int32 nNode) const
Definition: editdoc.cxx:2187
const ContentNode * GetObject(sal_Int32 nPos) const
Definition: editdoc.cxx:2091
sal_Int32 Count() const
Definition: editdoc.cxx:2143
sal_uInt16 GetDefTab() const
Definition: editdoc.hxx:783
void ClearSpellErrors()
Definition: editdoc.cxx:2235
EditPaM InsertText(EditPaM aPaM, std::u16string_view rStr)
Definition: editdoc.cxx:2271
EditPaM GetStartPaM() const
Definition: editdoc.cxx:2198
void GetPortions(sal_Int32 nPara, std::vector< sal_Int32 > &rList)
Definition: editeng.cxx:1841
OUString GetText(LineEnd eEnd=LINEEND_LF) const
Definition: editeng.cxx:573
editeng::LanguageSpan GetLanguage(const EditPaM &rPaM) const
Definition: editeng.cxx:482
sal_Int32 GetParagraphCount() const
Definition: editeng.cxx:589
void Append(EditLine *p)
Definition: editdoc.cxx:1108
sal_Int32 Count() const
Definition: editdoc.cxx:1093
void Reset()
Definition: editdoc.cxx:1063
void SetInvalid()
Definition: editdoc.hxx:549
EditLine * Clone() const
Definition: editdoc.cxx:961
void SetIndex(sal_Int32 n)
Definition: editdoc.hxx:317
void SetNode(ContentNode *p)
Definition: editdoc.cxx:1122
const ContentNode * GetNode() const
Definition: editdoc.hxx:312
sal_Int32 GetIndex() const
Definition: editdoc.hxx:316
EditPaM & Min()
Definition: editdoc.hxx:705
bool DbgIsBuggy(EditDoc const &rDoc) const
Definition: editdoc.cxx:1134
bool HasRange() const
Definition: editdoc.hxx:711
EditPaM & Max()
Definition: editdoc.hxx:706
void Adjust(const EditDoc &rNodes)
Definition: editdoc.cxx:1162
EditStatusFlags GetStatusWord() const
Definition: editstat.hxx:110
MapUnit GetMetric() const
Definition: editobj2.hxx:259
bool HasMetric() const
Definition: editobj2.hxx:258
ContentInfosType & GetContents()
Definition: editobj2.hxx:221
XParaPortionList * GetPortionInfo() const
Definition: editobj2.hxx:225
virtual bool GetVertical() const =0
virtual TextRotation GetRotation() const =0
ESelection GetSelection() const
Definition: editview.cxx:301
bool HasSelection() const
Definition: editview.cxx:314
void SetSelection(const ESelection &rNewSel)
Definition: editview.cxx:256
void InsertText(const OUString &rNew, bool bSelect=false, bool bLOKShowSelect=true)
Definition: editview.cxx:436
void ShowCursor(bool bGotoCursor=true, bool bForceVisCursor=true, bool bActivate=false)
Definition: editview.cxx:508
const SfxItemSet & GetEmptyItemSet() const
Definition: editview.cxx:555
vcl::Window * GetWindow() const
Definition: editview.cxx:357
void SetAttribs(const SfxItemSet &rSet)
Definition: editview.cxx:560
std::unique_ptr< ImpEditView > pImpEditView
Definition: editview.hxx:167
tools::Long GetDescent() const
tools::Long GetAscent() const
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
SfxStyleSheetPool * GetStyleSheetPool() const
Definition: impedit.hxx:1012
void WriteXML(SvStream &rOutput, const EditSelection &rSel)
Definition: impedit4.cxx:266
EESpellState StartThesaurus(EditView *pEditView, weld::Widget *pDialogParent)
Definition: impedit4.cxx:2441
bool UpdateFields()
Definition: impedit2.cxx:3049
short ReplaceTextOnly(ContentNode *pNode, sal_Int32 nCurrentStart, std::u16string_view rText, const css::uno::Sequence< sal_Int32 > &rOffsets)
Definition: impedit4.cxx:3013
sal_Int32 nBigTextObjectStart
Definition: impedit.hxx:545
css::uno::Reference< css::linguistic2::XSpellAlternatives > ImpSpell(EditView *pEditView)
Definition: impedit4.cxx:1813
sal_uInt16 GetLineHeight(sal_Int32 nParagraph, sal_Int32 nLine)
Definition: impedit2.cxx:3682
sal_Int32 StartSearchAndReplace(EditView *pEditView, const SvxSearchItem &rSearchItem)
Definition: impedit4.cxx:2468
void CallStatusHdl()
Definition: impedit3.cxx:4278
css::uno::Reference< css::linguistic2::XSpellChecker1 > xSpeller
Definition: impedit.hxx:546
const SfxItemSet & GetEmptyItemSet() const
Definition: impedit2.cxx:743
EditPaM ImpFastInsertText(EditPaM aPaM, const OUString &rStr)
Definition: impedit2.cxx:2864
const Size & GetPaperSize() const
Definition: impedit.hxx:852
void Convert(EditView *pEditView, weld::Widget *pDialogParent, LanguageType nSrcLang, LanguageType nDestLang, const vcl::Font *pDestFont, sal_Int32 nOptions, bool bIsInteractive, bool bMultipleDoc)
Definition: impedit4.cxx:1527
bool HasText(const SvxSearchItem &rSearchItem)
Definition: impedit4.cxx:2643
const MapMode & GetRefMapMode() const
Definition: impedit.hxx:1027
EditPaM ImpFastInsertParagraph(sal_Int32 nPara)
Definition: impedit2.cxx:2986
css::lang::Locale GetLocale(const EditPaM &rPaM) const
Definition: impedit4.cxx:1419
void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &rSet)
Definition: impedit5.cxx:679
void FormatDoc()
Definition: impedit3.cxx:400
void UndoActionStart(sal_uInt16 nId)
Definition: impedit5.cxx:246
OUString GetSelected(const EditSelection &rSel) const
Definition: impedit2.cxx:266
EditPaM ReadHTML(SvStream &rInput, const OUString &rBaseURL, EditSelection aSel, SvKeyValueIterator *pHTTPHeaderAttrs)
Definition: impedit4.cxx:162
ErrCode WriteRTF(SvStream &rOutput, EditSelection aSel)
Definition: impedit4.cxx:273
void DoOnlineSpelling(ContentNode *pThisNodeOnly=nullptr, bool bSpellAtCursorPos=false, bool bInterruptible=true)
Definition: impedit4.cxx:2205
SvtScriptType GetItemScriptType(const EditSelection &rSel) const
Definition: impedit2.cxx:1857
TextRotation GetRotation() const
Definition: impedit.hxx:860
void SetAutoCompleteText(const OUString &rStr, bool bUpdateTipWindow)
Definition: impedit4.cxx:2655
void SetAsianCompressionMode(CharCompressType n)
Definition: impedit4.cxx:3055
bool IsAddExtLeading() const
Definition: impedit.hxx:1159
double mfFontScaleY
Definition: impedit.hxx:536
EPaM CreateEPaM(const EditPaM &rPaM) const
Definition: impedit.hxx:1233
EditEngine * GetEditEnginePtr() const
Definition: impedit.hxx:1136
bool mbRoundToNearestPt
Definition: impedit.hxx:539
Size aPaperSize
Definition: impedit.hxx:501
EditPaM CreateEditPaM(const EPaM &rEPaM)
Definition: impedit.hxx:1239
const ParaPortion * FindParaPortion(const ContentNode *pNode) const
Definition: impedit.hxx:1319
EESpellState HasSpellErrors()
Definition: impedit4.cxx:2404
EditPaM CursorRight(const EditPaM &rPaM, sal_uInt16 nCharacterIteratorMode=css::i18n::CharacterIteratorMode::SKIPCELL)
Definition: impedit2.cxx:1243
void UpdateViews(EditView *pCurView=nullptr)
Definition: impedit3.cxx:316
void SeekCursor(ContentNode *pNode, sal_Int32 nPos, SvxFont &rFont, OutputDevice *pOut=nullptr)
Definition: impedit3.cxx:2859
EditDoc & GetEditDoc()
Definition: impedit.hxx:824
css::uno::Reference< css::linguistic2::XSpellChecker1 > const & GetSpeller()
Definition: impedit4.cxx:1424
void ClearSpellErrors()
Definition: impedit4.cxx:2436
editeng::LanguageSpan GetLanguage(const EditPaM &rPaM, sal_Int32 *pEndPos=nullptr) const
Definition: impedit4.cxx:1394
SfxItemSet GetAttribs(sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags=GetAttribsFlags::ALL) const
Definition: impedit5.cxx:398
bool SpellSentence(EditView const &rView, svx::SpellPortions &rToFill)
Definition: impedit4.cxx:1922
EditPaM ImpInsertParaBreak(EditPaM &rPaM, bool bKeepEndingAttribs=true)
Definition: impedit2.cxx:2922
sal_uInt16 GetI18NScriptType(const EditPaM &rPaM, sal_Int32 *pEndPos=nullptr) const
Definition: impedit2.cxx:1826
bool GetVertical() const
Definition: impedit.hxx:858
std::unique_ptr< SpellInfo > pSpellInfo
Definition: impedit.hxx:548
EditSelection SelectSentence(const EditSelection &rCurSel) const
Definition: impedit2.cxx:1609
void UndoActionEnd()
Definition: impedit5.cxx:255
EditSelection TransliterateText(const EditSelection &rSelection, TransliterationFlags nTransliterationMode)
Definition: impedit4.cxx:2674
bool bAddExtLeading
Definition: impedit.hxx:600
CharCompressType nAsianCompressionMode
Definition: impedit.hxx:541
bool IsInUndo() const
Definition: impedit.hxx:911
void SetModifyFlag(bool b)
Definition: impedit.hxx:979
void EnableUndo(bool bEnable)
Definition: impedit5.cxx:283
void SetRotation(TextRotation nRotation)
Definition: impedit3.cxx:2812
void UpdateSelections()
Definition: impedit2.cxx:3709
InternalEditStatus aStatus
Definition: impedit.hxx:556
void AddPortion(const EditSelection &rSel, const css::uno::Reference< css::linguistic2::XSpellAlternatives > &xAlt, svx::SpellPortions &rToFill, bool bIsField)
Definition: impedit4.cxx:1982
SfxItemPool * GetEditTextObjectPool() const
Definition: impedit.hxx:1110
void SetAttribs(EditSelection aSel, const SfxItemSet &rSet, SetAttribsMode nSpecial=SetAttribsMode::NONE, bool bSetSelection=true)
Definition: impedit5.cxx:489
EditPaM WordRight(const EditPaM &rPaM, sal_Int16 nWordType=css::i18n::WordType::ANYWORD_IGNOREWHITESPACES)
Definition: impedit2.cxx:1503
double mfSpacingScaleY
Definition: impedit.hxx:538
tools::Long GetColumnWidth(const Size &rPaperSize) const
Definition: impedit3.cxx:631
void FormatAndLayout(EditView *pCurView=nullptr, bool bCalledFromUndo=false)
Definition: impedit3.cxx:4412
std::unique_ptr< EditTextObject > GetEmptyTextObject()
Definition: impedit4.cxx:971
void AddPortionIterated(EditView const &rEditView, const EditSelection &rSel, const css::uno::Reference< css::linguistic2::XSpellAlternatives > &xAlt, svx::SpellPortions &rToFill)
Definition: impedit4.cxx:2004
bool bKernAsianPunctuation
Definition: impedit.hxx:599
EditEngine * pEditEngine
Definition: impedit.hxx:508
void FormatFullDoc()
Definition: impedit3.cxx:393
void Write(SvStream &rOutput, EETextFormat eFormat, const EditSelection &rSel)
Definition: impedit4.cxx:177
std::unique_ptr< ConvInfo > pConvInfo
Definition: impedit.hxx:552
EditPaM Read(SvStream &rInput, const OUString &rBaseURL, EETextFormat eFormat, const EditSelection &rSel, SvKeyValueIterator *pHTTPHeaderAttrs=nullptr)
Definition: impedit4.cxx:86
double mfSpacingScaleX
Definition: impedit.hxx:537
bool IsScriptChange(const EditPaM &rPaM) const
Definition: impedit2.cxx:1909
EditPaM ReadXML(SvStream &rInput, EditSelection aSel)
Definition: impedit4.cxx:126
EditUndoManager & GetUndoManager()
Definition: impedit.hxx:1290
void PutSpellingToSentenceStart(EditView const &rEditView)
Definition: impedit4.cxx:2196
bool IsFormatted() const
Definition: impedit.hxx:916
VclPtr< OutputDevice > pRefDev
Definition: impedit.hxx:517
bool ImpSearch(const SvxSearchItem &rSearchItem, const EditSelection &rSearchSelection, const EditPaM &rStartPos, EditSelection &rFoundSel)
Definition: impedit4.cxx:2564
void ResetUndoManager()
Definition: impedit5.cxx:277
css::uno::Reference< css::linguistic2::XSpellAlternatives > ImpFindNextError(EditSelection &rSelection)
Definition: impedit4.cxx:1878
bool HasConvertibleTextPortion(LanguageType nLang)
Definition: impedit4.cxx:1493
void GetAllMisspellRanges(std::vector< editeng::MisspellRanges > &rRanges) const
Definition: impedit4.cxx:1362
void ImpConvert(OUString &rConvTxt, LanguageType &rConvTxtLang, EditView *pEditView, LanguageType nSrcLang, const ESelection &rConvRange, bool bAllowImplicitChangesForNotConvertibleText, LanguageType nTargetLang, const vcl::Font *pTargetFont)
Definition: impedit4.cxx:1645
bool HasUndoManager() const
Definition: impedit.hxx:629
ViewsType aEditViews
Definition: impedit.hxx:509
OutputDevice * GetRefDevice() const
Definition: impedit.hxx:1024
EditSelection InsertTextObject(const EditTextObject &, EditPaM aPaM)
Definition: impedit4.cxx:1170
void CreateSpellInfo(bool bMultipleDocs)
Definition: impedit4.cxx:1432
void SetAllMisspellRanges(const std::vector< editeng::MisspellRanges > &rRanges)
Definition: impedit4.cxx:1379
bool WriteItemListAsRTF(ItemList &rLst, SvStream &rOutput, sal_Int32 nPara, sal_Int32 nPos, std::vector< std::unique_ptr< SvxFontItem > > &rFontTable, SvxColorList &rColorList)
Definition: impedit4.cxx:237
EditPaM ImpDeleteSelection(const EditSelection &rCurSel)
Definition: impedit2.cxx:2446
EESpellState Spell(EditView *pEditView, weld::Widget *pDialogParent, bool bMultipleDoc)
Definition: impedit4.cxx:1448
void SetVertical(bool bVertical)
Definition: impedit3.cxx:2797
sal_Int32 LogicToTwips(sal_Int32 n)
Definition: impedit4.cxx:3100
ESelection CreateESel(const EditSelection &rSel) const
Definition: impedit.hxx:1246
void ApplyChangedSentence(EditView const &rEditView, const svx::SpellPortions &rNewPortions, bool bRecheck)
Definition: impedit4.cxx:2072
void InsertUndo(std::unique_ptr< EditUndo > pUndo, bool bTryMerge=false)
Definition: impedit5.cxx:264
void SetKernAsianPunctuation(bool b)
Definition: impedit4.cxx:3068
tools::Rectangle PaMtoEditCursor(EditPaM aPaM, GetCursorFlags nFlags=GetCursorFlags::NONE)
Definition: impedit2.cxx:3155
EditPaM ReadText(SvStream &rInput, EditSelection aSel)
Definition: impedit4.cxx:109
InternalEditStatus & GetStatus()
Definition: impedit.hxx:1030
double roundToNearestPt(double fInput) const
Definition: impedit4.cxx:3108
EditPaM ReadRTF(SvStream &rInput, EditSelection aSel)
Definition: impedit4.cxx:136
void SetLanguageAndFont(const ESelection &rESel, LanguageType nLang, sal_uInt16 nLangWhichId, const vcl::Font *pFont, sal_uInt16 nFontWhichId)
Definition: impedit4.cxx:1612
css::uno::Reference< css::i18n::XBreakIterator > const & ImplGetBreakIterator() const
Definition: impedit3.cxx:4627
bool SetUpdateLayout(bool bUpdate, EditView *pCurView=nullptr, bool bForceUpdate=false)
Definition: impedit3.cxx:4146
EditSelection SelectWord(const EditSelection &rCurSelection, sal_Int16 nWordType=css::i18n::WordType::ANYWORD_IGNOREWHITESPACES, bool bAcceptStartOfWord=true)
Definition: impedit2.cxx:1576
void WriteItemAsRTF(const SfxPoolItem &rItem, SvStream &rOutput, sal_Int32 nPara, sal_Int32 nPos, std::vector< std::unique_ptr< SvxFontItem > > &rFontTable, SvxColorList &rColorList)
Definition: impedit4.cxx:658
void SetAddExtLeading(bool b)
Definition: impedit4.cxx:3081
void SetText(const OUString &rText)
Definition: impedit2.cxx:708
bool IsUpdateLayout() const
Definition: impedit.hxx:847
std::unique_ptr< EditTextObject > CreateTextObject()
Definition: impedit4.cxx:980
EditDoc aEditDoc
Definition: impedit.hxx:505
EditPaM ImpInsertText(const EditSelection &aCurEditSelection, const OUString &rStr)
Definition: impedit2.cxx:2715
void TextModified()
Definition: impedit2.cxx:768
ErrCode WriteText(SvStream &rOutput, EditSelection aSel)
Definition: impedit4.cxx:199
OUString aAutoCompleteText
Definition: impedit.hxx:554
bool IsUndoEnabled() const
Definition: impedit.hxx:909
tools::Rectangle aInvalidRect
Definition: impedit.hxx:565
bool ImplHasText() const
Definition: impedit4.cxx:3095
EditPaM InsertText(const EditSelection &aCurEditSelection, const OUString &rStr)
Definition: impedit2.cxx:662
void SetStyleSheet(EditSelection aSel, SfxStyleSheet *pStyle)
Definition: impedit5.cxx:47
const ParaPortionList & GetParaPortions() const
Definition: impedit.hxx:827
void CheckIdleFormatter()
Definition: impedit3.cxx:379
bool Search(const SvxSearchItem &rSearchItem, EditView *pView)
Definition: impedit4.cxx:2532
double mfFontScaleX
Definition: impedit.hxx:535
Timer aOnlineSpellTimer
Definition: impedit.hxx:572
EditView * pActiveView
Definition: impedit.hxx:510
bool AllowBigObjects() const
Definition: editstt2.hxx:58
bool UseCharAttribs() const
Definition: editstt2.hxx:34
void Insert(const SfxPoolItem *pItem)
Definition: editdoc.cxx:1912
const SfxPoolItem * Next()
Definition: editdoc.cxx:1902
void Clear()
Definition: editdoc.hxx:149
sal_Int32 Count() const
Definition: editdoc.hxx:147
const SfxPoolItem * First()
Definition: editdoc.cxx:1896
const css::lang::Locale & getLocale(bool bResolveSystem=true) const
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
static css::uno::Reference< css::linguistic2::XThesaurus > GetThesaurus()
Definition: unolingu.cxx:488
static css::uno::Reference< css::linguistic2::XSpellChecker1 > GetSpellChecker()
Definition: unolingu.cxx:478
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
FontMetric GetFontMetric() const
TextPortionList & GetTextPortions()
Definition: editdoc.hxx:646
sal_Int32 nFirstLineOffset
Definition: editdoc.hxx:603
void MarkInvalid(sal_Int32 nStart, sal_Int32 nDiff)
Definition: editdoc.cxx:527
tools::Long GetHeight() const
Definition: editdoc.hxx:641
void SetValid()
Definition: editdoc.hxx:625
sal_Int32 GetFirstLineOffset() const
Definition: editdoc.hxx:642
tools::Long nHeight
Definition: editdoc.hxx:597
ContentNode * GetNode() const
Definition: editdoc.hxx:645
EditLineList & GetLines()
Definition: editdoc.hxx:620
bool bForceRepaint
Definition: editdoc.hxx:610
void MarkSelectionInvalid(sal_Int32 nStart)
Definition: editdoc.cxx:563
constexpr tools::Long X() const
bool GetValue() const
EnumT GetValue() const
sal_Int16 GetValue() const
Item2Range GetItemSurrogates(sal_uInt16 nWhich) const
SfxItemPool * GetSecondaryPool() const
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
const OUString & GetName() const
virtual MapUnit GetMetric(sal_uInt16 nWhich) const
sal_uInt16 Count() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
bool Set(const SfxItemSet &, bool bDeep=true)
sal_uInt16 Which() const
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const=0
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
const OUString & GetName() const
SfxStyleFamily GetFamily() const
virtual SfxItemSet & GetItemSet()
constexpr tools::Long Width() const
bool IsWritable() const
SvStream & WriteNumberAsString(N n)
bool WriteByteStringLine(std::u16string_view rStr, rtl_TextEncoding eDestCharSet)
bool ReadByteStringLine(OUString &rStr, rtl_TextEncoding eSrcCharSet, sal_Int32 nMaxBytesToRead=0xFFFE)
SvStream & WriteOString(std::string_view rStr)
void SetError(ErrCode nErrorCode)
SvStream & WriteChar(char nChar)
rtl_TextEncoding GetStreamCharSet() const
ErrCode GetError() const
SvxColorItem item describes a color.
Definition: colritem.hxx:32
const Color & GetValue() const
Definition: colritem.hxx:57
This item describes a Font.
Definition: fontitem.hxx:30
void SetStyleName(const OUString &rStyleName)
Definition: fontitem.hxx:68
FontFamily GetFamily() const
Definition: fontitem.hxx:81
FontPitch GetPitch() const
Definition: fontitem.hxx:90
void SetFamily(FontFamily _eFamily)
Definition: fontitem.hxx:77
void SetPitch(FontPitch _ePitch)
Definition: fontitem.hxx:86
void SetFamilyName(const OUString &rFamilyName)
Definition: fontitem.hxx:59
rtl_TextEncoding GetCharSet() const
Definition: fontitem.hxx:99
const OUString & GetFamilyName() const
Definition: fontitem.hxx:63
void SetCharSet(rtl_TextEncoding _eEncoding)
Definition: fontitem.hxx:95
LanguageType GetLanguage() const
Definition: langitem.hxx:60
SvxInterLineSpaceRule GetInterLineSpaceRule() const
Definition: lspcitem.hxx:92
void SetBackward(bool bNewBackward)
SvxSearchCmd GetCommand() const
void SetSelection(bool bNewSelection)
const OUString & GetReplaceString() const
const i18nutil::SearchOptions2 & GetSearchOptions() const
bool GetSelection() const
bool GetBackward() const
void SpellDocument()
Definition: splwrap.cxx:252
static sal_Int16 CheckSpellLang(css::uno::Reference< css::linguistic2::XSpellChecker1 > const &xSpell, LanguageType nLang)
Definition: splwrap.cxx:170
sal_uInt16 Count() const
Definition: tstpitem.hxx:116
sal_Int32 & GetTabPos()
Definition: tstpitem.hxx:53
void Stop()
void Append(TextPortion *p)
Definition: editdoc.cxx:407
sal_Int32 Count() const
Definition: editdoc.cxx:392
sal_Int32 FindPortion(sal_Int32 nCharPos, sal_Int32 &rPortionStart, bool bPreferStartingPortion=false) const
Definition: editdoc.cxx:448
sal_Int32 GetLen() const
Definition: editdoc.hxx:409
virtual void Start(bool bStartTimer=true) override
Keeps track of misspelled ranges in paragraph.
Definition: edtspell.hxx:55
void SetValid()
Definition: edtspell.cxx:163
void ResetInvalidRange(size_t nStart, size_t nEnd)
Definition: edtspell.cxx:178
const std::vector< editeng::MisspellRange > & GetRanges() const
Definition: edtspell.hxx:70
bool IsValid() const
Definition: edtspell.cxx:158
bool HasWrong(size_t nStart, size_t nEnd) const
Definition: edtspell.cxx:338
WrongList * Clone() const
Definition: edtspell.cxx:426
void ClearWrongs(size_t nStart, size_t nEnd, const ContentNode *pNode)
Definition: edtspell.cxx:362
size_t GetInvalidEnd() const
Definition: edtspell.hxx:79
void InsertWrong(size_t nStart, size_t nEnd)
Definition: edtspell.cxx:396
void SetRanges(std::vector< editeng::MisspellRange > &&rRanges)
Definition: edtspell.cxx:153
size_t GetInvalidStart() const
Definition: edtspell.hxx:78
bool HasAnyWrong(size_t nStart, size_t nEnd) const
Definition: edtspell.cxx:350
const SfxPoolItem * GetItem() const
Definition: editobj2.hxx:57
sal_Int32 & GetEnd()
Definition: editobj2.hxx:60
sal_Int32 GetLen() const
Definition: editobj2.hxx:65
bool IsFeature() const
Definition: editobj.cxx:62
sal_Int32 & GetStart()
Definition: editobj2.hxx:59
double getSpacingScaleY() const
Definition: editobj2.hxx:116
double getFontScaleY() const
Definition: editobj2.hxx:114
sal_uInt32 GetPaperWidth() const
Definition: editobj2.hxx:110
bool RefDevIsVirtual() const
Definition: editobj2.hxx:111
void push_back(XParaPortion *p)
Definition: editobj.cxx:85
OutputDevice * GetRefDevPtr() const
Definition: editobj2.hxx:109
const MapMode & GetRefMapMode() const
Definition: editobj2.hxx:112
double getSpacingScaleX() const
Definition: editobj2.hxx:115
double getFontScaleX() const
Definition: editobj2.hxx:113
static bool IsChinese(LanguageType nLang)
constexpr void SetLeft(tools::Long v)
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
constexpr Point TopLeft() const
void SetPos(const Point &rPoint)
constexpr void SetRight(tools::Long v)
constexpr void SetBottom(tools::Long v)
tools::Rectangle & Intersection(const tools::Rectangle &rRect)
constexpr tools::Long Bottom() const
constexpr bool IsEmpty() const
bool SearchForward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
bool SearchBackward(const OUString &rStr, sal_Int32 *pStart, sal_Int32 *pEnd, css::util::SearchResult *pRes=nullptr)
OUString transliterate(const OUString &rStr, sal_Int32 nStart, sal_Int32 nLen) const
bool needLanguageForTheMode() const
FontFamily GetFamilyType()
const OUString & GetStyleName() const
const OUString & GetFamilyName() const
const Size & GetFontSize() const
FontPitch GetPitch()
rtl_TextEncoding GetCharSet() const
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
int nCount
#define DBG_ASSERT(sCon, aError)
virtual css::uno::Reference< css::embed::XEmbeddedObject > GetObject() override
#define DEF_METRIC
Definition: editattr.hxx:60
#define EE_PARA_NOT_FOUND
Definition: editdata.hxx:48
#define EDITUNDO_REPLACEALL
Definition: editdata.hxx:79
EETextFormat
Definition: editdata.hxx:35
EESpellState
Definition: editdata.hxx:40
#define EE_INDEX_NOT_FOUND
Definition: editdata.hxx:53
#define EDITUNDO_INSERT
Definition: editdata.hxx:72
#define EE_READWRITE_WRONGFORMAT
Definition: editdata.hxx:60
bool IsScriptItemValid(sal_uInt16 nItemId, short nScriptType)
Definition: editdoc.cxx:103
EditCharAttrib * MakeCharAttrib(SfxItemPool &rPool, const SfxPoolItem &rAttr, sal_Int32 nS, sal_Int32 nE)
Definition: editdoc.cxx:219
sal_uInt16 GetScriptItemId(sal_uInt16 nItemId, SvtScriptType nScriptType)
Definition: editdoc.cxx:73
void ConvertItem(std::unique_ptr< SfxPoolItem > &rPoolItem, MapUnit eSourceUnit, MapUnit eDestUnit)
Definition: editdoc.cxx:823
void ConvertAndPutItems(SfxItemSet &rDest, const SfxItemSet &rSource, const MapUnit *pSourceUnit, const MapUnit *pDestUnit)
Definition: editdoc.cxx:888
std::vector< Color > SvxColorList
Definition: editdoc.hxx:131
EditCharAttrib * GetAttrib(CharAttribList::AttribsType &rAttribs, std::size_t nAttr)
Definition: editdoc.hxx:839
EditTextObjectImpl & toImpl(EditTextObject &rObj)
Definition: editobj2.hxx:273
constexpr TypedWhichId< SvxContourItem > EE_CHAR_OUTLINE(EE_CHAR_START+8)
constexpr TypedWhichId< SvxKerningItem > EE_CHAR_KERNING(EE_CHAR_START+12)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CJK(EE_CHAR_START+17)
constexpr TypedWhichId< SvxFieldItem > EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
constexpr TypedWhichId< SvxTabStopItem > EE_PARA_TABS(EE_PARA_START+17)
constexpr TypedWhichId< SvxUnderlineItem > EE_CHAR_UNDERLINE(EE_CHAR_START+5)
constexpr TypedWhichId< SvxAdjustItem > EE_PARA_JUST(EE_PARA_START+16)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
constexpr TypedWhichId< SvxAutoKernItem > EE_CHAR_PAIRKERNING(EE_CHAR_START+11)
constexpr TypedWhichId< SvxShadowedItem > EE_CHAR_SHADOW(EE_CHAR_START+9)
constexpr TypedWhichId< SvxULSpaceItem > EE_PARA_ULSPACE(EE_PARA_START+14)
constexpr TypedWhichId< SvxOverlineItem > EE_CHAR_OVERLINE(EE_CHAR_START+29)
constexpr sal_uInt16 EE_PARA_START(EE_ITEMS_START+0)
constexpr TypedWhichId< SvxLanguageItem > EE_CHAR_LANGUAGE_CTL(EE_CHAR_START+16)
constexpr sal_uInt16 EE_FEATURE_LINEBR(EE_FEATURE_TAB+1)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT(EE_CHAR_START+4)
constexpr TypedWhichId< SvxLRSpaceItem > EE_PARA_LRSPACE(EE_PARA_START+13)
constexpr TypedWhichId< SvxColorItem > EE_CHAR_COLOR(EE_CHAR_START+0)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT_CTL(EE_CHAR_START+22)
constexpr TypedWhichId< SvxCrossedOutItem > EE_CHAR_STRIKEOUT(EE_CHAR_START+6)
constexpr TypedWhichId< SvxPostureItem > EE_CHAR_ITALIC(EE_CHAR_START+7)
constexpr TypedWhichId< SvxLineSpacingItem > EE_PARA_SBL(EE_PARA_START+15)
constexpr TypedWhichId< SvxEmphasisMarkItem > EE_CHAR_EMPHASISMARK(EE_CHAR_START+25)
constexpr TypedWhichId< SvxEscapementItem > EE_CHAR_ESCAPEMENT(EE_CHAR_START+10)
constexpr sal_uInt16 EE_CHAR_END(EE_CHAR_START+32)
constexpr TypedWhichId< SfxInt16Item > EE_PARA_OUTLLEVEL(EE_PARA_START+11)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CTL(EE_CHAR_START+20)
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT_CJK(EE_CHAR_START+21)
constexpr TypedWhichId< SvxLanguageItem > EE_CHAR_LANGUAGE_CJK(EE_CHAR_START+15)
constexpr TypedWhichId< SvxFrameDirectionItem > EE_PARA_WRITINGDIR(EE_PARA_START+0)
constexpr sal_uInt16 EE_FEATURE_TAB(EE_FEATURE_START+0)
constexpr TypedWhichId< SvxPostureItem > EE_CHAR_ITALIC_CJK(EE_CHAR_START+23)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO_CTL(EE_CHAR_START+18)
constexpr TypedWhichId< SvxPostureItem > EE_CHAR_ITALIC_CTL(EE_CHAR_START+24)
constexpr TypedWhichId< SvxLRSpaceItem > EE_PARA_OUTLLRSPACE(EE_PARA_START+10)
constexpr TypedWhichId< SvxLanguageItem > EE_CHAR_LANGUAGE(EE_CHAR_START+14)
constexpr TypedWhichId< SvxCharReliefItem > EE_CHAR_RELIEF(EE_CHAR_START+26)
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT_CJK(EE_CHAR_START+19)
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO(EE_CHAR_START+1)
#define SVSTREAM_WRITE_ERROR
#define DFLT_ESC_AUTO_SUB
#define DFLT_ESC_AUTO_SUPER
FontRelief
UNOTOOLS_DLLPUBLIC bool IsOpenSymbol(std::u16string_view rFontName)
FontLineStyle
LINESTYLE_SINGLE
LINESTYLE_DOUBLE
LINESTYLE_NONE
LINESTYLE_DOTTED
FontStrikeout
STRIKEOUT_DOUBLE
STRIKEOUT_SINGLE
STRIKEOUT_NONE
PITCH_VARIABLE
PITCH_FIXED
FontItalic
ITALIC_NORMAL
ITALIC_NONE
ITALIC_OBLIQUE
FontEmphasisMark
FAMILY_DECORATIVE
FAMILY_DONTKNOW
FAMILY_SCRIPT
FAMILY_SWISS
FAMILY_MODERN
FAMILY_ROMAN
WEIGHT_BOLD
@ Horizontal_RL_TB
Horizontal, from right to left, from top to bottom (typical for arabic/hebrew languages).
static void lcl_FindValidAttribs(ItemList &rLst, ContentNode *pNode, sal_Int32 nIndex, sal_uInt16 nScriptType)
Definition: impedit4.cxx:249
sal_Int32 nIndex
sal_Int64 n
#define LANGUAGE_SYSTEM
#define LANGUAGE_NONE
SvtScriptType
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
MapUnit
SVT_DLLPUBLIC SvStream & Out_String(SvStream &, std::u16string_view, rtl_TextEncoding eDestEnc=RTL_TEXTENCODING_MS_1252)
SvtScriptType FromI18NToSvtScriptType(sal_Int16 nI18NType)
SvtScriptType GetScriptTypeOfLanguage(LanguageType nLang)
B2IRange fround(const B2DRange &rRange)
int i
m
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
FontWeight
std::vector< SpellPortion > SpellPortions
Definition: outliner.hxx:87
long Long
sal_Int16 nId
const char GetValue[]
#define OOO_STRING_SVTOOLS_RTF_SNEXT
#define OOO_STRING_SVTOOLS_RTF_F
#define OOO_STRING_SVTOOLS_RTF_TX
#define OOO_STRING_SVTOOLS_RTF_OUTL
#define OOO_STRING_SVTOOLS_RTF_OL
#define OOO_STRING_SVTOOLS_RTF_SB
#define OOO_STRING_SVTOOLS_RTF_SA
#define OOO_STRING_SVTOOLS_RTF_ACCCOMMA
#define OOO_STRING_SVTOOLS_RTF_OLNONE
#define OOO_STRING_SVTOOLS_RTF_QC
#define OOO_STRING_SVTOOLS_RTF_SL
#define OOO_STRING_SVTOOLS_RTF_RED
#define OOO_STRING_SVTOOLS_RTF_IMPR
#define OOO_STRING_SVTOOLS_RTF_B
#define OOO_STRING_SVTOOLS_RTF_S
#define OOO_STRING_SVTOOLS_RTF_ACCNONE
#define OOO_STRING_SVTOOLS_RTF_RTF
#define OOO_STRING_SVTOOLS_RTF_CF
#define OOO_STRING_SVTOOLS_RTF_KERNING
#define OOO_STRING_SVTOOLS_RTF_FI
#define OOO_STRING_SVTOOLS_RTF_SHAD
#define OOO_STRING_SVTOOLS_RTF_FROMAN
#define OOO_STRING_SVTOOLS_RTF_FS
#define OOO_STRING_SVTOOLS_RTF_FDECOR
#define OOO_STRING_SVTOOLS_RTF_ULD
#define OOO_STRING_SVTOOLS_RTF_STRIKE
#define OOO_STRING_SVTOOLS_RTF_UL
#define OOO_STRING_SVTOOLS_RTF_QL
#define OOO_STRING_SVTOOLS_RTF_PAR
#define OOO_STRING_SVTOOLS_RTF_SBASEDON
#define OOO_STRING_SVTOOLS_RTF_FSCRIPT
#define OOO_STRING_SVTOOLS_RTF_FCHARSET
#define OOO_STRING_SVTOOLS_RTF_QR
#define OOO_STRING_SVTOOLS_RTF_BLUE
#define OOO_STRING_SVTOOLS_RTF_ANSI
#define OOO_STRING_SVTOOLS_RTF_DEFTAB
#define OOO_STRING_SVTOOLS_RTF_DN
#define OOO_STRING_SVTOOLS_RTF_EXPNDTW
#define OOO_STRING_SVTOOLS_RTF_OLD
#define OOO_STRING_SVTOOLS_RTF_ACCDOT
#define OOO_STRING_SVTOOLS_RTF_STYLESHEET
#define OOO_STRING_SVTOOLS_RTF_UP
#define OOO_STRING_SVTOOLS_RTF_OLDB
#define OOO_STRING_SVTOOLS_RTF_FPRQ
#define OOO_STRING_SVTOOLS_RTF_GREEN
#define OOO_STRING_SVTOOLS_RTF_IGNORE
#define OOO_STRING_SVTOOLS_RTF_COLORTBL
#define OOO_STRING_SVTOOLS_RTF_FSWISS
#define OOO_STRING_SVTOOLS_RTF_FMODERN
#define OOO_STRING_SVTOOLS_RTF_PLAIN
#define OOO_STRING_SVTOOLS_RTF_ULDB
#define OOO_STRING_SVTOOLS_RTF_RI
#define OOO_STRING_SVTOOLS_RTF_SLMULT
#define OOO_STRING_SVTOOLS_RTF_ULNONE
#define OOO_STRING_SVTOOLS_RTF_LI
#define OOO_STRING_SVTOOLS_RTF_FONTTBL
#define OOO_STRING_SVTOOLS_RTF_EMBO
#define OOO_STRING_SVTOOLS_RTF_I
#define OOO_STRING_SVTOOLS_RTF_FNIL
#define OOO_STRING_SVTOOLS_RTF_TAB
#define OOO_STRING_SVTOOLS_RTF_PARD
TOOLS_DLLPUBLIC SvStream & endl(SvStream &rStr)
Definition: editdoc.hxx:56
sal_Int32 nIndex
Definition: editdoc.hxx:58
sal_Int32 nPara
Definition: editdoc.hxx:57
bool HasRange() const
Definition: editdata.hxx:151
EditLineList aLines
Definition: editobj2.hxx:87
TextPortionList aTextPortions
Definition: editobj2.hxx:88
tools::Long nHeight
Definition: editobj2.hxx:84
sal_uInt16 nFirstLineOffset
Definition: editobj2.hxx:85
LanguageType nLang
Definition: editdata.hxx:350
css::lang::Locale Locale
contains a portion of text that has the same language attributes applied and belongs to the same scri...
OUString sText
contains the text of the portion.
css::uno::Reference< css::linguistic2::XSpellAlternatives > xAlternatives
for wrong words this reference is filled with the error information otherwise it's an empty reference
bool bIsField
Marks the portion as field, footnote symbol or any other special content that should be protected aga...
LanguageType eLanguage
contains the language applied to the text.
SvParserState
SvxAdjust
Definition: svxenum.hxx:77
TransliterationFlags
sal_uInt16 sal_Unicode
Count
RET_OK
void SvxWriteXML(EditEngine &rEditEngine, SvStream &rStream, const ESelection &rSel)
this function exports the selected content of an edit engine into a xml stream
Definition: xmltxtexp.cxx:291
EditPaM SvxReadXML(EditEngine &rEditEngine, SvStream &rStream, const ESelection &rSel)
this function imports xml from the stream into the selected of an edit engine
Definition: xmltxtimp.cxx:132