Mode esborrar des del menú: tria un joc descarregat i s'elimina
This commit is contained in:
@@ -40,6 +40,7 @@ class GameRow(QFrame):
|
|||||||
self.root = root
|
self.root = root
|
||||||
self._update_available = False
|
self._update_available = False
|
||||||
self._busy = False
|
self._busy = False
|
||||||
|
self._delete_mode = False
|
||||||
self.setObjectName("gameRow")
|
self.setObjectName("gameRow")
|
||||||
self.setFrameShape(QFrame.StyledPanel)
|
self.setFrameShape(QFrame.StyledPanel)
|
||||||
# La fila és un botó: cursor de mà i ressaltat en passar el ratolí.
|
# La fila és un botó: cursor de mà i ressaltat en passar el ratolí.
|
||||||
@@ -118,6 +119,11 @@ class GameRow(QFrame):
|
|||||||
self._update_available = available
|
self._update_available = available
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
|
def set_delete_mode(self, on: bool) -> None:
|
||||||
|
"""Activa/desactiva el mode esborrar (canvia el text d'acció a 'Esborra')."""
|
||||||
|
self._delete_mode = on
|
||||||
|
self.refresh()
|
||||||
|
|
||||||
def refresh(self) -> None:
|
def refresh(self) -> None:
|
||||||
"""Recarrega icona, descripció i estat des de la cache local."""
|
"""Recarrega icona, descripció i estat des de la cache local."""
|
||||||
meta = load_meta(self.root, self.game.id)
|
meta = load_meta(self.root, self.game.id)
|
||||||
@@ -143,20 +149,31 @@ class GameRow(QFrame):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _set_status(self, meta: GameMeta) -> None:
|
def _set_status(self, meta: GameMeta) -> None:
|
||||||
if not self.is_installed():
|
installed = self.is_installed()
|
||||||
|
|
||||||
|
# Text d'estat (independent del mode esborrar).
|
||||||
|
if not installed:
|
||||||
self.status_label.setText("No descarregat")
|
self.status_label.setText("No descarregat")
|
||||||
self.status_label.setStyleSheet("color: #cc8855; font-size: 11px;")
|
self.status_label.setStyleSheet("color: #cc8855; font-size: 11px;")
|
||||||
self._set_action("Descarrega", "#4a90d9")
|
|
||||||
elif self._update_available:
|
elif self._update_available:
|
||||||
self.status_label.setText("⬆ Actualització disponible")
|
self.status_label.setText("⬆ Actualització disponible")
|
||||||
self.status_label.setStyleSheet(
|
self.status_label.setStyleSheet(
|
||||||
"color: #e0a030; font-weight: bold; font-size: 11px;"
|
"color: #e0a030; font-weight: bold; font-size: 11px;"
|
||||||
)
|
)
|
||||||
self._set_action("Actualitza", "#e0a030")
|
|
||||||
else:
|
else:
|
||||||
ver = f" {meta.version}" if meta.version else ""
|
ver = f" {meta.version}" if meta.version else ""
|
||||||
self.status_label.setText(f"Descarregat{ver}")
|
self.status_label.setText(f"Descarregat{ver}")
|
||||||
self.status_label.setStyleSheet("color: #6fae6f; font-size: 11px;")
|
self.status_label.setStyleSheet("color: #6fae6f; font-size: 11px;")
|
||||||
|
|
||||||
|
# Text d'acció (què fa el clic).
|
||||||
|
if self._delete_mode:
|
||||||
|
# Només es pot esborrar el que està descarregat.
|
||||||
|
self._set_action("Esborra", "#d9534f") if installed else self.action_label.clear()
|
||||||
|
elif not installed:
|
||||||
|
self._set_action("Descarrega", "#4a90d9")
|
||||||
|
elif self._update_available:
|
||||||
|
self._set_action("Actualitza", "#e0a030")
|
||||||
|
else:
|
||||||
self._set_action("Juga", "#6fae6f")
|
self._set_action("Juga", "#6fae6f")
|
||||||
|
|
||||||
def _set_action(self, text: str, color: str) -> None:
|
def _set_action(self, text: str, color: str) -> None:
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.settings = load_settings()
|
self.settings = load_settings()
|
||||||
self.pool = QThreadPool.globalInstance()
|
self.pool = QThreadPool.globalInstance()
|
||||||
self.rows: dict[str, GameRow] = {}
|
self.rows: dict[str, GameRow] = {}
|
||||||
|
self._delete_mode = False
|
||||||
# Mantener referencias a los workers en vuelo: si no, Python los recolecta
|
# Mantener referencias a los workers en vuelo: si no, Python los recolecta
|
||||||
# (junto a su objeto de señales) antes de que la señal en cola `finished`
|
# (junto a su objeto de señales) antes de que la señal en cola `finished`
|
||||||
# llegue al hilo principal, y la UI nunca se refresca.
|
# llegue al hilo principal, y la UI nunca se refresca.
|
||||||
@@ -95,6 +96,11 @@ class MainWindow(QMainWindow):
|
|||||||
self.action_check.triggered.connect(self._check_updates)
|
self.action_check.triggered.connect(self._check_updates)
|
||||||
menu.addAction(self.action_check)
|
menu.addAction(self.action_check)
|
||||||
|
|
||||||
|
menu.addSeparator()
|
||||||
|
self.action_delete = QAction("Esborra un joc", self, checkable=True)
|
||||||
|
self.action_delete.toggled.connect(self._set_delete_mode)
|
||||||
|
menu.addAction(self.action_delete)
|
||||||
|
|
||||||
def _on_toggle_hide(self, checked: bool) -> None:
|
def _on_toggle_hide(self, checked: bool) -> None:
|
||||||
self.settings.hide_not_downloaded = checked
|
self.settings.hide_not_downloaded = checked
|
||||||
save_settings(self.settings)
|
save_settings(self.settings)
|
||||||
@@ -150,9 +156,25 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# --------------------------------------------------------------- accions
|
# --------------------------------------------------------------- accions
|
||||||
|
|
||||||
|
def _set_delete_mode(self, on: bool) -> None:
|
||||||
|
self._delete_mode = on
|
||||||
|
for row in self.rows.values():
|
||||||
|
row.set_delete_mode(on)
|
||||||
|
if on:
|
||||||
|
self._log(
|
||||||
|
"Mode esborrar: tria un joc descarregat per eliminar-lo "
|
||||||
|
"(o desmarca «Esborra un joc» per cancel·lar)."
|
||||||
|
)
|
||||||
|
|
||||||
def _on_activate(self, game: Game) -> None:
|
def _on_activate(self, game: Game) -> None:
|
||||||
"""Clic sobre la fila: descarrega/actualitza si cal, si no juga."""
|
"""Clic sobre la fila. En mode esborrar elimina; si no, descarrega/actualitza o juga."""
|
||||||
row = self.rows[game.id]
|
row = self.rows[game.id]
|
||||||
|
if self._delete_mode:
|
||||||
|
if not row.is_installed():
|
||||||
|
return # res a esborrar; segueix en mode esborrar
|
||||||
|
if self._on_delete(game):
|
||||||
|
self.action_delete.setChecked(False) # surt del mode esborrar
|
||||||
|
return
|
||||||
if row.primary_action_is_download():
|
if row.primary_action_is_download():
|
||||||
self._on_download(game)
|
self._on_download(game)
|
||||||
else:
|
else:
|
||||||
@@ -206,7 +228,8 @@ class MainWindow(QMainWindow):
|
|||||||
row.set_busy(False)
|
row.set_busy(False)
|
||||||
row.refresh()
|
row.refresh()
|
||||||
|
|
||||||
def _on_delete(self, game: Game) -> None:
|
def _on_delete(self, game: Game) -> bool:
|
||||||
|
"""Esborra la descàrrega local (amb confirmació). Retorna True si s'ha esborrat."""
|
||||||
resp = QMessageBox.question(
|
resp = QMessageBox.question(
|
||||||
self,
|
self,
|
||||||
"Esborrar descàrrega",
|
"Esborrar descàrrega",
|
||||||
@@ -216,7 +239,7 @@ class MainWindow(QMainWindow):
|
|||||||
QMessageBox.No,
|
QMessageBox.No,
|
||||||
)
|
)
|
||||||
if resp != QMessageBox.Yes:
|
if resp != QMessageBox.Yes:
|
||||||
return
|
return False
|
||||||
self._log(f"=== Esborra: {game.name} ===")
|
self._log(f"=== Esborra: {game.name} ===")
|
||||||
gitops.delete_local(self.root, game, log=self._log)
|
gitops.delete_local(self.root, game, log=self._log)
|
||||||
if game.id in self.settings.updates_pending:
|
if game.id in self.settings.updates_pending:
|
||||||
@@ -228,3 +251,4 @@ class MainWindow(QMainWindow):
|
|||||||
row.set_update_available(False)
|
row.set_update_available(False)
|
||||||
row.refresh()
|
row.refresh()
|
||||||
self._apply_filter() # si està actiu "amaga no descarregats", ara s'amaga
|
self._apply_filter() # si està actiu "amaga no descarregats", ara s'amaga
|
||||||
|
return True
|
||||||
|
|||||||
Reference in New Issue
Block a user