1 /*
2 * Xournal++
3 *
4 * Helper for reading / writing files
5 *
6 * @author Xournal++ Team
7 * https://github.com/xournalpp/xournalpp
8 *
9 * @license GNU GPLv2 or later
10 */
11
12 #pragma once
13
14 #include <cstring>
15 #include <optional>
16
17 #include <gio/gio.h>
18
19 #include "filesystem.h"
20
21 namespace Util {
22 /**
23 * Read a file to a string
24 *
25 * @param path Path to read
26 * @param showErrorToUser Show an error to the user, if the file could not be read
27 *
28 * @return contents if the file was read, std::nullopt if not
29 */
30 [[maybe_unused]] [[nodiscard]] std::optional<std::string> readString(fs::path const& path, bool showErrorToUser = true);
31
32 /**
33 * Get escaped path, all " and \ are escaped
34 */
35 [[maybe_unused]] [[nodiscard]] std::string getEscapedPath(const fs::path& path);
36
37 /**
38 * @return true if this file has .xopp or .xoj extension
39 */
40 [[maybe_unused]] [[nodiscard]] bool hasXournalFileExt(const fs::path& path);
41
42 /**
43 * Clear the the last known xournal extension (last .xoj, .xopp etc.)
44 *
45 * @param ext An extension to clear additionally, eg .pdf (would also clear
46 * .pdf.xopp etc.)
47 */
48 void clearExtensions(fs::path& path, const std::string& ext = "");
49
50 // Uri must be ASCII-encoded!
51 [[maybe_unused]] [[nodiscard]] std::optional<fs::path> fromUri(const std::string& uri);
52
53 [[maybe_unused]] [[nodiscard]] std::optional<std::string> toUri(const fs::path& path);
54
55
56 [[maybe_unused]] [[nodiscard]] fs::path fromGFile(GFile* file);
57 [[maybe_unused]] [[nodiscard]] GFile* toGFile(fs::path const& path);
58
59 [[maybe_unused]] [[nodiscard]] inline fs::path fromGFilename(char* path, bool owned = true) {
60 auto deleter = [path, owned]() {
61 if (owned) {
62 g_free(path);
63 }
64 };
65
66 if (path == nullptr) {
67 return {};
68 }
69 size_t pSize{0};
70 GError* err{};
71 auto* u8Path = g_filename_to_utf8(path, std::strlen(path), nullptr, &pSize, &err);
72 if (err) {
73 g_message("Failed to convert g_filename to utf8 with error code: %d\n%s", err->code, err->message);
74 g_error_free(err);
75 deleter();
76 return {};
77 }
78 auto ret = fs::u8path(u8Path, u8Path + pSize);
79 g_free(u8Path);
80 deleter();
81 return ret;
82 }
83
toGFilename(fs::path const & path)84 [[maybe_unused]] [[nodiscard]] inline std::string toGFilename(fs::path const& path) {
85 auto u8path = path.u8string();
86 size_t pSize{0};
87 GError* err{};
88 auto* local = g_filename_from_utf8(u8path.c_str(), ssize_t(u8path.size()), nullptr, &pSize, &err);
89 if (err) {
90 g_message("Failed to convert g_filename from utf8 with error code: %d\n%s", err->code, err->message);
91 g_error_free(err);
92 return {};
93 }
94 auto ret = std::string{local, pSize};
95 g_free(local);
96 return ret;
97 }
98
99
100 void openFileWithDefaultApplication(const fs::path& filename);
101 void openFileWithFilebrowser(const fs::path& filename);
102
103 [[maybe_unused]] [[nodiscard]] bool isChildOrEquivalent(fs::path const& path, fs::path const& base);
104
105 [[maybe_unused]] bool safeRenameFile(fs::path const& from, fs::path const& to);
106
107 [[maybe_unused]] fs::path ensureFolderExists(const fs::path& p);
108
109 /**
110 * Convert to platform compatible path. Call this before
111 * passing a path to another program.
112 */
113 fs::path getLongPath(const fs::path& path);
114
115 /**
116 * Return the configuration folder path (may not be guaranteed to exist).
117 */
118 [[maybe_unused]] [[nodiscard]] fs::path getConfigFolder();
119 [[maybe_unused]] [[nodiscard]] fs::path getConfigSubfolder(const fs::path& subfolder = "");
120 [[maybe_unused]] [[nodiscard]] fs::path getCacheSubfolder(const fs::path& subfolder = "");
121 [[maybe_unused]] [[nodiscard]] fs::path getDataSubfolder(const fs::path& subfolder = "");
122 [[maybe_unused]] [[nodiscard]] fs::path getConfigFile(const fs::path& relativeFileName = "");
123 [[maybe_unused]] [[nodiscard]] fs::path getCacheFile(const fs::path& relativeFileName = "");
124 [[maybe_unused]] [[nodiscard]] fs::path getTmpDirSubfolder(const fs::path& subfolder = "");
125 [[maybe_unused]] [[nodiscard]] fs::path getAutosaveFilepath();
126 [[maybe_unused]] [[nodiscard]] fs::path getGettextFilepath(const char* localeDir);
127
128 } // namespace Util
129