Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / tool / editutil.cxx
blob27fdf89118621b2ea75c89be06e7207ed36579ee
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <comphelper/string.hxx>
22 #include <editeng/eeitem.hxx>
24 #include <svx/algitem.hxx>
25 #include <svtools/colorcfg.hxx>
26 #include <editeng/editview.hxx>
27 #include <editeng/editstat.hxx>
28 #include <editeng/escapementitem.hxx>
29 #include <editeng/flditem.hxx>
30 #include <editeng/numitem.hxx>
31 #include <editeng/justifyitem.hxx>
32 #include <editeng/editobj.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/outdev.hxx>
35 #include <svl/inethist.hxx>
36 #include <unotools/syslocale.hxx>
38 #include <com/sun/star/text/textfield/Type.hpp>
39 #include <com/sun/star/document/XDocumentProperties.hpp>
41 #include "editutil.hxx"
42 #include "global.hxx"
43 #include "attrib.hxx"
44 #include "document.hxx"
45 #include "docpool.hxx"
46 #include "patattr.hxx"
47 #include "scmod.hxx"
48 #include "inputopt.hxx"
49 #include "compiler.hxx"
51 using namespace com::sun::star;
53 // STATIC DATA
54 // Delimiters zusaetzlich zu EditEngine-Default:
56 const sal_Char ScEditUtil::pCalcDelimiters[] = "=()+-*/^&<>";
58 OUString ScEditUtil::ModifyDelimiters( const OUString& rOld )
60 // underscore is used in function argument names
61 OUString aRet = OUString( comphelper::string::remove(rOld, '_') ) +
62 OUString::createFromAscii( pCalcDelimiters ) +
63 ScCompiler::GetNativeSymbol(ocSep); // argument separator is localized.
64 return aRet;
67 static OUString lcl_GetDelimitedString( const EditEngine& rEngine, const sal_Char c )
69 sal_Int32 nParCount = rEngine.GetParagraphCount();
70 OUStringBuffer aRet( nParCount * 80 );
71 for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
73 if (nPar > 0)
74 aRet.append(c);
75 aRet.append( rEngine.GetText( nPar ));
77 return aRet.makeStringAndClear();
80 static OUString lcl_GetDelimitedString( const EditTextObject& rEdit, const sal_Char c )
82 sal_Int32 nParCount = rEdit.GetParagraphCount();
83 OUStringBuffer aRet( nParCount * 80 );
84 for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
86 if (nPar > 0)
87 aRet.append(c);
88 aRet.append( rEdit.GetText( nPar ));
90 return aRet.makeStringAndClear();
93 OUString ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine )
95 return lcl_GetDelimitedString(rEngine, ' ');
98 OUString ScEditUtil::GetSpaceDelimitedString( const EditTextObject& rEdit )
100 return lcl_GetDelimitedString(rEdit, ' ');
103 OUString ScEditUtil::GetMultilineString( const EditEngine& rEngine )
105 return lcl_GetDelimitedString(rEngine, '\n');
108 OUString ScEditUtil::GetMultilineString( const EditTextObject& rEdit )
110 return lcl_GetDelimitedString(rEdit, '\n');
113 OUString ScEditUtil::GetString( const EditTextObject& rEditText, const ScDocument* pDoc )
115 // ScFieldEditEngine is needed to resolve field contents.
116 if (pDoc)
118 /* TODO: make ScDocument::GetEditEngine() const? Most likely it's only
119 * not const because of the pointer assignment, make that mutable, and
120 * then remove the ugly const_cast here. */
121 EditEngine& rEE = const_cast<ScDocument*>(pDoc)->GetEditEngine();
122 rEE.SetText( rEditText);
123 return GetMultilineString( rEE);
125 else
127 static osl::Mutex aMutex;
128 osl::MutexGuard aGuard( aMutex);
129 EditEngine& rEE = ScGlobal::GetStaticFieldEditEngine();
130 rEE.SetText( rEditText);
131 return GetMultilineString( rEE);
135 EditTextObject* ScEditUtil::CreateURLObjectFromURL( ScDocument& rDoc, const OUString& rURL, const OUString& rText )
137 SvxURLField aUrlField( rURL, rText, SVXURLFORMAT_APPDEFAULT);
138 EditEngine& rEE = rDoc.GetEditEngine();
139 rEE.SetText( EMPTY_OUSTRING );
140 rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ),
141 ESelection( EE_PARA_MAX_COUNT, EE_TEXTPOS_MAX_COUNT ) );
143 return rEE.CreateTextObject();
146 void ScEditUtil::RemoveCharAttribs( EditTextObject& rEditText, const ScPatternAttr& rAttr )
148 const struct {
149 sal_uInt16 nAttrType;
150 sal_uInt16 nCharType;
151 } AttrTypeMap[] = {
152 { ATTR_FONT, EE_CHAR_FONTINFO },
153 { ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT },
154 { ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT },
155 { ATTR_FONT_COLOR, EE_CHAR_COLOR }
157 sal_uInt16 nMapCount = sizeof (AttrTypeMap) / sizeof (AttrTypeMap[0]);
159 const SfxItemSet& rSet = rAttr.GetItemSet();
160 const SfxPoolItem* pItem;
161 for (sal_uInt16 i = 0; i < nMapCount; ++i)
163 if ( rSet.GetItemState(AttrTypeMap[i].nAttrType, false, &pItem) == SFX_ITEM_SET )
164 rEditText.RemoveCharAttribs(AttrTypeMap[i].nCharType);
168 EditTextObject* ScEditUtil::Clone( const EditTextObject& rObj, ScDocument& rDestDoc )
170 EditTextObject* pNew = NULL;
172 EditEngine& rEngine = rDestDoc.GetEditEngine();
173 if (rObj.HasOnlineSpellErrors())
175 sal_uLong nControl = rEngine.GetControlWord();
176 const sal_uLong nSpellControl = EE_CNTRL_ONLINESPELLING | EE_CNTRL_ALLOWBIGOBJS;
177 bool bNewControl = ( (nControl & nSpellControl) != nSpellControl );
178 if (bNewControl)
179 rEngine.SetControlWord(nControl | nSpellControl);
180 rEngine.SetText(rObj);
181 pNew = rEngine.CreateTextObject();
182 if (bNewControl)
183 rEngine.SetControlWord(nControl);
185 else
187 rEngine.SetText(rObj);
188 pNew = rEngine.CreateTextObject();
191 return pNew;
194 OUString ScEditUtil::GetCellFieldValue(
195 const SvxFieldData& rFieldData, const ScDocument* pDoc, Color** ppTextColor )
197 OUString aRet;
198 switch (rFieldData.GetClassId())
200 case text::textfield::Type::URL:
202 const SvxURLField& rField = static_cast<const SvxURLField&>(rFieldData);
203 OUString aURL = rField.GetURL();
205 switch (rField.GetFormat())
207 case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
208 case SVXURLFORMAT_REPR:
209 aRet = rField.GetRepresentation();
210 break;
211 case SVXURLFORMAT_URL:
212 aRet = aURL;
213 break;
214 default:
218 svtools::ColorConfigEntry eEntry =
219 INetURLHistory::GetOrCreate()->QueryUrl(aURL) ? svtools::LINKSVISITED : svtools::LINKS;
221 if (ppTextColor)
222 *ppTextColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
224 break;
225 case text::textfield::Type::EXTENDED_TIME:
227 const SvxExtTimeField& rField = static_cast<const SvxExtTimeField&>(rFieldData);
228 if (pDoc)
229 aRet = rField.GetFormatted(*pDoc->GetFormatTable(), ScGlobal::eLnge);
230 else
232 /* TODO: quite expensive, we could have a global formatter? */
233 SvNumberFormatter aFormatter( comphelper::getProcessComponentContext(), ScGlobal::eLnge );
234 aRet = rField.GetFormatted(aFormatter, ScGlobal::eLnge);
237 break;
238 case text::textfield::Type::DATE:
240 Date aDate(Date::SYSTEM);
241 aRet = ScGlobal::pLocaleData->getDate(aDate);
243 break;
244 case text::textfield::Type::DOCINFO_TITLE:
246 if (pDoc)
248 SfxObjectShell* pDocShell = pDoc->GetDocumentShell();
249 if (pDocShell)
251 aRet = pDocShell->getDocProperties()->getTitle();
252 if (aRet.isEmpty())
253 aRet = pDocShell->GetTitle();
256 if (aRet.isEmpty())
257 aRet = "?";
259 break;
260 case text::textfield::Type::TABLE:
262 const SvxTableField& rField = static_cast<const SvxTableField&>(rFieldData);
263 SCTAB nTab = rField.GetTab();
264 OUString aName;
265 if (pDoc && pDoc->GetName(nTab, aName))
266 aRet = aName;
267 else
268 aRet = "?";
270 break;
271 default:
272 aRet = "?";
275 if (aRet.isEmpty()) // leer ist baeh
276 aRet = " "; // Space ist Default der Editengine
278 return aRet;
281 Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, sal_Bool bForceToTop )
283 // bForceToTop = always align to top, for editing
284 // (sal_False for querying URLs etc.)
286 if (!pPattern)
287 pPattern = pDoc->GetPattern( nCol, nRow, nTab );
289 Point aStartPos = aScrPos;
291 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
292 long nLayoutSign = bLayoutRTL ? -1 : 1;
294 const ScMergeAttr* pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
295 long nCellX = (long) ( pDoc->GetColWidth(nCol,nTab) * nPPTX );
296 if ( pMerge->GetColMerge() > 1 )
298 SCCOL nCountX = pMerge->GetColMerge();
299 for (SCCOL i=1; i<nCountX; i++)
300 nCellX += (long) ( pDoc->GetColWidth(nCol+i,nTab) * nPPTX );
302 long nCellY = (long) ( pDoc->GetRowHeight(nRow,nTab) * nPPTY );
303 if ( pMerge->GetRowMerge() > 1 )
305 SCROW nCountY = pMerge->GetRowMerge();
306 nCellY += (long) pDoc->GetScaledRowHeight( nRow+1, nRow+nCountY-1, nTab, nPPTY);
309 const SvxMarginItem* pMargin = (const SvxMarginItem*)&pPattern->GetItem(ATTR_MARGIN);
310 sal_uInt16 nIndent = 0;
311 if ( ((const SvxHorJustifyItem&)pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue() ==
312 SVX_HOR_JUSTIFY_LEFT )
313 nIndent = ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue();
314 long nPixDifX = (long) ( ( pMargin->GetLeftMargin() + nIndent ) * nPPTX );
315 aStartPos.X() += nPixDifX * nLayoutSign;
316 nCellX -= nPixDifX + (long) ( pMargin->GetRightMargin() * nPPTX ); // wegen Umbruch etc.
318 // vertikale Position auf die in der Tabelle anpassen
320 long nPixDifY;
321 long nTopMargin = (long) ( pMargin->GetTopMargin() * nPPTY );
322 SvxCellVerJustify eJust = (SvxCellVerJustify) ((const SvxVerJustifyItem&)pPattern->
323 GetItem(ATTR_VER_JUSTIFY)).GetValue();
325 // asian vertical is always edited top-aligned
326 sal_Bool bAsianVertical = ((const SfxBoolItem&)pPattern->GetItem( ATTR_STACKED )).GetValue() &&
327 ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
329 if ( eJust == SVX_VER_JUSTIFY_TOP ||
330 ( bForceToTop && ( SC_MOD()->GetInputOptions().GetTextWysiwyg() || bAsianVertical ) ) )
331 nPixDifY = nTopMargin;
332 else
334 MapMode aMode = pDev->GetMapMode();
335 pDev->SetMapMode( MAP_PIXEL );
337 long nTextHeight = pDoc->GetNeededSize( nCol, nRow, nTab,
338 pDev, nPPTX, nPPTY, aZoomX, aZoomY, false );
339 if (!nTextHeight)
340 { // leere Zelle
341 Font aFont;
342 // font color doesn't matter here
343 pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aZoomY );
344 pDev->SetFont(aFont);
345 nTextHeight = pDev->GetTextHeight() + nTopMargin +
346 (long) ( pMargin->GetBottomMargin() * nPPTY );
349 pDev->SetMapMode(aMode);
351 if ( nTextHeight > nCellY + nTopMargin || bForceToTop )
352 nPixDifY = 0; // zu gross -> oben anfangen
353 else
355 if ( eJust == SVX_VER_JUSTIFY_CENTER )
356 nPixDifY = nTopMargin + ( nCellY - nTextHeight ) / 2;
357 else
358 nPixDifY = nCellY - nTextHeight + nTopMargin; // JUSTIFY_BOTTOM
362 aStartPos.Y() += nPixDifY;
363 nCellY -= nPixDifY;
365 if ( bLayoutRTL )
366 aStartPos.X() -= nCellX - 2; // excluding grid on both sides
368 // -1 -> Gitter nicht ueberschreiben
369 return Rectangle( aStartPos, Size(nCellX-1,nCellY-1) );
372 ScEditAttrTester::ScEditAttrTester( ScEditEngineDefaulter* pEng ) :
373 pEngine( pEng ),
374 pEditAttrs( NULL ),
375 bNeedsObject( false ),
376 bNeedsCellAttr( false )
378 if ( pEngine->GetParagraphCount() > 1 )
380 bNeedsObject = sal_True; //! Zellatribute finden ?
382 else
384 const SfxPoolItem* pItem = NULL;
385 pEditAttrs = new SfxItemSet( pEngine->GetAttribs(
386 ESelection(0,0,0,pEngine->GetTextLen(0)), EditEngineAttribs_OnlyHard ) );
387 const SfxItemSet& rEditDefaults = pEngine->GetDefaults();
389 for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++)
391 SfxItemState eState = pEditAttrs->GetItemState( nId, false, &pItem );
392 if (eState == SFX_ITEM_DONTCARE)
393 bNeedsObject = sal_True;
394 else if (eState == SFX_ITEM_SET)
396 if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
397 nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
399 // Escapement and kerning are kept in EditEngine because there are no
400 // corresponding cell format items. User defined attributes are kept in
401 // EditEngine because "user attributes applied to all the text" is different
402 // from "user attributes applied to the cell".
404 if ( *pItem != rEditDefaults.Get(nId) )
405 bNeedsObject = sal_True;
407 else
408 if (!bNeedsCellAttr)
409 if ( *pItem != rEditDefaults.Get(nId) )
410 bNeedsCellAttr = sal_True;
411 // rEditDefaults contains the defaults from the cell format
415 // Feldbefehle enthalten?
417 SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, false );
418 if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
419 bNeedsObject = sal_True;
421 // not converted characters?
423 SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, false );
424 if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
425 bNeedsObject = sal_True;
429 ScEditAttrTester::~ScEditAttrTester()
431 delete pEditAttrs;
434 ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP,
435 sal_Bool bDeleteEnginePoolP )
437 pEnginePool( pEnginePoolP ),
438 pDefaults( NULL ),
439 bDeleteEnginePool( bDeleteEnginePoolP ),
440 bDeleteDefaults( false )
444 ScEnginePoolHelper::ScEnginePoolHelper( const ScEnginePoolHelper& rOrg )
446 pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ),
447 pDefaults( NULL ),
448 bDeleteEnginePool( rOrg.bDeleteEnginePool ),
449 bDeleteDefaults( false )
453 ScEnginePoolHelper::~ScEnginePoolHelper()
455 if ( bDeleteDefaults )
456 delete pDefaults;
457 if ( bDeleteEnginePool )
458 SfxItemPool::Free(pEnginePool);
461 ScEditEngineDefaulter::ScEditEngineDefaulter( SfxItemPool* pEnginePoolP,
462 sal_Bool bDeleteEnginePoolP )
464 ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ),
465 EditEngine( pEnginePoolP )
467 // All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage.
468 // DefaultLanguage for InputHandler's EditEngine is updated later.
470 SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
473 ScEditEngineDefaulter::ScEditEngineDefaulter( const ScEditEngineDefaulter& rOrg )
475 ScEnginePoolHelper( rOrg ),
476 EditEngine( pEnginePool )
478 SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
481 ScEditEngineDefaulter::~ScEditEngineDefaulter()
485 void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, sal_Bool bRememberCopy )
487 if ( bRememberCopy )
489 if ( bDeleteDefaults )
490 delete pDefaults;
491 pDefaults = new SfxItemSet( rSet );
492 bDeleteDefaults = sal_True;
494 const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
495 sal_Bool bUndo = IsUndoEnabled();
496 EnableUndo( false );
497 sal_Bool bUpdateMode = GetUpdateMode();
498 if ( bUpdateMode )
499 SetUpdateMode( false );
500 sal_Int32 nPara = GetParagraphCount();
501 for ( sal_Int32 j=0; j<nPara; j++ )
503 SetParaAttribs( j, rNewSet );
505 if ( bUpdateMode )
506 SetUpdateMode( sal_True );
507 if ( bUndo )
508 EnableUndo( sal_True );
511 void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, sal_Bool bTakeOwnership )
513 if ( bDeleteDefaults )
514 delete pDefaults;
515 pDefaults = pSet;
516 bDeleteDefaults = bTakeOwnership;
517 if ( pDefaults )
518 SetDefaults( *pDefaults, false );
521 void ScEditEngineDefaulter::SetDefaultItem( const SfxPoolItem& rItem )
523 if ( !pDefaults )
525 pDefaults = new SfxItemSet( GetEmptyItemSet() );
526 bDeleteDefaults = sal_True;
528 pDefaults->Put( rItem );
529 SetDefaults( *pDefaults, false );
532 const SfxItemSet& ScEditEngineDefaulter::GetDefaults()
534 if ( !pDefaults )
536 pDefaults = new SfxItemSet( GetEmptyItemSet() );
537 bDeleteDefaults = sal_True;
539 return *pDefaults;
542 void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject )
544 sal_Bool bUpdateMode = GetUpdateMode();
545 if ( bUpdateMode )
546 SetUpdateMode( false );
547 EditEngine::SetText( rTextObject );
548 if ( pDefaults )
549 SetDefaults( *pDefaults, false );
550 if ( bUpdateMode )
551 SetUpdateMode( sal_True );
554 void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
555 const SfxItemSet& rSet, sal_Bool bRememberCopy )
557 sal_Bool bUpdateMode = GetUpdateMode();
558 if ( bUpdateMode )
559 SetUpdateMode( false );
560 EditEngine::SetText( rTextObject );
561 SetDefaults( rSet, bRememberCopy );
562 if ( bUpdateMode )
563 SetUpdateMode( sal_True );
566 void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
567 SfxItemSet* pSet, sal_Bool bTakeOwnership )
569 sal_Bool bUpdateMode = GetUpdateMode();
570 if ( bUpdateMode )
571 SetUpdateMode( false );
572 EditEngine::SetText( rTextObject );
573 SetDefaults( pSet, bTakeOwnership );
574 if ( bUpdateMode )
575 SetUpdateMode( sal_True );
578 void ScEditEngineDefaulter::SetText( const OUString& rText )
580 sal_Bool bUpdateMode = GetUpdateMode();
581 if ( bUpdateMode )
582 SetUpdateMode( false );
583 EditEngine::SetText( rText );
584 if ( pDefaults )
585 SetDefaults( *pDefaults, false );
586 if ( bUpdateMode )
587 SetUpdateMode( sal_True );
590 void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
591 const SfxItemSet& rSet, sal_Bool bRememberCopy )
593 sal_Bool bUpdateMode = GetUpdateMode();
594 if ( bUpdateMode )
595 SetUpdateMode( false );
596 EditEngine::SetText( rText );
597 SetDefaults( rSet, bRememberCopy );
598 if ( bUpdateMode )
599 SetUpdateMode( sal_True );
602 void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
603 SfxItemSet* pSet, sal_Bool bTakeOwnership )
605 sal_Bool bUpdateMode = GetUpdateMode();
606 if ( bUpdateMode )
607 SetUpdateMode( false );
608 EditEngine::SetText( rText );
609 SetDefaults( pSet, bTakeOwnership );
610 if ( bUpdateMode )
611 SetUpdateMode( sal_True );
614 void ScEditEngineDefaulter::RepeatDefaults()
616 if ( pDefaults )
618 sal_Int32 nPara = GetParagraphCount();
619 for ( sal_Int32 j=0; j<nPara; j++ )
620 SetParaAttribs( j, *pDefaults );
624 void ScEditEngineDefaulter::RemoveParaAttribs()
626 SfxItemSet* pCharItems = NULL;
627 sal_Bool bUpdateMode = GetUpdateMode();
628 if ( bUpdateMode )
629 SetUpdateMode( false );
630 sal_Int32 nParCount = GetParagraphCount();
631 for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
633 const SfxItemSet& rParaAttribs = GetParaAttribs( nPar );
634 sal_uInt16 nWhich;
635 for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
637 const SfxPoolItem* pParaItem;
638 if ( rParaAttribs.GetItemState( nWhich, false, &pParaItem ) == SFX_ITEM_SET )
640 // if defaults are set, use only items that are different from default
641 if ( !pDefaults || *pParaItem != pDefaults->Get(nWhich) )
643 if (!pCharItems)
644 pCharItems = new SfxItemSet( GetEmptyItemSet() );
645 pCharItems->Put( *pParaItem );
650 if ( pCharItems )
652 std::vector<sal_uInt16> aPortions;
653 GetPortions( nPar, aPortions );
655 // loop through the portions of the paragraph, and set only those items
656 // that are not overridden by existing character attributes
658 sal_uInt16 nStart = 0;
659 for ( std::vector<sal_uInt16>::const_iterator it(aPortions.begin()); it != aPortions.end(); ++it )
661 sal_uInt16 nEnd = *it;
662 ESelection aSel( nPar, nStart, nPar, nEnd );
663 SfxItemSet aOldCharAttrs = GetAttribs( aSel );
664 SfxItemSet aNewCharAttrs = *pCharItems;
665 for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
667 // Clear those items that are different from existing character attributes.
668 // Where no character attributes are set, GetAttribs returns the paragraph attributes.
669 const SfxPoolItem* pItem;
670 if ( aNewCharAttrs.GetItemState( nWhich, false, &pItem ) == SFX_ITEM_SET &&
671 *pItem != aOldCharAttrs.Get(nWhich) )
673 aNewCharAttrs.ClearItem(nWhich);
676 if ( aNewCharAttrs.Count() )
677 QuickSetAttribs( aNewCharAttrs, aSel );
679 nStart = nEnd;
682 DELETEZ( pCharItems );
685 if ( rParaAttribs.Count() )
687 // clear all paragraph attributes (including defaults),
688 // so they are not contained in resulting EditTextObjects
690 SetParaAttribs( nPar, SfxItemSet( *rParaAttribs.GetPool(), rParaAttribs.GetRanges() ) );
693 if ( bUpdateMode )
694 SetUpdateMode( sal_True );
697 ScTabEditEngine::ScTabEditEngine( ScDocument* pDoc )
698 : ScEditEngineDefaulter( pDoc->GetEnginePool() )
700 SetEditTextObjectPool( pDoc->GetEditPool() );
701 Init((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
704 ScTabEditEngine::ScTabEditEngine( const ScPatternAttr& rPattern,
705 SfxItemPool* pEnginePoolP, SfxItemPool* pTextObjectPool )
706 : ScEditEngineDefaulter( pEnginePoolP )
708 if ( pTextObjectPool )
709 SetEditTextObjectPool( pTextObjectPool );
710 Init( rPattern );
713 void ScTabEditEngine::Init( const ScPatternAttr& rPattern )
715 SetRefMapMode(MAP_100TH_MM);
716 SfxItemSet* pEditDefaults = new SfxItemSet( GetEmptyItemSet() );
717 rPattern.FillEditItemSet( pEditDefaults );
718 SetDefaults( pEditDefaults );
719 // wir haben keine StyleSheets fuer Text
720 SetControlWord( GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
723 // Feldbefehle fuer Kopf- und Fusszeilen
726 // Zahlen aus \sw\source\core\doc\numbers.cxx
729 static OUString lcl_GetCharStr( sal_Int32 nNo )
731 OSL_ENSURE( nNo, "0 is an invalid number !!" );
732 OUString aStr;
734 const sal_Int32 coDiff = 'Z' - 'A' +1;
735 sal_Int32 nCalc;
737 do {
738 nCalc = nNo % coDiff;
739 if( !nCalc )
740 nCalc = coDiff;
741 aStr = OUString( (sal_Unicode)('a' - 1 + nCalc ) ) + aStr;
742 nNo = sal::static_int_cast<sal_Int32>( nNo - nCalc );
743 if( nNo )
744 nNo /= coDiff;
745 } while( nNo );
746 return aStr;
749 static OUString lcl_GetNumStr(sal_Int32 nNo, SvxNumType eType)
751 OUString aTmpStr('0');
752 if( nNo )
754 switch( eType )
756 case SVX_CHARS_UPPER_LETTER:
757 case SVX_CHARS_LOWER_LETTER:
758 aTmpStr = lcl_GetCharStr( nNo );
759 break;
761 case SVX_ROMAN_UPPER:
762 case SVX_ROMAN_LOWER:
763 if( nNo < 4000 )
764 aTmpStr = SvxNumberFormat::CreateRomanString( nNo, ( eType == SVX_ROMAN_UPPER ) );
765 else
766 aTmpStr = OUString();
767 break;
769 case SVX_NUMBER_NONE:
770 aTmpStr = OUString();
771 break;
773 // CHAR_SPECIAL:
774 // ????
776 // case ARABIC: ist jetzt default
777 default:
778 aTmpStr = OUString::number(nNo);
779 break;
782 if( SVX_CHARS_UPPER_LETTER == eType )
783 aTmpStr = aTmpStr.toAsciiUpperCase();
785 return aTmpStr;
788 ScHeaderFieldData::ScHeaderFieldData()
790 aDate( Date::EMPTY ),
791 aTime( Time::EMPTY )
793 nPageNo = nTotalPages = 0;
794 eNumType = SVX_ARABIC;
797 ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pEnginePoolP, sal_Bool bDeleteEnginePoolP )
798 : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
802 OUString ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField,
803 sal_Int32 /* nPara */, sal_uInt16 /* nPos */,
804 Color*& /* rTxtColor */, Color*& /* rFldColor */ )
806 const SvxFieldData* pFieldData = rField.GetField();
807 if (!pFieldData)
808 return OUString("?");
810 OUString aRet;
811 sal_Int32 nClsId = pFieldData->GetClassId();
812 switch (nClsId)
814 case text::textfield::Type::PAGE:
815 aRet = lcl_GetNumStr( aData.nPageNo,aData.eNumType );
816 break;
817 case text::textfield::Type::PAGES:
818 aRet = lcl_GetNumStr( aData.nTotalPages,aData.eNumType );
819 break;
820 case text::textfield::Type::EXTENDED_TIME:
821 case text::textfield::Type::TIME:
822 // For now, time field in the header / footer is always dynamic.
823 aRet = ScGlobal::pLocaleData->getTime(aData.aTime);
824 break;
825 case text::textfield::Type::DOCINFO_TITLE:
826 aRet = aData.aTitle;
827 break;
828 case text::textfield::Type::EXTENDED_FILE:
830 switch (static_cast<const SvxExtFileField*>(pFieldData)->GetFormat())
832 case SVXFILEFORMAT_FULLPATH :
833 aRet = aData.aLongDocName;
834 break;
835 default:
836 aRet = aData.aShortDocName;
839 break;
840 case text::textfield::Type::TABLE:
841 aRet = aData.aTabName;
842 break;
843 case text::textfield::Type::DATE:
844 aRet = ScGlobal::pLocaleData->getDate(aData.aDate);
845 break;
846 default:
847 aRet = "?";
850 return aRet;
854 // Feld-Daten
857 ScFieldEditEngine::ScFieldEditEngine(
858 ScDocument* pDoc, SfxItemPool* pEnginePoolP,
859 SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP) :
860 ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
861 mpDoc(pDoc), bExecuteURL(true)
863 if ( pTextObjectPool )
864 SetEditTextObjectPool( pTextObjectPool );
865 // EE_CNTRL_URLSFXEXECUTE nicht, weil die Edit-Engine den ViewFrame nicht kennt
866 // wir haben keine StyleSheets fuer Text
867 SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
870 OUString ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
871 sal_Int32 /* nPara */, sal_uInt16 /* nPos */,
872 Color*& rTxtColor, Color*& /* rFldColor */ )
874 const SvxFieldData* pFieldData = rField.GetField();
876 if (!pFieldData)
877 return OUString(" ");
879 return ScEditUtil::GetCellFieldValue(*pFieldData, mpDoc, &rTxtColor);
882 void ScFieldEditEngine::FieldClicked( const SvxFieldItem& rField, sal_Int32, sal_uInt16 )
884 const SvxFieldData* pFld = rField.GetField();
886 if ( pFld && pFld->ISA( SvxURLField ) && bExecuteURL )
888 const SvxURLField* pURLField = (const SvxURLField*) pFld;
889 ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
893 ScNoteEditEngine::ScNoteEditEngine( SfxItemPool* pEnginePoolP,
894 SfxItemPool* pTextObjectPool, sal_Bool bDeleteEnginePoolP ) :
895 ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
897 if ( pTextObjectPool )
898 SetEditTextObjectPool( pTextObjectPool );
899 SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
902 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */