import traceback from PyQt5.QtWidgets import QDialog, QCommandLinkButton, QListWidgetItem, QFileDialog, QWidget, QHBoxLayout, QLabel, QToolButton, QLayout from PyQt5.QtGui import QPixmap, QResizeEvent, QFont from PyQt5.QtCore import Qt, pyqtSignal from ui.welcome.welcome_dialog_ui import Ui_WelcomeDialog from model import RecentProject from business import ProjectManager from properties.config import PROJECT_EXTENSION class RecentProjectListWidget(QWidget): deleted = pyqtSignal() pinned = pyqtSignal(bool) def __init__(self, recentProject : RecentProject): super().__init__() self.project = recentProject self.__selected = False self.setupUi() self.setupActions() self.__setProject(recentProject) self.setSelected(False) def setupUi(self): layout = QHBoxLayout() # label self.__text = QLabel() layout.addWidget(self.__text) # space layout.addStretch() # pin button self.__pin_button = QToolButton() self.__pin_button.setFont(QFont("Font Awesome 5 Free")) self.__pin_button.setText("\uf08d") self.__pin_button.setCheckable(True) layout.addWidget(self.__pin_button) # delete button self.__del_button = QToolButton() self.__del_button.setFont(QFont("Font Awesome 5 Free")) self.__del_button.setText("\uf2ed") layout.addWidget(self.__del_button) # pin indicator self.__pin_indicator = QLabel() self.__pin_indicator.setFont(QFont("Font Awesome 5 Free")) self.__pin_indicator.setText("\uf08d") layout.addWidget(self.__pin_indicator) # done layout.setSizeConstraint(QLayout.SetMinimumSize) self.setLayout(layout) def setupActions(self): self.__pin_button.toggled.connect(self.__pinnedToggled) self.__del_button.pressed.connect(self.deleted) def setSelected(self, selected : bool = True): self.__selected = selected self.__pin_button.setVisible(selected) self.__del_button.setVisible(selected) self.__pin_indicator.setVisible(not self.__selected and self.__pin_button.isChecked()) def setPinned(self, isPinned : bool = True): self.__pin_button.setChecked(isPinned) def __setProject(self, project : RecentProject): self.__text = project.name self.setPinned(project.pinned) def __pinnedToggled(self, isPinned : bool): self.__pin_indicator.setVisible(not self.__selected and isPinned) if (isPinned != self.project.pinned): self.pinned.emit(isPinned) class WelcomeDialog(QDialog): NEW_PROJECT = 0 OPEN_PROJECT = 1 def __init__(self, projectManager : ProjectManager, parent : QWidget = None): super().__init__(parent) self.__projectManager = projectManager self.resultAction : int = None self.projectToOpen : str = None self.setResult(QDialog.Rejected) self.setupUi() self.setupActions() self.populateRecentProjects() def setupUi(self) -> None: self.ui = Ui_WelcomeDialog() self.ui.setupUi(self) self.image = QPixmap(self.ui.picture.pixmap()) def setupActions(self) -> None: self.ui.buttonNewProject.pressed.connect(self.newProjectPressed) self.ui.buttonOpenProject.pressed.connect(self.openProjectPressed) self.ui.listRecentProjects.currentItemChanged.connect(self.listRecentProjectsCurrentChanged) self.ui.listRecentProjects.itemActivated.connect(self.listRecentProjectsItemActivated) def resizeEvent(self, event : QResizeEvent) -> None: super().resizeEvent(event) picSize = self.ui.picture.size() pic = self.image.scaled(picSize, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) self.ui.picture.setPixmap(pic) def populateRecentProjects(self) -> None: projects = list(self.__projectManager.getRecentProjects()) projects = sorted(projects, key=lambda x: (x.pinned, x.dateAccessed), reverse=True) for project in projects: widget = RecentProjectListWidget(project) widget.pinned.connect(self.__projectPinned) widget.deleted.connect(self.__projectDeleted) item = QListWidgetItem(project.name) item.setData(Qt.UserRole, project) item.setSizeHint(widget.sizeHint()) self.ui.listRecentProjects.addItem(item) self.ui.listRecentProjects.setItemWidget(item, widget) def newProjectPressed(self) -> None: self.resultAction = WelcomeDialog.NEW_PROJECT self.accept() def openProjectPressed(self) -> None: proj = QFileDialog.getOpenFileName( self, self.tr('Open project'), '', self.tr(f'Project files (*.{PROJECT_EXTENSION});;All files (*.*)')) if proj[0]: self.projectToOpen = proj[0] self.resultAction = WelcomeDialog.OPEN_PROJECT self.accept() def listRecentProjectsCurrentChanged(self, current : QListWidgetItem, previous : QListWidgetItem) -> None: if not current is None: RecentProjectListWidget = self.ui.listRecentProjects.itemWidget(current) RecentProjectListWidget.setSelected(True) if not previous is None: RecentProjectListWidget = self.ui.listRecentProjects.itemWidget(previous) if not RecentProjectListWidget is None: RecentProjectListWidget.setSelected(False) def listRecentProjectsItemActivated(self, item : QListWidgetItem) -> None: project : RecentProject = item.data(Qt.UserRole) self.resultAction = WelcomeDialog.OPEN_PROJECT self.projectToOpen = project.path self.accept() def __projectPinned(self, isPinned : bool) -> None: project = self.ui.listRecentProjects.currentItem().data(Qt.UserRole) self.__projectManager.pinRecentProject(project, isPinned) def __projectDeleted(self) -> None: project = self.ui.listRecentProjects.currentItem().data(Qt.UserRole) try: self.__projectManager.deleteRecentProject(project) self.ui.listRecentProjects.takeItem(self.ui.listRecentProjects.currentRow()) except: print("Error while deleting! ") traceback.print_exc()