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 "scitems.hxx"
21 : #include <comphelper/string.hxx>
22 : #include <editeng/eeitem.hxx>
23 :
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>
37 :
38 : #include <com/sun/star/text/textfield/Type.hpp>
39 : #include <com/sun/star/document/XDocumentProperties.hpp>
40 :
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"
50 :
51 : using namespace com::sun::star;
52 :
53 : // STATIC DATA
54 : // Delimiters zusaetzlich zu EditEngine-Default:
55 :
56 0 : 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 0 : nPPTX(nScaleX),nPPTY(nScaleY),aZoomX(rX),aZoomY(rY) {}
63 :
64 1570 : OUString ScEditUtil::ModifyDelimiters( const OUString& rOld )
65 : {
66 : // underscore is used in function argument names
67 3140 : OUString aRet = OUString( comphelper::string::remove(rOld, '_') ) +
68 6280 : "=()+-*/^&<>" +
69 4710 : ScCompiler::GetNativeSymbol(ocSep); // argument separator is localized.
70 1570 : return aRet;
71 : }
72 :
73 1512 : static OUString lcl_GetDelimitedString( const EditEngine& rEngine, const sal_Char c )
74 : {
75 1512 : sal_Int32 nParCount = rEngine.GetParagraphCount();
76 1512 : OUStringBuffer aRet( nParCount * 80 );
77 3109 : for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
78 : {
79 1597 : if (nPar > 0)
80 85 : aRet.append(c);
81 1597 : aRet.append( rEngine.GetText( nPar ));
82 : }
83 1512 : return aRet.makeStringAndClear();
84 : }
85 :
86 0 : static OUString lcl_GetDelimitedString( const EditTextObject& rEdit, const sal_Char c )
87 : {
88 0 : sal_Int32 nParCount = rEdit.GetParagraphCount();
89 0 : OUStringBuffer aRet( nParCount * 80 );
90 0 : for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
91 : {
92 0 : if (nPar > 0)
93 0 : aRet.append(c);
94 0 : aRet.append( rEdit.GetText( nPar ));
95 : }
96 0 : return aRet.makeStringAndClear();
97 : }
98 :
99 1173 : OUString ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine )
100 : {
101 1173 : return lcl_GetDelimitedString(rEngine, ' ');
102 : }
103 339 : OUString ScEditUtil::GetMultilineString( const EditEngine& rEngine )
104 : {
105 339 : return lcl_GetDelimitedString(rEngine, '\n');
106 : }
107 :
108 0 : OUString ScEditUtil::GetMultilineString( const EditTextObject& rEdit )
109 : {
110 0 : return lcl_GetDelimitedString(rEdit, '\n');
111 : }
112 :
113 326 : OUString ScEditUtil::GetString( const EditTextObject& rEditText, const ScDocument* pDoc )
114 : {
115 : // ScFieldEditEngine is needed to resolve field contents.
116 326 : if (pDoc)
117 : {
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 322 : EditEngine& rEE = const_cast<ScDocument*>(pDoc)->GetEditEngine();
122 322 : rEE.SetText( rEditText);
123 322 : return GetMultilineString( rEE);
124 : }
125 : else
126 : {
127 4 : static osl::Mutex aMutex;
128 4 : osl::MutexGuard aGuard( aMutex);
129 4 : EditEngine& rEE = ScGlobal::GetStaticFieldEditEngine();
130 4 : rEE.SetText( rEditText);
131 4 : return GetMultilineString( rEE);
132 : }
133 : }
134 :
135 0 : EditTextObject* ScEditUtil::CreateURLObjectFromURL( ScDocument& rDoc, const OUString& rURL, const OUString& rText )
136 : {
137 0 : SvxURLField aUrlField( rURL, rText, SVXURLFORMAT_APPDEFAULT);
138 0 : EditEngine& rEE = rDoc.GetEditEngine();
139 0 : rEE.SetText( EMPTY_OUSTRING );
140 : rEE.QuickInsertField( SvxFieldItem( aUrlField, EE_FEATURE_FIELD ),
141 0 : ESelection( EE_PARA_MAX_COUNT, EE_TEXTPOS_MAX_COUNT ) );
142 :
143 0 : return rEE.CreateTextObject();
144 : }
145 :
146 0 : void ScEditUtil::RemoveCharAttribs( EditTextObject& rEditText, const ScPatternAttr& rAttr )
147 : {
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 }
156 0 : };
157 0 : sal_uInt16 nMapCount = sizeof (AttrTypeMap) / sizeof (AttrTypeMap[0]);
158 :
159 0 : const SfxItemSet& rSet = rAttr.GetItemSet();
160 : const SfxPoolItem* pItem;
161 0 : for (sal_uInt16 i = 0; i < nMapCount; ++i)
162 : {
163 0 : if ( rSet.GetItemState(AttrTypeMap[i].nAttrType, false, &pItem) == SfxItemState::SET )
164 0 : rEditText.RemoveCharAttribs(AttrTypeMap[i].nCharType);
165 : }
166 0 : }
167 :
168 8 : EditTextObject* ScEditUtil::Clone( const EditTextObject& rObj, ScDocument& rDestDoc )
169 : {
170 8 : EditTextObject* pNew = NULL;
171 :
172 8 : EditEngine& rEngine = rDestDoc.GetEditEngine();
173 8 : if (rObj.HasOnlineSpellErrors())
174 : {
175 0 : EEControlBits nControl = rEngine.GetControlWord();
176 0 : const EEControlBits nSpellControl = EEControlBits::ONLINESPELLING | EEControlBits::ALLOWBIGOBJS;
177 0 : bool bNewControl = ( (nControl & nSpellControl) != nSpellControl );
178 0 : if (bNewControl)
179 0 : rEngine.SetControlWord(nControl | nSpellControl);
180 0 : rEngine.SetText(rObj);
181 0 : pNew = rEngine.CreateTextObject();
182 0 : if (bNewControl)
183 0 : rEngine.SetControlWord(nControl);
184 : }
185 : else
186 : {
187 8 : rEngine.SetText(rObj);
188 8 : pNew = rEngine.CreateTextObject();
189 : }
190 :
191 8 : return pNew;
192 : }
193 :
194 48 : OUString ScEditUtil::GetCellFieldValue(
195 : const SvxFieldData& rFieldData, const ScDocument* pDoc, Color** ppTextColor )
196 : {
197 48 : OUString aRet;
198 48 : switch (rFieldData.GetClassId())
199 : {
200 : case text::textfield::Type::URL:
201 : {
202 42 : const SvxURLField& rField = static_cast<const SvxURLField&>(rFieldData);
203 42 : OUString aURL = rField.GetURL();
204 :
205 42 : switch (rField.GetFormat())
206 : {
207 : case SVXURLFORMAT_APPDEFAULT: //TODO: configurable with App???
208 : case SVXURLFORMAT_REPR:
209 42 : aRet = rField.GetRepresentation();
210 42 : break;
211 : case SVXURLFORMAT_URL:
212 0 : aRet = aURL;
213 0 : break;
214 : default:
215 : ;
216 : }
217 :
218 : svtools::ColorConfigEntry eEntry =
219 42 : INetURLHistory::GetOrCreate()->QueryUrl(aURL) ? svtools::LINKSVISITED : svtools::LINKS;
220 :
221 42 : if (ppTextColor)
222 41 : *ppTextColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
223 : }
224 42 : break;
225 : case text::textfield::Type::EXTENDED_TIME:
226 : {
227 0 : const SvxExtTimeField& rField = static_cast<const SvxExtTimeField&>(rFieldData);
228 0 : if (pDoc)
229 0 : aRet = rField.GetFormatted(*pDoc->GetFormatTable(), ScGlobal::eLnge);
230 : else
231 : {
232 : /* TODO: quite expensive, we could have a global formatter? */
233 0 : SvNumberFormatter aFormatter( comphelper::getProcessComponentContext(), ScGlobal::eLnge );
234 0 : aRet = rField.GetFormatted(aFormatter, ScGlobal::eLnge);
235 : }
236 : }
237 0 : break;
238 : case text::textfield::Type::DATE:
239 : {
240 2 : Date aDate(Date::SYSTEM);
241 2 : aRet = ScGlobal::pLocaleData->getDate(aDate);
242 : }
243 2 : break;
244 : case text::textfield::Type::DOCINFO_TITLE:
245 : {
246 2 : if (pDoc)
247 : {
248 1 : SfxObjectShell* pDocShell = pDoc->GetDocumentShell();
249 1 : if (pDocShell)
250 : {
251 1 : aRet = pDocShell->getDocProperties()->getTitle();
252 1 : if (aRet.isEmpty())
253 0 : aRet = pDocShell->GetTitle();
254 : }
255 : }
256 2 : if (aRet.isEmpty())
257 1 : aRet = "?";
258 : }
259 2 : break;
260 : case text::textfield::Type::TABLE:
261 : {
262 2 : const SvxTableField& rField = static_cast<const SvxTableField&>(rFieldData);
263 2 : SCTAB nTab = rField.GetTab();
264 2 : OUString aName;
265 2 : if (pDoc && pDoc->GetName(nTab, aName))
266 1 : aRet = aName;
267 : else
268 1 : aRet = "?";
269 : }
270 2 : break;
271 : default:
272 0 : aRet = "?";
273 : }
274 :
275 48 : if (aRet.isEmpty()) // leer ist baeh
276 17 : aRet = " "; // Space ist Default der Editengine
277 :
278 48 : return aRet;
279 : }
280 :
281 0 : Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, bool bForceToTop )
282 : {
283 : // bForceToTop = always align to top, for editing
284 : // (sal_False for querying URLs etc.)
285 :
286 0 : if (!pPattern)
287 0 : pPattern = pDoc->GetPattern( nCol, nRow, nTab );
288 :
289 0 : Point aStartPos = aScrPos;
290 :
291 0 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
292 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
293 :
294 0 : const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(&pPattern->GetItem(ATTR_MERGE));
295 0 : long nCellX = (long) ( pDoc->GetColWidth(nCol,nTab) * nPPTX );
296 0 : if ( pMerge->GetColMerge() > 1 )
297 : {
298 0 : SCCOL nCountX = pMerge->GetColMerge();
299 0 : for (SCCOL i=1; i<nCountX; i++)
300 0 : nCellX += (long) ( pDoc->GetColWidth(nCol+i,nTab) * nPPTX );
301 : }
302 0 : long nCellY = (long) ( pDoc->GetRowHeight(nRow,nTab) * nPPTY );
303 0 : if ( pMerge->GetRowMerge() > 1 )
304 : {
305 0 : SCROW nCountY = pMerge->GetRowMerge();
306 0 : nCellY += (long) pDoc->GetScaledRowHeight( nRow+1, nRow+nCountY-1, nTab, nPPTY);
307 : }
308 :
309 0 : const SvxMarginItem* pMargin = static_cast<const SvxMarginItem*>(&pPattern->GetItem(ATTR_MARGIN));
310 0 : sal_uInt16 nIndent = 0;
311 0 : if ( static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue() ==
312 : SVX_HOR_JUSTIFY_LEFT )
313 0 : nIndent = static_cast<const SfxUInt16Item&>(pPattern->GetItem(ATTR_INDENT)).GetValue();
314 0 : long nPixDifX = (long) ( ( pMargin->GetLeftMargin() + nIndent ) * nPPTX );
315 0 : aStartPos.X() += nPixDifX * nLayoutSign;
316 0 : nCellX -= nPixDifX + (long) ( pMargin->GetRightMargin() * nPPTX ); // wegen Umbruch etc.
317 :
318 : // vertikale Position auf die in der Tabelle anpassen
319 :
320 : long nPixDifY;
321 0 : long nTopMargin = (long) ( pMargin->GetTopMargin() * nPPTY );
322 : SvxCellVerJustify eJust = (SvxCellVerJustify) static_cast<const SvxVerJustifyItem&>(pPattern->
323 0 : GetItem(ATTR_VER_JUSTIFY)).GetValue();
324 :
325 : // asian vertical is always edited top-aligned
326 0 : bool bAsianVertical = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_STACKED )).GetValue() &&
327 0 : static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
328 :
329 0 : if ( eJust == SVX_VER_JUSTIFY_TOP ||
330 0 : ( bForceToTop && ( SC_MOD()->GetInputOptions().GetTextWysiwyg() || bAsianVertical ) ) )
331 0 : nPixDifY = nTopMargin;
332 : else
333 : {
334 0 : MapMode aMode = pDev->GetMapMode();
335 0 : pDev->SetMapMode( MAP_PIXEL );
336 :
337 : long nTextHeight = pDoc->GetNeededSize( nCol, nRow, nTab,
338 0 : pDev, nPPTX, nPPTY, aZoomX, aZoomY, false );
339 0 : if (!nTextHeight)
340 : { // leere Zelle
341 0 : vcl::Font aFont;
342 : // font color doesn't matter here
343 0 : pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aZoomY );
344 0 : pDev->SetFont(aFont);
345 0 : nTextHeight = pDev->GetTextHeight() + nTopMargin +
346 0 : (long) ( pMargin->GetBottomMargin() * nPPTY );
347 : }
348 :
349 0 : pDev->SetMapMode(aMode);
350 :
351 0 : if ( nTextHeight > nCellY + nTopMargin || bForceToTop )
352 0 : nPixDifY = 0; // zu gross -> oben anfangen
353 : else
354 : {
355 0 : if ( eJust == SVX_VER_JUSTIFY_CENTER )
356 0 : nPixDifY = nTopMargin + ( nCellY - nTextHeight ) / 2;
357 : else
358 0 : nPixDifY = nCellY - nTextHeight + nTopMargin; // JUSTIFY_BOTTOM
359 0 : }
360 : }
361 :
362 0 : aStartPos.Y() += nPixDifY;
363 0 : nCellY -= nPixDifY;
364 :
365 0 : if ( bLayoutRTL )
366 0 : aStartPos.X() -= nCellX - 2; // excluding grid on both sides
367 :
368 : // -1 -> Gitter nicht ueberschreiben
369 0 : return Rectangle( aStartPos, Size(nCellX-1,nCellY-1) );
370 : }
371 :
372 220 : ScEditAttrTester::ScEditAttrTester( ScEditEngineDefaulter* pEng ) :
373 : pEngine( pEng ),
374 : pEditAttrs( NULL ),
375 : bNeedsObject( false ),
376 220 : bNeedsCellAttr( false )
377 : {
378 220 : if ( pEngine->GetParagraphCount() > 1 )
379 : {
380 3 : bNeedsObject = true; //TODO: find cell attributes ?
381 : }
382 : else
383 : {
384 217 : const SfxPoolItem* pItem = NULL;
385 : pEditAttrs = new SfxItemSet( pEngine->GetAttribs(
386 217 : ESelection(0,0,0,pEngine->GetTextLen(0)), EditEngineAttribs_OnlyHard ) );
387 217 : const SfxItemSet& rEditDefaults = pEngine->GetDefaults();
388 :
389 4100 : for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++)
390 : {
391 3883 : SfxItemState eState = pEditAttrs->GetItemState( nId, false, &pItem );
392 3883 : if (eState == SfxItemState::DONTCARE)
393 0 : bNeedsObject = true;
394 3883 : else if (eState == SfxItemState::SET)
395 : {
396 1694 : if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
397 1545 : nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
398 : {
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".
403 :
404 298 : if ( *pItem != rEditDefaults.Get(nId) )
405 149 : bNeedsObject = true;
406 : }
407 : else
408 1545 : if (!bNeedsCellAttr)
409 176 : if ( *pItem != rEditDefaults.Get(nId) )
410 176 : bNeedsCellAttr = true;
411 : // rEditDefaults contains the defaults from the cell format
412 : }
413 : }
414 :
415 : // Feldbefehle enthalten?
416 :
417 217 : SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, false );
418 217 : if ( eFieldState == SfxItemState::DONTCARE || eFieldState == SfxItemState::SET )
419 18 : bNeedsObject = true;
420 :
421 : // not converted characters?
422 :
423 217 : SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, false );
424 217 : if ( eConvState == SfxItemState::DONTCARE || eConvState == SfxItemState::SET )
425 0 : bNeedsObject = true;
426 : }
427 220 : }
428 :
429 220 : ScEditAttrTester::~ScEditAttrTester()
430 : {
431 220 : delete pEditAttrs;
432 220 : }
433 :
434 10836 : ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP,
435 : bool bDeleteEnginePoolP )
436 : :
437 : pEnginePool( pEnginePoolP ),
438 : pDefaults( NULL ),
439 : bDeleteEnginePool( bDeleteEnginePoolP ),
440 10836 : bDeleteDefaults( false )
441 : {
442 10836 : }
443 :
444 92 : ScEnginePoolHelper::ScEnginePoolHelper( const ScEnginePoolHelper& rOrg )
445 : :
446 37 : pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ),
447 : pDefaults( NULL ),
448 : bDeleteEnginePool( rOrg.bDeleteEnginePool ),
449 129 : bDeleteDefaults( false )
450 : {
451 92 : }
452 :
453 8871 : ScEnginePoolHelper::~ScEnginePoolHelper()
454 : {
455 8871 : if ( bDeleteDefaults )
456 1378 : delete pDefaults;
457 8871 : if ( bDeleteEnginePool )
458 6711 : SfxItemPool::Free(pEnginePool);
459 8871 : }
460 :
461 10836 : ScEditEngineDefaulter::ScEditEngineDefaulter( SfxItemPool* pEnginePoolP,
462 : bool bDeleteEnginePoolP )
463 : :
464 : ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ),
465 10836 : EditEngine( pEnginePoolP )
466 : {
467 : // All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage.
468 : // DefaultLanguage for InputHandler's EditEngine is updated later.
469 :
470 10836 : SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
471 10836 : }
472 :
473 92 : ScEditEngineDefaulter::ScEditEngineDefaulter( const ScEditEngineDefaulter& rOrg )
474 : :
475 : ScEnginePoolHelper( rOrg ),
476 92 : EditEngine( pEnginePool )
477 : {
478 92 : SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
479 92 : }
480 :
481 9831 : ScEditEngineDefaulter::~ScEditEngineDefaulter()
482 : {
483 9831 : }
484 :
485 13424 : void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, bool bRememberCopy )
486 : {
487 13424 : if ( bRememberCopy )
488 : {
489 2122 : if ( bDeleteDefaults )
490 18 : delete pDefaults;
491 2122 : pDefaults = new SfxItemSet( rSet );
492 2122 : bDeleteDefaults = true;
493 : }
494 13424 : const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
495 13424 : bool bUndo = IsUndoEnabled();
496 13424 : EnableUndo( false );
497 13424 : bool bUpdateMode = GetUpdateMode();
498 13424 : if ( bUpdateMode )
499 2664 : SetUpdateMode( false );
500 13424 : sal_Int32 nPara = GetParagraphCount();
501 26917 : for ( sal_Int32 j=0; j<nPara; j++ )
502 : {
503 13493 : SetParaAttribs( j, rNewSet );
504 : }
505 13424 : if ( bUpdateMode )
506 2664 : SetUpdateMode( true );
507 13424 : if ( bUndo )
508 4489 : EnableUndo( true );
509 13424 : }
510 :
511 2132 : void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, bool bTakeOwnership )
512 : {
513 2132 : if ( bDeleteDefaults )
514 806 : delete pDefaults;
515 2132 : pDefaults = pSet;
516 2132 : bDeleteDefaults = bTakeOwnership;
517 2132 : if ( pDefaults )
518 2132 : SetDefaults( *pDefaults, false );
519 2132 : }
520 :
521 438 : void ScEditEngineDefaulter::SetDefaultItem( const SfxPoolItem& rItem )
522 : {
523 438 : if ( !pDefaults )
524 : {
525 0 : pDefaults = new SfxItemSet( GetEmptyItemSet() );
526 0 : bDeleteDefaults = true;
527 : }
528 438 : pDefaults->Put( rItem );
529 438 : SetDefaults( *pDefaults, false );
530 438 : }
531 :
532 217 : const SfxItemSet& ScEditEngineDefaulter::GetDefaults()
533 : {
534 217 : if ( !pDefaults )
535 : {
536 0 : pDefaults = new SfxItemSet( GetEmptyItemSet() );
537 0 : bDeleteDefaults = true;
538 : }
539 217 : return *pDefaults;
540 : }
541 :
542 2672 : void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject )
543 : {
544 2672 : bool bUpdateMode = GetUpdateMode();
545 2672 : if ( bUpdateMode )
546 2503 : SetUpdateMode( false );
547 2672 : EditEngine::SetText( rTextObject );
548 2672 : if ( pDefaults )
549 1901 : SetDefaults( *pDefaults, false );
550 2672 : if ( bUpdateMode )
551 2503 : SetUpdateMode( true );
552 2672 : }
553 :
554 4936 : void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
555 : const SfxItemSet& rSet, bool bRememberCopy )
556 : {
557 4936 : bool bUpdateMode = GetUpdateMode();
558 4936 : if ( bUpdateMode )
559 4936 : SetUpdateMode( false );
560 4936 : EditEngine::SetText( rTextObject );
561 4936 : SetDefaults( rSet, bRememberCopy );
562 4936 : if ( bUpdateMode )
563 4936 : SetUpdateMode( true );
564 4936 : }
565 :
566 106 : void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
567 : SfxItemSet* pSet, bool bTakeOwnership )
568 : {
569 106 : bool bUpdateMode = GetUpdateMode();
570 106 : if ( bUpdateMode )
571 0 : SetUpdateMode( false );
572 106 : EditEngine::SetText( rTextObject );
573 106 : SetDefaults( pSet, bTakeOwnership );
574 106 : if ( bUpdateMode )
575 0 : SetUpdateMode( true );
576 106 : }
577 :
578 10222 : void ScEditEngineDefaulter::SetText( const OUString& rText )
579 : {
580 10222 : bool bUpdateMode = GetUpdateMode();
581 10222 : if ( bUpdateMode )
582 5737 : SetUpdateMode( false );
583 10222 : EditEngine::SetText( rText );
584 10222 : if ( pDefaults )
585 1905 : SetDefaults( *pDefaults, false );
586 10222 : if ( bUpdateMode )
587 5737 : SetUpdateMode( true );
588 10222 : }
589 :
590 30 : void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
591 : const SfxItemSet& rSet, bool bRememberCopy )
592 : {
593 30 : bool bUpdateMode = GetUpdateMode();
594 30 : if ( bUpdateMode )
595 30 : SetUpdateMode( false );
596 30 : EditEngine::SetText( rText );
597 30 : SetDefaults( rSet, bRememberCopy );
598 30 : if ( bUpdateMode )
599 30 : SetUpdateMode( true );
600 30 : }
601 :
602 705 : void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
603 : SfxItemSet* pSet, bool bTakeOwnership )
604 : {
605 705 : bool bUpdateMode = GetUpdateMode();
606 705 : if ( bUpdateMode )
607 0 : SetUpdateMode( false );
608 705 : EditEngine::SetText( rText );
609 705 : SetDefaults( pSet, bTakeOwnership );
610 705 : if ( bUpdateMode )
611 0 : SetUpdateMode( true );
612 705 : }
613 :
614 0 : void ScEditEngineDefaulter::RepeatDefaults()
615 : {
616 0 : if ( pDefaults )
617 : {
618 0 : sal_Int32 nPara = GetParagraphCount();
619 0 : for ( sal_Int32 j=0; j<nPara; j++ )
620 0 : SetParaAttribs( j, *pDefaults );
621 : }
622 0 : }
623 :
624 0 : void ScEditEngineDefaulter::RemoveParaAttribs()
625 : {
626 0 : SfxItemSet* pCharItems = NULL;
627 0 : bool bUpdateMode = GetUpdateMode();
628 0 : if ( bUpdateMode )
629 0 : SetUpdateMode( false );
630 0 : sal_Int32 nParCount = GetParagraphCount();
631 0 : for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
632 : {
633 0 : const SfxItemSet& rParaAttribs = GetParaAttribs( nPar );
634 : sal_uInt16 nWhich;
635 0 : for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
636 : {
637 : const SfxPoolItem* pParaItem;
638 0 : if ( rParaAttribs.GetItemState( nWhich, false, &pParaItem ) == SfxItemState::SET )
639 : {
640 : // if defaults are set, use only items that are different from default
641 0 : if ( !pDefaults || *pParaItem != pDefaults->Get(nWhich) )
642 : {
643 0 : if (!pCharItems)
644 0 : pCharItems = new SfxItemSet( GetEmptyItemSet() );
645 0 : pCharItems->Put( *pParaItem );
646 : }
647 : }
648 : }
649 :
650 0 : if ( pCharItems )
651 : {
652 0 : std::vector<sal_Int32> aPortions;
653 0 : GetPortions( nPar, aPortions );
654 :
655 : // loop through the portions of the paragraph, and set only those items
656 : // that are not overridden by existing character attributes
657 :
658 0 : sal_Int32 nStart = 0;
659 0 : for ( std::vector<sal_Int32>::const_iterator it(aPortions.begin()); it != aPortions.end(); ++it )
660 : {
661 0 : sal_Int32 nEnd = *it;
662 0 : ESelection aSel( nPar, nStart, nPar, nEnd );
663 0 : SfxItemSet aOldCharAttrs = GetAttribs( aSel );
664 0 : SfxItemSet aNewCharAttrs = *pCharItems;
665 0 : for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
666 : {
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 0 : if ( aNewCharAttrs.GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
671 0 : *pItem != aOldCharAttrs.Get(nWhich) )
672 : {
673 0 : aNewCharAttrs.ClearItem(nWhich);
674 : }
675 : }
676 0 : if ( aNewCharAttrs.Count() )
677 0 : QuickSetAttribs( aNewCharAttrs, aSel );
678 :
679 0 : nStart = nEnd;
680 0 : }
681 :
682 0 : DELETEZ( pCharItems );
683 : }
684 :
685 0 : if ( rParaAttribs.Count() )
686 : {
687 : // clear all paragraph attributes (including defaults),
688 : // so they are not contained in resulting EditTextObjects
689 :
690 0 : SetParaAttribs( nPar, SfxItemSet( *rParaAttribs.GetPool(), rParaAttribs.GetRanges() ) );
691 : }
692 : }
693 0 : if ( bUpdateMode )
694 0 : SetUpdateMode( true );
695 0 : }
696 :
697 578 : ScTabEditEngine::ScTabEditEngine( ScDocument* pDoc )
698 578 : : ScEditEngineDefaulter( pDoc->GetEnginePool() )
699 : {
700 578 : SetEditTextObjectPool( pDoc->GetEditPool() );
701 578 : Init(static_cast<const ScPatternAttr&>(pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)));
702 578 : }
703 :
704 1 : ScTabEditEngine::ScTabEditEngine( const ScPatternAttr& rPattern,
705 : SfxItemPool* pEnginePoolP, SfxItemPool* pTextObjectPool )
706 1 : : ScEditEngineDefaulter( pEnginePoolP )
707 : {
708 1 : if ( pTextObjectPool )
709 1 : SetEditTextObjectPool( pTextObjectPool );
710 1 : Init( rPattern );
711 1 : }
712 :
713 579 : void ScTabEditEngine::Init( const ScPatternAttr& rPattern )
714 : {
715 579 : SetRefMapMode(MAP_100TH_MM);
716 579 : SfxItemSet* pEditDefaults = new SfxItemSet( GetEmptyItemSet() );
717 579 : rPattern.FillEditItemSet( pEditDefaults );
718 579 : SetDefaults( pEditDefaults );
719 : // wir haben keine StyleSheets fuer Text
720 579 : SetControlWord( GetControlWord() & ~EEControlBits::RTFSTYLESHEETS );
721 579 : }
722 :
723 : // Feldbefehle fuer Kopf- und Fusszeilen
724 :
725 : // Zahlen aus \sw\source\core\doc\numbers.cxx
726 :
727 0 : static OUString lcl_GetCharStr( sal_Int32 nNo )
728 : {
729 : OSL_ENSURE( nNo, "0 is an invalid number !!" );
730 0 : OUString aStr;
731 :
732 0 : const sal_Int32 coDiff = 'Z' - 'A' +1;
733 : sal_Int32 nCalc;
734 :
735 0 : do {
736 0 : nCalc = nNo % coDiff;
737 0 : if( !nCalc )
738 0 : nCalc = coDiff;
739 0 : aStr = OUString( (sal_Unicode)('a' - 1 + nCalc ) ) + aStr;
740 0 : nNo = sal::static_int_cast<sal_Int32>( nNo - nCalc );
741 0 : if( nNo )
742 0 : nNo /= coDiff;
743 : } while( nNo );
744 0 : return aStr;
745 : }
746 :
747 947 : static OUString lcl_GetNumStr(sal_Int32 nNo, SvxNumType eType)
748 : {
749 947 : OUString aTmpStr('0');
750 947 : if( nNo )
751 : {
752 503 : switch( eType )
753 : {
754 : case SVX_CHARS_UPPER_LETTER:
755 : case SVX_CHARS_LOWER_LETTER:
756 0 : aTmpStr = lcl_GetCharStr( nNo );
757 0 : break;
758 :
759 : case SVX_ROMAN_UPPER:
760 : case SVX_ROMAN_LOWER:
761 0 : if( nNo < 4000 )
762 0 : aTmpStr = SvxNumberFormat::CreateRomanString( nNo, ( eType == SVX_ROMAN_UPPER ) );
763 : else
764 0 : aTmpStr.clear();
765 0 : break;
766 :
767 : case SVX_NUMBER_NONE:
768 0 : aTmpStr.clear();
769 0 : break;
770 :
771 : // CHAR_SPECIAL:
772 : // ????
773 :
774 : // case ARABIC: ist jetzt default
775 : default:
776 503 : aTmpStr = OUString::number(nNo);
777 503 : break;
778 : }
779 :
780 503 : if( SVX_CHARS_UPPER_LETTER == eType )
781 0 : aTmpStr = aTmpStr.toAsciiUpperCase();
782 : }
783 947 : return aTmpStr;
784 : }
785 :
786 11155 : ScHeaderFieldData::ScHeaderFieldData()
787 : :
788 : aDate( Date::EMPTY ),
789 11155 : aTime( tools::Time::EMPTY )
790 : {
791 11155 : nPageNo = nTotalPages = 0;
792 11155 : eNumType = SVX_ARABIC;
793 11155 : }
794 :
795 8024 : ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pEnginePoolP, bool bDeleteEnginePoolP )
796 8024 : : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
797 : {
798 8024 : }
799 :
800 2170 : OUString ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField,
801 : sal_Int32 /* nPara */, sal_Int32 /* nPos */,
802 : Color*& /* rTxtColor */, Color*& /* rFldColor */ )
803 : {
804 2170 : const SvxFieldData* pFieldData = rField.GetField();
805 2170 : if (!pFieldData)
806 0 : return OUString("?");
807 :
808 2170 : OUString aRet;
809 2170 : sal_Int32 nClsId = pFieldData->GetClassId();
810 2170 : switch (nClsId)
811 : {
812 : case text::textfield::Type::PAGE:
813 801 : aRet = lcl_GetNumStr( aData.nPageNo,aData.eNumType );
814 801 : break;
815 : case text::textfield::Type::PAGES:
816 146 : aRet = lcl_GetNumStr( aData.nTotalPages,aData.eNumType );
817 146 : 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 146 : aRet = ScGlobal::pLocaleData->getTime(aData.aTime);
822 146 : break;
823 : case text::textfield::Type::DOCINFO_TITLE:
824 146 : aRet = aData.aTitle;
825 146 : break;
826 : case text::textfield::Type::EXTENDED_FILE:
827 : {
828 0 : switch (static_cast<const SvxExtFileField*>(pFieldData)->GetFormat())
829 : {
830 : case SVXFILEFORMAT_FULLPATH :
831 0 : aRet = aData.aLongDocName;
832 0 : break;
833 : default:
834 0 : aRet = aData.aShortDocName;
835 : }
836 : }
837 0 : break;
838 : case text::textfield::Type::TABLE:
839 784 : aRet = aData.aTabName;
840 784 : break;
841 : case text::textfield::Type::DATE:
842 147 : aRet = ScGlobal::pLocaleData->getDate(aData.aDate);
843 147 : break;
844 : default:
845 0 : aRet = "?";
846 : }
847 :
848 2170 : return aRet;
849 : }
850 :
851 : // Feld-Daten
852 :
853 1184 : ScFieldEditEngine::ScFieldEditEngine(
854 : ScDocument* pDoc, SfxItemPool* pEnginePoolP,
855 : SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP) :
856 : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
857 1184 : mpDoc(pDoc), bExecuteURL(true)
858 : {
859 1184 : if ( pTextObjectPool )
860 674 : SetEditTextObjectPool( pTextObjectPool );
861 1184 : SetControlWord( EEControlBits(GetControlWord() | EEControlBits::MARKFIELDS) & ~EEControlBits::RTFSTYLESHEETS );
862 1184 : }
863 :
864 47 : OUString ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
865 : sal_Int32 /* nPara */, sal_Int32 /* nPos */,
866 : Color*& rTxtColor, Color*& /* rFldColor */ )
867 : {
868 47 : const SvxFieldData* pFieldData = rField.GetField();
869 :
870 47 : if (!pFieldData)
871 0 : return OUString(" ");
872 :
873 47 : return ScEditUtil::GetCellFieldValue(*pFieldData, mpDoc, &rTxtColor);
874 : }
875 :
876 0 : void ScFieldEditEngine::FieldClicked( const SvxFieldItem& rField, sal_Int32, sal_Int32 )
877 : {
878 0 : const SvxFieldData* pFld = rField.GetField();
879 :
880 0 : if ( pFld && pFld->ISA( SvxURLField ) && bExecuteURL )
881 : {
882 0 : const SvxURLField* pURLField = static_cast<const SvxURLField*>(pFld);
883 0 : ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
884 : }
885 0 : }
886 :
887 3 : ScNoteEditEngine::ScNoteEditEngine( SfxItemPool* pEnginePoolP,
888 : SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP ) :
889 3 : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
890 : {
891 3 : if ( pTextObjectPool )
892 3 : SetEditTextObjectPool( pTextObjectPool );
893 3 : SetControlWord( EEControlBits(GetControlWord() | EEControlBits::MARKFIELDS) & ~EEControlBits::RTFSTYLESHEETS );
894 159 : }
895 :
896 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|