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