commonuisupport/grid/src/GRDCELLS.CPP
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "GRDCELLS.H"
       
    17 #include "GRDPANIC.H"
       
    18 
       
    19 
       
    20 EXPORT_C CGridCellRegion* CGridCellRegion::NewL(const TRangeRef& aBounds)
       
    21 /** Creates a new selected region.
       
    22 
       
    23 @param aBounds The boundary of the region, defined as cell range.
       
    24 @return A pointer to the new selected region object. */
       
    25 	{
       
    26 	CGridCellRegion* self = new(ELeave) CGridCellRegion(aBounds);
       
    27 	CleanupStack::PushL(self);
       
    28 	self->ConstructL();
       
    29 	CleanupStack::Pop();
       
    30 	return self;
       
    31 	}
       
    32 
       
    33 CGridCellRegion::CGridCellRegion(const TRangeRef &aBounds)
       
    34 	: iBounds(aBounds)
       
    35 	{
       
    36 	}
       
    37 
       
    38 EXPORT_C CGridCellRegion::~CGridCellRegion()
       
    39 /** Destructor.
       
    40 
       
    41 Frees all resources owned by the object prior to its destruction. */
       
    42 	{
       
    43 	delete iRangeList;
       
    44 	}
       
    45 
       
    46 void CGridCellRegion::ConstructL()
       
    47 	{
       
    48 	iRangeList = new(ELeave) CArrayFixFlat<TRangeRef>(1);
       
    49 	}
       
    50 
       
    51 EXPORT_C void CGridCellRegion::AddColL(TInt aCol)
       
    52 /** Defines a new cell range one column in width, and adds it to the region.
       
    53 
       
    54 The row number of the start cell of the new range is the row number defining 
       
    55 the start of the region boundary.
       
    56 
       
    57 The row number of the end cell of the new range is the row number defining 
       
    58 the end of the region boundary.
       
    59 
       
    60 @param aCol The new column. This must lie on or within the region boundary, 
       
    61 otherwise no new range is added to the region. */
       
    62 	{
       
    63 	if (aCol<iBounds.iFrom.iCol || aCol>iBounds.iTo.iCol)
       
    64 		return;
       
    65 	TRangeRef cellRange;
       
    66 	cellRange.iFrom.iCol = cellRange.iTo.iCol = aCol;
       
    67 	cellRange.iFrom.iRow = iBounds.iFrom.iRow;
       
    68 	cellRange.iTo.iRow = iBounds.iTo.iRow;
       
    69 	iRangeList->AppendL(cellRange);
       
    70 	}
       
    71 
       
    72 EXPORT_C void CGridCellRegion::AddRowL(TInt aRow)
       
    73 /** Defines a new cell range one row in height, and adds it to the region.
       
    74 
       
    75 The column number of the start cell of the new range is the column number 
       
    76 defining the start of the region boundary.
       
    77 
       
    78 The column number of the end cell of the new range is the column number defining 
       
    79 the end of the region boundary.
       
    80 
       
    81 @param aRow The new row. This must lie on or within the region boundary, otherwise 
       
    82 no new range is added to the region. */
       
    83 	{
       
    84 	if (aRow<iBounds.iFrom.iRow || aRow>iBounds.iTo.iRow)
       
    85 		return;
       
    86 	TRangeRef cellRange;
       
    87 	cellRange.iFrom.iRow = cellRange.iTo.iRow = aRow;
       
    88 	cellRange.iFrom.iCol = iBounds.iFrom.iCol;
       
    89 	cellRange.iTo.iCol = iBounds.iTo.iCol;
       
    90 	iRangeList->AppendL(cellRange);
       
    91 	}
       
    92 
       
    93 LOCAL_C void NormalizeRange(TRangeRef& aRange)
       
    94 	{
       
    95 	if (aRange.iFrom.iCol>aRange.iTo.iCol)
       
    96 		{
       
    97 		TInt temp=aRange.iFrom.iCol;
       
    98 		aRange.iFrom.iCol=aRange.iTo.iCol;
       
    99 		aRange.iTo.iCol=temp;
       
   100 		}
       
   101 	if (aRange.iFrom.iRow>aRange.iTo.iRow)
       
   102 		{
       
   103 		TInt temp=aRange.iFrom.iRow;
       
   104 		aRange.iFrom.iRow=aRange.iTo.iRow;
       
   105 		aRange.iTo.iRow=temp;
       
   106 		}
       
   107 	}	
       
   108 
       
   109 EXPORT_C void CGridCellRegion::AddCellRangeL(const TRangeRef& aCellRange)
       
   110 /** Adds the specified range to the region.
       
   111 
       
   112 @param aCellRange The new range. This must lie on or within the region boundary, 
       
   113 otherwise it is not added to the region. */
       
   114 	{
       
   115 	TRangeRef range=aCellRange;
       
   116 	NormalizeRange(range);
       
   117 	if (range.iTo.iRow<iBounds.iFrom.iRow || range.iFrom.iRow>iBounds.iTo.iRow
       
   118 		|| range.iTo.iCol<iBounds.iFrom.iCol || range.iFrom.iCol>iBounds.iTo.iCol)
       
   119 		{
       
   120 		return;
       
   121 		}
       
   122 	iRangeList->AppendL(range);
       
   123 	}
       
   124 
       
   125 EXPORT_C void CGridCellRegion::SetLastCellRange(const TRangeRef& aCellRange)
       
   126 /** Replaces the last range in the region with the specified range.
       
   127 
       
   128 Note that a region is implemented as an array of ranges, and the last range 
       
   129 is the last one in the array.
       
   130 
       
   131 @param aCellRange The range to replace the last range in the region. Note 
       
   132 that it is the caller's responsibility to ensure that this region lies within 
       
   133 the region boundary, as no checks are made by the function.
       
   134 @panic GRIDIMG 1 If the region is empty. */
       
   135 	{
       
   136 	__ASSERT_DEBUG(iRangeList->Count()>0,Panic(ECellRegionNothingSelected));
       
   137 	TRangeRef range=aCellRange;
       
   138 	NormalizeRange(range);
       
   139 	(*iRangeList)[iRangeList->Count()-1]=range;
       
   140 	}
       
   141 
       
   142 EXPORT_C void CGridCellRegion::ResizeBounds(const TCellRef& aNewToBounds)
       
   143 /** Defines a new region boundary by replacing the end cell with the specified 
       
   144 cell.
       
   145 
       
   146 Any existing ranges that are now wholly outside the new region boundary are 
       
   147 deleted.
       
   148 
       
   149 Any existing ranges whose boundaries were the same as the old region boundary, 
       
   150 are stretched or shrunk so that their boundaries are now on the new region 
       
   151 boundary.
       
   152 
       
   153 Any existing ranges that now intersect the new region boundary are truncated 
       
   154 back to the new region boundary.
       
   155 
       
   156 Any existing ranges that remain wholly within the new region boundary remain 
       
   157 unchanged.
       
   158 
       
   159 @param aNewToBounds The new end cell for the region boundary. */
       
   160 	{
       
   161 	TRangeRef newBounds(iBounds.iFrom,aNewToBounds);
       
   162 	TInt end=iRangeList->Count();
       
   163 	for (TInt ii=0;ii<end;ii++)
       
   164 		{
       
   165 		TRangeRef& range=(*iRangeList)[ii];
       
   166 		if (range.iFrom.iRow>newBounds.iTo.iRow || range.iFrom.iCol>newBounds.iTo.iCol)
       
   167 			{
       
   168 			iRangeList->Delete(ii--);
       
   169 			end--;
       
   170 			continue;
       
   171 			}
       
   172 		if (IsColSelected(range.iFrom.iCol,ii))
       
   173 			range.iTo.iRow=newBounds.iTo.iRow;
       
   174 		else
       
   175 			range.iTo.iRow = Min(range.iTo.iRow,newBounds.iTo.iRow);
       
   176 		if (IsRowSelected(range.iFrom.iRow,ii))
       
   177 			range.iTo.iCol=newBounds.iTo.iCol;
       
   178 		else
       
   179 			range.iTo.iCol = Min(range.iTo.iCol,newBounds.iTo.iCol);
       
   180 		}
       
   181 	iBounds=newBounds;
       
   182 	}
       
   183 
       
   184 EXPORT_C void CGridCellRegion::Reset()
       
   185 /** Deletes all ranges from the region. */
       
   186 	{
       
   187 	iRangeList->Reset();
       
   188 	}
       
   189 
       
   190 EXPORT_C TInt CGridCellRegion::Count() const
       
   191 /** Gets the number of ranges in the region.
       
   192 
       
   193 @return The number of ranges in the region. */
       
   194 	{
       
   195 	return(iRangeList->CArrayFixBase::Count());
       
   196 	}
       
   197 
       
   198 EXPORT_C TBool CGridCellRegion::IsCellSelected(const TCellRef &aCell) const
       
   199 /** Tests whether the specified cell is selected.
       
   200 
       
   201 A cell is selected if it is in the region.
       
   202 
       
   203 @param aCell The cell to be tested.
       
   204 @return True, if the cell is selected; false, otherwise. Note that this is 
       
   205 also false if the region is empty. */
       
   206 	{
       
   207 	TInt end=iRangeList->Count();
       
   208 	for (TInt ii=0;ii<end;ii++)
       
   209 		{
       
   210 		if (IsCellSelected(aCell,ii))
       
   211 			return ETrue;
       
   212 		}
       
   213 	return EFalse;
       
   214 	}
       
   215 
       
   216 EXPORT_C TBool CGridCellRegion::IsCellSelected(const TCellRef &aCell,TInt aIndex) const
       
   217 /** Tests whether the specified cell is selected in the range identified by the 
       
   218 specified index.
       
   219 
       
   220 A cell is selected if it lies in the range.
       
   221 
       
   222 Note that a region is implemented as an array of ranges, and the index identifies 
       
   223 a specific range within that array.
       
   224 
       
   225 @param aCell The cell to be tested.
       
   226 @param aIndex An index value identifying a specific range within the region.
       
   227 @return True, if the specified cell is in the range identified by the index; 
       
   228 false, otherwise.
       
   229 @panic GRIDIMG 2 In debug mode only, if the index value is illegal. */
       
   230 	{
       
   231 	__ASSERT_DEBUG(aIndex>=0&&aIndex<iRangeList->Count(),Panic(ECellRegionInvalidIndex));
       
   232 	TRangeRef temp=(*iRangeList)[aIndex];
       
   233 	return (TBool)(temp.iFrom.iRow<=aCell.iRow && temp.iTo.iRow>=aCell.iRow &&
       
   234 		temp.iFrom.iCol<=aCell.iCol && temp.iTo.iCol>=aCell.iCol);
       
   235 	}
       
   236 
       
   237 EXPORT_C TBool CGridCellRegion::IsCellSelectedLastIndex(const TCellRef &aCell) const
       
   238 /** Tests whether the specified cell is selected in the last range of the region.
       
   239 
       
   240 A cell is selected if it lies in the range.
       
   241 
       
   242 Note that a region is implemented as an array of ranges, and the last range 
       
   243 is the last one in the array.
       
   244 
       
   245 @param aCell The cell to be tested.
       
   246 @return True, if the specified cell is in the last range of the region; false, 
       
   247 otherwise. Note that this is also false if the region is empty. */
       
   248 	{
       
   249 	TInt index=iRangeList->Count();
       
   250 	return (index) ? IsCellSelected(aCell,index-1) : EFalse;
       
   251 	}
       
   252 
       
   253 EXPORT_C TBool CGridCellRegion::IsRowSelected(TInt aRow) const
       
   254 /** Tests whether the specified row is selected.
       
   255 
       
   256 A row is selected if the row lies within one of the region's ranges, and the 
       
   257 range spans all of the columns defined by the region boundary (i.e. extends 
       
   258 from one side of the region boundary to the other).
       
   259 
       
   260 @param aRow The row to be tested.
       
   261 @return True, if the row is selected; false otherwise. */
       
   262 	{
       
   263 	TInt end=iRangeList->Count();
       
   264 	for (TInt ii=0;ii<end;ii++)
       
   265 		{
       
   266 		if (IsRowSelected(aRow,ii))
       
   267 			return ETrue;
       
   268 		}
       
   269 	return EFalse;
       
   270 	}
       
   271 
       
   272 EXPORT_C TBool CGridCellRegion::IsRowSelected(TInt aRow,TInt aIndex) const
       
   273 /** Tests whether the specified row is selected in the range identified by the 
       
   274 specified index.
       
   275 
       
   276 A row is selected in a range only if it lies in the range, and the range spans 
       
   277 all of the columns defined by region boundary (i.e. extends from one side 
       
   278 of the region boundary to the other).
       
   279 
       
   280 Note that a region is implemented as an array of ranges, and the index identifies 
       
   281 a specific range within that array.
       
   282 
       
   283 @param aRow The row to be tested.
       
   284 @param aIndex An index value identifying a specific range within the region.
       
   285 @return True, if the row is selected; false otherwise.
       
   286 @panic GRIDIMG 2 In debug mode only, if the index value is illegal. */
       
   287 	{
       
   288 	__ASSERT_DEBUG(aIndex>=0&&aIndex<iRangeList->Count(),Panic(ECellRegionInvalidIndex));
       
   289 	TRangeRef range=(*iRangeList)[aIndex];
       
   290 	return (TBool)(range.iFrom.iRow<=aRow && range.iTo.iRow>=aRow
       
   291 		&& range.iFrom.iCol==iBounds.iFrom.iCol && range.iTo.iCol==iBounds.iTo.iCol);
       
   292 	}
       
   293 
       
   294 EXPORT_C TBool CGridCellRegion::IsRowSelectedLastIndex(TInt aRow) const
       
   295 /** Tests whether the specified row is selected in the last range in the region.
       
   296 
       
   297 A row is selected in a range only if it lies in the range, and the range spans 
       
   298 all of the columns defined by region boundary (i.e. extends from one side 
       
   299 of the region boundary to the other).
       
   300 
       
   301 Note that a region is implemented as an array of ranges, and the last range 
       
   302 is the last one in the array.
       
   303 
       
   304 @param aRow The row to be tested.
       
   305 @return True, if the row is selected; false otherwise. Note that this is also 
       
   306 false if the region is empty. */
       
   307 	{
       
   308 	TInt index=iRangeList->Count();
       
   309 	return (index) ? IsRowSelected(aRow,index-1) : EFalse;
       
   310 	}
       
   311 
       
   312 EXPORT_C TBool CGridCellRegion::IsAnyRowSelected() const
       
   313 /** Tests whether any row is selected.
       
   314 
       
   315 A row is selected if any range spans all of the columns defined by region 
       
   316 boundary (i.e. extends from one side of the region boundary to the other).
       
   317 
       
   318 @return True, if any row is selected; false, otherwise. */
       
   319 	{
       
   320 	TInt end=iRangeList->Count();
       
   321 	for (TInt ii=0;ii<end;ii++)
       
   322 		{
       
   323 		TRangeRef range=(*iRangeList)[ii];
       
   324 		if (range.iFrom.iCol==iBounds.iFrom.iCol && range.iTo.iCol==iBounds.iTo.iCol)
       
   325 			return ETrue;
       
   326 		}
       
   327 	return EFalse;
       
   328 	}
       
   329 
       
   330 EXPORT_C TBool CGridCellRegion::IsColSelected(TInt aCol) const
       
   331 /** Tests whether the specified column is selected.
       
   332 
       
   333 A column is selected if the column lies within one of the region's ranges, 
       
   334 and the range spans all of the rows defined by the region boundary (i.e. extends 
       
   335 from the top of the region boundary to the bottom).
       
   336 
       
   337 @param aCol The column to be tested.
       
   338 @return True, if the column is selected; false, otherwise. */
       
   339 	{
       
   340 	TInt end=iRangeList->Count();
       
   341 	for (TInt ii=0;ii<end;ii++)
       
   342 		{
       
   343 		if (IsColSelected(aCol,ii))
       
   344 			return ETrue;
       
   345 		}
       
   346 	return EFalse;
       
   347 	}
       
   348 
       
   349 EXPORT_C TBool CGridCellRegion::IsColSelected(TInt aCol,TInt aIndex) const
       
   350 /** Tests whether the specified column is selected in the range identified by the 
       
   351 specified index.
       
   352 
       
   353 A column is selected in a range only if it lies in the range, and the range 
       
   354 spans all of the rows defined by the region boundary (i.e. extends from the 
       
   355 top of the region boundary to the bottom).
       
   356 
       
   357 Note that a region is implemented as an array of ranges, and the index identifies 
       
   358 a specific range within that array.
       
   359 
       
   360 @param aCol The column to be tested.
       
   361 @param aIndex An index value identifying a specific range within the region.
       
   362 @return True, if the column is selected; false, otherwise.
       
   363 @panic GRIDIMG 2 In debug mode only, if the index value is illegal. */
       
   364 	{
       
   365 	__ASSERT_DEBUG(aIndex>=0&&aIndex<iRangeList->Count(),Panic(ECellRegionInvalidIndex));
       
   366 	TRangeRef range=(*iRangeList)[aIndex];
       
   367 	return (TBool)(range.iFrom.iCol<=aCol && range.iTo.iCol>=aCol
       
   368 		&& range.iFrom.iRow==iBounds.iFrom.iRow && range.iTo.iRow==iBounds.iTo.iRow);
       
   369 	}
       
   370 
       
   371 EXPORT_C TBool CGridCellRegion::IsColSelectedLastIndex(TInt aCol) const
       
   372 /** Tests whether the specified column is selected in the last range in the region.
       
   373 
       
   374 A column is selected in a range only if it lies in the range, and the range 
       
   375 spans all of the rows defined by the region boundary (i.e. extends from the 
       
   376 top of the region boundary to the bottom).
       
   377 
       
   378 Note that a region is implemented as an array of ranges, and the last range 
       
   379 is the last one in the array.
       
   380 
       
   381 @param aCol The column to be tested.
       
   382 @return True, if the column is selected; false otherwise. Note that this is 
       
   383 also false if the region is empty. */
       
   384 	{
       
   385 	TInt index=iRangeList->Count();
       
   386 	return (index) ? IsColSelected(aCol,index-1) : EFalse;
       
   387 	}
       
   388 
       
   389 
       
   390 EXPORT_C TBool CGridCellRegion::IsAnyColSelected() const
       
   391 /** Tests whether any column is selected.
       
   392 
       
   393 A column is selected if any range spans all of the rows defined by region 
       
   394 boundary (i.e. extends from the top of the region boundary to the bottom).
       
   395 
       
   396 @return True, if any column is selected; false, otherwise. */
       
   397 	{
       
   398 	TInt end=iRangeList->Count();
       
   399 	for (TInt ii=0;ii<end;ii++)
       
   400 		{
       
   401 		TRangeRef range=(*iRangeList)[ii];
       
   402 		if (range.iFrom.iRow==iBounds.iFrom.iRow && range.iTo.iRow==iBounds.iTo.iRow)
       
   403 			return ETrue;
       
   404 		}
       
   405 	return EFalse;
       
   406 	}
       
   407 
       
   408 EXPORT_C TBool CGridCellRegion::IsRangeSelected(const TRangeRef &aRange) const
       
   409 /** Tests whether the specified range is selected.
       
   410 
       
   411 A range is selected if it is one of the ranges making up the region.
       
   412 
       
   413 @param aRange The range to be tested.
       
   414 @return True, if the range is one of the ranges making up the region; false, 
       
   415 otherwise. */
       
   416 	{
       
   417 	TInt end=iRangeList->Count();
       
   418 	for (TInt ii=0;ii<end;ii++)
       
   419 		{
       
   420 		if (IsRangeSelected(aRange,ii))
       
   421 			return ETrue;
       
   422 		}
       
   423 	return EFalse;
       
   424 	}
       
   425 
       
   426 EXPORT_C TBool CGridCellRegion::IsRangeSelected(const TRangeRef &aRange,TInt aIndex) const
       
   427 /** Tests whether the specified range is the same as the range identified by the 
       
   428 specified index.
       
   429 
       
   430 Note that a region is implemented as an array of ranges, and the index identifies 
       
   431 a specific range within that array.
       
   432 
       
   433 @param aRange The range to be tested.
       
   434 @param aIndex An index value identifying a specific range within the region.
       
   435 @return True, if the specified range is the same as the range identified by 
       
   436 the index; false, otherwise.
       
   437 @panic GRIDIMG 2 In debug mode only, if the index value is illegal. */
       
   438 	{
       
   439 	__ASSERT_DEBUG(aIndex>=0&&aIndex<iRangeList->Count(),Panic(ECellRegionInvalidIndex));
       
   440 	return (TBool)((*iRangeList)[aIndex]==aRange);
       
   441 	}
       
   442 
       
   443 EXPORT_C TBool CGridCellRegion::IsRangeSelectedLastIndex(const TRangeRef &aRange) const
       
   444 /** Tests whether the specified range is the same as the last range in the region.
       
   445 
       
   446 Note that a region is implemented as an array of ranges, and the last range 
       
   447 is the last one in the array.
       
   448 
       
   449 @param aRange The range to be tested.
       
   450 @return True, if the specified range is the same as the last range in the region; 
       
   451 false, otherwise. Note that this is also false if the region is empty. */
       
   452 	{
       
   453 	TInt index=iRangeList->Count();
       
   454 	return (index) ? IsRangeSelected(aRange,index-1) : EFalse;
       
   455 	}
       
   456 
       
   457 EXPORT_C TRangeRef CGridCellRegion::operator[](TInt aIndex) const
       
   458 /** Gets the range within the region that is identified by the specified index.
       
   459 
       
   460 Note that a region is implemented as an array of ranges.
       
   461 
       
   462 @param aIndex The index value.
       
   463 @return The cell range. */
       
   464 	{
       
   465 	return (*iRangeList)[aIndex];
       
   466 	}
       
   467 
       
   468 EXPORT_C const CArrayFix<TRangeRef>* CGridCellRegion::RangeList() const
       
   469 /** Gets a pointer to the internal array of ranges that constitutes the region.
       
   470 
       
   471 @return A pointer to the array of ranges that constitutes the region. */
       
   472 	{
       
   473 	return iRangeList;
       
   474 	}