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 2479 : OUString ScEditUtil::ModifyDelimiters( const OUString& rOld )
59 : {
60 : // underscore is used in function argument names
61 4958 : OUString aRet = OUString( comphelper::string::remove(rOld, '_') ) +
62 12395 : OUString::createFromAscii( pCalcDelimiters ) +
63 7437 : ScCompiler::GetNativeSymbol(ocSep); // argument separator is localized.
64 2479 : return aRet;
65 : }
66 :
67 2224 : static OUString lcl_GetDelimitedString( const EditEngine& rEngine, const sal_Char c )
68 : {
69 2224 : sal_Int32 nParCount = rEngine.GetParagraphCount();
70 2224 : OUStringBuffer aRet( nParCount * 80 );
71 4595 : for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
72 : {
73 2371 : if (nPar > 0)
74 147 : aRet.append(c);
75 2371 : aRet.append( rEngine.GetText( nPar ));
76 : }
77 2224 : 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 1830 : OUString ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine )
94 : {
95 1830 : return lcl_GetDelimitedString(rEngine, ' ');
96 : }
97 394 : OUString ScEditUtil::GetMultilineString( const EditEngine& rEngine )
98 : {
99 394 : 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 392 : OUString ScEditUtil::GetString( const EditTextObject& rEditText, const ScDocument* pDoc )
108 : {
109 : // ScFieldEditEngine is needed to resolve field contents.
110 392 : 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 384 : EditEngine& rEE = const_cast<ScDocument*>(pDoc)->GetEditEngine();
116 384 : rEE.SetText( rEditText);
117 384 : return GetMultilineString( rEE);
118 : }
119 : else
120 : {
121 8 : static osl::Mutex aMutex;
122 8 : osl::MutexGuard aGuard( aMutex);
123 8 : EditEngine& rEE = ScGlobal::GetStaticFieldEditEngine();
124 8 : rEE.SetText( rEditText);
125 8 : 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) == SfxItemState::SET )
158 0 : rEditText.RemoveCharAttribs(AttrTypeMap[i].nCharType);
159 : }
160 0 : }
161 :
162 16 : EditTextObject* ScEditUtil::Clone( const EditTextObject& rObj, ScDocument& rDestDoc )
163 : {
164 16 : EditTextObject* pNew = NULL;
165 :
166 16 : EditEngine& rEngine = rDestDoc.GetEditEngine();
167 16 : 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 16 : rEngine.SetText(rObj);
182 16 : pNew = rEngine.CreateTextObject();
183 : }
184 :
185 16 : return pNew;
186 : }
187 :
188 50 : OUString ScEditUtil::GetCellFieldValue(
189 : const SvxFieldData& rFieldData, const ScDocument* pDoc, Color** ppTextColor )
190 : {
191 50 : OUString aRet;
192 50 : switch (rFieldData.GetClassId())
193 : {
194 : case text::textfield::Type::URL:
195 : {
196 38 : const SvxURLField& rField = static_cast<const SvxURLField&>(rFieldData);
197 38 : OUString aURL = rField.GetURL();
198 :
199 38 : switch (rField.GetFormat())
200 : {
201 : case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
202 : case SVXURLFORMAT_REPR:
203 38 : aRet = rField.GetRepresentation();
204 38 : break;
205 : case SVXURLFORMAT_URL:
206 0 : aRet = aURL;
207 0 : break;
208 : default:
209 : ;
210 : }
211 :
212 : svtools::ColorConfigEntry eEntry =
213 38 : INetURLHistory::GetOrCreate()->QueryUrl(aURL) ? svtools::LINKSVISITED : svtools::LINKS;
214 :
215 38 : if (ppTextColor)
216 36 : *ppTextColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
217 : }
218 38 : 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 4 : Date aDate(Date::SYSTEM);
235 4 : aRet = ScGlobal::pLocaleData->getDate(aDate);
236 : }
237 4 : break;
238 : case text::textfield::Type::DOCINFO_TITLE:
239 : {
240 4 : if (pDoc)
241 : {
242 2 : SfxObjectShell* pDocShell = pDoc->GetDocumentShell();
243 2 : if (pDocShell)
244 : {
245 2 : aRet = pDocShell->getDocProperties()->getTitle();
246 2 : if (aRet.isEmpty())
247 0 : aRet = pDocShell->GetTitle();
248 : }
249 : }
250 4 : if (aRet.isEmpty())
251 2 : aRet = "?";
252 : }
253 4 : break;
254 : case text::textfield::Type::TABLE:
255 : {
256 4 : const SvxTableField& rField = static_cast<const SvxTableField&>(rFieldData);
257 4 : SCTAB nTab = rField.GetTab();
258 4 : OUString aName;
259 4 : if (pDoc && pDoc->GetName(nTab, aName))
260 2 : aRet = aName;
261 : else
262 2 : aRet = "?";
263 : }
264 4 : break;
265 : default:
266 0 : aRet = "?";
267 : }
268 :
269 50 : if (aRet.isEmpty()) // leer ist baeh
270 18 : aRet = " "; // Space ist Default der Editengine
271 :
272 50 : 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 : bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
286 0 : long nLayoutSign = bLayoutRTL ? -1 : 1;
287 :
288 0 : const ScMergeAttr* pMerge = static_cast<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 = static_cast<const SvxMarginItem*>(&pPattern->GetItem(ATTR_MARGIN));
304 0 : sal_uInt16 nIndent = 0;
305 0 : if ( static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue() ==
306 : SVX_HOR_JUSTIFY_LEFT )
307 0 : nIndent = static_cast<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) static_cast<const SvxVerJustifyItem&>(pPattern->
317 0 : GetItem(ATTR_VER_JUSTIFY)).GetValue();
318 :
319 : // asian vertical is always edited top-aligned
320 0 : bool bAsianVertical = static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_STACKED )).GetValue() &&
321 0 : static_cast<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 : vcl::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 434 : ScEditAttrTester::ScEditAttrTester( ScEditEngineDefaulter* pEng ) :
367 : pEngine( pEng ),
368 : pEditAttrs( NULL ),
369 : bNeedsObject( false ),
370 434 : bNeedsCellAttr( false )
371 : {
372 434 : if ( pEngine->GetParagraphCount() > 1 )
373 : {
374 6 : bNeedsObject = true; //! Zellatribute finden ?
375 : }
376 : else
377 : {
378 428 : const SfxPoolItem* pItem = NULL;
379 : pEditAttrs = new SfxItemSet( pEngine->GetAttribs(
380 428 : ESelection(0,0,0,pEngine->GetTextLen(0)), EditEngineAttribs_OnlyHard ) );
381 428 : const SfxItemSet& rEditDefaults = pEngine->GetDefaults();
382 :
383 8128 : for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++)
384 : {
385 7700 : SfxItemState eState = pEditAttrs->GetItemState( nId, false, &pItem );
386 7700 : if (eState == SfxItemState::DONTCARE)
387 0 : bNeedsObject = true;
388 7700 : else if (eState == SfxItemState::SET)
389 : {
390 3330 : if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
391 3038 : 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 584 : if ( *pItem != rEditDefaults.Get(nId) )
399 292 : bNeedsObject = true;
400 : }
401 : else
402 3038 : if (!bNeedsCellAttr)
403 346 : if ( *pItem != rEditDefaults.Get(nId) )
404 346 : bNeedsCellAttr = true;
405 : // rEditDefaults contains the defaults from the cell format
406 : }
407 : }
408 :
409 : // Feldbefehle enthalten?
410 :
411 428 : SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, false );
412 428 : if ( eFieldState == SfxItemState::DONTCARE || eFieldState == SfxItemState::SET )
413 36 : bNeedsObject = true;
414 :
415 : // not converted characters?
416 :
417 428 : SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, false );
418 428 : if ( eConvState == SfxItemState::DONTCARE || eConvState == SfxItemState::SET )
419 0 : bNeedsObject = true;
420 : }
421 434 : }
422 :
423 434 : ScEditAttrTester::~ScEditAttrTester()
424 : {
425 434 : delete pEditAttrs;
426 434 : }
427 :
428 16811 : ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP,
429 : bool bDeleteEnginePoolP )
430 : :
431 : pEnginePool( pEnginePoolP ),
432 : pDefaults( NULL ),
433 : bDeleteEnginePool( bDeleteEnginePoolP ),
434 16811 : bDeleteDefaults( false )
435 : {
436 16811 : }
437 :
438 182 : ScEnginePoolHelper::ScEnginePoolHelper( const ScEnginePoolHelper& rOrg )
439 : :
440 74 : pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ),
441 : pDefaults( NULL ),
442 : bDeleteEnginePool( rOrg.bDeleteEnginePool ),
443 256 : bDeleteDefaults( false )
444 : {
445 182 : }
446 :
447 16991 : ScEnginePoolHelper::~ScEnginePoolHelper()
448 : {
449 16991 : if ( bDeleteDefaults )
450 5102 : delete pDefaults;
451 16991 : if ( bDeleteEnginePool )
452 14242 : SfxItemPool::Free(pEnginePool);
453 16991 : }
454 :
455 16811 : ScEditEngineDefaulter::ScEditEngineDefaulter( SfxItemPool* pEnginePoolP,
456 : bool bDeleteEnginePoolP )
457 : :
458 : ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ),
459 16811 : EditEngine( pEnginePoolP )
460 : {
461 : // All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage.
462 : // DefaultLanguage for InputHandler's EditEngine is updated later.
463 :
464 16811 : SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
465 16811 : }
466 :
467 182 : ScEditEngineDefaulter::ScEditEngineDefaulter( const ScEditEngineDefaulter& rOrg )
468 : :
469 : ScEnginePoolHelper( rOrg ),
470 182 : EditEngine( pEnginePool )
471 : {
472 182 : SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
473 182 : }
474 :
475 18407 : ScEditEngineDefaulter::~ScEditEngineDefaulter()
476 : {
477 18407 : }
478 :
479 21601 : void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, bool bRememberCopy )
480 : {
481 21601 : if ( bRememberCopy )
482 : {
483 3484 : if ( bDeleteDefaults )
484 36 : delete pDefaults;
485 3484 : pDefaults = new SfxItemSet( rSet );
486 3484 : bDeleteDefaults = true;
487 : }
488 21601 : const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
489 21601 : bool bUndo = IsUndoEnabled();
490 21601 : EnableUndo( false );
491 21601 : bool bUpdateMode = GetUpdateMode();
492 21601 : if ( bUpdateMode )
493 4315 : SetUpdateMode( false );
494 21601 : sal_Int32 nPara = GetParagraphCount();
495 43298 : for ( sal_Int32 j=0; j<nPara; j++ )
496 : {
497 21697 : SetParaAttribs( j, rNewSet );
498 : }
499 21601 : if ( bUpdateMode )
500 4315 : SetUpdateMode( true );
501 21601 : if ( bUndo )
502 6529 : EnableUndo( true );
503 21601 : }
504 :
505 3675 : void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, bool bTakeOwnership )
506 : {
507 3675 : if ( bDeleteDefaults )
508 2021 : delete pDefaults;
509 3675 : pDefaults = pSet;
510 3675 : bDeleteDefaults = bTakeOwnership;
511 3675 : if ( pDefaults )
512 3675 : SetDefaults( *pDefaults, false );
513 3675 : }
514 :
515 1047 : void ScEditEngineDefaulter::SetDefaultItem( const SfxPoolItem& rItem )
516 : {
517 1047 : if ( !pDefaults )
518 : {
519 0 : pDefaults = new SfxItemSet( GetEmptyItemSet() );
520 0 : bDeleteDefaults = true;
521 : }
522 1047 : pDefaults->Put( rItem );
523 1047 : SetDefaults( *pDefaults, false );
524 1047 : }
525 :
526 428 : const SfxItemSet& ScEditEngineDefaulter::GetDefaults()
527 : {
528 428 : if ( !pDefaults )
529 : {
530 0 : pDefaults = new SfxItemSet( GetEmptyItemSet() );
531 0 : bDeleteDefaults = true;
532 : }
533 428 : return *pDefaults;
534 : }
535 :
536 4174 : void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject )
537 : {
538 4174 : bool bUpdateMode = GetUpdateMode();
539 4174 : if ( bUpdateMode )
540 4090 : SetUpdateMode( false );
541 4174 : EditEngine::SetText( rTextObject );
542 4174 : if ( pDefaults )
543 2900 : SetDefaults( *pDefaults, false );
544 4174 : if ( bUpdateMode )
545 4090 : SetUpdateMode( true );
546 4174 : }
547 :
548 8588 : void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
549 : const SfxItemSet& rSet, bool bRememberCopy )
550 : {
551 8588 : bool bUpdateMode = GetUpdateMode();
552 8588 : if ( bUpdateMode )
553 8588 : SetUpdateMode( false );
554 8588 : EditEngine::SetText( rTextObject );
555 8588 : SetDefaults( rSet, bRememberCopy );
556 8588 : if ( bUpdateMode )
557 8588 : SetUpdateMode( true );
558 8588 : }
559 :
560 212 : void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
561 : SfxItemSet* pSet, bool bTakeOwnership )
562 : {
563 212 : bool bUpdateMode = GetUpdateMode();
564 212 : if ( bUpdateMode )
565 0 : SetUpdateMode( false );
566 212 : EditEngine::SetText( rTextObject );
567 212 : SetDefaults( pSet, bTakeOwnership );
568 212 : if ( bUpdateMode )
569 0 : SetUpdateMode( true );
570 212 : }
571 :
572 15449 : void ScEditEngineDefaulter::SetText( const OUString& rText )
573 : {
574 15449 : bool bUpdateMode = GetUpdateMode();
575 15449 : if ( bUpdateMode )
576 9138 : SetUpdateMode( false );
577 15449 : EditEngine::SetText( rText );
578 15449 : if ( pDefaults )
579 1927 : SetDefaults( *pDefaults, false );
580 15449 : if ( bUpdateMode )
581 9138 : SetUpdateMode( true );
582 15449 : }
583 :
584 60 : void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
585 : const SfxItemSet& rSet, bool bRememberCopy )
586 : {
587 60 : bool bUpdateMode = GetUpdateMode();
588 60 : if ( bUpdateMode )
589 60 : SetUpdateMode( false );
590 60 : EditEngine::SetText( rText );
591 60 : SetDefaults( rSet, bRememberCopy );
592 60 : if ( bUpdateMode )
593 60 : SetUpdateMode( true );
594 60 : }
595 :
596 1766 : void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
597 : SfxItemSet* pSet, bool bTakeOwnership )
598 : {
599 1766 : bool bUpdateMode = GetUpdateMode();
600 1766 : if ( bUpdateMode )
601 0 : SetUpdateMode( false );
602 1766 : EditEngine::SetText( rText );
603 1766 : SetDefaults( pSet, bTakeOwnership );
604 1766 : if ( bUpdateMode )
605 0 : SetUpdateMode( true );
606 1766 : }
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 : 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 ) == SfxItemState::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 ) == SfxItemState::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 907 : ScTabEditEngine::ScTabEditEngine( ScDocument* pDoc )
692 907 : : ScEditEngineDefaulter( pDoc->GetEnginePool() )
693 : {
694 907 : SetEditTextObjectPool( pDoc->GetEditPool() );
695 907 : Init(static_cast<const ScPatternAttr&>(pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)));
696 907 : }
697 :
698 2 : ScTabEditEngine::ScTabEditEngine( const ScPatternAttr& rPattern,
699 : SfxItemPool* pEnginePoolP, SfxItemPool* pTextObjectPool )
700 2 : : ScEditEngineDefaulter( pEnginePoolP )
701 : {
702 2 : if ( pTextObjectPool )
703 2 : SetEditTextObjectPool( pTextObjectPool );
704 2 : Init( rPattern );
705 2 : }
706 :
707 909 : void ScTabEditEngine::Init( const ScPatternAttr& rPattern )
708 : {
709 909 : SetRefMapMode(MAP_100TH_MM);
710 909 : SfxItemSet* pEditDefaults = new SfxItemSet( GetEmptyItemSet() );
711 909 : rPattern.FillEditItemSet( pEditDefaults );
712 909 : SetDefaults( pEditDefaults );
713 : // wir haben keine StyleSheets fuer Text
714 909 : SetControlWord( GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
715 909 : }
716 :
717 : // Feldbefehle fuer Kopf- und Fusszeilen
718 :
719 : // Zahlen aus \sw\source\core\doc\numbers.cxx
720 :
721 0 : static OUString lcl_GetCharStr( sal_Int32 nNo )
722 : {
723 : OSL_ENSURE( nNo, "0 is an invalid number !!" );
724 0 : OUString aStr;
725 :
726 0 : const sal_Int32 coDiff = 'Z' - 'A' +1;
727 : sal_Int32 nCalc;
728 :
729 0 : do {
730 0 : nCalc = nNo % coDiff;
731 0 : if( !nCalc )
732 0 : nCalc = coDiff;
733 0 : aStr = OUString( (sal_Unicode)('a' - 1 + nCalc ) ) + aStr;
734 0 : nNo = sal::static_int_cast<sal_Int32>( nNo - nCalc );
735 0 : if( nNo )
736 0 : nNo /= coDiff;
737 : } while( nNo );
738 0 : return aStr;
739 : }
740 :
741 1648 : static OUString lcl_GetNumStr(sal_Int32 nNo, SvxNumType eType)
742 : {
743 1648 : OUString aTmpStr('0');
744 1648 : if( nNo )
745 : {
746 900 : switch( eType )
747 : {
748 : case SVX_CHARS_UPPER_LETTER:
749 : case SVX_CHARS_LOWER_LETTER:
750 0 : aTmpStr = lcl_GetCharStr( nNo );
751 0 : break;
752 :
753 : case SVX_ROMAN_UPPER:
754 : case SVX_ROMAN_LOWER:
755 0 : if( nNo < 4000 )
756 0 : aTmpStr = SvxNumberFormat::CreateRomanString( nNo, ( eType == SVX_ROMAN_UPPER ) );
757 : else
758 0 : aTmpStr = OUString();
759 0 : break;
760 :
761 : case SVX_NUMBER_NONE:
762 0 : aTmpStr = OUString();
763 0 : break;
764 :
765 : // CHAR_SPECIAL:
766 : // ????
767 :
768 : // case ARABIC: ist jetzt default
769 : default:
770 900 : aTmpStr = OUString::number(nNo);
771 900 : break;
772 : }
773 :
774 900 : if( SVX_CHARS_UPPER_LETTER == eType )
775 0 : aTmpStr = aTmpStr.toAsciiUpperCase();
776 : }
777 1648 : return aTmpStr;
778 : }
779 :
780 18218 : ScHeaderFieldData::ScHeaderFieldData()
781 : :
782 : aDate( Date::EMPTY ),
783 18218 : aTime( tools::Time::EMPTY )
784 : {
785 18218 : nPageNo = nTotalPages = 0;
786 18218 : eNumType = SVX_ARABIC;
787 18218 : }
788 :
789 13074 : ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pEnginePoolP, bool bDeleteEnginePoolP )
790 13074 : : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
791 : {
792 13074 : }
793 :
794 3748 : OUString ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField,
795 : sal_Int32 /* nPara */, sal_Int32 /* nPos */,
796 : Color*& /* rTxtColor */, Color*& /* rFldColor */ )
797 : {
798 3748 : const SvxFieldData* pFieldData = rField.GetField();
799 3748 : if (!pFieldData)
800 0 : return OUString("?");
801 :
802 3748 : OUString aRet;
803 3748 : sal_Int32 nClsId = pFieldData->GetClassId();
804 3748 : switch (nClsId)
805 : {
806 : case text::textfield::Type::PAGE:
807 1406 : aRet = lcl_GetNumStr( aData.nPageNo,aData.eNumType );
808 1406 : break;
809 : case text::textfield::Type::PAGES:
810 242 : aRet = lcl_GetNumStr( aData.nTotalPages,aData.eNumType );
811 242 : break;
812 : case text::textfield::Type::EXTENDED_TIME:
813 : case text::textfield::Type::TIME:
814 : // For now, time field in the header / footer is always dynamic.
815 242 : aRet = ScGlobal::pLocaleData->getTime(aData.aTime);
816 242 : break;
817 : case text::textfield::Type::DOCINFO_TITLE:
818 242 : aRet = aData.aTitle;
819 242 : break;
820 : case text::textfield::Type::EXTENDED_FILE:
821 : {
822 0 : switch (static_cast<const SvxExtFileField*>(pFieldData)->GetFormat())
823 : {
824 : case SVXFILEFORMAT_FULLPATH :
825 0 : aRet = aData.aLongDocName;
826 0 : break;
827 : default:
828 0 : aRet = aData.aShortDocName;
829 : }
830 : }
831 0 : break;
832 : case text::textfield::Type::TABLE:
833 1372 : aRet = aData.aTabName;
834 1372 : break;
835 : case text::textfield::Type::DATE:
836 244 : aRet = ScGlobal::pLocaleData->getDate(aData.aDate);
837 244 : break;
838 : default:
839 0 : aRet = "?";
840 : }
841 :
842 3748 : return aRet;
843 : }
844 :
845 : // Feld-Daten
846 :
847 1276 : ScFieldEditEngine::ScFieldEditEngine(
848 : ScDocument* pDoc, SfxItemPool* pEnginePoolP,
849 : SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP) :
850 : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
851 1276 : mpDoc(pDoc), bExecuteURL(true)
852 : {
853 1276 : if ( pTextObjectPool )
854 1048 : SetEditTextObjectPool( pTextObjectPool );
855 1276 : SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
856 1276 : }
857 :
858 48 : OUString ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
859 : sal_Int32 /* nPara */, sal_Int32 /* nPos */,
860 : Color*& rTxtColor, Color*& /* rFldColor */ )
861 : {
862 48 : const SvxFieldData* pFieldData = rField.GetField();
863 :
864 48 : if (!pFieldData)
865 0 : return OUString(" ");
866 :
867 48 : return ScEditUtil::GetCellFieldValue(*pFieldData, mpDoc, &rTxtColor);
868 : }
869 :
870 0 : void ScFieldEditEngine::FieldClicked( const SvxFieldItem& rField, sal_Int32, sal_Int32 )
871 : {
872 0 : const SvxFieldData* pFld = rField.GetField();
873 :
874 0 : if ( pFld && pFld->ISA( SvxURLField ) && bExecuteURL )
875 : {
876 0 : const SvxURLField* pURLField = static_cast<const SvxURLField*>(pFld);
877 0 : ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
878 : }
879 0 : }
880 :
881 4 : ScNoteEditEngine::ScNoteEditEngine( SfxItemPool* pEnginePoolP,
882 : SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP ) :
883 4 : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
884 : {
885 4 : if ( pTextObjectPool )
886 4 : SetEditTextObjectPool( pTextObjectPool );
887 4 : SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
888 232 : }
889 :
890 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|