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 #include <Debug.h> 36 #include <AppDefs.h> 37 #include <InterfaceDefs.h> 38 39 #include "Attributes.h" 40 #include "Commands.h" 41 #include "PoseView.h" 42 #include "Utilities.h" 43 #include "ViewState.h" 44 45 #include <new> 46 #include <string.h> 47 #include <stdlib.h> 48 49 50 const char *kColumnVersionName = "BColumn:version"; 51 const char *kColumnTitleName = "BColumn:fTitle"; 52 const char *kColumnOffsetName = "BColumn:fOffset"; 53 const char *kColumnWidthName = "BColumn:fWidth"; 54 const char *kColumnAlignmentName = "BColumn:fAlignment"; 55 const char *kColumnAttrName = "BColumn:fAttrName"; 56 const char *kColumnAttrHashName = "BColumn:fAttrHash"; 57 const char *kColumnAttrTypeName = "BColumn:fAttrType"; 58 const char *kColumnStatFieldName = "BColumn:fStatField"; 59 const char *kColumnEditableName = "BColumn:fEditable"; 60 61 const char *kViewStateVersionName = "ViewState:version"; 62 const char *kViewStateViewModeName = "ViewState:fViewMode"; 63 const char *kViewStateLastIconModeName = "ViewState:fLastIconMode"; 64 const char *kViewStateListOriginName = "ViewState:fListOrigin"; 65 const char *kViewStateIconOriginName = "ViewState:fIconOrigin"; 66 const char *kViewStatePrimarySortAttrName = "ViewState:fPrimarySortAttr"; 67 const char *kViewStatePrimarySortTypeName = "ViewState:fPrimarySortType"; 68 const char *kViewStateSecondarySortAttrName = "ViewState:fSecondarySortAttr"; 69 const char *kViewStateSecondarySortTypeName = "ViewState:fSecondarySortType"; 70 const char *kViewStateReverseSortName = "ViewState:fReverseSort"; 71 const char *kViewStateIconSizeName = "ViewState:fIconSize"; 72 73 74 BColumn::BColumn(const char *title, float offset, float width, alignment align, 75 const char *attributeName, uint32 attrType, bool statField, 76 bool editable) 77 : 78 fTitle(title), 79 fAttrName(attributeName) 80 { 81 fOffset = offset; 82 fWidth = width; 83 fAlignment = align; 84 fAttrHash = AttrHashString(attributeName, attrType); 85 fAttrType = attrType; 86 fStatField = statField; 87 fEditable = editable; 88 } 89 90 91 BColumn::~BColumn() 92 { 93 } 94 95 96 BColumn::BColumn(BMallocIO *stream, bool endianSwap) 97 { 98 StringFromStream(&fTitle, stream, endianSwap); 99 stream->Read(&fOffset, sizeof(float)); 100 stream->Read(&fWidth, sizeof(float)); 101 stream->Read(&fAlignment, sizeof(alignment)); 102 StringFromStream(&fAttrName, stream, endianSwap); 103 stream->Read(&fAttrHash, sizeof(uint32)); 104 stream->Read(&fAttrType, sizeof(uint32)); 105 stream->Read(&fStatField, sizeof(bool)); 106 stream->Read(&fEditable, sizeof(bool)); 107 108 if (endianSwap) { 109 PRINT(("endian swapping column\n")); 110 fOffset = B_SWAP_FLOAT(fOffset); 111 fWidth = B_SWAP_FLOAT(fWidth); 112 STATIC_ASSERT(sizeof(BColumn::fAlignment) == sizeof(int32)); 113 fAlignment = (alignment)B_SWAP_INT32(fAlignment); 114 fAttrHash = B_SWAP_INT32(fAttrHash); 115 fAttrType = B_SWAP_INT32(fAttrType); 116 } 117 } 118 119 120 BColumn::BColumn(const BMessage &message, int32 index) 121 { 122 message.FindString(kColumnTitleName, index, &fTitle); 123 message.FindFloat(kColumnOffsetName, index, &fOffset); 124 message.FindFloat(kColumnWidthName, index, &fWidth); 125 message.FindInt32(kColumnAlignmentName, index, (int32 *)&fAlignment); 126 message.FindString(kColumnAttrName, index, &fAttrName); 127 message.FindInt32(kColumnAttrHashName, index, (int32 *)&fAttrHash); 128 message.FindInt32(kColumnAttrTypeName, index, (int32 *)&fAttrType); 129 message.FindBool(kColumnStatFieldName, index, &fStatField); 130 message.FindBool(kColumnEditableName, index, &fEditable); 131 } 132 133 134 BColumn * 135 BColumn::InstantiateFromStream(BMallocIO *stream, bool endianSwap) 136 { 137 // compare stream header in canonical form 138 uint32 key = AttrHashString("BColumn", B_OBJECT_TYPE); 139 int32 version = kColumnStateArchiveVersion; 140 141 if (endianSwap) { 142 key = SwapUInt32(key); 143 version = SwapInt32(version); 144 } 145 146 // PRINT(("validating key %x, version %d\n", key, version)); 147 if (!ValidateStream(stream, key, version)) 148 return 0; 149 150 // PRINT(("instantiating column, %s\n", endianSwap ? "endian swapping," : "")); 151 return _Sanitize(new (std::nothrow) BColumn(stream, endianSwap)); 152 } 153 154 155 BColumn * 156 BColumn::InstantiateFromMessage(const BMessage &message, int32 index) 157 { 158 int32 version = kColumnStateArchiveVersion; 159 int32 messageVersion; 160 161 if (message.FindInt32(kColumnVersionName, index, &messageVersion) != B_OK) 162 return NULL; 163 164 if (version != messageVersion) 165 return NULL; 166 167 return _Sanitize(new (std::nothrow) BColumn(message, index)); 168 } 169 170 171 void 172 BColumn::ArchiveToStream(BMallocIO *stream) const 173 { 174 // write class identifier and version info 175 uint32 key = AttrHashString("BColumn", B_OBJECT_TYPE); 176 stream->Write(&key, sizeof(uint32)); 177 int32 version = kColumnStateArchiveVersion; 178 stream->Write(&version, sizeof(int32)); 179 180 // PRINT(("ArchiveToStream column, key %x, version %d\n", key, version)); 181 182 StringToStream(&fTitle, stream); 183 stream->Write(&fOffset, sizeof(float)); 184 stream->Write(&fWidth, sizeof(float)); 185 stream->Write(&fAlignment, sizeof(alignment)); 186 StringToStream(&fAttrName, stream); 187 stream->Write(&fAttrHash, sizeof(uint32)); 188 stream->Write(&fAttrType, sizeof(uint32)); 189 stream->Write(&fStatField, sizeof(bool)); 190 stream->Write(&fEditable, sizeof(bool)); 191 } 192 193 194 void 195 BColumn::ArchiveToMessage(BMessage &message) const 196 { 197 message.AddInt32(kColumnVersionName, kColumnStateArchiveVersion); 198 199 message.AddString(kColumnTitleName, fTitle); 200 message.AddFloat(kColumnOffsetName, fOffset); 201 message.AddFloat(kColumnWidthName, fWidth); 202 message.AddInt32(kColumnAlignmentName, fAlignment); 203 message.AddString(kColumnAttrName, fAttrName); 204 message.AddInt32(kColumnAttrHashName, static_cast<int32>(fAttrHash)); 205 message.AddInt32(kColumnAttrTypeName, static_cast<int32>(fAttrType)); 206 message.AddBool(kColumnStatFieldName, fStatField); 207 message.AddBool(kColumnEditableName, fEditable); 208 } 209 210 211 BColumn * 212 BColumn::_Sanitize(BColumn *column) 213 { 214 if (column == NULL) 215 return NULL; 216 217 // sanity-check the resulting column 218 if (column->fTitle.Length() > 500 219 || column->fOffset < 0 220 || column->fOffset > 10000 221 || column->fWidth < 0 222 || column->fWidth > 10000 223 || (int32)column->fAlignment < B_ALIGN_LEFT 224 || (int32)column->fAlignment > B_ALIGN_CENTER 225 || column->fAttrName.Length() > 500) { 226 PRINT(("column data not valid\n")); 227 delete column; 228 return NULL; 229 } 230 #if DEBUG 231 else if (endianSwap) 232 PRINT(("Instantiated foreign column ok\n")); 233 #endif 234 235 return column; 236 } 237 238 239 // #pragma mark - 240 241 242 BViewState::BViewState() 243 { 244 fViewMode = kListMode; 245 fLastIconMode = 0; 246 fIconSize = 32; 247 fListOrigin.Set(0, 0); 248 fIconOrigin.Set(0, 0); 249 fPrimarySortAttr = AttrHashString(kAttrStatName, B_STRING_TYPE); 250 fPrimarySortType = B_STRING_TYPE; 251 fSecondarySortAttr = 0; 252 fSecondarySortType = 0; 253 fReverseSort = false; 254 fStateNeedsSaving = false; 255 } 256 257 258 BViewState::BViewState(BMallocIO *stream, bool endianSwap) 259 { 260 stream->Read(&fViewMode, sizeof(uint32)); 261 stream->Read(&fLastIconMode, sizeof(uint32)); 262 stream->Read(&fListOrigin, sizeof(BPoint)); 263 stream->Read(&fIconOrigin, sizeof(BPoint)); 264 stream->Read(&fPrimarySortAttr, sizeof(uint32)); 265 stream->Read(&fPrimarySortType, sizeof(uint32)); 266 stream->Read(&fSecondarySortAttr, sizeof(uint32)); 267 stream->Read(&fSecondarySortType, sizeof(uint32)); 268 stream->Read(&fReverseSort, sizeof(bool)); 269 stream->Read(&fIconSize, sizeof(uint32)); 270 271 if (endianSwap) { 272 PRINT(("endian swapping view state\n")); 273 fViewMode = B_SWAP_INT32(fViewMode); 274 fLastIconMode = B_SWAP_INT32(fLastIconMode); 275 fIconSize = B_SWAP_INT32(fIconSize); 276 swap_data(B_POINT_TYPE, &fListOrigin, sizeof(fListOrigin), B_SWAP_ALWAYS); 277 swap_data(B_POINT_TYPE, &fIconOrigin, sizeof(fIconOrigin), B_SWAP_ALWAYS); 278 fPrimarySortAttr = B_SWAP_INT32(fPrimarySortAttr); 279 fSecondarySortAttr = B_SWAP_INT32(fSecondarySortAttr); 280 fPrimarySortType = B_SWAP_INT32(fPrimarySortType); 281 fSecondarySortType = B_SWAP_INT32(fSecondarySortType); 282 } 283 284 fStateNeedsSaving = false; 285 286 _Sanitize(this, true); 287 } 288 289 290 BViewState::BViewState(const BMessage &message) 291 { 292 message.FindInt32(kViewStateViewModeName, (int32 *)&fViewMode); 293 message.FindInt32(kViewStateLastIconModeName, (int32 *)&fLastIconMode); 294 message.FindPoint(kViewStateListOriginName, &fListOrigin); 295 message.FindPoint(kViewStateIconOriginName, &fIconOrigin); 296 message.FindInt32(kViewStatePrimarySortAttrName, (int32 *)&fPrimarySortAttr); 297 message.FindInt32(kViewStatePrimarySortTypeName, (int32 *)&fPrimarySortType); 298 message.FindInt32(kViewStateSecondarySortAttrName, (int32 *)&fSecondarySortAttr); 299 message.FindInt32(kViewStateSecondarySortTypeName, (int32 *)&fSecondarySortType); 300 message.FindBool(kViewStateReverseSortName, &fReverseSort); 301 fStateNeedsSaving = false; 302 303 _Sanitize(this, true); 304 } 305 306 307 void 308 BViewState::ArchiveToStream(BMallocIO *stream) const 309 { 310 // write class identifier and verison info 311 uint32 key = AttrHashString("BViewState", B_OBJECT_TYPE); 312 stream->Write(&key, sizeof(key)); 313 int32 version = kViewStateArchiveVersion; 314 stream->Write(&version, sizeof(version)); 315 316 stream->Write(&fViewMode, sizeof(uint32)); 317 stream->Write(&fLastIconMode, sizeof(uint32)); 318 stream->Write(&fListOrigin, sizeof(BPoint)); 319 stream->Write(&fIconOrigin, sizeof(BPoint)); 320 stream->Write(&fPrimarySortAttr, sizeof(uint32)); 321 stream->Write(&fPrimarySortType, sizeof(uint32)); 322 stream->Write(&fSecondarySortAttr, sizeof(uint32)); 323 stream->Write(&fSecondarySortType, sizeof(uint32)); 324 stream->Write(&fReverseSort, sizeof(bool)); 325 stream->Write(&fIconSize, sizeof(uint32)); 326 } 327 328 329 void 330 BViewState::ArchiveToMessage(BMessage &message) const 331 { 332 message.AddInt32(kViewStateVersionName, kViewStateArchiveVersion); 333 334 message.AddInt32(kViewStateViewModeName, static_cast<int32>(fViewMode)); 335 message.AddInt32(kViewStateLastIconModeName, static_cast<int32>(fLastIconMode)); 336 message.AddPoint(kViewStateListOriginName, fListOrigin); 337 message.AddPoint(kViewStateIconOriginName, fIconOrigin); 338 message.AddInt32(kViewStatePrimarySortAttrName, static_cast<int32>(fPrimarySortAttr)); 339 message.AddInt32(kViewStatePrimarySortTypeName, static_cast<int32>(fPrimarySortType)); 340 message.AddInt32(kViewStateSecondarySortAttrName, static_cast<int32>(fSecondarySortAttr)); 341 message.AddInt32(kViewStateSecondarySortTypeName, static_cast<int32>(fSecondarySortType)); 342 message.AddBool(kViewStateReverseSortName, fReverseSort); 343 message.AddInt32(kViewStateIconSizeName, static_cast<int32>(fIconSize)); 344 } 345 346 347 BViewState * 348 BViewState::InstantiateFromStream(BMallocIO *stream, bool endianSwap) 349 { 350 // compare stream header in canonical form 351 uint32 key = AttrHashString("BViewState", B_OBJECT_TYPE); 352 int32 version = kViewStateArchiveVersion; 353 354 if (endianSwap) { 355 key = SwapUInt32(key); 356 version = SwapInt32(version); 357 } 358 359 if (!ValidateStream(stream, key, version)) 360 return NULL; 361 362 return _Sanitize(new (std::nothrow) BViewState(stream, endianSwap)); 363 } 364 365 366 BViewState * 367 BViewState::InstantiateFromMessage(const BMessage &message) 368 { 369 int32 version = kViewStateArchiveVersion; 370 371 int32 messageVersion; 372 if (message.FindInt32(kViewStateVersionName, &messageVersion) != B_OK) 373 return NULL; 374 375 if (version != messageVersion) 376 return NULL; 377 378 return _Sanitize(new (std::nothrow) BViewState(message)); 379 } 380 381 382 BViewState * 383 BViewState::_Sanitize(BViewState *state, bool fixOnly) 384 { 385 if (state == NULL) 386 return NULL; 387 388 if (state->fViewMode == kListMode) { 389 if (state->fListOrigin.x < 0) 390 state->fListOrigin.x = 0; 391 if (state->fListOrigin.y < 0) 392 state->fListOrigin.y = 0; 393 } 394 if (state->fIconSize < 16) 395 state->fIconSize = 16; 396 if (state->fIconSize > 64) 397 state->fIconSize = 64; 398 399 if (fixOnly) 400 return state; 401 402 // do a sanity check here 403 if ((state->fViewMode != kListMode 404 && state->fViewMode != kIconMode 405 && state->fViewMode != kMiniIconMode 406 && state->fViewMode != kScaleIconMode 407 && state->fViewMode != 0) 408 || (state->fLastIconMode != kListMode 409 && state->fLastIconMode != kIconMode 410 && state->fLastIconMode != kMiniIconMode 411 && state->fLastIconMode != kScaleIconMode 412 && state->fLastIconMode != 0)) { 413 PRINT(("Bad data instantiating ViewState, view mode %x, lastIconMode %x\n", 414 state->fViewMode, state->fLastIconMode)); 415 416 delete state; 417 return NULL; 418 } 419 #if DEBUG 420 else if (endianSwap) 421 PRINT(("Instantiated foreign view state ok\n")); 422 #endif 423 424 return state; 425 } 426 427