Skip to content

Commit

Permalink
Unreliable internationalization on Windows (#3426)
Browse files Browse the repository at this point in the history
Savely derive the data and locale directory for all supported platforms

Co-authored-by: rolandlo <roland_loetscher@hotmail.com>
  • Loading branch information
LittleHuba and rolandlo committed Oct 25, 2021
1 parent 08923a3 commit f76a263
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 64 deletions.
1 change: 1 addition & 0 deletions src/Xournalpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "CrashHandler.h"
#include "Stacktrace.h"
#include "filesystem.h"

#ifdef _WIN32
#include "win32/console.h"
Expand Down
40 changes: 3 additions & 37 deletions src/control/XournalMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,7 @@ void initResourcePath(GladeSearchpath* gladePath, const gchar* relativePathAndFi

void initLocalisation() {
#ifdef ENABLE_NLS

#ifdef _WIN32
#undef PACKAGE_LOCALE_DIR
#define PACKAGE_LOCALE_DIR "../share/locale/"
#endif

#ifdef __APPLE__
#undef PACKAGE_LOCALE_DIR
fs::path p = Stacktrace::getExePath();
p /= "../Resources/share/locale/";
const char* PACKAGE_LOCALE_DIR = p.c_str();
#endif

fs::path localeDir = Util::getGettextFilepath(PACKAGE_LOCALE_DIR);
fs::path localeDir = Util::getGettextFilepath(Util::getLocalePath().u8string().c_str());
bindtextdomain(GETTEXT_PACKAGE, localeDir.u8string().c_str());
textdomain(GETTEXT_PACKAGE);

Expand Down Expand Up @@ -436,44 +423,23 @@ void initResourcePath(GladeSearchpath* gladePath, const gchar* relativePathAndFi

// -----------------------------------------------------------------------

#ifdef __APPLE__
fs::path p = Stacktrace::getExePath();
p /= "../Resources";
fs::path p = Util::getDataPath();
p /= relativePathAndFile;

if (fs::exists(p)) {
gladePath->addSearchDirectory(p.parent_path());
return;
}

std::string msg = FS(_F("Missing the needed UI file:\n{1}\n .app corrupted?\nPath: {2}") % relativePathAndFile %
p.u8string());

if (!failIfNotFound) {
msg += _("\nWill now attempt to run without this file.");
}
XojMsgBox::showErrorToUser(nullptr, msg);
#else
// Check at the target installation directory
fs::path absolute = PACKAGE_DATA_DIR;
absolute /= PROJECT_PACKAGE;
absolute /= relativePathAndFile;

if (fs::exists(absolute)) {
gladePath->addSearchDirectory(absolute.parent_path());
return;
}

std::string msg =
FS(_F("<span foreground='red' size='x-large'>Missing the needed UI file:\n<b>{1}</b></span>\nCould "
"not find them at any location.\n Not relative\n Not in the Working Path\n Not in {2}") %
relativePathAndFile % PACKAGE_DATA_DIR);
relativePathAndFile % Util::getDataPath().string());

if (!failIfNotFound) {
msg += _("\n\nWill now attempt to run without this file.");
}
XojMsgBox::showErrorToUser(nullptr, msg);
#endif

if (failIfNotFound) {
exit(12);
Expand Down
14 changes: 1 addition & 13 deletions src/gui/dialog/LanguageConfigGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,6 @@
#include "filesystem.h"
#include "i18n.h"

#ifdef _WIN32
#undef PACKAGE_LOCALE_DIR
#define PACKAGE_LOCALE_DIR "../share/locale/"
#endif

#ifdef __APPLE__
#include "Stacktrace.h"
#undef PACKAGE_LOCALE_DIR
fs::path p = Stacktrace::getExePath() / "../Resources/share/locale/";
const char* PACKAGE_LOCALE_DIR = p.c_str();
#endif

LanguageConfigGui::LanguageConfigGui(GladeSearchpath* gladeSearchPath, GtkWidget* w, Settings* settings):
GladeGui(gladeSearchPath, "settingsLanguageConfig.glade", "offscreenwindow"), settings(settings) {
auto dropdown = get("languageSettingsDropdown");
Expand All @@ -33,7 +21,7 @@ LanguageConfigGui::LanguageConfigGui(GladeSearchpath* gladeSearchPath, GtkWidget

// Fetch available locales
try {
fs::path baseLocaleDir = Util::getGettextFilepath(PACKAGE_LOCALE_DIR);
fs::path baseLocaleDir = Util::getGettextFilepath(Util::getLocalePath().u8string().c_str());
for (auto const& d: fs::directory_iterator(baseLocaleDir)) {
if (fs::exists(d.path() / "LC_MESSAGES" / (std::string(GETTEXT_PACKAGE) + ".mo"))) {
availableLocales.push_back(d.path().filename().u8string());
Expand Down
36 changes: 35 additions & 1 deletion src/util/PathUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
#include <array>
#include <fstream>

#include <config-paths.h>
#include <config.h>
#include <glib.h>
#include <stdlib.h>

#include "Stacktrace.h"
#include "StringUtils.h"
#include "Util.h"
#include "XojMsgBox.h"
Expand Down Expand Up @@ -184,7 +187,8 @@ auto Util::getGettextFilepath(const char* localeDir) -> fs::path {
}
}
const char* dir = (gettextEnv) ? directories.c_str() : localeDir;
g_message("TEXTDOMAINDIR = %s, PACKAGE_LOCALE_DIR = %s, chosen directory = %s", gettextEnv, localeDir, dir);
g_message("TEXTDOMAINDIR = %s, Platform-specific locale dir = %s, chosen directory = %s", gettextEnv, localeDir,
dir);
return fs::path(dir);
}

Expand Down Expand Up @@ -296,3 +300,33 @@ bool Util::safeRenameFile(fs::path const& from, fs::path const& to) {
}
return true;
}

auto Util::getDataPath() -> fs::path {
#ifdef _WIN32
TCHAR szFileName[MAX_PATH];
GetModuleFileName(nullptr, szFileName, MAX_PATH);
auto exePath = std::string(szFileName);
std::string::size_type pos = exePath.find_last_of("\\/");
fs::path p = exePath.substr(0, pos);
p = p / ".." / "share" / PROJECT_PACKAGE;
return p;
#elif defined(__APPLE__)
fs::path p = Stacktrace::getExePath();
p = p / ".." / "Resources";
return p;
#else
fs::path p = PACKAGE_DATA_DIR;
p /= PROJECT_PACKAGE;
return p;
#endif
}

auto Util::getLocalePath() -> fs::path {
#ifdef _WIN32
return getDataPath() / ".." / "locale";
#elif defined(__APPLE__)
return getDataPath() / "share" / "locale";
#else
return getDataPath() / ".." / "locale";
#endif
}
2 changes: 2 additions & 0 deletions src/util/PathUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,7 @@ fs::path getLongPath(const fs::path& path);
[[maybe_unused]] [[nodiscard]] fs::path getTmpDirSubfolder(const fs::path& subfolder = "");
[[maybe_unused]] [[nodiscard]] fs::path getAutosaveFilepath();
[[maybe_unused]] [[nodiscard]] fs::path getGettextFilepath(const char* localeDir);
[[maybe_unused]] [[nodiscard]] fs::path getDataPath();
[[maybe_unused]] [[nodiscard]] fs::path getLocalePath();

} // namespace Util
14 changes: 8 additions & 6 deletions src/xoj-preview-extractor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ endif ()
add_definitions (-DBUILD_THUMBNAILER)

add_executable (xournalpp-thumbnailer
xournalpp-thumbnailer.cpp
"${PROJECT_SOURCE_DIR}/src/util/GzUtil.cpp"
"${PROJECT_SOURCE_DIR}/src/util/PlaceholderString.cpp"
"${PROJECT_SOURCE_DIR}/src/util/StringUtils.cpp"
"${PROJECT_SOURCE_DIR}/src/util/XojPreviewExtractor.cpp"
)
xournalpp-thumbnailer.cpp
"${PROJECT_SOURCE_DIR}/src/util/GzUtil.cpp"
"${PROJECT_SOURCE_DIR}/src/util/PlaceholderString.cpp"
"${PROJECT_SOURCE_DIR}/src/util/StringUtils.cpp"
"${PROJECT_SOURCE_DIR}/src/util/PathUtil.cpp"
"${PROJECT_SOURCE_DIR}/src/util/Stacktrace.cpp"
"${PROJECT_SOURCE_DIR}/src/util/XojPreviewExtractor.cpp"
)

# MacOS workaround: "-framework ____" flags need to be passed as one string.
# See https://sourceforge.net/p/plplot/mailman/message/19574644/ for more details
Expand Down
7 changes: 3 additions & 4 deletions src/xoj-preview-extractor/xournalpp-thumbnailer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <config-paths.h>
#include <config.h>

#include "PathUtil.h"
#include "XojPreviewExtractor.h"
#include "i18n.h"
using std::cerr;
Expand All @@ -33,7 +34,7 @@ using std::string;

void initLocalisation() {
#ifdef ENABLE_NLS
bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
bindtextdomain(GETTEXT_PACKAGE, Util::getLocalePath().u8string().c_str());
textdomain(GETTEXT_PACKAGE);
#endif // ENABLE_NLS

Expand Down Expand Up @@ -156,9 +157,7 @@ int main(int argc, char* argv[]) {
return CAIRO_STATUS_READ_ERROR;
}

for (auto i = 0; i < length; i++) {
data[i] = closure->data[closure->pos + i];
}
for (auto i = 0; i < length; i++) { data[i] = closure->data[closure->pos + i]; }
closure->pos += length;
return CAIRO_STATUS_SUCCESS;
};
Expand Down
3 changes: 3 additions & 0 deletions windows-setup/package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ echo "copy gspawn-win64-helper"
cp /mingw64/bin/gspawn-win64-helper.exe "$setup_dir"/bin
cp /mingw64/bin/gspawn-win64-helper-console.exe "$setup_dir"/bin

echo "copy gdbus"
cp /mingw64/bin/gdbus.exe "$setup_dir"/bin

echo "create installer"
bash make_version_nsh.sh
"/c/Program Files (x86)/NSIS/Bin/makensis.exe" xournalpp.nsi
Expand Down
4 changes: 1 addition & 3 deletions windows-setup/xournalpp.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,9 @@ Section "Xournal++" SecXournalpp
WriteRegDWORD SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\Xournal++" "NoRepair" 1

!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
;Create shortcuts and set working directory for Xournal++ to the bin subfolder to make localizations work
;Create shortcuts
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
SetOutPath "$INSTDIR\bin"
CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Xournal++.lnk" '"$INSTDIR\bin\xournalpp.exe"'
SetOutPath "$INSTDIR"
CreateShortcut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" '"$INSTDIR\Uninstall.exe"'

!insertmacro RefreshShellIconCreate "$SMPROGRAMS\$StartMenuFolder\Xournal++.lnk"
Expand Down

0 comments on commit f76a263

Please sign in to comment.