xref: /haiku/src/kits/tracker/ViewState.cpp (revision 97f11716bfaa0f385eb0e28a52bf56a5023b9e99)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 
36 #include <Debug.h>
37 #include <AppDefs.h>
38 #include <InterfaceDefs.h>
39 
40 #include "Attributes.h"
41 #include "Commands.h"
42 #include "PoseView.h"
43 #include "Utilities.h"
44 #include "ViewState.h"
45 
46 #include <new>
47 #include <string.h>
48 #include <stdlib.h>
49 
50 
51 const char* kColumnVersionName = "BColumn:version";
52 const char* kColumnTitleName = "BColumn:fTitle";
53 const char* kColumnOffsetName = "BColumn:fOffset";
54 const char* kColumnWidthName = "BColumn:fWidth";
55 const char* kColumnAlignmentName = "BColumn:fAlignment";
56 const char* kColumnAttrName = "BColumn:fAttrName";
57 const char* kColumnAttrHashName = "BColumn:fAttrHash";
58 const char* kColumnAttrTypeName = "BColumn:fAttrType";
59 const char* kColumnDisplayAsName = "BColumn:fDisplayAs";
60 const char* kColumnStatFieldName = "BColumn:fStatField";
61 const char* kColumnEditableName = "BColumn:fEditable";
62 
63 const char* kViewStateVersionName = "ViewState:version";
64 const char* kViewStateViewModeName = "ViewState:fViewMode";
65 const char* kViewStateLastIconModeName = "ViewState:fLastIconMode";
66 const char* kViewStateListOriginName = "ViewState:fListOrigin";
67 const char* kViewStateIconOriginName = "ViewState:fIconOrigin";
68 const char* kViewStatePrimarySortAttrName = "ViewState:fPrimarySortAttr";
69 const char* kViewStatePrimarySortTypeName = "ViewState:fPrimarySortType";
70 const char* kViewStateSecondarySortAttrName = "ViewState:fSecondarySortAttr";
71 const char* kViewStateSecondarySortTypeName = "ViewState:fSecondarySortType";
72 const char* kViewStateReverseSortName = "ViewState:fReverseSort";
73 const char* kViewStateIconSizeName = "ViewState:fIconSize";
74 const char* kViewStateLastIconSizeName = "ViewState:fLastIconSize";
75 
76 
77 static const int32 kColumnStateMinArchiveVersion = 21;
78 	// bump version when layout changes
79 
80 
81 //	#pragma mark - BColumn
82 
83 
BColumn(const char * title,float width,alignment align,const char * attributeName,uint32 attrType,const char * displayAs,bool statField,bool editable)84 BColumn::BColumn(const char* title, float width,
85 	alignment align, const char* attributeName, uint32 attrType,
86 	const char* displayAs, bool statField, bool editable)
87 {
88 	_Init(title, width, align, attributeName, attrType, displayAs,
89 		statField, editable);
90 }
91 
92 
BColumn(const char * title,float width,alignment align,const char * attributeName,uint32 attrType,bool statField,bool editable)93 BColumn::BColumn(const char* title, float width,
94 	alignment align, const char* attributeName, uint32 attrType,
95 	bool statField, bool editable)
96 {
97 	_Init(title, width, align, attributeName, attrType, NULL,
98 		statField, editable);
99 }
100 
101 
~BColumn()102 BColumn::~BColumn()
103 {
104 }
105 
106 
BColumn(BMallocIO * stream,int32 version,bool endianSwap)107 BColumn::BColumn(BMallocIO* stream, int32 version, bool endianSwap)
108 {
109 	StringFromStream(&fTitle, stream, endianSwap);
110 	stream->Read(&fOffset, sizeof(float));
111 	stream->Read(&fWidth, sizeof(float));
112 	stream->Read(&fAlignment, sizeof(alignment));
113 	StringFromStream(&fAttrName, stream, endianSwap);
114 	stream->Read(&fAttrHash, sizeof(uint32));
115 	stream->Read(&fAttrType, sizeof(uint32));
116 	stream->Read(&fStatField, sizeof(bool));
117 	stream->Read(&fEditable, sizeof(bool));
118 	if (version == kColumnStateArchiveVersion)
119 		StringFromStream(&fDisplayAs, stream, endianSwap);
120 
121 	if (endianSwap) {
122 		PRINT(("endian swapping column\n"));
123 		fOffset = B_SWAP_FLOAT(fOffset);
124 		fWidth = B_SWAP_FLOAT(fWidth);
125 		STATIC_ASSERT(sizeof(alignment) == sizeof(int32));
126 		fAlignment = (alignment)B_SWAP_INT32(fAlignment);
127 		fAttrHash = B_SWAP_INT32(fAttrHash);
128 		fAttrType = B_SWAP_INT32(fAttrType);
129 	}
130 
131 	fOffset = ceilf(fOffset * _Scale());
132 	fWidth = ceilf(fWidth * _Scale());
133 }
134 
135 
BColumn(const BMessage & message,int32 index)136 BColumn::BColumn(const BMessage &message, int32 index)
137 {
138 	if (message.FindString(kColumnTitleName, index, &fTitle) != B_OK)
139 		fTitle.SetTo(B_EMPTY_STRING);
140 
141 	if (message.FindFloat(kColumnOffsetName, index, &fOffset) != B_OK)
142 		fOffset = -1.0f;
143 	else
144 		fOffset = ceilf(fOffset * _Scale());
145 
146 	if (message.FindFloat(kColumnWidthName, index, &fWidth) != B_OK)
147 		fWidth = -1.0f;
148 	else
149 		fWidth = ceilf(fWidth * _Scale());
150 
151 	if (message.FindInt32(kColumnAlignmentName, index, (int32*)&fAlignment)
152 			!= B_OK) {
153 		fAlignment = B_ALIGN_LEFT;
154 	}
155 
156 	if (message.FindString(kColumnAttrName, index, &fAttrName) != B_OK)
157 		fAttrName = BString(B_EMPTY_STRING);
158 
159 	if (message.FindInt32(kColumnAttrHashName, index, (int32*)&fAttrHash)
160 			!= B_OK) {
161 		fAttrHash = 0;
162 	}
163 
164 	if (message.FindInt32(kColumnAttrTypeName, index, (int32*)&fAttrType)
165 			!= B_OK) {
166 		fAttrType = 0;
167 	}
168 
169 	if (message.FindString(kColumnDisplayAsName, index, &fDisplayAs) != B_OK)
170 		fDisplayAs.SetTo(B_EMPTY_STRING);
171 
172 	if (message.FindBool(kColumnStatFieldName, index, &fStatField) != B_OK)
173 		fStatField = false;
174 
175 	if (message.FindBool(kColumnEditableName, index, &fEditable) != B_OK)
176 		fEditable = false;
177 }
178 
179 
180 void
_Init(const char * title,float width,alignment align,const char * attributeName,uint32 attrType,const char * displayAs,bool statField,bool editable)181 BColumn::_Init(const char* title, float width,
182 	alignment align, const char* attributeName, uint32 attrType,
183 	const char* displayAs, bool statField, bool editable)
184 {
185 	fTitle = title;
186 	fAttrName = attributeName;
187 	fDisplayAs = displayAs;
188 	fOffset = -1.0f;
189 	fWidth = width * _Scale();
190 	fAlignment = align;
191 	fAttrHash = AttrHashString(attributeName, attrType);
192 	fAttrType = attrType;
193 	fStatField = statField;
194 	fEditable = editable;
195 }
196 
197 
198 /* static */ float
_Scale()199 BColumn::_Scale()
200 {
201 	return (be_plain_font->Size() / 12.0f);
202 }
203 
204 
205 BColumn*
InstantiateFromStream(BMallocIO * stream,bool endianSwap)206 BColumn::InstantiateFromStream(BMallocIO* stream, bool endianSwap)
207 {
208 	// compare stream header in canonical form
209 
210 	// we can't use ValidateStream(), as we preserve backwards compatibility
211 	int32 version;
212 	uint32 key;
213 	if (stream->Read(&key, sizeof(uint32)) <= 0
214 		|| stream->Read(&version, sizeof(int32)) <=0)
215 		return 0;
216 
217 	if (endianSwap) {
218 		key = SwapUInt32(key);
219 		version = SwapInt32(version);
220 	}
221 
222 	if (key != AttrHashString("BColumn", B_OBJECT_TYPE)
223 		|| version < kColumnStateMinArchiveVersion)
224 		return 0;
225 
226 //	PRINT(("instantiating column, %s\n", endianSwap ? "endian swapping," : ""));
227 	return _Sanitize(new (std::nothrow) BColumn(stream, version, endianSwap));
228 }
229 
230 
231 BColumn*
InstantiateFromMessage(const BMessage & message,int32 index)232 BColumn::InstantiateFromMessage(const BMessage &message, int32 index)
233 {
234 	int32 version = kColumnStateArchiveVersion;
235 	int32 messageVersion;
236 
237 	if (message.FindInt32(kColumnVersionName, index, &messageVersion) != B_OK)
238 		return NULL;
239 
240 	if (version != messageVersion)
241 		return NULL;
242 
243 	return _Sanitize(new (std::nothrow) BColumn(message, index));
244 }
245 
246 
247 void
ArchiveToStream(BMallocIO * stream) const248 BColumn::ArchiveToStream(BMallocIO* stream) const
249 {
250 	// write class identifier and version info
251 	uint32 key = AttrHashString("BColumn", B_OBJECT_TYPE);
252 	stream->Write(&key, sizeof(uint32));
253 	int32 version = kColumnStateArchiveVersion;
254 	stream->Write(&version, sizeof(int32));
255 
256 //	PRINT(("ArchiveToStream column, key %x, version %d\n", key, version));
257 
258 	const float offset = floorf(fOffset / _Scale()),
259 		width = floorf(fWidth / _Scale());
260 
261 	StringToStream(&fTitle, stream);
262 	stream->Write(&offset, sizeof(float));
263 	stream->Write(&width, sizeof(float));
264 	stream->Write(&fAlignment, sizeof(alignment));
265 	StringToStream(&fAttrName, stream);
266 	stream->Write(&fAttrHash, sizeof(uint32));
267 	stream->Write(&fAttrType, sizeof(uint32));
268 	stream->Write(&fStatField, sizeof(bool));
269 	stream->Write(&fEditable, sizeof(bool));
270 	StringToStream(&fDisplayAs, stream);
271 }
272 
273 
274 void
ArchiveToMessage(BMessage & message) const275 BColumn::ArchiveToMessage(BMessage &message) const
276 {
277 	const float offset = floorf(fOffset / _Scale()),
278 		width = floorf(fWidth / _Scale());
279 
280 	message.AddInt32(kColumnVersionName, kColumnStateArchiveVersion);
281 
282 	message.AddString(kColumnTitleName, fTitle);
283 	message.AddFloat(kColumnOffsetName, offset);
284 	message.AddFloat(kColumnWidthName, width);
285 	message.AddInt32(kColumnAlignmentName, fAlignment);
286 	message.AddString(kColumnAttrName, fAttrName);
287 	message.AddInt32(kColumnAttrHashName, static_cast<int32>(fAttrHash));
288 	message.AddInt32(kColumnAttrTypeName, static_cast<int32>(fAttrType));
289 	message.AddString(kColumnDisplayAsName, fDisplayAs.String());
290 	message.AddBool(kColumnStatFieldName, fStatField);
291 	message.AddBool(kColumnEditableName, fEditable);
292 }
293 
294 
295 BColumn*
_Sanitize(BColumn * column)296 BColumn::_Sanitize(BColumn* column)
297 {
298 	if (column == NULL)
299 		return NULL;
300 
301 	// sanity-check the resulting column
302 	if (column->fTitle.Length() > 500
303 		|| column->fOffset < 0
304 		|| column->fOffset > 10000
305 		|| column->fWidth < 0
306 		|| column->fWidth > 10000
307 		|| (int32)column->fAlignment < B_ALIGN_LEFT
308 		|| (int32)column->fAlignment > B_ALIGN_CENTER
309 		|| column->fAttrName.Length() > 500) {
310 		PRINT(("column data not valid\n"));
311 		delete column;
312 		return NULL;
313 	}
314 #if DEBUG
315 // TODO: Whatever this is supposed to mean, fix it.
316 //	else if (endianSwap)
317 //		PRINT(("Instantiated foreign column ok\n"));
318 #endif
319 
320 	return column;
321 }
322 
323 
324 //	#pragma mark - BViewState
325 
326 
BViewState()327 BViewState::BViewState()
328 {
329 	_Init();
330 	_StorePreviousState();
331 }
332 
333 
BViewState(BMallocIO * stream,bool endianSwap)334 BViewState::BViewState(BMallocIO* stream, bool endianSwap)
335 {
336 	_Init();
337 	stream->Read(&fViewMode, sizeof(uint32));
338 	stream->Read(&fLastIconMode, sizeof(uint32));
339 	stream->Read(&fListOrigin, sizeof(BPoint));
340 	stream->Read(&fIconOrigin, sizeof(BPoint));
341 	stream->Read(&fPrimarySortAttr, sizeof(uint32));
342 	stream->Read(&fPrimarySortType, sizeof(uint32));
343 	stream->Read(&fSecondarySortAttr, sizeof(uint32));
344 	stream->Read(&fSecondarySortType, sizeof(uint32));
345 	stream->Read(&fReverseSort, sizeof(bool));
346 	stream->Read(&fIconSize, sizeof(uint32));
347 	stream->Read(&fLastIconSize, sizeof(uint32));
348 
349 	if (endianSwap) {
350 		PRINT(("endian swapping view state\n"));
351 		fViewMode = B_SWAP_INT32(fViewMode);
352 		fLastIconMode = B_SWAP_INT32(fLastIconMode);
353 		fIconSize = B_SWAP_INT32(fIconSize);
354 		fLastIconSize = B_SWAP_INT32(fLastIconSize);
355 		swap_data(B_POINT_TYPE, &fListOrigin,
356 			sizeof(fListOrigin), B_SWAP_ALWAYS);
357 		swap_data(B_POINT_TYPE, &fIconOrigin,
358 			sizeof(fIconOrigin), B_SWAP_ALWAYS);
359 		fPrimarySortAttr = B_SWAP_INT32(fPrimarySortAttr);
360 		fSecondarySortAttr = B_SWAP_INT32(fSecondarySortAttr);
361 		fPrimarySortType = B_SWAP_INT32(fPrimarySortType);
362 		fSecondarySortType = B_SWAP_INT32(fSecondarySortType);
363 	}
364 
365 	_StorePreviousState();
366 	_Sanitize(this, true);
367 }
368 
369 
BViewState(const BMessage & message)370 BViewState::BViewState(const BMessage &message)
371 {
372 	_Init();
373 	message.FindInt32(kViewStateViewModeName, (int32*)&fViewMode);
374 	message.FindInt32(kViewStateLastIconModeName, (int32*)&fLastIconMode);
375 	message.FindInt32(kViewStateLastIconSizeName,(int32*)&fLastIconSize);
376 	message.FindInt32(kViewStateIconSizeName, (int32*)&fIconSize);
377 	message.FindPoint(kViewStateListOriginName, &fListOrigin);
378 	message.FindPoint(kViewStateIconOriginName, &fIconOrigin);
379 	message.FindInt32(kViewStatePrimarySortAttrName,
380 		(int32*)&fPrimarySortAttr);
381 	message.FindInt32(kViewStatePrimarySortTypeName,
382 		(int32*)&fPrimarySortType);
383 	message.FindInt32(kViewStateSecondarySortAttrName,
384 		(int32*)&fSecondarySortAttr);
385 	message.FindInt32(kViewStateSecondarySortTypeName,
386 		(int32*)&fSecondarySortType);
387 	message.FindBool(kViewStateReverseSortName, &fReverseSort);
388 
389 	_StorePreviousState();
390 	_Sanitize(this, true);
391 }
392 
393 
394 void
ArchiveToStream(BMallocIO * stream)395 BViewState::ArchiveToStream(BMallocIO* stream)
396 {
397 	_ArchiveToStream(stream);
398 	_StorePreviousState();
399 }
400 
401 
402 void
ArchiveToMessage(BMessage & message)403 BViewState::ArchiveToMessage(BMessage &message)
404 {
405 	_ArchiveToMessage(message);
406 	_StorePreviousState();
407 }
408 
409 
410 BViewState*
InstantiateFromStream(BMallocIO * stream,bool endianSwap)411 BViewState::InstantiateFromStream(BMallocIO* stream, bool endianSwap)
412 {
413 	// compare stream header in canonical form
414 	uint32 key = AttrHashString("BViewState", B_OBJECT_TYPE);
415 	int32 version = kViewStateArchiveVersion;
416 
417 	if (endianSwap) {
418 		key = SwapUInt32(key);
419 		version = SwapInt32(version);
420 	}
421 
422 	if (!ValidateStream(stream, key, version))
423 		return NULL;
424 
425 	return _Sanitize(new (std::nothrow) BViewState(stream, endianSwap));
426 }
427 
428 
429 BViewState*
InstantiateFromMessage(const BMessage & message)430 BViewState::InstantiateFromMessage(const BMessage &message)
431 {
432 	int32 version = kViewStateArchiveVersion;
433 
434 	int32 messageVersion;
435 	if (message.FindInt32(kViewStateVersionName, &messageVersion) != B_OK)
436 		return NULL;
437 
438 	if (version != messageVersion)
439 		return NULL;
440 
441 	return _Sanitize(new (std::nothrow) BViewState(message));
442 }
443 
444 
445 void
_Init()446 BViewState::_Init()
447 {
448 	fViewMode = kListMode;
449 	fLastIconMode = 0;
450 	fIconSize = B_LARGE_ICON;
451 	fLastIconSize = B_LARGE_ICON;
452 	fListOrigin.Set(0, 0);
453 	fIconOrigin.Set(0, 0);
454 	fPrimarySortAttr = AttrHashString(kAttrStatName, B_STRING_TYPE);
455 	fPrimarySortType = B_STRING_TYPE;
456 	fSecondarySortAttr = 0;
457 	fSecondarySortType = 0;
458 	fReverseSort = false;
459 }
460 
461 
462 void
_StorePreviousState()463 BViewState::_StorePreviousState()
464 {
465 	fPreviousViewMode = fViewMode;
466 	fPreviousLastIconMode = fLastIconMode;
467 	fPreviousIconSize = fIconSize;
468 	fPreviousLastIconSize = fLastIconSize;
469 	fPreviousListOrigin = fListOrigin;
470 	fPreviousIconOrigin = fIconOrigin;
471 	fPreviousPrimarySortAttr = fPrimarySortAttr;
472 	fPreviousSecondarySortAttr = fSecondarySortAttr;
473 	fPreviousPrimarySortType = fPrimarySortType;
474 	fPreviousSecondarySortType = fSecondarySortType;
475 	fPreviousReverseSort = fReverseSort;
476 }
477 
478 
479 BViewState*
_Sanitize(BViewState * state,bool fixOnly)480 BViewState::_Sanitize(BViewState* state, bool fixOnly)
481 {
482 	if (state == NULL)
483 		return NULL;
484 
485 	if (state->fViewMode == kListMode) {
486 		if (state->fListOrigin.x < 0)
487 			state->fListOrigin.x = 0;
488 
489 		if (state->fListOrigin.y < 0)
490 			state->fListOrigin.y = 0;
491 	}
492 	if (state->fIconSize < 16)
493 		state->fIconSize = 16;
494 
495 	if (state->fIconSize > 128)
496 		state->fIconSize = 128;
497 
498 	if (state->fLastIconSize < 16)
499 		state->fLastIconSize = 16;
500 
501 	if (state->fLastIconSize > 128)
502 		state->fLastIconSize = 128;
503 
504 	if (fixOnly)
505 		return state;
506 
507 	// do a sanity check here
508 	if ((state->fViewMode != kListMode
509 			&& state->fViewMode != kIconMode
510 			&& state->fViewMode != kMiniIconMode
511 			&& state->fViewMode != 0)
512 		|| (state->fLastIconMode != kListMode
513 			&& state->fLastIconMode != kIconMode
514 			&& state->fLastIconMode != kMiniIconMode
515 			&& state->fLastIconMode != 0)) {
516 		PRINT(("Bad data instantiating ViewState, view mode %" B_PRIx32
517 			", lastIconMode %" B_PRIx32 "\n", state->fViewMode,
518 			state->fLastIconMode));
519 
520 		delete state;
521 		return NULL;
522 	}
523 #if DEBUG
524 // TODO: Whatever this is supposed to mean, fix it.
525 //	else if (endianSwap)
526 //		PRINT(("Instantiated foreign view state ok\n"));
527 #endif
528 
529 	return state;
530 }
531 
532 
533 void
_ArchiveToStream(BMallocIO * stream) const534 BViewState::_ArchiveToStream(BMallocIO* stream) const
535 {
536 	// write class identifier and verison info
537 	uint32 key = AttrHashString("BViewState", B_OBJECT_TYPE);
538 	stream->Write(&key, sizeof(key));
539 	int32 version = kViewStateArchiveVersion;
540 	stream->Write(&version, sizeof(version));
541 
542 	stream->Write(&fViewMode, sizeof(uint32));
543 	stream->Write(&fLastIconMode, sizeof(uint32));
544 	stream->Write(&fListOrigin, sizeof(BPoint));
545 	stream->Write(&fIconOrigin, sizeof(BPoint));
546 	stream->Write(&fPrimarySortAttr, sizeof(uint32));
547 	stream->Write(&fPrimarySortType, sizeof(uint32));
548 	stream->Write(&fSecondarySortAttr, sizeof(uint32));
549 	stream->Write(&fSecondarySortType, sizeof(uint32));
550 	stream->Write(&fReverseSort, sizeof(bool));
551 	stream->Write(&fIconSize, sizeof(uint32));
552 	stream->Write(&fLastIconSize, sizeof(uint32));
553 }
554 
555 
556 void
_ArchiveToMessage(BMessage & message) const557 BViewState::_ArchiveToMessage(BMessage &message) const
558 {
559 	message.AddInt32(kViewStateVersionName, kViewStateArchiveVersion);
560 
561 	message.AddInt32(kViewStateViewModeName, static_cast<int32>(fViewMode));
562 	message.AddInt32(kViewStateLastIconModeName,
563 		static_cast<int32>(fLastIconMode));
564 	message.AddPoint(kViewStateListOriginName, fListOrigin);
565 	message.AddPoint(kViewStateIconOriginName, fIconOrigin);
566 	message.AddInt32(kViewStatePrimarySortAttrName,
567 		static_cast<int32>(fPrimarySortAttr));
568 	message.AddInt32(kViewStatePrimarySortTypeName,
569 		static_cast<int32>(fPrimarySortType));
570 	message.AddInt32(kViewStateSecondarySortAttrName,
571 		static_cast<int32>(fSecondarySortAttr));
572 	message.AddInt32(kViewStateSecondarySortTypeName,
573 		static_cast<int32>(fSecondarySortType));
574 	message.AddBool(kViewStateReverseSortName, fReverseSort);
575 	message.AddInt32(kViewStateIconSizeName, static_cast<int32>(fIconSize));
576 	message.AddInt32(kViewStateLastIconSizeName,
577 		static_cast<int32>(fLastIconSize));
578 }
579