# /********************************************************************** # * * # * Copyright (c) 2021 Javier Braña * # * * # * 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 FreeCAD import FreeCADGui from PySide import QtGui, QtCore import datetime import getpass if FreeCAD.GuiUp: import FreeCADGui, os from PySide import QtCore else: # \cond def translate(ctxt, txt): return txt def QT_TRANSLATE_NOOP(ctxt, txt): return txt # \endcond try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s import PVPlantResources from PVPlantResources import DirIcons as DirIcons class SafeDict(dict): """Diccionario seguro para manejar placeholders no definidos""" def __missing__(self, key): return f'{{{key}}}' class RenameDialog(QtGui.QDialog): def __init__(self): super(RenameDialog, self).__init__() self.setupUI() def setupUI(self): self.setWindowTitle("Renombrar objetos con plantilla") self.setMinimumWidth(400) layout = QtGui.QVBoxLayout(self) # Campo para la plantilla layout.addWidget(QtGui.QLabel("Plantilla de nombre:")) self.template_input = QtGui.QLineEdit() self.template_input.setPlaceholderText("Ej: {label}_mod_{index:03d}_{date:%Y%m%d}") layout.addWidget(self.template_input) # Info de placeholders info = QtGui.QLabel( "Placeholders disponibles:\n" "• {index} - Número en orden\n" "• {label} - Nombre actual del objeto\n" "• {name} - Nombre interno\n" "• {date} - Fecha actual\n" "• {time} - Hora actual\n" "• {user} - Usuario del sistema\n" "• {datetime} - Fecha y hora completa\n" "Formatos: {date:%Y/%m/%d}, {index:03d}, etc." ) layout.addWidget(info) # Botones btn_box = QtGui.QDialogButtonBox() btn_box.addButton(QtGui.QDialogButtonBox.Apply) btn_box.addButton(QtGui.QDialogButtonBox.Close) btn_box.clicked.connect(self.on_button_click) layout.addWidget(btn_box) def on_button_click(self, button): if button == btn_box.button(QtGui.QDialogButtonBox.Apply): self.rename_objects() else: self.close() def rename_objects(self): template = self.template_input.text() if not template: QtGui.QMessageBox.warning(self, "Error", "¡La plantilla no puede estar vacía!") return selected_objects = FreeCADGui.Selection.getSelection() if not selected_objects: QtGui.QMessageBox.warning(self, "Error", "¡No hay objetos seleccionados!") return now = datetime.datetime.now() user_name = getpass.getuser() errors = [] for idx, obj in enumerate(selected_objects, 1): try: placeholders = SafeDict({ 'index': idx, 'label': obj.Label, 'name': obj.Name, 'date': now.date(), 'time': now.time(), 'datetime': now, 'user': user_name }) new_name = template.format_map(placeholders) obj.Label = new_name except Exception as e: errors.append(f"{obj.Name}: {str(e)}") FreeCAD.ActiveDocument.recompute() if errors: error_msg = "\n".join(errors) QtGui.QMessageBox.critical(self, "Errores", f"Error(es) encontrado(s):\n{error_msg}") else: QtGui.QMessageBox.information(self, "Éxito", "¡Objetos renombrados correctamente!") class CommandRenamer: "the Arch Building command definition" def GetResources(self): return {'Pixmap': str(os.path.join(DirIcons, "trackersetup.svg")), 'MenuText': QtCore.QT_TRANSLATE_NOOP("PVPlantTracker", "TrackerSetup"), 'Accel': "R, F", 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PVPlanTracker", "Creates a TrackerSetup object from setup dialog.")} def IsActive(self): return (not FreeCAD.ActiveDocument is None and not FreeCAD.ActiveDocument.getObject("Site") is None) def Activated(self): self.TaskPanel = renamerTaskPanel() FreeCADGui.Control.showDialog(self.TaskPanel) return