Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <hintids.hxx>
21 : #include <editeng/tstpitem.hxx>
22 : #include <editeng/lrspitem.hxx>
23 : #include <editeng/scripttypeitem.hxx>
24 : #include <com/sun/star/i18n/ScriptType.hpp>
25 : #include <txatbase.hxx>
26 : #include <txtftn.hxx>
27 : #include <fmtftn.hxx>
28 : #include <editsh.hxx>
29 : #include <edimp.hxx>
30 : #include <doc.hxx>
31 : #include <swundo.hxx>
32 : #include <ndtxt.hxx>
33 : #include <ftnidx.hxx>
34 : #include <expfld.hxx>
35 : #include <rootfrm.hxx>
36 : #include <cntfrm.hxx>
37 : #include <breakit.hxx>
38 : #include <txtfld.hxx>
39 : #include <fmtfld.hxx>
40 : #include <crsskip.hxx>
41 : #include <txtfrm.hxx>
42 : #include <scriptinfo.hxx>
43 : #include <svl/ctloptions.hxx>
44 : #include <svl/itemiter.hxx>
45 : #include <charfmt.hxx>
46 : #include <numrule.hxx>
47 :
48 : #include <algorithm>
49 : #include <charatr.hxx>
50 :
51 : /*
52 : * hard Formatting (Attributes)
53 : */
54 :
55 : // if selection is bigger as max nodes or more than max selections
56 : // => no attributes
57 59108 : static inline sal_uInt16 getMaxLookup()
58 : {
59 59108 : return 1000;
60 : }
61 :
62 27858 : bool SwEditShell::GetPaMAttr( SwPaM* pPaM, SfxItemSet& rSet,
63 : const bool bMergeIndentValuesOfNumRule ) const
64 : {
65 : // ??? pPaM can be different from the Cursor ???
66 27858 : if( GetCrsrCnt() > getMaxLookup() )
67 : {
68 0 : rSet.InvalidateAllItems();
69 0 : return false;
70 : }
71 :
72 27858 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
73 27858 : SfxItemSet *pSet = &rSet;
74 :
75 55794 : for(SwPaM& rCurrentPaM : pPaM->GetRingContainer())
76 : {
77 : // #i27615# if the cursor is in front of the numbering label
78 : // the attributes to get are those from the numbering format.
79 27936 : if (rCurrentPaM.IsInFrontOfLabel())
80 : {
81 0 : SwTextNode * pTextNd = rCurrentPaM.GetPoint()->nNode.GetNode().GetTextNode();
82 :
83 0 : if (pTextNd)
84 : {
85 0 : SwNumRule * pNumRule = pTextNd->GetNumRule();
86 :
87 0 : if (pNumRule)
88 : {
89 0 : int nListLevel = pTextNd->GetActualListLevel();
90 :
91 0 : if (nListLevel < 0)
92 0 : nListLevel = 0;
93 :
94 0 : if (nListLevel >= MAXLEVEL)
95 0 : nListLevel = MAXLEVEL - 1;
96 :
97 : const OUString & aCharFormatName =
98 0 : pNumRule->Get(static_cast<sal_uInt16>(nListLevel)).GetCharFormatName();
99 : SwCharFormat * pCharFormat =
100 0 : GetDoc()->FindCharFormatByName(aCharFormatName);
101 :
102 0 : if (pCharFormat)
103 0 : rSet.Put(pCharFormat->GetAttrSet());
104 : }
105 : }
106 :
107 0 : continue;
108 : }
109 :
110 27936 : sal_uLong nSttNd = rCurrentPaM.GetMark()->nNode.GetIndex(),
111 27936 : nEndNd = rCurrentPaM.GetPoint()->nNode.GetIndex();
112 27936 : sal_Int32 nSttCnt = rCurrentPaM.GetMark()->nContent.GetIndex();
113 27936 : sal_Int32 nEndCnt = rCurrentPaM.GetPoint()->nContent.GetIndex();
114 :
115 27936 : if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
116 : {
117 33 : std::swap(nSttNd, nEndNd);
118 33 : std::swap(nSttCnt, nEndCnt);
119 : }
120 :
121 27936 : if( nEndNd - nSttNd >= getMaxLookup() )
122 : {
123 0 : rSet.ClearItem();
124 0 : rSet.InvalidateAllItems();
125 0 : return false;
126 : }
127 :
128 : // at first node the node enter his values into the GetSet (Initial)
129 : // all additional nodes are additional merged to GetSet
130 55972 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
131 : {
132 28036 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
133 28036 : switch( pNd->GetNodeType() )
134 : {
135 : case ND_TEXTNODE:
136 : {
137 28036 : const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
138 28036 : const sal_Int32 nEnd = (n == nEndNd)
139 : ? nEndCnt
140 28036 : : pNd->GetTextNode()->GetText().getLength();
141 :
142 : static_cast<SwTextNode*>(pNd)->GetAttr( *pSet, nStt, nEnd,
143 : false, true,
144 28036 : bMergeIndentValuesOfNumRule );
145 : }
146 28036 : break;
147 : case ND_GRFNODE:
148 : case ND_OLENODE:
149 0 : static_cast<SwContentNode*>(pNd)->GetAttr( *pSet );
150 0 : break;
151 :
152 : default:
153 0 : pNd = 0;
154 : }
155 :
156 28036 : if( pNd )
157 : {
158 28036 : if( pSet != &rSet )
159 178 : rSet.MergeValues( aSet );
160 :
161 28036 : if( aSet.Count() )
162 72 : aSet.ClearItem();
163 : }
164 28036 : pSet = &aSet;
165 : }
166 :
167 : }
168 :
169 27858 : return true;
170 : }
171 :
172 27858 : bool SwEditShell::GetCurAttr( SfxItemSet& rSet,
173 : const bool bMergeIndentValuesOfNumRule ) const
174 : {
175 27858 : return GetPaMAttr( GetCrsr(), rSet, bMergeIndentValuesOfNumRule );
176 : }
177 :
178 0 : bool SwEditShell::GetCurParAttr( SfxItemSet& rSet) const
179 : {
180 0 : return GetPaMParAttr( GetCrsr(), rSet );
181 : }
182 :
183 0 : bool SwEditShell::GetPaMParAttr( SwPaM* pPaM, SfxItemSet& rSet ) const
184 : {
185 : // number of nodes the function has explored so far
186 0 : sal_uInt16 numberOfLookup = 0;
187 :
188 0 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
189 0 : SfxItemSet* pSet = &rSet;
190 :
191 0 : for(SwPaM& rCurrentPaM : pPaM->GetRingContainer())
192 : { // for all the point and mark (selections)
193 :
194 : // get the start and the end node of the current selection
195 0 : sal_uLong nSttNd = rCurrentPaM.GetMark()->nNode.GetIndex(),
196 0 : nEndNd = rCurrentPaM.GetPoint()->nNode.GetIndex();
197 :
198 : // reverse start and end if there number aren't sorted correctly
199 0 : if( nSttNd > nEndNd )
200 0 : std::swap(nSttNd, nEndNd);
201 :
202 : // for all the nodes in the current selection
203 : // get the node (paragraph) attributes
204 : // and merge them in rSet
205 0 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
206 : {
207 : // get the node
208 0 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
209 :
210 0 : if( pNd->IsTextNode() )
211 : {
212 : // get the node (paragraph) attributes
213 0 : static_cast<SwContentNode*>(pNd)->GetAttr(*pSet);
214 :
215 0 : if( pSet != &rSet && aSet.Count() )
216 : {
217 0 : rSet.MergeValues( aSet );
218 0 : aSet.ClearItem();
219 : }
220 :
221 0 : pSet = &aSet;
222 : }
223 :
224 0 : ++numberOfLookup;
225 :
226 : // if the maximum number of node that can be inspected has been reached
227 0 : if (numberOfLookup >= getMaxLookup())
228 0 : return false;
229 : }
230 : }
231 :
232 0 : return true;
233 : }
234 :
235 3314 : SwTextFormatColl* SwEditShell::GetCurTextFormatColl( ) const
236 : {
237 3314 : return GetPaMTextFormatColl( GetCrsr() );
238 : }
239 :
240 3314 : SwTextFormatColl* SwEditShell::GetPaMTextFormatColl( SwPaM* pPaM ) const
241 : {
242 : // number of nodes the function have explored so far
243 3314 : sal_uInt16 numberOfLookup = 0;
244 :
245 6628 : for(SwPaM& rCurrentPaM : pPaM->GetRingContainer())
246 : { // for all the point and mark (selections)
247 :
248 : // get the start and the end node of the current selection
249 3314 : sal_uLong nSttNd = rCurrentPaM.GetMark()->nNode.GetIndex(),
250 3314 : nEndNd = rCurrentPaM.GetPoint()->nNode.GetIndex();
251 :
252 : // reverse start and end if they aren't sorted correctly
253 3314 : if( nSttNd > nEndNd )
254 0 : std::swap(nSttNd, nEndNd);
255 :
256 : // for all the nodes in the current Point and Mark
257 3314 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
258 : {
259 : // get the node
260 3314 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
261 :
262 3314 : ++numberOfLookup;
263 :
264 : // if the maximum number of node that can be inspected has been reached
265 3314 : if (numberOfLookup >= getMaxLookup())
266 3314 : return NULL;
267 :
268 3314 : if( pNd->IsTextNode() )
269 : {
270 : // if it's a text node get its named paragraph format
271 3314 : SwTextFormatColl* pFormat = pNd->GetTextNode()->GetTextColl();
272 :
273 : // if the paragraph format exist stop here and return it
274 3314 : if( pFormat != NULL )
275 3314 : return pFormat;
276 : }
277 : }
278 : }
279 :
280 : // if none of the selected node contain a named paragraph format
281 0 : return NULL;
282 : }
283 :
284 0 : std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> SwEditShell::GetItemWithPaM( sal_uInt16 nWhich )
285 : {
286 0 : std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> vItem;
287 0 : for(SwPaM& rCurrentPaM : GetCrsr()->GetRingContainer())
288 : { // for all the point and mark (selections)
289 :
290 : // get the start and the end node of the current selection
291 0 : sal_uLong nSttNd = rCurrentPaM.Start()->nNode.GetIndex(),
292 0 : nEndNd = rCurrentPaM.End()->nNode.GetIndex();
293 0 : sal_Int32 nSttCnt = rCurrentPaM.Start()->nContent.GetIndex();
294 0 : sal_Int32 nEndCnt = rCurrentPaM.End()->nContent.GetIndex();
295 :
296 0 : SwPaM* pNewPaM = 0;
297 0 : const SfxPoolItem* pItem = 0;
298 :
299 : // for all the nodes in the current selection
300 0 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
301 : {
302 0 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
303 0 : if( pNd->IsTextNode() )
304 : {
305 0 : SwTextNode* pTextNd = static_cast< SwTextNode* >( pNd );
306 0 : const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
307 : const sal_Int32 nEnd = (n == nEndNd)
308 0 : ? nEndCnt : pTextNd->GetText().getLength();
309 0 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTextNd );
310 0 : sal_uInt8 nScript = pScriptInfo ? pScriptInfo->ScriptType( nStt ) : css::i18n::ScriptType::WEAK;
311 0 : nWhich = GetWhichOfScript( nWhich, nScript );
312 :
313 : // item from attribute set
314 0 : if( pTextNd->HasSwAttrSet() )
315 : {
316 0 : pNewPaM = new SwPaM(*pNd, nStt, *pNd, nEnd);
317 0 : pItem = pTextNd->GetSwAttrSet().GetItem( nWhich );
318 0 : vItem.push_back( std::make_pair( pItem, std::unique_ptr<SwPaM>(pNewPaM) ) );
319 : }
320 :
321 0 : if( !pTextNd->HasHints() )
322 0 : continue;
323 :
324 : // items with limited range
325 0 : const size_t nSize = pTextNd->GetpSwpHints()->Count();
326 0 : for( size_t m = 0; m < nSize; m++ )
327 : {
328 0 : const SwTextAttr* pHt = (*pTextNd->GetpSwpHints())[m];
329 0 : if( pHt->Which() == RES_TXTATR_AUTOFMT ||
330 0 : pHt->Which() == RES_TXTATR_CHARFMT ||
331 0 : pHt->Which() == RES_TXTATR_INETFMT )
332 : {
333 0 : const sal_Int32 nAttrStart = pHt->GetStart();
334 0 : const sal_Int32* pAttrEnd = pHt->End();
335 :
336 : // Ignore items not in selection
337 0 : if( nAttrStart > nEnd )
338 0 : break;
339 0 : if( *pAttrEnd <= nStt )
340 0 : continue;
341 :
342 0 : nScript = pScriptInfo ? pScriptInfo->ScriptType( nStt ) : css::i18n::ScriptType::WEAK;
343 0 : nWhich = GetWhichOfScript( nWhich, nScript );
344 0 : const SfxItemSet* pAutoSet = CharFormat::GetItemSet( pHt->GetAttr() );
345 0 : if( pAutoSet )
346 : {
347 0 : SfxItemIter aItemIter( *pAutoSet );
348 0 : pItem = aItemIter.GetCurItem();
349 0 : while( pItem )
350 : {
351 0 : if( pItem->Which() == nWhich )
352 : {
353 0 : sal_Int32 nStart = 0, nStop = 0;
354 0 : if( nAttrStart < nStt ) //Attribut starts before selection
355 0 : nStart = nStt;
356 : else
357 0 : nStart = nAttrStart;
358 0 : if( *pAttrEnd > nEnd ) //Attribut ends after selection
359 0 : nStop = nEnd;
360 : else
361 0 : nStop = *pAttrEnd;
362 0 : pNewPaM = new SwPaM(*pNd, nStart, *pNd, nStop);
363 0 : vItem.push_back( std::make_pair( pItem, std::unique_ptr<SwPaM>(pNewPaM) ) );
364 0 : break;
365 : }
366 0 : pItem = aItemIter.NextItem();
367 : }
368 : // default item
369 0 : if( !pItem && !pTextNd->HasSwAttrSet() )
370 : {
371 0 : pNewPaM = new SwPaM(*pNd, nStt, *pNd, nEnd);
372 0 : pItem = pAutoSet->GetPool()->GetPoolDefaultItem( nWhich );
373 0 : vItem.push_back( std::make_pair( pItem, std::unique_ptr<SwPaM>(pNewPaM)) );
374 0 : }
375 : }
376 : }
377 : }
378 : }
379 : }
380 : }
381 0 : return vItem;
382 : }
383 :
384 0 : bool SwEditShell::GetCurFootnote( SwFormatFootnote* pFillFootnote )
385 : {
386 : // The cursor must be positioned on the current footnotes anchor:
387 0 : SwPaM* pCrsr = GetCrsr();
388 0 : SwTextNode* pTextNd = pCrsr->GetNode().GetTextNode();
389 0 : if( !pTextNd )
390 0 : return false;
391 :
392 : SwTextAttr *const pFootnote = pTextNd->GetTextAttrForCharAt(
393 0 : pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
394 0 : if( pFootnote && pFillFootnote )
395 : {
396 : // Transfer data from the attribute
397 0 : const SwFormatFootnote &rFootnote = static_cast<SwTextFootnote*>(pFootnote)->GetFootnote();
398 0 : pFillFootnote->SetNumber( rFootnote );
399 0 : pFillFootnote->SetEndNote( rFootnote.IsEndNote() );
400 : }
401 0 : return 0 != pFootnote;
402 : }
403 :
404 0 : bool SwEditShell::SetCurFootnote( const SwFormatFootnote& rFillFootnote )
405 : {
406 0 : bool bChgd = false;
407 0 : StartAllAction();
408 :
409 0 : for(SwPaM& rCrsr : GetCrsr()->GetRingContainer())
410 : {
411 : bChgd |=
412 0 : mpDoc->SetCurFootnote( rCrsr, rFillFootnote.GetNumStr(), rFillFootnote.GetNumber(), rFillFootnote.IsEndNote() );
413 :
414 : }
415 :
416 0 : EndAllAction();
417 0 : return bChgd;
418 : }
419 :
420 0 : bool SwEditShell::HasFootnotes( bool bEndNotes ) const
421 : {
422 0 : const SwFootnoteIdxs &rIdxs = mpDoc->GetFootnoteIdxs();
423 0 : for ( auto pIdx : rIdxs )
424 : {
425 0 : const SwFormatFootnote &rFootnote = pIdx->GetFootnote();
426 0 : if ( bEndNotes == rFootnote.IsEndNote() )
427 0 : return true;
428 : }
429 0 : return false;
430 : }
431 :
432 : /// Give a List of all footnotes and their beginning texts
433 0 : size_t SwEditShell::GetSeqFootnoteList( SwSeqFieldList& rList, bool bEndNotes )
434 : {
435 0 : rList.Clear();
436 :
437 0 : const size_t nFootnoteCnt = mpDoc->GetFootnoteIdxs().size();
438 : SwTextFootnote* pTextFootnote;
439 0 : for( size_t n = 0; n < nFootnoteCnt; ++n )
440 : {
441 0 : pTextFootnote = mpDoc->GetFootnoteIdxs()[ n ];
442 0 : const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
443 0 : if ( rFootnote.IsEndNote() != bEndNotes )
444 0 : continue;
445 :
446 0 : SwNodeIndex* pIdx = pTextFootnote->GetStartNode();
447 0 : if( pIdx )
448 : {
449 0 : SwNodeIndex aIdx( *pIdx, 1 );
450 0 : SwTextNode* pTextNd = aIdx.GetNode().GetTextNode();
451 0 : if( !pTextNd )
452 0 : pTextNd = static_cast<SwTextNode*>(mpDoc->GetNodes().GoNext( &aIdx ));
453 :
454 0 : if( pTextNd )
455 : {
456 0 : OUString sText( rFootnote.GetViewNumStr( *mpDoc ));
457 0 : if( !sText.isEmpty() )
458 0 : sText += " ";
459 0 : sText += pTextNd->GetExpandText( 0, -1 );
460 :
461 : _SeqFieldLstElem* pNew = new _SeqFieldLstElem( sText,
462 0 : pTextFootnote->GetSeqRefNo() );
463 0 : while( rList.InsertSort( pNew ) )
464 0 : pNew->sDlgEntry += " ";
465 0 : }
466 : }
467 : }
468 :
469 0 : return rList.Count();
470 : }
471 :
472 : /// Adjust left margin via object bar (similar to adjustment of numerations).
473 1698 : bool SwEditShell::IsMoveLeftMargin( bool bRight, bool bModulus ) const
474 : {
475 1698 : bool bRet = true;
476 :
477 : const SvxTabStopItem& rTabItem = static_cast<const SvxTabStopItem&>(GetDoc()->
478 1698 : GetDefault( RES_PARATR_TABSTOP ));
479 1698 : sal_uInt16 nDefDist = static_cast<sal_uInt16>(rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134);
480 1698 : if( !nDefDist )
481 0 : return false;
482 :
483 3420 : for(SwPaM& rPaM : GetCrsr()->GetRingContainer())
484 : {
485 1722 : sal_uLong nSttNd = rPaM.GetMark()->nNode.GetIndex(),
486 1722 : nEndNd = rPaM.GetPoint()->nNode.GetIndex();
487 :
488 1722 : if( nSttNd > nEndNd )
489 0 : std::swap(nSttNd, nEndNd);
490 :
491 : SwContentNode* pCNd;
492 3464 : for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n )
493 1742 : if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTextNode() ))
494 : {
495 : const SvxLRSpaceItem& rLS = static_cast<const SvxLRSpaceItem&>(
496 1742 : pCNd->GetAttr( RES_LR_SPACE ));
497 1742 : if( bRight )
498 : {
499 871 : long nNext = rLS.GetTextLeft() + nDefDist;
500 871 : if( bModulus )
501 871 : nNext = ( nNext / nDefDist ) * nDefDist;
502 871 : SwFrm* pFrm = pCNd->getLayoutFrm( GetLayout() );
503 871 : if ( pFrm )
504 : {
505 871 : const sal_uInt16 nFrmWidth = static_cast<sal_uInt16>( pFrm->IsVertical() ?
506 0 : pFrm->Frm().Height() :
507 871 : pFrm->Frm().Width() );
508 871 : bRet = nFrmWidth > ( nNext + MM50 );
509 : }
510 : else
511 0 : bRet = false;
512 : }
513 : }
514 :
515 1722 : if( !bRet )
516 0 : break;
517 :
518 : }
519 1698 : return bRet;
520 : }
521 :
522 0 : void SwEditShell::MoveLeftMargin( bool bRight, bool bModulus )
523 : {
524 0 : StartAllAction();
525 0 : StartUndo( UNDO_START );
526 :
527 0 : SwPaM* pCrsr = GetCrsr();
528 0 : if( pCrsr->GetNext() != pCrsr ) // Multiple selection ?
529 : {
530 0 : SwPamRanges aRangeArr( *pCrsr );
531 0 : SwPaM aPam( *pCrsr->GetPoint() );
532 0 : for( SwPamRanges::size_type n = 0; n < aRangeArr.Count(); ++n )
533 0 : GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ),
534 0 : bRight, bModulus );
535 : }
536 : else
537 0 : GetDoc()->MoveLeftMargin( *pCrsr, bRight, bModulus );
538 :
539 0 : EndUndo( UNDO_END );
540 0 : EndAllAction();
541 0 : }
542 :
543 6514 : static inline SvtScriptType lcl_SetScriptFlags( sal_uInt16 nType )
544 : {
545 6514 : switch( nType )
546 : {
547 : case ::com::sun::star::i18n::ScriptType::LATIN:
548 6512 : return SvtScriptType::LATIN;
549 : case ::com::sun::star::i18n::ScriptType::ASIAN:
550 2 : return SvtScriptType::ASIAN;
551 : case ::com::sun::star::i18n::ScriptType::COMPLEX:
552 0 : return SvtScriptType::COMPLEX;
553 : default:
554 0 : return SvtScriptType::NONE;
555 : }
556 : }
557 :
558 7167 : static bool lcl_IsNoEndTextAttrAtPos( const SwTextNode& rTNd, sal_Int32 nPos,
559 : SvtScriptType &rScrpt, bool bInSelection, bool bNum )
560 : {
561 7167 : bool bRet = false;
562 7167 : OUString sExp;
563 :
564 : // consider numbering
565 7167 : if ( bNum )
566 : {
567 64 : bRet = false;
568 :
569 64 : if ( rTNd.IsInList() )
570 : {
571 : OSL_ENSURE( rTNd.GetNumRule(),
572 : "<lcl_IsNoEndTextAttrAtPos(..)> - no list style found at text node. Serious defect -> please inform OD." );
573 0 : const SwNumRule* pNumRule = rTNd.GetNumRule();
574 0 : if(pNumRule)
575 : {
576 0 : int nListLevel = rTNd.GetActualListLevel();
577 :
578 0 : if (nListLevel < 0)
579 0 : nListLevel = 0;
580 :
581 0 : if (nListLevel >= MAXLEVEL)
582 0 : nListLevel = MAXLEVEL - 1;
583 :
584 0 : const SwNumFormat &rNumFormat = pNumRule->Get( static_cast<sal_uInt16>(nListLevel) );
585 0 : if( SVX_NUM_BITMAP != rNumFormat.GetNumberingType() )
586 : {
587 0 : if ( SVX_NUM_CHAR_SPECIAL == rNumFormat.GetNumberingType() )
588 0 : sExp = OUString(rNumFormat.GetBulletChar());
589 : else
590 0 : sExp = rTNd.GetNumString();
591 : }
592 : }
593 : }
594 : }
595 :
596 : // and fields
597 7167 : if (nPos < rTNd.GetText().getLength() && CH_TXTATR_BREAKWORD == rTNd.GetText()[nPos])
598 : {
599 653 : const SwTextAttr* const pAttr = rTNd.GetTextAttrForCharAt( nPos );
600 653 : if (pAttr)
601 : {
602 653 : bRet = true; // all other than fields can be
603 : // defined as weak-script ?
604 653 : if ( RES_TXTATR_FIELD == pAttr->Which() )
605 : {
606 5 : const SwField* const pField = pAttr->GetFormatField().GetField();
607 5 : if (pField)
608 : {
609 5 : sExp += pField->ExpandField(true);
610 : }
611 : }
612 : }
613 : }
614 :
615 7167 : const sal_Int32 nEnd = sExp.getLength();
616 7167 : if ( nEnd )
617 : {
618 0 : if( bInSelection )
619 : {
620 : sal_uInt16 nScript;
621 0 : for( sal_Int32 n = 0; n < nEnd;
622 0 : n = g_pBreakIt->GetBreakIter()->endOfScript( sExp, n, nScript ))
623 : {
624 0 : nScript = g_pBreakIt->GetBreakIter()->getScriptType( sExp, n );
625 0 : rScrpt |= lcl_SetScriptFlags( nScript );
626 : }
627 : }
628 : else
629 0 : rScrpt |= lcl_SetScriptFlags( g_pBreakIt->GetBreakIter()->
630 0 : getScriptType( sExp, nEnd-1 ));
631 : }
632 :
633 7167 : return bRet;
634 : }
635 :
636 : /// returns the script type of the selection
637 7080 : SvtScriptType SwEditShell::GetScriptType() const
638 : {
639 7080 : SvtScriptType nRet = SvtScriptType::NONE;
640 :
641 : {
642 14202 : for(SwPaM& rPaM : GetCrsr()->GetRingContainer())
643 : {
644 7122 : const SwPosition *pStt = rPaM.Start(),
645 7122 : *pEnd = pStt == rPaM.GetMark()
646 : ? rPaM.GetPoint()
647 7122 : : rPaM.GetMark();
648 7122 : if( pStt == pEnd || *pStt == *pEnd )
649 : {
650 7103 : const SwTextNode* pTNd = pStt->nNode.GetNode().GetTextNode();
651 7103 : if( pTNd )
652 : {
653 : // try to get SwScriptInfo
654 7103 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
655 :
656 7103 : sal_Int32 nPos = pStt->nContent.GetIndex();
657 : //Task 90448: we need the scripttype of the previous
658 : // position, if no selection exist!
659 7103 : if( nPos )
660 : {
661 1721 : SwIndex aIdx( pStt->nContent );
662 1721 : if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) )
663 1721 : nPos = aIdx.GetIndex();
664 : }
665 :
666 : sal_uInt16 nScript;
667 :
668 7103 : if (!pTNd->GetText().isEmpty())
669 : {
670 : nScript = pScriptInfo ?
671 1776 : pScriptInfo->ScriptType( nPos ) :
672 3552 : g_pBreakIt->GetBreakIter()->getScriptType( pTNd->GetText(), nPos );
673 : }
674 : else
675 5327 : nScript = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
676 :
677 7103 : if( !lcl_IsNoEndTextAttrAtPos( *pTNd, nPos, nRet, false, false ))
678 6450 : nRet |= lcl_SetScriptFlags( nScript );
679 : }
680 : }
681 19 : else if ( g_pBreakIt->GetBreakIter().is() )
682 : {
683 19 : sal_uLong nEndIdx = pEnd->nNode.GetIndex();
684 19 : SwNodeIndex aIdx( pStt->nNode );
685 88 : for( ; aIdx.GetIndex() <= nEndIdx; ++aIdx )
686 69 : if( aIdx.GetNode().IsTextNode() )
687 : {
688 69 : const SwTextNode* pTNd = aIdx.GetNode().GetTextNode();
689 69 : const OUString& rText = pTNd->GetText();
690 :
691 : // try to get SwScriptInfo
692 69 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
693 :
694 69 : sal_Int32 nChg = aIdx == pStt->nNode
695 19 : ? pStt->nContent.GetIndex()
696 88 : : 0;
697 69 : sal_Int32 nEndPos = aIdx == nEndIdx
698 19 : ? pEnd->nContent.GetIndex()
699 88 : : rText.getLength();
700 :
701 : OSL_ENSURE( nEndPos <= rText.getLength(),
702 : "Index outside the range - endless loop!" );
703 69 : if (nEndPos > rText.getLength())
704 0 : nEndPos = rText.getLength();
705 :
706 : sal_uInt16 nScript;
707 202 : while( nChg < nEndPos )
708 : {
709 : nScript = pScriptInfo ?
710 64 : pScriptInfo->ScriptType( nChg ) :
711 64 : g_pBreakIt->GetBreakIter()->getScriptType(
712 192 : rText, nChg );
713 :
714 64 : if( !lcl_IsNoEndTextAttrAtPos( *pTNd, nChg, nRet, true,
715 64 : 0 == nChg && rText.getLength() == nEndPos))
716 64 : nRet |= lcl_SetScriptFlags( nScript );
717 :
718 128 : if( (SvtScriptType::LATIN | SvtScriptType::ASIAN |
719 128 : SvtScriptType::COMPLEX) == nRet )
720 0 : break;
721 :
722 64 : sal_Int32 nFieldPos = nChg+1;
723 :
724 : nChg = pScriptInfo ?
725 : pScriptInfo->NextScriptChg( nChg ) :
726 64 : g_pBreakIt->GetBreakIter()->endOfScript(
727 128 : rText, nChg, nScript );
728 :
729 : nFieldPos = rText.indexOf(
730 64 : CH_TXTATR_BREAKWORD, nFieldPos);
731 64 : if ((-1 != nFieldPos) && (nFieldPos < nChg))
732 0 : nChg = nFieldPos;
733 : }
734 138 : if( (SvtScriptType::LATIN | SvtScriptType::ASIAN |
735 138 : SvtScriptType::COMPLEX) == nRet )
736 0 : break;
737 19 : }
738 : }
739 14244 : if( (SvtScriptType::LATIN | SvtScriptType::ASIAN |
740 14244 : SvtScriptType::COMPLEX) == nRet )
741 0 : break;
742 :
743 : }
744 : }
745 7080 : if( nRet == SvtScriptType::NONE )
746 653 : nRet = SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM );
747 7080 : return nRet;
748 : }
749 :
750 0 : sal_uInt16 SwEditShell::GetCurLang() const
751 : {
752 0 : const SwPaM* pCrsr = GetCrsr();
753 0 : const SwPosition& rPos = *pCrsr->GetPoint();
754 0 : const SwTextNode* pTNd = rPos.nNode.GetNode().GetTextNode();
755 : sal_uInt16 nLang;
756 0 : if( pTNd )
757 : {
758 : //JP 24.9.2001: if exist no selection, then get the language before
759 : // the current character!
760 0 : sal_Int32 nPos = rPos.nContent.GetIndex();
761 0 : if( nPos && !pCrsr->HasMark() )
762 0 : --nPos;
763 0 : nLang = pTNd->GetLang( nPos );
764 : }
765 : else
766 0 : nLang = LANGUAGE_DONTKNOW;
767 0 : return nLang;
768 : }
769 :
770 0 : sal_uInt16 SwEditShell::GetScalingOfSelectedText() const
771 : {
772 0 : const SwPaM* pCrsr = GetCrsr();
773 0 : const SwPosition* pStt = pCrsr->Start();
774 0 : const SwTextNode* pTNd = pStt->nNode.GetNode().GetTextNode();
775 : OSL_ENSURE( pTNd, "no textnode available" );
776 :
777 : sal_uInt16 nScaleWidth;
778 0 : if( pTNd )
779 : {
780 0 : const SwPosition* pEnd = pStt == pCrsr->GetPoint()
781 : ? pCrsr->GetMark()
782 0 : : pCrsr->GetPoint();
783 0 : const sal_Int32 nStt = pStt->nContent.GetIndex();
784 0 : const sal_Int32 nEnd = pStt->nNode == pEnd->nNode
785 0 : ? pEnd->nContent.GetIndex()
786 0 : : pTNd->GetText().getLength();
787 0 : nScaleWidth = pTNd->GetScalingOfSelectedText( nStt, nEnd );
788 : }
789 : else
790 0 : nScaleWidth = 100; // default are no scaling -> 100%
791 0 : return nScaleWidth;
792 177 : }
793 :
794 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|