Files
gzth/anita_theme_setting/models/anita_theme_style_item.py
T
2024-06-20 13:39:24 +08:00

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