- Nouveau layout : menus en haut, vignettes a gauche, viewer au centre - Panneau vignettes redimensionnable (splitter) - Miniatures de chaque page - Drag & drop pour reordonner - Clic droit : supprimer page, inserer page blanche - Clic = naviguer vers la page - Viewer PDF ameliore : - Ajustement auto a l'ouverture - Roulette = defiler les pages - Ctrl+roulette = zoom - Drag & drop de fichier PDF sur la fenetre - Barre de progression pendant les traitements - Fusion de PDF (Fichier > Fusionner) - Enlever les fonds perdus (Annotations > Enlever) - Menus par categorie : Imposition, Pages, Annotations - Toolbar : Ouvrir, Enregistrer, Zoom, info page - Style sombre coherent CopyDev - Suppression du numero de telephone dans A propos Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
110 lines
3.9 KiB
Python
110 lines
3.9 KiB
Python
"""Panneau lateral de vignettes des pages — V2."""
|
|
|
|
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QListWidget, QListWidgetItem,
|
|
QAbstractItemView, QMenu, QSizePolicy)
|
|
from PyQt6.QtGui import QIcon, QPixmap
|
|
from PyQt6.QtCore import Qt, pyqtSignal, QSize
|
|
|
|
|
|
class PagePanel(QWidget):
|
|
"""Panneau de vignettes avec drag & drop, suppression, insertion."""
|
|
|
|
page_selected = pyqtSignal(int) # page index cliquee
|
|
pages_reordered = pyqtSignal(list) # nouvelle liste d'indices
|
|
page_delete_requested = pyqtSignal(int) # demande suppression
|
|
page_insert_requested = pyqtSignal(int) # demande insertion page blanche apres
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.setMinimumWidth(100)
|
|
self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Expanding)
|
|
self._setup_ui()
|
|
|
|
def _setup_ui(self):
|
|
layout = QVBoxLayout(self)
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
self._list = QListWidget()
|
|
self._list.setIconSize(QSize(120, 170))
|
|
self._list.setSpacing(4)
|
|
self._list.setStyleSheet("""
|
|
QListWidget {
|
|
background: #252525;
|
|
border: none;
|
|
padding: 4px;
|
|
}
|
|
QListWidget::item {
|
|
background: #333;
|
|
border: 1px solid #444;
|
|
border-radius: 4px;
|
|
padding: 4px;
|
|
color: #ccc;
|
|
font-size: 10px;
|
|
}
|
|
QListWidget::item:selected {
|
|
background: #0066cc;
|
|
border: 1px solid #0088ff;
|
|
color: white;
|
|
}
|
|
""")
|
|
|
|
self._list.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove)
|
|
self._list.setDefaultDropAction(Qt.DropAction.MoveAction)
|
|
self._list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
|
self._list.customContextMenuRequested.connect(self._context_menu)
|
|
self._list.currentRowChanged.connect(self._on_row_changed)
|
|
self._list.model().rowsMoved.connect(self._on_rows_moved)
|
|
|
|
layout.addWidget(self._list)
|
|
|
|
def load_thumbnails(self, viewer):
|
|
"""Charger les miniatures depuis le viewer."""
|
|
self._list.clear()
|
|
for i in range(viewer.total_pages):
|
|
thumb = viewer.get_page_thumbnail(i, 120)
|
|
item = QListWidgetItem()
|
|
item.setText(f" Page {i + 1}")
|
|
item.setData(Qt.ItemDataRole.UserRole, i)
|
|
if thumb:
|
|
item.setIcon(QIcon(thumb))
|
|
self._list.addItem(item)
|
|
|
|
def select_page(self, index):
|
|
"""Selectionner une page sans emettre le signal."""
|
|
self._list.blockSignals(True)
|
|
self._list.setCurrentRow(index)
|
|
self._list.blockSignals(False)
|
|
|
|
def _on_row_changed(self, row):
|
|
if row >= 0:
|
|
self.page_selected.emit(row)
|
|
|
|
def _on_rows_moved(self):
|
|
indices = []
|
|
for i in range(self._list.count()):
|
|
item = self._list.item(i)
|
|
original_index = item.data(Qt.ItemDataRole.UserRole)
|
|
indices.append(original_index)
|
|
self.pages_reordered.emit(indices)
|
|
|
|
def _context_menu(self, pos):
|
|
item = self._list.itemAt(pos)
|
|
if not item:
|
|
return
|
|
row = self._list.row(item)
|
|
|
|
menu = QMenu(self)
|
|
menu.setStyleSheet("""
|
|
QMenu { background: #333; color: #eee; border: 1px solid #555; }
|
|
QMenu::item:selected { background: #0066cc; }
|
|
""")
|
|
|
|
act_insert = menu.addAction("Inserer une page blanche apres")
|
|
act_delete = menu.addAction("Supprimer cette page")
|
|
|
|
action = menu.exec(self._list.mapToGlobal(pos))
|
|
if action == act_delete:
|
|
self.page_delete_requested.emit(row)
|
|
elif action == act_insert:
|
|
self.page_insert_requested.emit(row)
|