19550c5ecSStephan Aßmus/*
29550c5ecSStephan Aßmus * Copyright 2015, TigerKid001.
39550c5ecSStephan Aßmus * All rights reserved. Distributed under the terms of the MIT License.
49550c5ecSStephan Aßmus */
59550c5ecSStephan Aßmus
6f52ceebaSSidhant Sharma [:TigerKid#include "PackageContentsView.h"
7f52ceebaSSidhant Sharma [:TigerKid
8f52ceebaSSidhant Sharma [:TigerKid#include <algorithm>
9f52ceebaSSidhant Sharma [:TigerKid#include <stdio.h>
10f52ceebaSSidhant Sharma [:TigerKid
11f52ceebaSSidhant Sharma [:TigerKid#include <Autolock.h>
12f52ceebaSSidhant Sharma [:TigerKid#include <Catalog.h>
1384316965SStephan Aßmus#include <FindDirectory.h>
14f52ceebaSSidhant Sharma [:TigerKid#include <LayoutBuilder.h>
15f52ceebaSSidhant Sharma [:TigerKid#include <LayoutUtils.h>
16f52ceebaSSidhant Sharma [:TigerKid#include <OutlineListView.h>
17f52ceebaSSidhant Sharma [:TigerKid#include <Path.h>
1884316965SStephan Aßmus#include <ScrollBar.h>
19f52ceebaSSidhant Sharma [:TigerKid#include <ScrollView.h>
207457ccb4SAugustin Cavalier#include <StringFormat.h>
2184316965SStephan Aßmus#include <StringItem.h>
22f52ceebaSSidhant Sharma [:TigerKid
2384316965SStephan Aßmus#include <package/PackageDefs.h>
24f52ceebaSSidhant Sharma [:TigerKid#include <package/hpkg/NoErrorOutput.h>
25f52ceebaSSidhant Sharma [:TigerKid#include <package/hpkg/PackageContentHandler.h>
26f52ceebaSSidhant Sharma [:TigerKid#include <package/hpkg/PackageEntry.h>
2784316965SStephan Aßmus#include <package/hpkg/PackageReader.h>
2884316965SStephan Aßmus
2984316965SStephan Aßmususing namespace BPackageKit;
30f52ceebaSSidhant Sharma [:TigerKid
31f52ceebaSSidhant Sharma [:TigerKidusing BPackageKit::BHPKG::BNoErrorOutput;
32f52ceebaSSidhant Sharma [:TigerKidusing BPackageKit::BHPKG::BPackageContentHandler;
33f52ceebaSSidhant Sharma [:TigerKidusing BPackageKit::BHPKG::BPackageEntry;
34f52ceebaSSidhant Sharma [:TigerKidusing BPackageKit::BHPKG::BPackageEntryAttribute;
35f52ceebaSSidhant Sharma [:TigerKidusing BPackageKit::BHPKG::BPackageInfoAttributeValue;
36f52ceebaSSidhant Sharma [:TigerKidusing BPackageKit::BHPKG::BPackageReader;
37f52ceebaSSidhant Sharma [:TigerKid
38f52ceebaSSidhant Sharma [:TigerKid#undef B_TRANSLATION_CONTEXT
39f52ceebaSSidhant Sharma [:TigerKid#define B_TRANSLATION_CONTEXT "PackageContentsView"
40f52ceebaSSidhant Sharma [:TigerKid
41f52ceebaSSidhant Sharma [:TigerKid
42f52ceebaSSidhant Sharma [:TigerKid//! Layouts the scrollbar so it looks nice with no border and the document
43f52ceebaSSidhant Sharma [:TigerKid// window look.
44f52ceebaSSidhant Sharma [:TigerKidclass CustomScrollView : public BScrollView {
45f52ceebaSSidhant Sharma [:TigerKidpublic:
46f52ceebaSSidhant Sharma [:TigerKid	CustomScrollView(const char* name, BView* target)
47f52ceebaSSidhant Sharma [:TigerKid		:
48f52ceebaSSidhant Sharma [:TigerKid		BScrollView(name, target, 0, false, true, B_NO_BORDER)
49f52ceebaSSidhant Sharma [:TigerKid	{
50f52ceebaSSidhant Sharma [:TigerKid	}
51f52ceebaSSidhant Sharma [:TigerKid
52f52ceebaSSidhant Sharma [:TigerKid	virtual void DoLayout()
53f52ceebaSSidhant Sharma [:TigerKid	{
54f52ceebaSSidhant Sharma [:TigerKid		BRect innerFrame = Bounds();
55f52ceebaSSidhant Sharma [:TigerKid		innerFrame.right -= B_V_SCROLL_BAR_WIDTH + 1;
56f52ceebaSSidhant Sharma [:TigerKid
57f52ceebaSSidhant Sharma [:TigerKid		BView* target = Target();
58f52ceebaSSidhant Sharma [:TigerKid		if (target != NULL) {
59f52ceebaSSidhant Sharma [:TigerKid			Target()->MoveTo(innerFrame.left, innerFrame.top);
60f52ceebaSSidhant Sharma [:TigerKid			Target()->ResizeTo(innerFrame.Width(), innerFrame.Height());
61f52ceebaSSidhant Sharma [:TigerKid		}
62f52ceebaSSidhant Sharma [:TigerKid
63f52ceebaSSidhant Sharma [:TigerKid		BScrollBar* scrollBar = ScrollBar(B_VERTICAL);
64f52ceebaSSidhant Sharma [:TigerKid		if (scrollBar != NULL) {
65f52ceebaSSidhant Sharma [:TigerKid			BRect rect = innerFrame;
66f52ceebaSSidhant Sharma [:TigerKid			rect.left = rect.right + 1;
67f52ceebaSSidhant Sharma [:TigerKid			rect.right = rect.left + B_V_SCROLL_BAR_WIDTH;
68f52ceebaSSidhant Sharma [:TigerKid			rect.bottom -= B_H_SCROLL_BAR_HEIGHT;
69f52ceebaSSidhant Sharma [:TigerKid
70f52ceebaSSidhant Sharma [:TigerKid			scrollBar->MoveTo(rect.left, rect.top);
71f52ceebaSSidhant Sharma [:TigerKid			scrollBar->ResizeTo(rect.Width(), rect.Height());
72f52ceebaSSidhant Sharma [:TigerKid		}
73f52ceebaSSidhant Sharma [:TigerKid	}
74f52ceebaSSidhant Sharma [:TigerKid};
75f52ceebaSSidhant Sharma [:TigerKid
769550c5ecSStephan Aßmus// #pragma mark - PackageEntryItem
779550c5ecSStephan Aßmus
789550c5ecSStephan Aßmus
799550c5ecSStephan Aßmusclass PackageEntryItem : public BStringItem {
809550c5ecSStephan Aßmuspublic:
8178814465SStephan Aßmus	PackageEntryItem(const BPackageEntry* entry, const BString& path)
829550c5ecSStephan Aßmus		:
839550c5ecSStephan Aßmus		BStringItem(entry->Name()),
8478814465SStephan Aßmus		fPath(path)
859550c5ecSStephan Aßmus	{
8678814465SStephan Aßmus		if (fPath.Length() > 0)
8778814465SStephan Aßmus			fPath.Append("/");
8878814465SStephan Aßmus		fPath.Append(entry->Name());
899550c5ecSStephan Aßmus	}
9087084745SMichael Lotz
9178814465SStephan Aßmus	inline const BString& EntryPath() const
929550c5ecSStephan Aßmus	{
9378814465SStephan Aßmus		return fPath;
949550c5ecSStephan Aßmus	}
959550c5ecSStephan Aßmus
969550c5ecSStephan Aßmusprivate:
9778814465SStephan Aßmus	BString fPath;
989550c5ecSStephan Aßmus};
999550c5ecSStephan Aßmus
100f52ceebaSSidhant Sharma [:TigerKid
1019550c5ecSStephan Aßmus// #pragma mark - PackageContentOutliner
102f52ceebaSSidhant Sharma [:TigerKid
103f52ceebaSSidhant Sharma [:TigerKid
10484316965SStephan Aßmusclass PackageContentOutliner : public BPackageContentHandler {
1059550c5ecSStephan Aßmuspublic:
10684316965SStephan Aßmus	PackageContentOutliner(BOutlineListView* listView,
10784316965SStephan Aßmus			const PackageInfo* packageInfo,
10884316965SStephan Aßmus			BLocker& packageLock, PackageInfoRef& packageInfoRef)
1099550c5ecSStephan Aßmus		:
1109550c5ecSStephan Aßmus		fListView(listView),
1119550c5ecSStephan Aßmus		fLastParentEntry(NULL),
1129550c5ecSStephan Aßmus		fLastParentItem(NULL),
1139550c5ecSStephan Aßmus		fLastEntry(NULL),
11484316965SStephan Aßmus		fLastItem(NULL),
11584316965SStephan Aßmus
11684316965SStephan Aßmus		fPackageInfoToPopulate(packageInfo),
11784316965SStephan Aßmus		fPackageLock(packageLock),
11884316965SStephan Aßmus		fPackageInfoRef(packageInfoRef)
119f52ceebaSSidhant Sharma [:TigerKid	{
120f52ceebaSSidhant Sharma [:TigerKid	}
121f52ceebaSSidhant Sharma [:TigerKid
122f52ceebaSSidhant Sharma [:TigerKid	virtual status_t HandleEntry(BPackageEntry* entry)
123f52ceebaSSidhant Sharma [:TigerKid	{
12478814465SStephan Aßmus//		printf("HandleEntry(%s/%s)\n",
12578814465SStephan Aßmus//			entry->Parent() != NULL ? entry->Parent()->Name() : "NULL",
12678814465SStephan Aßmus//			entry->Name());
12784316965SStephan Aßmus
128fed7859aSStephan Aßmus		if (fListView->LockLooperWithTimeout(1000000) != B_OK)
12984316965SStephan Aßmus			return B_ERROR;
13084316965SStephan Aßmus
13178814465SStephan Aßmus		// Check if we are still supposed to popuplate the list
13278814465SStephan Aßmus		if (fPackageInfoRef.Get() != fPackageInfoToPopulate) {
13378814465SStephan Aßmus//			printf("stopping package content population\n");
13478814465SStephan Aßmus			fListView->UnlockLooper();
13578814465SStephan Aßmus			return B_ERROR;
13678814465SStephan Aßmus		}
13778814465SStephan Aßmus
13878814465SStephan Aßmus		BString path;
13978814465SStephan Aßmus		const BPackageEntry* parent = entry->Parent();
14078814465SStephan Aßmus		while (parent != NULL) {
14178814465SStephan Aßmus			if (path.Length() > 0)
14278814465SStephan Aßmus				path.Prepend("/");
14378814465SStephan Aßmus			path.Prepend(parent->Name());
14478814465SStephan Aßmus			parent = parent->Parent();
14578814465SStephan Aßmus		}
14678814465SStephan Aßmus
14778814465SStephan Aßmus		PackageEntryItem* item = new PackageEntryItem(entry, path);
1489550c5ecSStephan Aßmus
149f52ceebaSSidhant Sharma [:TigerKid		if (entry->Parent() == NULL) {
15078814465SStephan Aßmus//			printf("  adding root entry\n");
1519550c5ecSStephan Aßmus			fListView->AddItem(item);
15284316965SStephan Aßmus			fLastParentEntry = NULL;
15384316965SStephan Aßmus			fLastParentItem = NULL;
1549550c5ecSStephan Aßmus		} else if (entry->Parent() == fLastEntry) {
15578814465SStephan Aßmus//			printf("  adding to last entry %s\n", fLastEntry->Name());
1569550c5ecSStephan Aßmus			fListView->AddUnder(item, fLastItem);
1579550c5ecSStephan Aßmus			fLastParentEntry = fLastEntry;
1589550c5ecSStephan Aßmus			fLastParentItem = fLastItem;
1599550c5ecSStephan Aßmus		} else if (entry->Parent() == fLastParentEntry) {
16078814465SStephan Aßmus//			printf("  adding to last parent %s\n", fLastParentEntry->Name());
1619550c5ecSStephan Aßmus			fListView->AddUnder(item, fLastParentItem);
162f52ceebaSSidhant Sharma [:TigerKid		} else {
1639550c5ecSStephan Aßmus			// Not the last parent entry, need to search for the parent
1649550c5ecSStephan Aßmus			// among the already added list items.
1659550c5ecSStephan Aßmus			bool foundParent = false;
16684316965SStephan Aßmus			for (int32 i = 0; i < fListView->FullListCountItems(); i++) {
1679550c5ecSStephan Aßmus				PackageEntryItem* listItem
16884316965SStephan Aßmus					= dynamic_cast<PackageEntryItem*>(
16984316965SStephan Aßmus						fListView->FullListItemAt(i));
1709550c5ecSStephan Aßmus				if (listItem == NULL)
1719550c5ecSStephan Aßmus					continue;
17278814465SStephan Aßmus				if (listItem->EntryPath() == path) {
17378814465SStephan Aßmus					fLastParentEntry = entry->Parent();
1749550c5ecSStephan Aßmus					fLastParentItem = listItem;
17578814465SStephan Aßmus//					printf("  found parent %s\n", listItem->Text());
17684316965SStephan Aßmus					fListView->AddUnder(item, listItem);
1779550c5ecSStephan Aßmus					foundParent = true;
1789550c5ecSStephan Aßmus					break;
1799550c5ecSStephan Aßmus				}
1809550c5ecSStephan Aßmus			}
1819550c5ecSStephan Aßmus			if (!foundParent) {
1829550c5ecSStephan Aßmus				// NOTE: Should not happen. Just add this entry at the
1839550c5ecSStephan Aßmus				// root level.
18478814465SStephan Aßmus//				printf("Did not find parent entry for %s (%s)!\n",
18578814465SStephan Aßmus//					entry->Name(), entry->Parent()->Name());
1869550c5ecSStephan Aßmus				fListView->AddItem(item);
18784316965SStephan Aßmus				fLastParentEntry = NULL;
18884316965SStephan Aßmus				fLastParentItem = NULL;
189f52ceebaSSidhant Sharma [:TigerKid			}
190f52ceebaSSidhant Sharma [:TigerKid		}
1919550c5ecSStephan Aßmus
1929550c5ecSStephan Aßmus		fLastEntry = entry;
1939550c5ecSStephan Aßmus		fLastItem = item;
1949550c5ecSStephan Aßmus
19584316965SStephan Aßmus		fListView->UnlockLooper();
19684316965SStephan Aßmus
197f52ceebaSSidhant Sharma [:TigerKid		return B_OK;
198f52ceebaSSidhant Sharma [:TigerKid	}
199f52ceebaSSidhant Sharma [:TigerKid
200f52ceebaSSidhant Sharma [:TigerKid	virtual status_t HandleEntryAttribute(BPackageEntry* entry,
201f52ceebaSSidhant Sharma [:TigerKid		BPackageEntryAttribute* attribute)
202f52ceebaSSidhant Sharma [:TigerKid	{
203f52ceebaSSidhant Sharma [:TigerKid		return B_OK;
204f52ceebaSSidhant Sharma [:TigerKid	}
205f52ceebaSSidhant Sharma [:TigerKid
206f52ceebaSSidhant Sharma [:TigerKid	virtual status_t HandleEntryDone(BPackageEntry* entry)
207f52ceebaSSidhant Sharma [:TigerKid	{
208f52ceebaSSidhant Sharma [:TigerKid		return B_OK;
209f52ceebaSSidhant Sharma [:TigerKid	}
210f52ceebaSSidhant Sharma [:TigerKid
211f52ceebaSSidhant Sharma [:TigerKid	virtual status_t HandlePackageAttribute(
212f52ceebaSSidhant Sharma [:TigerKid		const BPackageInfoAttributeValue& value)
213f52ceebaSSidhant Sharma [:TigerKid	{
214f52ceebaSSidhant Sharma [:TigerKid		return B_OK;
215f52ceebaSSidhant Sharma [:TigerKid	}
21687084745SMichael Lotz
217f52ceebaSSidhant Sharma [:TigerKid	virtual void HandleErrorOccurred()
218f52ceebaSSidhant Sharma [:TigerKid	{
219f52ceebaSSidhant Sharma [:TigerKid	}
22087084745SMichael Lotz
2219550c5ecSStephan Aßmusprivate:
2229550c5ecSStephan Aßmus	BOutlineListView*		fListView;
2239550c5ecSStephan Aßmus
2249550c5ecSStephan Aßmus	const BPackageEntry*	fLastParentEntry;
2259550c5ecSStephan Aßmus	PackageEntryItem*		fLastParentItem;
2269550c5ecSStephan Aßmus
2279550c5ecSStephan Aßmus	const BPackageEntry*	fLastEntry;
2289550c5ecSStephan Aßmus	PackageEntryItem*		fLastItem;
22984316965SStephan Aßmus
23084316965SStephan Aßmus	const PackageInfo*		fPackageInfoToPopulate;
23184316965SStephan Aßmus	BLocker&				fPackageLock;
23284316965SStephan Aßmus	PackageInfoRef&			fPackageInfoRef;
233f52ceebaSSidhant Sharma [:TigerKid};
234f52ceebaSSidhant Sharma [:TigerKid
235f52ceebaSSidhant Sharma [:TigerKid
236f52ceebaSSidhant Sharma [:TigerKid// #pragma mark - PackageContentView
237f52ceebaSSidhant Sharma [:TigerKid
238f52ceebaSSidhant Sharma [:TigerKid
2399550c5ecSStephan AßmusPackageContentsView::PackageContentsView(const char* name)
240f52ceebaSSidhant Sharma [:TigerKid	:
2419550c5ecSStephan Aßmus	BView("package_contents_view", B_WILL_DRAW),
24236ab52c7SStephan Aßmus	fPackageLock("package contents populator lock"),
24336ab52c7SStephan Aßmus	fLastPackageState(NONE)
244f52ceebaSSidhant Sharma [:TigerKid{
24587084745SMichael Lotz	fContentListView = new BOutlineListView("content list view",
2469550c5ecSStephan Aßmus		B_SINGLE_SELECTION_LIST);
24787084745SMichael Lotz
24887084745SMichael Lotz	BScrollView* scrollView = new CustomScrollView("contents scroll view",
2499550c5ecSStephan Aßmus		fContentListView);
25087084745SMichael Lotz
251f52ceebaSSidhant Sharma [:TigerKid	BLayoutBuilder::Group<>(this)
252f52ceebaSSidhant Sharma [:TigerKid		.Add(scrollView, 1.0f)
2539550c5ecSStephan Aßmus		.SetInsets(0.0f, -1.0f, -1.0f, -1.0f)
254f52ceebaSSidhant Sharma [:TigerKid	;
25584316965SStephan Aßmus
25684316965SStephan Aßmus	_InitContentPopulator();
257f52ceebaSSidhant Sharma [:TigerKid}
258f52ceebaSSidhant Sharma [:TigerKid
259f52ceebaSSidhant Sharma [:TigerKid
260f52ceebaSSidhant Sharma [:TigerKidPackageContentsView::~PackageContentsView()
261f52ceebaSSidhant Sharma [:TigerKid{
2629550c5ecSStephan Aßmus	Clear();
26384316965SStephan Aßmus
26484316965SStephan Aßmus	delete_sem(fContentPopulatorSem);
26584316965SStephan Aßmus	if (fContentPopulator >= 0)
26684316965SStephan Aßmus		wait_for_thread(fContentPopulator, NULL);
267f52ceebaSSidhant Sharma [:TigerKid}
268f52ceebaSSidhant Sharma [:TigerKid
269f52ceebaSSidhant Sharma [:TigerKid
270f52ceebaSSidhant Sharma [:TigerKidvoid
271f52ceebaSSidhant Sharma [:TigerKidPackageContentsView::AttachedToWindow()
272f52ceebaSSidhant Sharma [:TigerKid{
273f52ceebaSSidhant Sharma [:TigerKid	BView::AttachedToWindow();
274f52ceebaSSidhant Sharma [:TigerKid}
275f52ceebaSSidhant Sharma [:TigerKid
276f52ceebaSSidhant Sharma [:TigerKid
277f52ceebaSSidhant Sharma [:TigerKidvoid
278f52ceebaSSidhant Sharma [:TigerKidPackageContentsView::AllAttached()
279f52ceebaSSidhant Sharma [:TigerKid{
280f52ceebaSSidhant Sharma [:TigerKid	BView::AllAttached();
281f52ceebaSSidhant Sharma [:TigerKid}
282f52ceebaSSidhant Sharma [:TigerKid
283f52ceebaSSidhant Sharma [:TigerKid
284f52ceebaSSidhant Sharma [:TigerKidvoid
28584316965SStephan AßmusPackageContentsView::SetPackage(const PackageInfoRef& package)
286f52ceebaSSidhant Sharma [:TigerKid{
28736ab52c7SStephan Aßmus	// When getting a ref to the same package, don't return when the
28836ab52c7SStephan Aßmus	// package state has changed, since in that case, we may now be able
28936ab52c7SStephan Aßmus	// to read contents where we previously could not. (For example, the
29036ab52c7SStephan Aßmus	// package has been installed.)
29136ab52c7SStephan Aßmus	if (fPackage == package
29236ab52c7SStephan Aßmus		&& (package.Get() == NULL || package->State() == fLastPackageState)) {
29384316965SStephan Aßmus		return;
29436ab52c7SStephan Aßmus	}
29584316965SStephan Aßmus
29678814465SStephan Aßmus//	printf("PackageContentsView::SetPackage(%s)\n",
29772992391SStephan Aßmus//		package.Get() != NULL ? package->Name().String() : "NULL");
29884316965SStephan Aßmus
2999550c5ecSStephan Aßmus	Clear();
3009550c5ecSStephan Aßmus
30184316965SStephan Aßmus	{
30284316965SStephan Aßmus		BAutolock lock(&fPackageLock);
30384316965SStephan Aßmus		fPackage = package;
30436ab52c7SStephan Aßmus		fLastPackageState = package.Get() != NULL ? package->State() : NONE;
30584316965SStephan Aßmus	}
30684316965SStephan Aßmus	release_sem_etc(fContentPopulatorSem, 1, 0);
30784316965SStephan Aßmus}
30884316965SStephan Aßmus
30984316965SStephan Aßmus
31087084745SMichael Lotzvoid
31184316965SStephan AßmusPackageContentsView::Clear()
31284316965SStephan Aßmus{
31384316965SStephan Aßmus	{
31484316965SStephan Aßmus		BAutolock lock(&fPackageLock);
31584316965SStephan Aßmus		fPackage.Unset();
31684316965SStephan Aßmus	}
31784316965SStephan Aßmus
31884316965SStephan Aßmus	fContentListView->MakeEmpty();
31984316965SStephan Aßmus}
32084316965SStephan Aßmus
32184316965SStephan Aßmus
32284316965SStephan Aßmus// #pragma mark - private
32384316965SStephan Aßmus
32484316965SStephan Aßmus
32584316965SStephan Aßmusvoid
32684316965SStephan AßmusPackageContentsView::_InitContentPopulator()
32784316965SStephan Aßmus{
32884316965SStephan Aßmus	fContentPopulatorSem = create_sem(0, "PopulatePackageContents");
32984316965SStephan Aßmus	if (fContentPopulatorSem >= 0) {
33084316965SStephan Aßmus		fContentPopulator = spawn_thread(&_ContentPopulatorThread,
33184316965SStephan Aßmus			"Package Contents Populator", B_NORMAL_PRIORITY, this);
33284316965SStephan Aßmus		if (fContentPopulator >= 0)
33384316965SStephan Aßmus			resume_thread(fContentPopulator);
33484316965SStephan Aßmus	} else
33584316965SStephan Aßmus		fContentPopulator = -1;
33684316965SStephan Aßmus}
33784316965SStephan Aßmus
33884316965SStephan Aßmus
33984316965SStephan Aßmus/*static*/ int32
34084316965SStephan AßmusPackageContentsView::_ContentPopulatorThread(void* arg)
34184316965SStephan Aßmus{
34284316965SStephan Aßmus	PackageContentsView* view = reinterpret_cast<PackageContentsView*>(arg);
34384316965SStephan Aßmus
34484316965SStephan Aßmus	while (acquire_sem(view->fContentPopulatorSem) == B_OK) {
34584316965SStephan Aßmus		PackageInfoRef package;
34684316965SStephan Aßmus		{
34784316965SStephan Aßmus			BAutolock lock(&view->fPackageLock);
34884316965SStephan Aßmus			package = view->fPackage;
34984316965SStephan Aßmus		}
35084316965SStephan Aßmus
35120988420SStephan Aßmus		if (package.Get() != NULL) {
35220988420SStephan Aßmus			if (!view->_PopuplatePackageContens(*package.Get())) {
353fed7859aSStephan Aßmus				if (view->LockLooperWithTimeout(1000000) == B_OK) {
35420988420SStephan Aßmus					view->fContentListView->AddItem(
35520988420SStephan Aßmus						new BStringItem(B_TRANSLATE("<Package contents not "
35620988420SStephan Aßmus							"available for remote packages>")));
35720988420SStephan Aßmus					view->UnlockLooper();
35820988420SStephan Aßmus				}
35920988420SStephan Aßmus			}
36020988420SStephan Aßmus		}
36184316965SStephan Aßmus	}
36284316965SStephan Aßmus
36384316965SStephan Aßmus	return 0;
36484316965SStephan Aßmus}
36584316965SStephan Aßmus
36684316965SStephan Aßmus
36720988420SStephan Aßmusbool
36884316965SStephan AßmusPackageContentsView::_PopuplatePackageContens(const PackageInfo& package)
36984316965SStephan Aßmus{
37084316965SStephan Aßmus	BPath packagePath;
37184316965SStephan Aßmus
37284316965SStephan Aßmus	// Obtain path to the package file
37384316965SStephan Aßmus	if (package.IsLocalFile()) {
374f52ceebaSSidhant Sharma [:TigerKid		BString pathString = package.LocalFilePath();
375f52ceebaSSidhant Sharma [:TigerKid		packagePath.SetTo(pathString.String());
37684316965SStephan Aßmus	} else {
37784316965SStephan Aßmus		int32 installLocation = _InstallLocation(package);
37884316965SStephan Aßmus		if (installLocation == B_PACKAGE_INSTALLATION_LOCATION_SYSTEM) {
37984316965SStephan Aßmus			if (find_directory(B_SYSTEM_PACKAGES_DIRECTORY, &packagePath)
38084316965SStephan Aßmus				!= B_OK) {
38120988420SStephan Aßmus				return false;
38284316965SStephan Aßmus			}
38384316965SStephan Aßmus		} else if (installLocation == B_PACKAGE_INSTALLATION_LOCATION_HOME) {
38484316965SStephan Aßmus			if (find_directory(B_USER_PACKAGES_DIRECTORY, &packagePath)
38584316965SStephan Aßmus				!= B_OK) {
38620988420SStephan Aßmus				return false;
38784316965SStephan Aßmus			}
38884316965SStephan Aßmus		} else {
38984316965SStephan Aßmus			printf("PackageContentsView::_PopuplatePackageContens(): "
39084316965SStephan Aßmus				"unknown install location");
39120988420SStephan Aßmus			return false;
3929550c5ecSStephan Aßmus		}
39384316965SStephan Aßmus
39484316965SStephan Aßmus		packagePath.Append(package.FileName());
39584316965SStephan Aßmus	}
39684316965SStephan Aßmus
39784316965SStephan Aßmus	// Setup a BPackageReader
39884316965SStephan Aßmus	BNoErrorOutput errorOutput;
39984316965SStephan Aßmus	BPackageReader reader(&errorOutput);
40084316965SStephan Aßmus
40184316965SStephan Aßmus	status_t status = reader.Init(packagePath.Path());
40284316965SStephan Aßmus	if (status != B_OK) {
40384316965SStephan Aßmus		printf("PackageContentsView::_PopuplatePackageContens(): "
40484316965SStephan Aßmus			"failed to init BPackageReader(%s): %s\n",
40584316965SStephan Aßmus			packagePath.Path(), strerror(status));
40620988420SStephan Aßmus		return false;
40784316965SStephan Aßmus	}
40884316965SStephan Aßmus
40984316965SStephan Aßmus	// Scan package contents and populate list
41084316965SStephan Aßmus	PackageContentOutliner contentHandler(fContentListView, &package,
41184316965SStephan Aßmus		fPackageLock, fPackage);
41284316965SStephan Aßmus	status = reader.ParseContent(&contentHandler);
41384316965SStephan Aßmus	if (status != B_OK) {
414fed7859aSStephan Aßmus		printf("PackageContentsView::_PopuplatePackageContens(): "
41584316965SStephan Aßmus			"failed parse package contents: %s\n", strerror(status));
41620988420SStephan Aßmus		// NOTE: Do not return false, since it taken to mean this
417fed7859aSStephan Aßmus		// is a remote package, but is it not, we simply want to stop
418fed7859aSStephan Aßmus		// populating the contents early.
419f52ceebaSSidhant Sharma [:TigerKid	}
42020988420SStephan Aßmus	return true;
421f52ceebaSSidhant Sharma [:TigerKid}
422f52ceebaSSidhant Sharma [:TigerKid
423f52ceebaSSidhant Sharma [:TigerKid
42484316965SStephan Aßmusint32
42584316965SStephan AßmusPackageContentsView::_InstallLocation(const PackageInfo& package) const
4269550c5ecSStephan Aßmus{
42784316965SStephan Aßmus	const PackageInstallationLocationSet& locations
42884316965SStephan Aßmus		= package.InstallationLocations();
42984316965SStephan Aßmus
43084316965SStephan Aßmus	// If the package is already installed, return its first installed location
43184316965SStephan Aßmus	if (locations.size() != 0)
43284316965SStephan Aßmus		return *locations.begin();
43384316965SStephan Aßmus
43484316965SStephan Aßmus	return B_PACKAGE_INSTALLATION_LOCATION_SYSTEM;
435f52ceebaSSidhant Sharma [:TigerKid}
436