249 lines
9.6 KiB
Python
249 lines
9.6 KiB
Python
from PySide6.QtWidgets import (QWidget, QVBoxLayout, QTableWidget,
|
|
QTableWidgetItem, QHeaderView, QMenu,
|
|
QMessageBox, QPushButton, QHBoxLayout)
|
|
from PySide6.QtCore import Qt, Signal
|
|
from database import get_session
|
|
from models import Document, Folder
|
|
import os
|
|
from preferences import Preferences
|
|
|
|
class DocumentListView(QWidget):
|
|
document_selected = Signal(int) # Signal emitted when document is selected
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.current_folder_id = None
|
|
self.setup_ui()
|
|
|
|
def setup_ui(self):
|
|
layout = QVBoxLayout(self)
|
|
|
|
# Toolbar
|
|
toolbar = QHBoxLayout()
|
|
self.refresh_btn = QPushButton("Atualizar")
|
|
self.refresh_btn.clicked.connect(self.refresh_documents)
|
|
toolbar.addWidget(self.refresh_btn)
|
|
|
|
self.delete_btn = QPushButton("Excluir Selecionados")
|
|
self.delete_btn.clicked.connect(self.delete_selected)
|
|
toolbar.addWidget(self.delete_btn)
|
|
|
|
layout.addLayout(toolbar)
|
|
|
|
# Documents table
|
|
self.docs_table = QTableWidget()
|
|
self.docs_table.setColumnCount(7)
|
|
self.docs_table.setHorizontalHeaderLabels([
|
|
"Marca", "Modelo", "Ano", "Tipo", "Variante",
|
|
"Nome do Arquivo", "Observações"
|
|
])
|
|
header = self.docs_table.horizontalHeader()
|
|
header.setSectionResizeMode(QHeaderView.ResizeToContents)
|
|
header.setSectionResizeMode(6, QHeaderView.Stretch) # Observações column stretches
|
|
|
|
self.docs_table.setSortingEnabled(True)
|
|
self.docs_table.setSelectionBehavior(QTableWidget.SelectRows)
|
|
self.docs_table.setSelectionMode(QTableWidget.SingleSelection)
|
|
|
|
self.docs_table.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
self.docs_table.customContextMenuRequested.connect(self.show_context_menu)
|
|
self.docs_table.doubleClicked.connect(self.open_document)
|
|
|
|
layout.addWidget(self.docs_table)
|
|
|
|
def set_folder(self, folder_id):
|
|
self.current_folder_id = folder_id
|
|
self.refresh_documents()
|
|
|
|
def refresh_documents(self):
|
|
session = get_session()
|
|
|
|
try:
|
|
# First, let's check all documents and fix their folder associations
|
|
all_documents = session.query(Document).all()
|
|
for doc in all_documents:
|
|
# Check if the document exists
|
|
if os.path.exists(doc.file_path):
|
|
# Always try to find the most specific folder
|
|
folders = session.query(Folder).all()
|
|
best_folder = self.find_best_matching_folder(doc.file_path, folders)
|
|
|
|
if best_folder:
|
|
if doc.folder_id != best_folder.id:
|
|
doc.folder_id = best_folder.id
|
|
session.add(doc)
|
|
else:
|
|
session.delete(doc)
|
|
|
|
# Commit any changes made
|
|
session.commit()
|
|
|
|
# Now get documents for the current folder
|
|
if self.current_folder_id is not None:
|
|
documents = session.query(Document).filter(
|
|
Document.folder_id == self.current_folder_id
|
|
).all()
|
|
else:
|
|
documents = session.query(Document).all()
|
|
|
|
# Update the table
|
|
self.docs_table.setRowCount(len(documents))
|
|
for row, doc in enumerate(documents):
|
|
self.docs_table.setItem(row, 0, QTableWidgetItem(doc.marca))
|
|
self.docs_table.setItem(row, 1, QTableWidgetItem(doc.modelo))
|
|
self.docs_table.setItem(row, 2, QTableWidgetItem(str(doc.ano)))
|
|
self.docs_table.setItem(row, 3, QTableWidgetItem(doc.tipo_documento))
|
|
self.docs_table.setItem(row, 4, QTableWidgetItem(doc.variante))
|
|
self.docs_table.setItem(row, 5, QTableWidgetItem(doc.file_name))
|
|
self.docs_table.setItem(row, 6, QTableWidgetItem(doc.observacoes))
|
|
|
|
# Store document ID in the first column
|
|
self.docs_table.item(row, 0).setData(Qt.UserRole, doc.id)
|
|
|
|
except Exception as e:
|
|
QMessageBox.critical(self, "Erro", f"Erro ao atualizar documentos: {str(e)}")
|
|
finally:
|
|
session.close()
|
|
|
|
def get_folder_path(self, folder):
|
|
"""Get the full path for a folder"""
|
|
try:
|
|
path_parts = []
|
|
current = folder
|
|
while current:
|
|
path_parts.insert(0, current.name)
|
|
current = current.parent
|
|
|
|
# Get base path from preferences
|
|
preferences = Preferences()
|
|
base_path = preferences.get_save_path()
|
|
if base_path:
|
|
# Make sure we're using forward slashes and the correct base path
|
|
# Only add 'Root' if it's not already in the path
|
|
if path_parts and path_parts[0] != "Root":
|
|
path_parts.insert(0, "Root")
|
|
full_path = os.path.join(base_path, *path_parts)
|
|
# Convert to forward slashes for consistency
|
|
return full_path.replace("\\", "/")
|
|
except Exception as e:
|
|
print(f"Error getting folder path: {str(e)}")
|
|
return None
|
|
|
|
def find_best_matching_folder(self, doc_path, folders):
|
|
"""Find the most specific matching folder for a document path"""
|
|
doc_path = doc_path.replace("\\", "/")
|
|
best_match = None
|
|
longest_match = 0
|
|
|
|
for folder in folders:
|
|
folder_path = self.get_folder_path(folder)
|
|
if folder_path:
|
|
folder_path = folder_path.replace("\\", "/")
|
|
|
|
# Make sure paths end with slash for exact directory matching
|
|
folder_path = folder_path.rstrip("/") + "/"
|
|
doc_dir = os.path.dirname(doc_path).rstrip("/") + "/"
|
|
|
|
if doc_dir.startswith(folder_path):
|
|
match_length = len(folder_path)
|
|
if match_length > longest_match:
|
|
longest_match = match_length
|
|
best_match = folder
|
|
|
|
return best_match
|
|
|
|
def show_context_menu(self, position):
|
|
menu = QMenu()
|
|
open_action = menu.addAction("Abrir Documento")
|
|
open_folder_action = menu.addAction("Abrir Pasta")
|
|
menu.addSeparator()
|
|
delete_action = menu.addAction("Excluir")
|
|
|
|
action = menu.exec_(self.docs_table.mapToGlobal(position))
|
|
|
|
current_row = self.docs_table.currentRow()
|
|
if current_row >= 0:
|
|
doc_id = self.docs_table.item(current_row, 0).data(Qt.UserRole)
|
|
|
|
if action == open_action:
|
|
self.open_document()
|
|
elif action == open_folder_action:
|
|
self.open_document_folder(doc_id)
|
|
elif action == delete_action:
|
|
self.delete_document(doc_id)
|
|
|
|
def open_document(self, index=None):
|
|
"""Open the selected document"""
|
|
if index:
|
|
row = index.row()
|
|
else:
|
|
row = self.docs_table.currentRow()
|
|
|
|
if row >= 0:
|
|
doc_id = self.docs_table.item(row, 0).data(Qt.UserRole)
|
|
session = get_session()
|
|
try:
|
|
doc = session.query(Document).get(doc_id)
|
|
if doc and os.path.exists(doc.file_path):
|
|
# Use the default system application to open the file
|
|
os.startfile(doc.file_path)
|
|
else:
|
|
QMessageBox.warning(self, "Erro", "Arquivo não encontrado.")
|
|
except Exception as e:
|
|
QMessageBox.critical(self, "Erro", f"Erro ao abrir documento: {str(e)}")
|
|
finally:
|
|
session.close()
|
|
|
|
def open_document_folder(self, doc_id):
|
|
session = get_session()
|
|
document = session.query(Document).get(doc_id)
|
|
|
|
if document and os.path.exists(document.file_path):
|
|
folder_path = os.path.dirname(document.file_path)
|
|
os.startfile(folder_path)
|
|
else:
|
|
QMessageBox.warning(self, "Erro",
|
|
"Não foi possível abrir a pasta do documento.")
|
|
|
|
session.close()
|
|
|
|
def delete_document(self, doc_id):
|
|
reply = QMessageBox.question(
|
|
self,
|
|
"Confirmar Exclusão",
|
|
"Tem certeza que deseja excluir este documento?",
|
|
QMessageBox.Yes | QMessageBox.No
|
|
)
|
|
|
|
if reply == QMessageBox.Yes:
|
|
session = get_session()
|
|
document = session.query(Document).get(doc_id)
|
|
if document:
|
|
session.delete(document)
|
|
session.commit()
|
|
session.close()
|
|
self.refresh_documents()
|
|
|
|
def delete_selected(self):
|
|
selected_rows = set(item.row() for item in self.docs_table.selectedItems())
|
|
if not selected_rows:
|
|
return
|
|
|
|
reply = QMessageBox.question(
|
|
self,
|
|
"Confirmar Exclusão",
|
|
f"Tem certeza que deseja excluir {len(selected_rows)} documento(s)?",
|
|
QMessageBox.Yes | QMessageBox.No
|
|
)
|
|
|
|
if reply == QMessageBox.Yes:
|
|
session = get_session()
|
|
for row in selected_rows:
|
|
doc_id = self.docs_table.item(row, 0).data(Qt.UserRole)
|
|
document = session.query(Document).get(doc_id)
|
|
if document:
|
|
session.delete(document)
|
|
session.commit()
|
|
session.close()
|
|
self.refresh_documents()
|