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