Пример #1
0
bool CMusicInfoScanner::DoScan(const CStdString& strDirectory)
{
  if (m_handle)
    m_handle->SetText(Prettify(strDirectory));

  std::set<std::string>::const_iterator it = m_seenPaths.find(strDirectory);
  if (it != m_seenPaths.end())
    return true;

  m_seenPaths.insert(strDirectory);

  // Discard all excluded files defined by m_musicExcludeRegExps
  vector<string> regexps = g_advancedSettings.m_audioExcludeFromScanRegExps;
  if (CUtil::ExcludeFileOrFolder(strDirectory, regexps))
    return true;

  // load subfolder
  CFileItemList items;
  CDirectory::GetDirectory(strDirectory, items, g_advancedSettings.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(SortByLabel, 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.empty())
      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(SortByLabel, SortOrderAscending);

    // and then scan in the new information
    if (RetrieveMusicInfo(strDirectory, items) > 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/(float)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;
}
Пример #2
0
bool CGUIDialogVideoInfo::OnMessage(CGUIMessage& message)
{
  switch ( message.GetMessage() )
  {
  case GUI_MSG_WINDOW_DEINIT:
    {
      ClearCastList();
    }
    break;

  case GUI_MSG_CLICKED:
    {
      int iControl = message.GetSenderId();
      if (iControl == CONTROL_BTN_REFRESH)
      {
        if (m_movieItem->GetVideoInfoTag()->m_iSeason < 0 && !m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty()) // tv show
        {
          bool bCanceled=false;
          if (CGUIDialogYesNo::ShowAndGetInput(20377,20378,-1,-1,bCanceled))
          {
            m_bRefreshAll = true;
            CVideoDatabase db;
            if (db.Open())
            {
              db.SetPathHash(m_movieItem->GetVideoInfoTag()->m_strPath,"");
              db.Close();
            }
          }
          else
            m_bRefreshAll = false;

          if (bCanceled)
            return false;
        }
        m_bRefresh = true;
        Close();
        return true;
      }
      else if (iControl == CONTROL_BTN_TRACKS)
      {
        m_bViewReview = !m_bViewReview;
        Update();
      }
      else if (iControl == CONTROL_BTN_PLAY)
      {
        Play();
      }
      else if (iControl == CONTROL_BTN_RESUME)
      {
        Play(true);
      }
      else if (iControl == CONTROL_BTN_GET_THUMB)
      {
        OnGetArt();
      }
      else if (iControl == CONTROL_BTN_PLAY_TRAILER)
      {
        PlayTrailer();
      }
      else if (iControl == CONTROL_BTN_GET_FANART)
      {
        OnGetFanart();
      }
      else if (iControl == CONTROL_BTN_DIRECTOR)
      {
        CStdString strDirector = StringUtils::Join(m_movieItem->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
        OnSearch(strDirector);
      }
      else if (iControl == CONTROL_LIST)
      {
        int iAction = message.GetParam1();
        if (ACTION_SELECT_ITEM == iAction || ACTION_MOUSE_LEFT_CLICK == iAction)
        {
          CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl);
          OnMessage(msg);
          int iItem = msg.GetParam1();
          if (iItem < 0 || iItem >= m_castList->Size())
            break;
          CStdString strItem = m_castList->Get(iItem)->GetLabel();
          CStdString strFind;
          strFind.Format(" %s ",g_localizeStrings.Get(20347));
          int iPos = strItem.Find(strFind);
          if (iPos == -1)
            iPos = strItem.size();
          CStdString tmp = strItem.Left(iPos);
          OnSearch(tmp);
        }
      }
    }
    break;
  case GUI_MSG_NOTIFY_ALL:
    {
      if (IsActive() && message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem())
      {
        CFileItemPtr item = boost::static_pointer_cast<CFileItem>(message.GetItem());
        if (item && m_movieItem->GetPath().Equals(item->GetPath()))
        { // Just copy over the stream details and the thumb if we don't already have one
          if (!m_movieItem->HasArt("thumb"))
            m_movieItem->SetArt("thumb", item->GetArt("thumb"));
          m_movieItem->GetVideoInfoTag()->m_streamDetails = item->GetVideoInfoTag()->m_streamDetails;
        }
        return true;
      }
    }
  }

  return CGUIDialog::OnMessage(message);
}
Пример #3
0
void CPeripherals::OnSettingAction(const CSetting *setting)
{
  if (setting == nullptr)
    return;

  const std::string &settingId = setting->GetId();
  if (settingId == CSettings::SETTING_INPUT_PERIPHERALS)
  {
    CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);

    CFileItemList items;
    GetDirectory("peripherals://all/", items);

    int iPos = -1;
    do
    {
      pDialog->Reset();
      pDialog->SetHeading(CVariant{35000});
      pDialog->SetUseDetails(true);
      pDialog->SetItems(items);
      pDialog->SetSelected(iPos);
      pDialog->Open();

      iPos = pDialog->IsConfirmed() ? pDialog->GetSelectedItem() : -1;

      if (iPos >= 0)
      {
        CFileItemPtr pItem = items.Get(iPos);

        // show an error if the peripheral doesn't have any settings
        PeripheralPtr peripheral = GetByPath(pItem->GetPath());
        if (!peripheral || peripheral->GetSettings().empty())
        {
          CGUIDialogOK::ShowAndGetInput(CVariant{35000}, CVariant{35004});
          continue;
        }

        CGUIDialogPeripheralSettings *pSettingsDialog = (CGUIDialogPeripheralSettings *)g_windowManager.GetWindow(WINDOW_DIALOG_PERIPHERAL_SETTINGS);
        if (pItem && pSettingsDialog)
        {
          // pass peripheral item properties to settings dialog so skin authors
          // can use it to show more detailed information about the device
          pSettingsDialog->SetProperty("vendor", pItem->GetProperty("vendor"));
          pSettingsDialog->SetProperty("product", pItem->GetProperty("product"));
          pSettingsDialog->SetProperty("bus", pItem->GetProperty("bus"));
          pSettingsDialog->SetProperty("location", pItem->GetProperty("location"));
          pSettingsDialog->SetProperty("class", pItem->GetProperty("class"));
          pSettingsDialog->SetProperty("version", pItem->GetProperty("version"));

          // open settings dialog
          pSettingsDialog->SetFileItem(pItem.get());
          pSettingsDialog->Open();
        }
      }
    } while (pDialog->IsConfirmed());
  }
  else if (settingId == CSettings::SETTING_INPUT_CONTROLLERCONFIG)
    g_windowManager.ActivateWindow(WINDOW_DIALOG_GAME_CONTROLLERS);
  else if (settingId == CSettings::SETTING_INPUT_TESTRUMBLE)
    TestFeature(FEATURE_RUMBLE);
}
Пример #4
0
void CBackgroundInfoLoader::Run()
{
  try
  {
    if (!m_vecItems.empty())
    {
      OnLoaderStart();

      // Stage 1: All "fast" stuff we have already cached
      for (std::vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter)
      {
        CFileItemPtr pItem = *iter;

        // Ask the callback if we should abort
        if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop)
          break;

        try
        {
          if (LoadItemCached(pItem.get()) && m_pObserver)
            m_pObserver->OnItemLoaded(pItem.get());
        }
        catch (...)
        {
          CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItemCached - Unhandled exception for item %s", CURL::GetRedacted(pItem->GetPath()).c_str());
        }
      }

      // Stage 2: All "slow" stuff that we need to lookup
      for (std::vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter)
      {
        CFileItemPtr pItem = *iter;

        // Ask the callback if we should abort
        if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop)
          break;

        try
        {
          if (LoadItemLookup(pItem.get()) && m_pObserver)
            m_pObserver->OnItemLoaded(pItem.get());
        }
        catch (...)
        {
          CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItemLookup - Unhandled exception for item %s", CURL::GetRedacted(pItem->GetPath()).c_str());
        }
      }
    }

    OnLoaderFinish();
    m_bIsLoading = false;
  }
  catch (...)
  {
    m_bIsLoading = false;
    CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
  }
}
Пример #5
0
/// \brief Add unique file and folders and its subfolders to playlist
/// \param pItem The file item to add
void CGUIWindowMusicBase::AddItemToPlayList(const CFileItemPtr &pItem, CFileItemList &queuedItems)
{
  if (!pItem->CanQueue() || pItem->IsRAR() || pItem->IsZIP() || pItem->IsParentFolder()) // no zip/rar enques thank you!
    return;

  // fast lookup is needed here
  queuedItems.SetFastLookup(true);

  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->GetPath()))
    { // 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)
      CFileItemPtr item(new CFileItem(pItem->GetPath() + "-1/", true));
      item->SetCanQueue(true); // workaround for CanQueue() check above
      AddItemToPlayList(item, queuedItems);
      return;
    }
  }
  if (pItem->m_bIsFolder || (g_windowManager.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->GetPath(), items);
    //OnRetrieveMusicInfo(items);
    FormatAndSort(items);
    SetupFanart(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->GetPath()))
        {
          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(pItem);
    }
    else if (pItem->IsPlugin() && pItem->GetProperty("isplayable") == "true")
    {
      // python files can be played
      queuedItems.Add(pItem);
    }
    else if (!pItem->IsNFO() && pItem->IsAudio())
    {
      CFileItemPtr itemCheck = queuedItems.Get(pItem->GetPath());
      if (!itemCheck || itemCheck->m_lStartOffset != pItem->m_lStartOffset)
      { // add item
        CFileItemPtr item(new CFileItem(*pItem));
        m_musicdatabase.SetPropertiesForFileItem(*item);
        queuedItems.Add(item);
      }
    }
  }
}
Пример #6
0
bool CGUIDialogContextMenu::OnContextButton(const std::string &type, const CFileItemPtr& item, CONTEXT_BUTTON button)
{
  // Add Source doesn't require a valid share
  if (button == CONTEXT_BUTTON_ADD_SOURCE)
  {
    if (CProfilesManager::Get().IsMasterProfile())
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;
    }
    else if (!CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
      return false;

    return CGUIDialogMediaSource::ShowAndAddMediaSource(type);
  }

  // buttons that are available on both sources and autosourced items
  if (!item) return false;

  switch (button)
  {
  case CONTEXT_BUTTON_EJECT_DRIVE:
    return g_mediaManager.Eject(item->GetPath());

#ifdef HAS_DVD_DRIVE
  case CONTEXT_BUTTON_PLAY_DISC:
    return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, true); // restart

  case CONTEXT_BUTTON_RESUME_DISC:
    return MEDIA_DETECT::CAutorun::PlayDisc(item->GetPath(), true, false); // resume

  case CONTEXT_BUTTON_EJECT_DISC:
    g_mediaManager.ToggleTray(g_mediaManager.TranslateDevicePath(item->GetPath())[0]);
#endif
    return true;
  default:
    break;
  }

  // the rest of the operations require a valid share
  CMediaSource *share = GetShare(type, item.get());
  if (!share) return false;
  switch (button)
  {
  case CONTEXT_BUTTON_EDIT_SOURCE:
    if (CProfilesManager::Get().IsMasterProfile())
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;
    }
    else if (!g_passwordManager.IsProfileLockUnlocked())
      return false;

    return CGUIDialogMediaSource::ShowAndEditMediaSource(type, *share);

  case CONTEXT_BUTTON_REMOVE_SOURCE:
  {
    if (CProfilesManager::Get().IsMasterProfile())
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;
    }
    else
    {
      if (!CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsMasterLockUnlocked(false))
        return false;
      if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
        return false;
    }
    // prompt user if they want to really delete the source
    if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{751}, CVariant{750}))
      return false;

    // check default before we delete, as deletion will kill the share object
    std::string defaultSource(GetDefaultShareNameByType(type));
    if (!defaultSource.empty())
    {
      if (share->strName == defaultSource)
        ClearDefault(type);
    }
    CMediaSourceSettings::Get().DeleteSource(type, share->strName, share->strPath);
    return true;
  }
  case CONTEXT_BUTTON_SET_DEFAULT:
    if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
      return false;
    else if (!g_passwordManager.IsMasterLockUnlocked(true))
      return false;

    // make share default
    SetDefault(type, share->strName);
    return true;

  case CONTEXT_BUTTON_CLEAR_DEFAULT:
    if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
      return false;
    else if (!g_passwordManager.IsMasterLockUnlocked(true))
      return false;
    // remove share default
    ClearDefault(type);
    return true;

  case CONTEXT_BUTTON_SET_THUMB:
    {
      if (CProfilesManager::Get().GetCurrentProfile().canWriteSources() && !g_passwordManager.IsProfileLockUnlocked())
        return false;
      else if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      // setup our thumb list
      CFileItemList items;

      // add the current thumb, if available
      if (!share->m_strThumbnailImage.empty())
      {
        CFileItemPtr current(new CFileItem("thumb://Current", false));
        current->SetArt("thumb", share->m_strThumbnailImage);
        current->SetLabel(g_localizeStrings.Get(20016));
        items.Add(current);
      }
      else if (item->HasArt("thumb"))
      { // already have a thumb that the share doesn't know about - must be a local one, so we mayaswell reuse it.
        CFileItemPtr current(new CFileItem("thumb://Current", false));
        current->SetArt("thumb", item->GetArt("thumb"));
        current->SetLabel(g_localizeStrings.Get(20016));
        items.Add(current);
      }
      // see if there's a local thumb for this item
      std::string folderThumb = item->GetFolderThumb();
      if (XFILE::CFile::Exists(folderThumb))
      {
        CFileItemPtr local(new CFileItem("thumb://Local", false));
        local->SetArt("thumb", folderThumb);
        local->SetLabel(g_localizeStrings.Get(20017));
        items.Add(local);
      }
      // and add a "no thumb" entry as well
      CFileItemPtr nothumb(new CFileItem("thumb://None", false));
      nothumb->SetIconImage(item->GetIconImage());
      nothumb->SetLabel(g_localizeStrings.Get(20018));
      items.Add(nothumb);

      std::string strThumb;
      VECSOURCES shares;
      g_mediaManager.GetLocalDrives(shares);
      if (!CGUIDialogFileBrowser::ShowAndGetImage(items, shares, g_localizeStrings.Get(1030), strThumb))
        return false;

      if (strThumb == "thumb://Current")
        return true;

      if (strThumb == "thumb://Local")
        strThumb = folderThumb;

      if (strThumb == "thumb://None")
        strThumb = "";

      if (!share->m_ignore)
      {
        CMediaSourceSettings::Get().UpdateSource(type,share->strName,"thumbnail",strThumb);
        CMediaSourceSettings::Get().Save();
      }
      else if (!strThumb.empty())
      { // this is some sort of an auto-share, so store in the texture database
        CTextureDatabase db;
        if (db.Open())
          db.SetTextureForPath(item->GetPath(), "thumb", strThumb);
      }

      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }

  case CONTEXT_BUTTON_ADD_LOCK:
    {
      // prompt user for mastercode when changing lock settings) only for default user
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      std::string strNewPassword = "";
      if (!CGUIDialogLockSettings::ShowAndGetLock(share->m_iLockMode,strNewPassword))
        return false;
      // password entry and re-entry succeeded, write out the lock data
      share->m_iHasLock = 2;
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockcode", strNewPassword);
      strNewPassword = StringUtils::Format("%i", share->m_iLockMode);
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockmode", strNewPassword);
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0");
      CMediaSourceSettings::Get().Save();

      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  case CONTEXT_BUTTON_RESET_LOCK:
    {
      // prompt user for profile lock when changing lock settings
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0");
      CMediaSourceSettings::Get().Save();
      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  case CONTEXT_BUTTON_REMOVE_LOCK:
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      if (!CGUIDialogYesNo::ShowAndGetInput(CVariant{12335}, CVariant{750}))
        return false;

      share->m_iHasLock = 0;
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockmode", "0");
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockcode", "0");
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0");
      CMediaSourceSettings::Get().Save();
      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  case CONTEXT_BUTTON_REACTIVATE_LOCK:
    {
      bool maxRetryExceeded = false;
      if (CSettings::Get().GetInt("masterlock.maxretries") != 0)
        maxRetryExceeded = (share->m_iBadPwdCount >= CSettings::Get().GetInt("masterlock.maxretries"));
      if (!maxRetryExceeded)
      {
        // don't prompt user for mastercode when reactivating a lock
        g_passwordManager.LockSource(type, share->strName, true);
        return true;
      }
      return false;
    }
  case CONTEXT_BUTTON_CHANGE_LOCK:
    {
      if (!g_passwordManager.IsMasterLockUnlocked(true))
        return false;

      std::string strNewPW;
      std::string strNewLockMode;
      if (CGUIDialogLockSettings::ShowAndGetLock(share->m_iLockMode,strNewPW))
        strNewLockMode = StringUtils::Format("%i",share->m_iLockMode);
      else
        return false;
      // password ReSet and re-entry succeeded, write out the lock data
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockcode", strNewPW);
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "lockmode", strNewLockMode);
      CMediaSourceSettings::Get().UpdateSource(type, share->strName, "badpwdcount", "0");
      CMediaSourceSettings::Get().Save();
      CGUIMessage msg(GUI_MSG_NOTIFY_ALL,0,0,GUI_MSG_UPDATE_SOURCES);
      g_windowManager.SendThreadMessage(msg);
      return true;
    }
  default:
    break;
  }
  return false;
}
Пример #7
0
bool CGUIDialogFileBrowser::OnMessage(CGUIMessage& message)
{
  switch ( message.GetMessage() )
  {
  case GUI_MSG_WINDOW_DEINIT:
    {
      if (m_thumbLoader.IsLoading())
        m_thumbLoader.StopThread();
      CGUIDialog::OnMessage(message);
      ClearFileItems();
      m_addNetworkShareEnabled = false;
      return true;
    }
    break;

  case GUI_MSG_WINDOW_INIT:
    {
      m_bConfirmed = false;
      m_bFlip = false;
      bool bIsDir = false;
      // this code allows two different selection modes for directories
      // end the path with a slash to start inside the directory
      if (URIUtils::HasSlashAtEnd(m_selectedPath))
      {
        bIsDir = true;
        bool bFool;
        int iSource = CUtil::GetMatchingSource(m_selectedPath,m_shares,bFool);
        bFool = true;
        if (iSource > -1 && iSource < (int)m_shares.size())
        {
          if (m_shares[iSource].strPath.Equals(m_selectedPath))
            bFool = false;
        }

        if (bFool && !CDirectory::Exists(m_selectedPath))
          m_selectedPath.Empty();
      }
      else
      {
        if (!CFile::Exists(m_selectedPath) && !CDirectory::Exists(m_selectedPath))
            m_selectedPath.Empty();
      }

      // find the parent folder if we are a file browser (don't do this for folders)
      m_Directory->SetPath(m_selectedPath);
      if (!m_browsingForFolders && !bIsDir)
        m_Directory->SetPath(URIUtils::GetParentPath(m_selectedPath));
      Update(m_Directory->GetPath());
      m_viewControl.SetSelectedItem(m_selectedPath);
      return CGUIDialog::OnMessage(message);
    }
    break;

  case GUI_MSG_CLICKED:
    {
      if (m_viewControl.HasControl(message.GetSenderId()))  // list control
      {
        int iItem = m_viewControl.GetSelectedItem();
        int iAction = message.GetParam1();
        if (iItem < 0) break;
        if (iAction == ACTION_SELECT_ITEM || iAction == ACTION_MOUSE_LEFT_CLICK)
        {
          OnClick(iItem);
          return true;
        }
        else if (iAction == ACTION_HIGHLIGHT_ITEM && m_multipleSelection)
        {
          CFileItemPtr pItem = (*m_vecItems)[iItem];
          if (!pItem->m_bIsShareOrDrive && !pItem->m_bIsFolder)
          {
            pItem->Select(!pItem->IsSelected());
            CGUIMessage msg(GUI_MSG_ITEM_SELECT, GetID(), message.GetSenderId(), iItem + 1);
            OnMessage(msg);
          }
        }
      }
      else if (message.GetSenderId() == CONTROL_OK)
      {
        if (m_browsingForFolders == 2)
        {
          CStdString strTest;
          int iItem = m_viewControl.GetSelectedItem();

          CStdString strPath;
          if (iItem == 0)
            strPath = m_selectedPath;
          else
            strPath = (*m_vecItems)[iItem]->GetPath();

          URIUtils::AddFileToFolder(strPath,"1",strTest);
          CFile file;
          if (file.OpenForWrite(strTest,true))
          {
            file.Close();
            CFile::Delete(strTest);
            m_bConfirmed = true;
            Close();
          }
          else
            CGUIDialogOK::ShowAndGetInput(257,20072,0,0);
        }
        else
        {
          if (m_multipleSelection)
          {
            for (int iItem = 0; iItem < m_vecItems->Size(); ++iItem)
            {
              CFileItemPtr pItem = (*m_vecItems)[iItem];
              if (pItem->IsSelected())
                m_markedPath.push_back(pItem->GetPath());
            }
          }
          m_bConfirmed = true;
          Close();
        }
        return true;
      }
      else if (message.GetSenderId() == CONTROL_CANCEL)
      {
        Close();
        return true;
      }
      else if (message.GetSenderId() == CONTROL_NEWFOLDER)
      {
        CStdString strInput;
        if (CGUIDialogKeyboard::ShowAndGetInput(strInput,g_localizeStrings.Get(119),false))
        {
          CStdString strPath;
          URIUtils::AddFileToFolder(m_vecItems->GetPath(),strInput,strPath);
          if (CDirectory::Create(strPath))
            Update(m_vecItems->GetPath());
          else
            CGUIDialogOK::ShowAndGetInput(20069,20072,20073,0);
        }
      }
      else if (message.GetSenderId() == CONTROL_FLIP)
        m_bFlip = !m_bFlip;
    }
    break;
  case GUI_MSG_SETFOCUS:
    {
      if (m_viewControl.HasControl(message.GetControlId()) && m_viewControl.GetCurrentControl() != message.GetControlId())
      {
        m_viewControl.SetFocused();
        return true;
      }
    }
    break;
  case GUI_MSG_NOTIFY_ALL:
    { // Message is received only if this window is active
      if (message.GetParam1() == GUI_MSG_REMOVED_MEDIA)
      {
        if (m_Directory->IsVirtualDirectoryRoot() && IsActive())
        {
          int iItem = m_viewControl.GetSelectedItem();
          Update(m_Directory->GetPath());
          m_viewControl.SetSelectedItem(iItem);
        }
        else if (m_Directory->IsRemovable())
        { // check that we have this removable share still
          if (!m_rootDir.IsInSource(m_Directory->GetPath()))
          { // don't have this share any more
            if (IsActive()) Update("");
            else
            {
              m_history.ClearPathHistory();
              m_Directory->SetPath("");
            }
          }
        }
        return true;
      }
      else if (message.GetParam1()==GUI_MSG_UPDATE_SOURCES)
      { // State of the sources changed, so update our view
        if (m_Directory->IsVirtualDirectoryRoot() && IsActive())
        {
          int iItem = m_viewControl.GetSelectedItem();
          Update(m_Directory->GetPath());
          m_viewControl.SetSelectedItem(iItem);
        }
        return true;
      }
      else if (message.GetParam1()==GUI_MSG_UPDATE_PATH)
      {
        if (IsActive())
        {
          if((message.GetStringParam() == m_Directory->GetPath()) ||
             (m_Directory->IsMultiPath() && XFILE::CMultiPathDirectory::HasPath(m_Directory->GetPath(), message.GetStringParam())))
          {
            int iItem = m_viewControl.GetSelectedItem();
            Update(m_Directory->GetPath());
            m_viewControl.SetSelectedItem(iItem);
          }
        }
      }
    }
    break;

  }
  return CGUIDialog::OnMessage(message);
}
Пример #8
0
void CGUIWindowMusicBase::GetContextButtons(int itemNumber, CContextButtons &buttons)
{
  CFileItemPtr item;
  if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
    item = m_vecItems->Get(itemNumber);

  if (item)
  {
    if (item && !item->IsParentFolder())
    {
      if (item->CanQueue() && !item->IsAddonsPath() && !item->IsScript())
      {
        buttons.Add(CONTEXT_BUTTON_QUEUE_ITEM, 13347); //queue

        // allow a folder to be ad-hoc queued and played by the default player
        if (item->m_bIsFolder || (item->IsPlayList() &&
           !g_advancedSettings.m_playlistAsFolders))
        {
          buttons.Add(CONTEXT_BUTTON_PLAY_ITEM, 208); // Play
        }
        else
        { // check what players we have, if we have multiple display play with option
          std::vector<std::string> players;
          CPlayerCoreFactory::GetInstance().GetPlayers(*item, players);
          if (players.size() >= 1)
            buttons.Add(CONTEXT_BUTTON_PLAY_WITH, 15213); // Play With...
        }
        if (item->IsSmartPlayList())
        {
            buttons.Add(CONTEXT_BUTTON_PLAY_PARTYMODE, 15216); // Play in Partymode
        }

        if (item->IsSmartPlayList() || m_vecItems->IsSmartPlayList())
          buttons.Add(CONTEXT_BUTTON_EDIT_SMART_PLAYLIST, 586);
        else if (item->IsPlayList() || m_vecItems->IsPlayList())
          buttons.Add(CONTEXT_BUTTON_EDIT, 586);
      }
      if (!m_vecItems->IsMusicDb() && !m_vecItems->IsInternetStream()           &&
          !item->IsPath("add") && !item->IsParentFolder() &&
          !item->IsPlugin() && !item->IsMusicDb()         &&
          !item->IsLibraryFolder() &&
          !StringUtils::StartsWithNoCase(item->GetPath(), "addons://")              &&
          (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
      {
        buttons.Add(CONTEXT_BUTTON_SCAN, 13352);
      }
#ifdef HAS_DVD_DRIVE
      // enable Rip CD Audio or Track button if we have an audio disc
      if (g_mediaManager.IsDiscInDrive() && m_vecItems->IsCDDA())
      {
        // those cds can also include Audio Tracks: CDExtra and MixedMode!
        MEDIA_DETECT::CCdInfo *pCdInfo = g_mediaManager.GetCdInfo();
        if (pCdInfo->IsAudio(1) || pCdInfo->IsCDExtra(1) || pCdInfo->IsMixedMode(1))
          buttons.Add(CONTEXT_BUTTON_RIP_TRACK, 610);
      }
#endif
    }

    // enable CDDB lookup if the current dir is CDDA
    if (g_mediaManager.IsDiscInDrive() && m_vecItems->IsCDDA() &&
       (CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
    {
      buttons.Add(CONTEXT_BUTTON_CDDB, 16002);
    }
  }
  CGUIMediaWindow::GetContextButtons(itemNumber, buttons);
}
Пример #9
0
bool CGUIWindowMusicBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
  CFileItemPtr item;
  if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
    item = m_vecItems->Get(itemNumber);

  if (CGUIDialogContextMenu::OnContextButton("music", item, button))
  {
    if (button == CONTEXT_BUTTON_REMOVE_SOURCE)
      OnRemoveSource(itemNumber);

    Update(m_vecItems->GetPath());
    return true;
  }

  switch (button)
  {
  case CONTEXT_BUTTON_QUEUE_ITEM:
    OnQueueItem(itemNumber);
    return true;

  case CONTEXT_BUTTON_INFO:
    OnItemInfo(itemNumber);
    return true;

  case CONTEXT_BUTTON_EDIT:
    {
      std::string playlist = item->IsPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items
      g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST_EDITOR, playlist);
      // need to update
      m_vecItems->RemoveDiscCache(GetID());
      return true;
    }

  case CONTEXT_BUTTON_EDIT_SMART_PLAYLIST:
    {
      std::string playlist = item->IsSmartPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items
      if (CGUIDialogSmartPlaylistEditor::EditPlaylist(playlist, "music"))
        Refresh(true); // need to update
      return true;
    }

  case CONTEXT_BUTTON_PLAY_ITEM:
    PlayItem(itemNumber);
    return true;

  case CONTEXT_BUTTON_PLAY_WITH:
    {
      std::vector<std::string> players;
      CPlayerCoreFactory::GetInstance().GetPlayers(*item, players);
      std::string player = CPlayerCoreFactory::GetInstance().SelectPlayerDialog(players);
      if (!player.empty())
        OnClick(itemNumber, player);
      return true;
    }

  case CONTEXT_BUTTON_PLAY_PARTYMODE:
    g_partyModeManager.Enable(PARTYMODECONTEXT_MUSIC, item->GetPath());
    return true;

  case CONTEXT_BUTTON_ACTIVE_ADSP_SETTINGS:
    g_windowManager.ActivateWindow(WINDOW_DIALOG_AUDIO_DSP_OSD_SETTINGS);
    return true;

  case CONTEXT_BUTTON_RIP_CD:
    OnRipCD();
    return true;

#ifdef HAS_CDDA_RIPPER
  case CONTEXT_BUTTON_CANCEL_RIP_CD:
    CCDDARipper::GetInstance().CancelJobs();
    return true;
#endif

  case CONTEXT_BUTTON_RIP_TRACK:
    OnRipTrack(itemNumber);
    return true;

  case CONTEXT_BUTTON_SCAN:
    OnScan(itemNumber);
    return true;

  case CONTEXT_BUTTON_CDDB:
    if (m_musicdatabase.LookupCDDBInfo(true))
      Refresh();
    return true;

  default:
    break;
  }

  return CGUIMediaWindow::OnContextButton(itemNumber, button);
}
Пример #10
0
void CGUIWindowVideoNav::GetContextButtons(int itemNumber, CContextButtons &buttons)
{
    CFileItemPtr item;
    if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
        item = m_vecItems->Get(itemNumber);

    CGUIWindowVideoBase::GetContextButtons(itemNumber, buttons);

    if (item && item->GetProperty("pluginreplacecontextitems").asBoolean())
        return;

    CVideoDatabaseDirectory dir;
    NODE_TYPE node = dir.GetDirectoryChildType(m_vecItems->GetPath());

    if (!item)
    {
        // nothing to do here
    }
    else if (m_vecItems->GetPath().Equals("sources://video/"))
    {
        // get the usual shares
        CGUIDialogContextMenu::GetContextButtons("video", item, buttons);
        // add scan button somewhere here
        if (g_application.IsVideoScanning())
            buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);  // Stop Scanning
        if (!item->IsDVD() && item->GetPath() != "add" && !item->IsParentFolder() &&
                (CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser))
        {
            CVideoDatabase database;
            database.Open();
            ADDON::ScraperPtr info = database.GetScraperForPath(item->GetPath());

            if (!g_application.IsVideoScanning())
            {
                if (!item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath()))
                {
                    if (info && info->Content() != CONTENT_NONE)
                        buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
                    else
                        buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
                }
            }

            if (info && !g_application.IsVideoScanning())
                buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
        }
    }
    else
    {
        // are we in the playlists location?
        bool inPlaylists = m_vecItems->GetPath().Equals(CUtil::VideoPlaylistsLocation()) ||
                           m_vecItems->GetPath().Equals("special://videoplaylists/");

        if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_artist.empty())
        {
            CMusicDatabase database;
            database.Open();
            if (database.GetArtistByName(StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator)) > -1)
                buttons.Add(CONTEXT_BUTTON_GO_TO_ARTIST, 20396);
        }
        if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0)
        {
            CMusicDatabase database;
            database.Open();
            if (database.GetAlbumByName(item->GetVideoInfoTag()->m_strAlbum) > -1)
                buttons.Add(CONTEXT_BUTTON_GO_TO_ALBUM, 20397);
        }
        if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_strAlbum.size() > 0 &&
                item->GetVideoInfoTag()->m_artist.size() > 0                              &&
                item->GetVideoInfoTag()->m_strTitle.size() > 0)
        {
            CMusicDatabase database;
            database.Open();
            if (database.GetSongByArtistAndAlbumAndTitle(StringUtils::Join(item->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator),
                    item->GetVideoInfoTag()->m_strAlbum,
                    item->GetVideoInfoTag()->m_strTitle) > -1)
            {
                buttons.Add(CONTEXT_BUTTON_PLAY_OTHER, 20398);
            }
        }
        if (!item->IsParentFolder())
        {
            ADDON::ScraperPtr info;
            VIDEO::SScanSettings settings;
            GetScraperForItem(item.get(), info, settings);

            if (info && info->Content() == CONTENT_TVSHOWS)
                buttons.Add(CONTEXT_BUTTON_INFO, item->m_bIsFolder ? 20351 : 20352);
            else if (info && info->Content() == CONTENT_MUSICVIDEOS)
                buttons.Add(CONTEXT_BUTTON_INFO,20393);
            else if (info && info->Content() == CONTENT_MOVIES)
                buttons.Add(CONTEXT_BUTTON_INFO, 13346);

            // can we update the database?
            if (CProfilesManager::Get().GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser)
            {
                if (!item->IsPlugin() && !item->IsScript() && !item->IsLiveTV() && !item->IsAddonsPath() &&
                        item->GetPath() != "sources://video/" &&
                        item->GetPath() != "special://videoplaylists/" &&
                        !StringUtils::StartsWith(item->GetPath(), "newsmartplaylist://") &&
                        !StringUtils::StartsWith(item->GetPath(), "newplaylist://") &&
                        !StringUtils::StartsWith(item->GetPath(), "newtag://"))
                {
                    if (item->m_bIsFolder)
                    {
                        // Have both options for folders since we don't know whether all childs are watched/unwatched
                        buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
                        buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103);   //Mark as Watched
                    }
                    else
                    {
                        if (item->GetOverlayImage().Equals("OverlayWatched.png"))
                            buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); //Mark as UnWatched
                        else
                            buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103);   //Mark as Watched
                    }
                }
                if (!g_application.IsVideoScanning() && item->IsVideoDb() && item->HasVideoInfoTag() &&
                        (item->GetVideoInfoTag()->m_type == "movie" ||       // movies
                         item->GetVideoInfoTag()->m_type == "tvshow" ||      // tvshows
                         item->GetVideoInfoTag()->m_type == "episode" ||     // episodes
                         item->GetVideoInfoTag()->m_type == "musicvideo" ||  // musicvideos
                         item->GetVideoInfoTag()->m_type == "tag" ||         // tags
                         item->GetVideoInfoTag()->m_type == "set"))          // sets
                {
                    buttons.Add(CONTEXT_BUTTON_EDIT, 16106);
                }
                if (node == NODE_TYPE_TITLE_TVSHOWS)
                {
                    if (g_application.IsVideoScanning())
                        buttons.Add(CONTEXT_BUTTON_STOP_SCANNING, 13353);
                    else
                        buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
                }

                if (node == NODE_TYPE_SEASONS && item->m_bIsFolder)
                    buttons.Add(CONTEXT_BUTTON_SET_SEASON_ART, 13511);

                if (node == NODE_TYPE_ACTOR && !dir.IsAllItem(item->GetPath()) && item->m_bIsFolder)
                {
                    if (StringUtils::StartsWithNoCase(m_vecItems->GetPath(), "videodb://musicvideos")) // mvids
                        buttons.Add(CONTEXT_BUTTON_SET_ARTIST_THUMB, 13359);
                    else
                        buttons.Add(CONTEXT_BUTTON_SET_ACTOR_THUMB, 20403);
                }
            }

            if (!m_vecItems->IsVideoDb() && !m_vecItems->IsVirtualDirectoryRoot())
            {   // non-video db items, file operations are allowed
                if ((CSettings::Get().GetBool("filelists.allowfiledeletion") &&
                        CUtil::SupportsWriteFileOperations(item->GetPath())) ||
                        (inPlaylists && !URIUtils::GetFileName(item->GetPath()).Equals("PartyMode-Video.xsp")
                         && (item->IsPlayList() || item->IsSmartPlayList())))
                {
                    buttons.Add(CONTEXT_BUTTON_DELETE, 117);
                    buttons.Add(CONTEXT_BUTTON_RENAME, 118);
                }
                // add "Set/Change content" to folders
                if (item->m_bIsFolder && !item->IsVideoDb() && !item->IsPlayList() && !item->IsSmartPlayList() && !item->IsLibraryFolder() && !item->IsLiveTV() && !item->IsPlugin() && !item->IsAddonsPath() && !URIUtils::IsUPnP(item->GetPath()))
                {
                    if (!g_application.IsVideoScanning())
                    {
                        if (info && info->Content() != CONTENT_NONE)
                        {
                            buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20442);
                            buttons.Add(CONTEXT_BUTTON_SCAN, 13349);
                        }
                        else
                            buttons.Add(CONTEXT_BUTTON_SET_CONTENT, 20333);
                    }
                }
            }
            if (item->IsPlugin() || item->IsScript() || m_vecItems->IsPlugin())
                buttons.Add(CONTEXT_BUTTON_PLUGIN_SETTINGS, 1045);
        }
    }
}
Пример #11
0
bool CGUIWindowVideoNav::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
    CFileItemPtr item;
    if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
        item = m_vecItems->Get(itemNumber);
    if (CGUIDialogContextMenu::OnContextButton("video", item, button))
    {
        //TODO should we search DB for entries from plugins?
        if (button == CONTEXT_BUTTON_REMOVE_SOURCE && !item->IsPlugin()
                && !item->IsLiveTV() &&!item->IsRSS() && !URIUtils::IsUPnP(item->GetPath()))
        {
            OnUnAssignContent(item->GetPath(),20375,20340,20341);
        }
        Refresh();
        return true;
    }
    switch (button)
    {
    case CONTEXT_BUTTON_EDIT:
    {
        CONTEXT_BUTTON ret = (CONTEXT_BUTTON)CGUIDialogVideoInfo::ManageVideoItem(item);
        if (ret >= 0)
        {
            if (ret == CONTEXT_BUTTON_MARK_WATCHED)
                m_viewControl.SetSelectedItem(itemNumber + 1);

            Refresh(true);
        }
        return true;
    }

    case CONTEXT_BUTTON_SET_SEASON_ART:
    case CONTEXT_BUTTON_SET_ACTOR_THUMB:
    case CONTEXT_BUTTON_SET_ARTIST_THUMB:
    {
        std::string type = "season";
        if (button == CONTEXT_BUTTON_SET_ACTOR_THUMB)
            type = "actor";
        else if (button == CONTEXT_BUTTON_SET_ARTIST_THUMB)
            type = "artist";

        bool result = CGUIDialogVideoInfo::ManageVideoItemArtwork(m_vecItems->Get(itemNumber), type);
        Refresh();

        return result;
    }
    case CONTEXT_BUTTON_GO_TO_ARTIST:
    {
        CStdString strPath;
        CMusicDatabase database;
        database.Open();
        strPath = StringUtils::Format("musicdb://artists/%ld/",
                                      database.GetArtistByName(StringUtils::Join(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator)));
        g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
        return true;
    }
    case CONTEXT_BUTTON_GO_TO_ALBUM:
    {
        CStdString strPath;
        CMusicDatabase database;
        database.Open();
        strPath = StringUtils::Format("musicdb://albums/%ld/",
                                      database.GetAlbumByName(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum));
        g_windowManager.ActivateWindow(WINDOW_MUSIC_NAV,strPath);
        return true;
    }
    case CONTEXT_BUTTON_PLAY_OTHER:
    {
        CMusicDatabase database;
        database.Open();
        CSong song;
        if (database.GetSong(database.GetSongByArtistAndAlbumAndTitle(StringUtils::Join(m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_artist, g_advancedSettings.m_videoItemSeparator),m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strAlbum,
                             m_vecItems->Get(itemNumber)->GetVideoInfoTag()->m_strTitle),
                             song))
        {
            CApplicationMessenger::Get().PlayFile(song);
        }
        return true;
    }

    default:
        break;

    }
    return CGUIWindowVideoBase::OnContextButton(itemNumber, button);
}
Пример #12
0
void CGUIWindowVideoNav::OnDeleteItem(CFileItemPtr pItem)
{
    if (m_vecItems->IsParentFolder())
        return;

    if (!m_vecItems->IsVideoDb() && !pItem->IsVideoDb())
    {
        if (!pItem->GetPath().Equals("newsmartplaylist://video") &&
                !pItem->GetPath().Equals("special://videoplaylists/") &&
                !pItem->GetPath().Equals("sources://video/") &&
                !StringUtils::StartsWithNoCase(pItem->GetPath(), "newtag://"))
            CGUIWindowVideoBase::OnDeleteItem(pItem);
    }
    else if (StringUtils::StartsWithNoCase(pItem->GetPath(), "videodb://movies/sets/") &&
             pItem->GetPath().size() > 22 && pItem->m_bIsFolder)
    {
        CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
        pDialog->SetHeading(432);
        CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(433),pItem->GetLabel().c_str());
        pDialog->SetLine(1, strLabel);
        pDialog->SetLine(2, "");;
        pDialog->DoModal();
        if (pDialog->IsConfirmed())
        {
            CFileItemList items;
            CDirectory::GetDirectory(pItem->GetPath(),items,"",DIR_FLAG_NO_FILE_DIRS);
            for (int i=0; i<items.Size(); ++i)
                OnDeleteItem(items[i]);

            CVideoDatabaseDirectory dir;
            CQueryParams params;
            dir.GetQueryParams(pItem->GetPath(),params);
            m_database.DeleteSet(params.GetSetId());
        }
    }
    else if (m_vecItems->GetContent() == "tags" && pItem->m_bIsFolder)
    {
        CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO);
        pDialog->SetHeading(432);
        CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(433), pItem->GetLabel().c_str());
        pDialog->SetLine(1, strLabel);
        pDialog->SetLine(2, "");
        pDialog->DoModal();
        if (pDialog->IsConfirmed())
        {
            CVideoDatabaseDirectory dir;
            CQueryParams params;
            dir.GetQueryParams(pItem->GetPath(), params);
            m_database.DeleteTag(params.GetTagId(), (VIDEODB_CONTENT_TYPE)params.GetContentType());
        }
    }
    else if (m_vecItems->GetPath().Equals(CUtil::VideoPlaylistsLocation()) ||
             m_vecItems->GetPath().Equals("special://videoplaylists/"))
    {
        pItem->m_bIsFolder = false;
        CFileUtils::DeleteItem(pItem);
    }
    else
    {
        if (!CGUIDialogVideoInfo::DeleteVideoItem(pItem))
            return;
    }

    CUtil::DeleteVideoDatabaseDirectoryCache();
}
Пример #13
0
void CGUIWindowVideoNav::LoadVideoInfo(CFileItemList &items, CVideoDatabase &database, bool allowReplaceLabels)
{
    // TODO: this could possibly be threaded as per the music info loading,
    //       we could also cache the info
    if (!items.GetContent().empty() && !items.IsPlugin())
        return; // don't load for listings that have content set and weren't created from plugins

    CStdString content = items.GetContent();
    // determine content only if it isn't set
    if (content.empty())
    {
        content = database.GetContentForPath(items.GetPath());
        items.SetContent(content.empty() ? "files" : content);
    }

    /*
      If we have a matching item in the library, so we can assign the metadata to it. In addition, we can choose
      * whether the item is stacked down (eg in the case of folders representing a single item)
      * whether or not we assign the library's labels to the item, or leave the item as is.

      As certain users (read: certain developers) don't want either of these to occur, we compromise by stacking
      items down only if stacking is available and enabled.

      Similarly, we assign the "clean" library labels to the item only if the "Replace filenames with library titles"
      setting is enabled.
      */
    const bool stackItems    = items.GetProperty("isstacked").asBoolean() || (StackingAvailable(items) && CSettings::Get().GetBool("myvideos.stackvideos"));
    const bool replaceLabels = allowReplaceLabels && CSettings::Get().GetBool("myvideos.replacelabels");

    CFileItemList dbItems;
    /* NOTE: In the future when GetItemsForPath returns all items regardless of whether they're "in the library"
             we won't need the fetchedPlayCounts code, and can "simply" do this directly on absense of content. */
    bool fetchedPlayCounts = false;
    if (!content.empty())
    {
        database.GetItemsForPath(content, items.GetPath(), dbItems);
        dbItems.SetFastLookup(true);
    }

    for (int i = 0; i < items.Size(); i++)
    {
        CFileItemPtr pItem = items[i];
        CFileItemPtr match;
        if (!content.empty()) /* optical media will be stacked down, so it's path won't match the base path */
            match = dbItems.Get(pItem->IsOpticalMediaFile() ? pItem->GetLocalMetadataPath() : pItem->GetPath());
        if (match)
        {
            pItem->UpdateInfo(*match, replaceLabels);

            if (stackItems)
            {
                if (match->m_bIsFolder)
                    pItem->SetPath(match->GetVideoInfoTag()->m_strPath);
                else
                    pItem->SetPath(match->GetVideoInfoTag()->m_strFileNameAndPath);
                // if we switch from a file to a folder item it means we really shouldn't be sorting files and
                // folders separately
                if (pItem->m_bIsFolder != match->m_bIsFolder)
                {
                    items.SetSortIgnoreFolders(true);
                    pItem->m_bIsFolder = match->m_bIsFolder;
                }
            }
        }
        else
        {
            /* NOTE: Currently we GetPlayCounts on our items regardless of whether content is set
                      as if content is set, GetItemsForPaths doesn't return anything not in the content tables.
                      This code can be removed once the content tables are always filled */
            if (!pItem->m_bIsFolder && !fetchedPlayCounts)
            {
                database.GetPlayCounts(items.GetPath(), items);
                fetchedPlayCounts = true;
            }

            // preferably use some information from PVR info tag if available
            if (pItem->HasPVRRecordingInfoTag())
                pItem->GetPVRRecordingInfoTag()->CopyClientInfo(pItem->GetVideoInfoTag());

            // set the watched overlay
            if (pItem->IsVideo())
                pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pItem->HasVideoInfoTag() && pItem->GetVideoInfoTag()->m_playCount > 0);
        }
    }
}
Пример #14
0
bool CGUIWindowVideoNav::OnClick(int iItem)
{
    CFileItemPtr item = m_vecItems->Get(iItem);
    if (!item->m_bIsFolder && item->IsVideoDb() && !item->Exists())
    {
        CLog::Log(LOGDEBUG, "%s called on '%s' but file doesn't exist", __FUNCTION__, item->GetPath().c_str());
        if (!CGUIDialogVideoInfo::DeleteVideoItemFromDatabase(item, true))
            return true;

        // update list
        Refresh(true);
        m_viewControl.SetSelectedItem(iItem);
        return true;
    }
    else if (StringUtils::StartsWithNoCase(item->GetPath(), "newtag://"))
    {
        // dont allow update while scanning
        if (g_application.IsVideoScanning())
        {
            CGUIDialogOK::ShowAndGetInput(257, 0, 14057, 0);
            return true;
        }

        //Get the new title
        CStdString strTag;
        if (!CGUIKeyboardFactory::ShowAndGetInput(strTag, g_localizeStrings.Get(20462), false))
            return true;

        CVideoDatabase videodb;
        if (!videodb.Open())
            return true;

        // get the media type and convert from plural to singular (by removing the trailing "s")
        CStdString mediaType = item->GetPath().substr(9);
        mediaType = mediaType.substr(0, mediaType.size() - 1);
        CStdString localizedType = CGUIDialogVideoInfo::GetLocalizedVideoType(mediaType);
        if (localizedType.empty())
            return true;

        if (!videodb.GetSingleValue("tag", "tag.idTag", videodb.PrepareSQL("tag.strTag = '%s' AND tag.idTag IN (SELECT taglinks.idTag FROM taglinks WHERE taglinks.media_type = '%s')", strTag.c_str(), mediaType.c_str())).empty())
        {
            CStdString strError = StringUtils::Format(g_localizeStrings.Get(20463), strTag.c_str());
            CGUIDialogOK::ShowAndGetInput(20462, "", strError, "");
            return true;
        }

        int idTag = videodb.AddTag(strTag);
        CFileItemList items;
        CStdString strLabel = StringUtils::Format(g_localizeStrings.Get(20464), localizedType.c_str());
        if (CGUIDialogVideoInfo::GetItemsForTag(strLabel, mediaType, items, idTag))
        {
            for (int index = 0; index < items.Size(); index++)
            {
                if (!items[index]->HasVideoInfoTag() || items[index]->GetVideoInfoTag()->m_iDbId <= 0)
                    continue;

                videodb.AddTagToItem(items[index]->GetVideoInfoTag()->m_iDbId, idTag, mediaType);
            }
        }

        Refresh(true);
        return true;
    }

    return CGUIWindowVideoBase::OnClick(iItem);
}
Пример #15
0
void CBackgroundInfoLoader::Run()
{
    try
    {
        if (m_vecItems.size() > 0)
        {
            OnLoaderStart();

            for (std::vector<CFileItemPtr>::const_iterator iter = m_vecItems.begin(); iter != m_vecItems.end(); ++iter)
            {
                CFileItemPtr pItem = *iter;

                // Ask the callback if we should abort
                if ((m_pProgressCallback && m_pProgressCallback->Abort()) || m_bStop)
                    break;

                try
                {
                    if (LoadItem(pItem.get()) && m_pObserver)
                        m_pObserver->OnItemLoaded(pItem.get());
                }
                catch (...)
                {
                    CLog::Log(LOGERROR, "CBackgroundInfoLoader::LoadItem - Unhandled exception for item %s", CURL::GetRedacted(pItem->GetPath()).c_str());
                }
            }
        }

        OnLoaderFinish();
        m_bIsLoading = false;
    }
    catch (...)
    {
        m_bIsLoading = false;
        CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
    }
}
Пример #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);
#ifdef HAS_DVD_DRIVE
  if (pItem->IsDVD())
  {
    MEDIA_DETECT::CAutorun::PlayDiscAskResume(pItem->GetPath());
    return;
  }
#endif

  // if its a folder, build a playlist
  if ((pItem->m_bIsFolder && !pItem->IsPlugin()) || (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);
    if (g_partyModeManager.IsEnabled())
    {
      g_partyModeManager.AddUserSongs(queuedItems, true);
      return;
    }

    /*
    std::string strPlayListDirectory = m_vecItems->GetPath();
    URIUtils::RemoveSlashAtEnd(strPlayListDirectory);
    */

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

    // play!
    g_playlistPlayer.Play();
  }
  else if (pItem->IsPlayList())
  {
    // load the playlist the old way
    LoadPlayList(pItem->GetPath());
  }
  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);
  }
}
void CGUIDialogSmartPlaylistRule::OnBrowse()
{
  CFileItemList items;
  CMusicDatabase database;
  database.Open();
  CVideoDatabase videodatabase;
  videodatabase.Open();

  std::string basePath;
  if (m_type.Equals("songs") || m_type.Equals("albums") || m_type.Equals("artists") || m_type.Equals("mixed"))
    basePath = "musicdb://";
  else
    basePath = "videodb://";

  VIDEODB_CONTENT_TYPE type = VIDEODB_CONTENT_MOVIES;
  if (m_type.Equals("movies"))
    basePath += "1/";
  else if (m_type.Equals("tvshows"))
  {
    type = VIDEODB_CONTENT_TVSHOWS;
    basePath += "2/";
  }
  else if (m_type.Equals("musicvideos"))
  {
    type = VIDEODB_CONTENT_MUSICVIDEOS;
    basePath += "3/";
  }
  else if (m_type.Equals("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 += "2/";
  }

  int iLabel = 0;
  if (m_rule.m_field == FieldGenre)
  {
    if (m_type.Equals("tvshows") || m_type.Equals("episodes") || m_type.Equals("movies"))
      videodatabase.GetGenresNav(basePath + "1/", items, type);
    else if (m_type.Equals("songs") || m_type.Equals("albums") || m_type.Equals("artists") || m_type.Equals("mixed"))
      database.GetGenresNav("musicdb://1/",items);
    if (m_type.Equals("musicvideos") || m_type.Equals("mixed"))
    {
      CFileItemList items2;
      videodatabase.GetGenresNav("videodb://3/1/",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 (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums") || m_type.Equals("artists"))
      database.GetArtistsNav("musicdb://2/", items, m_rule.m_field == FieldAlbumArtist, -1);
    if (m_type.Equals("musicvideos") || m_type.Equals("mixed"))
    {
      CFileItemList items2;
      videodatabase.GetMusicVideoArtistsByName("", items2);
      items.Append(items2);
    }
    iLabel = 557;
  }
  else if (m_rule.m_field == FieldAlbum)
  {
    if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums"))
      database.GetAlbumsNav("musicdb://3/", items);
    if (m_type.Equals("musicvideos") || m_type.Equals("mixed"))
    {
      CFileItemList items2;
      videodatabase.GetMusicVideoAlbumsByName("", items2);
      items.Append(items2);
    }
    iLabel = 558;
  }
  else if (m_rule.m_field == FieldActor)
  {
    videodatabase.GetActorsNav(basePath + "4/",items,type);
    iLabel = 20337;
  }
  else if (m_rule.m_field == FieldYear)
  {
    if (m_type.Equals("songs") || m_type.Equals("mixed") || m_type.Equals("albums"))
      database.GetYearsNav("musicdb://9/", items);
    if (!m_type.Equals("songs") && !m_type.Equals("albums"))
    {
      CFileItemList items2;
      videodatabase.GetYearsNav(basePath + "3/", items2, type);
      items.Append(items2);
    }
    iLabel = 562;
  }
  else if (m_rule.m_field == FieldDirector)
  {
    videodatabase.GetDirectorsNav(basePath + "5/", items, type);
    iLabel = 20339;
  }
  else if (m_rule.m_field == FieldStudio)
  {
    if (m_type.Equals("movies"))
      basePath += "6/";
    else if (m_type.Equals("musicvideos") || m_type.Equals("mixed"))
      basePath += "7/";
    else
      basePath += "5/";

    videodatabase.GetStudiosNav(basePath, 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.Equals("tvshows") && m_rule.m_field == FieldTitle))
  {
    videodatabase.GetTvShowsNav(basePath + "2/", items);
    iLabel = 20343;
  }
  else if (m_rule.m_field == FieldTitle)
  {
    if (m_type.Equals("songs"))
    {
      database.GetSongsNav("musicdb://4/", items, -1, -1, -1);
      iLabel = 134;
    }
    else if (m_type.Equals("movies"))
    {
      videodatabase.GetMoviesNav(basePath + "2/", items);
      iLabel = 20342;
    }
    else if (m_type.Equals("episodes"))
    {
      videodatabase.GetEpisodesNav(basePath + "2/-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;
    }
    else if (m_type.Equals("musicvideos"))
    {
      videodatabase.GetMusicVideosNav(basePath + "2/", items);
      iLabel = 20389;
    }
    else
      assert(false);
  }
  else if (m_rule.m_field == FieldPlaylist)
  {
    // 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
    CStdString path = "special://videoplaylists/";
    if (m_type.Equals("songs") || m_type.Equals("albums") || m_type.Equals("artists"))
      path = "special://musicplaylists/";
    XFILE::CDirectory::GetDirectory(path, items, ".xsp", XFILE::DIR_FLAG_NO_FILE_DIRS);
    for (int i = 0; i < items.Size(); i++)
    {
      CFileItemPtr item = items[i];
      CSmartPlaylist playlist;
      if (playlist.OpenAndReadName(item->GetPath()))
        item->SetLabel(playlist.GetName());
    }
    iLabel = 559;
  }
  else if (m_rule.m_field == FieldPath)
  {
    VECSOURCES sources;
    if (m_type == "songs" || m_type == "mixed")
      sources = *g_settings.GetSourcesFromType("music");
    if (m_type != "songs")
    {
      VECSOURCES sources2 = *g_settings.GetSourcesFromType("video");
      sources.insert(sources.end(),sources2.begin(),sources2.end());
    }
    g_mediaManager.GetLocalDrives(sources);
    
    CStdString 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://1/7/", items, VIDEODB_CONTENT_MOVIES);
    iLabel = 20434;
  }
  else if (m_rule.m_field == FieldTag)
  {
    if (m_type == "movies")
      videodatabase.GetTagsNav(basePath + "9/", items, VIDEODB_CONTENT_MOVIES);
    else
      return;
    iLabel = 20459;
  }
  else
  { // TODO: Add browseability in here.
    assert(false);
  }

  // sort the items
  items.Sort(SORT_METHOD_LABEL, SortOrderAscending);

  CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT);
  pDialog->Reset();
  pDialog->SetItems(&items);
  CStdString strHeading;
  strHeading.Format(g_localizeStrings.Get(13401),g_localizeStrings.Get(iLabel));
  pDialog->SetHeading(strHeading);
  pDialog->SetMultiSelection(true);

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

  pDialog->DoModal();
  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();
}
Пример #18
0
/**
 * 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 CStdString& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */)
{
  bool bPlaying(false);
  CFileItemList vecItems;

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

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

  // is this a root folder we have to check the content to determine a disc type
  if( bRoot )
  {
    // 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() != "..")
      {
        CStdString name = pItem->GetPath();
        URIUtils::RemoveSlashAtEnd(name);
        name = URIUtils::GetFileName(name);

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

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

          g_application.PlayFile(item, false);
          bPlaying = true;
          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 (name.Equals("BDMV") && bAllowVideo
        && (bypassSettings || g_guiSettings.GetBool("dvds.autorun")))
        {
          CFileItem item(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.IsEmpty())
            item.m_lStartOffset = STARTOFFSET_RESUME;

          g_application.PlayFile(item, false);
          bPlaying = true;
          return true;
        }

        // Video CDs can have multiple file formats. First we need to determine which one is used on the CD
        CStdString strExt;
        if (name.Equals("MPEGAV"))
          strExt = ".dat";
        if (name.Equals("MPEG2"))
          strExt = ".mpg";

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

  // check video first
  if (!nAddedToPlaylist && !bPlaying && (bypassSettings || g_guiSettings.GetBool("dvds.autorun")))
  {
    // stack video files
    CFileItemList tempItems;
    tempItems.Append(vecItems);
    if (g_settings.m_videoStacking)
      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->GetPath(), 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 || g_guiSettings.GetBool("audiocds.autorun")) && 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;
        CStdString strExec;
        strExec.Format("XBMC.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;
}
Пример #19
0
bool CDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items, const CHints &hints, bool allowThreads)
{
  try
  {
    CStdString realPath = URIUtils::SubstitutePath(strPath);
    boost::shared_ptr<IDirectory> pDirectory(CDirectoryFactory::Create(realPath));
    if (!pDirectory.get())
      return false;

    // check our cache for this path
    if (g_directoryCache.GetDirectory(strPath, items, (hints.flags & DIR_FLAG_READ_CACHE) == DIR_FLAG_READ_CACHE))
      items.SetPath(strPath);
    else
    {
      // need to clear the cache (in case the directory fetch fails)
      // and (re)fetch the folder
      if (hints.flags & DIR_FLAG_BYPASS_CACHE)
        g_directoryCache.ClearDirectory(strPath);

      pDirectory->SetFlags(hints.flags);

      bool result = false, cancel = false;
      while (!result && !cancel)
      {
        if (g_application.IsCurrentThread() && allowThreads && !URIUtils::IsSpecial(strPath))
        {
          CSingleExit ex(g_graphicsContext);

          CGetDirectory get(pDirectory, realPath);
          if(!get.Wait(TIME_TO_BUSY_DIALOG))
          {
            CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
            dialog->Show();

            while(!get.Wait(10))
            {
              CSingleLock lock(g_graphicsContext);

              if(dialog->IsCanceled())
              {
                cancel = true;
                break;
              }
              g_windowManager.ProcessRenderLoop(false);
            }
            if(dialog)
              dialog->Close();
          }
          result = get.GetDirectory(items);
        }
        else
        {
          items.SetPath(strPath);
          result = pDirectory->GetDirectory(realPath, items);
        }

        if (!result)
        {
          if (!cancel && g_application.IsCurrentThread() && pDirectory->ProcessRequirements())
            continue;
          CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str());
          return false;
        }
      }

      // cache the directory, if necessary
      if (hints.flags & DIR_FLAG_BYPASS_CACHE)
        g_directoryCache.SetDirectory(strPath, items, pDirectory->GetCacheType(strPath));
    }

    // now filter for allowed files
    pDirectory->SetMask(hints.mask);
    for (int i = 0; i < items.Size(); ++i)
    {
      CFileItemPtr item = items[i];
      // TODO: we shouldn't be checking the gui setting here;
      // callers should use getHidden instead
      if ((!item->m_bIsFolder && !pDirectory->IsAllowed(item->GetPath())) ||
          (item->GetProperty("file:hidden").asBoolean() && !(hints.flags & DIR_FLAG_GET_HIDDEN) && !g_guiSettings.GetBool("filelists.showhidden")))
      {
        items.Remove(i);
        i--; // don't confuse loop
      }
    }

    //  Should any of the files we read be treated as a directory?
    //  Disable for database folders, as they already contain the extracted items
    if (!(hints.flags & DIR_FLAG_NO_FILE_DIRS) && !items.IsMusicDb() && !items.IsVideoDb() && !items.IsSmartPlayList())
      FilterFileDirectories(items, hints.mask);

    return true;
  }
#ifndef _LINUX
  catch (const win32_exception &e)
  {
    e.writelog(__FUNCTION__);
  }
#endif
  catch (...)
  {
    CLog::Log(LOGERROR, "%s - Unhandled exception", __FUNCTION__);
  }
  CLog::Log(LOGERROR, "%s - Error getting %s", __FUNCTION__, strPath.c_str());
  return false;
}
Пример #20
0
void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char *resultname, CFileItemPtr item, const CVariant &parameterObject, const std::set<std::string> &validFields, CVariant &result, bool append /* = true */, CThumbLoader *thumbLoader /* = NULL */)
{
  CVariant object;
  std::set<std::string> fields(validFields.begin(), validFields.end());

  if (item.get())
  {
    std::set<std::string>::const_iterator fileField = fields.find("file");
    if (fileField != fields.end())
    {
      if (allowFile)
      {
        if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->GetPath().empty())
          object["file"] = item->GetVideoInfoTag()->GetPath().c_str();
        if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetURL().empty())
          object["file"] = item->GetMusicInfoTag()->GetURL().c_str();

        if (!object.isMember("file"))
          object["file"] = item->GetPath().c_str();
      }
      fields.erase(fileField);
    }

    if (ID)
    {
      if (item->HasPVRChannelInfoTag() && item->GetPVRChannelInfoTag()->ChannelID() > 0)
         object[ID] = item->GetPVRChannelInfoTag()->ChannelID();
      else if (item->HasEPGInfoTag() && item->GetEPGInfoTag()->UniqueBroadcastID() > 0)
         object[ID] = item->GetEPGInfoTag()->UniqueBroadcastID();
      else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > 0)
        object[ID] = (int)item->GetMusicInfoTag()->GetDatabaseId();
      else if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > 0)
        object[ID] = item->GetVideoInfoTag()->m_iDbId;

      if (stricmp(ID, "id") == 0)
      {
        if (item->HasPVRChannelInfoTag())
          object["type"] = "channel";
        else if (item->HasMusicInfoTag())
        {
          std::string type = item->GetMusicInfoTag()->GetType();
          if (type == "album" || type == "song" || type == "artist")
            object["type"] = type;
          else
            object["type"] = "song";
        }
        else if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->m_type.empty())
        {
          std::string type = item->GetVideoInfoTag()->m_type;
          if (type == "movie" || type == "tvshow" || type == "episode" || type == "musicvideo")
            object["type"] = type;
        }
        else if (item->HasPictureInfoTag())
          object["type"] = "picture";

        if (!object.isMember("type"))
          object["type"] = "unknown";

        if (fields.find("filetype") != fields.end())
        {
          if (item->m_bIsFolder)
            object["filetype"] = "directory";
          else 
            object["filetype"] = "file";
        }
      }
    }

    bool deleteThumbloader = false;
    if (thumbLoader == NULL)
    {
      if (item->HasVideoInfoTag())
        thumbLoader = new CVideoThumbLoader();
      else if (item->HasMusicInfoTag())
        thumbLoader = new CMusicThumbLoader();

      if (thumbLoader != NULL)
      {
        deleteThumbloader = true;
        thumbLoader->OnLoaderStart();
      }
    }

    if (item->HasPVRChannelInfoTag())
      FillDetails(item->GetPVRChannelInfoTag(), item, fields, object, thumbLoader);
    if (item->HasEPGInfoTag())
      FillDetails(item->GetEPGInfoTag(), item, fields, object, thumbLoader);
    if (item->HasVideoInfoTag())
      FillDetails(item->GetVideoInfoTag(), item, fields, object, thumbLoader);
    if (item->HasMusicInfoTag())
      FillDetails(item->GetMusicInfoTag(), item, fields, object, thumbLoader);
    if (item->HasPictureInfoTag())
      FillDetails(item->GetPictureInfoTag(), item, fields, object, thumbLoader);
    
    FillDetails(item.get(), item, fields, object, thumbLoader);

    if (deleteThumbloader)
      delete thumbLoader;

    object["label"] = item->GetLabel().c_str();
  }
  else
    object = CVariant(CVariant::VariantTypeNull);

  if (resultname)
  {
    if (append)
      result[resultname].append(object);
    else
      result[resultname] = object;
  }
}
Пример #21
0
void CGUIDialogFileBrowser::Update(const CStdString &strDirectory)
{
  if (m_browsingForImages && m_thumbLoader.IsLoading())
    m_thumbLoader.StopThread();
  // get selected item
  int iItem = m_viewControl.GetSelectedItem();
  CStdString strSelectedItem = "";
  if (iItem >= 0 && iItem < m_vecItems->Size())
  {
    CFileItemPtr pItem = (*m_vecItems)[iItem];
    if (!pItem->IsParentFolder())
    {
      strSelectedItem = pItem->GetPath();
      URIUtils::RemoveSlashAtEnd(strSelectedItem);
      m_history.SetSelectedItem(strSelectedItem, m_Directory->GetPath().IsEmpty()?"empty":m_Directory->GetPath());
    }
  }

  if (!m_singleList)
  {
    CFileItemList items;
    CStdString strParentPath;

    if (!m_rootDir.GetDirectory(strDirectory, items,m_useFileDirectories))
    {
      CLog::Log(LOGERROR,"CGUIDialogFileBrowser::GetDirectory(%s) failed", strDirectory.c_str());

      // We assume, we can get the parent
      // directory again
      CStdString strParentPath = m_history.GetParentPath();
      m_history.RemoveParentPath();
      Update(strParentPath);
      return;
    }

    // check if current directory is a root share
    if (!m_rootDir.IsSource(strDirectory))
    {
      if (URIUtils::GetParentPath(strDirectory, strParentPath))
      {
        CFileItemPtr pItem(new CFileItem(".."));
        pItem->SetPath(strParentPath);
        pItem->m_bIsFolder = true;
        pItem->m_bIsShareOrDrive = false;
        items.AddFront(pItem, 0);
      }
    }
    else
    {
      // yes, this is the root of a share
      // add parent path to the virtual directory
      CFileItemPtr pItem(new CFileItem(".."));
      pItem->SetPath("");
      pItem->m_bIsShareOrDrive = false;
      pItem->m_bIsFolder = true;
      items.AddFront(pItem, 0);
      strParentPath = "";
    }

    ClearFileItems();
    m_vecItems->Copy(items);
    m_Directory->SetPath(strDirectory);
    m_strParentPath = strParentPath;
  }

  // if we're getting the root source listing
  // make sure the path history is clean
  if (strDirectory.IsEmpty())
    m_history.ClearPathHistory();

  // some evil stuff don't work with the '/' mask, e.g. shoutcast directory - make sure no files are in there
  if (m_browsingForFolders)
  {
    for (int i=0;i<m_vecItems->Size();++i)
      if (!(*m_vecItems)[i]->m_bIsFolder)
      {
        m_vecItems->Remove(i);
        i--;
      }
  }

  // No need to set thumbs

  m_vecItems->FillInDefaultIcons();

  OnSort();

  if (m_Directory->GetPath().IsEmpty() && m_addNetworkShareEnabled &&
     (g_settings.GetMasterProfile().getLockMode() == LOCK_MODE_EVERYONE ||
      g_settings.IsMasterUser() || g_passwordManager.bMasterUser))
  { // we are in the virtual directory - add the "Add Network Location" item
    CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(1032)));
    pItem->SetPath("net://");
    pItem->m_bIsFolder = true;
    m_vecItems->Add(pItem);
  }
  if (m_Directory->GetPath().IsEmpty() && !m_addSourceType.IsEmpty())
  {
    CFileItemPtr pItem(new CFileItem(g_localizeStrings.Get(21359)));
    pItem->SetPath("source://");
    pItem->m_bIsFolder = true;
    m_vecItems->Add(pItem);
  }

  m_viewControl.SetItems(*m_vecItems);
  m_viewControl.SetCurrentView((m_browsingForImages && CAutoSwitch::ByFileCount(*m_vecItems)) ? DEFAULT_VIEW_ICONS : DEFAULT_VIEW_LIST);

  CStdString strPath2 = m_Directory->GetPath();
  URIUtils::RemoveSlashAtEnd(strPath2);
  strSelectedItem = m_history.GetSelectedItem(strPath2==""?"empty":strPath2);

  bool bSelectedFound = false;
  for (int i = 0; i < (int)m_vecItems->Size(); ++i)
  {
    CFileItemPtr pItem = (*m_vecItems)[i];
    strPath2 = pItem->GetPath();
    URIUtils::RemoveSlashAtEnd(strPath2);
    if (strPath2 == strSelectedItem)
    {
      m_viewControl.SetSelectedItem(i);
      bSelectedFound = true;
      break;
    }
  }

  // if we haven't found the selected item, select the first item
  if (!bSelectedFound)
    m_viewControl.SetSelectedItem(0);

  m_history.AddPath(m_Directory->GetPath());

  if (m_browsingForImages)
    m_thumbLoader.Load(*m_vecItems);
}
Пример #22
0
bool CFileItemHandler::GetField(const std::string &field, const CVariant &info, const CFileItemPtr &item, CVariant &result, bool &fetchedArt, CThumbLoader *thumbLoader /* = NULL */)
{
  if (result.isMember(field) && !result[field].empty())
    return true;

  // overwrite serialized values
  if (item)
  {
    if (field == "mimetype" && item->GetMimeType().empty())
    {
      item->FillInMimeType(false);
      result[field] = item->GetMimeType();
      return true;
    }
  }

  // check for serialized values
  if (info.isMember(field) && !info[field].isNull())
  {
    result[field] = info[field];
    return true;
  }

  // check if the field requires special handling
  if (item)
  {
    if (item->IsAlbum())
    {
      if (field == "albumlabel")
      {
        result[field] = item->GetProperty("album_label");
        return true;
      }
      if (item->HasProperty("album_" + field + "_array"))
      {
        result[field] = item->GetProperty("album_" + field + "_array");
        return true;
      }
      if (item->HasProperty("album_" + field))
      {
        result[field] = item->GetProperty("album_" + field);
        return true;
      }
    }
    
    if (item->HasProperty("artist_" + field + "_array"))
    {
      result[field] = item->GetProperty("artist_" + field + "_array");
      return true;
    }
    if (item->HasProperty("artist_" + field))
    {
      result[field] = item->GetProperty("artist_" + field);
      return true;
    }

    if (field == "art")
    {
      if (thumbLoader != NULL && item->GetArt().size() <= 0 && !fetchedArt &&
        ((item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > -1) || (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > -1)))
      {
        thumbLoader->FillLibraryArt(*item);
        fetchedArt = true;
      }

      CGUIListItem::ArtMap artMap = item->GetArt();
      CVariant artObj(CVariant::VariantTypeObject);
      for (CGUIListItem::ArtMap::const_iterator artIt = artMap.begin(); artIt != artMap.end(); ++artIt)
      {
        if (!artIt->second.empty())
          artObj[artIt->first] = CTextureUtils::GetWrappedImageURL(artIt->second);
      }

      result["art"] = artObj;
      return true;
    }
    
    if (field == "thumbnail")
    {
      if (thumbLoader != NULL && !item->HasArt("thumb") && !fetchedArt &&
        ((item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > -1) || (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > -1)))
      {
        thumbLoader->FillLibraryArt(*item);
        fetchedArt = true;
      }
      else if (item->HasPictureInfoTag() && !item->HasArt("thumb"))
        item->SetArt("thumb", CTextureUtils::GetWrappedThumbURL(item->GetPath()));
      
      if (item->HasArt("thumb"))
        result["thumbnail"] = CTextureUtils::GetWrappedImageURL(item->GetArt("thumb"));
      else
        result["thumbnail"] = "";
      
      return true;
    }
    
    if (field == "fanart")
    {
      if (thumbLoader != NULL && !item->HasArt("fanart") && !fetchedArt &&
        ((item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > -1) || (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > -1)))
      {
        thumbLoader->FillLibraryArt(*item);
        fetchedArt = true;
      }
      
      if (item->HasArt("fanart"))
        result["fanart"] = CTextureUtils::GetWrappedImageURL(item->GetArt("fanart"));
      else
        result["fanart"] = "";
      
      return true;
    }
    
    if (item->HasVideoInfoTag() && item->GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS)
    {
      if (item->GetVideoInfoTag()->m_iSeason < 0 && field == "season")
      {
        result[field] = (int)item->GetProperty("totalseasons").asInteger();
        return true;
      }
      if (field == "watchedepisodes")
      {
        result[field] = (int)item->GetProperty("watchedepisodes").asInteger();
        return true;
      }
    }
    
    if (field == "lastmodified" && item->m_dateTime.IsValid())
    {
      result[field] = item->m_dateTime.GetAsLocalizedDateTime();
      return true;
    }

    if (item->HasProperty(field))
    {
      result[field] = item->GetProperty(field);
      return true;
    }
  }

  return false;
}
Пример #23
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->GetPath()) == 0)
      bIsDAAPplaylist = true;
  }
#endif
  // if its a folder, build a playlist
  if ((pItem->m_bIsFolder && !pItem->IsPlugin()) || (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);
    if (g_partyModeManager.IsEnabled())
    {
      g_partyModeManager.AddUserSongs(queuedItems, true);
      return;
    }

    /*
    CStdString strPlayListDirectory = m_vecItems->GetPath();
    URIUtils::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();
  }
  else if (pItem->IsPlayList())
  {
    // load the playlist the old way
    LoadPlayList(pItem->GetPath());
  }
  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);
  }
}
Пример #24
0
bool CPlayListPlayer::Play(int iSong, bool bAutoPlay /* = false */, bool bPlayPrevious /* = false */)
{
  if (m_iCurrentPlayList == PLAYLIST_NONE)
    return false;

  CPlayList& playlist = GetPlaylist(m_iCurrentPlayList);
  if (playlist.size() <= 0) 
    return false;
  if (iSong < 0) 
    iSong = 0;
  if (iSong >= playlist.size()) 
    iSong = playlist.size() - 1;

  // check if the item itself is a playlist, and can be expanded
  // only allow a few levels, this could end up in a loop
  // if they refer to each other in a loop
  for(int i=0;i<5;i++)
  {
     if(!playlist.Expand(iSong))
        break;
  }

  m_iCurrentSong = iSong;
  CFileItemPtr item = playlist[m_iCurrentSong];
  playlist.SetPlayed(true);

  m_bPlaybackStarted = false;

  unsigned int playAttempt = XbmcThreads::SystemClockMillis();
  if (!g_application.PlayFile(*item, bAutoPlay))
  {
    CLog::Log(LOGERROR,"Playlist Player: skipping unplayable item: %i, path [%s]", m_iCurrentSong, item->GetPath().c_str());
    playlist.SetUnPlayable(m_iCurrentSong);

    // abort on 100 failed CONSECTUTIVE songs
    if (!m_iFailedSongs)
      m_failedSongsStart = playAttempt;
    m_iFailedSongs++;
    if ((m_iFailedSongs >= g_advancedSettings.m_playlistRetries && g_advancedSettings.m_playlistRetries >= 0)
        || ((XbmcThreads::SystemClockMillis() - m_failedSongsStart  >= (unsigned int)g_advancedSettings.m_playlistTimeout * 1000) && g_advancedSettings.m_playlistTimeout))
    {
      CLog::Log(LOGDEBUG,"Playlist Player: one or more items failed to play... aborting playback");

      // open error dialog
      CGUIDialogOK::ShowAndGetInput(16026, 16027, 16029, 0);

      CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_STOPPED, 0, 0, m_iCurrentPlayList, m_iCurrentSong);
      g_windowManager.SendThreadMessage(msg);
      Reset();
      GetPlaylist(m_iCurrentPlayList).Clear();
      m_iCurrentPlayList = PLAYLIST_NONE;
      m_iFailedSongs = 0;
      m_failedSongsStart = 0;
      return false;
    }

    // how many playable items are in the playlist?
    if (playlist.GetPlayable() > 0)
    {
      return bPlayPrevious ? PlayPrevious() : PlayNext();
    }
    // none? then abort playback
    else
    {
      CLog::Log(LOGDEBUG,"Playlist Player: no more playable items... aborting playback");
      CGUIMessage msg(GUI_MSG_PLAYLISTPLAYER_STOPPED, 0, 0, m_iCurrentPlayList, m_iCurrentSong);
      g_windowManager.SendThreadMessage(msg);
      Reset();
      m_iCurrentPlayList = PLAYLIST_NONE;
      return false;
    }
  }

  // TODO - move the above failure logic and the below success logic
  //        to callbacks instead so we don't rely on the return value
  //        of PlayFile()

  // consecutive error counter so reset if the current item is playing
  m_iFailedSongs = 0;
  m_failedSongsStart = 0;
  m_bPlaybackStarted = true;
  m_bPlayedFirstFile = true;
  return true;
}
Пример #25
0
bool CGUIWindowMusicBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button)
{
  CFileItemPtr item;
  if (itemNumber >= 0 && itemNumber < m_vecItems->Size())
    item = m_vecItems->Get(itemNumber);

  switch (button)
  {
  case CONTEXT_BUTTON_QUEUE_ITEM:
    OnQueueItem(itemNumber);
    return true;

  case CONTEXT_BUTTON_INFO:
    OnInfo(itemNumber);
    return true;

  case CONTEXT_BUTTON_SONG_INFO:
    {
      ShowSongInfo(item.get());
      return true;
    }

  case CONTEXT_BUTTON_EDIT:
    {
      CStdString playlist = item->IsPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items
      g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST_EDITOR, playlist);
      // need to update
      m_vecItems->RemoveDiscCache(GetID());
      return true;
    }

  case CONTEXT_BUTTON_EDIT_SMART_PLAYLIST:
    {
      CStdString playlist = item->IsSmartPlayList() ? item->GetPath() : m_vecItems->GetPath(); // save path as activatewindow will destroy our items
      if (CGUIDialogSmartPlaylistEditor::EditPlaylist(playlist, "music"))
      { // need to update
        m_vecItems->RemoveDiscCache(GetID());
        Update(m_vecItems->GetPath());
      }
      return true;
    }

  case CONTEXT_BUTTON_PLAY_ITEM:
    PlayItem(itemNumber);
    return true;

  case CONTEXT_BUTTON_PLAY_WITH:
    {
      VECPLAYERCORES vecCores;  // base class?
      CPlayerCoreFactory::GetPlayers(*item, vecCores);
      g_application.m_eForcedNextPlayer = CPlayerCoreFactory::SelectPlayerDialog(vecCores);
      if( g_application.m_eForcedNextPlayer != EPC_NONE )
        OnClick(itemNumber);
      return true;
    }

  case CONTEXT_BUTTON_PLAY_PARTYMODE:
    g_partyModeManager.Enable(PARTYMODECONTEXT_MUSIC, item->GetPath());
    return true;

  case CONTEXT_BUTTON_STOP_SCANNING:
    {
      CGUIDialogMusicScan *scanner = (CGUIDialogMusicScan *)g_windowManager.GetWindow(WINDOW_DIALOG_MUSIC_SCAN);
      if (scanner)
        scanner->StopScanning();
      return true;
    }

  case CONTEXT_BUTTON_NOW_PLAYING:
    g_windowManager.ActivateWindow(WINDOW_MUSIC_PLAYLIST);
    return true;

  case CONTEXT_BUTTON_GOTO_ROOT:
    Update("");
    return true;

  case CONTEXT_BUTTON_SETTINGS:
    g_windowManager.ActivateWindow(WINDOW_SETTINGS_MYMUSIC);
    return true;
  case CONTEXT_BUTTON_LASTFM_UNBAN_ITEM:
    if (CLastFmManager::GetInstance()->Unban(*item->GetMusicInfoTag()))
    {
      g_directoryCache.ClearDirectory(m_vecItems->GetPath());
      m_vecItems->RemoveDiscCache(GetID());
      Update(m_vecItems->GetPath());
    }
    return true;
  case CONTEXT_BUTTON_LASTFM_UNLOVE_ITEM:
    if (CLastFmManager::GetInstance()->Unlove(*item->GetMusicInfoTag()))
    {
      g_directoryCache.ClearDirectory(m_vecItems->GetPath());
      m_vecItems->RemoveDiscCache(GetID());
      Update(m_vecItems->GetPath());
    }
    return true;
  default:
    break;
  }

  return CGUIMediaWindow::OnContextButton(itemNumber, button);
}
Пример #26
0
void CAnnouncementManager::Announce(AnnouncementFlag flag, const char *sender, const char *message, CFileItemPtr item, CVariant &data)
{
  if (!item.get())
  {
    Announce(flag, sender, message, data);
    return;
  }

  // Extract db id of item
  CVariant object = data.isNull() || data.isObject() ? data : CVariant::VariantTypeObject;
  CStdString type;
  int id = 0;
  
  if(item->HasPVRChannelInfoTag())
  {
    const PVR::CPVRChannel *channel = item->GetPVRChannelInfoTag();
    id = channel->ChannelID();
    type = "channel";

    object["item"]["title"] = channel->ChannelName();
    object["item"]["channeltype"] = channel->IsRadio() ? "radio" : "tv";

    if (data.isMember("player") && data["player"].isMember("playerid"))
      object["player"]["playerid"] = channel->IsRadio() ? PLAYLIST_MUSIC : PLAYLIST_VIDEO;
  }
  else if (item->HasVideoInfoTag())
  {
    id = item->GetVideoInfoTag()->m_iDbId;

    // TODO: Can be removed once this is properly handled when starting playback of a file
    if (id <= 0 && !item->GetPath().empty() &&
       (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean()))
    {
      CVideoDatabase videodatabase;
      if (videodatabase.Open())
      {
        CStdString path = item->GetPath();
        CStdString videoInfoTagPath(item->GetVideoInfoTag()->m_strFileNameAndPath);
        if (StringUtils::StartsWith(videoInfoTagPath, "removable://"))
          path = videoInfoTagPath;
        if (videodatabase.LoadVideoInfo(path, *item->GetVideoInfoTag()))
          id = item->GetVideoInfoTag()->m_iDbId;

        videodatabase.Close();
      }
    }

    if (!item->GetVideoInfoTag()->m_type.empty())
      type = item->GetVideoInfoTag()->m_type;
    else
      CVideoDatabase::VideoContentTypeToString((VIDEODB_CONTENT_TYPE)item->GetVideoContentType(), type);

    if (id <= 0)
    {
      // TODO: Can be removed once this is properly handled when starting playback of a file
      item->SetProperty(LOOKUP_PROPERTY, false);

      CStdString title = item->GetVideoInfoTag()->m_strTitle;
      if (title.empty())
        title = item->GetLabel();
      object["item"]["title"] = title;

      switch (item->GetVideoContentType())
      {
      case VIDEODB_CONTENT_MOVIES:
        if (item->GetVideoInfoTag()->m_iYear > 0)
          object["item"]["year"] = item->GetVideoInfoTag()->m_iYear;
        break;
      case VIDEODB_CONTENT_EPISODES:
        if (item->GetVideoInfoTag()->m_iEpisode >= 0)
          object["item"]["episode"] = item->GetVideoInfoTag()->m_iEpisode;
        if (item->GetVideoInfoTag()->m_iSeason >= 0)
          object["item"]["season"] = item->GetVideoInfoTag()->m_iSeason;
        if (!item->GetVideoInfoTag()->m_strShowTitle.empty())
          object["item"]["showtitle"] = item->GetVideoInfoTag()->m_strShowTitle;
        break;
      case VIDEODB_CONTENT_MUSICVIDEOS:
        if (!item->GetVideoInfoTag()->m_strAlbum.empty())
          object["item"]["album"] = item->GetVideoInfoTag()->m_strAlbum;
        if (!item->GetVideoInfoTag()->m_artist.empty())
          object["item"]["artist"] = StringUtils::Join(item->GetVideoInfoTag()->m_artist, " / ");
        break;
      }
    }
  }
  else if (item->HasMusicInfoTag())
  {
    id = item->GetMusicInfoTag()->GetDatabaseId();
    type = MediaTypeSong;

    // TODO: Can be removed once this is properly handled when starting playback of a file
    if (id <= 0 && !item->GetPath().empty() &&
       (!item->HasProperty(LOOKUP_PROPERTY) || item->GetProperty(LOOKUP_PROPERTY).asBoolean()))
    {
      CMusicDatabase musicdatabase;
      if (musicdatabase.Open())
      {
        CSong song;
        if (musicdatabase.GetSongByFileName(item->GetPath(), song, item->m_lStartOffset))
        {
          item->GetMusicInfoTag()->SetSong(song);
          id = item->GetMusicInfoTag()->GetDatabaseId();
        }

        musicdatabase.Close();
      }
    }

    if (id <= 0)
    {
      // TODO: Can be removed once this is properly handled when starting playback of a file
      item->SetProperty(LOOKUP_PROPERTY, false);

      CStdString title = item->GetMusicInfoTag()->GetTitle();
      if (title.empty())
        title = item->GetLabel();
      object["item"]["title"] = title;

      if (item->GetMusicInfoTag()->GetTrackNumber() > 0)
        object["item"]["track"] = item->GetMusicInfoTag()->GetTrackNumber();
      if (!item->GetMusicInfoTag()->GetAlbum().empty())
        object["item"]["album"] = item->GetMusicInfoTag()->GetAlbum();
      if (!item->GetMusicInfoTag()->GetArtist().empty())
        object["item"]["artist"] = item->GetMusicInfoTag()->GetArtist();
    }
  }
  else if (item->IsVideo())
  {
    // video item but has no video info tag.
    type = "movies";
    object["item"]["title"] = item->GetLabel();
  }
  else if (item->HasPictureInfoTag())
  {
    type = "picture";
    object["item"]["file"] = item->GetPath();
  }
  else
    type = "unknown";

  object["item"]["type"] = type;
  if (id > 0)
    object["item"]["id"] = id;

  Announce(flag, sender, message, object);
}
Пример #27
0
/**
 * 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 CStdString& strDrive, int& nAddedToPlaylist, bool bRoot, bool bypassSettings /* = false */, bool startFromBeginning /* = false */)
{
  bool bPlaying(false);
  CFileItemList vecItems;

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

  // Sorting necessary for easier HDDVD handling
  vecItems.Sort(SORT_METHOD_LABEL, 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 )
  {
    CStdString 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() != "..")
      {
        CStdString name = pItem->GetPath();
        URIUtils::RemoveSlashAtEnd(name);
        name = URIUtils::GetFileName(name);

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

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

          g_application.PlayFile(item, false);
          bPlaying = true;
          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 (name.Equals("BDMV") && bAllowVideo
        && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          CFileItem item(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.IsEmpty())
            item.m_lStartOffset = STARTOFFSET_RESUME;

          g_application.PlayFile(item, false);
          bPlaying = true;
          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 (name.Equals("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(SORT_METHOD_LABEL, 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 (name.Equals("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(SORT_METHOD_LABEL, 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(SORT_METHOD_LABEL, 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(SORT_METHOD_SIZE, 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.IsEmpty())
            item.m_lStartOffset = STARTOFFSET_RESUME;

            // get playername
            CStdString 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);
              bPlaying = true;
              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);
          bPlaying = true;
          return true;
        }
				
        // Video CDs can have multiple file formats. First we need to determine which one is used on the CD
        CStdString strExt;
        if (name.Equals("MPEGAV"))
          strExt = ".dat";
        if (name.Equals("MPEG2"))
          strExt = ".mpg";

        // If a file format was extracted we are sure this is a VCD. Autoplay if settings indicate we should.
        if (!strExt.IsEmpty() && bAllowVideo
             && (bypassSettings || CSettings::Get().GetBool("dvds.autorun")))
        {
          CFileItemList items;
          CDirectory::GetDirectory(pItem->GetPath(), items, strExt);
          if (items.Size())
          {
            items.Sort(SORT_METHOD_LABEL, SortOrderAscending);
            g_playlistPlayer.ClearPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Add(PLAYLIST_VIDEO, items);
            g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_VIDEO);
            g_playlistPlayer.Play(0);
            bPlaying = true;
            return true;
          }
        }
        /* Probably want this if/when we add some automedia action dialog...
        else if (pItem->GetPath().Find("PICTURES") != -1 && bAllowPictures
              && (bypassSettings))
        {
          bPlaying = true;
          CStdString strExec;
          strExec.Format("XBMC.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->GetPath(), 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;
        CStdString strExec;
        strExec.Format("XBMC.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;
}
Пример #28
0
void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char *resultname, CFileItemPtr item, const CVariant &parameterObject, const CVariant &validFields, CVariant &result, bool append /* = true */)
{
    CVariant object;
    bool hasFileField = false;
    bool hasThumbnailField = false;

    if (item.get())
    {
        for (unsigned int i = 0; i < validFields.size(); i++)
        {
            CStdString field = validFields[i].asString();

            if (field == "file")
                hasFileField = true;
            if (field == "thumbnail")
                hasThumbnailField = true;
        }

        if (allowFile && hasFileField)
        {
            if (item->HasVideoInfoTag() && !item->GetVideoInfoTag()->GetPath().IsEmpty())
                object["file"] = item->GetVideoInfoTag()->GetPath().c_str();
            if (item->HasMusicInfoTag() && !item->GetMusicInfoTag()->GetURL().IsEmpty())
                object["file"] = item->GetMusicInfoTag()->GetURL().c_str();

            if (!object.isMember("file"))
                object["file"] = item->GetPath().c_str();
        }

        if (ID)
        {
            if (stricmp(ID, "genreid") == 0)
            {
                CStdString genre = item->GetPath();
                genre.TrimRight('/');
                object[ID] = atoi(genre.c_str());
            }
            else if (item->HasMusicInfoTag() && item->GetMusicInfoTag()->GetDatabaseId() > 0)
                object[ID] = (int)item->GetMusicInfoTag()->GetDatabaseId();
            else if (item->HasVideoInfoTag() && item->GetVideoInfoTag()->m_iDbId > 0)
                object[ID] = item->GetVideoInfoTag()->m_iDbId;

            if (stricmp(ID, "id") == 0)
            {
                if (item->HasMusicInfoTag())
                {
                    if (item->m_bIsFolder && item->IsAlbum())
                        object["type"] = "album";
                    else
                        object["type"] = "song";
                }
                else if (item->HasVideoInfoTag())
                {
                    switch (item->GetVideoContentType())
                    {
                    case VIDEODB_CONTENT_EPISODES:
                        object["type"] = "episode";
                        break;

                    case VIDEODB_CONTENT_MUSICVIDEOS:
                        object["type"] = "musicvideo";
                        break;

                    case VIDEODB_CONTENT_MOVIES:
                        object["type"] = "movie";
                        break;

                    default:
                        break;
                    }
                }
                else if (item->HasPictureInfoTag())
                    object["type"] = "picture";

                if (!object.isMember("type"))
                    object["type"] = "unknown";
            }
        }

        if (hasThumbnailField)
        {
            if (item->HasThumbnail())
                object["thumbnail"] = item->GetThumbnailImage().c_str();
            else if (item->HasVideoInfoTag())
            {
                CStdString strPath, strFileName;
                URIUtils::Split(item->GetCachedVideoThumb(), strPath, strFileName);
                CStdString cachedThumb = strPath + "auto-" + strFileName;

                if (CFile::Exists(cachedThumb))
                    object["thumbnail"] = cachedThumb;
            }
            else if (item->HasPictureInfoTag())
            {
                CStdString thumb = CTextureCache::Get().CheckAndCacheImage(CTextureCache::GetWrappedThumbURL(item->GetPath()));
                if (!thumb.empty())
                    object["thumbnail"] = thumb;
            }

            if (!object.isMember("thumbnail"))
                object["thumbnail"] = "";
        }

        if (item->HasVideoInfoTag())
            FillDetails(item->GetVideoInfoTag(), item, validFields, object);
        if (item->HasMusicInfoTag())
            FillDetails(item->GetMusicInfoTag(), item, validFields, object);
        if (item->HasPictureInfoTag())
            FillDetails(item->GetPictureInfoTag(), item, validFields, object);

        object["label"] = item->GetLabel().c_str();
    }
    else
        object = CVariant(CVariant::VariantTypeNull);

    if (resultname)
    {
        if (append)
            result[resultname].append(object);
        else
            result[resultname] = object;
    }
}
Пример #29
0
bool CGUIDialogVideoInfo::OnMessage(CGUIMessage& message)
{
  switch ( message.GetMessage() )
  {
  case GUI_MSG_WINDOW_DEINIT:
    {
      ClearCastList();
    }
    break;

  case GUI_MSG_WINDOW_INIT:
    {
      m_dlgProgress = (CGUIDialogProgress*)g_windowManager.GetWindow(WINDOW_DIALOG_PROGRESS);

      m_bRefresh = false;
      m_bRefreshAll = true;
      m_hasUpdatedThumb = false;

      CGUIDialog::OnMessage(message);
      m_bViewReview = true;

      CVideoDatabase database;
      ADDON::ScraperPtr scraper;

      if(database.Open())
      {
        scraper = database.GetScraperForPath(m_movieItem->GetVideoInfoTag()->GetPath());
        database.Close();
      }

      CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_REFRESH, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Left(2).Equals("xx") && scraper);
      CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_THUMB, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin"));

      VIDEODB_CONTENT_TYPE type = (VIDEODB_CONTENT_TYPE)m_movieItem->GetVideoContentType();
      if (type == VIDEODB_CONTENT_TVSHOWS || type == VIDEODB_CONTENT_MOVIES)
        CONTROL_ENABLE_ON_CONDITION(CONTROL_BTN_GET_FANART, (g_settings.GetCurrentProfile().canWriteDatabases() || g_passwordManager.bMasterUser) && !m_movieItem->GetVideoInfoTag()->m_strIMDBNumber.Mid(2).Equals("plugin"));
      else
        CONTROL_DISABLE(CONTROL_BTN_GET_FANART);

      Update();
      return true;
    }
    break;


  case GUI_MSG_CLICKED:
    {
      int iControl = message.GetSenderId();
      if (iControl == CONTROL_BTN_REFRESH)
      {
        if (m_movieItem->GetVideoInfoTag()->m_iSeason < 0 && !m_movieItem->GetVideoInfoTag()->m_strShowTitle.IsEmpty()) // tv show
        {
          bool bCanceled=false;
          if (CGUIDialogYesNo::ShowAndGetInput(20377,20378,-1,-1,bCanceled))
          {
            m_bRefreshAll = true;
            CVideoDatabase db;
            if (db.Open())
            {
              db.SetPathHash(m_movieItem->GetVideoInfoTag()->m_strPath,"");
              db.Close();
            }
          }
          else
            m_bRefreshAll = false;

          if (bCanceled)
            return false;
        }
        m_bRefresh = true;
        Close();
        return true;
      }
      else if (iControl == CONTROL_BTN_TRACKS)
      {
        m_bViewReview = !m_bViewReview;
        Update();
      }
      else if (iControl == CONTROL_BTN_PLAY)
      {
        Play();
      }
      else if (iControl == CONTROL_BTN_RESUME)
      {
        Play(true);
      }
      else if (iControl == CONTROL_BTN_GET_THUMB)
      {
        OnGetThumb();
      }
      else if (iControl == CONTROL_BTN_PLAY_TRAILER)
      {
        PlayTrailer();
      }
      else if (iControl == CONTROL_BTN_GET_FANART)
      {
        OnGetFanart();
      }
      else if (iControl == CONTROL_BTN_DIRECTOR)
      {
        CStdString strDirector = StringUtils::Join(m_movieItem->GetVideoInfoTag()->m_director, g_advancedSettings.m_videoItemSeparator);
        OnSearch(strDirector);
      }
      else if (iControl == CONTROL_LIST)
      {
        int iAction = message.GetParam1();
        if (ACTION_SELECT_ITEM == iAction || ACTION_MOUSE_LEFT_CLICK == iAction)
        {
          CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), iControl);
          OnMessage(msg);
          int iItem = msg.GetParam1();
          if (iItem < 0 || iItem >= m_castList->Size())
            break;
          CStdString strItem = m_castList->Get(iItem)->GetLabel();
          CStdString strFind;
          strFind.Format(" %s ",g_localizeStrings.Get(20347));
          int iPos = strItem.Find(strFind);
          if (iPos == -1)
            iPos = strItem.size();
          CStdString tmp = strItem.Left(iPos);
          OnSearch(tmp);
        }
      }
    }
    break;
  case GUI_MSG_NOTIFY_ALL:
    {
      if (IsActive() && message.GetParam1() == GUI_MSG_UPDATE_ITEM && message.GetItem())
      {
        CFileItemPtr item = boost::static_pointer_cast<CFileItem>(message.GetItem());
        if (item && m_movieItem->GetPath().Equals(item->GetPath()))
        { // Just copy over the stream details and the thumb if we don't already have one
          if (!m_movieItem->HasThumbnail())
            m_movieItem->SetThumbnailImage(item->GetThumbnailImage());
          m_movieItem->GetVideoInfoTag()->m_streamDetails = item->GetVideoInfoTag()->m_streamDetails;
        }
        return true;
      }
    }
  }

  return CGUIDialog::OnMessage(message);
}
Пример #30
0
bool Addon_music_spotify::GetContextButtons(CFileItemPtr& item,
		CContextButtons &buttons) {
	if (isReady()) {
		CURL url(item->GetPath());
		CStdString uri = url.GetFileNameWithoutPath();
		//the path will look something like this "musicdb://2/spotify:artist:0LcJLqbBmaGUft1e9Mm8HV/-1/"
		//if we are trying to show all tracks for a spotify artist, we cant use the params becouse they are only integers.

		if (uri.Left(13).Equals("spotify:album")) {
			uri = uri.Left(uri.Find('#'));
			sp_link *spLink = sp_link_create_from_string(uri);
			sp_album *spAlbum = sp_link_as_album(spLink);
			SxAlbum* salbum = AlbumStore::getInstance()->getAlbum(spAlbum, true);
			if (salbum) {
				buttons.Add(
						CONTEXT_BUTTON_SPOTIFY_TOGGLE_STAR_ALBUM,
						salbum->isStarred() ?
								Settings::getInstance()->getUnstarAlbumString() :
								Settings::getInstance()->getStarAlbumString());
				AlbumStore::getInstance()->removeAlbum(salbum);
				buttons.Add(CONTEXT_BUTTON_SPOTIFY_BROWSE_ARTIST,
						Settings::getInstance()->getBrowseArtistString());
			}
			sp_link_release(spLink);
			sp_album_release(spAlbum);
		} else if (uri.Left(13).Equals("spotify:track")) {
			uri = uri.Left(uri.Find('.'));
			Logger::printOut(uri);
			sp_link *spLink = sp_link_create_from_string(uri);
			sp_track* spTrack = sp_link_as_track(spLink);
			buttons.Add(
					CONTEXT_BUTTON_SPOTIFY_TOGGLE_STAR_TRACK,
					sp_track_is_starred(Session::getInstance()->getSpSession(), spTrack) ?
							Settings::getInstance()->getUnstarTrackString() :
							Settings::getInstance()->getStarTrackString());
			buttons.Add(CONTEXT_BUTTON_SPOTIFY_BROWSE_ALBUM,
					Settings::getInstance()->getBrowseAlbumString());
			buttons.Add(CONTEXT_BUTTON_SPOTIFY_BROWSE_ARTIST,
					Settings::getInstance()->getBrowseArtistString());

			//this is unstable as it is now... find a solution later

			SxAlbum* salbum = AlbumStore::getInstance()->getAlbum(
					sp_track_album(spTrack), true);
			if (salbum) {
				while (!Session::getInstance()->lock())
					;
				while (!salbum->isLoaded()) {
					Session::getInstance()->processEvents();
				}
				Session::getInstance()->unlock();
				buttons.Add(
						CONTEXT_BUTTON_SPOTIFY_TOGGLE_STAR_ALBUM,
						salbum->isStarred() ?
								Settings::getInstance()->getUnstarAlbumString() :
								Settings::getInstance()->getStarAlbumString());
				AlbumStore::getInstance()->removeAlbum(salbum);
			}

			sp_track_release(spTrack);
			sp_link_release(spLink);
		}
	}
	return true;
}