[MERGE] from trunk after fonts have been added
bzr revid: xmo@openerp.com-20131015114534-bmuu05j125s9mbo9
This commit is contained in:
Vendored
+7
-1
@@ -47,7 +47,13 @@ Depends:
|
||||
Conflicts: tinyerp-server, openerp-server, openerp-web
|
||||
Replaces: tinyerp-server, openerp-server, openerp-web
|
||||
Recommends:
|
||||
graphviz, ghostscript, postgresql, python-matplotlib, poppler-utils
|
||||
antiword,
|
||||
graphviz,
|
||||
ghostscript,
|
||||
postgresql,
|
||||
python-gevent,
|
||||
python-matplotlib,
|
||||
poppler-utils
|
||||
Description: OpenERP Enterprise Resource Management
|
||||
OpenERP, previously known as TinyERP, is a complete ERP and CRM. The main
|
||||
features are accounting (analytic and financial), stock management, sales and
|
||||
|
||||
@@ -25,6 +25,7 @@ import res_partner
|
||||
import res_bank
|
||||
import res_config
|
||||
import res_currency
|
||||
import res_font
|
||||
import res_company
|
||||
import res_users
|
||||
import res_request
|
||||
|
||||
@@ -112,9 +112,6 @@ class res_company(osv.osv):
|
||||
|
||||
def _get_companies_from_partner(self, cr, uid, ids, context=None):
|
||||
return self.pool['res.company'].search(cr, uid, [('partner_id', 'in', ids)], context=context)
|
||||
|
||||
def _get_font(self, cr, uid, context=None):
|
||||
return sorted(customfonts.RegisterCustomFonts())
|
||||
|
||||
_columns = {
|
||||
'name': fields.related('partner_id', 'name', string='Company Name', size=128, required=True, store=True, type='char'),
|
||||
@@ -128,7 +125,7 @@ class res_company(osv.osv):
|
||||
'rml_footer': fields.text('Report Footer', help="Footer text displayed at the bottom of all reports."),
|
||||
'rml_footer_readonly': fields.related('rml_footer', type='text', string='Report Footer', readonly=True),
|
||||
'custom_footer': fields.boolean('Custom Footer', help="Check this to define the report footer manually. Otherwise it will be filled in automatically."),
|
||||
'font': fields.selection(_get_font, "Font",help="Set the font into the report header, will be used for every RML report of the company"),
|
||||
'font': fields.many2one('res.font', string="Font",help="Set the font into the report header, it will be used as default font in the RML reports of the user company"),
|
||||
'logo': fields.related('partner_id', 'image', string="Logo", type="binary"),
|
||||
'logo_web': fields.function(_get_logo_web, string="Logo Web", type="binary", store={
|
||||
'res.company': (lambda s, c, u, i, x: i, ['partner_id'], 10),
|
||||
@@ -192,10 +189,11 @@ class res_company(osv.osv):
|
||||
|
||||
default_para = re.sub('fontName.?=.?".*"', 'fontName="%s"'% font,header)
|
||||
return re.sub('(<setFont.?name.?=.?)(".*?")(.)', '\g<1>"%s"\g<3>'% font,default_para)
|
||||
fontname = self.pool.get('res.font').browse(cr, uid, font, context=context).name
|
||||
return {'value':{
|
||||
'rml_header': _change_header(rml_header,font),
|
||||
'rml_header2':_change_header(rml_header2,font),
|
||||
'rml_header3':_change_header(rml_header3,font)
|
||||
'rml_header': _change_header(rml_header,fontname),
|
||||
'rml_header2':_change_header(rml_header2,fontname),
|
||||
'rml_header3':_change_header(rml_header3,fontname)
|
||||
}}
|
||||
|
||||
def on_change_country(self, cr, uid, ids, country_id, context=None):
|
||||
@@ -294,6 +292,15 @@ class res_company(osv.osv):
|
||||
def _get_logo(self, cr, uid, ids):
|
||||
return open(os.path.join( tools.config['root_path'], 'addons', 'base', 'res', 'res_company_logo.png'), 'rb') .read().encode('base64')
|
||||
|
||||
def _get_font(self, cr, uid, ids):
|
||||
font_obj = self.pool.get('res.font')
|
||||
res = font_obj.search(cr, uid, [('name', '=', 'Helvetica')], limit=1)
|
||||
if res:
|
||||
return res[0]
|
||||
|
||||
font_obj.init_no_scan(cr, uid)
|
||||
return font_obj.search(cr, uid, [('name', '=', 'Helvetica')], limit=1)[0]
|
||||
|
||||
_header = """
|
||||
<header>
|
||||
<pageTemplate>
|
||||
@@ -388,6 +395,9 @@ class res_company(osv.osv):
|
||||
return {'value': {'rml_header': self._header_letter}}
|
||||
return {'value': {'rml_header': self._header_a4}}
|
||||
|
||||
def act_discover_fonts(self, cr, uid, ids, context=None):
|
||||
return self.pool.get("res.font").discover_fonts(cr, uid, ids, context)
|
||||
|
||||
_defaults = {
|
||||
'currency_id': _get_euro,
|
||||
'paper_format': 'a4',
|
||||
@@ -395,12 +405,11 @@ class res_company(osv.osv):
|
||||
'rml_header2': _header2,
|
||||
'rml_header3': _header3,
|
||||
'logo':_get_logo,
|
||||
'font':'Helvetica',
|
||||
'font':_get_font,
|
||||
}
|
||||
|
||||
_constraints = [
|
||||
(osv.osv._check_recursion, 'Error! You can not create recursive companies.', ['parent_id'])
|
||||
]
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -80,7 +80,15 @@
|
||||
<field name="custom_footer" on_change="onchange_footer(custom_footer, phone, fax, email, website, vat, company_registry, bank_ids)"/>
|
||||
<field name="rml_footer" attrs="{'invisible': [('custom_footer','=',False)]}"/>
|
||||
<field name="rml_footer_readonly" attrs="{'invisible': [('custom_footer','=',True)]}"/>
|
||||
<field name="font" on_change="onchange_font_name(font, rml_header, rml_header2, rml_header3)"/>
|
||||
</group>
|
||||
<group>
|
||||
<label for="font" />
|
||||
<div>
|
||||
<div>
|
||||
<field name="font" class="oe_inline" colspan="2"/>
|
||||
<button string="(reload fonts)" name="act_discover_fonts" type="object" class="oe_link" colspan="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Header/Footer" groups="base.group_no_one">
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program 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 Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from reportlab.pdfbase import ttfonts
|
||||
from openerp.osv import fields, osv
|
||||
from openerp.report.render.rml2pdf import customfonts
|
||||
|
||||
import logging
|
||||
|
||||
"""This module allows the mapping of some system-available TTF fonts to
|
||||
the reportlab engine.
|
||||
|
||||
This file could be customized per distro (although most Linux/Unix ones)
|
||||
should have the same filenames, only need the code below).
|
||||
|
||||
Due to an awful configuration that ships with reportlab at many Linux
|
||||
and Ubuntu distros, we have to override the search path, too.
|
||||
"""
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class res_font(osv.Model):
|
||||
_name = "res.font"
|
||||
_description = 'Fonts available'
|
||||
_order = 'name'
|
||||
|
||||
_columns = {
|
||||
'name': fields.char("Name", required=True),
|
||||
}
|
||||
|
||||
_sql_constraints = [
|
||||
('name_font_uniq', 'unique(name)', 'You can not register two fonts with the same name'),
|
||||
]
|
||||
|
||||
def discover_fonts(self, cr, uid, ids, context=None):
|
||||
"""Scan fonts on the file system, add them to the list of known fonts
|
||||
and create font object for the new ones"""
|
||||
customfonts.CustomTTFonts = customfonts.BaseCustomTTFonts
|
||||
|
||||
found_fonts = {}
|
||||
for font_path in customfonts.list_all_sysfonts():
|
||||
try:
|
||||
font = ttfonts.TTFontFile(font_path)
|
||||
_logger.debug("Found font %s at %s", font.name, font_path)
|
||||
if not found_fonts.get(font.familyName):
|
||||
found_fonts[font.familyName] = {'name': font.familyName}
|
||||
|
||||
mode = font.styleName.lower().replace(" ", "")
|
||||
|
||||
customfonts.CustomTTFonts.append((font.familyName, font.name, font_path, mode))
|
||||
except ttfonts.TTFError:
|
||||
_logger.warning("Could not register Font %s", font_path)
|
||||
|
||||
# add default PDF fonts
|
||||
for family in customfonts.BasePDFFonts:
|
||||
if not found_fonts.get(family):
|
||||
found_fonts[family] = {'name': family}
|
||||
|
||||
# remove deleted fonts
|
||||
existing_font_ids = self.search(cr, uid, [], context=context)
|
||||
existing_font_names = []
|
||||
for font in self.browse(cr, uid, existing_font_ids):
|
||||
existing_font_names.append(font.name)
|
||||
if font.name not in found_fonts.keys():
|
||||
self.unlink(cr, uid, font.id, context=context)
|
||||
|
||||
# add unknown fonts
|
||||
for family, vals in found_fonts.items():
|
||||
if family not in existing_font_names:
|
||||
self.create(cr, uid, vals, context=context)
|
||||
return True
|
||||
|
||||
def init_no_scan(self, cr, uid, context=None):
|
||||
"""Add demo data for PDF fonts without scan (faster for db creation)"""
|
||||
for font in customfonts.BasePDFFonts:
|
||||
if not self.search(cr, uid, [('name', '=', font)], context=context):
|
||||
self.create(cr, uid, {'name':font}, context=context)
|
||||
return True
|
||||
@@ -37,18 +37,30 @@ should have the same filenames, only need the code below).
|
||||
Due to an awful configuration that ships with reportlab at many Linux
|
||||
and Ubuntu distros, we have to override the search path, too.
|
||||
"""
|
||||
_fonts_cache = {'registered_fonts': [], 'total_system_fonts': 0}
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# Basic fonts familly included in PDF standart, will always be in the font list
|
||||
# Basic fonts family included in PDF standart, will always be in the font list
|
||||
BasePDFFonts = [
|
||||
('Helvetica', 'Helvetica'),
|
||||
('Times', 'Times'),
|
||||
('Courier', 'Courier'),
|
||||
'Helvetica',
|
||||
'Times',
|
||||
'Courier'
|
||||
]
|
||||
|
||||
# List of fonts found on the disk
|
||||
CustomTTFonts = []
|
||||
CustomTTFonts = BaseCustomTTFonts = [ ('Helvetica', "DejaVu Sans", "DejaVuSans.ttf", 'normal'),
|
||||
('Helvetica', "DejaVu Sans Bold", "DejaVuSans-Bold.ttf", 'bold'),
|
||||
('Helvetica', "DejaVu Sans Oblique", "DejaVuSans-Oblique.ttf", 'italic'),
|
||||
('Helvetica', "DejaVu Sans BoldOblique", "DejaVuSans-BoldOblique.ttf", 'bolditalic'),
|
||||
('Times', "Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
|
||||
('Times', "Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
|
||||
('Times', "Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
|
||||
('Times', "Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
|
||||
('Courier', "FreeMono", "FreeMono.ttf", 'normal'),
|
||||
('Courier', "FreeMono Bold", "FreeMonoBold.ttf", 'bold'),
|
||||
('Courier', "FreeMono Oblique", "FreeMonoOblique.ttf", 'italic'),
|
||||
('Courier', "FreeMono BoldOblique", "FreeMonoBoldOblique.ttf", 'bolditalic'),
|
||||
]
|
||||
|
||||
|
||||
# Search path for TTF files, in addition of rl_config.TTFSearchPath
|
||||
TTFSearchPath = [
|
||||
@@ -73,7 +85,7 @@ TTFSearchPath = [
|
||||
'c:/windows/fonts'
|
||||
]
|
||||
|
||||
def all_sysfonts_list():
|
||||
def list_all_sysfonts():
|
||||
"""
|
||||
This function returns list of font directories of system.
|
||||
"""
|
||||
@@ -89,76 +101,6 @@ def all_sysfonts_list():
|
||||
filepath.append(os.path.join(dirname, filename))
|
||||
return filepath
|
||||
|
||||
def init_new_font(familyName, name, font_dir):
|
||||
return {
|
||||
'regular':(familyName, name, font_dir, 'regular'),
|
||||
'italic':(),
|
||||
'bold':(familyName, name, font_dir, 'bold'),
|
||||
'bolditalic':(),
|
||||
}
|
||||
|
||||
def RegisterCustomFonts():
|
||||
"""
|
||||
This function prepares a list for all system fonts to be registered
|
||||
in reportlab and returns the updated list with new fonts.
|
||||
"""
|
||||
global CustomTTFonts
|
||||
all_system_fonts = all_sysfonts_list()
|
||||
if len(all_system_fonts) != _fonts_cache['total_system_fonts']:
|
||||
font_modes, last_family, registered_font_list, _fonts_cache['registered_fonts'] = {}, "", [], list(BasePDFFonts)
|
||||
|
||||
#Prepares a list of registered fonts. Remove such fonts those don't have cmap for Unicode.
|
||||
for dirname in all_system_fonts:
|
||||
try:
|
||||
font_info = ttfonts.TTFontFile(dirname)
|
||||
if font_info.styleName in ('Regular','Normal','Book','Medium', 'Roman'):
|
||||
_fonts_cache['registered_fonts'].append((font_info.name, font_info.fullName))
|
||||
registered_font_list.append((font_info.familyName, font_info.name, dirname, font_info.styleName.lower().replace(" ", "")))
|
||||
_logger.debug("Found font %s at %s", font_info.name, dirname)
|
||||
except:
|
||||
_logger.warning("Could not register Font %s", dirname)
|
||||
|
||||
#Prepare font list for mapping.Each font family requires four type of modes(regular,bold,italic,bolditalic).
|
||||
#If all modes are not found, dummy entries are made for remaining modes.
|
||||
for familyName, name, font_dir, mode in sorted(registered_font_list):
|
||||
if not last_family or not font_modes:
|
||||
last_family = familyName
|
||||
font_modes = init_new_font(familyName, name, font_dir)
|
||||
|
||||
if last_family != familyName:
|
||||
# new font familly, adding previous to the list of fonts
|
||||
if not font_modes['italic']:
|
||||
font_modes['italic'] = font_modes['regular'][:3]+('italic',)
|
||||
if not font_modes['bolditalic']:
|
||||
font_modes['bolditalic'] = font_modes['bold'][:3]+('bolditalic',)
|
||||
CustomTTFonts.extend(font_modes.values())
|
||||
font_modes = init_new_font(familyName, name, font_dir)
|
||||
|
||||
if (mode== 'normal') or (mode == 'regular') or (mode == 'medium') or (mode == 'book') or (mode == 'roman'):
|
||||
font_modes['regular'] = (familyName, name, font_dir, 'regular')
|
||||
elif (mode == 'italic') or (mode == 'oblique'):
|
||||
font_modes['italic'] = (familyName, name, font_dir, 'italic')
|
||||
elif mode == 'bold':
|
||||
font_modes['bold'] = (familyName, name, font_dir, 'bold')
|
||||
elif (mode == 'bolditalic') or (mode == 'boldoblique'):
|
||||
font_modes['bolditalic'] = (familyName, name, font_dir, 'bolditalic')
|
||||
last_family = familyName
|
||||
|
||||
# add the last one
|
||||
if font_modes:
|
||||
if not font_modes['italic']:
|
||||
font_modes['italic'] = font_modes['regular'][:3]+('italic',)
|
||||
if not font_modes['bolditalic']:
|
||||
font_modes['bolditalic'] = font_modes['bold'][:3]+('bolditalic',)
|
||||
CustomTTFonts.extend(font_modes.values())
|
||||
|
||||
_fonts_cache['total_system_fonts'] = len(all_system_fonts)
|
||||
|
||||
# remove duplicates
|
||||
CustomTTFonts = sorted(list(set(CustomTTFonts)))
|
||||
_fonts_cache['registered_fonts'] = sorted(list(set(_fonts_cache['registered_fonts'])))
|
||||
return _fonts_cache['registered_fonts']
|
||||
|
||||
def SetCustomFonts(rmldoc):
|
||||
""" Map some font names to the corresponding TTF fonts
|
||||
|
||||
@@ -167,8 +109,6 @@ def SetCustomFonts(rmldoc):
|
||||
This function is called once per report, so it should
|
||||
avoid system-wide processing (cache it, instead).
|
||||
"""
|
||||
if not _fonts_cache['registered_fonts']:
|
||||
RegisterCustomFonts()
|
||||
for name, font, filename, mode in CustomTTFonts:
|
||||
if os.path.isabs(filename) and os.path.exists(filename):
|
||||
rmldoc.setTTFontMapping(name, font, filename, mode)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#-----------------------------------------------------------
|
||||
import datetime
|
||||
import errno
|
||||
import fcntl
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
@@ -21,6 +20,11 @@ import time
|
||||
import traceback
|
||||
|
||||
import werkzeug.serving
|
||||
|
||||
try:
|
||||
import fcntl
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
from setproctitle import setproctitle
|
||||
except ImportError:
|
||||
|
||||
Reference in New Issue
Block a user