fromdatetimeimportdatetimeimportsysfrompathlibimportPathfromtypingimportOptional,DictfromPySide6.QtWidgetsimportQApplication,QMainWindow,QWidget,QHeaderViewfromPySide6.QtCoreimportSignalfromPySide6.QtGuiimport(QResizeEvent,QStandardItemModel,QStandardItem,)# Add the parent directory of 'src' to sys.pathcurrent_dir=Path(__file__).resolve().parentparent_dir=current_dir.parent.parent# Adjust according to your project structuresys.path.append(str(parent_dir))# UI importsfromsrc.ui.welcome_uiimportUi_MainWindow# noqa: E402# Core importsfromsrc.core.project_creation_dialogimportProjectCreationDialog# noqa: E402fromsrc.core.project_opening_dialogimportProjectOpeningDialog# noqa: E402fromsrc.core.settingsimport(# noqa: E402load_settings,load_themes,load_current_theme,get_recent_project_paths,load_ui,update_image,)fromsrc.core.videoeditorimportVideoEditorWindow# noqa: E402# Utils importsfromsrc.utils.logger_utilityimportlogger# noqa: E402
[docs]classMain(QMainWindow):"""Main class for the application"""styleSheetUpdated=Signal(str)videoEditorOpened=Signal(str)@logger.catchdef__init__(self,parent:Optional[QWidget]=None)->None:"""Initializer"""super().__init__(parent)self.customStyleSheet=""self.settings:Dict=load_settings()self.themes:Dict=load_themes()self.current_theme:Dict=load_current_theme()logger.info("Main window initialized")self.ui=load_ui(main_window=self,ui=Ui_MainWindow(),settings=self.settings,current_theme=self.current_theme,themes=self.themes,)# Populate the recent projects list with the 10 latest projectsself.populate_recent_projects()self.ui.recentProjectsTableView.doubleClicked.connect(lambda:self.open_project_from_list(self.ui.recentProjectsTableView.selectedIndexes()[0]))
[docs]@logger.catchdefresizeEvent(self,event:QResizeEvent)->None:"""Resize event for the main window"""super().resizeEvent(event)update_image(ui=self.ui,current_theme=self.current_theme)self.update_table_view()
[docs]@logger.catchdefupdate_table_view(self)->None:"""Update the table view based on the theme and resize event."""# Resize to fit the window, expand if neededself.ui.recentProjectsTableView.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
[docs]@logger.catchdefpopulate_recent_projects(self):# Create a model with 3 columnsmodel=QStandardItemModel(0,3,self)model.setHorizontalHeaderLabels(["Project Path","Last Modified","Size"])forprojectinget_recent_project_paths():# Convert the last_modified timestamp to a human-readable formatlast_modified_date=datetime.fromtimestamp(project["last_modified"]).strftime("%Y-%m-%d %H:%M:%S")# Format the size in a more readable format, e.g., in KB, MBsize_kb=project["size"]/1024# Convert size to KBifsize_kb<1024:size_str=f"{size_kb:.2f} KB"else:size_mb=size_kb/1024size_str=f"{size_mb:.2f} MB"# Create items for each columnpath_item=QStandardItem(project["path"])modified_item=QStandardItem(last_modified_date)size_item=QStandardItem(size_str)# Append the row to the modelmodel.appendRow([path_item,modified_item,size_item])# Set the model to the table viewself.ui.recentProjectsTableView.setModel(model)# Resize columns to fit contentself.ui.recentProjectsTableView.resizeColumnsToContents()
[docs]@logger.catchdefopen_project_from_list(self,index):# Retrieve the project path from the model item at the clicked indexmodel=self.ui.recentProjectsTableView.model()project_path=model.data(model.index(index.row(),0))# Assuming the project path is in the first column# Now you can call the method to open the projectself.open_video_editor(project_path)
[docs]@logger.catchdefshow_project_creation_dialog(self)->None:"""Show the project creation dialog"""try:dialog:ProjectCreationDialog=ProjectCreationDialog(self)dialog.projectCreated.connect(self.open_video_editor)# Connect to the new methodself.videoEditorOpened.connect(dialog.close)# Close dialog when VideoEditor opensself.videoEditorOpened.connect(self.close)# Close the main window (WelcomeScreen) as wellifdialog.exec():passexceptExceptionase:logger.error(f"Error showing project creation dialog: {e}")
[docs]@logger.catchdefshow_project_open_dialog(self)->None:"""Show the project open dialog"""try:dialog:ProjectOpeningDialog=ProjectOpeningDialog(self)dialog.projectSelected.connect(self.open_video_editor)self.videoEditorOpened.connect(dialog.close)# Close dialog when VideoEditor opensself.videoEditorOpened.connect(self.close)# Close the main window (WelcomeScreen) as welldialog.exec()exceptExceptionase:logger.error(f"Error showing project open dialog: {e}")
[docs]@logger.catchdefopen_video_editor(self,project_file_path:str)->None:"""Open the video editor with the project file"""try:self.videoEditor=VideoEditorWindow(self)# Change window title as current project name with file pathself.videoEditor.setWindowTitle(f"Manim Studio - {project_file_path}")# Emit the signal after VideoEditor dialog is openedself.videoEditorOpened.emit(project_file_path)self.close()self.videoEditor.show()exceptExceptionase:logger.error(f"Error opening video editor: {e}")pass
if__name__=="__main__":"""Main entry point for the application"""app=QApplication(sys.argv)widget=Main()widget.show()sys.exit(app.exec())