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