def __init__(self, parent=None, style='default', paths=[]): from PySide.QtGui import QFontDatabase self._ui = parent # parent UI self._style = style # style to parse self._font_db = QFontDatabase() # font database self._fonts = dict() # dictionary of valid font types (ui, mono) self._config_paths = () # paths for cfg mods self._config_files = dict() # cfg files self._qss_paths = () # qss file paths self._qss_files = dict() # qss files self._initialized = False # debugging data self._data = dict() if not self._initialized: self.run(paths=paths)
def findSizes(self,font): fontLogger.debug("font.key()=%s" % font.key()) fontDatabase = QFontDatabase() self.sizeCombo.blockSignals(True) self.sizeCombo.clear() self.sizeComboFs.blockSignals(True) self.sizeComboFs.clear() styleStr = fontDatabase.styleString(font) if fontDatabase.isSmoothlyScalable(font.family(),styleStr): for size in QFontDatabase.standardSizes(): self.sizeCombo.addItem(str(size)) self.sizeComboFs.addItem(str(size)) else: for size in fontDatabase.smoothSizes(font.family(),styleStr): self.sizeCombo.addItem(str(size)) self.sizeComboFs.addItem(str(size)) self.sizeCombo.blockSignals(False) self.sizeComboFs.blockSignals(False) currentSize = unicode(QSettings().value("worksheet/fontsize", QtReduceDefaults.FONTSIZE)) sizeIndex = self.sizeCombo.findText(currentSize) self.sizeCombo.setCurrentIndex(sizeIndex) currentSize = unicode(QSettings().value("worksheet/fontsizefs", QtReduceDefaults.FONTSIZEFS)) sizeIndex = self.sizeCombo.findText(currentSize) self.sizeComboFs.setCurrentIndex(sizeIndex)
def __nextGoodFontSize(self,font,size,step): info = QFontInfo(font) family = info.family() fontDatabase = QFontDatabase() styleStr = fontDatabase.styleString(font) fontLogger.debug("family=%s, style=%s" % (family,styleStr)) if fontDatabase.isSmoothlyScalable(family,styleStr): sizes = QFontDatabase.standardSizes() else: sizes = fontDatabase.smoothSizes(family,styleStr) fontLogger.debug("looking for %s in %s step %d" % (size,sizes,step)) nSize = size while nSize not in sizes and sizes[0] <= nSize and nSize <= sizes[-1]: nSize += step if nSize < sizes[0]: fontLogger.debug("out of range - returning %s" % sizes[0]) return sizes[0] if sizes[-1] < nSize: fontLogger.debug("out of range - returning %s" % sizes[-1]) return sizes[-1] fontLogger.debug("found %s" % nSize) return nSize
def setUpClass(cls): super(TestClockClient,cls).setUpClass() mainlog.setLevel(logging.WARNING) # logging.WARNING) cls.mem_logger = MemLogger() app = QApplication.instance() if app is None: app = QApplication(sys.argv) font_database = QFontDatabase() cls.app = app cls.window = MainWindow("TEST_CLOCK",cls.mem_logger,dao, font_database, call_mode=JsonCallWrapper.DIRECT_MODE) # IN_PROCESS_MODE cls.window.show()
def __init__(self,parent=None): super(QtReduceFontComboBox,self).__init__() fdb = QFontDatabase() l = [] self.fontDict = {} for fam in fdb.families(QFontDatabase.Latin): for sty in fdb.styles(fam): if not fam in l and fdb.isFixedPitch(fam,sty) \ and not fdb.bold(fam,sty) and not fdb.italic(fam,sty) \ and self.__osxHack(fam): fontLogger.debug("family=%s, style=%s, isFixedPitch=%s" % (fam, sty, fdb.isFixedPitch(fam,sty))) sizes = fdb.smoothSizes(fam,sty) if sizes: font = fdb.font(fam,sty,sizes[0]) if not font.exactMatch(): fontLogger.debug("no exactMatch for %s %s %s" % (fam,sty,sizes[0])) l += [fam] self.fontDict.update({str(fam):font}) l.sort self.addItems(l) self.currentIndexChanged.connect(self.currentIndexChangedHandler)
def findSizes(self, font): fontDatabase = QFontDatabase() currentSize = self.sizeComboBox.currentText() with Lib.BlockSignals(self.sizeComboBox): self.sizeComboBox.clear() if fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font)): for size in QFontDatabase.standardSizes(): self.sizeComboBox.addItem(str(size)) else: for size in fontDatabase.smoothSizes( font.family(), fontDatabase.styleString(font)): self.sizeComboBox.addItem(str(size)) self.sizeComboBox.setEditable(False) sizeIndex = self.sizeComboBox.findText(currentSize) if sizeIndex == -1: self.sizeComboBox.setCurrentIndex( max(0, self.sizeComboBox.count() / 3)) else: self.sizeComboBox.setCurrentIndex(sizeIndex)
def __nextGoodFontSize(self, font, size, step): info = QFontInfo(font) family = info.family() fontDatabase = QFontDatabase() styleStr = fontDatabase.styleString(font) fontLogger.debug("family=%s, style=%s" % (family, styleStr)) if fontDatabase.isSmoothlyScalable(family, styleStr): sizes = QFontDatabase.standardSizes() else: sizes = fontDatabase.smoothSizes(family, styleStr) fontLogger.debug("looking for %s in %s step %d" % (size, sizes, step)) nSize = size while nSize not in sizes and sizes[0] <= nSize and nSize <= sizes[-1]: nSize += step if nSize < sizes[0]: fontLogger.debug("out of range - returning %s" % sizes[0]) return sizes[0] if sizes[-1] < nSize: fontLogger.debug("out of range - returning %s" % sizes[-1]) return sizes[-1] fontLogger.debug("found %s" % nSize) return nSize
class StylesheetManager(object): """ The StylesheetManager reads and parses stylesheet data, plus does some basic sass substitution via external config files. :param QtGui.QWidget parent: parent UI. :param str style: default style name. :param list paths: additional search paths. """ def __init__(self, parent=None, style='default', paths=[]): from PySide.QtGui import QFontDatabase self._ui = parent # parent UI self._style = style # style to parse self._font_db = QFontDatabase() # font database self._fonts = dict() # dictionary of valid font types (ui, mono) self._config_paths = () # paths for cfg mods self._config_files = dict() # cfg files self._qss_paths = () # qss file paths self._qss_files = dict() # qss files self._initialized = False # debugging data self._data = dict() if not self._initialized: self.run(paths=paths) def run(self, paths=[]): """ Read all of the currently defined config files/stylesheets. :param str style: style name to parse. :param list paths: additional search paths. """ self._fonts = self.initializeFontsList() self._config_paths = self._get_config_paths(paths=paths) self._config_files = self._get_config_files(self._config_paths) self._qss_paths = self._get_qss_paths(paths=paths) self._qss_files = self._get_qss_files(self._qss_paths) # set parent defaults if not already set defaults = self.font_defaults() for default in defaults.keys(): if hasattr(self._ui, default): if getattr(self._ui, default) is None: value = defaults.get(default) #print '# DEBUG: setting UI default; "%s", "%s"' % (default, value) setattr(self._ui, default, value) self._initialized = True @property def style(self): return self._style def style_data(self, **kwargs): """ Return the stylesheet data. :returns: parsed stylesheet data. :rtype: str """ stylesheet_name = kwargs.pop('stylesheet_name', 'default') palette_style = kwargs.pop('palette_style', 'default') font_style = kwargs.pop('font_style', 'default') self._data = dict() parser = StyleParser(self, style=stylesheet_name, palette_style=palette_style, font_style=font_style) parser.run(style=stylesheet_name, palette_style=palette_style, font_style=font_style) data = parser.data(**kwargs) # grab data here for debugging self._data = parser._data return data @property def config_names(self): """ Returns a list of config file names. :returns: list of config names. :rtype: list """ return self._config_files.keys() def config_files(self, style='default'): """ Returns a dictionary of config files for the given style. :param str style: style name to return. :returns: font/palette config files. :rtype: dict """ return self._config_files.get(style, {}) @property def qss_names(self): """ Returns a list of stylesheet file names. :returns: list of stylesheet names. :rtype: list """ return self._qss_files.keys() @property def palette_styles(self): """ Returns a list of palette style names. :returns: list of palette names. :rtype: list """ styles = [] for style_name, files in self._config_files.iteritems(): if 'palette' in files: value = files.get('palette', None) if value is not None: if os.path.exists(value): styles.append(style_name) return styles @property def font_styles(self): """ Returns a list of font style names. :returns: list of font style names. :rtype: list """ styles = [] for style_name, files in self._config_files.iteritems(): if 'fonts' in files: value = files.get('fonts', None) if value is not None: if os.path.exists(value): styles.append(style_name) return styles @property def qss_files(self): return self._qss_files.values() def _get_config_paths(self, paths=[]): """ Read configs from config paths. :param list paths: list of paths to add to the scan. :returns: array of search paths. :rtype: tuple """ if paths and type(paths) in [str, unicode]: paths = [ paths, ] cfg_paths = () cfg_paths = cfg_paths + (options.SCENEGRAPH_CONFIG_PATH, ) # read external paths if 'SCENEGRAPH_CONFIG_PATH' in os.environ: spaths = os.getenv('SCENEGRAPH_CONFIG_PATH').split(':') if paths: for p in paths: if p not in spaths: spaths.append(p) for path in spaths: if path not in cfg_paths: if not os.path.exists(path): log.warning( 'config path "%s" does not exist, skipping.' % path) continue log.debug('reading config external path: "%s".' % path) cfg_paths = cfg_paths + (path, ) return cfg_paths def _get_qss_paths(self, paths=[]): """ Read stylesheets from config paths. :param list paths: list of paths to add to the scan. :returns: array of search paths. :rtype: tuple """ if paths and type(paths) in [str, unicode]: paths = [ paths, ] qss_paths = () qss_paths = qss_paths + (options.SCENEGRAPH_STYLESHEET_PATH, ) # read external paths if 'SCENEGRAPH_STYLESHEET_PATH' in os.environ: qpaths = os.getenv('SCENEGRAPH_STYLESHEET_PATH').split(':') if paths: for p in paths: if p not in qpaths: qpaths.append(p) for path in qpaths: if path not in qss_paths: if not os.path.exists(path): log.warning( 'stylesheet path "%s" does not exist, skipping.' % path) continue log.debug('reading external stylesheet path: "%s".' % path) qss_paths = qss_paths + (path, ) return qss_paths def _get_config_files(self, paths=[]): """ Get config files. :param list path: ist of paths to add to the scan. :returns: dictionary of config names/filenames. :rtype: dict """ cfg_files = dict() if not paths: return [] for path in paths: for fn in os.listdir(path): bn, fext = os.path.splitext(fn) if fext.lower() in ['.ini', '.cfg']: cfg_file = os.path.join(path, fn) names = bn.split('-') if len(names) < 2: log.warning('improperly named config file: "%s"' % cfg_file) continue style_name, cfg_type = names if style_name not in cfg_files: cfg_files[style_name] = dict(fonts=None, palette=None) log.debug('adding %s config "%s" from "%s".' % (cfg_type, style_name, cfg_file)) cfg_files[style_name][cfg_type] = cfg_file return cfg_files def _get_qss_files(self, paths=[]): """ Get qss files. :param list path: ist of paths to add to the scan. :returns: dictionary of stylesheet names/filenames. :rtype: dict """ qss_files = dict() if not paths: return [] for path in paths: for fn in os.listdir(path): bn, fext = os.path.splitext(fn) if fext.lower() in ['.qss', '.css']: qss_file = os.path.join(path, fn) if qss_file not in qss_files.values(): style_name = self._parse_stylesheet_name(qss_file) if style_name is None: log.warning('cannot parse style name from "%s".' % qss_file) style_name = 'no-style' log.debug('adding stylesheet "%s" from "%s".' % (style_name, qss_file)) if style_name not in qss_files: qss_files[style_name] = qss_file return qss_files def _parse_stylesheet_name(self, filename): """ Parse the stylesheet name from a file. :param str: filename to read. :returns: style name. :rtype: str """ style_name = None if os.path.exists(filename): for line in open(filename, 'r'): line = line.rstrip('\n') rline = line.lstrip(' ') rline = rline.rstrip() smatch = re.search(regex.get('style_name'), rline) if smatch: style_name = smatch.group('style') break return style_name def add_config(self, filename, name=None): """ Add a config to the config files attribute. :param str filename: filename to read. :param str name: name of the config. """ if filename in self._config_files.values(): for cfg_name, cfg_file in self._config_files.iteritems(): if cfg_file == filename: if name != cfg_name: self._config_files.pop(cfg_name) self._config_files[name] = filename #- Fonts ----- def initializeFontsList(self, valid=[]): """ Builds the manager fonts list. :param list valid: list of valid font names. :returns: dictionary of fonts. :rtype: dict """ if not valid: valid = [ x for fontlist in options.SCENEGRAPH_VALID_FONTS.values() for x in fontlist ] result = dict(ui=[], mono=[]) for font_name in self._font_db.families(): if font_name in valid: if not self._font_db.isFixedPitch(font_name): result['ui'].append(font_name) else: result['mono'].append(font_name) return result def buildUIFontList(self, valid=[]): """ Returns a list of monospace fonts. """ if not valid: valid = options.SCENEGRAPH_VALID_FONTS.get('ui') families = [] for font_name in self._fonts.get('ui'): if font_name in valid: families.append(font_name) return families def buildMonospaceFontList(self, valid=[]): """ Returns a list of monospace fonts. """ if not valid: valid = options.SCENEGRAPH_VALID_FONTS.get('mono') families = [] for font_name in self._fonts.get('mono'): if font_name in valid: families.append(font_name) return families def buildNodesFontList(self, valid=[]): """ Returns a list of fonts for node display. """ if not valid: valid = options.SCENEGRAPH_VALID_FONTS.get('nodes') families = [] all_fonts = [x for fontlist in self._fonts.values() for x in fontlist] for font_name in all_fonts: if font_name in valid: families.append(font_name) return families def font_defaults(self, platform=None, style='default'): """ Builds a dictionary of font & size defaults by platform. :param str platform: os type :returns: font and font size defaults dictionary. :rtype: dict """ if platform is None: platform = options.PLATFORM defaults = dict() def_font_config = self.config_files(style).get('fonts', None) if not os.path.exists(def_font_config): log.error('config "%s" does not exist.' % def_font_config) return defaults parser = StyleParser(self) data = parser._parse_configs(def_font_config) data = parser._parse_platform_data(data) # substitute attribute names for attr, val in data.iteritems(): attr = re.sub('-', '_', attr) defaults[attr] = val return defaults
from PySide.QtCore import Qt, QCoreApplication from PySide.QtGui import QPixmap, QFont, QFontDatabase, QApplication, QSplashScreen #create application and set properties if __name__ == '__main__': #QCoreApplication.setAttribute(Qt.AA_ShareOpenGLContexts) #QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) app = QApplication(sys.argv) app.setOrganizationName('Bioinformatics and Integrative Genomics') app.setOrganizationDomain('http://big.cdu.edu.cn') app.setApplicationName('Krait') #set font family QFontDatabase.addApplicationFont(":/fonts/roboto.ttf") #support windows 7, 10 taskbar icon import ctypes if os.name == 'nt': myappid = 'BIG.Krait.ssr.1.0' ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) splash_img = QPixmap(":/icons/splash.png") splash = QSplashScreen(splash_img) splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen | Qt.FramelessWindowHint) splash.setStyleSheet("font-family:roboto; font-size: 14px;") splash.setEnabled(False) splash.show()
#* as published by the Free Software Foundation; either version 2 of * #* the License, or (at your option) any later version. * #* for detail see the LICENCE text file. * #* * #* FreeCAD is distributed in the hope that it will be useful, * #* but WITHOUT ANY WARRANTY; without even the implied warranty of * #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * #* GNU Lesser General Public License for more details. * #* * #* You should have received a copy of the GNU General Public License * #* along with Dimensioning FreeCAD Workbench. * #* If not, see <https://www.gnu.org/licenses/> * #* * #***************************************************************************/ import FreeCADGui, FreeCAD import Dimensioning_rc #create resources import Page import Orthographic import Annotation import Image import Test from PySide.QtGui import QFontDatabase # load default font QFontDatabase.addApplicationFont(":/fonts/ISO_3098.ttf") QFontDatabase.addApplicationFont(":/fonts/ISO_3098Italic.ttf")
class StylesheetManager(object): """ The StylesheetManager reads and parses stylesheet data, plus does some basic sass substitution via external config files. :param QtGui.QWidget parent: parent UI. :param str style: default style name. :param list paths: additional search paths. """ def __init__(self, parent=None, style='default', paths=[]): from PySide.QtGui import QFontDatabase self._ui = parent # parent UI self._style = style # style to parse self._font_db = QFontDatabase() # font database self._fonts = dict() # dictionary of valid font types (ui, mono) self._config_paths = () # paths for cfg mods self._config_files = dict() # cfg files self._qss_paths = () # qss file paths self._qss_files = dict() # qss files self._initialized = False # debugging data self._data = dict() if not self._initialized: self.run(paths=paths) def run(self, paths=[]): """ Read all of the currently defined config files/stylesheets. :param str style: style name to parse. :param list paths: additional search paths. """ self._fonts = self.initializeFontsList() self._config_paths = self._get_config_paths(paths=paths) self._config_files = self._get_config_files(self._config_paths) self._qss_paths = self._get_qss_paths(paths=paths) self._qss_files = self._get_qss_files(self._qss_paths) # set parent defaults if not already set defaults = self.font_defaults() for default in defaults.keys(): if hasattr(self._ui, default): if getattr(self._ui, default) is None: value = defaults.get(default) #print '# DEBUG: setting UI default; "%s", "%s"' % (default, value) setattr(self._ui, default, value) self._initialized = True @property def style(self): return self._style def style_data(self, **kwargs): """ Return the stylesheet data. :returns: parsed stylesheet data. :rtype: str """ stylesheet_name = kwargs.pop('stylesheet_name', 'default') palette_style = kwargs.pop('palette_style', 'default') font_style = kwargs.pop('font_style', 'default') self._data = dict() parser = StyleParser(self, style=stylesheet_name, palette_style=palette_style, font_style=font_style) parser.run(style=stylesheet_name, palette_style=palette_style, font_style=font_style) data = parser.data(**kwargs) # grab data here for debugging self._data = parser._data return data @property def config_names(self): """ Returns a list of config file names. :returns: list of config names. :rtype: list """ return self._config_files.keys() def config_files(self, style='default'): """ Returns a dictionary of config files for the given style. :param str style: style name to return. :returns: font/palette config files. :rtype: dict """ return self._config_files.get(style, {}) @property def qss_names(self): """ Returns a list of stylesheet file names. :returns: list of stylesheet names. :rtype: list """ return self._qss_files.keys() @property def palette_styles(self): """ Returns a list of palette style names. :returns: list of palette names. :rtype: list """ styles = [] for style_name, files in self._config_files.iteritems(): if 'palette' in files: value = files.get('palette', None) if value is not None: if os.path.exists(value): styles.append(style_name) return styles @property def font_styles(self): """ Returns a list of font style names. :returns: list of font style names. :rtype: list """ styles = [] for style_name, files in self._config_files.iteritems(): if 'fonts' in files: value = files.get('fonts', None) if value is not None: if os.path.exists(value): styles.append(style_name) return styles @property def qss_files(self): return self._qss_files.values() def _get_config_paths(self, paths=[]): """ Read configs from config paths. :param list paths: list of paths to add to the scan. :returns: array of search paths. :rtype: tuple """ if paths and type(paths) in [str, unicode]: paths = [paths,] cfg_paths = () cfg_paths = cfg_paths + (options.SCENEGRAPH_CONFIG_PATH,) # read external paths if 'SCENEGRAPH_CONFIG_PATH' in os.environ: spaths = os.getenv('SCENEGRAPH_CONFIG_PATH').split(':') if paths: for p in paths: if p not in spaths: spaths.append(p) for path in spaths: if path not in cfg_paths: if not os.path.exists(path): log.warning('config path "%s" does not exist, skipping.' % path) continue log.debug('reading config external path: "%s".' % path) cfg_paths = cfg_paths + (path,) return cfg_paths def _get_qss_paths(self, paths=[]): """ Read stylesheets from config paths. :param list paths: list of paths to add to the scan. :returns: array of search paths. :rtype: tuple """ if paths and type(paths) in [str, unicode]: paths = [paths,] qss_paths = () qss_paths = qss_paths + (options.SCENEGRAPH_STYLESHEET_PATH,) # read external paths if 'SCENEGRAPH_STYLESHEET_PATH' in os.environ: qpaths = os.getenv('SCENEGRAPH_STYLESHEET_PATH').split(':') if paths: for p in paths: if p not in qpaths: qpaths.append(p) for path in qpaths: if path not in qss_paths: if not os.path.exists(path): log.warning('stylesheet path "%s" does not exist, skipping.' % path) continue log.debug('reading external stylesheet path: "%s".' % path) qss_paths = qss_paths + (path,) return qss_paths def _get_config_files(self, paths=[]): """ Get config files. :param list path: ist of paths to add to the scan. :returns: dictionary of config names/filenames. :rtype: dict """ cfg_files = dict() if not paths: return [] for path in paths: for fn in os.listdir(path): bn, fext = os.path.splitext(fn) if fext.lower() in ['.ini', '.cfg']: cfg_file = os.path.join(path, fn) names = bn.split('-') if len(names) < 2: log.warning('improperly named config file: "%s"' % cfg_file) continue style_name, cfg_type = names if style_name not in cfg_files: cfg_files[style_name] = dict(fonts=None, palette=None) log.debug('adding %s config "%s" from "%s".' % (cfg_type, style_name, cfg_file)) cfg_files[style_name][cfg_type] = cfg_file return cfg_files def _get_qss_files(self, paths=[]): """ Get qss files. :param list path: ist of paths to add to the scan. :returns: dictionary of stylesheet names/filenames. :rtype: dict """ qss_files = dict() if not paths: return [] for path in paths: for fn in os.listdir(path): bn, fext = os.path.splitext(fn) if fext.lower() in ['.qss', '.css']: qss_file = os.path.join(path, fn) if qss_file not in qss_files.values(): style_name = self._parse_stylesheet_name(qss_file) if style_name is None: log.warning('cannot parse style name from "%s".' % qss_file) style_name = 'no-style' log.debug('adding stylesheet "%s" from "%s".' % (style_name, qss_file)) if style_name not in qss_files: qss_files[style_name] = qss_file return qss_files def _parse_stylesheet_name(self, filename): """ Parse the stylesheet name from a file. :param str: filename to read. :returns: style name. :rtype: str """ style_name = None if os.path.exists(filename): for line in open(filename,'r'): line = line.rstrip('\n') rline = line.lstrip(' ') rline = rline.rstrip() smatch = re.search(regex.get('style_name'), rline) if smatch: style_name = smatch.group('style') break return style_name def add_config(self, filename, name=None): """ Add a config to the config files attribute. :param str filename: filename to read. :param str name: name of the config. """ if filename in self._config_files.values(): for cfg_name, cfg_file in self._config_files.iteritems(): if cfg_file == filename: if name != cfg_name: self._config_files.pop(cfg_name) self._config_files[name] = filename #- Fonts ----- def initializeFontsList(self, valid=[]): """ Builds the manager fonts list. :param list valid: list of valid font names. :returns: dictionary of fonts. :rtype: dict """ if not valid: valid = [x for fontlist in options.SCENEGRAPH_VALID_FONTS.values() for x in fontlist] result = dict(ui=[], mono=[]) for font_name in self._font_db.families(): if font_name in valid: if not self._font_db.isFixedPitch(font_name): result['ui'].append(font_name) else: result['mono'].append(font_name) return result def buildUIFontList(self, valid=[]): """ Returns a list of monospace fonts. """ if not valid: valid = options.SCENEGRAPH_VALID_FONTS.get('ui') families = [] for font_name in self._fonts.get('ui'): if font_name in valid: families.append(font_name) return families def buildMonospaceFontList(self, valid=[]): """ Returns a list of monospace fonts. """ if not valid: valid = options.SCENEGRAPH_VALID_FONTS.get('mono') families = [] for font_name in self._fonts.get('mono'): if font_name in valid: families.append(font_name) return families def buildNodesFontList(self, valid=[]): """ Returns a list of fonts for node display. """ if not valid: valid = options.SCENEGRAPH_VALID_FONTS.get('nodes') families = [] all_fonts = [x for fontlist in self._fonts.values() for x in fontlist] for font_name in all_fonts: if font_name in valid: families.append(font_name) return families def font_defaults(self, platform=None, style='default'): """ Builds a dictionary of font & size defaults by platform. :param str platform: os type :returns: font and font size defaults dictionary. :rtype: dict """ if platform is None: platform = options.PLATFORM defaults = dict() def_font_config = self.config_files(style).get('fonts', None) if not os.path.exists(def_font_config): log.error('config "%s" does not exist.' % def_font_config) return defaults parser = StyleParser(self) data = parser._parse_configs(def_font_config) data = parser._parse_platform_data(data) # substitute attribute names for attr, val in data.iteritems(): attr = re.sub('-', '_', attr) defaults[attr] = val return defaults
def main(): """ @return int """ import os, sys from PySide.QtCore import QTextCodec # Use UTF-8 encoding for Qt #sys_codec = QTextCodec.codecForLocale() u8codec = QTextCodec.codecForName("UTF-8") QTextCodec.setCodecForCStrings(u8codec) QTextCodec.setCodecForTr(u8codec) debug = '--debug' in sys.argv # bool print >> sys.stderr, "reader: debug = %s" % debug from sakurakit import skdebug #skdebug.DEBUG = config.APP_DEBUG or '--debug' in sys.argv skdebug.DEBUG = debug import config config.APP_DEBUG = debug from sakurakit.skdebug import dprint, dwarn dprint("enter") if '--help' in sys.argv: print_help() dprint("exit: help") #sys.exit(os.EX_USAGE) return 0 # Singleton # - Through mutex # See: http://code.activestate.com/recipes/474070-creating-a-single-instance-application/ # See: http://code.google.com/p/python-windows-tiler/source/browse/singleinstance.py # - Through file # See: http://stackoverflow.com/questions/380870/python-single-instance-of-program dprint("check single instance") from lockfile import lockfile app_mutex = lockfile.SingleProcessMutex() single_app = app_mutex.tryLock() if not single_app: dprint("multiple instances are running") dprint("python = %s" % sys.executable) #dprint("rootdir = %s" % rootdir) #dprint("mecabrc = %s" % mecabrc_path) from sakurakit import skos # Must be set before any GUI is showing up # http://stackoverflow.com/questions/1551605/how-to-set-applications-taskbar-icon-in-windows-7 if skos.WIN: dprint("set app id") from sakurakit import skwin skwin.set_app_id("org.sakurakit.reader") # Detect user language import settings ss = settings.global_() uilang = ss.uiLanguage() if not uilang: uilang = guess_language() ss.setValue('Language', uilang) lang = ss.userLanguage() if not lang: lang = guess_language() ss.setValue('UserLanguage', lang) dprint("user language = %s" % lang) # Warm-up shiboken dlls #if os.name == 'nt': # dprint("load shiboken plugins") # import pytexscript # import pytexthook #Switch to OpenGL engine #from Qt5.QtWidgets import QApplication #QApplication.setGraphicsSystem("opengl") #dprint("elevate process priviledges") #from sakurakit import skos #if skos.WIN: # from sakurakit import skwin # skwin.enable_drop_event() dprint("init dic locations") from opencc import opencc opencc.setdicpaths(config.OPENCC_DICS) from hanviet import hanviet hanviet.setdicpaths(config.HANVIET_DICS) from hanjaconv import hanjaconv hanjaconv.setdicdir(config.HANJA_DIC_PATH) from pinyinconv import pinyinconv pinyinconv.setdicpath(config.PINYIN_DIC_PATH) dprint("create app") import app a = app.Application(sys.argv) #dprint("os default font:", a.font()) #a.setFont(config.FONT_DEFAULT) #dprint("current default font:", a.font()) # Fix the encoding issue for the current directory #from PySide.QtCore import QDir #QDir.setCurrent(a.applicationDirPath()) if not single_app: from rpcman import RpcClient dprint("send metacall") r = RpcClient() r.start() if r.waitForConnected(): r.activate() a.processEvents() else: dprint("warning: cannot connect to the server") dwarn("leave: multiple instance") #sys.exit(os.EX_UNAVAILABLE) return 0 # Must come after QApplication is created dprint("load fonts") from PySide.QtGui import QFontDatabase for path in config.FONT_LOCATIONS.itervalues(): if os.path.exists(path): for root, dirs, files in os.walk(path): FONT_EXTS = frozenset(('.otf', '.ttf', '.ttc')) for f in files: if os.path.splitext(f.lower())[1] in FONT_EXTS: p = os.path.join(root, f) index = QFontDatabase.addApplicationFont(p) if index >= 0: dprint( QFontDatabase.applicationFontFamilies(index)) else: dwarn("failed to load font %s" % f) ff = config.ui_font(ss.uiLanguage()) if ff: a.setFontFamily(ff) #ff = ss.applicationFontFamily() #if ff: # dprint("font family = %s" % ff) # a.setFontFamily(ff) #ss.applicationFontFamilyChanged.connect(a.setFontFamily) dprint("load translation") a.loadTranslations() dprint("autosync settings") ss.autoSync() # Load before qapplication is created opt_splash = '--nosplash' not in sys.argv if opt_splash: dprint("show splash") from splashscreen import StartupSplashScreen splash = StartupSplashScreen() splash.show() a.processEvents() # process event to make it show #dprint("cache fonts") #import fonts #fonts.test() # Take the ownership of sakurakit translation dprint("take the ownership of translations") from sakurakit import sktr sktr.manager().setParent(a) import mytr mytr.manager().setParent(a) mytr.my.setParent(a) # There should be at least one existing window (rootWindow), or sth is wrong #a.setQuitOnLastWindowClosed(False) #dprint("check unicode codec") #from sakurakit.skunicode import qunicode #ustr = qunicode("あのね", 'utf8') #assert ustr, "failed to load text code plugin from qt.conf" #dprint('init directories') #from PySide.QtCore import QDir import rc from sakurakit import skfileio dprint("remove broken caches") for it in rc.DIR_APP_TMP, : if os.path.exists(it): skfileio.removetree(it) map( skfileio.makedirs, ( rc.DIR_YAML_SUB, rc.DIR_XML_COMMENT, rc.DIR_XML_VOICE, rc.DIR_XML_REF, #rc.DIR_DICT_MECAB, # not used rc.DIR_CACHE_AVATAR, rc.DIR_CACHE_AWS, rc.DIR_CACHE_DATA, rc.DIR_CACHE_IMAGE, rc.DIR_CACHE_DMM, rc.DIR_CACHE_TOKUTEN, rc.DIR_CACHE_FREEM, rc.DIR_CACHE_STEAM, rc.DIR_CACHE_MELON, rc.DIR_CACHE_GETCHU, rc.DIR_CACHE_GYUTTO, rc.DIR_CACHE_DIGIKET, rc.DIR_CACHE_DLSITE, rc.DIR_CACHE_HOLYSEAL, rc.DIR_CACHE_SCAPE, rc.DIR_CACHE_TRAILERS, rc.DIR_CACHE_WEB, rc.DIR_CACHE_SYNC, rc.DIR_TMP_OCR, rc.DIR_TMP_TERM, # not needed, though rc.DIR_TMP_TTS, )) if skos.WIN: from sakurakit import skwin for it in rc.DIR_APP_LIBRARY, rc.DIR_APP_CACHE: if os.path.exists(it): skwin.set_file_readonly(it) dprint("load settings") ss.setParent(a) dprint("append library path") from sakurakit import skpaths skpaths.append_paths(( # TransCAT must be initialized BEFORE JBeijing, or the translation will fail ss.transcatLocation(), ss.jbeijingLocation(), ss.ezTransLocation(), ss.atlasLocation(), ss.zunkoLocation(), ss.localeEmulatorLocation(), ss.ntleasLocation(), os.path.join(ss.dreyeLocation(), r"DreyeMT\SDK\bin") if ss.dreyeLocation() else "", )) path = ss.lecLocation() if path: skpaths.append_paths(( os.path.join(path, r"Nova\JaEn"), os.path.join(path, r"PARS\EnRU"), )) path = ss.fastaitLocation() if path: path = os.path.join(path, 'GTS') if os.path.exists(path): dllpaths = skfileio.listdirs(path) if dllpaths: skpaths.append_paths(dllpaths) if sys.getrecursionlimit() < config.PY_RECURSION_LIMIT: dprint("increase recursion limit") sys.setrecursionlimit(config.PY_RECURSION_LIMIT) dprint("reduce socket timeout") import socket socket.setdefaulttimeout(config.PY_SOCKET_TIMEOUT) #import threading #if threading.stack_size() < config.PY_STACK_SIZE: # dprint("increase stack size") # threading.stack_size(config.PY_STACK_SIZE) # On unix: # stackoverflow.com/questions/5061582/setting-stacksize-in-a-python-script #import resource #resource.setrlimit(resource.RLIMIT_STACK, (2**29,-1)) dprint("config python site-packages") # Disable requests SSL certificate warning # https://github.com/kennethreitz/requests/issues/2214 import requests requests.packages.urllib3.disable_warnings() # Disable HTTP request session # See: http://docs.python-requests.org/en/latest/user/advanced/#keep-alive # See: http://stackoverflow.com/questions/10115126/python-requests-close-http-connection #import requests #s = requests.session() #s.config['keep_alive'] = False import numpy numpy.seterr(all='ignore') # ignore overflow warning dprint("update settings") ss_version = ss.version() if ss_version != config.VERSION_TIMESTAMP: dprint("app update detected, migrate settings") if ss_version: migrate(ss_version) from sakurakit import skdatetime ss.setUpdateTime(skdatetime.current_unixtime()) ss.setVersion(config.VERSION_TIMESTAMP) ss.sync() if not ss.userName() or not ss.userId(): dprint("set user credential to guest") # Must be consistent with dataman.GUEST ss.setValue('UserId', 4) ss.setValue('UserName', 'guest') ss.setValue('UserPassword', 'guest') ss.setValue('UserGender', '') ss.setValue('UserAvatar', '') ss.setValue('UserColor', '') if ss.isCursorThemeEnabled(): dprint("load cursor theme") import curtheme curtheme.load() # Disable RBMT if CaboCha or UniDic is disabled #if ss.isTranslationSyntaxEnabled() and not ( # ss.isCaboChaEnabled() and ss.meCabDictionary() == 'unidic'): # ss.setTranslationSyntaxEnabled(False) #dprint("set max thread count") from PySide.QtCore import QThreadPool currentThreadCount = QThreadPool.globalInstance().maxThreadCount() if currentThreadCount < config.QT_THREAD_COUNT: dprint("increase thread pool capacity: %s -> %s" % (currentThreadCount, config.QT_THREAD_COUNT)) QThreadPool.globalInstance().setMaxThreadCount(config.QT_THREAD_COUNT) dprint("register qml plugins") import qmlplugin dprint("query system metrics") import sysinfo dprint("create main object") import main m = main.MainObject(a) m.init() if opt_splash: dprint("schedule to finish splash") splash.finishLater(1500) # hide after 1.5 seconds from functools import partial from sakurakit import skevents skevents.runlater(partial(m.run, a.arguments()), 50) #m.run(a.arguments()) #import netman #netman.manager().queryComments(gameId=183) #import hashutil #print hashutil.md5sum('/Users/jichi/tmp/t.cpp') dprint("exec") returnCode = a.exec_() # FIXME: Cannot normally exit # Shiboken 1.2 hang on exit! # All destructors are Invoked! dprint("unlock the mutex") app_mutex.unlock() import defs if returnCode == defs.EXIT_RESTART: skos.restart_my_process(['-B']) # -B: force disabling *.pyc and *.pyo else: #sys.exit(returnCode) #if skos.WIN: # prevent hanging on windows/mac skos.kill_my_process()