Add a way to delete entries in the recent projects list

This commit is contained in:
Veronica Berglyd Olsen
2023-12-29 13:41:10 +01:00
parent bbabc41ac2
commit 53228faaa3
2 changed files with 70 additions and 15 deletions
+6 -6
View File
@@ -652,12 +652,12 @@ class Config:
} }
conf["Sizes"] = { conf["Sizes"] = {
"mainwindow": self._packList(self._mainWinSize), "mainwindow": self._packList(self._mainWinSize),
"welcome": self._packList(self._welcomeSize), "welcome": self._packList(self._welcomeSize),
"preferences": self._packList(self._prefsWinSize), "preferences": self._packList(self._prefsWinSize),
"mainpane": self._packList(self._mainPanePos), "mainpane": self._packList(self._mainPanePos),
"viewpane": self._packList(self._viewPanePos), "viewpane": self._packList(self._viewPanePos),
"outlinepane": self._packList(self._outlnPanePos), "outlinepane": self._packList(self._outlnPanePos),
} }
conf["Project"] = { conf["Project"] = {
+64 -9
View File
@@ -36,7 +36,7 @@ from PyQt5.QtCore import (
) )
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QComboBox, QDialog, QDialogButtonBox, QFileDialog, QFormLayout, QComboBox, QDialog, QDialogButtonBox, QFileDialog, QFormLayout,
QHBoxLayout, QLabel, QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QHBoxLayout, QLabel, QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut,
QSpinBox, QStackedWidget, QStyle, QStyleOptionViewItem, QStyledItemDelegate, QSpinBox, QStackedWidget, QStyle, QStyleOptionViewItem, QStyledItemDelegate,
QToolButton, QVBoxLayout, QWidget, qApp QToolButton, QVBoxLayout, QWidget, qApp
) )
@@ -76,6 +76,9 @@ class GuiWelcome(QDialog):
self.resize(*CONFIG.welcomeWinSize) self.resize(*CONFIG.welcomeWinSize)
# Elements
# ========
self.bgImage = SHARED.theme.loadDecoration("welcome") self.bgImage = SHARED.theme.loadDecoration("welcome")
self.nwImage = SHARED.theme.loadDecoration("nw-text", h=hD) self.nwImage = SHARED.theme.loadDecoration("nw-text", h=hD)
@@ -102,8 +105,9 @@ class GuiWelcome(QDialog):
# Buttons # Buttons
# ======= # =======
self.btnBox = QDialogButtonBox(QDialogButtonBox.Open | QDialogButtonBox.Cancel, self) self.btnBox = QDialogButtonBox(QDialogButtonBox.Open | QDialogButtonBox.Cancel, self)
self.btnBox.accepted.connect(self._openSelectedProject) self.btnBox.accepted.connect(self.tabOpen.openSelectedItem)
self.btnBox.rejected.connect(self.close) self.btnBox.rejected.connect(self.close)
self.newButton = self.btnBox.addButton(self.tr("New Project"), QDialogButtonBox.ActionRole) self.newButton = self.btnBox.addButton(self.tr("New Project"), QDialogButtonBox.ActionRole)
@@ -116,6 +120,7 @@ class GuiWelcome(QDialog):
# Assemble # Assemble
# ======== # ========
self.innerBox = QVBoxLayout() self.innerBox = QVBoxLayout()
self.innerBox.addSpacing(hB) self.innerBox.addSpacing(hB)
self.innerBox.addWidget(self.nwLabel) self.innerBox.addWidget(self.nwLabel)
@@ -187,13 +192,6 @@ class GuiWelcome(QDialog):
self._openProjectPath(path) self._openProjectPath(path)
return return
@pyqtSlot()
def _openSelectedProject(self) -> None:
"""Open the selected project."""
if selected := self.tabOpen.listWidget.selectedIndexes():
self._openProjectPath(Path(str(selected[0].data()[1])))
return
@pyqtSlot(Path) @pyqtSlot(Path)
def _openProjectPath(self, path: Path) -> None: def _openProjectPath(self, path: Path) -> None:
"""Emit a project open signal.""" """Emit a project open signal."""
@@ -225,19 +223,28 @@ class _OpenProjectPage(QWidget):
hPx = CONFIG.pxInt(6) hPx = CONFIG.pxInt(6)
vPx = CONFIG.pxInt(4) vPx = CONFIG.pxInt(4)
# List View
self.listModel = _ProjectListModel(self) self.listModel = _ProjectListModel(self)
self.itemDelegate = _ProjectListItem(self) self.itemDelegate = _ProjectListItem(self)
self.listWidget = QListView(self) self.listWidget = QListView(self)
self.listWidget.setItemDelegate(self.itemDelegate) self.listWidget.setItemDelegate(self.itemDelegate)
self.listWidget.setModel(self.listModel) self.listWidget.setModel(self.listModel)
self.listWidget.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.listWidget.clicked.connect(self._projectClicked) self.listWidget.clicked.connect(self._projectClicked)
self.listWidget.doubleClicked.connect(self._projectDoubleClicked) self.listWidget.doubleClicked.connect(self._projectDoubleClicked)
self.listWidget.customContextMenuRequested.connect(self._openContextMenu)
# Info / Tool
self.selectedPath = QLineEdit(self) self.selectedPath = QLineEdit(self)
self.selectedPath.setContentsMargins(hPx, vPx, hPx, vPx) self.selectedPath.setContentsMargins(hPx, vPx, hPx, vPx)
self.selectedPath.setReadOnly(True) self.selectedPath.setReadOnly(True)
self.keyDelete = QShortcut(self)
self.keyDelete.setKey(Qt.Key.Key_Delete)
self.keyDelete.activated.connect(self._deleteSelectedItem)
# Assemble
self.outerBox = QVBoxLayout() self.outerBox = QVBoxLayout()
self.outerBox.addWidget(self.listWidget) self.outerBox.addWidget(self.listWidget)
self.outerBox.addWidget(self.selectedPath) self.outerBox.addWidget(self.selectedPath)
@@ -256,6 +263,17 @@ class _OpenProjectPage(QWidget):
return return
##
# Public Slots
##
@pyqtSlot()
def openSelectedItem(self) -> None:
"""Open the currently selected project item."""
if (selection := self.listWidget.selectedIndexes()) and (index := selection[0]).isValid():
self.openProjectRequest.emit(Path(str(index.data()[1])))
return
## ##
# Private Slots # Private Slots
## ##
@@ -275,6 +293,30 @@ class _OpenProjectPage(QWidget):
self.openProjectRequest.emit(Path(str(index.data()[1]))) self.openProjectRequest.emit(Path(str(index.data()[1])))
return return
@pyqtSlot()
def _deleteSelectedItem(self) -> None:
"""Delete the currently selected project item."""
if (selection := self.listWidget.selectedIndexes()) and (index := selection[0]).isValid():
text = self.tr(
"Remove '{0}' from the recent projects list? "
"The project files will not be deleted."
).format(index.data()[0])
if SHARED.question(text):
self.listModel.removeEntry(index)
return
@pyqtSlot("QPoint")
def _openContextMenu(self, pos: QPoint) -> None:
"""Open the custom context menu."""
ctxMenu = QMenu(self)
action = ctxMenu.addAction(self.tr("Open Project"))
action.triggered.connect(self.openSelectedItem)
action = ctxMenu.addAction(self.tr("Remove Project"))
action.triggered.connect(self._deleteSelectedItem)
ctxMenu.exec_(self.mapToGlobal(pos))
ctxMenu.deleteLater()
return
# END Class _OpenProjectPage # END Class _OpenProjectPage
@@ -358,6 +400,19 @@ class _ProjectListModel(QAbstractListModel):
"""Return data for an individual item.""" """Return data for an individual item."""
return self._data[index.row()] if index.isValid() else ("", "", "") return self._data[index.row()] if index.isValid() else ("", "", "")
def removeEntry(self, index: QModelIndex) -> bool:
"""Remove an entry in the model."""
if index.isValid() and (path := index.data()[1]):
try:
self.beginRemoveRows(index.parent(), index.row(), index.row())
self._data.pop(index.row())
self.endRemoveRows()
except IndexError:
return False
CONFIG.recentProjects.remove(path)
return True
return False
# END Class _ProjectListModel # END Class _ProjectListModel