[subtitles] adds new dialog for subtitles to core.
authorJonathan Marshall <jmarshall@xbmc.org>
Sun, 3 Nov 2013 00:08:16 +0000 (13:08 +1300)
committerJonathan Marshall <jmarshall@xbmc.org>
Tue, 12 Nov 2013 08:49:47 +0000 (21:49 +1300)
XBMC.xcodeproj/project.pbxproj
language/English/strings.po
project/VS2010Express/XBMC.vcxproj
project/VS2010Express/XBMC.vcxproj.filters
system/settings/settings.xml
xbmc/Application.cpp
xbmc/guilib/WindowIDs.h
xbmc/input/ButtonTranslator.cpp
xbmc/video/dialogs/GUIDialogSubtitles.cpp [new file with mode: 0644]
xbmc/video/dialogs/GUIDialogSubtitles.h [new file with mode: 0644]
xbmc/video/dialogs/Makefile

index 15f14ed..1310889 100644 (file)
                7C4458BD161E203800A905F6 /* Screenshot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4458BB161E203800A905F6 /* Screenshot.cpp */; };
                7C45DBE910F325C400D4BBF3 /* DAVDirectory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C45DBE710F325C400D4BBF3 /* DAVDirectory.cpp */; };
                7C4705AE12EF584C00369E51 /* AddonInstaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4705AC12EF584C00369E51 /* AddonInstaller.cpp */; };
+               7C4E6F721829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */; };
+               7C4E6F731829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */; };
+               7C4E6F741829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */; };
                7C5608C70F1754930056433A /* ExternalPlayer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C5608C40F1754930056433A /* ExternalPlayer.cpp */; };
                7C62F24210505BC7002AD2C1 /* Bookmark.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C62F24010505BC7002AD2C1 /* Bookmark.cpp */; };
                7C62F45E1057A62D002AD2C1 /* DirectoryNodeSingles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C62F45C1057A62D002AD2C1 /* DirectoryNodeSingles.cpp */; };
                7C45DBE810F325C400D4BBF3 /* DAVDirectory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DAVDirectory.h; sourceTree = "<group>"; };
                7C4705AC12EF584C00369E51 /* AddonInstaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AddonInstaller.cpp; sourceTree = "<group>"; };
                7C4705AD12EF584C00369E51 /* AddonInstaller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddonInstaller.h; sourceTree = "<group>"; };
+               7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GUIDialogSubtitles.cpp; sourceTree = "<group>"; };
+               7C4E6F711829AA9700F1068F /* GUIDialogSubtitles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GUIDialogSubtitles.h; sourceTree = "<group>"; };
                7C5608C40F1754930056433A /* ExternalPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExternalPlayer.cpp; sourceTree = "<group>"; };
                7C5608C50F1754930056433A /* ExternalPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExternalPlayer.h; sourceTree = "<group>"; };
                7C62F24010505BC7002AD2C1 /* Bookmark.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Bookmark.cpp; sourceTree = "<group>"; };
                                E38E17AB0D25F9FA00618676 /* GUIDialogFileStacking.h */,
                                886328150E07B37200BB3DAB /* GUIDialogFullScreenInfo.cpp */,
                                886328160E07B37200BB3DAB /* GUIDialogFullScreenInfo.h */,
+                               7C4E6F701829AA9700F1068F /* GUIDialogSubtitles.cpp */,
+                               7C4E6F711829AA9700F1068F /* GUIDialogSubtitles.h */,
                                F5E55B65107412DE006E788A /* GUIDialogTeletext.cpp */,
                                F5E55B64107412DE006E788A /* GUIDialogTeletext.h */,
                                E38E17E00D25F9FA00618676 /* GUIDialogVideoBookmarks.cpp */,
                                7C7BCDC517727951004842FB /* IListProvider.cpp in Sources */,
                                7C7BCDC717727951004842FB /* StaticProvider.cpp in Sources */,
                                7C8FC6EE1829A4580045153D /* DirectoryProvider.cpp in Sources */,
+                               7C4E6F721829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                7C7BCDCB17727951004842FB /* IListProvider.cpp in Sources */,
                                7C7BCDCD17727952004842FB /* StaticProvider.cpp in Sources */,
                                7C8FC6F01829A4580045153D /* DirectoryProvider.cpp in Sources */,
+                               7C4E6F741829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                7C7BCDC817727951004842FB /* IListProvider.cpp in Sources */,
                                7C7BCDCA17727951004842FB /* StaticProvider.cpp in Sources */,
                                7C8FC6EF1829A4580045153D /* DirectoryProvider.cpp in Sources */,
+                               7C4E6F731829AA9700F1068F /* GUIDialogSubtitles.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 5e69781..f5eedae 100755 (executable)
@@ -11991,7 +11991,62 @@ msgctxt "#24104"
 msgid "Add-on is incompatible due to unmet dependencies."
 msgstr ""
 
-#empty strings from id 24105 to 24999
+#: system/settings/settings.xml
+msgctxt "#24105"
+msgid "Pause when searching for subtitles"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#24106"
+msgid "If not saved to movie folder subtitles will be downloaded to custom subtitle folder"
+msgstr ""
+
+#: xbmc/dialogs/GUIDialogSubtitles.cpp 
+msgctxt "#24107"
+msgid "Searching for subtitles ..."
+msgstr ""
+
+#: xbmc/dialogs/GUIDialogSubtitles.cpp
+msgctxt "#24108"
+msgid "%d subtitles found"
+msgstr ""
+
+#: xbmc/dialogs/GUIDialogSubtitles.cpp
+msgctxt "#24109"
+msgid "No subtitles found"
+msgstr ""
+
+#: xbmc/dialogs/GUIDialogSubtitles.cpp
+msgctxt "#24110"
+msgid "Downloading subtitles ..."
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#24111"
+msgid "Languages to download subtitles for"
+msgstr ""
+
+#: system/settings/settings.xml
+msgctxt "#24112"
+msgid "Set languages to use when searching for subtitles. Not all subtitle services will use all languages."
+msgstr ""
+
+#: xbmc/dialogs/GUIDialogSubtitles.cpp
+msgctxt "#24113"
+msgid "Failed to download subtitle"
+msgstr ""
+
+#: xbmc/dialogs/GUIDialogSubtitles.cpp
+msgctxt "#24114"
+msgid "No subtitle services installed"
+msgstr ""
+
+#: system/settings/settings.xml 
+msgctxt "#24115"
+msgid "Save subtitles to movie folder"
+msgstr ""
+
+#empty strings from id 24116 to 24999
 
 msgctxt "#25000"
 msgid "Notifications"
index 6f6d7b1..b1f8cc3 100644 (file)
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogAudioSubtitleSettings.cpp" />
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogFileStacking.cpp" />
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogFullScreenInfo.cpp" />
+    <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogSubtitles.cpp" />
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogTeletext.cpp" />
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogVideoBookmarks.cpp" />
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogVideoInfo.cpp" />
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogAudioSubtitleSettings.h" />
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogFileStacking.h" />
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogFullScreenInfo.h" />
+    <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogSubtitles.h" />
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogTeletext.h" />
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogVideoBookmarks.h" />
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogVideoInfo.h" />
index 65b0c0f..67e3150 100644 (file)
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogFullScreenInfo.cpp">
       <Filter>video\dialogs</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogSubtitles.cpp">
+      <Filter>video\dialogs</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\xbmc\video\dialogs\GUIDialogTeletext.cpp">
       <Filter>video\dialogs</Filter>
     </ClCompile>
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogFullScreenInfo.h">
       <Filter>video\dialogs</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogSubtitles.h">
+      <Filter>video\dialogs</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\xbmc\video\dialogs\GUIDialogTeletext.h">
       <Filter>video\dialogs</Filter>
     </ClInclude>
index 41d9a6a..b930051 100644 (file)
         </setting>
       </group>
       <group id="2">
+        <setting id="subtitles.savetomoviefolder" type="boolean" label="24115" help="24106">
+          <level>1</level>
+          <default>true</default>
+          <control type="toggle" />
+        </setting>
+        <setting id="subtitles.pauseonsearch" type="boolean" label="24105" help="">
+          <level>1</level>
+          <default>true</default>
+          <control type="toggle" />
+        </setting>
+        <setting id="subtitles.languages" type="list[string]" label="24111" help="24112">
+          <level>1</level>
+          <default>English</default>
+          <constraints>
+            <options>languages</options>
+            <delimiter>,</delimiter>
+            <minimum>1</minimum>
+          </constraints>
+          <control type="list" format="string">
+            <multiselect>true</multiselect>
+          </control>
+        </setting>
         <setting id="subtitles.custompath" type="path" label="21366" help="36191">
           <level>1</level>
           <default></default>
index 2a75dc9..ebcea40 100644 (file)
 #include "dialogs/GUIDialogCache.h"
 #include "dialogs/GUIDialogPlayEject.h"
 #include "dialogs/GUIDialogMediaFilter.h"
+#include "video/dialogs/GUIDialogSubtitles.h"
 #include "utils/XMLUtils.h"
 #include "addons/AddonInstaller.h"
 
@@ -1346,6 +1347,7 @@ bool CApplication::Initialize()
     g_windowManager.Add(new CGUIDialogPeripheralSettings);
     
     g_windowManager.Add(new CGUIDialogMediaFilter);
+    g_windowManager.Add(new CGUIDialogSubtitles);
 
     g_windowManager.Add(new CGUIWindowMusicPlayList);
     g_windowManager.Add(new CGUIWindowMusicSongs);
@@ -3318,6 +3320,7 @@ bool CApplication::Cleanup()
     g_windowManager.Delete(WINDOW_DIALOG_ACCESS_POINTS);
     g_windowManager.Delete(WINDOW_DIALOG_SLIDER);
     g_windowManager.Delete(WINDOW_DIALOG_MEDIA_FILTER);
+    g_windowManager.Delete(WINDOW_DIALOG_SUBTITLES);
 
     /* Delete PVR related windows and dialogs */
     g_windowManager.Delete(WINDOW_PVR);
index e59c1c1..68a8e9b 100644 (file)
 #define WINDOW_DIALOG_PERIPHERAL_SETTINGS 10150
 #define WINDOW_DIALOG_EXT_PROGRESS        10151
 #define WINDOW_DIALOG_MEDIA_FILTER        10152
+#define WINDOW_DIALOG_SUBTITLES           10153
 
 #define WINDOW_MUSIC_PLAYLIST             10500
 #define WINDOW_MUSIC_FILES                10501
index 46df3d5..627e52b 100644 (file)
@@ -354,6 +354,7 @@ static const ActionMapping windows[] =
         {"karaokelargeselector"     , WINDOW_DIALOG_KARAOKE_SELECTOR},
         {"sliderdialog"             , WINDOW_DIALOG_SLIDER},
         {"addoninformation"         , WINDOW_DIALOG_ADDON_INFO},
+        {"subtitlesearch"           , WINDOW_DIALOG_SUBTITLES},
         {"musicplaylist"            , WINDOW_MUSIC_PLAYLIST},
         {"musicfiles"               , WINDOW_MUSIC_FILES},
         {"musiclibrary"             , WINDOW_MUSIC_NAV},
diff --git a/xbmc/video/dialogs/GUIDialogSubtitles.cpp b/xbmc/video/dialogs/GUIDialogSubtitles.cpp
new file mode 100644 (file)
index 0000000..329a3f1
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://www.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
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "system.h"
+#include "GUIUserMessages.h"
+#include "Application.h"
+#include "GUIDialogSubtitles.h"
+#include "addons/AddonManager.h"
+#include "cores/IPlayer.h"
+#include "dialogs/GUIDialogKaiToast.h"
+#include "filesystem/AddonsDirectory.h"
+#include "filesystem/File.h"
+#include "filesystem/PluginDirectory.h"
+#include "filesystem/SpecialProtocol.h"
+#include "guilib/GUIImage.h"
+#include "settings/MediaSettings.h"
+#include "settings/Settings.h"
+#include "settings/SettingsManager.h"
+#include "settings/VideoSettings.h"
+#include "utils/JobManager.h"
+#include "utils/LangCodeExpander.h"
+#include "utils/log.h"
+#include "utils/StringUtils.h"
+#include "utils/URIUtils.h"
+#include "URL.h"
+#include "Util.h"
+
+using namespace ADDON;
+using namespace XFILE;
+
+#define CONTROL_NAMELABEL            100
+#define CONTROL_NAMELOGO             110
+#define CONTROL_SUBLIST              120
+#define CONTROL_SUBSEXIST            130
+#define CONTROL_SUBSTATUS            140
+#define CONTROL_SERVICELIST          150
+
+/*! \brief simple job to retrieve a directory and store a string (language)
+ */
+class CSubtitlesJob: public CJob
+{
+public:
+  CSubtitlesJob(const CURL &url, const std::string &language) : m_url(url), m_language(language)
+  {
+    m_items = new CFileItemList;
+  }
+  virtual ~CSubtitlesJob()
+  {
+    delete m_items;
+  }
+  virtual bool DoWork()
+  {
+    CDirectory::GetDirectory(m_url.Get(), *m_items);
+    return true;
+  }
+  virtual bool operator==(const CJob *job) const
+  {
+    if (strcmp(job->GetType(),GetType()) == 0)
+    {
+      const CSubtitlesJob* rjob = dynamic_cast<const CSubtitlesJob*>(job);
+      if (rjob)
+      {
+        return m_url.Get() == rjob->m_url.Get() &&
+               m_language == rjob->m_language;
+      }
+    }
+    return false;
+  }
+  const CFileItemList *GetItems() const { return m_items; }
+  const CURL &GetURL() const { return m_url; }
+  const std::string &GetLanguage() const { return m_language; }
+private:
+  CURL           m_url;
+  CFileItemList *m_items;
+  std::string    m_language;
+};
+
+CGUIDialogSubtitles::CGUIDialogSubtitles(void)
+    : CGUIDialog(WINDOW_DIALOG_SUBTITLES, "DialogSubtitles.xml")
+{
+  m_loadType  = KEEP_IN_MEMORY;
+  m_subtitles = new CFileItemList;
+  m_serviceItems = new CFileItemList;
+  m_pausedOnRun = false;
+  m_updateSubsList = false;
+}
+
+CGUIDialogSubtitles::~CGUIDialogSubtitles(void)
+{
+  CancelJobs();
+  delete m_subtitles;
+  delete m_serviceItems;
+}
+
+bool CGUIDialogSubtitles::OnMessage(CGUIMessage& message)
+{
+  if  (message.GetMessage() == GUI_MSG_CLICKED)
+  {
+    int iControl = message.GetSenderId();
+
+    if (iControl == CONTROL_SUBLIST)
+    {
+      CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_SUBLIST);
+      OnMessage(msg);
+
+      int item = msg.GetParam1();
+      if (item >= 0 && item < m_subtitles->Size())
+        Download(*m_subtitles->Get(item));
+      return true;
+    }
+    else if (iControl == CONTROL_SERVICELIST)
+    {
+      CGUIMessage msg(GUI_MSG_ITEM_SELECTED, GetID(), CONTROL_SERVICELIST);
+      OnMessage(msg);
+
+      int item = msg.GetParam1();
+      if (item >= 0 && item < m_serviceItems->Size() &&
+          SetService(m_serviceItems->Get(item)->GetProperty("Addon.ID").asString()))
+        Search();
+
+      return true;
+    }
+  }
+  else if (message.GetMessage() == GUI_MSG_WINDOW_DEINIT)
+  {
+    // Resume the video if the user has requested it
+    if (g_application.m_pPlayer->IsPaused() && m_pausedOnRun)
+      g_application.m_pPlayer->Pause();
+
+    CGUIDialog::OnMessage(message);
+
+    ClearSubtitles();
+    ClearServices();
+    return true;
+  }
+  return CGUIDialog::OnMessage(message);
+}
+
+void CGUIDialogSubtitles::OnInitWindow()
+{
+  // Pause the video if the user has requested it
+  m_pausedOnRun = false;
+  if (CSettings::Get().GetBool("subtitles.pauseonsearch") && !g_application.m_pPlayer->IsPaused())
+  {
+    g_application.m_pPlayer->Pause();
+    m_pausedOnRun = true;
+  }
+
+  FillServices();
+  CGUIWindow::OnInitWindow();
+  Search();
+}
+
+void CGUIDialogSubtitles::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
+{
+  if (m_bInvalidated)
+  {
+    // take copies of our variables to ensure we don't hold the lock for long.
+    std::string status;
+    CFileItemList subs;
+    {
+      CSingleLock lock(m_section);
+      status = m_status;
+      subs.Assign(*m_subtitles);
+    }
+    SET_CONTROL_LABEL(CONTROL_SUBSTATUS, status);
+
+    if (m_updateSubsList)
+    {
+      CGUIMessage message(GUI_MSG_LABEL_BIND, GetID(), CONTROL_SUBLIST, 0, 0, &subs);
+      OnMessage(message);
+      m_updateSubsList = false;
+    }
+
+    if (!m_subtitles->IsEmpty() && !GetFocusedControl())
+    { // set focus to the list
+      CGUIMessage msg(GUI_MSG_SETFOCUS, GetID(), CONTROL_SUBLIST);
+      OnMessage(msg);
+    }
+  }
+  CGUIDialog::Process(currentTime, dirtyregions);
+}
+
+void CGUIDialogSubtitles::FillServices()
+{
+  ClearServices();
+
+  VECADDONS addons;
+  ADDON::CAddonMgr::Get().GetAddons(ADDON_SUBTITLE_MODULE, addons, true);
+
+  if (addons.empty())
+  {
+    UpdateStatus(NO_SERVICES);
+    return;
+  }
+
+  for (VECADDONS::const_iterator addonIt = addons.begin(); addonIt != addons.end(); addonIt++)
+  {
+    CFileItemPtr item(CAddonsDirectory::FileItemFromAddon(*addonIt, "plugin://", false));
+    m_serviceItems->Add(item);
+  }
+
+  // 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());
+}
+
+bool CGUIDialogSubtitles::SetService(const std::string &service)
+{
+  if (service != m_currentService)
+  {
+    m_currentService = service;
+    CLog::Log(LOGDEBUG, "New Service [%s] ", m_currentService.c_str());
+
+    CFileItemPtr currentService = GetService();
+    // highlight this item in the skin
+    for (int i = 0; i < m_serviceItems->Size(); i++)
+    {
+      CFileItemPtr pItem = m_serviceItems->Get(i);
+      pItem->Select(pItem == currentService);
+    }
+
+    SET_CONTROL_LABEL(CONTROL_NAMELABEL, currentService->GetLabel());
+
+    CGUIImage* image = (CGUIImage*)GetControl(CONTROL_NAMELOGO);
+    if (image)
+      image->SetFileName(currentService->GetArt("thumb"));
+
+    if (g_application.m_pPlayer->GetSubtitleCount() == 0)
+      SET_CONTROL_HIDDEN(CONTROL_SUBSEXIST);
+    else
+      SET_CONTROL_VISIBLE(CONTROL_SUBSEXIST);
+
+    return true;
+  }
+  return false;
+}
+
+const CFileItemPtr CGUIDialogSubtitles::GetService() const
+{
+  for (int i = 0; i < m_serviceItems->Size(); i++)
+  {
+    if (m_serviceItems->Get(i)->GetProperty("Addon.ID") == m_currentService)
+      return m_serviceItems->Get(i);
+  }
+  return CFileItemPtr();
+}
+
+void CGUIDialogSubtitles::Search()
+{
+  if (m_currentService.empty())
+    return; // no services available
+
+  UpdateStatus(SEARCHING);
+  ClearSubtitles();
+
+  CURL url("plugin://" + m_currentService + "/");
+  url.SetOption("action", "search");
+
+  const CSetting *setting = CSettings::Get().GetSetting("subtitles.languages");
+  if (setting)
+    url.SetOption("languages", setting->ToString());
+
+  AddJob(new CSubtitlesJob(url, ""));
+}
+
+void CGUIDialogSubtitles::OnJobComplete(unsigned int jobID, bool success, CJob *job)
+{
+  const CURL &url             = ((CSubtitlesJob *)job)->GetURL();
+  const CFileItemList *items  = ((CSubtitlesJob *)job)->GetItems();
+  const std::string &language = ((CSubtitlesJob *)job)->GetLanguage();
+  if (url.GetOption("action") == "search")
+    OnSearchComplete(items);
+  else
+    OnDownloadComplete(items, language);
+  CJobQueue::OnJobComplete(jobID, success, job);
+}
+
+void CGUIDialogSubtitles::OnSearchComplete(const CFileItemList *items)
+{
+  CSingleLock lock(m_section);
+  m_subtitles->Assign(*items);
+  UpdateStatus(SEARCH_COMPLETE);
+  m_updateSubsList = true;
+  SetInvalid();
+}
+
+void CGUIDialogSubtitles::UpdateStatus(STATUS status)
+{
+  CSingleLock lock(m_section);
+  std::string label;
+  switch (status)
+  {
+    case NO_SERVICES:
+      label = g_localizeStrings.Get(24114);
+      break;
+    case SEARCHING:
+      label = g_localizeStrings.Get(24107);
+      break;
+    case SEARCH_COMPLETE:
+      if (!m_subtitles->IsEmpty())
+        label = StringUtils::Format(g_localizeStrings.Get(24108).c_str(), m_subtitles->Size());
+      else
+        label = g_localizeStrings.Get(24109);
+      break;
+    case DOWNLOADING:
+      label = g_localizeStrings.Get(24110);
+      break;
+    default:
+      break;
+  }
+  if (label != m_status)
+  {
+    m_status = label;
+    SetInvalid();
+  }
+}
+
+void CGUIDialogSubtitles::Download(const CFileItem &subtitle)
+{
+  UpdateStatus(DOWNLOADING);
+
+  // subtitle URL should be of the form plugin://<addonid>/?param=foo&param=bar
+  // we just append (if not already present) the action=download parameter.
+  CURL url(subtitle.GetAsUrl());
+  if (url.GetOption("action").empty())
+    url.SetOption("action", "download");
+
+  AddJob(new CSubtitlesJob(url, subtitle.GetLabel()));
+}
+
+void CGUIDialogSubtitles::OnDownloadComplete(const CFileItemList *items, const std::string &language)
+{
+  if (items->IsEmpty())
+  {
+    CFileItemPtr service = GetService();
+    if (service)
+      CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, service->GetLabel(), g_localizeStrings.Get(24113));
+    UpdateStatus(SEARCH_COMPLETE);
+    return;
+  }
+
+  CStdString strFileName;
+  CStdString strDestPath;
+  if (g_application.CurrentFileItem().IsStack())
+  {
+    for (int i = 0; i < items->Size(); i++)
+    {
+//    check for all stack items and match to given subs, item [0] == CD1, item [1] == CD2
+//    CLog::Log(LOGDEBUG, "Stack Subs [%s} Found", vecItems[i]->GetLabel().c_str());
+    }
+  }
+  else if (StringUtils::StartsWith(g_application.CurrentFile(), "http://"))
+  {
+    strFileName = "TemporarySubs";
+    strDestPath = "special://temp/";
+  }
+  else
+  {
+    strFileName = URIUtils::GetFileName(g_application.CurrentFile());
+    if (CSettings::Get().GetBool("subtitles.savetomoviefolder"))
+    {
+      strDestPath = URIUtils::GetDirectory(g_application.CurrentFile());
+      if (!CUtil::SupportsWriteFileOperations(strDestPath))
+        strDestPath.clear();
+    }
+    if (strDestPath.empty())
+    {
+      if (CSpecialProtocol::TranslatePath("special://subtitles").empty())
+        strDestPath = "special://temp";
+      else
+        strDestPath = "special://subtitles";
+    }
+  }
+  // Extract the language and appropriate extension
+  CStdString strSubLang;
+  g_LangCodeExpander.ConvertToTwoCharCode(strSubLang, language);
+  CStdString strUrl = items->Get(0)->GetPath();
+  CStdString strSubExt = URIUtils::GetExtension(strUrl);
+
+  // construct subtitle path
+  URIUtils::RemoveExtension(strFileName);
+  CStdString strSubName;
+  strSubName.Format("%s.%s%s", strFileName.c_str(), strSubLang.c_str(), strSubExt.c_str());
+  CStdString strSubPath = URIUtils::AddFileToFolder(strDestPath, strSubName);
+
+  // and copy the file across
+  CFile::Cache(strUrl, strSubPath);
+  SetSubtitles(strSubPath);
+  // Close the window
+  Close();
+}
+
+void CGUIDialogSubtitles::ClearSubtitles()
+{
+  CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_SUBLIST);
+  OnMessage(msg);
+  CSingleLock lock(m_section);
+  m_subtitles->Clear();
+}
+
+void CGUIDialogSubtitles::ClearServices()
+{
+  CGUIMessage msg(GUI_MSG_LABEL_RESET, GetID(), CONTROL_SERVICELIST);
+  OnMessage(msg);
+  m_serviceItems->Clear();
+  m_currentService.clear();
+}
+
+void CGUIDialogSubtitles::SetSubtitles(const std::string &subtitle)
+{
+  if (g_application.m_pPlayer)
+  {
+    int nStream = g_application.m_pPlayer->AddSubtitle(subtitle);
+    if(nStream >= 0)
+    {
+      g_application.m_pPlayer->SetSubtitle(nStream);
+      g_application.m_pPlayer->SetSubtitleVisible(true);
+      CMediaSettings::Get().GetCurrentVideoSettings().m_SubtitleDelay = 0.0f;
+      g_application.m_pPlayer->SetSubTitleDelay(0);
+    }
+  }
+}
diff --git a/xbmc/video/dialogs/GUIDialogSubtitles.h b/xbmc/video/dialogs/GUIDialogSubtitles.h
new file mode 100644 (file)
index 0000000..3851854
--- /dev/null
@@ -0,0 +1,67 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2013 Team XBMC
+ *      http://www.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
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, see
+ *  <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <string>
+#include "guilib/GUIDialog.h"
+#include "threads/CriticalSection.h"
+#include "utils/JobManager.h"
+
+class CFileItem;
+class CFileItemList;
+
+class CGUIDialogSubtitles : public CGUIDialog, CJobQueue
+{
+public:
+  CGUIDialogSubtitles(void);
+  virtual ~CGUIDialogSubtitles(void);
+  virtual bool OnMessage(CGUIMessage& message);
+  virtual void OnInitWindow();
+
+protected:
+  virtual void Process(unsigned int currentTime, CDirtyRegionList &dirtyregions);
+  virtual void OnJobComplete(unsigned int jobID, bool success, CJob *job);
+
+  bool SetService(const std::string &service);
+  const CFileItemPtr GetService() const;
+  void FillServices();
+  void ClearServices();
+  void ClearSubtitles();
+
+  enum STATUS { NO_SERVICES = 0, SEARCHING, SEARCH_COMPLETE, DOWNLOADING };
+  void UpdateStatus(STATUS status);
+
+  void Search();
+  void OnSearchComplete(const CFileItemList *items);
+
+  void Download(const CFileItem &subtitle);
+  void OnDownloadComplete(const CFileItemList *items, const std::string &language);
+
+  void SetSubtitles(const std::string &subtitle);
+
+  CCriticalSection m_section;
+  CFileItemList* m_subtitles;
+  CFileItemList* m_serviceItems;
+  std::string    m_currentService;
+  std::string    m_status;
+  bool           m_pausedOnRun;
+  bool           m_updateSubsList; ///< true if we need to update our subs list
+};
index b080a2a..2db1835 100644 (file)
@@ -1,6 +1,7 @@
 SRCS=GUIDialogAudioSubtitleSettings.cpp \
      GUIDialogFileStacking.cpp \
      GUIDialogFullScreenInfo.cpp \
+     GUIDialogSubtitles.cpp \
      GUIDialogTeletext.cpp \
      GUIDialogVideoBookmarks.cpp \
      GUIDialogVideoInfo.cpp \