197 lines
6.9 KiB
Python
197 lines
6.9 KiB
Python
"""
|
|
Silique (https://www.silique.fr)
|
|
Copyright (C) 2022-2025
|
|
|
|
This program is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU Lesser 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 Lesser General Public License for more
|
|
details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
"""
|
|
|
|
from rich.console import Console
|
|
from rich.tree import Tree
|
|
from rich.table import Table
|
|
from rich.panel import Panel
|
|
|
|
from ..i18n import _
|
|
from ..util import CommonOutput
|
|
|
|
|
|
class OutputFamily(CommonOutput):
|
|
level = 10
|
|
name = "console"
|
|
variable_hidden_color = "orange1"
|
|
variable_normal_color = None
|
|
value_unmodified_color = "gold1"
|
|
value_modified_color = "green"
|
|
value_default_color = None
|
|
error_color = 'bright_red'
|
|
|
|
|
|
def run(self):
|
|
max_width = self.root.rougailconfig["display.console.max_width"]
|
|
self.console = Console(force_terminal=True, width=max_width)
|
|
with self.console.capture() as capture:
|
|
ret = self.root.print()
|
|
return ret, capture.get()
|
|
|
|
def print(self) -> None:
|
|
ret = self.root.exporter()
|
|
for out in self.out:
|
|
self.console.print(out)
|
|
return ret
|
|
|
|
def header(self):
|
|
caption_line = ""
|
|
if self.root_family.variable_default_enable:
|
|
caption_line += _("Variable") + "\n"
|
|
if self.root_family.variable_hidden_enable:
|
|
caption_line += f'[{self.variable_hidden_color}]{_("Unmodifiable variable")}[/{self.variable_hidden_color}]\n'
|
|
header_value = ""
|
|
if self.root_family.value_unmodified_enable:
|
|
header_value += f'[{self.value_unmodified_color}]{_("Default value")}[/{self.value_unmodified_color}]\n'
|
|
if self.root_family.value_modified_enable:
|
|
header_value += f'[{self.value_modified_color}]{_("Modified value")}[/{self.value_modified_color}]\n'
|
|
if self.root_family.value_default_enable:
|
|
header_value += f'(:hourglass_flowing_sand: {_("Original default value")})\n'
|
|
caption = Table.grid(padding=1, collapse_padding=True)
|
|
caption.pad_edge = False
|
|
caption.add_row(caption_line[:-1], header_value[:-1])
|
|
self.out.append(Panel.fit(caption, title=_("Caption")))
|
|
#
|
|
layers = Table.grid(padding=1, collapse_padding=True)
|
|
caption.pad_edge = False
|
|
if self.root.layer_datas:
|
|
max_len = 0
|
|
for datas in self.root.layer_datas.values():
|
|
for data in datas.values():
|
|
max_len = max(max_len, len(data))
|
|
display_layers = ["" for i in range(max_len)]
|
|
for datas in self.root.layer_datas.values():
|
|
for data in datas.values():
|
|
last_index = len(data) - 1
|
|
for idx in range(max_len):
|
|
if last_index < idx:
|
|
display_layers[idx] += "\n"
|
|
else:
|
|
display_layers[idx] += data[idx] + "\n"
|
|
layers.add_row(*[layer[:-1] for layer in display_layers])
|
|
self.out.append(Panel.fit(layers, title=_("Layers")))
|
|
|
|
def error_header(self):
|
|
tree = Tree(
|
|
f"[bold][{self.error_color}]:stop_sign: {_('ERRORS')}[/{self.error_color}][/bold]",
|
|
guide_style=f"bold {self.error_color}",
|
|
)
|
|
self.out.append(tree)
|
|
return tree
|
|
|
|
def display_error(self, tree, error, level):
|
|
return tree.add(error)
|
|
|
|
def display_warnings(
|
|
self,
|
|
warnings: list,
|
|
) -> None:
|
|
tree = Tree(
|
|
f"[bold][bright_yellow]:bell: {_('WARNINGS')}[/bright_yellow][/bold]",
|
|
guide_style="bold bright_yellow",
|
|
)
|
|
for warning in warnings:
|
|
tree.add(warning)
|
|
self.out.append(tree)
|
|
|
|
def add_variable(
|
|
self, *args, **kwargs,
|
|
):
|
|
key, value = super().add_variable(*args, **kwargs)
|
|
if isinstance(value, list):
|
|
subtree = self.get_tree().add(
|
|
":notebook: " + _("{0}:").format(key),
|
|
guide_style="bold bright_blue",
|
|
)
|
|
for val in value:
|
|
subtree.add(str(val))
|
|
else:
|
|
self.get_tree().add(":notebook: " + _("{0}: {1}").format(key, value))
|
|
|
|
def colorize(
|
|
self,
|
|
values,
|
|
option=None,
|
|
) -> str:
|
|
multi = False
|
|
ret = []
|
|
default = []
|
|
for idx, data in enumerate(values):
|
|
value = data["value"]
|
|
if isinstance(value, list):
|
|
multi = True
|
|
else:
|
|
value = [value]
|
|
for vidx, val in enumerate(value):
|
|
if len(ret) == vidx:
|
|
ret.append("")
|
|
default.append(False)
|
|
if idx:
|
|
if not default[vidx]:
|
|
if ret[vidx]:
|
|
ret[vidx] += " "
|
|
ret[vidx] += "("
|
|
default[vidx] = True
|
|
else:
|
|
ret[vidx] += " "
|
|
ret[vidx] += ":hourglass_flowing_sand: "
|
|
if option:
|
|
val = self.convert_value(
|
|
option,
|
|
val,
|
|
)
|
|
color = data["color"]
|
|
if color is not None:
|
|
ret[vidx] += f"[{color}]{val}[/{color}]"
|
|
else:
|
|
ret[vidx] += val
|
|
loaded_from = data["loaded_from"]
|
|
if loaded_from:
|
|
ret[vidx] += f" :arrow_backward: {loaded_from}"
|
|
for idx in range(len(ret)):
|
|
if default[idx]:
|
|
ret[idx] += ")"
|
|
if not multi:
|
|
if not ret:
|
|
return ""
|
|
return ret[0]
|
|
return ret
|
|
|
|
def get_tree(self):
|
|
if self.tree is None:
|
|
if self.parent is None:
|
|
tree = Tree
|
|
else:
|
|
tree = self.parent.add
|
|
# if self.is_leader:
|
|
# self.tree = tree(
|
|
# ":notebook: " + _("{0}:").format(self.family),
|
|
# guide_style="bold bright_blue",
|
|
# )
|
|
# elif self.no_icon:
|
|
if self.no_icon:
|
|
self.tree = tree(
|
|
self.family,
|
|
guide_style="bold bright_blue",
|
|
)
|
|
else:
|
|
self.tree = tree(
|
|
f":open_file_folder: {self.family}",
|
|
guide_style="bold bright_blue",
|
|
)
|
|
return self.tree
|