diff --git a/version_control.py b/version_control.py new file mode 100644 index 0000000..7bb978a --- /dev/null +++ b/version_control.py @@ -0,0 +1,188 @@ +from PySide6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QPushButton, + QTableWidget, QTableWidgetItem, QHeaderView, + QMessageBox, QInputDialog, QFileDialog) +from PySide6.QtCore import Qt +from database import get_session +from models import Document, DocumentVersion +import os +import shutil +from datetime import datetime + +class VersionControl(QWidget): + def __init__(self, parent=None): + super().__init__(parent) + self.current_document = None + self.setup_ui() + + def setup_ui(self): + layout = QVBoxLayout(self) + + # Buttons + button_layout = QHBoxLayout() + self.new_version_btn = QPushButton("Nova Versão") + self.new_version_btn.clicked.connect(self.create_new_version) + self.restore_btn = QPushButton("Restaurar Versão") + self.restore_btn.clicked.connect(self.restore_version) + + button_layout.addWidget(self.new_version_btn) + button_layout.addWidget(self.restore_btn) + layout.addLayout(button_layout) + + # Versions table + self.versions_table = QTableWidget() + self.versions_table.setColumnCount(4) + self.versions_table.setHorizontalHeaderLabels([ + "Versão", "Data de Criação", "Alterações", "Caminho" + ]) + header = self.versions_table.horizontalHeader() + header.setSectionResizeMode(QHeaderView.Stretch) + layout.addWidget(self.versions_table) + + def load_document(self, doc_id): + session = get_session() + self.current_document = session.query(Document).get(doc_id) + self.refresh_versions() + session.close() + + def refresh_versions(self): + if not self.current_document: + return + + session = get_session() + versions = session.query(DocumentVersion)\ + .filter(DocumentVersion.document_id == self.current_document.id)\ + .order_by(DocumentVersion.version_number.desc())\ + .all() + + self.versions_table.setRowCount(len(versions)) + for row, version in enumerate(versions): + self.versions_table.setItem(row, 0, + QTableWidgetItem(str(version.version_number))) + self.versions_table.setItem(row, 1, + QTableWidgetItem(version.created_at.strftime("%Y-%m-%d %H:%M:%S"))) + self.versions_table.setItem(row, 2, + QTableWidgetItem(version.changes or "")) + self.versions_table.setItem(row, 3, + QTableWidgetItem(version.file_path)) + + session.close() + + def create_new_version(self): + if not self.current_document: + return + + # Get new file + file_path, _ = QFileDialog.getOpenFileName( + self, + "Selecionar Nova Versão", + "", + "Todos os Arquivos (*)" + ) + + if not file_path: + return + + # Get change description + changes, ok = QInputDialog.getMultiLineText( + self, + "Descrição das Alterações", + "Descreva as alterações feitas nesta versão:" + ) + + if not ok: + return + + try: + session = get_session() + + # Get next version number + latest_version = session.query(DocumentVersion)\ + .filter(DocumentVersion.document_id == self.current_document.id)\ + .order_by(DocumentVersion.version_number.desc())\ + .first() + + next_version = 1 if not latest_version else latest_version.version_number + 1 + + # Create version directory if it doesn't exist + doc_dir = os.path.dirname(self.current_document.file_path) + versions_dir = os.path.join(doc_dir, "versions") + os.makedirs(versions_dir, exist_ok=True) + + # Copy file to versions directory + new_file_name = f"v{next_version}_{os.path.basename(file_path)}" + new_file_path = os.path.join(versions_dir, new_file_name) + shutil.copy2(file_path, new_file_path) + + # Create new version record + new_version = DocumentVersion( + document_id=self.current_document.id, + version_number=next_version, + file_path=new_file_path, + changes=changes + ) + + session.add(new_version) + session.commit() + + # Update current document + self.current_document.file_path = file_path + session.commit() + + self.refresh_versions() + QMessageBox.information(self, "Sucesso", + "Nova versão criada com sucesso!") + + except Exception as e: + QMessageBox.critical(self, "Erro", + f"Erro ao criar nova versão: {str(e)}") + finally: + session.close() + + def restore_version(self): + current_row = self.versions_table.currentRow() + if current_row < 0: + QMessageBox.warning(self, "Aviso", + "Selecione uma versão para restaurar.") + return + + version_path = self.versions_table.item(current_row, 3).text() + if not os.path.exists(version_path): + QMessageBox.critical(self, "Erro", + "Arquivo da versão não encontrado.") + return + + reply = QMessageBox.question( + self, + "Confirmar Restauração", + "Tem certeza que deseja restaurar esta versão? A versão atual será salva como uma nova versão.", + QMessageBox.Yes | QMessageBox.No + ) + + if reply == QMessageBox.Yes: + try: + session = get_session() + + # Create new version from current state + current_version = DocumentVersion( + document_id=self.current_document.id, + version_number=self.current_document.versions[-1].version_number + 1, + file_path=self.current_document.file_path, + changes="Versão automática antes da restauração" + ) + + session.add(current_version) + + # Restore selected version + shutil.copy2(version_path, self.current_document.file_path) + + session.commit() + self.refresh_versions() + + QMessageBox.information(self, "Sucesso", + "Versão restaurada com sucesso!") + + except Exception as e: + QMessageBox.critical(self, "Erro", + f"Erro ao restaurar versão: {str(e)}") + finally: + session.close()