From aaba5e7c8c50ae1d14904f76dc838f003a1d2351 Mon Sep 17 00:00:00 2001 From: bunjee Date: Fri, 19 Apr 2019 17:43:42 +0200 Subject: [PATCH] Add subtitle support --- MotionBox.pro | 4 +- content/AreaContextualApplication.qml | 4 +- content/BarControls.qml | 4 +- content/Gui.qml | 18 +- content/PageSubtitles.qml | 334 +++++++++++++++++++++++ content/PageSubtitlesSearch.qml | 233 ++++++++++++++++ content/PanelBrowse.qml | 2 - content/{PanelShare.qml => PanelGet.qml} | 158 +++-------- content/PanelRelated.qml | 8 +- content/PanelSearch.qml | 2 - content/PanelSettings.qml | 28 +- content/StyleApplication.qml | 4 +- dist/changes/1.5.1.md | 4 + src/controllers/ControllerCore.cpp | 31 ++- src/controllers/ControllerCore.h | 7 +- src/io/DataLocal.cpp | 33 +++ src/io/DataLocal.h | 10 + 17 files changed, 701 insertions(+), 183 deletions(-) create mode 100644 content/PageSubtitles.qml create mode 100644 content/PageSubtitlesSearch.qml rename content/{PanelShare.qml => PanelGet.qml} (59%) diff --git a/MotionBox.pro b/MotionBox.pro index ff852dba..aa24c124 100644 --- a/MotionBox.pro +++ b/MotionBox.pro @@ -87,7 +87,7 @@ OTHER_FILES += configure.sh \ content/PanelRelated.qml \ content/PanelCover.qml \ content/PanelSettings.qml \ - content/PanelShare.qml \ + content/PanelGet.qml \ content/PanelAdd.qml \ content/PanelPreview.qml \ content/BarWindowApplication.qml \ @@ -117,6 +117,8 @@ OTHER_FILES += configure.sh \ content/PageAboutText.qml \ content/PageAboutMessage.qml \ content/PageAboutCredits.qml \ + content/PageSubtitles.qml \ + content/PageSubtitlesSearch.qml \ dist/MotionBox.rc \ dist/qrc.sh \ dist/doc/readme.md \ diff --git a/content/AreaContextualApplication.qml b/content/AreaContextualApplication.qml index c946d80c..377bd220 100644 --- a/content/AreaContextualApplication.qml +++ b/content/AreaContextualApplication.qml @@ -624,7 +624,7 @@ AreaContextual { listContextual.setCurrentId(0); - var path = core.openFile("Select File"); + var path = core.openFile(qsTr("Select File")); panelBrowse.browse(path); } @@ -632,7 +632,7 @@ AreaContextual { listContextual.setCurrentId(1); - /* var */ path = core.openFolder("Select Folder"); + /* var */ path = core.openFolder(qsTr("Select Folder")); panelBrowse.browse(path); } diff --git a/content/BarControls.qml b/content/BarControls.qml index ec456f27..5f0337a9 100644 --- a/content/BarControls.qml +++ b/content/BarControls.qml @@ -403,12 +403,12 @@ MouseArea width: st.dp44 checkable: true - checked : panelShare.isExposed + checked : panelGet.isExposed icon : st.icon24x24_share iconSourceSize: st.size24x24 - onPressed: panelShare.toggleExpose() + onPressed: panelGet.toggleExpose() } ButtonPushIcon diff --git a/content/Gui.qml b/content/Gui.qml index bc3bfdbb..6e7ab651 100644 --- a/content/Gui.qml +++ b/content/Gui.qml @@ -882,9 +882,9 @@ Item return; } - else if (panelShare.isExposed) + else if (panelGet.isExposed) { - panelShare.collapse(); + panelGet.collapse(); return; } @@ -1008,7 +1008,7 @@ Item if (buttonAdd.checked || actionCue.tryPush(actionAddShow)) return; panelSettings.collapse(); - panelShare .collapse(); + panelGet .collapse(); playlistTemp.clearTracks(); @@ -1470,7 +1470,7 @@ Item panelApplication.collapse(); panelSettings.collapse(); - panelShare .collapse(); + panelGet .collapse(); panelDiscover.collapse(); @@ -3145,9 +3145,9 @@ Item { panelSettings.collapse(); } - else if (panelShare.isExposed) + else if (panelGet.isExposed) { - panelShare.collapse(); + panelGet.collapse(); } else if (panelDiscover.isExposed) { @@ -3554,8 +3554,8 @@ Item else if (id == actionSettingsExpose) panelSettings.expose (); else if (id == actionSettingsCollapse) panelSettings.collapse(); - else if (id == actionShareExpose) panelShare.expose (); - else if (id == actionShareCollapse) panelShare.collapse(); + else if (id == actionShareExpose) panelGet.expose (); + else if (id == actionShareCollapse) panelGet.collapse(); else if (id == actionSearchExpose) lineEditSearch.focus(); @@ -3645,7 +3645,7 @@ Item PanelDiscover { id: panelDiscover } - PanelShare { id: panelShare } + PanelGet { id: panelGet } PanelSettings { id: panelSettings } diff --git a/content/PageSubtitles.qml b/content/PageSubtitles.qml new file mode 100644 index 00000000..5aa58e98 --- /dev/null +++ b/content/PageSubtitles.qml @@ -0,0 +1,334 @@ +//================================================================================================= +/* + Copyright (C) 2015-2017 MotionBox authors united with omega. + + Author: Benjamin Arnaud. + + This file is part of MotionBox. + + - GNU General Public License Usage: + This file may be used under the terms of the GNU General Public License version 3 as published + by the Free Software Foundation and appearing in the LICENSE.md file included in the packaging + of this file. Please review the following information to ensure the GNU General Public License + requirements will be met: https://www.gnu.org/licenses/gpl.html. +*/ +//================================================================================================= + +import QtQuick 1.0 +import Sky 1.0 + +Item +{ + //--------------------------------------------------------------------------------------------- + // Properties private + //--------------------------------------------------------------------------------------------- + + property bool pEnable: (playerTab && playerTab.currentIndex != -1) + + property bool pSearch: false + + property bool pAdd: (pSearch || playerTab.subtitle == "") + + property int pHeight: st.list_itemSize * 6 + + property variant pItem: loader.item + + //--------------------------------------------------------------------------------------------- + // Settings + //--------------------------------------------------------------------------------------------- + + height: lineEdit.height + loader.height + + //--------------------------------------------------------------------------------------------- + // Events + //--------------------------------------------------------------------------------------------- + + onVisibleChanged: + { + if (visible || pSearch == false) return; + + pSearchHide(); + } + + //--------------------------------------------------------------------------------------------- + // Connections + //--------------------------------------------------------------------------------------------- + + Connections + { + target: player + + onTabChanged: pUpdateText() + } + + Connections + { + target: playerTab + + onSubtitleChanged: pUpdateText() + } + + //--------------------------------------------------------------------------------------------- + // Functions private + //--------------------------------------------------------------------------------------------- + + function pStartSearch(query) + { + if (query == "") return; + + if (core.checkUrl(query) == false) + { + if (pSearch) + { + pItem.hideCompletion(); + } + else pSearchShow(); + + pItem.search(query); + } + else pSearchHide(); + } + + //--------------------------------------------------------------------------------------------- + + function pSearchShow() + { + loader.source = Qt.resolvedUrl("PageSubtitlesSearch.qml"); + loader.visible = true; + + pSearch = true; + } + + function pSearchHide() + { + if (lineEdit.isFocused) + { + window.clearFocus(); + } + + pSearch = false; + + lineEdit.text = playerTab.subtitle; + } + + function pSearchToogle() + { + if (pSearch == false) + { + lineEdit.text = ""; + + lineEdit.focus(); + } + else pSearchHide(); + } + + //--------------------------------------------------------------------------------------------- + + function pUpdateText() + { + if (pSearch) return; + + lineEdit.text = playerTab.subtitle; + } + + //--------------------------------------------------------------------------------------------- + + function pGetText() + { + if (pEnable) + { + return qsTr("What subtitle are you looking for ?"); + } + else return qsTr("No track selected"); + } + + //--------------------------------------------------------------------------------------------- + // Childs + //--------------------------------------------------------------------------------------------- + + LineEditBox + { + id: lineEdit + + anchors.left : parent.left + anchors.right: buttonAdd.left + + enabled: (pEnable && (pSearch || text == "")) + + text: playerTab.subtitle + +//#QT_4 + textDefault: pGetText() +//#ELSE + textDefault: (text) ? text + : pGetText() + + textInput.visible: isFocused + + itemTextDefault.visible: (isFocused == false) +//#END + + font.pixelSize: st.dp14 + + itemTextDefault.elide: Text.ElideLeft + + onIsFocusedChanged: if (isFocused && pSearch == false) pSearchShow() + + onTextChanged: if (pSearch) pItem.applyText(text) + + function onKeyPressed(event) + { + if (event.key == Qt.Key_Up) + { + event.accepted = true; + + if (pItem) pItem.selectPrevious(); + } + else if (event.key == Qt.Key_Down) + { + event.accepted = true; + + if (pItem) pItem.selectNext(); + } + else if (event.key == Qt.Key_Return || event.key == Qt.Key_Enter) + { + event.accepted = true; + + if (event.isAutoRepeat) return; + + pStartSearch(text); + } + else if (event.key == Qt.Key_Escape) + { + event.accepted = true; + + window.clearFocus(); + } + } + } + + ButtonPianoIcon + { + id: buttonAdd + + anchors.right : buttonSearch.left + anchors.top : buttonSearch.top + anchors.bottom: buttonSearch.bottom + + width: buttonSearch.width + + borderLeft : borderSize + borderRight: 0 + + enabled: pEnable + + highlighted: (pAdd) ? false : player.isPlaying + + icon: (pAdd) ? st.icon24x24_addIn + : st.icon16x16_close + + iconSourceSize: (pAdd) ? st.size24x24 + : st.size16x16 + + onClicked: + { + if (pAdd) + { + if (lineEdit.isFocused) window.clearFocus(); + + var path = core.openSubtitle(qsTr("Select Subtitle")); + + if (path == "") return; + + pSearch = false; + + playerTab.subtitle = path; + } + else playerTab.subtitle = ""; + } + } + + ButtonPianoIcon + { + id: buttonSearch + + anchors.right : parent.right + anchors.top : lineEdit.top + anchors.bottom: lineEdit.bottom + + width: height + borderSizeWidth + + borderLeft : borderSize + borderRight: 0 + + enabled: pEnable + + checkable: true + checked : pSearch + + icon : st.icon32x32_search + iconSourceSize: st.size32x32 + + onPressed: pSearchToogle() + } + + BorderHorizontal + { + id: border + + anchors.top: lineEdit.bottom + + visible: loader.visible + } + + Loader + { + id: loader + + anchors.left : parent.left + anchors.right: parent.right + anchors.top : border.bottom + + height: 0 + + visible: false + + states: State + { + name: "visible"; when: pSearch + + PropertyChanges + { + target: loader + + height: pHeight + } + } + + transitions: Transition + { + SequentialAnimation + { + NumberAnimation + { + property: "height" + + duration: st.duration_faster + + easing.type: st.easing + } + + ScriptAction + { + script: + { + if (pSearch) return; + + loader.visible = false; + loader.source = ""; + } + } + } + } + } +} diff --git a/content/PageSubtitlesSearch.qml b/content/PageSubtitlesSearch.qml new file mode 100644 index 00000000..2320c219 --- /dev/null +++ b/content/PageSubtitlesSearch.qml @@ -0,0 +1,233 @@ +//================================================================================================= +/* + Copyright (C) 2015-2017 MotionBox authors united with omega. + + Author: Benjamin Arnaud. + + This file is part of MotionBox. + + - GNU General Public License Usage: + This file may be used under the terms of the GNU General Public License version 3 as published + by the Free Software Foundation and appearing in the LICENSE.md file included in the packaging + of this file. Please review the following information to ensure the GNU General Public License + requirements will be met: https://www.gnu.org/licenses/gpl.html. +*/ +//================================================================================================= + +import QtQuick 1.0 +import Sky 1.0 + +Item +{ + //--------------------------------------------------------------------------------------------- + // Properties private + //--------------------------------------------------------------------------------------------- + + property string pSearchEngine: "opensubtitles" + + property bool pVisible: (scrollCompletion.visible == false) + + property bool pTextEvents: true + + //--------------------------------------------------------------------------------------------- + // Aliases private + //--------------------------------------------------------------------------------------------- + + property alias pFolder: model.folder + + //--------------------------------------------------------------------------------------------- + // Settings + //--------------------------------------------------------------------------------------------- + + height: pHeight + + //--------------------------------------------------------------------------------------------- + // Events + //--------------------------------------------------------------------------------------------- + + Component.onCompleted: + { + pFolder = core.createFolder(); + + scrollLanguages.scrollToItemTop(scrollLanguages.currentIndex); + } + + Component.onDestruction: pFolder.tryDelete() + + //--------------------------------------------------------------------------------------------- + // Functions + //--------------------------------------------------------------------------------------------- + + function search(query) + { + var language; + + var index = scrollLanguages.currentIndex; + + if (index == -1) + { + language = "english"; + } + else language = modelLanguage.titleAt(index).toLowerCase(); + + var source = controllerPlaylist.createSource(pSearchEngine, "subtitles", language, query); + + pFolder.loadSource(source); + } + + function applyText(text) + { + if (pTextEvents == false) return; + + scrollCompletion.currentIndex = -1; + + scrollCompletion.query = text; + + scrollCompletion.runQuery(); + + if (text) + { + scrollCompletion.visible = true; + } + else scrollCompletion.visible = false; + } + + //--------------------------------------------------------------------------------------------- + + function selectPrevious() + { + if (scrollCompletion.visible) + { + scrollCompletion.selectPrevious(); + } + } + + function selectNext() + { + if (scrollCompletion.visible) + { + scrollCompletion.selectNext(); + } + } + + //--------------------------------------------------------------------------------------------- + + function showCompletion() + { + scrollCompletion.visible = true; + } + + function hideCompletion() + { + scrollCompletion.visible = false; + + scrollCompletion.currentIndex = -1; + } + + //--------------------------------------------------------------------------------------------- + // Childs + //--------------------------------------------------------------------------------------------- + + ScrollCompletion + { + id: scrollLanguages + + anchors.top : parent.top + anchors.bottom: parent.bottom + + width: st.dp128 + + visible: pVisible + + currentIndex: local.subtitleIndex + + model: ModelList + { + id: modelLanguage + + titles: controllerPlaylist.getLanguages() + } + + onCurrentIndexChanged: + { + var text = lineEdit.text; + + if (text) search(text); + + local.subtitleIndex = currentIndex; + } + } + + BorderVertical + { + id: border + + anchors.left: scrollLanguages.right + + visible: pVisible + } + + ScrollCompletion + { + id: scrollFolder + + anchors.left : border.right + anchors.right : parent.right + anchors.top : parent.top + anchors.bottom: parent.bottom + + visible: pVisible + + model: ModelLibraryFolder { id: model } + + textDefault: (labelLoading.visible) ? "" : qsTr("Type a subtitle query") + } + + LabelLoadingButton + { + id: labelLoading + + anchors.top: parent.top + + anchors.topMargin: st.dp8 + + anchors.horizontalCenter: scrollFolder.horizontalCenter + + visible: (pFolder) ? pFolder.queryIsLoading : false + + text: qsTr("Loading...") + + onClicked: pFolder.abortQuery() + } + + ScrollCompletion + { + id: scrollCompletion + + anchors.fill: parent + + visible: false + + delegate: ComponentCompletion + { + itemText.font.pixelSize: st.dp14 + } + + textDefault: qsTr("Type a subtitle query") + + onCompletionChanged: + { + if (currentIndex != -1) + { + pTextEvents = false; + + lineEdit.text = completion; + + pTextEvents = true; + + lineEdit.moveCursorAtEnd(); + } + else scrollTo(0); + } + } +} diff --git a/content/PanelBrowse.qml b/content/PanelBrowse.qml index 3c321a6f..9cf09211 100644 --- a/content/PanelBrowse.qml +++ b/content/PanelBrowse.qml @@ -1709,8 +1709,6 @@ MouseArea { if (currentIndex != -1) { - scrollToItem(currentIndex); - pTextEvents = false; lineEdit.text = completion; diff --git a/content/PanelShare.qml b/content/PanelGet.qml similarity index 59% rename from content/PanelShare.qml rename to content/PanelGet.qml index 2fde44e0..92cba8d5 100644 --- a/content/PanelShare.qml +++ b/content/PanelGet.qml @@ -19,7 +19,7 @@ import Sky 1.0 Panel { - id: panelShare + id: panelGet //--------------------------------------------------------------------------------------------- // Properties @@ -27,6 +27,8 @@ Panel /* read */ property bool isExposed: false + /* read */ property int indexCurrent: -1 + //--------------------------------------------------------------------------------------------- // Settings //--------------------------------------------------------------------------------------------- @@ -34,12 +36,14 @@ Panel anchors.right: parent.right anchors.top : parent.bottom - anchors.rightMargin: (gui.isMini) ? -st.border_size : st.dp52 + anchors.rightMargin: (gui.isMini) ? 0 : st.dp52 - width: buttonWebpage.x + buttonWebpage.width + st.dp7 + borderRight + width: st.dp480 + borderSizeWidth - height: bar.height + st.dp50 + borderSizeHeight + height: bar.height + loader.height + borderSizeHeight + borderLeft : (gui.isMini) ? 0 : borderSize + borderRight : borderLeft borderBottom: 0 visible: false @@ -56,7 +60,7 @@ Panel AnchorChanges { - target: panelShare + target: panelGet anchors.top : undefined anchors.bottom: parent.bottom @@ -114,6 +118,13 @@ Panel panelSettings.collapse(); + if (indexCurrent == -1) + { + indexCurrent = 0; + + loader.load(Qt.resolvedUrl("PageSubtitles.qml")); + } + isExposed = true; z = 1; @@ -144,143 +155,40 @@ Panel // Childs //--------------------------------------------------------------------------------------------- - BarTitleSmall + BarTitle { id: bar anchors.left : parent.left anchors.right: parent.right - borderTop: 0 - } - - BarTitleText - { - id: itemShare - - anchors.top : bar.top - anchors.bottom: bar.bottom - - anchors.bottomMargin: bar.borderBottom - - width: lineEdit.x + lineEdit.width + st.dp6 - - horizontalAlignment: Text.AlignHCenter - verticalAlignment : Text.AlignVCenter - - text: qsTr("Share Track") - - font.pixelSize: st.dp12 - } - - BorderVertical - { - id: border - - anchors.left: itemShare.right - } - - BarTitleText - { - anchors.left : border.right - anchors.right : parent.right - anchors.top : itemShare.top - anchors.bottom: itemShare.bottom - - leftMargin: st.dp8 - - verticalAlignment: Text.AlignVCenter - - text: qsTr("Go to") - - font.pixelSize: st.dp12 - } - - ButtonPianoIcon - { - anchors.right: parent.right - - width : st.barTitleSmall_height + borderSizeWidth - height: st.barTitleSmall_height + height: st.dp32 + borderSizeHeight - borderLeft : borderSize - borderRight: 0 - - icon : st.icon16x16_close - iconSourceSize: st.size16x16 - - onClicked: collapse() - } - - Image - { - id: image - - anchors.top : bar.bottom - anchors.bottom: parent.bottom - - width: st.dp50 - - sourceSize: Qt.size(width, height) - - visible: (source != "") - } - - BorderVertical - { - id: borderImage - - anchors.left: image.right - anchors.top : bar.bottom - - visible: image.visible - } - - LineEditCopy - { - id: lineEdit - - anchors.left: (borderImage.visible) ? borderImage.right - : parent.left - - anchors.top: bar.bottom + borderTop: 0 - anchors.leftMargin: st.dp6 - anchors.topMargin : st.dp6 + ButtonPiano + { + width: st.dp128 - width: st.dp180 + checkable: true + checked : (indexCurrent == 0) - text: currentTab.source + checkHover: false - textDefault: qsTr("No track selected") + text: qsTr("Subtitles") - onTextChanged: - { - if (text == "") - { - image.source = ""; - } - else image.source = controllerPlaylist.backendCoverFromUrl(currentTab.source); + font.pixelSize: st.dp14 } } - ButtonPushFull + LoaderSlide { - id: buttonWebpage - - anchors.left: lineEdit.right - anchors.top : bar.bottom - - anchors.leftMargin: st.dp13 - anchors.topMargin : st.dp5 - - enabled: (currentTab.source != "") + id: loader - icon : st.icon16x16_external - iconSourceSize: st.size16x16 - - text: gui.getOpenTitle(currentTab.source) + anchors.left : parent.left + anchors.right: parent.right + anchors.top : bar.bottom - onClicked: gui.openSource(currentTab.source) + height: (item) ? item.height : 0 } } diff --git a/content/PanelRelated.qml b/content/PanelRelated.qml index 905ea1c0..f4814d7b 100644 --- a/content/PanelRelated.qml +++ b/content/PanelRelated.qml @@ -529,14 +529,14 @@ Panel anchors.fill: parent - textDefault: qsTr("No related tracks") - - textVisible: (count == 1 && playlist != null && playlist.queryIsLoading == false) - playlist: (related) ? related.currentItem : null enableLoad: false + textDefault: qsTr("No related tracks") + + textVisible: (count == 1 && playlist != null && playlist.queryIsLoading == false) + buttonLink.anchors.rightMargin: 0 buttonLink.visible: (checkBox.visible && list.indexActive) diff --git a/content/PanelSearch.qml b/content/PanelSearch.qml index 2986f02e..4ccf507b 100644 --- a/content/PanelSearch.qml +++ b/content/PanelSearch.qml @@ -318,8 +318,6 @@ Panel { pIndexFocus = -1; - scrollToItem(currentIndex); - pTextEvents = false; lineEditSearch.text = completion; diff --git a/content/PanelSettings.qml b/content/PanelSettings.qml index 9da5d12d..8f8646fd 100644 --- a/content/PanelSettings.qml +++ b/content/PanelSettings.qml @@ -42,12 +42,14 @@ Panel anchors.right: parent.right anchors.top : parent.bottom - anchors.rightMargin: (gui.isMini) ? -st.border_size : st.dp96 + anchors.rightMargin: (gui.isMini) ? 0 : st.dp96 width: buttonMaximum.x + buttonMaximum.width + st.dp7 + borderRight height: barBottom.y + barBottom.height + st.dp50 + borderSizeHeight + borderLeft : (gui.isMini) ? 0 : borderSize + borderRight : borderLeft borderBottom: 0 visible: false @@ -134,13 +136,13 @@ Panel gui.panelAddHide(); - panelShare.collapse(); + panelGet.collapse(); isExposed = true; z = 1; - panelShare.z = 0; + panelGet.z = 0; visible = true; @@ -207,7 +209,7 @@ Panel BarTitleText { anchors.left : borderTop.right - anchors.right : buttonClose.left + anchors.right : parent.right anchors.top : itemOutput.top anchors.bottom: itemOutput.bottom @@ -219,24 +221,6 @@ Panel font.pixelSize: st.dp12 } - ButtonPianoIcon - { - id: buttonClose - - anchors.right: parent.right - - width : st.barTitleSmall_height + borderSizeWidth - height: st.barTitleSmall_height - - borderLeft : borderSize - borderRight: 0 - - icon : st.icon16x16_close - iconSourceSize: st.size16x16 - - onClicked: collapse() - } - ButtonPushLeft { id: buttonAudio diff --git a/content/StyleApplication.qml b/content/StyleApplication.qml index 83dd92fa..52c60858 100644 --- a/content/StyleApplication.qml +++ b/content/StyleApplication.qml @@ -50,8 +50,8 @@ Style //--------------------------------------------------------------------------------------------- - property int minimumWidth : 800 * scale - property int minimumHeight: 540 * scale + property int minimumWidth : 800 * ratio + property int minimumHeight: 540 * ratio property url logoApplication: "pictures/logo.svg" diff --git a/dist/changes/1.5.1.md b/dist/changes/1.5.1.md index cb109045..2f039eea 100644 --- a/dist/changes/1.5.1.md +++ b/dist/changes/1.5.1.md @@ -25,6 +25,10 @@ - Add 'ratio' support. +- Create 'PageSubtitles(s)'. + +- Rename 'PanelShare' to 'PanelGet'. + - Gui: Remove 'keepState' in the 'applyProxy' function. - BarWindowApplication: Add 'toggleTouch' on ViewDrag. diff --git a/src/controllers/ControllerCore.cpp b/src/controllers/ControllerCore.cpp index 69aa91c9..e679ddb6 100644 --- a/src/controllers/ControllerCore.cpp +++ b/src/controllers/ControllerCore.cpp @@ -403,16 +403,7 @@ ControllerCore::ControllerCore() : WController() /* Q_INVOKABLE */ QString ControllerCore::openFile(const QString & title) { - QString path = QFileDialog::getOpenFileName(NULL, title, _pathOpen, - WControllerPlaylist::getFileFilter()); - - if (path.isEmpty()) return QString(); - - QFileInfo info(path); - - _pathOpen = info.absolutePath(); - - return WControllerFile::fileUrl(info.absoluteFilePath()); + return getFile(title, WControllerPlaylist::getFilterFile()); } /* Q_INVOKABLE */ QString ControllerCore::openFolder(const QString & title) @@ -428,6 +419,11 @@ ControllerCore::ControllerCore() : WController() return WControllerFile::fileUrl(_pathOpen); } +/* Q_INVOKABLE */ QString ControllerCore::openSubtitle(const QString & title) +{ + return getFile(title, WControllerPlaylist::getFilterSubtitle()); +} + //------------------------------------------------------------------------------------------------- /* Q_INVOKABLE */ void ControllerCore::saveShot(WWindow * window) const @@ -814,6 +810,21 @@ void ControllerCore::deleteBrowse() _local->setCache(false); } +//------------------------------------------------------------------------------------------------- + +QString ControllerCore::getFile(const QString & title, const QString & filter) +{ + QString path = QFileDialog::getOpenFileName(NULL, title, _pathOpen, filter); + + if (path.isEmpty()) return QString(); + + QFileInfo info(path); + + _pathOpen = info.absoluteFilePath(); + + return WControllerFile::fileUrl(info.absoluteFilePath()); +} + //------------------------------------------------------------------------------------------------- // Properties //------------------------------------------------------------------------------------------------- diff --git a/src/controllers/ControllerCore.h b/src/controllers/ControllerCore.h index b60e580c..1a906248 100644 --- a/src/controllers/ControllerCore.h +++ b/src/controllers/ControllerCore.h @@ -74,8 +74,9 @@ class ControllerCore : public WController Q_INVOKABLE bool updateVersion(); - Q_INVOKABLE QString openFile (const QString & title); - Q_INVOKABLE QString openFolder(const QString & title); + Q_INVOKABLE QString openFile (const QString & title); + Q_INVOKABLE QString openFolder (const QString & title); + Q_INVOKABLE QString openSubtitle(const QString & title); Q_INVOKABLE void saveShot (WWindow * window) const; Q_INVOKABLE void saveSplash(WWindow * window, int border) const; @@ -141,6 +142,8 @@ class ControllerCore : public WController void deleteBrowse(); + QString getFile(const QString & title, const QString & filter); + signals: void cacheEmptyChanged(); diff --git a/src/io/DataLocal.cpp b/src/io/DataLocal.cpp index 85f955d7..f5930e83 100644 --- a/src/io/DataLocal.cpp +++ b/src/io/DataLocal.cpp @@ -99,6 +99,8 @@ class DataLocalWrite : public WAbstractThreadAction WAbstractBackend::Output output; WAbstractBackend::Quality quality; + int subtitleIndex; + bool cache; QString proxyHost; @@ -192,6 +194,8 @@ class DataLocalWrite : public WAbstractThreadAction stream.writeTextElement("output", QString::number(output)); stream.writeTextElement("quality", QString::number(quality)); + stream.writeTextElement("subtitleIndex", QString::number(subtitleIndex)); + stream.writeTextElement("cache", QString::number(cache)); stream.writeTextElement("proxyHost", proxyHost); @@ -267,6 +271,8 @@ class DataLocalWrite : public WAbstractThreadAction _output = WAbstractBackend::OutputMedia; _quality = WAbstractBackend::QualityHigh; + _subtitleIndex = 20; // English + _cache = false; _proxyPort = -1; @@ -516,6 +522,13 @@ class DataLocalWrite : public WAbstractThreadAction _quality = static_cast (WControllerXml::readNextInt(&stream)); + //--------------------------------------------------------------------------------------------- + // subtitleIndex + + if (WControllerXml::readNextStartElement(&stream, "subtitleIndex") == false) return false; + + _subtitleIndex = WControllerXml::readNextInt(&stream); + //--------------------------------------------------------------------------------------------- // cache @@ -669,6 +682,8 @@ class DataLocalWrite : public WAbstractThreadAction action->output = _output; action->quality = _quality; + action->subtitleIndex = _subtitleIndex; + action->cache = _cache; action->proxyHost = _proxyHost; @@ -1055,6 +1070,24 @@ void DataLocal::setQuality(WAbstractBackend::Quality quality) //------------------------------------------------------------------------------------------------- +int DataLocal::subtitleIndex() const +{ + return _subtitleIndex; +} + +void DataLocal::setSubtitleIndex(int index) +{ + if (_subtitleIndex == index) return; + + _subtitleIndex = index; + + emit subtitleIndexChanged(); + + save(); +} + +//------------------------------------------------------------------------------------------------- + bool DataLocal::cache() const { return _cache; diff --git a/src/io/DataLocal.h b/src/io/DataLocal.h index 3d8d4e38..402975d1 100644 --- a/src/io/DataLocal.h +++ b/src/io/DataLocal.h @@ -80,6 +80,9 @@ class DataLocal : public WLocalObject Q_PROPERTY(WAbstractBackend::Quality quality READ quality WRITE setQuality NOTIFY qualityChanged) + Q_PROPERTY(int subtitleIndex READ subtitleIndex WRITE setSubtitleIndex + NOTIFY subtitleIndexChanged) + Q_PROPERTY(bool cache READ cache WRITE setCache NOTIFY cacheChanged) Q_PROPERTY(QString proxyHost READ proxyHost WRITE setProxyHost NOTIFY proxyHostChanged) @@ -159,6 +162,8 @@ class DataLocal : public WLocalObject void outputChanged (); void qualityChanged(); + void subtitleIndexChanged(); + void cacheChanged(); void proxyHostChanged (); @@ -246,6 +251,9 @@ class DataLocal : public WLocalObject WAbstractBackend::Quality quality() const; void setQuality(WAbstractBackend::Quality quality); + int subtitleIndex() const; + void setSubtitleIndex(int index); + bool cache() const; void setCache(bool cache); @@ -328,6 +336,8 @@ class DataLocal : public WLocalObject WAbstractBackend::Output _output; WAbstractBackend::Quality _quality; + int _subtitleIndex; + bool _cache; QString _proxyHost;