bool StPlayList::remove(const StString& thePath, const bool theToRemovePhysically) { StString aPath = thePath; StPlayItem* aRemItem = NULL; StMutexAuto anAutoLock(myMutex); if(myCurrent == NULL) { // empty playlist return false; } else if(aPath != myCurrent->getPath()) { // search play item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(aPath == anItem->getPath()) { aRemItem = anItem; break; } } } else { // walk to another playlist position aRemItem = myCurrent; const bool aPlayedFlag = aRemItem->getPlayedFlag(); if(myCurrent->hasNext()) { myCurrent = myCurrent->getNext(); } else if(myCurrent->hasPrev()) { myCurrent = myCurrent->getPrev(); } else { myCurrent = NULL; myPlayedCount = 0; } if(myCurrent != NULL) { if(aRemItem->getPlayedFlag() != aPlayedFlag) { // the item has not been played yet - mark it as such aRemItem->setPlayedFlag(aPlayedFlag); } else { // one played item has been removed --myPlayedCount; } } } // remove item itself const bool isDeleted = aRemItem != NULL && (!theToRemovePhysically || StFileNode::removeFile(aPath)); if(isDeleted) { delPlayItem(aRemItem); delete aRemItem; } anAutoLock.unlock(); signals.onPlaylistChange(); return isDeleted; }
void StPlayList::addToNode(const StHandle<StFileNode>& theFileNode, const StString& thePathToAdd) { StString aPath = theFileNode->getPath(); StMutexAuto anAutoLock(myMutex); if(myCurrent == NULL) { return; } else if(aPath != myCurrent->getPath()) { for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(aPath == anItem->getPath()) { myCurrent = anItem; break; } } } StFileNode* aFileNode = myCurrent->getFileNode(); if(aFileNode->getParent() != &myFoldersRoot) { // convert filenode to metafile with empty root aFileNode->reParent(&myFoldersRoot); aFileNode->setSubPath(StString()); aFileNode->add(new StFileNode(aPath, aFileNode)); } aFileNode->add(new StFileNode(thePathToAdd, aFileNode)); }
void StPlayList::open(const StCString& thePath, const StCString& theItem) { StMutexAuto anAutoLock(myMutex); // check if it is recently played playlist bool hasTarget = !theItem.isEmpty(); StString aTarget = hasTarget ? theItem : thePath; if(!hasTarget) { for(size_t anIter = 0; anIter < myRecent.size(); ++anIter) { const StHandle<StRecentItem>& aRecent = myRecent[anIter]; const StHandle<StFileNode>& aFile = aRecent->File; if(aFile->size() != 1) { continue; } if(thePath.isEquals(aFile->getPath())) { hasTarget = true; aTarget = aFile->getValue(0)->getSubPath(); break; } } } clear(); int aSearchDeep = myRecursionDeep; StString aFolderPath; StString aFileName; if(StFolder::isFolder(thePath)) { // add all files from the folder and subfolders aFolderPath = thePath; aSearchDeep = myRecursionDeep; myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list } else if(StFileNode::isFileExists(thePath)) { // search only current folder StFileNode::getFolderAndFile(thePath, aFolderPath, aFileName); aSearchDeep = 1; bool hasSupportedExt = false; StString anExt = StFileNode::getExtension(aFileName); for(size_t anExtId = 0; anExtId < myExtensions.size() && !hasSupportedExt; ++anExtId) { hasSupportedExt = anExt.isEqualsIgnoreCase(myExtensions[anExtId]); } // parse m3u playlist if(anExt.isEqualsIgnoreCase(stCString("m3u"))) { StRawFile aRawFile(thePath); if(aRawFile.readFile()) { StString aTitle; char* anIter = (char* )aRawFile.getBuffer(); if(anIter[0] == '\xEF' && anIter[1] == '\xBB' && anIter[2] == '\xBF') { // skip BOM for UTF8 written by some stupid programs anIter += 3; } while(anIter != NULL) { anIter = parseM3UIter(anIter, aTitle); } myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list if(hasTarget) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); return; } } if(!hasSupportedExt) { // file with unsupported extension? StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addPlayItem(new StPlayItem(aFileNode, myDefStParams)); } } else { // not a filesystem element - probably url or invalid path StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addRecentFile(*aFileNode); // append to recent files list addPlayItem(new StPlayItem(aFileNode, myDefStParams)); anAutoLock.unlock(); signals.onPlaylistChange(); return; } StFolder* aSubFolder = new StFolder(aFolderPath, &myFoldersRoot); aSubFolder->init(myExtensions, aSearchDeep); myFoldersRoot.add(aSubFolder); addToPlayList(aSubFolder); myCurrent = myFirst; if(hasTarget || !aFileName.isEmpty()) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; if(myPlsFile.isNull()) { addRecentFile(*anItem->getFileNode()); // append to recent files list } break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); }