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