v1.2.38 Fix for locale issues on non-en-US locales.

This commit is contained in:
Robin Davies
2024-08-19 00:27:28 -04:00
parent 6358682eb1
commit fa3d8815cd
16 changed files with 194 additions and 64 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
cmake_minimum_required(VERSION 3.16.0)
project(pipedal
VERSION 1.2.37
VERSION 1.2.38
DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi"
HOMEPAGE_URL "https://rerdavies.github.io/pipedal"
)
set (DISPLAY_VERSION "v1.2.37beta4")
set (DISPLAY_VERSION "v1.2.38beta5")
set (CMAKE_INSTALL_PREFIX "/usr/")
+2 -2
View File
@@ -6,11 +6,11 @@
<a href="https://rerdavies.github.io/pipedal/LicensePiPedal.html"><img src="https://img.shields.io/badge/MIT-MIT?label=license&color=%23808080"/></a>
<a href="https://github.com/rerdavies/pipedal/actions"><img src="https://img.shields.io/github/actions/workflow/status/rerdavies/pipedal/cmake.yml?branch=main"/></a>
Download:&nbsp;<a href='https://rerdavies.github.io/pipedal/download.html'>v1.2.37 Beta4</a>&nbsp;&nbsp;&nbsp;&nbsp; Website:&nbsp;[https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
Download:&nbsp;<a href='https://rerdavies.github.io/pipedal/download.html'>v1.2.38 Beta5</a>&nbsp;&nbsp;&nbsp;&nbsp; Website:&nbsp;[https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
&nbsp;
#### NEW version 1.2.37 Beta4 release, providing support for Raspberry Pi OS Bookworm. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
#### NEW version 1.2.38 Beta5 release, providing support for Raspberry Pi OS Bookworm. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
&nbsp;
+1 -1
View File
@@ -26,7 +26,7 @@ Run the following commands to install dependent libraries required by the PiPeda
sudo apt install -y libasound2-dev jackd2 uuid-dev libxrandr-dev
sudo apt install -y authbind
sudo apt install -y libavahi-client-dev
sudo apt install -y libnm-dev
sudo apt install -y libnm-dev libicu-dev
sudo apt install -y libsdbus-c++-dev libzip-dev
+3 -3
View File
@@ -13,17 +13,17 @@ page_icon: img/Install4.jpg
Download the most recent Debian (.deb) package for your platform:
- [Raspberry Pi OS bookworm (64-bit) v1.2.37 Beta4](https://github.com/rerdavies/pipedal/releases/download/)
- [Raspberry Pi OS bookworm (64-bit) v1.2.38 Beta5](https://github.com/rerdavies/pipedal/releases/download/)
- [Ubuntu/Raspberry Pi OS bullseyeye (64-bit) v1.2.31](https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb)
Version 1.2.37 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31.
Version 1.2.38 has not yet been tested on Ubuntu or Raspberry Pi OS bullseye. On these platforms, we recommend that you use version 1.1.31.
Install the package by running
```
sudo apt update
cd ~/Downloads
sudo apt-get install pipedal_1.2.37_arm64.deb
sudo apt-get install pipedal_1.2.38_arm64.deb
```
Adjust accordingly if you have downloaded v1.1.31.
+5
View File
@@ -1,4 +1,9 @@
# Release Notes
## Pipedal 1.2.38 Beta5
Fixes:
- PiPedal won't run on non-en-US locales.
## Pipedal 1.2.37 Beta4
You can now upload GuitarML Proteus models from the GuitarML project into TooB ML.
+3 -3
View File
@@ -4,17 +4,17 @@
Download the most recent Debian (.deb) package for your platform:
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.2.37/pipedal_1.2.37_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.2.37 Beta4</a>
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.2.38/pipedal_1.2.38_arm64.deb">Raspberry Pi OS Bookworm (64-bit) v1.2.38 Beta5</a>
- <a href="https://github.com/rerdavies/pipedal/releases/download/v1.1.31/pipedal_1.1.31_arm64.deb">Ubuntu 21.04 or Raspberry Pi OS bullseyeyeye (64-bit) v1.1.31</a>
v1.2.37 Beta4 is does not currently support Ubuntu 21.04, or older versions of Raspberry Pi OS.
v1.2.38 Beta5 is does not currently support Ubuntu 21.04, or older versions of Raspberry Pi OS.
Install the package by running
```
sudo apt update
cd ~/Downloads
sudo apt-get install ./pipedal_1.2.37_arm64.deb
sudo apt-get install ./pipedal_1.2.38_arm64.deb
```
Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation.
+2 -2
View File
@@ -1,13 +1,13 @@
<img src="GithubBanner.png" width="100%"/>
<a href="Installing.html"><i>v1.2.37</i></a>
<a href="Installing.html"><i>v1.2.38</i></a>
&nbsp;
To download PiPedal, click [here](download.md).
> NEW version 1.2.37 Beta4 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
> NEW version 1.2.38 Beta5 release. See the [release notes](https://rerdavies.github.io/pipedal/ReleaseNotes) for details.
Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet.
+4 -1
View File
@@ -133,6 +133,7 @@ endif()
set (PIPEDAL_SOURCES
WebServerConfig.cpp WebServerConfig.hpp
Locale.hpp Locale.cpp
Finally.hpp
ZipFile.cpp ZipFile.hpp
TemporaryFile.cpp TemporaryFile.hpp
@@ -204,7 +205,6 @@ set (PIPEDAL_SOURCES
AdminClient.hpp AdminClient.cpp
MidiBinding.hpp MidiBinding.cpp
PiPedalMath.hpp
Locale.hpp Locale.cpp
Lv2EventBufferWriter.hpp Lv2EventBufferWriter.cpp
IpSubnet.hpp
PiPedalAlsa.hpp PiPedalAlsa.cpp
@@ -235,6 +235,9 @@ set (PIPEDAL_INCLUDES
)
set(PIPEDAL_LIBS libpipedald zip
icui18n
icuuc
icudata
pthread atomic stdc++fs asound avahi-common avahi-client systemd
${VST3_LIBRARIES}
${LILV_0_LIBRARIES}
-1
View File
@@ -607,7 +607,6 @@ void SetVarPermissions(
if (fs::is_directory(path)) {
fs::permissions(path, directoryPermissions, fs::perm_options::replace);
for (const auto& entry : fs::recursive_directory_iterator(path)) {
cout << " " << entry.path() << endl;
if (chown(entry.path().c_str(),uid,gid) != 0)
{
+117 -26
View File
@@ -23,43 +23,134 @@
#include <stdlib.h>
#include "Lv2Log.hpp"
#include <unicode/utypes.h>
#include <unicode/ucol.h>
#include <unicode/unistr.h>
#include <unicode/sortkey.h>
#include <stdexcept>
#include "ss.hpp"
#include <mutex>
// Must be UNICODE. Should reflect system locale. (.e.g en-US.UTF8, de-de.UTF8)
// This is correct for libstdc++; most probably not correct for Windows or CLANG. :-(
using namespace pipedal;
static const char*getLocale(const char*localeEnvironmentVariable)
std::string getCurrentLocale() {
std::string locale = setlocale(LC_ALL, nullptr);
if (locale.empty() || locale == "C") {
// If setlocale fails, try getting it from environment variables
const char* lang = getenv("LC_ALL");
if (lang) {
locale = lang;
} else {
// If LANG is not set, fall back to a default
lang = getenv("LC_COLLATE");
if (lang)
{
locale = lang;
} else{
lang = getenv("LANG");
if (lang) {
locale = lang;
} else {
locale = "en_US";
}
}
}
}
// Extract just the language and country code
size_t dot_pos = locale.find('.');
if (dot_pos != std::string::npos) {
locale = locale.substr(0, dot_pos);
}
return locale;
}
Collator::~Collator() {
}
class LocaleImpl;
class CollatorImpl : public Collator {
public:
CollatorImpl(std::shared_ptr<LocaleImpl> LocaleImpl,icu::Locale &locale);
~CollatorImpl();
virtual int Compare(const std::string &left, const std::string&right);
private:
icu::Collator* collator = nullptr;
std::shared_ptr<LocaleImpl> localeImpl;
};
CollatorImpl::~CollatorImpl()
{
const char*result = getenv(localeEnvironmentVariable);
if (result == nullptr)
{
result = getenv("LC_ALL");
}
delete collator;
localeImpl = nullptr;
}
CollatorImpl::CollatorImpl(std::shared_ptr<LocaleImpl> localeImpl, icu::Locale &locale)
:localeImpl(localeImpl)
{
UErrorCode status = U_ZERO_ERROR;
if (result == nullptr) {
result = "en_US.UTF-8";
this->collator = icu::Collator::createInstance(locale, status);
if (U_FAILURE(status)) {
throw std::runtime_error(SS("Failed to create collator: " << u_errorName(status)));
}
std::stringstream s;
s << "Locale: " << result;
Lv2Log::error(s.str());
return result;
}
int CollatorImpl::Compare(const std::string &left, const std::string&right) {
return collator->compare(left.c_str(),right.c_str());
}
Locale::ptr g_instance;
class LocaleImpl: public Locale, public std::enable_shared_from_this<LocaleImpl> {
public:
LocaleImpl();
virtual const std::string &CurrentLocale() const ;
virtual Collator::ptr GetCollator();
private:
std::unique_ptr<icu::Locale> locale;
std::string currentLocale;
};
LocaleImpl::LocaleImpl()
{
currentLocale = getCurrentLocale();
locale = std::make_unique<icu::Locale>(currentLocale.c_str());
}
const std::string &LocaleImpl::CurrentLocale() const
{
return currentLocale;
}
void Locale::setDefaultLocale() {
const char* locale = getLocale("LC_ALL");
try {
setlocale(LC_ALL,locale);
} catch (const std::exception&)
{
std::stringstream s;
s << "Failed to set default locale (" << locale << "). Defaulting to en_US.";
Lv2Log::error(s.str());
std::setlocale(LC_ALL,"en_US.UTF-8");
}
Collator::ptr LocaleImpl::GetCollator(){
auto pThis = shared_from_this();
return std::shared_ptr<Collator>(new CollatorImpl(pThis,*locale));
}
const std::collate<char>& Locale::collation() { return std::use_facet<std::collate<char> >(std::locale()); }
static std::mutex createMutex;
Locale::~Locale()
{
}
Locale::ptr Locale::g_instance;
Locale::ptr Locale::GetInstance()
{
std::lock_guard lock { createMutex};
if (g_instance)
{
return g_instance;
}
g_instance = std::make_shared<LocaleImpl>();
return g_instance;
}
+25 -5
View File
@@ -19,14 +19,34 @@
#pragma once
#include <locale>
#include <memory>
#include <string>
namespace pipedal {
class Locale {
class Collator {
public:
static void setDefaultLocale();
using ptr = std::shared_ptr<Collator>;
virtual int Compare(const std::string &left, const std::string&right) = 0;
virtual ~Collator();
};
class Locale {
protected:
Locale() { }
public:
virtual ~Locale();
// no copy, no move
Locale(const Locale&) = delete;
Locale(Locale&&) = delete;
Locale&operator =(const Locale&) = delete;
Locale&operator =(Locale&&) = delete;
using ptr = std::shared_ptr<Locale>;
static const std::collate<char>& collation();
static ptr GetInstance();
virtual const std::string &CurrentLocale() const = 0;
virtual Collator::ptr GetCollator() = 0;
private:
static ptr g_instance;
};
}
+6 -6
View File
@@ -21,7 +21,7 @@
#include "PluginHost.hpp"
#include <lilv/lilv.h>
#include <stdexcept>
#include <locale>
#include "Locale.hpp"
#include <string_view>
#include "Lv2Log.hpp"
#include <functional>
@@ -461,16 +461,16 @@ void PluginHost::Load(const char *lv2Path)
Lv2Log::info("lilv: " + s);
}
const auto &collation = std::use_facet<std::collate<char>>(std::locale());
auto compare = [&collation](
auto collator = Locale::GetInstance()->GetCollator();
auto compare = [&collator](
const std::shared_ptr<Lv2PluginInfo> &left,
const std::shared_ptr<Lv2PluginInfo> &right)
{
const char *pb1 = left->name().c_str();
const char *pb2 = right->name().c_str();
return collation.compare(
pb1, pb1 + left->name().size(),
pb2, pb2 + right->name().size()) < 0;
return collator->Compare(
left->name(),right->name())
< 0;
};
std::sort(this->plugins_.begin(), this->plugins_.end(), compare);
+11 -7
View File
@@ -18,6 +18,7 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "pch.h"
#include "Locale.hpp"
#include "Storage.hpp"
#include "AudioConfig.hpp"
#include "PiPedalException.hpp"
@@ -40,7 +41,6 @@ const char *BANKS_FILENAME = "index.banks";
#define USER_SETTINGS_FILENAME "userSettings.json";
Storage::Storage()
: locale("en_US.UTF-8")
{
SetConfigRoot("~/var/Config");
SetDataRoot("~/var/PiPedal");
@@ -1525,9 +1525,10 @@ std::vector<std::string> Storage::GetFileList(const UiFileProperty &fileProperty
}
// sort lexicographically
auto collator = Locale::GetInstance()->GetCollator();
std::sort(result.begin(), result.end(), [this](const std::string&left,const std::string&right) {
return this->locale(left,right) < 0;
std::sort(result.begin(), result.end(), [&collator](const std::string&left,const std::string&right) {
return collator->Compare(left,right) < 0;
});
return result;
}
@@ -1606,12 +1607,14 @@ std::vector<FileEntry> Storage::GetFileList2(const std::string &relativePath,con
// sort lexicographically
std::sort(result.begin(), result.end(),[this](const FileEntry&l, const FileEntry&r) {
auto collator = Locale::GetInstance()->GetCollator();
std::sort(result.begin(), result.end(),[&collator](const FileEntry&l, const FileEntry&r) {
if (l.isDirectory_ != r.isDirectory_)
{
return l.isDirectory_ > r.isDirectory_;
}
return this->locale(l.filename_,r.filename_);
return collator->Compare(l.filename_,r.filename_) < 0;
});
return result;
@@ -1813,10 +1816,11 @@ void Storage::FillSampleDirectoryTree(FilePropertyDirectoryTree*node, const std:
node->children_.push_back(std::move(childTree));
}
}
auto collator = Locale::GetInstance()->GetCollator();
std::sort(node->children_.begin(),node->children_.end(),
[this](const FilePropertyDirectoryTree::ptr&left,const FilePropertyDirectoryTree::ptr&right)
[&collator](const FilePropertyDirectoryTree::ptr&left,const FilePropertyDirectoryTree::ptr&right)
{
return this->locale(left->directoryName_,right->directoryName_);
return collator->Compare(left->directoryName_,right->directoryName_) < 0;
});
}
FilePropertyDirectoryTree::ptr Storage::GetFilePropertydirectoryTree(const UiFileProperty&uiFileProperty) const
-2
View File
@@ -30,7 +30,6 @@
#include "WifiDirectConfigSettings.hpp"
#include "FileEntry.hpp"
#include <map>
#include <locale>
#include "FilePropertyDirectoryTree.hpp"
@@ -67,7 +66,6 @@ struct PluginPresetValues {
class Storage {
private:
std::locale locale;
std::filesystem::path dataRoot;
std::filesystem::path configRoot;
BankIndex bankIndex;
+12 -1
View File
@@ -19,7 +19,7 @@
#include "pch.h"
#include "util.hpp"
#include "Locale.hpp"
#include "AudioConfig.hpp"
#include "WebServer.hpp"
#include <iostream>
@@ -230,6 +230,17 @@ int main(int argc, char *argv[])
try
{
{
auto locale = Locale::GetInstance();
Lv2Log::info(SS("Locale: " << locale->CurrentLocale()));
try {
auto collator = locale->GetCollator();
} catch (std::exception&e)
{
Lv2Log::error(e.what());
return EXIT_SUCCESS; //tell systemd not to auto-restart.
}
}
PiPedalModel model;
model.Init(configuration);
+1 -2
View File
@@ -1,4 +1,4 @@
- Zip file upload in a subdirectory.
- Bug: text Cursor hovering over the breadcrumb bar in file property dialog.
- Turning off wifi-direct sould re-enable NetworkManager.
- ToobML save/restore state.
@@ -16,6 +16,5 @@
Pri Description
-----------------
9 Upload proteus patches.
8 Migrate to Vite toolchain.
5 Re-use plugin instances when rebuilding pedalboard.