xref: /AOO41X/main/sc/source/core/tool/editutil.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // System - Includes -----------------------------------------------------
32 
33 
34 
35 // INCLUDE ---------------------------------------------------------------
36 
37 #include "scitems.hxx"
38 #include <editeng/eeitem.hxx>
39 
40 #include <svx/algitem.hxx>
41 #include <svtools/colorcfg.hxx>
42 #include <editeng/editview.hxx>
43 #include <editeng/editstat.hxx>
44 #include <editeng/escpitem.hxx>
45 #include <editeng/flditem.hxx>
46 #include <editeng/numitem.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/outdev.hxx>
49 #include <svl/inethist.hxx>
50 #include <unotools/syslocale.hxx>
51 #ifndef _SVSTDARR_USHORTS
52 #define _SVSTDARR_USHORTS
53 #include <svl/svstdarr.hxx>
54 #endif
55 
56 #include "editutil.hxx"
57 #include "global.hxx"
58 #include "attrib.hxx"
59 #include "document.hxx"
60 #include "docpool.hxx"
61 #include "patattr.hxx"
62 #include "scmod.hxx"
63 #include "inputopt.hxx"
64 #include "compiler.hxx"
65 
66 // STATIC DATA -----------------------------------------------------------
67 
68 //	Delimiters zusaetzlich zu EditEngine-Default:
69 
70 const sal_Char __FAR_DATA ScEditUtil::pCalcDelimiters[] = "=()+-*/^&<>";
71 
72 
73 //------------------------------------------------------------------------
74 
75 String ScEditUtil::ModifyDelimiters( const String& rOld )
76 {
77 	String aRet = rOld;
78 	aRet.EraseAllChars( '_' );	// underscore is used in function argument names
79 	aRet.AppendAscii( RTL_CONSTASCII_STRINGPARAM( pCalcDelimiters ) );
80     aRet.Append(ScCompiler::GetNativeSymbol(ocSep)); // argument separator is localized.
81 	return aRet;
82 }
83 
84 static String lcl_GetDelimitedString( const EditEngine& rEngine, const sal_Char c )
85 {
86 	String aRet;
87 	sal_uInt16 nParCount = rEngine.GetParagraphCount();
88 	for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
89 	{
90 		if (nPar > 0)
91 			aRet += c;
92 		aRet += rEngine.GetText( nPar );
93 	}
94 	return aRet;
95 }
96 
97 String ScEditUtil::GetSpaceDelimitedString( const EditEngine& rEngine )
98 {
99     return lcl_GetDelimitedString(rEngine, ' ');
100 }
101 
102 String ScEditUtil::GetMultilineString( const EditEngine& rEngine )
103 {
104     return lcl_GetDelimitedString(rEngine, '\n');
105 }
106 
107 //------------------------------------------------------------------------
108 
109 Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, sal_Bool bForceToTop )
110 {
111 	// bForceToTop = always align to top, for editing
112 	// (sal_False for querying URLs etc.)
113 
114 	if (!pPattern)
115 		pPattern = pDoc->GetPattern( nCol, nRow, nTab );
116 
117 	Point aStartPos = aScrPos;
118 
119 	sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
120 	long nLayoutSign = bLayoutRTL ? -1 : 1;
121 
122 	const ScMergeAttr* pMerge = (const ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
123 	long nCellX = (long) ( pDoc->GetColWidth(nCol,nTab) * nPPTX );
124 	if ( pMerge->GetColMerge() > 1 )
125 	{
126 		SCCOL nCountX = pMerge->GetColMerge();
127 		for (SCCOL i=1; i<nCountX; i++)
128 			nCellX += (long) ( pDoc->GetColWidth(nCol+i,nTab) * nPPTX );
129 	}
130 	long nCellY = (long) ( pDoc->GetRowHeight(nRow,nTab) * nPPTY );
131 	if ( pMerge->GetRowMerge() > 1 )
132 	{
133 		SCROW nCountY = pMerge->GetRowMerge();
134         nCellY += (long) pDoc->GetScaledRowHeight( nRow+1, nRow+nCountY-1, nTab, nPPTY);
135 	}
136 
137 	const SvxMarginItem* pMargin = (const SvxMarginItem*)&pPattern->GetItem(ATTR_MARGIN);
138 	sal_uInt16 nIndent = 0;
139 	if ( ((const SvxHorJustifyItem&)pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue() ==
140 				SVX_HOR_JUSTIFY_LEFT )
141 		nIndent = ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue();
142 	long nPixDifX	= (long) ( ( pMargin->GetLeftMargin() + nIndent ) * nPPTX );
143 	aStartPos.X()	+= nPixDifX * nLayoutSign;
144 	nCellX			-= nPixDifX + (long) ( pMargin->GetRightMargin() * nPPTX );		// wegen Umbruch etc.
145 
146 	//	vertikale Position auf die in der Tabelle anpassen
147 
148 	long nPixDifY;
149 	long nTopMargin = (long) ( pMargin->GetTopMargin() * nPPTY );
150 	SvxCellVerJustify eJust = (SvxCellVerJustify) ((const SvxVerJustifyItem&)pPattern->
151 												GetItem(ATTR_VER_JUSTIFY)).GetValue();
152 
153 	//	asian vertical is always edited top-aligned
154     sal_Bool bAsianVertical = ((const SfxBoolItem&)pPattern->GetItem( ATTR_STACKED )).GetValue() &&
155 		((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN )).GetValue();
156 
157 	if ( eJust == SVX_VER_JUSTIFY_TOP ||
158 			( bForceToTop && ( SC_MOD()->GetInputOptions().GetTextWysiwyg() || bAsianVertical ) ) )
159 		nPixDifY = nTopMargin;
160 	else
161 	{
162 		MapMode aMode = pDev->GetMapMode();
163 		pDev->SetMapMode( MAP_PIXEL );
164 
165 		long nTextHeight = pDoc->GetNeededSize( nCol, nRow, nTab,
166 												pDev, nPPTX, nPPTY, aZoomX, aZoomY, sal_False );
167 		if (!nTextHeight)
168 		{									// leere Zelle
169 			Font aFont;
170 			// font color doesn't matter here
171 			pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aZoomY );
172 			pDev->SetFont(aFont);
173 			nTextHeight = pDev->GetTextHeight() + nTopMargin +
174 							(long) ( pMargin->GetBottomMargin() * nPPTY );
175 		}
176 
177 		pDev->SetMapMode(aMode);
178 
179 		if ( nTextHeight > nCellY + nTopMargin || bForceToTop )
180 			nPixDifY = 0;							// zu gross -> oben anfangen
181 		else
182 		{
183 			if ( eJust == SVX_VER_JUSTIFY_CENTER )
184 				nPixDifY = nTopMargin + ( nCellY - nTextHeight ) / 2;
185 			else
186 				nPixDifY = nCellY - nTextHeight + nTopMargin;		// JUSTIFY_BOTTOM
187 		}
188 	}
189 
190 	aStartPos.Y() += nPixDifY;
191 	nCellY		-= nPixDifY;
192 
193 	if ( bLayoutRTL )
194 		aStartPos.X() -= nCellX - 2;	// excluding grid on both sides
195 
196 														//	-1 -> Gitter nicht ueberschreiben
197 	return Rectangle( aStartPos, Size(nCellX-1,nCellY-1) );
198 }
199 
200 //------------------------------------------------------------------------
201 
202 ScEditAttrTester::ScEditAttrTester( ScEditEngineDefaulter* pEng ) :
203 	pEngine( pEng ),
204 	pEditAttrs( NULL ),
205 	bNeedsObject( sal_False ),
206 	bNeedsCellAttr( sal_False )
207 {
208 	if ( pEngine->GetParagraphCount() > 1 )
209 	{
210 		bNeedsObject = sal_True;			//!	Zellatribute finden ?
211 	}
212 	else
213 	{
214 		const SfxPoolItem* pItem = NULL;
215 		pEditAttrs = new SfxItemSet( pEngine->GetAttribs(
216 										ESelection(0,0,0,pEngine->GetTextLen(0)), EditEngineAttribs_OnlyHard ) );
217         const SfxItemSet& rEditDefaults = pEngine->GetDefaults();
218 
219 		for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++)
220 		{
221 			SfxItemState eState = pEditAttrs->GetItemState( nId, sal_False, &pItem );
222 			if (eState == SFX_ITEM_DONTCARE)
223 				bNeedsObject = sal_True;
224 			else if (eState == SFX_ITEM_SET)
225 			{
226 				if ( nId == EE_CHAR_ESCAPEMENT || nId == EE_CHAR_PAIRKERNING ||
227 						nId == EE_CHAR_KERNING || nId == EE_CHAR_XMLATTRIBS )
228 				{
229 					//	Escapement and kerning are kept in EditEngine because there are no
230 					//	corresponding cell format items. User defined attributes are kept in
231 					//	EditEngine because "user attributes applied to all the text" is different
232 					//	from "user attributes applied to the cell".
233 
234 					if ( *pItem != rEditDefaults.Get(nId) )
235 						bNeedsObject = sal_True;
236 				}
237 				else
238 					if (!bNeedsCellAttr)
239 						if ( *pItem != rEditDefaults.Get(nId) )
240 							bNeedsCellAttr = sal_True;
241                 //  rEditDefaults contains the defaults from the cell format
242 			}
243 		}
244 
245 		//	Feldbefehle enthalten?
246 
247 		SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, sal_False );
248 		if ( eFieldState == SFX_ITEM_DONTCARE || eFieldState == SFX_ITEM_SET )
249 			bNeedsObject = sal_True;
250 
251 		//	not converted characters?
252 
253 		SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, sal_False );
254 		if ( eConvState == SFX_ITEM_DONTCARE || eConvState == SFX_ITEM_SET )
255 			bNeedsObject = sal_True;
256 	}
257 }
258 
259 ScEditAttrTester::~ScEditAttrTester()
260 {
261 	delete pEditAttrs;
262 }
263 
264 
265 //------------------------------------------------------------------------
266 
267 ScEnginePoolHelper::ScEnginePoolHelper( SfxItemPool* pEnginePoolP,
268 				sal_Bool bDeleteEnginePoolP )
269 			:
270 			pEnginePool( pEnginePoolP ),
271 			pDefaults( NULL ),
272 			bDeleteEnginePool( bDeleteEnginePoolP ),
273 			bDeleteDefaults( sal_False )
274 {
275 }
276 
277 
278 ScEnginePoolHelper::ScEnginePoolHelper( const ScEnginePoolHelper& rOrg )
279 			:
280 			pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ),
281 			pDefaults( NULL ),
282 			bDeleteEnginePool( rOrg.bDeleteEnginePool ),
283 			bDeleteDefaults( sal_False )
284 {
285 }
286 
287 
288 ScEnginePoolHelper::~ScEnginePoolHelper()
289 {
290 	if ( bDeleteDefaults )
291 		delete pDefaults;
292 	if ( bDeleteEnginePool )
293 		SfxItemPool::Free(pEnginePool);
294 }
295 
296 
297 //------------------------------------------------------------------------
298 
299 ScEditEngineDefaulter::ScEditEngineDefaulter( SfxItemPool* pEnginePoolP,
300 				sal_Bool bDeleteEnginePoolP )
301 			:
302 			ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ),
303 			EditEngine( pEnginePoolP )
304 {
305 	//	All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage.
306 	//	DefaultLanguage for InputHandler's EditEngine is updated later.
307 
308 	SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
309 }
310 
311 
312 ScEditEngineDefaulter::ScEditEngineDefaulter( const ScEditEngineDefaulter& rOrg )
313 			:
314 			ScEnginePoolHelper( rOrg ),
315 			EditEngine( pEnginePool )
316 {
317 	SetDefaultLanguage( ScGlobal::GetEditDefaultLanguage() );
318 }
319 
320 
321 ScEditEngineDefaulter::~ScEditEngineDefaulter()
322 {
323 }
324 
325 
326 void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, sal_Bool bRememberCopy )
327 {
328 	if ( bRememberCopy )
329 	{
330 		if ( bDeleteDefaults )
331 			delete pDefaults;
332 		pDefaults = new SfxItemSet( rSet );
333 		bDeleteDefaults = sal_True;
334 	}
335 	const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
336 	sal_Bool bUndo = IsUndoEnabled();
337 	EnableUndo( sal_False );
338 	sal_Bool bUpdateMode = GetUpdateMode();
339 	if ( bUpdateMode )
340 		SetUpdateMode( sal_False );
341 	sal_uInt16 nPara = GetParagraphCount();
342 	for ( sal_uInt16 j=0; j<nPara; j++ )
343 	{
344 		SetParaAttribs( j, rNewSet );
345 	}
346 	if ( bUpdateMode )
347 		SetUpdateMode( sal_True );
348 	if ( bUndo )
349 		EnableUndo( sal_True );
350 }
351 
352 
353 void ScEditEngineDefaulter::SetDefaults( SfxItemSet* pSet, sal_Bool bTakeOwnership )
354 {
355 	if ( bDeleteDefaults )
356 		delete pDefaults;
357 	pDefaults = pSet;
358 	bDeleteDefaults = bTakeOwnership;
359 	if ( pDefaults )
360 		SetDefaults( *pDefaults, sal_False );
361 }
362 
363 
364 void ScEditEngineDefaulter::SetDefaultItem( const SfxPoolItem& rItem )
365 {
366 	if ( !pDefaults )
367 	{
368 		pDefaults = new SfxItemSet( GetEmptyItemSet() );
369 		bDeleteDefaults = sal_True;
370 	}
371 	pDefaults->Put( rItem );
372 	SetDefaults( *pDefaults, sal_False );
373 }
374 
375 const SfxItemSet& ScEditEngineDefaulter::GetDefaults()
376 {
377     if ( !pDefaults )
378     {
379         pDefaults = new SfxItemSet( GetEmptyItemSet() );
380         bDeleteDefaults = sal_True;
381     }
382     return *pDefaults;
383 }
384 
385 void ScEditEngineDefaulter::SetText( const EditTextObject& rTextObject )
386 {
387 	sal_Bool bUpdateMode = GetUpdateMode();
388 	if ( bUpdateMode )
389 		SetUpdateMode( sal_False );
390 	EditEngine::SetText( rTextObject );
391 	if ( pDefaults )
392 		SetDefaults( *pDefaults, sal_False );
393 	if ( bUpdateMode )
394 		SetUpdateMode( sal_True );
395 }
396 
397 void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
398 			const SfxItemSet& rSet, sal_Bool bRememberCopy )
399 {
400 	sal_Bool bUpdateMode = GetUpdateMode();
401 	if ( bUpdateMode )
402 		SetUpdateMode( sal_False );
403 	EditEngine::SetText( rTextObject );
404 	SetDefaults( rSet, bRememberCopy );
405 	if ( bUpdateMode )
406 		SetUpdateMode( sal_True );
407 }
408 
409 void ScEditEngineDefaulter::SetTextNewDefaults( const EditTextObject& rTextObject,
410 			SfxItemSet* pSet, sal_Bool bTakeOwnership )
411 {
412 	sal_Bool bUpdateMode = GetUpdateMode();
413 	if ( bUpdateMode )
414 		SetUpdateMode( sal_False );
415 	EditEngine::SetText( rTextObject );
416 	SetDefaults( pSet, bTakeOwnership );
417 	if ( bUpdateMode )
418 		SetUpdateMode( sal_True );
419 }
420 
421 
422 void ScEditEngineDefaulter::SetText( const String& rText )
423 {
424 	sal_Bool bUpdateMode = GetUpdateMode();
425 	if ( bUpdateMode )
426 		SetUpdateMode( sal_False );
427 	EditEngine::SetText( rText );
428 	if ( pDefaults )
429 		SetDefaults( *pDefaults, sal_False );
430 	if ( bUpdateMode )
431 		SetUpdateMode( sal_True );
432 }
433 
434 void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText,
435 			const SfxItemSet& rSet, sal_Bool bRememberCopy )
436 {
437 	sal_Bool bUpdateMode = GetUpdateMode();
438 	if ( bUpdateMode )
439 		SetUpdateMode( sal_False );
440 	EditEngine::SetText( rText );
441 	SetDefaults( rSet, bRememberCopy );
442 	if ( bUpdateMode )
443 		SetUpdateMode( sal_True );
444 }
445 
446 void ScEditEngineDefaulter::SetTextNewDefaults( const String& rText,
447 			SfxItemSet* pSet, sal_Bool bTakeOwnership )
448 {
449 	sal_Bool bUpdateMode = GetUpdateMode();
450 	if ( bUpdateMode )
451 		SetUpdateMode( sal_False );
452 	EditEngine::SetText( rText );
453 	SetDefaults( pSet, bTakeOwnership );
454 	if ( bUpdateMode )
455 		SetUpdateMode( sal_True );
456 }
457 
458 void ScEditEngineDefaulter::RepeatDefaults()
459 {
460     if ( pDefaults )
461     {
462         sal_uInt16 nPara = GetParagraphCount();
463         for ( sal_uInt16 j=0; j<nPara; j++ )
464             SetParaAttribs( j, *pDefaults );
465     }
466 }
467 
468 void ScEditEngineDefaulter::RemoveParaAttribs()
469 {
470 	SfxItemSet* pCharItems = NULL;
471 	sal_Bool bUpdateMode = GetUpdateMode();
472 	if ( bUpdateMode )
473 		SetUpdateMode( sal_False );
474 	sal_uInt16 nParCount = GetParagraphCount();
475 	for (sal_uInt16 nPar=0; nPar<nParCount; nPar++)
476 	{
477 		const SfxItemSet& rParaAttribs = GetParaAttribs( nPar );
478 		sal_uInt16 nWhich;
479 		for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
480 		{
481 			const SfxPoolItem* pParaItem;
482 			if ( rParaAttribs.GetItemState( nWhich, sal_False, &pParaItem ) == SFX_ITEM_SET )
483 			{
484 				//	if defaults are set, use only items that are different from default
485 				if ( !pDefaults || *pParaItem != pDefaults->Get(nWhich) )
486 				{
487 					if (!pCharItems)
488 						pCharItems = new SfxItemSet( GetEmptyItemSet() );
489 					pCharItems->Put( *pParaItem );
490 				}
491 			}
492 		}
493 
494 		if ( pCharItems )
495 		{
496 			SvUShorts aPortions;
497 			GetPortions( nPar, aPortions );
498 
499 			//	loop through the portions of the paragraph, and set only those items
500 			//	that are not overridden by existing character attributes
501 
502 			sal_uInt16 nPCount = aPortions.Count();
503 			sal_uInt16 nStart = 0;
504 			for ( sal_uInt16 nPos=0; nPos<nPCount; nPos++ )
505 			{
506 				sal_uInt16 nEnd = aPortions.GetObject( nPos );
507 				ESelection aSel( nPar, nStart, nPar, nEnd );
508 				SfxItemSet aOldCharAttrs = GetAttribs( aSel );
509 				SfxItemSet aNewCharAttrs = *pCharItems;
510 				for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
511 				{
512 					//	Clear those items that are different from existing character attributes.
513 					//	Where no character attributes are set, GetAttribs returns the paragraph attributes.
514 					const SfxPoolItem* pItem;
515 					if ( aNewCharAttrs.GetItemState( nWhich, sal_False, &pItem ) == SFX_ITEM_SET &&
516 						 *pItem != aOldCharAttrs.Get(nWhich) )
517 					{
518 						aNewCharAttrs.ClearItem(nWhich);
519 					}
520 				}
521 				if ( aNewCharAttrs.Count() )
522 					QuickSetAttribs( aNewCharAttrs, aSel );
523 
524 				nStart = nEnd;
525 			}
526 
527 			DELETEZ( pCharItems );
528 		}
529 
530 		if ( rParaAttribs.Count() )
531 		{
532 			//	clear all paragraph attributes (including defaults),
533 			//	so they are not contained in resulting EditTextObjects
534 
535 			SetParaAttribs( nPar, SfxItemSet( *rParaAttribs.GetPool(), rParaAttribs.GetRanges() ) );
536 		}
537 	}
538 	if ( bUpdateMode )
539 		SetUpdateMode( sal_True );
540 }
541 
542 //------------------------------------------------------------------------
543 
544 ScTabEditEngine::ScTabEditEngine( ScDocument* pDoc )
545 		: ScEditEngineDefaulter( pDoc->GetEnginePool() )
546 {
547 	SetEditTextObjectPool( pDoc->GetEditPool() );
548 	Init((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
549 }
550 
551 ScTabEditEngine::ScTabEditEngine( const ScPatternAttr& rPattern,
552             SfxItemPool* pEnginePoolP, SfxItemPool* pTextObjectPool )
553         : ScEditEngineDefaulter( pEnginePoolP )
554 {
555 	if ( pTextObjectPool )
556 		SetEditTextObjectPool( pTextObjectPool );
557 	Init( rPattern );
558 }
559 
560 void ScTabEditEngine::Init( const ScPatternAttr& rPattern )
561 {
562 	SetRefMapMode(MAP_100TH_MM);
563 	SfxItemSet* pEditDefaults = new SfxItemSet( GetEmptyItemSet() );
564 	rPattern.FillEditItemSet( pEditDefaults );
565 	SetDefaults( pEditDefaults );
566 	// wir haben keine StyleSheets fuer Text
567 	SetControlWord( GetControlWord() & ~EE_CNTRL_RTFSTYLESHEETS );
568 }
569 
570 //------------------------------------------------------------------------
571 //		Feldbefehle fuer Kopf- und Fusszeilen
572 //------------------------------------------------------------------------
573 
574 //
575 //		Zahlen aus \sw\source\core\doc\numbers.cxx
576 //
577 
578 String lcl_GetCharStr( sal_Int32 nNo )
579 {
580 	DBG_ASSERT( nNo, "0 ist eine ungueltige Nummer !!" );
581 	String aStr;
582 
583     const sal_Int32 coDiff = 'Z' - 'A' +1;
584     sal_Int32 nCalc;
585 
586 	do {
587 		nCalc = nNo % coDiff;
588 		if( !nCalc )
589 			nCalc = coDiff;
590 		aStr.Insert( (sal_Unicode)('a' - 1 + nCalc ), 0 );
591         nNo = sal::static_int_cast<sal_Int32>( nNo - nCalc );
592 		if( nNo )
593 			nNo /= coDiff;
594 	} while( nNo );
595 	return aStr;
596 }
597 
598 String lcl_GetNumStr( sal_Int32 nNo, SvxNumType eType )
599 {
600 	String aTmpStr( '0' );
601 	if( nNo )
602 	{
603 		switch( eType )
604 		{
605 		case SVX_CHARS_UPPER_LETTER:
606 		case SVX_CHARS_LOWER_LETTER:
607 			aTmpStr = lcl_GetCharStr( nNo );
608 			break;
609 
610 		case SVX_ROMAN_UPPER:
611 		case SVX_ROMAN_LOWER:
612             if( nNo < 4000 )
613                 aTmpStr = SvxNumberFormat::CreateRomanString( nNo, ( eType == SVX_ROMAN_UPPER ) );
614             else
615                 aTmpStr.Erase();
616 			break;
617 
618 		case SVX_NUMBER_NONE:
619 			aTmpStr.Erase();
620 			break;
621 
622 //		CHAR_SPECIAL:
623 //			????
624 
625 //		case ARABIC:	ist jetzt default
626 		default:
627 			aTmpStr = String::CreateFromInt32( nNo );
628 			break;
629 		}
630 
631         if( SVX_CHARS_UPPER_LETTER == eType )
632 			aTmpStr.ToUpperAscii();
633 	}
634 	return aTmpStr;
635 }
636 
637 ScHeaderFieldData::ScHeaderFieldData()
638 {
639 	nPageNo = nTotalPages = 0;
640 	eNumType = SVX_ARABIC;
641 }
642 
643 ScHeaderEditEngine::ScHeaderEditEngine( SfxItemPool* pEnginePoolP, sal_Bool bDeleteEnginePoolP )
644         : ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
645 {
646 }
647 
648 String __EXPORT ScHeaderEditEngine::CalcFieldValue( const SvxFieldItem& rField,
649                                     sal_uInt16 /* nPara */, sal_uInt16 /* nPos */,
650                                     Color*& /* rTxtColor */, Color*& /* rFldColor */ )
651 {
652 	String aRet;
653 	const SvxFieldData*	pFieldData = rField.GetField();
654 	if ( pFieldData )
655 	{
656 		TypeId aType = pFieldData->Type();
657 		if (aType == TYPE(SvxPageField))
658             aRet = lcl_GetNumStr( aData.nPageNo,aData.eNumType );
659 		else if (aType == TYPE(SvxPagesField))
660             aRet = lcl_GetNumStr( aData.nTotalPages,aData.eNumType );
661 		else if (aType == TYPE(SvxTimeField))
662             aRet = ScGlobal::pLocaleData->getTime(aData.aTime);
663 		else if (aType == TYPE(SvxFileField))
664 			aRet = aData.aTitle;
665 		else if (aType == TYPE(SvxExtFileField))
666 		{
667 			switch ( ((const SvxExtFileField*)pFieldData)->GetFormat() )
668 			{
669 				case SVXFILEFORMAT_FULLPATH :
670 					aRet = aData.aLongDocName;
671 				break;
672 				default:
673 					aRet = aData.aShortDocName;
674 			}
675 		}
676 		else if (aType == TYPE(SvxTableField))
677 			aRet = aData.aTabName;
678 		else if (aType == TYPE(SvxDateField))
679             aRet = ScGlobal::pLocaleData->getDate(aData.aDate);
680 		else
681 		{
682 			//DBG_ERROR("unbekannter Feldbefehl");
683 			aRet = '?';
684 		}
685 	}
686 	else
687 	{
688 		DBG_ERROR("FieldData ist 0");
689 		aRet = '?';
690 	}
691 
692 	return aRet;
693 }
694 
695 //------------------------------------------------------------------------
696 //
697 //							Feld-Daten
698 //
699 //------------------------------------------------------------------------
700 
701 ScFieldEditEngine::ScFieldEditEngine( SfxItemPool* pEnginePoolP,
702             SfxItemPool* pTextObjectPool, sal_Bool bDeleteEnginePoolP )
703 		:
704         ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
705 		bExecuteURL( sal_True )
706 {
707 	if ( pTextObjectPool )
708 		SetEditTextObjectPool( pTextObjectPool );
709 	//	EE_CNTRL_URLSFXEXECUTE nicht, weil die Edit-Engine den ViewFrame nicht kennt
710 	// wir haben keine StyleSheets fuer Text
711 	SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
712 }
713 
714 String __EXPORT ScFieldEditEngine::CalcFieldValue( const SvxFieldItem& rField,
715                                     sal_uInt16 /* nPara */, sal_uInt16 /* nPos */,
716                                     Color*& rTxtColor, Color*& /* rFldColor */ )
717 {
718 	String aRet;
719 	const SvxFieldData*	pFieldData = rField.GetField();
720 
721 	if ( pFieldData )
722 	{
723 		TypeId aType = pFieldData->Type();
724 
725 		if (aType == TYPE(SvxURLField))
726 		{
727 			String aURL = ((const SvxURLField*)pFieldData)->GetURL();
728 
729 			switch ( ((const SvxURLField*)pFieldData)->GetFormat() )
730 			{
731 				case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
732 				case SVXURLFORMAT_REPR:
733 					aRet = ((const SvxURLField*)pFieldData)->GetRepresentation();
734 					break;
735 
736 				case SVXURLFORMAT_URL:
737 					aRet = aURL;
738 					break;
739 			}
740 
741             svtools::ColorConfigEntry eEntry =
742                 INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? svtools::LINKSVISITED : svtools::LINKS;
743 			rTxtColor = new Color( SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor );
744 		}
745 		else
746 		{
747 			//DBG_ERROR("unbekannter Feldbefehl");
748 			aRet = '?';
749 		}
750 	}
751 
752 	if (!aRet.Len()) 		// leer ist baeh
753 		aRet = ' ';			// Space ist Default der Editengine
754 
755 	return aRet;
756 }
757 
758 void __EXPORT ScFieldEditEngine::FieldClicked( const SvxFieldItem& rField, sal_uInt16, sal_uInt16 )
759 {
760 	const SvxFieldData* pFld = rField.GetField();
761 
762 	if ( pFld && pFld->ISA( SvxURLField ) && bExecuteURL )
763 	{
764 		const SvxURLField* pURLField = (const SvxURLField*) pFld;
765 		ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame() );
766 	}
767 }
768 
769 //------------------------------------------------------------------------
770 
771 ScNoteEditEngine::ScNoteEditEngine( SfxItemPool* pEnginePoolP,
772             SfxItemPool* pTextObjectPool, sal_Bool bDeleteEnginePoolP ) :
773     ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP )
774 {
775 	if ( pTextObjectPool )
776 		SetEditTextObjectPool( pTextObjectPool );
777 	SetControlWord( (GetControlWord() | EE_CNTRL_MARKFIELDS) & ~EE_CNTRL_RTFSTYLESHEETS );
778 }
779