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