from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QTreeWidget, QTreeWidgetItem, QPushButton, QLineEdit, QLabel, QScrollArea, QWidget, QCheckBox, QFrame) from PyQt6.QtCore import Qt, pyqtSignal from .prompt_categories import PROMPT_CATEGORIES class PromptWindow(QDialog): prompt_selected = pyqtSignal(str) def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Готовые промпты") self.setModal(False) self.selected_prompts = set() self.setup_ui() self.load_categories() def setup_ui(self): self.setStyleSheet(""" QDialog { background-color: #1e1e1e; min-width: 1200px; min-height: 800px; } QScrollArea { background-color: #252526; border: none; border-radius: 8px; } QScrollArea > QWidget > QWidget { background-color: #252526; } QLabel { color: #d4d4d4; font-size: 14px; font-weight: 600; padding: 12px; background-color: #2d2d2d; border-radius: 6px; margin-bottom: 8px; } QCheckBox { color: #d4d4d4; font-size: 13px; padding: 6px; spacing: 8px; } QCheckBox:hover { background-color: #2d2d2d; border-radius: 4px; } QCheckBox::indicator { width: 18px; height: 18px; border-radius: 4px; } QCheckBox::indicator:unchecked { border: 2px solid #565656; background-color: #252526; } QCheckBox::indicator:checked { border: 2px solid #007acc; background-color: #007acc; } QCheckBox::indicator:hover { border-color: #007acc; } QPushButton { background-color: #2d2d2d; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 6px; padding: 8px 16px; font-weight: 500; min-width: 120px; font-size: 13px; } QPushButton:hover { background-color: #3e3e3e; border-color: #565656; } QPushButton:pressed { background-color: #565656; } QLineEdit { background-color: #252526; color: #d4d4d4; border: 1px solid #3e3e3e; border-radius: 6px; padding: 8px 12px; font-size: 13px; min-height: 32px; } QLineEdit:focus { border-color: #007acc; } QFrame { background-color: #252526; border: 1px solid #3e3e3e; border-radius: 8px; padding: 12px; margin: 4px; } QFrame:hover { border-color: #565656; } """) layout = QVBoxLayout(self) layout.setContentsMargins(16, 16, 16, 16) layout.setSpacing(12) # Поиск search_layout = QHBoxLayout() search_layout.setSpacing(8) search_label = QLabel("🔍 Поиск:") search_label.setStyleSheet("background: transparent; padding: 0;") self.search_input = QLineEdit() self.search_input.setPlaceholderText("Введите текст для поиска...") self.search_input.textChanged.connect(self.filter_prompts) search_layout.addWidget(search_label) search_layout.addWidget(self.search_input) layout.addLayout(search_layout) # Горизонтальная прокрутка для категорий categories_scroll = QScrollArea() categories_scroll.setWidgetResizable(True) categories_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn) categories_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) categories_scroll.setMinimumHeight(600) categories_widget = QWidget() self.categories_layout = QHBoxLayout(categories_widget) self.categories_layout.setSpacing(12) self.categories_layout.setContentsMargins(12, 12, 12, 12) categories_scroll.setWidget(categories_widget) layout.addWidget(categories_scroll) # Кнопки buttons_layout = QHBoxLayout() buttons_layout.setSpacing(8) add_button = QPushButton("✨ Добавить выбранные") add_button.clicked.connect(self.add_selected) close_button = QPushButton("❌ Закрыть") close_button.clicked.connect(self.close) buttons_layout.addWidget(add_button) buttons_layout.addWidget(close_button) buttons_layout.addStretch() layout.addLayout(buttons_layout) def load_categories(self): """Загрузка категорий и промптов""" for category, subcategories in PROMPT_CATEGORIES.items(): # Создаем фрейм для категории category_frame = QFrame() category_layout = QVBoxLayout(category_frame) category_layout.setSpacing(5) # Добавляем заголовок категории category_label = QLabel(category) category_layout.addWidget(category_label) # Создаем скролл для подкатегорий subcategories_scroll = QScrollArea() subcategories_scroll.setWidgetResizable(True) subcategories_widget = QWidget() subcategories_layout = QVBoxLayout(subcategories_widget) for subcategory, prompts in subcategories.items(): # Добавляем заголовок подкатегории subcategory_label = QLabel(subcategory) subcategories_layout.addWidget(subcategory_label) # Добавляем чекбоксы для промптов for prompt in prompts: checkbox = QCheckBox(prompt) checkbox.stateChanged.connect(lambda state, p=prompt: self.on_checkbox_changed(state, p)) subcategories_layout.addWidget(checkbox) subcategories_scroll.setWidget(subcategories_widget) category_layout.addWidget(subcategories_scroll) # Добавляем категорию в горизонтальный layout self.categories_layout.addWidget(category_frame) def on_checkbox_changed(self, state, prompt): """Обработка изменения состояния чекбокса""" if state == Qt.CheckState.Checked.value: self.selected_prompts.add(prompt) else: self.selected_prompts.discard(prompt) def filter_prompts(self, text): """Фильтрация промптов по поисковому запросу""" text = text.lower() for i in range(self.categories_layout.count()): category_frame = self.categories_layout.itemAt(i).widget() for j in range(category_frame.layout().count()): widget = category_frame.layout().itemAt(j).widget() if isinstance(widget, QScrollArea): scroll_widget = widget.widget() for k in range(scroll_widget.layout().count()): sub_widget = scroll_widget.layout().itemAt(k).widget() if isinstance(sub_widget, QCheckBox): sub_widget.setVisible(text in sub_widget.text().lower()) elif isinstance(sub_widget, QLabel): # Показываем/скрываем заголовок подкатегории в зависимости от видимости его промптов has_visible_prompts = False for l in range(k + 1, scroll_widget.layout().count()): next_widget = scroll_widget.layout().itemAt(l).widget() if isinstance(next_widget, QCheckBox) and next_widget.isVisible(): has_visible_prompts = True break sub_widget.setVisible(has_visible_prompts) def add_selected(self): """Добавление выбранных промптов""" if self.selected_prompts: prompts_text = ", ".join(sorted(self.selected_prompts)) self.prompt_selected.emit(prompts_text)