177 lines
6.6 KiB
Python
177 lines
6.6 KiB
Python
from PySide6.QtWidgets import (QTreeView, QFileDialog, QMenu, QInputDialog,
|
|
QMessageBox)
|
|
from PySide6.QtCore import Qt, QModelIndex, Signal
|
|
from PySide6.QtGui import QStandardItemModel, QStandardItem
|
|
from database import get_session
|
|
from models import Folder
|
|
import os
|
|
from preferences import Preferences
|
|
|
|
class FolderTreeView(QTreeView):
|
|
folder_selected = Signal(int) # Signal for folder selection
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.model = QStandardItemModel()
|
|
self.model.setHorizontalHeaderLabels(['Pastas'])
|
|
self.setModel(self.model)
|
|
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
self.customContextMenuRequested.connect(self.show_context_menu)
|
|
self.preferences = Preferences()
|
|
self.load_folders()
|
|
|
|
# Connect selection changed signal
|
|
self.selectionModel().selectionChanged.connect(self.on_folder_selected)
|
|
|
|
def load_folders(self):
|
|
self.model.clear()
|
|
self.model.setHorizontalHeaderLabels(['Pastas'])
|
|
session = get_session()
|
|
|
|
root_folders = session.query(Folder).filter(Folder.parent_id == None).all()
|
|
|
|
for folder in root_folders:
|
|
item = QStandardItem(folder.name)
|
|
item.setData(folder.id)
|
|
self.model.appendRow(item)
|
|
self.load_subfolders(folder, item)
|
|
|
|
session.close()
|
|
|
|
def load_subfolders(self, folder, parent_item):
|
|
session = get_session()
|
|
subfolders = session.query(Folder).filter(Folder.parent_id == folder.id).all()
|
|
|
|
for subfolder in subfolders:
|
|
item = QStandardItem(subfolder.name)
|
|
item.setData(subfolder.id)
|
|
parent_item.appendRow(item)
|
|
self.load_subfolders(subfolder, item)
|
|
|
|
session.close()
|
|
|
|
def get_physical_path(self, folder):
|
|
"""Get the physical path for a folder"""
|
|
base_path = self.preferences.get_save_path()
|
|
if not base_path:
|
|
QMessageBox.warning(self, "Erro", "Por favor, configure o diretório de salvamento nas preferências primeiro.")
|
|
return None
|
|
|
|
path_parts = []
|
|
current = folder
|
|
while current:
|
|
path_parts.insert(0, current.name)
|
|
current = current.parent
|
|
|
|
# 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("\\", "/")
|
|
|
|
def create_physical_folder(self, folder):
|
|
"""Create the physical folder on disk"""
|
|
physical_path = self.get_physical_path(folder)
|
|
if physical_path and not os.path.exists(physical_path):
|
|
try:
|
|
os.makedirs(physical_path)
|
|
return True
|
|
except Exception as e:
|
|
QMessageBox.warning(self, "Erro", f"Erro ao criar pasta física: {str(e)}")
|
|
return False
|
|
return True
|
|
|
|
def show_context_menu(self, position):
|
|
menu = QMenu()
|
|
add_action = menu.addAction("Nova Pasta")
|
|
delete_action = menu.addAction("Excluir Pasta")
|
|
rename_action = menu.addAction("Renomear")
|
|
|
|
action = menu.exec_(self.mapToGlobal(position))
|
|
|
|
if action == add_action:
|
|
self.add_folder()
|
|
elif action == delete_action:
|
|
self.delete_folder()
|
|
elif action == rename_action:
|
|
self.rename_folder()
|
|
|
|
def on_folder_selected(self, selected, deselected):
|
|
indexes = selected.indexes()
|
|
if indexes:
|
|
current_item = self.model.itemFromIndex(indexes[0])
|
|
folder_id = current_item.data()
|
|
self.folder_selected.emit(folder_id)
|
|
|
|
def add_folder(self):
|
|
name, ok = QInputDialog.getText(self, "Nova Pasta", "Nome da pasta:")
|
|
if ok and name:
|
|
session = get_session()
|
|
current_index = self.currentIndex()
|
|
|
|
new_folder = Folder(name=name)
|
|
if current_index.isValid():
|
|
parent_id = self.model.itemFromIndex(current_index).data()
|
|
parent_folder = session.query(Folder).get(parent_id)
|
|
new_folder.parent_id = parent_id
|
|
new_folder.parent = parent_folder
|
|
|
|
session.add(new_folder)
|
|
session.commit()
|
|
|
|
# Create physical folder
|
|
if not self.create_physical_folder(new_folder):
|
|
session.delete(new_folder)
|
|
session.commit()
|
|
|
|
session.close()
|
|
self.load_folders()
|
|
|
|
def delete_folder(self):
|
|
current_index = self.currentIndex()
|
|
if not current_index.isValid():
|
|
return
|
|
|
|
reply = QMessageBox.question(self, "Confirmar Exclusão",
|
|
"Tem certeza que deseja excluir esta pasta?\nIsso também excluirá a pasta física do disco.",
|
|
QMessageBox.Yes | QMessageBox.No)
|
|
|
|
if reply == QMessageBox.Yes:
|
|
session = get_session()
|
|
folder_id = self.model.itemFromIndex(current_index).data()
|
|
folder = session.query(Folder).get(folder_id)
|
|
if folder:
|
|
# Delete physical folder
|
|
physical_path = self.get_physical_path(folder)
|
|
if physical_path and os.path.exists(physical_path):
|
|
try:
|
|
os.rmdir(physical_path) # Only removes if empty
|
|
except Exception as e:
|
|
QMessageBox.warning(self, "Aviso", f"Não foi possível excluir a pasta física: {str(e)}")
|
|
|
|
session.delete(folder)
|
|
session.commit()
|
|
session.close()
|
|
self.load_folders()
|
|
|
|
def rename_folder(self):
|
|
current_index = self.currentIndex()
|
|
if not current_index.isValid():
|
|
return
|
|
|
|
current_name = self.model.itemFromIndex(current_index).text()
|
|
name, ok = QInputDialog.getText(self, "Renomear Pasta",
|
|
"Novo nome:", text=current_name)
|
|
|
|
if ok and name:
|
|
session = get_session()
|
|
folder_id = self.model.itemFromIndex(current_index).data()
|
|
folder = session.query(Folder).get(folder_id)
|
|
if folder:
|
|
folder.name = name
|
|
session.commit()
|
|
session.close()
|
|
self.load_folders()
|