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