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()