/
Ig.Ro
/
PDF_View
Обзор
Документация
Войти
/
Ig.Ro
/
PDF_View
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
utils.py
256 строк
11 KB
Ig.Ro
upload files
14 янв 2026, 16:44
14 янв 2026, 16:44
2d33e26
Код
Авторство
О чём код?
import os import shutil import logging from pathlib import Path from math import sqrt from PyQt6.QtWidgets import ( QDialog, QVBoxLayout, QCheckBox, QPushButton, QHBoxLayout, QGroupBox, QLabel as QLabelWidget, QSpinBox, QMessageBox ) from PyQt6.QtCore import QSettings logger = logging.getLogger("PDFViewer") MAX_PDF_FILE_SIZE = 100 * 1024 * 1024 POPPLER_DIR = Path("poppler") RENDER_DPI = 120 TITLE_BLOCK_WIDTH_MM = 190 TITLE_BLOCK_HEIGHT_MM = 60 FORMAT_BOUNDS = [ (310, 'A5'), (438, 'A4'), (605, 'A3'), (712, 'A4×3'), (812, 'A2'), (938, 'A4×4'), (1008, 'A3×3'), (1061, 'A1'), (1176, 'A4×5'), (1277, 'A3×4'), (1344, 'A4×6'), (1424, 'A2×3'), (1478, 'A0'), (1522, 'A4×7'), (1625, 'A3×5'), (1744, 'A4×8'), (1806, 'A2×4'), (1872, 'A3×6'), (1942, 'A4×9'), (2046, 'A1×3'), (2091, 'A0×2'), (2152, 'A3×7'), (2351, 'A2×5'), (2652, 'A1×4'), (float('inf'), 'A0×3'), ] def get_format_by_diagonal(diagonal_mm: int) -> str: for bound, fmt in FORMAT_BOUNDS: if diagonal_mm < bound: return fmt return 'A0×3' def calculate_dimensions(w_px: int, h_px: int, dpi: int): w_mm = round(w_px * 25.4 / dpi) h_mm = round(h_px * 25.4 / dpi) d_mm = round(sqrt(w_mm ** 2 + h_mm ** 2)) fmt = get_format_by_diagonal(d_mm) return w_mm, h_mm, d_mm, fmt def ensure_poppler(): import shutil pdftoppm_in_path = shutil.which("pdftoppm") if pdftoppm_in_path: logger.info("pdftoppm найден в PATH") return str(Path(pdftoppm_in_path).parent) for root, dirs, files in os.walk(POPPLER_DIR): if "pdftoppm.exe" in files: path = str(Path(root)) logger.info(f"Poppler (pdftoppm) найден в папке: {path}") return path logger.warning("pdftoppm не найден") return None class SettingsDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Настройки приложения") self.setModal(True) self.resize(400, 520) # Увеличили высоту для новой настройки self.settings = QSettings("MyCompany", "PDFViewer") layout = QVBoxLayout() startup_group = QGroupBox("Настройки запуска") startup_layout = QVBoxLayout() self.auto_open_checkbox = QCheckBox("Открывать последний файл при запуске") self.auto_open_checkbox.setChecked(self.settings.value("auto_open_last_file", True, type=bool)) startup_layout.addWidget(self.auto_open_checkbox) self.restore_tabs_checkbox = QCheckBox("Восстанавливать вкладки при запуске") self.restore_tabs_checkbox.setChecked(self.settings.value("restore_tabs", True, type=bool)) startup_layout.addWidget(self.restore_tabs_checkbox) help_label = QLabelWidget("При включении этой опции приложение запомнит\n" "открытые вкладки и восстановит их при следующем запуске.") help_label.setWordWrap(True) help_label.setStyleSheet("color: gray; font-size: 9px;") startup_layout.addWidget(help_label) last_file = self.settings.value("last_file", "") if last_file and os.path.isfile(last_file): last_file_info = QLabelWidget(f"Последний файл:\n{os.path.basename(last_file)}") last_file_info.setWordWrap(True) last_file_info.setStyleSheet("color: gray; font-size: 10px;") startup_layout.addWidget(last_file_info) startup_group.setLayout(startup_layout) layout.addWidget(startup_group) view_group = QGroupBox("Настройки просмотра") view_layout = QVBoxLayout() self.save_window_state_checkbox = QCheckBox("Запоминать размер и положение окна") self.save_window_state_checkbox.setChecked(self.settings.value("save_window_state", True, type=bool)) view_layout.addWidget(self.save_window_state_checkbox) self.save_file_state_checkbox = QCheckBox("Запоминать масштаб и поворот для каждого файла") self.save_file_state_checkbox.setChecked(self.settings.value("save_file_state", True, type=bool)) view_layout.addWidget(self.save_file_state_checkbox) self.cache_pages_checkbox = QCheckBox("Кэшировать страницы PDF") self.cache_pages_checkbox.setChecked(self.settings.value("cache_pages", True, type=bool)) view_layout.addWidget(self.cache_pages_checkbox) view_group.setLayout(view_layout) layout.addWidget(view_group) tabs_group = QGroupBox("Настройки вкладок") tabs_layout = QVBoxLayout() self.max_tabs_checkbox = QCheckBox("Ограничить количество вкладок") self.max_tabs_checkbox.setChecked(self.settings.value("limit_tabs", True, type=bool)) self.max_tabs_checkbox.toggled.connect(self.on_limit_tabs_toggled) tabs_layout.addWidget(self.max_tabs_checkbox) tabs_limit_layout = QHBoxLayout() tabs_limit_layout.addWidget(QLabelWidget("Максимальное количество вкладок:")) self.max_tabs_spin = QSpinBox() self.max_tabs_spin.setMinimum(1) self.max_tabs_spin.setMaximum(50) self.max_tabs_spin.setValue(self.settings.value("max_tabs", 10, type=int)) tabs_limit_layout.addWidget(self.max_tabs_spin) tabs_limit_layout.addStretch() tabs_layout.addLayout(tabs_limit_layout) self.max_tabs_spin.setEnabled(self.max_tabs_checkbox.isChecked()) tabs_group.setLayout(tabs_layout) layout.addWidget(tabs_group) # Группа: Автозакрытие вкладок auto_close_group = QGroupBox("Автозакрытие вкладок") auto_close_layout = QVBoxLayout() self.close_first_tab_checkbox = QCheckBox("Закрывать первую вкладку при превышении лимита") self.close_first_tab_checkbox.setChecked(self.settings.value("close_first_tab", False, type=bool)) auto_close_layout.addWidget(self.close_first_tab_checkbox) close_help_label = QLabelWidget("При включении этой опции при попытке открыть новую вкладку\n" "при достижении лимита будет автоматически закрыта первая вкладка.") close_help_label.setWordWrap(True) close_help_label.setStyleSheet("color: gray; font-size: 9px;") auto_close_layout.addWidget(close_help_label) auto_close_group.setLayout(auto_close_layout) layout.addWidget(auto_close_group) title_block_group = QGroupBox("Основная надпись (картинка в картинке)") title_block_layout = QVBoxLayout() self.title_block_enabled_checkbox = QCheckBox("Показывать увеличенную основную надпись") self.title_block_enabled_checkbox.setChecked(self.settings.value("title_block_enabled", True, type=bool)) title_block_layout.addWidget(self.title_block_enabled_checkbox) scale_layout = QHBoxLayout() scale_layout.addWidget(QLabelWidget("Масштаб основной надписи:")) self.title_block_scale_spin = QSpinBox() self.title_block_scale_spin.setMinimum(100) self.title_block_scale_spin.setMaximum(500) self.title_block_scale_spin.setSingleStep(50) self.title_block_scale_spin.setValue(self.settings.value("title_block_scale", 200, type=int)) self.title_block_scale_spin.setSuffix("%") scale_layout.addWidget(self.title_block_scale_spin) scale_layout.addStretch() title_block_layout.addLayout(scale_layout) title_block_group.setLayout(title_block_layout) layout.addWidget(title_block_group) buttons_layout = QHBoxLayout() buttons_layout.addStretch() self.reset_button = QPushButton("Сбросить настройки") self.reset_button.clicked.connect(self.reset_settings) buttons_layout.addWidget(self.reset_button) self.cancel_button = QPushButton("Отмена") self.cancel_button.clicked.connect(self.reject) buttons_layout.addWidget(self.cancel_button) self.save_button = QPushButton("Сохранить") self.save_button.clicked.connect(self.accept) self.save_button.setDefault(True) buttons_layout.addWidget(self.save_button) layout.addLayout(buttons_layout) self.setLayout(layout) def on_limit_tabs_toggled(self, checked): self.max_tabs_spin.setEnabled(checked) def reset_settings(self): reply = QMessageBox.question( self, "Сброс настроек", "Вы уверены, что хотите сбросить все настройки к значениям по умолчанию?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.Yes: self.auto_open_checkbox.setChecked(True) self.restore_tabs_checkbox.setChecked(True) self.save_window_state_checkbox.setChecked(True) self.save_file_state_checkbox.setChecked(True) self.cache_pages_checkbox.setChecked(True) self.title_block_enabled_checkbox.setChecked(True) self.title_block_scale_spin.setValue(200) self.max_tabs_checkbox.setChecked(True) self.max_tabs_spin.setValue(10) self.close_first_tab_checkbox.setChecked(False) def get_settings(self): return { "auto_open_last_file": self.auto_open_checkbox.isChecked(), "restore_tabs": self.restore_tabs_checkbox.isChecked(), "save_window_state": self.save_window_state_checkbox.isChecked(), "save_file_state": self.save_file_state_checkbox.isChecked(), "cache_pages": self.cache_pages_checkbox.isChecked(), "title_block_enabled": self.title_block_enabled_checkbox.isChecked(), "title_block_scale": self.title_block_scale_spin.value(), "limit_tabs": self.max_tabs_checkbox.isChecked(), "max_tabs": self.max_tabs_spin.value(), "close_first_tab": self.close_first_tab_checkbox.isChecked() }