1 /* 2 * Copyright 2002-2006, Haiku Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ingo Weinhold, bonefish@users.sf.net 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 11 #include <NodeInfo.h> 12 13 #include <new> 14 #include <string.h> 15 16 #include <MimeTypes.h> 17 #include <Bitmap.h> 18 #include <Entry.h> 19 #include <Node.h> 20 #include <Path.h> 21 #include <Rect.h> 22 23 #include <fs_attr.h> 24 #include <fs_info.h> 25 26 using namespace std; 27 28 // attribute names 29 #define NI_BEOS "BEOS" 30 static const char *kNITypeAttribute = NI_BEOS ":TYPE"; 31 static const char *kNIPreferredAppAttribute = NI_BEOS ":PREF_APP"; 32 static const char *kNIAppHintAttribute = NI_BEOS ":PPATH"; 33 static const char *kNIMiniIconAttribute = NI_BEOS ":M:STD_ICON"; 34 static const char *kNILargeIconAttribute = NI_BEOS ":L:STD_ICON"; 35 36 37 /*! \brief Creates an uninitialized BNodeInfo object. 38 39 After created a BNodeInfo with this, you should call SetTo(). 40 41 \see SetTo(BNode *node) 42 */ 43 BNodeInfo::BNodeInfo() 44 : 45 fNode(NULL), 46 fCStatus(B_NO_INIT) 47 { 48 } 49 50 // constructor 51 /*! \brief Creates a BNodeInfo object and initializes it to the supplied node. 52 53 \param node The node to gather information on. Can be any flavor. 54 55 \see SetTo(BNode *node) 56 */ 57 BNodeInfo::BNodeInfo(BNode *node) 58 : 59 fNode(NULL), 60 fCStatus(B_NO_INIT) 61 { 62 fCStatus = SetTo(node); 63 } 64 65 // destructor 66 /*! \brief Frees all resources associated with this object. 67 68 The BNode object passed to the constructor or to SetTo() is not deleted. 69 */ 70 BNodeInfo::~BNodeInfo() 71 { 72 } 73 74 // SetTo 75 /*! \brief Initializes the BNodeInfo to the supplied node. 76 77 The BNodeInfo object does not copy the supplied object, but uses it 78 directly. You must not delete the object you supply while the BNodeInfo 79 does exist. The BNodeInfo does not take over ownership of the BNode and 80 it doesn't delete it on destruction. 81 82 \param node The node to play with 83 84 \return 85 - \c B_OK: Everything went fine. 86 - \c B_BAD_VALUE: The node was bad. 87 */ 88 status_t 89 BNodeInfo::SetTo(BNode *node) 90 { 91 fNode = NULL; 92 // check parameter 93 fCStatus = (node && node->InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 94 if (fCStatus == B_OK) 95 fNode = node; 96 return fCStatus; 97 } 98 99 // InitCheck 100 /*! \brief returns whether the object has been properly initialized. 101 102 \return 103 - \c B_OK: Everything went fine. 104 - \c B_NO_INIT: The node is not properly initialized. 105 */ 106 status_t 107 BNodeInfo::InitCheck() const 108 { 109 return fCStatus; 110 } 111 112 // GetType 113 /*! \brief Gets the node's MIME type. 114 115 Writes the contents of the "BEOS:TYPE" attribute into the supplied buffer 116 \a type. 117 118 \param type A pointer to a pre-allocated character buffer of size 119 \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the 120 node shall be written. 121 \return 122 - \c B_OK: Everything went fine. 123 - \c B_NO_INIT: The object is not properly initialized. 124 - \c B_BAD_VALUE: \c NULL \a type or the type string stored in the 125 attribute is longer than \c B_MIME_TYPE_LENGTH. 126 - \c B_BAD_TYPE: The attribute the type string is stored in has the wrong 127 type. 128 - \c B_ENTRY_NOT_FOUND: No type is set on the node. 129 - other error codes 130 */ 131 status_t 132 BNodeInfo::GetType(char *type) const 133 { 134 // check parameter and initialization 135 status_t error = (type ? B_OK : B_BAD_VALUE); 136 if (error == B_OK && InitCheck() != B_OK) 137 error = B_NO_INIT; 138 // get the attribute info and check type and length of the attr contents 139 attr_info attrInfo; 140 if (error == B_OK) 141 error = fNode->GetAttrInfo(kNITypeAttribute, &attrInfo); 142 if (error == B_OK && attrInfo.type != B_MIME_STRING_TYPE) 143 error = B_BAD_TYPE; 144 if (error == B_OK && attrInfo.size > B_MIME_TYPE_LENGTH) 145 error = B_BAD_DATA; 146 147 // read the data 148 if (error == B_OK) { 149 ssize_t read = fNode->ReadAttr(kNITypeAttribute, attrInfo.type, 0, 150 type, attrInfo.size); 151 if (read < 0) 152 error = read; 153 else if (read != attrInfo.size) 154 error = B_ERROR; 155 156 if (error == B_OK) { 157 // attribute strings doesn't have to be null terminated 158 type[min_c(attrInfo.size, B_MIME_TYPE_LENGTH - 1)] = '\0'; 159 } 160 } 161 return error; 162 } 163 164 // SetType 165 /*! \brief Sets the node's MIME type. 166 167 The supplied string is written into the node's "BEOS:TYPE" attribute. 168 169 If \a type is \c NULL, the respective attribute is removed. 170 171 \param type The MIME type to be assigned to the node. Must not be longer 172 than \c B_MIME_TYPE_LENGTH (including the terminating null). 173 May be \c NULL. 174 \return 175 - \c B_OK: Everything went fine. 176 - \c B_NO_INIT: The object is not properly initialized. 177 - \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH. 178 - other error codes 179 */ 180 status_t 181 BNodeInfo::SetType(const char *type) 182 { 183 // check parameter and initialization 184 status_t error = B_OK; 185 if (error == B_OK && type && strlen(type) >= B_MIME_TYPE_LENGTH) 186 error = B_BAD_VALUE; 187 if (error == B_OK && InitCheck() != B_OK) 188 error = B_NO_INIT; 189 190 // write/remove the attribute 191 if (error == B_OK) { 192 if (type) { 193 size_t toWrite = strlen(type) + 1; 194 ssize_t written = fNode->WriteAttr(kNITypeAttribute, 195 B_MIME_STRING_TYPE, 0, type, 196 toWrite); 197 if (written < 0) 198 error = written; 199 else if (written != (ssize_t)toWrite) 200 error = B_ERROR; 201 } else 202 error = fNode->RemoveAttr(kNITypeAttribute); 203 } 204 return error; 205 } 206 207 // GetIcon 208 /*! \brief Gets the node's icon. 209 210 The icon stored in the node's "BEOS:L:STD_ICON" (large) or 211 "BEOS:M:STD_ICON" (mini) attribute is retrieved. 212 213 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 214 to store the requested icon (16x16 for the mini and 32x32 for the 215 large icon). 216 \param k Specifies the size of the icon to be retrieved: \c B_MINI_ICON 217 for the mini and \c B_LARGE_ICON for the large icon. 218 \return 219 - \c B_OK: Everything went fine. 220 - \c B_NO_INIT: The object is not properly initialized. 221 - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a k or bitmap 222 dimensions (\a icon) and icon size (\a k) do not match. 223 - other error codes 224 */ 225 status_t 226 BNodeInfo::GetIcon(BBitmap *icon, icon_size k) const 227 { 228 status_t error = B_OK; 229 // set some icon size related variables 230 const char *attribute = NULL; 231 BRect bounds; 232 uint32 attrType = 0; 233 size_t attrSize = 0; 234 switch (k) { 235 case B_MINI_ICON: 236 attribute = kNIMiniIconAttribute; 237 bounds.Set(0, 0, 15, 15); 238 attrType = B_MINI_ICON_TYPE; 239 attrSize = 16 * 16; 240 break; 241 case B_LARGE_ICON: 242 attribute = kNILargeIconAttribute; 243 bounds.Set(0, 0, 31, 31); 244 attrType = B_LARGE_ICON_TYPE; 245 attrSize = 32 * 32; 246 break; 247 default: 248 error = B_BAD_VALUE; 249 break; 250 } 251 252 // check parameter and initialization 253 if (error == B_OK 254 && (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) { 255 error = B_BAD_VALUE; 256 } 257 if (error == B_OK && InitCheck() != B_OK) 258 error = B_NO_INIT; 259 260 // get the attribute info and check type and size of the attr contents 261 attr_info attrInfo; 262 if (error == B_OK) 263 error = fNode->GetAttrInfo(attribute, &attrInfo); 264 if (error == B_OK && attrInfo.type != attrType) 265 error = B_BAD_TYPE; 266 if (error == B_OK && attrInfo.size != attrSize) 267 error = B_BAD_DATA; 268 269 // read the attribute 270 if (error == B_OK) { 271 bool otherColorSpace = (icon->ColorSpace() != B_CMAP8); 272 char *buffer = NULL; 273 ssize_t read; 274 if (otherColorSpace) { 275 // other color space than stored in attribute 276 buffer = new(nothrow) char[attrSize]; 277 if (!buffer) 278 error = B_NO_MEMORY; 279 if (error == B_OK) { 280 read = fNode->ReadAttr(attribute, attrType, 0, buffer, 281 attrSize); 282 } 283 } else { 284 read = fNode->ReadAttr(attribute, attrType, 0, icon->Bits(), 285 attrSize); 286 } 287 if (error == B_OK) { 288 if (read < 0) 289 error = read; 290 else if (read != attrInfo.size) 291 error = B_ERROR; 292 } 293 if (otherColorSpace) { 294 // other color space than stored in attribute 295 if (error == B_OK) { 296 error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW, 297 0, B_CMAP8); 298 } 299 delete[] buffer; 300 } 301 } 302 return error; 303 } 304 305 // SetIcon 306 /*! \brief Sets the node's icon. 307 308 The icon is stored in the node's "BEOS:L:STD_ICON" (large) or 309 "BEOS:M:STD_ICON" (mini) attribute. 310 311 If \a icon is \c NULL, the respective attribute is removed. 312 313 \param icon A pointer to the BBitmap containing the icon to be set. 314 May be \c NULL. 315 \param k Specifies the size of the icon to be set: \c B_MINI_ICON 316 for the mini and \c B_LARGE_ICON for the large icon. 317 \return 318 - \c B_OK: Everything went fine. 319 - \c B_NO_INIT: The object is not properly initialized. 320 - \c B_BAD_VALUE: Unknown icon size \a k or bitmap dimensions (\a icon) 321 and icon size (\a k) do not match. 322 - other error codes 323 */ 324 status_t 325 BNodeInfo::SetIcon(const BBitmap *icon, icon_size k) 326 { 327 status_t error = B_OK; 328 // set some icon size related variables 329 const char *attribute = NULL; 330 BRect bounds; 331 uint32 attrType = 0; 332 size_t attrSize = 0; 333 switch (k) { 334 case B_MINI_ICON: 335 attribute = kNIMiniIconAttribute; 336 bounds.Set(0, 0, 15, 15); 337 attrType = B_MINI_ICON_TYPE; 338 attrSize = 16 * 16; 339 break; 340 case B_LARGE_ICON: 341 attribute = kNILargeIconAttribute; 342 bounds.Set(0, 0, 31, 31); 343 attrType = B_LARGE_ICON_TYPE; 344 attrSize = 32 * 32; 345 break; 346 default: 347 error = B_BAD_VALUE; 348 break; 349 } 350 351 // check parameter and initialization 352 if (error == B_OK && icon 353 && (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) { 354 error = B_BAD_VALUE; 355 } 356 if (error == B_OK && InitCheck() != B_OK) 357 error = B_NO_INIT; 358 359 // write/remove the attribute 360 if (error == B_OK) { 361 if (icon) { 362 bool otherColorSpace = (icon->ColorSpace() != B_CMAP8); 363 ssize_t written = 0; 364 if (otherColorSpace) { 365 BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8); 366 error = bitmap.InitCheck(); 367 if (error == B_OK) 368 error = bitmap.ImportBits(icon); 369 if (error == B_OK) { 370 written = fNode->WriteAttr(attribute, attrType, 0, 371 bitmap.Bits(), attrSize); 372 } 373 } else { 374 written = fNode->WriteAttr(attribute, attrType, 0, 375 icon->Bits(), attrSize); 376 } 377 if (error == B_OK) { 378 if (written < 0) 379 error = written; 380 else if (written != (ssize_t)attrSize) 381 error = B_ERROR; 382 } 383 } else // no icon given => remove 384 error = fNode->RemoveAttr(attribute); 385 } 386 return error; 387 } 388 389 // GetPreferredApp 390 /*! \brief Gets the node's preferred application. 391 392 Writes the contents of the "BEOS:PREF_APP" attribute into the supplied 393 buffer \a signature. The preferred application is identifief by its 394 signature. 395 396 \param signature A pointer to a pre-allocated character buffer of size 397 \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the 398 preferred application shall be written. 399 \param verb Specifies the type of access the preferred application is 400 requested for. Currently only \c B_OPEN is meaningful. 401 \return 402 - \c B_OK: Everything went fine. 403 - \c B_NO_INIT: The object is not properly initialized. 404 - \c B_BAD_VALUE: \c NULL \a signature or bad app_verb \a verb. 405 - other error codes 406 */ 407 status_t 408 BNodeInfo::GetPreferredApp(char *signature, app_verb verb) const 409 { 410 // check parameter and initialization 411 status_t error = (signature && verb == B_OPEN ? B_OK : B_BAD_VALUE); 412 if (error == B_OK && InitCheck() != B_OK) 413 error = B_NO_INIT; 414 415 // get the attribute info and check type and length of the attr contents 416 attr_info attrInfo; 417 if (error == B_OK) 418 error = fNode->GetAttrInfo(kNIPreferredAppAttribute, &attrInfo); 419 if (error == B_OK && attrInfo.type != B_MIME_STRING_TYPE) 420 error = B_BAD_TYPE; 421 if (error == B_OK && attrInfo.size > B_MIME_TYPE_LENGTH) 422 error = B_BAD_DATA; 423 424 // read the data 425 if (error == B_OK) { 426 ssize_t read = fNode->ReadAttr(kNIPreferredAppAttribute, attrInfo.type, 427 0, signature, attrInfo.size); 428 if (read < 0) 429 error = read; 430 else if (read != attrInfo.size) 431 error = B_ERROR; 432 433 if (error == B_OK) { 434 // attribute strings doesn't have to be null terminated 435 signature[min_c(attrInfo.size, B_MIME_TYPE_LENGTH - 1)] = '\0'; 436 } 437 } 438 return error; 439 } 440 441 // SetPreferredApp 442 /*! \brief Sets the node's preferred application. 443 444 The supplied string is written into the node's "BEOS:PREF_APP" attribute. 445 446 If \a signature is \c NULL, the respective attribute is removed. 447 448 \param signature The signature of the preferred application to be set. 449 Must not be longer than \c B_MIME_TYPE_LENGTH (including the 450 terminating null). May be \c NULL. 451 \param verb Specifies the type of access the preferred application shall 452 be set for. Currently only \c B_OPEN is meaningful. 453 \return 454 - \c B_OK: Everything went fine. 455 - \c B_NO_INIT: The object is not properly initialized. 456 - \c B_BAD_VALUE: \c NULL \a signature, \a signature is longer than 457 \c B_MIME_TYPE_LENGTH or bad app_verb \a verb. 458 - other error codes 459 */ 460 status_t 461 BNodeInfo::SetPreferredApp(const char *signature, app_verb verb) 462 { 463 // check parameters and initialization 464 status_t error = (verb == B_OPEN ? B_OK : B_BAD_VALUE); 465 if (error == B_OK && signature && strlen(signature) >= B_MIME_TYPE_LENGTH) 466 error = B_BAD_VALUE; 467 if (error == B_OK && InitCheck() != B_OK) 468 error = B_NO_INIT; 469 470 // write/remove the attribute 471 if (error == B_OK) { 472 if (signature) { 473 size_t toWrite = strlen(signature) + 1; 474 ssize_t written = fNode->WriteAttr(kNIPreferredAppAttribute, 475 B_MIME_STRING_TYPE, 0, 476 signature, toWrite); 477 if (written < 0) 478 error = written; 479 else if (written != (ssize_t)toWrite) 480 error = B_ERROR; 481 } else 482 error = fNode->RemoveAttr(kNIPreferredAppAttribute); 483 } 484 return error; 485 } 486 487 // GetAppHint 488 /*! \brief Returns a hint in form of and entry_ref to the application that 489 shall be used to open this node. 490 491 The path contained in the node's "BEOS:PPATH" attribute is converted into 492 an entry_ref and returned in \a ref. 493 494 \param ref A pointer to a pre-allocated entry_ref into which the requested 495 app hint shall be written. 496 \return 497 - \c B_OK: Everything went fine. 498 - \c B_NO_INIT: The object is not properly initialized. 499 - \c B_BAD_VALUE: \c NULL \a ref. 500 - other error codes 501 */ 502 status_t 503 BNodeInfo::GetAppHint(entry_ref *ref) const 504 { 505 // check parameter and initialization 506 status_t error = (ref ? B_OK : B_BAD_VALUE); 507 if (error == B_OK && InitCheck() != B_OK) 508 error = B_NO_INIT; 509 510 // get the attribute info and check type and length of the attr contents 511 attr_info attrInfo; 512 if (error == B_OK) 513 error = fNode->GetAttrInfo(kNIAppHintAttribute, &attrInfo); 514 // NOTE: The attribute type should be B_STRING_TYPE, but R5 uses 515 // B_MIME_STRING_TYPE. 516 if (error == B_OK && attrInfo.type != B_MIME_STRING_TYPE) 517 error = B_BAD_TYPE; 518 if (error == B_OK && attrInfo.size > B_PATH_NAME_LENGTH) 519 error = B_BAD_DATA; 520 521 // read the data 522 if (error == B_OK) { 523 char path[B_PATH_NAME_LENGTH]; 524 ssize_t read = fNode->ReadAttr(kNIAppHintAttribute, attrInfo.type, 0, 525 path, attrInfo.size); 526 if (read < 0) 527 error = read; 528 else if (read != attrInfo.size) 529 error = B_ERROR; 530 // get the entry_ref for the path 531 if (error == B_OK) { 532 // attribute strings doesn't have to be null terminated 533 path[min_c(attrInfo.size, B_PATH_NAME_LENGTH - 1)] = '\0'; 534 error = get_ref_for_path(path, ref); 535 } 536 } 537 return error; 538 } 539 540 // SetAppHint 541 /*! \brief Sets the node's app hint. 542 543 The supplied entry_ref is converted into a path and stored in the node's 544 "BEOS:PPATH" attribute. 545 546 If \a ref is \c NULL, the respective attribute is removed. 547 548 \param ref A pointer to an entry_ref referring to the application. 549 May be \c NULL. 550 \return 551 - \c B_OK: Everything went fine. 552 - \c B_NO_INIT: The object is not properly initialized. 553 - \c B_BAD_VALUE: \c NULL \a ref. 554 - other error codes 555 */ 556 status_t 557 BNodeInfo::SetAppHint(const entry_ref *ref) 558 { 559 // check parameter and initialization 560 status_t error = B_OK; 561 if (error == B_OK && InitCheck() != B_OK) 562 error = B_NO_INIT; 563 564 // write/remove the attribute 565 if (error == B_OK) { 566 if (ref) { 567 BPath path; 568 error = path.SetTo(ref); 569 if (error == B_OK) { 570 size_t toWrite = strlen(path.Path()) + 1; 571 ssize_t written = fNode->WriteAttr(kNIAppHintAttribute, 572 B_MIME_STRING_TYPE, 0, 573 path.Path(), toWrite); 574 if (written < 0) 575 error = written; 576 else if (written != (ssize_t)toWrite) 577 error = B_ERROR; 578 } 579 } else 580 error = fNode->RemoveAttr(kNIAppHintAttribute); 581 } 582 return error; 583 } 584 585 // GetTrackerIcon 586 /*! \brief Gets the icon which tracker displays. 587 588 This method tries real hard to find an icon for the node: 589 - If the node has no type, return the icon for B_FILE_MIME_TYPE if it's a 590 regular file, for B_DIRECTORY_MIME_TYPE if it's a directory, etc. from 591 the MIME database. Even, if the node has an own icon! 592 - Ask GetIcon(). 593 - Get the preferred application and ask the MIME database, if that 594 application has a special icon for the node's file type. 595 - Ask the MIME database whether there is an icon for the node's file type. 596 - Ask the MIME database for the preferred application for the node's 597 file type and whether this application has a special icon for the type. 598 - Return the icon for whatever type of node (file/dir/etc.) from the MIME database. 599 This list is processed in the given order and the icon the first 600 successful attempt provides is returned. In case none of them yields an 601 icon, this method fails. This is very unlikely though. 602 603 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 604 to store the requested icon (16x16 for the mini and 32x32 for the 605 large icon). 606 \param iconSize Specifies the size of the icon to be retrieved: \c B_MINI_ICON 607 for the mini and \c B_LARGE_ICON for the large icon. 608 \return 609 - \c B_OK: Everything went fine. 610 - \c B_NO_INIT: The object is not properly initialized. 611 - \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a iconSize or bitmap 612 dimensions (\a icon) and icon size (\a iconSize) do not match. 613 - other error codes 614 */ 615 status_t 616 BNodeInfo::GetTrackerIcon(BBitmap *icon, icon_size iconSize) const 617 { 618 // set some icon size related variables 619 status_t error = B_OK; 620 BRect bounds; 621 switch (iconSize) { 622 case B_MINI_ICON: 623 bounds.Set(0, 0, 15, 15); 624 break; 625 case B_LARGE_ICON: 626 bounds.Set(0, 0, 31, 31); 627 break; 628 default: 629 error = B_BAD_VALUE; 630 break; 631 } 632 633 // check parameters and initialization 634 if (error == B_OK 635 && (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) { 636 error = B_BAD_VALUE; 637 } 638 if (error == B_OK && InitCheck() != B_OK) 639 error = B_NO_INIT; 640 641 bool success = false; 642 643 // get node MIME type, and, if that fails, the generic icon 644 char mimeString[B_MIME_TYPE_LENGTH]; 645 if (error == B_OK) { 646 if (GetType(mimeString) != B_OK) { 647 struct stat stat; 648 error = fNode->GetStat(&stat); 649 if (error == B_OK) { 650 // no type available -- get the icon for the appropriate type (file/dir/etc.) 651 BMimeType type; 652 if (S_ISREG(stat.st_mode)) { 653 // is it an application (executable) or just a regular file? 654 if ((stat.st_mode & S_IXUSR) != 0) 655 type.SetTo(B_APP_MIME_TYPE); 656 else 657 type.SetTo(B_FILE_MIME_TYPE); 658 } else if (S_ISDIR(stat.st_mode)) { 659 // it's either a volume or just a standard directory 660 fs_info info; 661 if (fs_stat_dev(stat.st_dev, &info) == 0 && stat.st_ino == info.root) 662 type.SetTo(B_VOLUME_MIME_TYPE); 663 else 664 type.SetTo(B_DIRECTORY_MIME_TYPE); 665 } else if (S_ISLNK(stat.st_mode)) 666 type.SetTo(B_SYMLINK_MIME_TYPE); 667 668 error = type.GetIcon(icon, iconSize); 669 success = (error == B_OK); 670 } 671 } 672 } 673 674 // Ask GetIcon(). 675 if (error == B_OK && !success) 676 success = (GetIcon(icon, iconSize) == B_OK); 677 678 // Get the preferred application and ask the MIME database, if that 679 // application has a special icon for the node's file type. 680 if (error == B_OK && !success) { 681 char signature[B_MIME_TYPE_LENGTH]; 682 if (GetPreferredApp(signature) == B_OK) { 683 BMimeType type(signature); 684 success = (type.GetIconForType(mimeString, icon, iconSize) == B_OK); 685 } 686 } 687 688 // Ask the MIME database whether there is an icon for the node's file type. 689 BMimeType nodeType; 690 if (error == B_OK && !success) { 691 nodeType.SetTo(mimeString); 692 success = (nodeType.GetIcon(icon, iconSize) == B_OK); 693 } 694 695 // Ask the MIME database for the preferred application for the node's 696 // file type and whether this application has a special icon for the type. 697 if (error == B_OK && !success) { 698 char signature[B_MIME_TYPE_LENGTH]; 699 if (nodeType.GetPreferredApp(signature) == B_OK) { 700 BMimeType type(signature); 701 success = (type.GetIconForType(mimeString, icon, iconSize) == B_OK); 702 } 703 } 704 705 // Return the icon for "application/octet-stream" from the MIME database. 706 if (error == B_OK && !success) { 707 // get the "application/octet-stream" icon 708 BMimeType type(B_FILE_MIME_TYPE); 709 error = type.GetIcon(icon, iconSize); 710 success = (error == B_OK); 711 } 712 return error; 713 } 714 715 // GetTrackerIcon 716 /*! \brief Gets the icon which tracker displays for the node referred to by 717 the supplied entry_ref. 718 719 This methods works similar to the non-static version. The first argument 720 \a ref identifies the node in question. 721 722 \param ref An entry_ref referring to the node for which the icon shall be 723 retrieved. 724 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 725 to store the requested icon (16x16 for the mini and 32x32 for the 726 large icon). 727 \param iconSize Specifies the size of the icon to be retrieved: \c B_MINI_ICON 728 for the mini and \c B_LARGE_ICON for the large icon. 729 \return 730 - \c B_OK: Everything went fine. 731 - \c B_NO_INIT: The object is not properly initialized. 732 - \c B_BAD_VALUE: \c NULL ref or \a icon, unsupported icon size \a iconSize or 733 bitmap dimensions (\a icon) and icon size (\a iconSize) do not match. 734 - other error codes 735 */ 736 status_t 737 BNodeInfo::GetTrackerIcon(const entry_ref *ref, BBitmap *icon, icon_size iconSize) 738 { 739 // check ref param 740 status_t error = (ref ? B_OK : B_BAD_VALUE); 741 742 // init a BNode 743 BNode node; 744 if (error == B_OK) 745 error = node.SetTo(ref); 746 747 // init a BNodeInfo 748 BNodeInfo nodeInfo; 749 if (error == B_OK) 750 error = nodeInfo.SetTo(&node); 751 752 // let the non-static GetTrackerIcon() do the dirty work 753 if (error == B_OK) 754 error = nodeInfo.GetTrackerIcon(icon, iconSize); 755 return error; 756 } 757 758 // TODO: just here for providing binary compatibility 759 // (for example "Guido" needs this) 760 extern "C" 761 status_t 762 GetTrackerIcon__9BNodeInfoP9entry_refP7BBitmap9icon_size( 763 BNodeInfo *nodeInfo, entry_ref* ref, 764 BBitmap* bitmap, icon_size iconSize) 765 { 766 // NOTE: nodeInfo is ignored - maybe that's wrong! 767 return BNodeInfo::GetTrackerIcon(ref, bitmap, iconSize); 768 } 769 770 void 771 BNodeInfo::_ReservedNodeInfo1() 772 { 773 } 774 775 void 776 BNodeInfo::_ReservedNodeInfo2() 777 { 778 } 779 780 void 781 BNodeInfo::_ReservedNodeInfo3() 782 { 783 } 784 785 // = 786 /*! \brief Privatized assignment operator to prevent usage. 787 */ 788 BNodeInfo & 789 BNodeInfo::operator=(const BNodeInfo &nodeInfo) 790 { 791 return *this; 792 } 793 794 // copy constructor 795 /*! \brief Privatized copy constructor to prevent usage. 796 */ 797 BNodeInfo::BNodeInfo(const BNodeInfo &) 798 { 799 } 800 801 802 // #pragma mark - 803 804 namespace BPrivate { 805 806 /*! 807 Private function used by Tracker. Should be moved into the Tracker sources. 808 */ 809 extern bool 810 CheckNodeIconHintPrivate(const BNode *node, bool checkMiniIconOnly) 811 { 812 attr_info info; 813 if (node->GetAttrInfo(kNIMiniIconAttribute, &info) != B_OK && checkMiniIconOnly) 814 return false; 815 816 if (node->GetAttrInfo(kNILargeIconAttribute, &info) != B_OK) 817 return false; 818 819 return true; 820 } 821 822 } // namespace BPrivate 823