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