Merge pull request #3819 from arnova/subtitles_for_stacks
[vuplus_xbmc] / xbmc / video / dialogs / GUIDialogSubtitles.cpp
index 81f52b1..1be5b6b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *      Copyright (C) 2005-2013 Team XBMC
- *      http://www.xbmc.org
+ *      http://xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -30,6 +30,8 @@
 #include "filesystem/PluginDirectory.h"
 #include "filesystem/SpecialProtocol.h"
 #include "guilib/GUIImage.h"
+#include "guilib/GUIKeyboardFactory.h"
+#include "guilib/Key.h"
 #include "settings/MediaSettings.h"
 #include "settings/Settings.h"
 #include "settings/VideoSettings.h"
@@ -41,6 +43,7 @@
 #include "utils/URIUtils.h"
 #include "URL.h"
 #include "Util.h"
+#include "video/VideoDatabase.h"
 
 using namespace ADDON;
 using namespace XFILE;
@@ -51,6 +54,7 @@ using namespace XFILE;
 #define CONTROL_SUBSEXIST            130
 #define CONTROL_SUBSTATUS            140
 #define CONTROL_SERVICELIST          150
+#define CONTROL_MANUALSEARCH         160
 
 /*! \brief simple job to retrieve a directory and store a string (language)
  */
@@ -111,7 +115,9 @@ CGUIDialogSubtitles::~CGUIDialogSubtitles(void)
 
 bool CGUIDialogSubtitles::OnMessage(CGUIMessage& message)
 {
-  if  (message.GetMessage() == GUI_MSG_CLICKED)
+  if  (message.GetMessage() == GUI_MSG_CLICKED &&
+       (message.GetParam1() == ACTION_SELECT_ITEM ||
+        message.GetParam1() == ACTION_MOUSE_LEFT_CLICK))
   {
     int iControl = message.GetSenderId();
 
@@ -137,6 +143,15 @@ bool CGUIDialogSubtitles::OnMessage(CGUIMessage& message)
 
       return true;
     }
+    else if (iControl == CONTROL_MANUALSEARCH)
+    {
+      //manual search
+      if (CGUIKeyboardFactory::ShowAndGetInput(m_strManualSearch, g_localizeStrings.Get(24121), true))
+      {
+        Search(m_strManualSearch);
+        return true;
+      }
+    }
   }
   else if (message.GetMessage() == GUI_MSG_WINDOW_DEINIT)
   {
@@ -176,7 +191,7 @@ void CGUIDialogSubtitles::Process(unsigned int currentTime, CDirtyRegionList &di
     std::string status;
     CFileItemList subs;
     {
-      CSingleLock lock(m_section);
+      CSingleLock lock(m_critsection);
       status = m_status;
       subs.Assign(*m_subtitles);
     }
@@ -188,10 +203,19 @@ void CGUIDialogSubtitles::Process(unsigned int currentTime, CDirtyRegionList &di
       OnMessage(message);
       m_updateSubsList = false;
     }
-
-    if (!m_subtitles->IsEmpty() && !GetFocusedControl())
-    { // set focus to the list
-      CGUIMessage msg(GUI_MSG_SETFOCUS, GetID(), CONTROL_SUBLIST);
+    
+    int control = GetFocusedControlID();
+    // nothing has focus
+    if (!control)
+    {
+      CGUIMessage msg(GUI_MSG_SETFOCUS, GetID(), m_subtitles->IsEmpty() ?
+                      CONTROL_SERVICELIST : CONTROL_SUBLIST);
+      OnMessage(msg);
+    }
+    // subs list is focused but we have no subs
+    else if (control == CONTROL_SUBLIST && m_subtitles->IsEmpty())
+    {
+      CGUIMessage msg(GUI_MSG_SETFOCUS, GetID(), CONTROL_SERVICELIST);
       OnMessage(msg);
     }
   }
@@ -211,18 +235,30 @@ void CGUIDialogSubtitles::FillServices()
     return;
   }
 
+  std::string defaultService;
+  const CFileItem &item = g_application.CurrentUnstackedItem();
+  if (item.GetVideoContentType() == VIDEODB_CONTENT_TVSHOWS ||
+      item.GetVideoContentType() == VIDEODB_CONTENT_EPISODES)
+    // Set default service for tv shows
+    defaultService = CSettings::Get().GetString("subtitles.tv");
+  else
+    // Set default service for filemode and movies
+    defaultService = CSettings::Get().GetString("subtitles.movie");
+  
+  std::string service = addons.front()->ID();
   for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++)
   {
     CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://", false));
     m_serviceItems->Add(item);
+    if ((*addonIt)->ID() == defaultService)
+      service = (*addonIt)->ID();
   }
 
   // Bind our services to the UI
   CGUIMessage msg(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SERVICELIST, 0, 0, m_serviceItems);
   OnMessage(msg);
 
-  // TODO: Default service support will need to check through the items to find the CFileItem in the loop above.
-  SetService(m_serviceItems->Get(0)->GetProperty("Addon.ID").asString());
+  SetService(service);
 }
 
 bool CGUIDialogSubtitles::SetService(const std::string &service)
@@ -268,7 +304,7 @@ const CFileItemPtr CGUIDialogSubtitles::GetService() const
   return CFileItemPtr();
 }
 
-void CGUIDialogSubtitles::Search()
+void CGUIDialogSubtitles::Search(const std::string &search/*=""*/)
 {
   if (m_currentService.empty())
     return; // no services available
@@ -277,7 +313,13 @@ void CGUIDialogSubtitles::Search()
   ClearSubtitles();
 
   CURL url("plugin://" + m_currentService + "/");
-  url.SetOption("action", "search");
+  if (!search.empty())
+  {
+    url.SetOption("action", "manualsearch");
+    url.SetOption("searchstring", search);
+  }
+  else
+    url.SetOption("action", "search");
 
   const CSetting *setting = CSettings::Get().GetSetting("subtitles.languages");
   if (setting)
@@ -291,7 +333,7 @@ void CGUIDialogSubtitles::OnJobComplete(unsigned int jobID, bool success, CJob *
   const CURL &url             = ((CSubtitlesJob *)job)->GetURL();
   const CFileItemList *items  = ((CSubtitlesJob *)job)->GetItems();
   const std::string &language = ((CSubtitlesJob *)job)->GetLanguage();
-  if (url.GetOption("action") == "search")
+  if (url.GetOption("action") == "search" || url.GetOption("action") == "manualsearch")
     OnSearchComplete(items);
   else
     OnDownloadComplete(items, language);
@@ -300,7 +342,7 @@ void CGUIDialogSubtitles::OnJobComplete(unsigned int jobID, bool success, CJob *
 
 void CGUIDialogSubtitles::OnSearchComplete(const CFileItemList *items)
 {
-  CSingleLock lock(m_section);
+  CSingleLock lock(m_critsection);
   m_subtitles->Assign(*items);
   UpdateStatus(SEARCH_COMPLETE);
   m_updateSubsList = true;
@@ -309,7 +351,7 @@ void CGUIDialogSubtitles::OnSearchComplete(const CFileItemList *items)
 
 void CGUIDialogSubtitles::UpdateStatus(STATUS status)
 {
-  CSingleLock lock(m_section);
+  CSingleLock lock(m_critsection);
   std::string label;
   switch (status)
   {
@@ -364,6 +406,8 @@ void CGUIDialogSubtitles::OnDownloadComplete(const CFileItemList *items, const s
 
   CStdString strFileName;
   CStdString strDestPath;
+#if 0
+  // TODO: Code to download all subtitles for all stack items in one run
   if (g_application.CurrentFileItem().IsStack())
   {
     for (int i = 0; i < items->Size(); i++)
@@ -372,17 +416,22 @@ void CGUIDialogSubtitles::OnDownloadComplete(const CFileItemList *items, const s
 //    CLog::Log(LOGDEBUG, "Stack Subs [%s} Found", vecItems[i]->GetLabel().c_str());
     }
   }
-  else if (StringUtils::StartsWith(g_application.CurrentFile(), "http://"))
+#endif
+
+  // Get (unstacked) path
+  const CStdString &strCurrentFile = g_application.CurrentUnstackedItem().GetPath();
+
+  if (StringUtils::StartsWith(strCurrentFile, "http://"))
   {
     strFileName = "TemporarySubs";
     strDestPath = "special://temp/";
   }
   else
   {
-    strFileName = URIUtils::GetFileName(g_application.CurrentFile());
+    strFileName = URIUtils::GetFileName(strCurrentFile);
     if (CSettings::Get().GetBool("subtitles.savetomoviefolder"))
     {
-      strDestPath = URIUtils::GetDirectory(g_application.CurrentFile());
+      strDestPath = URIUtils::GetDirectory(strCurrentFile);
       if (!CUtil::SupportsWriteFileOperations(strDestPath))
         strDestPath.clear();
     }
@@ -407,6 +456,19 @@ void CGUIDialogSubtitles::OnDownloadComplete(const CFileItemList *items, const s
 
   // and copy the file across
   CFile::Cache(strUrl, strSubPath);
+
+  // for ".sub" subtitles we check if ".idx" counterpart exists and copy that as well
+  if (strSubExt.Equals(".sub"))
+  {
+    strUrl = URIUtils::ReplaceExtension(strUrl, ".idx");
+    if(CFile::Exists(strUrl))
+    {
+      CStdString strSubNameIdx = StringUtils::Format("%s.%s.idx", strFileName.c_str(), strSubLang.c_str());
+      strSubPath = URIUtils::AddFileToFolder(strDestPath, strSubNameIdx);
+      CFile::Cache(strUrl, strSubPath);
+    }
+  }
+
   SetSubtitles(strSubPath);
   // Close the window
   Close();
@@ -416,7 +478,7 @@ void CGUIDialogSubtitles::ClearSubtitles()
 {
   CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_SUBLIST);
   OnMessage(msg);
-  CSingleLock lock(m_section);
+  CSingleLock lock(m_critsection);
   m_subtitles->Clear();
 }