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 from .prompt_translations import PROMPT_TRANSLATIONS 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: #2b2b2b; min-width: 1500px; min-height: 700px; } QScrollArea { background-color: #1e1e1e; border: 1px solid #3b3b3b; border-radius: 4px; padding: 8px; } QScrollArea > QWidget > QWidget { background-color: #1e1e1e; } QLabel { color: #ffffff; font-size: 14px; font-weight: bold; padding: 8px; background-color: #3b3b3b; border-radius: 4px; } QCheckBox { color: #ffffff; font-size: 14px; padding: 4px; spacing: 8px; } QCheckBox::indicator { width: 18px; height: 18px; } QCheckBox::indicator:unchecked { border: 2px solid #555555; background-color: #3b3b3b; border-radius: 3px; } QCheckBox::indicator:checked { border: 2px solid #0d6efd; background-color: #0d6efd; border-radius: 3px; } QCheckBox::indicator:hover { border-color: #0b5ed7; } QPushButton { background-color: #0d6efd; color: white; border: none; border-radius: 4px; padding: 8px 16px; font-weight: bold; min-width: 120px; } QPushButton:hover { background-color: #0b5ed7; } QPushButton:pressed { background-color: #0a58ca; } QLineEdit { background-color: #3b3b3b; color: white; border: 1px solid #555555; border-radius: 4px; padding: 8px; font-size: 14px; min-height: 24px; } QFrame { background-color: #1e1e1e; border: 1px solid #3b3b3b; border-radius: 4px; } """) layout = QVBoxLayout(self) # Поиск search_layout = QHBoxLayout() search_label = QLabel("Поиск:") self.search_input = QLineEdit() 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_widget = QWidget() self.categories_layout = QHBoxLayout(categories_widget) self.categories_layout.setSpacing(10) categories_scroll.setWidget(categories_widget) layout.addWidget(categories_scroll) # Кнопки buttons_layout = QHBoxLayout() 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) 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: # Преобразуем русские названия в английские translated_prompts = [PROMPT_TRANSLATIONS.get(prompt, prompt) for prompt in self.selected_prompts] prompts_text = ", ".join(sorted(translated_prompts)) self.prompt_selected.emit(prompts_text)