xref: /haiku/src/apps/mediaplayer/playlist/FilePlaylistItem.cpp (revision 582b7d16856bef57f65c055a2051a1297c13bda3)
1c60fcc87SStephan Aßmus /*
2f70b711fSStephan Aßmus  * Copyright 2009-2010 Stephan Aßmus <superstippi@gmx.de>
3c60fcc87SStephan Aßmus  * All rights reserved. Distributed under the terms of the MIT license.
4c60fcc87SStephan Aßmus  */
5c60fcc87SStephan Aßmus 
6c60fcc87SStephan Aßmus #include "FilePlaylistItem.h"
7c60fcc87SStephan Aßmus 
8c60fcc87SStephan Aßmus #include <stdio.h>
9c60fcc87SStephan Aßmus 
10c60fcc87SStephan Aßmus #include <new>
11c60fcc87SStephan Aßmus 
12c60fcc87SStephan Aßmus #include <Directory.h>
13c60fcc87SStephan Aßmus #include <File.h>
14c60fcc87SStephan Aßmus #include <FindDirectory.h>
15c60fcc87SStephan Aßmus #include <MediaFile.h>
16b5387effSMarkus Himmel #include <MediaTrack.h>
17c60fcc87SStephan Aßmus #include <Path.h>
18ec2878c3SPhilippe Houdoin #include <TranslationUtils.h>
19c60fcc87SStephan Aßmus 
20f70b711fSStephan Aßmus #include "MediaFileTrackSupplier.h"
21c8ccdf52SStephan Aßmus #include "SubTitlesSRT.h"
22f70b711fSStephan Aßmus 
23c60fcc87SStephan Aßmus static const char* kPathKey = "path";
24c60fcc87SStephan Aßmus 
FilePlaylistItem(const entry_ref & ref)25c60fcc87SStephan Aßmus FilePlaylistItem::FilePlaylistItem(const entry_ref& ref)
26c60fcc87SStephan Aßmus {
27ec2878c3SPhilippe Houdoin 	fRefs.push_back(ref);
28ec2878c3SPhilippe Houdoin 	fNamesInTrash.push_back("");
29c60fcc87SStephan Aßmus }
30c60fcc87SStephan Aßmus 
31c60fcc87SStephan Aßmus 
FilePlaylistItem(const FilePlaylistItem & other)32c60fcc87SStephan Aßmus FilePlaylistItem::FilePlaylistItem(const FilePlaylistItem& other)
33c60fcc87SStephan Aßmus 	:
34ec2878c3SPhilippe Houdoin 	fRefs(other.fRefs),
35ec2878c3SPhilippe Houdoin 	fNamesInTrash(other.fNamesInTrash),
36ec2878c3SPhilippe Houdoin 	fImageRefs(other.fImageRefs),
37ec2878c3SPhilippe Houdoin 	fImageNamesInTrash(other.fImageNamesInTrash)
38c60fcc87SStephan Aßmus {
39c60fcc87SStephan Aßmus }
40c60fcc87SStephan Aßmus 
41c60fcc87SStephan Aßmus 
FilePlaylistItem(const BMessage * archive)42c60fcc87SStephan Aßmus FilePlaylistItem::FilePlaylistItem(const BMessage* archive)
43c60fcc87SStephan Aßmus {
44c60fcc87SStephan Aßmus 	const char* path;
45ec2878c3SPhilippe Houdoin 	entry_ref	ref;
46ec2878c3SPhilippe Houdoin 	if (archive != NULL) {
47ec2878c3SPhilippe Houdoin 		int32 i = 0;
48ec2878c3SPhilippe Houdoin 		while (archive->FindString(kPathKey, i, &path) == B_OK) {
49ec2878c3SPhilippe Houdoin 			if (get_ref_for_path(path, &ref) == B_OK) {
50ec2878c3SPhilippe Houdoin 				fRefs.push_back(ref);
51ec2878c3SPhilippe Houdoin 			}
52ec2878c3SPhilippe Houdoin 			i++;
53ec2878c3SPhilippe Houdoin 		}
54ec2878c3SPhilippe Houdoin 	}
55ec2878c3SPhilippe Houdoin 	if (fRefs.empty()) {
56ec2878c3SPhilippe Houdoin 		fRefs.push_back(entry_ref());
57ec2878c3SPhilippe Houdoin 	}
58ec2878c3SPhilippe Houdoin 	for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) {
59ec2878c3SPhilippe Houdoin 		fNamesInTrash.push_back("");
60c60fcc87SStephan Aßmus 	}
61c60fcc87SStephan Aßmus }
62c60fcc87SStephan Aßmus 
63c60fcc87SStephan Aßmus 
~FilePlaylistItem()64c60fcc87SStephan Aßmus FilePlaylistItem::~FilePlaylistItem()
65c60fcc87SStephan Aßmus {
66c60fcc87SStephan Aßmus }
67c60fcc87SStephan Aßmus 
68c60fcc87SStephan Aßmus 
69c60fcc87SStephan Aßmus PlaylistItem*
Clone() const70c60fcc87SStephan Aßmus FilePlaylistItem::Clone() const
71c60fcc87SStephan Aßmus {
72c60fcc87SStephan Aßmus 	return new (std::nothrow) FilePlaylistItem(*this);
73c60fcc87SStephan Aßmus }
74c60fcc87SStephan Aßmus 
75c60fcc87SStephan Aßmus 
76c60fcc87SStephan Aßmus BArchivable*
Instantiate(BMessage * archive)77c60fcc87SStephan Aßmus FilePlaylistItem::Instantiate(BMessage* archive)
78c60fcc87SStephan Aßmus {
79c60fcc87SStephan Aßmus 	if (validate_instantiation(archive, "FilePlaylistItem"))
80c60fcc87SStephan Aßmus 		return new (std::nothrow) FilePlaylistItem(archive);
81c60fcc87SStephan Aßmus 
82c60fcc87SStephan Aßmus 	return NULL;
83c60fcc87SStephan Aßmus }
84c60fcc87SStephan Aßmus 
85c60fcc87SStephan Aßmus 
86c60fcc87SStephan Aßmus // #pragma mark -
87c60fcc87SStephan Aßmus 
88c60fcc87SStephan Aßmus 
89c60fcc87SStephan Aßmus status_t
Archive(BMessage * into,bool deep) const90c60fcc87SStephan Aßmus FilePlaylistItem::Archive(BMessage* into, bool deep) const
91c60fcc87SStephan Aßmus {
92c60fcc87SStephan Aßmus 	status_t ret = BArchivable::Archive(into, deep);
93c60fcc87SStephan Aßmus 	if (ret != B_OK)
94c60fcc87SStephan Aßmus 		return ret;
95ec2878c3SPhilippe Houdoin 	for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) {
96ec2878c3SPhilippe Houdoin 		BPath path(&fRefs[i]);
97c60fcc87SStephan Aßmus 		ret = path.InitCheck();
98ec2878c3SPhilippe Houdoin 		if (ret != B_OK)
99c60fcc87SStephan Aßmus 			return ret;
100ec2878c3SPhilippe Houdoin 		ret = into->AddString(kPathKey, path.Path());
101ec2878c3SPhilippe Houdoin 		if (ret != B_OK)
102ec2878c3SPhilippe Houdoin 			return ret;
103ec2878c3SPhilippe Houdoin 	}
104ec2878c3SPhilippe Houdoin 	return B_OK;
105c60fcc87SStephan Aßmus }
106c60fcc87SStephan Aßmus 
107c60fcc87SStephan Aßmus 
108c60fcc87SStephan Aßmus status_t
SetAttribute(const Attribute & attribute,const BString & string)109c60fcc87SStephan Aßmus FilePlaylistItem::SetAttribute(const Attribute& attribute,
110c60fcc87SStephan Aßmus 	const BString& string)
111c60fcc87SStephan Aßmus {
112f70b711fSStephan Aßmus 	switch (attribute) {
113f70b711fSStephan Aßmus 		case ATTR_STRING_NAME:
114f70b711fSStephan Aßmus 		{
115ec2878c3SPhilippe Houdoin 			BEntry entry(&fRefs[0], false);
116f70b711fSStephan Aßmus 			return entry.Rename(string.String(), false);
117f70b711fSStephan Aßmus 		}
118f70b711fSStephan Aßmus 
119f70b711fSStephan Aßmus 		case ATTR_STRING_KEYWORDS:
120f70b711fSStephan Aßmus 			return _SetAttribute("Meta:Keywords", B_STRING_TYPE,
121f70b711fSStephan Aßmus 				string.String(), string.Length());
122f70b711fSStephan Aßmus 
123f70b711fSStephan Aßmus 		case ATTR_STRING_ARTIST:
124f70b711fSStephan Aßmus 			return _SetAttribute("Audio:Artist", B_STRING_TYPE,
125f70b711fSStephan Aßmus 				string.String(), string.Length());
126f70b711fSStephan Aßmus 		case ATTR_STRING_AUTHOR:
127f70b711fSStephan Aßmus 			return _SetAttribute("Media:Author", B_STRING_TYPE,
128f70b711fSStephan Aßmus 				string.String(), string.Length());
129f70b711fSStephan Aßmus 		case ATTR_STRING_ALBUM:
130f70b711fSStephan Aßmus 			return _SetAttribute("Audio:Album", B_STRING_TYPE,
131f70b711fSStephan Aßmus 				string.String(), string.Length());
132f70b711fSStephan Aßmus 		case ATTR_STRING_TITLE:
133f70b711fSStephan Aßmus 			return _SetAttribute("Media:Title", B_STRING_TYPE,
134f70b711fSStephan Aßmus 				string.String(), string.Length());
135f70b711fSStephan Aßmus 		case ATTR_STRING_AUDIO_BITRATE:
136f70b711fSStephan Aßmus 			return _SetAttribute("Audio:Bitrate", B_STRING_TYPE,
137f70b711fSStephan Aßmus 				string.String(), string.Length());
138f70b711fSStephan Aßmus 		case ATTR_STRING_VIDEO_BITRATE:
139f70b711fSStephan Aßmus 			return _SetAttribute("Video:Bitrate", B_STRING_TYPE,
140f70b711fSStephan Aßmus 				string.String(), string.Length());
141f70b711fSStephan Aßmus 
142f70b711fSStephan Aßmus 		default:
143c60fcc87SStephan Aßmus 			return B_NOT_SUPPORTED;
144c60fcc87SStephan Aßmus 	}
145f70b711fSStephan Aßmus }
146c60fcc87SStephan Aßmus 
147c60fcc87SStephan Aßmus 
148c60fcc87SStephan Aßmus status_t
GetAttribute(const Attribute & attribute,BString & string) const149c60fcc87SStephan Aßmus FilePlaylistItem::GetAttribute(const Attribute& attribute,
150c60fcc87SStephan Aßmus 	BString& string) const
151c60fcc87SStephan Aßmus {
152c60fcc87SStephan Aßmus 	if (attribute == ATTR_STRING_NAME) {
153*582b7d16SAdrien Destugues 		if (fRefs[0].name == NULL)
154*582b7d16SAdrien Destugues 			return B_NAME_NOT_FOUND;
155ec2878c3SPhilippe Houdoin 		string = fRefs[0].name;
156c60fcc87SStephan Aßmus 		return B_OK;
157c60fcc87SStephan Aßmus 	}
158f70b711fSStephan Aßmus 
159c60fcc87SStephan Aßmus 	return B_NOT_SUPPORTED;
160c60fcc87SStephan Aßmus }
161c60fcc87SStephan Aßmus 
162c60fcc87SStephan Aßmus 
163c60fcc87SStephan Aßmus status_t
SetAttribute(const Attribute & attribute,const int32 & value)164c60fcc87SStephan Aßmus FilePlaylistItem::SetAttribute(const Attribute& attribute,
165c60fcc87SStephan Aßmus 	const int32& value)
166c60fcc87SStephan Aßmus {
167f70b711fSStephan Aßmus 	switch (attribute) {
168f70b711fSStephan Aßmus 		case ATTR_INT32_TRACK:
169f70b711fSStephan Aßmus 			return _SetAttribute("Audio:Track", B_INT32_TYPE, &value,
170f70b711fSStephan Aßmus 				sizeof(int32));
171f70b711fSStephan Aßmus 		case ATTR_INT32_YEAR:
172f70b711fSStephan Aßmus 			return _SetAttribute("Media:Year", B_INT32_TYPE, &value,
173f70b711fSStephan Aßmus 				sizeof(int32));
174f70b711fSStephan Aßmus 		case ATTR_INT32_RATING:
175f70b711fSStephan Aßmus 			return _SetAttribute("Media:Rating", B_INT32_TYPE, &value,
176f70b711fSStephan Aßmus 				sizeof(int32));
177f70b711fSStephan Aßmus 
178f70b711fSStephan Aßmus 		default:
179c60fcc87SStephan Aßmus 			return B_NOT_SUPPORTED;
180c60fcc87SStephan Aßmus 	}
181f70b711fSStephan Aßmus }
182c60fcc87SStephan Aßmus 
183c60fcc87SStephan Aßmus 
184c60fcc87SStephan Aßmus status_t
GetAttribute(const Attribute & attribute,int32 & value) const185c60fcc87SStephan Aßmus FilePlaylistItem::GetAttribute(const Attribute& attribute,
186c60fcc87SStephan Aßmus 	int32& value) const
187c60fcc87SStephan Aßmus {
18886950f4eSCodeforEvolution 	switch (attribute) {
18986950f4eSCodeforEvolution 		case ATTR_INT32_TRACK:
19086950f4eSCodeforEvolution 			return _GetAttribute("Audio:Track", B_INT32_TYPE, &value,
19186950f4eSCodeforEvolution 				sizeof(int32));
19286950f4eSCodeforEvolution 		case ATTR_INT32_YEAR:
19386950f4eSCodeforEvolution 			return _GetAttribute("Media:Year", B_INT32_TYPE, &value,
19486950f4eSCodeforEvolution 				sizeof(int32));
19586950f4eSCodeforEvolution 		case ATTR_INT32_RATING:
19686950f4eSCodeforEvolution 			return _GetAttribute("Media:Rating", B_INT32_TYPE, &value,
19786950f4eSCodeforEvolution 				sizeof(int32));
19886950f4eSCodeforEvolution 
19986950f4eSCodeforEvolution 		default:
200c60fcc87SStephan Aßmus 			return B_NOT_SUPPORTED;
201c60fcc87SStephan Aßmus 	}
20286950f4eSCodeforEvolution }
203c60fcc87SStephan Aßmus 
204c60fcc87SStephan Aßmus 
205c60fcc87SStephan Aßmus status_t
SetAttribute(const Attribute & attribute,const int64 & value)206c60fcc87SStephan Aßmus FilePlaylistItem::SetAttribute(const Attribute& attribute,
207c60fcc87SStephan Aßmus 	const int64& value)
208c60fcc87SStephan Aßmus {
2091c68b67aSMarkus Himmel 	switch (attribute) {
2103248de3dSJulien Lepiller 		case ATTR_INT64_FRAME:
2113248de3dSJulien Lepiller 			return _SetAttribute("Media:Frame", B_INT64_TYPE, &value,
2123248de3dSJulien Lepiller 				sizeof(int64));
2131c68b67aSMarkus Himmel 		case ATTR_INT64_DURATION:
2141c68b67aSMarkus Himmel 			return _SetAttribute("Media:Length", B_INT64_TYPE, &value,
2151c68b67aSMarkus Himmel 				sizeof(int64));
2161c68b67aSMarkus Himmel 		default:
217c60fcc87SStephan Aßmus 			return B_NOT_SUPPORTED;
218c60fcc87SStephan Aßmus 	}
2191c68b67aSMarkus Himmel }
220c60fcc87SStephan Aßmus 
221c60fcc87SStephan Aßmus 
222c60fcc87SStephan Aßmus status_t
GetAttribute(const Attribute & attribute,int64 & value) const223c60fcc87SStephan Aßmus FilePlaylistItem::GetAttribute(const Attribute& attribute,
224c60fcc87SStephan Aßmus 	int64& value) const
225c60fcc87SStephan Aßmus {
2261c68b67aSMarkus Himmel 	switch (attribute) {
2273248de3dSJulien Lepiller 		case ATTR_INT64_FRAME:
2283248de3dSJulien Lepiller 			return _GetAttribute("Media:Frame", B_INT64_TYPE, &value,
2293248de3dSJulien Lepiller 				sizeof(int64));
2301c68b67aSMarkus Himmel 		case ATTR_INT64_DURATION:
2311c68b67aSMarkus Himmel 			return _GetAttribute("Media:Length", B_INT64_TYPE, &value,
2321c68b67aSMarkus Himmel 				sizeof(int64));
2331c68b67aSMarkus Himmel 		default:
234c60fcc87SStephan Aßmus 			return B_NOT_SUPPORTED;
235c60fcc87SStephan Aßmus 	}
2361c68b67aSMarkus Himmel }
237c60fcc87SStephan Aßmus 
238c60fcc87SStephan Aßmus 
2393248de3dSJulien Lepiller status_t
SetAttribute(const Attribute & attribute,const float & value)2403248de3dSJulien Lepiller FilePlaylistItem::SetAttribute(const Attribute& attribute,
2413248de3dSJulien Lepiller 	const float& value)
2423248de3dSJulien Lepiller {
2433248de3dSJulien Lepiller 	if (attribute == ATTR_FLOAT_VOLUME) {
2443248de3dSJulien Lepiller 		return _SetAttribute("Media:Volume", B_FLOAT_TYPE, &value,
2453248de3dSJulien Lepiller 			sizeof(float));
2463248de3dSJulien Lepiller 	}
2473248de3dSJulien Lepiller 
2483248de3dSJulien Lepiller 	return B_NOT_SUPPORTED;
2493248de3dSJulien Lepiller }
2503248de3dSJulien Lepiller 
2513248de3dSJulien Lepiller 
2523248de3dSJulien Lepiller status_t
GetAttribute(const Attribute & attribute,float & value) const2533248de3dSJulien Lepiller FilePlaylistItem::GetAttribute(const Attribute& attribute,
2543248de3dSJulien Lepiller 	float& value) const
2553248de3dSJulien Lepiller {
2563248de3dSJulien Lepiller 	if (attribute == ATTR_FLOAT_VOLUME) {
2573248de3dSJulien Lepiller 		return _GetAttribute("Media:Volume", B_FLOAT_TYPE, &value,
2583248de3dSJulien Lepiller 			sizeof(float));
2593248de3dSJulien Lepiller 	}
2603248de3dSJulien Lepiller 
2613248de3dSJulien Lepiller 	return B_NOT_SUPPORTED;
2623248de3dSJulien Lepiller }
2633248de3dSJulien Lepiller 
2643248de3dSJulien Lepiller 
265c60fcc87SStephan Aßmus // #pragma mark -
266c60fcc87SStephan Aßmus 
267c60fcc87SStephan Aßmus 
268c60fcc87SStephan Aßmus BString
LocationURI() const269c60fcc87SStephan Aßmus FilePlaylistItem::LocationURI() const
270c60fcc87SStephan Aßmus {
271ec2878c3SPhilippe Houdoin 	BPath path(&fRefs[0]);
272c60fcc87SStephan Aßmus 	BString locationURI("file://");
273c60fcc87SStephan Aßmus 	locationURI << path.Path();
274c60fcc87SStephan Aßmus 	return locationURI;
275c60fcc87SStephan Aßmus }
276c60fcc87SStephan Aßmus 
277c60fcc87SStephan Aßmus 
278c60fcc87SStephan Aßmus status_t
GetIcon(BBitmap * bitmap,icon_size iconSize) const279c60fcc87SStephan Aßmus FilePlaylistItem::GetIcon(BBitmap* bitmap, icon_size iconSize) const
280c60fcc87SStephan Aßmus {
281ec2878c3SPhilippe Houdoin 	BNode node(&fRefs[0]);
282c60fcc87SStephan Aßmus 	BNodeInfo info(&node);
283c60fcc87SStephan Aßmus 	return info.GetTrackerIcon(bitmap, iconSize);
284c60fcc87SStephan Aßmus }
285c60fcc87SStephan Aßmus 
286c60fcc87SStephan Aßmus 
287c60fcc87SStephan Aßmus status_t
MoveIntoTrash()288c60fcc87SStephan Aßmus FilePlaylistItem::MoveIntoTrash()
289c60fcc87SStephan Aßmus {
290ec2878c3SPhilippe Houdoin 	if (fNamesInTrash[0].Length() != 0) {
291c60fcc87SStephan Aßmus 		// Already in the trash!
292c60fcc87SStephan Aßmus 		return B_ERROR;
293c60fcc87SStephan Aßmus 	}
294c60fcc87SStephan Aßmus 
295ec2878c3SPhilippe Houdoin 	status_t err;
296ec2878c3SPhilippe Houdoin 	err = _MoveIntoTrash(&fRefs, &fNamesInTrash);
297ec2878c3SPhilippe Houdoin 	if (err != B_OK)
298c60fcc87SStephan Aßmus 		return err;
299c60fcc87SStephan Aßmus 
300ec2878c3SPhilippe Houdoin 	if (fImageRefs.empty())
301ec2878c3SPhilippe Houdoin 		return B_OK;
302ec2878c3SPhilippe Houdoin 
303ec2878c3SPhilippe Houdoin 	err = _MoveIntoTrash(&fImageRefs, &fImageNamesInTrash);
304ec2878c3SPhilippe Houdoin 	if (err != B_OK)
305c60fcc87SStephan Aßmus 		return err;
306ec2878c3SPhilippe Houdoin 
307ec2878c3SPhilippe Houdoin 	return B_OK;
308c60fcc87SStephan Aßmus }
309c60fcc87SStephan Aßmus 
310c60fcc87SStephan Aßmus 
311c60fcc87SStephan Aßmus status_t
RestoreFromTrash()312c60fcc87SStephan Aßmus FilePlaylistItem::RestoreFromTrash()
313c60fcc87SStephan Aßmus {
314ec2878c3SPhilippe Houdoin 	if (fNamesInTrash[0].Length() <= 0) {
315c60fcc87SStephan Aßmus 		// Not in the trash!
316c60fcc87SStephan Aßmus 		return B_ERROR;
317c60fcc87SStephan Aßmus 	}
318c60fcc87SStephan Aßmus 
319ec2878c3SPhilippe Houdoin 	status_t err;
320ec2878c3SPhilippe Houdoin 	err = _RestoreFromTrash(&fRefs, &fNamesInTrash);
321ec2878c3SPhilippe Houdoin 	if (err != B_OK)
322c60fcc87SStephan Aßmus 		return err;
323ec2878c3SPhilippe Houdoin 
324ec2878c3SPhilippe Houdoin 	if (fImageRefs.empty())
325ec2878c3SPhilippe Houdoin 		return B_OK;
326ec2878c3SPhilippe Houdoin 
327ec2878c3SPhilippe Houdoin 	err = _RestoreFromTrash(&fImageRefs, &fImageNamesInTrash);
328ec2878c3SPhilippe Houdoin 	if (err != B_OK)
329c60fcc87SStephan Aßmus 		return err;
330c60fcc87SStephan Aßmus 
331ec2878c3SPhilippe Houdoin 	return B_OK;
332c60fcc87SStephan Aßmus }
333c60fcc87SStephan Aßmus 
334c60fcc87SStephan Aßmus 
335c60fcc87SStephan Aßmus // #pragma mark -
336c60fcc87SStephan Aßmus 
337f70b711fSStephan Aßmus TrackSupplier*
_CreateTrackSupplier() const33870efd0dbSDario Casalinuovo FilePlaylistItem::_CreateTrackSupplier() const
339c60fcc87SStephan Aßmus {
340c8ccdf52SStephan Aßmus 	MediaFileTrackSupplier* supplier
341ec2878c3SPhilippe Houdoin 		= new(std::nothrow) MediaFileTrackSupplier();
342ec2878c3SPhilippe Houdoin 	if (supplier == NULL)
343c8ccdf52SStephan Aßmus 		return NULL;
344ec2878c3SPhilippe Houdoin 
345ec2878c3SPhilippe Houdoin 	for (vector<entry_ref>::size_type i = 0; i < fRefs.size(); i++) {
346ec2878c3SPhilippe Houdoin 		BMediaFile* mediaFile = new(std::nothrow) BMediaFile(&fRefs[i]);
347ec2878c3SPhilippe Houdoin 		if (mediaFile == NULL) {
348ec2878c3SPhilippe Houdoin 			delete supplier;
349ec2878c3SPhilippe Houdoin 			return NULL;
350ec2878c3SPhilippe Houdoin 		}
351ec2878c3SPhilippe Houdoin 		if (supplier->AddMediaFile(mediaFile) != B_OK)
352ec2878c3SPhilippe Houdoin 			delete mediaFile;
353ec2878c3SPhilippe Houdoin 	}
354ec2878c3SPhilippe Houdoin 
355ec2878c3SPhilippe Houdoin 	for (vector<entry_ref>::size_type i = 0; i < fImageRefs.size(); i++) {
356ec2878c3SPhilippe Houdoin 		BBitmap* bitmap = BTranslationUtils::GetBitmap(&fImageRefs[i]);
357ec2878c3SPhilippe Houdoin 		if (bitmap == NULL)
358ec2878c3SPhilippe Houdoin 			continue;
359ec2878c3SPhilippe Houdoin 		if (supplier->AddBitmap(bitmap) != B_OK)
360ec2878c3SPhilippe Houdoin 			delete bitmap;
361c8ccdf52SStephan Aßmus 	}
362c8ccdf52SStephan Aßmus 
363c8ccdf52SStephan Aßmus 	// Search for subtitle files in the same folder
364c8ccdf52SStephan Aßmus 	// TODO: Error checking
365ec2878c3SPhilippe Houdoin 	BEntry entry(&fRefs[0], true);
366c8ccdf52SStephan Aßmus 
367c8ccdf52SStephan Aßmus 	char originalName[B_FILE_NAME_LENGTH];
368c8ccdf52SStephan Aßmus 	entry.GetName(originalName);
369c8ccdf52SStephan Aßmus 	BString nameWithoutExtension(originalName);
370c8ccdf52SStephan Aßmus 	int32 extension = nameWithoutExtension.FindLast('.');
371c8ccdf52SStephan Aßmus 	if (extension > 0)
372c8ccdf52SStephan Aßmus 		nameWithoutExtension.Truncate(extension);
373c8ccdf52SStephan Aßmus 
374c8ccdf52SStephan Aßmus 	BPath path;
375c8ccdf52SStephan Aßmus 	entry.GetPath(&path);
376c8ccdf52SStephan Aßmus 	path.GetParent(&path);
377c8ccdf52SStephan Aßmus 	BDirectory directory(path.Path());
378c8ccdf52SStephan Aßmus 	while (directory.GetNextEntry(&entry) == B_OK) {
379c8ccdf52SStephan Aßmus 		char name[B_FILE_NAME_LENGTH];
380c8ccdf52SStephan Aßmus 		if (entry.GetName(name) != B_OK)
381c8ccdf52SStephan Aßmus 			continue;
382c8ccdf52SStephan Aßmus 		BString nameString(name);
383c8ccdf52SStephan Aßmus 		if (nameString == originalName)
384c8ccdf52SStephan Aßmus 			continue;
385c8ccdf52SStephan Aßmus 		if (nameString.IFindFirst(nameWithoutExtension) < 0)
386c8ccdf52SStephan Aßmus 			continue;
387c8ccdf52SStephan Aßmus 
388c8ccdf52SStephan Aßmus 		BFile file(&entry, B_READ_ONLY);
389c8ccdf52SStephan Aßmus 		if (file.InitCheck() != B_OK)
390c8ccdf52SStephan Aßmus 			continue;
391c8ccdf52SStephan Aßmus 
392c8ccdf52SStephan Aßmus 		int32 pos = nameString.FindLast('.');
393c8ccdf52SStephan Aßmus 		if (pos < 0)
394c8ccdf52SStephan Aßmus 			continue;
395c8ccdf52SStephan Aßmus 
396c8ccdf52SStephan Aßmus 		BString extensionString(nameString.String() + pos + 1);
397c8ccdf52SStephan Aßmus 		extensionString.ToLower();
398c8ccdf52SStephan Aßmus 
399c8ccdf52SStephan Aßmus 		BString language = "default";
400c8ccdf52SStephan Aßmus 		if (pos > 1) {
401c8ccdf52SStephan Aßmus 			int32 end = pos;
402c8ccdf52SStephan Aßmus 			while (pos > 0 && *(nameString.String() + pos - 1) != '.')
403c8ccdf52SStephan Aßmus 				pos--;
404c8ccdf52SStephan Aßmus 			language.SetTo(nameString.String() + pos, end - pos);
405c8ccdf52SStephan Aßmus 		}
406c8ccdf52SStephan Aßmus 
407c8ccdf52SStephan Aßmus 		if (extensionString == "srt") {
408c8ccdf52SStephan Aßmus 			SubTitles* subTitles
409c8ccdf52SStephan Aßmus 				= new(std::nothrow) SubTitlesSRT(&file, language.String());
410c8ccdf52SStephan Aßmus 			if (subTitles != NULL && !supplier->AddSubTitles(subTitles))
411c8ccdf52SStephan Aßmus 				delete subTitles;
412c8ccdf52SStephan Aßmus 		}
413c8ccdf52SStephan Aßmus 	}
414f70b711fSStephan Aßmus 
415f70b711fSStephan Aßmus 	return supplier;
416f70b711fSStephan Aßmus }
417f70b711fSStephan Aßmus 
418f70b711fSStephan Aßmus 
419f70b711fSStephan Aßmus status_t
AddRef(const entry_ref & ref)420ec2878c3SPhilippe Houdoin FilePlaylistItem::AddRef(const entry_ref& ref)
421ec2878c3SPhilippe Houdoin {
422ec2878c3SPhilippe Houdoin 	fRefs.push_back(ref);
423ec2878c3SPhilippe Houdoin 	fNamesInTrash.push_back("");
424ec2878c3SPhilippe Houdoin 	return B_OK;
425ec2878c3SPhilippe Houdoin }
426ec2878c3SPhilippe Houdoin 
427ec2878c3SPhilippe Houdoin 
428ec2878c3SPhilippe Houdoin status_t
AddImageRef(const entry_ref & ref)429ec2878c3SPhilippe Houdoin FilePlaylistItem::AddImageRef(const entry_ref& ref)
430ec2878c3SPhilippe Houdoin {
431ec2878c3SPhilippe Houdoin 	fImageRefs.push_back(ref);
432ec2878c3SPhilippe Houdoin 	fImageNamesInTrash.push_back("");
433ec2878c3SPhilippe Houdoin 	return B_OK;
434ec2878c3SPhilippe Houdoin }
435ec2878c3SPhilippe Houdoin 
436ec2878c3SPhilippe Houdoin 
437ec2878c3SPhilippe Houdoin const entry_ref&
ImageRef() const438ec2878c3SPhilippe Houdoin FilePlaylistItem::ImageRef() const
439ec2878c3SPhilippe Houdoin {
440ec2878c3SPhilippe Houdoin 	static entry_ref ref;
441ec2878c3SPhilippe Houdoin 
442ec2878c3SPhilippe Houdoin 	if (fImageRefs.empty())
443ec2878c3SPhilippe Houdoin 		return ref;
444ec2878c3SPhilippe Houdoin 
445ec2878c3SPhilippe Houdoin 	return fImageRefs[0];
446ec2878c3SPhilippe Houdoin }
447ec2878c3SPhilippe Houdoin 
448ec2878c3SPhilippe Houdoin 
449b5387effSMarkus Himmel bigtime_t
_CalculateDuration()45070efd0dbSDario Casalinuovo FilePlaylistItem::_CalculateDuration()
451b5387effSMarkus Himmel {
452b5387effSMarkus Himmel 	BMediaFile mediaFile(&Ref());
453b5387effSMarkus Himmel 
454b5387effSMarkus Himmel 	if (mediaFile.InitCheck() != B_OK || mediaFile.CountTracks() < 1)
455b5387effSMarkus Himmel 		return 0;
456b5387effSMarkus Himmel 
457b5387effSMarkus Himmel 	return mediaFile.TrackAt(0)->Duration();
458b5387effSMarkus Himmel }
459b5387effSMarkus Himmel 
460b5387effSMarkus Himmel 
461ec2878c3SPhilippe Houdoin status_t
_SetAttribute(const char * attrName,type_code type,const void * data,size_t size)462f70b711fSStephan Aßmus FilePlaylistItem::_SetAttribute(const char* attrName, type_code type,
463f70b711fSStephan Aßmus 	const void* data, size_t size)
464f70b711fSStephan Aßmus {
465ec2878c3SPhilippe Houdoin 	BEntry entry(&fRefs[0], true);
466f70b711fSStephan Aßmus 	BNode node(&entry);
467f70b711fSStephan Aßmus 	if (node.InitCheck() != B_OK)
468f70b711fSStephan Aßmus 		return node.InitCheck();
469f70b711fSStephan Aßmus 
470f70b711fSStephan Aßmus 	ssize_t written = node.WriteAttr(attrName, type, 0, data, size);
471f70b711fSStephan Aßmus 	if (written != (ssize_t)size) {
472f70b711fSStephan Aßmus 		if (written < 0)
473f70b711fSStephan Aßmus 			return (status_t)written;
474f70b711fSStephan Aßmus 		return B_IO_ERROR;
475f70b711fSStephan Aßmus 	}
476f70b711fSStephan Aßmus 	return B_OK;
477f70b711fSStephan Aßmus }
478f70b711fSStephan Aßmus 
479f70b711fSStephan Aßmus 
480f70b711fSStephan Aßmus status_t
_GetAttribute(const char * attrName,type_code type,void * data,size_t size) const481f70b711fSStephan Aßmus FilePlaylistItem::_GetAttribute(const char* attrName, type_code type,
4821c68b67aSMarkus Himmel 	void* data, size_t size) const
483f70b711fSStephan Aßmus {
484ec2878c3SPhilippe Houdoin 	BEntry entry(&fRefs[0], true);
485f70b711fSStephan Aßmus 	BNode node(&entry);
486f70b711fSStephan Aßmus 	if (node.InitCheck() != B_OK)
487f70b711fSStephan Aßmus 		return node.InitCheck();
488f70b711fSStephan Aßmus 
489f70b711fSStephan Aßmus 	ssize_t read = node.ReadAttr(attrName, type, 0, data, size);
490f70b711fSStephan Aßmus 	if (read != (ssize_t)size) {
491f70b711fSStephan Aßmus 		if (read < 0)
492f70b711fSStephan Aßmus 			return (status_t)read;
493f70b711fSStephan Aßmus 		return B_IO_ERROR;
494f70b711fSStephan Aßmus 	}
495f70b711fSStephan Aßmus 	return B_OK;
496c60fcc87SStephan Aßmus }
497c60fcc87SStephan Aßmus 
498ec2878c3SPhilippe Houdoin 
499ec2878c3SPhilippe Houdoin status_t
_MoveIntoTrash(vector<entry_ref> * refs,vector<BString> * namesInTrash)500ec2878c3SPhilippe Houdoin FilePlaylistItem::_MoveIntoTrash(vector<entry_ref>* refs,
501ec2878c3SPhilippe Houdoin 	vector<BString>* namesInTrash)
502ec2878c3SPhilippe Houdoin {
503ec2878c3SPhilippe Houdoin 	char trashPath[B_PATH_NAME_LENGTH];
504ec2878c3SPhilippe Houdoin 	status_t err = find_directory(B_TRASH_DIRECTORY, (*refs)[0].device,
505ec2878c3SPhilippe Houdoin 		true /*create it*/, trashPath, B_PATH_NAME_LENGTH);
506ec2878c3SPhilippe Houdoin 	if (err != B_OK) {
507ec2878c3SPhilippe Houdoin 		fprintf(stderr, "failed to find Trash: %s\n", strerror(err));
508ec2878c3SPhilippe Houdoin 		return err;
509ec2878c3SPhilippe Houdoin 	}
510ec2878c3SPhilippe Houdoin 
511ec2878c3SPhilippe Houdoin 	BDirectory trashDir(trashPath);
51220e36f6eSPhilippe Saint-Pierre 	err = trashDir.InitCheck();
513ec2878c3SPhilippe Houdoin 	if (err != B_OK) {
514ec2878c3SPhilippe Houdoin 		fprintf(stderr, "failed to init BDirectory for %s: %s\n",
515ec2878c3SPhilippe Houdoin 			trashPath, strerror(err));
516ec2878c3SPhilippe Houdoin 		return err;
517ec2878c3SPhilippe Houdoin 	}
518ec2878c3SPhilippe Houdoin 
519ec2878c3SPhilippe Houdoin 	for (vector<entry_ref>::size_type i = 0; i < refs->size(); i++) {
520ec2878c3SPhilippe Houdoin 		BEntry entry(&(*refs)[i]);
521ec2878c3SPhilippe Houdoin 		err = entry.InitCheck();
522ec2878c3SPhilippe Houdoin 		if (err != B_OK) {
523ec2878c3SPhilippe Houdoin 			fprintf(stderr, "failed to init BEntry for %s: %s\n",
524ec2878c3SPhilippe Houdoin 				(*refs)[i].name, strerror(err));
525ec2878c3SPhilippe Houdoin 			return err;
526ec2878c3SPhilippe Houdoin 		}
527ec2878c3SPhilippe Houdoin 
528ec2878c3SPhilippe Houdoin 		// Find a unique name for the entry in the trash
529ec2878c3SPhilippe Houdoin 		(*namesInTrash)[i] = (*refs)[i].name;
530ec2878c3SPhilippe Houdoin 		int32 uniqueNameIndex = 1;
531ec2878c3SPhilippe Houdoin 		while (true) {
532ec2878c3SPhilippe Houdoin 			BEntry test(&trashDir, (*namesInTrash)[i].String());
533ec2878c3SPhilippe Houdoin 			if (!test.Exists())
534ec2878c3SPhilippe Houdoin 				break;
535ec2878c3SPhilippe Houdoin 			(*namesInTrash)[i] = (*refs)[i].name;
536ec2878c3SPhilippe Houdoin 			(*namesInTrash)[i] << ' ' << uniqueNameIndex;
537ec2878c3SPhilippe Houdoin 			uniqueNameIndex++;
538ec2878c3SPhilippe Houdoin 		}
539ec2878c3SPhilippe Houdoin 
540ec2878c3SPhilippe Houdoin 		// Remember the original path
541ec2878c3SPhilippe Houdoin 		BPath originalPath;
542ec2878c3SPhilippe Houdoin 		entry.GetPath(&originalPath);
543ec2878c3SPhilippe Houdoin 
544ec2878c3SPhilippe Houdoin 		// Finally, move the entry into the trash
545ec2878c3SPhilippe Houdoin 		err = entry.MoveTo(&trashDir, (*namesInTrash)[i].String());
546ec2878c3SPhilippe Houdoin 		if (err != B_OK) {
547ec2878c3SPhilippe Houdoin 			fprintf(stderr, "failed to move entry into trash %s: %s\n",
548ec2878c3SPhilippe Houdoin 				trashPath, strerror(err));
549ec2878c3SPhilippe Houdoin 			return err;
550ec2878c3SPhilippe Houdoin 		}
551ec2878c3SPhilippe Houdoin 
552ec2878c3SPhilippe Houdoin 		// Allow Tracker to restore this entry
553ec2878c3SPhilippe Houdoin 		BNode node(&entry);
554ec2878c3SPhilippe Houdoin 		BString originalPathString(originalPath.Path());
555ec2878c3SPhilippe Houdoin 		node.WriteAttrString("_trk/original_path", &originalPathString);
556ec2878c3SPhilippe Houdoin 	}
557ec2878c3SPhilippe Houdoin 
558ec2878c3SPhilippe Houdoin 	return B_OK;
559ec2878c3SPhilippe Houdoin }
560ec2878c3SPhilippe Houdoin 
561ec2878c3SPhilippe Houdoin 
562ec2878c3SPhilippe Houdoin status_t
_RestoreFromTrash(vector<entry_ref> * refs,vector<BString> * namesInTrash)563ec2878c3SPhilippe Houdoin FilePlaylistItem::_RestoreFromTrash(vector<entry_ref>* refs,
564ec2878c3SPhilippe Houdoin 	vector<BString>* namesInTrash)
565ec2878c3SPhilippe Houdoin {
566ec2878c3SPhilippe Houdoin 	char trashPath[B_PATH_NAME_LENGTH];
567ec2878c3SPhilippe Houdoin 	status_t err = find_directory(B_TRASH_DIRECTORY, (*refs)[0].device,
568ec2878c3SPhilippe Houdoin 		false /*create it*/, trashPath, B_PATH_NAME_LENGTH);
569ec2878c3SPhilippe Houdoin 	if (err != B_OK) {
570ec2878c3SPhilippe Houdoin 		fprintf(stderr, "failed to find Trash: %s\n", strerror(err));
571ec2878c3SPhilippe Houdoin 		return err;
572ec2878c3SPhilippe Houdoin 	}
573ec2878c3SPhilippe Houdoin 
574ec2878c3SPhilippe Houdoin 	for (vector<entry_ref>::size_type i = 0; i < refs->size(); i++) {
575ec2878c3SPhilippe Houdoin 		// construct the entry to the file in the trash
576ec2878c3SPhilippe Houdoin 		// TODO: BEntry(const BDirectory* directory, const char* path) is broken!
577ec2878c3SPhilippe Houdoin 		//	BEntry entry(trashPath, (*namesInTrash)[i].String());
578ec2878c3SPhilippe Houdoin 		BPath path(trashPath, (*namesInTrash)[i].String());
579ec2878c3SPhilippe Houdoin 		BEntry entry(path.Path());
580ec2878c3SPhilippe Houdoin 		err = entry.InitCheck();
581ec2878c3SPhilippe Houdoin 		if (err != B_OK) {
582ec2878c3SPhilippe Houdoin 			fprintf(stderr, "failed to init BEntry for %s: %s\n",
583ec2878c3SPhilippe Houdoin 				(*namesInTrash)[i].String(), strerror(err));
584ec2878c3SPhilippe Houdoin 			return err;
585ec2878c3SPhilippe Houdoin 		}
586ec2878c3SPhilippe Houdoin 		//entry.GetPath(&path);
587ec2878c3SPhilippe Houdoin 		//printf("moving '%s'\n", path.Path());
588ec2878c3SPhilippe Houdoin 
589ec2878c3SPhilippe Houdoin 		// construct the folder of the original entry_ref
590ec2878c3SPhilippe Houdoin 		node_ref nodeRef;
591ec2878c3SPhilippe Houdoin 		nodeRef.device = (*refs)[i].device;
592ec2878c3SPhilippe Houdoin 		nodeRef.node = (*refs)[i].directory;
593ec2878c3SPhilippe Houdoin 		BDirectory originalDir(&nodeRef);
594ec2878c3SPhilippe Houdoin 		err = originalDir.InitCheck();
595ec2878c3SPhilippe Houdoin 		if (err != B_OK) {
596ec2878c3SPhilippe Houdoin 			fprintf(stderr, "failed to init original BDirectory for "
597ec2878c3SPhilippe Houdoin 				"%s: %s\n", (*refs)[i].name, strerror(err));
598ec2878c3SPhilippe Houdoin 			return err;
599ec2878c3SPhilippe Houdoin 		}
600ec2878c3SPhilippe Houdoin 
601ec2878c3SPhilippe Houdoin 		//path.SetTo(&originalDir, fItems[i].name);
602ec2878c3SPhilippe Houdoin 		//printf("as '%s'\n", path.Path());
603ec2878c3SPhilippe Houdoin 
604ec2878c3SPhilippe Houdoin 		// Reset the name here, the user may have already moved the entry
605ec2878c3SPhilippe Houdoin 		// out of the trash via Tracker for example.
606ec2878c3SPhilippe Houdoin 		(*namesInTrash)[i] = "";
607ec2878c3SPhilippe Houdoin 
608ec2878c3SPhilippe Houdoin 		// Finally, move the entry back into the original folder
609ec2878c3SPhilippe Houdoin 		err = entry.MoveTo(&originalDir, (*refs)[i].name);
610ec2878c3SPhilippe Houdoin 		if (err != B_OK) {
611ec2878c3SPhilippe Houdoin 			fprintf(stderr, "failed to restore entry from trash "
612ec2878c3SPhilippe Houdoin 				"%s: %s\n", (*refs)[i].name, strerror(err));
613ec2878c3SPhilippe Houdoin 			return err;
614ec2878c3SPhilippe Houdoin 		}
615ec2878c3SPhilippe Houdoin 
616ec2878c3SPhilippe Houdoin 		// Remove the attribute that helps Tracker restore the entry.
617ec2878c3SPhilippe Houdoin 		BNode node(&entry);
618ec2878c3SPhilippe Houdoin 		node.RemoveAttr("_trk/original_path");
619ec2878c3SPhilippe Houdoin 	}
620ec2878c3SPhilippe Houdoin 
621ec2878c3SPhilippe Houdoin 	return B_OK;
622ec2878c3SPhilippe Houdoin }
623ec2878c3SPhilippe Houdoin 
624