View | Details | Raw Unified | Return to issue 107203
Collapse All | Expand All

(-)sc/source/core/data/global.cxx (+19 lines)
Lines 2008-2010 Link Here
2008
    return pLocale;
2008
    return pLocale;
2009
}
2009
}
2010
2010
2011
2012
namespace sc
2013
{
2014
2015
    FillSeriesData::FillSeriesData()
2016
        : eDir(FILL_TO_BOTTOM)
2017
        , eCmd(FILL_LINEAR)
2018
        , eDateCmd(FILL_DAY)
2019
        , fStart(MAXDOUBLE)
2020
        , aStart()
2021
        , fStep(1.0)
2022
        , fMax(MAXDOUBLE)
2023
        , aMax()
2024
        , bUseString(false)
2025
    {
2026
    }
2027
2028
}
2029
(-)sc/source/core/data/table2.cxx (-1 / +1 lines)
Lines 890-896 Link Here
890
}
890
}
891
891
892
892
893
double ScTable::GetValue( SCCOL nCol, SCROW nRow )
893
double ScTable::GetValue( SCCOL nCol, SCROW nRow ) const
894
{
894
{
895
	if (ValidColRow( nCol, nRow ))
895
	if (ValidColRow( nCol, nRow ))
896
		return aCol[nCol].GetValue( nRow );
896
		return aCol[nCol].GetValue( nRow );
(-)sc/source/core/data/table4.cxx (-147 / +142 lines)
Lines 64-70 Link Here
64
#include <svtools/zforlist.hxx>
64
#include <svtools/zforlist.hxx>
65
#include <vcl/keycodes.hxx>
65
#include <vcl/keycodes.hxx>
66
#include <rtl/math.hxx>
66
#include <rtl/math.hxx>
67
#include <unotools/charclass.hxx>
68
67
69
#include "attrib.hxx"
68
#include "attrib.hxx"
70
#include "patattr.hxx"
69
#include "patattr.hxx"
Lines 81-86 Link Here
81
#include "rangenam.hxx"
80
#include "rangenam.hxx"
82
#include "docpool.hxx"
81
#include "docpool.hxx"
83
#include "progress.hxx"
82
#include "progress.hxx"
83
#include "sc/valuestringparser.hxx"
84
84
85
#include <math.h>
85
#include <math.h>
86
86
Lines 92-152 Link Here
92
92
93
// -----------------------------------------------------------------------
93
// -----------------------------------------------------------------------
94
94
95
short lcl_DecompValueString( String& aValue, sal_Int32& nVal, USHORT* pMinDigits = NULL )
96
{
97
	if ( !aValue.Len() )
98
	{
99
		nVal = 0;
100
		return 0;
101
	}
102
	const sal_Unicode* p = aValue.GetBuffer();
103
	xub_StrLen nNeg = 0;
104
	xub_StrLen nNum = 0;
105
	if ( p[nNum] == '-' )
106
		nNum = nNeg = 1;
107
	while ( p[nNum] && CharClass::isAsciiNumeric( p[nNum] ) )
108
		nNum++;
109
110
    sal_Unicode cNext = p[nNum];            // 0 if at the end
111
    sal_Unicode cLast = p[aValue.Len()-1];
112
113
    // #i5550# If there are numbers at the beginning and the end,
114
    // prefer the one at the beginning only if it's followed by a space.
115
    // Otherwise, use the number at the end, to enable things like IP addresses.
116
    if ( nNum > nNeg && ( cNext == 0 || cNext == ' ' || !CharClass::isAsciiNumeric(cLast) ) )
117
	{	// number at the beginning
118
		nVal = aValue.Copy( 0, nNum ).ToInt32();
119
		//	#60893# any number with a leading zero sets the minimum number of digits
120
		if ( p[nNeg] == '0' && pMinDigits && ( nNum - nNeg > *pMinDigits ) )
121
			*pMinDigits = nNum - nNeg;
122
		aValue.Erase( 0, nNum );
123
		return -1;
124
	}
125
	else
126
	{
127
		nNeg = 0;
128
		xub_StrLen nEnd = nNum = aValue.Len() - 1;
129
		while ( nNum && CharClass::isAsciiNumeric( p[nNum] ) )
130
			nNum--;
131
		if ( p[nNum] == '-' )
132
		{
133
			nNum--;
134
			nNeg = 1;
135
		}
136
		if ( nNum < nEnd - nNeg )
137
		{	// number at the end
138
			nVal = aValue.Copy( nNum + 1 ).ToInt32();
139
			//	#60893# any number with a leading zero sets the minimum number of digits
140
			if ( p[nNum+1+nNeg] == '0' && pMinDigits && ( nEnd - nNum - nNeg > *pMinDigits ) )
141
				*pMinDigits = nEnd - nNum - nNeg;
142
			aValue.Erase( nNum + 1 );
143
			return 1;
144
		}
145
	}
146
	nVal = 0;
147
	return 0;
148
}
149
150
String lcl_ValueString( sal_Int32 nValue, USHORT nMinDigits )
95
String lcl_ValueString( sal_Int32 nValue, USHORT nMinDigits )
151
{
96
{
152
	if ( nMinDigits <= 1 )
97
	if ( nMinDigits <= 1 )
Lines 197-202 Link Here
197
{
142
{
198
	DBG_ASSERT( nCol1==nCol2 || nRow1==nRow2, "FillAnalyse: falscher Bereich" );
143
	DBG_ASSERT( nCol1==nCol2 || nRow1==nRow2, "FillAnalyse: falscher Bereich" );
199
144
145
    using sc::ValueStringParser;
200
	rInc = 0.0;
146
	rInc = 0.0;
201
	rMinDigits = 0;
147
	rMinDigits = 0;
202
	rListData = NULL;
148
	rListData = NULL;
Lines 362-380 Link Here
362
		}
308
		}
363
		else if ( nCount > 1 )
309
		else if ( nCount > 1 )
364
		{
310
		{
365
			//	pass rMinDigits to all DecompValueString calls
311
			// rMinDigits is the maximum of all MinDigits values that has
366
			//	-> longest number defines rMinDigits
312
            // been got from analyzed cells
367
313
368
			sal_Int32 nVal1;
314
            const ValueStringParser aValueString1(aStr);
369
			short nFlag1 = lcl_DecompValueString( aStr, nVal1, &rMinDigits );
315
			sal_Int32 nVal1(aValueString1.GetValue());
370
			if ( nFlag1 )
316
            rMinDigits = sal::static_int_cast<USHORT>(aValueString1.GetMinDigits());
317
			if (aValueString1.HasValue())
371
			{
318
			{
372
				sal_Int32 nVal2;
373
				GetString( nCol+nAddX, nRow+nAddY, aStr );
319
				GetString( nCol+nAddX, nRow+nAddY, aStr );
374
				short nFlag2 = lcl_DecompValueString( aStr, nVal2, &rMinDigits );
320
                const ValueStringParser aValueString2(aStr);
375
				if ( nFlag1 == nFlag2 )
321
                sal_Int32 nVal2(aValueString2.GetValue());
322
                rMinDigits = std::max(rMinDigits,
323
                        sal::static_int_cast<USHORT>(aValueString2.GetMinDigits()));
324
				if (CanBeOrdered(aValueString1, aValueString2))
376
				{
325
				{
377
					rInc = (double)nVal2 - (double)nVal1;
326
					rInc = static_cast<double>(nVal2) - static_cast<double>(nVal1);
378
                    nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
327
                    nCol = sal::static_int_cast<SCCOL>( nCol + nAddX );
379
                    nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
328
                    nRow = sal::static_int_cast<SCROW>( nRow + nAddY );
380
					BOOL bVal = TRUE;
329
					BOOL bVal = TRUE;
Lines 388-397 Link Here
388
								((ScStringCell*)pCell)->GetString( aStr );
337
								((ScStringCell*)pCell)->GetString( aStr );
389
							else
338
							else
390
								((ScEditCell*)pCell)->GetString( aStr );
339
								((ScEditCell*)pCell)->GetString( aStr );
391
							nFlag2 = lcl_DecompValueString( aStr, nVal2, &rMinDigits );
340
                            const ValueStringParser aValueString(aStr);
392
							if ( nFlag1 == nFlag2 )
341
                            nVal2 = aValueString.GetValue();
342
                            rMinDigits = std::max(rMinDigits,
343
                                    sal::static_int_cast<USHORT>(aValueString.GetMinDigits()));
344
                            if (CanBeOrdered(aValueString1, aValueString))
393
							{
345
							{
394
								double nDiff = (double)nVal2 - (double)nVal1;
346
								double nDiff = static_cast<double>(nVal2) - static_cast<double>(nVal1);
395
								if ( !::rtl::math::approxEqual( nDiff, rInc ) )
347
								if ( !::rtl::math::approxEqual( nDiff, rInc ) )
396
									bVal = FALSE;
348
									bVal = FALSE;
397
								nVal1 = nVal2;
349
								nVal1 = nVal2;
Lines 411-419 Link Here
411
		}
363
		}
412
		else
364
		else
413
		{
365
		{
414
			//	call DecompValueString to set rMinDigits
366
			// just set rMinDigits
415
			sal_Int32 nDummy;
367
            const ValueStringParser aValueString(aStr);
416
			lcl_DecompValueString( aStr, nDummy, &rMinDigits );
368
            rMinDigits = aValueString.GetMinDigits();
417
		}
369
		}
418
	}
370
	}
419
}
371
}
Lines 747-753 Link Here
747
			BOOL bFirst = TRUE;
699
			BOOL bFirst = TRUE;
748
			BOOL bGetCell = TRUE;
700
			BOOL bGetCell = TRUE;
749
			USHORT nCellDigits = 0;
701
			USHORT nCellDigits = 0;
750
			short nHeadNoneTail = 0;
702
			bool bIsValue(false);
703
            bool bIsPrefix(false);
751
			sal_Int32 nStringValue = 0;
704
			sal_Int32 nStringValue = 0;
752
			String aValue;
705
			String aValue;
753
            ScBaseCell* pSrcCell = NULL;
706
            ScBaseCell* pSrcCell = NULL;
Lines 780-789 Link Here
780
									((ScEditCell*)pSrcCell)->GetString( aValue );
733
									((ScEditCell*)pSrcCell)->GetString( aValue );
781
								if ( !(nScFillModeMouseModifier & KEY_MOD1) )
734
								if ( !(nScFillModeMouseModifier & KEY_MOD1) )
782
								{
735
								{
783
									nCellDigits = 0;	// look at each source cell individually
736
                                    // look at each source cell individually
784
									nHeadNoneTail = lcl_DecompValueString(
737
                                    const sc::ValueStringParser aValueString(aValue);
785
										aValue, nStringValue, &nCellDigits );
738
                                    bIsValue = aValueString.HasValue();
786
739
                                    nCellDigits = aValueString.GetMinDigits();
740
                                    aValue = aValueString.GetBaseSubstring();
741
                                    nStringValue = aValueString.GetValue();
742
                                    bIsPrefix = aValueString.IsPrefix();
787
                                    bIsOrdinalSuffix = aValue.Equals(
743
                                    bIsOrdinalSuffix = aValue.Equals(
788
                                            ScGlobal::GetOrdinalSuffix( nStringValue));
744
                                            ScGlobal::GetOrdinalSuffix( nStringValue));
789
								}
745
								}
Lines 804-810 Link Here
804
						break;
760
						break;
805
					case CELLTYPE_STRING:
761
					case CELLTYPE_STRING:
806
					case CELLTYPE_EDIT:
762
					case CELLTYPE_EDIT:
807
						if ( nHeadNoneTail )
763
						if (bIsValue)
808
						{
764
						{
809
                            // #i48009# with the "nStringValue+(long)nDelta" expression within the
765
                            // #i48009# with the "nStringValue+(long)nDelta" expression within the
810
                            // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
766
                            // lcl_ValueString calls, gcc 3.4.1 makes wrong optimizations (ok in 3.4.3),
Lines 812-818 Link Here
812
                            sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
768
                            sal_Int32 nNextValue = nStringValue+(sal_Int32)nDelta;
813
769
814
							String aStr;
770
							String aStr;
815
							if ( nHeadNoneTail < 0 )
771
							if (bIsPrefix)
816
							{
772
							{
817
                                aCol[nCol].Insert( static_cast<SCROW>(nRow),
773
                                aCol[nCol].Insert( static_cast<SCROW>(nRow),
818
                                        lcl_getSuffixCell( pDocument,
774
                                        lcl_getSuffixCell( pDocument,
Lines 902-917 Link Here
902
			if (!bPositive)
858
			if (!bPositive)
903
				nInc = -nInc;
859
				nInc = -nInc;
904
			double nEndVal = (nInc>=0.0) ? MAXDOUBLE : -MAXDOUBLE;
860
			double nEndVal = (nInc>=0.0) ? MAXDOUBLE : -MAXDOUBLE;
861
            sc::FillSeriesData aFillData;
862
            aFillData.eDir = eFillDir;
863
            aFillData.eCmd = eFillCmd;
864
            aFillData.eDateCmd = eDateCmd;
865
            aFillData.fStep = nInc;
866
            aFillData.fMax = nEndVal;
905
			if (bVertical)
867
			if (bVertical)
906
                FillSeries( static_cast<SCCOL>(nCol), nRow1,
868
                FillSeries( static_cast<SCCOL>(nCol), nRow1,
907
                        static_cast<SCCOL>(nCol), nRow2, nFillCount, eFillDir,
869
                        static_cast<SCCOL>(nCol), nRow2, nFillCount, aFillData,
908
                        eFillCmd, eDateCmd, nInc, nEndVal, nMinDigits, FALSE,
870
                        nMinDigits, FALSE, rProgress );
909
                        rProgress );
910
			else
871
			else
911
                FillSeries( nCol1, static_cast<SCROW>(nRow), nCol2,
872
                FillSeries( nCol1, static_cast<SCROW>(nRow), nCol2,
912
                        static_cast<SCROW>(nRow), nFillCount, eFillDir,
873
                        static_cast<SCROW>(nRow), nFillCount, aFillData,
913
                        eFillCmd, eDateCmd, nInc, nEndVal, nMinDigits, FALSE,
874
                        nMinDigits, FALSE, rProgress );
914
                        rProgress );
915
			nProgress = rProgress.GetState();
875
			nProgress = rProgress.GetState();
916
		}
876
		}
917
877
Lines 1013-1031 Link Here
1013
							((ScEditCell*)pCell)->GetString( aValue );
973
							((ScEditCell*)pCell)->GetString( aValue );
1014
						if ( !(nScFillModeMouseModifier & KEY_MOD1) )
974
						if ( !(nScFillModeMouseModifier & KEY_MOD1) )
1015
						{
975
						{
1016
							sal_Int32 nVal;
976
                            // look at each source cell individually
1017
							USHORT nCellDigits = 0;	// look at each source cell individually
977
                            const sc::ValueStringParser aValueString(aValue);
1018
							short nFlag = lcl_DecompValueString( aValue, nVal, &nCellDigits );
978
							sal_Int32 nVal(aValueString.GetValue());
1019
							if ( nFlag < 0 )
979
							USHORT nCellDigits(sal::static_int_cast<USHORT>(
980
                                        aValueString.GetMinDigits()));
981
                            aValue = aValueString.GetBaseSubstring();
982
                            if (aValueString.HasValue())
1020
                            {
983
                            {
1021
                                if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
984
                                if (aValueString.IsPrefix())
1022
                                    aValue = ScGlobal::GetOrdinalSuffix( nVal + nDelta);
985
                                {
986
                                    if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
987
                                        aValue = ScGlobal::GetOrdinalSuffix( nVal + nDelta);
1023
988
1024
								aValue.Insert( lcl_ValueString( nVal + nDelta, nCellDigits ), 0 );
989
                                    aValue.Insert( lcl_ValueString( nVal + nDelta, nCellDigits ), 0 );
990
                                }
991
                                else
992
                                {
993
                                    aValue += lcl_ValueString( nVal + nDelta, nCellDigits );
994
                                }
1025
                            }
995
                            }
1026
							else if ( nFlag > 0 )
996
                        }
1027
								aValue += lcl_ValueString( nVal + nDelta, nCellDigits );
1028
						}
1029
					}
997
					}
1030
					break;
998
					break;
1031
					case CELLTYPE_VALUE:
999
					case CELLTYPE_VALUE:
Lines 1054-1060 Link Here
1054
            BOOL bValueOk;
1022
            BOOL bValueOk;
1055
			double nStart;
1023
			double nStart;
1056
            sal_Int32 nVal = 0;
1024
            sal_Int32 nVal = 0;
1057
			short nHeadNoneTail = 0;
1025
			bool bHasValue(false);
1026
            bool bIsPrefix(false);
1058
			ScBaseCell*	pCell = GetCell( nCol1, nRow1 );
1027
			ScBaseCell*	pCell = GetCell( nCol1, nRow1 );
1059
			if ( pCell )
1028
			if ( pCell )
1060
			{
1029
			{
Lines 1068-1075 Link Here
1068
							((ScStringCell*)pCell)->GetString( aValue );
1037
							((ScStringCell*)pCell)->GetString( aValue );
1069
						else
1038
						else
1070
							((ScEditCell*)pCell)->GetString( aValue );
1039
							((ScEditCell*)pCell)->GetString( aValue );
1071
						nHeadNoneTail = lcl_DecompValueString( aValue, nVal );
1040
                        {
1072
						if ( nHeadNoneTail )
1041
                            const sc::ValueStringParser aValueString(aValue);
1042
                            aValue = aValueString.GetBaseSubstring();
1043
                            bHasValue = aValueString.HasValue();
1044
                            bIsPrefix = aValueString.IsPrefix();
1045
                            nVal = aValueString.GetValue();
1046
                        }
1047
						if (bHasValue)
1073
							nStart = (double)nVal;
1048
							nStart = (double)nVal;
1074
						else
1049
						else
1075
							nStart = 0.0;
1050
							nStart = 0.0;
Lines 1108-1116 Link Here
1108
1083
1109
            if (bValueOk)
1084
            if (bValueOk)
1110
			{
1085
			{
1111
				if ( nHeadNoneTail )
1086
				if (bHasValue)
1112
				{
1087
				{
1113
					if ( nHeadNoneTail < 0 )
1088
					if (bIsPrefix)
1114
                    {
1089
                    {
1115
                        if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
1090
                        if (aValue.Equals( ScGlobal::GetOrdinalSuffix( nVal)))
1116
                            aValue = ScGlobal::GetOrdinalSuffix( (sal_Int32)nStart );
1091
                            aValue = ScGlobal::GetOrdinalSuffix( (sal_Int32)nStart );
Lines 1239-1255 Link Here
1239
	rVal = aDate - aNullDate;
1214
	rVal = aDate - aNullDate;
1240
}
1215
}
1241
1216
1242
void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1217
1243
					ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
1218
void
1244
					double nStepValue, double nMaxValue, USHORT nArgMinDigits,
1219
ScTable::FillSeries(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1245
					BOOL bAttribs, ScProgress& rProgress )
1220
        ULONG nFillCount, const sc::FillSeriesData& rFillData,
1221
        USHORT nArgMinDigits, bool bAttribs, ScProgress& rProgress)
1246
{
1222
{
1247
	//
1223
	//
1248
	//	Richtung auswerten
1224
	//	Richtung auswerten
1249
	//
1225
	//
1250
1226
1251
	BOOL bVertical = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP);
1227
	BOOL bVertical = (rFillData.eDir == FILL_TO_BOTTOM || rFillData.eDir == FILL_TO_TOP);
1252
	BOOL bPositive = (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_RIGHT);
1228
	BOOL bPositive = (rFillData.eDir == FILL_TO_BOTTOM || rFillData.eDir == FILL_TO_RIGHT);
1253
1229
1254
    ULONG nCol = 0;
1230
    ULONG nCol = 0;
1255
    ULONG nRow = 0;
1231
    ULONG nRow = 0;
Lines 1340-1348 Link Here
1340
1316
1341
		if (pSrcCell)
1317
		if (pSrcCell)
1342
		{
1318
		{
1319
            double fMaxValue(rFillData.fMax);
1343
			CellType eCellType = pSrcCell->GetCellType();
1320
			CellType eCellType = pSrcCell->GetCellType();
1344
1321
1345
			if (eFillCmd == FILL_SIMPLE)				// kopieren
1322
			if (rFillData.eCmd == FILL_SIMPLE)				// kopieren
1346
			{
1323
			{
1347
				if (eCellType == CELLTYPE_FORMULA)
1324
				if (eCellType == CELLTYPE_FORMULA)
1348
				{
1325
				{
Lines 1385-1432 Link Here
1385
				{
1362
				{
1386
					if (!bError && !bOverflow)
1363
					if (!bError && !bOverflow)
1387
					{
1364
					{
1388
						switch (eFillCmd)
1365
						switch (rFillData.eCmd)
1389
						{
1366
						{
1390
							case FILL_LINEAR:
1367
							case FILL_LINEAR:
1391
								{
1368
								{
1392
									//	#86365# use multiplication instead of repeated addition
1369
									//	#86365# use multiplication instead of repeated addition
1393
									//	to avoid accumulating rounding errors
1370
									//	to avoid accumulating rounding errors
1394
									nVal = nStartVal;
1371
									nVal = nStartVal;
1395
									double nAdd = nStepValue;
1372
									double nAdd = rFillData.fStep;
1396
									if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
1373
									if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
1397
										 !SubTotal::SafePlus( nVal, nAdd ) )
1374
										 !SubTotal::SafePlus( nVal, nAdd ) )
1398
										bError = TRUE;
1375
										bError = TRUE;
1399
								}
1376
								}
1400
								break;
1377
								break;
1401
							case FILL_GROWTH:
1378
							case FILL_GROWTH:
1402
								if (!SubTotal::SafeMult(nVal, nStepValue))
1379
								if (!SubTotal::SafeMult(nVal, rFillData.fStep))
1403
									bError = TRUE;
1380
									bError = TRUE;
1404
								break;
1381
								break;
1405
							case FILL_DATE:
1382
							case FILL_DATE:
1406
								if (fabs(nVal) > _D_MAX_LONG_)
1383
								if (fabs(nVal) > _D_MAX_LONG_)
1407
									bError = TRUE;
1384
									bError = TRUE;
1408
								else
1385
								else
1409
									IncDate(nVal, nDayOfMonth, nStepValue, eFillDateCmd);
1386
									IncDate(nVal, nDayOfMonth, rFillData.fStep, rFillData.eDateCmd); break;
1410
								break;
1411
                            default:
1387
                            default:
1412
                            {
1388
                            {
1413
                                // added to avoid warnings
1389
                                // added to avoid warnings
1414
                            }
1390
                            }
1415
						}
1391
						}
1416
1392
1417
						if (nStepValue >= 0)
1393
						if (rFillData.fStep >= 0)
1418
						{
1394
						{
1419
							if (nVal > nMaxValue)			// Zielwert erreicht?
1395
							if (nVal > fMaxValue)			// Zielwert erreicht?
1420
							{
1396
							{
1421
								nVal = nMaxValue;
1397
								nVal = fMaxValue;
1422
								bOverflow = TRUE;
1398
								bOverflow = TRUE;
1423
							}
1399
							}
1424
						}
1400
						}
1425
						else
1401
						else
1426
						{
1402
						{
1427
							if (nVal < nMaxValue)
1403
							if (nVal < fMaxValue)
1428
							{
1404
							{
1429
								nVal = nMaxValue;
1405
								nVal = fMaxValue;
1430
								bOverflow = TRUE;
1406
								bOverflow = TRUE;
1431
							}
1407
							}
1432
						}
1408
						}
Lines 1445-1471 Link Here
1445
			}
1421
			}
1446
			else if (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT)
1422
			else if (eCellType == CELLTYPE_STRING || eCellType == CELLTYPE_EDIT)
1447
			{
1423
			{
1448
				if ( nStepValue >= 0 )
1424
				if (rFillData.fStep >= 0)
1449
				{
1425
				{
1450
					if ( nMaxValue >= (double)LONG_MAX )
1426
					if (fMaxValue >= static_cast<double>(LONG_MAX))
1451
						nMaxValue = (double)LONG_MAX - 1;
1427
						fMaxValue = static_cast<double>(LONG_MAX) - 1;
1452
				}
1428
				}
1453
				else
1429
				else
1454
				{
1430
				{
1455
					if ( nMaxValue <= (double)LONG_MIN )
1431
					if (fMaxValue <= static_cast<double>(LONG_MIN))
1456
						nMaxValue = (double)LONG_MIN + 1;
1432
						fMaxValue = static_cast<double>(LONG_MIN) + 1;
1457
				}
1433
				}
1458
				String aValue;
1434
				String aValue;
1459
				if (eCellType == CELLTYPE_STRING)
1435
				if (eCellType == CELLTYPE_STRING)
1460
					((ScStringCell*)pSrcCell)->GetString( aValue );
1436
					((ScStringCell*)pSrcCell)->GetString( aValue );
1461
				else
1437
				else
1462
					((ScEditCell*)pSrcCell)->GetString( aValue );
1438
					((ScEditCell*)pSrcCell)->GetString( aValue );
1463
				sal_Int32 nStringValue;
1439
                const sc::ValueStringParser aValueString(aValue);
1464
				USHORT nMinDigits = nArgMinDigits;
1440
				sal_Int32 nStringValue(aValueString.GetValue());
1465
				short nHeadNoneTail = lcl_DecompValueString( aValue, nStringValue, &nMinDigits );
1441
                USHORT nMinDigits(0);
1466
				if ( nHeadNoneTail )
1442
                if (nArgMinDigits == 0 && rFillData.bUseString)
1443
                {
1444
                    const sc::ValueStringParser aStart(rFillData.aStart);
1445
                    const sc::ValueStringParser aMax(rFillData.aMax);
1446
                    nMinDigits = std::max(aStart.GetMinDigits(), aMax.GetMinDigits());
1447
                }
1448
                else
1449
                {
1450
                    nMinDigits = std::max(
1451
                            nArgMinDigits,
1452
                            sal::static_int_cast<USHORT>(aValueString.GetMinDigits()));
1453
                }
1454
                aValue = aValueString.GetBaseSubstring();
1455
				if (aValueString.HasValue())
1467
				{
1456
				{
1468
					double nStartVal = (double)nStringValue;
1457
					double nStartVal = static_cast<double>(nStringValue);
1469
					double nVal = nStartVal;
1458
					double nVal = nStartVal;
1470
					long nIndex = 0;
1459
					long nIndex = 0;
1471
					BOOL bError = FALSE;
1460
					BOOL bError = FALSE;
Lines 1479-1499 Link Here
1479
					{
1468
					{
1480
						if (!bError && !bOverflow)
1469
						if (!bError && !bOverflow)
1481
						{
1470
						{
1482
							switch (eFillCmd)
1471
							switch (rFillData.eCmd)
1483
							{
1472
							{
1484
								case FILL_LINEAR:
1473
								case FILL_LINEAR:
1485
									{
1474
									{
1486
										//	#86365# use multiplication instead of repeated addition
1475
										//	#86365# use multiplication instead of repeated addition
1487
										//	to avoid accumulating rounding errors
1476
										//	to avoid accumulating rounding errors
1488
										nVal = nStartVal;
1477
										nVal = nStartVal;
1489
										double nAdd = nStepValue;
1478
										double nAdd = rFillData.fStep;
1490
										if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
1479
										if ( !SubTotal::SafeMult( nAdd, (double) ++nIndex ) ||
1491
											 !SubTotal::SafePlus( nVal, nAdd ) )
1480
											 !SubTotal::SafePlus( nVal, nAdd ) )
1492
											bError = TRUE;
1481
											bError = TRUE;
1493
									}
1482
									}
1494
									break;
1483
									break;
1495
								case FILL_GROWTH:
1484
								case FILL_GROWTH:
1496
									if (!SubTotal::SafeMult(nVal, nStepValue))
1485
									if (!SubTotal::SafeMult(nVal, rFillData.fStep))
1497
										bError = TRUE;
1486
										bError = TRUE;
1498
									break;
1487
									break;
1499
                                default:
1488
                                default:
Lines 1502-1520 Link Here
1502
                                }
1491
                                }
1503
							}
1492
							}
1504
1493
1505
							if (nStepValue >= 0)
1494
							if (rFillData.fStep >= 0)
1506
							{
1495
							{
1507
								if (nVal > nMaxValue)			// Zielwert erreicht?
1496
								if (nVal > fMaxValue)			// Zielwert erreicht?
1508
								{
1497
								{
1509
									nVal = nMaxValue;
1498
									nVal = fMaxValue;
1510
									bOverflow = TRUE;
1499
									bOverflow = TRUE;
1511
								}
1500
								}
1512
							}
1501
							}
1513
							else
1502
							else
1514
							{
1503
							{
1515
								if (nVal < nMaxValue)
1504
								if (nVal < fMaxValue)
1516
								{
1505
								{
1517
									nVal = nMaxValue;
1506
									nVal = fMaxValue;
1518
									bOverflow = TRUE;
1507
									bOverflow = TRUE;
1519
								}
1508
								}
1520
							}
1509
							}
Lines 1524-1532 Link Here
1524
							aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue);
1513
							aCol[nCol].SetError(static_cast<SCROW>(nRow), errNoValue);
1525
						else if (!bOverflow)
1514
						else if (!bOverflow)
1526
						{
1515
						{
1527
							nStringValue = (sal_Int32)nVal;
1516
							nStringValue = static_cast<sal_Int32>(nVal);
1528
							String aStr;
1517
							String aStr;
1529
							if ( nHeadNoneTail < 0 )
1518
							if (aValueString.IsPrefix())
1530
							{
1519
							{
1531
                                aCol[nCol].Insert( static_cast<SCROW>(nRow),
1520
                                aCol[nCol].Insert( static_cast<SCROW>(nRow),
1532
                                        lcl_getSuffixCell( pDocument,
1521
                                        lcl_getSuffixCell( pDocument,
Lines 1563-1570 Link Here
1563
					ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
1552
					ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
1564
					double nStepValue, double nMaxValue)
1553
					double nStepValue, double nMaxValue)
1565
{
1554
{
1555
    sc::FillSeriesData aFillData;
1556
    aFillData.eDir = eFillDir;
1557
    aFillData.eCmd = eFillCmd;
1558
    aFillData.eDateCmd = eFillDateCmd;
1559
    aFillData.fStep = nStepValue;
1560
    aFillData.fMax = nMaxValue;
1561
    Fill(nCol1, nRow1, nCol2, nRow2, nFillCount, aFillData);
1562
}
1563
1564
1565
void ScTable::Fill( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1566
					ULONG nFillCount, const sc::FillSeriesData& rFillData)
1567
{
1566
	ULONG nProgCount;
1568
	ULONG nProgCount;
1567
	if (eFillDir == FILL_TO_BOTTOM || eFillDir == FILL_TO_TOP)
1569
	if (rFillData.eDir == FILL_TO_BOTTOM || rFillData.eDir == FILL_TO_TOP)
1568
		nProgCount = nCol2 - nCol1 + 1;
1570
		nProgCount = nCol2 - nCol1 + 1;
1569
	else
1571
	else
1570
		nProgCount = nRow2 - nRow1 + 1;
1572
		nProgCount = nRow2 - nRow1 + 1;
Lines 1574-1584 Link Here
1574
1576
1575
	bSharedNameInserted = FALSE;
1577
	bSharedNameInserted = FALSE;
1576
1578
1577
	if (eFillCmd == FILL_AUTO)
1579
	if (rFillData.eCmd == FILL_AUTO)
1578
		FillAuto(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir, aProgress);
1580
		FillAuto(nCol1, nRow1, nCol2, nRow2, nFillCount, rFillData.eDir, aProgress);
1579
	else
1581
	else
1580
		FillSeries(nCol1, nRow1, nCol2, nRow2, nFillCount, eFillDir,
1582
		FillSeries(nCol1, nRow1, nCol2, nRow2, nFillCount, rFillData, 0, true, aProgress);
1581
					eFillCmd, eFillDateCmd, nStepValue, nMaxValue, 0, TRUE, aProgress);
1582
1583
1583
	if (bSharedNameInserted)						// Wurde Shared-Name eingefuegt?
1584
	if (bSharedNameInserted)						// Wurde Shared-Name eingefuegt?
1584
		pDocument->GetRangeName()->SetSharedMaxIndex(
1585
		pDocument->GetRangeName()->SetSharedMaxIndex(
Lines 1985-1993 Link Here
1985
{
1986
{
1986
	for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileColRowNameFormula();
1987
	for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileColRowNameFormula();
1987
}
1988
}
1988
1989
1990
1991
1992
1993
(-)sc/source/core/data/documen3.cxx (-5 / +18 lines)
Lines 905-921 Link Here
905
}
905
}
906
906
907
void ScDocument::Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
907
void ScDocument::Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData& rMark,
908
						ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
908
                        ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
909
						double nStepValue, double nMaxValue)
909
                        double nStepValue, double nMaxValue)
910
{
910
{
911
    sc::FillSeriesData aFillData;
912
    aFillData.eDir = eFillDir;
913
    aFillData.eCmd = eFillCmd;
914
    aFillData.eDateCmd = eFillDateCmd;
915
    aFillData.fStep = nStepValue;
916
    aFillData.fMax = nMaxValue;
917
    Fill(nCol1, nRow1, nCol2, nRow2, rMark, nFillCount, aFillData);
918
}
919
920
921
void
922
ScDocument::Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
923
        const ScMarkData& rMark, ULONG nFillCount,
924
        const sc::FillSeriesData& rFillData)
925
{
911
	PutInOrder( nCol1, nCol2 );
926
	PutInOrder( nCol1, nCol2 );
912
	PutInOrder( nRow1, nRow2 );
927
	PutInOrder( nRow1, nRow2 );
913
	for (SCTAB i=0; i <= MAXTAB; i++)
928
	for (SCTAB i=0; i <= MAXTAB; i++)
914
		if (pTab[i])
929
		if (pTab[i])
915
			if (rMark.GetTableSelect(i))
930
			if (rMark.GetTableSelect(i))
916
				pTab[i]->Fill(nCol1, nRow1, nCol2, nRow2,
931
				pTab[i]->Fill(nCol1, nRow1, nCol2, nRow2, nFillCount, rFillData);
917
								nFillCount, eFillDir, eFillCmd, eFillDateCmd,
918
								nStepValue, nMaxValue);
919
}
932
}
920
933
921
String ScDocument::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY )
934
String ScDocument::GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY )
(-)sc/source/core/data/makefile.mk (+1 lines)
Lines 112-117 Link Here
112
	$(SLO)$/tabprotection.obj \
112
	$(SLO)$/tabprotection.obj \
113
	$(SLO)$/userdat.obj \
113
	$(SLO)$/userdat.obj \
114
	$(SLO)$/validat.obj \
114
	$(SLO)$/validat.obj \
115
	$(SLO)$/valuestringparser.obj \
115
	$(SLO)$/postit.obj
116
	$(SLO)$/postit.obj
116
117
117
EXCEPTIONSFILES= \
118
EXCEPTIONSFILES= \
(-)sc/source/core/data/valuestringparser.cxx (+217 lines)
Line 0 Link Here
1
/*************************************************************************
2
 *
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * Copyright 2008 by Sun Microsystems, Inc.
6
 *
7
 * OpenOffice.org - a multi-platform office productivity suite
8
 *
9
 * $RCSfile: $
10
 * $Revision: $
11
 *
12
 * This file is part of OpenOffice.org.
13
 *
14
 * OpenOffice.org is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Lesser General Public License version 3
16
 * only, as published by the Free Software Foundation.
17
 *
18
 * OpenOffice.org is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU Lesser General Public License version 3 for more details
22
 * (a copy is included in the LICENSE file that accompanied this code).
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * version 3 along with OpenOffice.org.  If not, see
26
 * <http://www.openoffice.org/license.html>
27
 * for a copy of the LGPLv3 License.
28
 *
29
 ************************************************************************/
30
31
#include "precompiled_sc.hxx"
32
33
#include <unotools/charclass.hxx>
34
35
#include "global.hxx"
36
#include "sc/valuestringparser.hxx"
37
38
39
namespace sc
40
{
41
42
    namespace
43
    {
44
        
45
        short lcl_DecompValueString( String& aValue, sal_Int32& nVal, USHORT* pMinDigits = NULL )
46
        {
47
            if ( !aValue.Len() )
48
            {
49
                nVal = 0;
50
                return 0;
51
            }
52
            const sal_Unicode* p = aValue.GetBuffer();
53
            xub_StrLen nNeg = 0;
54
            xub_StrLen nNum = 0;
55
            if ( p[nNum] == '-' )
56
                nNum = nNeg = 1;
57
            while ( p[nNum] && CharClass::isAsciiNumeric( p[nNum] ) )
58
                nNum++;
59
60
            sal_Unicode cNext = p[nNum];            // 0 if at the end
61
            sal_Unicode cLast = p[aValue.Len()-1];
62
63
            // #i5550# If there are numbers at the beginning and the end,
64
            // prefer the one at the beginning only if it's followed by a space.
65
            // Otherwise, use the number at the end, to enable things like IP addresses.
66
            if ( nNum > nNeg && ( cNext == 0 || cNext == ' ' || !CharClass::isAsciiNumeric(cLast) ) )
67
            {	// number at the beginning
68
                nVal = aValue.Copy( 0, nNum ).ToInt32();
69
                //	#60893# any number with a leading zero sets the minimum number of digits
70
                if ( p[nNeg] == '0' && pMinDigits && ( nNum - nNeg > *pMinDigits ) )
71
                    *pMinDigits = nNum - nNeg;
72
                aValue.Erase( 0, nNum );
73
                return -1;
74
            }
75
            else
76
            {
77
                nNeg = 0;
78
                xub_StrLen nEnd = nNum = aValue.Len() - 1;
79
                while ( nNum && CharClass::isAsciiNumeric( p[nNum] ) )
80
                    nNum--;
81
                if ( p[nNum] == '-' )
82
                {
83
                    nNum--;
84
                    nNeg = 1;
85
                }
86
                if ( nNum < nEnd - nNeg )
87
                {	// number at the end
88
                    nVal = aValue.Copy( nNum + 1 ).ToInt32();
89
                    //	#60893# any number with a leading zero sets the minimum number of digits
90
                    if ( p[nNum+1+nNeg] == '0' && pMinDigits && ( nEnd - nNum - nNeg > *pMinDigits ) )
91
                        *pMinDigits = nEnd - nNum - nNeg;
92
                    aValue.Erase( nNum + 1 );
93
                    return 1;
94
                }
95
            }
96
            nVal = 0;
97
            return 0;
98
        }
99
100
    }
101
102
103
    ValueStringParser::ValueStringParser(const String& rString)
104
        : m_aString(rString)
105
        , m_aNumericSubstring()
106
        , m_aBaseSubstring()
107
        , m_nValue(0)
108
        , m_nMinDigits(0)
109
        , m_bHasValue(false)
110
        , m_bIsPrefix(false)
111
    {
112
        impl_DecompValueString();
113
    }
114
115
116
    bool
117
    ValueStringParser::HasValue() const
118
    {
119
        return m_bHasValue;
120
    }
121
122
123
    sal_Int32
124
    ValueStringParser::GetValue() const
125
    {
126
        return m_nValue;
127
    }
128
129
130
    sal_Int16
131
    ValueStringParser::GetMinDigits() const
132
    {
133
        return m_nMinDigits;
134
    }
135
136
137
    const String&
138
    ValueStringParser::GetNumericSubstring() const
139
    {
140
        if (m_bHasValue && m_aNumericSubstring.Len() == 0)
141
        {
142
            if (m_bIsPrefix)
143
            {
144
                m_aNumericSubstring = m_aString.Copy(0,
145
                        m_aString.Len() - m_aBaseSubstring.Len());
146
            }
147
            else
148
            {
149
                m_aNumericSubstring = m_aString.Copy(m_aBaseSubstring.Len());
150
            }
151
        }
152
153
        return m_aNumericSubstring;
154
    }
155
156
157
    const String&
158
    ValueStringParser::GetBaseSubstring() const
159
    {
160
        return m_aBaseSubstring;
161
    }
162
163
164
    bool
165
    ValueStringParser::IsPrefix() const
166
    {
167
        return m_bIsPrefix;
168
    }
169
170
171
    void
172
    ValueStringParser::impl_DecompValueString()
173
    {
174
        String aString(m_aString);
175
        sal_Int32 nValue(0);
176
        USHORT nMinDigits(0);
177
        const short nResult(lcl_DecompValueString(aString, nValue, &nMinDigits));
178
        m_aBaseSubstring = aString;
179
        if (nResult != 0)
180
        {
181
            m_bHasValue = true;
182
            m_nValue = nValue;
183
            m_nMinDigits = nMinDigits;
184
            m_bIsPrefix = nResult < 0;
185
        }
186
    }
187
188
189
    bool
190
    CanBeOrdered(
191
            const ValueStringParser& rValueString1,
192
            const ValueStringParser& rValueString2)
193
    {
194
        if (rValueString1.HasValue() && rValueString2.HasValue()
195
                && rValueString1.IsPrefix() == rValueString2.IsPrefix())
196
        {
197
            if (rValueString1.IsPrefix())
198
            {
199
                // check if both base substrings are ordinal suffixes
200
                const String aSuffix1(ScGlobal::GetOrdinalSuffix(rValueString1.GetValue()));
201
                const String aSuffix2(ScGlobal::GetOrdinalSuffix(rValueString2.GetValue()));
202
                if (rValueString1.GetBaseSubstring() == aSuffix1
203
                        && rValueString2.GetBaseSubstring() == aSuffix2)
204
                {
205
                    return true;
206
                }
207
                // if they are not, just continue and check, if they are
208
                // the same
209
            }
210
            return rValueString1.GetBaseSubstring() == rValueString2.GetBaseSubstring();
211
        }
212
        return false;
213
    }
214
215
}
216
217
// vim: set sts=4 sw=4 et:
(-)sc/source/ui/unoobj/cellsuno.cxx (-2 / +8 lines)
Lines 5424-5431 Link Here
5424
		if (!bError)
5424
		if (!bError)
5425
		{
5425
		{
5426
			ScDocFunc aFunc(*pDocSh);
5426
			ScDocFunc aFunc(*pDocSh);
5427
			aFunc.FillSeries( aRange, NULL, eDir, eCmd, eDateCmd,
5427
            sc::FillSeriesData aFillData;
5428
								MAXDOUBLE, fStep, fEndValue, TRUE, TRUE );
5428
            aFillData.eDir = eDir;
5429
            aFillData.eCmd = eCmd;
5430
            aFillData.eDateCmd = eDateCmd;
5431
            aFillData.fStart = MAXDOUBLE;
5432
            aFillData.fStep = fStep;
5433
            aFillData.fMax = fEndValue;
5434
			aFunc.FillSeries( aRange, NULL, aFillData, TRUE, TRUE );
5429
		}
5435
		}
5430
	}
5436
	}
5431
}
5437
}
(-)sc/source/ui/docshell/docfunc.cxx (-26 / +55 lines)
Lines 3775-3790 Link Here
3775
            pDoc->CopyToDocument( aCopyRange, IDF_AUTOFILL, FALSE, pUndoDoc, &aMark );
3775
            pDoc->CopyToDocument( aCopyRange, IDF_AUTOFILL, FALSE, pUndoDoc, &aMark );
3776
		}
3776
		}
3777
3777
3778
        sc::FillSeriesData aFillData;
3779
        aFillData.eDir = eDir;
3780
        aFillData.eCmd = FILL_SIMPLE;
3781
        aFillData.eDateCmd = FILL_DAY;
3782
        aFillData.fStart = MAXDOUBLE;
3783
        aFillData.fStep = 1.0;
3784
        aFillData.fMax = 1e307;
3785
3778
		pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
3786
		pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
3779
					aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
3787
					aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
3780
					nCount, eDir, FILL_SIMPLE );
3788
					nCount, aFillData );
3781
		AdjustRowHeight(rRange);
3789
		AdjustRowHeight(rRange);
3782
3790
3783
		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
3791
		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
3784
		{
3792
		{
3785
			rDocShell.GetUndoManager()->AddUndoAction(
3793
			rDocShell.GetUndoManager()->AddUndoAction(
3786
				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
3794
				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
3787
									eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307,
3795
									aFillData,
3788
									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
3796
									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
3789
		}
3797
		}
3790
3798
Lines 3800-3809 Link Here
3800
	return bSuccess;
3808
	return bSuccess;
3801
}
3809
}
3802
3810
3803
BOOL ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
3811
3804
							FillDir	eDir, FillCmd eCmd, FillDateCmd	eDateCmd,
3812
bool
3805
							double fStart, double fStep, double fMax,
3813
ScDocFunc::FillSeries(
3806
							BOOL bRecord, BOOL bApi )
3814
        const ScRange& rRange, const ScMarkData* pTabMark,
3815
        const sc::FillSeriesData& rFillData, bool bRecord, bool bApi)
3807
{
3816
{
3808
	ScDocShellModificator aModificator( rDocShell );
3817
	ScDocShellModificator aModificator( rDocShell );
3809
3818
Lines 3839-3854 Link Here
3839
		SCSIZE nCount = pDoc->GetEmptyLinesInBlock(
3848
		SCSIZE nCount = pDoc->GetEmptyLinesInBlock(
3840
				aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
3849
				aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
3841
				aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
3850
				aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
3842
				DirFromFillDir(eDir) );
3851
				DirFromFillDir(rFillData.eDir) );
3843
3852
3844
		//	#27665# mindestens eine Zeile/Spalte als Quellbereich behalten:
3853
		//	#27665# mindestens eine Zeile/Spalte als Quellbereich behalten:
3845
		SCSIZE nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ?
3854
		SCSIZE nTotLines = ( rFillData.eDir == FILL_TO_BOTTOM || rFillData.eDir == FILL_TO_TOP ) ?
3846
            static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
3855
            static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
3847
            static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
3856
            static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
3848
		if ( nCount >= nTotLines )
3857
		if ( nCount >= nTotLines )
3849
			nCount = nTotLines - 1;
3858
			nCount = nTotLines - 1;
3850
3859
3851
		switch (eDir)
3860
		switch (rFillData.eDir)
3852
		{
3861
		{
3853
			case FILL_TO_BOTTOM:
3862
			case FILL_TO_BOTTOM:
3854
                aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
3863
                aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
Lines 3885-3900 Link Here
3885
		if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
3894
		if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
3886
			aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
3895
			aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
3887
		{
3896
		{
3888
			if ( fStart != MAXDOUBLE )
3897
			if (rFillData.fStart != MAXDOUBLE)
3889
			{
3898
			{
3890
				SCCOL nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
3899
				SCCOL nValX = (rFillData.eDir == FILL_TO_LEFT)
3891
				SCROW nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
3900
                    ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
3901
				SCROW nValY = (rFillData.eDir == FILL_TO_TOP )
3902
                    ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
3892
				SCTAB nTab = aDestArea.aStart.Tab();
3903
				SCTAB nTab = aDestArea.aStart.Tab();
3893
				pDoc->SetValue( nValX, nValY, nTab, fStart );
3904
                if (rFillData.bUseString)
3905
                {
3906
                    OSL_ENSURE(rFillData.aStart.Len() != 0, "there is no starting string");
3907
                    pDoc->SetString(nValX, nValY, nTab, rFillData.aStart);
3908
                }
3909
                else
3910
                {
3911
                    pDoc->SetValue(nValX, nValY, nTab, rFillData.fStart);
3912
                }
3894
			}
3913
			}
3895
			pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
3914
			pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
3896
						aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
3915
						aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
3897
						nCount, eDir, eCmd, eDateCmd, fStep, fMax );
3916
						nCount, rFillData );
3898
			AdjustRowHeight(rRange);
3917
			AdjustRowHeight(rRange);
3899
3918
3900
			rDocShell.PostPaintGridAll();
3919
			rDocShell.PostPaintGridAll();
Lines 3906-3912 Link Here
3906
		{
3925
		{
3907
			rDocShell.GetUndoManager()->AddUndoAction(
3926
			rDocShell.GetUndoManager()->AddUndoAction(
3908
				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
3927
				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
3909
									eDir, eCmd, eDateCmd, fStart, fStep, fMax,
3928
									rFillData,
3910
									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
3929
									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
3911
		}
3930
		}
3912
3931
Lines 4021-4040 Link Here
4021
            IDF_AUTOFILL, FALSE, pUndoDoc, &aMark );
4040
            IDF_AUTOFILL, FALSE, pUndoDoc, &aMark );
4022
	}
4041
	}
4023
4042
4024
	pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4043
    {
4025
				aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
4044
        sc::FillSeriesData aFillData;
4026
				nCount, eDir, eCmd, eDateCmd, fStep, fMax );
4045
        aFillData.eDir = eDir;
4046
        aFillData.eCmd = eCmd;
4047
        aFillData.eDateCmd = eDateCmd;
4048
        aFillData.fStep = fStep;
4049
        aFillData.fMax = fMax;
4027
4050
4028
	AdjustRowHeight(aDestArea);
4051
        pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4052
                    aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
4053
                    nCount, aFillData );
4029
4054
4030
	if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
4055
        AdjustRowHeight(aDestArea);
4031
	{
4032
		rDocShell.GetUndoManager()->AddUndoAction(
4033
			new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4034
								eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax,
4035
								pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
4036
	}
4037
4056
4057
        if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
4058
        {
4059
            aFillData.fStart = MAXDOUBLE;
4060
            rDocShell.GetUndoManager()->AddUndoAction(
4061
                new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4062
                                    aFillData,
4063
                                    pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
4064
        }
4065
    }
4066
4038
	rDocShell.PostPaintGridAll();
4067
	rDocShell.PostPaintGridAll();
4039
//	rDocShell.PostPaintDataChanged();
4068
//	rDocShell.PostPaintDataChanged();
4040
	aModificator.SetDocumentModified();
4069
	aModificator.SetDocumentModified();
(-)sc/source/ui/attrdlg/scdlgfact.hxx (+1 lines)
Lines 181-186 Link Here
181
	virtual double		GetStep() const;
181
	virtual double		GetStep() const;
182
	virtual double		GetMax() const;
182
	virtual double		GetMax() const;
183
	virtual String		GetStartStr() const;
183
	virtual String		GetStartStr() const;
184
	virtual String		GetMaxStr() const;
184
	virtual void		SetEdStartValEnabled(BOOL bFlag=FALSE);
185
	virtual void		SetEdStartValEnabled(BOOL bFlag=FALSE);
185
};
186
};
186
187
(-)sc/source/ui/attrdlg/scdlgfact.cxx (+4 lines)
Lines 326-331 Link Here
326
{
326
{
327
	return pDlg->GetStartStr();
327
	return pDlg->GetStartStr();
328
}
328
}
329
String	AbstractScFillSeriesDlg_Impl::GetMaxStr() const
330
{
331
	return pDlg->GetMaxStr();
332
}
329
void	AbstractScFillSeriesDlg_Impl::SetEdStartValEnabled(BOOL bFlag)
333
void	AbstractScFillSeriesDlg_Impl::SetEdStartValEnabled(BOOL bFlag)
330
{
334
{
331
	pDlg->SetEdStartValEnabled(bFlag);
335
	pDlg->SetEdStartValEnabled(bFlag);
(-)sc/source/ui/miscdlgs/filldlg.cxx (-6 / +51 lines)
Lines 45-53 Link Here
45
#include "document.hxx"
45
#include "document.hxx"
46
#include "miscdlgs.hrc"
46
#include "miscdlgs.hrc"
47
47
48
#define _FILLDLG_CXX
49
#include "filldlg.hxx"
48
#include "filldlg.hxx"
50
#undef _FILLDLG_CXX
49
#include "sc/valuestringparser.hxx"
51
50
52
51
53
52
Lines 247-252 Link Here
247
	else
246
	else
248
		bValOk = rDoc.GetFormatTable()->IsNumberFormat( aStr, nKey, fStartVal );
247
		bValOk = rDoc.GetFormatTable()->IsNumberFormat( aStr, nKey, fStartVal );
249
248
249
    if (!bValOk)
250
    {
251
        sc::ValueStringParser aValueString(aStr);
252
        bValOk = aValueString.HasValue();
253
        if (bValOk)
254
        {
255
            fStartVal = aValueString.GetValue();
256
        }
257
    }
258
250
	return bValOk;
259
	return bValOk;
251
}
260
}
252
261
Lines 278-287 Link Here
278
	else
287
	else
279
		bValOk = rDoc.GetFormatTable()->IsNumberFormat( aStr, nKey, fEndVal );
288
		bValOk = rDoc.GetFormatTable()->IsNumberFormat( aStr, nKey, fEndVal );
280
289
290
    if (!bValOk)
291
    {
292
        sc::ValueStringParser aValueString(aStr);
293
        bValOk = aValueString.HasValue();
294
        if (bValOk)
295
        {
296
            fEndVal = aValueString.GetValue();
297
        }
298
    }
299
281
	return bValOk;
300
	return bValOk;
282
}
301
}
283
302
284
303
304
namespace
305
{
306
307
    bool
308
    lcl_CheckStartEndString(const String& rStart, const String& rEnd)
309
    {
310
        const sc::ValueStringParser aStartValueString(rStart);
311
        const sc::ValueStringParser aEndValueString(rEnd);
312
        const bool bStartEmpty(rStart.Len() == 0);
313
        const bool bEndEmpty(rEnd.Len() == 0);
314
        const bool bStartIsValue(aStartValueString.HasValue());
315
        const bool bEndIsValue(aEndValueString.HasValue());
316
        bool bValOk((bStartEmpty || bStartIsValue) && (bEndEmpty || bEndIsValue));
317
        if (bValOk)
318
        {
319
            if (bStartIsValue && bEndIsValue)
320
            {
321
                bValOk = CanBeOrdered(aStartValueString, aEndValueString);
322
            }
323
        }
324
        return bValOk;
325
    }
326
327
}
328
285
//----------------------------------------------------------------------------
329
//----------------------------------------------------------------------------
286
// Handler:
330
// Handler:
287
//----------------------------------------------------------------------------
331
//----------------------------------------------------------------------------
Lines 359-364 Link Here
359
		bAllOk = FALSE;
403
		bAllOk = FALSE;
360
		pEdWrong = &aEdEndVal;
404
		pEdWrong = &aEdEndVal;
361
	}
405
	}
406
    else if (!lcl_CheckStartEndString(aEdStartVal.GetText(), aEdEndVal.GetText()))
407
    {
408
        bAllOk = FALSE;
409
        pEdWrong = &aEdEndVal;
410
    }
362
	if ( bAllOk )
411
	if ( bAllOk )
363
		EndDialog( RET_OK );
412
		EndDialog( RET_OK );
364
	else
413
	else
Lines 372-378 Link Here
372
421
373
	return 0;
422
	return 0;
374
}
423
}
375
376
377
378
(-)sc/source/ui/undo/undoblk3.cxx (-22 / +25 lines)
Lines 578-598 Link Here
578
ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
578
ScUndoAutoFill::ScUndoAutoFill( ScDocShell* pNewDocShell,
579
				const ScRange& rRange, const ScRange& rSourceArea,
579
				const ScRange& rRange, const ScRange& rSourceArea,
580
				ScDocument* pNewUndoDoc, const ScMarkData& rMark,
580
				ScDocument* pNewUndoDoc, const ScMarkData& rMark,
581
				FillDir eNewFillDir, FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
581
				const sc::FillSeriesData& rFillData, USHORT nMaxShIndex )
582
				double fNewStartValue, double fNewStepValue, double fNewMaxValue,
583
				USHORT nMaxShIndex )
584
		//
582
		//
585
	:	ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
583
	:	ScBlockUndo( pNewDocShell, rRange, SC_UNDO_AUTOHEIGHT ),
586
		//
584
		//
587
		aSource			( rSourceArea ),
585
		aSource			( rSourceArea ),
588
		aMarkData		( rMark ),
586
		aMarkData		( rMark ),
589
		pUndoDoc		( pNewUndoDoc ),
587
		pUndoDoc		( pNewUndoDoc ),
590
		eFillDir		( eNewFillDir ),
588
		m_aFillData(rFillData),
591
		eFillCmd		( eNewFillCmd ),
589
        nStartChangeAction(0L),
592
		eFillDateCmd	( eNewFillDateCmd ),
590
        nEndChangeAction(0L),
593
		fStartValue		( fNewStartValue ),
594
		fStepValue		( fNewStepValue ),
595
		fMaxValue		( fNewMaxValue ),
596
		nMaxSharedIndex	( nMaxShIndex)
591
		nMaxSharedIndex	( nMaxShIndex)
597
{
592
{
598
	SetChangeTrack();
593
	SetChangeTrack();
Lines 702-708 Link Here
702
//!	Tabellen selektieren
697
//!	Tabellen selektieren
703
698
704
    SCCOLROW nCount = 0;
699
    SCCOLROW nCount = 0;
705
	switch (eFillDir)
700
	switch (m_aFillData.eDir)
706
	{
701
	{
707
		case FILL_TO_BOTTOM:
702
		case FILL_TO_BOTTOM:
708
			nCount = aBlockRange.aEnd.Row() - aSource.aEnd.Row();
703
			nCount = aBlockRange.aEnd.Row() - aSource.aEnd.Row();
Lines 719-736 Link Here
719
	}
714
	}
720
715
721
	ScDocument* pDoc = pDocShell->GetDocument();
716
	ScDocument* pDoc = pDocShell->GetDocument();
722
	if ( fStartValue != MAXDOUBLE )
717
	if (m_aFillData.fStart != MAXDOUBLE)
723
	{
718
	{
724
		SCCOL nValX = (eFillDir == FILL_TO_LEFT) ? aSource.aEnd.Col() : aSource.aStart.Col();
719
		SCCOL nValX = (m_aFillData.eDir == FILL_TO_LEFT)
725
		SCROW nValY = (eFillDir == FILL_TO_TOP ) ? aSource.aEnd.Row() : aSource.aStart.Row();
720
            ? aSource.aEnd.Col() : aSource.aStart.Col();
721
		SCROW nValY = (m_aFillData.eDir == FILL_TO_TOP )
722
            ? aSource.aEnd.Row() : aSource.aStart.Row();
726
		SCTAB nTab = aSource.aStart.Tab();
723
		SCTAB nTab = aSource.aStart.Tab();
727
		pDoc->SetValue( nValX, nValY, nTab, fStartValue );
724
        if (m_aFillData.bUseString)
725
        {
726
            OSL_ENSURE(rFillData.aStart.Len() != 0, "there is no starting string");
727
            pDoc->SetString(nValX, nValY, nTab, m_aFillData.aStart);
728
        }
729
        else
730
        {
731
            pDoc->SetValue(nValX, nValY, nTab, m_aFillData.fStart);
732
        }
728
	}
733
	}
729
	pDoc->Fill( aSource.aStart.Col(), aSource.aStart.Row(),
734
	pDoc->Fill(aSource.aStart.Col(), aSource.aStart.Row(),
730
				aSource.aEnd.Col(),   aSource.aEnd.Row(),
735
				aSource.aEnd.Col(),   aSource.aEnd.Row(),
731
				aMarkData, nCount,
736
				aMarkData, nCount, m_aFillData)
732
				eFillDir, eFillCmd, eFillDateCmd,
737
        ;
733
				fStepValue, fMaxValue );
734
738
735
	SetChangeTrack();
739
	SetChangeTrack();
736
740
Lines 751-761 Link Here
751
	if (rTarget.ISA(ScTabViewTarget))
755
	if (rTarget.ISA(ScTabViewTarget))
752
	{
756
	{
753
		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
757
		ScTabViewShell& rViewShell = *((ScTabViewTarget&)rTarget).GetViewShell();
754
		if (eFillCmd==FILL_SIMPLE)
758
		if (m_aFillData.eCmd==FILL_SIMPLE)
755
			rViewShell.FillSimple( eFillDir, TRUE );
759
			rViewShell.FillSimple(m_aFillData.eDir, TRUE);
756
		else
760
		else
757
			rViewShell.FillSeries( eFillDir, eFillCmd, eFillDateCmd,
761
			rViewShell.FillSeries(m_aFillData, true);
758
								   fStartValue, fStepValue, fMaxValue, TRUE );
759
	}
762
	}
760
}
763
}
761
764
(-)sc/source/ui/inc/undoblk.hxx (-9 / +7 lines)
Lines 48-53 Link Here
48
class SvxSearchItem;
48
class SvxSearchItem;
49
class SdrUndoAction;
49
class SdrUndoAction;
50
50
51
// namespace sc
52
// {
53
    // struct FillSeriesData;
54
// }
55
51
//----------------------------------------------------------------------------
56
//----------------------------------------------------------------------------
52
57
53
class ScUndoInsertCells: public ScMoveUndo
58
class ScUndoInsertCells: public ScMoveUndo
Lines 413-421 Link Here
413
					ScUndoAutoFill( ScDocShell* pNewDocShell,
418
					ScUndoAutoFill( ScDocShell* pNewDocShell,
414
									const ScRange& rRange, const ScRange& rSourceArea,
419
									const ScRange& rRange, const ScRange& rSourceArea,
415
									ScDocument* pNewUndoDoc, const ScMarkData& rMark,
420
									ScDocument* pNewUndoDoc, const ScMarkData& rMark,
416
									FillDir eNewFillDir,
421
									const sc::FillSeriesData& rFillData,
417
									FillCmd eNewFillCmd, FillDateCmd eNewFillDateCmd,
418
									double fNewStartValue, double fNewStepValue, double fNewMaxValue,
419
									USHORT nMaxShIndex );
422
									USHORT nMaxShIndex );
420
	virtual 		~ScUndoAutoFill();
423
	virtual 		~ScUndoAutoFill();
421
424
Lines 430-441 Link Here
430
	ScRange			aSource;
433
	ScRange			aSource;
431
	ScMarkData		aMarkData;
434
	ScMarkData		aMarkData;
432
	ScDocument*		pUndoDoc;
435
	ScDocument*		pUndoDoc;
433
	FillDir			eFillDir;
436
    sc::FillSeriesData m_aFillData;
434
	FillCmd			eFillCmd;
435
	FillDateCmd		eFillDateCmd;
436
	double			fStartValue;
437
	double			fStepValue;
438
	double			fMaxValue;
439
	ULONG			nStartChangeAction;
437
	ULONG			nStartChangeAction;
440
	ULONG			nEndChangeAction;
438
	ULONG			nEndChangeAction;
441
	USHORT			nMaxSharedIndex;
439
	USHORT			nMaxSharedIndex;
(-)sc/source/ui/inc/viewfunc.hxx (-4 / +5 lines)
Lines 244-253 Link Here
244
	BOOL			RemoveMerge( BOOL bRecord = TRUE );
244
	BOOL			RemoveMerge( BOOL bRecord = TRUE );
245
245
246
	void			FillSimple( FillDir eDir, BOOL bRecord = TRUE );
246
	void			FillSimple( FillDir eDir, BOOL bRecord = TRUE );
247
	void			FillSeries( FillDir	eDir, FillCmd eCmd, FillDateCmd	eDateCmd,
247
    void			FillSeries( FillDir	eDir, FillCmd eCmd, FillDateCmd	eDateCmd,
248
								double fStart, double fStep, double fMax, BOOL bRecord = TRUE );
248
                                double fStart, double fStep, double fMax, BOOL bRecord = TRUE );
249
	void			FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
249
	void FillSeries(const sc::FillSeriesData& rFillData, bool bRecord = true);
250
								SCCOL nEndCol, SCROW nEndRow, ULONG nCount, BOOL bRecord = TRUE );
250
    void			FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
251
                                SCCOL nEndCol, SCROW nEndRow, ULONG nCount, BOOL bRecord = TRUE );
251
	void			FillCrossDblClick();
252
	void			FillCrossDblClick();
252
253
253
	void			TransliterateText( sal_Int32 nType );
254
	void			TransliterateText( sal_Int32 nType );
(-)sc/source/ui/inc/filldlg.hxx (-3 / +4 lines)
Lines 78-83 Link Here
78
	double		GetMax() const				{ return fEndVal; }
78
	double		GetMax() const				{ return fEndVal; }
79
79
80
	String		GetStartStr() const			{ return aEdStartVal.GetText(); }
80
	String		GetStartStr() const			{ return aEdStartVal.GetText(); }
81
    String GetMaxStr() const
82
    {
83
        return aEdEndVal.GetText();
84
    }
81
85
82
	void		SetEdStartValEnabled(BOOL bFlag=FALSE);
86
	void		SetEdStartValEnabled(BOOL bFlag=FALSE);
83
87
Lines 129-135 Link Here
129
	double		fIncrement;
133
	double		fIncrement;
130
	double		fEndVal;
134
	double		fEndVal;
131
135
132
#ifdef _FILLDLG_CXX
133
private:
136
private:
134
	void Init( USHORT nPossDir );
137
	void Init( USHORT nPossDir );
135
	BOOL CheckStartVal();
138
	BOOL CheckStartVal();
Lines 138-147 Link Here
138
141
139
	DECL_LINK( OKHdl, void * );
142
	DECL_LINK( OKHdl, void * );
140
	DECL_LINK( DisableHdl, Button * );
143
	DECL_LINK( DisableHdl, Button * );
141
#endif
142
};
144
};
143
145
144
146
145
146
#endif // SC_FILLDLG_HXX
147
#endif // SC_FILLDLG_HXX
147
148
(-)sc/source/ui/inc/docfunc.hxx (-8 / +6 lines)
Lines 154-168 Link Here
154
	BOOL			TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
154
	BOOL			TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
155
							const ScTabOpParam& rParam, BOOL bRecord, BOOL bApi );
155
							const ScTabOpParam& rParam, BOOL bRecord, BOOL bApi );
156
156
157
	BOOL			FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
157
    BOOL			FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
158
								FillDir eDir, BOOL bRecord, BOOL bApi );
158
                                FillDir eDir, BOOL bRecord, BOOL bApi );
159
	BOOL			FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
159
	bool			FillSeries(const ScRange& rRange, const ScMarkData* pTabMark,
160
								FillDir	eDir, FillCmd eCmd, FillDateCmd	eDateCmd,
160
                                const sc::FillSeriesData& rFillData, bool bRecord, bool bApi);
161
								double fStart, double fStep, double fMax,
162
								BOOL bRecord, BOOL bApi );
163
					// FillAuto: rRange wird von Source-Range auf Dest-Range angepasst
161
					// FillAuto: rRange wird von Source-Range auf Dest-Range angepasst
164
	BOOL			FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
162
    BOOL			FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
165
								FillDir eDir, ULONG nCount, BOOL bRecord, BOOL bApi );
163
                                FillDir eDir, ULONG nCount, BOOL bRecord, BOOL bApi );
166
164
167
	BOOL			ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi );
165
	BOOL			ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi );
168
166
(-)sc/source/ui/view/viewfun2.cxx (-3 / +16 lines)
Lines 1232-1247 Link Here
1232
//----------------------------------------------------------------------------
1232
//----------------------------------------------------------------------------
1233
1233
1234
void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
1234
void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
1235
							 double fStart, double fStep, double fMax, BOOL bRecord )
1235
                             double fStart, double fStep, double fMax, BOOL bRecord )
1236
{
1236
{
1237
    sc::FillSeriesData aFillData;
1238
    aFillData.eDir = eDir;
1239
    aFillData.eCmd = eCmd;
1240
    aFillData.eDateCmd = eDateCmd;
1241
    aFillData.fStart = fStart;
1242
    aFillData.fStep = fStep;
1243
    aFillData.fMax = fMax;
1244
    FillSeries(aFillData, bRecord);
1245
}
1246
1247
1248
void
1249
ScViewFunc::FillSeries(const sc::FillSeriesData& rFillData, bool bRecord)
1250
{
1237
	ScRange aRange;
1251
	ScRange aRange;
1238
	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1252
	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1239
	{
1253
	{
1240
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1254
		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1241
		const ScMarkData& rMark = GetViewData()->GetMarkData();
1255
		const ScMarkData& rMark = GetViewData()->GetMarkData();
1242
		BOOL bSuccess = pDocSh->GetDocFunc().
1256
		BOOL bSuccess = pDocSh->GetDocFunc().
1243
						FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
1257
						FillSeries(aRange, &rMark, rFillData, bRecord, FALSE);
1244
									fStart, fStep, fMax, bRecord, FALSE );
1245
		if (bSuccess)
1258
		if (bSuccess)
1246
		{
1259
		{
1247
			pDocSh->UpdateOle(GetViewData());
1260
			pDocSh->UpdateOle(GetViewData());
(-)sc/source/ui/view/cellsh1.cxx (-64 / +97 lines)
Lines 111-116 Link Here
111
#include <svx/svxdlg.hxx> //CHINA001
111
#include <svx/svxdlg.hxx> //CHINA001
112
#include <svx/dialogs.hrc> //CHINA001
112
#include <svx/dialogs.hrc> //CHINA001
113
#include "scabstdlg.hxx" //CHINA001
113
#include "scabstdlg.hxx" //CHINA001
114
#include "sc/valuestringparser.hxx"
115
114
#define IS_AVAILABLE(WhichId,ppItem) \
116
#define IS_AVAILABLE(WhichId,ppItem) \
115
    (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
117
    (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET)
116
118
Lines 126-131 Link Here
126
using namespace ::com::sun::star::beans;
128
using namespace ::com::sun::star::beans;
127
using namespace ::com::sun::star::uno;
129
using namespace ::com::sun::star::uno;
128
130
131
132
namespace
133
{
134
135
    sc::FillSeriesData
136
    lcl_CreateFillSeriesData(const AbstractScFillSeriesDlg& rFillDlg)
137
    {
138
        sc::FillSeriesData aFillData;
139
        aFillData.eDir = rFillDlg.GetFillDir();
140
        aFillData.eCmd = rFillDlg.GetFillCmd();
141
        aFillData.eDateCmd = rFillDlg.GetFillDateCmd();
142
        {
143
            const sc::ValueStringParser aValueString(rFillDlg.GetStartStr());
144
            aFillData.bUseString = aValueString.GetBaseSubstring().Len() != 0;
145
            if (aFillData.bUseString)
146
            {
147
                aFillData.aStart = rFillDlg.GetStartStr();
148
                aFillData.aMax = rFillDlg.GetMaxStr();
149
            }
150
        }
151
        aFillData.fStart = rFillDlg.GetStart();
152
        aFillData.fMax = rFillDlg.GetMax();
153
        aFillData.fStep = rFillDlg.GetStep();
154
155
        return aFillData;
156
    }
157
158
159
    double
160
    lcl_GetNumericValue(const String& rStr)
161
    {
162
        double fResult(0.0);
163
        sc::ValueStringParser aValueString(rStr);
164
        if (aValueString.HasValue())
165
        {
166
            fResult = aValueString.GetValue();
167
        }
168
        return fResult;
169
    }
170
171
}
172
129
//------------------------------------------------------------------
173
//------------------------------------------------------------------
130
void ScCellShell::ExecuteEdit( SfxRequest& rReq )
174
void ScCellShell::ExecuteEdit( SfxRequest& rReq )
131
{
175
{
Lines 561-572 Link Here
561
				SCROW nEndRow;
605
				SCROW nEndRow;
562
				SCTAB nEndTab;
606
				SCTAB nEndTab;
563
				USHORT nPossDir = FDS_OPT_NONE;
607
				USHORT nPossDir = FDS_OPT_NONE;
564
				FillDir		eFillDir	 = FILL_TO_BOTTOM;
608
                sc::FillSeriesData aFillData;
565
				FillCmd		eFillCmd	 = FILL_LINEAR;
566
				FillDateCmd	eFillDateCmd = FILL_DAY;
567
				double fStartVal = MAXDOUBLE;
568
				double fIncVal	 = 1;
569
				double fMaxVal	 = MAXDOUBLE;
570
				BOOL   bDoIt	 = FALSE;
609
				BOOL   bDoIt	 = FALSE;
571
610
572
				GetViewData()->GetSimpleArea( nStartCol, nStartRow, nStartTab,
611
				GetViewData()->GetSimpleArea( nStartCol, nStartRow, nStartTab,
Lines 575-587 Link Here
575
				if( nStartCol!=nEndCol )
614
				if( nStartCol!=nEndCol )
576
				{
615
				{
577
					nPossDir |= FDS_OPT_HORZ;
616
					nPossDir |= FDS_OPT_HORZ;
578
					eFillDir=FILL_TO_RIGHT;
617
					aFillData.eDir = FILL_TO_RIGHT;
579
				}
618
				}
580
619
581
				if( nStartRow!=nEndRow )
620
				if( nStartRow!=nEndRow )
582
				{
621
				{
583
					nPossDir |= FDS_OPT_VERT;
622
					nPossDir |= FDS_OPT_VERT;
584
					eFillDir=FILL_TO_BOTTOM;
623
					aFillData.eDir = FILL_TO_BOTTOM;
585
				}
624
				}
586
625
587
				ScDocument* 	 pDoc = GetViewData()->GetDocument();
626
				ScDocument* 	 pDoc = GetViewData()->GetDocument();
Lines 613-654 Link Here
613
					if( aFillDir.Len() )
652
					if( aFillDir.Len() )
614
						switch( aFillDir.GetChar(0) )
653
						switch( aFillDir.GetChar(0) )
615
						{
654
						{
616
							case 'B': case 'b': eFillDir=FILL_TO_BOTTOM; break;
655
							case 'B': case 'b': aFillData.eDir = FILL_TO_BOTTOM; break;
617
							case 'R': case 'r': eFillDir=FILL_TO_RIGHT; break;
656
							case 'R': case 'r': aFillData.eDir = FILL_TO_RIGHT; break;
618
							case 'T': case 't': eFillDir=FILL_TO_TOP; break;
657
							case 'T': case 't': aFillData.eDir = FILL_TO_TOP; break;
619
							case 'L': case 'l': eFillDir=FILL_TO_LEFT; break;
658
							case 'L': case 'l': aFillData.eDir = FILL_TO_LEFT; break;
620
						}
659
						}
621
660
622
					if( aFillCmd.Len() )
661
					if( aFillCmd.Len() )
623
						switch( aFillCmd.GetChar(0) )
662
						switch( aFillCmd.GetChar(0) )
624
						{
663
						{
625
							case 'S': case 's': eFillCmd=FILL_SIMPLE; break;
664
							case 'S': case 's': aFillData.eCmd = FILL_SIMPLE; break;
626
							case 'L': case 'l': eFillCmd=FILL_LINEAR; break;
665
							case 'L': case 'l': aFillData.eCmd = FILL_LINEAR; break;
627
							case 'G': case 'g': eFillCmd=FILL_GROWTH; break;
666
							case 'G': case 'g': aFillData.eCmd = FILL_GROWTH; break;
628
							case 'D': case 'd': eFillCmd=FILL_DATE; break;
667
							case 'D': case 'd': aFillData.eCmd = FILL_DATE; break;
629
							case 'A': case 'a': eFillCmd=FILL_AUTO; break;
668
							case 'A': case 'a': aFillData.eCmd = FILL_AUTO; break;
630
						}
669
						}
631
670
632
					if( aFillDateCmd.Len() )
671
					if( aFillDateCmd.Len() )
633
						switch( aFillDateCmd.GetChar(0) )
672
						switch( aFillDateCmd.GetChar(0) )
634
						{
673
						{
635
							case 'D': case 'd': eFillDateCmd=FILL_DAY; break;
674
							case 'D': case 'd': aFillData.eDateCmd = FILL_DAY; break;
636
							case 'W': case 'w': eFillDateCmd=FILL_WEEKDAY; break;
675
							case 'W': case 'w': aFillData.eDateCmd = FILL_WEEKDAY; break;
637
							case 'M': case 'm': eFillDateCmd=FILL_MONTH; break;
676
							case 'M': case 'm': aFillData.eDateCmd = FILL_MONTH; break;
638
							case 'Y': case 'y': eFillDateCmd=FILL_YEAR; break;
677
							case 'Y': case 'y': aFillData.eDateCmd = FILL_YEAR; break;
639
						}
678
						}
640
679
641
					nKey = 0;
680
					nKey = 0;
642
					if( pFormatter->IsNumberFormat( aFillStart, nKey, fTmpVal ))
681
					if( pFormatter->IsNumberFormat( aFillStart, nKey, fTmpVal ))
643
						fStartVal = fTmpVal;
682
						aFillData.fStart = fTmpVal;
644
683
645
					nKey = 0;
684
					nKey = 0;
646
					if( pFormatter->IsNumberFormat( aFillStep, nKey, fTmpVal ))
685
					if( pFormatter->IsNumberFormat( aFillStep, nKey, fTmpVal ))
647
						fIncVal = fTmpVal;
686
						aFillData.fStep = fTmpVal;
648
687
649
					nKey = 0;
688
					nKey = 0;
650
					if( pFormatter->IsNumberFormat( aFillMax, nKey, fTmpVal ))
689
					if( pFormatter->IsNumberFormat( aFillMax, nKey, fTmpVal ))
651
						fMaxVal = fTmpVal;
690
						aFillData.fMax = fTmpVal;
652
691
653
					bDoIt	= TRUE;
692
					bDoIt	= TRUE;
654
693
Lines 670-680 Link Here
670
						short nPrivType = pPrivEntry->GetType();
709
						short nPrivType = pPrivEntry->GetType();
671
						if ( ( nPrivType & NUMBERFORMAT_DATE)>0)
710
						if ( ( nPrivType & NUMBERFORMAT_DATE)>0)
672
						{
711
						{
673
						   eFillCmd=FILL_DATE;
712
						   aFillData.eCmd = FILL_DATE;
674
						}
713
						}
675
						else if(eCellType==CELLTYPE_STRING)
714
						else if(eCellType==CELLTYPE_STRING)
676
						{
715
						{
677
						   eFillCmd=FILL_AUTO;
716
						   aFillData.eCmd = FILL_AUTO;
678
						}
717
						}
679
					}
718
					}
680
719
Lines 688-703 Link Here
688
						String aEndStr;
727
						String aEndStr;
689
728
690
						pDoc->GetInputString( nStartCol, nStartRow, nStartTab, aStartStr);
729
						pDoc->GetInputString( nStartCol, nStartRow, nStartTab, aStartStr);
691
						pDoc->GetValue( nStartCol, nStartRow, nStartTab, fStartVal );
730
						aFillData.fStart = lcl_GetNumericValue(aStartStr);
692
731
693
732
694
						if(eFillDir==FILL_TO_BOTTOM && nStartRow < nEndRow )
733
						if(aFillData.eDir == FILL_TO_BOTTOM && nStartRow < nEndRow )
695
						{
734
						{
696
							pDoc->GetInputString( nStartCol, nStartRow+1, nStartTab, aEndStr);
735
							pDoc->GetInputString( nStartCol, nStartRow+1, nStartTab, aEndStr);
697
							if(aEndStr.Len()>0)
736
							if(aEndStr.Len()>0)
698
							{
737
							{
699
								pDoc->GetValue( nStartCol, nStartRow+1, nStartTab, fInputEndVal);
738
								fInputEndVal = lcl_GetNumericValue(aEndStr);
700
								fIncVal=fInputEndVal-fStartVal;
739
								aFillData.fStep = fInputEndVal - aFillData.fStart;
701
							}
740
							}
702
						}
741
						}
703
						else
742
						else
Lines 707-756 Link Here
707
								pDoc->GetInputString( nStartCol+1, nStartRow, nStartTab, aEndStr);
746
								pDoc->GetInputString( nStartCol+1, nStartRow, nStartTab, aEndStr);
708
								if(aEndStr.Len()>0)
747
								if(aEndStr.Len()>0)
709
								{
748
								{
710
									pDoc->GetValue( nStartCol+1, nStartRow, nStartTab, fInputEndVal);
749
									fInputEndVal = lcl_GetNumericValue(aEndStr);
711
									fIncVal=fInputEndVal-fStartVal;
750
									aFillData.fStep = fInputEndVal - aFillData.fStart;
712
								}
751
								}
713
							}
752
							}
714
						}
753
						}
715
						if(eFillCmd==FILL_DATE)
754
						if (aFillData.eCmd == FILL_DATE)
716
						{
755
						{
717
							Date aNullDate = *pDoc->GetFormatTable()->GetNullDate();
756
							Date aNullDate = *pDoc->GetFormatTable()->GetNullDate();
718
							Date aStartDate = aNullDate;
757
							Date aStartDate = aNullDate;
719
							aStartDate+= (long)fStartVal;
758
							aStartDate += static_cast<long>(aFillData.fStart);
720
							Date aEndDate = aNullDate;
759
							Date aEndDate = aNullDate;
721
							aEndDate+= (long)fInputEndVal;
760
							aEndDate += static_cast<long>(fInputEndVal);
722
							double fTempDate=0;
761
							double fTempDate=0;
723
762
724
							if(aStartDate.GetYear()!=aEndDate.GetYear())
763
							if(aStartDate.GetYear()!=aEndDate.GetYear())
725
							{
764
							{
726
								eFillDateCmd = FILL_YEAR;
765
								aFillData.eDateCmd = FILL_YEAR;
727
								fTempDate=aEndDate.GetYear()-aStartDate.GetYear();
766
								fTempDate=aEndDate.GetYear()-aStartDate.GetYear();
728
							}
767
							}
729
							if(aStartDate.GetMonth()!=aEndDate.GetMonth())
768
							if(aStartDate.GetMonth()!=aEndDate.GetMonth())
730
							{
769
							{
731
								eFillDateCmd = FILL_MONTH;
770
								aFillData.eDateCmd = FILL_MONTH;
732
								fTempDate=fTempDate*12+aEndDate.GetMonth()-aStartDate.GetMonth();
771
								fTempDate=fTempDate*12+aEndDate.GetMonth()-aStartDate.GetMonth();
733
							}
772
							}
734
							if(aStartDate.GetDay()==aEndDate.GetDay())
773
							if(aStartDate.GetDay()==aEndDate.GetDay())
735
							{
774
							{
736
								fIncVal=fTempDate;
775
								aFillData.fStep = fTempDate;
737
							}
776
							}
738
						}
777
						}
739
					}
778
					}
740
//CHINA001					ScFillSeriesDlg* pDlg = new ScFillSeriesDlg(
779
//CHINA001					ScFillSeriesDlg* pDlg = new ScFillSeriesDlg(
741
//CHINA001					pTabViewShell->GetDialogParent(), *pDoc,
780
//CHINA001					pTabViewShell->GetDialogParent(), *pDoc,
742
//CHINA001					eFillDir, eFillCmd, eFillDateCmd,
781
//CHINA001					eDir, eCmd, eDateCmd,
743
//CHINA001					aStartStr, fIncVal, fMaxVal,
782
//CHINA001					aStartStr, fIncVal, fMaxVal,
744
//CHINA001					nPossDir);
783
//CHINA001					nPossDir);
745
					ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
784
					ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
746
					DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
785
					DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
747
786
748
					AbstractScFillSeriesDlg* pDlg = pFact->CreateScFillSeriesDlg( pTabViewShell->GetDialogParent(),
787
					AbstractScFillSeriesDlg* pDlg = pFact->CreateScFillSeriesDlg(
749
															*pDoc,
788
                            pTabViewShell->GetDialogParent(), *pDoc,
750
															eFillDir, eFillCmd, eFillDateCmd,
789
                            aFillData.eDir, aFillData.eCmd, aFillData.eDateCmd,
751
															aStartStr, fIncVal, fMaxVal,
790
                            aStartStr, aFillData.fStep, aFillData.fMax,
752
															nPossDir,
791
                            nPossDir, RID_SCDLG_FILLSERIES)
753
															RID_SCDLG_FILLSERIES);
792
                        ;
754
					DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
793
					DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001
755
794
756
					if ( nStartCol != nEndCol && nStartRow != nEndRow )
795
					if ( nStartCol != nEndCol && nStartRow != nEndRow )
Lines 760-779 Link Here
760
799
761
					if ( pDlg->Execute() == RET_OK )
800
					if ( pDlg->Execute() == RET_OK )
762
					{
801
					{
763
						eFillDir		= pDlg->GetFillDir();
802
                        aFillData = lcl_CreateFillSeriesData(*pDlg);
764
						eFillCmd		= pDlg->GetFillCmd();
803
                        aFillData.bUseString = true;
765
						eFillDateCmd	= pDlg->GetFillDateCmd();
804
						if (aFillData.eCmd == FILL_AUTO)
766
767
						if(eFillCmd==FILL_AUTO)
768
						{
805
						{
769
							String aStr=pDlg->GetStartStr();
806
							if (aFillData.aStart.Len() > 0)
770
							if(aStr.Len()>0)
807
								pTabViewShell->EnterData(nStartCol, nStartRow, nStartTab, aFillData.aStart);
771
								pTabViewShell->EnterData( nStartCol, nStartRow, nStartTab, aStr );
772
						}
808
						}
773
						fStartVal		= pDlg->GetStart();
809
						bDoIt = TRUE;
774
						fIncVal			= pDlg->GetStep();
775
						fMaxVal			= pDlg->GetMax();
776
						bDoIt			= TRUE;
777
					}
810
					}
778
					delete pDlg;
811
					delete pDlg;
779
				}
812
				}
Lines 781-794 Link Here
781
				if( bDoIt )
814
				if( bDoIt )
782
				{
815
				{
783
					//nScFillModeMouseModifier = 0;	// kein Ctrl/Copy
816
					//nScFillModeMouseModifier = 0;	// kein Ctrl/Copy
784
					pTabViewShell->FillSeries( eFillDir, eFillCmd, eFillDateCmd, fStartVal, fIncVal, fMaxVal );
817
					pTabViewShell->FillSeries(aFillData);
785
818
786
					if( ! rReq.IsAPI() )
819
					if( ! rReq.IsAPI() )
787
					{
820
					{
788
						String	aPara;
821
						String	aPara;
789
						Color*	pColor=0;
822
						Color*	pColor=0;
790
823
791
						switch( eFillDir )
824
						switch( aFillData.eDir )
792
						{
825
						{
793
							case FILL_TO_BOTTOM:	aPara = 'B'; break;
826
							case FILL_TO_BOTTOM:	aPara = 'B'; break;
794
							case FILL_TO_RIGHT:		aPara = 'R'; break;
827
							case FILL_TO_RIGHT:		aPara = 'R'; break;
Lines 798-804 Link Here
798
						}
831
						}
799
						rReq.AppendItem( SfxStringItem( FID_FILL_SERIES, aPara ) );
832
						rReq.AppendItem( SfxStringItem( FID_FILL_SERIES, aPara ) );
800
833
801
						switch( eFillCmd )
834
						switch( aFillData.eCmd )
802
						{
835
						{
803
							case FILL_SIMPLE:		aPara = 'S'; break;
836
							case FILL_SIMPLE:		aPara = 'S'; break;
804
							case FILL_LINEAR:		aPara = 'L'; break;
837
							case FILL_LINEAR:		aPara = 'L'; break;
Lines 809-815 Link Here
809
						}
842
						}
810
						rReq.AppendItem( SfxStringItem( FN_PARAM_1, aPara ) );
843
						rReq.AppendItem( SfxStringItem( FN_PARAM_1, aPara ) );
811
844
812
						switch( eFillDateCmd )
845
						switch( aFillData.eDateCmd )
813
						{
846
						{
814
							case FILL_DAY:			aPara = 'D'; break;
847
							case FILL_DAY:			aPara = 'D'; break;
815
							case FILL_WEEKDAY:		aPara = 'W'; break;
848
							case FILL_WEEKDAY:		aPara = 'W'; break;
Lines 822-834 Link Here
822
						ULONG nFormatKey = pFormatter->GetStandardFormat(NUMBERFORMAT_NUMBER,
855
						ULONG nFormatKey = pFormatter->GetStandardFormat(NUMBERFORMAT_NUMBER,
823
									ScGlobal::eLnge );
856
									ScGlobal::eLnge );
824
857
825
						pFormatter->GetOutputString( fIncVal, nFormatKey, aPara, &pColor );
858
						pFormatter->GetOutputString(aFillData.fStep, nFormatKey, aPara, &pColor);
826
						rReq.AppendItem( SfxStringItem( FN_PARAM_3, aPara ) );
859
						rReq.AppendItem( SfxStringItem( FN_PARAM_3, aPara ) );
827
860
828
						pFormatter->GetOutputString( fStartVal, nFormatKey, aPara, &pColor );
861
						pFormatter->GetOutputString(aFillData.fStart, nFormatKey, aPara, &pColor);
829
						rReq.AppendItem( SfxStringItem( FN_PARAM_4, aPara ) );
862
						rReq.AppendItem( SfxStringItem( FN_PARAM_4, aPara ) );
830
863
831
						pFormatter->GetOutputString( fMaxVal, nFormatKey, aPara, &pColor );
864
						pFormatter->GetOutputString(aFillData.fMax, nFormatKey, aPara, &pColor);
832
						rReq.AppendItem( SfxStringItem( FN_PARAM_5, aPara ) );
865
						rReq.AppendItem( SfxStringItem( FN_PARAM_5, aPara ) );
833
866
834
						rReq.Done();
867
						rReq.Done();
(-)sc/inc/scabstdlg.hxx (+1 lines)
Lines 128-133 Link Here
128
	virtual double		GetStep() const	= 0;
128
	virtual double		GetStep() const	= 0;
129
	virtual double		GetMax() const = 0;
129
	virtual double		GetMax() const = 0;
130
	virtual String		GetStartStr() const = 0;
130
	virtual String		GetStartStr() const = 0;
131
    virtual String		GetMaxStr() const = 0;
131
	virtual void		SetEdStartValEnabled(BOOL bFlag=FALSE) = 0;
132
	virtual void		SetEdStartValEnabled(BOOL bFlag=FALSE) = 0;
132
};
133
};
133
134
(-)sc/inc/table.hxx (-8 / +10 lines)
Lines 275-281 Link Here
275
                            aCol[rPos.Col()].GetValue( rPos.Row() ) :
275
                            aCol[rPos.Col()].GetValue( rPos.Row() ) :
276
                            0.0;
276
                            0.0;
277
                    }
277
                    }
278
	double		GetValue( SCCOL nCol, SCROW nRow );
278
	double		GetValue( SCCOL nCol, SCROW nRow ) const;
279
	void		GetFormula( SCCOL nCol, SCROW nRow, String& rFormula,
279
	void		GetFormula( SCCOL nCol, SCROW nRow, String& rFormula,
280
							BOOL bAsciiExport = FALSE );
280
							BOOL bAsciiExport = FALSE );
281
281
Lines 441-449 Link Here
441
                                 std::set<USHORT>& rIndexes) const;
441
                                 std::set<USHORT>& rIndexes) const;
442
	void 		ReplaceRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
442
	void 		ReplaceRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
443
									  const ScRangeData::IndexMap& rMap );
443
									  const ScRangeData::IndexMap& rMap );
444
    void		Fill( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
445
                        ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
446
                        double nStepValue, double nMaxValue);
444
	void		Fill( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
447
	void		Fill( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
445
						ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
448
						ULONG nFillCount, const sc::FillSeriesData& rFillData);
446
						double nStepValue, double nMaxValue);
447
	String		GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY );
449
	String		GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY );
448
450
449
	void		UpdateSelectionFunction( ScFunctionData& rData,
451
	void		UpdateSelectionFunction( ScFunctionData& rData,
Lines 664-674 Link Here
664
	void		DestroySortCollator();
666
	void		DestroySortCollator();
665
667
666
private:
668
private:
667
	void		FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
669
	void FillSeries(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
668
								ULONG nFillCount, FillDir eFillDir, FillCmd eFillCmd,
670
            ULONG nFillCount, const sc::FillSeriesData& rFillData,
669
								FillDateCmd eFillDateCmd,
671
            USHORT nMinDigits, bool bAttribs, ScProgress& rProgress);
670
								double nStepValue, double nMaxValue, USHORT nMinDigits,
671
								BOOL bAttribs, ScProgress& rProgress );
672
	void		FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
672
	void		FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
673
								FillCmd& rCmd, FillDateCmd& rDateCmd,
673
								FillCmd& rCmd, FillDateCmd& rDateCmd,
674
								double& rInc, USHORT& rMinDigits,
674
								double& rInc, USHORT& rMinDigits,
Lines 752-757 Link Here
752
    // also invalidates script type, broadcasts for "calc as shown"
752
    // also invalidates script type, broadcasts for "calc as shown"
753
    void        InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
753
    void        InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
754
                                     BOOL bNumFormatChanged, BOOL bBroadcast );
754
                                     BOOL bNumFormatChanged, BOOL bBroadcast );
755
756
    bool impl_getNumericValue(const SCCOL nCol, const SCROW nRow, double& rValue) const;
755
};
757
};
756
758
757
759
(-)sc/inc/sc/valuestringparser.hxx (+110 lines)
Line 0 Link Here
1
/*************************************************************************
2
 *
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * Copyright 2008 by Sun Microsystems, Inc.
6
 *
7
 * OpenOffice.org - a multi-platform office productivity suite
8
 *
9
 * $RCSfile: $
10
 * $Revision: $
11
 *
12
 * This file is part of OpenOffice.org.
13
 *
14
 * OpenOffice.org is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Lesser General Public License version 3
16
 * only, as published by the Free Software Foundation.
17
 *
18
 * OpenOffice.org is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU Lesser General Public License version 3 for more details
22
 * (a copy is included in the LICENSE file that accompanied this code).
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * version 3 along with OpenOffice.org.  If not, see
26
 * <http://www.openoffice.org/license.html>
27
 * for a copy of the LGPLv3 License.
28
 *
29
 ************************************************************************/
30
31
#ifndef SC_VALUESTRINGPARSER_HXX_INCLUDED
32
#define SC_VALUESTRINGPARSER_HXX_INCLUDED
33
34
#include <tools/string.hxx>
35
36
#include "scdllapi.h"
37
38
39
namespace sc
40
{
41
42
    /** Extract numeric value from a string and supply more info about it.
43
        Only integer numbers staying at the beginning or at the end of the
44
        string are recognized.
45
46
        The only function usable when there is no numeric value (i.e. when
47
        HasValue() returns false) is GetBaseSubstring(), returning the
48
        original string. The other functions return default values of their
49
        respective types.
50
     */
51
    class SC_DLLPUBLIC ValueStringParser
52
    {
53
    public:
54
        /** Examine rString for possible numeric value.
55
         */
56
        SC_DLLPUBLIC ValueStringParser(const String& rString);
57
58
        /** Tell if the string contains (recognizable) numeric value.
59
         */
60
        SC_DLLPUBLIC bool HasValue() const;
61
62
        /** Get the found numeric value.
63
         */
64
        SC_DLLPUBLIC sal_Int32 GetValue() const;
65
66
        /** Get the minimum number of digits required for representation
67
            of the number. Value 0 means there is no requirement.
68
         */
69
        SC_DLLPUBLIC sal_Int16 GetMinDigits() const;
70
71
        /** Get the numeric substring (if any). This function returns
72
            nonempty string iff HasValue() == true.
73
         */
74
        SC_DLLPUBLIC const String& GetNumericSubstring() const;
75
76
        /** Get the base (i.e. non-numeric substring.
77
         */
78
        SC_DLLPUBLIC const String& GetBaseSubstring() const;
79
80
        /** Tell if the number is prefix of the base substring.
81
         */
82
        SC_DLLPUBLIC bool IsPrefix() const;
83
84
    private:
85
        void impl_DecompValueString();
86
87
    private:
88
        String m_aString;
89
        mutable String m_aNumericSubstring;
90
        String m_aBaseSubstring;
91
        sal_Int32 m_nValue;
92
        sal_Int16 m_nMinDigits;
93
        bool m_bHasValue;
94
        bool m_bIsPrefix;
95
    };
96
97
    /** Test if the two parsed strings can be ordered. They can be iff
98
        they both have numeric value and either share a common prefix/suffix
99
        or their suffix makes valid ordinal numbers from both of them.
100
     */
101
    SC_DLLPUBLIC bool
102
    CanBeOrdered(
103
            const ValueStringParser& rValueString1,
104
            const ValueStringParser& rValueString2);
105
106
}
107
108
#endif
109
110
// vim: set sts=4 sw=4 et:
(-)sc/inc/global.hxx (+20 lines)
Lines 965-968 Link Here
965
extern ::utl::TransliterationWrapper* GetScGlobalpTransliteration();//CHINA001
965
extern ::utl::TransliterationWrapper* GetScGlobalpTransliteration();//CHINA001
966
extern const LocaleDataWrapper* GetScGlobalpLocaleData();
966
extern const LocaleDataWrapper* GetScGlobalpLocaleData();
967
967
968
namespace sc
969
{
970
971
    struct FillSeriesData
972
    {
973
        FillDir eDir;
974
        FillCmd eCmd;
975
        FillDateCmd eDateCmd;
976
        double fStart;
977
        String aStart;
978
        double fStep;
979
        double fMax;
980
        String aMax;
981
        bool bUseString;
982
983
        FillSeriesData();
984
    };
985
986
}
987
968
#endif
988
#endif
(-)sc/inc/document.hxx (-5 / +9 lines)
Lines 740-745 Link Here
740
	SC_DLLPUBLIC void			GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString );
740
	SC_DLLPUBLIC void			GetInputString( SCCOL nCol, SCROW nRow, SCTAB nTab, String& rString );
741
	SC_DLLPUBLIC double			GetValue( const ScAddress& );
741
	SC_DLLPUBLIC double			GetValue( const ScAddress& );
742
	SC_DLLPUBLIC void			GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, double& rValue );
742
	SC_DLLPUBLIC void			GetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, double& rValue );
743
743
	SC_DLLPUBLIC double			RoundValueAsShown( double fVal, ULONG nFormat );
744
	SC_DLLPUBLIC double			RoundValueAsShown( double fVal, ULONG nFormat );
744
	SC_DLLPUBLIC void			GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
745
	SC_DLLPUBLIC void			GetNumberFormat( SCCOL nCol, SCROW nRow, SCTAB nTab,
745
									 sal_uInt32& rFormat );
746
									 sal_uInt32& rFormat );
Lines 1070-1080 Link Here
1070
1071
1071
	void			UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
1072
	void			UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY );
1072
1073
1073
	void			Fill(	SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1074
    void			Fill(	SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1074
							const ScMarkData& rMark,
1075
                            const ScMarkData& rMark,
1075
							ULONG nFillCount, FillDir eFillDir = FILL_TO_BOTTOM,
1076
                            ULONG nFillCount, FillDir eFillDir = FILL_TO_BOTTOM,
1076
							FillCmd eFillCmd = FILL_LINEAR, FillDateCmd eFillDateCmd = FILL_DAY,
1077
                            FillCmd eFillCmd = FILL_LINEAR, FillDateCmd eFillDateCmd = FILL_DAY,
1077
							double nStepValue = 1.0, double nMaxValue = 1E307);
1078
                            double nStepValue = 1.0, double nMaxValue = 1E307);
1079
	void Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1080
            const ScMarkData& rMark, ULONG nFillCount,
1081
            const sc::FillSeriesData& rFillData);
1078
	String			GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY );
1082
	String			GetAutoFillPreview( const ScRange& rSource, SCCOL nEndX, SCROW nEndY );
1079
1083
1080
	BOOL			GetSelectionFunction( ScSubTotalFunc eFunc,
1084
	BOOL			GetSelectionFunction( ScSubTotalFunc eFunc,

Return to issue 107203