xref: /haiku/src/kits/tracker/TrackerInitialState.cpp (revision 7bdeef54a24d3417300f251af891df962b638b9b)
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 static const int32 sDefaultQueryTemplateCount = 3;
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("Work phone", kAttrWorkPhone,
376 			B_STRING_TYPE, true, true, 90, B_ALIGN_LEFT, false);
377 		installer.AddExtraAttribute("Fax", kAttrFax, B_STRING_TYPE,
378 			true, true, 90, B_ALIGN_LEFT, false);
379 		installer.AddExtraAttribute("URL", kAttrURL, B_STRING_TYPE,
380 			true, true, 120, B_ALIGN_LEFT, false);
381 		installer.AddExtraAttribute("Group", kAttrGroup, B_STRING_TYPE,
382 			true, true, 120, B_ALIGN_LEFT, false);
383 		installer.AddExtraAttribute("Nickname", kAttrNickname, B_STRING_TYPE,
384 			true, true, 120, B_ALIGN_LEFT, false);
385 	}
386 
387 	InstallMimeIfNeeded(B_PRINTER_SPOOL_MIMETYPE, R_SpoolFileIcon,
388 		"Printer spool", "Printer spool file.", "application/x-vnd.Be-PRNT");
389 
390 	{
391 #if B_BEOS_VERSION_DANO
392 		ExtraAttributeLazyInstaller installer(B_PRINTER_SPOOL_MIMETYPE);
393 		installer.AddExtraAttribute("Status", PSRV_SPOOL_ATTR_STATUS,
394 			B_STRING_TYPE, true, false, 60, B_ALIGN_LEFT, false);
395 		installer.AddExtraAttribute("Page count", PSRV_SPOOL_ATTR_PAGECOUNT,
396 			B_INT32_TYPE, true, false, 40, B_ALIGN_RIGHT, false);
397 		installer.AddExtraAttribute("Description",
398 			PSRV_SPOOL_ATTR_DESCRIPTION, B_STRING_TYPE, true, true, 100,
399 			B_ALIGN_LEFT, false);
400 		installer.AddExtraAttribute("Printer name", PSRV_SPOOL_ATTR_PRINTER,
401 			B_STRING_TYPE, true, false, 80, B_ALIGN_LEFT, false);
402 		installer.AddExtraAttribute("Job creator type",
403 			PSRV_SPOOL_ATTR_MIMETYPE, B_ASCII_TYPE, true, false, 60,
404 			B_ALIGN_LEFT, false);
405 #else
406 		ExtraAttributeLazyInstaller installer(B_PRINTER_SPOOL_MIMETYPE);
407 		installer.AddExtraAttribute("Page count", "_spool/Page Count",
408 			B_INT32_TYPE, true, false, 40, B_ALIGN_RIGHT, false);
409 		installer.AddExtraAttribute("Description", "_spool/Description",
410 			B_ASCII_TYPE, true, true, 100, B_ALIGN_LEFT, false);
411 		installer.AddExtraAttribute("Printer name", "_spool/Printer",
412 			B_ASCII_TYPE, true, false, 80, B_ALIGN_LEFT, false);
413 		installer.AddExtraAttribute("Job creator type", "_spool/MimeType",
414 			B_ASCII_TYPE, true, false, 60, B_ALIGN_LEFT, false);
415 #endif
416 	}
417 
418 	InstallMimeIfNeeded(B_PRINTER_MIMETYPE, R_GenericPrinterIcon,
419 		"Printer", "Printer queue.", kTrackerSignature);
420 		// application/x-vnd.Be-PRNT
421 		// for now set tracker as a default handler for the printer because we
422 		// just want to open it as a folder
423 #if B_BEOS_VERSION_DANO
424 	{
425 		ExtraAttributeLazyInstaller installer(B_PRINTER_MIMETYPE);
426 		installer.AddExtraAttribute("Driver", PSRV_PRINTER_ATTR_DRV_NAME,
427 			B_STRING_TYPE, true, false, 120, B_ALIGN_LEFT, false);
428 		installer.AddExtraAttribute("Transport",
429 			PSRV_PRINTER_ATTR_TRANSPORT, B_STRING_TYPE, true, false,
430 			60, B_ALIGN_RIGHT, false);
431 		installer.AddExtraAttribute("Connection",
432 			PSRV_PRINTER_ATTR_CNX, B_STRING_TYPE, true, false,
433 			40, B_ALIGN_LEFT, false);
434 		installer.AddExtraAttribute("Description",
435 			PSRV_PRINTER_ATTR_COMMENTS, B_STRING_TYPE, true, true,
436 			140, B_ALIGN_LEFT, false);
437 	}
438 #endif
439 }
440 
441 
442 void
443 TTracker::InstallIndices()
444 {
445 	BVolumeRoster roster;
446 	BVolume volume;
447 
448 	roster.Rewind();
449 	while (roster.GetNextVolume(&volume) == B_OK) {
450 		if (volume.IsReadOnly() || !volume.IsPersistent()
451 			|| !volume.KnowsAttr() || !volume.KnowsQuery())
452 			continue;
453 		InstallIndices(volume.Device());
454 	}
455 }
456 
457 
458 void
459 TTracker::InstallIndices(dev_t device)
460 {
461 	fs_create_index(device, kAttrQueryLastChange, B_INT32_TYPE, 0);
462 	fs_create_index(device, "_trk/recentQuery", B_INT32_TYPE, 0);
463 }
464 
465 
466 void
467 TTracker::InstallDefaultTemplates()
468 {
469 	// the following templates are in big endian and we rely on the Tracker
470 	// translation support to swap them on little endian machines
471 	//
472 	// in case there is an attribute (B_RECT_TYPE) that gets swapped by the media
473 	// (unzip, file system endianness swapping, etc., the correct endianness for
474 	// the correct machine has to be used here
475 
476 	static AttributeTemplate sDefaultQueryTemplate[] =
477 		/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
478 		   application_octet-stream */
479 	{
480 		{
481 			// default frame
482 			kAttrWindowFrame,
483 			B_RECT_TYPE,
484 			16,
485 			(const char*)&kDefaultFrame
486 		},
487 		{
488 			// attr: _trk/viewstate
489 			kAttrViewState_be,
490 			B_RAW_TYPE,
491 			49,
492 			"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
493 				"\000\000\000\000\000\000\000\000\000\000\357\323\335RCSTR\000\000"
494 				"\000\000\000\000\000\000\000"
495 		},
496 		{
497 			// attr: _trk/columns
498 			kAttrColumns_be,
499 			B_RAW_TYPE,
500 			0,
501 			NULL
502 		}
503 	};
504 
505 #undef B_TRANSLATION_CONTEXT
506 #define B_TRANSLATION_CONTEXT "Default Query Columns"
507 
508 	static const ColumnData defaultQueryColumns[] =
509 	{
510 		{ B_TRANSLATE_MARK("Name"), 40, 145, B_ALIGN_LEFT, "_stat/name",
511 			B_STRING_TYPE, true, true },
512 		{ B_TRANSLATE_MARK("Path"), 200, 225, B_ALIGN_LEFT, "_trk/path",
513 			B_STRING_TYPE, false, false },
514 		{ B_TRANSLATE_MARK("Size"), 440, 41, B_ALIGN_LEFT, "_stat/size",
515 			B_OFF_T_TYPE, true, false },
516 		{ B_TRANSLATE_MARK("Modified"), 496, 138, B_ALIGN_LEFT, "_stat/modified",
517 			B_TIME_TYPE, true, false }
518 	};
519 
520 
521 	static AttributeTemplate sBookmarkQueryTemplate[] =
522 		/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
523 		   application_x-vnd.Be-bookmark */
524 	{
525 		{
526 			// default frame
527 			kAttrWindowFrame,
528 			B_RECT_TYPE,
529 			16,
530 			(const char*)&kDefaultFrame
531 		},
532 		{
533 			// attr: _trk/viewstate
534 			kAttrViewState_be,
535 			B_RAW_TYPE,
536 			49,
537 			"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
538 				"\000\000\000\000\000\000\000\000\000\000w\373\175RCSTR\000\000\000"
539 				"\000\000\000\000\000\000"
540 		},
541 		{
542 			// attr: _trk/columns
543 			kAttrColumns_be,
544 			B_RAW_TYPE,
545 			0,
546 			NULL
547 		}
548 	};
549 
550 
551 #undef B_TRANSLATION_CONTEXT
552 #define B_TRANSLATION_CONTEXT "Bookmark Query Columns"
553 
554 
555 	static const ColumnData bookmarkQueryColumns[] =
556 	{
557 		{ B_TRANSLATE_MARK("Title"), 40, 171, B_ALIGN_LEFT, "META:title",
558 			B_STRING_TYPE, false, true },
559 		{ B_TRANSLATE_MARK("URL"), 226, 287, B_ALIGN_LEFT, kAttrURL,
560 			B_STRING_TYPE, false, true },
561 		{ B_TRANSLATE_MARK("Keywords"), 528, 130, B_ALIGN_LEFT, "META:keyw",
562 			B_STRING_TYPE, false, true }
563 	};
564 
565 
566 	static AttributeTemplate sPersonQueryTemplate[] =
567 		/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
568 		   application_x-vnd.Be-bookmark */
569 	{
570 		{
571 			// default frame
572 			kAttrWindowFrame,
573 			B_RECT_TYPE,
574 			16,
575 			(const char*)&kDefaultFrame
576 		},
577 		{
578 			// attr: _trk/viewstate
579 			kAttrViewState_be,
580 			B_RAW_TYPE,
581 			49,
582 			"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
583 				"\000\000\000\000\000\000\000\000\000\000\357\323\335RCSTR\000\000"
584 				"\000\000\000\000\000\000\000"
585 		},
586 		{
587 			// attr: _trk/columns
588 			kAttrColumns_be,
589 			B_RAW_TYPE,
590 			0,
591 			NULL
592 		},
593 	};
594 
595 
596 #undef B_TRANSLATION_CONTEXT
597 #define B_TRANSLATION_CONTEXT "Person Query Columns"
598 
599 
600 	static const ColumnData personQueryColumns[] =
601 	{
602 		{ B_TRANSLATE_MARK("Name"), 40, 115, B_ALIGN_LEFT, "_stat/name",
603 			B_STRING_TYPE, true, true },
604 		{ B_TRANSLATE_MARK("Work Phone"), 170, 90, B_ALIGN_LEFT, kAttrWorkPhone,
605 			B_STRING_TYPE, false, true },
606 		{ B_TRANSLATE_MARK("E-mail"), 275, 93, B_ALIGN_LEFT, kAttrEmail,
607 			B_STRING_TYPE, false, true },
608 		{ B_TRANSLATE_MARK("Company"), 383, 120, B_ALIGN_LEFT, kAttrCompany,
609 			B_STRING_TYPE, false, true }
610 	};
611 
612 
613 	static AttributeTemplate sEmailQueryTemplate[] =
614 		/* /boot/home/config/settings/Tracker/DefaultQueryTemplates/
615 		   text_x-email */
616 	{
617 		{
618 			// default frame
619 			kAttrWindowFrame,
620 			B_RECT_TYPE,
621 			16,
622 			(const char*)&kDefaultFrame
623 		},
624 		{
625 			// attr: _trk/viewstate
626 			kAttrViewState_be,
627 			B_RAW_TYPE,
628 			49,
629 			"o^\365R\000\000\000\012Tlst\000\000\000\000\000\000\000\000\000\000"
630 				"\000\000\000\000\000\000\000\000\000\000\366_\377ETIME\000\000\000"
631 				"\000\000\000\000\000\000"
632 		},
633 		{
634 			// attr: _trk/columns
635 			kAttrColumns_be,
636 			B_RAW_TYPE,
637 			0,
638 			NULL
639 		},
640 	};
641 
642 
643 #undef B_TRANSLATION_CONTEXT
644 #define B_TRANSLATION_CONTEXT "Email Query Columns"
645 
646 
647 	static const ColumnData emailQueryColumns[] =
648 	{
649 		{ B_TRANSLATE_MARK("Subject"), 40, 110, B_ALIGN_LEFT, "MAIL:subject",
650 			B_STRING_TYPE, false, false },
651 		{ B_TRANSLATE_MARK("From"), 165, 153, B_ALIGN_LEFT, "MAIL:from",
652 			B_STRING_TYPE, false, false },
653 		{ B_TRANSLATE_MARK("When"), 333, 120, B_ALIGN_LEFT, "MAIL:when",
654 			B_STRING_TYPE, false, false },
655 		{ B_TRANSLATE_MARK("Status"), 468, 50, B_ALIGN_RIGHT, "MAIL:status",
656 			B_STRING_TYPE, false, true }
657 	};
658 
659 
660 	BNode node;
661 	BString query(kQueryTemplates);
662 	query += "/application_octet-stream";
663 
664 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
665 			&node, false)) {
666 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
667 				&node, true)) {
668 			BMallocIO stream;
669 			size_t n = mkColumnsBits(stream,
670 					defaultQueryColumns, 4, "Default Query Columns");
671 			sDefaultQueryTemplate[2].fSize = n;
672 			sDefaultQueryTemplate[2].fBits = (const char*)stream.Buffer();
673 
674 			AttributeStreamFileNode fileNode(&node);
675 			AttributeStreamTemplateNode tmp(sDefaultQueryTemplate, 3);
676 			fileNode << tmp;
677 		}
678 	}
679 
680 	(query = kQueryTemplates) += "/application_x-vnd.Be-bookmark";
681 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
682 			&node, false)) {
683 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
684 				&node, true)) {
685 			BMallocIO stream;
686 			size_t n = mkColumnsBits(stream,
687 				bookmarkQueryColumns, 3, "Bookmark Query Columns");
688 			sBookmarkQueryTemplate[2].fSize = n;
689 			sBookmarkQueryTemplate[2].fBits = (const char*)stream.Buffer();
690 
691 			AttributeStreamFileNode fileNode(&node);
692 			AttributeStreamTemplateNode tmp(sBookmarkQueryTemplate, 3);
693 			fileNode << tmp;
694 		}
695 	}
696 
697 	(query = kQueryTemplates) += "/application_x-person";
698 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
699 			&node, false)) {
700 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
701 				&node, true)) {
702 			BMallocIO stream;
703 			size_t n = mkColumnsBits(stream,
704 				personQueryColumns, 4, "Person Query Columns");
705 			sPersonQueryTemplate[2].fSize = n;
706 			sPersonQueryTemplate[2].fBits = (const char*)stream.Buffer();
707 
708 			AttributeStreamFileNode fileNode(&node);
709 			AttributeStreamTemplateNode tmp(sPersonQueryTemplate, 3);
710 			fileNode << tmp;
711 		}
712 	}
713 
714 	(query = kQueryTemplates) += "/text_x-email";
715 	if (!BContainerWindow::DefaultStateSourceNode(query.String(),
716 			&node, false)) {
717 		if (BContainerWindow::DefaultStateSourceNode(query.String(),
718 				&node, true)) {
719 			BMallocIO stream;
720 			size_t n = mkColumnsBits(stream,
721 				emailQueryColumns, 4, "Email Query Columns");
722 			sEmailQueryTemplate[2].fSize = n;
723 			sEmailQueryTemplate[2].fBits = (const char*)stream.Buffer();
724 
725 			AttributeStreamFileNode fileNode(&node);
726 			AttributeStreamTemplateNode tmp(sEmailQueryTemplate, 3);
727 			fileNode << tmp;
728 		}
729 	}
730 }
731 
732 
733 void
734 TTracker::InstallTemporaryBackgroundImages()
735 {
736 	// make the large Haiku Logo the default background
737 
738 	BPath path;
739 	status_t status = find_directory(B_SYSTEM_DATA_DIRECTORY, &path);
740 	if (status < B_OK) {
741 		// TODO: this error shouldn't be shown to the regular user
742 		BString errorMessage(B_TRANSLATE("At %func \nfind_directory() "
743 			"failed. \nReason: %error"));
744 		errorMessage.ReplaceFirst("%func", __PRETTY_FUNCTION__);
745 		errorMessage.ReplaceFirst("%error", strerror(status));
746 		BAlert* alert = new BAlert("AlertError", errorMessage.String(),
747 			B_TRANSLATE("OK"), NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT);
748 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
749 		alert->Go();
750 		return;
751 	}
752 	path.Append("artwork");
753 
754 	BString defaultBackgroundImage("/HAIKU logo - white on blue - big.png");
755 
756 	BDirectory dir;
757 	if (FSGetBootDeskDir(&dir) == B_OK) {
758 		// install a default background if there is no background defined yet
759 		attr_info info;
760 		if (dir.GetAttrInfo(kBackgroundImageInfo, &info) != B_OK) {
761 			BScreen screen(B_MAIN_SCREEN_ID);
762 			BPoint logoPos;
763 			logoPos.x
764 				= floorf((screen.Frame().Width() - 605) * (sqrtf(5) - 1) / 2);
765 			logoPos.y = floorf((screen.Frame().Height() - 190) * 0.9);
766 			BMessage message;
767 			AddTemporaryBackgroundImages(&message,
768 				(BString(path.Path()) << defaultBackgroundImage).String(),
769 				BackgroundImage::kAtOffset, logoPos, 0xffffffff, false);
770 			::InstallTemporaryBackgroundImages(&dir, &message);
771 		}
772 	}
773 }
774