mirror of
https://github.com/strawberrymusicplayer/strawberry
synced 2025-01-31 09:44:50 +01:00
Add translations support (#82)
* Add translations support * Update .gitignore
This commit is contained in:
parent
034b032cfa
commit
954e0e8a59
2
.gitignore
vendored
2
.gitignore
vendored
@ -106,6 +106,8 @@ PKGBUILD
|
|||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
translations.pot
|
translations.pot
|
||||||
|
zanata.xml
|
||||||
|
.zanata-cache/
|
||||||
|
|
||||||
# Snap
|
# Snap
|
||||||
parts/
|
parts/
|
||||||
|
@ -114,6 +114,7 @@ pkg_check_modules(LIBUSBMUXD libusbmuxd)
|
|||||||
pkg_check_modules(LIBPLIST libplist)
|
pkg_check_modules(LIBPLIST libplist)
|
||||||
pkg_check_modules(LIBDEEZER libdeezer)
|
pkg_check_modules(LIBDEEZER libdeezer)
|
||||||
pkg_check_modules(LIBDZMEDIA libdzmedia)
|
pkg_check_modules(LIBDZMEDIA libdzmedia)
|
||||||
|
find_package(Gettext)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
@ -151,6 +152,11 @@ if(WIN32)
|
|||||||
set(QT_LIBRARIES ${QT_LIBRARIES} Qt5::WinExtras)
|
set(QT_LIBRARIES ${QT_LIBRARIES} Qt5::WinExtras)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(Qt5LinguistTools CONFIG)
|
||||||
|
if (Qt5LinguistTools_FOUND)
|
||||||
|
set(QT_LCONVERT_EXECUTABLE Qt5::lconvert)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(X11_FOUND)
|
if(X11_FOUND)
|
||||||
find_path(KEYSYMDEF_H NAMES "keysymdef.h" PATHS "${X11_INCLUDE_DIR}" PATH_SUFFIXES "X11")
|
find_path(KEYSYMDEF_H NAMES "keysymdef.h" PATHS "${X11_INCLUDE_DIR}" PATH_SUFFIXES "X11")
|
||||||
find_path(XF86KEYSYM_H NAMES "XF86keysym.h" PATHS "${XCB_INCLUDEDIR}" PATH_SUFFIXES "X11")
|
find_path(XF86KEYSYM_H NAMES "XF86keysym.h" PATHS "${XCB_INCLUDEDIR}" PATH_SUFFIXES "X11")
|
||||||
@ -346,6 +352,11 @@ optional_component(SPARKLE ON "Sparkle integration"
|
|||||||
DEPENDS "Sparkle" SPARKLE
|
DEPENDS "Sparkle" SPARKLE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
optional_component(TRANSLATIONS OFF "Translations (No languages included yet)"
|
||||||
|
DEPENDS "gettext" GETTEXT_FOUND
|
||||||
|
DEPENDS "Qt5LinguistTools" Qt5LinguistTools_FOUND
|
||||||
|
)
|
||||||
|
|
||||||
optional_component(STREAM_TIDAL ON "Streaming: Tidal support")
|
optional_component(STREAM_TIDAL ON "Streaming: Tidal support")
|
||||||
|
|
||||||
if (LIBDZMEDIA_FOUND OR LIBDEEZER_FOUND)
|
if (LIBDZMEDIA_FOUND OR LIBDEEZER_FOUND)
|
||||||
|
77
cmake/Translations.cmake
Normal file
77
cmake/Translations.cmake
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8.11)
|
||||||
|
|
||||||
|
find_program(GETTEXT_XGETTEXT_EXECUTABLE xgettext)
|
||||||
|
if(NOT GETTEXT_XGETTEXT_EXECUTABLE)
|
||||||
|
message(FATAL_ERROR "Could not find xgettext executable")
|
||||||
|
endif(NOT GETTEXT_XGETTEXT_EXECUTABLE)
|
||||||
|
|
||||||
|
set (XGETTEXT_OPTIONS
|
||||||
|
--qt
|
||||||
|
--keyword=tr:1,2c
|
||||||
|
--keyword=tr --flag=tr:1:pass-c-format --flag=tr:1:pass-qt-format
|
||||||
|
--keyword=trUtf8 --flag=tr:1:pass-c-format --flag=tr:1:pass-qt-format
|
||||||
|
--keyword=translate:2,3c
|
||||||
|
--keyword=translate:2 --flag=translate:2:pass-c-format --flag=translate:2:pass-qt-format
|
||||||
|
--keyword=QT_TR_NOOP --flag=QT_TR_NOOP:1:pass-c-format --flag=QT_TR_NOOP:1:pass-qt-format
|
||||||
|
--keyword=QT_TRANSLATE_NOOP:2 --flag=QT_TRANSLATE_NOOP:2:pass-c-format --flag=QT_TRANSLATE_NOOP:2:pass-qt-format
|
||||||
|
--keyword=_ --flag=_:1:pass-c-format --flag=_:1:pass-qt-format
|
||||||
|
--keyword=N_ --flag=N_:1:pass-c-format --flag=N_:1:pass-qt-format
|
||||||
|
--from-code=utf-8
|
||||||
|
)
|
||||||
|
|
||||||
|
macro(add_pot outfiles header pot)
|
||||||
|
# Make relative filenames for all source files
|
||||||
|
set(add_pot_sources)
|
||||||
|
foreach(_filename ${ARGN})
|
||||||
|
get_filename_component(_absolute_filename ${_filename} ABSOLUTE)
|
||||||
|
file(RELATIVE_PATH _relative_filename ${CMAKE_CURRENT_SOURCE_DIR} ${_absolute_filename})
|
||||||
|
list(APPEND add_pot_sources ${_relative_filename})
|
||||||
|
endforeach(_filename)
|
||||||
|
|
||||||
|
# Generate the .pot
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${pot}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
COMMAND ${GETTEXT_XGETTEXT_EXECUTABLE} ${XGETTEXT_OPTIONS} -s -C --omit-header --output=${CMAKE_CURRENT_BINARY_DIR}/pot.temp ${add_pot_sources}
|
||||||
|
COMMAND cat ${header} ${CMAKE_CURRENT_BINARY_DIR}/pot.temp > ${pot}
|
||||||
|
DEPENDS ${add_pot_sources} ${header}
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND ${outfiles} ${pot})
|
||||||
|
endmacro(add_pot)
|
||||||
|
|
||||||
|
# Syntax is:
|
||||||
|
# add_po(sources_var po_prefix LANGUAGES language1 language2 ... DIRECTORY dir)
|
||||||
|
|
||||||
|
macro(add_po outfiles po_prefix)
|
||||||
|
parse_arguments(ADD_PO
|
||||||
|
"LANGUAGES;DIRECTORY"
|
||||||
|
""
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach (_lang ${ADD_PO_LANGUAGES})
|
||||||
|
set(_po_filename "${_lang}.po")
|
||||||
|
set(_po_filepath "${CMAKE_CURRENT_SOURCE_DIR}/${ADD_PO_DIRECTORY}/${_po_filename}")
|
||||||
|
set(_qm_filename "strawberry_${_lang}.qm")
|
||||||
|
set(_qm_filepath "${CMAKE_CURRENT_BINARY_DIR}/${ADD_PO_DIRECTORY}/${_qm_filename}")
|
||||||
|
|
||||||
|
# Convert the .po files to .qm files
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${_qm_filepath}
|
||||||
|
COMMAND ${QT_LCONVERT_EXECUTABLE} ARGS ${_po_filepath} -o ${_qm_filepath} -of qm
|
||||||
|
DEPENDS ${_po_filepath} ${_po_filepath}
|
||||||
|
)
|
||||||
|
|
||||||
|
list(APPEND ${outfiles} ${_qm_filepath})
|
||||||
|
endforeach (_lang)
|
||||||
|
|
||||||
|
# Generate a qrc file for the translations
|
||||||
|
set(_qrc ${CMAKE_CURRENT_BINARY_DIR}/${ADD_PO_DIRECTORY}/translations.qrc)
|
||||||
|
file(WRITE ${_qrc} "<RCC><qresource prefix=\"/${ADD_PO_DIRECTORY}\">")
|
||||||
|
foreach(_lang ${ADD_PO_LANGUAGES})
|
||||||
|
file(APPEND ${_qrc} "<file>${po_prefix}${_lang}.qm</file>")
|
||||||
|
endforeach(_lang)
|
||||||
|
file(APPEND ${_qrc} "</qresource></RCC>")
|
||||||
|
qt5_add_resources(${outfiles} ${_qrc})
|
||||||
|
endmacro(add_po)
|
@ -1,18 +1,18 @@
|
|||||||
/* This file is part of Clementine.
|
/* This file is part of Strawberry.
|
||||||
Copyright 2016, John Maguire <john.maguire@gmail.com>
|
Copyright 2016, John Maguire <john.maguire@gmail.com>
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
Strawberry is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
Strawberry is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LAZY_H
|
#ifndef LAZY_H
|
||||||
|
@ -26,6 +26,10 @@ if(BUILD_WERROR)
|
|||||||
endif (LINUX)
|
endif (LINUX)
|
||||||
endif(BUILD_WERROR)
|
endif(BUILD_WERROR)
|
||||||
|
|
||||||
|
if(HAVE_TRANSLATIONS)
|
||||||
|
include(../cmake/Translations.cmake)
|
||||||
|
endif(HAVE_TRANSLATIONS)
|
||||||
|
|
||||||
# Set up definitions and paths
|
# Set up definitions and paths
|
||||||
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
@ -904,6 +908,37 @@ qt5_wrap_cpp(MOC ${HEADERS})
|
|||||||
qt5_wrap_ui(UIC ${UI})
|
qt5_wrap_ui(UIC ${UI})
|
||||||
qt5_add_resources(QRC ${RESOURCES})
|
qt5_add_resources(QRC ${RESOURCES})
|
||||||
|
|
||||||
|
if(HAVE_TRANSLATIONS)
|
||||||
|
|
||||||
|
set(LINGUAS "All" CACHE STRING "A space-seperated list of translations to compile in to Strawberry, or \"None\".")
|
||||||
|
if (LINGUAS STREQUAL "All")
|
||||||
|
# build LANGUAGES from all existing .po files
|
||||||
|
file(GLOB pofiles translations/*.po)
|
||||||
|
foreach(pofile ${pofiles})
|
||||||
|
get_filename_component(lang ${pofile} NAME_WE)
|
||||||
|
list(APPEND LANGUAGES ${lang})
|
||||||
|
endforeach(pofile)
|
||||||
|
else (LINGUAS STREQUAL "All")
|
||||||
|
if (NOT LINGUAS OR LINGUAS STREQUAL "None")
|
||||||
|
set (LANGUAGES "")
|
||||||
|
else (NOT LINGUAS OR LINGUAS STREQUAL "None")
|
||||||
|
string(REGEX MATCHALL [a-zA-Z_@]+ LANGUAGES ${LINGUAS})
|
||||||
|
endif (NOT LINGUAS OR LINGUAS STREQUAL "None")
|
||||||
|
endif (LINGUAS STREQUAL "All")
|
||||||
|
|
||||||
|
add_pot(POT
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/translations/header
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/translations/translations.pot
|
||||||
|
${SOURCES}
|
||||||
|
${MOC}
|
||||||
|
${UIC}
|
||||||
|
${OTHER_SOURCES}
|
||||||
|
../data/html/oauthsuccess.html
|
||||||
|
)
|
||||||
|
add_po(PO strawberry_ LANGUAGES ${LANGUAGES} DIRECTORY translations)
|
||||||
|
|
||||||
|
endif(HAVE_TRANSLATIONS)
|
||||||
|
|
||||||
add_library(strawberry_lib STATIC
|
add_library(strawberry_lib STATIC
|
||||||
${SOURCES}
|
${SOURCES}
|
||||||
${MOC}
|
${MOC}
|
||||||
|
@ -60,5 +60,6 @@
|
|||||||
|
|
||||||
#define USE_BUNDLE_DIR "${USE_BUNDLE_DIR}"
|
#define USE_BUNDLE_DIR "${USE_BUNDLE_DIR}"
|
||||||
|
|
||||||
#endif // CONFIG_H_IN
|
#cmakedefine HAVE_TRANSLATIONS
|
||||||
|
|
||||||
|
#endif // CONFIG_H_IN
|
||||||
|
@ -232,9 +232,9 @@ void ContextView::NoSong() {
|
|||||||
"font-weight: Regular;"
|
"font-weight: Regular;"
|
||||||
);
|
);
|
||||||
|
|
||||||
ui_->label_stop_top->setText("No song playing");
|
ui_->label_stop_top->setText(tr("No song playing"));
|
||||||
|
|
||||||
QString html = QString(
|
QString html = tr(
|
||||||
"%1 songs<br />\n"
|
"%1 songs<br />\n"
|
||||||
"%2 artists<br />\n"
|
"%2 artists<br />\n"
|
||||||
"%3 albums<br />\n"
|
"%3 albums<br />\n"
|
||||||
@ -404,7 +404,7 @@ void ContextView::SetSong(const Song &song) {
|
|||||||
if (albumlist.count() > 1) {
|
if (albumlist.count() > 1) {
|
||||||
ui_->label_play_albums->setVisible(true);
|
ui_->label_play_albums->setVisible(true);
|
||||||
ui_->label_play_albums->setMinimumSize(0, 20);
|
ui_->label_play_albums->setMinimumSize(0, 20);
|
||||||
ui_->label_play_albums->setText(QString("<b>Albums by %1</b>").arg( song.artist().toHtmlEscaped()));
|
ui_->label_play_albums->setText(tr("<b>Albums by %1</b>").arg( song.artist().toHtmlEscaped()));
|
||||||
ui_->label_play_albums->setStyleSheet("background-color: #3DADE8; color: rgb(255, 255, 255); font: 11pt;");
|
ui_->label_play_albums->setStyleSheet("background-color: #3DADE8; color: rgb(255, 255, 255); font: 11pt;");
|
||||||
for (CollectionBackend::Album album : albumlist) {
|
for (CollectionBackend::Album album : albumlist) {
|
||||||
SongList songs = app_->collection_backend()->GetSongs(song.artist(), album.album_name, opt);
|
SongList songs = app_->collection_backend()->GetSongs(song.artist(), album.album_name, opt);
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
/* This file is part of Clementine.
|
/* This file is part of Strawberry.
|
||||||
Copyright 2015, David Sansome <me@davidsansome.com>
|
Copyright 2015, David Sansome <me@davidsansome.com>
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
Strawberry is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
Strawberry is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
/* This file is part of Clementine.
|
/* This file is part of Strawberry.
|
||||||
Copyright 2015, David Sansome <me@davidsansome.com>
|
Copyright 2015, David Sansome <me@davidsansome.com>
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
Strawberry is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
Strawberry is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CORE_THREAD_H_
|
#ifndef THREAD_H
|
||||||
#define CORE_THREAD_H_
|
#define THREAD_H
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@ -40,4 +40,4 @@ class Thread : public QThread {
|
|||||||
Utilities::IoPriority io_priority_;
|
Utilities::IoPriority io_priority_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CORE_THREAD_H_
|
#endif // THREAD_H
|
||||||
|
@ -58,6 +58,9 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QtEvents>
|
#include <QtEvents>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
# include <QTranslator>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
@ -96,6 +99,10 @@
|
|||||||
# include "scoped_cftyperef.h"
|
# include "scoped_cftyperef.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
# include "potranslator.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Utilities {
|
namespace Utilities {
|
||||||
|
|
||||||
static QString tr(const char *str) {
|
static QString tr(const char *str) {
|
||||||
@ -764,6 +771,29 @@ QString DesktopEnvironment() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
|
||||||
|
QString SystemLanguageName() {
|
||||||
|
|
||||||
|
QString system_language = QLocale::system().uiLanguages().empty() ? QLocale::system().name() : QLocale::system().uiLanguages().first();
|
||||||
|
// uiLanguages returns strings with "-" as separators for language/region; however QTranslator needs "_" separators
|
||||||
|
system_language.replace("-", "_");
|
||||||
|
|
||||||
|
return system_language;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadTranslation(const QString &prefix, const QString &path, const QString &language) {
|
||||||
|
|
||||||
|
QTranslator *t = new PoTranslator;
|
||||||
|
if (t->load(prefix + "_" + language, path))
|
||||||
|
QCoreApplication::installTranslator(t);
|
||||||
|
else
|
||||||
|
delete t;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace Utilities
|
} // namespace Utilities
|
||||||
|
|
||||||
ScopedWCharArray::ScopedWCharArray(const QString &str)
|
ScopedWCharArray::ScopedWCharArray(const QString &str)
|
||||||
|
@ -154,6 +154,11 @@ QString GetRandomString(const int len, const QString &UseCharacters);
|
|||||||
|
|
||||||
QString DesktopEnvironment();
|
QString DesktopEnvironment();
|
||||||
|
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
QString SystemLanguageName();
|
||||||
|
void LoadTranslation(const QString &prefix, const QString &path, const QString &language);
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class ScopedWCharArray {
|
class ScopedWCharArray {
|
||||||
|
@ -460,7 +460,7 @@ void DeezerService::ClearSearch() {
|
|||||||
|
|
||||||
void DeezerService::SendSearch() {
|
void DeezerService::SendSearch() {
|
||||||
|
|
||||||
emit UpdateStatus("Searching...");
|
emit UpdateStatus(tr("Searching..."));
|
||||||
|
|
||||||
QList<Param> parameters;
|
QList<Param> parameters;
|
||||||
parameters << Param("q", search_text_);
|
parameters << Param("q", search_text_);
|
||||||
@ -503,7 +503,7 @@ void DeezerService::SearchFinished(QNetworkReply *reply, int id) {
|
|||||||
|
|
||||||
QJsonArray json_data = json_value.toArray();
|
QJsonArray json_data = json_value.toArray();
|
||||||
if (json_data.isEmpty()) {
|
if (json_data.isEmpty()) {
|
||||||
Error("No match.");
|
Error(tr("No match."));
|
||||||
CheckFinish();
|
CheckFinish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -588,7 +588,8 @@ void DeezerService::SearchFinished(QNetworkReply *reply, int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (albums_requested_ > 0) {
|
if (albums_requested_ > 0) {
|
||||||
emit UpdateStatus(QString("Retrieving %1 album%2...").arg(albums_requested_).arg(albums_requested_ == 1 ? "" : "s"));
|
if (albums_requested_ == 1) emit UpdateStatus(tr("Retrieving %1 album...").arg(albums_requested_));
|
||||||
|
else emit UpdateStatus(tr("Retrieving %1 albums...").arg(albums_requested_));
|
||||||
emit ProgressSetMaximum(albums_requested_);
|
emit ProgressSetMaximum(albums_requested_);
|
||||||
emit UpdateProgress(0);
|
emit UpdateProgress(0);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
/* This file is part of Clementine.
|
/*
|
||||||
Copyright 2016, Valeriy Malov <jazzvoid@gmail.com>
|
* Strawberry Music Player
|
||||||
|
* This file was part of Clementine.
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
* Copyright 2016, Valeriy Malov <jazzvoid@gmail.com>
|
||||||
it under the terms of the GNU General Public License as published by
|
*
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
(at your option) any later version.
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
Clementine is distributed in the hope that it will be useful,
|
* (at your option) any later version.
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
*
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* Strawberry is distributed in the hope that it will be useful,
|
||||||
GNU General Public License for more details.
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
You should have received a copy of the GNU General Public License
|
* GNU General Public License for more details.
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
*
|
||||||
*/
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
/* This file is part of Clementine.
|
/*
|
||||||
Copyright 2016, Valeriy Malov <jazzvoid@gmail.com>
|
* Strawberry Music Player
|
||||||
|
* This file was part of Clementine.
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
* Copyright 2016, Valeriy Malov <jazzvoid@gmail.com>
|
||||||
it under the terms of the GNU General Public License as published by
|
*
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
* Strawberry is free software: you can redistribute it and/or modify
|
||||||
(at your option) any later version.
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
Clementine is distributed in the hope that it will be useful,
|
* (at your option) any later version.
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
*
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* Strawberry is distributed in the hope that it will be useful,
|
||||||
GNU General Public License for more details.
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
You should have received a copy of the GNU General Public License
|
* GNU General Public License for more details.
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
*
|
||||||
*/
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef UDISKS2LISTER_H
|
#ifndef UDISKS2LISTER_H
|
||||||
#define UDISKS2LISTER_H
|
#define UDISKS2LISTER_H
|
||||||
|
@ -75,7 +75,7 @@ About::About(QWidget *parent):QDialog(parent) {
|
|||||||
<< Person("Valeriy Malov", "jazzvoid@gmail.com")
|
<< Person("Valeriy Malov", "jazzvoid@gmail.com")
|
||||||
<< Person("Nick Lanham", "nick@afternight.org");
|
<< Person("Nick Lanham", "nick@afternight.org");
|
||||||
|
|
||||||
QString Title("About Strawberry");
|
QString Title(tr("About Strawberry"));
|
||||||
|
|
||||||
QFont title_font;
|
QFont title_font;
|
||||||
title_font.setBold(true);
|
title_font.setBold(true);
|
||||||
@ -99,28 +99,27 @@ QString About::MainHtml() const {
|
|||||||
|
|
||||||
QString ret;
|
QString ret;
|
||||||
|
|
||||||
ret = QString("<p>Version %1</p>").arg(QCoreApplication::applicationVersion());
|
ret = tr("<p>Version %1</p>").arg(QCoreApplication::applicationVersion());
|
||||||
|
|
||||||
ret += QString("<p>");
|
ret += "<p>";
|
||||||
ret += QString("Strawberry is a audio player and music collection organizer.<br />");
|
ret += tr("Strawberry is a audio player and music collection organizer.<br />");
|
||||||
ret += QString("It is a fork of Clementine released in 2018 aimed at music collectors, audio enthusiasts and audiophiles.<br />");
|
ret += tr("It is a fork of Clementine released in 2018 aimed at music collectors, audio enthusiasts and audiophiles.<br />");
|
||||||
ret += QString("The name is inspired by the band Strawbs. It's based on a heavily modified version of Clementine created in 2012-2013. It's written in C++ and Qt 5.");
|
ret += tr("The name is inspired by the band Strawbs. It's based on a heavily modified version of Clementine created in 2012-2013. It's written in C++ and Qt 5.");
|
||||||
ret += QString("</p>");
|
ret += "</p>";
|
||||||
//ret += QString("<p>Website: <a href=\"http://www.strawbs.org/licenses/\">http://www.strawbs.org/</a></p>");
|
ret += "<p>";
|
||||||
ret += QString("<p>");
|
ret += tr("Strawberry is free software: you can redistribute it and/or modify<br />");
|
||||||
ret += QString("Strawberry is free software: you can redistribute it and/or modify<br />");
|
ret += tr("it under the terms of the GNU General Public License as published by<br />");
|
||||||
ret += QString("it under the terms of the GNU General Public License as published by<br />");
|
ret += tr("the Free Software Foundation, either version 3 of the License, or<br />");
|
||||||
ret += QString("the Free Software Foundation, either version 3 of the License, or<br />");
|
ret += tr("(at your option) any later version.<br />");
|
||||||
ret += QString("(at your option) any later version.<br />");
|
ret += "<br />";
|
||||||
ret += QString("<br />");
|
ret += tr("Strawberry is distributed in the hope that it will be useful,<br />");
|
||||||
ret += QString("Strawberry is distributed in the hope that it will be useful,<br />");
|
ret += tr("but WITHOUT ANY WARRANTY; without even the implied warranty of<br />");
|
||||||
ret += QString("but WITHOUT ANY WARRANTY; without even the implied warranty of<br />");
|
ret += tr("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />");
|
||||||
ret += QString("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br />");
|
ret += tr("GNU General Public License for more details.<br />");
|
||||||
ret += QString("GNU General Public License for more details.<br />");
|
ret += "<br />";
|
||||||
ret += QString("<br />");
|
ret += tr("You should have received a copy of the GNU General Public License<br />");
|
||||||
ret += QString("You should have received a copy of the GNU General Public License<br />");
|
ret += tr("along with Strawberry. If not, see <a href=\"http://www.gnu.org/licenses/\">http://www.gnu.org/licenses/</a>.");
|
||||||
ret += QString("along with Strawberry. If not, see <a href=\"http://www.gnu.org/licenses/\">http://www.gnu.org/licenses/</a>.");
|
ret += "</p>";
|
||||||
ret += QString("</p>");
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -130,25 +129,25 @@ QString About::ContributorsHtml() const {
|
|||||||
|
|
||||||
QString ret;
|
QString ret;
|
||||||
|
|
||||||
ret += QString("<p><b>Strawberry Authors</b>");
|
ret += tr("<p><b>Strawberry Authors</b>");
|
||||||
for (const Person &person : strawberry_authors_) {
|
for (const Person &person : strawberry_authors_) {
|
||||||
ret += "<br />" + PersonToHtml(person);
|
ret += "<br />" + PersonToHtml(person);
|
||||||
}
|
}
|
||||||
ret += QString("</p>");
|
ret += "</p>";
|
||||||
|
|
||||||
ret += QString("<p><b>Clementine Authors</b>");
|
ret += tr("<p><b>Clementine Authors</b>");
|
||||||
for (const Person &person : clementine_authors_) {
|
for (const Person &person : clementine_authors_) {
|
||||||
ret += "<br />" + PersonToHtml(person);
|
ret += "<br />" + PersonToHtml(person);
|
||||||
}
|
}
|
||||||
ret += QString("</p>");
|
ret += "</p>";
|
||||||
|
|
||||||
ret += QString("<p><b>Clementine Contributors</b>");
|
ret += tr("<p><b>Clementine Contributors</b>");
|
||||||
for (const Person &person : constributors_) {
|
for (const Person &person : constributors_) {
|
||||||
ret += "<br />" + PersonToHtml(person);
|
ret += "<br />" + PersonToHtml(person);
|
||||||
}
|
}
|
||||||
ret += QString("</p>");
|
ret += "</p>";
|
||||||
|
|
||||||
ret += QString("<p>Thanks to all the Amarok and Clementine contributors.</p>");
|
ret += tr("<p>Thanks to all the Amarok and Clementine contributors.</p>");
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -899,7 +899,7 @@ void EditTagDialog::SongSaveComplete(TagReaderReply *reply, const QString filena
|
|||||||
pending_--;
|
pending_--;
|
||||||
|
|
||||||
if (!reply->message().save_file_response().success()) {
|
if (!reply->message().save_file_response().success()) {
|
||||||
QString message = QString("An error occurred writing metadata to '%1'").arg(filename);
|
QString message = tr("An error occurred writing metadata to '%1'").arg(filename);
|
||||||
emit Error(message);
|
emit Error(message);
|
||||||
}
|
}
|
||||||
else if (song.directory_id() != -1) {
|
else if (song.directory_id() != -1) {
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
* along with Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ InternetSearchView::InternetSearchView(Application *app, InternetSearch *engine,
|
|||||||
QMenu *settings_menu = new QMenu(this);
|
QMenu *settings_menu = new QMenu(this);
|
||||||
settings_menu->addActions(group_by_actions_->actions());
|
settings_menu->addActions(group_by_actions_->actions());
|
||||||
settings_menu->addSeparator();
|
settings_menu->addSeparator();
|
||||||
settings_menu->addAction(IconLoader::Load("configure"), QString("Configure %1...").arg(Song::TextForSource(engine->source())), this, SLOT(OpenSettingsDialog()));
|
settings_menu->addAction(IconLoader::Load("configure"), tr("Configure %1...").arg(Song::TextForSource(engine->source())), this, SLOT(OpenSettingsDialog()));
|
||||||
ui_->settings->setMenu(settings_menu);
|
ui_->settings->setMenu(settings_menu);
|
||||||
|
|
||||||
connect(ui_->radiobutton_search_artists, SIGNAL(clicked(bool)), SLOT(SearchArtistsClicked(bool)));
|
connect(ui_->radiobutton_search_artists, SIGNAL(clicked(bool)), SLOT(SearchArtistsClicked(bool)));
|
||||||
@ -430,7 +430,7 @@ bool InternetSearchView::ResultsContextMenuEvent(QContextMenuEvent *event) {
|
|||||||
context_menu_->addSeparator();
|
context_menu_->addSeparator();
|
||||||
context_menu_->addMenu(tr("Group by"))->addActions(group_by_actions_->actions());
|
context_menu_->addMenu(tr("Group by"))->addActions(group_by_actions_->actions());
|
||||||
|
|
||||||
context_menu_->addAction(IconLoader::Load("configure"), QString("Configure %1...").arg(Song::TextForSource(engine_->source())), this, SLOT(OpenSettingsDialog()));
|
context_menu_->addAction(IconLoader::Load("configure"), tr("Configure %1...").arg(Song::TextForSource(engine_->source())), this, SLOT(OpenSettingsDialog()));
|
||||||
|
|
||||||
const bool enable_context_actions = ui_->results->selectionModel() && ui_->results->selectionModel()->hasSelection();
|
const bool enable_context_actions = ui_->results->selectionModel() && ui_->results->selectionModel()->hasSelection();
|
||||||
|
|
||||||
|
29
src/main.cpp
29
src/main.cpp
@ -51,11 +51,13 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QLibraryInfo>
|
||||||
#include <QFileDevice>
|
#include <QFileDevice>
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QNetworkProxy>
|
#include <QNetworkProxy>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QDir>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
@ -64,6 +66,9 @@
|
|||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
# include <QDBusArgument>
|
# include <QDBusArgument>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
# include <QTranslator>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
@ -84,6 +89,10 @@
|
|||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/networkproxyfactory.h"
|
#include "core/networkproxyfactory.h"
|
||||||
#include "core/scangiomodulepath.h"
|
#include "core/scangiomodulepath.h"
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
# include "core/potranslator.h"
|
||||||
|
#endif
|
||||||
|
#include "settings/behavioursettingspage.h"
|
||||||
|
|
||||||
#include "widgets/osd.h"
|
#include "widgets/osd.h"
|
||||||
|
|
||||||
@ -206,11 +215,31 @@ int main(int argc, char* argv[]) {
|
|||||||
// Resources
|
// Resources
|
||||||
Q_INIT_RESOURCE(data);
|
Q_INIT_RESOURCE(data);
|
||||||
Q_INIT_RESOURCE(icons);
|
Q_INIT_RESOURCE(icons);
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
Q_INIT_RESOURCE(translations);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
|
QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
QString override_language = options.language();
|
||||||
|
if (override_language.isEmpty()) {
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(BehaviourSettingsPage::kSettingsGroup);
|
||||||
|
override_language = s.value("language").toString();
|
||||||
|
s.endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString language = override_language.isEmpty() ? Utilities::SystemLanguageName() : override_language;
|
||||||
|
|
||||||
|
Utilities::LoadTranslation("qt", QLibraryInfo::location(QLibraryInfo::TranslationsPath), language);
|
||||||
|
Utilities::LoadTranslation("strawberry", ":/translations", language);
|
||||||
|
Utilities::LoadTranslation("strawberry", a.applicationDirPath(), language);
|
||||||
|
Utilities::LoadTranslation("strawberry", QDir::currentPath(), language);
|
||||||
|
#endif
|
||||||
|
|
||||||
Application app;
|
Application app;
|
||||||
|
|
||||||
// Network proxy
|
// Network proxy
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+↑</string>
|
<string>Ctrl+Up</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -74,7 +74,7 @@
|
|||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="shortcut">
|
<property name="shortcut">
|
||||||
<string>Ctrl+↓</string>
|
<string>Ctrl+Down</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -141,7 +141,7 @@ void ListenBrainzScrobbler::Authenticate() {
|
|||||||
|
|
||||||
bool result = QDesktopServices::openUrl(url);
|
bool result = QDesktopServices::openUrl(url);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
QMessageBox messagebox(QMessageBox::Information, "ListenBrainz Authentication", QString("Please open this URL in your browser:<br /><a href=\"%1\">%1</a>").arg(url.toString()), QMessageBox::Ok);
|
QMessageBox messagebox(QMessageBox::Information, tr("ListenBrainz Authentication"), tr("Please open this URL in your browser:<br /><a href=\"%1\">%1</a>").arg(url.toString()), QMessageBox::Ok);
|
||||||
messagebox.setTextFormat(Qt::RichText);
|
messagebox.setTextFormat(Qt::RichText);
|
||||||
messagebox.exec();
|
messagebox.exec();
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ void ScrobblingAPI20::Authenticate() {
|
|||||||
url_query.addQueryItem("cb", redirect_url.toString());
|
url_query.addQueryItem("cb", redirect_url.toString());
|
||||||
url.setQuery(url_query);
|
url.setQuery(url_query);
|
||||||
|
|
||||||
QMessageBox messagebox(QMessageBox::Information, QString("%1 Scrobbler Authentication").arg(name_), QString("Open URL in web browser?<br /><a href=\"%1\">%1</a><br />Press \"Save\" to copy the URL to clipboard and manually open it in a web browser.").arg(url.toString()), QMessageBox::Open|QMessageBox::Save|QMessageBox::Cancel);
|
QMessageBox messagebox(QMessageBox::Information, tr("%1 Scrobbler Authentication").arg(name_), tr("Open URL in web browser?<br /><a href=\"%1\">%1</a><br />Press \"Save\" to copy the URL to clipboard and manually open it in a web browser.").arg(url.toString()), QMessageBox::Open|QMessageBox::Save|QMessageBox::Cancel);
|
||||||
messagebox.setTextFormat(Qt::RichText);
|
messagebox.setTextFormat(Qt::RichText);
|
||||||
int result = messagebox.exec();
|
int result = messagebox.exec();
|
||||||
switch (result) {
|
switch (result) {
|
||||||
@ -141,7 +141,7 @@ void ScrobblingAPI20::Authenticate() {
|
|||||||
if (openurl_result) {
|
if (openurl_result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
QMessageBox messagebox_error(QMessageBox::Warning, QString("%1 Scrobbler Authentication").arg(name_), QString("Could not open URL. Please open this URL in your browser:<br /><a href=\"%1\">%1</a>").arg(url.toString()), QMessageBox::Ok);
|
QMessageBox messagebox_error(QMessageBox::Warning, tr("%1 Scrobbler Authentication").arg(name_), tr("Could not open URL. Please open this URL in your browser:<br /><a href=\"%1\">%1</a>").arg(url.toString()), QMessageBox::Ok);
|
||||||
messagebox_error.setTextFormat(Qt::RichText);
|
messagebox_error.setTextFormat(Qt::RichText);
|
||||||
messagebox_error.exec();
|
messagebox_error.exec();
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ void ScrobblingAPI20::Authenticate() {
|
|||||||
QApplication::clipboard()->setText(url.toString());
|
QApplication::clipboard()->setText(url.toString());
|
||||||
break;
|
break;
|
||||||
case QMessageBox::Cancel:
|
case QMessageBox::Cancel:
|
||||||
AuthError("Authentication was cancelled.");
|
AuthError(tr("Authentication was cancelled."));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -436,7 +436,7 @@ void ScrobblingAPI20::Scrobble(const Song &song) {
|
|||||||
if (app_->scrobbler()->IsOffline()) return;
|
if (app_->scrobbler()->IsOffline()) return;
|
||||||
|
|
||||||
if (!IsAuthenticated()) {
|
if (!IsAuthenticated()) {
|
||||||
emit ErrorMessage(QString("Scrobbler %1 is not authenticated!").arg(name_));
|
emit ErrorMessage(tr("Scrobbler %1 is not authenticated!").arg(name_));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,10 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QLocale>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
@ -37,6 +41,14 @@ class SettingsDialog;
|
|||||||
|
|
||||||
const char *BehaviourSettingsPage::kSettingsGroup = "Behaviour";
|
const char *BehaviourSettingsPage::kSettingsGroup = "Behaviour";
|
||||||
|
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
namespace {
|
||||||
|
bool LocaleAwareCompare(const QString &a, const QString &b) {
|
||||||
|
return a.localeAwareCompare(b) < 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
#endif
|
||||||
|
|
||||||
BehaviourSettingsPage::BehaviourSettingsPage(SettingsDialog *dialog) : SettingsPage(dialog), ui_(new Ui_BehaviourSettingsPage) {
|
BehaviourSettingsPage::BehaviourSettingsPage(SettingsDialog *dialog) : SettingsPage(dialog), ui_(new Ui_BehaviourSettingsPage) {
|
||||||
|
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
@ -71,6 +83,43 @@ BehaviourSettingsPage::BehaviourSettingsPage(SettingsDialog *dialog) : SettingsP
|
|||||||
ui_->combobox_menuplaymode->setItemData(1, MainWindow::PlayBehaviour_IfStopped);
|
ui_->combobox_menuplaymode->setItemData(1, MainWindow::PlayBehaviour_IfStopped);
|
||||||
ui_->combobox_menuplaymode->setItemData(2, MainWindow::PlayBehaviour_Always);
|
ui_->combobox_menuplaymode->setItemData(2, MainWindow::PlayBehaviour_Always);
|
||||||
|
|
||||||
|
#ifdef HAVE_TRANSLATIONS
|
||||||
|
// Populate the language combo box. We do this by looking at all the compiled in translations.
|
||||||
|
QDir dir(":/translations/");
|
||||||
|
QStringList codes(dir.entryList(QStringList() << "*.qm"));
|
||||||
|
QRegExp lang_re("^strawberry_(.*).qm$");
|
||||||
|
for (const QString &filename : codes) {
|
||||||
|
|
||||||
|
// The regex captures the "ru" from "strawberry_ru.qm"
|
||||||
|
if (!lang_re.exactMatch(filename)) continue;
|
||||||
|
|
||||||
|
QString code = lang_re.cap(1);
|
||||||
|
QString lookup_code = QString(code)
|
||||||
|
.replace("@latin", "_Latn")
|
||||||
|
.replace("_CN", "_Hans_CN")
|
||||||
|
.replace("_TW", "_Hant_TW");
|
||||||
|
|
||||||
|
QString language_name = QLocale::languageToString(QLocale(lookup_code).language());
|
||||||
|
QString native_name = QLocale(lookup_code).nativeLanguageName();
|
||||||
|
if (!native_name.isEmpty()) {
|
||||||
|
language_name = native_name;
|
||||||
|
}
|
||||||
|
QString name = QString("%1 (%2)").arg(language_name, code);
|
||||||
|
|
||||||
|
language_map_[name] = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
language_map_["English (en)"] = "en";
|
||||||
|
|
||||||
|
// Sort the names and show them in the UI
|
||||||
|
QStringList names = language_map_.keys();
|
||||||
|
std::stable_sort(names.begin(), names.end(), LocaleAwareCompare);
|
||||||
|
ui_->combobox_language->addItems(names);
|
||||||
|
#else
|
||||||
|
ui_->groupbox_language->setEnabled(false);
|
||||||
|
ui_->groupbox_language->setVisible(false);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BehaviourSettingsPage::~BehaviourSettingsPage() {
|
BehaviourSettingsPage::~BehaviourSettingsPage() {
|
||||||
@ -114,6 +163,12 @@ void BehaviourSettingsPage::Load() {
|
|||||||
|
|
||||||
ui_->spinbox_seekstepsec->setValue(s.value("seek_step_sec", 10).toInt());
|
ui_->spinbox_seekstepsec->setValue(s.value("seek_step_sec", 10).toInt());
|
||||||
|
|
||||||
|
QString name = language_map_.key(s.value("language").toString());
|
||||||
|
if (name.isEmpty())
|
||||||
|
ui_->combobox_language->setCurrentIndex(0);
|
||||||
|
else
|
||||||
|
ui_->combobox_language->setCurrentIndex(ui_->combobox_language->findText(name));
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -141,6 +196,9 @@ void BehaviourSettingsPage::Save() {
|
|||||||
s.setValue("doubleclick_playmode", doubleclick_playmode);
|
s.setValue("doubleclick_playmode", doubleclick_playmode);
|
||||||
s.setValue("menu_playmode", menu_playmode);
|
s.setValue("menu_playmode", menu_playmode);
|
||||||
s.setValue("seek_step_sec", ui_->spinbox_seekstepsec->value());
|
s.setValue("seek_step_sec", ui_->spinbox_seekstepsec->value());
|
||||||
|
|
||||||
|
s.setValue("language", language_map_.contains(ui_->combobox_language->currentText()) ? language_map_[ui_->combobox_language->currentText()] : QString());
|
||||||
|
|
||||||
s.endGroup();
|
s.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QMap>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include "settingspage.h"
|
#include "settingspage.h"
|
||||||
@ -49,6 +50,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui_BehaviourSettingsPage *ui_;
|
Ui_BehaviourSettingsPage *ui_;
|
||||||
|
QMap<QString, QString> language_map_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,6 +101,38 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupbox_language">
|
||||||
|
<property name="title">
|
||||||
|
<string>Language</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="combobox_language">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use the system default</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_language">
|
||||||
|
<property name="text">
|
||||||
|
<string>You will need to restart Strawberry if you change the language.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_1">
|
<widget class="QGroupBox" name="groupBox_1">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -243,7 +275,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_3">
|
<widget class="Line" name="line_4">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -237,7 +237,7 @@ void GlobalShortcutsSettingsPage::OpenGnomeKeybindingProperties() {
|
|||||||
|
|
||||||
if (!QProcess::startDetached("gnome-keybinding-properties")) {
|
if (!QProcess::startDetached("gnome-keybinding-properties")) {
|
||||||
if (!QProcess::startDetached("gnome-control-center", QStringList() << "keyboard")) {
|
if (!QProcess::startDetached("gnome-control-center", QStringList() << "keyboard")) {
|
||||||
QMessageBox::warning(this, "Error", QString("The \"%1\" command could not be started.").arg("gnome-keybinding-properties"));
|
QMessageBox::warning(this, "Error", tr("The \"%1\" command could not be started.").arg("gnome-keybinding-properties"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ void TidalService::SendLogin() {
|
|||||||
|
|
||||||
void TidalService::SendLogin(const QString &username, const QString &password) {
|
void TidalService::SendLogin(const QString &username, const QString &password) {
|
||||||
|
|
||||||
if (search_id_ != 0) emit UpdateStatus("Authenticating...");
|
if (search_id_ != 0) emit UpdateStatus(tr("Authenticating..."));
|
||||||
|
|
||||||
login_sent_ = true;
|
login_sent_ = true;
|
||||||
login_attempts_++;
|
login_attempts_++;
|
||||||
@ -471,7 +471,7 @@ int TidalService::Search(const QString &text, InternetSearch::SearchType type) {
|
|||||||
void TidalService::StartSearch() {
|
void TidalService::StartSearch() {
|
||||||
|
|
||||||
if (username_.isEmpty() || password_.isEmpty()) {
|
if (username_.isEmpty() || password_.isEmpty()) {
|
||||||
emit SearchError(pending_search_id_, "Missing username and/or password.");
|
emit SearchError(pending_search_id_, tr("Missing username and/or password."));
|
||||||
next_pending_search_id_ = 1;
|
next_pending_search_id_ = 1;
|
||||||
ShowConfig();
|
ShowConfig();
|
||||||
return;
|
return;
|
||||||
@ -509,7 +509,7 @@ void TidalService::ClearSearch() {
|
|||||||
|
|
||||||
void TidalService::SendSearch() {
|
void TidalService::SendSearch() {
|
||||||
|
|
||||||
emit UpdateStatus("Searching...");
|
emit UpdateStatus(tr("Searching..."));
|
||||||
|
|
||||||
switch (pending_search_type_) {
|
switch (pending_search_type_) {
|
||||||
case InternetSearch::SearchType_Artists:
|
case InternetSearch::SearchType_Artists:
|
||||||
@ -582,7 +582,7 @@ void TidalService::ArtistsReceived(QNetworkReply *reply, int search_id) {
|
|||||||
QJsonArray json_items = json_value.toArray();
|
QJsonArray json_items = json_value.toArray();
|
||||||
if (json_items.isEmpty()) {
|
if (json_items.isEmpty()) {
|
||||||
artist_search_ = false;
|
artist_search_ = false;
|
||||||
Error("No match.");
|
Error(tr("No match."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,7 +610,8 @@ void TidalService::ArtistsReceived(QNetworkReply *reply, int search_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (artist_albums_requested_ > 0) {
|
if (artist_albums_requested_ > 0) {
|
||||||
emit UpdateStatus(QString("Retrieving albums for %1 artist%2...").arg(artist_albums_requested_).arg(artist_albums_requested_ == 1 ? "" : "s"));
|
if (artist_albums_requested_ == 1) emit UpdateStatus(tr("Retrieving albums for %1 artist...").arg(artist_albums_requested_));
|
||||||
|
else emit UpdateStatus(tr("Retrieving albums for %1 artists...").arg(artist_albums_requested_));
|
||||||
emit ProgressSetMaximum(artist_albums_requested_);
|
emit ProgressSetMaximum(artist_albums_requested_);
|
||||||
emit UpdateProgress(0);
|
emit UpdateProgress(0);
|
||||||
}
|
}
|
||||||
@ -802,7 +803,8 @@ void TidalService::AlbumsFinished(const int artist_id, const int offset_requeste
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (album_songs_requested_ > 0) {
|
if (album_songs_requested_ > 0) {
|
||||||
emit UpdateStatus(QString("Retrieving songs for %1 album%2...").arg(album_songs_requested_).arg(album_songs_requested_ == 1 ? "" : "s"));
|
if (album_songs_requested_ == 1) emit UpdateStatus(tr("Retrieving songs for %1 album...").arg(album_songs_requested_));
|
||||||
|
else emit UpdateStatus(tr("Retrieving songs for %1 albums...").arg(album_songs_requested_));
|
||||||
emit ProgressSetMaximum(album_songs_requested_);
|
emit ProgressSetMaximum(album_songs_requested_);
|
||||||
emit UpdateProgress(0);
|
emit UpdateProgress(0);
|
||||||
}
|
}
|
||||||
|
8
src/translations/header
Normal file
8
src/translations/header
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Strawberry Music Player
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user