fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / tool / editutil.cxx
blob4d797ccda6743dfc502595cc73057dfb3435c8cd
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 ScEditUtil::ScEditUtil( ScDocument* pDocument, SCCOL nX, SCROW nY, SCTAB nZ,
57 const Point& rScrPosPixel,
58 OutputDevice* pDevice, double nScaleX, double nScaleY,
59 const Fraction& rX, const Fraction& rY ) :
60 pDoc(pDocument),nCol(nX),nRow(nY),nTab(nZ),
61 aScrPos(rScrPosPixel),pDev(pDevice),
62 nPPTX(nScaleX),nPPTY(nScaleY),aZoomX(rX),aZoomY(rY) {}
64 OUString ScEditUtil::ModifyDelimiters( const OUString& rOld )
66 // underscore is used in function argument names
67 OUString aRet = OUString( comphelper::string::remove(rOld, '_') ) +
68 "=()+-*/^&<>" +
69 ScCompiler::GetNativeSymbol(ocSep); // argument separator is localized.
70 return aRet;
73 static OUString lcl_GetDelimitedString( const EditEngine& rEngine, const sal_Char c )
75 sal_Int32 nParCount = rEngine.GetParagraphCount();
76 OUStringBuffer aRet( nParCount * 80 );
77 for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
79 if (nPar > 0)
80 aRet.append(c);
81 aRet.append( rEngine.GetText( nPar ));
83 return aRet.makeStringAndClear();
86 static OUString lcl_GetDelimitedString( const EditTextObject& rEdit, const sal_Char c )
88 sal_Int32 nParCount = rEdit.GetParagraphCount();
89 OUStringBuffer aRet( nParCount * 80 );
90 for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
92 if (nPar > 0)
93 aRet.append(c);
94 aRet.append( rEdit.GetText( nPar ));
96 return aRet.makeStringAndClear();
99 OUString ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine )
101 return lcl_GetDelimitedString(rEngine, ' ');
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) == SfxItemState::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 EEControlBits nControl = rEngine.GetControlWord();
176 const EEControlBits nSpellControl = EEControlBits::ONLINESPELLING | EEControlBits::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: //TODO: configurable with 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, 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 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
292 long nLayoutSign = bLayoutRTL ? -1 : 1;
294 const ScMergeAttr* pMerge = static_cast<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 = static_cast<const SvxMarginItem*>(&pPattern->GetItem(ATTR_MARGIN));
310 sal_uInt16 nIndent = 0;
311 if ( static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue() ==
312 SVX_HOR_JUSTIFY_LEFT )
313 nIndent = static_cast<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) static_cast<const SvxVerJustifyItem&>(pPattern->
323 GetItem(ATTR_VER_JUSTIFY)).GetValue();
325 // asian vertical is always edited top-aligned
326 bool bAsianVertical = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_STACKED )).GetValue() &&
327 static_cast<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 vcl::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 = true; //TODO: find cell attributes ?
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 == SfxItemState::DONTCARE)
393 bNeedsObject = true;
394 else if (eState == SfxItemState::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 = true;
407 else
408 if (!bNeedsCellAttr)
409 if ( *pItem != rEditDefaults.Get(nId) )
410 bNeedsCellAttr = 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 == SfxItemState::DONTCARE || eFieldState == SfxItemState::SET )
419 bNeedsObject = true;
421 // not converted characters?
423 SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, false );
424 if ( eConvState == SfxItemState::DONTCARE || eConvState == SfxItemState::SET )
425 bNeedsObject = true;
429 ScEditAttrTester::~ScEditAttrTester()
431 delete pEditAttrs;
434 ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP,
435 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 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, bool bRememberCopy )
487 if ( bRememberCopy )
489 if ( bDeleteDefaults )
490 delete pDefaults;
491 pDefaults = new SfxItemSet( rSet );
492 bDeleteDefaults = true;
494 const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
495 bool bUndo = IsUndoEnabled();
496 EnableUndo( false );
497 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( true );
507 if ( bUndo )
508 EnableUndo( true );
511 void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, 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 = true;
528 pDefaults->Put( rItem );
529 SetDefaults( *pDefaults, false );
532 const SfxItemSet& ScEditEngineDefaulter::GetDefaults()
534 if ( !pDefaults )
536 pDefaults = new SfxItemSet( GetEmptyItemSet() );
537 bDeleteDefaults = true;
539 return *pDefaults;
542 void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject )
544 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( true );
554 void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
555 const SfxItemSet& rSet, bool bRememberCopy )
557 bool bUpdateMode = GetUpdateMode();
558 if ( bUpdateMode )
559 SetUpdateMode( false );
560 EditEngine::SetText( rTextObject );
561 SetDefaults( rSet, bRememberCopy );
562 if ( bUpdateMode )
563 SetUpdateMode( true );
566 void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
567 SfxItemSet* pSet, bool bTakeOwnership )
569 bool bUpdateMode = GetUpdateMode();
570 if ( bUpdateMode )
571 SetUpdateMode( false );
572 EditEngine::SetText( rTextObject );
573 SetDefaults( pSet, bTakeOwnership );
574 if ( bUpdateMode )
575 SetUpdateMode( true );
578 void ScEditEngineDefaulter::SetText( const OUString& rText )
580 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( true );
590 void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
591 const SfxItemSet& rSet, bool bRememberCopy )
593 bool bUpdateMode = GetUpdateMode();
594 if ( bUpdateMode )
595 SetUpdateMode( false );
596 EditEngine::SetText( rText );
597 SetDefaults( rSet, bRememberCopy );
598 if ( bUpdateMode )
599 SetUpdateMode( true );
602 void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
603 SfxItemSet* pSet, bool bTakeOwnership )
605 bool bUpdateMode = GetUpdateMode();
606 if ( bUpdateMode )
607 SetUpdateMode( false );
608 EditEngine::SetText( rText );
609 SetDefaults( pSet, bTakeOwnership );
610 if ( bUpdateMode )
611 SetUpdateMode( 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 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 ) == SfxItemState::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_Int32> 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_Int32 nStart = 0;
659 for ( std::vector<sal_Int32>::const_iterator it(aPortions.begin()); it != aPortions.end(); ++it )
661 sal_Int32 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 ) == SfxItemState::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( true );
697 ScTabEditEngine::ScTabEditEngine( ScDocument* pDoc )
698 : ScEditEngineDefaulter( pDoc->GetEnginePool() )
700 SetEditTextObjectPool( pDoc->GetEditPool() );
701 Init(static_cast<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() & ~EEControlBits::RTFSTYLESHEETS );
723 // Feldbefehle fuer Kopf- und Fusszeilen
725 // Zahlen aus \sw\source\core\doc\numbers.cxx
727 static OUString lcl_GetCharStr( sal_Int32 nNo )
729 OSL_ENSURE( nNo, "0 is an invalid number !!" );
730 OUString aStr;
732 const sal_Int32 coDiff = 'Z' - 'A' +1;
733 sal_Int32 nCalc;
735 do {
736 nCalc = nNo % coDiff;
737 if( !nCalc )
738 nCalc = coDiff;
739 aStr = OUString( (sal_Unicode)('a' - 1 + nCalc ) ) + aStr;
740 nNo = sal::static_int_cast<sal_Int32>( nNo - nCalc );
741 if( nNo )
742 nNo /= coDiff;
743 } while( nNo );
744 return aStr;
747 static OUString lcl_GetNumStr(sal_Int32 nNo, SvxNumType eType)
749 OUString aTmpStr('0');
750 if( nNo )
752 switch( eType )
754 case SVX_CHARS_UPPER_LETTER:
755 case SVX_CHARS_LOWER_LETTER:
756 aTmpStr = lcl_GetCharStr( nNo );
757 break;
759 case SVX_ROMAN_UPPER:
760 case SVX_ROMAN_LOWER:
761 if( nNo < 4000 )
762 aTmpStr = SvxNumberFormat::CreateRomanString( nNo, ( eType == SVX_ROMAN_UPPER ) );
763 else
764 aTmpStr.clear();
765 break;
767 case SVX_NUMBER_NONE:
768 aTmpStr.clear();
769 break;
771 // CHAR_SPECIAL:
772 // ????
774 // case ARABIC: ist jetzt default
775 default:
776 aTmpStr = OUString::number(nNo);
777 break;
780 if( SVX_CHARS_UPPER_LETTER == eType )
781 aTmpStr = aTmpStr.toAsciiUpperCase();
783 return aTmpStr;
786 ScHeaderFieldData::ScHeaderFieldData()
788 aDate( Date::EMPTY ),
789 aTime( tools::Time::EMPTY )
791 nPageNo = nTotalPages = 0;
792 eNumType = SVX_ARABIC;
795 ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pEnginePoolP, bool bDeleteEnginePoolP )
796 : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
800 OUString ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField,
801 sal_Int32 /* nPara */, sal_Int32 /* nPos */,
802 Color*& /* rTxtColor */, Color*& /* rFldColor */ )
804 const SvxFieldData* pFieldData = rField.GetField();
805 if (!pFieldData)
806 return OUString("?");
808 OUString aRet;
809 sal_Int32 nClsId = pFieldData->GetClassId();
810 switch (nClsId)
812 case text::textfield::Type::PAGE:
813 aRet = lcl_GetNumStr( aData.nPageNo,aData.eNumType );
814 break;
815 case text::textfield::Type::PAGES:
816 aRet = lcl_GetNumStr( aData.nTotalPages,aData.eNumType );
817 break;
818 case text::textfield::Type::EXTENDED_TIME:
819 case text::textfield::Type::TIME:
820 // For now, time field in the header / footer is always dynamic.
821 aRet = ScGlobal::pLocaleData->getTime(aData.aTime);
822 break;
823 case text::textfield::Type::DOCINFO_TITLE:
824 aRet = aData.aTitle;
825 break;
826 case text::textfield::Type::EXTENDED_FILE:
828 switch (static_cast<const SvxExtFileField*>(pFieldData)->GetFormat())
830 case SVXFILEFORMAT_FULLPATH :
831 aRet = aData.aLongDocName;
832 break;
833 default:
834 aRet = aData.aShortDocName;
837 break;
838 case text::textfield::Type::TABLE:
839 aRet = aData.aTabName;
840 break;
841 case text::textfield::Type::DATE:
842 aRet = ScGlobal::pLocaleData->getDate(aData.aDate);
843 break;
844 default:
845 aRet = "?";
848 return aRet;
851 // Feld-Daten
853 ScFieldEditEngine::ScFieldEditEngine(
854 ScDocument* pDoc, SfxItemPool* pEnginePoolP,
855 SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP) :
856 ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
857 mpDoc(pDoc), bExecuteURL(true)
859 if ( pTextObjectPool )
860 SetEditTextObjectPool( pTextObjectPool );
861 SetControlWord( EEControlBits(GetControlWord() | EEControlBits::MARKFIELDS) & ~EEControlBits::RTFSTYLESHEETS );
864 OUString ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
865 sal_Int32 /* nPara */, sal_Int32 /* nPos */,
866 Color*& rTxtColor, Color*& /* rFldColor */ )
868 const SvxFieldData* pFieldData = rField.GetField();
870 if (!pFieldData)
871 return OUString(" ");
873 return ScEditUtil::GetCellFieldValue(*pFieldData, mpDoc, &rTxtColor);
876 void ScFieldEditEngine::FieldClicked( const SvxFieldItem& rField, sal_Int32, sal_Int32 )
878 const SvxFieldData* pFld = rField.GetField();
880 if ( pFld && pFld->ISA( SvxURLField ) && bExecuteURL )
882 const SvxURLField* pURLField = static_cast<const SvxURLField*>(pFld);
883 ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
887 ScNoteEditEngine::ScNoteEditEngine( SfxItemPool* pEnginePoolP,
888 SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP ) :
889 ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
891 if ( pTextObjectPool )
892 SetEditTextObjectPool( pTextObjectPool );
893 SetControlWord( EEControlBits(GetControlWord() | EEControlBits::MARKFIELDS) & ~EEControlBits::RTFSTYLESHEETS );
896 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */