# SPDX-License-Identifier: LGPL-2.1-or-later # *************************************************************************** # * Copyright (c) 2025 Samuel Abels * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * # * as published by the Free Software Foundation; either version 2 of * # * the License, or (at your option) any later version. * # * for detail see the LICENCE text file. * # * * # * 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 Library General Public License for more details. * # * * # * You should have received a copy of the GNU Library General Public * # * License along with this program; if not, write to the Free Software * # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * # * USA * # * * # *************************************************************************** import re from PySide import QtGui, QtCore import FreeCAD from ...shape import ToolBitShape def isub(text, old, repl_pattern): pattern = "|".join(re.escape(o) for o in old) return re.sub("(" + pattern + ")", repl_pattern, text, flags=re.I) def interpolate_colors(start_color, end_color, ratio): r = 1.0 - ratio red = start_color.red() * r + end_color.red() * ratio green = start_color.green() * r + end_color.green() * ratio blue = start_color.blue() * r + end_color.blue() * ratio return QtGui.QColor(int(red), int(green), int(blue)) class TwoLineTableCell(QtGui.QWidget): def __init__(self, parent=None): super(TwoLineTableCell, self).__init__(parent) self.tool_no = "" self.pocket = "" self.upper_text = "" self.lower_text = "" self.search_highlight = "" palette = self.palette() bg_role = self.backgroundRole() bg_color = palette.color(bg_role) fg_role = self.foregroundRole() fg_color = palette.color(fg_role) self.vbox = QtGui.QVBoxLayout() self.label_upper = QtGui.QLabel() self.label_upper.setStyleSheet("margin-top: 8px") self.label_upper.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) color = interpolate_colors(bg_color, fg_color, 0.8) style = "margin-bottom: 8px; color: {};".format(color.name()) self.label_lower = QtGui.QLabel() self.label_lower.setStyleSheet(style) self.label_lower.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) self.vbox.addWidget(self.label_upper) self.vbox.addWidget(self.label_lower) self.label_left = QtGui.QLabel() self.label_left.setMinimumWidth(40) self.label_left.setTextFormat(QtCore.Qt.RichText) self.label_left.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.label_left.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) ratio = self.devicePixelRatioF() self.icon_size = QtCore.QSize(50 * ratio, 60 * ratio) self.icon_widget = QtGui.QLabel() self.label_right = QtGui.QLabel() self.label_right.setMinimumWidth(40) self.label_right.setTextFormat(QtCore.Qt.RichText) self.label_right.setAlignment(QtCore.Qt.AlignCenter) self.label_right.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) self.hbox = QtGui.QHBoxLayout() self.hbox.addWidget(self.label_left, 0) self.hbox.addWidget(self.icon_widget, 0) self.hbox.addLayout(self.vbox, 1) self.hbox.addWidget(self.label_right, 0) self.setLayout(self.hbox) def _highlight(self, text): if not self.search_highlight: return text highlight_fmt = r'\1' return isub(text, self.search_highlight.split(" "), highlight_fmt) def _update(self): # Handle tool number display if self.tool_no is not None and self.tool_no != "": text = self._highlight(str(self.tool_no)) self.label_left.setText(f"{text}") self.label_left.setVisible(True) else: self.label_left.setVisible(False) text = self._highlight(self.pocket) lbl = FreeCAD.Qt.translate("CAM_Toolbit", "Pocket") text = f"{lbl}\n

{text}

" if text else "" self.label_right.setText(text) text = self._highlight(self.upper_text) self.label_upper.setText(f"{text}") text = self._highlight(self.lower_text) self.label_lower.setText(text) self.label_lower.setText(f"{text}") def set_tool_no(self, no): self.tool_no = no self._update() def set_pocket(self, pocket): self.pocket = str(pocket) if pocket else "" self._update() def set_upper_text(self, text): self.upper_text = text self._update() def set_lower_text(self, text): self.lower_text = text self._update() def set_icon(self, pixmap): self.hbox.removeWidget(self.icon_widget) self.icon_widget = QtGui.QLabel() self.icon_widget.setPixmap(pixmap) self.hbox.insertWidget(1, self.icon_widget, 0) def set_icon_from_shape(self, shape: ToolBitShape): icon = shape.get_icon() if not icon: return pixmap = icon.get_qpixmap(self.icon_size) if pixmap: self.set_icon(pixmap) def contains_text(self, text): for term in text.lower().split(" "): tool_no_str = str(self.tool_no) if self.tool_no is not None else "" # Check against the raw text content, not the HTML-formatted text if ( term not in tool_no_str.lower() and term not in self.upper_text.lower() and term not in self.lower_text.lower() ): return False return True def highlight(self, text): self.search_highlight = text self._update() class CompactTwoLineTableCell(TwoLineTableCell): def __init__(self, parent=None): super(CompactTwoLineTableCell, self).__init__(parent) # Reduce icon size ratio = self.devicePixelRatioF() self.icon_size = QtCore.QSize(32 * ratio, 32 * ratio) # Reduce margins self.label_upper.setStyleSheet("margin: 2px 0px 0px 0px; font-size: .8em;") self.label_lower.setStyleSheet("margin: 0px 0px 2px 0px; font-size: .8em;") self.vbox.setSpacing(0) self.hbox.setContentsMargins(0, 0, 0, 0)