diff options
66 files changed, 563 insertions, 424 deletions
diff --git a/addons/webinterface.default/addon.xml b/addons/webinterface.default/addon.xml index e305b31007..aa662231fa 100644 --- a/addons/webinterface.default/addon.xml +++ b/addons/webinterface.default/addon.xml @@ -5,7 +5,6 @@ name="Default" provider-name="Team-Kodi"> <requires> - <import addon="xbmc.gui" version="4.0.0"/> <import addon="xbmc.json" version="6.0.0"/> </requires> <extension diff --git a/configure.in b/configure.in index 24bb77bb3a..7bcf070a86 100644 --- a/configure.in +++ b/configure.in @@ -1116,8 +1116,27 @@ if test "$use_mysql" = "yes"; then AC_CHECK_LIB([mysqlclient], [main],, AC_MSG_ERROR($missing_library)) fi AC_CHECK_LIB([bluetooth], [hci_devid],, AC_MSG_RESULT([Could not find suitable version of libbluetooth])) -AC_CHECK_LIB([yajl], [main],, AC_MSG_ERROR($missing_library)) -AC_CHECK_LIB([tinyxml], [main],, AC_MSG_ERROR($missing_library)) + +PKG_CHECK_MODULES([TINYXML], [tinyxml >= 2.6.2], + [INCLUDES="$INCLUDES $TINYXML_CFLAGS"; LIBS="$LIBS $TINYXML_LIBS"], + AC_MSG_ERROR("libtinyxml >= 2.6.2 not found")) + +PKG_CHECK_MODULES([YAJL], [yajl >= 2], + [INCLUDES="$INCLUDES $YAJL_CFLAGS"; LIBS="$LIBS $YAJL_LIBS"; YAJL_FOUND="true"], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ +#include <yajl/yajl_version.h> +#if !defined YAJL_MAJOR || YAJL_MAJOR < 2 +#error yajl version < 2; +#endif + ]])],, [AC_MSG_ERROR([libyajl >= 2.0.0 not found])] + )]) + +if test "$YAJL_FOUND" != "true"; then + AC_CHECK_LIB([yajl], [main],, [AC_MSG_ERROR("libyajl >= 2.0.0 not found")]) + AC_CHECK_HEADERS([yajl/yajl_common.h], [AC_MSG_NOTICE(libyajl2 found)], [AC_MSG_ERROR("yajl/yajl_common.h not found")]) +fi + if test "$target_platform" = "target_android" ; then AC_CHECK_LIB([android], [main],, AC_MSG_ERROR($missing_library)) AC_CHECK_LIB([log], [__android_log_vprint],, AC_MSG_ERROR($missing_library)) @@ -1915,11 +1934,6 @@ else fi fi -# yajl version check (yajl_version.h was added in yajl 2.0) -AC_CHECK_HEADERS([yajl/yajl_version.h], [], [ -AC_DEFINE(YAJL_MAJOR, 1, [yajl version 1]) -], []) - # additional internal players case $add_players in *omxplayer*) diff --git a/docs/README.linux b/docs/README.linux index 47a22223ae..a9f1f271e5 100644 --- a/docs/README.linux +++ b/docs/README.linux @@ -53,7 +53,7 @@ Build-Depends: autoconf, automake, autopoint, autotools-dev, cmake, curl, libmodplug-dev, libmpcdec-dev, libmpeg2-4-dev, libmysqlclient-dev, libnfs-dev, libogg-dev, libpcre3-dev, libplist-dev, libpng12-dev | libpng-dev, libpostproc-dev, libpulse-dev, librtmp-dev, libsdl2-dev, libshairplay-dev, libsmbclient-dev, libsqlite3-dev, libssh-dev, - libssl-dev, libswscale-dev, libtag1-dev (>= 1.8), libtiff-dev, libtinyxml-dev, libtool, + libssl-dev, libswscale-dev, libtag1-dev (>= 1.8), libtiff-dev, libtinyxml-dev (>= 2.6.2), libtool, libudev-dev, libusb-dev, libva-dev, libvdpau-dev, libvorbis-dev, libxinerama-dev, libxml2-dev, libxmu-dev, libxrandr-dev, libxslt1-dev, libxt-dev, libyajl-dev (>=2.0), lsb-release, nasm [!amd64], python-dev, python-imaging, python-support, swig, unzip, diff --git a/language/English/strings.po b/language/English/strings.po index a1cb5ccfa4..666c0cb314 100755 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -872,7 +872,15 @@ msgctxt "#210" msgid "Previous" msgstr "" -#empty strings from id 211 to 212 +#: system/settings/settings.xml +msgctxt "#211" +msgid "50 Hz" +msgstr "" + +#: system/settings/settings.xml +msgctxt "#212" +msgid "59.94 Hz" +msgstr "" msgctxt "#213" msgid "Calibrate user interface..." @@ -8047,7 +8055,10 @@ msgctxt "#19107" msgid "at" msgstr "" -#empty string with id 19108 +#: system/settings/settings.xml +msgctxt "#19108" +msgid "Framerate (fallback)" +msgstr "" msgctxt "#19109" msgid "Couldn't save timer. Check the log for details." @@ -14627,7 +14638,11 @@ msgctxt "#36260" msgid "No info available yet." msgstr "" -#empty string with id 36261 +#. Description of setting "LiveTV -> Playback -> Refreshrate" with label #19108 +#: system/settings/settings.xml +msgctxt "#36261" +msgid "If enabled, this framerate is used for streams we were not able to detect fps." +msgstr "" #. Description of setting "Music -> Library -> Export music library" with label #20196 #: system/settings/settings.xml diff --git a/project/Win32BuildSetup/buildpvraddons.bat b/project/Win32BuildSetup/buildpvraddons.bat index b4cf4142ba..c13cc35d5b 100644 --- a/project/Win32BuildSetup/buildpvraddons.bat +++ b/project/Win32BuildSetup/buildpvraddons.bat @@ -9,7 +9,7 @@ SET DEPS_DIR=..\BuildDependencies SET TMP_DIR=%DEPS_DIR%\tmp SET LIBNAME=xbmc-pvr-addons -SET VERSION=28f0e74864791cb9bb123559acb3d82e995b2b80 +SET VERSION=b2dc035404e14f137033876d14ad92ae3bde5f27 SET SOURCE=%LIBNAME% SET GIT_URL=git://github.com/opdenkamp/%LIBNAME%.git SET SOURCE_DIR=%TMP_DIR%\%SOURCE% diff --git a/system/keyboardlayouts.xml b/system/keyboardlayouts.xml index ef2d27753f..b1aa50835e 100644 --- a/system/keyboardlayouts.xml +++ b/system/keyboardlayouts.xml @@ -244,6 +244,26 @@ Default font lacks support for all characters <row>`~</row> </keyboard> </layout> + <layout name="Spanish QWERTY"> + <keyboard> + <row>1234567890'¡</row> + <row>qwertyuiop`+</row> + <row>asdfghjklñ´ç</row> + <row><zxcvbnm,.-</row> + </keyboard> + <keyboard modifiers="shift"> + <row>1234567890?¿</row> + <row>QWERTYUIOP^*</row> + <row>ASDFGHJKLѨÇ</row> + <row>>ZXCVBNM;:_</row> + </keyboard> + <keyboard modifiers="symbol,shift+symbol"> + <row>!"·$%&/()=?¿</row> + <row>\|@#€£¥[]{}~</row> + <row>áéíóúü¹²³ªº±</row> + <row>ÁÉÍÓÚܼ½¾«»§</row> + </keyboard> + </layout> <layout name="Hebrew QWERTY"> <keyboard> <row>1234567890</row> diff --git a/system/settings/settings.xml b/system/settings/settings.xml index 113be3f037..e9f4b8e2d0 100644 --- a/system/settings/settings.xml +++ b/system/settings/settings.xml @@ -1337,6 +1337,20 @@ </control> </setting> </group> + <group id="3"> + <setting id="pvrplayback.fps" type="integer" label="19108" help="36261"> + <level>0</level> + <default>0</default> + <constraints> + <options> + <option label="351">0</option> <!-- OFF --> + <option label="211">1</option> <!-- 50Hz --> + <option label="212">2</option> <!-- 59.94Hz --> + </options> + </constraints> + <control type="spinner" format="string" /> + </setting> + </group> </category> <category id="pvrrecord" label="19043" help="36233"> <group id="1"> diff --git a/tools/depends/target/ffmpeg/Makefile b/tools/depends/target/ffmpeg/Makefile index 269a0c4df2..711182f6b0 100644 --- a/tools/depends/target/ffmpeg/Makefile +++ b/tools/depends/target/ffmpeg/Makefile @@ -7,7 +7,7 @@ DEPS= ../../Makefile.include FFMPEG-VERSION Makefile APPLY_PATCHES=no # configuration settings -ffmpg_config = --prefix=$(PREFIX) --extra-version="xbmc-$(VERSION)" +ffmpg_config = --prefix=$(PREFIX) --extra-version="kodi-$(VERSION)" ffmpg_config += --cc=$(CC) --cxx=$(CXX) --ar=$(AR) --ranlib=$(RANLIB) ffmpg_config += --disable-devices --disable-doc ffmpg_config += --disable-ffplay --disable-ffmpeg --disable-sdl diff --git a/tools/depends/target/ffmpeg/autobuild.sh b/tools/depends/target/ffmpeg/autobuild.sh index e57396dab0..8733de05f6 100755 --- a/tools/depends/target/ffmpeg/autobuild.sh +++ b/tools/depends/target/ffmpeg/autobuild.sh @@ -127,7 +127,7 @@ tar --strip-components=1 -xf ../${ARCHIVE} CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" LDFLAGS="$LDFLAGS" \ ./configure --prefix=$FFMPEG_PREFIX \ - --extra-version="xbmc-${VERSION}" \ + --extra-version="kodi-${VERSION}" \ --disable-devices \ --disable-ffplay \ --disable-ffmpeg \ @@ -167,6 +167,6 @@ then [ ${SUDO} ] && echo "Root priviledges are required to install to ${FFMPEG_PREFIX}" ${SUDO} make install && echo "$VERSION" > ../.ffmpeg-installed else - echo "ERROR: building ffmpeg failed" + echo "ERROR: Building ffmpeg failed" exit 1 fi diff --git a/tools/depends/target/xbmc-pvr-addons/Makefile b/tools/depends/target/xbmc-pvr-addons/Makefile index 2dc8eba520..5abf2b7566 100644 --- a/tools/depends/target/xbmc-pvr-addons/Makefile +++ b/tools/depends/target/xbmc-pvr-addons/Makefile @@ -2,7 +2,7 @@ include ../../Makefile.include #DEPS= ../../Makefile.include Makefile LIBNAME=xbmc-pvr-addons -VERSION=1d60b822d132ac4a8f9fbfc1f4048e941ad6371e +VERSION=b2dc035404e14f137033876d14ad92ae3bde5f27 GIT_DIR=$(TARBALLS_LOCATION)/$(LIBNAME).git BASE_URL=git://github.com/opdenkamp/$(LIBNAME).git DYLIB=$(PLATFORM)/addons/pvr.demo/.libs/libpvrdemo-addon.so diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp index f63d61f770..9116b04344 100644 --- a/xbmc/Application.cpp +++ b/xbmc/Application.cpp @@ -389,7 +389,7 @@ bool CApplication::OnEvent(XBMC_Event& newEvent) case XBMC_MOUSEBUTTONUP: case XBMC_MOUSEMOTION: g_Mouse.HandleEvent(newEvent); - CInputManager::GetInstance().ProcessMouse(g_application.GetActiveWindowID()); + CInputManager::GetInstance().ProcessMouse(g_windowManager.GetActiveWindowID()); break; case XBMC_VIDEORESIZE: if (!g_application.m_bInitializing && @@ -433,7 +433,7 @@ bool CApplication::OnEvent(XBMC_Event& newEvent) actionId = newEvent.touch.action; else { - int iWin = g_application.GetActiveWindowID(); + int iWin = g_windowManager.GetActiveWindowID(); CButtonTranslator::GetInstance().TranslateTouchAction(iWin, newEvent.touch.action, newEvent.touch.pointers, actionId); } @@ -614,8 +614,8 @@ bool CApplication::Create() #endif // !USE_STATIC_FFMPEG if (!strstr(FFMPEG_VERSION, FFMPEG_VER_SHA)) { - if (strstr(FFMPEG_VERSION, "xbmc")) - CLog::Log(LOGNOTICE, "WARNING: unknown ffmpeg-xbmc version detected"); + if (strstr(FFMPEG_VERSION, "kodi")) + CLog::Log(LOGNOTICE, "WARNING: unknown ffmpeg-kodi version detected"); else CLog::Log(LOGNOTICE, "WARNING: unsupported ffmpeg version detected"); } @@ -2139,7 +2139,7 @@ bool CApplication::OnKey(const CKey& key) g_Mouse.SetActive(false); // get the current active window - int iWin = GetActiveWindowID(); + int iWin = g_windowManager.GetActiveWindowID(); // this will be checked for certain keycodes that need // special handling if the screensaver is active @@ -2720,9 +2720,9 @@ void CApplication::FrameMove(bool processEvents, bool processGUI) #endif // process input actions - CInputManager::GetInstance().ProcessRemote(GetActiveWindowID()); - CInputManager::GetInstance().ProcessGamepad(GetActiveWindowID()); - CInputManager::GetInstance().ProcessEventServer(GetActiveWindowID(), frameTime); + CInputManager::GetInstance().ProcessRemote(g_windowManager.GetActiveWindowID()); + CInputManager::GetInstance().ProcessGamepad(g_windowManager.GetActiveWindowID()); + CInputManager::GetInstance().ProcessEventServer(g_windowManager.GetActiveWindowID(), frameTime); CInputManager::GetInstance().ProcessPeripherals(frameTime); if (processGUI && m_renderGUI) { @@ -2758,32 +2758,7 @@ bool CApplication::ExecuteInputAction(const CAction &action) return bResult; } -int CApplication::GetActiveWindowID(void) -{ - // Get the currently active window - int iWin = g_windowManager.GetActiveWindow() & WINDOW_ID_MASK; - // If there is a dialog active get the dialog id instead - if (g_windowManager.HasModalDialog()) - iWin = g_windowManager.GetTopMostModalDialogID() & WINDOW_ID_MASK; - - // If the window is FullScreenVideo check for special cases - if (iWin == WINDOW_FULLSCREEN_VIDEO) - { - // check if we're in a DVD menu - if(g_application.m_pPlayer->IsInMenu()) - iWin = WINDOW_VIDEO_MENU; - // check for LiveTV and switch to it's virtual window - else if (g_PVRManager.IsStarted() && g_application.CurrentFileItem().HasPVRChannelInfoTag()) - iWin = WINDOW_FULLSCREEN_LIVETV; - } - // special casing for PVR radio - if (iWin == WINDOW_VISUALISATION && g_PVRManager.IsStarted() && g_application.CurrentFileItem().HasPVRChannelInfoTag()) - iWin = WINDOW_FULLSCREEN_RADIO; - - // Return the window id - return iWin; -} bool CApplication::Cleanup() { diff --git a/xbmc/Application.h b/xbmc/Application.h index 5ac307dc84..b7d9308276 100644 --- a/xbmc/Application.h +++ b/xbmc/Application.h @@ -492,7 +492,7 @@ protected: PlayBackRet PlayStack(const CFileItem& item, bool bRestart); bool ExecuteInputAction(const CAction &action); - int GetActiveWindowID(void); + float NavigationIdleTime(); static bool AlwaysProcess(const CAction& action); diff --git a/xbmc/FileItem.cpp b/xbmc/FileItem.cpp index f8ffd44984..400624e3a1 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -62,6 +62,8 @@ #include "cores/paplayer/ASAPCodec.h" #endif +#include <assert.h> + using namespace std; using namespace XFILE; using namespace PLAYLIST; @@ -173,16 +175,17 @@ CFileItem::CFileItem(const CPVRChannel& channel) FillInMimeType(false); } -CFileItem::CFileItem(const CPVRRecording& record) +CFileItem::CFileItem(const CPVRRecordingPtr& record) { + assert(record.get()); + Initialize(); - m_strPath = record.m_strFileNameAndPath; m_bIsFolder = false; - *GetPVRRecordingInfoTag() = record; - SetLabel(record.m_strTitle); - m_strLabel2 = record.m_strPlot; - + m_pvrRecordingInfoTag = record; + m_strPath = record->m_strFileNameAndPath; + SetLabel(record->m_strTitle); + m_strLabel2 = record->m_strPlot; FillInMimeType(false); } @@ -230,7 +233,6 @@ CFileItem::CFileItem(const CFileItem& item): CGUIListItem() m_musicInfoTag = NULL; m_videoInfoTag = NULL; m_pvrChannelInfoTag = NULL; - m_pvrRecordingInfoTag = NULL; m_pvrTimerInfoTag = NULL; m_pictureInfoTag = NULL; *this = item; @@ -315,14 +317,12 @@ CFileItem::~CFileItem(void) delete m_musicInfoTag; delete m_videoInfoTag; delete m_pvrChannelInfoTag; - delete m_pvrRecordingInfoTag; delete m_pvrTimerInfoTag; delete m_pictureInfoTag; m_musicInfoTag = NULL; m_videoInfoTag = NULL; m_pvrChannelInfoTag = NULL; - m_pvrRecordingInfoTag = NULL; m_pvrTimerInfoTag = NULL; m_pictureInfoTag = NULL; } @@ -382,19 +382,10 @@ const CFileItem& CFileItem::operator=(const CFileItem& item) m_pvrChannelInfoTag = NULL; } - if (item.HasPVRRecordingInfoTag()) - { - m_pvrRecordingInfoTag = GetPVRRecordingInfoTag(); - if (m_pvrRecordingInfoTag) - *m_pvrRecordingInfoTag = *item.m_pvrRecordingInfoTag; - } + if (item.m_pvrRecordingInfoTag) + m_pvrRecordingInfoTag = item.m_pvrRecordingInfoTag; else - { - if (m_pvrRecordingInfoTag) - delete m_pvrRecordingInfoTag; - - m_pvrRecordingInfoTag = NULL; - } + m_pvrRecordingInfoTag.reset(); if (item.HasPVRTimerInfoTag()) { @@ -446,7 +437,6 @@ void CFileItem::Initialize() m_musicInfoTag = NULL; m_videoInfoTag = NULL; m_pvrChannelInfoTag = NULL; - m_pvrRecordingInfoTag = NULL; m_pvrTimerInfoTag = NULL; m_pictureInfoTag = NULL; m_bLabelPreformated=false; @@ -490,8 +480,7 @@ void CFileItem::Reset() m_epgInfoTag.reset(); delete m_pvrChannelInfoTag; m_pvrChannelInfoTag=NULL; - delete m_pvrRecordingInfoTag; - m_pvrRecordingInfoTag=NULL; + m_pvrRecordingInfoTag.reset(); delete m_pvrTimerInfoTag; m_pvrTimerInfoTag=NULL; delete m_pictureInfoTag; @@ -1399,8 +1388,8 @@ void CFileItem::UpdateInfo(const CFileItem &item, bool replaceLabels /*=true*/) { // copy info across (TODO: premiered info is normally stored in m_dateTime by the db) *GetVideoInfoTag() = *item.GetVideoInfoTag(); // preferably use some information from PVR info tag if available - if (HasPVRRecordingInfoTag()) - GetPVRRecordingInfoTag()->CopyClientInfo(GetVideoInfoTag()); + if (m_pvrRecordingInfoTag) + m_pvrRecordingInfoTag->CopyClientInfo(GetVideoInfoTag()); SetOverlayImage(ICON_OVERLAY_UNWATCHED, GetVideoInfoTag()->m_playCount > 0); SetInvalid(); } @@ -3119,14 +3108,6 @@ CPVRChannel* CFileItem::GetPVRChannelInfoTag() return m_pvrChannelInfoTag; } -CPVRRecording* CFileItem::GetPVRRecordingInfoTag() -{ - if (!m_pvrRecordingInfoTag) - m_pvrRecordingInfoTag = new CPVRRecording; - - return m_pvrRecordingInfoTag; -} - CPVRTimerInfoTag* CFileItem::GetPVRTimerInfoTag() { if (!m_pvrTimerInfoTag) @@ -3260,15 +3241,15 @@ int CFileItem::GetVideoContentType() const bool CFileItem::IsResumePointSet() const { return (HasVideoInfoTag() && GetVideoInfoTag()->m_resumePoint.IsSet()) || - (HasPVRRecordingInfoTag() && GetPVRRecordingInfoTag()->GetLastPlayedPosition() > 0); + (m_pvrRecordingInfoTag && m_pvrRecordingInfoTag->GetLastPlayedPosition() > 0); } double CFileItem::GetCurrentResumeTime() const { - if (HasPVRRecordingInfoTag()) + if (m_pvrRecordingInfoTag) { // This will retrieve 'fresh' resume information from the PVR server - int rc = GetPVRRecordingInfoTag()->GetLastPlayedPosition(); + int rc = m_pvrRecordingInfoTag->GetLastPlayedPosition(); if (rc > 0) return rc; // Fall through to default value diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index 239a8895f3..4f49b13868 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -51,6 +51,7 @@ namespace PVR class CPVRChannel; class CPVRRecording; class CPVRTimerInfoTag; + typedef boost::shared_ptr<PVR::CPVRRecording> CPVRRecordingPtr; } class CPictureInfoTag; @@ -103,7 +104,7 @@ public: CFileItem(const CVideoInfoTag& movie); CFileItem(const EPG::CEpgInfoTagPtr& tag); CFileItem(const PVR::CPVRChannel& channel); - CFileItem(const PVR::CPVRRecording& record); + CFileItem(const PVR::CPVRRecordingPtr& record); CFileItem(const PVR::CPVRTimerInfoTag& timer); CFileItem(const CMediaSource& share); virtual ~CFileItem(void); @@ -287,12 +288,10 @@ public: inline bool HasPVRRecordingInfoTag() const { - return m_pvrRecordingInfoTag != NULL; + return m_pvrRecordingInfoTag.get() != NULL; } - PVR::CPVRRecording* GetPVRRecordingInfoTag(); - - inline const PVR::CPVRRecording* GetPVRRecordingInfoTag() const + inline const PVR::CPVRRecordingPtr GetPVRRecordingInfoTag() const { return m_pvrRecordingInfoTag; } @@ -486,7 +485,7 @@ private: CVideoInfoTag* m_videoInfoTag; EPG::CEpgInfoTagPtr m_epgInfoTag; PVR::CPVRChannel* m_pvrChannelInfoTag; - PVR::CPVRRecording* m_pvrRecordingInfoTag; + PVR::CPVRRecordingPtr m_pvrRecordingInfoTag; PVR::CPVRTimerInfoTag * m_pvrTimerInfoTag; CPictureInfoTag* m_pictureInfoTag; bool m_bIsAlbum; diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp index 4bb7fe4df5..1f48ca684c 100644 --- a/xbmc/Util.cpp +++ b/xbmc/Util.cpp @@ -1865,11 +1865,11 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st vector<std::string> strLookInPaths; std::string strMovieFileName; - std::string strPath; + std::string strMoviePath; - URIUtils::Split(strMovie, strPath, strMovieFileName); + URIUtils::Split(strMovie, strMoviePath, strMovieFileName); std::string strMovieFileNameNoExt(URIUtils::ReplaceExtension(strMovieFileName, "")); - strLookInPaths.push_back(strPath); + strLookInPaths.push_back(strMoviePath); CURL url(strMovie); std::string isoFileNameNoExt; @@ -1911,8 +1911,8 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st { CURL url(strMovie); std::string strArchive = url.GetHostName(); - URIUtils::Split(strArchive, strPath, strMovieFileName); - strLookInPaths.push_back(strPath); + URIUtils::Split(strArchive, strMoviePath, strMovieFileName); + strLookInPaths.push_back(strMoviePath); } int iSize = strLookInPaths.size(); @@ -1970,9 +1970,9 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st // this is last because we dont want to check any common subdirs or cd-dirs in the alternate <subtitles> dir. if (CMediaSettings::Get().GetAdditionalSubtitleDirectoryChecked() == 1) { - strPath = CSettings::Get().GetString("subtitles.custompath"); - URIUtils::AddSlashAtEnd(strPath); - strLookInPaths.push_back(strPath); + std::string strPath2 = CSettings::Get().GetString("subtitles.custompath"); + URIUtils::AddSlashAtEnd(strPath2); + strLookInPaths.push_back(strPath2); } std::string strDest; @@ -1990,9 +1990,13 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st for (int j = 0; j < items.Size(); j++) { - URIUtils::Split(items[j]->GetPath(), strPath, strItem); + std::string strSubtitlePath; + URIUtils::Split(items[j]->GetPath(), strSubtitlePath, strItem); + + // Make sure filename uses the correct encoding + std::string strMovieFileNameNoExt2 = URIUtils::ChangeBasePath(strMoviePath, strMovieFileNameNoExt, strSubtitlePath, false); - if (StringUtils::StartsWithNoCase(strItem, strMovieFileNameNoExt) + if (StringUtils::StartsWithNoCase(strItem, strMovieFileNameNoExt2) || (!isoFileNameNoExt.empty() && StringUtils::StartsWithNoCase(strItem, isoFileNameNoExt))) { // is this a rar or zip-file @@ -2019,8 +2023,11 @@ void CUtil::ScanForExternalSubtitles(const std::string& strMovie, std::vector<st // is this a rar or zip-file if (URIUtils::IsRAR(strItem) || URIUtils::IsZIP(strItem)) { + // Make sure filename uses the correct encoding + std::string strMovieFileNameNoExt2 = URIUtils::ChangeBasePath(strMoviePath, strMovieFileNameNoExt, "", false); + // check strMovieFileNameNoExt in zip-file - ScanArchiveForSubtitles( items[j]->GetPath(), strMovieFileNameNoExt, vecSubtitles ); + ScanArchiveForSubtitles(items[j]->GetPath(), strMovieFileNameNoExt2, vecSubtitles ); } } } diff --git a/xbmc/addons/AddonCallbacksPVR.cpp b/xbmc/addons/AddonCallbacksPVR.cpp index 8056f8cdd6..108d3ca274 100644 --- a/xbmc/addons/AddonCallbacksPVR.cpp +++ b/xbmc/addons/AddonCallbacksPVR.cpp @@ -191,7 +191,7 @@ void CAddonCallbacksPVR::PVRTransferRecordingEntry(void *addonData, const ADDON_ } /* transfer this entry to the recordings container */ - CPVRRecording transferRecording(*recording, client->GetID()); + CPVRRecordingPtr transferRecording(new CPVRRecording(*recording, client->GetID())); xbmcRecordings->UpdateFromClient(transferRecording); } diff --git a/xbmc/addons/Repository.cpp b/xbmc/addons/Repository.cpp index f97aab3110..0d0b75a560 100644 --- a/xbmc/addons/Repository.cpp +++ b/xbmc/addons/Repository.cpp @@ -104,20 +104,6 @@ CRepository::~CRepository() { } -string CRepository::Checksum() const -{ - /* This code is duplicated in CRepositoryUpdateJob::GrabAddons(). - * If you make changes here, they may be applicable there, too. - */ - string result; - for (DirList::const_iterator it = m_dirs.begin(); it != m_dirs.end(); ++it) - { - if (!it->checksum.empty()) - result += FetchChecksum(it->checksum); - } - return result; -} - string CRepository::FetchChecksum(const string& url) { CFile file; @@ -165,11 +151,8 @@ string CRepository::GetAddonHash(const AddonPtr& addon) const x = y; \ } -VECADDONS CRepository::Parse(const DirInfo& dir) +bool CRepository::Parse(const DirInfo& dir, VECADDONS &result) { - VECADDONS result; - CXBMCTinyXML doc; - string file = dir.info; if (dir.compressed) { @@ -181,9 +164,10 @@ VECADDONS CRepository::Parse(const DirInfo& dir) file = url.Get(); } - if (doc.LoadFile(file) && doc.RootElement()) + CXBMCTinyXML doc; + if (doc.LoadFile(file) && doc.RootElement() && + CAddonMgr::Get().AddonsFromRepoXML(doc.RootElement(), result)) { - CAddonMgr::Get().AddonsFromRepoXML(doc.RootElement(), result); for (IVECADDONS i = result.begin(); i != result.end(); ++i) { AddonPtr addon = *i; @@ -204,9 +188,9 @@ VECADDONS CRepository::Parse(const DirInfo& dir) SET_IF_NOT_EMPTY(addon->Props().fanart,URIUtils::AddFileToFolder(dir.datadir,addon->ID()+"/fanart.jpg")) } } + return true; } - - return result; + return false; } void CRepository::OnPostInstall(bool restart, bool update) @@ -251,12 +235,13 @@ bool CRepositoryUpdateJob::DoWork() { if (ShouldCancel(0, 0)) return false; - RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(*i); - VECADDONS newAddons = GrabAddons(repo); - MergeAddons(addons, newAddons); + const RepositoryPtr repo = boost::dynamic_pointer_cast<CRepository>(*i); + VECADDONS newAddons; + if (GrabAddons(repo, newAddons)) + MergeAddons(addons, newAddons); } if (addons.empty()) - return false; + return true; //Nothing to do // check for updates CAddonDatabase database; @@ -343,63 +328,68 @@ bool CRepositoryUpdateJob::DoWork() return true; } -VECADDONS CRepositoryUpdateJob::GrabAddons(RepositoryPtr& repo) +bool CRepositoryUpdateJob::GrabAddons(const RepositoryPtr& repo, VECADDONS& addons) { CAddonDatabase database; - VECADDONS addons; database.Open(); - string checksum; - database.GetRepoChecksum(repo->ID(),checksum); - string reposum; + string oldReposum; + if (!database.GetRepoChecksum(repo->ID(), oldReposum)) + oldReposum = ""; - /* This for loop is duplicated in CRepository::Checksum(). - * If you make changes here, they may be applicable there, too. - */ + string reposum; for (CRepository::DirList::const_iterator it = repo->m_dirs.begin(); it != repo->m_dirs.end(); ++it) { if (ShouldCancel(0, 0)) - return addons; + return false; if (!it->checksum.empty()) - reposum += CRepository::FetchChecksum(it->checksum); + { + const string dirsum = CRepository::FetchChecksum(it->checksum); + if (dirsum.empty()) + { + CLog::Log(LOGERROR, "Failed to fetch checksum for directory listing %s for repository %s. ", (*it).info.c_str(), repo->ID().c_str()); + return false; + } + reposum += dirsum; + } } - if (checksum != reposum || checksum.empty()) + if (oldReposum != reposum || oldReposum.empty()) { map<string, AddonPtr> uniqueAddons; for (CRepository::DirList::const_iterator it = repo->m_dirs.begin(); it != repo->m_dirs.end(); ++it) { if (ShouldCancel(0, 0)) - return addons; - VECADDONS addons2 = CRepository::Parse(*it); - MergeAddons(uniqueAddons, addons2); + return false; + VECADDONS addons; + if (!CRepository::Parse(*it, addons)) + { //TODO: Hash is invalid and should not be saved, but should we fail? + //We can still report a partial addon listing. + CLog::Log(LOGERROR, "Failed to read directory listing %s for repository %s. ", (*it).info.c_str(), repo->ID().c_str()); + return false; + } + MergeAddons(uniqueAddons, addons); } - if (uniqueAddons.empty()) + bool add = true; + if (!repo->Props().libname.empty()) { - CLog::Log(LOGERROR,"Repository %s returned no add-ons, listing may have failed",repo->Name().c_str()); - reposum = checksum; // don't update the checksum + CFileItemList dummy; + string s = StringUtils::Format("plugin://%s/?action=update", repo->ID().c_str()); + add = CDirectory::GetDirectory(s, dummy); } - else + if (add) { - bool add=true; - if (!repo->Props().libname.empty()) - { - CFileItemList dummy; - string s = StringUtils::Format("plugin://%s/?action=update", repo->ID().c_str()); - add = CDirectory::GetDirectory(s, dummy); - } - if (add) - { - for (map<string, AddonPtr>::const_iterator i = uniqueAddons.begin(); i != uniqueAddons.end(); ++i) - addons.push_back(i->second); - database.AddRepository(repo->ID(),addons,reposum); - } + for (map<string, AddonPtr>::const_iterator i = uniqueAddons.begin(); i != uniqueAddons.end(); ++i) + addons.push_back(i->second); + database.AddRepository(repo->ID(),addons,reposum); } } else - database.GetRepository(repo->ID(),addons); - database.SetRepoTimestamp(repo->ID(),CDateTime::GetCurrentDateTime().GetAsDBDateTime()); - - return addons; + { + CLog::Log(LOGDEBUG, "Checksum for repository %s not changed.", repo->ID().c_str()); + database.GetRepository(repo->ID(), addons); + database.SetRepoTimestamp(repo->ID(), CDateTime::GetCurrentDateTime().GetAsDBDateTime()); + } + return true; } diff --git a/xbmc/addons/Repository.h b/xbmc/addons/Repository.h index 7829d5117b..8ac282c608 100644 --- a/xbmc/addons/Repository.h +++ b/xbmc/addons/Repository.h @@ -34,8 +34,6 @@ namespace ADDON CRepository(const cp_extension_t *props); virtual ~CRepository(); - std::string Checksum() const; - /*! \brief Get the md5 hash for an addon. \param the addon in question. \return the md5 hash for the given addon, empty if non exists. @@ -57,7 +55,7 @@ namespace ADDON typedef std::vector<DirInfo> DirList; DirList m_dirs; - static VECADDONS Parse(const DirInfo& dir); + static bool Parse(const DirInfo& dir, VECADDONS& addons); static std::string FetchChecksum(const std::string& url); virtual void OnPostInstall(bool restart, bool update); @@ -76,7 +74,7 @@ namespace ADDON virtual const char *GetType() const { return "repoupdate"; }; virtual bool DoWork(); private: - VECADDONS GrabAddons(RepositoryPtr& repo); + bool GrabAddons(const RepositoryPtr& repo, VECADDONS& addons); VECADDONS m_repos; }; diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp index 60ca6cce41..8f7c8a1ce8 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp @@ -3307,7 +3307,7 @@ bool CDVDPlayer::OpenAudioStream(CDVDStreamInfo& hint, bool reset) bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) { - if( m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD) ) + if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_DVD)) { /* set aspect ratio as requested by navigator for dvd's */ float aspect = static_cast<CDVDInputStreamNavigator*>(m_pInputStream)->GetVideoAspectRatio(); @@ -3318,6 +3318,24 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) } hint.software = true; } + else if (m_pInputStream && m_pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) + { + // set framerate if not set by demuxer + if (hint.fpsrate == 0 || hint.fpsscale == 0) + { + int fpsidx = CSettings::Get().GetInt("pvrplayback.fps"); + if (fpsidx == 1) + { + hint.fpsscale = 1000; + hint.fpsrate = 50000; + } + else if (fpsidx == 2) + { + hint.fpsscale = 1001; + hint.fpsrate = 60000; + } + } + } CDVDInputStream::IMenus* pMenus = dynamic_cast<CDVDInputStream::IMenus*>(m_pInputStream); if(pMenus && pMenus->IsInMenu()) diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp index 908ddcb176..33877af183 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp @@ -985,13 +985,17 @@ int CDVDPlayerVideo::OutputPicture(const DVDVideoPicture* src, double pts) double render_framerate = g_graphicsContext.GetFPS(); if (CSettings::Get().GetInt("videoplayer.adjustrefreshrate") == ADJUST_REFRESHRATE_OFF) render_framerate = config_framerate; + bool changerefresh = !m_bFpsInvalid && + (m_output.framerate == 0.0 || fmod(m_output.framerate, config_framerate) != 0.0) && + (render_framerate != config_framerate); + /* check so that our format or aspect has changed. if it has, reconfigure renderer */ if (!g_renderManager.IsConfigured() || ( m_output.width != pPicture->iWidth ) || ( m_output.height != pPicture->iHeight ) || ( m_output.dwidth != pPicture->iDisplayWidth ) || ( m_output.dheight != pPicture->iDisplayHeight ) - || (!m_bFpsInvalid && fmod(m_output.framerate, config_framerate) != 0.0 && render_framerate != config_framerate) + || changerefresh || ( m_output.color_format != (unsigned int)pPicture->format ) || ( m_output.extended_format != pPicture->extended_format ) || ( m_output.color_matrix != pPicture->color_matrix && pPicture->color_matrix != 0 ) // don't reconfigure on unspecified diff --git a/xbmc/cores/dvdplayer/DVDStreamInfo.h b/xbmc/cores/dvdplayer/DVDStreamInfo.h index de66625d99..c0e22a2330 100644 --- a/xbmc/cores/dvdplayer/DVDStreamInfo.h +++ b/xbmc/cores/dvdplayer/DVDStreamInfo.h @@ -56,7 +56,7 @@ public: // VIDEO - int fpsscale; // scale of 1000 and a rate of 29970 will result in 29.97 fps + int fpsscale; // scale of 1001 and a rate of 60000 will result in 59.94 fps int fpsrate; int rfpsscale; int rfpsrate; diff --git a/xbmc/dbwrappers/DatabaseQuery.cpp b/xbmc/dbwrappers/DatabaseQuery.cpp index d8353c34fe..5e6fd443ab 100644 --- a/xbmc/dbwrappers/DatabaseQuery.cpp +++ b/xbmc/dbwrappers/DatabaseQuery.cpp @@ -172,7 +172,7 @@ bool CDatabaseQueryRule::Save(TiXmlNode *parent) const rule.SetAttribute("field", TranslateField(m_field).c_str()); rule.SetAttribute("operator", TranslateOperator(m_operator).c_str()); - for (vector<std::string>::const_iterator it = m_parameter.begin(); it != m_parameter.end(); it++) + for (vector<std::string>::const_iterator it = m_parameter.begin(); it != m_parameter.end(); ++it) { TiXmlElement value("value"); TiXmlText text(*it); @@ -513,7 +513,7 @@ bool CDatabaseQueryRuleCombination::Save(CVariant &obj) const CVariant comboArray(CVariant::VariantTypeArray); if (!m_combinations.empty()) { - for (CDatabaseQueryRuleCombinations::const_iterator combo = m_combinations.begin(); combo != m_combinations.end(); combo++) + for (CDatabaseQueryRuleCombinations::const_iterator combo = m_combinations.begin(); combo != m_combinations.end(); ++combo) { CVariant comboObj(CVariant::VariantTypeObject); if ((*combo)->Save(comboObj)) @@ -523,7 +523,7 @@ bool CDatabaseQueryRuleCombination::Save(CVariant &obj) const } if (!m_rules.empty()) { - for (CDatabaseQueryRules::const_iterator rule = m_rules.begin(); rule != m_rules.end(); rule++) + for (CDatabaseQueryRules::const_iterator rule = m_rules.begin(); rule != m_rules.end(); ++rule) { CVariant ruleObj(CVariant::VariantTypeObject); if ((*rule)->Save(ruleObj)) diff --git a/xbmc/dbwrappers/dataset.cpp b/xbmc/dbwrappers/dataset.cpp index 35e8a6d934..e6ba7b511b 100644 --- a/xbmc/dbwrappers/dataset.cpp +++ b/xbmc/dbwrappers/dataset.cpp @@ -39,15 +39,16 @@ using namespace std; namespace dbiplus { //************* Database implementation *************** -Database::Database() { +Database::Database(): + error(), //S_NO_CONNECTION, + host(), + port(), + db(), + login(), + passwd(), + sequence_table("db_sequence") +{ active = false; // No connection yet - error = "";//S_NO_CONNECTION; - host = ""; - port = ""; - db = ""; - login = ""; - passwd = ""; - sequence_table = "db_sequence"; } Database::~Database() { @@ -71,11 +72,9 @@ int Database::connectFull(const char *newHost, const char *newPort, const char * string Database::prepare(const char *format, ...) { - string result = ""; - va_list args; va_start(args, format); - result = vprepare(format, args); + string result = vprepare(format, args); va_end(args); return result; @@ -83,7 +82,9 @@ string Database::prepare(const char *format, ...) //************* Dataset implementation *************** -Dataset::Dataset() { +Dataset::Dataset(): + select_sql("") +{ db = NULL; haveError = active = false; @@ -91,8 +92,6 @@ Dataset::Dataset() { fbof = feof = true; autocommit = true; - select_sql = ""; - fields_object = new Fields(); edit_object = new Fields(); @@ -100,7 +99,9 @@ Dataset::Dataset() { -Dataset::Dataset(Database *newDb) { +Dataset::Dataset(Database *newDb): + select_sql("") +{ db = newDb; haveError = active = false; @@ -108,8 +109,6 @@ Dataset::Dataset(Database *newDb) { fbof = feof = true; autocommit = true; - select_sql = ""; - fields_object = new Fields(); edit_object = new Fields(); @@ -514,8 +513,9 @@ for (unsigned int i=0; i < fields_object->size(); i++) //************* DbErrors implementation *************** -DbErrors::DbErrors() { - msg_ = "Unknown Database Error"; +DbErrors::DbErrors(): + msg_("Unknown Database Error") +{ } diff --git a/xbmc/dbwrappers/mysqldataset.cpp b/xbmc/dbwrappers/mysqldataset.cpp index 6161c473bf..d8df89fb03 100644 --- a/xbmc/dbwrappers/mysqldataset.cpp +++ b/xbmc/dbwrappers/mysqldataset.cpp @@ -1320,7 +1320,7 @@ void MysqlDataset::make_query(StringList &_sql) { { if (autocommit) db->start_transaction(); - for (list<string>::iterator i =_sql.begin(); i!=_sql.end(); i++) + for (list<string>::iterator i =_sql.begin(); i!=_sql.end(); ++i) { query = *i; Dataset::parse_sql(query); diff --git a/xbmc/dbwrappers/qry_dat.cpp b/xbmc/dbwrappers/qry_dat.cpp index 541302d3ef..b7b620a821 100644 --- a/xbmc/dbwrappers/qry_dat.cpp +++ b/xbmc/dbwrappers/qry_dat.cpp @@ -46,14 +46,15 @@ using namespace std; namespace dbiplus { //Constructors -field_value::field_value(){ - str_value = ""; +field_value::field_value() +{ field_type = ft_String; is_null = false; - } +} -field_value::field_value(const char *s) { - str_value = s; +field_value::field_value(const char *s): + str_value(s) +{ field_type = ft_String; is_null = false; } @@ -276,11 +277,10 @@ char field_value::get_asChar() const { return str_value[0]; } case ft_Boolean:{ - char c; if (bool_value) - return c='T'; + return 'T'; else - return c='F'; + return 'F'; } case ft_Char: { return char_value; diff --git a/xbmc/dbwrappers/sqlitedataset.cpp b/xbmc/dbwrappers/sqlitedataset.cpp index 632556a96f..112accf7cb 100644 --- a/xbmc/dbwrappers/sqlitedataset.cpp +++ b/xbmc/dbwrappers/sqlitedataset.cpp @@ -491,7 +491,7 @@ void SqliteDataset::make_query(StringList &_sql) { if (autocommit) db->start_transaction(); - for (list<string>::iterator i =_sql.begin(); i!=_sql.end(); i++) { + for (list<string>::iterator i =_sql.begin(); i!=_sql.end(); ++i) { query = *i; char* err=NULL; Dataset::parse_sql(query); diff --git a/xbmc/epg/EpgSearchFilter.cpp b/xbmc/epg/EpgSearchFilter.cpp index 39e328d0a2..003f9a1647 100644 --- a/xbmc/epg/EpgSearchFilter.cpp +++ b/xbmc/epg/EpgSearchFilter.cpp @@ -205,9 +205,10 @@ int EpgSearchFilter::FilterRecordings(CFileItemList &results) g_PVRRecordings->GetAll(recordings); // TODO inefficient! + CPVRRecordingPtr recording; for (int iRecordingPtr = 0; iRecordingPtr < recordings.Size(); iRecordingPtr++) { - CPVRRecording *recording = recordings.Get(iRecordingPtr)->GetPVRRecordingInfoTag(); + recording = recordings.Get(iRecordingPtr)->GetPVRRecordingInfoTag(); if (!recording) continue; diff --git a/xbmc/filesystem/PVRFile.cpp b/xbmc/filesystem/PVRFile.cpp index 4e9abf934a..0563dd7e9a 100644 --- a/xbmc/filesystem/PVRFile.cpp +++ b/xbmc/filesystem/PVRFile.cpp @@ -75,7 +75,7 @@ bool CPVRFile::Open(const CURL& url) CFileItemPtr tag = g_PVRRecordings->GetByPath(strURL); if (tag && tag->HasPVRRecordingInfoTag()) { - if (!g_PVRManager.OpenRecordedStream(*tag->GetPVRRecordingInfoTag())) + if (!g_PVRManager.OpenRecordedStream(tag->GetPVRRecordingInfoTag())) return false; m_isPlayRecording = true; diff --git a/xbmc/guilib/GUIFontTTF.cpp b/xbmc/guilib/GUIFontTTF.cpp index b67a8b5ed6..a16d3db162 100644 --- a/xbmc/guilib/GUIFontTTF.cpp +++ b/xbmc/guilib/GUIFontTTF.cpp @@ -53,9 +53,6 @@ using namespace std; #define CHARS_PER_TEXTURE_LINE 20 // number of characters to cache per texture line #define CHAR_CHUNK 64 // 64 chars allocated at a time (1024 bytes) -int CGUIFontTTFBase::justification_word_weight = 6; // weight of word spacing over letter spacing when justifying. - // A larger number means more of the "dead space" is placed between - // words rather than between letters. class CFreeTypeLibrary { @@ -423,26 +420,27 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors startX -= w; } - float spacePerLetter = 0; // for justification effects + float spacePerSpaceCharacter = 0; // for justification effects if ( alignment & XBFONT_JUSTIFIED ) { // first compute the size of the text to render in both characters and pixels - unsigned int lineChars = 0; + unsigned int numSpaces = 0; float linePixels = 0; for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos) { Character *ch = GetCharacter(*pos); if (ch) - { // spaces have multiple times the justification spacing of normal letters - lineChars += ((*pos & 0xffff) == L' ') ? justification_word_weight : 1; + { + if ((*pos & 0xffff) == L' ') + numSpaces += 1; linePixels += ch->advance; } } - if (lineChars > 1) - spacePerLetter = (maxPixelWidth - linePixels) / (lineChars - 1); + if (numSpaces > 0) + spacePerSpaceCharacter = (maxPixelWidth - linePixels) / numSpaces; } - float cursorX = 0; // current position along the line + float cursorX = 0; // current position along the line for (vecText::const_iterator pos = text.begin(); pos != text.end(); ++pos) { // If starting text on a new line, determine justification effects @@ -482,9 +480,9 @@ void CGUIFontTTFBase::DrawTextInternal(float x, float y, const vecColors &colors if ( alignment & XBFONT_JUSTIFIED ) { if ((*pos & 0xffff) == L' ') - cursorX += ch->advance + spacePerLetter * justification_word_weight; + cursorX += ch->advance + spacePerSpaceCharacter; else - cursorX += ch->advance + spacePerLetter; + cursorX += ch->advance; } else cursorX += ch->advance; diff --git a/xbmc/guilib/GUIFontTTF.h b/xbmc/guilib/GUIFontTTF.h index 29eac0bb07..c7af7ef64d 100644 --- a/xbmc/guilib/GUIFontTTF.h +++ b/xbmc/guilib/GUIFontTTF.h @@ -184,8 +184,6 @@ protected: float m_textureScaleX; float m_textureScaleY; - static int justification_word_weight; - std::string m_strFileName; XUTILS::auto_buffer m_fontFileInMemory; // used only in some cases, see CFreeTypeLibrary::GetFont() diff --git a/xbmc/guilib/GUIWindowManager.cpp b/xbmc/guilib/GUIWindowManager.cpp index 7552087885..188bf0b47b 100644 --- a/xbmc/guilib/GUIWindowManager.cpp +++ b/xbmc/guilib/GUIWindowManager.cpp @@ -117,6 +117,7 @@ #endif /* PVR related include Files */ +#include "pvr/PVRManager.h" #include "pvr/windows/GUIWindowPVRChannels.h" #include "pvr/windows/GUIWindowPVRRecordings.h" #include "pvr/windows/GUIWindowPVRGuide.h" @@ -1247,6 +1248,33 @@ int CGUIWindowManager::GetActiveWindow() const return WINDOW_INVALID; } +int CGUIWindowManager::GetActiveWindowID() +{ + // Get the currently active window + int iWin = GetActiveWindow() & WINDOW_ID_MASK; + + // If there is a dialog active get the dialog id instead + if (HasModalDialog()) + iWin = GetTopMostModalDialogID() & WINDOW_ID_MASK; + + // If the window is FullScreenVideo check for special cases + if (iWin == WINDOW_FULLSCREEN_VIDEO) + { + // check if we're in a DVD menu + if (g_application.m_pPlayer->IsInMenu()) + iWin = WINDOW_VIDEO_MENU; + // check for LiveTV and switch to it's virtual window + else if (g_PVRManager.IsStarted() && g_application.CurrentFileItem().HasPVRChannelInfoTag()) + iWin = WINDOW_FULLSCREEN_LIVETV; + } + // special casing for PVR radio + if (iWin == WINDOW_VISUALISATION && g_PVRManager.IsStarted() && g_application.CurrentFileItem().HasPVRChannelInfoTag()) + iWin = WINDOW_FULLSCREEN_RADIO; + + // Return the window id + return iWin; +} + // same as GetActiveWindow() except it first grabs dialogs int CGUIWindowManager::GetFocusedWindow() const { diff --git a/xbmc/guilib/GUIWindowManager.h b/xbmc/guilib/GUIWindowManager.h index 86d5c65d3e..3fb2371534 100644 --- a/xbmc/guilib/GUIWindowManager.h +++ b/xbmc/guilib/GUIWindowManager.h @@ -137,6 +137,7 @@ public: int RemoveThreadMessageByMessageIds(int *pMessageIDList); void AddMsgTarget( IMsgTargetCallback* pMsgTarget ); int GetActiveWindow() const; + int GetActiveWindowID(); int GetFocusedWindow() const; bool HasModalDialog() const; bool HasDialogOnScreen() const; diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp index 3066bf00e3..c768340a55 100644 --- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp +++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp @@ -359,7 +359,7 @@ void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char if (item->HasEPGInfoTag()) FillDetails(item->GetEPGInfoTag().get(), item, fields, object, thumbLoader); if (item->HasPVRRecordingInfoTag()) - FillDetails(item->GetPVRRecordingInfoTag(), item, fields, object, thumbLoader); + FillDetails(item->GetPVRRecordingInfoTag().get(), item, fields, object, thumbLoader); if (item->HasPVRTimerInfoTag()) FillDetails(item->GetPVRTimerInfoTag(), item, fields, object, thumbLoader); if (item->HasVideoInfoTag()) diff --git a/xbmc/interfaces/legacy/Dialog.cpp b/xbmc/interfaces/legacy/Dialog.cpp index b8884d5308..3238c3387b 100644 --- a/xbmc/interfaces/legacy/Dialog.cpp +++ b/xbmc/interfaces/legacy/Dialog.cpp @@ -392,10 +392,10 @@ namespace XBMCAddon const String& line3) throw (WindowException) { DelayedCallGuard dcguard(languageHook); - CGUIDialogProgress* pDialog= dlg; + CGUIDialogProgress* pDialog = dlg; if (pDialog == NULL) - throw WindowException("Error: Window is NULL, this is not possible :-)"); + throw WindowException("Dialog not created."); if (percent >= 0 && percent <= 100) { @@ -418,12 +418,16 @@ namespace XBMCAddon void DialogProgress::close() { DelayedCallGuard dcguard(languageHook); + if (dlg == NULL) + throw WindowException("Dialog not created."); dlg->Close(); open = false; } bool DialogProgress::iscanceled() { + if (dlg == NULL) + throw WindowException("Dialog not created."); return dlg->IsCanceled(); } @@ -463,11 +467,10 @@ namespace XBMCAddon void DialogProgressBG::update(int percent, const String& heading, const String& message) throw (WindowException) { DelayedCallGuard dcguard(languageHook); - CGUIDialogExtendedProgressBar* pDialog = dlg; CGUIDialogProgressBarHandle* pHandle = handle; - if (pDialog == NULL) - throw WindowException("Error: Window is NULL, this is not possible :-)"); + if (pHandle == NULL) + throw WindowException("Dialog not created."); if (percent >= 0 && percent <= 100) pHandle->SetPercentage((float)percent); @@ -480,12 +483,16 @@ namespace XBMCAddon void DialogProgressBG::close() { DelayedCallGuard dcguard(languageHook); + if (handle == NULL) + throw WindowException("Dialog not created."); handle->MarkFinished(); open = false; } bool DialogProgressBG::isFinished() { + if (handle == NULL) + throw WindowException("Dialog not created."); return handle->IsFinished(); } diff --git a/xbmc/interfaces/legacy/ListItem.cpp b/xbmc/interfaces/legacy/ListItem.cpp index a6cb1f9da4..aefea95daf 100644 --- a/xbmc/interfaces/legacy/ListItem.cpp +++ b/xbmc/interfaces/legacy/ListItem.cpp @@ -250,7 +250,7 @@ namespace XBMCAddon if (item->HasVideoInfoTag()) { std::ostringstream oss; - oss << item->GetVideoInfoTag()->GetDuration() / 60; + oss << item->GetVideoInfoTag()->GetDuration(); return oss.str(); } return "0"; @@ -354,7 +354,7 @@ namespace XBMCAddon else if (key == "sorttitle") item->GetVideoInfoTag()->m_strSortTitle = value; else if (key == "duration") - item->GetVideoInfoTag()->m_duration = CVideoInfoTag::GetDurationFromMinuteString(value); + item->GetVideoInfoTag()->m_duration = strtol(value.c_str(), NULL, 10); else if (key == "studio") item->GetVideoInfoTag()->m_studio = StringUtils::Split(value, g_advancedSettings.m_videoItemSeparator); else if (key == "tagline") diff --git a/xbmc/interfaces/legacy/ListItem.h b/xbmc/interfaces/legacy/ListItem.h index 50226c27a4..0d59172084 100644 --- a/xbmc/interfaces/legacy/ListItem.h +++ b/xbmc/interfaces/legacy/ListItem.h @@ -211,7 +211,7 @@ namespace XBMCAddon * - title : string (Big Fan) * - originaltitle : string (Big Fan) * - sorttitle : string (Big Fan) - * - duration : string (3:18) + * - duration : integer (245) - duration in seconds * - studio : string (Warner Bros.) * - tagline : string (An awesome movie) - short description of movie * - writer : string (Robert D. Siegel) diff --git a/xbmc/osx/OSXTextInputResponder.mm b/xbmc/osx/OSXTextInputResponder.mm index b77e56834e..aec7634537 100644 --- a/xbmc/osx/OSXTextInputResponder.mm +++ b/xbmc/osx/OSXTextInputResponder.mm @@ -28,7 +28,7 @@ #include "GUIUserMessages.h" #include "utils/log.h" #include "ApplicationMessenger.h" -#include "guilib/key.h" +#include "guilib/Key.h" #undef BOOL void SendKeyboardText(const char *text) diff --git a/xbmc/pictures/GUIViewStatePictures.cpp b/xbmc/pictures/GUIViewStatePictures.cpp index 20b682b916..dcb9f3be4d 100644 --- a/xbmc/pictures/GUIViewStatePictures.cpp +++ b/xbmc/pictures/GUIViewStatePictures.cpp @@ -73,10 +73,11 @@ std::string CGUIViewStateWindowPictures::GetLockType() std::string CGUIViewStateWindowPictures::GetExtensions() { + std::string extensions = g_advancedSettings.m_pictureExtensions; if (CSettings::Get().GetBool("pictures.showvideos")) - return g_advancedSettings.m_pictureExtensions+"|"+g_advancedSettings.m_videoExtensions; + extensions += "|" + g_advancedSettings.m_videoExtensions; - return g_advancedSettings.m_pictureExtensions; + return extensions; } VECSOURCES& CGUIViewStateWindowPictures::GetSources() diff --git a/xbmc/pictures/GUIViewStatePictures.h b/xbmc/pictures/GUIViewStatePictures.h index 53c1cca86d..e97a779c8c 100644 --- a/xbmc/pictures/GUIViewStatePictures.h +++ b/xbmc/pictures/GUIViewStatePictures.h @@ -27,10 +27,11 @@ class CGUIViewStateWindowPictures : public CGUIViewState public: CGUIViewStateWindowPictures(const CFileItemList& items); -protected: - virtual void SaveViewState(); virtual std::string GetLockType(); virtual std::string GetExtensions(); virtual VECSOURCES& GetSources(); + +protected: + virtual void SaveViewState(); }; diff --git a/xbmc/pictures/GUIWindowSlideShow.cpp b/xbmc/pictures/GUIWindowSlideShow.cpp index 0ce46565fc..4bffed30eb 100644 --- a/xbmc/pictures/GUIWindowSlideShow.cpp +++ b/xbmc/pictures/GUIWindowSlideShow.cpp @@ -45,6 +45,7 @@ #include "utils/log.h" #include "utils/TimeUtils.h" #include "interfaces/AnnouncementManager.h" +#include "pictures/GUIViewStatePictures.h" #include "pictures/PictureInfoTag.h" #include "pictures/PictureThumbLoader.h" @@ -1261,9 +1262,11 @@ void CGUIWindowSlideShow::AddItems(const std::string &strPath, path_set *recursi recursivePaths->insert(path); } - // fetch directory and sort accordingly CFileItemList items; - if (!CDirectory::GetDirectory(strPath, items, m_strExtensions.empty()?g_advancedSettings.m_pictureExtensions:m_strExtensions,DIR_FLAG_NO_FILE_DIRS,true)) + CGUIViewStateWindowPictures viewState(items); + + // fetch directory and sort accordingly + if (!CDirectory::GetDirectory(strPath, items, viewState.GetExtensions(), DIR_FLAG_NO_FILE_DIRS, true)) return; items.Sort(method, order, sortAttributes); diff --git a/xbmc/pvr/PVRDatabase.cpp b/xbmc/pvr/PVRDatabase.cpp index c1465e3f6f..2c2a1d80d5 100644 --- a/xbmc/pvr/PVRDatabase.cpp +++ b/xbmc/pvr/PVRDatabase.cpp @@ -74,11 +74,6 @@ void CPVRDatabase::CreateTables() // TODO use mapping table "iClientId integer, " - "iClientChannelNumber integer, " - "iClientSubChannelNumber integer, " - "sInputFormat varchar(32), " - "sStreamURL varchar(255), " - "iEncryptionSystem integer, " "idEpg integer" ")" @@ -238,7 +233,7 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) std::string strQuery = PrepareSQL("SELECT channels.idChannel, channels.iUniqueId, channels.bIsRadio, channels.bIsHidden, channels.bIsUserSetIcon, channels.bIsUserSetName, " "channels.sIconPath, channels.sChannelName, channels.bIsVirtual, channels.bEPGEnabled, channels.sEPGScraper, channels.iLastWatched, channels.iClientId, channels.bIsLocked, " - "channels.iClientChannelNumber, channels.iClientSubChannelNumber, channels.sInputFormat, channels.sInputFormat, channels.sStreamURL, channels.iEncryptionSystem, map_channelgroups_channels.iChannelNumber, channels.idEpg " + "map_channelgroups_channels.iChannelNumber, channels.idEpg " "FROM map_channelgroups_channels " "LEFT JOIN channels ON channels.idChannel = map_channelgroups_channels.idChannel " "WHERE map_channelgroups_channels.idGroup = %u", results.IsRadio() ? PVR_INTERNAL_GROUP_ID_RADIO : PVR_INTERNAL_GROUP_ID_TV); @@ -264,11 +259,6 @@ int CPVRDatabase::Get(CPVRChannelGroupInternal &results) channel->m_strEPGScraper = m_pDS->fv("sEPGScraper").get_asString(); channel->m_iLastWatched = (time_t) m_pDS->fv("iLastWatched").get_asInt(); channel->m_iClientId = m_pDS->fv("iClientId").get_asInt(); - channel->m_iClientChannelNumber.channel = m_pDS->fv("iClientChannelNumber").get_asInt(); - channel->m_iClientChannelNumber.subchannel = m_pDS->fv("iClientSubChannelNumber").get_asInt(); - channel->m_strInputFormat = m_pDS->fv("sInputFormat").get_asString(); - channel->m_strStreamURL = m_pDS->fv("sStreamURL").get_asString(); - channel->m_iClientEncryptionSystem = m_pDS->fv("iEncryptionSystem").get_asInt(); if (bIgnoreEpgDB) channel->m_iEpgId = -1; else @@ -740,11 +730,10 @@ bool CPVRDatabase::Persist(CPVRChannel &channel) strQuery = PrepareSQL("INSERT INTO channels (" "iUniqueId, bIsRadio, bIsHidden, bIsUserSetIcon, bIsUserSetName, bIsLocked, " "sIconPath, sChannelName, bIsVirtual, bEPGEnabled, sEPGScraper, iLastWatched, iClientId, " - "iClientChannelNumber, iClientSubChannelNumber, sInputFormat, sStreamURL, iEncryptionSystem, idEpg) " - "VALUES (%i, %i, %i, %i, %i, %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, '%s', '%s', %i, %i)", + "idEpg) " + "VALUES (%i, %i, %i, %i, %i, %i, '%s', '%s', %i, %i, '%s', %u, %i, %i)", channel.UniqueID(), (channel.IsRadio() ? 1 :0), (channel.IsHidden() ? 1 : 0), (channel.IsUserSetIcon() ? 1 : 0), (channel.IsUserSetName() ? 1 : 0), (channel.IsLocked() ? 1 : 0), channel.IconPath().c_str(), channel.ChannelName().c_str(), 0, (channel.EPGEnabled() ? 1 : 0), channel.EPGScraper().c_str(), channel.LastWatched(), channel.ClientID(), - channel.ClientChannelNumber(), channel.ClientSubChannelNumber(), channel.InputFormat().c_str(), channel.StreamURL().c_str(), channel.EncryptionSystem(), channel.EpgID()); } else @@ -753,11 +742,11 @@ bool CPVRDatabase::Persist(CPVRChannel &channel) strQuery = PrepareSQL("REPLACE INTO channels (" "iUniqueId, bIsRadio, bIsHidden, bIsUserSetIcon, bIsUserSetName, bIsLocked, " "sIconPath, sChannelName, bIsVirtual, bEPGEnabled, sEPGScraper, iLastWatched, iClientId, " - "iClientChannelNumber, iClientSubChannelNumber, sInputFormat, sStreamURL, iEncryptionSystem, idChannel, idEpg) " - "VALUES (%i, %i, %i, %i, %i, %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i, '%s', '%s', %i, %i, %i)", + "idChannel, idEpg) " + "VALUES (%i, %i, %i, %i, %i, %i, '%s', '%s', %i, %i, '%s', %u, %i, %i, %i)", channel.UniqueID(), (channel.IsRadio() ? 1 :0), (channel.IsHidden() ? 1 : 0), (channel.IsUserSetIcon() ? 1 : 0), (channel.IsUserSetName() ? 1 : 0), (channel.IsLocked() ? 1 : 0), channel.IconPath().c_str(), channel.ChannelName().c_str(), 0, (channel.EPGEnabled() ? 1 : 0), channel.EPGScraper().c_str(), channel.LastWatched(), channel.ClientID(), - channel.ClientChannelNumber(), channel.ClientSubChannelNumber(), channel.InputFormat().c_str(), channel.StreamURL().c_str(), channel.EncryptionSystem(), channel.ChannelID(), + channel.ChannelID(), channel.EpgID()); } diff --git a/xbmc/pvr/PVRGUIInfo.cpp b/xbmc/pvr/PVRGUIInfo.cpp index b178ec3a6b..796a0048a5 100644 --- a/xbmc/pvr/PVRGUIInfo.cpp +++ b/xbmc/pvr/PVRGUIInfo.cpp @@ -872,7 +872,6 @@ CEpgInfoTagPtr CPVRGUIInfo::GetPlayingTag() const void CPVRGUIInfo::UpdatePlayingTag(void) { CPVRChannelPtr currentChannel; - CPVRRecording recording; if (g_PVRManager.GetCurrentChannel(currentChannel)) { CEpgInfoTagPtr epgTag(GetPlayingTag()); @@ -896,10 +895,14 @@ void CPVRGUIInfo::UpdatePlayingTag(void) g_PVRManager.UpdateCurrentFile(); } } - else if (g_PVRClients->GetPlayingRecording(recording)) + else { - ResetPlayingTag(); - m_iDuration = recording.GetDuration() * 1000; + CPVRRecordingPtr recording(g_PVRClients->GetPlayingRecording()); + if (recording) + { + ResetPlayingTag(); + m_iDuration = recording->GetDuration() * 1000; + } } } diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp index 0f22fba993..9bfe8a10e8 100644 --- a/xbmc/pvr/PVRManager.cpp +++ b/xbmc/pvr/PVRManager.cpp @@ -44,6 +44,7 @@ #include "utils/JobManager.h" #include "interfaces/AnnouncementManager.h" #include "video/VideoDatabase.h" +#include "network/Network.h" #include "PVRManager.h" #include "PVRDatabase.h" @@ -1048,7 +1049,7 @@ bool CPVRManager::OpenLiveStream(const CFileItem &channel) return bReturn; } -bool CPVRManager::OpenRecordedStream(const CPVRRecording &tag) +bool CPVRManager::OpenRecordedStream(const CPVRRecordingPtr &tag) { bool bReturn = false; CSingleLock lock(m_critSection); @@ -1382,26 +1383,15 @@ bool CPVRManager::IsRecording(void) const bool CPVRManager::IsIdle(void) const { - if (!IsStarted()) - return true; - - if (IsRecording() || IsPlaying()) // pvr recording or playing? - { - return false; - } - else if (m_timers) // has active timers, etc.? + bool bReturn(true); + if (IsStarted()) { - const CDateTime now = CDateTime::GetUTCDateTime(); - const CDateTimeSpan idle(0, 0, CSettings::Get().GetInt("pvrpowermanagement.backendidletime"), 0); - - const CDateTime next = m_timers->GetNextEventTime(); - const CDateTimeSpan delta = next - now; - - if (delta <= idle) - return false; + if (IsRecording() || IsPlaying()) // pvr recording or playing? + bReturn = false; + else + bReturn = !IsNextEventWithinBackendIdleTime(); } - - return true; + return bReturn; } bool CPVRManager::CanSystemPowerdown(bool bAskUser /*= true*/) const @@ -1409,7 +1399,7 @@ bool CPVRManager::CanSystemPowerdown(bool bAskUser /*= true*/) const bool bReturn(true); if (IsStarted()) { - if (!m_addons->AllLocalBackendsIdle()) + if (!AllLocalBackendsIdle()) { if (bAskUser) { @@ -1424,6 +1414,62 @@ bool CPVRManager::CanSystemPowerdown(bool bAskUser /*= true*/) const return bReturn; } +bool CPVRManager::AllLocalBackendsIdle(void) const +{ + if (m_timers) + { + // active recording on local backend? + std::vector<CFileItemPtr> recordings = m_timers->GetActiveRecordings(); + for (std::vector<CFileItemPtr>::const_iterator timerIt = recordings.begin(); timerIt != recordings.end(); ++timerIt) + { + if (EventOccursOnLocalBackend(*timerIt)) + return false; + } + + // soon recording on local backend? + if (IsNextEventWithinBackendIdleTime()) + { + CFileItemPtr item = m_timers->GetNextActiveTimer(); + if (item.get() == NULL) + { + // Next event is due to automatic daily wakeup of PVR! + return false; + } + + if (EventOccursOnLocalBackend(item)) + return false; + } + } + return true; +} + +bool CPVRManager::EventOccursOnLocalBackend(const CFileItemPtr& item) const +{ + if (item && item->HasPVRTimerInfoTag()) + { + CPVRTimerInfoTag* tag = item->GetPVRTimerInfoTag(); + if (tag) + { + std::string hostname(m_addons->GetBackendHostnameByClientId(tag->m_iClientId)); + if (!hostname.empty() && g_application.getNetwork().IsLocalHost(hostname)) + return true; + } + } + return false; +} + +bool CPVRManager::IsNextEventWithinBackendIdleTime(void) const +{ + // timers going off soon? + const CDateTime now(CDateTime::GetUTCDateTime()); + const CDateTimeSpan idle( + 0, 0, CSettings::Get().GetInt("pvrpowermanagement.backendidletime"), 0); + const CDateTime next(m_timers->GetNextEventTime()); + const CDateTimeSpan delta(next - now); + + return (delta <= idle); +} + void CPVRManager::ShowPlayerInfo(int iTimeout) { if (IsStarted() && m_guiInfo) diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h index b50f5d7a42..bf0532cb42 100644 --- a/xbmc/pvr/PVRManager.h +++ b/xbmc/pvr/PVRManager.h @@ -28,6 +28,7 @@ #include "utils/JobManager.h" #include "utils/Observer.h" #include "interfaces/IAnnouncer.h" +#include "pvr/recordings/PVRRecording.h" class CGUIDialogProgressBarHandle; class CStopWatch; @@ -46,7 +47,6 @@ namespace PVR typedef boost::shared_ptr<PVR::CPVRChannel> CPVRChannelPtr; class CPVRChannelGroupsContainer; class CPVRChannelGroup; - class CPVRRecording; class CPVRRecordings; class CPVRTimers; class CPVRGUIInfo; @@ -319,7 +319,7 @@ namespace PVR * @param tag The recording to open. * @return True if the stream was opened, false otherwise. */ - bool OpenRecordedStream(const CPVRRecording &tag); + bool OpenRecordedStream(const CPVRRecordingPtr &tag); /*! * @brief Try to playback the given file item @@ -631,6 +631,11 @@ namespace PVR ManagerState GetState(void) const; void SetState(ManagerState state); + + bool AllLocalBackendsIdle(void) const; + bool EventOccursOnLocalBackend(const CFileItemPtr& item) const; + bool IsNextEventWithinBackendIdleTime(void) const; + /** @name containers */ //@{ CPVRChannelGroupsContainer * m_channelGroups; /*!< pointer to the channel groups container */ diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp index 06ff5b0b90..f327e15407 100644 --- a/xbmc/pvr/addons/PVRClient.cpp +++ b/xbmc/pvr/addons/PVRClient.cpp @@ -1365,15 +1365,13 @@ bool CPVRClient::GetPlayingChannel(CPVRChannelPtr &channel) const return false; } -bool CPVRClient::GetPlayingRecording(CPVRRecording &recording) const +CPVRRecordingPtr CPVRClient::GetPlayingRecording(void) const { CSingleLock lock(m_critSection); if (m_bReadyToUse && m_bIsPlayingRecording) - { - recording = m_playingRecording; - return true; - } - return false; + return m_playingRecording; + + return CPVRRecordingPtr(); } bool CPVRClient::OpenStream(const CPVRChannel &channel, bool bIsSwitchingChannel) @@ -1426,7 +1424,7 @@ bool CPVRClient::OpenStream(const CPVRChannel &channel, bool bIsSwitchingChannel return bReturn; } -bool CPVRClient::OpenStream(const CPVRRecording &recording) +bool CPVRClient::OpenStream(const CPVRRecordingPtr &recording) { bool bReturn(false); CloseStream(); @@ -1434,7 +1432,7 @@ bool CPVRClient::OpenStream(const CPVRRecording &recording) if (m_bReadyToUse && m_addonCapabilities.bSupportsRecordings) { PVR_RECORDING tag; - WriteClientRecordingInfo(recording, tag); + WriteClientRecordingInfo(*recording, tag); try { diff --git a/xbmc/pvr/addons/PVRClient.h b/xbmc/pvr/addons/PVRClient.h index 60f37a7ee1..58695cdda0 100644 --- a/xbmc/pvr/addons/PVRClient.h +++ b/xbmc/pvr/addons/PVRClient.h @@ -444,7 +444,7 @@ namespace PVR * @param recording The recording to open. * @return True if the stream has been opened succesfully, false otherwise. */ - bool OpenStream(const CPVRRecording &recording); + bool OpenStream(const CPVRRecordingPtr &recording); //@} /** @name PVR demultiplexer methods */ @@ -494,7 +494,7 @@ namespace PVR bool IsPlayingRecording(void) const; bool IsPlaying(void) const; bool GetPlayingChannel(CPVRChannelPtr &channel) const; - bool GetPlayingRecording(CPVRRecording &recording) const; + CPVRRecordingPtr GetPlayingRecording(void) const; static const char *ToString(const PVR_ERROR error); @@ -605,10 +605,10 @@ namespace PVR CCriticalSection m_critSection; - bool m_bIsPlayingTV; - CPVRChannelPtr m_playingChannel; - bool m_bIsPlayingRecording; - CPVRRecording m_playingRecording; + bool m_bIsPlayingTV; + CPVRChannelPtr m_playingChannel; + bool m_bIsPlayingRecording; + CPVRRecordingPtr m_playingRecording; ADDON::AddonVersion m_apiVersion; }; } diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index e87b5a3ca7..affe21638f 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -34,7 +34,8 @@ #include "pvr/recordings/PVRRecordings.h" #include "pvr/timers/PVRTimers.h" #include "cores/IPlayer.h" -#include "network/Network.h" + +#include <assert.h> using namespace ADDON; using namespace PVR; @@ -348,12 +349,10 @@ bool CPVRClients::GetPlayingChannel(CPVRChannelPtr &channel) const return false; } -bool CPVRClients::GetPlayingRecording(CPVRRecording &recording) const +CPVRRecordingPtr CPVRClients::GetPlayingRecording(void) const { PVR_CLIENT client; - if (GetPlayingClient(client)) - return client->GetPlayingRecording(recording); - return false; + return GetPlayingClient(client) ? client->GetPlayingRecording() : CPVRRecordingPtr(); } bool CPVRClients::HasTimerSupport(int iClientId) @@ -1193,18 +1192,20 @@ bool CPVRClients::OpenStream(const CPVRChannel &tag, bool bIsSwitchingChannel) return bReturn; } -bool CPVRClients::OpenStream(const CPVRRecording &tag) +bool CPVRClients::OpenStream(const CPVRRecordingPtr &tag) { + assert(tag.get()); + bool bReturn(false); CloseStream(); /* try to open the recording stream on the client */ PVR_CLIENT client; - if (GetConnectedClient(tag.m_iClientId, client) && + if (GetConnectedClient(tag->m_iClientId, client) && client->OpenStream(tag)) { CSingleLock lock(m_critSection); - m_playingClientId = tag.m_iClientId; + m_playingClientId = tag->m_iClientId; m_bIsPlayingRecording = true; m_strPlayingClientName = client->GetFriendlyName(); bReturn = true; @@ -1317,6 +1318,19 @@ bool CPVRClients::IsEncrypted(void) const return false; } +std::string CPVRClients::GetBackendHostnameByClientId(int iClientId) const +{ + PVR_CLIENT client; + std::string name; + + if (GetConnectedClient(iClientId, client)) + { + name = client->GetBackendHostname(); + } + + return name; +} + time_t CPVRClients::GetPlayingTime() const { PVR_CLIENT client; @@ -1356,32 +1370,3 @@ time_t CPVRClients::GetBufferTimeEnd() const return time; } -bool CPVRClients::NextEventWithinBackendIdleTime(const CPVRTimers& timers) -{ - // timers going off soon? - const CDateTime now(CDateTime::GetUTCDateTime()); - const CDateTimeSpan idle( - 0, 0, CSettings::Get().GetInt("pvrpowermanagement.backendidletime"), 0); - const CDateTime next(timers.GetNextEventTime()); - const CDateTimeSpan delta(next - now); - - return (delta <= idle); -} - -bool CPVRClients::AllLocalBackendsIdle() const -{ - PVR_CLIENTMAP clients; - GetConnectedClients(clients); - for (PVR_CLIENTMAP_CITR itr = clients.begin(); itr != clients.end(); itr++) - { - CPVRTimers timers; - PVR_ERROR ret = itr->second->GetTimers(&timers); - if (ret == PVR_ERROR_NOT_IMPLEMENTED || ret != PVR_ERROR_NO_ERROR) - continue; - - if (((timers.AmountActiveRecordings() > 0) || NextEventWithinBackendIdleTime(timers)) - && g_application.getNetwork().IsLocalHost(itr->second->GetBackendHostname())) - return false; - } - return true; -} diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h index 5b6753b7de..550244a928 100644 --- a/xbmc/pvr/addons/PVRClients.h +++ b/xbmc/pvr/addons/PVRClients.h @@ -288,14 +288,13 @@ namespace PVR * @param tag The recording to start playing. * @return True if the stream was opened successfully, false otherwise. */ - bool OpenStream(const CPVRRecording &tag); + bool OpenStream(const CPVRRecordingPtr &tag); /*! * @brief Get the recordings that is currently playing. - * @param recording A copy of the recording that is currently playing. - * @return True if a recording is playing, false otherwise. + * @return The recording that is currently playing, NULL otherwise. */ - bool GetPlayingRecording(CPVRRecording &recording) const; + CPVRRecordingPtr GetPlayingRecording(void) const; //@} @@ -546,11 +545,7 @@ namespace PVR bool GetPlayingClient(PVR_CLIENT &client) const; - /*! - * @brief Checks whether all local pvr backends (if any) are idle (no recording active, ...). - * @return True if all local backends are idle or no local backends are connected, false otherwise. - */ - bool AllLocalBackendsIdle() const; + std::string GetBackendHostnameByClientId(int iClientId) const; time_t GetPlayingTime() const; time_t GetBufferTimeStart() const; @@ -621,8 +616,6 @@ namespace PVR int GetClientId(const ADDON::AddonPtr client) const; - static bool NextEventWithinBackendIdleTime(const CPVRTimers& timers); - bool m_bChannelScanRunning; /*!< true when a channel scan is currently running, false otherwise */ bool m_bIsSwitchingChannels; /*!< true while switching channels */ int m_playingClientId; /*!< the ID of the client that is currently playing */ diff --git a/xbmc/pvr/channels/PVRChannel.cpp b/xbmc/pvr/channels/PVRChannel.cpp index 2e60f9b353..a0208b56c4 100644 --- a/xbmc/pvr/channels/PVRChannel.cpp +++ b/xbmc/pvr/channels/PVRChannel.cpp @@ -228,7 +228,6 @@ bool CPVRChannel::UpdateFromClient(const CPVRChannel &channel) m_strClientChannelName = channel.ClientChannelName(); UpdateEncryptionName(); - m_bChanged = true; SetChanged(); } diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp index 4aaa4e598c..6d9b428d43 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp @@ -75,52 +75,71 @@ bool CGUIDialogPVRChannelManager::OnActionMove(const CAction &action) { bool bReturn(false); int iActionId = action.GetID(); - if (GetFocusedControlID() == CONTROL_LIST_CHANNELS && - (iActionId == ACTION_MOVE_DOWN || iActionId == ACTION_MOVE_UP || - iActionId == ACTION_PAGE_DOWN || iActionId == ACTION_PAGE_UP || - iActionId == ACTION_MOUSE_MOVE)) // item should be selected on hover + + if (GetFocusedControlID() == CONTROL_LIST_CHANNELS) { - bReturn = true; - if (!m_bMovingMode) + if (iActionId == ACTION_MOUSE_MOVE) { - CGUIDialog::OnAction(action); int iSelected = m_viewControl.GetSelectedItem(); - if (iSelected != m_iSelected) + if (m_iSelected < iSelected) { - m_iSelected = iSelected; - SetData(m_iSelected); + iActionId = ACTION_MOVE_DOWN; + } + else if (m_iSelected > iSelected) + { + iActionId = ACTION_MOVE_UP; + } + else + { + return bReturn; } } - else + + if (iActionId == ACTION_MOVE_DOWN || iActionId == ACTION_MOVE_UP || + iActionId == ACTION_PAGE_DOWN || iActionId == ACTION_PAGE_UP || + iActionId == ACTION_FIRST_PAGE || iActionId == ACTION_LAST_PAGE) { - std::string strNumber; CGUIDialog::OnAction(action); + int iSelected = m_viewControl.GetSelectedItem(); - bool bMoveUp = iActionId == ACTION_PAGE_UP || iActionId == ACTION_MOVE_UP; - unsigned int iLines = bMoveUp ? abs(m_iSelected - m_viewControl.GetSelectedItem()) : 1; - bool bOutOfBounds = bMoveUp ? m_iSelected <= 0 : m_iSelected >= m_channelItems->Size() - 1; - if (bOutOfBounds) + bReturn = true; + if (!m_bMovingMode) { - bMoveUp = !bMoveUp; - iLines = m_channelItems->Size() - 1; + if (iSelected != m_iSelected) + { + m_iSelected = iSelected; + SetData(m_iSelected); + } } - - for (unsigned int iLine = 0; iLine < iLines; iLine++) + else { - unsigned int iNewSelect = bMoveUp ? m_iSelected - 1 : m_iSelected + 1; - if (m_channelItems->Get(iNewSelect)->GetProperty("Number").asString() != "-") + std::string strNumber; + + bool bMoveUp = iActionId == ACTION_PAGE_UP || iActionId == ACTION_MOVE_UP || iActionId == ACTION_FIRST_PAGE; + unsigned int iLines = bMoveUp ? abs(m_iSelected - iSelected) : 1; + bool bOutOfBounds = bMoveUp ? m_iSelected <= 0 : m_iSelected >= m_channelItems->Size() - 1; + if (bOutOfBounds) { - strNumber = StringUtils::Format("%i", m_iSelected+1); - m_channelItems->Get(iNewSelect)->SetProperty("Number", strNumber); - strNumber = StringUtils::Format("%i", iNewSelect+1); - m_channelItems->Get(m_iSelected)->SetProperty("Number", strNumber); + bMoveUp = !bMoveUp; + iLines = m_channelItems->Size() - 1; + } + for (unsigned int iLine = 0; iLine < iLines; iLine++) + { + unsigned int iNewSelect = bMoveUp ? m_iSelected - 1 : m_iSelected + 1; + if (m_channelItems->Get(iNewSelect)->GetProperty("Number").asString() != "-") + { + strNumber = StringUtils::Format("%i", m_iSelected+1); + m_channelItems->Get(iNewSelect)->SetProperty("Number", strNumber); + strNumber = StringUtils::Format("%i", iNewSelect+1); + m_channelItems->Get(m_iSelected)->SetProperty("Number", strNumber); + } + m_channelItems->Swap(iNewSelect, m_iSelected); + m_iSelected = iNewSelect; } - m_channelItems->Swap(iNewSelect, m_iSelected); - m_iSelected = iNewSelect; - } - m_viewControl.SetItems(*m_channelItems); - m_viewControl.SetSelectedItem(m_iSelected); + m_viewControl.SetItems(*m_channelItems); + m_viewControl.SetSelectedItem(m_iSelected); + } } } diff --git a/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp b/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp index bce27265a4..d29a3e20d0 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRGuideInfo.cpp @@ -176,7 +176,7 @@ bool CGUIDialogPVRGuideInfo::OnClickButtonSwitch(CGUIMessage &message) if (epgTag) { if (epgTag->HasRecording()) - ret = g_application.PlayFile(CFileItem(*epgTag->Recording())); + ret = g_application.PlayFile(CFileItem(epgTag->Recording())); else if (epgTag->HasPVRChannel()) ret = g_application.PlayFile(CFileItem(*epgTag->ChannelTag())); } diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp index 454455b096..bb1713c170 100644 --- a/xbmc/pvr/recordings/PVRRecording.cpp +++ b/xbmc/pvr/recordings/PVRRecording.cpp @@ -232,10 +232,7 @@ void CPVRRecording::UpdateMetadata(CVideoDatabase &db) if (!supportsPlayCount || !supportsLastPlayed) { if (!supportsPlayCount) - { - CFileItem pFileItem(*this); - m_playCount = db.GetPlayCount(pFileItem); - } + m_playCount = db.GetPlayCount(m_strFileNameAndPath); if (!supportsLastPlayed) db.GetResumeBookMark(m_strFileNameAndPath, m_resumePoint); diff --git a/xbmc/pvr/recordings/PVRRecording.h b/xbmc/pvr/recordings/PVRRecording.h index c9d9359651..0c14f6ed0b 100644 --- a/xbmc/pvr/recordings/PVRRecording.h +++ b/xbmc/pvr/recordings/PVRRecording.h @@ -84,6 +84,12 @@ namespace PVR CPVRRecording(void); CPVRRecording(const PVR_RECORDING &recording, unsigned int iClientId); + + private: + CPVRRecording(const CPVRRecording &tag); // intentionally not implemented. + CPVRRecording &operator =(const CPVRRecording &other); // intentionally not implemented. + + public: virtual ~CPVRRecording() {}; bool operator ==(const CPVRRecording& right) const; diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 14b1476b35..56eff347de 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -200,7 +200,7 @@ int CPVRRecordings::GetRecordings(CFileItemList* results) for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) { - CFileItemPtr pFileItem(new CFileItem(*it->second)); + CFileItemPtr pFileItem(new CFileItem(it->second)); results->Add(pFileItem); } @@ -236,7 +236,7 @@ bool CPVRRecordings::DeleteRecording(const CFileItem &item) return false; } - CPVRRecording *tag = (CPVRRecording *)item.GetPVRRecordingInfoTag(); + CPVRRecordingPtr tag = item.GetPVRRecordingInfoTag(); return tag->Delete(); } @@ -248,7 +248,7 @@ bool CPVRRecordings::RenameRecording(CFileItem &item, std::string &strNewName) return false; } - CPVRRecording* tag = item.GetPVRRecordingInfoTag(); + CPVRRecordingPtr tag = item.GetPVRRecordingInfoTag(); return tag->Rename(strNewName); } @@ -288,7 +288,7 @@ bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) if (!pItem->HasPVRRecordingInfoTag()) continue; - CPVRRecordingPtr recording = GetByFileItem(*pItem); + const CPVRRecordingPtr recording = pItem->GetPVRRecordingInfoTag(); if (recording) { recording->SetPlayCount(count); @@ -335,7 +335,7 @@ bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &ite if (m_database.IsOpen()) current->UpdateMetadata(m_database); - CFileItemPtr pFileItem(new CFileItem(*current)); + CFileItemPtr pFileItem(new CFileItem(current)); pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); pFileItem->SetPath(current->m_strFileNameAndPath); @@ -376,7 +376,7 @@ void CPVRRecordings::GetAll(CFileItemList &items) if (m_database.IsOpen()) current->UpdateMetadata(m_database); - CFileItemPtr pFileItem(new CFileItem(*current)); + CFileItemPtr pFileItem(new CFileItem(current)); pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false)); pFileItem->m_dateTime = current->RecordingTimeAsLocalTime(); pFileItem->SetPath(current->m_strFileNameAndPath); @@ -393,7 +393,7 @@ CFileItemPtr CPVRRecordings::GetById(unsigned int iId) const for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) { if (iId == it->second->m_iRecordingId) - item = CFileItemPtr(new CFileItem(*(it->second))); + item = CFileItemPtr(new CFileItem(it->second)); } return item; @@ -414,7 +414,7 @@ CFileItemPtr CPVRRecordings::GetByPath(const std::string &path) CPVRRecordingPtr current = it->second; if (URIUtils::PathEquals(path, current->m_strFileNameAndPath)) { - CFileItemPtr fileItem(new CFileItem(*current)); + CFileItemPtr fileItem(new CFileItem(current)); return fileItem; } } @@ -435,31 +435,25 @@ CPVRRecordingPtr CPVRRecordings::GetById(int iClientId, const std::string &strRe return retVal; } -CPVRRecordingPtr CPVRRecordings::GetByFileItem(const CFileItem &item) const -{ - const CPVRRecording *recording = item.GetPVRRecordingInfoTag(); - return GetById(recording->m_iClientId, recording->m_strRecordingId); -} - void CPVRRecordings::Clear() { CSingleLock lock(m_critSection); m_recordings.clear(); } -void CPVRRecordings::UpdateFromClient(const CPVRRecording &tag) +void CPVRRecordings::UpdateFromClient(const CPVRRecordingPtr &tag) { CSingleLock lock(m_critSection); - CPVRRecordingPtr newTag = GetById(tag.m_iClientId, tag.m_strRecordingId); + CPVRRecordingPtr newTag = GetById(tag->m_iClientId, tag->m_strRecordingId); if (newTag) { - newTag->Update(tag); + newTag->Update(*tag); } else { newTag = CPVRRecordingPtr(new CPVRRecording); - newTag->Update(tag); + newTag->Update(*tag); newTag->m_iRecordingId = ++m_iLastId; m_recordings.insert(std::make_pair(CPVRRecordingUid(newTag->m_iClientId, newTag->m_strRecordingId), newTag)); } diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h index 2c42e7dd56..9463887222 100644 --- a/xbmc/pvr/recordings/PVRRecordings.h +++ b/xbmc/pvr/recordings/PVRRecordings.h @@ -48,7 +48,6 @@ namespace PVR virtual const std::string GetDirectoryFromPath(const std::string &strPath, const std::string &strBase) const; virtual bool IsDirectoryMember(const std::string &strDirectory, const std::string &strEntryDirectory) const; virtual void GetSubDirectories(const std::string &strBase, CFileItemList *results); - CPVRRecordingPtr GetByFileItem(const CFileItem &item) const; /** * @brief recursively deletes all recordings in the specified directory @@ -65,7 +64,7 @@ namespace PVR int Load(); void Unload(); void Clear(); - void UpdateFromClient(const CPVRRecording &tag); + void UpdateFromClient(const CPVRRecordingPtr &tag); /** * @brief refresh the recordings list from the clients. diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp index 5adab71d41..025125c41a 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp @@ -549,7 +549,7 @@ bool CGUIWindowPVRBase::ActionPlayEpg(CFileItem *item) CFileItem fileItem; if (epgTag->HasRecording()) - fileItem = CFileItem(*epgTag->Recording()); + fileItem = CFileItem(epgTag->Recording()); else fileItem = CFileItem(*channel); diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp index ccaefc402d..8f20bad083 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp @@ -342,14 +342,17 @@ bool CGUIWindowPVRRecordings::OnContextButtonRename(CFileItem *item, CONTEXT_BUT if (button == CONTEXT_BUTTON_RENAME) { - bReturn = true; - - CPVRRecording *recording = item->GetPVRRecordingInfoTag(); - std::string strNewName = recording->m_strTitle; - if (CGUIKeyboardFactory::ShowAndGetInput(strNewName, g_localizeStrings.Get(19041), false)) + CPVRRecordingPtr recording = item->GetPVRRecordingInfoTag(); + if (recording) { - if (g_PVRRecordings->RenameRecording(*item, strNewName)) - Refresh(true); + bReturn = true; + + std::string strNewName = recording->m_strTitle; + if (CGUIKeyboardFactory::ShowAndGetInput(strNewName, g_localizeStrings.Get(19041), false)) + { + if (g_PVRRecordings->RenameRecording(*item, strNewName)) + Refresh(true); + } } } diff --git a/xbmc/utils/SaveFileStateJob.cpp b/xbmc/utils/SaveFileStateJob.cpp index 3be229bb38..813f6c2a19 100644 --- a/xbmc/utils/SaveFileStateJob.cpp +++ b/xbmc/utils/SaveFileStateJob.cpp @@ -105,7 +105,7 @@ bool CSaveFileStateJob::DoWork() // PVR: Set/clear recording's resume bookmark on the backend (if supported) if (m_item.HasPVRRecordingInfoTag()) { - PVR::CPVRRecording *recording = m_item.GetPVRRecordingInfoTag(); + PVR::CPVRRecordingPtr recording = m_item.GetPVRRecordingInfoTag(); recording->SetLastPlayedPosition(m_bookmark.timeInSeconds <= 0.0f ? 0 : (int)m_bookmark.timeInSeconds); recording->m_resumePoint = m_bookmark; } diff --git a/xbmc/utils/URIUtils.cpp b/xbmc/utils/URIUtils.cpp index 1127a9ac9c..5caa91ef5b 100644 --- a/xbmc/utils/URIUtils.cpp +++ b/xbmc/utils/URIUtils.cpp @@ -420,7 +420,7 @@ std::string URLDecodePath(const std::string& strPath) return StringUtils::Join(segments, "/"); } -std::string URIUtils::ChangeBasePath(const std::string &fromPath, const std::string &fromFile, const std::string &toPath) +std::string URIUtils::ChangeBasePath(const std::string &fromPath, const std::string &fromFile, const std::string &toPath, const bool &bAddPath /* = true */) { std::string toFile = fromFile; @@ -444,7 +444,10 @@ std::string URIUtils::ChangeBasePath(const std::string &fromPath, const std::str if (!IsDOSPath(fromPath) && IsDOSPath(toPath)) StringUtils::Replace(toFile, "/", "\\"); - return AddFileToFolder(toPath, toFile); + if (bAddPath) + return AddFileToFolder(toPath, toFile); + + return toFile; } CURL URIUtils::SubstitutePath(const CURL& url, bool reverse /* = false */) diff --git a/xbmc/utils/URIUtils.h b/xbmc/utils/URIUtils.h index dc280fc77b..8ddb2adf91 100644 --- a/xbmc/utils/URIUtils.h +++ b/xbmc/utils/URIUtils.h @@ -79,7 +79,7 @@ public: \param toPath the base path of the resulting URL \return the full path. */ - static std::string ChangeBasePath(const std::string &fromPath, const std::string &fromFile, const std::string &toPath); + static std::string ChangeBasePath(const std::string &fromPath, const std::string &fromFile, const std::string &toPath, const bool &bAddPath = true); static CURL SubstitutePath(const CURL& url, bool reverse = false); static std::string SubstitutePath(const std::string& strPath, bool reverse = false); diff --git a/xbmc/video/VideoDatabase.cpp b/xbmc/video/VideoDatabase.cpp index 5b2fa973ce..7560ffe01e 100644 --- a/xbmc/video/VideoDatabase.cpp +++ b/xbmc/video/VideoDatabase.cpp @@ -4759,10 +4759,9 @@ bool CVideoDatabase::GetPlayCounts(const std::string &strPath, CFileItemList &it return false; } -int CVideoDatabase::GetPlayCount(const CFileItem &item) +int CVideoDatabase::GetPlayCount(int iFileId) { - int id = GetFileId(item); - if (id < 0) + if (iFileId < 0) return 0; // not in db, so not watched try @@ -4771,7 +4770,7 @@ int CVideoDatabase::GetPlayCount(const CFileItem &item) if (NULL == m_pDB.get()) return -1; if (NULL == m_pDS.get()) return -1; - std::string strSQL = PrepareSQL("select playCount from files WHERE idFile=%i", id); + std::string strSQL = PrepareSQL("select playCount from files WHERE idFile=%i", iFileId); int count = 0; if (m_pDS->query(strSQL.c_str())) { @@ -4789,6 +4788,16 @@ int CVideoDatabase::GetPlayCount(const CFileItem &item) return -1; } +int CVideoDatabase::GetPlayCount(const std::string& strFilenameAndPath) +{ + return GetPlayCount(GetFileId(strFilenameAndPath)); +} + +int CVideoDatabase::GetPlayCount(const CFileItem &item) +{ + return GetPlayCount(GetFileId(item)); +} + void CVideoDatabase::UpdateFanart(const CFileItem &item, VIDEODB_CONTENT_TYPE type) { if (NULL == m_pDB.get()) return; diff --git a/xbmc/video/VideoDatabase.h b/xbmc/video/VideoDatabase.h index e1d8928ada..8012bd59c7 100644 --- a/xbmc/video/VideoDatabase.h +++ b/xbmc/video/VideoDatabase.h @@ -408,6 +408,13 @@ public: */ int GetPlayCount(const CFileItem &item); + /*! \brief Get the playcount of a filename and path + \param strFilenameAndPath filename and path to get the playcount for + \return the playcount of the item, or -1 on error + \sa SetPlayCount, IncrementPlayCount, GetPlayCounts + */ + int GetPlayCount(const std::string& strFilenameAndPath); + /*! \brief Update the last played time of an item Updates the last played date \param item CFileItem to update the last played time for @@ -868,6 +875,13 @@ private: */ bool LookupByFolders(const std::string &path, bool shows = false); + /*! \brief Get the playcount for a file id + \param iFileId file id to get the playcount for + \return the playcount of the item, or -1 on error + \sa SetPlayCount, IncrementPlayCount, GetPlayCounts + */ + int GetPlayCount(int iFileId); + virtual int GetMinSchemaVersion() const { return 60; }; virtual int GetSchemaVersion() const; virtual int GetExportVersion() const { return 1; }; diff --git a/xbmc/win32/WIN32Util.cpp b/xbmc/win32/WIN32Util.cpp index 7d5ea8863e..e3630e3647 100644 --- a/xbmc/win32/WIN32Util.cpp +++ b/xbmc/win32/WIN32Util.cpp @@ -772,8 +772,8 @@ bool CWIN32Util::EjectDrive(const char cDriveLetter) char VetoName[MAX_PATH]; bool bSuccess = false; - res = CM_Get_Parent(&DevInst, DevInst, 0); // disk's parent, e.g. the USB bridge, the SATA controller.... - res = CM_Get_DevNode_Status(&Status, &ProblemNumber, DevInst, 0); + CM_Get_Parent(&DevInst, DevInst, 0); // disk's parent, e.g. the USB bridge, the SATA controller.... + CM_Get_DevNode_Status(&Status, &ProblemNumber, DevInst, 0); for(int i=0;i<3;i++) { @@ -1387,8 +1387,14 @@ LONG CWIN32Util::UtilRegGetValue( const HKEY hKey, const char *const pcKey, DWOR { if (ppcBuffer) { - char *pcValue=*ppcBuffer; - if (!pcValue || !pdwSizeBuff || dwSize +dwSizeAdd > *pdwSizeBuff) pcValue= (char*)realloc(pcValue, dwSize +dwSizeAdd); + char *pcValue=*ppcBuffer, *pcValueTmp; + if (!pcValue || !pdwSizeBuff || dwSize +dwSizeAdd > *pdwSizeBuff) { + pcValueTmp = (char*)realloc(pcValue, dwSize +dwSizeAdd); + if(pcValueTmp != NULL) + { + pcValue = pcValueTmp; + } + } lRet= RegQueryValueEx(hKey,pcKey,NULL,NULL,(LPBYTE)pcValue,&dwSize); if ( lRet == ERROR_SUCCESS || *ppcBuffer ) *ppcBuffer= pcValue; diff --git a/xbmc/win32/XBMC_PC.cpp b/xbmc/win32/XBMC_PC.cpp index 41b1cca5b2..9593bdbc06 100644 --- a/xbmc/win32/XBMC_PC.cpp +++ b/xbmc/win32/XBMC_PC.cpp @@ -227,10 +227,9 @@ INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR commandLine, INT ) } #endif - HRESULT hr = E_FAIL; IMMDeviceEnumerator *pEnumerator = NULL; CMMNotificationClient cMMNC; - hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator); + HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator); if(SUCCEEDED(hr)) { pEnumerator->RegisterEndpointNotificationCallback(&cMMNC); diff --git a/xbmc/windowing/android/WinEventsAndroid.cpp b/xbmc/windowing/android/WinEventsAndroid.cpp index 8e1ba969bc..cce9b0df3c 100644 --- a/xbmc/windowing/android/WinEventsAndroid.cpp +++ b/xbmc/windowing/android/WinEventsAndroid.cpp @@ -220,7 +220,7 @@ bool CWinEventsAndroid::MessagePump() if (fabs(amount) >= ALMOST_ZERO) { - ret |= CInputManager::GetInstance().ProcessJoystickEvent(g_application.GetActiveWindowID(), + ret |= CInputManager::GetInstance().ProcessJoystickEvent(g_windowManager.GetActiveWindowID(), input_device.name, item, input_type, amount, holdTime); } } diff --git a/xbmc/windowing/osx/WinEventsIOS.mm b/xbmc/windowing/osx/WinEventsIOS.mm index ca54205719..4272a25cc7 100644 --- a/xbmc/windowing/osx/WinEventsIOS.mm +++ b/xbmc/windowing/osx/WinEventsIOS.mm @@ -71,7 +71,7 @@ bool CWinEventsIOS::MessagePump() unsigned int holdTime = pumpEvent.jbutton.holdTime; CLog::Log(LOGDEBUG,"CWinEventsIOS: Button press keyID = %i", wKeyID); - ret |= CInputManager::GetInstance().ProcessJoystickEvent(g_application.GetActiveWindowID(), joystickName, wKeyID, JACTIVE_BUTTON, fAmount, holdTime); + ret |= CInputManager::GetInstance().ProcessJoystickEvent(g_windowManager.GetActiveWindowID(), joystickName, wKeyID, JACTIVE_BUTTON, fAmount, holdTime); } else ret |= g_application.OnEvent(pumpEvent); |