diff options
52 files changed, 2731 insertions, 271 deletions
diff --git a/addons/library.xbmc.addon/libXBMC_addon.h b/addons/library.xbmc.addon/libXBMC_addon.h index c3ed54f5f7..df5c8bcb4b 100644 --- a/addons/library.xbmc.addon/libXBMC_addon.h +++ b/addons/library.xbmc.addon/libXBMC_addon.h @@ -166,19 +166,19 @@ namespace ADDON dlsym(m_libXBMC_addon, "XBMC_wake_on_lan"); if (XBMC_wake_on_lan == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } - XBMC_unknown_to_utf8 = (char* (*)(void* HANDLE, void* CB, const char* str)) + XBMC_unknown_to_utf8 = (const char* (*)(void* HANDLE, void* CB, const char* str)) dlsym(m_libXBMC_addon, "XBMC_unknown_to_utf8"); if (XBMC_unknown_to_utf8 == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } - XBMC_get_localized_string = (char* (*)(void* HANDLE, void* CB, int dwCode)) + XBMC_get_localized_string = (const char* (*)(void* HANDLE, void* CB, int dwCode)) dlsym(m_libXBMC_addon, "XBMC_get_localized_string"); if (XBMC_get_localized_string == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } - XBMC_free_string = (void (*)(void* HANDLE, void* CB, char* str)) + XBMC_free_string = (void (*)(void* HANDLE, void* CB, const char* str)) dlsym(m_libXBMC_addon, "XBMC_free_string"); if (XBMC_free_string == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } - XBMC_get_dvd_menu_language = (char* (*)(void* HANDLE, void* CB)) + XBMC_get_dvd_menu_language = (const char* (*)(void* HANDLE, void* CB)) dlsym(m_libXBMC_addon, "XBMC_get_dvd_menu_language"); if (XBMC_get_dvd_menu_language == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } @@ -318,7 +318,7 @@ namespace ADDON * @param str The string to translate. * @return The string translated to UTF8. Must be freed by calling FreeString() when done. */ - char* UnknownToUTF8(const char* str) + const char* UnknownToUTF8(const char* str) { return XBMC_unknown_to_utf8(m_Handle, m_Callbacks, str); } @@ -328,7 +328,7 @@ namespace ADDON * @param dwCode The code of the message to get. * @return The message. Must be freed by calling FreeString() when done. */ - char* GetLocalizedString(int dwCode) + const char* GetLocalizedString(int dwCode) { return XBMC_get_localized_string(m_Handle, m_Callbacks, dwCode); } @@ -338,7 +338,7 @@ namespace ADDON * @brief Get the DVD menu language. * @return The language. Must be freed by calling FreeString() when done. */ - char* GetDVDMenuLanguage() + const char* GetDVDMenuLanguage() { return XBMC_get_dvd_menu_language(m_Handle, m_Callbacks); } @@ -347,7 +347,7 @@ namespace ADDON * @brief Free the memory used by str * @param str The string to free */ - void FreeString(char* str) + void FreeString(const char* str) { return XBMC_free_string(m_Handle, m_Callbacks, str); } @@ -564,10 +564,10 @@ namespace ADDON bool (*XBMC_get_setting)(void *HANDLE, void* CB, const char* settingName, void *settingValue); void (*XBMC_queue_notification)(void *HANDLE, void* CB, const queue_msg_t type, const char *msg); bool (*XBMC_wake_on_lan)(void *HANDLE, void* CB, const char* mac); - char* (*XBMC_unknown_to_utf8)(void *HANDLE, void* CB, const char* str); - char* (*XBMC_get_localized_string)(void *HANDLE, void* CB, int dwCode); - char* (*XBMC_get_dvd_menu_language)(void *HANDLE, void* CB); - void (*XBMC_free_string)(void *HANDLE, void* CB, char* str); + const char* (*XBMC_unknown_to_utf8)(void *HANDLE, void* CB, const char* str); + const char* (*XBMC_get_localized_string)(void *HANDLE, void* CB, int dwCode); + const char* (*XBMC_get_dvd_menu_language)(void *HANDLE, void* CB); + void (*XBMC_free_string)(void *HANDLE, void* CB, const char* str); void* (*XBMC_open_file)(void *HANDLE, void* CB, const char* strFileName, unsigned int flags); void* (*XBMC_open_file_for_write)(void *HANDLE, void* CB, const char* strFileName, bool bOverWrite); ssize_t (*XBMC_read_file)(void *HANDLE, void* CB, void* file, void* lpBuf, size_t uiBufSize); diff --git a/addons/library.xbmc.gui/libXBMC_gui.h b/addons/library.xbmc.gui/libXBMC_gui.h index 72f732f0c9..8dbc38b8f6 100644 --- a/addons/library.xbmc.gui/libXBMC_gui.h +++ b/addons/library.xbmc.gui/libXBMC_gui.h @@ -36,13 +36,14 @@ typedef void* GUIHANDLE; #endif /* current ADDONGUI API version */ -#define XBMC_GUI_API_VERSION "5.7.0" +#define XBMC_GUI_API_VERSION "5.8.0" /* min. ADDONGUI API version */ -#define XBMC_GUI_MIN_API_VERSION "5.3.0" +#define XBMC_GUI_MIN_API_VERSION "5.8.0" #define ADDON_ACTION_PREVIOUS_MENU 10 #define ADDON_ACTION_CLOSE_DIALOG 51 +#define ADDON_ACTION_NAV_BACK 92 class CAddonGUIWindow; class CAddonGUISpinControl; @@ -50,6 +51,8 @@ class CAddonGUIRadioButton; class CAddonGUIProgressControl; class CAddonListItem; class CAddonGUIRenderingControl; +class CAddonGUISliderControl; +class CAddonGUISettingsSliderControl; class CHelper_libXBMC_gui { @@ -169,6 +172,125 @@ public: dlsym(m_libXBMC_gui, "GUI_control_release_rendering"); if (GUI_control_release_rendering == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + GUI_control_get_slider = (CAddonGUISliderControl* (*)(void *HANDLE, void *CB, CAddonGUIWindow *window, int controlId)) + dlsym(m_libXBMC_gui, "GUI_control_get_slider"); + if (GUI_control_get_slider == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_control_release_slider = (void (*)(CAddonGUISliderControl* p)) + dlsym(m_libXBMC_gui, "GUI_control_release_slider"); + if (GUI_control_release_slider == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_control_get_settings_slider = (CAddonGUISettingsSliderControl* (*)(void *HANDLE, void *CB, CAddonGUIWindow *window, int controlId)) + dlsym(m_libXBMC_gui, "GUI_control_get_settings_slider"); + if (GUI_control_get_settings_slider == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_control_release_settings_slider = (void (*)(CAddonGUISettingsSliderControl* p)) + dlsym(m_libXBMC_gui, "GUI_control_release_settings_slider"); + if (GUI_control_release_settings_slider == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_get_input_with_head = (bool (*)(void *HANDLE, void *CB, char &aTextString, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_get_input_with_head"); + if (GUI_dialog_keyboard_show_and_get_input_with_head == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_get_input = (bool (*)(void *HANDLE, void *CB, char &aTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_get_input"); + if (GUI_dialog_keyboard_show_and_get_input == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_get_new_password_with_head = (bool (*)(void *HANDLE, void *CB, char &newPassword, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_get_new_password_with_head"); + if (GUI_dialog_keyboard_show_and_get_new_password_with_head == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_get_new_password = (bool (*)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_get_new_password"); + if (GUI_dialog_keyboard_show_and_get_new_password == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_verify_new_password_with_head = (bool (*)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_verify_new_password_with_head"); + if (GUI_dialog_keyboard_show_and_verify_new_password_with_head == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_verify_new_password = (bool (*)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_verify_new_password"); + if (GUI_dialog_keyboard_show_and_verify_new_password == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_verify_password = (int (*)(void *HANDLE, void *CB, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_verify_password"); + if (GUI_dialog_keyboard_show_and_verify_password == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_show_and_get_filter = (bool (*)(void *HANDLE, void *CB, char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_show_and_get_filter"); + if (GUI_dialog_keyboard_show_and_get_filter == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_send_text_to_active_keyboard = (bool (*)(void *HANDLE, void *CB, const char *aTextString, bool closeKeyboard)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_send_text_to_active_keyboard"); + if (GUI_dialog_keyboard_send_text_to_active_keyboard == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_keyboard_is_activated = (bool (*)(void *HANDLE, void *CB)) + dlsym(m_libXBMC_gui, "GUI_dialog_keyboard_is_activated"); + if (GUI_dialog_keyboard_is_activated == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_verify_new_password = (bool (*)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_verify_new_password"); + if (GUI_dialog_numeric_show_and_verify_new_password == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_verify_password = (int (*)(void *HANDLE, void *CB, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_verify_password"); + if (GUI_dialog_numeric_show_and_verify_password == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_verify_input = (bool (*)(void *HANDLE, void *CB, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_verify_input"); + if (GUI_dialog_numeric_show_and_verify_input == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_get_time = (bool (*)(void *HANDLE, void *CB, tm &time, const char *strHeading)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_get_time"); + if (GUI_dialog_numeric_show_and_get_time == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_get_date = (bool (*)(void *HANDLE, void *CB, tm &date, const char *strHeading)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_get_date"); + if (GUI_dialog_numeric_show_and_get_date == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_get_ipaddress = (bool (*)(void *HANDLE, void *CB, char &IPAddress, unsigned int iMaxStringSize, const char *strHeading)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_get_ipaddress"); + if (GUI_dialog_numeric_show_and_get_ipaddress == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_get_number = (bool (*)(void *HANDLE, void *CB, char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_get_number"); + if (GUI_dialog_numeric_show_and_get_number == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_numeric_show_and_get_seconds = (bool (*)(void *HANDLE, void *CB, char &strTime, unsigned int iMaxStringSize, const char *strHeading)) + dlsym(m_libXBMC_gui, "GUI_dialog_numeric_show_and_get_seconds"); + if (GUI_dialog_numeric_show_and_get_seconds == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_filebrowser_show_and_get_file = (bool (*)(void *HANDLE, void *CB, const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList)) + dlsym(m_libXBMC_gui, "GUI_dialog_filebrowser_show_and_get_file"); + if (GUI_dialog_filebrowser_show_and_get_file == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_ok_show_and_get_input_single_text = (void (*)(void *HANDLE, void *CB, const char *heading, const char *text)) + dlsym(m_libXBMC_gui, "GUI_dialog_ok_show_and_get_input_single_text"); + if (GUI_dialog_ok_show_and_get_input_single_text == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_ok_show_and_get_input_line_text = (void (*)(void *HANDLE, void *CB, const char *heading, const char *line0, const char *line1, const char *line2)) + dlsym(m_libXBMC_gui, "GUI_dialog_ok_show_and_get_input_line_text"); + if (GUI_dialog_ok_show_and_get_input_line_text == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_yesno_show_and_get_input_singletext = (bool (*)(void *HANDLE, void *CB, const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel)) + dlsym(m_libXBMC_gui, "GUI_dialog_yesno_show_and_get_input_singletext"); + if (GUI_dialog_yesno_show_and_get_input_singletext == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_yesno_show_and_get_input_linetext = (bool (*)(void *HANDLE, void *CB, const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel)) + dlsym(m_libXBMC_gui, "GUI_dialog_yesno_show_and_get_input_linetext"); + if (GUI_dialog_yesno_show_and_get_input_linetext == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_yesno_show_and_get_input_linebuttontext = (bool (*)(void *HANDLE, void *CB, const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel)) + dlsym(m_libXBMC_gui, "GUI_dialog_yesno_show_and_get_input_linebuttontext"); + if (GUI_dialog_yesno_show_and_get_input_linebuttontext == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_text_viewer = (void (*)(void *hdl, void *cb, const char *heading, const char *text)) + dlsym(m_libXBMC_gui, "GUI_dialog_text_viewer"); + if (GUI_dialog_text_viewer == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GUI_dialog_select = (int (*)(void *hdl, void *cb, const char *heading, const char *entries[], unsigned int size, int selected)) + dlsym(m_libXBMC_gui, "GUI_dialog_select"); + if (GUI_dialog_select == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } m_Callbacks = GUI_register_me(m_Handle); return m_Callbacks != NULL; @@ -259,6 +381,177 @@ public: return GUI_control_release_rendering(p); } + CAddonGUISliderControl* Control_getSlider(CAddonGUIWindow *window, int controlId) + { + return GUI_control_get_slider(m_Handle, m_Callbacks, window, controlId); + } + + void Control_releaseSlider(CAddonGUISliderControl* p) + { + return GUI_control_release_slider(p); + } + + CAddonGUISettingsSliderControl* Control_getSettingsSlider(CAddonGUIWindow *window, int controlId) + { + return GUI_control_get_settings_slider(m_Handle, m_Callbacks, window, controlId); + } + + void Control_releaseSettingsSlider(CAddonGUISettingsSliderControl* p) + { + return GUI_control_release_settings_slider(p); + } + + /*! @name GUI Keyboard functions */ + //@{ + bool Dialog_Keyboard_ShowAndGetInput(char &strText, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_get_input_with_head(m_Handle, m_Callbacks, strText, iMaxStringSize, strHeading, allowEmptyResult, hiddenInput, autoCloseMs); + } + + bool Dialog_Keyboard_ShowAndGetInput(char &strText, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_get_input(m_Handle, m_Callbacks, strText, iMaxStringSize, allowEmptyResult, autoCloseMs); + } + + bool Dialog_Keyboard_ShowAndGetNewPassword(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_get_new_password_with_head(m_Handle, m_Callbacks, strNewPassword, iMaxStringSize, strHeading, allowEmptyResult, autoCloseMs); + } + + bool Dialog_Keyboard_ShowAndGetNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_get_new_password(m_Handle, m_Callbacks, strNewPassword, iMaxStringSize, autoCloseMs); + } + + bool Dialog_Keyboard_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_verify_new_password_with_head(m_Handle, m_Callbacks, strNewPassword, iMaxStringSize, strHeading, allowEmptyResult, autoCloseMs); + } + + bool Dialog_Keyboard_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_verify_new_password(m_Handle, m_Callbacks, strNewPassword, iMaxStringSize, autoCloseMs); + } + + int Dialog_Keyboard_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_verify_password(m_Handle, m_Callbacks, strPassword, iMaxStringSize, strHeading, iRetries, autoCloseMs); + } + + bool Dialog_Keyboard_ShowAndGetFilter(char &strText, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs = 0) + { + return GUI_dialog_keyboard_show_and_get_filter(m_Handle, m_Callbacks, strText, iMaxStringSize, searching, autoCloseMs); + } + + bool Dialog_Keyboard_SendTextToActiveKeyboard(const char *aTextString, bool closeKeyboard = false) + { + return GUI_dialog_keyboard_send_text_to_active_keyboard(m_Handle, m_Callbacks, aTextString, closeKeyboard); + } + + bool Dialog_Keyboard_isKeyboardActivated() + { + return GUI_dialog_keyboard_is_activated(m_Handle, m_Callbacks); + } + //@} + + /*! @name GUI Numeric functions */ + //@{ + bool Dialog_Numeric_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize) + { + return GUI_dialog_numeric_show_and_verify_new_password(m_Handle, m_Callbacks, strNewPassword, iMaxStringSize); + } + + int Dialog_Numeric_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries) + { + return GUI_dialog_numeric_show_and_verify_password(m_Handle, m_Callbacks, strPassword, iMaxStringSize, strHeading, iRetries); + } + + bool Dialog_Numeric_ShowAndVerifyInput(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput) + { + return GUI_dialog_numeric_show_and_verify_input(m_Handle, m_Callbacks, strPassword, iMaxStringSize, strHeading, bGetUserInput); + } + + bool Dialog_Numeric_ShowAndGetTime(tm &time, const char *strHeading) + { + return GUI_dialog_numeric_show_and_get_time(m_Handle, m_Callbacks, time, strHeading); + } + + bool Dialog_Numeric_ShowAndGetDate(tm &date, const char *strHeading) + { + return GUI_dialog_numeric_show_and_get_date(m_Handle, m_Callbacks, date, strHeading); + } + + bool Dialog_Numeric_ShowAndGetIPAddress(char &strIPAddress, unsigned int iMaxStringSize, const char *strHeading) + { + return GUI_dialog_numeric_show_and_get_ipaddress(m_Handle, m_Callbacks, strIPAddress, iMaxStringSize, strHeading); + } + + bool Dialog_Numeric_ShowAndGetNumber(char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs = 0) + { + return GUI_dialog_numeric_show_and_get_number(m_Handle, m_Callbacks, strInput, iMaxStringSize, strHeading, iAutoCloseTimeoutMs = 0); + } + + bool Dialog_Numeric_ShowAndGetSeconds(char &strTime, unsigned int iMaxStringSize, const char *strHeading) + { + return GUI_dialog_numeric_show_and_get_seconds(m_Handle, m_Callbacks, strTime, iMaxStringSize, strHeading); + } + //@} + + /*! @name GUI File browser functions */ + //@{ + bool Dialog_FileBrowser_ShowAndGetFile(const char *directory, const char *mask, const char *heading, char &strPath, unsigned int iMaxStringSize, bool useThumbs = false, bool useFileDirectories = false, bool singleList = false) + { + return GUI_dialog_filebrowser_show_and_get_file(m_Handle, m_Callbacks, directory, mask, heading, strPath, iMaxStringSize, useThumbs, useFileDirectories, singleList); + } + //@} + + /*! @name GUI OK Dialog functions */ + //@{ + void Dialog_OK_ShowAndGetInput(const char *heading, const char *text) + { + GUI_dialog_ok_show_and_get_input_single_text(m_Handle, m_Callbacks, heading, text); + } + + void Dialog_OK_ShowAndGetInput(const char *heading, const char *line0, const char *line1, const char *line2) + { + GUI_dialog_ok_show_and_get_input_line_text(m_Handle, m_Callbacks, heading, line0, line1, line2); + } + //@} + + /*! @name GUI Yes No Dialog functions */ + //@{ + bool Dialog_YesNo_ShowAndGetInput(const char *heading, const char *text, bool& bCanceled, const char *noLabel = "", const char *yesLabel = "") + { + return GUI_dialog_yesno_show_and_get_input_singletext(m_Handle, m_Callbacks, heading, text, bCanceled, noLabel, yesLabel); + } + + bool Dialog_YesNo_ShowAndGetInput(const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel = "", const char *yesLabel = "") + { + return GUI_dialog_yesno_show_and_get_input_linetext(m_Handle, m_Callbacks, heading, line0, line1, line2, noLabel, yesLabel); + } + + bool Dialog_YesNo_ShowAndGetInput(const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel = "", const char *yesLabel = "") + { + return GUI_dialog_yesno_show_and_get_input_linebuttontext(m_Handle, m_Callbacks, heading, line0, line1, line2, bCanceled, noLabel, yesLabel); + } + //@} + + /*! @name GUI Text viewer Dialog */ + //@{ + void Dialog_TextViewer(const char *heading, const char *text) + { + return GUI_dialog_text_viewer(m_Handle, m_Callbacks, heading, text); + } + //@} + + /*! @name GUI select Dialog */ + //@{ + int Dialog_Select(const char *heading, const char *entries[], unsigned int size, int selected = -1) + { + return GUI_dialog_select(m_Handle, m_Callbacks, heading, entries, size, selected); + } + //@} + protected: void* (*GUI_register_me)(void *HANDLE); void (*GUI_unregister_me)(void *HANDLE, void* CB); @@ -279,6 +572,36 @@ protected: void (*GUI_ListItem_destroy)(CAddonListItem* p); CAddonGUIRenderingControl* (*GUI_control_get_rendering)(void *HANDLE, void* CB, CAddonGUIWindow *window, int controlId); void (*GUI_control_release_rendering)(CAddonGUIRenderingControl* p); + CAddonGUISliderControl* (*GUI_control_get_slider)(void *HANDLE, void* CB, CAddonGUIWindow *window, int controlId); + void (*GUI_control_release_slider)(CAddonGUISliderControl* p); + CAddonGUISettingsSliderControl* (*GUI_control_get_settings_slider)(void *HANDLE, void* CB, CAddonGUIWindow *window, int controlId); + void (*GUI_control_release_settings_slider)(CAddonGUISettingsSliderControl* p); + bool (*GUI_dialog_keyboard_show_and_get_input_with_head)(void *HANDLE, void *CB, char &aTextString, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs); + bool (*GUI_dialog_keyboard_show_and_get_input)(void *HANDLE, void *CB, char &aTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs); + bool (*GUI_dialog_keyboard_show_and_get_new_password_with_head)(void *HANDLE, void *CB, char &newPassword, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, unsigned int autoCloseMs); + bool (*GUI_dialog_keyboard_show_and_get_new_password)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); + bool (*GUI_dialog_keyboard_show_and_verify_new_password_with_head)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, unsigned int autoCloseMs); + bool (*GUI_dialog_keyboard_show_and_verify_new_password)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); + int (*GUI_dialog_keyboard_show_and_verify_password)(void *HANDLE, void *CB, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs); + bool (*GUI_dialog_keyboard_show_and_get_filter)(void *HANDLE, void *CB, char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs); + bool (*GUI_dialog_keyboard_send_text_to_active_keyboard)(void *HANDLE, void *CB, const char *aTextString, bool closeKeyboard); + bool (*GUI_dialog_keyboard_is_activated)(void *HANDLE, void *CB); + bool (*GUI_dialog_numeric_show_and_verify_new_password)(void *HANDLE, void *CB, char &strNewPassword, unsigned int iMaxStringSize); + int (*GUI_dialog_numeric_show_and_verify_password)(void *HANDLE, void *CB, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries); + bool (*GUI_dialog_numeric_show_and_verify_input)(void *HANDLE, void *CB, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput); + bool (*GUI_dialog_numeric_show_and_get_time)(void *HANDLE, void *CB, tm &time, const char *strHeading); + bool (*GUI_dialog_numeric_show_and_get_date)(void *HANDLE, void *CB, tm &date, const char *strHeading); + bool (*GUI_dialog_numeric_show_and_get_ipaddress)(void *HANDLE, void *CB, char &IPAddress, unsigned int iMaxStringSize, const char *strHeading); + bool (*GUI_dialog_numeric_show_and_get_number)(void *HANDLE, void *CB, char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs); + bool (*GUI_dialog_numeric_show_and_get_seconds)(void *HANDLE, void *CB, char &strTime, unsigned int iMaxStringSize, const char *strHeading); + bool (*GUI_dialog_filebrowser_show_and_get_file)(void *HANDLE, void *CB, const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList); + void (*GUI_dialog_ok_show_and_get_input_single_text)(void *HANDLE, void *CB, const char *heading, const char *text); + void (*GUI_dialog_ok_show_and_get_input_line_text)(void *HANDLE, void *CB, const char *heading, const char *line0, const char *line1, const char *line2); + bool (*GUI_dialog_yesno_show_and_get_input_singletext)(void *HANDLE, void *CB, const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel); + bool (*GUI_dialog_yesno_show_and_get_input_linetext)(void *HANDLE, void *CB, const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel); + bool (*GUI_dialog_yesno_show_and_get_input_linebuttontext)(void *HANDLE, void *CB, const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel); + void (*GUI_dialog_text_viewer)(void *hdl, void *cb, const char *heading, const char *text); + int (*GUI_dialog_select)(void *hdl, void *cb, const char *heading, const char *entries[], unsigned int size, int selected); private: void *m_libXBMC_gui; @@ -350,6 +673,67 @@ private: void *m_cb; }; +class CAddonGUISliderControl +{ +public: + CAddonGUISliderControl(void *hdl, void *cb, CAddonGUIWindow *window, int controlId); + virtual ~CAddonGUISliderControl(void) {} + + virtual void SetVisible(bool yesNo); + virtual std::string GetDescription() const; + + virtual void SetIntRange(int iStart, int iEnd); + virtual void SetIntValue(int iValue); + virtual int GetIntValue() const; + virtual void SetIntInterval(int iInterval); + + virtual void SetPercentage(float fPercent); + virtual float GetPercentage() const; + + virtual void SetFloatRange(float fStart, float fEnd); + virtual void SetFloatValue(float fValue); + virtual float GetFloatValue() const; + virtual void SetFloatInterval(float fInterval); + +private: + CAddonGUIWindow *m_Window; + int m_ControlId; + GUIHANDLE m_SliderHandle; + void *m_Handle; + void *m_cb; +}; + +class CAddonGUISettingsSliderControl +{ +public: + CAddonGUISettingsSliderControl(void *hdl, void *cb, CAddonGUIWindow *window, int controlId); + virtual ~CAddonGUISettingsSliderControl(void) {} + + virtual void SetVisible(bool yesNo); + virtual void SetText(const char *label); + virtual std::string GetDescription() const; + + virtual void SetIntRange(int iStart, int iEnd); + virtual void SetIntValue(int iValue); + virtual int GetIntValue() const; + virtual void SetIntInterval(int iInterval); + + virtual void SetPercentage(float fPercent); + virtual float GetPercentage() const; + + virtual void SetFloatRange(float fStart, float fEnd); + virtual void SetFloatValue(float fValue); + virtual float GetFloatValue() const; + virtual void SetFloatInterval(float fInterval); + +private: + CAddonGUIWindow *m_Window; + int m_ControlId; + GUIHANDLE m_SettingsSliderHandle; + void *m_Handle; + void *m_cb; +}; + class CAddonListItem { friend class CAddonGUIWindow; @@ -383,6 +767,8 @@ friend class CAddonGUISpinControl; friend class CAddonGUIRadioButton; friend class CAddonGUIProgressControl; friend class CAddonGUIRenderingControl; +friend class CAddonGUISliderControl; +friend class CAddonGUISettingsSliderControl; public: CAddonGUIWindow(void *hdl, void *cb, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog); diff --git a/addons/skin.confluence/720p/DialogPVRChannelManager.xml b/addons/skin.confluence/720p/DialogPVRChannelManager.xml index 2bc8cda80f..b3130fe46f 100644 --- a/addons/skin.confluence/720p/DialogPVRChannelManager.xml +++ b/addons/skin.confluence/720p/DialogPVRChannelManager.xml @@ -245,16 +245,21 @@ </focusedlayout> </control> </control> - <control type="group" id="9002"> - <control type="group"> + <control type="group"> + <control type="grouplist" id="9002"> <left>490</left> - <top>70</top> - <control type="label"> + <top>75</top> + <onleft>60</onleft> + <onright>9000</onright> + <onup>34</onup> + <ondown>30</ondown> + <itemgap>5</itemgap> + <control type="label" id="9001"> <description>channel options Header</description> <left>0</left> <top>0</top> <width>380</width> - <height>20</height> + <height>25</height> <font>font12</font> <label>$LOCALIZE[31511]</label> <align>left</align> @@ -265,9 +270,9 @@ <control type="radiobutton" id="7"> <description>Channel activated</description> <left>0</left> - <top>25</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> <textcolor>white</textcolor> <focusedcolor>white</focusedcolor> @@ -278,17 +283,13 @@ <texturenofocus border="5">button-nofocus.png</texturenofocus> <pulseonselect>no</pulseonselect> <label>19074</label> - <onleft>60</onleft> - <onright>9000</onright> - <onup>34</onup> - <ondown>8</ondown> </control> <control type="edit" id="8"> <description>Channel name</description> <left>0</left> - <top>75</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> <textcolor>white</textcolor> <focusedcolor>white</focusedcolor> @@ -296,41 +297,43 @@ <texturefocus border="5">button-focus2.png</texturefocus> <texturenofocus border="5">button-nofocus.png</texturenofocus> <label>19201</label> - <onright>9000</onright> - <onleft>60</onleft> - <onup>7</onup> - <ondown>9</ondown> </control> - <control type="button" id="9"> - <description>Channel logo Button</description> + <control type="group" id="9005"> <left>0</left> - <top>125</top> + <top>0</top> <width>380</width> - <height>45</height> - <font>font12</font> - <texturefocus border="5">button-focus2.png</texturefocus> - <texturenofocus border="5">button-nofocus.png</texturenofocus> - <label>19202</label> - <onleft>60</onleft> - <onright>9000</onright> - <onup>8</onup> - <ondown>12</ondown> - </control> - <control type="image" id="10"> - <description>Current Channel Icon</description> - <left>337</left> - <top>128</top> - <width>39</width> - <height>39</height> - <aspectratio>keep</aspectratio> - <info>ListItem.Property(Icon)</info> + <height>40</height> + <control type="button" id="9"> + <description>Channel logo Button</description> + <left>0</left> + <top>0</top> + <width>380</width> + <height>40</height> + <font>font12</font> + <texturefocus border="5">button-focus2.png</texturefocus> + <texturenofocus border="5">button-nofocus.png</texturenofocus> + <label>19202</label> + <onleft>60</onleft> + <onright>9000</onright> + <onup>8</onup> + <ondown>12</ondown> + </control> + <control type="image"> + <description>Current Channel Icon</description> + <left>340</left> + <top>3</top> + <width>34</width> + <height>34</height> + <aspectratio>keep</aspectratio> + <info>ListItem.Property(Icon)</info> + </control> </control> <control type="radiobutton" id="12"> <description>EPG activated</description> <left>0</left> - <top>175</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> <textcolor>white</textcolor> <focusedcolor>white</focusedcolor> @@ -341,32 +344,24 @@ <texturenofocus border="5">button-nofocus.png</texturenofocus> <pulseonselect>no</pulseonselect> <label>19206</label> - <onleft>60</onleft> - <onright>9000</onright> - <onup>9</onup> - <ondown>13</ondown> </control> <control type="spincontrolex" id="13"> <description>EPG source</description> <left>0</left> - <top>225</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> <texturefocus border="5">button-focus2.png</texturefocus> <texturenofocus border="5">button-nofocus.png</texturenofocus> <label>19200</label> - <onright>9000</onright> - <onleft>60</onleft> - <onup>12</onup> - <ondown>14</ondown> </control> <control type="radiobutton" id="14"> <description>Parental locked</description> <left>0</left> - <top>275</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> <textcolor>white</textcolor> <focusedcolor>white</focusedcolor> @@ -377,21 +372,23 @@ <texturenofocus border="5">button-nofocus.png</texturenofocus> <pulseonselect>no</pulseonselect> <label>19267</label> - <onleft>60</onleft> - <onright>9000</onright> - <onup>13</onup> - <ondown>30</ondown> </control> </control> - <control type="group"> + <control type="grouplist"> <left>490</left> - <top>420</top> - <control type="label"> + <top>375</top> + <itemgap>5</itemgap> + <onleft>60</onleft> + <onright>9000</onright> + <onup>14</onup> + <ondown>7</ondown> + <animation effect="slide" start="0,0" end="0,45" time="0" condition="!Control.IsVisible(31)">Conditional</animation> + <control type="label" id="9003"> <description>channel options Header</description> <left>0</left> <top>0</top> <width>380</width> - <height>20</height> + <height>25</height> <font>font12</font> <label>$LOCALIZE[31026]</label> <align>left</align> @@ -399,55 +396,46 @@ <textcolor>blue</textcolor> <shadowcolor>black</shadowcolor> </control> - <control type="button" id="30"> - <description>Group Manager Button</description> + <control type="button" id="31"> + <description>New channel Button</description> <left>0</left> - <top>25</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> <texturefocus border="5">button-focus2.png</texturefocus> <texturenofocus border="5">button-nofocus.png</texturenofocus> <align>center</align> - <label>19205</label> - <onleft>60</onleft> - <onright>9000</onright> - <onup>14</onup> - <ondown>34</ondown> + <label>19204</label> </control> - <control type="button" id="34"> - <description>TV to Radio Button</description> + <control type="button" id="30"> + <description>Group Manager Button</description> <left>0</left> - <top>75</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> - <visible>IsEmpty(Window.Property(IsRadio))</visible> <texturefocus border="5">button-focus2.png</texturefocus> <texturenofocus border="5">button-nofocus.png</texturenofocus> <align>center</align> - <label>19024</label> - <onleft>60</onleft> - <onright>9000</onright> - <onup>30</onup> - <ondown>7</ondown> + <label>19205</label> </control> - <control type="button" id="34"> - <description>Radio to TV Button</description> + <control type="togglebutton" id="34"> + <description>TV/Radio toggle</description> <left>0</left> - <top>75</top> + <top>0</top> <width>380</width> - <height>45</height> + <height>40</height> <font>font12</font> - <visible>!IsEmpty(Window.Property(IsRadio))</visible> <texturefocus border="5">button-focus2.png</texturefocus> <texturenofocus border="5">button-nofocus.png</texturenofocus> + <alttexturefocus border="5">button-focus2.png</alttexturefocus> + <alttexturenofocus border="5">button-nofocus.png</alttexturenofocus> <align>center</align> - <label>19023</label> - <onleft>60</onleft> - <onright>9000</onright> - <onup>30</onup> - <ondown>7</ondown> + <aligny>center</aligny> + <label>19024</label> + <altlabel>19023</altlabel> + <usealttexture>!IsEmpty(Window.Property(IsRadio))</usealttexture> </control> </control> </control> diff --git a/addons/skin.confluence/720p/IncludesPVR.xml b/addons/skin.confluence/720p/IncludesPVR.xml index b1ea43ad6c..3b5285407a 100644 --- a/addons/skin.confluence/720p/IncludesPVR.xml +++ b/addons/skin.confluence/720p/IncludesPVR.xml @@ -189,7 +189,7 @@ <textcolor>blue</textcolor> <align>center</align> <aligny>center</aligny> - <visible>Control.IsVisible(5) | Control.IsVisible(6)</visible> + <visible>Control.IsVisible(5) | Control.IsVisible(6) | Control.IsVisible(7)</visible> </control> <control type="radiobutton" id="5"> <description>Group recording items by folder structure</description> @@ -205,6 +205,13 @@ <label>19051</label> <visible>Window.IsActive(TVChannels) | Window.IsActive(RadioChannels)</visible> </control> + <control type="radiobutton" id="7"> + <description>Show deleted recordings</description> + <textwidth>235</textwidth> + <include>ButtonCommonValues</include> + <label>19184</label> + <visible>Window.IsActive(TVRecordings) | Window.IsActive(RadioRecordings)</visible> + </control> <!-- Playback controls --> <include>CommonNowPlaying_Controls</include> </control> diff --git a/addons/skin.confluence/720p/includes.xml b/addons/skin.confluence/720p/includes.xml index e0ada12294..b858e05e74 100644 --- a/addons/skin.confluence/720p/includes.xml +++ b/addons/skin.confluence/720p/includes.xml @@ -80,7 +80,7 @@ <texture>black-back.png</texture> <animation effect="fade" time="400">Visible</animation> <animation effect="fade" time="200">Hidden</animation> - <visible>Window.IsActive(MovieInformation) | Window.IsActive(MusicInformation) | Window.IsActive(SongInformation) | Window.IsActive(FileBrowser) | Window.IsActive(TextViewer) | Window.IsActive(AddonSettings) | Window.IsActive(ContentSettings) | Window.IsActive(SelectDialog) | Window.IsActive(FileStackingDialog) | Window.IsActive(MediaSource) | Window.IsActive(PictureInfo) | Window.IsActive(PlayerControls) | Window.IsActive(VirtualKeyboard) | Window.IsActive(NumericInput) | Window.IsActive(ProfileSettings) | Window.IsActive(LockSettings) | Window.IsActive(SmartPlaylistEditor) | Window.IsActive(SmartPlaylistRule) | Window.IsActive(script-RSS_Editor-rssEditor.xml) | Window.IsActive(script-RSS_Editor-setEditor.xml) | Window.IsActive(AddonInformation) | Window.IsActive(Peripherals) | Window.IsActive(PeripheralSettings) | Window.IsActive(script-cu-lrclyrics-main.xml) | Window.IsActive(PVRChannelManager) | Window.IsActive(MediaFilter)</visible> + <visible>Window.IsActive(MovieInformation) | Window.IsActive(MusicInformation) | Window.IsActive(SongInformation) | Window.IsActive(FileBrowser) | Window.IsActive(TextViewer) | Window.IsActive(AddonSettings) | Window.IsActive(ContentSettings) | Window.IsActive(SelectDialog) | Window.IsActive(FileStackingDialog) | Window.IsActive(MediaSource) | Window.IsActive(PictureInfo) | Window.IsActive(PlayerControls) | Window.IsActive(VirtualKeyboard) | Window.IsActive(NumericInput) | Window.IsActive(ProfileSettings) | Window.IsActive(LockSettings) | Window.IsActive(SmartPlaylistEditor) | Window.IsActive(SmartPlaylistRule) | Window.IsActive(script-RSS_Editor-rssEditor.xml) | Window.IsActive(script-RSS_Editor-setEditor.xml) | Window.IsActive(AddonInformation) | Window.IsActive(Peripherals) | Window.IsActive(PeripheralSettings) | Window.IsActive(script-cu-lrclyrics-main.xml) | Window.IsActive(MediaFilter)</visible> </control> </include> <include name="WindowTitleCommons"> diff --git a/addons/skin.confluence/media/DefaultVideoDeleted.png b/addons/skin.confluence/media/DefaultVideoDeleted.png Binary files differnew file mode 100644 index 0000000000..cf6d3fb03c --- /dev/null +++ b/addons/skin.confluence/media/DefaultVideoDeleted.png diff --git a/addons/xbmc.codec/addon.xml b/addons/xbmc.codec/addon.xml index 284c9b63b3..849ade5216 100644 --- a/addons/xbmc.codec/addon.xml +++ b/addons/xbmc.codec/addon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="xbmc.codec" version="1.0.0" provider-name="Team-Kodi"> +<addon id="xbmc.codec" version="1.0.1" provider-name="Team-Kodi"> <requires> <import addon="xbmc.core" version="0.1.0"/> </requires> diff --git a/addons/xbmc.gui/addon.xml b/addons/xbmc.gui/addon.xml index bb2351c945..77b5fd4505 100644 --- a/addons/xbmc.gui/addon.xml +++ b/addons/xbmc.gui/addon.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="xbmc.gui" version="5.7.0" provider-name="Team-Kodi"> - <backwards-compatibility abi="5.3.0"/> +<addon id="xbmc.gui" version="5.8.0" provider-name="Team-Kodi"> + <backwards-compatibility abi="5.8.0"/> <requires> <import addon="xbmc.core" version="0.1.0"/> </requires> diff --git a/addons/xbmc.pvr/addon.xml b/addons/xbmc.pvr/addon.xml index 0d9187f52e..aa99e9f4d3 100644 --- a/addons/xbmc.pvr/addon.xml +++ b/addons/xbmc.pvr/addon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<addon id="xbmc.pvr" version="1.9.3" provider-name="Team-Kodi"> +<addon id="xbmc.pvr" version="1.9.4" provider-name="Team-Kodi"> <requires> <import addon="xbmc.core" version="0.1.0"/> </requires> diff --git a/language/English/strings.po b/language/English/strings.po index 140d4eb640..a1267de24c 100755..100644 --- a/language/English/strings.po +++ b/language/English/strings.po @@ -8292,7 +8292,11 @@ msgctxt "#19167" msgid "Scan for missing icons" msgstr "" -#empty string with id 19168 +#. Used in system info to show amount of it +#: xbmc/windows/GUIWindowSystemInfo.cpp +msgctxt "#19168" +msgid "Deleted and recoverable recordings" +msgstr "" msgctxt "#19169" msgid "Hide video information box" @@ -8343,7 +8347,11 @@ msgctxt "#19178" msgid "Show channel information when switching channels" msgstr "" -#empty string with id 19179 +#. Used as extension header on recordings window +#: xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +msgctxt "#19179" +msgid "Deleted" +msgstr "" #: system/settings/settings.xml msgctxt "#19180" @@ -8365,7 +8373,11 @@ msgctxt "#19183" msgid "Radio" msgstr "" -#empty string with id 19184 +#. Used on pvr recordings as button to show of them +#: skin.confluence +msgctxt "#19184" +msgid "Deleted recordings" +msgstr "" #: system/settings/settings.xml msgctxt "#19185" @@ -8839,7 +8851,37 @@ msgctxt "#19289" msgid "Hide group" msgstr "" -#empty strings from id 19290 to 19498 +#. Used on recordings context menu +#: xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +msgctxt "#19290" +msgid "Undelete" +msgstr "" + +#. Used on recordings context menu +#: xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +msgctxt "#19291" +msgid "Delete permanently" +msgstr "" + +#. Used on recordings context menu +#: xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +msgctxt "#19292" +msgid "Delete all permanently" +msgstr "" + +#. Used on yes no dialog +#: xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +msgctxt "#19293" +msgid "Delete all recordings permanently?" +msgstr "" + +#. Used on yes no dialog +#: xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +msgctxt "#19294" +msgid "Delete this recording permanently?" +msgstr "" + +#empty strings from id 19295 to 19498 #: xbmc/epg/Epg.cpp msgctxt "#19499" diff --git a/lib/addons/library.xbmc.addon/libXBMC_addon.cpp b/lib/addons/library.xbmc.addon/libXBMC_addon.cpp index e00bc77584..9355bc39b8 100644 --- a/lib/addons/library.xbmc.addon/libXBMC_addon.cpp +++ b/lib/addons/library.xbmc.addon/libXBMC_addon.cpp @@ -92,7 +92,7 @@ DLLEXPORT bool XBMC_wake_on_lan(void* hdl, void* cb, char* mac) return ((CB_AddOnLib*)cb)->WakeOnLan(mac); } -DLLEXPORT char* XBMC_unknown_to_utf8(void *hdl, void* cb, const char* str) +DLLEXPORT const char* XBMC_unknown_to_utf8(void *hdl, void* cb, const char* str) { if (cb == NULL) return NULL; @@ -100,7 +100,7 @@ DLLEXPORT char* XBMC_unknown_to_utf8(void *hdl, void* cb, const char* str) return ((CB_AddOnLib*)cb)->UnknownToUTF8(str); } -DLLEXPORT char* XBMC_get_localized_string(void *hdl, void* cb, int dwCode) +DLLEXPORT const char* XBMC_get_localized_string(void *hdl, void* cb, int dwCode) { if (cb == NULL) return ""; @@ -108,7 +108,7 @@ DLLEXPORT char* XBMC_get_localized_string(void *hdl, void* cb, int dwCode) return ((CB_AddOnLib*)cb)->GetLocalizedString(((AddonCB*)hdl)->addonData, dwCode); } -DLLEXPORT char* XBMC_get_dvd_menu_language(void *hdl, void* cb) +DLLEXPORT const char* XBMC_get_dvd_menu_language(void *hdl, void* cb) { if (cb == NULL) return ""; diff --git a/lib/addons/library.xbmc.gui/libXBMC_gui.cpp b/lib/addons/library.xbmc.gui/libXBMC_gui.cpp index 31b499e650..b7fb237069 100644 --- a/lib/addons/library.xbmc.gui/libXBMC_gui.cpp +++ b/lib/addons/library.xbmc.gui/libXBMC_gui.cpp @@ -81,6 +81,158 @@ DLLEXPORT int GUI_get_video_resolution(void *hdl, void *cb) return ((CB_GUILib*)cb)->GetVideoResolution(); } +/*! @name GUI Keyboard functions */ +//@{ +DLLEXPORT bool GUI_dialog_keyboard_show_and_get_input_with_head(void *hdl, void *cb, char &aTextString, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndGetInputWithHead(aTextString, iMaxStringSize, strHeading, allowEmptyResult, hiddenInput, autoCloseMs); +} + +DLLEXPORT bool GUI_dialog_keyboard_show_and_get_input(void *hdl, void *cb, char &aTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndGetInput(aTextString, iMaxStringSize, allowEmptyResult, autoCloseMs); +} + +DLLEXPORT bool GUI_dialog_keyboard_show_and_get_new_password_with_head(void *hdl, void *cb, char &newPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndGetNewPasswordWithHead(newPassword, iMaxStringSize, strHeading, allowEmptyResult, autoCloseMs); +} + +DLLEXPORT bool GUI_dialog_keyboard_show_and_get_new_password(void *hdl, void *cb, char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndGetNewPassword(strNewPassword, iMaxStringSize, autoCloseMs); +} + +DLLEXPORT bool GUI_dialog_keyboard_show_and_verify_new_password_with_head(void *hdl, void *cb, char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead(strNewPassword, iMaxStringSize, strHeading, allowEmptyResult, autoCloseMs); +} + +DLLEXPORT bool GUI_dialog_keyboard_show_and_verify_new_password(void *hdl, void *cb, char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndVerifyNewPassword(strNewPassword, iMaxStringSize, autoCloseMs); +} + +DLLEXPORT int GUI_dialog_keyboard_show_and_verify_password(void *hdl, void *cb, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndVerifyPassword(strPassword, iMaxStringSize, strHeading, iRetries, autoCloseMs); +} + +DLLEXPORT bool GUI_dialog_keyboard_show_and_get_filter(void *hdl, void *cb, char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_ShowAndGetFilter(aTextString, iMaxStringSize, searching, autoCloseMs); +} + +DLLEXPORT bool GUI_dialog_keyboard_send_text_to_active_keyboard(void *hdl, void *cb, const char *aTextString, bool closeKeyboard) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_SendTextToActiveKeyboard(aTextString, closeKeyboard); +} + +DLLEXPORT bool GUI_dialog_keyboard_is_activated(void *hdl, void *cb) +{ + return ((CB_GUILib*)cb)->Dialog_Keyboard_isKeyboardActivated(); +} +//@} + +/*! @name GUI Numeric functions */ +//@{ +DLLEXPORT bool GUI_dialog_numeric_show_and_verify_new_password(void *hdl, void *cb, char &strNewPassword, unsigned int iMaxStringSize) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndVerifyNewPassword(strNewPassword, iMaxStringSize); +} + +DLLEXPORT int GUI_dialog_numeric_show_and_verify_password(void *hdl, void *cb, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndVerifyPassword(strPassword, iMaxStringSize, strHeading, iRetries); +} + +DLLEXPORT bool GUI_dialog_numeric_show_and_verify_input(void *hdl, void *cb, char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndVerifyInput(strPassword, iMaxStringSize, strHeading, bGetUserInput); +} + +DLLEXPORT bool GUI_dialog_numeric_show_and_get_time(void *hdl, void *cb, tm &time, const char *strHeading) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndGetTime(time, strHeading); +} + +DLLEXPORT bool GUI_dialog_numeric_show_and_get_date(void *hdl, void *cb, tm &date, const char *strHeading) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndGetDate(date, strHeading); +} + +DLLEXPORT bool GUI_dialog_numeric_show_and_get_ipaddress(void *hdl, void *cb, char &IPAddress, unsigned int iMaxStringSize, const char *strHeading) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndGetIPAddress(IPAddress, iMaxStringSize, strHeading); +} + +DLLEXPORT bool GUI_dialog_numeric_show_and_get_number(void *hdl, void *cb, char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndGetNumber(strInput, iMaxStringSize, strHeading, iAutoCloseTimeoutMs); +} + +DLLEXPORT bool GUI_dialog_numeric_show_and_get_seconds(void *hdl, void *cb, char &timeString, unsigned int iMaxStringSize, const char *strHeading) +{ + return ((CB_GUILib*)cb)->Dialog_Numeric_ShowAndGetSeconds(timeString, iMaxStringSize, strHeading); +} +//@} + +/*! @name GUI File browser functions */ +//@{ +DLLEXPORT bool GUI_dialog_filebrowser_show_and_get_file(void *hdl, void *cb, const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs = false, bool useFileDirectories = false, bool singleList = false) +{ + return ((CB_GUILib*)cb)->Dialog_FileBrowser_ShowAndGetFile(directory, mask, heading, path, iMaxStringSize, useThumbs, useFileDirectories, singleList); +} +//@} + +/*! @name GUI OK Dialog functions */ +//@{ +DLLEXPORT void GUI_dialog_ok_show_and_get_input_single_text(void *hdl, void *cb, const char *heading, const char *text) +{ + return ((CB_GUILib*)cb)->Dialog_OK_ShowAndGetInputSingleText(heading, text); +} + +DLLEXPORT void GUI_dialog_ok_show_and_get_input_line_text(void *hdl, void *cb, const char *heading, const char *line0, const char *line1, const char *line2) +{ + return ((CB_GUILib*)cb)->Dialog_OK_ShowAndGetInputLineText(heading, line0, line1, line2); +} +//@} + +/*! @name GUI OK Dialog functions */ +//@{ +DLLEXPORT bool GUI_dialog_yesno_show_and_get_input_linetext(void *hdl, void *cb, const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel) +{ + return ((CB_GUILib*)cb)->Dialog_YesNo_ShowAndGetInputLineText(heading, line0, line1, line2, noLabel, yesLabel); +} + +DLLEXPORT bool GUI_dialog_yesno_show_and_get_input_singletext(void *hdl, void *cb, const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel) +{ + return ((CB_GUILib*)cb)->Dialog_YesNo_ShowAndGetInputSingleText(heading, text, bCanceled, noLabel, yesLabel); +} + +DLLEXPORT bool GUI_dialog_yesno_show_and_get_input_linebuttontext(void *hdl, void *cb, const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel) +{ + return ((CB_GUILib*)cb)->Dialog_YesNo_ShowAndGetInputLineButtonText(heading, line0, line1, line2, bCanceled, noLabel, yesLabel); +} +//@} + +/*! @name GUI Text viewer Dialog */ +//@{ +DLLEXPORT void GUI_dialog_text_viewer(void *hdl, void *cb, const char *heading, const char *text) +{ + return ((CB_GUILib*)cb)->Dialog_TextViewer(heading, text); +} +//@} + +/*! @name GUI select Dialog */ +//@{ +DLLEXPORT int GUI_dialog_select(void *hdl, void *cb, const char *heading, const char *entries[], unsigned int size, int selected) +{ + return ((CB_GUILib*)cb)->Dialog_Select(heading, entries, size, selected); +} +//@} + + DLLEXPORT CAddonGUIWindow* GUI_Window_create(void *hdl, void *cb, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog) { return new CAddonGUIWindow(hdl, cb, xmlFilename, defaultSkin, forceFallback, asDialog); @@ -115,7 +267,6 @@ DLLEXPORT bool GUI_Window_OnAction(GUIHANDLE handle, int actionId) return window->OnAction(actionId); } - CAddonGUIWindow::CAddonGUIWindow(void *hdl, void *cb, const char *xmlFilename, const char *defaultSkin, bool forceFallback, bool asDialog) : m_Handle(hdl) , m_cb(cb) @@ -444,7 +595,7 @@ void CAddonGUIProgressControl::SetPercentage(float fPercent) float CAddonGUIProgressControl::GetPercentage() const { if (!m_ProgressHandle) - return 0.0; + return 0.0f; return ((CB_GUILib*)m_cb)->Control_Progress_GetPercentage(((AddonCB*)m_Handle)->addonData, m_ProgressHandle); } @@ -473,6 +624,214 @@ string CAddonGUIProgressControl::GetDescription() const ///------------------------------------- +/// cGUISliderControl + +DLLEXPORT CAddonGUISliderControl* GUI_control_get_slider(void *hdl, void *cb, CAddonGUIWindow *window, int controlId) +{ + return new CAddonGUISliderControl(hdl, cb, window, controlId); +} + +DLLEXPORT void GUI_control_release_slider(CAddonGUISliderControl* p) +{ + delete p; +} + +CAddonGUISliderControl::CAddonGUISliderControl(void *hdl, void *cb, CAddonGUIWindow *window, int controlId) + : m_Window(window) + , m_ControlId(controlId) + , m_Handle(hdl) + , m_cb(cb) +{ + m_SliderHandle = ((CB_GUILib*)m_cb)->Window_GetControl_Slider(((AddonCB*)m_Handle)->addonData, m_Window->m_WindowHandle, controlId); +} + +void CAddonGUISliderControl::SetVisible(bool yesNo) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetVisible(((AddonCB*)m_Handle)->addonData, m_SliderHandle, yesNo); +} + +string CAddonGUISliderControl::GetDescription() const +{ + if (!m_SliderHandle) + return ""; + + return ((CB_GUILib*)m_cb)->Control_Slider_GetDescription(((AddonCB*)m_Handle)->addonData, m_SliderHandle); +} + +void CAddonGUISliderControl::SetIntRange(int iStart, int iEnd) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetIntRange(((AddonCB*)m_Handle)->addonData, m_SliderHandle, iStart, iEnd); +} + +void CAddonGUISliderControl::SetIntValue(int iValue) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetIntValue(((AddonCB*)m_Handle)->addonData, m_SliderHandle, iValue); +} + +int CAddonGUISliderControl::GetIntValue() const +{ + if (!m_SliderHandle) + return 0; + return ((CB_GUILib*)m_cb)->Control_Slider_GetIntValue(((AddonCB*)m_Handle)->addonData, m_SliderHandle); +} + +void CAddonGUISliderControl::SetIntInterval(int iInterval) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetIntInterval(((AddonCB*)m_Handle)->addonData, m_SliderHandle, iInterval); +} + +void CAddonGUISliderControl::SetPercentage(float fPercent) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetPercentage(((AddonCB*)m_Handle)->addonData, m_SliderHandle, fPercent); +} + +float CAddonGUISliderControl::GetPercentage() const +{ + if (!m_SliderHandle) + return 0.0f; + + return ((CB_GUILib*)m_cb)->Control_Slider_GetPercentage(((AddonCB*)m_Handle)->addonData, m_SliderHandle); +} + +void CAddonGUISliderControl::SetFloatRange(float fStart, float fEnd) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetFloatRange(((AddonCB*)m_Handle)->addonData, m_SliderHandle, fStart, fEnd); +} + +void CAddonGUISliderControl::SetFloatValue(float fValue) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetFloatValue(((AddonCB*)m_Handle)->addonData, m_SliderHandle, fValue); +} + +float CAddonGUISliderControl::GetFloatValue() const +{ + if (!m_SliderHandle) + return 0.0f; + return ((CB_GUILib*)m_cb)->Control_Slider_GetFloatValue(((AddonCB*)m_Handle)->addonData, m_SliderHandle); +} + +void CAddonGUISliderControl::SetFloatInterval(float fInterval) +{ + if (m_SliderHandle) + ((CB_GUILib*)m_cb)->Control_Slider_SetFloatInterval(((AddonCB*)m_Handle)->addonData, m_SliderHandle, fInterval); +} + + +///------------------------------------- +/// cGUISettingsSliderControl + +DLLEXPORT CAddonGUISettingsSliderControl* GUI_control_get_settings_slider(void *hdl, void *cb, CAddonGUIWindow *window, int controlId) +{ + return new CAddonGUISettingsSliderControl(hdl, cb, window, controlId); +} + +DLLEXPORT void GUI_control_release_settings_slider(CAddonGUISettingsSliderControl* p) +{ + delete p; +} + +CAddonGUISettingsSliderControl::CAddonGUISettingsSliderControl(void *hdl, void *cb, CAddonGUIWindow *window, int controlId) + : m_Window(window) + , m_ControlId(controlId) + , m_Handle(hdl) + , m_cb(cb) +{ + m_SettingsSliderHandle = ((CB_GUILib*)m_cb)->Window_GetControl_SettingsSlider(((AddonCB*)m_Handle)->addonData, m_Window->m_WindowHandle, controlId); +} + +void CAddonGUISettingsSliderControl::SetVisible(bool yesNo) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetVisible(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, yesNo); +} + +void CAddonGUISettingsSliderControl::SetText(const char *label) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetText(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, label); +} + +string CAddonGUISettingsSliderControl::GetDescription() const +{ + if (!m_SettingsSliderHandle) + return ""; + + return ((CB_GUILib*)m_cb)->Control_SettingsSlider_GetDescription(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle); +} + +void CAddonGUISettingsSliderControl::SetIntRange(int iStart, int iEnd) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetIntRange(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, iStart, iEnd); +} + +void CAddonGUISettingsSliderControl::SetIntValue(int iValue) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetIntValue(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, iValue); +} + +int CAddonGUISettingsSliderControl::GetIntValue() const +{ + if (!m_SettingsSliderHandle) + return 0; + return ((CB_GUILib*)m_cb)->Control_SettingsSlider_GetIntValue(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle); +} + +void CAddonGUISettingsSliderControl::SetIntInterval(int iInterval) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetIntInterval(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, iInterval); +} + +void CAddonGUISettingsSliderControl::SetPercentage(float fPercent) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetPercentage(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, fPercent); +} + +float CAddonGUISettingsSliderControl::GetPercentage() const +{ + if (!m_SettingsSliderHandle) + return 0.0f; + + return ((CB_GUILib*)m_cb)->Control_SettingsSlider_GetPercentage(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle); +} + +void CAddonGUISettingsSliderControl::SetFloatRange(float fStart, float fEnd) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetFloatRange(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, fStart, fEnd); +} + +void CAddonGUISettingsSliderControl::SetFloatValue(float fValue) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetFloatValue(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, fValue); +} + +float CAddonGUISettingsSliderControl::GetFloatValue() const +{ + if (!m_SettingsSliderHandle) + return 0.0f; + return ((CB_GUILib*)m_cb)->Control_SettingsSlider_GetFloatValue(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle); +} + +void CAddonGUISettingsSliderControl::SetFloatInterval(float fInterval) +{ + if (m_SettingsSliderHandle) + ((CB_GUILib*)m_cb)->Control_SettingsSlider_SetFloatInterval(((AddonCB*)m_Handle)->addonData, m_SettingsSliderHandle, fInterval); +} + + +///------------------------------------- /// cListItem DLLEXPORT CAddonListItem* GUI_ListItem_create(void *hdl, void *cb, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path) diff --git a/project/Win32BuildSetup/buildpvraddons.bat b/project/Win32BuildSetup/buildpvraddons.bat index c13cc35d5b..53a6af2a59 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=b2dc035404e14f137033876d14ad92ae3bde5f27 +SET VERSION=63be5d6bd030708f6621707a8b23ede74bf4494b SET SOURCE=%LIBNAME% SET GIT_URL=git://github.com/opdenkamp/%LIBNAME%.git SET SOURCE_DIR=%TMP_DIR%\%SOURCE% diff --git a/tools/depends/target/xbmc-pvr-addons/Makefile b/tools/depends/target/xbmc-pvr-addons/Makefile index 5abf2b7566..61d109bab6 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=b2dc035404e14f137033876d14ad92ae3bde5f27 +VERSION=63be5d6bd030708f6621707a8b23ede74bf4494b 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/FileItem.cpp b/xbmc/FileItem.cpp index b45131d736..8550bea709 100644 --- a/xbmc/FileItem.cpp +++ b/xbmc/FileItem.cpp @@ -738,7 +738,22 @@ bool CFileItem::IsPVRChannel() const bool CFileItem::IsPVRRecording() const { - if (HasPVRRecordingInfoTag()) return true; /// is this enough? + if (HasPVRRecordingInfoTag()) + return true; + return false; +} + +bool CFileItem::IsUsablePVRRecording() const +{ + if (m_pvrRecordingInfoTag && !m_pvrRecordingInfoTag->IsDeleted()) + return true; + return false; +} + +bool CFileItem::IsDeletedPVRRecording() const +{ + if (m_pvrRecordingInfoTag && m_pvrRecordingInfoTag->IsDeleted()) + return true; return false; } @@ -1165,11 +1180,16 @@ void CFileItem::FillInDefaultIcon() { // archive SetIconImage("DefaultFile.png"); } - else if ( IsPVRRecording() ) + else if ( IsUsablePVRRecording() ) { // PVR recording SetIconImage("DefaultVideo.png"); } + else if ( IsDeletedPVRRecording() ) + { + // PVR deleted recording + SetIconImage("DefaultVideoDeleted.png"); + } else if ( IsAudio() ) { // audio diff --git a/xbmc/FileItem.h b/xbmc/FileItem.h index f62c908c21..7e8c9b61ea 100644 --- a/xbmc/FileItem.h +++ b/xbmc/FileItem.h @@ -208,6 +208,8 @@ public: bool IsEPG() const; bool IsPVRChannel() const; bool IsPVRRecording() const; + bool IsUsablePVRRecording() const; + bool IsDeletedPVRRecording() const; bool IsPVRTimer() const; bool IsType(const char *ext) const; bool IsVirtualDirectoryRoot() const; diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp index 94c80d8abd..bde83123f7 100644 --- a/xbmc/GUIInfoManager.cpp +++ b/xbmc/GUIInfoManager.cpp @@ -657,6 +657,7 @@ const infomap pvr[] = {{ "isrecording", PVR_IS_RECORDING { "backendchannels", PVR_BACKEND_CHANNELS }, { "backendtimers", PVR_BACKEND_TIMERS }, { "backendrecordings", PVR_BACKEND_RECORDINGS }, + { "backenddeletedrecordings", PVR_BACKEND_DELETED_RECORDINGS }, { "backendnumber", PVR_BACKEND_NUMBER }, { "hasepg", PVR_HAS_EPG }, { "hastxt", PVR_HAS_TXT }, @@ -1418,6 +1419,7 @@ std::string CGUIInfoManager::GetLabel(int info, int contextWindow, std::string * case PVR_BACKEND_CHANNELS: case PVR_BACKEND_TIMERS: case PVR_BACKEND_RECORDINGS: + case PVR_BACKEND_DELETED_RECORDINGS: case PVR_BACKEND_NUMBER: case PVR_TOTAL_DISKSPACE: case PVR_NEXT_TIMER: diff --git a/xbmc/GUIInfoManager.h b/xbmc/GUIInfoManager.h index 67e41bd67d..20fe8108b8 100644 --- a/xbmc/GUIInfoManager.h +++ b/xbmc/GUIInfoManager.h @@ -466,29 +466,30 @@ namespace INFO #define PVR_BACKEND_CHANNELS (PVR_STRINGS_START + 12) #define PVR_BACKEND_TIMERS (PVR_STRINGS_START + 13) #define PVR_BACKEND_RECORDINGS (PVR_STRINGS_START + 14) -#define PVR_BACKEND_NUMBER (PVR_STRINGS_START + 15) -#define PVR_TOTAL_DISKSPACE (PVR_STRINGS_START + 16) -#define PVR_NEXT_TIMER (PVR_STRINGS_START + 17) -#define PVR_PLAYING_DURATION (PVR_STRINGS_START + 18) -#define PVR_PLAYING_TIME (PVR_STRINGS_START + 19) -#define PVR_PLAYING_PROGRESS (PVR_STRINGS_START + 20) -#define PVR_ACTUAL_STREAM_CLIENT (PVR_STRINGS_START + 21) -#define PVR_ACTUAL_STREAM_DEVICE (PVR_STRINGS_START + 22) -#define PVR_ACTUAL_STREAM_STATUS (PVR_STRINGS_START + 23) -#define PVR_ACTUAL_STREAM_SIG (PVR_STRINGS_START + 24) -#define PVR_ACTUAL_STREAM_SNR (PVR_STRINGS_START + 25) -#define PVR_ACTUAL_STREAM_SIG_PROGR (PVR_STRINGS_START + 26) -#define PVR_ACTUAL_STREAM_SNR_PROGR (PVR_STRINGS_START + 27) -#define PVR_ACTUAL_STREAM_BER (PVR_STRINGS_START + 28) -#define PVR_ACTUAL_STREAM_UNC (PVR_STRINGS_START + 29) -#define PVR_ACTUAL_STREAM_VIDEO_BR (PVR_STRINGS_START + 30) -#define PVR_ACTUAL_STREAM_AUDIO_BR (PVR_STRINGS_START + 31) -#define PVR_ACTUAL_STREAM_DOLBY_BR (PVR_STRINGS_START + 32) -#define PVR_ACTUAL_STREAM_CRYPTION (PVR_STRINGS_START + 33) -#define PVR_ACTUAL_STREAM_SERVICE (PVR_STRINGS_START + 34) -#define PVR_ACTUAL_STREAM_MUX (PVR_STRINGS_START + 35) -#define PVR_ACTUAL_STREAM_PROVIDER (PVR_STRINGS_START + 36) -#define PVR_BACKEND_DISKSPACE_PROGR (PVR_STRINGS_START + 37) +#define PVR_BACKEND_DELETED_RECORDINGS (PVR_STRINGS_START + 15) +#define PVR_BACKEND_NUMBER (PVR_STRINGS_START + 16) +#define PVR_TOTAL_DISKSPACE (PVR_STRINGS_START + 17) +#define PVR_NEXT_TIMER (PVR_STRINGS_START + 18) +#define PVR_PLAYING_DURATION (PVR_STRINGS_START + 19) +#define PVR_PLAYING_TIME (PVR_STRINGS_START + 20) +#define PVR_PLAYING_PROGRESS (PVR_STRINGS_START + 21) +#define PVR_ACTUAL_STREAM_CLIENT (PVR_STRINGS_START + 22) +#define PVR_ACTUAL_STREAM_DEVICE (PVR_STRINGS_START + 23) +#define PVR_ACTUAL_STREAM_STATUS (PVR_STRINGS_START + 24) +#define PVR_ACTUAL_STREAM_SIG (PVR_STRINGS_START + 25) +#define PVR_ACTUAL_STREAM_SNR (PVR_STRINGS_START + 26) +#define PVR_ACTUAL_STREAM_SIG_PROGR (PVR_STRINGS_START + 27) +#define PVR_ACTUAL_STREAM_SNR_PROGR (PVR_STRINGS_START + 28) +#define PVR_ACTUAL_STREAM_BER (PVR_STRINGS_START + 29) +#define PVR_ACTUAL_STREAM_UNC (PVR_STRINGS_START + 30) +#define PVR_ACTUAL_STREAM_VIDEO_BR (PVR_STRINGS_START + 31) +#define PVR_ACTUAL_STREAM_AUDIO_BR (PVR_STRINGS_START + 32) +#define PVR_ACTUAL_STREAM_DOLBY_BR (PVR_STRINGS_START + 33) +#define PVR_ACTUAL_STREAM_CRYPTION (PVR_STRINGS_START + 34) +#define PVR_ACTUAL_STREAM_SERVICE (PVR_STRINGS_START + 35) +#define PVR_ACTUAL_STREAM_MUX (PVR_STRINGS_START + 36) +#define PVR_ACTUAL_STREAM_PROVIDER (PVR_STRINGS_START + 37) +#define PVR_BACKEND_DISKSPACE_PROGR (PVR_STRINGS_START + 38) #define PVR_STRINGS_END PVR_ACTUAL_STREAM_PROVIDER #define WINDOW_PROPERTY 9993 diff --git a/xbmc/addons/AddonCallbacks.h b/xbmc/addons/AddonCallbacks.h index 9ae3242a15..6e51379fda 100644 --- a/xbmc/addons/AddonCallbacks.h +++ b/xbmc/addons/AddonCallbacks.h @@ -36,10 +36,10 @@ typedef void (*AddOnLogCallback)(void *addonData, const ADDON::addon_log_t logle typedef void (*AddOnQueueNotification)(void *addonData, const ADDON::queue_msg_t type, const char *msg); typedef bool (*AddOnWakeOnLan)(const char* mac); typedef bool (*AddOnGetSetting)(void *addonData, const char *settingName, void *settingValue); -typedef char* (*AddOnUnknownToUTF8)(const char *sourceDest); -typedef char* (*AddOnGetLocalizedString)(const void* addonData, long dwCode); -typedef char* (*AddOnGetDVDMenuLanguage)(const void* addonData); -typedef void (*AddOnFreeString)(const void* addonData, char* str); +typedef const char* (*AddOnUnknownToUTF8)(const char *sourceDest); +typedef const char* (*AddOnGetLocalizedString)(const void* addonData, long dwCode); +typedef const char* (*AddOnGetDVDMenuLanguage)(const void* addonData); +typedef void (*AddOnFreeString)(const void* addonData, const char* str); typedef void* (*AddOnOpenFile)(const void* addonData, const char* strFileName, unsigned int flags); typedef void* (*AddOnOpenFileForWrite)(const void* addonData, const char* strFileName, bool bOverWrite); @@ -154,6 +154,33 @@ typedef float (*GUIControl_Progress_GetPercentage)(void *addonData, GUIHAN typedef void (*GUIControl_Progress_SetInfo)(void *addonData, GUIHANDLE handle, int iInfo); typedef int (*GUIControl_Progress_GetInfo)(void *addonData, GUIHANDLE handle); typedef const char* (*GUIControl_Progress_GetDescription)(void *addonData, GUIHANDLE handle); +typedef GUIHANDLE (*GUIWindow_GetControl_Slider)(void *addonData, GUIHANDLE handle, int controlId); +typedef void (*GUIControl_Slider_SetVisible)(void *addonData, GUIHANDLE handle, bool yesNo); +typedef const char *(*GUIControl_Slider_GetDescription)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_Slider_SetIntRange)(void *addonData, GUIHANDLE handle, int iStart, int iEnd); +typedef void (*GUIControl_Slider_SetIntValue)(void *addonData, GUIHANDLE handle, int iValue); +typedef int (*GUIControl_Slider_GetIntValue)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_Slider_SetIntInterval)(void *addonData, GUIHANDLE handle, int iInterval); +typedef void (*GUIControl_Slider_SetPercentage)(void *addonData, GUIHANDLE handle, float fPercent); +typedef float (*GUIControl_Slider_GetPercentage)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_Slider_SetFloatRange)(void *addonData, GUIHANDLE handle, float fStart, float fEnd); +typedef void (*GUIControl_Slider_SetFloatValue)(void *addonData, GUIHANDLE handle, float fValue); +typedef float (*GUIControl_Slider_GetFloatValue)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_Slider_SetFloatInterval)(void *addonData, GUIHANDLE handle, float fInterval); +typedef GUIHANDLE (*GUIWindow_GetControl_SettingsSlider)(void *addonData, GUIHANDLE handle, int controlId); +typedef void (*GUIControl_SettingsSlider_SetVisible)(void *addonData, GUIHANDLE handle, bool yesNo); +typedef void (*GUIControl_SettingsSlider_SetText)(void *addonData, GUIHANDLE handle, const char *label); +typedef const char *(*GUIControl_SettingsSlider_GetDescription)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_SettingsSlider_SetIntRange)(void *addonData, GUIHANDLE handle, int iStart, int iEnd); +typedef void (*GUIControl_SettingsSlider_SetIntValue)(void *addonData, GUIHANDLE handle, int iValue); +typedef int (*GUIControl_SettingsSlider_GetIntValue)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_SettingsSlider_SetIntInterval)(void *addonData, GUIHANDLE handle, int iInterval); +typedef void (*GUIControl_SettingsSlider_SetPercentage)(void *addonData, GUIHANDLE handle, float fPercent); +typedef float (*GUIControl_SettingsSlider_GetPercentage)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_SettingsSlider_SetFloatRange)(void *addonData, GUIHANDLE handle, float fStart, float fEnd); +typedef void (*GUIControl_SettingsSlider_SetFloatValue)(void *addonData, GUIHANDLE handle, float fValue); +typedef float (*GUIControl_SettingsSlider_GetFloatValue)(void *addonData, GUIHANDLE handle); +typedef void (*GUIControl_SettingsSlider_SetFloatInterval)(void *addonData, GUIHANDLE handle, float fInterval); typedef GUIHANDLE (*GUIListItem_Create)(void *addonData, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path); typedef const char* (*GUIListItem_GetLabel)(void *addonData, GUIHANDLE handle); typedef void (*GUIListItem_SetLabel)(void *addonData, GUIHANDLE handle, const char *label); @@ -169,6 +196,39 @@ typedef void (*GUIRenderAddon_SetCallbacks)(void *addonData, GUIHANDLE ha typedef void (*GUIRenderAddon_Delete)(void *addonData, GUIHANDLE handle); typedef void (*GUIRenderAddon_MarkDirty)(void *addonData, GUIHANDLE handle); +typedef bool (*GUIDialog_Keyboard_ShowAndGetInputWithHead)(char &strTextString, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs); +typedef bool (*GUIDialog_Keyboard_ShowAndGetInput)(char &strTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs); +typedef bool (*GUIDialog_Keyboard_ShowAndGetNewPasswordWithHead)(char &newPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs); +typedef bool (*GUIDialog_Keyboard_ShowAndGetNewPassword)(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); +typedef bool (*GUIDialog_Keyboard_ShowAndVerifyNewPasswordWithHead)(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmpty, unsigned int autoCloseMs); +typedef bool (*GUIDialog_Keyboard_ShowAndVerifyNewPassword)(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); +typedef int (*GUIDialog_Keyboard_ShowAndVerifyPassword)(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs); +typedef bool (*GUIDialog_Keyboard_ShowAndGetFilter)(char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs); +typedef bool (*GUIDialog_Keyboard_SendTextToActiveKeyboard)(const char *aTextString, bool closeKeyboard); +typedef bool (*GUIDialog_Keyboard_isKeyboardActivated)(); + +typedef bool (*GUIDialog_Numeric_ShowAndVerifyNewPassword)(char &strNewPassword, unsigned int iMaxStringSize); +typedef int (*GUIDialog_Numeric_ShowAndVerifyPassword)(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries); +typedef bool (*GUIDialog_Numeric_ShowAndVerifyInput)(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput); +typedef bool (*GUIDialog_Numeric_ShowAndGetTime)(tm &time, const char *strHeading); +typedef bool (*GUIDialog_Numeric_ShowAndGetDate)(tm &date, const char *strHeading); +typedef bool (*GUIDialog_Numeric_ShowAndGetIPAddress)(char &strIPAddress, unsigned int iMaxStringSize, const char *strHeading); +typedef bool (*GUIDialog_Numeric_ShowAndGetNumber)(char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs); +typedef bool (*GUIDialog_Numeric_ShowAndGetSeconds)(char &timeString, unsigned int iMaxStringSize, const char *strHeading); + +typedef bool (*GUIDialog_FileBrowser_ShowAndGetFile)(const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList); + +typedef void (*GUIDialog_OK_ShowAndGetInputSingleText)(const char *heading, const char *text); +typedef void (*GUIDialog_OK_ShowAndGetInputLineText)(const char *heading, const char *line0, const char *line1, const char *line2); + +typedef bool (*GUIDialog_YesNo_ShowAndGetInputSingleText)(const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel); +typedef bool (*GUIDialog_YesNo_ShowAndGetInputLineText)(const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel); +typedef bool (*GUIDialog_YesNo_ShowAndGetInputLineButtonText)(const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel); + +typedef void (*GUIDialog_TextViewer)(const char *heading, const char *text); + +typedef int (*GUIDialog_Select)(const char *heading, const char *entries[], unsigned int size, int selected); + typedef struct CB_GUILib { GUILock Lock; @@ -239,6 +299,66 @@ typedef struct CB_GUILib GUIRenderAddon_SetCallbacks RenderAddon_SetCallbacks; GUIRenderAddon_Delete RenderAddon_Delete; + GUIWindow_GetControl_Slider Window_GetControl_Slider; + GUIControl_Slider_SetVisible Control_Slider_SetVisible; + GUIControl_Slider_GetDescription Control_Slider_GetDescription; + GUIControl_Slider_SetIntRange Control_Slider_SetIntRange; + GUIControl_Slider_SetIntValue Control_Slider_SetIntValue; + GUIControl_Slider_GetIntValue Control_Slider_GetIntValue; + GUIControl_Slider_SetIntInterval Control_Slider_SetIntInterval; + GUIControl_Slider_SetPercentage Control_Slider_SetPercentage; + GUIControl_Slider_GetPercentage Control_Slider_GetPercentage; + GUIControl_Slider_SetFloatRange Control_Slider_SetFloatRange; + GUIControl_Slider_SetFloatValue Control_Slider_SetFloatValue; + GUIControl_Slider_GetFloatValue Control_Slider_GetFloatValue; + GUIControl_Slider_SetFloatInterval Control_Slider_SetFloatInterval; + + GUIWindow_GetControl_SettingsSlider Window_GetControl_SettingsSlider; + GUIControl_SettingsSlider_SetVisible Control_SettingsSlider_SetVisible; + GUIControl_SettingsSlider_SetText Control_SettingsSlider_SetText; + GUIControl_SettingsSlider_GetDescription Control_SettingsSlider_GetDescription; + GUIControl_SettingsSlider_SetIntRange Control_SettingsSlider_SetIntRange; + GUIControl_SettingsSlider_SetIntValue Control_SettingsSlider_SetIntValue; + GUIControl_SettingsSlider_GetIntValue Control_SettingsSlider_GetIntValue; + GUIControl_SettingsSlider_SetIntInterval Control_SettingsSlider_SetIntInterval; + GUIControl_SettingsSlider_SetPercentage Control_SettingsSlider_SetPercentage; + GUIControl_SettingsSlider_GetPercentage Control_SettingsSlider_GetPercentage; + GUIControl_SettingsSlider_SetFloatRange Control_SettingsSlider_SetFloatRange; + GUIControl_SettingsSlider_SetFloatValue Control_SettingsSlider_SetFloatValue; + GUIControl_SettingsSlider_GetFloatValue Control_SettingsSlider_GetFloatValue; + GUIControl_SettingsSlider_SetFloatInterval Control_SettingsSlider_SetFloatInterval; + + GUIDialog_Keyboard_ShowAndGetInputWithHead Dialog_Keyboard_ShowAndGetInputWithHead; + GUIDialog_Keyboard_ShowAndGetInput Dialog_Keyboard_ShowAndGetInput; + GUIDialog_Keyboard_ShowAndGetNewPasswordWithHead Dialog_Keyboard_ShowAndGetNewPasswordWithHead; + GUIDialog_Keyboard_ShowAndGetNewPassword Dialog_Keyboard_ShowAndGetNewPassword; + GUIDialog_Keyboard_ShowAndVerifyNewPasswordWithHead Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead; + GUIDialog_Keyboard_ShowAndVerifyNewPassword Dialog_Keyboard_ShowAndVerifyNewPassword; + GUIDialog_Keyboard_ShowAndVerifyPassword Dialog_Keyboard_ShowAndVerifyPassword; + GUIDialog_Keyboard_ShowAndGetFilter Dialog_Keyboard_ShowAndGetFilter; + GUIDialog_Keyboard_SendTextToActiveKeyboard Dialog_Keyboard_SendTextToActiveKeyboard; + GUIDialog_Keyboard_isKeyboardActivated Dialog_Keyboard_isKeyboardActivated; + + GUIDialog_Numeric_ShowAndVerifyNewPassword Dialog_Numeric_ShowAndVerifyNewPassword; + GUIDialog_Numeric_ShowAndVerifyPassword Dialog_Numeric_ShowAndVerifyPassword; + GUIDialog_Numeric_ShowAndVerifyInput Dialog_Numeric_ShowAndVerifyInput; + GUIDialog_Numeric_ShowAndGetTime Dialog_Numeric_ShowAndGetTime; + GUIDialog_Numeric_ShowAndGetDate Dialog_Numeric_ShowAndGetDate; + GUIDialog_Numeric_ShowAndGetIPAddress Dialog_Numeric_ShowAndGetIPAddress; + GUIDialog_Numeric_ShowAndGetNumber Dialog_Numeric_ShowAndGetNumber; + GUIDialog_Numeric_ShowAndGetSeconds Dialog_Numeric_ShowAndGetSeconds; + + GUIDialog_FileBrowser_ShowAndGetFile Dialog_FileBrowser_ShowAndGetFile; + + GUIDialog_OK_ShowAndGetInputSingleText Dialog_OK_ShowAndGetInputSingleText; + GUIDialog_OK_ShowAndGetInputLineText Dialog_OK_ShowAndGetInputLineText; + + GUIDialog_YesNo_ShowAndGetInputSingleText Dialog_YesNo_ShowAndGetInputSingleText; + GUIDialog_YesNo_ShowAndGetInputLineText Dialog_YesNo_ShowAndGetInputLineText; + GUIDialog_YesNo_ShowAndGetInputLineButtonText Dialog_YesNo_ShowAndGetInputLineButtonText; + + GUIDialog_TextViewer Dialog_TextViewer; + GUIDialog_Select Dialog_Select; } CB_GUILib; typedef void (*PVRTransferEpgEntry)(void *userData, const ADDON_HANDLE handle, const EPG_TAG *epgentry); diff --git a/xbmc/addons/AddonCallbacksAddon.cpp b/xbmc/addons/AddonCallbacksAddon.cpp index 5824ce4201..0147f3f17f 100644 --- a/xbmc/addons/AddonCallbacksAddon.cpp +++ b/xbmc/addons/AddonCallbacksAddon.cpp @@ -252,7 +252,7 @@ bool CAddonCallbacksAddon::GetAddonSetting(void *addonData, const char *strSetti return false; } -char* CAddonCallbacksAddon::UnknownToUTF8(const char *strSource) +const char* CAddonCallbacksAddon::UnknownToUTF8(const char *strSource) { std::string string; if (strSource != NULL) @@ -263,7 +263,7 @@ char* CAddonCallbacksAddon::UnknownToUTF8(const char *strSource) return buffer; } -char* CAddonCallbacksAddon::GetLocalizedString(const void* addonData, long dwCode) +const char* CAddonCallbacksAddon::GetLocalizedString(const void* addonData, long dwCode) { CAddonCallbacks* helper = (CAddonCallbacks*) addonData; if (!helper || g_application.m_bStop) @@ -283,7 +283,7 @@ char* CAddonCallbacksAddon::GetLocalizedString(const void* addonData, long dwCod return buffer; } -char* CAddonCallbacksAddon::GetDVDMenuLanguage(const void* addonData) +const char* CAddonCallbacksAddon::GetDVDMenuLanguage(const void* addonData) { CAddonCallbacks* helper = (CAddonCallbacks*) addonData; if (!helper) @@ -295,7 +295,7 @@ char* CAddonCallbacksAddon::GetDVDMenuLanguage(const void* addonData) return buffer; } -void CAddonCallbacksAddon::FreeString(const void* addonData, char* str) +void CAddonCallbacksAddon::FreeString(const void* addonData, const char* str) { delete[] str; } diff --git a/xbmc/addons/AddonCallbacksAddon.h b/xbmc/addons/AddonCallbacksAddon.h index 6eed7cdbfd..142c177b9c 100644 --- a/xbmc/addons/AddonCallbacksAddon.h +++ b/xbmc/addons/AddonCallbacksAddon.h @@ -39,10 +39,10 @@ public: static bool GetAddonSetting(void *addonData, const char *strSettingName, void *settingValue); static void QueueNotification(void *addonData, const queue_msg_t type, const char *strMessage); static bool WakeOnLan(const char *mac); - static char* UnknownToUTF8(const char *strSource); - static char* GetLocalizedString(const void* addonData, long dwCode); - static char* GetDVDMenuLanguage(const void* addonData); - static void FreeString(const void* addonData, char* str); + static const char* UnknownToUTF8(const char *strSource); + static const char* GetLocalizedString(const void* addonData, long dwCode); + static const char* GetDVDMenuLanguage(const void* addonData); + static void FreeString(const void* addonData, const char* str); // file operations static void* OpenFile(const void* addonData, const char* strFileName, unsigned int flags); diff --git a/xbmc/addons/AddonCallbacksCodec.cpp b/xbmc/addons/AddonCallbacksCodec.cpp index 8ae1e4effc..9c7be30d47 100644 --- a/xbmc/addons/AddonCallbacksCodec.cpp +++ b/xbmc/addons/AddonCallbacksCodec.cpp @@ -81,6 +81,11 @@ private: tmp.codec_type = XBMC_CODEC_TYPE_SUBTITLE; tmp.codec_id = AV_CODEC_ID_DVB_TELETEXT; m_lookup.insert(std::make_pair("TELETEXT", tmp)); + + // rds is not returned by av_codec_next. we got our own decoder + tmp.codec_type = XBMC_CODEC_TYPE_RDS; + tmp.codec_id = AV_CODEC_ID_NONE; + m_lookup.insert(std::make_pair("RDS", tmp)); } std::map<std::string, xbmc_codec_t> m_lookup; diff --git a/xbmc/addons/AddonCallbacksGUI.cpp b/xbmc/addons/AddonCallbacksGUI.cpp index c0ac3b234f..9028e1ac25 100644 --- a/xbmc/addons/AddonCallbacksGUI.cpp +++ b/xbmc/addons/AddonCallbacksGUI.cpp @@ -38,6 +38,13 @@ #include "guilib/GUIEditControl.h" #include "guilib/GUIProgressControl.h" #include "guilib/GUIRenderingControl.h" +#include "guilib/GUIKeyboardFactory.h" +#include "dialogs/GUIDialogNumeric.h" +#include "dialogs/GUIDialogOK.h" +#include "dialogs/GUIDialogYesNo.h" +#include "dialogs/GUIDialogFileBrowser.h" +#include "dialogs/GUIDialogTextViewer.h" +#include "dialogs/GUIDialogSelect.h" #define CONTROL_BTNVIEWASICONS 2 #define CONTROL_BTNSORTBY 3 @@ -96,6 +103,8 @@ CAddonCallbacksGUI::CAddonCallbacksGUI(CAddon* addon) m_callbacks->Window_GetControl_Edit = CAddonCallbacksGUI::Window_GetControl_Edit; m_callbacks->Window_GetControl_Progress = CAddonCallbacksGUI::Window_GetControl_Progress; m_callbacks->Window_GetControl_RenderAddon = CAddonCallbacksGUI::Window_GetControl_RenderAddon; + m_callbacks->Window_GetControl_Slider = CAddonCallbacksGUI::Window_GetControl_Slider; + m_callbacks->Window_GetControl_SettingsSlider= CAddonCallbacksGUI::Window_GetControl_SettingsSlider; m_callbacks->Window_SetControlLabel = CAddonCallbacksGUI::Window_SetControlLabel; m_callbacks->Window_MarkDirtyRegion = CAddonCallbacksGUI::Window_MarkDirtyRegion; @@ -132,6 +141,66 @@ CAddonCallbacksGUI::CAddonCallbacksGUI(CAddon* addon) m_callbacks->RenderAddon_SetCallbacks = CAddonCallbacksGUI::RenderAddon_SetCallbacks; m_callbacks->RenderAddon_Delete = CAddonCallbacksGUI::RenderAddon_Delete; + + m_callbacks->Control_Slider_SetVisible = CAddonCallbacksGUI::Control_Slider_SetVisible; + m_callbacks->Control_Slider_GetDescription = CAddonCallbacksGUI::Control_Slider_GetDescription; + m_callbacks->Control_Slider_SetIntRange = CAddonCallbacksGUI::Control_Slider_SetIntRange; + m_callbacks->Control_Slider_SetIntValue = CAddonCallbacksGUI::Control_Slider_SetIntValue; + m_callbacks->Control_Slider_GetIntValue = CAddonCallbacksGUI::Control_Slider_GetIntValue; + m_callbacks->Control_Slider_SetIntInterval = CAddonCallbacksGUI::Control_Slider_SetIntInterval; + m_callbacks->Control_Slider_SetPercentage = CAddonCallbacksGUI::Control_Slider_SetPercentage; + m_callbacks->Control_Slider_GetPercentage = CAddonCallbacksGUI::Control_Slider_GetPercentage; + m_callbacks->Control_Slider_SetFloatRange = CAddonCallbacksGUI::Control_Slider_SetFloatRange; + m_callbacks->Control_Slider_SetFloatValue = CAddonCallbacksGUI::Control_Slider_SetFloatValue; + m_callbacks->Control_Slider_GetFloatValue = CAddonCallbacksGUI::Control_Slider_GetFloatValue; + m_callbacks->Control_Slider_SetFloatInterval = CAddonCallbacksGUI::Control_Slider_SetFloatInterval; + + m_callbacks->Control_SettingsSlider_SetVisible = CAddonCallbacksGUI::Control_SettingsSlider_SetVisible; + m_callbacks->Control_SettingsSlider_SetText = CAddonCallbacksGUI::Control_SettingsSlider_SetText; + m_callbacks->Control_SettingsSlider_GetDescription = CAddonCallbacksGUI::Control_SettingsSlider_GetDescription; + m_callbacks->Control_SettingsSlider_SetIntRange = CAddonCallbacksGUI::Control_SettingsSlider_SetIntRange; + m_callbacks->Control_SettingsSlider_SetIntValue = CAddonCallbacksGUI::Control_SettingsSlider_SetIntValue; + m_callbacks->Control_SettingsSlider_GetIntValue = CAddonCallbacksGUI::Control_SettingsSlider_GetIntValue; + m_callbacks->Control_SettingsSlider_SetIntInterval = CAddonCallbacksGUI::Control_SettingsSlider_SetIntInterval; + m_callbacks->Control_SettingsSlider_SetPercentage = CAddonCallbacksGUI::Control_SettingsSlider_SetPercentage; + m_callbacks->Control_SettingsSlider_GetPercentage = CAddonCallbacksGUI::Control_SettingsSlider_GetPercentage; + m_callbacks->Control_SettingsSlider_SetFloatRange = CAddonCallbacksGUI::Control_SettingsSlider_SetFloatRange; + m_callbacks->Control_SettingsSlider_SetFloatValue = CAddonCallbacksGUI::Control_SettingsSlider_SetFloatValue; + m_callbacks->Control_SettingsSlider_GetFloatValue = CAddonCallbacksGUI::Control_SettingsSlider_GetFloatValue; + m_callbacks->Control_SettingsSlider_SetFloatInterval = CAddonCallbacksGUI::Control_SettingsSlider_SetFloatInterval; + + m_callbacks->Dialog_Keyboard_ShowAndGetInputWithHead = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInputWithHead; + m_callbacks->Dialog_Keyboard_ShowAndGetInput = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInput; + m_callbacks->Dialog_Keyboard_ShowAndGetNewPasswordWithHead = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPasswordWithHead; + m_callbacks->Dialog_Keyboard_ShowAndGetNewPassword = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPassword; + m_callbacks->Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead; + m_callbacks->Dialog_Keyboard_ShowAndVerifyNewPassword = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPassword; + m_callbacks->Dialog_Keyboard_ShowAndVerifyPassword = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyPassword; + m_callbacks->Dialog_Keyboard_ShowAndGetFilter = CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetFilter; + m_callbacks->Dialog_Keyboard_SendTextToActiveKeyboard = CAddonCallbacksGUI::Dialog_Keyboard_SendTextToActiveKeyboard; + m_callbacks->Dialog_Keyboard_isKeyboardActivated = CAddonCallbacksGUI::Dialog_Keyboard_isKeyboardActivated; + + m_callbacks->Dialog_Numeric_ShowAndVerifyNewPassword = CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyNewPassword; + m_callbacks->Dialog_Numeric_ShowAndVerifyPassword = CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyPassword; + m_callbacks->Dialog_Numeric_ShowAndVerifyInput = CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyInput; + m_callbacks->Dialog_Numeric_ShowAndGetTime = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetTime; + m_callbacks->Dialog_Numeric_ShowAndGetDate = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetDate; + m_callbacks->Dialog_Numeric_ShowAndGetIPAddress = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetIPAddress; + m_callbacks->Dialog_Numeric_ShowAndGetNumber = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetNumber; + m_callbacks->Dialog_Numeric_ShowAndGetSeconds = CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetSeconds; + + m_callbacks->Dialog_FileBrowser_ShowAndGetFile = CAddonCallbacksGUI::Dialog_FileBrowser_ShowAndGetFile; + + m_callbacks->Dialog_OK_ShowAndGetInputSingleText = CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputSingleText; + m_callbacks->Dialog_OK_ShowAndGetInputLineText = CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputLineText; + + m_callbacks->Dialog_YesNo_ShowAndGetInputSingleText = CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputSingleText; + m_callbacks->Dialog_YesNo_ShowAndGetInputLineText = CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineText; + m_callbacks->Dialog_YesNo_ShowAndGetInputLineButtonText = CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineButtonText; + + m_callbacks->Dialog_TextViewer = CAddonCallbacksGUI::Dialog_TextViewer; + + m_callbacks->Dialog_Select = CAddonCallbacksGUI::Dialog_Select; } CAddonCallbacksGUI::~CAddonCallbacksGUI() @@ -1138,6 +1207,307 @@ const char* CAddonCallbacksGUI::Control_Progress_GetDescription(void *addonData, return buffer; } +/* + * GUI slider control callback functions + */ +GUIHANDLE CAddonCallbacksGUI::Window_GetControl_Slider(void *addonData, GUIHANDLE handle, int controlId) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return NULL; + + CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; + CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); + if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_SLIDER) + return NULL; + + return pGUIControl; +} + +void CAddonCallbacksGUI::Control_Slider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUIControl *pControl = (CGUIControl*)handle; + pControl->SetVisible(yesNo); +} + +const char* CAddonCallbacksGUI::Control_Slider_GetDescription(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return NULL; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + std::string string = pControl->GetDescription(); + + char *buffer = (char*) malloc (string.length()+1); + strcpy(buffer, string.c_str()); + return buffer; +} + +void CAddonCallbacksGUI::Control_Slider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + pControl->SetRange(iStart, iEnd); +} + +void CAddonCallbacksGUI::Control_Slider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + pControl->SetType(SPIN_CONTROL_TYPE_INT); + pControl->SetIntValue(iValue); +} + +int CAddonCallbacksGUI::Control_Slider_GetIntValue(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return 0; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + return pControl->GetIntValue(); +} + +void CAddonCallbacksGUI::Control_Slider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + pControl->SetIntInterval(iInterval); +} + +void CAddonCallbacksGUI::Control_Slider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); + pControl->SetPercentage(fPercent); +} + +float CAddonCallbacksGUI::Control_Slider_GetPercentage(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return 0.0f; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + return pControl->GetPercentage(); +} + +void CAddonCallbacksGUI::Control_Slider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + pControl->SetFloatRange(fStart, fEnd); +} + +void CAddonCallbacksGUI::Control_Slider_SetFloatValue(void *addonData, GUIHANDLE handle, float iValue) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); + pControl->SetFloatValue(iValue); +} + +float CAddonCallbacksGUI::Control_Slider_GetFloatValue(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return 0.0f; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + return pControl->GetFloatValue(); +} + +void CAddonCallbacksGUI::Control_Slider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISliderControl *pControl = (CGUISliderControl*)handle; + pControl->SetFloatInterval(fInterval); +} + +/* + * GUI settings slider control callback functions + */ +GUIHANDLE CAddonCallbacksGUI::Window_GetControl_SettingsSlider(void *addonData, GUIHANDLE handle, int controlId) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return NULL; + + CGUIAddonWindow *pAddonWindow = (CGUIAddonWindow*)handle; + CGUIControl* pGUIControl = (CGUIControl*)pAddonWindow->GetControl(controlId); + if (pGUIControl && pGUIControl->GetControlType() != CGUIControl::GUICONTROL_SETTINGS_SLIDER) + return NULL; + + return pGUIControl; +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUIControl *pControl = (CGUIControl*)handle; + pControl->SetVisible(yesNo); +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetText(void *addonData, GUIHANDLE handle, const char *label) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetText(label); +} + +const char* CAddonCallbacksGUI::Control_SettingsSlider_GetDescription(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return NULL; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + std::string string = pControl->GetDescription(); + + char *buffer = (char*) malloc (string.length()+1); + strcpy(buffer, string.c_str()); + return buffer; +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetRange(iStart, iEnd); +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetType(SPIN_CONTROL_TYPE_INT); + pControl->SetIntValue(iValue); +} + +int CAddonCallbacksGUI::Control_SettingsSlider_GetIntValue(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return 0; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + return pControl->GetIntValue(); +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetIntInterval(iInterval); +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); + pControl->SetPercentage(fPercent); +} + +float CAddonCallbacksGUI::Control_SettingsSlider_GetPercentage(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return 0.0f; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + return pControl->GetPercentage(); +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetFloatRange(fStart, fEnd); +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetFloatValue(void *addonData, GUIHANDLE handle, float fValue) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetType(SPIN_CONTROL_TYPE_FLOAT); + pControl->SetFloatValue(fValue); +} + +float CAddonCallbacksGUI::Control_SettingsSlider_GetFloatValue(void *addonData, GUIHANDLE handle) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return 0.0f; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + return pControl->GetFloatValue(); +} + +void CAddonCallbacksGUI::Control_SettingsSlider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval) +{ + CAddonCallbacks* helper = (CAddonCallbacks*) addonData; + if (!helper || !handle) + return; + + CGUISettingsSliderControl *pControl = (CGUISettingsSliderControl*)handle; + pControl->SetFloatInterval(fInterval); +} + +/* + * GUI list item control callback functions + */ GUIHANDLE CAddonCallbacksGUI::ListItem_Create(void *addonData, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path) { CAddonCallbacks* helper = (CAddonCallbacks*) addonData; @@ -1294,7 +1664,248 @@ void CAddonCallbacksGUI::RenderAddon_Delete(void *addonData, GUIHANDLE handle) Unlock(); } +/*! @name GUI Keyboard functions */ +//@{ +bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInputWithHead(char &aTextString, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs) +{ + std::string str = &aTextString; + bool bRet = CGUIKeyboardFactory::ShowAndGetInput(str, strHeading, allowEmptyResult, hiddenInput, autoCloseMs); + if (bRet) + strncpy(&aTextString, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetInput(char &aTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs) +{ + std::string str = &aTextString; + bool bRet = CGUIKeyboardFactory::ShowAndGetInput(str, allowEmptyResult, autoCloseMs); + if (bRet) + strncpy(&aTextString, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPasswordWithHead(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs) +{ + std::string str = &strNewPassword; + bool bRet = CGUIKeyboardFactory::ShowAndGetNewPassword(str, strHeading, allowEmptyResult, autoCloseMs); + if (bRet) + strncpy(&strNewPassword, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs) +{ + std::string str = &strNewPassword; + bool bRet = CGUIKeyboardFactory::ShowAndGetNewPassword(str, autoCloseMs); + if (bRet) + strncpy(&strNewPassword, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs) +{ + std::string str = &strNewPassword; + bool bRet = CGUIKeyboardFactory::ShowAndVerifyNewPassword(str, strHeading, allowEmptyResult, autoCloseMs); + if (bRet) + strncpy(&strNewPassword, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs) +{ + std::string str = &strNewPassword; + bool bRet = CGUIKeyboardFactory::ShowAndVerifyNewPassword(str, autoCloseMs); + if (bRet) + strncpy(&strNewPassword, str.c_str(), iMaxStringSize); + return bRet; +} + +int CAddonCallbacksGUI::Dialog_Keyboard_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs) +{ + std::string str = &strPassword; + int bRet = CGUIKeyboardFactory::ShowAndVerifyNewPassword(str, strHeading, iRetries, autoCloseMs); + if (bRet) + strncpy(&strPassword, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_ShowAndGetFilter(char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs) +{ + std::string strText = &aTextString; + bool bRet = CGUIKeyboardFactory::ShowAndGetFilter(strText, searching, autoCloseMs); + if (bRet) + strncpy(&aTextString, strText.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_SendTextToActiveKeyboard(const char *aTextString, bool closeKeyboard) +{ + return CGUIKeyboardFactory::SendTextToActiveKeyboard(aTextString, closeKeyboard); +} + +bool CAddonCallbacksGUI::Dialog_Keyboard_isKeyboardActivated() +{ + return CGUIKeyboardFactory::isKeyboardActivated(); +} +//@} + +/*! @name GUI Numeric functions */ +//@{ +bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize) +{ + std::string str = &strNewPassword; + bool bRet = CGUIDialogNumeric::ShowAndVerifyNewPassword(str); + if (bRet) + strncpy(&strNewPassword, str.c_str(), iMaxStringSize); + return bRet; +} + +int CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries) +{ + std::string str = &strPassword; + int bRet = CGUIDialogNumeric::ShowAndVerifyPassword(str, strHeading, iRetries); + if (bRet) + strncpy(&strPassword, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndVerifyInput(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput) +{ + std::string str = &strPassword; + bool bRet = CGUIDialogNumeric::ShowAndVerifyInput(str, strHeading, bGetUserInput); + if (bRet) + strncpy(&strPassword, str.c_str(), iMaxStringSize); + return bRet; +} +bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetTime(tm &time, const char *strHeading) +{ + SYSTEMTIME systemTime; + CDateTime dateTime(time); + dateTime.GetAsSystemTime(systemTime); + if (CGUIDialogNumeric::ShowAndGetTime(systemTime, strHeading)) + { + dateTime = systemTime; + dateTime.GetAsTm(time); + return true; + } + return false; +} + +bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetDate(tm &date, const char *strHeading) +{ + SYSTEMTIME systemTime; + CDateTime dateTime(date); + dateTime.GetAsSystemTime(systemTime); + if (CGUIDialogNumeric::ShowAndGetDate(systemTime, strHeading)) + { + dateTime = systemTime; + dateTime.GetAsTm(date); + return true; + } + return false; +} + +bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetIPAddress(char &strIPAddress, unsigned int iMaxStringSize, const char *strHeading) +{ + std::string strIP = &strIPAddress; + bool bRet = CGUIDialogNumeric::ShowAndGetIPAddress(strIP, strHeading); + if (bRet) + strncpy(&strIPAddress, strIP.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetNumber(char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs) +{ + std::string str = &strInput; + bool bRet = CGUIDialogNumeric::ShowAndGetNumber(str, strHeading, iAutoCloseTimeoutMs); + if (bRet) + strncpy(&strInput, str.c_str(), iMaxStringSize); + return bRet; +} + +bool CAddonCallbacksGUI::Dialog_Numeric_ShowAndGetSeconds(char &timeString, unsigned int iMaxStringSize, const char *strHeading) +{ + std::string str = &timeString; + bool bRet = CGUIDialogNumeric::ShowAndGetSeconds(str, strHeading); + if (bRet) + strncpy(&timeString, str.c_str(), iMaxStringSize); + return bRet; +} +//@} + +/*! @name GUI File browser functions */ +//@{ +bool CAddonCallbacksGUI::Dialog_FileBrowser_ShowAndGetFile(const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList) +{ + std::string strPath = &path; + bool bRet = CGUIDialogFileBrowser::ShowAndGetFile(directory, mask, heading, strPath, useThumbs, useFileDirectories, singleList); + if (bRet) + strncpy(&path, strPath.c_str(), iMaxStringSize); + return bRet; +} +//@} + +/*! @name GUI OK Dialog */ +//@{ +void CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputSingleText(const char *heading, const char *text) +{ + CGUIDialogOK::ShowAndGetInput(heading, text); +} + +void CAddonCallbacksGUI::Dialog_OK_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2) +{ + CGUIDialogOK::ShowAndGetInput(heading, line0, line1, line2); +} +//@} + +/*! @name GUI Yes No Dialog */ +//@{ +bool CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputSingleText(const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel) +{ + return CGUIDialogYesNo::ShowAndGetInput(heading, text, bCanceled, noLabel, yesLabel); +} + +bool CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel) +{ + return CGUIDialogYesNo::ShowAndGetInput(heading, line0, line1, line2, noLabel, yesLabel); +} + +bool CAddonCallbacksGUI::Dialog_YesNo_ShowAndGetInputLineButtonText(const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel) +{ + return CGUIDialogYesNo::ShowAndGetInput(heading, line0, line1, line2, bCanceled, noLabel, yesLabel); +} +//@} + +/*! @name GUI Text viewer Dialog */ +//@{ +void CAddonCallbacksGUI::Dialog_TextViewer(const char *heading, const char *text) +{ + CGUIDialogTextViewer* pDialog = (CGUIDialogTextViewer*)g_windowManager.GetWindow(WINDOW_DIALOG_TEXT_VIEWER); + pDialog->SetHeading(heading); + pDialog->SetText(text); + pDialog->DoModal(); +} +//@} + +/*! @name GUI select Dialog */ +//@{ +int CAddonCallbacksGUI::Dialog_Select(const char *heading, const char *entries[], unsigned int size, int selected) +{ + CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); + pDialog->Reset(); + pDialog->SetHeading(heading); + + for (unsigned int i = 0; i < size; i++) + pDialog->Add(entries[i]); + + if (selected > 0) + pDialog->SetSelected(selected); + + pDialog->DoModal(); + return pDialog->GetSelectedLabel(); +} +//@} CGUIAddonWindow::CGUIAddonWindow(int id, const std::string& strXML, CAddon* addon) : CGUIMediaWindow(id, strXML.c_str()) @@ -1593,7 +2204,7 @@ void CGUIAddonWindowDialog::Show_Internal(bool show /* = true */) // this dialog is derived from GUiMediaWindow // make sure it is rendered last - m_renderOrder = 2; + m_renderOrder = 1; while (m_bRunning && !g_application.m_bStop) { g_windowManager.ProcessRenderLoop(); diff --git a/xbmc/addons/AddonCallbacksGUI.h b/xbmc/addons/AddonCallbacksGUI.h index 2a3df8f9c1..ae032a7873 100644 --- a/xbmc/addons/AddonCallbacksGUI.h +++ b/xbmc/addons/AddonCallbacksGUI.h @@ -28,6 +28,7 @@ class CGUISpinControlEx; class CGUIButtonControl; class CGUIRadioButtonControl; +class CGUISliderControl; class CGUISettingsSliderControl; class CGUIEditControl; class CGUIRenderingControl; @@ -99,6 +100,36 @@ public: static void Control_Progress_SetInfo(void *addonData, GUIHANDLE handle, int iInfo); static int Control_Progress_GetInfo(void *addonData, GUIHANDLE handle); static const char * Control_Progress_GetDescription(void *addonData, GUIHANDLE handle); + + static GUIHANDLE Window_GetControl_Slider(void *addonData, GUIHANDLE handle, int controlId); + static void Control_Slider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo); + static const char * Control_Slider_GetDescription(void *addonData, GUIHANDLE handle); + static void Control_Slider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd); + static void Control_Slider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue); + static int Control_Slider_GetIntValue(void *addonData, GUIHANDLE handle); + static void Control_Slider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval); + static void Control_Slider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent); + static float Control_Slider_GetPercentage(void *addonData, GUIHANDLE handle); + static void Control_Slider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd); + static void Control_Slider_SetFloatValue(void *addonData, GUIHANDLE handle, float fValue); + static float Control_Slider_GetFloatValue(void *addonData, GUIHANDLE handle); + static void Control_Slider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval); + + static GUIHANDLE Window_GetControl_SettingsSlider(void *addonData, GUIHANDLE handle, int controlId); + static void Control_SettingsSlider_SetVisible(void *addonData, GUIHANDLE handle, bool yesNo); + static void Control_SettingsSlider_SetText(void *addonData, GUIHANDLE handle, const char *label); + static const char * Control_SettingsSlider_GetDescription(void *addonData, GUIHANDLE handle); + static void Control_SettingsSlider_SetIntRange(void *addonData, GUIHANDLE handle, int iStart, int iEnd); + static void Control_SettingsSlider_SetIntValue(void *addonData, GUIHANDLE handle, int iValue); + static int Control_SettingsSlider_GetIntValue(void *addonData, GUIHANDLE handle); + static void Control_SettingsSlider_SetIntInterval(void *addonData, GUIHANDLE handle, int iInterval); + static void Control_SettingsSlider_SetPercentage(void *addonData, GUIHANDLE handle, float fPercent); + static float Control_SettingsSlider_GetPercentage(void *addonData, GUIHANDLE handle); + static void Control_SettingsSlider_SetFloatRange(void *addonData, GUIHANDLE handle, float fStart, float fEnd); + static void Control_SettingsSlider_SetFloatValue(void *addonData, GUIHANDLE handle, float fValue); + static float Control_SettingsSlider_GetFloatValue(void *addonData, GUIHANDLE handle); + static void Control_SettingsSlider_SetFloatInterval(void *addonData, GUIHANDLE handle, float fInterval); + static GUIHANDLE ListItem_Create(void *addonData, const char *label, const char *label2, const char *iconImage, const char *thumbnailImage, const char *path); static const char * ListItem_GetLabel(void *addonData, GUIHANDLE handle); static void ListItem_SetLabel(void *addonData, GUIHANDLE handle, const char *label); @@ -114,6 +145,38 @@ public: static void RenderAddon_Delete(void *addonData, GUIHANDLE handle); static void RenderAddon_MarkDirty(void *addonData, GUIHANDLE handle); + static bool Dialog_Keyboard_ShowAndGetInput(char &aTextString, unsigned int iMaxStringSize, bool allowEmptyResult, unsigned int autoCloseMs); + static bool Dialog_Keyboard_ShowAndGetInputWithHead(char &aTextString, unsigned int iMaxStringSize, const char *heading, bool allowEmptyResult, bool hiddenInput, unsigned int autoCloseMs); + static bool Dialog_Keyboard_ShowAndGetNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); + static bool Dialog_Keyboard_ShowAndGetNewPasswordWithHead(char &newPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmptyResult, unsigned int autoCloseMs); + static bool Dialog_Keyboard_ShowAndVerifyNewPassword(char &strNewPassword, unsigned int iMaxStringSize, unsigned int autoCloseMs); + static bool Dialog_Keyboard_ShowAndVerifyNewPasswordWithHead(char &strNewPassword, unsigned int iMaxStringSize, const char *strHeading, bool allowEmpty, unsigned int autoCloseMs); + static int Dialog_Keyboard_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries, unsigned int autoCloseMs); + static bool Dialog_Keyboard_ShowAndGetFilter(char &aTextString, unsigned int iMaxStringSize, bool searching, unsigned int autoCloseMs); + static bool Dialog_Keyboard_SendTextToActiveKeyboard(const char *aTextString, bool closeKeyboard); + static bool Dialog_Keyboard_isKeyboardActivated(); + + static bool Dialog_Numeric_ShowAndVerifyNewPassword(char &strNewPasswor, unsigned int iMaxStringSized); + static int Dialog_Numeric_ShowAndVerifyPassword(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, int iRetries); + static bool Dialog_Numeric_ShowAndVerifyInput(char &strPassword, unsigned int iMaxStringSize, const char *strHeading, bool bGetUserInput); + static bool Dialog_Numeric_ShowAndGetTime(tm &time, const char *strHeading); + static bool Dialog_Numeric_ShowAndGetDate(tm &date, const char *strHeading); + static bool Dialog_Numeric_ShowAndGetIPAddress(char &strIPAddress, unsigned int iMaxStringSize, const char *strHeading); + static bool Dialog_Numeric_ShowAndGetNumber(char &strInput, unsigned int iMaxStringSize, const char *strHeading, unsigned int iAutoCloseTimeoutMs); + static bool Dialog_Numeric_ShowAndGetSeconds(char &timeString, unsigned int iMaxStringSize, const char *strHeading); + + static bool Dialog_FileBrowser_ShowAndGetFile(const char *directory, const char *mask, const char *heading, char &path, unsigned int iMaxStringSize, bool useThumbs, bool useFileDirectories, bool singleList); + + static void Dialog_OK_ShowAndGetInputSingleText(const char *heading, const char *text); + static void Dialog_OK_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2); + + static bool Dialog_YesNo_ShowAndGetInputSingleText(const char *heading, const char *text, bool& bCanceled, const char *noLabel, const char *yesLabel); + static bool Dialog_YesNo_ShowAndGetInputLineText(const char *heading, const char *line0, const char *line1, const char *line2, const char *noLabel, const char *yesLabel); + static bool Dialog_YesNo_ShowAndGetInputLineButtonText(const char *heading, const char *line0, const char *line1, const char *line2, bool &bCanceled, const char *noLabel, const char *yesLabel); + + static void Dialog_TextViewer(const char *heading, const char *text); + static int Dialog_Select(const char *heading, const char *entries[], unsigned int size, int selected); + private: CB_GUILib *m_callbacks; CAddon *m_addon; diff --git a/xbmc/addons/include/xbmc_codec_types.h b/xbmc/addons/include/xbmc_codec_types.h index 419196ed0b..98003e036e 100644 --- a/xbmc/addons/include/xbmc_codec_types.h +++ b/xbmc/addons/include/xbmc_codec_types.h @@ -34,6 +34,7 @@ typedef enum XBMC_CODEC_TYPE_AUDIO, XBMC_CODEC_TYPE_DATA, XBMC_CODEC_TYPE_SUBTITLE, + XBMC_CODEC_TYPE_RDS, XBMC_CODEC_TYPE_NB } xbmc_codec_type_t; diff --git a/xbmc/addons/include/xbmc_pvr_dll.h b/xbmc/addons/include/xbmc_pvr_dll.h index 6ef21f3b8e..3ad46fc64e 100644 --- a/xbmc/addons/include/xbmc_pvr_dll.h +++ b/xbmc/addons/include/xbmc_pvr_dll.h @@ -176,8 +176,9 @@ extern "C" * Show the channel scan dialog if this backend supports it. * @return PVR_ERROR_NO_ERROR if the dialog was displayed successfully. * @remarks Required if bSupportsChannelScan is set to true. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + * @note see libXBMC_gui.h about related parts */ - PVR_ERROR DialogChannelScan(void); + PVR_ERROR OpenDialogChannelScan(void); /*! * @return The total amount of channels on the backend, or -1 on error. @@ -201,7 +202,7 @@ extern "C" * Delete a channel from the backend. * @param channel The channel to delete. * @return PVR_ERROR_NO_ERROR if the channel has been deleted successfully. - * @remarks Optional. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + * @remarks Required if bSupportsChannelSettings is set to true. */ PVR_ERROR DeleteChannel(const PVR_CHANNEL& channel); @@ -209,7 +210,7 @@ extern "C" * Rename a channel on the backend. * @param channel The channel to rename, containing the new channel name. * @return PVR_ERROR_NO_ERROR if the channel has been renamed successfully. - * @remarks Optional. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + * @remarks Optional, and only used if bSupportsChannelSettings is set to true. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. */ PVR_ERROR RenameChannel(const PVR_CHANNEL& channel); @@ -217,7 +218,7 @@ extern "C" * Move a channel to another channel number on the backend. * @param channel The channel to move, containing the new channel number. * @return PVR_ERROR_NO_ERROR if the channel has been moved successfully. - * @remarks Optional. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + * @remarks Optional, and only used if bSupportsChannelSettings is set to true. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. */ PVR_ERROR MoveChannel(const PVR_CHANNEL& channel); @@ -225,17 +226,19 @@ extern "C" * Show the channel settings dialog, if supported by the backend. * @param channel The channel to show the dialog for. * @return PVR_ERROR_NO_ERROR if the dialog has been displayed successfully. - * @remarks Optional. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + * @remarks Required if bSupportsChannelSettings is set to true. + * @note see libXBMC_gui.h about related parts */ - PVR_ERROR DialogChannelSettings(const PVR_CHANNEL& channel); + PVR_ERROR OpenDialogChannelSettings(const PVR_CHANNEL& channel); /*! * Show the dialog to add a channel on the backend, if supported by the backend. * @param channel The channel to add. * @return PVR_ERROR_NO_ERROR if the channel has been added successfully. - * @remarks Optional. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + * @remarks Required if bSupportsChannelSettings is set to true. + * @note see libXBMC_gui.h about related parts */ - PVR_ERROR DialogAddChannel(const PVR_CHANNEL& channel); + PVR_ERROR OpenDialogChannelAdd(const PVR_CHANNEL& channel); //@} /** @name PVR recording methods @@ -245,19 +248,21 @@ extern "C" */ //@{ /*! - * @return The total amount of channels on the backend or -1 on error. + * @return The total amount of recordings on the backend or -1 on error. + * @param deleted if set return deleted recording (called if bSupportsRecordingsUndelete set to true) * @remarks Required if bSupportsRecordings is set to true. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. */ - int GetRecordingsAmount(void); + int GetRecordingsAmount(bool deleted); /*! * Request the list of all recordings from the backend, if supported. * Recording entries are added to XBMC by calling TransferRecordingEntry() on the callback. * @param handle Handle to pass to the callback method. + * @param deleted if set return deleted recording (called if bSupportsRecordingsUndelete set to true) * @return PVR_ERROR_NO_ERROR if the recordings have been fetched successfully. * @remarks Required if bSupportsRecordings is set to true. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. */ - PVR_ERROR GetRecordings(ADDON_HANDLE handle); + PVR_ERROR GetRecordings(ADDON_HANDLE handle, bool deleted); /*! * Delete a recording on the backend. @@ -268,6 +273,20 @@ extern "C" PVR_ERROR DeleteRecording(const PVR_RECORDING& recording); /*! + * Undelete a recording on the backend. + * @param recording The recording to undelete. + * @return PVR_ERROR_NO_ERROR if the recording has been undeleted successfully. + * @remarks Optional, and only used if bSupportsRecordingsUndelete is set to true. Return PVR_ERROR_NOT_IMPLEMENTED if this add-on won't provide this function. + */ + PVR_ERROR UndeleteRecording(const PVR_RECORDING& recording); + + /*! + * @brief Delete all recordings permanent which in the deleted folder on the backend. + * @return PVR_ERROR_NO_ERROR if the recordings has been deleted successfully. + */ + PVR_ERROR DeleteAllRecordingsFromTrash(); + + /*! * Rename a recording on the backend. * @param recording The recording to rename, containing the new name. * @return PVR_ERROR_NO_ERROR if the recording has been renamed successfully. @@ -617,7 +636,7 @@ extern "C" pClient->GetBackendName = GetBackendName; pClient->GetBackendVersion = GetBackendVersion; pClient->GetDriveSpace = GetDriveSpace; - pClient->DialogChannelScan = DialogChannelScan; + pClient->OpenDialogChannelScan = OpenDialogChannelScan; pClient->MenuHook = CallMenuHook; pClient->GetEpg = GetEPGForChannel; @@ -631,12 +650,14 @@ extern "C" pClient->DeleteChannel = DeleteChannel; pClient->RenameChannel = RenameChannel; pClient->MoveChannel = MoveChannel; - pClient->DialogChannelSettings = DialogChannelSettings; - pClient->DialogAddChannel = DialogAddChannel; + pClient->OpenDialogChannelSettings = OpenDialogChannelSettings; + pClient->OpenDialogChannelAdd = OpenDialogChannelAdd; pClient->GetRecordingsAmount = GetRecordingsAmount; pClient->GetRecordings = GetRecordings; pClient->DeleteRecording = DeleteRecording; + pClient->UndeleteRecording = UndeleteRecording; + pClient->DeleteAllRecordingsFromTrash = DeleteAllRecordingsFromTrash; pClient->RenameRecording = RenameRecording; pClient->SetRecordingPlayCount = SetRecordingPlayCount; pClient->SetRecordingLastPlayedPosition = SetRecordingLastPlayedPosition; diff --git a/xbmc/addons/include/xbmc_pvr_types.h b/xbmc/addons/include/xbmc_pvr_types.h index 8d78818e78..5285bd1551 100644 --- a/xbmc/addons/include/xbmc_pvr_types.h +++ b/xbmc/addons/include/xbmc_pvr_types.h @@ -75,10 +75,10 @@ struct DemuxPacket; #define PVR_STREAM_MAX_STREAMS 20 /* current PVR API version */ -#define XBMC_PVR_API_VERSION "1.9.3" +#define XBMC_PVR_API_VERSION "1.9.4" /* min. PVR API version */ -#define XBMC_PVR_MIN_API_VERSION "1.9.3" +#define XBMC_PVR_MIN_API_VERSION "1.9.4" #ifdef __cplusplus extern "C" { @@ -122,13 +122,14 @@ extern "C" { */ typedef enum { - PVR_MENUHOOK_UNKNOWN =-1, /*!< @brief unknown menu hook */ - PVR_MENUHOOK_ALL = 0, /*!< @brief all categories */ - PVR_MENUHOOK_CHANNEL = 1, /*!< @brief for channels */ - PVR_MENUHOOK_TIMER = 2, /*!< @brief for timers */ - PVR_MENUHOOK_EPG = 3, /*!< @brief for EPG */ - PVR_MENUHOOK_RECORDING = 4, /*!< @brief for recordings */ - PVR_MENUHOOK_SETTING = 5, /*!< @brief for settings */ + PVR_MENUHOOK_UNKNOWN =-1, /*!< @brief unknown menu hook */ + PVR_MENUHOOK_ALL = 0, /*!< @brief all categories */ + PVR_MENUHOOK_CHANNEL = 1, /*!< @brief for channels */ + PVR_MENUHOOK_TIMER = 2, /*!< @brief for timers */ + PVR_MENUHOOK_EPG = 3, /*!< @brief for EPG */ + PVR_MENUHOOK_RECORDING = 4, /*!< @brief for recordings */ + PVR_MENUHOOK_DELETED_RECORDING = 5, /*!< @brief for deleted recordings */ + PVR_MENUHOOK_SETTING = 6, /*!< @brief for settings */ } PVR_MENUHOOK_CAT; /*! @@ -150,9 +151,11 @@ extern "C" { bool bSupportsTV; /*!< @brief true if this add-on provides TV channels */ bool bSupportsRadio; /*!< @brief true if this add-on supports radio channels */ bool bSupportsRecordings; /*!< @brief true if this add-on supports playback of recordings stored on the backend */ + bool bSupportsRecordingsUndelete; /*!< @brief true if this add-on supports undelete of recordings stored on the backend */ bool bSupportsTimers; /*!< @brief true if this add-on supports the creation and editing of timers */ bool bSupportsChannelGroups; /*!< @brief true if this add-on supports channel groups */ bool bSupportsChannelScan; /*!< @brief true if this add-on support scanning for new channels on the backend */ + bool bSupportsChannelSettings; /*!< @brief true if this add-on supports the following functions: DeleteChannel, RenameChannel, MoveChannel, DialogChannelSettings and DialogAddChannel */ bool bHandlesInputStream; /*!< @brief true if this add-on provides an input stream. false if XBMC handles the stream. */ bool bHandlesDemuxing; /*!< @brief true if this add-on demultiplexes packets. */ bool bSupportsRecordingFolders; /*!< @brief true if the backend supports timers / recordings in folders. */ @@ -295,6 +298,7 @@ extern "C" { int iGenreSubType; /*!< @brief (optional) genre sub type */ int iPlayCount; /*!< @brief (optional) play count of this recording on the client */ int iLastPlayedPosition; /*!< @brief (optional) last played position of this recording on the client */ + bool bIsDeleted; /*!< @brief (optional) shows this recording is deleted and can be undelete */ } ATTRIBUTE_PACKED PVR_RECORDING; /*! @@ -349,17 +353,19 @@ extern "C" { int (__cdecl* GetChannelGroupsAmount)(void); PVR_ERROR (__cdecl* GetChannelGroups)(ADDON_HANDLE, bool); PVR_ERROR (__cdecl* GetChannelGroupMembers)(ADDON_HANDLE, const PVR_CHANNEL_GROUP&); - PVR_ERROR (__cdecl* DialogChannelScan)(void); + PVR_ERROR (__cdecl* OpenDialogChannelScan)(void); int (__cdecl* GetChannelsAmount)(void); PVR_ERROR (__cdecl* GetChannels)(ADDON_HANDLE, bool); PVR_ERROR (__cdecl* DeleteChannel)(const PVR_CHANNEL&); PVR_ERROR (__cdecl* RenameChannel)(const PVR_CHANNEL&); PVR_ERROR (__cdecl* MoveChannel)(const PVR_CHANNEL&); - PVR_ERROR (__cdecl* DialogChannelSettings)(const PVR_CHANNEL&); - PVR_ERROR (__cdecl* DialogAddChannel)(const PVR_CHANNEL&); - int (__cdecl* GetRecordingsAmount)(void); - PVR_ERROR (__cdecl* GetRecordings)(ADDON_HANDLE); + PVR_ERROR (__cdecl* OpenDialogChannelSettings)(const PVR_CHANNEL&); + PVR_ERROR (__cdecl* OpenDialogChannelAdd)(const PVR_CHANNEL&); + int (__cdecl* GetRecordingsAmount)(bool); + PVR_ERROR (__cdecl* GetRecordings)(ADDON_HANDLE, bool); PVR_ERROR (__cdecl* DeleteRecording)(const PVR_RECORDING&); + PVR_ERROR (__cdecl* UndeleteRecording)(const PVR_RECORDING&); + PVR_ERROR (__cdecl* DeleteAllRecordingsFromTrash)(void); PVR_ERROR (__cdecl* RenameRecording)(const PVR_RECORDING&); PVR_ERROR (__cdecl* SetRecordingPlayCount)(const PVR_RECORDING&, int); PVR_ERROR (__cdecl* SetRecordingLastPlayedPosition)(const PVR_RECORDING&, int); diff --git a/xbmc/dialogs/GUIDialogContextMenu.h b/xbmc/dialogs/GUIDialogContextMenu.h index 76cf6ca7a6..ce0c2b7b86 100644 --- a/xbmc/dialogs/GUIDialogContextMenu.h +++ b/xbmc/dialogs/GUIDialogContextMenu.h @@ -129,6 +129,8 @@ enum CONTEXT_BUTTON { CONTEXT_BUTTON_CANCELLED = 0, CONTEXT_BUTTON_MOVIESET_ADD_REMOVE_ITEMS, CONTEXT_BUTTON_BROWSE_INTO, CONTEXT_BUTTON_EDIT_SORTTITLE, + CONTEXT_BUTTON_UNDELETE, + CONTEXT_BUTTON_DELETE_ALL, CONTEXT_BUTTON_USER1, CONTEXT_BUTTON_USER2, CONTEXT_BUTTON_USER3, diff --git a/xbmc/dialogs/GUIDialogMediaSource.cpp b/xbmc/dialogs/GUIDialogMediaSource.cpp index bce1378242..533e6afabe 100644 --- a/xbmc/dialogs/GUIDialogMediaSource.cpp +++ b/xbmc/dialogs/GUIDialogMediaSource.cpp @@ -300,10 +300,16 @@ void CGUIDialogMediaSource::OnPathBrowse(int item) // add the recordings dir as needed if (CPVRDirectory::HasRecordings()) { - share1.strPath = "pvr://recordings/"; + share1.strPath = "pvr://recordings/active/"; share1.strName = g_localizeStrings.Get(19017); // TV Recordings extraShares.push_back(share1); } + if (CPVRDirectory::HasDeletedRecordings()) + { + share1.strPath = "pvr://recordings/deleted/"; + share1.strName = g_localizeStrings.Get(19108); // Deleted TV Recordings + extraShares.push_back(share1); + } } else if (m_type == "pictures") { diff --git a/xbmc/filesystem/PVRDirectory.cpp b/xbmc/filesystem/PVRDirectory.cpp index 7680f58fba..e03a9a04c6 100644 --- a/xbmc/filesystem/PVRDirectory.cpp +++ b/xbmc/filesystem/PVRDirectory.cpp @@ -71,8 +71,13 @@ bool CPVRDirectory::GetDirectory(const CURL& url, CFileItemList &items) item->SetLabelPreformated(true); items.Add(item); - item.reset(new CFileItem(base + "recordings/", true)); - item->SetLabel(g_localizeStrings.Get(19017)); + item.reset(new CFileItem(base + "recordings/active/", true)); + item->SetLabel(g_localizeStrings.Get(19017)); // TV Recordings + item->SetLabelPreformated(true); + items.Add(item); + + item.reset(new CFileItem(base + "recordings/deleted/", true)); + item->SetLabel(g_localizeStrings.Get(19108)); // Deleted TV Recordings item->SetLabelPreformated(true); items.Add(item); @@ -121,3 +126,9 @@ bool CPVRDirectory::HasRecordings() return g_PVRManager.IsStarted() ? g_PVRRecordings->GetNumRecordings() > 0 : false; } + +bool CPVRDirectory::HasDeletedRecordings() +{ + return g_PVRManager.IsStarted() ? + g_PVRRecordings->HasDeletedRecordings() : false; +} diff --git a/xbmc/filesystem/PVRDirectory.h b/xbmc/filesystem/PVRDirectory.h index 5df52899a7..b4443a9e19 100644 --- a/xbmc/filesystem/PVRDirectory.h +++ b/xbmc/filesystem/PVRDirectory.h @@ -38,6 +38,7 @@ public: static bool SupportsWriteFileOperations(const std::string& strPath); static bool IsLiveTV(const std::string& strPath); static bool HasRecordings(); + static bool HasDeletedRecordings(); virtual bool Exists(const CURL& url); diff --git a/xbmc/filesystem/PVRFile.cpp b/xbmc/filesystem/PVRFile.cpp index 0563dd7e9a..2b6a3ac4a1 100644 --- a/xbmc/filesystem/PVRFile.cpp +++ b/xbmc/filesystem/PVRFile.cpp @@ -70,7 +70,7 @@ bool CPVRFile::Open(const CURL& url) return false; } } - else if (StringUtils::StartsWith(strURL, "pvr://recordings/")) + else if (StringUtils::StartsWith(strURL, "pvr://recordings/active")) { CFileItemPtr tag = g_PVRRecordings->GetByPath(strURL); if (tag && tag->HasPVRRecordingInfoTag()) @@ -87,6 +87,11 @@ bool CPVRFile::Open(const CURL& url) return false; } } + else if (StringUtils::StartsWith(strURL, "pvr://recordings/deleted/")) + { + CLog::Log(LOGNOTICE, "PVRFile - Playback of deleted recordings is not possible (%s)", strURL.c_str()); + return false; + } else { CLog::Log(LOGERROR, "%s - invalid path specified %s", __FUNCTION__, strURL.c_str()); @@ -298,7 +303,7 @@ bool CPVRFile::Rename(const CURL& url, const CURL& urlnew) if (found != std::string::npos) newname = newname.substr(found+1); - if (StringUtils::StartsWith(path, "recordings/") && path[path.size()-1] != '/') + if (StringUtils::StartsWith(path, "recordings/active/") && path[path.size()-1] != '/') { std::string strURL = url.Get(); CFileItemPtr tag = g_PVRRecordings->GetByPath(strURL); diff --git a/xbmc/pvr/PVRGUIInfo.cpp b/xbmc/pvr/PVRGUIInfo.cpp index 796a0048a5..843c0b009a 100644 --- a/xbmc/pvr/PVRGUIInfo.cpp +++ b/xbmc/pvr/PVRGUIInfo.cpp @@ -71,6 +71,7 @@ void CPVRGUIInfo::ResetProperties(void) m_strBackendHost .clear(); m_strBackendTimers .clear(); m_strBackendRecordings .clear(); + m_strBackendDeletedRecordings .clear(); m_strBackendChannels .clear(); m_iBackendUsedDiskspace = 0; m_iBackendTotalDiskspace = 0; @@ -380,6 +381,9 @@ bool CPVRGUIInfo::TranslateCharInfo(DWORD dwInfo, std::string &strValue) const case PVR_BACKEND_RECORDINGS: CharInfoBackendRecordings(strValue); break; + case PVR_BACKEND_DELETED_RECORDINGS: + CharInfoBackendDeletedRecordings(strValue); + break; case PVR_BACKEND_NUMBER: CharInfoBackendNumber(strValue); break; @@ -637,6 +641,14 @@ void CPVRGUIInfo::CharInfoBackendRecordings(std::string &strValue) const strValue = m_strBackendRecordings; } +void CPVRGUIInfo::CharInfoBackendDeletedRecordings(std::string &strValue) const +{ + if (m_strBackendDeletedRecordings.empty()) + strValue = g_localizeStrings.Get(13205); /* Unknown */ + else + strValue = m_strBackendDeletedRecordings; +} + void CPVRGUIInfo::CharInfoPlayingClientName(std::string &strValue) const { if (m_strPlayingClientName.empty()) @@ -685,6 +697,7 @@ void CPVRGUIInfo::UpdateBackendCache(void) std::string strBackendHost; std::string strBackendTimers; std::string strBackendRecordings; + std::string strBackendDeletedRecordings; std::string strBackendChannels; long long iBackendkBUsed(0); long long iBackendkBTotal(0); @@ -727,27 +740,34 @@ void CPVRGUIInfo::UpdateBackendCache(void) else strBackendTimers = g_localizeStrings.Get(161); - int NumRecordings = activeClient->second->GetRecordingsAmount(); + int NumRecordings = activeClient->second->GetRecordingsAmount(false); if (NumRecordings >= 0) strBackendRecordings = StringUtils::Format("%i", NumRecordings); else strBackendRecordings = g_localizeStrings.Get(161); + int NumDeletedRecordings = activeClient->second->GetRecordingsAmount(true); + if (NumDeletedRecordings >= 0) + strBackendDeletedRecordings = StringUtils::Format("%i", NumDeletedRecordings); + else + strBackendDeletedRecordings = g_localizeStrings.Get(161); /* Unavailable */ + strBackendName = activeClient->second->GetBackendName(); strBackendVersion = activeClient->second->GetBackendVersion(); strBackendHost = activeClient->second->GetConnectionString(); } CSingleLock lock(m_critSection); - m_strBackendName = strBackendName; - m_strBackendVersion = strBackendVersion; - m_strBackendHost = strBackendHost; - m_strBackendTimers = strBackendTimers; - m_strBackendRecordings = strBackendRecordings; - m_strBackendChannels = strBackendChannels; - m_iActiveClients = iActiveClients; - m_iBackendUsedDiskspace = iBackendkBUsed; - m_iBackendTotalDiskspace = iBackendkBTotal; + m_strBackendName = strBackendName; + m_strBackendVersion = strBackendVersion; + m_strBackendHost = strBackendHost; + m_strBackendTimers = strBackendTimers; + m_strBackendRecordings = strBackendRecordings; + m_strBackendDeletedRecordings = strBackendDeletedRecordings; + m_strBackendChannels = strBackendChannels; + m_iActiveClients = iActiveClients; + m_iBackendUsedDiskspace = iBackendkBUsed; + m_iBackendTotalDiskspace = iBackendkBTotal; } void CPVRGUIInfo::UpdateTimersCache(void) diff --git a/xbmc/pvr/PVRGUIInfo.h b/xbmc/pvr/PVRGUIInfo.h index e71cc9d18f..d285345e1f 100644 --- a/xbmc/pvr/PVRGUIInfo.h +++ b/xbmc/pvr/PVRGUIInfo.h @@ -134,6 +134,7 @@ namespace PVR void CharInfoBackendChannels(std::string &strValue) const; void CharInfoBackendTimers(std::string &strValue) const; void CharInfoBackendRecordings(std::string &strValue) const; + void CharInfoBackendDeletedRecordings(std::string &strValue) const; void CharInfoPlayingClientName(std::string &strValue) const; void CharInfoEncryption(std::string &strValue) const; void CharInfoService(std::string &strValue) const; @@ -161,6 +162,7 @@ namespace PVR std::string m_strBackendHost; std::string m_strBackendTimers; std::string m_strBackendRecordings; + std::string m_strBackendDeletedRecordings; std::string m_strBackendChannels; long long m_iBackendUsedDiskspace; long long m_iBackendTotalDiskspace; diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp index f327e15407..1049e8c052 100644 --- a/xbmc/pvr/addons/PVRClient.cpp +++ b/xbmc/pvr/addons/PVRClient.cpp @@ -246,6 +246,7 @@ void CPVRClient::WriteClientRecordingInfo(const CPVRRecording &xbmcRecording, PV addonRecording.iLifetime = xbmcRecording.m_iLifetime; addonRecording.iPlayCount = xbmcRecording.m_playCount; addonRecording.iLastPlayedPosition = (int)xbmcRecording.m_resumePoint.timeInSeconds; + addonRecording.bIsDeleted = xbmcRecording.IsDeleted(); strncpy(addonRecording.strDirectory, xbmcRecording.m_strDirectory.c_str(), sizeof(addonRecording.strDirectory) - 1); strncpy(addonRecording.strStreamURL, xbmcRecording.m_strStreamURL.c_str(), sizeof(addonRecording.strStreamURL) - 1); strncpy(addonRecording.strIconPath, xbmcRecording.m_strIconPath.c_str(), sizeof(addonRecording.strIconPath) - 1); @@ -270,6 +271,7 @@ void CPVRClient::WriteClientTimerInfo(const CPVRTimerInfoTag &xbmcTimer, PVR_TIM addonTimer.iClientIndex = xbmcTimer.m_iClientIndex; addonTimer.state = xbmcTimer.m_state; + addonTimer.iClientIndex = xbmcTimer.m_iClientIndex; addonTimer.iClientChannelUid = xbmcTimer.m_iClientChannelUid; strncpy(addonTimer.strTitle, xbmcTimer.m_strTitle.c_str(), sizeof(addonTimer.strTitle) - 1); strncpy(addonTimer.strDirectory, xbmcTimer.m_strDirectory.c_str(), sizeof(addonTimer.strDirectory) - 1); @@ -453,12 +455,112 @@ PVR_ERROR CPVRClient::StartChannelScan(void) if (!m_addonCapabilities.bSupportsChannelScan) return PVR_ERROR_NOT_IMPLEMENTED; - try { return m_pStruct->DialogChannelScan(); } + try { return m_pStruct->OpenDialogChannelScan(); } catch (std::exception &e) { LogException(e, __FUNCTION__); } return PVR_ERROR_UNKNOWN; } +PVR_ERROR CPVRClient::OpenDialogChannelAdd(const CPVRChannel &channel) +{ + if (!m_bReadyToUse) + return PVR_ERROR_REJECTED; + + if (!m_addonCapabilities.bSupportsChannelSettings) + return PVR_ERROR_NOT_IMPLEMENTED; + + PVR_ERROR retVal(PVR_ERROR_UNKNOWN); + try + { + PVR_CHANNEL addonChannel; + WriteClientChannelInfo(channel, addonChannel); + + retVal = m_pStruct->OpenDialogChannelAdd(addonChannel); + LogError(retVal, __FUNCTION__); + } + catch (std::exception &e) + { + LogException(e, __FUNCTION__); + } + + return retVal; +} + +PVR_ERROR CPVRClient::OpenDialogChannelSettings(const CPVRChannel &channel) +{ + if (!m_bReadyToUse) + return PVR_ERROR_REJECTED; + + if (!m_addonCapabilities.bSupportsChannelSettings) + return PVR_ERROR_NOT_IMPLEMENTED; + + PVR_ERROR retVal(PVR_ERROR_UNKNOWN); + try + { + PVR_CHANNEL addonChannel; + WriteClientChannelInfo(channel, addonChannel); + + retVal = m_pStruct->OpenDialogChannelSettings(addonChannel); + LogError(retVal, __FUNCTION__); + } + catch (std::exception &e) + { + LogException(e, __FUNCTION__); + } + + return retVal; +} + +PVR_ERROR CPVRClient::DeleteChannel(const CPVRChannel &channel) +{ + if (!m_bReadyToUse) + return PVR_ERROR_REJECTED; + + if (!m_addonCapabilities.bSupportsChannelSettings) + return PVR_ERROR_NOT_IMPLEMENTED; + + PVR_ERROR retVal(PVR_ERROR_UNKNOWN); + try + { + PVR_CHANNEL addonChannel; + WriteClientChannelInfo(channel, addonChannel); + + retVal = m_pStruct->DeleteChannel(addonChannel); + LogError(retVal, __FUNCTION__); + } + catch (std::exception &e) + { + LogException(e, __FUNCTION__); + } + + return retVal; +} + +PVR_ERROR CPVRClient::RenameChannel(const CPVRChannel &channel) +{ + if (!m_bReadyToUse) + return PVR_ERROR_REJECTED; + + if (!m_addonCapabilities.bSupportsChannelSettings) + return PVR_ERROR_NOT_IMPLEMENTED; + + PVR_ERROR retVal(PVR_ERROR_UNKNOWN); + try + { + PVR_CHANNEL addonChannel; + WriteClientChannelInfo(channel, addonChannel); + + retVal = m_pStruct->RenameChannel(addonChannel); + LogError(retVal, __FUNCTION__); + } + catch (std::exception &e) + { + LogException(e, __FUNCTION__); + } + + return retVal; +} + void CPVRClient::CallMenuHook(const PVR_MENUHOOK &hook, const CFileItem *item) { if (!m_bReadyToUse) @@ -480,11 +582,16 @@ void CPVRClient::CallMenuHook(const PVR_MENUHOOK &hook, const CFileItem *item) hookData.cat = PVR_MENUHOOK_CHANNEL; WriteClientChannelInfo(*item->GetPVRChannelInfoTag(), hookData.data.channel); } - else if (item->IsPVRRecording()) + else if (item->IsUsablePVRRecording()) { hookData.cat = PVR_MENUHOOK_RECORDING; WriteClientRecordingInfo(*item->GetPVRRecordingInfoTag(), hookData.data.recording); } + else if (item->IsDeletedPVRRecording()) + { + hookData.cat = PVR_MENUHOOK_DELETED_RECORDING; + WriteClientRecordingInfo(*item->GetPVRRecordingInfoTag(), hookData.data.recording); + } else if (item->IsPVRTimer()) { hookData.cat = PVR_MENUHOOK_TIMER; @@ -644,25 +751,31 @@ PVR_ERROR CPVRClient::GetChannels(CPVRChannelGroup &channels, bool radio) return retVal; } -int CPVRClient::GetRecordingsAmount(void) +int CPVRClient::GetRecordingsAmount(bool deleted) { int iReturn(-EINVAL); - if (m_addonCapabilities.bSupportsRecordings) + if (!m_addonCapabilities.bSupportsRecordings || (deleted && !m_addonCapabilities.bSupportsRecordingsUndelete)) + return iReturn; + + try { - try { iReturn = m_pStruct->GetRecordingsAmount(); } - catch (std::exception &e) { LogException(e, __FUNCTION__); } + iReturn = m_pStruct->GetRecordingsAmount(deleted); + } + catch (std::exception &e) + { + LogException(e, __FUNCTION__); } return iReturn; } -PVR_ERROR CPVRClient::GetRecordings(CPVRRecordings *results) +PVR_ERROR CPVRClient::GetRecordings(CPVRRecordings *results, bool deleted) { if (!m_bReadyToUse) return PVR_ERROR_REJECTED; - if (!m_addonCapabilities.bSupportsRecordings) + if (!m_addonCapabilities.bSupportsRecordings || (deleted && !m_addonCapabilities.bSupportsRecordingsUndelete)) return PVR_ERROR_NOT_IMPLEMENTED; PVR_ERROR retVal(PVR_ERROR_UNKNOWN); @@ -671,7 +784,7 @@ PVR_ERROR CPVRClient::GetRecordings(CPVRRecordings *results) ADDON_HANDLE_STRUCT handle; handle.callerAddress = this; handle.dataAddress = (CPVRRecordings*) results; - retVal = m_pStruct->GetRecordings(&handle); + retVal = m_pStruct->GetRecordings(&handle, deleted); LogError(retVal, __FUNCTION__); } @@ -709,6 +822,55 @@ PVR_ERROR CPVRClient::DeleteRecording(const CPVRRecording &recording) return retVal; } +PVR_ERROR CPVRClient::UndeleteRecording(const CPVRRecording &recording) +{ + if (!m_bReadyToUse) + return PVR_ERROR_REJECTED; + + if (!m_addonCapabilities.bSupportsRecordingsUndelete) + return PVR_ERROR_NOT_IMPLEMENTED; + + PVR_ERROR retVal(PVR_ERROR_UNKNOWN); + try + { + PVR_RECORDING tag; + WriteClientRecordingInfo(recording, tag); + + retVal = m_pStruct->UndeleteRecording(tag); + + LogError(retVal, __FUNCTION__); + } + catch (std::exception &e) + { + LogException(e, __FUNCTION__); + } + + return retVal; +} + +PVR_ERROR CPVRClient::DeleteAllRecordingsFromTrash() +{ + if (!m_bReadyToUse) + return PVR_ERROR_REJECTED; + + if (!m_addonCapabilities.bSupportsRecordingsUndelete) + return PVR_ERROR_NOT_IMPLEMENTED; + + PVR_ERROR retVal(PVR_ERROR_UNKNOWN); + try + { + retVal = m_pStruct->DeleteAllRecordingsFromTrash(); + + LogError(retVal, __FUNCTION__); + } + catch (std::exception &e) + { + LogException(e, __FUNCTION__); + } + + return retVal; +} + PVR_ERROR CPVRClient::RenameRecording(const CPVRRecording &recording) { if (!m_bReadyToUse) @@ -1263,6 +1425,11 @@ bool CPVRClient::SupportsChannelScan(void) const return m_addonCapabilities.bSupportsChannelScan; } +bool CPVRClient::SupportsChannelSettings(void) const +{ + return m_addonCapabilities.bSupportsChannelSettings; +} + bool CPVRClient::SupportsEPG(void) const { return m_addonCapabilities.bSupportsEPG; @@ -1283,6 +1450,11 @@ bool CPVRClient::SupportsRecordings(void) const return m_addonCapabilities.bSupportsRecordings; } +bool CPVRClient::SupportsRecordingsUndelete(void) const +{ + return m_addonCapabilities.bSupportsRecordingsUndelete; +} + bool CPVRClient::SupportsRecordingFolders(void) const { return m_addonCapabilities.bSupportsRecordingFolders; diff --git a/xbmc/pvr/addons/PVRClient.h b/xbmc/pvr/addons/PVRClient.h index b6f3eb5aba..79d568f5c2 100644 --- a/xbmc/pvr/addons/PVRClient.h +++ b/xbmc/pvr/addons/PVRClient.h @@ -157,6 +157,34 @@ namespace PVR PVR_ERROR StartChannelScan(void); /*! + * @brief Request the client to open dialog about given channel to add + * @param channel The channel to add + * @return PVR_ERROR_NO_ERROR if the add has been fetched successfully. + */ + PVR_ERROR OpenDialogChannelAdd(const CPVRChannel &channel); + + /*! + * @brief Request the client to open dialog about given channel settings + * @param channel The channel to edit + * @return PVR_ERROR_NO_ERROR if the edit has been fetched successfully. + */ + PVR_ERROR OpenDialogChannelSettings(const CPVRChannel &channel); + + /*! + * @brief Request the client to delete given channel + * @param channel The channel to delete + * @return PVR_ERROR_NO_ERROR if the delete has been fetched successfully. + */ + PVR_ERROR DeleteChannel(const CPVRChannel &channel); + + /*! + * @brief Request the client to rename given channel + * @param channel The channel to rename + * @return PVR_ERROR_NO_ERROR if the rename has been fetched successfully. + */ + PVR_ERROR RenameChannel(const CPVRChannel &channel); + + /*! * @return True if this add-on has menu hooks, false otherwise. */ bool HaveMenuHooks(PVR_MENUHOOK_CAT cat) const; @@ -233,16 +261,18 @@ namespace PVR //@{ /*! - * @return The total amount of channels on the server or -1 on error. + * @param deleted if set return deleted recording + * @return The total amount of recordingd on the server or -1 on error. */ - int GetRecordingsAmount(void); + int GetRecordingsAmount(bool deleted); /*! * @brief Request the list of all recordings from the backend. * @param results The container to add the recordings to. + * @param deleted if set return deleted recording * @return PVR_ERROR_NO_ERROR if the list has been fetched successfully. */ - PVR_ERROR GetRecordings(CPVRRecordings *results); + PVR_ERROR GetRecordings(CPVRRecordings *results, bool deleted); /*! * @brief Delete a recording on the backend. @@ -252,6 +282,19 @@ namespace PVR PVR_ERROR DeleteRecording(const CPVRRecording &recording); /*! + * @brief Undelete a recording on the backend. + * @param recording The recording to undelete. + * @return PVR_ERROR_NO_ERROR if the recording has been undeleted successfully. + */ + PVR_ERROR UndeleteRecording(const CPVRRecording &recording); + + /*! + * @brief Delete all recordings permanent which in the deleted folder on the backend. + * @return PVR_ERROR_NO_ERROR if the recordings has been deleted successfully. + */ + PVR_ERROR DeleteAllRecordingsFromTrash(); + + /*! * @brief Rename a recording on the backend. * @param recording The recording to rename. * @return PVR_ERROR_NO_ERROR if the recording has been renamed successfully. @@ -475,10 +518,12 @@ namespace PVR bool SupportsChannelGroups(void) const; bool SupportsChannelScan(void) const; + bool SupportsChannelSettings(void) const; bool SupportsEPG(void) const; bool SupportsLastPlayedPosition(void) const; bool SupportsRadio(void) const; bool SupportsRecordings(void) const; + bool SupportsRecordingsUndelete(void) const; bool SupportsRecordingFolders(void) const; bool SupportsRecordingPlayCount(void) const; bool SupportsRecordingEdl(void) const; diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp index 961373b36b..7659104ded 100644 --- a/xbmc/pvr/addons/PVRClients.cpp +++ b/xbmc/pvr/addons/PVRClients.cpp @@ -438,7 +438,7 @@ PVR_ERROR CPVRClients::RenameTimer(const CPVRTimerInfoTag &timer, const std::str return error; } -PVR_ERROR CPVRClients::GetRecordings(CPVRRecordings *recordings) +PVR_ERROR CPVRClients::GetRecordings(CPVRRecordings *recordings, bool deleted) { PVR_ERROR error(PVR_ERROR_NO_ERROR); PVR_CLIENTMAP clients; @@ -446,7 +446,7 @@ PVR_ERROR CPVRClients::GetRecordings(CPVRRecordings *recordings) for (PVR_CLIENTMAP_CITR itrClients = clients.begin(); itrClients != clients.end(); itrClients++) { - PVR_ERROR currentError = (*itrClients).second->GetRecordings(recordings); + PVR_ERROR currentError = (*itrClients).second->GetRecordings(recordings, deleted); if (currentError != PVR_ERROR_NOT_IMPLEMENTED && currentError != PVR_ERROR_NO_ERROR) { @@ -486,6 +486,81 @@ PVR_ERROR CPVRClients::DeleteRecording(const CPVRRecording &recording) return error; } +PVR_ERROR CPVRClients::UndeleteRecording(const CPVRRecording &recording) +{ + PVR_ERROR error(PVR_ERROR_UNKNOWN); + + if (!recording.IsDeleted()) + return error; + + PVR_CLIENT client; + if (GetConnectedClient(recording.m_iClientId, client)) + error = client->UndeleteRecording(recording); + + if (error != PVR_ERROR_NO_ERROR) + CLog::Log(LOGERROR, "PVR - %s - cannot undelete recording from client '%d': %s",__FUNCTION__, recording.m_iClientId, CPVRClient::ToString(error)); + + return error; +} + +PVR_ERROR CPVRClients::DeleteAllRecordingsFromTrash() +{ + PVR_ERROR error(PVR_ERROR_NO_ERROR); + PVR_CLIENTMAP clients; + GetConnectedClients(clients); + + std::vector<PVR_CLIENT> suppClients; + for (PVR_CLIENTMAP_CITR itrClients = clients.begin(); itrClients != clients.end(); ++itrClients) + { + if (itrClients->second->SupportsRecordingsUndelete() && itrClients->second->GetRecordingsAmount(true) > 0) + suppClients.push_back(itrClients->second); + } + + int selection = 0; + if (suppClients.size() > 1) + { + // have user select client + CGUIDialogSelect* pDialog = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); + pDialog->Reset(); + pDialog->SetHeading(19292); /* Delete all permanently */ + pDialog->Add(g_localizeStrings.Get(24032)); /* All Add-ons */ + + PVR_CLIENTMAP_CITR itrClients; + for (itrClients = clients.begin(); itrClients != clients.end(); ++itrClients) + { + if (itrClients->second->SupportsRecordingsUndelete() && itrClients->second->GetRecordingsAmount(true) > 0) + pDialog->Add(itrClients->second->GetBackendName()); + } + pDialog->DoModal(); + selection = pDialog->GetSelectedLabel(); + } + + if (selection == 0) + { + typedef std::vector<PVR_CLIENT>::const_iterator suppClientsCITR; + for (suppClientsCITR itrSuppClients = suppClients.begin(); itrSuppClients != suppClients.end(); ++itrSuppClients) + { + PVR_ERROR currentError = (*itrSuppClients)->DeleteAllRecordingsFromTrash(); + if (currentError != PVR_ERROR_NO_ERROR) + { + CLog::Log(LOGERROR, "PVR - %s - cannot delete all recordings from client '%d': %s",__FUNCTION__, (*itrSuppClients)->GetID(), CPVRClient::ToString(currentError)); + error = currentError; + } + } + } + else if (selection >= 1 && selection <= (int)suppClients.size()) + { + PVR_ERROR currentError = suppClients[selection-1]->DeleteAllRecordingsFromTrash(); + if (currentError != PVR_ERROR_NO_ERROR) + { + CLog::Log(LOGERROR, "PVR - %s - cannot delete all recordings from client '%d': %s",__FUNCTION__, suppClients[selection-1]->GetID(), CPVRClient::ToString(currentError)); + error = currentError; + } + } + + return error; +} + bool CPVRClients::SetRecordingLastPlayedPosition(const CPVRRecording &recording, int lastplayedposition, PVR_ERROR *error) { *error = PVR_ERROR_UNKNOWN; @@ -818,6 +893,93 @@ void CPVRClients::StartChannelScan(void) m_bChannelScanRunning = false; } +std::vector<PVR_CLIENT> CPVRClients::GetClientsSupportingChannelSettings(bool bRadio) const +{ + std::vector<PVR_CLIENT> possibleSettingsClients; + CSingleLock lock(m_critSection); + + /* get clients that support channel settings */ + for (PVR_CLIENTMAP_CITR itr = m_clientMap.begin(); itr != m_clientMap.end(); itr++) + { + if (itr->second->ReadyToUse() && itr->second->SupportsChannelSettings() && + ((bRadio && itr->second->SupportsRadio()) || (!bRadio && itr->second->SupportsTV()))) + possibleSettingsClients.push_back(itr->second); + } + + return possibleSettingsClients; +} + + +bool CPVRClients::OpenDialogChannelAdd(const CPVRChannel &channel) +{ + PVR_ERROR error = PVR_ERROR_UNKNOWN; + + PVR_CLIENT client; + if (GetConnectedClient(channel.ClientID(), client)) + error = client->OpenDialogChannelAdd(channel); + else + CLog::Log(LOGERROR, "PVR - %s - cannot find client %d",__FUNCTION__, channel.ClientID()); + + if (error == PVR_ERROR_NOT_IMPLEMENTED) + { + CGUIDialogOK::ShowAndGetInput(19033,19038,0,0); + return true; + } + + return error == PVR_ERROR_NO_ERROR; +} + +bool CPVRClients::OpenDialogChannelSettings(const CPVRChannel &channel) +{ + PVR_ERROR error = PVR_ERROR_UNKNOWN; + + PVR_CLIENT client; + if (GetConnectedClient(channel.ClientID(), client)) + error = client->OpenDialogChannelSettings(channel); + else + CLog::Log(LOGERROR, "PVR - %s - cannot find client %d",__FUNCTION__, channel.ClientID()); + + if (error == PVR_ERROR_NOT_IMPLEMENTED) + { + CGUIDialogOK::ShowAndGetInput(19033,19038,0,0); + return true; + } + + return error == PVR_ERROR_NO_ERROR; +} + +bool CPVRClients::DeleteChannel(const CPVRChannel &channel) +{ + PVR_ERROR error = PVR_ERROR_UNKNOWN; + + PVR_CLIENT client; + if (GetConnectedClient(channel.ClientID(), client)) + error = client->DeleteChannel(channel); + else + CLog::Log(LOGERROR, "PVR - %s - cannot find client %d",__FUNCTION__, channel.ClientID()); + + if (error == PVR_ERROR_NOT_IMPLEMENTED) + { + CGUIDialogOK::ShowAndGetInput(19033,19038,0,0); + return true; + } + + return error == PVR_ERROR_NO_ERROR; +} + +bool CPVRClients::RenameChannel(const CPVRChannel &channel) +{ + PVR_ERROR error = PVR_ERROR_UNKNOWN; + + PVR_CLIENT client; + if (GetConnectedClient(channel.ClientID(), client)) + error = client->RenameChannel(channel); + else + CLog::Log(LOGERROR, "PVR - %s - cannot find client %d",__FUNCTION__, channel.ClientID()); + + return (error == PVR_ERROR_NO_ERROR || error == PVR_ERROR_NOT_IMPLEMENTED); +} + bool CPVRClients::IsKnownClient(const AddonPtr client) const { // database IDs start at 1 @@ -1096,6 +1258,12 @@ bool CPVRClients::SupportsChannelScan(int iClientId) const return GetConnectedClient(iClientId, client) && client->SupportsChannelScan(); } +bool CPVRClients::SupportsChannelSettings(int iClientId) const +{ + PVR_CLIENT client; + return GetConnectedClient(iClientId, client) && client->SupportsChannelSettings(); +} + bool CPVRClients::SupportsEPG(int iClientId) const { PVR_CLIENT client; @@ -1120,6 +1288,12 @@ bool CPVRClients::SupportsRecordings(int iClientId) const return GetConnectedClient(iClientId, client) && client->SupportsRecordings(); } +bool CPVRClients::SupportsRecordingsUndelete(int iClientId) const +{ + PVR_CLIENT client; + return GetConnectedClient(iClientId, client) && client->SupportsRecordingsUndelete(); +} + bool CPVRClients::SupportsRecordingFolders(int iClientId) const { PVR_CLIENT client; diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h index 23bb080a01..129bbaa5d3 100644 --- a/xbmc/pvr/addons/PVRClients.h +++ b/xbmc/pvr/addons/PVRClients.h @@ -362,11 +362,19 @@ namespace PVR bool SupportsRecordings(int iClientId) const; /*! + * @brief Check whether a client supports undelete of recordings. + * @param iClientId The id of the client to check. + * @return True if the supports undeleted of recordings, false otherwise. + */ + bool SupportsRecordingsUndelete(int iClientId) const; + + /*! * @brief Get all recordings from clients * @param recordings Store the recordings in this container. + * @param deleted Return deleted recordings * @return The amount of recordings that were added. */ - PVR_ERROR GetRecordings(CPVRRecordings *recordings); + PVR_ERROR GetRecordings(CPVRRecordings *recordings, bool deleted); /*! * @brief Rename a recordings on the backend. @@ -385,6 +393,20 @@ namespace PVR PVR_ERROR DeleteRecording(const CPVRRecording &recording); /*! + * @brief Undelete a recording from the backend. + * @param recording The recording to undelete. + * @param error An error if it occured. + * @return True if the recording was undeleted successfully, false otherwise. + */ + PVR_ERROR UndeleteRecording(const CPVRRecording &recording); + + /*! + * @brief Delete all recordings permanent which in the deleted folder on the backend. + * @return PVR_ERROR_NO_ERROR if the recordings has been deleted successfully. + */ + PVR_ERROR DeleteAllRecordingsFromTrash(); + + /*! * @brief Set play count of a recording on the backend. * @param recording The recording to set the play count. * @param count Play count. @@ -528,11 +550,50 @@ namespace PVR //@} + /*! @name Channel settings methods */ + //@{ + + /*! + * @return All clients that support channel settings inside addon. + */ + std::vector<PVR_CLIENT> GetClientsSupportingChannelSettings(bool bRadio) const; + + /*! + * @brief Open addon settings dialog to add a channel + * @param channel The channel to edit. + * @return True if the edit was successfull, false otherwise. + */ + bool OpenDialogChannelAdd(const CPVRChannel &channel); + + /*! + * @brief Open addon settings dialog to related channel + * @param channel The channel to edit. + * @return True if the edit was successfull, false otherwise. + */ + bool OpenDialogChannelSettings(const CPVRChannel &channel); + + /*! + * @brief Inform addon to delete channel + * @param channel The channel to delete. + * @return True if it was successfull, false otherwise. + */ + bool DeleteChannel(const CPVRChannel &channel); + + /*! + * @brief Request the client to rename given channel + * @param channel The channel to rename + * @return True if the edit was successfull, false otherwise. + */ + bool RenameChannel(const CPVRChannel &channel); + + //@} + void Notify(const Observable &obs, const ObservableMessage msg); bool GetClient(const std::string &strId, ADDON::AddonPtr &addon) const; bool SupportsChannelScan(int iClientId) const; + bool SupportsChannelSettings(int iClientId) const; bool SupportsLastPlayedPosition(int iClientId) const; bool SupportsRadio(int iClientId) const; bool SupportsRecordingFolders(int iClientId) const; diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp index 6d9b428d43..79fe33796e 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp +++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.cpp @@ -52,6 +52,7 @@ #define RADIOBUTTON_PARENTAL_LOCK 14 #define CONTROL_LIST_CHANNELS 20 #define BUTTON_GROUP_MANAGER 30 +#define BUTTON_NEW_CHANNEL 31 #define BUTTON_RADIO_TV 34 using namespace PVR; @@ -61,6 +62,7 @@ CGUIDialogPVRChannelManager::CGUIDialogPVRChannelManager(void) : m_bIsRadio(false), m_bMovingMode(false), m_bContainsChanges(false), + m_bAllowNewChannel(false), m_iSelected(0), m_channelItems(new CFileItemList) { @@ -160,6 +162,7 @@ void CGUIDialogPVRChannelManager::OnInitWindow() m_bIsRadio = false; m_bMovingMode = false; m_bContainsChanges = false; + m_bAllowNewChannel = false; SetProperty("IsRadio", ""); Update(); SetData(m_iSelected); @@ -246,6 +249,7 @@ bool CGUIDialogPVRChannelManager::OnClickButtonRadioTV(CGUIMessage &message) m_iSelected = 0; m_bMovingMode = false; + m_bAllowNewChannel = false; m_bContainsChanges = false; m_bIsRadio = !m_bIsRadio; SetProperty("IsRadio", m_bIsRadio ? "true" : ""); @@ -434,6 +438,42 @@ bool CGUIDialogPVRChannelManager::OnClickButtonGroupManager(CGUIMessage &message return true; } +bool CGUIDialogPVRChannelManager::OnClickButtonNewChannel() +{ + int iSelection = 0; + if (g_PVRClients->ConnectedClientAmount() > 1) + { + CGUIDialogSelect* pDlgSelect = (CGUIDialogSelect*)g_windowManager.GetWindow(WINDOW_DIALOG_SELECT); + if (!pDlgSelect) + return false; + + pDlgSelect->SetHeading(19213); // Select Client + + PVR_CLIENT_ITR itr; + for (itr = m_clientsWithSettingsList.begin() ; itr != m_clientsWithSettingsList.end(); ++itr) + pDlgSelect->Add((*itr)->Name()); + pDlgSelect->DoModal(); + + iSelection = pDlgSelect->GetSelectedLabel(); + } + + if (iSelection >= 0 && iSelection < (int)m_clientsWithSettingsList.size()) + { + int iClientID = m_clientsWithSettingsList[iSelection]->GetID(); + + CPVRChannel channel(m_bIsRadio); + channel.SetChannelName(g_localizeStrings.Get(19204)); // New channel + channel.SetEPGEnabled(g_PVRClients->SupportsEPG(iClientID)); + channel.SetClientID(iClientID); + + if (g_PVRClients->OpenDialogChannelAdd(channel)) + Update(); + else + CGUIDialogOK::ShowAndGetInput(2103, 0, 16029, 0); // Add-on error;Check the log file for details. + } + return true; +} + bool CGUIDialogPVRChannelManager::OnMessageClick(CGUIMessage &message) { int iControl = message.GetSenderId(); @@ -463,6 +503,8 @@ bool CGUIDialogPVRChannelManager::OnMessageClick(CGUIMessage &message) return OnClickEPGSourceSpin(message); case BUTTON_GROUP_MANAGER: return OnClickButtonGroupManager(message); + case BUTTON_NEW_CHANNEL: + return OnClickButtonNewChannel(); default: return false; } @@ -517,7 +559,13 @@ bool CGUIDialogPVRChannelManager::OnPopupMenu(int iItem) if (!pItem) return false; - buttons.Add(CONTEXT_BUTTON_MOVE, 116); /* Move channel up or down */ + buttons.Add(CONTEXT_BUTTON_MOVE, 116); /* Move channel up or down */ + + if (pItem->GetProperty("SupportsSettings").asBoolean()) + { + buttons.Add(CONTEXT_BUTTON_SETTINGS, 10004); /* Open add-on channel settings dialog */ + buttons.Add(CONTEXT_BUTTON_DELETE, 117); /* Delete add-on channel */ + } int choice = CGUIDialogContextMenu::ShowAndGetChoice(buttons); @@ -545,6 +593,35 @@ bool CGUIDialogPVRChannelManager::OnContextButton(int itemNumber, CONTEXT_BUTTON m_bMovingMode = true; pItem->Select(true); } + else if (button == CONTEXT_BUTTON_SETTINGS) + { + if (!g_PVRClients->OpenDialogChannelSettings(*pItem->GetPVRChannelInfoTag())) + CGUIDialogOK::ShowAndGetInput(2103, 0, 16029, 0); // Add-on error;Check the log file for details. + } + else if (button == CONTEXT_BUTTON_DELETE) + { + CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); + if (!pDialog) + return true; + + pDialog->SetHeading(19211); // Delete channel + pDialog->SetText(750); // Are you sure? + pDialog->DoModal(); + + if (pDialog->IsConfirmed()) + { + CPVRChannel *channel = pItem->GetPVRChannelInfoTag(); + if (g_PVRClients->DeleteChannel(*channel)) + { + g_PVRChannelGroups->GetGroupAll(channel->IsRadio())->RemoveFromGroup(*channel); + m_channelItems->Remove(m_iSelected); + m_viewControl.SetItems(*m_channelItems); + Renumber(); + } + else + CGUIDialogOK::ShowAndGetInput(2103, 0, 16029, 0); // Add-on error;Check the log file for details. + } + } else if (button == CONTEXT_BUTTON_EDIT_SOURCE) { std::string strURL = pItem->GetProperty("StreamURL").asString(); @@ -605,6 +682,7 @@ void CGUIDialogPVRChannelManager::Update() std::string clientName; g_PVRClients->GetClientName(channel->ClientID(), clientName); channelFile->SetProperty("ClientName", clientName); + channelFile->SetProperty("SupportsSettings", g_PVRClients->SupportsChannelSettings(channel->ClientID())); m_channelItems->Add(channelFile); } @@ -616,6 +694,15 @@ void CGUIDialogPVRChannelManager::Update() SET_CONTROL_LABELS(SPIN_EPGSOURCE_SELECTION, 0, &labels); } + m_clientsWithSettingsList = g_PVRClients->GetClientsSupportingChannelSettings(m_bIsRadio); + if (!m_clientsWithSettingsList.empty()) + m_bAllowNewChannel = true; + + if (m_bAllowNewChannel) + SET_CONTROL_VISIBLE(BUTTON_NEW_CHANNEL); + else + SET_CONTROL_HIDDEN(BUTTON_NEW_CHANNEL); + Renumber(); m_viewControl.SetItems(*m_channelItems); m_viewControl.SetSelectedItem(m_iSelected); @@ -629,6 +716,19 @@ void CGUIDialogPVRChannelManager::Clear(void) m_channelItems->Clear(); } +void CGUIDialogPVRChannelManager::RenameChannel(CFileItemPtr pItem) +{ + std::string strChannelName = pItem->GetProperty("Name").asString(); + if (strChannelName != pItem->GetPVRChannelInfoTag()->ChannelName()) + { + CPVRChannel channel = pItem->GetPVRChannelInfoTag(); + channel.SetChannelName(strChannelName); + + if (!g_PVRClients->RenameChannel(channel)) + CGUIDialogOK::ShowAndGetInput(2103, 0, 16029, 0); // Add-on error;Check the log file for details. + } +} + bool CGUIDialogPVRChannelManager::PersistChannel(CFileItemPtr pItem, CPVRChannelGroupPtr group, unsigned int *iChannelNumber) { if (!pItem || !pItem->HasPVRChannelInfoTag() || !group) @@ -669,7 +769,13 @@ void CGUIDialogPVRChannelManager::SaveList(void) return; for (int iListPtr = 0; iListPtr < m_channelItems->Size(); iListPtr++) { + if (!m_channelItems->HasPVRChannelInfoTag()) + continue; + CFileItemPtr pItem = m_channelItems->Get(iListPtr); + if (pItem->GetProperty("SupportsSettings").asBoolean()) + RenameChannel(pItem); + PersistChannel(pItem, group, &iNextChannelNumber); pDlgProgress->SetPercentage(iListPtr * 100 / m_channelItems->Size()); diff --git a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h index 2204c5ed8a..9101556a58 100644 --- a/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h +++ b/xbmc/pvr/dialogs/GUIDialogPVRChannelManager.h @@ -22,7 +22,8 @@ #include "guilib/GUIDialog.h" #include "dialogs/GUIDialogContextMenu.h" #include "view/GUIViewControl.h" -#include "../channels/PVRChannelGroup.h" +#include "pvr/channels/PVRChannelGroup.h" +#include "pvr/addons/PVRClient.h" namespace PVR { @@ -61,6 +62,7 @@ namespace PVR virtual bool OnClickButtonUseEPG(CGUIMessage &message); virtual bool OnClickEPGSourceSpin(CGUIMessage &message); virtual bool OnClickButtonGroupManager(CGUIMessage &message); + virtual bool OnClickButtonNewChannel(); virtual bool PersistChannel(CFileItemPtr pItem, CPVRChannelGroupPtr group, unsigned int *iChannelNumber); virtual void SetItemsUnchanged(void); @@ -71,12 +73,17 @@ namespace PVR void SaveList(void); void Renumber(void); void SetData(int iItem); + void RenameChannel(CFileItemPtr pItem); bool m_bIsRadio; bool m_bMovingMode; bool m_bContainsChanges; + bool m_bAllowNewChannel; int m_iSelected; CFileItemList* m_channelItems; CGUIViewControl m_viewControl; + + typedef std::vector<PVR_CLIENT>::iterator PVR_CLIENT_ITR; + std::vector<PVR_CLIENT> m_clientsWithSettingsList; }; } diff --git a/xbmc/pvr/recordings/PVRRecording.cpp b/xbmc/pvr/recordings/PVRRecording.cpp index bb1713c170..96153a0571 100644 --- a/xbmc/pvr/recordings/PVRRecording.cpp +++ b/xbmc/pvr/recordings/PVRRecording.cpp @@ -103,6 +103,7 @@ CPVRRecording::CPVRRecording(const PVR_RECORDING &recording, unsigned int iClien m_strIconPath = recording.strIconPath; m_strThumbnailPath = recording.strThumbnailPath; m_strFanartPath = recording.strFanartPath; + m_bIsDeleted = recording.bIsDeleted; } bool CPVRRecording::operator ==(const CPVRRecording& right) const @@ -124,7 +125,8 @@ bool CPVRRecording::operator ==(const CPVRRecording& right) const m_strIconPath == right.m_strIconPath && m_strThumbnailPath == right.m_strThumbnailPath && m_strFanartPath == right.m_strFanartPath && - m_iRecordingId == right.m_iRecordingId); + m_iRecordingId == right.m_iRecordingId && + m_bIsDeleted == right.m_bIsDeleted); } bool CPVRRecording::operator !=(const CPVRRecording& right) const @@ -145,6 +147,7 @@ void CPVRRecording::Serialize(CVariant& value) const value["starttime"] = m_recordingTime.IsValid() ? m_recordingTime.GetAsDBDateTime() : ""; value["endtime"] = m_recordingTime.IsValid() ? (m_recordingTime + m_duration).GetAsDBDateTime() : ""; value["recordingid"] = m_iRecordingId; + value["deleted"] = m_bIsDeleted; if (!value.isMember("art")) value["art"] = CVariant(CVariant::VariantTypeObject); @@ -169,6 +172,7 @@ void CPVRRecording::Reset(void) m_strFanartPath .clear(); m_bGotMetaData = false; m_iRecordingId = 0; + m_bIsDeleted = false; m_recordingTime.Reset(); CVideoInfoTag::Reset(); @@ -194,6 +198,18 @@ bool CPVRRecording::Delete(void) return true; } +bool CPVRRecording::Undelete(void) +{ + PVR_ERROR error = g_PVRClients->UndeleteRecording(*this); + if (error != PVR_ERROR_NO_ERROR) + { + DisplayError(error); + return false; + } + + return true; +} + bool CPVRRecording::Rename(const std::string &strNewName) { m_strTitle = StringUtils::Format("%s", strNewName.c_str()); @@ -315,6 +331,7 @@ void CPVRRecording::Update(const CPVRRecording &tag) m_strIconPath = tag.m_strIconPath; m_strThumbnailPath = tag.m_strThumbnailPath; m_strFanartPath = tag.m_strFanartPath; + m_bIsDeleted = tag.m_bIsDeleted; if (g_PVRClients->SupportsRecordingPlayCount(m_iClientId)) m_playCount = tag.m_playCount; @@ -360,7 +377,7 @@ void CPVRRecording::UpdatePath(void) strDirectory = StringUtils::Format("%s/", m_strDirectory.c_str()); if (!m_strChannelName.empty()) strChannel = StringUtils::Format(" (%s)", m_strChannelName.c_str()); - m_strFileNameAndPath = StringUtils::Format("pvr://recordings/%s%s, TV%s, %s.pvr", strDirectory.c_str(), strTitle.c_str(), strChannel.c_str(), strDatetime.c_str()); + m_strFileNameAndPath = StringUtils::Format("pvr://recordings/%s/%s%s, TV%s, %s.pvr", (m_bIsDeleted ? "deleted" : "active"), strDirectory.c_str(), strTitle.c_str(), strChannel.c_str(), strDatetime.c_str()); } } diff --git a/xbmc/pvr/recordings/PVRRecording.h b/xbmc/pvr/recordings/PVRRecording.h index c3a9adac87..0eb0abb3f7 100644 --- a/xbmc/pvr/recordings/PVRRecording.h +++ b/xbmc/pvr/recordings/PVRRecording.h @@ -115,6 +115,12 @@ namespace PVR bool Delete(void); /*! + * @brief Undelete this recording on the client (if supported). + * @return True if it was undeleted successfully, false otherwise. + */ + bool Undelete(void); + + /*! * @brief Rename this recording on the client (if supported). * @param strNewName The new name. * @return True if it was renamed successfully, false otherwise. @@ -183,9 +189,15 @@ namespace PVR */ void CopyClientInfo(CVideoInfoTag *target) const; + /*! + * @brief If deleted but can be undeleted it is true + */ + bool IsDeleted() const { return m_bIsDeleted; } + private: CDateTime m_recordingTime; /*!< start time of the recording */ bool m_bGotMetaData; + bool m_bIsDeleted; /*!< set if entry is a deleted recording which can be undelete */ void UpdatePath(void); void DisplayError(PVR_ERROR err) const; diff --git a/xbmc/pvr/recordings/PVRRecordings.cpp b/xbmc/pvr/recordings/PVRRecordings.cpp index 56eff347de..91a7880601 100644 --- a/xbmc/pvr/recordings/PVRRecordings.cpp +++ b/xbmc/pvr/recordings/PVRRecordings.cpp @@ -57,7 +57,8 @@ void CPVRRecordings::UpdateFromClients(void) { CSingleLock lock(m_critSection); Clear(); - g_PVRClients->GetRecordings(this); + g_PVRClients->GetRecordings(this, false); + g_PVRClients->GetRecordings(this, true); } std::string CPVRRecordings::TrimSlashes(const std::string &strOrig) const @@ -107,10 +108,11 @@ bool CPVRRecordings::IsDirectoryMember(const std::string &strDirectory, const st StringUtils::StartsWithNoCase(strUseEntryDirectory, strUseDirectory); } -void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList *results) +void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList *results, bool bDeleted) { std::string strUseBase = TrimSlashes(strBase); std::set<CFileItemPtr> unwatchedFolders; + std::string strBasePath = bDeleted ? "deleted" : "active"; for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) { @@ -121,9 +123,9 @@ void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList std::string strFilePath; if(strUseBase.empty()) - strFilePath = StringUtils::Format("pvr://recordings/%s/", strCurrent.c_str()); + strFilePath = StringUtils::Format("pvr://recordings/%s/%s/", strBasePath.c_str(), strCurrent.c_str()); else - strFilePath = StringUtils::Format("pvr://recordings/%s/%s/", strUseBase.c_str(), strCurrent.c_str()); + strFilePath = StringUtils::Format("pvr://recordings/%s/%s/%s/", strBasePath.c_str(), strUseBase.c_str(), strCurrent.c_str()); CFileItemPtr pFileItem; if (m_database.IsOpen()) @@ -194,17 +196,28 @@ int CPVRRecordings::GetNumRecordings() return m_recordings.size(); } -int CPVRRecordings::GetRecordings(CFileItemList* results) +bool CPVRRecordings::HasDeletedRecordings() +{ + CSingleLock lock(m_critSection); + return m_bHasDeleted; +} + +int CPVRRecordings::GetRecordings(CFileItemList* results, bool bDeleted) { CSingleLock lock(m_critSection); + int iRecCount = 0; for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) { + if (it->second->IsDeleted() != bDeleted) + continue; + CFileItemPtr pFileItem(new CFileItem(it->second)); results->Add(pFileItem); + iRecCount++; } - return m_recordings.size(); + return iRecCount; } bool CPVRRecordings::Delete(const CFileItem& item) @@ -240,9 +253,21 @@ bool CPVRRecordings::DeleteRecording(const CFileItem &item) return tag->Delete(); } +bool CPVRRecordings::Undelete(const CFileItem &item) +{ + if (!item.IsDeletedPVRRecording()) + { + CLog::Log(LOGERROR, "CPVRRecordings - %s - cannot undelete file: no valid recording tag", __FUNCTION__); + return false; + } + + CPVRRecordingPtr tag = item.GetPVRRecordingInfoTag(); + return tag->Undelete(); +} + bool CPVRRecordings::RenameRecording(CFileItem &item, std::string &strNewName) { - if (!item.IsPVRRecording()) + if (!item.IsUsablePVRRecording()) { CLog::Log(LOGERROR, "CPVRRecordings - %s - cannot rename file: no valid recording tag", __FUNCTION__); return false; @@ -252,6 +277,11 @@ bool CPVRRecordings::RenameRecording(CFileItem &item, std::string &strNewName) return tag->Rename(strNewName); } +bool CPVRRecordings::DeleteAllRecordingsFromTrash() +{ + return g_PVRClients->DeleteAllRecordingsFromTrash(); +} + bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count) { bool bResult = false; @@ -320,9 +350,13 @@ bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &ite { strDirectoryPath.erase(0, 10); + // Check directory name is for deleted recordings + bool bDeleted = StringUtils::StartsWith(strDirectoryPath, "/deleted"); + strDirectoryPath.erase(0, bDeleted ? 8 : 7); + // get the directory structure if in non-flatten mode if (m_bGroupItems) - GetSubDirectories(strDirectoryPath, &items); + GetSubDirectories(strDirectoryPath, &items, bDeleted); // get all files of the currrent directory or recursively all files starting at the current directory if in flatten mode for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) @@ -330,7 +364,7 @@ bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &ite CPVRRecordingPtr current = it->second; // skip items that are not members of the target directory - if (!IsDirectoryMember(strDirectoryPath, current->m_strDirectory)) + if (!IsDirectoryMember(strDirectoryPath, current->m_strDirectory) || current->IsDeleted() != bDeleted) continue; if (m_database.IsOpen()) @@ -367,12 +401,15 @@ bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &ite return false; } -void CPVRRecordings::GetAll(CFileItemList &items) +void CPVRRecordings::GetAll(CFileItemList &items, bool bDeleted) { CSingleLock lock(m_critSection); for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) { CPVRRecordingPtr current = it->second; + if (current->IsDeleted() != bDeleted) + continue; + if (m_database.IsOpen()) current->UpdateMetadata(m_database); @@ -409,14 +446,18 @@ CFileItemPtr CPVRRecordings::GetByPath(const std::string &path) if (StringUtils::StartsWith(fileName, "recordings/")) { + // Check directory name is for deleted recordings + fileName.erase(0, 11); + bool bDeleted = StringUtils::StartsWith(fileName, "deleted/"); + for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++) { CPVRRecordingPtr current = it->second; - if (URIUtils::PathEquals(path, current->m_strFileNameAndPath)) - { - CFileItemPtr fileItem(new CFileItem(current)); - return fileItem; - } + if (!URIUtils::PathEquals(path, current->m_strFileNameAndPath) || bDeleted != current->IsDeleted()) + continue; + + CFileItemPtr fileItem(new CFileItem(current)); + return fileItem; } } @@ -438,6 +479,7 @@ CPVRRecordingPtr CPVRRecordings::GetById(int iClientId, const std::string &strRe void CPVRRecordings::Clear() { CSingleLock lock(m_critSection); + m_bHasDeleted = false; m_recordings.clear(); } @@ -445,6 +487,9 @@ void CPVRRecordings::UpdateFromClient(const CPVRRecordingPtr &tag) { CSingleLock lock(m_critSection); + if (tag->IsDeleted()) + m_bHasDeleted = true; + CPVRRecordingPtr newTag = GetById(tag->m_iClientId, tag->m_strRecordingId); if (newTag) { diff --git a/xbmc/pvr/recordings/PVRRecordings.h b/xbmc/pvr/recordings/PVRRecordings.h index 9463887222..367c01acdb 100644 --- a/xbmc/pvr/recordings/PVRRecordings.h +++ b/xbmc/pvr/recordings/PVRRecordings.h @@ -42,12 +42,13 @@ namespace PVR unsigned int m_iLastId; bool m_bGroupItems; CVideoDatabase m_database; + bool m_bHasDeleted; virtual void UpdateFromClients(void); virtual std::string TrimSlashes(const std::string &strOrig) const; 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); + virtual void GetSubDirectories(const std::string &strBase, CFileItemList *results, bool bDeleted = false); /** * @brief recursively deletes all recordings in the specified directory @@ -72,7 +73,8 @@ namespace PVR void Update(void); int GetNumRecordings(); - int GetRecordings(CFileItemList* results); + bool HasDeletedRecordings(); + int GetRecordings(CFileItemList* results, bool bDeleted = false); /** * Deletes the item in question, be it a directory or a file @@ -80,13 +82,15 @@ namespace PVR * @return whether the item was deleted successfully */ bool Delete(const CFileItem &item); + bool Undelete(const CFileItem &item); + bool DeleteAllRecordingsFromTrash(); bool RenameRecording(CFileItem &item, std::string &strNewName); bool SetRecordingsPlayCount(const CFileItemPtr &item, int count); bool GetDirectory(const std::string& strPath, CFileItemList &items); CFileItemPtr GetByPath(const std::string &path); CPVRRecordingPtr GetById(int iClientId, const std::string &strRecordingId) const; - void GetAll(CFileItemList &items); + void GetAll(CFileItemList &items, bool bDeleted = false); CFileItemPtr GetById(unsigned int iId) const; void SetGroupItems(bool value) { m_bGroupItems = value; }; diff --git a/xbmc/pvr/windows/GUIViewStatePVR.cpp b/xbmc/pvr/windows/GUIViewStatePVR.cpp index 3941bfa8bf..7f335802c3 100644 --- a/xbmc/pvr/windows/GUIViewStatePVR.cpp +++ b/xbmc/pvr/windows/GUIViewStatePVR.cpp @@ -63,7 +63,7 @@ void CGUIViewStateWindowPVRRecordings::SaveViewState(void) bool CGUIViewStateWindowPVRRecordings::HideParentDirItems(void) { - return (CGUIViewState::HideParentDirItems() || m_items.GetPath() == "pvr://recordings/"); + return (CGUIViewState::HideParentDirItems() || m_items.GetPath() == "pvr://recordings/active/" || m_items.GetPath() == "pvr://recordings/deleted/"); } CGUIViewStateWindowPVRGuide::CGUIViewStateWindowPVRGuide(const int windowId, const CFileItemList& items) : CGUIViewStatePVR(windowId, items) diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.cpp b/xbmc/pvr/windows/GUIWindowPVRBase.cpp index 025125c41a..f1dfde7ba8 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRBase.cpp @@ -178,7 +178,9 @@ bool CGUIWindowPVRBase::OnContextButton(int itemNumber, CONTEXT_BUTTON button) g_PVRClients->ProcessMenuHooks(item->GetEPGInfoTag()->ChannelTag()->ClientID(), PVR_MENUHOOK_EPG, item.get()); else if (item->IsPVRChannel()) g_PVRClients->ProcessMenuHooks(item->GetPVRChannelInfoTag()->ClientID(), PVR_MENUHOOK_CHANNEL, item.get()); - else if (item->IsPVRRecording()) + else if (item->IsDeletedPVRRecording()) + g_PVRClients->ProcessMenuHooks(item->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_DELETED_RECORDING, item.get()); + else if (item->IsUsablePVRRecording()) g_PVRClients->ProcessMenuHooks(item->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_RECORDING, item.get()); else if (item->IsPVRTimer()) g_PVRClients->ProcessMenuHooks(item->GetPVRTimerInfoTag()->m_iClientId, PVR_MENUHOOK_TIMER, item.get()); diff --git a/xbmc/pvr/windows/GUIWindowPVRBase.h b/xbmc/pvr/windows/GUIWindowPVRBase.h index 6bfbe38cc1..f8f0b0346e 100644 --- a/xbmc/pvr/windows/GUIWindowPVRBase.h +++ b/xbmc/pvr/windows/GUIWindowPVRBase.h @@ -28,6 +28,7 @@ #define CONTROL_BTNSORTASC 4 #define CONTROL_BTNGROUPITEMS 5 #define CONTROL_BTNSHOWHIDDEN 6 +#define CONTROL_BTNSHOWDELETED 7 #define CONTROL_BTNCHANNELGROUPS 28 #define CONTROL_BTNFILTERCHANNELS 31 diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp index 8f20bad083..7ebafc1a7a 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.cpp @@ -39,7 +39,8 @@ using namespace PVR; CGUIWindowPVRRecordings::CGUIWindowPVRRecordings(bool bRadio) : - CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_RECORDINGS : WINDOW_TV_RECORDINGS, "MyPVRRecordings.xml") + CGUIWindowPVRBase(bRadio, bRadio ? WINDOW_RADIO_RECORDINGS : WINDOW_TV_RECORDINGS, "MyPVRRecordings.xml") , + m_bShowDeletedRecordings(false) { } @@ -69,15 +70,18 @@ void CGUIWindowPVRRecordings::OnWindowLoaded() std::string CGUIWindowPVRRecordings::GetDirectoryPath(void) { - if (StringUtils::StartsWith(m_vecItems->GetPath(), "pvr://recordings/")) + std::string basePath = StringUtils::Format("pvr://recordings/%s/", m_bShowDeletedRecordings ? "deleted" : "active"); + + if (StringUtils::StartsWith(m_vecItems->GetPath(), basePath)) return m_vecItems->GetPath(); - return "pvr://recordings/"; + + return basePath; } std::string CGUIWindowPVRRecordings::GetResumeString(const CFileItem& item) { std::string resumeString; - if (item.IsPVRRecording()) + if (item.IsUsablePVRRecording()) { // First try to find the resume position on the back-end, if that fails use video database @@ -109,40 +113,62 @@ void CGUIWindowPVRRecordings::GetContextButtons(int itemNumber, CContextButtons return; CFileItemPtr pItem = m_vecItems->Get(itemNumber); + bool isDeletedRecording = false; + if (pItem->HasPVRRecordingInfoTag()) { + isDeletedRecording = pItem->GetPVRRecordingInfoTag()->IsDeleted(); + buttons.Add(CONTEXT_BUTTON_INFO, 19053); /* Get Information of this recording */ - buttons.Add(CONTEXT_BUTTON_FIND, 19003); /* Find similar program */ - buttons.Add(CONTEXT_BUTTON_PLAY_ITEM, 12021); /* Play this recording */ - std::string resumeString = GetResumeString(*pItem); - if (!resumeString.empty()) + if (!isDeletedRecording) { - buttons.Add(CONTEXT_BUTTON_RESUME_ITEM, resumeString); + buttons.Add(CONTEXT_BUTTON_FIND, 19003); /* Find similar program */ + buttons.Add(CONTEXT_BUTTON_PLAY_ITEM, 12021); /* Play this recording */ + std::string resumeString = GetResumeString(*pItem); + if (!resumeString.empty()) + { + buttons.Add(CONTEXT_BUTTON_RESUME_ITEM, resumeString); + } + } + else + { + buttons.Add(CONTEXT_BUTTON_UNDELETE, 19290); /* Undelete this recording */ + buttons.Add(CONTEXT_BUTTON_DELETE, 19291); /* Delete this permanently */ + if (m_vecItems->GetObjectCount() > 1) + buttons.Add(CONTEXT_BUTTON_DELETE_ALL, 19292); /* Delete all permanently */ } } - if (pItem->m_bIsFolder) - { - // Have both options for folders since we don't know whether all childs are watched/unwatched - buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); /* Mark as UnWatched */ - buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); /* Mark as Watched */ - } - if (pItem->HasPVRRecordingInfoTag()) + if (!isDeletedRecording) { - if (pItem->GetPVRRecordingInfoTag()->m_playCount > 0) + if (pItem->m_bIsFolder) + { + // Have both options for folders since we don't know whether all childs are watched/unwatched buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); /* Mark as UnWatched */ - else buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); /* Mark as Watched */ + } + if (pItem->HasPVRRecordingInfoTag()) + { + if (pItem->GetPVRRecordingInfoTag()->m_playCount > 0) + buttons.Add(CONTEXT_BUTTON_MARK_UNWATCHED, 16104); /* Mark as UnWatched */ + else + buttons.Add(CONTEXT_BUTTON_MARK_WATCHED, 16103); /* Mark as Watched */ - buttons.Add(CONTEXT_BUTTON_RENAME, 118); /* Rename this recording */ + buttons.Add(CONTEXT_BUTTON_RENAME, 118); /* Rename this recording */ + } + + buttons.Add(CONTEXT_BUTTON_DELETE, 117); } - - buttons.Add(CONTEXT_BUTTON_DELETE, 117); - if (pItem->HasPVRRecordingInfoTag() && - g_PVRClients->HasMenuHooks(pItem->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_RECORDING)) - buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */ + if (pItem->HasPVRRecordingInfoTag()) + { + if (!isDeletedRecording && g_PVRClients->HasMenuHooks(pItem->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_RECORDING)) + buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */ + else if (isDeletedRecording && g_PVRClients->HasMenuHooks(pItem->GetPVRRecordingInfoTag()->m_iClientId, PVR_MENUHOOK_DELETED_RECORDING)) + buttons.Add(CONTEXT_BUTTON_MENU_HOOKS, 19195); /* PVR client specific action */ + } - CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); + if (!isDeletedRecording) + CGUIWindowPVRBase::GetContextButtons(itemNumber, buttons); } bool CGUIWindowPVRRecordings::OnAction(const CAction &action) @@ -150,7 +176,7 @@ bool CGUIWindowPVRRecordings::OnAction(const CAction &action) if (action.GetID() == ACTION_PARENT_DIR || action.GetID() == ACTION_NAV_BACK) { - if (m_vecItems->GetPath() != "pvr://recordings/") + if (m_vecItems->GetPath() != "pvr://recordings/active/" && m_vecItems->GetPath() != "pvr://recordings/deleted/") { GoParentFolder(); return true; @@ -168,6 +194,8 @@ bool CGUIWindowPVRRecordings::OnContextButton(int itemNumber, CONTEXT_BUTTON but return OnContextButtonPlay(pItem.get(), button) || OnContextButtonRename(pItem.get(), button) || OnContextButtonDelete(pItem.get(), button) || + OnContextButtonUndelete(pItem.get(), button) || + OnContextButtonDeleteAll(pItem.get(), button) || OnContextButtonInfo(pItem.get(), button) || OnContextButtonMarkWatched(pItem, button) || CGUIWindowPVRBase::OnContextButton(itemNumber, button); @@ -177,7 +205,30 @@ bool CGUIWindowPVRRecordings::Update(const std::string &strDirectory, bool updat { m_thumbLoader.StopThread(); - return CGUIWindowPVRBase::Update(strDirectory); + bool bReturn = CGUIWindowPVRBase::Update(strDirectory); + + /* empty list for deleted recordings */ + if (m_vecItems->GetObjectCount() == 0 && m_bShowDeletedRecordings) + { + /* show the normal recordings instead */ + m_bShowDeletedRecordings = false; + Update(GetDirectoryPath()); + } + + return bReturn; +} + +void CGUIWindowPVRRecordings::UpdateButtons(void) +{ + CGUIRadioButtonControl *btnShowDeleted = (CGUIRadioButtonControl*) GetControl(CONTROL_BTNSHOWDELETED); + if (btnShowDeleted) + { + btnShowDeleted->SetVisible(g_PVRRecordings->HasDeletedRecordings()); + btnShowDeleted->SetSelected(m_bShowDeletedRecordings); + } + + CGUIWindowPVRBase::UpdateButtons(); + SET_CONTROL_LABEL(CONTROL_LABEL_HEADER1, m_bShowDeletedRecordings ? g_localizeStrings.Get(19179) : ""); /* Deleted recordings trash */ } bool CGUIWindowPVRRecordings::OnMessage(CGUIMessage &message) @@ -236,6 +287,16 @@ bool CGUIWindowPVRRecordings::OnMessage(CGUIMessage &message) g_PVRRecordings->SetGroupItems(radioButton->IsSelected()); Refresh(true); } + else if (message.GetSenderId() == CONTROL_BTNSHOWDELETED) + { + CGUIRadioButtonControl *radioButton = (CGUIRadioButtonControl*) GetControl(CONTROL_BTNSHOWDELETED); + if (radioButton) + { + m_bShowDeletedRecordings = radioButton->IsSelected(); + Update(GetDirectoryPath()); + } + bReturn = true; + } break; case GUI_MSG_REFRESH_LIST: switch(message.GetParam1()) @@ -276,7 +337,7 @@ bool CGUIWindowPVRRecordings::ActionDeleteRecording(CFileItem *item) return bReturn; pDialog->SetHeading(122); // Confirm delete - pDialog->SetLine(0, item->m_bIsFolder ? 19113 : 19112); // Are you sure? + pDialog->SetLine(0, item->m_bIsFolder ? 19113 : item->GetPVRRecordingInfoTag()->IsDeleted() ? 19294 : 19112); // Delete all recordings in this folder? / Delete this recording permanently? / Delete this recording? pDialog->SetLine(1, ""); pDialog->SetLine(2, item->GetLabel()); pDialog->SetChoice(1, 117); // Delete @@ -297,7 +358,8 @@ bool CGUIWindowPVRRecordings::ActionDeleteRecording(CFileItem *item) m_vecItems->Remove(item); /* go to the parent folder if we're in a subdirectory and just deleted the last item */ - if (m_vecItems->GetPath() != "pvr://recordings/" && m_vecItems->GetObjectCount() == 0) + if (m_vecItems->GetPath() != "pvr://recordings/active/" && + m_vecItems->GetPath() != "pvr://recordings/deleted/" && m_vecItems->GetObjectCount() == 0) GoParentFolder(); } @@ -309,6 +371,72 @@ bool CGUIWindowPVRRecordings::OnContextButtonDelete(CFileItem *item, CONTEXT_BUT return button == CONTEXT_BUTTON_DELETE ? ActionDeleteRecording(item) : false; } +bool CGUIWindowPVRRecordings::OnContextButtonUndelete(CFileItem *item, CONTEXT_BUTTON button) +{ + bool bReturn = false; + + if (button != CONTEXT_BUTTON_UNDELETE || !item->IsDeletedPVRRecording()) + return bReturn; + + /* undelete the recording */ + if (g_PVRRecordings->Undelete(*item)) + { + g_PVRManager.TriggerRecordingsUpdate(); + bReturn = true; + + /* remove the item from the list immediately, otherwise the + item count further down may be wrong */ + m_vecItems->Remove(item); + + /* go to the parent folder if we're in a subdirectory and just deleted the last item */ + if (m_vecItems->GetPath() != "pvr://recordings/deleted/" && m_vecItems->GetObjectCount() == 0) + GoParentFolder(); + } + + return bReturn; +} + +bool CGUIWindowPVRRecordings::OnContextButtonDeleteAll(CFileItem *item, CONTEXT_BUTTON button) +{ + bool bReturn = false; + + if (button != CONTEXT_BUTTON_DELETE_ALL || !item->IsDeletedPVRRecording()) + return bReturn; + + /* show a confirmation dialog */ + CGUIDialogYesNo* pDialog = (CGUIDialogYesNo*)g_windowManager.GetWindow(WINDOW_DIALOG_YES_NO); + if (!pDialog) + return bReturn; + + + pDialog->SetHeading(19292); // Delete all permanently + pDialog->SetLine(0, 19293); // Delete all recordings permanently? + pDialog->SetLine(1, ""); + pDialog->SetLine(2, ""); + pDialog->SetChoice(1, 117); // Delete + + /* prompt for the user's confirmation */ + pDialog->DoModal(); + if (!pDialog->IsConfirmed()) + return bReturn; + + /* undelete the recording */ + if (g_PVRRecordings->DeleteAllRecordingsFromTrash()) + { + g_PVRManager.TriggerRecordingsUpdate(); + bReturn = true; + + /* remove the item from the list immediately, otherwise the + item count further down may be wrong */ + m_vecItems->Clear(); + + /* go to the parent folder if we're in a subdirectory and just deleted the last item */ + if (m_vecItems->GetPath() != "pvr://recordings/deleted/" && m_vecItems->GetObjectCount() == 0) + GoParentFolder(); + } + return bReturn; +} + bool CGUIWindowPVRRecordings::OnContextButtonInfo(CFileItem *item, CONTEXT_BUTTON button) { bool bReturn = false; diff --git a/xbmc/pvr/windows/GUIWindowPVRRecordings.h b/xbmc/pvr/windows/GUIWindowPVRRecordings.h index 72ba2e8951..6d45ca0fe7 100644 --- a/xbmc/pvr/windows/GUIWindowPVRRecordings.h +++ b/xbmc/pvr/windows/GUIWindowPVRRecordings.h @@ -40,6 +40,7 @@ namespace PVR void GetContextButtons(int itemNumber, CContextButtons &buttons); bool OnContextButton(int itemNumber, CONTEXT_BUTTON button); bool Update(const std::string &strDirectory, bool updateFilterPath = true); + void UpdateButtons(void); void UnregisterObservers(void); void ResetObservers(void); @@ -50,6 +51,8 @@ namespace PVR private: bool ActionDeleteRecording(CFileItem *item); bool OnContextButtonDelete(CFileItem *item, CONTEXT_BUTTON button); + bool OnContextButtonUndelete(CFileItem *item, CONTEXT_BUTTON button); + bool OnContextButtonDeleteAll(CFileItem *item, CONTEXT_BUTTON button); bool OnContextButtonInfo(CFileItem *item, CONTEXT_BUTTON button); bool OnContextButtonPlay(CFileItem *item, CONTEXT_BUTTON button); bool OnContextButtonRename(CFileItem *item, CONTEXT_BUTTON button); @@ -57,5 +60,6 @@ namespace PVR CVideoThumbLoader m_thumbLoader; CVideoDatabase m_database; + bool m_bShowDeletedRecordings; }; } diff --git a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp index bfbbaf134e..bcac15a25a 100644 --- a/xbmc/pvr/windows/GUIWindowPVRSearch.cpp +++ b/xbmc/pvr/windows/GUIWindowPVRSearch.cpp @@ -116,7 +116,7 @@ bool CGUIWindowPVRSearch::OnContextButton(const CFileItem &item, CONTEXT_BUTTON if (tag) m_searchfilter.m_strSearchTerm = "\"" + tag->Title() + "\""; } - else if (item.IsPVRRecording()) + else if (item.IsUsablePVRRecording()) m_searchfilter.m_strSearchTerm = "\"" + item.GetPVRRecordingInfoTag()->m_strTitle + "\""; else if (item.IsPVRTimer()) m_searchfilter.m_strSearchTerm = "\"" + item.GetPVRTimerInfoTag()->m_strTitle + "\""; diff --git a/xbmc/video/windows/GUIWindowVideoBase.cpp b/xbmc/video/windows/GUIWindowVideoBase.cpp index c78b5bdaf7..0547b8ad51 100644 --- a/xbmc/video/windows/GUIWindowVideoBase.cpp +++ b/xbmc/video/windows/GUIWindowVideoBase.cpp @@ -1410,7 +1410,7 @@ bool CGUIWindowVideoBase::OnPlayMedia(int iItem) } CLog::Log(LOGDEBUG, "%s %s", __FUNCTION__, CURL::GetRedacted(item.GetPath()).c_str()); - if (StringUtils::StartsWith(item.GetPath(), "pvr://recordings/")) + if (StringUtils::StartsWith(item.GetPath(), "pvr://recordings/active/")) { if (!g_PVRManager.IsStarted()) return false; diff --git a/xbmc/windows/GUIWindowSystemInfo.cpp b/xbmc/windows/GUIWindowSystemInfo.cpp index 9e281b5439..68f3a437f9 100644 --- a/xbmc/windows/GUIWindowSystemInfo.cpp +++ b/xbmc/windows/GUIWindowSystemInfo.cpp @@ -182,6 +182,7 @@ void CGUIWindowSystemInfo::FrameMove() SetControlLabel(i++, "%s: %s", 19116, PVR_BACKEND_DISKSPACE); SetControlLabel(i++, "%s: %s", 19019, PVR_BACKEND_CHANNELS); SetControlLabel(i++, "%s: %s", 19163, PVR_BACKEND_RECORDINGS); + SetControlLabel(i++, "%s: %s", 19168, PVR_BACKEND_DELETED_RECORDINGS); // Deleted and recoverable recordings SetControlLabel(i++, "%s: %s", 19025, PVR_BACKEND_TIMERS); } |