1# vim: ts=8:sts=8:sw=8:noexpandtab 2 3# This file is part of ReText 4# Copyright: 2012-2021 Dmitry Shachnev 5# 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19import sys 20import markups 21import markups.common 22from os.path import dirname, exists, join, expanduser 23 24from PyQt5.QtCore import QByteArray, QLocale, QSettings, QStandardPaths 25from PyQt5.QtGui import QFont, QFontDatabase 26 27app_version = "7.2.2" 28 29settings = QSettings('ReText project', 'ReText') 30 31if not str(settings.fileName()).endswith('.conf'): 32 # We are on Windows probably 33 settings = QSettings(QSettings.Format.IniFormat, QSettings.Scope.UserScope, 34 'ReText project', 'ReText') 35 36datadirs = [] 37 38def initializeDataDirs(): 39 assert not datadirs 40 41 try: 42 datadirs.append(dirname(dirname(__file__))) 43 except NameError: 44 pass 45 46 dataLocations = QStandardPaths.standardLocations(QStandardPaths.StandardLocation.GenericDataLocation) 47 datadirs.extend(join(d, 'retext') for d in dataLocations) 48 49 if sys.platform == "win32": 50 # Windows compatibility: Add "PythonXXX\share\" path 51 datadirs.append(join(dirname(sys.executable), 'share', 'retext')) 52 53 # For virtualenvs 54 datadirs.append(join(dirname(dirname(sys.executable)), 'share', 'retext')) 55 56_iconPath = None 57 58def getBundledIcon(iconName): 59 global _iconPath 60 if _iconPath is None: 61 for dir in ['icons'] + datadirs: 62 _iconPath = join(dir, 'icons') 63 if exists(_iconPath): 64 break 65 return join(_iconPath, iconName + '.png') 66 67configOptions = { 68 'appStyleSheet': '', 69 'autoSave': False, 70 'defaultCodec': '', 71 'defaultMarkup': markups.MarkdownMarkup.name, 72 'defaultPreviewState': 'editor', 73 'detectEncoding': True, 74 'directoryPath': expanduser("~"), 75 'documentStatsEnabled': False, 76 'editorFont': QFont(), 77 'font': QFont(), 78 'handleWebLinks': False, 79 'hideToolBar': False, 80 'highlightCurrentLine': 'disabled', 81 'iconTheme': '', 82 'lastTabIndex': 0, 83 'lineNumbersEnabled': False, 84 'markdownDefaultFileExtension': '.mkd', 85 'openFilesInExistingWindow': True, 86 'openLastFilesOnStartup': False, 87 'orderedListMode': 'increment', 88 'paperSize': '', 89 'pygmentsStyle': 'default', 90 'recentDocumentsCount': 10, 91 'relativeLineNumbers': False, 92 'restDefaultFileExtension': '.rst', 93 'rightMargin': 0, 94 'rightMarginWrap': False, 95 'saveWindowGeometry': False, 96 'showDirectoryTree': False, 97 'spellCheck': False, 98 'spellCheckLocale': '', 99 'styleSheet': '', 100 'syncScroll': True, 101 'tabBarAutoHide': False, 102 'tabInsertsSpaces': True, 103 'tabWidth': 4, 104 'uiLanguage': QLocale.system().name(), 105 'useFakeVim': False, 106 'useWebEngine': False, 107 'useWebKit': False, 108 'wideCursor': False, 109 'windowGeometry': QByteArray(), 110 'windowTitleFullPath': False, 111} 112 113def readFromSettings(key, keytype, settings=settings, default=None): 114 if isinstance(default, QFont): 115 family = readFromSettings(key, str, settings, default.family()) 116 size = readFromSettings(key + 'Size', int, settings, 0) 117 return QFont(family, size) 118 if not settings.contains(key): 119 return default 120 try: 121 value = settings.value(key, type=keytype) 122 if isinstance(value, keytype): 123 return value 124 return keytype(value) 125 except TypeError as error: 126 # Type mismatch 127 print('Warning: '+str(error)) 128 # Return an instance of keytype 129 return default if (default is not None) else keytype() 130 131def readListFromSettings(key, settings=settings): 132 if not settings.contains(key): 133 return [] 134 value = settings.value(key) 135 if isinstance(value, str): 136 return [value] 137 else: 138 return value 139 140def writeToSettings(key, value, default, settings=settings): 141 if isinstance(value, QFont): 142 writeToSettings(key, value.family(), '', settings) 143 writeToSettings(key + 'Size', max(value.pointSize(), 0), 0, settings) 144 elif value == default: 145 settings.remove(key) 146 else: 147 settings.setValue(key, value) 148 149def writeListToSettings(key, value, settings=settings): 150 if len(value) > 1: 151 settings.setValue(key, value) 152 elif len(value) == 1: 153 settings.setValue(key, value[0]) 154 else: 155 settings.remove(key) 156 157def getSettingsFilePath(settings=settings): 158 return settings.fileName() 159 160 161class ReTextSettings(object): 162 def __init__(self): 163 for option in configOptions: 164 value = configOptions[option] 165 object.__setattr__(self, option, readFromSettings( 166 option, type(value), default=value)) 167 168 def __setattr__(self, option, value): 169 if not option in configOptions: 170 raise AttributeError('Unknown attribute') 171 object.__setattr__(self, option, value) 172 writeToSettings(option, value, configOptions[option]) 173 174 def __getattribute__(self, option): 175 value = object.__getattribute__(self, option) 176 # Choose a font just-in-time, because when the settings are 177 # loaded it is too early to work. 178 if option == 'font' and not value.family(): 179 value = QFont() 180 if option == 'editorFont' and not value.family(): 181 value = QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont) 182 return value 183 184globalSettings = ReTextSettings() 185 186markups.common.PYGMENTS_STYLE = globalSettings.pygmentsStyle 187