1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
## Fonty Python Copyright (C) 2006, 2007, 2008, 2009 Donn.C.Ingle
## Contact: donn.ingle@gmail.com - I hope this email lasts.
##
## This file is part of Fonty Python.
## Fonty Python is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## Fonty Python 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 General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Fonty Python. If not, see <http://www.gnu.org/licenses/>.
import os, subprocess, errno
class CharMapApp(object):
'''
Base class for whatever character viewer apps I may support.
'''
def __init__( self, appname ):
self.appname = appname
self.is_installed = self.do_i_exist()
def do_i_exist( self ):
for path in os.environ.get('PATH', '').split(':'):
if os.path.exists(os.path.join(path, self.appname)) and \
not os.path.isdir(os.path.join(path, self.appname)):
return True
return False
def OpenApp( self, *args ): pass
def Cleanup( self ): pass
def Run( self, cmd ):
proc = subprocess.Popen( cmd, shell=False )
## gucharmap: Fonty actually holds still and waits here until gucharmap is closed.
## kfontview: Fonty just runs-through. kfontview is a different beast.
## Both still work and Fonty stays active. Multiple instances of the viewers can be opened!
proc.wait()
class Gucharmap( CharMapApp ):
'''
The wiring needed to support gucharmap.
It requires a dodge before and after spawning the app --
one must temporarily install the font to be viewed
and then remove it again afterwards.
'''
def OpenApp( self, *args ):
src=args[0]
dest=args[1]
self.dest = dest
fam=args[2]
sz=args[3]
cmd = [ self.appname, u'--font=%s, %s' % (fam, sz)]
## gucharmap requires the font to be installed already, so fake it:
self.already_installed = False
try:
os.symlink( src, dest )
except OSError, detail:
if detail.errno != errno.EEXIST:
# Not EEXIST means the link failed, don't open the charmap
return False
else:
# Error EEXIST: file exists.
# User may have installed it previously (or something).
self.already_installed = True
self.Run( cmd )
def Cleanup( self ):
# Remove the fake installed font -- if it's a candidate:
if not self.already_installed:
try:
os.unlink( self.dest )
except:
# What to do? Start yelling? Nah...
pass
class Kfontview( CharMapApp ):
'''
Wiring for kfontview -- really easy to use.
'''
def OpenApp( self, *args ):
url=args[0]
cmd = [ self.appname, u'%s' % url]
self.Run( cmd )
## Oct 2009
class CharMapController(object):
'''
Control the character map viewing objects (above) that Fonty supports.
UNSET is always the initial "chosen app" when this instantiates.
'''
def __init__( self, config_callback ):
self.config_callback = config_callback
SUPPORTED_CHAR_MAP_APPS = { "gucharmap":Gucharmap, "kfontview":Kfontview }
## Which of the supported apps are actually available?
self.AVAILABLE_APP_DICT = {}
for appname, klass in SUPPORTED_CHAR_MAP_APPS.iteritems():
## Instantiate an app class:
i = klass( appname )
if i.is_installed: self.AVAILABLE_APP_DICT[appname] = i
## Flag to signify if there are available apps to use.
self.APPS_ARE_AVAILABLE = False if len(self.AVAILABLE_APP_DICT) == 0 else True
self.__CURRENT_APPNAME = "UNSET"
self.QUICK_APPNAME_LIST = self.AVAILABLE_APP_DICT.keys()
def SET_CURRENT_APPNAME(self, x):
## If the new name (x) is UNSET or some appname that is not available
## then give x a new value of the first thing in the list of what is
## actually available.
if x not in self.QUICK_APPNAME_LIST and self.APPS_ARE_AVAILABLE:
x = self.QUICK_APPNAME_LIST[0]
self.__CURRENT_APPNAME = x ## It's possible that x is "UNSET"
self.config_callback( x ) ## go set the config's app_char_map var too.
def GET_CURRENT_APPNAME( self ):
'''
This is only called when APPS_ARE_AVAILABLE is True: See dialogues.py
Think of this as raising an error if APPS_ARE_AVAILABLE is False!
'''
if self.__CURRENT_APPNAME == "UNSET":
x = self.QUICK_APPNAME_LIST[0]
return x
else:
return self.__CURRENT_APPNAME
def GetInstance( self ):
'''
This is only called when APPS_ARE_AVAILABLE is True: See gui_Fitmap.py
in can_have_button method.
Think of this as raising an error if APPS_ARE_AVAILABLE is False!
'''
## Fetch an instance from my dict
return self.AVAILABLE_APP_DICT[ self.__CURRENT_APPNAME ]
|