Add server-side icon support
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
* Add server-side icons
|
||||
* Add support for file link to BinaryField
|
||||
* Add model field access
|
||||
* Add loading attribute on fields
|
||||
|
||||
+6
-4
@@ -62,7 +62,7 @@ class MenuitemTagHandler:
|
||||
|
||||
# TODO maybe use a prefetch for this:
|
||||
cursor.execute(cursor.limit_clause(
|
||||
"SELECT a.name, a.type, act.view_type, v.type " \
|
||||
"SELECT a.name, a.type, act.view_type, v.type, icon.name " \
|
||||
"FROM ir_action a " \
|
||||
"LEFT JOIN ir_action_report report ON (a.id = report.action) " \
|
||||
"LEFT JOIN ir_action_act_window act ON (a.id = act.action) " \
|
||||
@@ -70,14 +70,15 @@ class MenuitemTagHandler:
|
||||
"LEFT JOIN ir_action_url url ON (a.id = url.action) " \
|
||||
"LEFT JOIN ir_action_act_window_view wv ON " \
|
||||
"(act.id = wv.act_window) " \
|
||||
"LEFT JOIN ir_ui_view v on (v.id = wv.view) " \
|
||||
"LEFT JOIN ir_ui_view v ON (v.id = wv.view) " \
|
||||
"LEFT JOIN ir_ui_icon icon ON (a.icon = icon.id) " \
|
||||
"WHERE report.id = %s " \
|
||||
"OR act.id = %s " \
|
||||
"OR wizard.id = %s " \
|
||||
"OR url.id = %s " \
|
||||
"ORDER by wv.sequence", 1),
|
||||
(action_id, action_id, action_id, action_id))
|
||||
action_name, action_type, view_type, view_mode = \
|
||||
action_name, action_type, view_type, view_mode, icon_name = \
|
||||
cursor.fetchone()
|
||||
|
||||
values['action'] = '%s,%s' % (action_type, action_id)
|
||||
@@ -85,6 +86,8 @@ class MenuitemTagHandler:
|
||||
icon = attributes.get('icon', '')
|
||||
if icon:
|
||||
values['icon'] = icon
|
||||
elif icon_name:
|
||||
values['icon'] = icon_name
|
||||
elif action_type == 'ir.action.wizard':
|
||||
values['icon'] = 'tryton-executable'
|
||||
elif action_type == 'ir.action.report':
|
||||
@@ -126,7 +129,6 @@ class MenuitemTagHandler:
|
||||
|
||||
self.values = values
|
||||
|
||||
|
||||
def characters(self, data):
|
||||
pass
|
||||
|
||||
|
||||
+11
-7
@@ -22,6 +22,7 @@ class Action(ModelSQL, ModelView):
|
||||
'Keywords')
|
||||
groups = fields.Many2Many('ir.action-res.group', 'action_id', 'gid',
|
||||
'Groups')
|
||||
icon = fields.Many2One('ir.ui.icon', 'Icon')
|
||||
active = fields.Boolean('Active', select=2)
|
||||
|
||||
def __init__(self):
|
||||
@@ -183,15 +184,18 @@ class ActionKeyword(ModelSQL, ModelView):
|
||||
('action', '=', action_keyword.action.id),
|
||||
])
|
||||
if action_id:
|
||||
res.append(action_obj.read(action_id[0]))
|
||||
columns = set(action_obj._columns.keys()
|
||||
+ action_obj._inherit_fields.keys())
|
||||
columns.add('icon.rec_name')
|
||||
if action_keyword.action.type == 'ir.action.report':
|
||||
del res[-1]['report_content_data']
|
||||
del res[-1]['report_content']
|
||||
del res[-1]['style_content']
|
||||
res[-1]['email'] = encoder.encode(res[-1]['email'])
|
||||
to_remove = ('report_content_data', 'report_content',
|
||||
'style_content')
|
||||
elif action_keyword.action.type == 'ir.action.act_window':
|
||||
for field in ('domain', 'context', 'search_value'):
|
||||
del res[-1][field]
|
||||
to_remove = ('domain', 'context', 'search_value')
|
||||
else:
|
||||
to_remove = set()
|
||||
columns.difference_update(to_remove)
|
||||
res.append(action_obj.read(action_id[0], list(columns)))
|
||||
return res
|
||||
|
||||
ActionKeyword()
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
#this repository contains the full copyright notices and license terms.
|
||||
from menu import *
|
||||
from view import *
|
||||
from icon import *
|
||||
|
||||
@@ -181,6 +181,7 @@ page =
|
||||
| vpaned)*
|
||||
}
|
||||
attlist.page &= attribute angle { text }?
|
||||
attlist.page &= attribute icon { text }?
|
||||
attlist.page &=
|
||||
[ a:defaultValue = "Unknown" ] attribute string { text }?
|
||||
attlist.page &= [ a:defaultValue = "4" ] attribute col { text }?
|
||||
|
||||
@@ -671,6 +671,11 @@
|
||||
<attribute name="angle"/>
|
||||
</optional>
|
||||
</define>
|
||||
<define name="attlist.page" combine="interleave">
|
||||
<optional>
|
||||
<attribute name="icon"/>
|
||||
</optional>
|
||||
</define>
|
||||
<define name="attlist.page" combine="interleave">
|
||||
<optional>
|
||||
<attribute name="string" a:defaultValue="Unknown"/>
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of this
|
||||
# repository contains the full copyright notices and license terms.
|
||||
from __future__ import with_statement
|
||||
|
||||
import os
|
||||
|
||||
from trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.tools import file_open
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class Icon(ModelSQL, ModelView):
|
||||
'Icon'
|
||||
_name = 'ir.ui.icon'
|
||||
_description = __doc__
|
||||
|
||||
name = fields.Char('Name', required=True, select=1)
|
||||
module = fields.Char('Module', readonly=True)
|
||||
path = fields.Char('SVG Path', readonly=True)
|
||||
icon = fields.Function(fields.Char('Icon', depends=['path']), 'get_icon')
|
||||
sequence = fields.Integer('Sequence')
|
||||
|
||||
def __init__(self):
|
||||
super(Icon, self).__init__()
|
||||
self._order.insert(0, ('sequence', 'ASC'))
|
||||
self._rpc.update({
|
||||
'list_icons': False,
|
||||
})
|
||||
|
||||
def default_module(self):
|
||||
return Transaction().context.get('module') or ''
|
||||
|
||||
def default_sequence(self):
|
||||
return 10
|
||||
|
||||
def list_icons(self):
|
||||
icons = {}
|
||||
for icon in self.browse(self.search([],
|
||||
order=[('sequence', 'ASC'), ('id', 'ASC')])):
|
||||
if icon.name not in icons:
|
||||
icons[icon.name] = icon.id
|
||||
return sorted((icon_id, name) for name, icon_id in icons.iteritems())
|
||||
|
||||
def get_icon(self, ids, name):
|
||||
result = {}
|
||||
for icon in self.browse(ids):
|
||||
path = os.path.join(icon.module, icon.path.replace('/', os.sep))
|
||||
with file_open(path, subdir='modules') as fp:
|
||||
result[icon.id] = fp.read()
|
||||
return result
|
||||
|
||||
Icon()
|
||||
Reference in New Issue
Block a user