"""Splitter tab for extracting files from aggregated markdown.""" import os from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QProgressBar, QFileDialog, QMessageBox ) from PyQt6.QtCore import Qt, QCoreApplication from core.splitter import Splitter from core.exceptions import ObsidianToolException class SplitterTab(QWidget): """Tab for splitting aggregated markdown files.""" def __init__(self): """Initialize the splitter tab.""" super().__init__() self.splitter = Splitter() self.init_ui() def init_ui(self): """Initialize the user interface.""" layout = QVBoxLayout(self) layout.setSpacing(15) layout.setContentsMargins(20, 20, 20, 20) # Aggregated File section layout.addWidget(QLabel("Aggregated File:")) file_layout = QHBoxLayout() self.file_edit = QLineEdit() self.file_edit.setReadOnly(True) self.file_edit.setPlaceholderText("Select an aggregated .md file...") file_layout.addWidget(self.file_edit) self.file_btn = QPushButton("Browse...") self.file_btn.setMaximumWidth(100) self.file_btn.clicked.connect(self.browse_file) file_layout.addWidget(self.file_btn) layout.addLayout(file_layout) # Output Directory section layout.addWidget(QLabel("Output Directory:")) output_layout = QHBoxLayout() self.output_edit = QLineEdit() self.output_edit.setReadOnly(True) self.output_edit.setPlaceholderText("Select output directory...") output_layout.addWidget(self.output_edit) self.output_btn = QPushButton("Browse...") self.output_btn.setMaximumWidth(100) self.output_btn.clicked.connect(self.browse_output) output_layout.addWidget(self.output_btn) layout.addLayout(output_layout) # Spacer layout.addSpacing(20) # Action button self.split_btn = QPushButton("Split Files") self.split_btn.setMinimumHeight(40) self.split_btn.clicked.connect(self.split_files) layout.addWidget(self.split_btn) # Progress bar self.progress_bar = QProgressBar() self.progress_bar.setValue(0) layout.addWidget(self.progress_bar) # Status label self.status_label = QLabel("Ready") self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter) self.status_label.setStyleSheet("color: #666; font-style: italic;") layout.addWidget(self.status_label) # Add stretch to push everything to the top layout.addStretch() def browse_file(self): """Open dialog to select aggregated file.""" file_path, _ = QFileDialog.getOpenFileName( self, "Select Aggregated File", os.path.expanduser("~"), "Markdown Files (*.md);;All Files (*)" ) if file_path: self.file_edit.setText(file_path) self.status_label.setText("Aggregated file selected") def browse_output(self): """Open dialog to select output directory.""" directory = QFileDialog.getExistingDirectory( self, "Select Output Directory", os.path.expanduser("~") ) if directory: self.output_edit.setText(directory) self.status_label.setText("Output directory selected") def split_files(self): """Perform the split operation.""" aggregated_file = self.file_edit.text() output_dir = self.output_edit.text() # Validate inputs if not aggregated_file: QMessageBox.warning( self, "Input Required", "Please select an aggregated file." ) return if not output_dir: QMessageBox.warning( self, "Input Required", "Please select an output directory." ) return # Confirm if output directory is not empty if os.path.exists(output_dir) and os.listdir(output_dir): reply = QMessageBox.question( self, "Directory Not Empty", "The output directory is not empty. Files may be overwritten.\n\n" "Do you want to continue?", QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, QMessageBox.StandardButton.No ) if reply == QMessageBox.StandardButton.No: return # Disable UI during operation self.set_ui_enabled(False) self.progress_bar.setValue(0) self.status_label.setText("Splitting files...") try: # Progress callback def update_progress(percentage, message): self.progress_bar.setValue(percentage) self.status_label.setText(message) QCoreApplication.processEvents() # Keep UI responsive # Perform split result = self.splitter.split( aggregated_file, output_dir, update_progress ) # Show success message QMessageBox.information( self, "Success", f"Split complete!\n\n" f"Files created: {result['files_created']}\n" f"Directories created: {result['directories_created']}\n" f"Output directory: {result['output_dir']}" ) self.status_label.setText("Split completed successfully") except ObsidianToolException as e: QMessageBox.critical( self, "Error", f"Split failed:\n\n{str(e)}" ) self.status_label.setText("Split failed") self.progress_bar.setValue(0) except Exception as e: QMessageBox.critical( self, "Unexpected Error", f"An unexpected error occurred:\n\n{str(e)}" ) self.status_label.setText("Split failed") self.progress_bar.setValue(0) finally: # Re-enable UI self.set_ui_enabled(True) def set_ui_enabled(self, enabled: bool): """Enable or disable UI elements during operation.""" self.file_btn.setEnabled(enabled) self.output_btn.setEnabled(enabled) self.split_btn.setEnabled(enabled)