예제 #1
0
void CGUIDialogAddonInfo::OnUpdate()
{
  if (!m_localAddon)
    return;

  CAddonDatabase database;
  if (!database.Open())
    return;

  std::vector<std::pair<AddonVersion, std::string>> versions;
  if (!database.GetAvailableVersions(m_localAddon->ID(), versions))
    return;

  CFileItemList items;
  if (XFILE::CDirectory::GetDirectory("special://home/addons/packages/", items, ".zip", DIR_FLAG_NO_FILE_DIRS))
  {
    for (int i = 0; i < items.Size(); ++i)
    {
      std::string packageId;
      std::string versionString;
      if (AddonVersion::SplitFileName(packageId, versionString, items[i]->GetLabel()))
      {
        if (packageId == m_localAddon->ID())
        {
          std::string hash;
          std::string path(items[i]->GetPath());
          if (database.GetPackageHash(m_localAddon->ID(), items[i]->GetPath(), hash))
          {
            std::string md5 = CUtil::GetFileMD5(path);
            if (md5 == hash)
              versions.push_back(std::make_pair(AddonVersion(versionString), LOCAL_CACHE));
          }
        }
      }
    }
  }

  auto* dialog = static_cast<CGUIDialogSelect*>(g_windowManager.GetWindow(WINDOW_DIALOG_SELECT));
  dialog->Reset();
  dialog->SetHeading(CVariant{21338});
  dialog->SetUseDetails(true);

  std::stable_sort(versions.begin(), versions.end(), CompareVersion);

  for (const auto& versionInfo : versions)
  {
    CFileItem item(StringUtils::Format(g_localizeStrings.Get(21339).c_str(), versionInfo.first.asString().c_str()));
    if (versionInfo.first == m_localAddon->Version())
      item.Select(true);

    AddonPtr repo;
    if (versionInfo.second == LOCAL_CACHE)
    {
      item.SetProperty("Addon.Summary", g_localizeStrings.Get(24095));
      item.SetIconImage("DefaultAddonRepository.png");
      dialog->Add(item);
    }
    else if (CAddonMgr::GetInstance().GetAddon(versionInfo.second, repo, ADDON_REPOSITORY))
    {
      item.SetProperty("Addon.Summary", repo->Name());
      item.SetIconImage(repo->Icon());
      dialog->Add(item);
    }
  }

  dialog->Open();
  if (dialog->IsConfirmed())
  {
    Close();

    auto selected = versions.at(dialog->GetSelectedLabel());

    //add or remove from blacklist to toggle auto updating. if downgrading
    //turn off, if upgrading to latest turn it back on
    if (selected.first < m_localAddon->Version())
      database.BlacklistAddon(m_localAddon->ID());
    if (selected.first == versions.at(0).first)
      database.RemoveAddonFromBlacklist(m_localAddon->ID());

    if (selected.second == LOCAL_CACHE)
      CAddonInstaller::GetInstance().InstallFromZip(StringUtils::Format("special://home/addons/packages/%s-%s.zip",
          m_localAddon->ID().c_str(), selected.first.asString().c_str()));
    else
      CAddonInstaller::GetInstance().Install(m_addon->ID(), selected.first, selected.second);
  }
}
예제 #2
0
bool CMusicInfoScanner::DoScan(const CStdString& strDirectory)
{
  if (m_handle)
    m_handle->SetText(Prettify(strDirectory));

  /*
   * remove this path from the list we're processing. This must be done prior to
   * the check for file or folder exclusion to prevent an infinite while loop
   * in Process().
   */
  set<CStdString>::iterator it = m_pathsToScan.find(strDirectory);
  if (it != m_pathsToScan.end())
    m_pathsToScan.erase(it);

  // Discard all excluded files defined by m_musicExcludeRegExps

  CStdStringArray regexps = g_advancedSettings.m_audioExcludeFromScanRegExps;

  if (CUtil::ExcludeFileOrFolder(strDirectory, regexps))
    return true;

  // load subfolder
  CFileItemList items;
  CDirectory::GetDirectory(strDirectory, items, g_settings.m_musicExtensions + "|.jpg|.tbn|.lrc|.cdg");

  // sort and get the path hash.  Note that we don't filter .cue sheet items here as we want
  // to detect changes in the .cue sheet as well.  The .cue sheet items only need filtering
  // if we have a changed hash.
  items.Sort(SORT_METHOD_LABEL, SortOrderAscending);
  CStdString hash;
  GetPathHash(items, hash);

  // check whether we need to rescan or not
  CStdString dbHash;
  if ((m_flags & SCAN_RESCAN) || !m_musicDatabase.GetPathHash(strDirectory, dbHash) || dbHash != hash)
  { // path has changed - rescan
    if (dbHash.IsEmpty())
      CLog::Log(LOGDEBUG, "%s Scanning dir '%s' as not in the database", __FUNCTION__, strDirectory.c_str());
    else
      CLog::Log(LOGDEBUG, "%s Rescanning dir '%s' due to change", __FUNCTION__, strDirectory.c_str());

    // filter items in the sub dir (for .cue sheet support)
    items.FilterCueItems();
    items.Sort(SORT_METHOD_LABEL, SortOrderAscending);

    // and then scan in the new information
    if (RetrieveMusicInfo(items, strDirectory) > 0)
    {
      if (m_handle)
        OnDirectoryScanned(strDirectory);
    }

    // save information about this folder
    m_musicDatabase.SetPathHash(strDirectory, hash);
  }
  else
  { // path is the same - no need to rescan
    CLog::Log(LOGDEBUG, "%s Skipping dir '%s' due to no change", __FUNCTION__, strDirectory.c_str());
    m_currentItem += CountFiles(items, false);  // false for non-recursive

    // updated the dialog with our progress
    if (m_handle)
    {
      if (m_itemCount>0)
        m_handle->SetPercentage(m_currentItem/(double)m_itemCount*100);
      OnDirectoryScanned(strDirectory);
    }
  }

  // now scan the subfolders
  for (int i = 0; i < items.Size(); ++i)
  {
    CFileItemPtr pItem = items[i];

    if (m_bStop)
      break;
    // if we have a directory item (non-playlist) we then recurse into that folder
    if (pItem->m_bIsFolder && !pItem->IsParentFolder() && !pItem->IsPlayList())
    {
      CStdString strPath=pItem->GetPath();
      if (!DoScan(strPath))
      {
        m_bStop = true;
      }
    }
  }

  return !m_bStop;
}
예제 #3
0
JSONRPC_STATUS CPVROperations::GetBroadcasts(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
  if (!g_PVRManager.IsStarted())
    return FailedToExecute;

  CPVRChannelGroupsContainer *channelGroupContainer = g_PVRManager.ChannelGroups();
  if (channelGroupContainer == NULL)
    return FailedToExecute;

  CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["channelid"].asInteger());
  if (channel == NULL)
    return InvalidParams;

  CEpg *channelEpg = channel->GetEPG();
  if (channelEpg == NULL)
    return InternalError;

  CFileItemList programFull;
  channelEpg->Get(programFull);

  HandleFileItemList("broadcastid", false, "broadcasts", programFull, parameterObject, result, programFull.Size(), true);

  return OK;
}
예제 #4
0
bool CPVRRecordings::ChangeRecordingsPlayCount(const CFileItemPtr &item, int count)
{
  bool bResult = false;

  if (m_database.IsOpen())
  {
    bResult = true;

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str());
    CFileItemList items;
    if (item->m_bIsFolder)
    {
      XFILE::CDirectory::GetDirectory(item->GetPath(), items);
    }
    else
      items.Add(item);

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size());
    for (int i=0;i<items.Size();++i)
    {
      CLog::Log(LOGDEBUG, "CPVRRecordings - %s - setting watched for item %d", __FUNCTION__, i);

      CFileItemPtr pItem=items[i];
      if (pItem->m_bIsFolder)
      {
        CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str());
        if (pItem->GetLabel() != "..")
        {
          ChangeRecordingsPlayCount(pItem, count);
        }
        continue;
      }

      if (!pItem->HasPVRRecordingInfoTag())
        continue;

      const CPVRRecordingPtr recording = pItem->GetPVRRecordingInfoTag();
      if (recording)
      {
        if (count == INCREMENT_PLAY_COUNT)
          recording->IncrementPlayCount();
        else
          recording->SetPlayCount(count);

        // Clear resume bookmark
        if (recording->m_playCount > 0)
        {
          m_database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME);
          recording->SetLastPlayedPosition(0);
        }

        if (count == INCREMENT_PLAY_COUNT)
          m_database.IncrementPlayCount(*pItem);
        else
          m_database.SetPlayCount(*pItem, count);
      }
    }

    g_PVRManager.PublishEvent(RecordingsInvalidated);
  }

  return bResult;
}
예제 #5
0
//  Add an "* All ..." folder to the CFileItemList
//  depending on the child node
void CDirectoryNode::AddQueuingFolder(CFileItemList& items) const
{
  CFileItemPtr pItem;

  CMusicDbUrl musicUrl;
  if (!musicUrl.FromString(BuildPath()))
    return;

  // always hide "all" items
  if (g_advancedSettings.m_bMusicLibraryHideAllItems)
    return;

  // no need for "all" item when only one item
  if (items.GetObjectCount() <= 1)
    return;

  switch (GetChildType())
  {
    //  Have no queuing folder
  case NODE_TYPE_ROOT:
  case NODE_TYPE_OVERVIEW:
  case NODE_TYPE_TOP100:
    break;

  /* no need for all genres
  case NODE_TYPE_GENRE:
    pItem.reset(new CFileItem(g_localizeStrings.Get(15105)));  // "All Genres"
    musicUrl.AppendPath("-1/");
    pItem->SetPath(musicUrl.ToString());
    break;
  */

  case NODE_TYPE_ARTIST:
    if (GetType() == NODE_TYPE_OVERVIEW) return;
    pItem.reset(new CFileItem(g_localizeStrings.Get(15103)));  // "All Artists"
    musicUrl.AppendPath("-1/");
    pItem->SetPath(musicUrl.ToString());
    break;

    //  All album related nodes
  case NODE_TYPE_ALBUM:
    if (GetType() == NODE_TYPE_OVERVIEW) return;
  case NODE_TYPE_ALBUM_RECENTLY_PLAYED:
  case NODE_TYPE_ALBUM_RECENTLY_ADDED:
  case NODE_TYPE_ALBUM_COMPILATIONS:
  case NODE_TYPE_ALBUM_TOP100:
  case NODE_TYPE_YEAR_ALBUM:
    pItem.reset(new CFileItem(g_localizeStrings.Get(15102)));  // "All Albums"
    musicUrl.AppendPath("-1/");
    pItem->SetPath(musicUrl.ToString());
    break;

    //  All song related nodes
/*  case NODE_TYPE_ALBUM_RECENTLY_PLAYED_SONGS:
  case NODE_TYPE_ALBUM_RECENTLY_ADDED_SONGS:
  case NODE_TYPE_ALBUM_COMPILATIONS_SONGS:
  case NODE_TYPE_ALBUM_TOP100_SONGS:
  case NODE_TYPE_SONG_TOP100:
  case NODE_TYPE_SONG:
    pItem = new CFileItem(g_localizeStrings.Get(15104));  // "All Songs"
    musicUrl.AppendPath("-1/");
    pItem->SetPath(musicUrl.ToString());
    break;*/
  default:
    break;
  }

  if (pItem)
  {
    pItem->m_bIsFolder = true;
    pItem->SetSpecialSort(g_advancedSettings.m_bMusicLibraryAllItemsOnBottom ? SortSpecialOnBottom : SortSpecialOnTop);
    pItem->SetCanQueue(false);
    pItem->SetLabelPreformated(true);
    if (g_advancedSettings.m_bMusicLibraryAllItemsOnBottom)
      items.Add(pItem);
    else
      items.AddFront(pItem, (items.Size() > 0 && items[0]->IsParentFolder()) ? 1 : 0);
  }
}
예제 #6
0
// \brief With this function you can react on a users click in the list/thumb panel.
// It returns true, if the click is handled.
// This function calls OnPlayMedia()
bool CGUIMediaWindow::OnClick(int iItem)
{
  if ( iItem < 0 || iItem >= (int)m_vecItems->Size() ) return true;
  CFileItemPtr pItem = m_vecItems->Get(iItem);

  if (pItem->IsParentFolder())
  {
    GoParentFolder();
    return true;
  }
  else if (pItem->m_bIsFolder)
  {
    if ( pItem->m_bIsShareOrDrive )
    {
      const CStdString& strLockType=m_guiState->GetLockType();
      ASSERT(g_settings.m_vecProfiles.size() > 0);
      if (g_settings.m_vecProfiles[0].getLockMode() != LOCK_MODE_EVERYONE)
        if (!strLockType.IsEmpty() && !g_passwordManager.IsItemUnlocked(pItem.get(), strLockType))
            return true;

      if (!HaveDiscOrConnection(pItem->m_strPath, pItem->m_iDriveType))
        return true;
    }

    // check for the partymode playlist items - they may not exist yet
    if ((pItem->m_strPath == g_settings.GetUserDataItem("PartyMode.xsp")) ||
        (pItem->m_strPath == g_settings.GetUserDataItem("PartyMode-Video.xsp")))
    {
      // party mode playlist item - if it doesn't exist, prompt for user to define it
      if (!XFILE::CFile::Exists(pItem->m_strPath))
      {
        m_vecItems->RemoveDiscCache();
        if (CGUIDialogSmartPlaylistEditor::EditPlaylist(pItem->m_strPath))
          Update(m_vecItems->m_strPath);
        return true;
      }
    }

    // remove the directory cache if the folder is not normally cached
    CFileItemList items(pItem->m_strPath);
    if (!items.AlwaysCache())
      items.RemoveDiscCache();

    CFileItem directory(*pItem);
    if (!Update(directory.m_strPath))
      ShowShareErrorMessage(&directory);

    return true;
  }
  else if (pItem->IsPlugin() && pItem->GetProperty("isplayable") != "true")
  {
    return DIRECTORY::CPluginDirectory::RunScriptWithParams(pItem->m_strPath);
  }
  else
  {
    m_iSelectedItem = m_viewControl.GetSelectedItem();

    if (pItem->m_strPath == "newplaylist://")
    {
      m_vecItems->RemoveDiscCache();
      g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST_EDITOR,"newplaylist://");
      return true;
    }
    else if (pItem->m_strPath.Left(19).Equals("newsmartplaylist://"))
    {
      m_vecItems->RemoveDiscCache();
      if (CGUIDialogSmartPlaylistEditor::NewPlaylist(pItem->m_strPath.Mid(19)))
        Update(m_vecItems->m_strPath);
      return true;
    }
#ifndef _BOXEE_
    if (m_guiState.get() && m_guiState->AutoPlayNextItem() && !g_partyModeManager.IsEnabled() && !pItem->IsPlayList())
    {
      // TODO: music videos!
      if (pItem->m_strPath == "add" && pItem->GetLabel() == g_localizeStrings.Get(1026) && m_guiState->GetPlaylist() == PLAYLIST_MUSIC) // 'add source button' in empty root
      {
        if (CGUIDialogMediaSource::ShowAndAddMediaSource("music"))
        {
          Update("");
          return true;
        }
        return false;
      }

      //play and add current directory to temporary playlist
      int iPlaylist=m_guiState->GetPlaylist();
      if (iPlaylist != PLAYLIST_NONE)
      {
        g_playlistPlayer.ClearPlaylist(iPlaylist);
        g_playlistPlayer.Reset();
        int songToPlay = 0;
        CFileItemList queueItems;
        for ( int i = 0; i < m_vecItems->Size(); i++ )
        {
          CFileItemPtr item = m_vecItems->Get(i);

          if (item->m_bIsFolder)
            continue;

          if (!item->IsPlayList() && !item->IsZIP() && !item->IsRAR())
            queueItems.Add(item);

          if (item == pItem)
          { // item that was clicked
            songToPlay = queueItems.Size() - 1;
          }
        }
        g_playlistPlayer.Add(iPlaylist, queueItems);

        // Save current window and directory to know where the selected item was
        if (m_guiState.get())
          m_guiState->SetPlaylistDirectory(m_vecItems->m_strPath);

        // figure out where we start playback
        if (g_playlistPlayer.IsShuffled(iPlaylist))
        {
          int iIndex = g_playlistPlayer.GetPlaylist(iPlaylist).FindOrder(songToPlay);
          g_playlistPlayer.GetPlaylist(iPlaylist).Swap(0, iIndex);
          songToPlay = 0;
        }

        // play
        g_playlistPlayer.SetCurrentPlaylist(iPlaylist);
        g_playlistPlayer.Play(songToPlay);
      }
      return true;
    }
    else
#endif
    {
      return OnPlayMedia(iItem);
    }
  }

  return false;
}
예제 #7
0
void CGUIWindowMusicBase::OnInfo(CFileItem *pItem, bool bShowInfo)
{
  if (pItem->m_bIsFolder && pItem->IsParentFolder()) 
    return;

  if (pItem->IsVideoDb())
  {
    OnContextButton(m_viewControl.GetSelectedItem(), CONTEXT_BUTTON_INFO); // nasty but it is the same item i promise :)
    return;
  }

  CStdString strPath = pItem->m_strPath;

  // Try to find an album to lookup from the current item
  CAlbum album;
  CArtist artist;
  bool foundAlbum = false;
  
  album.idAlbum = -1;
  
  if (pItem->IsMusicDb())
  {
    CQueryParams params;
    CDirectoryNode::GetDatabaseInfo(pItem->m_strPath, params);
    if (params.GetAlbumId() == -1)
    {
      artist.idArtist = params.GetArtistId();
      artist.strArtist = pItem->GetMusicInfoTag()->GetArtist();
    }
    else
    {
      // show dialog box indicating we're searching the album name
      if (m_dlgProgress && bShowInfo)
      {
        m_dlgProgress->SetHeading(185);
        m_dlgProgress->SetLine(0, 501);
        m_dlgProgress->SetLine(1, "");
        m_dlgProgress->SetLine(2, "");
        m_dlgProgress->StartModal();
        m_dlgProgress->Progress();
        if (m_dlgProgress->IsCanceled()) 
          return;
      }

      album.idAlbum = params.GetAlbumId();
      album.strAlbum = pItem->GetMusicInfoTag()->GetAlbum();
      album.strArtist = pItem->GetMusicInfoTag()->GetArtist();

      // we're going to need it's path as well (we assume that there's only one) - this is for
      // assigning thumbs to folders, and obtaining the local folder.jpg
      m_musicdatabase.GetAlbumPath(album.idAlbum, strPath);
    }
  }
  else
  { // lookup is done on a folder - find the albums in the folder
    CFileItemList items;
    GetDirectory(strPath, items);

    // check the first song we find in the folder, and grab it's album info
    for (int i = 0; i < items.Size() && !foundAlbum; i++)
    {
      CFileItem* pItem = items[i];
      pItem->LoadMusicTag();
      if (pItem->HasMusicInfoTag() && pItem->GetMusicInfoTag()->Loaded() && 
         !pItem->GetMusicInfoTag()->GetAlbum().IsEmpty())
      {
        // great, have a song - use it.
        CSong song(*pItem->GetMusicInfoTag());
        // this function won't be needed if/when the tag has idSong information
        if (!m_musicdatabase.GetAlbumFromSong(song, album))
        { // album isn't in the database - construct it from the tag info we have
          CMusicInfoTag *tag = pItem->GetMusicInfoTag();
          album.strAlbum = tag->GetAlbum();
          album.strArtist = tag->GetAlbumArtist().IsEmpty() ? tag->GetArtist() : tag->GetAlbumArtist();
          album.idAlbum = -1; // the -1 indicates it's not in the database
        }
        foundAlbum = true;
      }
    }
    if (!foundAlbum)
    {
      CLog::Log(LOGINFO, "%s called on a folder containing no songs with tag info - nothing can be done", __FUNCTION__);
      if (m_dlgProgress && bShowInfo) m_dlgProgress->Close();
    }
  }

  if (m_dlgProgress && bShowInfo) m_dlgProgress->Close();

  if (album.idAlbum == -1 && foundAlbum == false)
    ShowArtistInfo(artist, pItem->m_strPath, false, bShowInfo);
  else
    ShowAlbumInfo(album, strPath, false, bShowInfo);
}
예제 #8
0
bool CAddonsDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  CStdString path1(strPath);
  URIUtils::RemoveSlashAtEnd(path1);
  CURL path(path1);
  items.ClearProperties();

  items.SetContent("addons");

  VECADDONS addons;
  // get info from repository
  bool reposAsFolders = true;
  if (path.GetHostName().Equals("enabled"))
  {
    CAddonMgr::Get().GetAllAddons(addons, true);
    items.SetProperty("reponame",g_localizeStrings.Get(24062));
    items.SetLabel(g_localizeStrings.Get(24062));
  }
  else if (path.GetHostName().Equals("disabled"))
  { // grab all disabled addons, including disabled repositories
    reposAsFolders = false;
    CAddonMgr::Get().GetAllAddons(addons, false, true, false);
    items.SetProperty("reponame",g_localizeStrings.Get(24039));
    items.SetLabel(g_localizeStrings.Get(24039));
  }
  else if (path.GetHostName().Equals("outdated"))
  {
    reposAsFolders = false;
    CAddonMgr::Get().GetAllOutdatedAddons(addons);
    items.SetProperty("reponame",g_localizeStrings.Get(24043));
    items.SetLabel(g_localizeStrings.Get(24043));
  }
  else if (path.GetHostName().Equals("repos"))
  {
    CAddonMgr::Get().GetAddons(ADDON_REPOSITORY,addons,true);
    items.SetLabel(g_localizeStrings.Get(24033)); // Get Add-ons
  }
  else if (path.GetHostName().Equals("sources"))
  {
    return GetScriptsAndPlugins(path.GetFileName(), items);
  }
  else if (path.GetHostName().Equals("all"))
  {
    CAddonDatabase database;
    database.Open();
    database.GetAddons(addons);
    items.SetProperty("reponame",g_localizeStrings.Get(24032));
    items.SetLabel(g_localizeStrings.Get(24032));
  }
  else if (path.GetHostName().Equals("search"))
  {
    CStdString search(path.GetFileName());
    if (search.IsEmpty() && !GetKeyboardInput(16017, search))
      return false;

    items.SetProperty("reponame",g_localizeStrings.Get(283));
    items.SetLabel(g_localizeStrings.Get(283));

    CAddonDatabase database;
    database.Open();
    database.Search(search, addons);
    GenerateListing(path, addons, items, true);

    path.SetFileName(search);
    items.SetPath(path.Get());
    return true;
  }
  else
  {
    reposAsFolders = false;
    AddonPtr addon;
    CAddonMgr::Get().GetAddon(path.GetHostName(),addon);
    if (!addon)
      return false;

    // ensure our repos are up to date
    CAddonInstaller::Get().UpdateRepos(false, true);
    CAddonDatabase database;
    database.Open();
    database.GetRepository(addon->ID(),addons);
    items.SetProperty("reponame",addon->Name());
    items.SetLabel(addon->Name());
  }

  if (path.GetFileName().IsEmpty())
  {
    if (!path.GetHostName().Equals("repos"))
    {
      for (int i=ADDON_UNKNOWN+1;i<ADDON_VIZ_LIBRARY;++i)
      {
        for (unsigned int j=0;j<addons.size();++j)
        {
          if (addons[j]->IsType((TYPE)i))
          {
            CFileItemPtr item(new CFileItem(TranslateType((TYPE)i,true)));
            item->SetPath(URIUtils::AddFileToFolder(strPath,TranslateType((TYPE)i,false)));
            item->m_bIsFolder = true;
            CStdString thumb = GetIcon((TYPE)i);
            if (!thumb.IsEmpty() && g_TextureManager.HasTexture(thumb))
              item->SetThumbnailImage(thumb);
            items.Add(item);
            break;
          }
        }
      }
      items.SetPath(strPath);
      return true;
    }
  }
  else
  {
    TYPE type = TranslateType(path.GetFileName());
    items.SetProperty("addoncategory",TranslateType(type, true));
    items.SetLabel(TranslateType(type, true));
    items.SetPath(strPath);

    // FIXME: Categorisation of addons needs adding here
    for (unsigned int j=0;j<addons.size();++j)
    {
      if (!addons[j]->IsType(type))
        addons.erase(addons.begin()+j--);
    }
  }

  items.SetPath(strPath);
  GenerateListing(path, addons, items, reposAsFolders);
  // check for available updates
  if (path.GetHostName().Equals("enabled"))
  {
    CAddonDatabase database;
    database.Open();
    for (int i=0;i<items.Size();++i)
    {
      AddonPtr addon2;
      database.GetAddon(items[i]->GetProperty("Addon.ID").asString(),addon2);
      if (addon2 && addon2->Version() > AddonVersion(items[i]->GetProperty("Addon.Version").asString())
                 && !database.IsAddonBlacklisted(addon2->ID(),addon2->Version().c_str()))
      {
        items[i]->SetProperty("Addon.Status",g_localizeStrings.Get(24068));
        items[i]->SetProperty("Addon.UpdateAvail", true);
      }
    }
  }
  if (path.GetHostName().Equals("repos") && items.Size() > 1)
  {
    CFileItemPtr item(new CFileItem("addons://all/",true));
    item->SetLabel(g_localizeStrings.Get(24032));
    items.Add(item);
  }

  return true;
}
예제 #9
0
void CGUIDialogSmartPlaylistRule::OnBrowse()
{
  CFileItemList items;
  CMusicDatabase database;
  database.Open();
  CVideoDatabase videodatabase;
  videodatabase.Open();

  std::string basePath;
  if (CSmartPlaylist::IsMusicType(m_type))
    basePath = "musicdb://";
  else
    basePath = "videodb://";

  VIDEODB_CONTENT_TYPE type = VIDEODB_CONTENT_MOVIES;
  if (m_type == "movies")
    basePath += "movies/";
  else if (m_type == "tvshows")
  {
    type = VIDEODB_CONTENT_TVSHOWS;
    basePath += "tvshows/";
  }
  else if (m_type == "musicvideos")
  {
    type = VIDEODB_CONTENT_MUSICVIDEOS;
    basePath += "musicvideos/";
  }
  else if (m_type == "episodes")
  {
    if (m_rule.m_field == FieldGenre || m_rule.m_field == FieldYear ||
        m_rule.m_field == FieldStudio)
      type = VIDEODB_CONTENT_TVSHOWS;
    else
      type = VIDEODB_CONTENT_EPISODES;
    basePath += "tvshows/";
  }

  int iLabel = 0;
  if (m_rule.m_field == FieldGenre)
  {
    if (m_type == "tvshows" ||
        m_type == "episodes" ||
        m_type == "movies")
      videodatabase.GetGenresNav(basePath + "genres/", items, type);
    else if (m_type == "songs" ||
             m_type == "albums" ||
             m_type == "artists" ||
             m_type == "mixed")
      database.GetGenresNav("musicdb://genres/",items);
    if (m_type == "musicvideos" ||
        m_type == "mixed")
    {
      CFileItemList items2;
      videodatabase.GetGenresNav("videodb://musicvideos/genres/",items2,VIDEODB_CONTENT_MUSICVIDEOS);
      items.Append(items2);
    }
    iLabel = 515;
  }
  else if (m_rule.m_field == FieldCountry)
  {
    videodatabase.GetCountriesNav(basePath, items, type);
    iLabel = 574;
  }
  else if (m_rule.m_field == FieldArtist || m_rule.m_field == FieldAlbumArtist)
  {
    if (CSmartPlaylist::IsMusicType(m_type))
      database.GetArtistsNav("musicdb://artists/", items, m_rule.m_field == FieldAlbumArtist, -1);
    if (m_type == "musicvideos" ||
        m_type == "mixed")
    {
      CFileItemList items2;
      videodatabase.GetMusicVideoArtistsByName("", items2);
      items.Append(items2);
    }
    iLabel = 557;
  }
  else if (m_rule.m_field == FieldAlbum)
  {
    if (CSmartPlaylist::IsMusicType(m_type))
      database.GetAlbumsNav("musicdb://albums/", items);
    if (m_type == "musicvideos" ||
        m_type == "mixed")
    {
      CFileItemList items2;
      videodatabase.GetMusicVideoAlbumsByName("", items2);
      items.Append(items2);
    }
    iLabel = 558;
  }
  else if (m_rule.m_field == FieldActor)
  {
    videodatabase.GetActorsNav(basePath + "actors/",items,type);
    iLabel = 20337;
  }
  else if (m_rule.m_field == FieldYear)
  {
    if (CSmartPlaylist::IsMusicType(m_type))
      database.GetYearsNav("musicdb://years/", items);
    if (CSmartPlaylist::IsVideoType(m_type))
    {
      CFileItemList items2;
      videodatabase.GetYearsNav(basePath + "years/", items2, type);
      items.Append(items2);
    }
    iLabel = 562;
  }
  else if (m_rule.m_field == FieldDirector)
  {
    videodatabase.GetDirectorsNav(basePath + "directors/", items, type);
    iLabel = 20339;
  }
  else if (m_rule.m_field == FieldStudio)
  {
    videodatabase.GetStudiosNav(basePath + "studios/", items, type);
    iLabel = 572;
  }
  else if (m_rule.m_field == FieldWriter)
  {
    videodatabase.GetWritersNav(basePath, items, type);
    iLabel = 20417;
  }
  else if (m_rule.m_field == FieldTvShowTitle ||
          (m_type == "tvshows" && m_rule.m_field == FieldTitle))
  {
    videodatabase.GetTvShowsNav(basePath + "titles/", items);
    iLabel = 20343;
  }
  else if (m_rule.m_field == FieldTitle)
  {
    if (m_type == "songs" || m_type == "mixed")
    {
      database.GetSongsNav("musicdb://songs/", items, -1, -1, -1);
      iLabel = 134;
    }
    if (m_type == "movies")
    {
      videodatabase.GetMoviesNav(basePath + "titles/", items);
      iLabel = 20342;
    }
    if (m_type == "episodes")
    {
      videodatabase.GetEpisodesNav(basePath + "titles/-1/-1/", items);
      // we need to replace the db label (<season>x<episode> <title>) with the title only
      CLabelFormatter format("%T", "");
      for (int i = 0; i < items.Size(); i++)
        format.FormatLabel(items[i].get());
      iLabel = 20360;
    }
    if (m_type == "musicvideos" || m_type == "mixed")
    {
      videodatabase.GetMusicVideosNav(basePath + "titles/", items);
      iLabel = 20389;
    }
  }
  else if (m_rule.m_field == FieldPlaylist || m_rule.m_field == FieldVirtualFolder)
  {
    // use filebrowser to grab another smart playlist

    // Note: This can cause infinite loops (playlist that refers to the same playlist) but I don't
    //       think there's any decent way to deal with this, as the infinite loop may be an arbitrary
    //       number of playlists deep, eg playlist1 -> playlist2 -> playlist3 ... -> playlistn -> playlist1
    if (CSmartPlaylist::IsVideoType(m_type))
      XFILE::CDirectory::GetDirectory("special://videoplaylists/", items, ".xsp", XFILE::DIR_FLAG_NO_FILE_DIRS);
    if (CSmartPlaylist::IsMusicType(m_type))
    {
      CFileItemList items2;
      XFILE::CDirectory::GetDirectory("special://musicplaylists/", items2, ".xsp", XFILE::DIR_FLAG_NO_FILE_DIRS);
      items.Append(items2);
    }

    for (int i = 0; i < items.Size(); i++)
    {
      CFileItemPtr item = items[i];
      CSmartPlaylist playlist;
      // don't list unloadable smartplaylists or any referencable smartplaylists
      // which do not match the type of the current smartplaylist
      if (!playlist.Load(item->GetPath()) ||
         (m_rule.m_field == FieldPlaylist &&
         (!CSmartPlaylist::CheckTypeCompatibility(m_type, playlist.GetType()) ||
         (!playlist.GetGroup().empty() || playlist.IsGroupMixed()))))
      {
        items.Remove(i);
        i -= 1;
        continue;
      }

      if (!playlist.GetName().empty())
        item->SetLabel(playlist.GetName());
    }
    iLabel = 559;
  }
  else if (m_rule.m_field == FieldPath)
  {
    VECSOURCES sources;
    if (m_type == "songs" || m_type == "mixed")
      sources = *CMediaSourceSettings::Get().GetSources("music");
    if (CSmartPlaylist::IsVideoType(m_type))
    {
      VECSOURCES sources2 = *CMediaSourceSettings::Get().GetSources("video");
      sources.insert(sources.end(),sources2.begin(),sources2.end());
    }
    g_mediaManager.GetLocalDrives(sources);
    
    std::string path = m_rule.GetParameter();
    CGUIDialogFileBrowser::ShowAndGetDirectory(sources, g_localizeStrings.Get(657), path, false);
    if (m_rule.m_parameter.size() > 0)
      m_rule.m_parameter.clear();
    if (!path.empty())
      m_rule.m_parameter.push_back(path);

    UpdateButtons();
    return;
  }
  else if (m_rule.m_field == FieldSet)
  {
    videodatabase.GetSetsNav("videodb://movies/sets/", items, VIDEODB_CONTENT_MOVIES);
    iLabel = 20434;
  }
  else if (m_rule.m_field == FieldTag)
  {
    VIDEODB_CONTENT_TYPE type = VIDEODB_CONTENT_MOVIES;
    if (m_type == "tvshows" ||
        m_type == "episodes")
      type = VIDEODB_CONTENT_TVSHOWS;
    else if (m_type == "musicvideos")
      type = VIDEODB_CONTENT_MUSICVIDEOS;
    else if (m_type != "movies")
      return;

    videodatabase.GetTagsNav(basePath + "tags/", items, type);
    iLabel = 20459;
  }
  else
  { // TODO: Add browseability in here.
    assert(false);
  }

  // sort the items
  items.Sort(SortByLabel, SortOrderAscending, CSettings::Get().GetBool(CSettings::SETTING_FILELISTS_IGNORETHEWHENSORTING) ? SortAttributeIgnoreArticle : SortAttributeNone);

  CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
  pDialog->Reset();
  pDialog->SetItems(&items);
  std::string strHeading = StringUtils::Format(g_localizeStrings.Get(13401).c_str(), g_localizeStrings.Get(iLabel).c_str());
  pDialog->SetHeading(CVariant{std::move(strHeading)});
  pDialog->SetMultiSelection(m_rule.m_field != FieldPlaylist && m_rule.m_field != FieldVirtualFolder);

  if (!m_rule.m_parameter.empty())
    pDialog->SetSelected(m_rule.m_parameter);

  pDialog->Open();
  if (pDialog->IsConfirmed())
  {
    const CFileItemList &items = pDialog->GetSelectedItems();
    m_rule.m_parameter.clear();
    for (int index = 0; index < items.Size(); index++)
      m_rule.m_parameter.push_back(items[index]->GetLabel());

    UpdateButtons();
  }
  pDialog->Reset();
}
예제 #10
0
bool CRecentlyAddedJob::UpdateVideo()
{
  CGUIWindow* home = g_windowManager.GetWindow(WINDOW_HOME);

  if ( home == NULL )
    return false;

  CLog::Log(LOGDEBUG, "CRecentlyAddedJob::UpdateVideos() - Running RecentlyAdded home screen update");
  
  int            i = 0;
  CFileItemList  items;
  CVideoDatabase videodatabase;
  
  videodatabase.Open();

  if (videodatabase.GetRecentlyAddedMoviesNav("videodb://4/", items, NUM_ITEMS))
  {  
    for (; i < items.Size(); ++i)
    {
      CFileItemPtr item = items.Get(i);
      CStdString   value;
      CStdString   strRating;
      value.Format("%i", i + 1);
      strRating.Format("%.1f", item->GetVideoInfoTag()->m_fRating);
      
      home->SetProperty("LatestMovie." + value + ".Title"       , item->GetLabel());
      home->SetProperty("LatestMovie." + value + ".Rating"      , strRating);
      home->SetProperty("LatestMovie." + value + ".Year"        , item->GetVideoInfoTag()->m_iYear);
      home->SetProperty("LatestMovie." + value + ".Plot"        , item->GetVideoInfoTag()->m_strPlot);
      home->SetProperty("LatestMovie." + value + ".RunningTime" , item->GetVideoInfoTag()->m_strRuntime);
      home->SetProperty("LatestMovie." + value + ".Path"        , item->GetVideoInfoTag()->m_strFileNameAndPath);
      home->SetProperty("LatestMovie." + value + ".Trailer"     , item->GetVideoInfoTag()->m_strTrailer);

      if (!item->HasThumbnail())
        m_thumbLoader.LoadItem(item.get());

      home->SetProperty("LatestMovie." + value + ".Thumb"       , item->GetThumbnailImage());
      home->SetProperty("LatestMovie." + value + ".Fanart"      , item->GetProperty("fanart_image"));
    }
  } 
  for (; i < NUM_ITEMS; ++i)
  {
    CStdString value;
    value.Format("%i", i + 1);
    home->SetProperty("LatestMovie." + value + ".Title"       , "");
    home->SetProperty("LatestMovie." + value + ".Thumb"       , "");
    home->SetProperty("LatestMovie." + value + ".Rating"      , "");
    home->SetProperty("LatestMovie." + value + ".Year"        , "");
    home->SetProperty("LatestMovie." + value + ".Plot"        , "");
    home->SetProperty("LatestMovie." + value + ".RunningTime" , "");
    home->SetProperty("LatestMovie." + value + ".Path"        , "");
    home->SetProperty("LatestMovie." + value + ".Trailer"     , "");
    home->SetProperty("LatestMovie." + value + ".Fanart"      , "");
  }
 
  i = 0;
  CFileItemList  TVShowItems; 
 
  if (videodatabase.GetRecentlyAddedEpisodesNav("videodb://5/", TVShowItems, NUM_ITEMS))
  {
    for (; i < TVShowItems.Size(); ++i)
    {    
      CFileItemPtr item          = TVShowItems.Get(i);
      int          EpisodeSeason = item->GetVideoInfoTag()->m_iSeason;
      int          EpisodeNumber = item->GetVideoInfoTag()->m_iEpisode;
      CStdString   EpisodeNo;
      CStdString   value;
      CStdString   strRating;
      EpisodeNo.Format("s%02de%02d", EpisodeSeason, EpisodeNumber);
      value.Format("%i", i + 1);
      strRating.Format("%.1f", item->GetVideoInfoTag()->m_fRating);

      CFileItem show(item->GetVideoInfoTag()->m_strShowPath, true);

      home->SetProperty("LatestEpisode." + value + ".ShowTitle"     , item->GetVideoInfoTag()->m_strShowTitle);
      home->SetProperty("LatestEpisode." + value + ".EpisodeTitle"  , item->GetVideoInfoTag()->m_strTitle);
      home->SetProperty("LatestEpisode." + value + ".Rating"        , strRating);      
      home->SetProperty("LatestEpisode." + value + ".Plot"          , item->GetVideoInfoTag()->m_strPlot);
      home->SetProperty("LatestEpisode." + value + ".EpisodeNo"     , EpisodeNo);
      home->SetProperty("LatestEpisode." + value + ".EpisodeSeason" , EpisodeSeason);
      home->SetProperty("LatestEpisode." + value + ".EpisodeNumber" , EpisodeNumber);
      home->SetProperty("LatestEpisode." + value + ".Path"          , item->GetVideoInfoTag()->m_strFileNameAndPath);

      if (!item->HasThumbnail())
        m_thumbLoader.LoadItem(item.get());

      std::string seasonThumb;
      if (item->GetVideoInfoTag()->m_iIdSeason > 0)
        seasonThumb = videodatabase.GetArtForItem(item->GetVideoInfoTag()->m_iIdSeason, "season", "thumb");

      home->SetProperty("LatestEpisode." + value + ".Thumb"         , item->GetThumbnailImage());
      home->SetProperty("LatestEpisode." + value + ".ShowThumb"     , item->GetProperty("tvshowthumb"));
      home->SetProperty("LatestEpisode." + value + ".SeasonThumb"   , seasonThumb);
      home->SetProperty("LatestEpisode." + value + ".Fanart"        , item->GetProperty("fanart_image"));
    }
  } 
  for (; i < NUM_ITEMS; ++i)
  {
    CStdString value;
    value.Format("%i", i + 1);
    home->SetProperty("LatestEpisode." + value + ".ShowTitle"     , "");
    home->SetProperty("LatestEpisode." + value + ".EpisodeTitle"  , "");
    home->SetProperty("LatestEpisode." + value + ".Rating"        , "");      
    home->SetProperty("LatestEpisode." + value + ".Plot"          , "");
    home->SetProperty("LatestEpisode." + value + ".EpisodeNo"     , "");
    home->SetProperty("LatestEpisode." + value + ".EpisodeSeason" , "");
    home->SetProperty("LatestEpisode." + value + ".EpisodeNumber" , "");
    home->SetProperty("LatestEpisode." + value + ".Path"          , "");
    home->SetProperty("LatestEpisode." + value + ".Thumb"         , "");
    home->SetProperty("LatestEpisode." + value + ".ShowThumb"     , "");
    home->SetProperty("LatestEpisode." + value + ".SeasonThumb"   , "");
    home->SetProperty("LatestEpisode." + value + ".Fanart"        , "");
  }  

  i = 0;
  CFileItemList MusicVideoItems;

  if (videodatabase.GetRecentlyAddedMusicVideosNav("videodb://6/", MusicVideoItems, NUM_ITEMS))
  {
    for (; i < MusicVideoItems.Size(); ++i)
    {
      CFileItemPtr item = MusicVideoItems.Get(i);
      CStdString   value;
      value.Format("%i", i + 1);

      home->SetProperty("LatestMusicVideo." + value + ".Title"       , item->GetLabel());
      home->SetProperty("LatestMusicVideo." + value + ".Year"        , item->GetVideoInfoTag()->m_iYear);
      home->SetProperty("LatestMusicVideo." + value + ".Plot"        , item->GetVideoInfoTag()->m_strPlot);
      home->SetProperty("LatestMusicVideo." + value + ".RunningTime" , item->GetVideoInfoTag()->m_strRuntime);
      home->SetProperty("LatestMusicVideo." + value + ".Path"        , item->GetVideoInfoTag()->m_strFileNameAndPath);
      home->SetProperty("LatestMusicVideo." + value + ".Artist"      , StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator));

      if (!item->HasThumbnail())
        m_thumbLoader.LoadItem(item.get());

      home->SetProperty("LatestMusicVideo." + value + ".Thumb"       , item->GetThumbnailImage());
      home->SetProperty("LatestMusicVideo." + value + ".Fanart"      , item->GetProperty("fanart_image"));
    }
  }
  for (; i < NUM_ITEMS; ++i)
  {
    CStdString value;
    value.Format("%i", i + 1);
    home->SetProperty("LatestMusicVideo." + value + ".Title"       , "");
    home->SetProperty("LatestMusicVideo." + value + ".Thumb"       , "");
    home->SetProperty("LatestMusicVideo." + value + ".Year"        , "");
    home->SetProperty("LatestMusicVideo." + value + ".Plot"        , "");
    home->SetProperty("LatestMusicVideo." + value + ".RunningTime" , "");
    home->SetProperty("LatestMusicVideo." + value + ".Path"        , "");
    home->SetProperty("LatestMusicVideo." + value + ".Artist"      , "");
    home->SetProperty("LatestMusicVideo." + value + ".Fanart"      , "");
  }

  videodatabase.Close();
  return true;
}
예제 #11
0
bool CGUIControlListSetting::OnClick()
{
  if (m_pButton == NULL)
    return false;

  CGUIDialogSelect *dialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
  if (dialog == NULL)
    return false;

  CFileItemList options;
  if (!GetItems(m_pSetting, options) || options.Size() <= 1)
    return false;

  const CSettingControlList *control = static_cast<const CSettingControlList*>(m_pSetting->GetControl());
  
  dialog->Reset();
  dialog->SetHeading(g_localizeStrings.Get(m_pSetting->GetLabel()));
  dialog->SetItems(&options);
  dialog->SetMultiSelection(control->CanMultiSelect());
  dialog->DoModal();

  if (!dialog->IsConfirmed())
    return false;

  const CFileItemList &items = dialog->GetSelectedItems();
  std::vector<CVariant> values;
  for (int index = 0; index < items.Size(); index++)
  {
    const CFileItemPtr item = items[index];
    if (item == NULL || !item->HasProperty("value"))
      return false;

    values.push_back(item->GetProperty("value"));
  }

  bool ret = false;
  switch (m_pSetting->GetType())
  {
    case SettingTypeInteger:
      if (values.size() > 1)
        return false;
      ret = ((CSettingInt *)m_pSetting)->SetValue((int)values.at(0).asInteger());
      break;

    case SettingTypeString:
      if (values.size() > 1)
        return false;
      ret = ((CSettingString *)m_pSetting)->SetValue(values.at(0).asString());
      break;

    case SettingTypeList:
      ret = CSettings::Get().SetList(m_pSetting->GetId(), values);
      break;
    
    default:
      break;
  }

  if (ret)
    Update();

  return ret;
}
예제 #12
0
bool CRecentlyAddedJob::UpdateMusic()
{
  CGUIWindow* home = g_windowManager.GetWindow(WINDOW_HOME);
  
  if ( home == NULL )
    return false;
  
  CLog::Log(LOGDEBUG, "CRecentlyAddedJob::UpdateMusic() - Running RecentlyAdded home screen update");
  
  int            i = 0;
  CFileItemList  musicItems;
  CMusicDatabase musicdatabase;
  CMusicThumbLoader loader;
  
  musicdatabase.Open();
  
  if (musicdatabase.GetRecentlyAddedAlbumSongs("musicdb://", musicItems, NUM_ITEMS))
  {
    long idAlbum = -1;
    CStdString strAlbumThumb;
    CStdString strAlbumFanart;
    for (; i < musicItems.Size(); ++i)
    {
      CFileItemPtr item = musicItems.Get(i);
      CStdString   value;
      value.Format("%i", i + 1);
      
      CStdString   strRating;
      CStdString   strAlbum  = item->GetMusicInfoTag()->GetAlbum();
      CStdString   strArtist = StringUtils::Join(item->GetMusicInfoTag()->GetArtist(), g_advancedSettings.m_musicItemSeparator);

      if (idAlbum != item->GetMusicInfoTag()->GetAlbumId())
      {
        strAlbumThumb.clear();
        strAlbumFanart.clear();
        idAlbum = item->GetMusicInfoTag()->GetAlbumId();

        if (loader.LoadItem(item.get()))
        {
          strAlbumThumb = item->GetThumbnailImage();
          strAlbumFanart = item->GetProperty("fanart_image").asString();
        }
      }

      strRating.Format("%c", item->GetMusicInfoTag()->GetRating());
      
      home->SetProperty("LatestSong." + value + ".Title"   , item->GetMusicInfoTag()->GetTitle());
      home->SetProperty("LatestSong." + value + ".Year"    , item->GetMusicInfoTag()->GetYear());
      home->SetProperty("LatestSong." + value + ".Artist"  , strArtist);      
      home->SetProperty("LatestSong." + value + ".Album"   , strAlbum);
      home->SetProperty("LatestSong." + value + ".Rating"  , strRating);
      home->SetProperty("LatestSong." + value + ".Path"    , item->GetMusicInfoTag()->GetURL());
      home->SetProperty("LatestSong." + value + ".Thumb"   , strAlbumThumb);
      home->SetProperty("LatestSong." + value + ".Fanart"  , strAlbumFanart);
    }
  }
  for (; i < NUM_ITEMS; ++i)
  {
    CStdString value;
    value.Format("%i", i + 1);
    home->SetProperty("LatestSong." + value + ".Title"   , "");
    home->SetProperty("LatestSong." + value + ".Year"    , "");
    home->SetProperty("LatestSong." + value + ".Artist"  , "");      
    home->SetProperty("LatestSong." + value + ".Album"   , "");
    home->SetProperty("LatestSong." + value + ".Rating"  , "");
    home->SetProperty("LatestSong." + value + ".Path"    , "");
    home->SetProperty("LatestSong." + value + ".Thumb"   , "");
    home->SetProperty("LatestSong." + value + ".Fanart"  , "");
  }
  
  i = 0;
  VECALBUMS albums;
  
  if (musicdatabase.GetRecentlyAddedAlbums(albums, NUM_ITEMS))
  { 
    for (; i < (int)albums.size(); ++i)
    {
      CStdString value;
      CStdString strPath;
      CStdString strThumb;
      CStdString strFanart;
      CStdString strDBpath;
      CStdString strSQLAlbum;
      CAlbum&    album=albums[i];     

      value.Format("%i", i + 1);
      strThumb = musicdatabase.GetArtForItem(album.idAlbum, "album", "thumb");
      strFanart = musicdatabase.GetArtistArtForItem(album.idAlbum, "album", "fanart");
      strDBpath.Format("musicdb://3/%i/", album.idAlbum);
      strSQLAlbum.Format("idAlbum=%i", album.idAlbum);
      
      CStdString strArtist = musicdatabase.GetSingleValue("albumview", "strArtists", strSQLAlbum);
      
      home->SetProperty("LatestAlbum." + value + ".Title"   , album.strAlbum);
      home->SetProperty("LatestAlbum." + value + ".Year"    , album.iYear);
      home->SetProperty("LatestAlbum." + value + ".Artist"  , strArtist);      
      home->SetProperty("LatestAlbum." + value + ".Rating"  , album.iRating);
      home->SetProperty("LatestAlbum." + value + ".Path"    , strDBpath);
      home->SetProperty("LatestAlbum." + value + ".Thumb"   , strThumb);
      home->SetProperty("LatestAlbum." + value + ".Fanart"  , strFanart);
    }
  }
  for (; i < NUM_ITEMS; ++i)
  {
    CStdString value;
    value.Format("%i", i + 1);
    home->SetProperty("LatestAlbum." + value + ".Title"   , "");
    home->SetProperty("LatestAlbum." + value + ".Year"    , "");
    home->SetProperty("LatestAlbum." + value + ".Artist"  , "");      
    home->SetProperty("LatestAlbum." + value + ".Rating"  , "");
    home->SetProperty("LatestAlbum." + value + ".Path"    , "");
    home->SetProperty("LatestAlbum." + value + ".Thumb"   , "");
    home->SetProperty("LatestAlbum." + value + ".Fanart"  , "");            
  }
  
  musicdatabase.Close();
  return true;
}
예제 #13
0
파일: FileScanner.cpp 프로젝트: Kr0nZ/boxee
//
//  Synchronize function will sync the file system with two different tables at the database
//  - video_files||audio_files - the fileScanner wont add files to those table, just can delete from it.
//         the resolver is the only thread that add files to those tables.
//  - unresolved_video_files||unresolved_audio_files - delete and add files from and to the tables.
void CFileScanner::SynchronizeFolderAndDatabase(const CStdString& strPath, const CStdString& strShareType,  const CStdString& strSharePath, CFileItemList &folderItems)
{

  CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, sync folder %s  with database (filescanner)", strPath.c_str());

  int iFolderId = 0;
  bool  bMarkAsNewFolder = false;
  bool  updateFolderStatus = false;
  std::map<std::string, BOXEE::BXMetadata*> dbResolvedItems;
  std::map<std::string, BOXEE::BXMetadata*>::iterator db_resolved_it;

  std::map<std::string, BOXEE::BXMetadata*> dbUnResolvedItems;
  std::map<std::string, BOXEE::BXMetadata*>::iterator db_unresolved_it;

  // if the folder doesnt exist then we should create a new db folder
  CStdString folderType = (strShareType == "music") ? "musicFolder" : "videoFolder";
  iFolderId = m_MDE->GetMediaFolderId(strPath.c_str(), folderType.c_str());

  if (iFolderId == 0)
  {
    iFolderId = m_MDE->AddMediaFolder(strPath.c_str(), folderType.c_str(), BoxeeUtils::GetModTime(strPath));
    bMarkAsNewFolder = true;
  }

  CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, folder %s id %d (filescanner)",strPath.c_str(), iFolderId);

  if (strShareType == "music")
  {
    m_MDE->GetAudiosByFolder(dbResolvedItems, strPath.c_str());
    m_MDE->GetUnresolvedAudioFilesByFolder(dbUnResolvedItems, iFolderId);
  }
  else if (strShareType == "video")
  {
    m_MDE->GetVideosByFolder(dbResolvedItems, strPath.c_str(), true );
    m_MDE->GetUnresolvedVideoFilesByFolder(dbUnResolvedItems, iFolderId);
  }
  else
  {
    CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, not music or video share - skip (filescanner)");
    return;
  }

  // Go over all folder items
  int i =0;
  while (m_currentShareValid && i < folderItems.Size() &&  (!dbResolvedItems.empty() || !dbUnResolvedItems.empty()))
  {
    db_resolved_it = dbResolvedItems.find(folderItems[i]->m_strPath);
    db_unresolved_it = dbUnResolvedItems.find(folderItems[i]->m_strPath);
    bool bRemoveFromFolderItems = false;

    // the item was found in the both resolved_filles table and folder,
    // so we shouldn't add or remove it from the data base
    // we will only modify the ResolvedItems since  we can just delete
    // from those tables and not add to it
    if (db_resolved_it != dbResolvedItems.end())
    {
      // check also if the video file still fits for size limitation then
      if ((strShareType != "video")  || folderItems[i]->m_bIsFolder || folderItems[i]->GetSize() >=  g_guiSettings.GetInt("myvideos.videosize") * 1024 * 1024)
      {
        delete db_resolved_it->second;
        dbResolvedItems.erase(db_resolved_it);
      }
      else
      {
        CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase file %s doesn't fit size limitation %lld - remove from the data base (filescanner)",folderItems[i]->m_strPath.c_str(),folderItems[i]->GetSize());
      }
      bRemoveFromFolderItems = true;
    }
    else
    {
      CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, file %s wasn't found in video_files  (filescanner)", folderItems[i]->m_strPath.c_str());
    }

    // the item was found in the both data base and folder,
    // so we shouldn't add or remove it from the data base
    if (db_unresolved_it != dbUnResolvedItems.end())
    {
      // check also if the file still fits for size limitation then
      if  ((strShareType != "video")  || folderItems[i]->m_bIsFolder || folderItems[i]->GetSize() >=  g_guiSettings.GetInt("myvideos.videosize") * 1024 * 1024)
      {
        delete db_unresolved_it->second;
        dbUnResolvedItems.erase(db_unresolved_it);
      }
      else
      {
        CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase  file %s doesn't fit size limitation - remove from the data base (filescanner)",folderItems[i]->m_strPath.c_str());
      }
      bRemoveFromFolderItems = true;
    }
    else
    {
      CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, file %s wasn't found in unresolved_video_files  (filescanner)", folderItems[i]->m_strPath.c_str());
    }

    if (bRemoveFromFolderItems)
      folderItems.Remove(i);
    else
      i++;
  }

  // after this phase we have too lists:
  // dbResolvedlist   - items that exist only in the resolved table and need to be deleted
  // dbUnResolvedlist - items that exist only in the unresolved tables and need to be deleted
  // folderlist - new items that exist only in the folder and need to be add to the unresolved_folder
  for (i = 0 ; m_currentShareValid && i < folderItems.Size(); i++ )
  {
    iFolderId = m_MDE->GetMediaFolderId(strPath.c_str(), folderType.c_str());

    updateFolderStatus = true;

    if (strShareType == "video")
    {
      if (folderItems[i]->m_bIsFolder || folderItems[i]->GetSize() >=  g_guiSettings.GetInt("myvideos.videosize") * 1024 * 1024)
      {
        CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, Added %s %s to db (filescanner)",(folderItems[i]->m_bIsFolder)?"folder":"file", folderItems[i]->m_strPath.c_str());
        m_MDE->AddVideoFile(folderItems[i]->m_strPath, strSharePath, iFolderId, folderItems[i]->m_dwSize);
      }
      else
      {
        CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, file %s size is %lld smaller then limitation (filescanner)", folderItems[i]->m_strPath.c_str(), folderItems[i]->GetSize());
      }
    }
    else
    {
      CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, Add file %s to db (filescanner)", folderItems[i]->m_strPath.c_str());
      m_MDE->AddAudioFile(folderItems[i]->m_strPath, strSharePath, iFolderId, folderItems[i]->m_dwSize);
    }
  }

  db_resolved_it = dbResolvedItems.begin();
  while (m_currentShareValid && db_resolved_it != dbResolvedItems.end())
  {
    CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, delete file %s from resolved table (filescanner)", db_resolved_it->first.c_str());
    updateFolderStatus = true;
    if (strShareType == "video")
      m_MDE->RemoveVideoByPath(db_resolved_it->first);
    else
      m_MDE->RemoveAudioByPath(db_resolved_it->first);
    ++db_resolved_it;
  }


  db_unresolved_it = dbUnResolvedItems.begin();
  while (m_currentShareValid && db_unresolved_it != dbUnResolvedItems.end())
  {
    CLog::Log(LOGDEBUG,"CFileScanner::SynchronizeFolderAndDatabase, delete file %s from unresolved table (filescanner)", db_unresolved_it->first.c_str());
    updateFolderStatus = true;
    if (strShareType == "video")
      m_MDE->RemoveUnresolvedVideoByPath(db_unresolved_it->first);
    else
      m_MDE->RemoveUnresolvedAudioByPath(db_unresolved_it->first);
    ++db_unresolved_it;
  }

  if (updateFolderStatus || bMarkAsNewFolder)
  {
    m_MDE->MarkFolderNew(strPath.c_str());
  }

}
예제 #14
0
bool CButtonTranslator::Load()
{
  translatorMap.clear();

  //directories to search for keymaps
  //they're applied in this order,
  //so keymaps in profile/keymaps/
  //override e.g. system/keymaps
  static const char* DIRS_TO_CHECK[] = {
    "special://xbmc/system/keymaps/",
    "special://masterprofile/keymaps/",
    "special://profile/keymaps/"
  };
  bool success = false;

  for(unsigned int dirIndex = 0; dirIndex < sizeof(DIRS_TO_CHECK)/sizeof(DIRS_TO_CHECK[0]); ++dirIndex) {
    if( XFILE::CDirectory::Exists(DIRS_TO_CHECK[dirIndex]) )
    {
      CFileItemList files;
      XFILE::CDirectory::GetDirectory(DIRS_TO_CHECK[dirIndex], files, "*.xml");
      //sort the list for filesystem based prioties, e.g. 01-keymap.xml, 02-keymap-overrides.xml
      files.Sort(SORT_METHOD_FILE, SORT_ORDER_ASC);
      for(int fileIndex = 0; fileIndex<files.Size(); ++fileIndex)
        success |= LoadKeymap(files[fileIndex]->m_strPath);
    }
  }

  if (!success)
  {
    CLog::Log(LOGERROR, "Error loading keymaps from: %s or %s or %s", DIRS_TO_CHECK[0], DIRS_TO_CHECK[1], DIRS_TO_CHECK[2]);
    return false;
  }

#if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
#ifdef _LINUX
#define REMOTEMAP "Lircmap.xml"
#else
#define REMOTEMAP "IRSSmap.xml"
#endif
  CStdString lircmapPath;
  URIUtils::AddFileToFolder("special://xbmc/system/", REMOTEMAP, lircmapPath);
  lircRemotesMap.clear();
  if(CFile::Exists(lircmapPath))
    success |= LoadLircMap(lircmapPath);
  else
    CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no system %s found, skipping", REMOTEMAP);

  lircmapPath = g_settings.GetUserDataItem(REMOTEMAP);
  if(CFile::Exists(lircmapPath))
    success |= LoadLircMap(lircmapPath);
  else
    CLog::Log(LOGDEBUG, "CButtonTranslator::Load - no userdata %s found, skipping", REMOTEMAP);

  if (!success)
    CLog::Log(LOGERROR, "CButtonTranslator::Load - unable to load remote map %s", REMOTEMAP);
    // don't return false - it is to only indicate a fatal error (which this is not)

#endif

  // Done!
  return true;
}
예제 #15
0
파일: URL.cpp 프로젝트: Kr0nZ/boxee
CStdString CURI::GetWithoutUserDetails() const
{
  CStdString strURL;

  if (m_strProtocol.Equals("stack"))
  {
    CFileItemList items;
    CStdString strURL2;
    strURL2 = Get();
    DIRECTORY::CStackDirectory dir;
    dir.GetDirectory(strURL2,items);
    vector<CStdString> newItems;
    for (int i=0;i<items.Size();++i)
    {
      CURI url(items[i]->m_strPath);
      items[i]->m_strPath = url.GetWithoutUserDetails();
      newItems.push_back(items[i]->m_strPath);
    }
    dir.ConstructStackPath(newItems,strURL);
    return strURL;
  }

  unsigned int sizeneed = m_strProtocol.length()
                        + m_strDomain.length()
                        + m_strHostName.length()
                        + m_strFileName.length()
                        + m_strOptions.length()
                        + m_strProtocolOptions.length()
                        + 10;

  strURL.reserve(sizeneed);

  if (m_strProtocol == "")
    return m_strFileName;

  strURL = m_strProtocol;
  strURL += "://";

  if (m_strHostName != "")
  {
    if (m_strProtocol.Equals("rar") || m_strProtocol.Equals("zip"))
      strURL += CURI(m_strHostName).GetWithoutUserDetails();
    else
      strURL += m_strHostName;

    if ( HasPort() )
    {
      CStdString strPort;
      strPort.Format("%i", m_iPort);
      strURL += ":";
      strURL += strPort;
    }
    strURL += "/";
  }
  strURL += m_strFileName;

  if( m_strOptions.length() > 0 )
    strURL += m_strOptions;
  if( m_strProtocolOptions.length() > 0 )
    strURL += "|"+m_strProtocolOptions;

  return strURL;
}
예제 #16
0
void CGUIWindowMusicBase::PlayItem(int iItem)
{
  // restrictions should be placed in the appropiate window code
  // only call the base code if the item passes since this clears
  // the current playlist

  const CFileItemPtr pItem = m_vecItems->Get(iItem);

  // special case for DAAP playlist folders
  bool bIsDAAPplaylist = false;
#ifdef HAS_FILESYSTEM_DAAP
  if (pItem->IsDAAP() && pItem->m_bIsFolder)
  {
    CDAAPDirectory dirDAAP;
    if (dirDAAP.GetCurrLevel(pItem->m_strPath) == 0)
      bIsDAAPplaylist = true;
  }
#endif
  // if its a folder, build a playlist
  if (pItem->m_bIsFolder || (g_windowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList()))
  {
    // make a copy so that we can alter the queue state
    CFileItemPtr item(new CFileItem(*m_vecItems->Get(iItem)));

    //  Allow queuing of unqueueable items
    //  when we try to queue them directly
    if (!item->CanQueue())
      item->SetCanQueue(true);

    // skip ".."
    if (item->IsParentFolder())
      return;

    CFileItemList queuedItems;
    AddItemToPlayList(item, queuedItems);
#ifndef _BOXEE_
    if (g_partyModeManager.IsEnabled())
    {
      g_partyModeManager.AddUserSongs(queuedItems, true);
      return;
    }
#endif

//Boxee
    for (int i=0; i<queuedItems.Size()-1; i++)
      queuedItems[i]->SetProperty("NextItemLabel", queuedItems[i+1]->GetLabel());
//end Boxee

    /*
    CStdString strPlayListDirectory = m_vecItems->m_strPath;
    CUtil::RemoveSlashAtEnd(strPlayListDirectory);
    */

    g_playlistPlayer.ClearPlaylist(PLAYLIST_MUSIC);
    g_playlistPlayer.Reset();
    g_playlistPlayer.Add(PLAYLIST_MUSIC, queuedItems);
    g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_MUSIC);

    // activate the playlist window if its not activated yet
    if (bIsDAAPplaylist && GetID() == g_windowManager.GetActiveWindow())
      g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST);

    // play!
    g_playlistPlayer.Play();

    g_application.getApplicationMessenger().SwitchToFullscreen();

  }
  else if (pItem->IsPlayList())
  {
    // load the playlist the old way
    LoadPlayList(pItem->m_strPath);
  }
  else
  {
    // just a single item, play it
    // TODO: Add music-specific code for single playback of an item here (See OnClick in MediaWindow, and OnPlayMedia below)
    OnClick(iItem);
  }
}
예제 #17
0
/*!
  \brief Overwrite to fill fileitems from a source
  \param strDirectory Path to read
  \param items Fill with items specified in \e strDirectory
  */
bool CGUIMediaWindow::GetDirectory(const CStdString &strDirectory, CFileItemList &items)
{
  // cleanup items
  if (items.Size())
    items.Clear();

  CStdString strParentPath=m_history.GetParentPath();

  CLog::Log(LOGDEBUG,"CGUIMediaWindow::GetDirectory (%s)", strDirectory.c_str());
  CLog::Log(LOGDEBUG,"  ParentPath = [%s]", strParentPath.c_str());

  // see if we can load a previously cached folder
  CFileItemList cachedItems(strDirectory);
  if (!strDirectory.IsEmpty() && cachedItems.Load())
  {
    items.Assign(cachedItems);
  }
  else
  {
    unsigned int time = CTimeUtils::GetTimeMS();

    if (!m_rootDir.GetDirectory(strDirectory, items))
      return false;

    // took over a second, and not normally cached, so cache it
    if (time + 1000 < CTimeUtils::GetTimeMS() && items.CacheToDiscIfSlow())
      items.Save();

    // if these items should replace the current listing, then pop it off the top
    if (items.GetReplaceListing())
      m_history.RemoveParentPath();
  }

  if (m_guiState.get() && !m_guiState->HideParentDirItems() && !items.m_strPath.IsEmpty())
  {
    CFileItemPtr pItem(new CFileItem(".."));
    pItem->m_strPath = strParentPath;
    pItem->m_bIsFolder = true;
    pItem->m_bIsShareOrDrive = false;
    items.AddFront(pItem, 0);
  }

  int iWindow = GetID();
  CStdStringArray regexps;

  if (iWindow == WINDOW_VIDEO_FILES)
    regexps = g_advancedSettings.m_videoExcludeFromListingRegExps;
  if (iWindow == WINDOW_MUSIC_FILES)
    regexps = g_advancedSettings.m_audioExcludeFromListingRegExps;
  if (iWindow == WINDOW_PICTURES)
    regexps = g_advancedSettings.m_pictureExcludeFromListingRegExps;

  if (regexps.size())
  {
    for (int i=0; i < items.Size();)
    {
      if (CUtil::ExcludeFileOrFolder(items[i]->m_strPath, regexps))
        items.Remove(i);
      else
        i++;
    }
  }

  // clear window properties at root or plugin root
  if (items.IsVirtualDirectoryRoot() || items.IsPluginRoot())
    ClearProperties();

  return true;
}
예제 #18
0
void CGUIWindowMusicBase::OnInfo(CFileItem *pItem, bool bShowInfo)
{
// Boxee
  if (bShowInfo)
  {
    g_application.CurrentFileItem() = *pItem;
    if (pItem->IsLastFM() || pItem->IsRSS() || pItem->IsPlugin() || pItem->IsShoutCast())
    {
      CGUIDialogBoxeeAppCtx *pContext = (CGUIDialogBoxeeAppCtx*)g_windowManager.GetWindow(WINDOW_DIALOG_BOXEE_APP_CTX);
      pContext->SetItem(*pItem);
      pContext->DoModal();
    }
    else
    {
      if (pItem->HasMusicInfoTag() && !pItem->GetPropertyBOOL("IsArtist"))
      {
        CGUIDialogBoxeeMusicCtx *pContext = (CGUIDialogBoxeeMusicCtx*)g_windowManager.GetWindow(WINDOW_DIALOG_BOXEE_MUSIC_CTX);
        pContext->SetItem(*pItem);
        pContext->OnMoreInfo();
      }
      else
      {
  	    CGUIWindowMusicInfo* pDlgInfo = (CGUIWindowMusicInfo*)g_windowManager.GetWindow(WINDOW_MUSIC_INFO);
        if (pDlgInfo)
        {
          *(pDlgInfo->GetCurrentListItem()) = *pItem;
          pDlgInfo->DoModal();
        }
      }
    }
    return;
  }
// end boxee section  

  if (pItem->m_bIsFolder && pItem->IsParentFolder()) 
    return;

  if (!pItem->m_bIsFolder)
  { // song lookup
    ShowSongInfo(pItem);
    return;
  }

  CStdString strPath = pItem->m_strPath;

  // Try to find an album to lookup from the current item
  CAlbum album;
  CArtist artist;
  bool foundAlbum = false;
  
  album.idAlbum = -1;
  
  // we have a folder
  if (pItem->IsMusicDb())
  {
    CQueryParams params;
    CDirectoryNode::GetDatabaseInfo(pItem->m_strPath, params);
    if (params.GetAlbumId() == -1)
    { // artist lookup
      artist.idArtist = params.GetArtistId();
      artist.strArtist = pItem->GetMusicInfoTag()->GetArtist();
    }
    else
    { // album lookup
      album.idAlbum = params.GetAlbumId();
      album.strAlbum = pItem->GetMusicInfoTag()->GetAlbum();
      album.strArtist = pItem->GetMusicInfoTag()->GetArtist();

      // we're going to need it's path as well (we assume that there's only one) - this is for
      // assigning thumbs to folders, and obtaining the local folder.jpg
      m_musicdatabase.GetAlbumPath(album.idAlbum, strPath);
    }
  }
  else
  { // from filemode, so find the albums in the folder
    CFileItemList items;
    GetDirectory(strPath, items);

    // show dialog box indicating we're searching the album name
    if (m_dlgProgress && bShowInfo)
    {
      m_dlgProgress->SetHeading(185);
      m_dlgProgress->SetLine(0, 501);
      m_dlgProgress->SetLine(1, "");
      m_dlgProgress->SetLine(2, "");
      m_dlgProgress->StartModal();
      m_dlgProgress->Progress();
      if (m_dlgProgress->IsCanceled())
        return;
    }
    // check the first song we find in the folder, and grab it's album info
    for (int i = 0; i < items.Size() && !foundAlbum; i++)
    {
      CFileItemPtr pItem = items[i];
      pItem->LoadMusicTag();
      if (pItem->HasMusicInfoTag() && pItem->GetMusicInfoTag()->Loaded() && 
         !pItem->GetMusicInfoTag()->GetAlbum().IsEmpty())
      {
        // great, have a song - use it.
        CSong song(*pItem->GetMusicInfoTag());
        // this function won't be needed if/when the tag has idSong information
        if (!m_musicdatabase.GetAlbumFromSong(song, album))
        { // album isn't in the database - construct it from the tag info we have
          CMusicInfoTag *tag = pItem->GetMusicInfoTag();
          album.strAlbum = tag->GetAlbum();
          album.strArtist = tag->GetAlbumArtist().IsEmpty() ? tag->GetArtist() : tag->GetAlbumArtist();
          album.idAlbum = -1; // the -1 indicates it's not in the database
        }
        foundAlbum = true;
      }
    }
    if (!foundAlbum)
    {
      CLog::Log(LOGINFO, "%s called on a folder containing no songs with tag info - nothing can be done", __FUNCTION__);
      if (m_dlgProgress && bShowInfo)
        m_dlgProgress->Close();
      return;
    }

    if (m_dlgProgress && bShowInfo)
      m_dlgProgress->Close();
  }

  if (album.idAlbum == -1 && foundAlbum == false)
    ShowArtistInfo(artist, pItem->m_strPath, false, bShowInfo);
  else
    ShowAlbumInfo(album, strPath, false, bShowInfo);
}
예제 #19
0
void CGUIWindowMusicBase::UpdateThumb(const CAlbum &album, const CStdString &path)
{
  // check user permissions
  bool saveDb = album.idAlbum != -1;
  bool saveDirThumb = true;
  if (!g_settings.m_vecProfiles[g_settings.m_iLastLoadedProfileIndex].canWriteDatabases() && !g_passwordManager.bMasterUser)
  {
    saveDb = false;
    saveDirThumb = false;
  }

  CStdString albumThumb(CUtil::GetCachedAlbumThumb(album.strAlbum, album.strArtist));

  // Update the thumb in the music database (songs + albums)
  CStdString albumPath(path);
  if (saveDb && CFile::Exists(albumThumb))
    m_musicdatabase.SaveAlbumThumb(album.idAlbum, albumThumb);

  // Update currently playing song if it's from the same album.  This is necessary as when the album
  // first gets it's cover, the info manager's item doesn't have the updated information (so will be
  // sending a blank thumb to the skin.)
  if (g_application.IsPlayingAudio())
  {
    CStdString strSongFolder;
    const CMusicInfoTag* tag=g_infoManager.GetCurrentSongTag();
    if (tag)
    {
      // really, this may not be enough as it is to reliably update this item.  eg think of various artists albums
      // that aren't tagged as such (and aren't yet scanned).  But we probably can't do anything better than this
      // in that case
      if (album.strAlbum == tag->GetAlbum() && (album.strArtist == tag->GetAlbumArtist() || 
                                                album.strArtist == tag->GetArtist()))
      {
        g_infoManager.SetCurrentAlbumThumb(albumThumb);
      }
    }
  }

  // Save this thumb as the directory thumb if it's the only album in the folder (files view nicety)
  // We do this by grabbing all the songs in the folder, and checking to see whether they come
  // from the same album.
  if (saveDirThumb && CFile::Exists(albumThumb) && !albumPath.IsEmpty() && !CUtil::IsCDDA(albumPath))
  {
    CFileItemList items;
    GetDirectory(albumPath, items);
    OnRetrieveMusicInfo(items);
    VECSONGS songs;
    for (int i = 0; i < items.Size(); i++)
    {
      CFileItem *item = items[i];
      if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->Loaded())
      {
        CSong song(*item->GetMusicInfoTag());
        songs.push_back(song);
      }
    }
    CMusicInfoScanner::CheckForVariousArtists(songs);
    CStdString album, artist;
    if (CMusicInfoScanner::HasSingleAlbum(songs, album, artist))
    { // can cache as the folder thumb
      CStdString folderThumb(CUtil::GetCachedMusicThumb(albumPath));
      ::CopyFile(albumThumb, folderThumb, false);
    }
  }

  // update the file listing
  int iSelectedItem = m_viewControl.GetSelectedItem();
  if (iSelectedItem >= 0 && m_vecItems->Get(iSelectedItem))
  {
    CFileItem* pSelectedItem=m_vecItems->Get(iSelectedItem);
    if (pSelectedItem->m_bIsFolder)
    {
      // refresh only the icon of
      // the current folder
      pSelectedItem->FreeMemory();
      if (!pSelectedItem->HasThumbnail())
        pSelectedItem->SetThumbnailImage(albumThumb);
      pSelectedItem->FillInDefaultIcon();
    }
    else
    {
      // Refresh all items
      m_vecItems->RemoveDiscCache();
      Update(m_vecItems->m_strPath);
    }

    //  Do we have to autoswitch to the thumb control?
    m_guiState.reset(CGUIViewState::GetViewState(GetID(), *m_vecItems));
    UpdateButtons();
  }
}
예제 #20
0
void CApplicationMessenger::ProcessMessage(ThreadMessage *pMsg)
{
  switch (pMsg->dwMessage)
  {
    case TMSG_SHUTDOWN:
      {
        switch (CSettings::Get().GetInt("powermanagement.shutdownstate"))
        {
          case POWERSTATE_SHUTDOWN:
            Powerdown();
            break;

          case POWERSTATE_SUSPEND:
            Suspend();
            break;

          case POWERSTATE_HIBERNATE:
            Hibernate();
            break;

          case POWERSTATE_QUIT:
            Quit();
            break;

          case POWERSTATE_MINIMIZE:
            Minimize();
            break;

          case TMSG_RENDERER_FLUSH:
            g_renderManager.Flush();
            break;
        }
      }
      break;

    case TMSG_POWERDOWN:
      {
        g_application.Stop(EXITCODE_POWERDOWN);
        g_powerManager.Powerdown();
      }
      break;

    case TMSG_QUIT:
      {
        g_application.Stop(EXITCODE_QUIT);
      }
      break;

    case TMSG_HIBERNATE:
      {
        g_PVRManager.SetWakeupCommand();
        g_powerManager.Hibernate();
      }
      break;

    case TMSG_SUSPEND:
      {
        g_PVRManager.SetWakeupCommand();
        g_powerManager.Suspend();
      }
      break;

    case TMSG_RESTART:
    case TMSG_RESET:
      {
        g_application.Stop(EXITCODE_REBOOT);
        g_powerManager.Reboot();
      }
      break;

    case TMSG_RESTARTAPP:
      {
#if defined(TARGET_WINDOWS) || defined(TARGET_LINUX)
        g_application.Stop(EXITCODE_RESTARTAPP);
#endif
      }
      break;

    case TMSG_INHIBITIDLESHUTDOWN:
      {
        g_application.InhibitIdleShutdown(pMsg->dwParam1 != 0);
      }
      break;

    case TMSG_ACTIVATESCREENSAVER:
      {
        g_application.ActivateScreenSaver();
      }
      break;

    case TMSG_MEDIA_PLAY:
      {
        // first check if we were called from the PlayFile() function
        if (pMsg->lpVoid && pMsg->dwParam2 == 0)
        {
          CFileItem *item = (CFileItem *)pMsg->lpVoid;
          g_application.PlayFile(*item, pMsg->dwParam1 != 0);
          delete item;
          return;
        }
        // restore to previous window if needed
        if (g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW ||
            g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
            g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION)
          g_windowManager.PreviousWindow();

        g_application.ResetScreenSaver();
        g_application.WakeUpScreenSaverAndDPMS();

        //g_application.StopPlaying();
        // play file
        if(pMsg->lpVoid)
        {
          CFileItemList *list = (CFileItemList *)pMsg->lpVoid;

          if (list->Size() > 0)
          {
            int playlist = PLAYLIST_MUSIC;
            for (int i = 0; i < list->Size(); i++)
            {
              if ((*list)[i]->IsVideo())
              {
                playlist = PLAYLIST_VIDEO;
                break;
              }
            }

            g_playlistPlayer.ClearPlaylist(playlist);
            g_playlistPlayer.SetCurrentPlaylist(playlist);
            //For single item lists try PlayMedia. This covers some more cases where a playlist is not appropriate
            //It will fall through to PlayFile
            if (list->Size() == 1 && !(*list)[0]->IsPlayList())
              g_application.PlayMedia(*((*list)[0]), playlist);
            else
            {
              // Handle "shuffled" option if present
              if (list->HasProperty("shuffled") && list->GetProperty("shuffled").isBoolean())
                g_playlistPlayer.SetShuffle(playlist, list->GetProperty("shuffled").asBoolean(), false);
              // Handle "repeat" option if present
              if (list->HasProperty("repeat") && list->GetProperty("repeat").isInteger())
                g_playlistPlayer.SetRepeat(playlist, (PLAYLIST::REPEAT_STATE)list->GetProperty("repeat").asInteger(), false);

              g_playlistPlayer.Add(playlist, (*list));
              g_playlistPlayer.Play(pMsg->dwParam1);
            }
          }

          delete list;
        }
        else if (pMsg->dwParam1 == PLAYLIST_MUSIC || pMsg->dwParam1 == PLAYLIST_VIDEO)
        {
          if (g_playlistPlayer.GetCurrentPlaylist() != (int)pMsg->dwParam1)
            g_playlistPlayer.SetCurrentPlaylist(pMsg->dwParam1);

          PlayListPlayerPlay(pMsg->dwParam2);
        }
      }
      break;

    case TMSG_MEDIA_RESTART:
      g_application.Restart(true);
      break;

    case TMSG_PICTURE_SHOW:
      {
        CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
        if (!pSlideShow) return ;

        // stop playing file
        if (g_application.m_pPlayer->IsPlayingVideo()) g_application.StopPlaying();

        if (g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO)
          g_windowManager.PreviousWindow();

        g_application.ResetScreenSaver();
        g_application.WakeUpScreenSaverAndDPMS();

        g_graphicsContext.Lock();

        if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
          g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
        if (URIUtils::IsZIP(pMsg->strParam) || URIUtils::IsRAR(pMsg->strParam)) // actually a cbz/cbr
        {
          CFileItemList items;
          CStdString strPath;
          if (URIUtils::IsZIP(pMsg->strParam))
            URIUtils::CreateArchivePath(strPath, "zip", pMsg->strParam.c_str(), "");
          else
            URIUtils::CreateArchivePath(strPath, "rar", pMsg->strParam.c_str(), "");

          CUtil::GetRecursiveListing(strPath, items, g_advancedSettings.m_pictureExtensions);
          if (items.Size() > 0)
          {
            pSlideShow->Reset();
            for (int i=0;i<items.Size();++i)
            {
              pSlideShow->Add(items[i].get());
            }
            pSlideShow->Select(items[0]->GetPath());
          }
        }
        else
        {
          CFileItem item(pMsg->strParam, false);
          pSlideShow->Reset();
          pSlideShow->Add(&item);
          pSlideShow->Select(pMsg->strParam);
        }
        g_graphicsContext.Unlock();
      }
      break;

    case TMSG_PICTURE_SLIDESHOW:
      {
        CGUIWindowSlideShow *pSlideShow = (CGUIWindowSlideShow *)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
        if (!pSlideShow) return ;

        if (g_application.m_pPlayer->IsPlayingVideo())
          g_application.StopPlaying();

        g_graphicsContext.Lock();
        pSlideShow->Reset();

        CFileItemList items;
        CStdString strPath = pMsg->strParam;
        CStdString extensions = g_advancedSettings.m_pictureExtensions;
        if (pMsg->dwParam1)
          extensions += "|.tbn";
        CUtil::GetRecursiveListing(strPath, items, extensions);

        if (items.Size() > 0)
        {
          for (int i=0;i<items.Size();++i)
            pSlideShow->Add(items[i].get());
          pSlideShow->StartSlideShow(); //Start the slideshow!
        }

        if (g_windowManager.GetActiveWindow() != WINDOW_SLIDESHOW)
        {
          if(items.Size() == 0)
          {
            CSettings::Get().SetString("screensaver.mode", "screensaver.xbmc.builtin.dim");
            g_application.ActivateScreenSaver();
          }
          else
            g_windowManager.ActivateWindow(WINDOW_SLIDESHOW);
        }

        g_graphicsContext.Unlock();
      }
      break;

    case TMSG_SETLANGUAGE:
      g_application.SetLanguage(pMsg->strParam);
      break;
    case TMSG_MEDIA_STOP:
      {
        // restore to previous window if needed
        bool stopSlideshow = true;
        bool stopVideo = true;
        bool stopMusic = true;
        if (pMsg->dwParam1 >= PLAYLIST_MUSIC && pMsg->dwParam1 <= PLAYLIST_PICTURE)
        {
          stopSlideshow = (pMsg->dwParam1 == PLAYLIST_PICTURE);
          stopVideo = (pMsg->dwParam1 == PLAYLIST_VIDEO);
          stopMusic = (pMsg->dwParam1 == PLAYLIST_MUSIC);
        }

        if ((stopSlideshow && g_windowManager.GetActiveWindow() == WINDOW_SLIDESHOW) ||
            (stopVideo && g_windowManager.GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO) ||
            (stopMusic && g_windowManager.GetActiveWindow() == WINDOW_VISUALISATION))
          g_windowManager.PreviousWindow();

        g_application.ResetScreenSaver();
        g_application.WakeUpScreenSaverAndDPMS();

        // stop playing file
        if (g_application.m_pPlayer->IsPlaying()) g_application.StopPlaying();
      }
      break;

    case TMSG_MEDIA_PAUSE:
      if (g_application.m_pPlayer->HasPlayer())
      {
        g_application.ResetScreenSaver();
        g_application.WakeUpScreenSaverAndDPMS();
        g_application.m_pPlayer->Pause();
      }
      break;

    case TMSG_MEDIA_UNPAUSE:
      if (g_application.m_pPlayer->IsPausedPlayback())
      {
        g_application.ResetScreenSaver();
        g_application.WakeUpScreenSaverAndDPMS();
        g_application.m_pPlayer->Pause();
      }
      break;

    case TMSG_MEDIA_PAUSE_IF_PLAYING:
      if (g_application.m_pPlayer->IsPlaying() && !g_application.m_pPlayer->IsPaused())
      {
        g_application.ResetScreenSaver();
        g_application.WakeUpScreenSaverAndDPMS();
        g_application.m_pPlayer->Pause();
      }
      break;

    case TMSG_SWITCHTOFULLSCREEN:
      if( g_windowManager.GetActiveWindow() != WINDOW_FULLSCREEN_VIDEO )
        g_application.SwitchToFullScreen();
      break;

    case TMSG_TOGGLEFULLSCREEN:
      g_graphicsContext.Lock();
      g_graphicsContext.ToggleFullScreenRoot();
      g_graphicsContext.Unlock();
      break;

    case TMSG_MINIMIZE:
      g_application.Minimize();
      break;

    case TMSG_EXECUTE_OS:
      /* Suspend AE temporarily so exclusive or hog-mode sinks */
      /* don't block external player's access to audio device  */
      if (!CAEFactory::Suspend())
      {
        CLog::Log(LOGNOTICE, "%s: Failed to suspend AudioEngine before launching external program",__FUNCTION__);
      }
#if defined( TARGET_POSIX) && !defined(TARGET_DARWIN)
      CUtil::RunCommandLine(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
#elif defined(TARGET_WINDOWS)
      CWIN32Util::XBMCShellExecute(pMsg->strParam.c_str(), (pMsg->dwParam1 == 1));
#endif
      /* Resume AE processing of XBMC native audio */
      if (!CAEFactory::Resume())
      {
        CLog::Log(LOGFATAL, "%s: Failed to restart AudioEngine after return from external player",__FUNCTION__);
      }
      break;

    case TMSG_EXECUTE_SCRIPT:
      CScriptInvocationManager::Get().Execute(pMsg->strParam);
      break;

    case TMSG_EXECUTE_BUILT_IN:
      CBuiltins::Execute(pMsg->strParam.c_str());
      break;

    case TMSG_PLAYLISTPLAYER_PLAY:
      if (pMsg->dwParam1 != (unsigned int) -1)
        g_playlistPlayer.Play(pMsg->dwParam1);
      else
        g_playlistPlayer.Play();
      break;

    case TMSG_PLAYLISTPLAYER_PLAY_SONG_ID:
      if (pMsg->dwParam1 != (unsigned int) -1)
      {
        bool *result = (bool*)pMsg->lpVoid;
        *result = g_playlistPlayer.PlaySongId(pMsg->dwParam1);
      }
      else
        g_playlistPlayer.Play();
      break;

    case TMSG_PLAYLISTPLAYER_NEXT:
      g_playlistPlayer.PlayNext();
      break;

    case TMSG_PLAYLISTPLAYER_PREV:
      g_playlistPlayer.PlayPrevious();
      break;

    case TMSG_PLAYLISTPLAYER_ADD:
      if(pMsg->lpVoid)
      {
        CFileItemList *list = (CFileItemList *)pMsg->lpVoid;

        g_playlistPlayer.Add(pMsg->dwParam1, (*list));
        delete list;
      }
      break;

    case TMSG_PLAYLISTPLAYER_INSERT:
      if (pMsg->lpVoid)
      {
        CFileItemList *list = (CFileItemList *)pMsg->lpVoid;
        g_playlistPlayer.Insert(pMsg->dwParam1, (*list), pMsg->dwParam2);
        delete list;
      }
      break;

    case TMSG_PLAYLISTPLAYER_REMOVE:
      if (pMsg->dwParam1 != (unsigned int) -1)
        g_playlistPlayer.Remove(pMsg->dwParam1,pMsg->dwParam2);
      break;

    case TMSG_PLAYLISTPLAYER_CLEAR:
      g_playlistPlayer.ClearPlaylist(pMsg->dwParam1);
      break;

    case TMSG_PLAYLISTPLAYER_SHUFFLE:
      g_playlistPlayer.SetShuffle(pMsg->dwParam1, pMsg->dwParam2 > 0);
      break;

    case TMSG_PLAYLISTPLAYER_REPEAT:
      g_playlistPlayer.SetRepeat(pMsg->dwParam1, (PLAYLIST::REPEAT_STATE)pMsg->dwParam2);
      break;

    case TMSG_PLAYLISTPLAYER_GET_ITEMS:
      if (pMsg->lpVoid)
      {
        PLAYLIST::CPlayList playlist = g_playlistPlayer.GetPlaylist(pMsg->dwParam1);
        CFileItemList *list = (CFileItemList *)pMsg->lpVoid;

        for (int i = 0; i < playlist.size(); i++)
          list->Add(CFileItemPtr(new CFileItem(*playlist[i])));
      }
      break;

    case TMSG_PLAYLISTPLAYER_SWAP:
      if (pMsg->lpVoid)
      {
        vector<int> *indexes = (vector<int> *)pMsg->lpVoid;
        if (indexes->size() == 2)
          g_playlistPlayer.Swap(pMsg->dwParam1, indexes->at(0), indexes->at(1));
        delete indexes;
      }
      break;

    // Window messages below here...
    case TMSG_DIALOG_DOMODAL:  //doModel of window
      {
        CGUIDialog* pDialog = (CGUIDialog*)g_windowManager.GetWindow(pMsg->dwParam1);
        if (!pDialog) return ;
        pDialog->DoModal();
      }
      break;

    case TMSG_NETWORKMESSAGE:
      {
        g_application.getNetwork().NetworkMessage((CNetwork::EMESSAGE)pMsg->dwParam1, (int)pMsg->dwParam2);
      }
      break;

    case TMSG_GUI_DO_MODAL:
      {
        CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
        if (pDialog)
          pDialog->DoModal((int)pMsg->dwParam1, pMsg->strParam);
      }
      break;

    case TMSG_GUI_SHOW:
      {
        CGUIDialog *pDialog = (CGUIDialog *)pMsg->lpVoid;
        if (pDialog)
          pDialog->Show();
      }
      break;

    case TMSG_GUI_WINDOW_CLOSE:
      {
        CGUIWindow *window = (CGUIWindow *)pMsg->lpVoid;
        if (window)
          window->Close(pMsg->dwParam2 & 0x1 ? true : false, pMsg->dwParam1, pMsg->dwParam2 & 0x2 ? true : false);
      }
      break;

    case TMSG_GUI_ACTIVATE_WINDOW:
      {
        g_windowManager.ActivateWindow(pMsg->dwParam1, pMsg->params, pMsg->dwParam2 > 0);
      }
      break;

    case TMSG_GUI_ADDON_DIALOG:
      {
        if (pMsg->lpVoid)
        { // TODO: This is ugly - really these python dialogs should just be normal XBMC dialogs
          ((ADDON::CGUIAddonWindowDialog *) pMsg->lpVoid)->Show_Internal(pMsg->dwParam2 > 0);
        }
      }
      break;

#ifdef HAS_PYTHON
    case TMSG_GUI_PYTHON_DIALOG:
      {
        // This hack is not much better but at least I don't need to make ApplicationMessenger
        //  know about Addon (Python) specific classes.
        CAction caction(pMsg->dwParam1);
        ((CGUIWindow*)pMsg->lpVoid)->OnAction(caction);
      }
      break;
#endif

    case TMSG_GUI_ACTION:
      {
        if (pMsg->lpVoid)
        {
          CAction *action = (CAction *)pMsg->lpVoid;
          if (pMsg->dwParam1 == WINDOW_INVALID)
            g_application.OnAction(*action);
          else
          {
            CGUIWindow *pWindow = g_windowManager.GetWindow(pMsg->dwParam1);  
            if (pWindow)
              pWindow->OnAction(*action);
            else
              CLog::Log(LOGWARNING, "Failed to get window with ID %i to send an action to", pMsg->dwParam1);
          }
          delete action;
        }
      }
      break;

    case TMSG_GUI_MESSAGE:
      {
        if (pMsg->lpVoid)
        {
          CGUIMessage *message = (CGUIMessage *)pMsg->lpVoid;
          g_windowManager.SendMessage(*message, pMsg->dwParam1);
          delete message;
        }
      }
      break;

    case TMSG_GUI_INFOLABEL:
      {
        if (pMsg->lpVoid)
        {
          vector<CStdString> *infoLabels = (vector<CStdString> *)pMsg->lpVoid;
          for (unsigned int i = 0; i < pMsg->params.size(); i++)
            infoLabels->push_back(g_infoManager.GetLabel(g_infoManager.TranslateString(pMsg->params[i])));
        }
      }
      break;
    case TMSG_GUI_INFOBOOL:
      {
        if (pMsg->lpVoid)
        {
          vector<bool> *infoLabels = (vector<bool> *)pMsg->lpVoid;
          for (unsigned int i = 0; i < pMsg->params.size(); i++)
            infoLabels->push_back(g_infoManager.EvaluateBool(pMsg->params[i]));
        }
      }
      break;

    case TMSG_CALLBACK:
      {
        ThreadMessageCallback *callback = (ThreadMessageCallback*)pMsg->lpVoid;
        callback->callback(callback->userptr);
      }
      break;

    case TMSG_VOLUME_SHOW:
      {
        CAction action((int)pMsg->dwParam1);
        g_application.ShowVolumeBar(&action);
      }
      break;

    case TMSG_SPLASH_MESSAGE:
      {
        if (g_application.GetSplash())
          g_application.GetSplash()->Show(pMsg->strParam);
      }
      break;
      
    case TMSG_DISPLAY_SETUP:
    {
      *((bool*)pMsg->lpVoid) = g_application.InitWindow();
      g_application.SetRenderGUI(true);
    }
    break;
    
    case TMSG_DISPLAY_DESTROY:
    {
      *((bool*)pMsg->lpVoid) = g_application.DestroyWindow();
      g_application.SetRenderGUI(false);
    }
    break;

    case TMSG_UPDATE_CURRENT_ITEM:
    {
      CFileItem* item = (CFileItem*)pMsg->lpVoid;
      if (!item)
        return;
      if (pMsg->dwParam1 == 1 && item->HasMusicInfoTag()) // only grab music tag
        g_infoManager.SetCurrentSongTag(*item->GetMusicInfoTag());
      else if (pMsg->dwParam1 == 2 && item->HasVideoInfoTag()) // only grab video tag
        g_infoManager.SetCurrentVideoTag(*item->GetVideoInfoTag());
      else
        g_infoManager.SetCurrentItem(*item);
      delete item;
      break;
    }

    case TMSG_LOADPROFILE:
    {
      CGUIWindowLoginScreen::LoadProfile(pMsg->dwParam1);
      break;
    }
    case TMSG_CECTOGGLESTATE:
    {
      *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_SWITCH_TOGGLE);
      break;
    }
    case TMSG_CECACTIVATESOURCE:
    {
      *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_ACTIVATE_SOURCE);
      break;
    }
    case TMSG_CECSTANDBY:
    {
      *((bool*)pMsg->lpVoid) = g_peripherals.ToggleDeviceState(STATE_STANDBY);
      break;
    }
    case TMSG_START_ANDROID_ACTIVITY:
    {
#if defined(TARGET_ANDROID)
      if (pMsg->params.size())
      {
        CXBMCApp::StartActivity(pMsg->params[0],
                                pMsg->params.size() > 1 ? pMsg->params[1] : "",
                                pMsg->params.size() > 2 ? pMsg->params[2] : "",
                                pMsg->params.size() > 3 ? pMsg->params[3] : "");
      }
#endif
      break;
    }
  }
}
예제 #21
0
/// \brief Add unique file and folders and its subfolders to playlist
/// \param pItem The file item to add
void CGUIWindowMusicBase::AddItemToPlayList(const CFileItem* pItem, CFileItemList &queuedItems)
{
  if (!pItem->CanQueue() || pItem->IsRAR() || pItem->IsZIP() || pItem->IsParentFolder()) // no zip/rar enques thank you!
    return;

  if (pItem->IsMusicDb() && pItem->m_bIsFolder && !pItem->IsParentFolder())
  { // we have a music database folder, just grab the "all" item underneath it
    CMusicDatabaseDirectory dir;
    if (!dir.ContainsSongs(pItem->m_strPath))
    { // grab the ALL item in this category
      // Genres will still require 2 lookups, and queuing the entire Genre folder
      // will require 3 lookups (genre, artist, album)
      CFileItem item(pItem->m_strPath + "-1/", true);
      item.SetCanQueue(true); // workaround for CanQueue() check above
      AddItemToPlayList(&item, queuedItems);
      return;
    }
  }
  if (pItem->m_bIsFolder || (m_gWindowManager.GetActiveWindow() == WINDOW_MUSIC_NAV && pItem->IsPlayList()))
  {
    // Check if we add a locked share
    if ( pItem->m_bIsShareOrDrive )
    {
      CFileItem item = *pItem;
      if ( !g_passwordManager.IsItemUnlocked( &item, "music" ) )
        return ;
    }

    // recursive
    CFileItemList items;
    GetDirectory(pItem->m_strPath, items);
    //OnRetrieveMusicInfo(items);
    FormatAndSort(items);
    for (int i = 0; i < items.Size(); ++i)
      AddItemToPlayList(items[i], queuedItems);
  }
  else
  {
    if (pItem->IsPlayList())
    {
      auto_ptr<CPlayList> pPlayList (CPlayListFactory::Create(*pItem));
      if (pPlayList.get())
      {
        // load it
        if (!pPlayList->Load(pItem->m_strPath))
        {
          CGUIDialogOK::ShowAndGetInput(6, 0, 477, 0);
          return; //hmmm unable to load playlist?
        }

        CPlayList playlist = *pPlayList;
        for (int i = 0; i < (int)playlist.size(); ++i)
          AddItemToPlayList(&playlist[i], queuedItems);
        return;
      }
    }
    else if(pItem->IsInternetStream())
    { // just queue the internet stream, it will be expanded on play
      queuedItems.Add(new CFileItem(*pItem));
    }
    else if (!pItem->IsNFO() && pItem->IsAudio())
    {
      CFileItem *itemCheck = queuedItems.Get(pItem->m_strPath);
      if (!itemCheck || itemCheck->m_lStartOffset != pItem->m_lStartOffset)
      { // add item
        CLog::Log(LOGDEBUG, "Adding item (%s) to playlist", pItem->m_strPath.c_str());
        queuedItems.Add(new CFileItem(*pItem));
      }
    }
  }
}
예제 #22
0
//*********************************************************************************************
bool CFileRar::Open(const CURL& url, bool bBinary)
{
  CStdString strFile; 
  url.GetURL(strFile);
  
  InitFromUrl(url);
  CFileItemList items;
  g_RarManager.GetFilesInRar(items,m_strRarPath,false);
  int i;
  for (i=0;i<items.Size();++i)
  {
    if (items[i]->GetLabel() == m_strPathInRar)
      break;
  }

  if (i<items.Size())
    if (items[i]->m_idepth == 0x30) // stored
    {
      if (!OpenInArchive())
        return false;

      m_iFileSize = items[i]->m_dwSize;
      m_bOpen = true;
      
      // perform 'noidx' check
      CFileInfo* pFile = g_RarManager.GetFileInRar(m_strRarPath,m_strPathInRar);
      if (pFile)
        if (pFile->m_iIsSeekable == -1)
        {
          if (Seek(-1,SEEK_END) == -1)
          {
            m_bSeekable = false;
            pFile->m_iIsSeekable = 0;
          }
        }
        else
         m_bSeekable = (pFile->m_iIsSeekable == 1);

        return true;
    }
    else 
    {
#ifdef HAS_XBOX_HARDWARE
      if (items[i]->m_dwSize > ((__int64)4)*1024*1024*1024) // 4 gig limit of fat-x
      {
        CGUIDialogOK::ShowAndGetInput(257,21395,-1,-1);
        CLog::Log(LOGERROR,"CFileRar::Open: Can't cache files bigger than 4GB due to fat-x limits.");
        return false;
      }
#endif
      m_bUseFile = true;
      CStdString strPathInCache;
      
      if (!g_RarManager.CacheRarredFile(strPathInCache, m_strRarPath, m_strPathInRar, EXFILE_AUTODELETE | m_bFileOptions, m_strCacheDir, items[i]->m_dwSize))
      {
      	CLog::Log(LOGERROR,"filerar::open failed to cache file %s",m_strPathInRar.c_str());
        return false;
      }
      
      if (!m_File.Open( strPathInCache, bBinary)) 
      {
		CLog::Log(LOGERROR,"filerar::open failed to open file in cache: %s",strPathInCache.c_str());
        return false;
      }
      
      m_bOpen = true;
      return true;
    }

  return false;
}
예제 #23
0
std::string CGUIDialogSelectGameClient::ShowAndGetGameClient(const std::string &gamePath, const GameClientVector& candidates, const GameClientVector& installable)
{
  std::string gameClient;

  LogGameClients(candidates, installable);

  std::string extension = URIUtils::GetExtension(gamePath);
  std::string xmlPath = CSavestateUtils::MakeMetadataPath(gamePath);

  // Load savestate
  CSavestate save;
  CSavestateDatabase db;
  CLog::Log(LOGDEBUG, "Select game client dialog: Loading savestate metadata %s", CURL::GetRedacted(xmlPath).c_str());
  const bool bLoaded = db.GetSavestate(xmlPath, save);

  // Get savestate game client
  std::string saveGameClient;
  if (bLoaded)
  {
    saveGameClient = save.GameClient();
    CLog::Log(LOGDEBUG, "Select game client dialog: Auto-selecting %s", saveGameClient.c_str());
  }

  // "Select emulator for {0:s}"
  CGUIDialogSelect *dialog = GetDialog(StringUtils::Format(g_localizeStrings.Get(35258), extension));
  if (dialog != nullptr)
  {
    // Turn the addons into items
    CFileItemList items;
    for (const auto &candidate : candidates)
    {
      CFileItemPtr item(XFILE::CAddonsDirectory::FileItemFromAddon(candidate, candidate->ID()));
      item->SetLabel2(g_localizeStrings.Get(35257)); // "Installed"
      if (item->GetPath() == saveGameClient)
        item->SetLabel2(item->GetLabel2() + ", " + g_localizeStrings.Get(35259)); // "Saved"
      items.Add(std::move(item));
    }
    for (const auto &addon : installable)
    {
      CFileItemPtr item(XFILE::CAddonsDirectory::FileItemFromAddon(addon, addon->ID()));
      items.Add(std::move(item));
    }
    items.Sort(SortByLabel, SortOrderAscending);

    dialog->SetItems(items);

    for (int i = 0; i < items.Size(); i++)
    {
      if (items[i]->GetPath() == saveGameClient)
        dialog->SetSelected(i);
    }

    dialog->Open();

    // If the "Get More" button has been pressed, show a list of installable addons
    if (dialog->IsConfirmed())
    {
      int selectedIndex = dialog->GetSelectedItem();

      if (0 <= selectedIndex && selectedIndex < items.Size())
      {
        gameClient = items[selectedIndex]->GetPath();

        CLog::Log(LOGDEBUG, "Select game client dialog: User selected emulator %s", gameClient.c_str());

        if (Install(gameClient))
        {
          // If the addon is disabled we need to enable it
          if (!Enable(gameClient))
            CLog::Log(LOGDEBUG, "Failed to enable game client %s", gameClient.c_str());
        }
        else
          CLog::Log(LOGDEBUG, "Failed to install game client: %s", gameClient.c_str());
      }
      else
      {
        CLog::Log(LOGDEBUG, "Select game client dialog: User selected invalid emulator %d", selectedIndex);
      }
    }
    else
    {
      CLog::Log(LOGDEBUG, "Select game client dialog: User cancelled game client installation");
    }
  }

  return gameClient;
}
예제 #24
0
void CPlayList::Add(CFileItemList& items)
{
  for (int i = 0; i < (int)items.Size(); i++)
    Add(items[i]);
}
예제 #25
0
bool CGUIWindowPVRBase::PlayRecording(CFileItem *item, bool bPlayMinimized /* = false */, bool bCheckResume /* = true */)
{
  if (!item->HasPVRRecordingInfoTag())
    return false;

  std::string stream = item->GetPVRRecordingInfoTag()->m_strStreamURL;
  if (stream.empty())
  {
    if (bCheckResume)
      CheckResumeRecording(item);
    CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(*item)));
    return true;
  }

  /* Isolate the folder from the filename */
  size_t found = stream.find_last_of("/");
  if (found == std::string::npos)
    found = stream.find_last_of("\\");

  if (found != std::string::npos)
  {
    /* Check here for asterisk at the begin of the filename */
    if (stream[found+1] == '*')
    {
      /* Create a "stack://" url with all files matching the extension */
      std::string ext = URIUtils::GetExtension(stream);
      std::string dir = stream.substr(0, found);

      CFileItemList items;
      XFILE::CDirectory::GetDirectory(dir, items);
      items.Sort(SortByFile, SortOrderAscending);

      std::vector<int> stack;
      for (int i = 0; i < items.Size(); ++i)
      {
        if (URIUtils::HasExtension(items[i]->GetPath(), ext))
          stack.push_back(i);
      }

      if (stack.empty())
      {
        /* If we have a stack change the path of the item to it */
        XFILE::CStackDirectory dir;
        std::string stackPath = dir.ConstructStackPath(items, stack);
        item->SetPath(stackPath);
      }
    }
    else
    {
      /* If no asterisk is present play only the given stream URL */
      item->SetPath(stream);
    }
  }
  else
  {
    CLog::Log(LOGERROR, "CGUIWindowPVRCommon - %s - can't open recording: no valid filename", __FUNCTION__);
    CGUIDialogOK::ShowAndGetInput(CVariant{19033}, CVariant{19036});
    return false;
  }

  if (bCheckResume)
    CheckResumeRecording(item);
  CApplicationMessenger::GetInstance().PostMsg(TMSG_MEDIA_PLAY, 0, 0, static_cast<void*>(new CFileItem(*item)));

  return true;
}
예제 #26
0
파일: Autorun.cpp 프로젝트: Sithisackt/kodi
/**
 * This method tries to determine what type of disc is located in the given drive and starts to play the content appropriately.
 */
bool CAutorun::RunDisc(IDirectory* pDir, const std::string& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */)
{
  bool bPlaying(false);
  CFileItemList vecItems;

  const CURL pathToUrl(strDrive);
  if ( !pDir->GetDirectory( pathToUrl, vecItems ) )
  {
    return false;
  }

  // Sorting necessary for easier HDDVD handling
  vecItems.Sort(SortByLabel, SortOrderAscending);

  bool bAllowVideo = true;
//  bool bAllowPictures = true;
  bool bAllowMusic = true;
  if (!g_passwordManager.IsMasterLockUnlocked(false))
  {
    bAllowVideo = !CProfilesManager::Get().GetCurrentProfile().videoLocked();
//    bAllowPictures = !CProfilesManager::Get().GetCurrentProfile().picturesLocked();
    bAllowMusic = !CProfilesManager::Get().GetCurrentProfile().musicLocked();
  }

  // is this a root folder we have to check the content to determine a disc type
  if( bRoot )
  {
    std::string hddvdname = "";
    CFileItemPtr phddvdItem;

    // check root folders next, for normal structured dvd's
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];

      // is the current item a (non system) folder?
      if (pItem->m_bIsFolder && pItem->GetPath() != "." && pItem->GetPath() != "..")
      {
        std::string name = pItem->GetPath();
        URIUtils::RemoveSlashAtEnd(name);
        name = URIUtils::GetFileName(name);

        // Check if the current foldername indicates a DVD structure (name is "VIDEO_TS")
        if (StringUtils::EqualsNoCase(name, "VIDEO_TS") && bAllowVideo
        && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          std::string path = URIUtils::AddFileToFolder(pItem->GetPath(), "VIDEO_TS.IFO");
          if(!CFile::Exists(path))
            path = URIUtils::AddFileToFolder(pItem->GetPath(), "video_ts.ifo");
          CFileItemPtr item(new CFileItem(path, false));
          item->SetLabel(g_mediaManager.GetDiskLabel(strDrive));
          item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

          if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty())
            item->m_lStartOffset = STARTOFFSET_RESUME;

          g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false);
          g_playlistPlayer.Add(PLAYLIST_VIDEO, item);
          g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.Play(0);
          return true;
        }

        // Check if the current foldername indicates a Blu-Ray structure (default is "BDMV").
        // A BR should also include an "AACS" folder for encryption, Sony-BRs can also include update folders for PS3 (PS3_UPDATE / PS3_VPRM).
        // ToDo: for the time beeing, the DVD autorun settings are used to determine if the BR should be started automatically.
        if (StringUtils::EqualsNoCase(name, "BDMV") && bAllowVideo
        && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          CFileItemPtr item(new CFileItem(URIUtils::AddFileToFolder(pItem->GetPath(), "index.bdmv"), false));
          item->SetLabel(g_mediaManager.GetDiskLabel(strDrive));
          item->GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

          if (!startFromBeginning && !item->GetVideoInfoTag()->m_strFileNameAndPath.empty())
            item->m_lStartOffset = STARTOFFSET_RESUME;

          g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false);
          if (!CGUIWindowVideoBase::ShowPlaySelection(item))
            return false;
          g_playlistPlayer.Add(PLAYLIST_VIDEO, item);
          g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.Play(0);
          return true;
        }

        // Check if the current foldername indicates a HD DVD structure (default is "HVDVD_TS").
        // Most HD DVD will also include an "ADV_OBJ" folder for advanced content. This folder should be handled first.
        // ToDo: for the time beeing, the DVD autorun settings are used to determine if the HD DVD should be started automatically.
        CFileItemList items, sitems;
        
        // Advanced Content HD DVD (most discs?)
        if (StringUtils::EqualsNoCase(name, "ADV_OBJ"))
        {
          CLog::Log(LOGINFO,"HD DVD: Checking for playlist.");
          // find playlist file
          CDirectory::GetDirectory(pItem->GetPath(), items, "*.xpl");
          if (items.Size())
          {
            // HD DVD Standard says the highest numbered playlist has to be handled first.
            CLog::Log(LOGINFO,"HD DVD: Playlist found. Set filetypes to *.xpl for external player.");
            items.Sort(SortByLabel, SortOrderDescending);
            phddvdItem = pItem; 
            hddvdname = URIUtils::GetFileName(items[0]->GetPath());
            CLog::Log(LOGINFO,"HD DVD: %s", items[0]->GetPath().c_str());
          }
        }

        // Standard Content HD DVD (few discs?)
        if (StringUtils::EqualsNoCase(name, "HVDVD_TS") && bAllowVideo
        && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          if (hddvdname == "")
          {
            CLog::Log(LOGINFO,"HD DVD: Checking for ifo.");
            // find Video Manager or Title Set Information
            CDirectory::GetDirectory(pItem->GetPath(), items, "HV*.ifo");
            if (items.Size())
            {
              // HD DVD Standard says the lowest numbered ifo has to be handled first.
              CLog::Log(LOGINFO,"HD DVD: IFO found. Set filename to HV* and filetypes to *.ifo for external player.");
              items.Sort(SortByLabel, SortOrderAscending);
              phddvdItem = pItem; 
              hddvdname = URIUtils::GetFileName(items[0]->GetPath());
              CLog::Log(LOGINFO,"HD DVD: %s",items[0]->GetPath().c_str());
            }
          }
          // Find and sort *.evo files for internal playback.
          // While this algorithm works for all of my HD DVDs, it may fail on other discs. If there are very large extras which are
          // alphabetically before the main movie they will be sorted to the top of the playlist and get played first.
          CDirectory::GetDirectory(pItem->GetPath(), items, "*.evo");
          if (items.Size())
          {
            // Sort *.evo files in alphabetical order.
            items.Sort(SortByLabel, SortOrderAscending);
            int64_t asize = 0;
            int ecount = 0;
            // calculate average size of elements above 1gb
            for (int j = 0; j < items.Size(); j++)
              if (items[j]->m_dwSize > 1000000000)
              {
                ecount++;
                asize = asize + items[j]->m_dwSize;
              }
            asize = asize / ecount;
            // Put largest files in alphabetical order to top of new list.
            for (int j = 0; j < items.Size(); j++)
              if (items[j]->m_dwSize >= asize)
                sitems.Add (items[j]);
            // Sort *.evo files by size.
            items.Sort(SortBySize, SortOrderDescending);
            // Add other files with descending size to bottom of new list.
            for (int j = 0; j < items.Size(); j++)
              if (items[j]->m_dwSize < asize)
                sitems.Add (items[j]);
            // Replace list with optimized list.
            items.Clear();
            items.Copy (sitems);
            sitems.Clear();
          }
          if (hddvdname != "")
          {
            CFileItem item(URIUtils::AddFileToFolder(phddvdItem->GetPath(), hddvdname), false);
            item.SetLabel(g_mediaManager.GetDiskLabel(strDrive));
            item.GetVideoInfoTag()->m_strFileNameAndPath = g_mediaManager.GetDiskUniqueId(strDrive);

            if (!startFromBeginning && !item.GetVideoInfoTag()->m_strFileNameAndPath.empty())
            item.m_lStartOffset = STARTOFFSET_RESUME;

            // get playername
            std::string hddvdplayer = CPlayerCoreFactory::Get().GetPlayerName(CPlayerCoreFactory::Get().GetDefaultPlayer(item));
            
            // Single *.xpl or *.ifo files require an external player to handle playback.
            // If no matching rule was found, DVDPlayer will be default player.
            if (hddvdplayer != "DVDPlayer")
            {
              CLog::Log(LOGINFO,"HD DVD: External singlefile playback initiated: %s",hddvdname.c_str());
              g_application.PlayFile(item, false);
              return true;
            } else
              CLog::Log(LOGINFO,"HD DVD: No external player found. Fallback to internal one.");
          }

          //  internal *.evo playback.
          CLog::Log(LOGINFO,"HD DVD: Internal multifile playback initiated.");
          g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.SetShuffle (PLAYLIST_VIDEO, false);
          g_playlistPlayer.Add(PLAYLIST_VIDEO, items);
          g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
          g_playlistPlayer.Play(0);
          return true;
        }
				
        // Video CDs can have multiple file formats. First we need to determine which one is used on the CD
        std::string strExt;
        if (StringUtils::EqualsNoCase(name, "MPEGAV"))
          strExt = ".dat";
        if (StringUtils::EqualsNoCase(name, "MPEG2"))
          strExt = ".mpg";

        // If a file format was extracted we are sure this is a VCD. Autoplay if settings indicate we should.
        if (!strExt.empty() && bAllowVideo
             && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          CFileItemList items;
          CDirectory::GetDirectory(pItem->GetPath(), items, strExt);
          if (items.Size())
          {
            items.Sort(SortByLabel, SortOrderAscending);
            g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Add(PLAYLIST_VIDEO, items);
            g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Play(0);
            return true;
          }
        }
        /* Probably want this if/when we add some automedia action dialog...
        else if (pItem->GetPath().Find("PICTURES") != -1 && bAllowPictures
              && (bypassSettings))
        {
          bPlaying = true;
          std::string strExec = StringUtils::Format("RecursiveSlideShow(%s)", pItem->GetPath().c_str());
          CBuiltins::Execute(strExec);
          return true;
        }
        */
      }
    }
  }

  // check video first
  if (!nAddedToPlaylist && !bPlaying && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
  {
    // stack video files
    CFileItemList tempItems;
    tempItems.Append(vecItems);
    if (CSettings::Get().GetBool("myvideos.stackvideos"))
      tempItems.Stack();
    CFileItemList itemlist;

    for (int i = 0; i < tempItems.Size(); i++)
    {
      CFileItemPtr pItem = tempItems[i];
      if (!pItem->m_bIsFolder && pItem->IsVideo())
      {
        bPlaying = true;
        if (pItem->IsStack())
        {
          // TODO: remove this once the app/player is capable of handling stacks immediately
          CStackDirectory dir;
          CFileItemList items;
          dir.GetDirectory(pItem->GetURL(), items);
          itemlist.Append(items);
        }
        else
          itemlist.Add(pItem);
      }
    }
    if (itemlist.Size())
    {
      if (!bAllowVideo)
      {
        if (!bypassSettings)
          return false;

        if (g_windowManager.GetActiveWindow() != WINDOW_VIDEO_FILES)
          if (!g_passwordManager.IsMasterLockUnlocked(true))
            return false;
      }
      g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
      g_playlistPlayer.Add(PLAYLIST_VIDEO, itemlist);
      g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
      g_playlistPlayer.Play(0);
    }
  }
  // then music
  if (!bPlaying && (bypassSettings || CSettings::Get().GetInt("audiocds.autoaction") == AUTOCD_PLAY) && bAllowMusic)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];
      if (!pItem->m_bIsFolder && pItem->IsAudio())
      {
        nAddedToPlaylist++;
        g_playlistPlayer.Add(PLAYLIST_MUSIC, pItem);
      }
    }
  }
  /* Probably want this if/when we add some automedia action dialog...
  // and finally pictures
  if (!nAddedToPlaylist && !bPlaying && bypassSettings && bAllowPictures)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr pItem = vecItems[i];
      if (!pItem->m_bIsFolder && pItem->IsPicture())
      {
        bPlaying = true;
        std::string strExec = StringUtils::Format("RecursiveSlideShow(%s)", strDrive.c_str());
        CBuiltins::Execute(strExec);
        break;
      }
    }
  }
  */

  // check subdirs if we are not playing yet
  if (!bPlaying)
  {
    for (int i = 0; i < vecItems.Size(); i++)
    {
      CFileItemPtr  pItem = vecItems[i];
      if (pItem->m_bIsFolder)
      {
        if (pItem->GetPath() != "." && pItem->GetPath() != ".." )
        {
          if (RunDisc(pDir, pItem->GetPath(), nAddedToPlaylist, false, bypassSettings, startFromBeginning))
          {
            bPlaying = true;
            break;
          }
        }
      } // if (non system) folder
    } // for all items in directory
  } // if root folder

  return bPlaying;
}
예제 #27
0
int CMusicInfoScanner::RetrieveMusicInfo(CFileItemList& items, const CStdString& strDirectory)
{
  CSongMap songsMap;

  // get all information for all files in current directory from database, and remove them
  if (m_musicDatabase.RemoveSongsFromPath(strDirectory, songsMap))
    m_needsCleanup = true;

  VECSONGS songsToAdd;

  CStdStringArray regexps = g_advancedSettings.m_audioExcludeFromScanRegExps;

  // for every file found, but skip folder
  for (int i = 0; i < items.Size(); ++i)
  {
    CFileItemPtr pItem = items[i];
    CStdString strExtension;
    URIUtils::GetExtension(pItem->GetPath(), strExtension);

    if (m_bStop)
      return 0;

    // Discard all excluded files defined by m_musicExcludeRegExps
    if (CUtil::ExcludeFileOrFolder(pItem->GetPath(), regexps))
      continue;

    // dont try reading id3tags for folders, playlists or shoutcast streams
    if (!pItem->m_bIsFolder && !pItem->IsPlayList() && !pItem->IsPicture() && !pItem->IsLyrics() )
    {
      m_currentItem++;
//      CLog::Log(LOGDEBUG, "%s - Reading tag for: %s", __FUNCTION__, pItem->GetPath().c_str());

      // grab info from the song
      CSong *dbSong = songsMap.Find(pItem->GetPath());

      CMusicInfoTag& tag = *pItem->GetMusicInfoTag();
      if (!tag.Loaded() )
      { // read the tag from a file
        auto_ptr<IMusicInfoTagLoader> pLoader (CMusicInfoTagLoaderFactory::CreateLoader(pItem->GetPath()));
        if (NULL != pLoader.get())
          pLoader->Load(pItem->GetPath(), tag);
      }

      // if we have the itemcount, update our
      // dialog with the progress we made
      if (m_handle && m_itemCount>0)
        m_handle->SetPercentage(m_currentItem/(double)m_itemCount*100);

      if (tag.Loaded())
      {
        CSong song(tag);

        // ensure our song has a valid filename or else it will assert in AddSong()
        if (song.strFileName.IsEmpty())
        {
          // copy filename from path in case UPnP or other tag loaders didn't specify one (FIXME?)
          song.strFileName = pItem->GetPath();

          // if we still don't have a valid filename, skip the song
          if (song.strFileName.IsEmpty())
          {
            // this shouldn't ideally happen!
            CLog::Log(LOGERROR, "Skipping song since it doesn't seem to have a filename");
            continue;
          }
        }

        song.iStartOffset = pItem->m_lStartOffset;
        song.iEndOffset = pItem->m_lEndOffset;
        song.strThumb = pItem->GetUserMusicThumb(true);
        if (dbSong)
        { // keep the db-only fields intact on rescan...
          song.iTimesPlayed = dbSong->iTimesPlayed;
          song.lastPlayed = dbSong->lastPlayed;
          song.iKaraokeNumber = dbSong->iKaraokeNumber;

          if (song.rating == '0') song.rating = dbSong->rating;
          if (song.strThumb.empty())
            song.strThumb = dbSong->strThumb;
        }
        songsToAdd.push_back(song);
//        CLog::Log(LOGDEBUG, "%s - Tag loaded for: %s", __FUNCTION__, pItem->GetPath().c_str());
      }
      else
        CLog::Log(LOGDEBUG, "%s - No tag found for: %s", __FUNCTION__, pItem->GetPath().c_str());
    }
  }

  VECALBUMS albums;
  CategoriseAlbums(songsToAdd, albums);
  FindArtForAlbums(albums, items.GetPath());

  // finally, add these to the database
  m_musicDatabase.BeginTransaction();
  int numAdded = 0;
  set<long> albumsToScan;
  set<long> artistsToScan;
  for (VECALBUMS::iterator i = albums.begin(); i != albums.end(); ++i)
  {
    vector<int> songIDs;
    int idAlbum = m_musicDatabase.AddAlbum(*i, songIDs);
    numAdded += i->songs.size();
    if (m_bStop)
    {
      m_musicDatabase.RollbackTransaction();
      return numAdded;
    }

    // Build the artist & album sets
    albumsToScan.insert(idAlbum);
    for (vector<int>::iterator j = songIDs.begin(); j != songIDs.end(); ++j)
    {
      vector<long> songArtists;
      m_musicDatabase.GetArtistsBySong(*j, false, songArtists);
      artistsToScan.insert(songArtists.begin(), songArtists.end());
    }
    std::vector<long> albumArtists;
    m_musicDatabase.GetArtistsByAlbum(idAlbum, false, albumArtists);
    artistsToScan.insert(albumArtists.begin(), albumArtists.end());
  }
  m_musicDatabase.CommitTransaction();

  // Download info & artwork
  bool bCanceled;
  for (set<long>::iterator it = artistsToScan.begin(); it != artistsToScan.end(); ++it)
  {
    bCanceled = false;
    if (find(m_artistsScanned.begin(),m_artistsScanned.end(), *it) == m_artistsScanned.end())
    {
      CStdString strArtist = m_musicDatabase.GetArtistById(*it);
      m_artistsScanned.push_back(*it);
      if (!m_bStop && (m_flags & SCAN_ONLINE))
      {
        CStdString strPath;
        strPath.Format("musicdb://2/%u/", *it);

        if (!DownloadArtistInfo(strPath, strArtist, bCanceled)) // assume we want to retry
          m_artistsScanned.pop_back();
      }
      else
      {
        map<string, string> artwork = GetArtistArtwork(*it);
        m_musicDatabase.SetArtForItem(*it, "artist", artwork);
      }
    }
  }

  if (m_flags & SCAN_ONLINE)
  {
    for (set<long>::iterator it = albumsToScan.begin(); it != albumsToScan.end(); ++it)
    {
      if (m_bStop)
        return songsToAdd.size();

      CStdString strPath;
      strPath.Format("musicdb://3/%u/",*it);

      CAlbum album;
      m_musicDatabase.GetAlbumInfo(*it, album, NULL);
      bCanceled = false;
      if (find(m_albumsScanned.begin(), m_albumsScanned.end(), *it) == m_albumsScanned.end())
      {
        CMusicAlbumInfo albumInfo;
        if (DownloadAlbumInfo(strPath, StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator), album.strAlbum, bCanceled, albumInfo))
          m_albumsScanned.push_back(*it);
      }
    }
  }
  if (m_handle)
    m_handle->SetTitle(g_localizeStrings.Get(505));

  return songsToAdd.size();
}
예제 #28
0
JSONRPC_STATUS CPlayerOperations::Open(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
  CVariant optionShuffled = parameterObject["options"]["shuffled"];
  CVariant optionRepeat = parameterObject["options"]["repeat"];
  CVariant optionResume = parameterObject["options"]["resume"];

  if (parameterObject["item"].isObject() && parameterObject["item"].isMember("playlistid"))
  {
    int playlistid = (int)parameterObject["item"]["playlistid"].asInteger();

    if (playlistid < PLAYLIST_PICTURE)
    {
      // Apply the "shuffled" option if available
      if (optionShuffled.isBoolean())
        g_playlistPlayer.SetShuffle(playlistid, optionShuffled.asBoolean(), false);
      // Apply the "repeat" option if available
      if (!optionRepeat.isNull())
        g_playlistPlayer.SetRepeat(playlistid, (REPEAT_STATE)ParseRepeatState(optionRepeat), false);
    }

    switch (playlistid)
    {
      case PLAYLIST_MUSIC:
      case PLAYLIST_VIDEO:
        CApplicationMessenger::Get().MediaPlay(playlistid, (int)parameterObject["item"]["position"].asInteger());
        OnPlaylistChanged();
        break;

      case PLAYLIST_PICTURE:
        return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean());
        break;
    }

    return ACK;
  }
  else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("path"))
  {
    bool random = (optionShuffled.isBoolean() && optionShuffled.asBoolean()) ||
                  (!optionShuffled.isBoolean() && parameterObject["item"]["random"].asBoolean());
    return StartSlideshow(parameterObject["item"]["path"].asString(), parameterObject["item"]["recursive"].asBoolean(), random);
  }
  else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("partymode"))
  {
    if (g_partyModeManager.IsEnabled())
      g_partyModeManager.Disable();
    CApplicationMessenger::Get().ExecBuiltIn("playercontrol(partymode(" + parameterObject["item"]["partymode"].asString() + "))");
    return ACK;
  }
  else if (parameterObject["item"].isObject() && parameterObject["item"].isMember("channelid"))
  {
    if (!g_PVRManager.IsStarted())
      return FailedToExecute;

    CPVRChannelGroupsContainer *channelGroupContainer = g_PVRChannelGroups;
    if (channelGroupContainer == NULL)
      return FailedToExecute;

    CPVRChannelPtr channel = channelGroupContainer->GetChannelById((int)parameterObject["item"]["channelid"].asInteger());
    if (channel == NULL)
      return InvalidParams;

    CApplicationMessenger::Get().MediaPlay(CFileItem(*channel.get()));
    return ACK;
  }
  else
  {
    CFileItemList list;
    if (FillFileItemList(parameterObject["item"], list) && list.Size() > 0)
    {
      bool slideshow = true;
      for (int index = 0; index < list.Size(); index++)
      {
        if (!list[index]->IsPicture())
        {
          slideshow = false;
          break;
        }
      }

      if (slideshow)
      {
        CGUIWindowSlideShow *slideshow = (CGUIWindowSlideShow*)g_windowManager.GetWindow(WINDOW_SLIDESHOW);
        if (!slideshow)
          return FailedToExecute;

        SendSlideshowAction(ACTION_STOP);
        slideshow->Reset();
        for (int index = 0; index < list.Size(); index++)
          slideshow->Add(list[index].get());

        return StartSlideshow("", false, optionShuffled.isBoolean() && optionShuffled.asBoolean());
      }
      else
      {
        // Handle "shuffled" option
        if (optionShuffled.isBoolean())
          list.SetProperty("shuffled", optionShuffled);
        // Handle "repeat" option
        if (!optionRepeat.isNull())
          list.SetProperty("repeat", ParseRepeatState(optionRepeat));
        // Handle "resume" option
        if (list.Size() == 1)
        {
          if (optionResume.isBoolean() && optionResume.asBoolean())
            list[0]->m_lStartOffset = STARTOFFSET_RESUME;
          else if (optionResume.isDouble())
            list[0]->SetProperty("StartPercent", optionResume);
          else if (optionResume.isObject())
            list[0]->m_lStartOffset = (int)(ParseTimeInSeconds(optionResume) * 75.0);
        }

        CApplicationMessenger::Get().MediaPlay(list);
      }

      return ACK;
    }
    else
      return InvalidParams;
  }

  return InvalidParams;
}
예제 #29
0
bool CGUIBaseContainer::OnMessage(CGUIMessage& message)
{
  if (message.GetControlId() == GetID() )
  {
    if (!m_staticContent)
    {
      if (message.GetMessage() == GUI_MSG_LABEL_BIND && message.GetPointer())
      { // bind our items
        Reset();
        CFileItemList *items = (CFileItemList *)message.GetPointer();
        for (int i = 0; i < items->Size(); i++)
          m_items.push_back(items->Get(i));
        UpdateLayout(true); // true to refresh all items
        UpdateScrollByLetter();
        SelectItem(message.GetParam1());
        return true;
      }
      else if (message.GetMessage() == GUI_MSG_LABEL_RESET)
      {
        Reset();
        SetPageControlRange();
        return true;
      }
    }
    if (message.GetMessage() == GUI_MSG_ITEM_SELECT)
    {
      SelectItem(message.GetParam1());
      return true;
    }
    else if (message.GetMessage() == GUI_MSG_ITEM_SELECTED)
    {
      message.SetParam1(GetSelectedItem());
      return true;
    }
    else if (message.GetMessage() == GUI_MSG_PAGE_CHANGE)
    {
      if (message.GetSenderId() == m_pageControl && IsVisible())
      { // update our page if we're visible - not much point otherwise
        if ((int)message.GetParam1() != m_offset)
          m_pageChangeTimer.StartZero();
        ScrollToOffset(message.GetParam1());
        return true;
      }
    }
    else if (message.GetMessage() == GUI_MSG_REFRESH_LIST)
    { // update our list contents
      for (unsigned int i = 0; i < m_items.size(); ++i)
        m_items[i]->SetInvalid();
    }
    else if (message.GetMessage() == GUI_MSG_MOVE_OFFSET)
    {
      int count = (int)message.GetParam1();
      while (count < 0)
      {
        MoveUp(true);
        count++;
      }
      while (count > 0)
      {
        MoveDown(true);
        count--;
      }
      return true;
    }
  }
  return CGUIControl::OnMessage(message);
}
예제 #30
0
void CGUIDialogPluginSettings::CreateControls()
{
  CGUISpinControlEx *pOriginalSpin = (CGUISpinControlEx*)GetControl(CONTROL_DEFAULT_SPIN);
  CGUIRadioButtonControl *pOriginalRadioButton = (CGUIRadioButtonControl *)GetControl(CONTROL_DEFAULT_RADIOBUTTON);
  CGUIButtonControl *pOriginalButton = (CGUIButtonControl *)GetControl(CONTROL_DEFAULT_BUTTON);
  CGUIImage *pOriginalImage = (CGUIImage *)GetControl(CONTROL_DEFAULT_SEPARATOR);
  CGUILabelControl *pOriginalLabel = (CGUILabelControl *)GetControl(CONTROL_DEFAULT_LABEL_SEPARATOR);

  if (!pOriginalSpin || !pOriginalRadioButton || !pOriginalButton || !pOriginalImage)
    return;

  pOriginalSpin->SetVisible(false);
  pOriginalRadioButton->SetVisible(false);
  pOriginalButton->SetVisible(false);
  pOriginalImage->SetVisible(false);
  if (pOriginalLabel)
    pOriginalLabel->SetVisible(false);

  // clear the category group
  CGUIControlGroupList *group = (CGUIControlGroupList *)GetControl(CONTROL_AREA);
  if (!group)
    return;

  // set our dialog heading
  SET_CONTROL_LABEL(CONTROL_HEADING_LABEL, m_strHeading);

  // Create our base path, used for type "fileenum" settings
  CStdString basepath = "Q:\\plugins\\";
  CUtil::AddFileToFolder(basepath, m_url.GetHostName(), basepath);
  CUtil::AddFileToFolder(basepath, m_url.GetFileName(), basepath);

  CGUIControl* pControl = NULL;
  int controlId = CONTROL_START_CONTROL;
  TiXmlElement *setting = m_settings.GetPluginRoot()->FirstChildElement("setting");
  while (setting)
  {
    const char *type = setting->Attribute("type");
    const char *id = setting->Attribute("id");
    CStdString values;
    if (setting->Attribute("values"))
      values = setting->Attribute("values");
    CStdString lvalues;
    if (setting->Attribute("lvalues"))
      lvalues = setting->Attribute("lvalues");
    CStdString entries;
    if (setting->Attribute("entries"))
      entries = setting->Attribute("entries");
    CStdString label;
    if (setting->Attribute("label") && atoi(setting->Attribute("label")) > 0)
      label.Format("$LOCALIZE[%s]", setting->Attribute("label"));
    else
      label = setting->Attribute("label");

    if (type)
    {
      if (strcmpi(type, "text") == 0 || strcmpi(type, "ipaddress") == 0 ||
        strcmpi(type, "integer") == 0 || strcmpi(type, "video") == 0 ||
        strcmpi(type, "music") == 0 || strcmpi(type, "pictures") == 0 ||
        strcmpi(type, "folder") == 0 || strcmpi(type, "programs") == 0 ||
        strcmpi(type, "files") == 0 || strcmpi(type, "action") == 0)
      {
        pControl = new CGUIButtonControl(*pOriginalButton);
        if (!pControl) return;
        ((CGUIButtonControl *)pControl)->SettingsCategorySetTextAlign(XBFONT_CENTER_Y);
        ((CGUIButtonControl *)pControl)->SetLabel(label);
        if (id)
          ((CGUIButtonControl *)pControl)->SetLabel2(m_settings.Get(id));
      }
      else if (strcmpi(type, "bool") == 0)
      {
        pControl = new CGUIRadioButtonControl(*pOriginalRadioButton);
        if (!pControl) return;
        ((CGUIRadioButtonControl *)pControl)->SetLabel(label);
        ((CGUIRadioButtonControl *)pControl)->SetSelected(m_settings.Get(id) == "true");
      }
      else if (strcmpi(type, "enum") == 0 || strcmpi(type, "labelenum") == 0)
      {
        vector<CStdString> valuesVec;
        vector<CStdString> entryVec;

        pControl = new CGUISpinControlEx(*pOriginalSpin);
        if (!pControl) return;
        ((CGUISpinControlEx *)pControl)->SetText(label);

        if (!lvalues.IsEmpty())
          CUtil::Tokenize(lvalues, valuesVec, "|");
        else
          CUtil::Tokenize(values, valuesVec, "|");
        if (!entries.IsEmpty())
          CUtil::Tokenize(entries, entryVec, "|");
        for (unsigned int i = 0; i < valuesVec.size(); i++)
        {
          int iAdd = i;
          if (entryVec.size() > i)
            iAdd = atoi(entryVec[i]);
          if (!lvalues.IsEmpty())
          {
            CStdString replace = g_localizeStringsTemp.Get(atoi(valuesVec[i]));
            if (replace.IsEmpty())
              replace = g_localizeStrings.Get(atoi(valuesVec[i]));
            ((CGUISpinControlEx *)pControl)->AddLabel(replace, iAdd);
          }
          else
            ((CGUISpinControlEx *)pControl)->AddLabel(valuesVec[i], iAdd);
        }
        if (strcmpi(type, "labelenum") == 0)
        { // need to run through all our settings and find the one that matches
          ((CGUISpinControlEx*) pControl)->SetValueFromLabel(m_settings.Get(id));
        }
        else
          ((CGUISpinControlEx*) pControl)->SetValue(atoi(m_settings.Get(id)));

      }
      else if (strcmpi(type, "fileenum") == 0)
      {
        pControl = new CGUISpinControlEx(*pOriginalSpin);
        if (!pControl) return;
        ((CGUISpinControlEx *)pControl)->SetText(label);

        //find Folders...
        CFileItemList items;
        CStdString enumpath;
        CUtil::AddFileToFolder(basepath, values, enumpath);
        CStdString mask;
        if (setting->Attribute("mask"))
          mask = setting->Attribute("mask");
        if (!mask.IsEmpty())
          CDirectory::GetDirectory(enumpath, items, mask);
        else
          CDirectory::GetDirectory(enumpath, items);

        int iItem = 0;
        for (int i = 0; i < items.Size(); ++i)
        {
          CFileItemPtr pItem = items[i];
          if ((mask.Equals("/") && pItem->m_bIsFolder) || !pItem->m_bIsFolder)
          {
            ((CGUISpinControlEx *)pControl)->AddLabel(pItem->GetLabel(), iItem);
            if (pItem->GetLabel().Equals(m_settings.Get(id)))
              ((CGUISpinControlEx *)pControl)->SetValue(iItem);
            iItem++;
          }
        }
      }
      else if (strcmpi(type, "lsep") == 0 && pOriginalLabel)
      {
        pControl = new CGUILabelControl(*pOriginalLabel);
        if (pControl)
          ((CGUILabelControl *)pControl)->SetLabel(label);
      }
      else if ((strcmpi(type, "sep") == 0 || strcmpi(type, "lsep") == 0) && pOriginalImage)
        pControl = new CGUIImage(*pOriginalImage);
    }

    if (pControl)
    {
      pControl->SetWidth(group->GetWidth());
      pControl->SetVisible(true);
      pControl->SetID(controlId);
      pControl->AllocResources();
      group->AddControl(pControl);
      pControl = NULL;
    }

    setting = setting->NextSiblingElement("setting");
    controlId++;
  }
  EnableControls();
}