int main(int argc, char** argv) { Application app(argc, argv); QString appdir = app.applicationDirPath(); QStringList paths = QIcon::themeSearchPaths(); paths.prepend(appdir + "/../share/focuswriter/icons"); paths.prepend(appdir + "/icons"); QIcon::setThemeSearchPaths(paths); paths.clear(); paths.append(appdir + "/sounds/"); paths.append(appdir + "/../share/focuswriter/sounds/"); paths.append(appdir + "/../Resources/sounds"); foreach (const QString& path, paths) { if (QFile::exists(path)) { Sound::setPath(path); break; } } // Find data paths QStringList locations; #if defined(Q_OS_MAC) QFileInfo portable(appdir + "/../../../Data"); QString path = QDir::homePath() + "/Library/Application Support/GottCode/FocusWriter/"; locations.append(QDir::homePath() + "/Library/Spelling"); locations.append("/Library/Spelling"); locations.append(appdir + "/../Resources/Dictionaries"); #elif defined(Q_OS_UNIX) QFileInfo portable(appdir + "/Data"); QString path = qgetenv("XDG_DATA_HOME"); if (path.isEmpty()) { path = QDir::homePath() + "/.local/share"; } path += "/focuswriter/"; QStringList xdg = QString(qgetenv("XDG_DATA_DIRS")).split(QChar(':'), QString::SkipEmptyParts); if (xdg.isEmpty()) { xdg.append("/usr/local/share"); xdg.append("/usr/share"); } QStringList subdirs = QStringList() << "/hunspell" << "/myspell/dicts" << "/myspell"; foreach (const QString& subdir, subdirs) { foreach (const QString& dir, xdg) { QString path = dir + subdir; if (!locations.contains(path)) { locations.append(path); } }
int main(int argc, char** argv) { Application app(argc, argv); if (app.isRunning()) { app.sendMessage(app.files().join(QLatin1String("\n"))); return 0; } QString appdir = app.applicationDirPath(); // Allow passing Theme as signal parameter qRegisterMetaType<Theme>("Theme"); // Find application data dirs QStringList datadirs; #if defined(Q_OS_MAC) QFileInfo portable(appdir + "/../../../Data"); datadirs.append(appdir + "/../Resources"); #elif defined(Q_OS_UNIX) QFileInfo portable(appdir + "/Data"); datadirs.append(DATADIR); datadirs.append(appdir + "/../share/focuswriter"); #else QFileInfo portable(appdir + "/Data"); datadirs.append(appdir); #endif // Handle portability QString userdir; if (portable.exists() && portable.isWritable()) { userdir = portable.absoluteFilePath(); QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setPath(QSettings::IniFormat, QSettings::UserScope, userdir + "/Settings"); } // Set locations of fallback icons { QStringList paths = QIcon::themeSearchPaths(); foreach (const QString& path, datadirs) { paths.prepend(path + "/icons"); } QIcon::setThemeSearchPaths(paths); }
AppSettings::AppSettings() { QCoreApplication::setOrganizationName("ghostwriter"); QCoreApplication::setApplicationName("ghostwriter"); QCoreApplication::setApplicationVersion(APPVERSION); // The following was lifted/modded from FocusWriter. // See GPL license at the beginning of this file. // QString appDir = qApp->applicationDirPath(); // Set up portable settings directories. #if defined(Q_OS_MAC) QFileInfo portable(appDir + "/../../../data"); #elif defined(Q_OS_UNIX) QFileInfo portable(appDir + "/data"); #else QFileInfo portable(appDir + "/data"); #endif // Handle portability QString userDir; if (portable.exists() && portable.isWritable()) { userDir = portable.absoluteFilePath(); QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setPath ( QSettings::IniFormat, QSettings::UserScope, userDir + "/settings" ); translationsPath = appDir + "/translations"; } else { #ifdef Q_OS_WIN32 // On Windows, don't ever use the registry to store settings, for the // sake of cleanness, ability to load configuration files on other // machines, and also for the user's privacy. // QSettings::setDefaultFormat(QSettings::IniFormat); #endif QSettings settings; userDir = QFileInfo(settings.fileName()).dir().absolutePath(); QStringList translationPaths; translationPaths.append(appDir + "/translations"); translationPaths.append(appDir + "/../share/" + QCoreApplication::applicationName().toLower() + "/translations"); translationPaths.append(appDir + "/../Resources/translations"); foreach (const QString& path, translationPaths) { if (QFile::exists(path)) { translationsPath = path; break; } } } QDir themeDir(userDir + "/themes"); if (!themeDir.exists()) { themeDir.mkpath(themeDir.path()); } themeDirectoryPath = themeDir.absolutePath(); QDir dictionaryDir(userDir + "/dictionaries"); if (!dictionaryDir.exists()) { dictionaryDir.mkpath(dictionaryDir.path()); } dictionaryPath = dictionaryDir.absolutePath(); DictionaryManager::setPath(dictionaryPath); QStringList dictdirs; dictdirs.append(DictionaryManager::path()); dictionaryDir = QDir(appDir + "/dictionaries"); if (dictionaryDir.exists()) { dictdirs.append(dictionaryDir.path()); } QDir::setSearchPaths("dict", dictdirs); // End FocusWriter lift/mod // Depending on the OS and Qt version, the default monospaced font returned // by the Monospace style hint and/or font family tends to something not // even monospaced, or, at best "Courier". QTBUG-34082 seems to be what is // causing the issue. Regardless, we want the prettiest monospaced font // available, so see which preferred fonts are available on the system // before before resorting to style hints. // QFontDatabase fontDb; QStringList fontFamilies = fontDb.families(); QStringList preferredFonts; #ifdef Q_OS_MAC preferredFonts.append("Menlo"); #endif preferredFonts.append("DejaVu Sans Mono"); #ifdef Q_OS_MAC preferredFonts.append("Monaco"); #elif defined(Q_OS_LINUX) preferredFonts.append("Ubuntu Mono"); preferredFonts.append("Liberation Mono"); #elif defined(Q_OS_WIN32) preferredFonts.append("Consolas"); preferredFonts.append("Lucida Console"); #endif preferredFonts.append("Courier New"); preferredFonts.append("Courier"); // Pick the first font in the list of preferredFonts that is installed // (i.e., in the font database) to use as the default font on the very // first start up of this program. // bool fontMatchFound = false; for (int i = 0; i < preferredFonts.size(); i++) { fontMatchFound = std::binary_search ( fontFamilies.begin(), fontFamilies.end(), preferredFonts[i] ); if (fontMatchFound) { defaultFont = QFont(preferredFonts[i]); break; } } if (!fontMatchFound) { // This case should not really happen, since the Courier family is // cross-platform. This is just a precaution. // qWarning() << "No fixed-width fonts were found. Using sytem default..."; defaultFont = QFont(""); defaultFont.setFixedPitch(true); defaultFont.setStyleHint(QFont::Monospace); } // Last but not least, load some basic settings from the configuration file, // but only those that need special validation. Things like window // dimensions and file history can be handled elsewhere. // QSettings appSettings; autoSaveEnabled = appSettings.value(GW_AUTOSAVE_KEY, QVariant(true)).toBool(); backupFileEnabled = appSettings.value(GW_BACKUP_FILE_KEY, QVariant(true)).toBool(); font = defaultFont; font.fromString(appSettings.value(GW_FONT_KEY, QVariant(defaultFont.toString())).toString()); tabWidth = appSettings.value(GW_TAB_WIDTH_KEY, QVariant(DEFAULT_TAB_WIDTH)).toInt(); if ((tabWidth < MIN_TAB_WIDTH) || (tabWidth > MAX_TAB_WIDTH)) { tabWidth = DEFAULT_TAB_WIDTH; } insertSpacesForTabsEnabled = appSettings.value(GW_SPACES_FOR_TABS_KEY, QVariant(false)).toBool(); useUnderlineForEmphasis = appSettings.value(GW_UNDERLINE_ITALICS_KEY, QVariant(false)).toBool(); largeHeadingSizesEnabled = appSettings.value(GW_LARGE_HEADINGS_KEY, QVariant(true)).toBool(); autoMatchEnabled = appSettings.value(GW_AUTO_MATCH_KEY, QVariant(true)).toBool(); autoMatchDoubleQuotesEnabled = appSettings.value(GW_AUTO_MATCH_DOUBLE_QUOTES_KEY, QVariant(true)).toBool(); autoMatchSingleQuotesEnabled = appSettings.value(GW_AUTO_MATCH_SINGLE_QUOTES_KEY, QVariant(true)).toBool(); autoMatchParenthesesEnabled = appSettings.value(GW_AUTO_MATCH_PARENTHESES_KEY, QVariant(true)).toBool(); autoMatchSquareBracketsEnabled = appSettings.value(GW_AUTO_MATCH_SQUARE_BRACKETS_KEY, QVariant(true)).toBool(); autoMatchBracesEnabled = appSettings.value(GW_AUTO_MATCH_BRACES_KEY, QVariant(true)).toBool(); autoMatchAsterisksEnabled = appSettings.value(GW_AUTO_MATCH_ASTERISKS_KEY, QVariant(true)).toBool(); autoMatchUnderscoresEnabled = appSettings.value(GW_AUTO_MATCH_UNDERSCORES_KEY, QVariant(true)).toBool(); autoMatchBackticksEnabled = appSettings.value(GW_AUTO_MATCH_BACKTICKS_KEY, QVariant(true)).toBool(); autoMatchAngleBracketsEnabled = appSettings.value(GW_AUTO_MATCH_ANGLE_BRACKETS_KEY, QVariant(true)).toBool(); bulletPointCyclingEnabled = appSettings.value(GW_BULLET_CYCLING_KEY, QVariant(true)).toBool(); focusMode = (FocusMode) appSettings.value(GW_FOCUS_MODE_KEY, QVariant(FocusModeSentence)).toInt(); if ((focusMode < FocusModeDisabled) || (focusMode > FocusModeParagraph)) { focusMode = FocusModeSentence; } hideMenuBarInFullScreenEnabled = appSettings.value(GW_HIDE_MENU_BAR_IN_FULL_SCREEN_KEY, QVariant(true)).toBool(); fileHistoryEnabled = appSettings.value(GW_REMEMBER_FILE_HISTORY_KEY, QVariant(true)).toBool(); displayTimeInFullScreenEnabled = appSettings.value(GW_DISPLAY_TIME_IN_FULL_SCREEN_KEY, QVariant(true)).toBool(); themeName = appSettings.value(GW_THEME_KEY, QVariant("Classic Light")).toString(); dictionaryLanguage = appSettings.value(GW_DICTIONARY_KEY, QLocale().name()).toString(); locale = appSettings.value(GW_LOCALE_KEY, QLocale().name()).toString(); liveSpellCheckEnabled = appSettings.value(GW_LIVE_SPELL_CHECK_KEY, QVariant(true)).toBool(); editorWidth = (EditorWidth) appSettings.value(GW_EDITOR_WIDTH_KEY, QVariant(EditorWidthMedium)).toInt(); blockquoteStyle = (BlockquoteStyle) appSettings.value(GW_BLOCKQUOTE_STYLE_KEY, QVariant(BlockquoteStylePlain)).toInt(); if ((editorWidth < EditorWidthNarrow) || (editorWidth > EditorWidthFull)) { editorWidth = EditorWidthMedium; } #ifdef Q_OS_MAC HudWindowButtonLayout defaultHudButtonLayout = HudWindowButtonLayoutLeft; #else HudWindowButtonLayout defaultHudButtonLayout = HudWindowButtonLayoutRight; #endif hudButtonLayout = (HudWindowButtonLayout) appSettings.value(GW_HUD_BUTTON_LAYOUT_KEY, QVariant(defaultHudButtonLayout)).toInt(); alternateHudRowColorsEnabled = appSettings.value(GW_HUD_ROW_COLORS_KEY, QVariant(false)).toBool(); desktopCompositingEnabled = appSettings.value(GW_DESKTOP_COMPOSITING_KEY, QVariant(true)).toBool(); hudOpacity = appSettings.value(GW_HUD_OPACITY_KEY, QVariant(200)).toInt(); }
static int check(const char *path) { struct stat sb; long complen, namemax, pathmax, svnamemax; int last; char *end, *p, *pathd; if ((pathd = strdup(path)) == NULL) err(1, "strdup"); p = pathd; if (Pflag && *p == '\0') { warnx("%s: empty pathname", path); goto bad; } if ((Pflag || pflag) && (*p == '-' || strstr(p, "/-") != NULL)) { warnx("%s: contains a component starting with '-'", path); goto bad; } if (!pflag) { errno = 0; namemax = pathconf(*p == '/' ? "/" : ".", _PC_NAME_MAX); if (namemax == -1 && errno != 0) namemax = NAME_MAX; } else namemax = _POSIX_NAME_MAX; for (;;) { p += strspn(p, "/"); complen = (long)strcspn(p, "/"); end = p + complen; last = *end == '\0'; *end = '\0'; if (namemax != -1 && complen > namemax) { warnx("%s: %s: component too long (limit %ld)", path, p, namemax); goto bad; } if (!pflag && stat(pathd, &sb) == -1 && errno != ENOENT) { warn("%s: %.*s", path, (int)(strlen(pathd) - complen - 1), pathd); goto bad; } if (pflag && !portable(p)) { warnx("%s: %s: component contains non-portable " "character", path, p); goto bad; } if (last) break; if (!pflag) { errno = 0; svnamemax = namemax; namemax = pathconf(pathd, _PC_NAME_MAX); if (namemax == -1 && errno != 0) namemax = svnamemax; } *end = '/'; p = end + 1; } if (!pflag) { errno = 0; pathmax = pathconf(path, _PC_PATH_MAX); if (pathmax == -1 && errno != 0) pathmax = PATH_MAX; } else pathmax = _POSIX_PATH_MAX; if (pathmax != -1 && strlen(path) >= (size_t)pathmax) { warnx("%s: path too long (limit %ld)", path, pathmax - 1); goto bad; } free(pathd); return (0); bad: free(pathd); return (1); }