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