~openerp-chinese-team/openerp-china/openerp-china

« back to all changes in this revision

Viewing changes to oecn_base_fonts/oecn_font_installer.py

  • Committer: JoshuaJan
  • Date: 2013-03-28 09:08:19 UTC
  • Revision ID: popkar77@gmail.com-20130328090819-3h2qaqjnthe9ek68
moreĀ configure

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
#__author__ = jeff@openerp.cn, joshua@openerp.cn
 
3
 
 
4
from osv import fields, osv
 
5
from reportlab.lib.fontfinder import FontFinder
 
6
import openerp.report.render.rml2pdf.customfonts as cfonts
 
7
from reportlab.lib.styles import ParagraphStyle
 
8
from reportlab import rl_config
 
9
import simplejson as json
 
10
import re
 
11
 
 
12
try:
 
13
    from openerp import SUPERUSER_ID
 
14
except ImportError:
 
15
    SUPERUSER_ID = SUPERUSER_ID
 
16
    
 
17
#patch for ReportLab
 
18
import reportlab_patch
 
19
 
 
20
RMLS = ['rml_header', 'rml_header2', 'rml_header3']
 
21
OE_FONTS = ['Helvetica', 'DejaVuSans', 'Times', 'Times-Roman', 'Courier']
 
22
 
 
23
 
 
24
class oecn_base_fonts_map(osv.osv_memory):
 
25
    _name = 'oecn_base_fonts.map'
 
26
    _description = 'The line base fonts mapping'
 
27
 
 
28
    # try to get the font from the cache first (system_fonts)
 
29
    system_fonts = []
 
30
    
 
31
    def get_system_fonts(self, cr, uid, context=None):
 
32
        if self.system_fonts:
 
33
            return self.system_fonts
 
34
        else:
 
35
            return self._system_fonts_get(cr, uid)
 
36
        
 
37
    def _system_fonts_get(self, cr, uid, context=None):
 
38
        ''' get fonts list on server '''
 
39
        # consider both windows and unix like systems
 
40
        # get all folders under fonts/ directory
 
41
        res = []
 
42
        ff = FontFinder(useCache=False)
 
43
        fontdirs = []
 
44
        if not context:
 
45
            context = {}
 
46
        #if context.get('custom_font_path'):
 
47
            #fontdirs.append(context['custom_font_path'])
 
48
        fontdirs += rl_config.TTFSearchPath[:] + \
 
49
            rl_config.T1SearchPath[:] + \
 
50
            rl_config.CMapSearchPath[:]
 
51
        ff.addDirectories(set(fontdirs))
 
52
        ff.search()
 
53
        for familyName in ff.getFamilyNames():
 
54
            for font in ff.getFontsInFamily(familyName):
 
55
                if font.fileName[-4:].lower() in (".ttf", ".ttc"):
 
56
                    try:
 
57
                        fileName = font.fileName.decode('utf-8')
 
58
                    except UnicodeDecodeError:
 
59
                        #for Chinese file name(Windows OS)
 
60
                        fileName = font.fileName.decode('gbk')
 
61
                    res.append((fileName, font.name))
 
62
 
 
63
        #cache the font list in class variable
 
64
        oecn_base_fonts_map.system_fonts = res
 
65
        return res
 
66
 
 
67
    def _pdf_fonts_get(self, cr, uid, context=None):
 
68
        return [('Helvetica', 'Helvetica'),
 
69
                ('DejaVuSans', 'DejaVuSans'),
 
70
                ('Times', 'Times'),
 
71
                ('Times-Roman', 'Times-Roman'),
 
72
                ('Courier', 'Courier')]
 
73
 
 
74
    _columns = {
 
75
        'pdf_font': fields.selection(_pdf_fonts_get, 'Original Fonts', 
 
76
                                     required=True),
 
77
        'new_font': fields.selection(get_system_fonts, 'Replaced With', 
 
78
                                     required=True),
 
79
        'name': fields.char('Font Alias', size=20, required=True, 
 
80
                            help='use this font alias in custom rml report \
 
81
                            template'),        
 
82
    }
 
83
    
 
84
    def onchange_new_font(self, cr, uid, ids, new_font):
 
85
        """get the default 'Font Alias'"""
 
86
 
 
87
        for font_path, font_name in self.system_fonts:
 
88
            if new_font == font_path:
 
89
                return {'value': {'name': font_name}}
 
90
            
 
91
oecn_base_fonts_map()
 
92
 
 
93
 
 
94
class oecn_font_installer(osv.osv_memory):
 
95
    _name = 'oecn.font.installer'
 
96
    _inherit = 'res.config.installer'
 
97
    
 
98
    def _convert_system_font_2_base_font(self, wrap_style, new_mappings):
 
99
        if not new_mappings:
 
100
            return False
 
101
        new_mappings = json.loads(new_mappings)
 
102
        cfonts.CustomTTFonts = new_mappings
 
103
        if wrap_style:
 
104
            ParagraphStyle.defaults['wordWrap'] = 'CJK'
 
105
        return True
 
106
                    
 
107
    def __init__(self, pool, cr):
 
108
        super(osv.osv_memory, self).__init__(pool, cr)
 
109
        config_obj = pool.get("ir.config_parameter")
 
110
        wrap_style = config_obj.get_param(cr, SUPERUSER_ID, 'wrap_style')
 
111
        new_mappings = config_obj.get_param(cr, SUPERUSER_ID, 'fonts_map')
 
112
        self._convert_system_font_2_base_font(wrap_style, new_mappings)
 
113
        
 
114
    _columns = {
 
115
        'wrap': fields.boolean('CJK wrap', required=True, 
 
116
                               help="If you are using CJK fonts, \
 
117
                               check this option will wrap your \
 
118
                               words properly at the edge of the  pdf report"),
 
119
        'map_ids': fields.many2many('oecn_base_fonts.map', 
 
120
                                    'oecn_base_font_conf_ref',
 
121
                                    'conf_id', 'map_id', 'Replace Fonts'),
 
122
        
 
123
    }
 
124
    
 
125
    def _get_wrap(self, cr, uid, *args):
 
126
        wrap_style = self.pool.get('ir.config_parameter').get_param(
 
127
            cr, SUPERUSER_ID, 'wrap_style')
 
128
        return wrap_style
 
129
 
 
130
    def _get_map_ids(self, cr, uid, *args):
 
131
        mappings = self.pool.get('ir.config_parameter').get_param(
 
132
            cr, SUPERUSER_ID, 'fonts_map')
 
133
 
 
134
        mappings_obj = self.pool.get('oecn_base_fonts.map')
 
135
        default_fonts = None, None
 
136
        ids = []
 
137
        if mappings:
 
138
            mappings = json.loads(mappings)        
 
139
            for mapping in mappings:
 
140
                val = {'pdf_font': mapping[0],
 
141
                       'name': mapping[1],
 
142
                       'new_font': mapping[2]}
 
143
                try:
 
144
                    id = mappings_obj.create(cr, uid, val)
 
145
                    ids.append(id)
 
146
                except Exception:
 
147
                    mappings = None
 
148
                    mappings_obj.unlink(cr, uid, ids)
 
149
        if not mappings:
 
150
            system_fonts = mappings_obj.get_system_fonts(cr, uid)
 
151
            for font_path, name, in system_fonts: 
 
152
                if name in ('SimHei', 'SimSun', 'WenQuanYiZenHei'):
 
153
                    default_fonts = (font_path, name)
 
154
                    break
 
155
            for fonts in OE_FONTS:
 
156
                val = {'pdf_font': fonts,
 
157
                       'name': default_fonts[1] or system_fonts[0][1],
 
158
                       'new_font': default_fonts[0] or system_fonts[0][0]}
 
159
                id = mappings_obj.create(cr, uid, val)
 
160
                ids.append(id)                    
 
161
        return ids
 
162
 
 
163
    _defaults = {
 
164
        'wrap': _get_wrap,
 
165
        'map_ids': _get_map_ids,
 
166
    }
 
167
    
 
168
    def execute(self, cr, uid, ids, context=None):
 
169
        company_obj = self.pool.get('res.company')
 
170
        company_ids = company_obj.search(cr, uid, [])
 
171
        p = re.compile('<setFont name=".*?" ')
 
172
        for o in self.browse(cr, uid, ids, context=context):
 
173
            config_obj = self.pool.get('ir.config_parameter')
 
174
            new_mappings = json.dumps([(new_mapping.pdf_font,
 
175
                                        new_mapping.name,
 
176
                                        new_mapping.new_font,
 
177
                                        'all') 
 
178
                                       for new_mapping in o.map_ids])
 
179
            config_obj.set_param(cr, uid, 'wrap_style', o.wrap)
 
180
            config_obj.set_param(cr, uid, 'fonts_map', new_mappings)
 
181
            for company in company_obj.read(cr, uid, company_ids, RMLS):
 
182
                '''
 
183
                To be improved
 
184
                Becacuse some report(header and footer, custom_default.xml, 
 
185
                hr_custom_default.xml, hr_custom_default.xml) 
 
186
                releady  <setfont='DejaVu sans'/>  in the rml.             
 
187
                '''
 
188
                value = {}
 
189
                for rml in RMLS:
 
190
                    new_font_rml = '<setFont name="' + o.map_ids[0].name + '" '
 
191
                    value[rml] = p.sub(new_font_rml, company[rml])
 
192
                company_obj.write(cr, uid, company['id'], value)            
 
193
            self._convert_system_font_2_base_font(o.wrap, new_mappings)
 
194
            
 
195
        
 
196
            
 
197
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 
198