1 /************************************************************************ 2 ** 3 ** Copyright (C) 2015-2019 Kevin B. Hendricks, Stratford Ontario Canada 4 ** Copyright (C) 2016-2020 Doug Massay 5 ** Copyright (C) 2009-2011 Strahinja Markovic <strahinja.markovic@gmail.com> 6 ** 7 ** This file is part of Sigil. 8 ** 9 ** Sigil is free software: you can redistribute it and/or modify 10 ** it under the terms of the GNU General Public License as published by 11 ** the Free Software Foundation, either version 3 of the License, or 12 ** (at your option) any later version. 13 ** 14 ** Sigil is distributed in the hope that it will be useful, 15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 ** GNU General Public License for more details. 18 ** 19 ** You should have received a copy of the GNU General Public License 20 ** along with Sigil. If not, see <http://www.gnu.org/licenses/>. 21 ** 22 *************************************************************************/ 23 24 #pragma once 25 #ifndef UTILITY_H 26 #define UTILITY_H 27 28 29 #include <QCoreApplication> 30 #include <QtCore/QString> 31 #include <QColor> 32 #include <QSet> 33 34 class QStringList; 35 class QStringRef; 36 class QWidget; 37 class QMenu; 38 39 struct ExceptionBase; 40 41 class Utility 42 { 43 Q_DECLARE_TR_FUNCTIONS(Utility) 44 45 public: 46 47 enum Casing { 48 Casing_Uppercase, /**< Change characters to uppercase */ 49 Casing_Lowercase, /**< Change characters to lowercase */ 50 Casing_Titlecase, /**< Change first character of each word to uppercase, reset to lowercase. */ 51 Casing_Capitalize, /**< Change first character of sentence to uppercase, rest to lowercase. */ 52 }; 53 54 enum Val_Msg_Type { 55 INFO_BRUSH, 56 WARNING_BRUSH, 57 ERROR_BRUSH, 58 }; 59 60 static QString ChangeCase(const QString &text, const Casing &casing); 61 62 // Define the user preferences location to be used 63 static QString DefinePrefsDir(); 64 65 // Indicates if application palette in dark mode 66 static bool IsDarkMode(); 67 68 // Indicates Windows system dark mode is enabled 69 static bool IsWindowsSysDarkMode(); 70 71 // Should Windows Sigil be using dark mode? 72 static bool WindowsShouldUseDarkMode(); 73 74 #if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC) 75 // Return correct path(s) for Linux hunspell dictionaries 76 static QStringList LinuxHunspellDictionaryDirs(); 77 #endif 78 79 // Uses QUuid to generate a random UUID but also removes 80 // the curly braces that QUuid::createUuid() adds 81 static QString CreateUUID(); 82 83 // Returns true if the string is mixed case, false otherwise. 84 // For instance, "test" and "TEST" return false, "teSt" returns true. 85 static bool IsMixedCase(const QString &string); 86 87 // Returns a substring of a QStringRef as a real string 88 // the characters included are in the interval: 89 // [ start_index, end_index > 90 static QString Substring(int start_index, int end_index, const QStringRef &string); 91 92 // Returns a substring of a specified string; 93 // the characters included are in the interval: 94 // [ start_index, end_index > 95 static QString Substring(int start_index, int end_index, const QString &string); 96 97 // Returns a substring of a specified string; 98 // the characters included are in the interval: 99 // [ start_index, end_index > 100 static QStringRef SubstringRef(int start_index, int end_index, const QString &string); 101 102 // Replace the first occurrence of string "before" 103 // with string "after" in string "string" 104 static QString ReplaceFirst(const QString &before, const QString &after, const QString &string); 105 106 // Copies every file and folder in the source folder 107 // to the destination folder; the paths to the folders are submitted; 108 // the destination folder needs to be created in advance 109 static void CopyFiles(const QString &fullfolderpath_source, const QString &fullfolderpath_destination); 110 111 // Johns own recursive directory removal code 112 static bool removeDir(const QString &dirName); 113 114 // Deletes the specified file if it exists 115 static bool SDeleteFile(const QString &fullfilepath); 116 117 static bool ForceCopyFile(const QString &fullinpath, const QString &fulloutpath); 118 119 static bool SMoveFile(const QString &oldfilepath, const QString &newfilepath); 120 121 static bool RenameFile(const QString &oldfilepath, const QString &newfilepath); 122 123 // Returns path to a random filename with the specified extension in 124 // the systems TEMP directory. The caller has responsibility for 125 // creating a file at this location and removing it afterwards. 126 static QString GetTemporaryFileNameWithExtension(const QString &extension); 127 128 // Returns true if the file can be read; 129 // shows an error dialog if it can't 130 // with a message elaborating what's wrong 131 static bool IsFileReadable(const QString &fullfilepath); 132 133 // Reads the text file specified with the full file path; 134 // text needs to be in UTF-8 or UTF-16; if the file cannot 135 // be read, an error dialog is shown and an empty string returned 136 static QString ReadUnicodeTextFile(const QString &fullfilepath); 137 138 // Writes the provided text variable to the specified 139 // file; if the file exists, it is truncated 140 static void WriteUnicodeTextFile(const QString &text, const QString &fullfilepath); 141 142 // Converts Mac and Windows style line endings to Unix style 143 // line endings that are expected throughout the Qt framework 144 static QString ConvertLineEndings(const QString &text); 145 146 // Decodes XML escaped string to normal text 147 // & -> & ' -> ' " -> " < -> < > -> > 148 static QString DecodeXML(const QString &text); 149 150 // Encodes (Escapes) XML string 151 // & -> & ' -> ' " -> " < -> < > -> > 152 static QString EncodeXML(const QString &text); 153 154 155 /** 156 * URL encodes the provided path string. 157 * The path separator ('/') and the ID hash ('#') are left alone. 158 * 159 * @param path The path to encode. 160 * @return The encoded path string. 161 */ 162 static bool NeedToPercentEncode(uint cp); 163 static QString URLEncodePath(const QString &path); 164 165 /** 166 * URL decodes the provided path string. 167 * 168 * @param path The path to decode. 169 * @return The decoded path string. 170 */ 171 static QString URLDecodePath(const QString &path); 172 173 static void DisplayStdErrorDialog(const QString &error_message, const QString &detailed_text = QString()); 174 175 static void DisplayStdWarningDialog(const QString &warning_message, const QString &detailed_text = QString()); 176 177 static void DisplayExceptionErrorDialog(const QString &error_info); 178 179 // Returns a value for the environment variable name passed; 180 // if the env var isn't set, it returns an empty string 181 static QString GetEnvironmentVar(const QString &variable_name); 182 183 // Returns the same number, but rounded to one decimal place 184 static float RoundToOneDecimal(float number); 185 186 static QWidget *GetMainWindow(); 187 188 static QString getSpellingSafeText(const QString &raw_text); 189 190 static bool has_non_ascii_chars(const QString &str); 191 static bool use_filename_warning(const QString &filename); 192 193 #if defined(Q_OS_WIN32) 194 static std::wstring QStringToStdWString(const QString &str); 195 static QString stdWStringToQString(const std::wstring &str); 196 #endif 197 198 static bool UnZip(const QString &zippath, const QString &destdir); 199 static QStringList ZipInspect(const QString &zippath); 200 201 // Generate relative path to destination from starting directory path 202 // Both paths should be absolute and preferably cannonical 203 static QString relativePath(const QString & destination, const QString & starting_dir); 204 205 // works with absolute or book paths 206 static QString longestCommonPath(const QStringList& filepaths, const QString& sep); 207 208 // works with absolute or book paths 209 static QString resolveRelativeSegmentsInFilePath(const QString& file_path, const QString &sep); 210 211 // start_folder is the book path (internal to epub) to the starting folder 212 static QString buildBookPath(const QString& dest_relpath, const QString& start_folder); 213 214 // both the "from" and "to" book paths are to FILES 215 static QString buildRelativePath(const QString &from_file_bkpath, const QString &to_file_bkpath); 216 217 static std::pair<QString, QString> parseRelativeHREF(const QString &relative_href); 218 219 static QString buildRelativeHREF(const QString &apath, const QString &afrag); 220 221 static QString startingDir(const QString &file_bookpath); 222 223 // sort list of strings by list of counts in a decreasing fashion, highest count first 224 static bool sort_pair_in_reverse(const std::pair<int,QString> &a, const std::pair<int,QString> &b); 225 static QStringList sortByCounts(const QStringList &folderlst, const QList<int> &countlst); 226 227 // perform a locale aware string sort 228 static QStringList LocaleAwareSort(const QStringList &names); 229 230 // inject dark mode css into html for Preview, AVTab, ImageTab, ViewImage, and SelectFiles 231 static QString AddDarkCSS(const QString &html); 232 233 // return the proper background color for QWebEngineView 234 static QColor WebViewBackgroundColor(bool followpref = false); 235 236 // return the qbrushes for ValidationResultsView 237 static QBrush ValidationResultBrush(const Val_Msg_Type &valres); 238 239 // parse a line of data from a csv file into a list of string values 240 static QStringList parseCSVLine(const QString &data); 241 242 // create a line of data in csv format 243 static QString createCSVLine(const QStringList &data); 244 245 // Generate a Unique Id given a root id and Used Set 246 static QString GenerateUniqueId(const QString &id, const QSet<QString>& Used); 247 248 }; 249 #endif // UTILITY_H 250 251 252