fix utf8 problems on windows, loading files with special characters

master
Fabian Keßler 6 years ago committed by Fabian Keßler
parent 1e314821c0
commit 0779ff480c
  1. 12
      src/control/Control.cpp
  2. 3
      src/control/XournalMain.cpp
  3. 14
      src/control/jobs/BaseExportJob.cpp
  4. 5
      src/control/stockdlg/ImageOpenDlg.cpp
  5. 8
      src/control/stockdlg/XojOpenDlg.cpp
  6. 5
      src/gui/dialog/LatexSettingsPanel.cpp
  7. 5
      src/gui/dialog/PageTemplateDialog.cpp
  8. 2
      src/gui/dialog/SettingsDialog.cpp
  9. 31
      src/util/PathUtil.h

@ -2304,10 +2304,10 @@ auto Control::showSaveDialog() -> bool {
auto suggested_name = this->doc->createSaveFilename(Document::XOPP, this->settings->getDefaultSaveName()); auto suggested_name = this->doc->createSaveFilename(Document::XOPP, this->settings->getDefaultSaveName());
this->doc->unlock(); this->doc->unlock();
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), suggested_folder.string().c_str()); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), Util::toGFilename(suggested_folder).c_str());
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), suggested_name.string().c_str()); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), Util::toGFilename(suggested_name).c_str());
gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), this->settings->getLastOpenPath().string().c_str(), gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog),
nullptr); Util::toGFilename(this->settings->getLastOpenPath()).c_str(), nullptr);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), false); // handled below gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), false); // handled below
@ -2319,7 +2319,7 @@ auto Control::showSaveDialog() -> bool {
return false; return false;
} }
auto fileTmp = Util::fromGtkFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); auto fileTmp = Util::fromGFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
Util::clearExtensions(fileTmp); Util::clearExtensions(fileTmp);
fileTmp += ".xopp"; fileTmp += ".xopp";
// Since we add the extension after the OK button, we have to check manually on existing files // Since we add the extension after the OK button, we have to check manually on existing files
@ -2328,7 +2328,7 @@ auto Control::showSaveDialog() -> bool {
} }
} }
auto filename = Util::fromGtkFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); auto filename = Util::fromGFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
settings->setLastSavePath(filename.parent_path()); settings->setLastSavePath(filename.parent_path());
gtk_widget_destroy(dialog); gtk_widget_destroy(dialog);

@ -379,7 +379,7 @@ auto XournalMain::run(int argc, char* argv[]) -> int {
XojMsgBox::showErrorToUser(static_cast<GtkWindow*>(*win), msg); XojMsgBox::showErrorToUser(static_cast<GtkWindow*>(*win), msg);
} }
fs::path p(optFilename[0]); fs::path p = Util::fromGFilename(optFilename[0]);
try { try {
if (fs::exists(p)) { if (fs::exists(p)) {
@ -392,6 +392,7 @@ auto XournalMain::run(int argc, char* argv[]) -> int {
"You have to copy the file to a local directory.") % "You have to copy the file to a local directory.") %
p.u8string().c_str() % e.what()); p.u8string().c_str() % e.what());
XojMsgBox::showErrorToUser(static_cast<GtkWindow*>(*win), msg); XojMsgBox::showErrorToUser(static_cast<GtkWindow*>(*win), msg);
opened = control->newFile("", optFilename[0]);
} }
} }

@ -57,8 +57,9 @@ auto BaseExportJob::showFilechooser() -> bool {
fs::path name = doc->createSaveFilename(Document::PDF, settings->getDefaultSaveName()); fs::path name = doc->createSaveFilename(Document::PDF, settings->getDefaultSaveName());
doc->unlock(); doc->unlock();
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), folder.string().c_str()); gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), true);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name.string().c_str()); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), Util::toGFilename(folder).c_str());
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), Util::toGFilename(name).c_str());
gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->control->getWindow()->getWindow())); gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(this->control->getWindow()->getWindow()));
@ -67,15 +68,10 @@ auto BaseExportJob::showFilechooser() -> bool {
gtk_widget_destroy(dialog); gtk_widget_destroy(dialog);
return false; return false;
} }
auto uri = [](char* uri) { this->filepath = Util::fromGFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
std::string ret{uri};
g_free(uri);
return ret;
}(gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog)));
this->filepath = Util::fromGtkFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
Util::clearExtensions(this->filepath); Util::clearExtensions(this->filepath);
// Since we add the extension after the OK button, we have to check manually on existing files // Since we add the extension after the OK button, we have to check manually on existing files
if (isUriValid(uri) && control->askToReplace(filepath)) { if (control->askToReplace(filepath)) {
break; break;
} }
} }

@ -20,7 +20,8 @@ auto ImageOpenDlg::show(GtkWindow* win, Settings* settings, bool localOnly, bool
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filterSupported); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filterSupported);
if (!settings->getLastImagePath().empty()) { if (!settings->getLastImagePath().empty()) {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), settings->getLastImagePath().string().c_str()); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
Util::toGFilename(settings->getLastImagePath()).c_str());
} }
GtkWidget* cbAttach = nullptr; GtkWidget* cbAttach = nullptr;
@ -47,7 +48,7 @@ auto ImageOpenDlg::show(GtkWindow* win, Settings* settings, bool localOnly, bool
// e.g. from last used files, there is no folder selected // e.g. from last used files, there is no folder selected
// in this case do not store the folder // in this case do not store the folder
if (auto folder = Util::fromGtkFilename(gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog))); if (auto folder = Util::fromGFilename(gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog)));
!folder.empty()) { !folder.empty()) {
settings->setLastImagePath(folder); settings->setLastImagePath(folder);
} }

@ -21,7 +21,7 @@ XojOpenDlg::XojOpenDlg(GtkWindow* win, Settings* settings): win(win), settings(s
g_warning("lastOpenPath is not set!"); g_warning("lastOpenPath is not set!");
currentFolder = g_get_home_dir(); currentFolder = g_get_home_dir();
} }
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), currentFolder.string().c_str()); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), Util::toGFilename(currentFolder).c_str());
} }
XojOpenDlg::~XojOpenDlg() { XojOpenDlg::~XojOpenDlg() {
@ -75,7 +75,7 @@ auto XojOpenDlg::runDialog() -> fs::path {
return fs::path{}; return fs::path{};
} }
auto file = Util::fromGtkFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); auto file = Util::fromGFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
settings->setLastOpenPath(file.parent_path()); settings->setLastOpenPath(file.parent_path());
return file; return file;
} }
@ -121,7 +121,7 @@ auto XojOpenDlg::showOpenDialog(bool pdf, bool& attachPdf) -> fs::path {
auto lastOpenPath = this->settings->getLastOpenPath(); auto lastOpenPath = this->settings->getLastOpenPath();
if (!lastOpenPath.empty()) { if (!lastOpenPath.empty()) {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(this->dialog), lastOpenPath.string().c_str()); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(this->dialog), Util::toGFilename(lastOpenPath).c_str());
} }
auto lastSavePath = this->settings->getLastSavePath(); auto lastSavePath = this->settings->getLastSavePath();
@ -145,7 +145,7 @@ auto XojOpenDlg::showOpenDialog(bool pdf, bool& attachPdf) -> fs::path {
} }
void XojOpenDlg::updatePreviewCallback(GtkFileChooser* fileChooser, void* userData) { void XojOpenDlg::updatePreviewCallback(GtkFileChooser* fileChooser, void* userData) {
auto filepath = Util::fromGtkFilename(gtk_file_chooser_get_preview_filename(fileChooser)); auto filepath = Util::fromGFilename(gtk_file_chooser_get_preview_filename(fileChooser));
if (filepath.empty()) { if (filepath.empty()) {
gtk_file_chooser_set_preview_widget_active(fileChooser, false); gtk_file_chooser_set_preview_widget_active(fileChooser, false);

@ -27,14 +27,15 @@ LatexSettingsPanel::~LatexSettingsPanel() {
void LatexSettingsPanel::load(const LatexSettings& settings) { void LatexSettingsPanel::load(const LatexSettings& settings) {
gtk_toggle_button_set_active(this->cbAutoDepCheck, settings.autoCheckDependencies); gtk_toggle_button_set_active(this->cbAutoDepCheck, settings.autoCheckDependencies);
if (!settings.globalTemplatePath.empty()) { if (!settings.globalTemplatePath.empty()) {
gtk_file_chooser_set_filename(this->globalTemplateChooser, settings.globalTemplatePath.string().c_str()); gtk_file_chooser_set_filename(this->globalTemplateChooser,
Util::toGFilename(settings.globalTemplatePath).c_str());
} }
gtk_entry_set_text(GTK_ENTRY(this->get("latexSettingsGenCmd")), settings.genCmd.c_str()); gtk_entry_set_text(GTK_ENTRY(this->get("latexSettingsGenCmd")), settings.genCmd.c_str());
} }
void LatexSettingsPanel::save(LatexSettings& settings) { void LatexSettingsPanel::save(LatexSettings& settings) {
settings.autoCheckDependencies = gtk_toggle_button_get_active(this->cbAutoDepCheck); settings.autoCheckDependencies = gtk_toggle_button_get_active(this->cbAutoDepCheck);
settings.globalTemplatePath = Util::fromGtkFilename(gtk_file_chooser_get_filename(this->globalTemplateChooser)); settings.globalTemplatePath = Util::fromGFilename(gtk_file_chooser_get_filename(this->globalTemplateChooser));
settings.genCmd = gtk_entry_get_text(GTK_ENTRY(this->get("latexSettingsGenCmd"))); settings.genCmd = gtk_entry_get_text(GTK_ENTRY(this->get("latexSettingsGenCmd")));
} }

@ -90,7 +90,8 @@ void PageTemplateDialog::saveToFile() {
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filterXoj); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filterXoj);
if (!settings->getLastSavePath().empty()) { if (!settings->getLastSavePath().empty()) {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), settings->getLastSavePath().string().c_str()); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
Util::toGFilename(settings->getLastSavePath()).c_str());
} }
time_t curtime = time(nullptr); time_t curtime = time(nullptr);
@ -107,7 +108,7 @@ void PageTemplateDialog::saveToFile() {
return; return;
} }
auto filepath = Util::fromGtkFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); auto filepath = Util::fromGFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
settings->setLastSavePath(filepath.parent_path()); settings->setLastSavePath(filepath.parent_path());
gtk_widget_destroy(dialog); gtk_widget_destroy(dialog);

@ -569,7 +569,7 @@ void SettingsDialog::save() {
settings->setMenubarVisible(getCheckbox("cbHideMenubarStartup")); settings->setMenubarVisible(getCheckbox("cbHideMenubarStartup"));
settings->setDefaultSaveName(gtk_entry_get_text(GTK_ENTRY(get("txtDefaultSaveName")))); settings->setDefaultSaveName(gtk_entry_get_text(GTK_ENTRY(get("txtDefaultSaveName"))));
// Todo(fabian): use Util::fromGtkFilename! // Todo(fabian): use Util::fromGFilename!
char* uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(get("fcAudioPath"))); char* uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(get("fcAudioPath")));
if (uri != nullptr) { if (uri != nullptr) {
settings->setAudioFolder(uri); settings->setAudioFolder(uri);

@ -11,6 +11,7 @@
#pragma once #pragma once
#include <cstring>
#include <optional> #include <optional>
#include <gio/gio.h> #include <gio/gio.h>
@ -55,15 +56,41 @@ void clearExtensions(fs::path& path, const std::string& ext = "");
[[maybe_unused]] [[nodiscard]] fs::path fromGFile(GFile* file); [[maybe_unused]] [[nodiscard]] fs::path fromGFile(GFile* file);
[[maybe_unused]] [[nodiscard]] GFile* toGFile(fs::path const& path); [[maybe_unused]] [[nodiscard]] GFile* toGFile(fs::path const& path);
[[maybe_unused]] [[nodiscard]] inline fs::path fromGtkFilename(char* path) { [[maybe_unused]] [[nodiscard]] inline fs::path fromGFilename(char* path) {
if (path == nullptr) { if (path == nullptr) {
return {}; return {};
} }
auto ret = fs::path{path}; size_t pSize{0};
GError* err{};
auto* u8Path = g_filename_to_utf8(path, std::strlen(path), nullptr, &pSize, &err);
if (err) {
g_message("Failed to convert g_filename to utf8 with error code: %d\n%s", err->code, err->message);
g_error_free(err);
g_free(path);
return {};
}
auto ret = fs::u8path(u8Path, u8Path + pSize);
g_free(u8Path);
g_free(path); g_free(path);
return ret; return ret;
} }
[[maybe_unused]] [[nodiscard]] inline std::string toGFilename(fs::path const& path) {
auto u8path = path.u8string();
size_t pSize{0};
GError* err{};
auto* local = g_filename_from_utf8(u8path.c_str(), ssize_t(u8path.size()), nullptr, &pSize, &err);
if (err) {
g_message("Failed to convert g_filename from utf8 with error code: %d\n%s", err->code, err->message);
g_error_free(err);
return {};
}
auto ret = std::string{local, pSize};
g_free(local);
return ret;
}
void openFileWithDefaultApplication(const fs::path& filename); void openFileWithDefaultApplication(const fs::path& filename);
void openFileWithFilebrowser(const fs::path& filename); void openFileWithFilebrowser(const fs::path& filename);

Loading…
Cancel
Save