diff --git a/src/control/Control.cpp b/src/control/Control.cpp index 674ea17f..026bcea7 100644 --- a/src/control/Control.cpp +++ b/src/control/Control.cpp @@ -2304,10 +2304,10 @@ auto Control::showSaveDialog() -> bool { auto suggested_name = this->doc->createSaveFilename(Document::XOPP, this->settings->getDefaultSaveName()); this->doc->unlock(); - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), suggested_folder.string().c_str()); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), suggested_name.string().c_str()); - gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), this->settings->getLastOpenPath().string().c_str(), - nullptr); + 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), Util::toGFilename(suggested_name).c_str()); + gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(dialog), + Util::toGFilename(this->settings->getLastOpenPath()).c_str(), nullptr); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), false); // handled below @@ -2319,7 +2319,7 @@ auto Control::showSaveDialog() -> bool { 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); fileTmp += ".xopp"; // 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()); gtk_widget_destroy(dialog); diff --git a/src/control/XournalMain.cpp b/src/control/XournalMain.cpp index a9994ef1..8b79f506 100644 --- a/src/control/XournalMain.cpp +++ b/src/control/XournalMain.cpp @@ -379,7 +379,7 @@ auto XournalMain::run(int argc, char* argv[]) -> int { XojMsgBox::showErrorToUser(static_cast(*win), msg); } - fs::path p(optFilename[0]); + fs::path p = Util::fromGFilename(optFilename[0]); try { 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.") % p.u8string().c_str() % e.what()); XojMsgBox::showErrorToUser(static_cast(*win), msg); + opened = control->newFile("", optFilename[0]); } } diff --git a/src/control/jobs/BaseExportJob.cpp b/src/control/jobs/BaseExportJob.cpp index 782448dc..011e0fce 100644 --- a/src/control/jobs/BaseExportJob.cpp +++ b/src/control/jobs/BaseExportJob.cpp @@ -57,8 +57,9 @@ auto BaseExportJob::showFilechooser() -> bool { fs::path name = doc->createSaveFilename(Document::PDF, settings->getDefaultSaveName()); doc->unlock(); - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), folder.string().c_str()); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), name.string().c_str()); + gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), true); + 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())); @@ -67,15 +68,10 @@ auto BaseExportJob::showFilechooser() -> bool { gtk_widget_destroy(dialog); return false; } - auto uri = [](char* uri) { - 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))); + this->filepath = Util::fromGFilename(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog))); Util::clearExtensions(this->filepath); // 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; } } diff --git a/src/control/stockdlg/ImageOpenDlg.cpp b/src/control/stockdlg/ImageOpenDlg.cpp index fea2028f..9372c4c8 100644 --- a/src/control/stockdlg/ImageOpenDlg.cpp +++ b/src/control/stockdlg/ImageOpenDlg.cpp @@ -20,7 +20,8 @@ auto ImageOpenDlg::show(GtkWindow* win, Settings* settings, bool localOnly, bool gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filterSupported); 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; @@ -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 // 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()) { settings->setLastImagePath(folder); } diff --git a/src/control/stockdlg/XojOpenDlg.cpp b/src/control/stockdlg/XojOpenDlg.cpp index dfef3593..ed7f667c 100644 --- a/src/control/stockdlg/XojOpenDlg.cpp +++ b/src/control/stockdlg/XojOpenDlg.cpp @@ -21,7 +21,7 @@ XojOpenDlg::XojOpenDlg(GtkWindow* win, Settings* settings): win(win), settings(s g_warning("lastOpenPath is not set!"); 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() { @@ -75,7 +75,7 @@ auto XojOpenDlg::runDialog() -> 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()); return file; } @@ -121,7 +121,7 @@ auto XojOpenDlg::showOpenDialog(bool pdf, bool& attachPdf) -> fs::path { auto lastOpenPath = this->settings->getLastOpenPath(); 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(); @@ -145,7 +145,7 @@ auto XojOpenDlg::showOpenDialog(bool pdf, bool& attachPdf) -> fs::path { } 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()) { gtk_file_chooser_set_preview_widget_active(fileChooser, false); diff --git a/src/gui/dialog/LatexSettingsPanel.cpp b/src/gui/dialog/LatexSettingsPanel.cpp index 35222649..a903a67c 100644 --- a/src/gui/dialog/LatexSettingsPanel.cpp +++ b/src/gui/dialog/LatexSettingsPanel.cpp @@ -27,14 +27,15 @@ LatexSettingsPanel::~LatexSettingsPanel() { void LatexSettingsPanel::load(const LatexSettings& settings) { gtk_toggle_button_set_active(this->cbAutoDepCheck, settings.autoCheckDependencies); 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()); } void LatexSettingsPanel::save(LatexSettings& settings) { 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"))); } diff --git a/src/gui/dialog/PageTemplateDialog.cpp b/src/gui/dialog/PageTemplateDialog.cpp index f9b104d2..d842023e 100644 --- a/src/gui/dialog/PageTemplateDialog.cpp +++ b/src/gui/dialog/PageTemplateDialog.cpp @@ -90,7 +90,8 @@ void PageTemplateDialog::saveToFile() { gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filterXoj); 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); @@ -107,7 +108,7 @@ void PageTemplateDialog::saveToFile() { 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()); gtk_widget_destroy(dialog); diff --git a/src/gui/dialog/SettingsDialog.cpp b/src/gui/dialog/SettingsDialog.cpp index 3b2d9347..14750b5d 100644 --- a/src/gui/dialog/SettingsDialog.cpp +++ b/src/gui/dialog/SettingsDialog.cpp @@ -569,7 +569,7 @@ void SettingsDialog::save() { settings->setMenubarVisible(getCheckbox("cbHideMenubarStartup")); 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"))); if (uri != nullptr) { settings->setAudioFolder(uri); diff --git a/src/util/PathUtil.h b/src/util/PathUtil.h index 4b993667..9626189d 100644 --- a/src/util/PathUtil.h +++ b/src/util/PathUtil.h @@ -11,6 +11,7 @@ #pragma once +#include #include #include @@ -55,15 +56,41 @@ void clearExtensions(fs::path& path, const std::string& ext = ""); [[maybe_unused]] [[nodiscard]] fs::path fromGFile(GFile* file); [[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) { 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); 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 openFileWithFilebrowser(const fs::path& filename);