332 lines
12 KiB
Python
332 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import models, fields, api, exceptions
|
|
import logging
|
|
import json
|
|
from .anita_utility import apply_alpha
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AnitaThemeStyleItem(models.Model):
|
|
'''
|
|
user theme style setting
|
|
'''
|
|
_name = 'anita_theme_setting.style_item'
|
|
_order = 'sequence asc'
|
|
_description = "style item"
|
|
|
|
sub_group = fields.Many2one(
|
|
comodel_name="anita_theme_setting.style_item_sub_group", string="sub group")
|
|
theme_mode = fields.Many2one(
|
|
comodel_name="anita_theme_setting.theme_mode",
|
|
related="sub_group.group.theme_style.theme_mode",
|
|
store=True,
|
|
string="theme mode")
|
|
theme_style = fields.Many2one(
|
|
comodel_name="anita_theme_setting.theme_style",
|
|
related = "sub_group.group.theme_style",
|
|
string="theme style")
|
|
|
|
name = fields.Char(string="name", required=True, default="var1")
|
|
val = fields.Char(string="val", compute="_compute_val")
|
|
sequence = fields.Integer(string="sequence", default=0)
|
|
mode = fields.Selection(
|
|
selection=[('override', 'override'), ('primary', 'primary')],
|
|
string="mode",
|
|
default="override",
|
|
help="override or primary, override is override the default style and primary is create a new style")
|
|
val_template = fields.Char(
|
|
string="val template",
|
|
required=True,
|
|
default="background: {var1}", help="Save the last val")
|
|
vars = fields.One2many(
|
|
string="vars",
|
|
comodel_name="anita_theme_setting.theme_var",
|
|
inverse_name="style_item")
|
|
selectors = fields.Char(string="selectors", required=True)
|
|
is_default = fields.Boolean(string="Is Default", default=True)
|
|
type = fields.Selection(
|
|
string="type",
|
|
selection=[('normal', 'normal'),
|
|
('login', 'login')],
|
|
default='normal')
|
|
login_style = fields.Char(string="login style", default="login_style1")
|
|
|
|
|
|
def check_vars(self, default_mode, sub_group_id, default_vars):
|
|
'''
|
|
check vars
|
|
:return:
|
|
'''
|
|
# check vars
|
|
self.ensure_one()
|
|
var_val_cache = default_mode.get_var_val_cache()
|
|
|
|
# get current var cache
|
|
old_var_cache = {var.name: var for var in self.vars}
|
|
default_var_cache = \
|
|
{default_var["name"]: default_var for default_var in default_vars}
|
|
|
|
tmp_vals = []
|
|
for default_var in default_vars:
|
|
|
|
color = default_var.get("color", False)
|
|
ref_var = default_var.get("ref_var",False)
|
|
if ref_var:
|
|
if ref_var not in var_val_cache:
|
|
color = False
|
|
_logger.info("ref var {ref_var} not in var cache".format(ref_var=ref_var))
|
|
else:
|
|
color = var_val_cache[ref_var]
|
|
|
|
# item exits must keep
|
|
if default_var["name"] not in old_var_cache:
|
|
tmp_vals.append({
|
|
"sub_group": sub_group_id,
|
|
"name": default_var["name"],
|
|
"style_item": self.id,
|
|
"type": default_var["type"],
|
|
"color": color,
|
|
"image": default_var.get('image', False),
|
|
"image_url": default_var.get('image_url', False),
|
|
"svg": default_var.get('svg', False),
|
|
"is_default": default_var.get('is_default', True),
|
|
"identity": default_var.get('identity', False),
|
|
"ref_var": ref_var,
|
|
"disable_opacity": default_var.get('disable_opacity', False),
|
|
})
|
|
else:
|
|
# keep the val, maybe user will
|
|
tmp_var = old_var_cache[default_var["name"]]
|
|
tmp_var.write({
|
|
"type": default_var["type"],
|
|
"is_default": default_var.get('is_default', True),
|
|
"identity": default_var.get('identity', False),
|
|
"color": color,
|
|
"image": default_var.get('image', False),
|
|
"image_url": default_var.get('image_url', False),
|
|
"svg": default_var.get('svg', False),
|
|
"ref_var": ref_var,
|
|
"disable_opacity": default_var.get('disable_opacity', False),
|
|
})
|
|
|
|
# create the missing vars
|
|
self.env["anita_theme_setting.theme_var"].create(tmp_vals)
|
|
|
|
# unlink the old var
|
|
for name in old_var_cache:
|
|
if name not in default_var_cache:
|
|
tmp_var = old_var_cache[name]
|
|
tmp_var.unlink()
|
|
|
|
@api.depends('selectors', 'val_template', "vars")
|
|
def _compute_val(self):
|
|
'''
|
|
compute the val
|
|
:return:
|
|
'''
|
|
# check if mode has background image
|
|
for record in self:
|
|
# if every var is color and the color val is same as the ref var
|
|
background_image = record.theme_style.background_image
|
|
scss_var_cache = record.theme_mode.get_scss_var_record_cache()
|
|
opacity = record.theme_style.opacity
|
|
vars_cache = dict()
|
|
all_color = True
|
|
all_ref = True
|
|
all_same = True
|
|
for var in record.vars:
|
|
if var.type == 'color':
|
|
# check if has opacity
|
|
color = var.color
|
|
if var.ref_var and var.ref_var in scss_var_cache:
|
|
ref_color = scss_var_cache[var.ref_var]
|
|
if ref_color != color:
|
|
all_same = False
|
|
else:
|
|
all_ref = False
|
|
|
|
try:
|
|
if background_image:
|
|
if not var.disable_opacity:
|
|
color = apply_alpha(var.name, color, opacity, var.color_type)
|
|
except Exception as e:
|
|
_logger.error("apply alpha error {e}".format(e=e))
|
|
|
|
vars_cache[var.name] = color
|
|
elif var.type == 'image':
|
|
vars_cache[var.name] = var.image_file_url
|
|
all_color = False
|
|
elif var.type == 'image_url':
|
|
vars_cache[var.name] = var.image_url
|
|
all_color = False
|
|
else:
|
|
vars_cache[var.name] = var.svg
|
|
all_color = False
|
|
|
|
# if all the color are the original color, them ignore it
|
|
if all_color and all_ref and all_same:
|
|
record.val = False
|
|
else:
|
|
if not record.vars:
|
|
record.val = False
|
|
else:
|
|
try:
|
|
record.val = str(record.val_template).format(**vars_cache)
|
|
except Exception as error:
|
|
record.val = False
|
|
_logger.info('parse var value error, item name {item_name}->{error}'.format(
|
|
item_name=record['name'], error=error))
|
|
|
|
def get_style_item_data(self):
|
|
'''
|
|
get the style item data
|
|
:return:
|
|
'''
|
|
export_style = self.env.context.get('export_style', False)
|
|
style_items = []
|
|
for record in self:
|
|
style_item = record.read(
|
|
fields=["id", "name", "is_default", "val_template", "val", "selectors"])[0]
|
|
|
|
try:
|
|
style_item['selectors'] = json.loads(style_item['selectors'])
|
|
except Exception as error:
|
|
_logger.info('try to decode selectors error!', error)
|
|
|
|
if not export_style:
|
|
# maybe the image is very large, so do not read the image
|
|
style_item["vars"] = \
|
|
record.vars.read(
|
|
["name", "identity", "type", "image_file_url", "image_url", "color", "svg", "color_type"])
|
|
else:
|
|
style_item["vars"] = \
|
|
record.vars.read(
|
|
["name", "identity", "type", "image", "image_url", "color", "svg", "color_type"])
|
|
for tmp_var in style_item["vars"]:
|
|
if tmp_var["image"]:
|
|
tmp_var["image"] = str(tmp_var["image"])
|
|
|
|
style_items.append(style_item)
|
|
return style_items
|
|
|
|
def write(self, vals):
|
|
"""
|
|
rewrite to check if the selectors are right
|
|
:param vals:
|
|
:return:
|
|
"""
|
|
super(AnitaThemeStyleItem, self).write(vals)
|
|
|
|
vars_cache = dict()
|
|
for var in self.vars:
|
|
if var.type == 'color':
|
|
vars_cache[var.name] = var.color
|
|
elif var.type == 'image':
|
|
vars_cache[var.name] = var.image_file_url
|
|
elif var.type == 'image_url':
|
|
vars_cache[var.name] = var.image_url
|
|
else:
|
|
vars_cache[var.name] = var.svg
|
|
|
|
# check the var
|
|
try:
|
|
str(self.val_template).format(**vars_cache)
|
|
except Exception as error:
|
|
_logger.info('parse var value error, item name {item_name}->{error}'.format(
|
|
item_name=self['name'], error=error))
|
|
|
|
def get_login_style_data(
|
|
self, theme_style_id, login_style):
|
|
"""
|
|
get login style data
|
|
:return:
|
|
"""
|
|
result = []
|
|
theme_style = self.env["anita_theme_setting.theme_style"].browse(theme_style_id)
|
|
sub_group_ids = theme_style.mapped('groups.sub_groups.id')
|
|
style_items = self.search(
|
|
[('type', '=', 'login'),
|
|
('login_style', '=', login_style),
|
|
('sub_group', 'in', sub_group_ids)])
|
|
for style_item in style_items:
|
|
val = style_item.val
|
|
if val == "":
|
|
continue
|
|
if not style_item.selectors:
|
|
continue
|
|
try:
|
|
selector = ','.join(json.loads(style_item["selectors"]))
|
|
tmp_txt = selector + " {" + val + "}"
|
|
result.append(tmp_txt)
|
|
except Exception as error:
|
|
_logger.info(error)
|
|
return ";".join(result)
|
|
|
|
def delete_style_item(self):
|
|
'''
|
|
delete style item
|
|
:return:
|
|
'''
|
|
self.ensure_one()
|
|
self.unlink()
|
|
|
|
def create_style_item(
|
|
self, default_mode, sub_group, style_item, style_item_index):
|
|
'''
|
|
create group from default data
|
|
:return:
|
|
'''
|
|
selectors = json.dumps(style_item["selectors"])
|
|
var_infos = style_item["vars"]
|
|
var_val_cache = default_mode.get_var_val_cache()
|
|
|
|
var_vals = []
|
|
for var_index, var_info in enumerate(var_infos):
|
|
|
|
color = var_info.get("color", False)
|
|
ref_var = var_info.get("ref_var", False)
|
|
if ref_var:
|
|
if ref_var not in var_val_cache:
|
|
color = False
|
|
_logger.info("ref var not in var cache", ref_var)
|
|
else:
|
|
color = var_val_cache[ref_var]
|
|
|
|
var_vals.append((0, 0, {
|
|
"name": var_info["name"],
|
|
"type": var_info["type"],
|
|
"sequence": var_index,
|
|
"color": color,
|
|
"image": var_info.get('image', False),
|
|
"image_url": var_info.get('image_url', False),
|
|
"svg": var_info.get('svg', False),
|
|
"identity": var_info.get('identity', False),
|
|
"ref_var": ref_var
|
|
}))
|
|
|
|
style_item_val = {
|
|
"name": style_item["name"],
|
|
"sequence": style_item_index,
|
|
"val_template": style_item["val_template"],
|
|
"selectors": selectors,
|
|
"vars": var_vals,
|
|
"sub_group": sub_group
|
|
}
|
|
|
|
return self.create([style_item_val])
|
|
|
|
def resert_var(self):
|
|
"""
|
|
reset var, resut to the derfault value
|
|
:return:
|
|
"""
|
|
if not self.ref_var and self.type != 'color':
|
|
return False
|
|
# get mode first
|
|
var_cache = self.sub_group.group.theme_style.theme_mode.get_scss_vars_cache()
|
|
for var in self.vars.filtered(lambda x: x.type == 'color'):
|
|
if var.ref_var:
|
|
var.color = var_cache.get(var.ref_var, False)
|
|
return True |