xref: /haiku/src/kits/tracker/TrackerInitialState.cpp (revision a629567a9001547736cfe892cdf992be16868fed)
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 // ToDo:
36 // add code to initialize a subset of the mime database, including
37 // important sniffer rules
38 
39 
40 #include <Alert.h>
41 #include <Catalog.h>
42 #include <Directory.h>
43 #include <InterfaceDefs.h>
44 #include <Locale.h>
45 #include <Message.h>
46 #include <Node.h>
47 #include <Path.h>
48 #include <Screen.h>
49 #include <VolumeRoster.h>
50 
51 #include <fs_attr.h>
52 #include <fs_index.h>
53 
54 #include "pr_server.h"
55 
56 #include "Attributes.h"
57 #include "AttributeStream.h"
58 #include "BackgroundImage.h"
59 #include "Bitmaps.h"
60 #include "ContainerWindow.h"
61 #include "MimeTypes.h"
62 #include "FSUtils.h"
63 #include "QueryContainerWindow.h"
64 #include "Tracker.h"
65 
66 
67 enum {
68 	kForceLargeIcon = 0x1,
69 	kForceMiniIcon = 0x2,
70 	kForceShortDescription = 0x4,
71 	kForceLongDescription = 0x8,
72 	kForcePreferredApp = 0x10
73 };
74 
75 
76 const char* kAttrName = "META:name";
77 const char* kAttrCompany = "META:company";
78 const char* kAttrAddress = "META:address";
79 const char* kAttrCity = "META:city";
80 const char* kAttrState = "META:state";
81 const char* kAttrZip = "META:zip";
82 const char* kAttrCountry = "META:country";
83 const char* kAttrHomePhone = "META:hphone";
84 const char* kAttrWorkPhone = "META:wphone";
85 const char* kAttrFax = "META:fax";
86 const char* kAttrEmail = "META:email";
87 const char* kAttrURL = "META:url";
88 const char* kAttrGroup = "META:group";
89 const char* kAttrNickname = "META:nickname";
90 
91 const char* kNetPositiveSignature = "application/x-vnd.Be-NPOS";
92 const char* kPeopleSignature = "application/x-vnd.Be-PEPL";
93 
94 // the following templates are in big endian and we rely on the Tracker
95 // translation support to swap them on little endian machines
96 //
97 // in case there is an attribute (B_RECT_TYPE) that gets swapped by the media
98 // (unzip, file system endianness swapping, etc., the correct endianness for
99 // the correct machine has to be used here
100 
101 const BRect kDefaultFrame(40, 40, 695, 350);
102 const int32 kDefaultQueryTemplateCount = 3;
103 
104 const AttributeTemplate kDefaultQueryTemplate[] =
105 	/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
106 		application_octet-stream */
107 {
108 	{
109 		// default frame
110 		kAttrWindowFrame,
111 		B_RECT_TYPE,
112 		16,
113 		(const char*)&kDefaultFrame
114 	},
115 	{
116 		// attr: _trk/viewstate
117 		kAttrViewState_be,
118 		B_RAW_TYPE,
119 		49,
120 		"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
121 		"\000\000\000\000\000\000\000\000\000\000\357\323\335RCSTR\000\000"
122 		"\000\000\000\000\000\000\000"
123 	},
124 	{
125 		// attr: _trk/columns
126 		kAttrColumns_be,
127 		B_RAW_TYPE,
128 		223,
129 		"O\362VR\000\000\000\025\000\000\000\004Name\000B \000\000C\021\000"
130 		"\000\000\000\000\000\000\000\000\012_stat/name\000\357\323\335RCST"
131 		"R\001\001O\362VR\000\000\000\025\000\000\000\004Path\000CH\000\000"
132 		"Ca\000\000\000\000\000\000\000\000\000\011_trk/path\000\357_\174RC"
133 		"STR\000\000O\362VR\000\000\000\025\000\000\000\004Size\000C\334\000"
134 		"\000B$\000\000\000\000\000\001\000\000\000\012_stat/size\000\317\317"
135 		"\306TOFFT\001\000O\362VR\000\000\000\025\000\000\000\010Modified\000"
136 		"C\370\000\000C\012\000\000\000\000\000\000\000\000\000\016_stat/mo"
137 		"dified\000]KmETIME\001\000"
138 	}
139 };
140 
141 
142 const AttributeTemplate kBookmarkQueryTemplate[] =
143 	/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
144 		application_x-vnd.Be-bookmark */
145 {
146 	{
147 		// default frame
148 		kAttrWindowFrame,
149 		B_RECT_TYPE,
150 		16,
151 		(const char*)&kDefaultFrame
152 	},
153 	{
154 		// attr: _trk/viewstate
155 		kAttrViewState_be,
156 		B_RAW_TYPE,
157 		49,
158 		"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
159 		"\000\000\000\000\000\000\000\000\000\000w\373\175RCSTR\000\000\000"
160 		"\000\000\000\000\000\000"
161 	},
162 	{
163 		// attr: _trk/columns
164 		kAttrColumns_be,
165 		B_RAW_TYPE,
166 		163,
167 		"O\362VR\000\000\000\025\000\000\000\005Title\000B \000\000C+\000\000"
168 		"\000\000\000\000\000\000\000\012META:title\000w\373\175RCSTR\000\001"
169 		"O\362VR\000\000\000\025\000\000\000\003URL\000Cb\000\000C\217\200"
170 		"\000\000\000\000\000\000\000\000\010META:url\000\343[TRCSTR\000\001O"
171 		"\362VR\000\000\000\025\000\000\000\010Keywords\000D\004\000\000C\002"
172 		"\000\000\000\000\000\000\000\000\000\011META:keyw\000\333\363\334"
173 		"RCSTR\000\001"
174 	}
175 };
176 
177 
178 const AttributeTemplate kPersonQueryTemplate[] =
179 	/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
180 		application_x-vnd.Be-bookmark */
181 {
182 	{
183 		// default frame
184 		kAttrWindowFrame,
185 		B_RECT_TYPE,
186 		16,
187 		(const char*)&kDefaultFrame
188 	},
189 	{
190 		// attr: _trk/viewstate
191 		kAttrViewState_be,
192 		B_RAW_TYPE,
193 		49,
194 		"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
195 		"\000\000\000\000\000\000\000\000\000\000\357\323\335RCSTR\000\000"
196 		"\000\000\000\000\000\000\000"
197 	},
198 	{
199 		// attr: _trk/columns
200 		kAttrColumns_be,
201 		B_RAW_TYPE,
202 		230,
203 		"O\362VR\000\000\000\025\000\000\000\004Name\000B \000\000B\346\000"
204 		"\000\000\000\000\000\000\000\000\012_stat/name\000\357\323\335RCST"
205 		"R\001\001O\362VR\000\000\000\025\000\000\000\012Work Phone\000C*\000"
206 		"\000B\264\000\000\000\000\000\000\000\000\000\013META:wphone\000C_"
207 		"uRCSTR\000\001O\362VR\000\000\000\025\000\000\000\006E-mail\000C\211"
208 		"\200\000B\272\000\000\000\000\000\000\000\000\000\012META:email\000"
209 		"sW\337RCSTR\000\001O\362VR\000\000\000\025\000\000\000\007Company"
210 		"\000C\277\200\000B\360\000\000\000\000\000\000\000\000\000\014"
211 		"META:company\000CS\174RCSTR\000\001"
212 	},
213 };
214 
215 
216 const AttributeTemplate kEmailQueryTemplate[] =
217 	/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
218 		text_x-email */
219 {
220 	{
221 		// default frame
222 		kAttrWindowFrame,
223 		B_RECT_TYPE,
224 		16,
225 		(const char*)&kDefaultFrame
226 	},
227 	{
228 		// attr: _trk/viewstate
229 		kAttrViewState_be,
230 		B_RAW_TYPE,
231 		49,
232 		"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
233 		"\000\000\000\000\000\000\000\000\000\000\366_\377ETIME\000\000\000"
234 		"\000\000\000\000\000\000"
235 	},
236 	{
237 		// attr: _trk/columns
238 		kAttrColumns_be,
239 		B_RAW_TYPE,
240 		222,
241 		"O\362VR\000\000\000\025\000\000\000\007Subject\000B \000\000B\334"
242 		"\000\000\000\000\000\000\000\000\000\014MAIL:subject\000\343\173\337"
243 		"RCSTR\000\000O\362VR\000\000\000\025\000\000\000\004From\000C%\000"
244 		"\000C\031\000\000\000\000\000\000\000\000\000\011MAIL:from\000\317"
245 		"s_RCSTR\000\000O\362VR\000\000\000\025\000\000\000\004When\000C\246"
246 		"\200\000B\360\000\000\000\000\000\000\000\000\000\011MAIL:when\000"
247 		"\366_\377ETIME\000\000O\362VR\000\000\000\025\000\000\000\006Status"
248 		"\000C\352\000\000BH\000\000\000\000\000\001\000\000\000\013"
249 		"MAIL:status\000G\363\134RCSTR\000\001"
250 	},
251 };
252 
253 
254 namespace BPrivate {
255 
256 class ExtraAttributeLazyInstaller {
257 public:
258 	ExtraAttributeLazyInstaller(const char* type);
259 	~ExtraAttributeLazyInstaller();
260 
261 	bool AddExtraAttribute(const char* publicName, const char* name,
262 		uint32 type, bool viewable, bool editable, float width,
263 		int32 alignment, bool extra);
264 
265 	status_t InitCheck() const;
266 public:
267 	BMimeType fMimeType;
268 	BMessage fExtraAttrs;
269 	bool fDirty;
270 };
271 
272 }	// namespace BPrivate
273 
274 
275 //	#pragma mark - ExtraAttributeLazyInstaller
276 
277 
278 ExtraAttributeLazyInstaller::ExtraAttributeLazyInstaller(const char* type)
279 	:
280 	fMimeType(type),
281 	fDirty(false)
282 {
283 	if (fMimeType.InitCheck() == B_OK)
284 		fMimeType.GetAttrInfo(&fExtraAttrs);
285 }
286 
287 
288 ExtraAttributeLazyInstaller::~ExtraAttributeLazyInstaller()
289 {
290 	if (fMimeType.InitCheck() == B_OK && fDirty)
291 		fMimeType.SetAttrInfo(&fExtraAttrs);
292 }
293 
294 
295 bool
296 ExtraAttributeLazyInstaller::AddExtraAttribute(const char* publicName,
297 	const char* name, uint32 type, bool viewable, bool editable, float width,
298 	int32 alignment, bool extra)
299 {
300 	for (int32 index = 0; ; index++) {
301 		const char* oldPublicName;
302 		if (fExtraAttrs.FindString("attr:public_name", index, &oldPublicName)
303 				!= B_OK) {
304 			break;
305 		}
306 
307 		if (strcmp(oldPublicName, publicName) == 0)
308 			// already got this extra atribute, no work left
309 			return false;
310 	}
311 
312 	fExtraAttrs.AddString("attr:public_name", publicName);
313 	fExtraAttrs.AddString("attr:name", name);
314 	fExtraAttrs.AddInt32("attr:type", (int32)type);
315 	fExtraAttrs.AddBool("attr:viewable", viewable);
316 	fExtraAttrs.AddBool("attr:editable", editable);
317 	fExtraAttrs.AddInt32("attr:width", (int32)width);
318 	fExtraAttrs.AddInt32("attr:alignment", alignment);
319 	fExtraAttrs.AddBool("attr:extra", extra);
320 
321 	fDirty = true;
322 	return true;
323 }
324 
325 
326 // #pragma mark - static functions
327 
328 
329 static void
330 InstallTemporaryBackgroundImages(BNode* node, BMessage* message)
331 {
332 	int32 size = message->FlattenedSize();
333 
334 	try {
335 		char* buffer = new char[size];
336 		message->Flatten(buffer, size);
337 		node->WriteAttr(kBackgroundImageInfo, B_MESSAGE_TYPE, 0, buffer,
338 			(size_t)size);
339 		delete[] buffer;
340 	} catch (...) {
341 		;
342 	}
343 }
344 
345 
346 static void
347 AddTemporaryBackgroundImages(BMessage* message, const char* imagePath,
348 	BackgroundImage::Mode mode, BPoint offset, uint32 workspaces,
349 	bool textWidgetOutlines)
350 {
351 	message->AddString(kBackgroundImageInfoPath, imagePath);
352 	message->AddInt32(kBackgroundImageInfoWorkspaces, (int32)workspaces);
353 	message->AddInt32(kBackgroundImageInfoMode, mode);
354 	message->AddBool(kBackgroundImageInfoTextOutline, textWidgetOutlines);
355 	message->AddPoint(kBackgroundImageInfoOffset, offset);
356 }
357 
358 
359 // #pragma mark - TrackerInitialState
360 
361 
362 #undef B_TRANSLATION_CONTEXT
363 #define B_TRANSLATION_CONTEXT "TrackerInitialState"
364 
365 
366 bool
367 TTracker::InstallMimeIfNeeded(const char* type, int32 bitsID,
368 	const char* shortDescription, const char* longDescription,
369 	const char* preferredAppSignature, uint32 forceMask)
370 {
371 	// used by InitMimeTypes - checks if a metamime of a given <type> is
372 	// installed and if it has all the specified attributes; if not, the
373 	// whole mime type is installed and all attributes are set; nulls can
374 	// be passed for attributes that don't matter; returns true if anything
375 	// had to be changed
376 
377 	BBitmap vectorIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK,
378 		B_RGBA32);
379 	BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
380 	BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
381 	char tmp[B_MIME_TYPE_LENGTH];
382 
383 	BMimeType mime(type);
384 	bool installed = mime.IsInstalled();
385 
386 	if (!installed
387 		|| (bitsID >= 0 && ((forceMask & kForceLargeIcon)
388 			|| mime.GetIcon(&vectorIcon, B_LARGE_ICON) != B_OK))
389 		|| (bitsID >= 0 && ((forceMask & kForceLargeIcon)
390 			|| mime.GetIcon(&largeIcon, B_LARGE_ICON) != B_OK))
391 		|| (bitsID >= 0 && ((forceMask & kForceMiniIcon)
392 			|| mime.GetIcon(&miniIcon, B_MINI_ICON) != B_OK))
393 		|| (shortDescription && ((forceMask & kForceShortDescription)
394 			|| mime.GetShortDescription(tmp) != B_OK))
395 		|| (longDescription && ((forceMask & kForceLongDescription)
396 			|| mime.GetLongDescription(tmp) != B_OK))
397 		|| (preferredAppSignature && ((forceMask & kForcePreferredApp)
398 			|| mime.GetPreferredApp(tmp) != B_OK))) {
399 
400 		if (!installed)
401 			mime.Install();
402 
403 		if (bitsID >= 0) {
404 			const uint8* iconData;
405 			size_t iconSize;
406 			if (GetTrackerResources()->
407 					GetIconResource(bitsID, &iconData, &iconSize) == B_OK)
408 				mime.SetIcon(iconData, iconSize);
409 
410 			if (GetTrackerResources()->
411 					GetIconResource(bitsID, B_LARGE_ICON, &largeIcon) == B_OK)
412 				mime.SetIcon(&largeIcon, B_LARGE_ICON);
413 
414 			if (GetTrackerResources()->
415 					GetIconResource(bitsID, B_MINI_ICON, &miniIcon) == B_OK)
416 				mime.SetIcon(&miniIcon, B_MINI_ICON);
417 		}
418 
419 		if (shortDescription)
420 			mime.SetShortDescription(shortDescription);
421 
422 		if (longDescription)
423 			mime.SetLongDescription(longDescription);
424 
425 		if (preferredAppSignature)
426 			mime.SetPreferredApp(preferredAppSignature);
427 
428 		return true;
429 	}
430 	return false;
431 }
432 
433 
434 void
435 TTracker::InitMimeTypes()
436 {
437 	InstallMimeIfNeeded(B_APP_MIME_TYPE, R_AppIcon, "Be Application",
438 		"Generic Be application executable.", kTrackerSignature);
439 
440 	InstallMimeIfNeeded(B_FILE_MIMETYPE, R_FileIcon,
441 		"Generic file", "Generic document file.", kTrackerSignature);
442 
443 	InstallMimeIfNeeded(B_VOLUME_MIMETYPE, R_HardDiskIcon,
444 		"Be Volume", "Disk volume.", kTrackerSignature);
445 
446 	InstallMimeIfNeeded(B_QUERY_MIMETYPE, R_QueryDirIcon,
447 		"Be Query", "Query to locate items on disks.", kTrackerSignature);
448 
449 	InstallMimeIfNeeded(B_QUERY_TEMPLATE_MIMETYPE, R_QueryTemplateIcon,
450 		"Be Query template", "", kTrackerSignature);
451 
452 	InstallMimeIfNeeded(B_LINK_MIMETYPE, R_BrokenLinkIcon, "Symbolic link",
453 		"Link to another item in the file system.", kTrackerSignature);
454 
455 	InstallMimeIfNeeded(B_ROOT_MIMETYPE, R_RootIcon,
456 		"Be Root", "File system root.", kTrackerSignature);
457 
458 	InstallMimeIfNeeded(B_BOOKMARK_MIMETYPE, R_BookmarkIcon,
459 		"Bookmark", "Bookmark for a web page.", kNetPositiveSignature);
460 
461 	{
462 		// install a couple of extra fields for bookmark
463 
464 		ExtraAttributeLazyInstaller installer(B_BOOKMARK_MIMETYPE);
465 		installer.AddExtraAttribute("URL", "META:url", B_STRING_TYPE,
466 			true, true, 170, B_ALIGN_LEFT, false);
467 		installer.AddExtraAttribute("Keywords", "META:keyw", B_STRING_TYPE,
468 			true, true, 130, B_ALIGN_LEFT, false);
469 		installer.AddExtraAttribute("Title", "META:title", B_STRING_TYPE,
470 			true, true, 130, B_ALIGN_LEFT, false);
471 	}
472 
473 	InstallMimeIfNeeded(B_PERSON_MIMETYPE, R_PersonIcon,
474 		"Person", "Contact information for a person.", kPeopleSignature);
475 
476 	{
477 		ExtraAttributeLazyInstaller installer(B_PERSON_MIMETYPE);
478 		installer.AddExtraAttribute("Contact name", kAttrName, B_STRING_TYPE,
479 			true, true, 120, B_ALIGN_LEFT, false);
480 		installer.AddExtraAttribute("Company", kAttrCompany, B_STRING_TYPE,
481 			true, true, 120, B_ALIGN_LEFT, false);
482 		installer.AddExtraAttribute("Address", kAttrAddress, B_STRING_TYPE,
483 			true, true, 120, B_ALIGN_LEFT, false);
484 		installer.AddExtraAttribute("City", kAttrCity, B_STRING_TYPE,
485 			true, true, 90, B_ALIGN_LEFT, false);
486 		installer.AddExtraAttribute("State", kAttrState, B_STRING_TYPE,
487 			true, true, 50, B_ALIGN_LEFT, false);
488 		installer.AddExtraAttribute("Zip", kAttrZip, B_STRING_TYPE,
489 			true, true, 50, B_ALIGN_LEFT, false);
490 		installer.AddExtraAttribute("Country", kAttrCountry, B_STRING_TYPE,
491 			true, true, 120, B_ALIGN_LEFT, false);
492 		installer.AddExtraAttribute("E-mail", kAttrEmail, B_STRING_TYPE,
493 			true, true, 120, B_ALIGN_LEFT, false);
494 		installer.AddExtraAttribute("Home phone", kAttrHomePhone,
495 			B_STRING_TYPE, true, true, 90, B_ALIGN_LEFT, false);
496 		installer.AddExtraAttribute("Work phone", kAttrWorkPhone,
497 			B_STRING_TYPE, true, true, 90, B_ALIGN_LEFT, false);
498 		installer.AddExtraAttribute("Fax", kAttrFax, B_STRING_TYPE,
499 			true, true, 90, B_ALIGN_LEFT, false);
500 		installer.AddExtraAttribute("URL", kAttrURL, B_STRING_TYPE,
501 			true, true, 120, B_ALIGN_LEFT, false);
502 		installer.AddExtraAttribute("Group", kAttrGroup, B_STRING_TYPE,
503 			true, true, 120, B_ALIGN_LEFT, false);
504 		installer.AddExtraAttribute("Nickname", kAttrNickname, B_STRING_TYPE,
505 			true, true, 120, B_ALIGN_LEFT, false);
506 	}
507 
508 	InstallMimeIfNeeded(B_PRINTER_SPOOL_MIMETYPE, R_SpoolFileIcon,
509 		"Printer spool", "Printer spool file.", "application/x-vnd.Be-PRNT");
510 
511 	{
512 #if B_BEOS_VERSION_DANO
513 		ExtraAttributeLazyInstaller installer(B_PRINTER_SPOOL_MIMETYPE);
514 		installer.AddExtraAttribute("Status", PSRV_SPOOL_ATTR_STATUS,
515 			B_STRING_TYPE, true, false, 60, B_ALIGN_LEFT, false);
516 		installer.AddExtraAttribute("Page count", PSRV_SPOOL_ATTR_PAGECOUNT,
517 			B_INT32_TYPE, true, false, 40, B_ALIGN_RIGHT, false);
518 		installer.AddExtraAttribute("Description",
519 			PSRV_SPOOL_ATTR_DESCRIPTION, B_STRING_TYPE, true, true, 100,
520 			B_ALIGN_LEFT, false);
521 		installer.AddExtraAttribute("Printer name", PSRV_SPOOL_ATTR_PRINTER,
522 			B_STRING_TYPE, true, false, 80, B_ALIGN_LEFT, false);
523 		installer.AddExtraAttribute("Job creator type",
524 			PSRV_SPOOL_ATTR_MIMETYPE, B_ASCII_TYPE, true, false, 60,
525 			B_ALIGN_LEFT, false);
526 #else
527 		ExtraAttributeLazyInstaller installer(B_PRINTER_SPOOL_MIMETYPE);
528 		installer.AddExtraAttribute("Page count", "_spool/Page Count",
529 			B_INT32_TYPE, true, false, 40, B_ALIGN_RIGHT, false);
530 		installer.AddExtraAttribute("Description", "_spool/Description",
531 			B_ASCII_TYPE, true, true, 100, B_ALIGN_LEFT, false);
532 		installer.AddExtraAttribute("Printer name", "_spool/Printer",
533 			B_ASCII_TYPE, true, false, 80, B_ALIGN_LEFT, false);
534 		installer.AddExtraAttribute("Job creator type", "_spool/MimeType",
535 			B_ASCII_TYPE, true, false, 60, B_ALIGN_LEFT, false);
536 #endif
537 	}
538 
539 	InstallMimeIfNeeded(B_PRINTER_MIMETYPE, R_GenericPrinterIcon,
540 		"Printer", "Printer queue.", kTrackerSignature);
541 		// application/x-vnd.Be-PRNT
542 		// for now set tracker as a default handler for the printer because we
543 		// just want to open it as a folder
544 #if B_BEOS_VERSION_DANO
545 	{
546 		ExtraAttributeLazyInstaller installer(B_PRINTER_MIMETYPE);
547 		installer.AddExtraAttribute("Driver", PSRV_PRINTER_ATTR_DRV_NAME,
548 			B_STRING_TYPE, true, false, 120, B_ALIGN_LEFT, false);
549 		installer.AddExtraAttribute("Transport",
550 			PSRV_PRINTER_ATTR_TRANSPORT, B_STRING_TYPE, true, false,
551 			60, B_ALIGN_RIGHT, false);
552 		installer.AddExtraAttribute("Connection",
553 			PSRV_PRINTER_ATTR_CNX, B_STRING_TYPE, true, false,
554 			40, B_ALIGN_LEFT, false);
555 		installer.AddExtraAttribute("Description",
556 			PSRV_PRINTER_ATTR_COMMENTS, B_STRING_TYPE, true, true,
557 			140, B_ALIGN_LEFT, false);
558 	}
559 #endif
560 }
561 
562 
563 void
564 TTracker::InstallIndices()
565 {
566 	BVolumeRoster roster;
567 	BVolume volume;
568 
569 	roster.Rewind();
570 	while (roster.GetNextVolume(&volume) == B_OK) {
571 		if (volume.IsReadOnly() || !volume.IsPersistent()
572 			|| !volume.KnowsAttr() || !volume.KnowsQuery())
573 			continue;
574 		InstallIndices(volume.Device());
575 	}
576 }
577 
578 
579 void
580 TTracker::InstallIndices(dev_t device)
581 {
582 	fs_create_index(device, kAttrQueryLastChange, B_INT32_TYPE, 0);
583 	fs_create_index(device, "_trk/recentQuery", B_INT32_TYPE, 0);
584 }
585 
586 
587 void
588 TTracker::InstallDefaultTemplates()
589 {
590 	BNode node;
591 	BString query(kQueryTemplates);
592 	query += "/application_octet-stream";
593 
594 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
595 			&node, false)) {
596 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
597 				&node, true)) {
598 			AttributeStreamFileNode fileNode(&node);
599 			AttributeStreamTemplateNode tmp(kDefaultQueryTemplate, 3);
600 			fileNode << tmp;
601 		}
602 	}
603 
604 	(query = kQueryTemplates) += "/application_x-vnd.Be-bookmark";
605 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
606 			&node, false)) {
607 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
608 				&node, true)) {
609 			AttributeStreamFileNode fileNode(&node);
610 			AttributeStreamTemplateNode tmp(kBookmarkQueryTemplate, 3);
611 			fileNode << tmp;
612 		}
613 	}
614 
615 	(query = kQueryTemplates) += "/application_x-person";
616 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
617 			&node, false)) {
618 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
619 				&node, true)) {
620 			AttributeStreamFileNode fileNode(&node);
621 			AttributeStreamTemplateNode tmp(kPersonQueryTemplate, 3);
622 			fileNode << tmp;
623 		}
624 	}
625 
626 	(query = kQueryTemplates) += "/text_x-email";
627 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
628 			&node, false)) {
629 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
630 				&node, true)) {
631 			AttributeStreamFileNode fileNode(&node);
632 			AttributeStreamTemplateNode tmp(kEmailQueryTemplate, 3);
633 			fileNode << tmp;
634 		}
635 	}
636 }
637 
638 
639 void
640 TTracker::InstallTemporaryBackgroundImages()
641 {
642 	// make the large Haiku Logo the default background
643 
644 	BPath path;
645 	status_t status = find_directory(B_SYSTEM_DATA_DIRECTORY, &path);
646 	if (status < B_OK) {
647 		// TODO: this error shouldn't be shown to the regular user
648 		BString errorMessage(B_TRANSLATE("At %func \nfind_directory() "
649 			"failed. \nReason: %error"));
650 		errorMessage.ReplaceFirst("%func", __PRETTY_FUNCTION__);
651 		errorMessage.ReplaceFirst("%error", strerror(status));
652 		BAlert* alert = new BAlert("AlertError", errorMessage.String(),
653 			B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
654 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
655 		alert->Go();
656 		return;
657 	}
658 	path.Append("artwork");
659 
660 	BString defaultBackgroundImage("/HAIKU logo - white on blue - big.png");
661 
662 	BDirectory dir;
663 	if (FSGetBootDeskDir(&dir) == B_OK) {
664 		// install a default background if there is no background defined yet
665 		attr_info info;
666 		if (dir.GetAttrInfo(kBackgroundImageInfo, &info) != B_OK) {
667 			BScreen screen(B_MAIN_SCREEN_ID);
668 			BPoint logoPos;
669 			logoPos.x
670 				= floorf((screen.Frame().Width() - 605) * (sqrtf(5) - 1) / 2);
671 			logoPos.y = floorf((screen.Frame().Height() - 190) * 0.9);
672 			BMessage message;
673 			AddTemporaryBackgroundImages(&message,
674 				(BString(path.Path()) << defaultBackgroundImage).String(),
675 				BackgroundImage::kAtOffset, logoPos, 0xffffffff, false);
676 			::InstallTemporaryBackgroundImages(&dir, &message);
677 		}
678 	}
679 }
680