Carregar ficheiros para "/"

This commit is contained in:
2024-12-19 09:03:07 -08:00
commit 30b1c5b775
5 changed files with 1041 additions and 0 deletions

296
backup_manager.py Normal file
View File

@ -0,0 +1,296 @@
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QProgressDialog, QFileDialog, QMessageBox)
from PySide6.QtCore import Qt
from database import get_session
from models import Document, DocumentVersion, Folder, Tag
import os
import json
import shutil
import zipfile
from datetime import datetime
class BackupManager(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Export button
self.export_btn = QPushButton("Exportar Documentos")
self.export_btn.clicked.connect(self.export_documents)
layout.addWidget(self.export_btn)
# Import button
self.import_btn = QPushButton("Importar Documentos")
self.import_btn.clicked.connect(self.import_documents)
layout.addWidget(self.import_btn)
def export_documents(self):
export_dir = QFileDialog.getExistingDirectory(
self,
"Selecionar Pasta para Exportação"
)
if not export_dir:
return
try:
session = get_session()
# Create export directory structure
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
export_path = os.path.join(export_dir, f"doc_export_{timestamp}")
os.makedirs(export_path)
# Create progress dialog
documents = session.query(Document).all()
progress = QProgressDialog(
"Exportando documentos...",
"Cancelar",
0,
len(documents),
self
)
progress.setWindowModality(Qt.WindowModal)
# Export metadata
metadata = {
'documents': [],
'folders': [],
'tags': []
}
# Export documents and their versions
for i, doc in enumerate(documents):
if progress.wasCanceled():
break
# Create document directory
doc_dir = os.path.join(export_path, f"doc_{doc.id}")
os.makedirs(doc_dir)
# Copy main document
if os.path.exists(doc.file_path):
shutil.copy2(doc.file_path,
os.path.join(doc_dir, os.path.basename(doc.file_path)))
# Copy versions
versions_dir = os.path.join(doc_dir, "versions")
os.makedirs(versions_dir)
for version in doc.versions:
if os.path.exists(version.file_path):
shutil.copy2(
version.file_path,
os.path.join(versions_dir, os.path.basename(version.file_path))
)
# Add document metadata
doc_data = {
'id': doc.id,
'file_name': doc.file_name,
'marca': doc.marca,
'modelo': doc.modelo,
'ano': doc.ano,
'cilindrada': doc.cilindrada,
'codigo_motor': doc.codigo_motor,
'tipo_documento': doc.tipo_documento,
'variante': doc.variante,
'observacoes': doc.observacoes,
'folder_id': doc.folder_id,
'tags': [tag.name for tag in doc.tags],
'versions': [{
'version_number': v.version_number,
'file_name': os.path.basename(v.file_path),
'changes': v.changes,
'created_at': v.created_at.isoformat()
} for v in doc.versions]
}
metadata['documents'].append(doc_data)
progress.setValue(i + 1)
# Export folders
folders = session.query(Folder).all()
for folder in folders:
folder_data = {
'id': folder.id,
'name': folder.name,
'parent_id': folder.parent_id
}
metadata['folders'].append(folder_data)
# Export tags
tags = session.query(Tag).all()
for tag in tags:
tag_data = {
'name': tag.name,
'color': tag.color
}
metadata['tags'].append(tag_data)
# Save metadata
with open(os.path.join(export_path, 'metadata.json'), 'w',
encoding='utf-8') as f:
json.dump(metadata, f, ensure_ascii=False, indent=2)
# Create ZIP archive
zip_path = f"{export_path}.zip"
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, _, files in os.walk(export_path):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, export_path)
zipf.write(file_path, arcname)
# Clean up temporary directory
shutil.rmtree(export_path)
QMessageBox.information(
self,
"Sucesso",
f"Exportação concluída com sucesso!\nArquivo: {zip_path}"
)
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro durante a exportação: {str(e)}")
finally:
session.close()
def import_documents(self):
zip_path, _ = QFileDialog.getOpenFileName(
self,
"Selecionar Arquivo de Importação",
"",
"Arquivos ZIP (*.zip)"
)
if not zip_path:
return
try:
session = get_session()
# Create temporary directory for extraction
temp_dir = os.path.join(os.path.dirname(zip_path), "temp_import")
os.makedirs(temp_dir, exist_ok=True)
# Extract ZIP file
with zipfile.ZipFile(zip_path, 'r') as zipf:
zipf.extractall(temp_dir)
# Read metadata
with open(os.path.join(temp_dir, 'metadata.json'), 'r',
encoding='utf-8') as f:
metadata = json.load(f)
# Import tags
for tag_data in metadata['tags']:
if not session.query(Tag)\
.filter(Tag.name == tag_data['name']).first():
tag = Tag(
name=tag_data['name'],
color=tag_data['color']
)
session.add(tag)
# Import folders
for folder_data in metadata['folders']:
if not session.query(Folder)\
.filter(Folder.id == folder_data['id']).first():
folder = Folder(
id=folder_data['id'],
name=folder_data['name'],
parent_id=folder_data['parent_id']
)
session.add(folder)
# Create progress dialog
progress = QProgressDialog(
"Importando documentos...",
"Cancelar",
0,
len(metadata['documents']),
self
)
progress.setWindowModality(Qt.WindowModal)
# Import documents
for i, doc_data in enumerate(metadata['documents']):
if progress.wasCanceled():
break
# Check if document already exists
existing_doc = session.query(Document)\
.filter(Document.file_name == doc_data['file_name'])\
.filter(Document.folder_id == doc_data['folder_id'])\
.first()
if not existing_doc:
# Copy document file
doc_dir = os.path.join(temp_dir, f"doc_{doc_data['id']}")
original_file = os.path.join(doc_dir, doc_data['file_name'])
if os.path.exists(original_file):
# Create new document
new_doc = Document(
file_name=doc_data['file_name'],
file_path=original_file,
marca=doc_data['marca'],
modelo=doc_data['modelo'],
ano=doc_data['ano'],
cilindrada=doc_data['cilindrada'],
codigo_motor=doc_data['codigo_motor'],
tipo_documento=doc_data['tipo_documento'],
variante=doc_data['variante'],
observacoes=doc_data['observacoes'],
folder_id=doc_data['folder_id']
)
# Add tags
for tag_name in doc_data['tags']:
tag = session.query(Tag)\
.filter(Tag.name == tag_name).first()
if tag:
new_doc.tags.append(tag)
session.add(new_doc)
session.flush() # Get new_doc.id
# Import versions
versions_dir = os.path.join(doc_dir, "versions")
if os.path.exists(versions_dir):
for version_data in doc_data['versions']:
version_file = os.path.join(
versions_dir,
version_data['file_name']
)
if os.path.exists(version_file):
new_version = DocumentVersion(
document_id=new_doc.id,
version_number=version_data['version_number'],
file_path=version_file,
changes=version_data['changes'],
created_at=datetime.fromisoformat(
version_data['created_at'])
)
session.add(new_version)
progress.setValue(i + 1)
session.commit()
# Clean up
shutil.rmtree(temp_dir)
QMessageBox.information(self, "Sucesso",
"Importação concluída com sucesso!")
except Exception as e:
session.rollback()
QMessageBox.critical(self, "Erro",
f"Erro durante a importação: {str(e)}")
finally:
session.close()

144
batch_upload.py Normal file
View File

@ -0,0 +1,144 @@
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QTableWidget, QTableWidgetItem, QHeaderView,
QFileDialog, QMessageBox, QProgressDialog)
from PySide6.QtCore import Qt, Signal
import os
from database import get_session
from models import Document
from document_form import DocumentForm
class BatchUploadWidget(QWidget):
upload_completed = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.files_to_upload = []
self.folder_id = None
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Buttons
button_layout = QHBoxLayout()
self.add_files_btn = QPushButton("Adicionar Arquivos")
self.add_files_btn.clicked.connect(self.add_files)
self.remove_files_btn = QPushButton("Remover Selecionados")
self.remove_files_btn.clicked.connect(self.remove_selected_files)
self.upload_all_btn = QPushButton("Upload em Lote")
self.upload_all_btn.clicked.connect(self.upload_all)
button_layout.addWidget(self.add_files_btn)
button_layout.addWidget(self.remove_files_btn)
button_layout.addWidget(self.upload_all_btn)
layout.addLayout(button_layout)
# Files table
self.files_table = QTableWidget()
self.files_table.setColumnCount(2)
self.files_table.setHorizontalHeaderLabels(["Nome do Arquivo", "Caminho"])
self.files_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
layout.addWidget(self.files_table)
# Create document form for metadata
self.doc_form = DocumentForm()
layout.addWidget(self.doc_form)
def add_files(self):
files, _ = QFileDialog.getOpenFileNames(
self,
"Selecionar Arquivos",
"",
"Todos os Arquivos (*);;PDF (*.pdf);;Imagens (*.png *.jpg);;Documentos (*.doc *.docx)"
)
for file_path in files:
if file_path not in [self.files_table.item(row, 1).text()
for row in range(self.files_table.rowCount())]:
row = self.files_table.rowCount()
self.files_table.insertRow(row)
self.files_table.setItem(row, 0, QTableWidgetItem(os.path.basename(file_path)))
self.files_table.setItem(row, 1, QTableWidgetItem(file_path))
def remove_selected_files(self):
rows = set(item.row() for item in self.files_table.selectedItems())
for row in sorted(rows, reverse=True):
self.files_table.removeRow(row)
def upload_all(self):
if not self.validate_form():
return
progress = QProgressDialog(
"Fazendo upload dos arquivos...",
"Cancelar",
0,
self.files_table.rowCount(),
self
)
progress.setWindowModality(Qt.WindowModal)
try:
session = get_session()
for row in range(self.files_table.rowCount()):
if progress.wasCanceled():
break
file_path = self.files_table.item(row, 1).text()
# Create new document with metadata
new_doc = Document(
file_path=file_path,
file_name=os.path.basename(file_path),
marca=self.doc_form.marca_edit.text(),
modelo=self.doc_form.modelo_edit.text(),
ano=self.doc_form.ano_spin.value(),
cilindrada=self.doc_form.cilindrada_edit.text(),
codigo_motor=self.doc_form.codigo_motor_edit.text(),
tipo_documento=self.doc_form.tipo_combo.currentText(),
variante=self.doc_form.variante_combo.currentText(),
observacoes=self.doc_form.observacoes_edit.toPlainText(),
folder_id=self.folder_id
)
session.add(new_doc)
progress.setValue(row + 1)
session.commit()
session.close()
QMessageBox.information(self, "Sucesso",
"Upload em lote concluído com sucesso!")
self.clear_form()
self.upload_completed.emit()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro durante o upload em lote: {str(e)}")
session.rollback()
session.close()
progress.close()
def validate_form(self):
if self.files_table.rowCount() == 0:
QMessageBox.warning(self, "Validação",
"Adicione pelo menos um arquivo.")
return False
if not self.doc_form.marca_edit.text():
QMessageBox.warning(self, "Validação",
"Por favor, preencha a marca.")
return False
if not self.doc_form.modelo_edit.text():
QMessageBox.warning(self, "Validação",
"Por favor, preencha o modelo.")
return False
return True
def clear_form(self):
self.files_table.setRowCount(0)
self.doc_form.clear_form()

205
comments.py Normal file
View File

@ -0,0 +1,205 @@
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QTextEdit, QListWidget, QListWidgetItem,
QLabel, QMenu, QMessageBox, QDialog)
from PySide6.QtCore import Qt, Signal, QPoint
from PySide6.QtGui import QAction
from database import get_session
from models import Comment, Document
from datetime import datetime
class CommentWidget(QWidget):
comment_updated = Signal()
def __init__(self, comment, parent=None):
super().__init__(parent)
self.comment = comment
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
layout.setContentsMargins(5, 5, 5, 5)
# Header with timestamp and options
header_layout = QHBoxLayout()
timestamp = QLabel(self.comment.created_at.strftime("%d/%m/%Y %H:%M"))
timestamp.setStyleSheet("color: gray; font-size: 10px;")
header_layout.addWidget(timestamp)
if self.comment.updated_at and self.comment.updated_at != self.comment.created_at:
edited_label = QLabel("(editado)")
edited_label.setStyleSheet("color: gray; font-size: 10px;")
header_layout.addWidget(edited_label)
header_layout.addStretch()
# Options button
options_btn = QPushButton("...")
options_btn.setFixedWidth(30)
options_btn.clicked.connect(self.show_options)
header_layout.addWidget(options_btn)
layout.addLayout(header_layout)
# Comment text
text_label = QLabel(self.comment.text)
text_label.setWordWrap(True)
layout.addWidget(text_label)
# Location info if available
if self.comment.page_number:
location = f"Página {self.comment.page_number}"
if self.comment.x_coord and self.comment.y_coord:
location += f" (x: {self.comment.x_coord}, y: {self.comment.y_coord})"
location_label = QLabel(location)
location_label.setStyleSheet("color: gray; font-style: italic; font-size: 10px;")
layout.addWidget(location_label)
def show_options(self):
menu = QMenu(self)
edit_action = QAction("Editar", self)
edit_action.triggered.connect(self.edit_comment)
menu.addAction(edit_action)
delete_action = QAction("Excluir", self)
delete_action.triggered.connect(self.delete_comment)
menu.addAction(delete_action)
# Show menu at button position
button = self.sender()
pos = button.mapToGlobal(QPoint(0, button.height()))
menu.exec_(pos)
def edit_comment(self):
dialog = CommentDialog(self.comment.text, self)
if dialog.exec_():
try:
session = get_session()
comment = session.query(Comment).get(self.comment.id)
comment.text = dialog.comment_text()
comment.updated_at = datetime.utcnow()
session.commit()
self.comment_updated.emit()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao editar comentário: {str(e)}")
finally:
session.close()
def delete_comment(self):
reply = QMessageBox.question(
self,
"Confirmar Exclusão",
"Tem certeza que deseja excluir este comentário?",
QMessageBox.Yes | QMessageBox.No
)
if reply == QMessageBox.Yes:
try:
session = get_session()
comment = session.query(Comment).get(self.comment.id)
session.delete(comment)
session.commit()
self.comment_updated.emit()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao excluir comentário: {str(e)}")
finally:
session.close()
class CommentsList(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.current_document = None
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Header
header_layout = QHBoxLayout()
header_layout.addWidget(QLabel("Comentários"))
self.add_comment_btn = QPushButton("Novo Comentário")
self.add_comment_btn.clicked.connect(self.add_comment)
header_layout.addWidget(self.add_comment_btn)
layout.addLayout(header_layout)
# Comments list
self.comments_list = QListWidget()
layout.addWidget(self.comments_list)
def load_document(self, doc_id):
self.current_document = doc_id
self.refresh_comments()
def refresh_comments(self):
self.comments_list.clear()
if self.current_document:
session = get_session()
document = session.query(Document).get(self.current_document)
for comment in document.comments:
item = QListWidgetItem()
widget = CommentWidget(comment)
widget.comment_updated.connect(self.refresh_comments)
item.setSizeHint(widget.sizeHint())
self.comments_list.addItem(item)
self.comments_list.setItemWidget(item, widget)
session.close()
def add_comment(self):
if not self.current_document:
return
dialog = CommentDialog(parent=self)
if dialog.exec_():
try:
session = get_session()
comment = Comment(
document_id=self.current_document,
text=dialog.comment_text()
)
session.add(comment)
session.commit()
self.refresh_comments()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao adicionar comentário: {str(e)}")
finally:
session.close()
class CommentDialog(QDialog):
def __init__(self, initial_text="", parent=None):
super().__init__(parent)
self.initial_text = initial_text
self.setup_ui()
def setup_ui(self):
self.setWindowTitle("Comentário")
layout = QVBoxLayout(self)
self.text_edit = QTextEdit()
self.text_edit.setPlainText(self.initial_text)
layout.addWidget(self.text_edit)
buttons_layout = QHBoxLayout()
cancel_btn = QPushButton("Cancelar")
cancel_btn.clicked.connect(self.reject)
buttons_layout.addWidget(cancel_btn)
save_btn = QPushButton("Salvar")
save_btn.clicked.connect(self.accept)
buttons_layout.addWidget(save_btn)
layout.addLayout(buttons_layout)
def comment_text(self):
return self.text_edit.toPlainText()

23
database.py Normal file
View File

@ -0,0 +1,23 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Base
import os
# Get the absolute path to the database file
DATABASE_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "automotive_docs.db")
DATABASE_URL = f"sqlite:///{DATABASE_FILE}"
def init_db():
# Create new engine
engine = create_engine(DATABASE_URL)
# Create tables if they don't exist
if not os.path.exists(DATABASE_FILE):
Base.metadata.create_all(engine)
return engine
def get_session():
engine = create_engine(DATABASE_URL)
Session = sessionmaker(bind=engine)
return Session()

373
document_collections.py Normal file
View File

@ -0,0 +1,373 @@
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
QListWidget, QListWidgetItem, QInputDialog,
QMessageBox, QMenu, QDialog, QLabel, QLineEdit,
QTextEdit, QComboBox)
from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QAction, QColor, QIcon
from database import get_session
from models import Collection, Document
import json
class CollectionDialog(QDialog):
def __init__(self, collection=None, parent=None):
super().__init__(parent)
self.collection = collection
self.setup_ui()
def setup_ui(self):
self.setWindowTitle("Coleção")
layout = QVBoxLayout(self)
# Name
name_layout = QHBoxLayout()
name_layout.addWidget(QLabel("Nome:"))
self.name_edit = QLineEdit()
if self.collection:
self.name_edit.setText(self.collection.name)
name_layout.addWidget(self.name_edit)
layout.addLayout(name_layout)
# Description
layout.addWidget(QLabel("Descrição:"))
self.desc_edit = QTextEdit()
if self.collection:
self.desc_edit.setText(self.collection.description)
layout.addWidget(self.desc_edit)
# Color
color_layout = QHBoxLayout()
color_layout.addWidget(QLabel("Cor:"))
self.color_combo = QComboBox()
colors = ["#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#FF00FF", "#00FFFF"]
for color in colors:
self.color_combo.addItem("")
self.color_combo.setItemData(
self.color_combo.count() - 1,
QColor(color),
Qt.BackgroundRole
)
if self.collection:
index = colors.index(self.collection.color)
self.color_combo.setCurrentIndex(index)
color_layout.addWidget(self.color_combo)
layout.addLayout(color_layout)
# Buttons
button_layout = QHBoxLayout()
cancel_btn = QPushButton("Cancelar")
cancel_btn.clicked.connect(self.reject)
button_layout.addWidget(cancel_btn)
save_btn = QPushButton("Salvar")
save_btn.clicked.connect(self.accept)
button_layout.addWidget(save_btn)
layout.addLayout(button_layout)
def get_data(self):
return {
'name': self.name_edit.text(),
'description': self.desc_edit.toPlainText(),
'color': self.color_combo.itemData(
self.color_combo.currentIndex(),
Qt.BackgroundRole
).name()
}
class CollectionsWidget(QWidget):
collection_selected = Signal(int) # collection_id
def __init__(self, parent=None):
super().__init__(parent)
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Toolbar
toolbar = QHBoxLayout()
new_btn = QPushButton("Nova Coleção")
new_btn.clicked.connect(self.add_collection)
toolbar.addWidget(new_btn)
toolbar.addStretch()
layout.addLayout(toolbar)
# Collections list
self.collections_list = QListWidget()
self.collections_list.itemClicked.connect(self.on_collection_clicked)
self.collections_list.setContextMenuPolicy(Qt.CustomContextMenu)
self.collections_list.customContextMenuRequested.connect(
self.show_context_menu)
layout.addWidget(self.collections_list)
self.refresh_collections()
def refresh_collections(self):
self.collections_list.clear()
try:
session = get_session()
collections = session.query(Collection).all()
for collection in collections:
item = QListWidgetItem(collection.name)
item.setData(Qt.UserRole, collection.id)
item.setBackground(QColor(collection.color))
# Add document count
doc_count = len(collection.documents)
item.setToolTip(
f"{collection.description}\n\n"
f"Documentos: {doc_count}"
)
self.collections_list.addItem(item)
session.close()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao carregar coleções: {str(e)}")
def add_collection(self):
dialog = CollectionDialog(parent=self)
if dialog.exec_():
try:
session = get_session()
data = dialog.get_data()
collection = Collection(
name=data['name'],
description=data['description'],
color=data['color']
)
session.add(collection)
session.commit()
self.refresh_collections()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao criar coleção: {str(e)}")
finally:
session.close()
def edit_collection(self, collection_id):
try:
session = get_session()
collection = session.query(Collection).get(collection_id)
if collection:
dialog = CollectionDialog(collection, self)
if dialog.exec_():
data = dialog.get_data()
collection.name = data['name']
collection.description = data['description']
collection.color = data['color']
session.commit()
self.refresh_collections()
session.close()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao editar coleção: {str(e)}")
def delete_collection(self, collection_id):
reply = QMessageBox.question(
self,
"Confirmar Exclusão",
"Tem certeza que deseja excluir esta coleção?",
QMessageBox.Yes | QMessageBox.No
)
if reply == QMessageBox.Yes:
try:
session = get_session()
collection = session.query(Collection).get(collection_id)
if collection:
session.delete(collection)
session.commit()
self.refresh_collections()
session.close()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao excluir coleção: {str(e)}")
def on_collection_clicked(self, item):
collection_id = item.data(Qt.UserRole)
self.collection_selected.emit(collection_id)
def show_context_menu(self, position):
item = self.collections_list.itemAt(position)
if not item:
return
collection_id = item.data(Qt.UserRole)
menu = QMenu()
edit_action = menu.addAction("Editar")
edit_action.triggered.connect(
lambda: self.edit_collection(collection_id))
delete_action = menu.addAction("Excluir")
delete_action.triggered.connect(
lambda: self.delete_collection(collection_id))
menu.exec_(self.collections_list.mapToGlobal(position))
class CollectionDocuments(QWidget):
document_selected = Signal(int) # document_id
def __init__(self, parent=None):
super().__init__(parent)
self.current_collection = None
self.setup_ui()
def setup_ui(self):
layout = QVBoxLayout(self)
# Header
header_layout = QHBoxLayout()
self.collection_label = QLabel()
header_layout.addWidget(self.collection_label)
self.add_doc_btn = QPushButton("Adicionar Documento")
self.add_doc_btn.clicked.connect(self.add_document)
header_layout.addWidget(self.add_doc_btn)
layout.addLayout(header_layout)
# Documents list
self.documents_list = QListWidget()
self.documents_list.itemClicked.connect(self.on_document_clicked)
self.documents_list.setContextMenuPolicy(Qt.CustomContextMenu)
self.documents_list.customContextMenuRequested.connect(
self.show_context_menu)
layout.addWidget(self.documents_list)
def load_collection(self, collection_id):
self.current_collection = collection_id
self.refresh_documents()
def refresh_documents(self):
self.documents_list.clear()
if not self.current_collection:
return
try:
session = get_session()
collection = session.query(Collection).get(self.current_collection)
if collection:
self.collection_label.setText(
f"Coleção: {collection.name}"
)
for doc in collection.documents:
item = QListWidgetItem(doc.file_name)
item.setData(Qt.UserRole, doc.id)
item.setToolTip(
f"Marca: {doc.marca}\n"
f"Modelo: {doc.modelo}\n"
f"Ano: {doc.ano}"
)
self.documents_list.addItem(item)
session.close()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao carregar documentos: {str(e)}")
def add_document(self):
if not self.current_collection:
return
try:
session = get_session()
# Get documents not in collection
collection = session.query(Collection).get(self.current_collection)
all_docs = session.query(Document).all()
collection_doc_ids = [doc.id for doc in collection.documents]
available_docs = [doc for doc in all_docs
if doc.id not in collection_doc_ids]
if not available_docs:
QMessageBox.information(
self,
"Aviso",
"Não há documentos disponíveis para adicionar."
)
return
# Show document selection dialog
doc_names = [f"{doc.file_name} ({doc.marca} {doc.modelo})"
for doc in available_docs]
name, ok = QInputDialog.getItem(
self,
"Adicionar Documento",
"Selecione um documento:",
doc_names,
0,
False
)
if ok and name:
index = doc_names.index(name)
doc = available_docs[index]
collection.documents.append(doc)
session.commit()
self.refresh_documents()
session.close()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao adicionar documento: {str(e)}")
def remove_document(self, doc_id):
if not self.current_collection:
return
try:
session = get_session()
collection = session.query(Collection).get(self.current_collection)
document = session.query(Document).get(doc_id)
if collection and document:
collection.documents.remove(document)
session.commit()
self.refresh_documents()
session.close()
except Exception as e:
QMessageBox.critical(self, "Erro",
f"Erro ao remover documento: {str(e)}")
def on_document_clicked(self, item):
doc_id = item.data(Qt.UserRole)
self.document_selected.emit(doc_id)
def show_context_menu(self, position):
item = self.documents_list.itemAt(position)
if not item:
return
doc_id = item.data(Qt.UserRole)
menu = QMenu()
remove_action = menu.addAction("Remover da Coleção")
remove_action.triggered.connect(
lambda: self.remove_document(doc_id))
menu.exec_(self.documents_list.mapToGlobal(position))