diff options
Diffstat (limited to 'raveos-center/raveos_center/oldalak/alkalmazasok.py')
| -rw-r--r-- | raveos-center/raveos_center/oldalak/alkalmazasok.py | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/oldalak/alkalmazasok.py b/raveos-center/raveos_center/oldalak/alkalmazasok.py new file mode 100644 index 0000000..4ab95e6 --- /dev/null +++ b/raveos-center/raveos_center/oldalak/alkalmazasok.py @@ -0,0 +1,508 @@ +from PyQt6.QtCore import Qt +from PyQt6.QtWidgets import ( + QCheckBox, + QFrame, + QHBoxLayout, + QLineEdit, + QMessageBox, + QPushButton, + QVBoxLayout, + QWidget, +) + +from raveos_center import katalogus +from raveos_center.elemek import Kartya, Oldal, cimke, frissit_stilus, gomb +from raveos_center.folyamat import FolyamatAblak +from raveos_center.hatter import gyorsitott + +AZON = "alkalmazasok" +MENU = "Alkalmazások" +IKON = "alkalmazasok" + +CSAK_TELEPITETT = "telepitett" + + +class KattinthatoSor(QWidget): + def __init__(self, jelolo): + super().__init__() + self.jelolo = jelolo + self.setCursor(Qt.CursorShape.PointingHandCursor) + + def mouseReleaseEvent(self, esemeny): + if esemeny.button() == Qt.MouseButton.LeftButton and self.rect().contains(esemeny.position().toPoint()): + self.jelolo.toggle() + super().mouseReleaseEvent(esemeny) + + +class AppSor(QWidget): + def __init__(self, app, oldal): + super().__init__() + self.app = app + self.oldal = oldal + self.telepitve = False + self.setObjectName("appsor") + self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True) + doboz = QVBoxLayout(self) + doboz.setContentsMargins(16, 12, 16, 12) + doboz.setSpacing(8) + + felso = QHBoxLayout() + felso.setSpacing(14) + self.jelolo = QCheckBox() + self.jelolo.setVisible(app["type"] != "message") + self.jelolo.toggled.connect(self._sor_jelolve) + felso.addWidget(self.jelolo) + betu = cimke(app["name"][:1].upper(), "kezdobetu") + betu.setAlignment(Qt.AlignmentFlag.AlignCenter) + betu.setFixedSize(36, 36) + felso.addWidget(betu) + szovegek = QVBoxLayout() + szovegek.setSpacing(2) + nevsor = QHBoxLayout() + nevsor.setSpacing(10) + nev = cimke(app["name"]) + nev.setStyleSheet("font-size: 14px; font-weight: 600;") + nevsor.addWidget(nev) + nevsor.addWidget(cimke(katalogus.forras(app), "monohalvany")) + self.allapot = cimke("TELEPÍTVE", "allapotcimke") + self.allapot.setProperty("szin", "zold") + self.allapot.hide() + nevsor.addWidget(self.allapot) + nevsor.addStretch(1) + szovegek.addLayout(nevsor) + leiras = katalogus.loc(app.get("desc")) + self.leiras = cimke(leiras, "halvany") + self.leiras.setToolTip(leiras) + self.leiras.setMinimumWidth(80) + szovegek.addWidget(self.leiras) + felso.addLayout(szovegek, 1) + + self.eltavolit_gomb = None + if app["type"] == "choice": + self.eltavolit_gomb = gomb("Eltávolítás", kicsi=True) + self.eltavolit_gomb.clicked.connect(lambda: self._opcio_muvelet(False)) + felso.addWidget(self.eltavolit_gomb) + self.gomb = gomb("", kicsi=True) + self.gomb.setMinimumWidth(110) + self.gomb.clicked.connect(self._kattint) + felso.addWidget(self.gomb) + doboz.addLayout(felso) + + self.opciok = [] + if app["type"] == "choice": + self._opcio_lista(doboz) + elif app["type"] != "message": + self.setCursor(Qt.CursorShape.PointingHandCursor) + self.frissit(oldal.index) + + def mouseReleaseEvent(self, esemeny): + if ( + esemeny.button() == Qt.MouseButton.LeftButton + and self.app["type"] not in ("choice", "message") + and self.rect().contains(esemeny.position().toPoint()) + ): + self.jelolo.toggle() + super().mouseReleaseEvent(esemeny) + + def resizeEvent(self, esemeny): + super().resizeEvent(esemeny) + teljes = self.leiras.toolTip() + self.leiras.setText( + self.leiras.fontMetrics().elidedText(teljes, Qt.TextElideMode.ElideRight, max(80, self.leiras.width())) + ) + + def _opcio_lista(self, doboz): + lista = QVBoxLayout() + lista.setContentsMargins(82, 4, 0, 0) + lista.setSpacing(6) + fej = QHBoxLayout() + fej.addWidget(cimke("VÁLASSZ, AKÁR TÖBBET IS", "monohalvany")) + fej.addStretch(1) + mind = gomb("Mind kijelölése", kicsi=True) + mind.clicked.connect(self._mind) + fej.addWidget(mind) + lista.addLayout(fej) + for o in self.app.get("options", []): + jelolo = QCheckBox(o["name"]) + jelolo.setMinimumWidth(130) + jelolo.toggled.connect(lambda _: self._gombok_opcio()) + kontener = KattinthatoSor(jelolo) + sor = QHBoxLayout(kontener) + sor.setContentsMargins(0, 2, 0, 2) + sor.setSpacing(10) + sor.addWidget(jelolo) + leiras = cimke(katalogus.loc(o.get("desc")), "halvany") + sor.addWidget(leiras, 1) + allapot = cimke("TELEPÍTVE", "allapotcimke") + allapot.setProperty("szin", "zold") + sor.addWidget(allapot) + lista.addWidget(kontener) + self.opciok.append((jelolo, allapot, o)) + doboz.addLayout(lista) + + def _mind(self): + mind = all(j.isChecked() for j, _, _ in self.opciok) + for j, _, _ in self.opciok: + j.setChecked(not mind) + + def _sor_jelolve(self, jelolve): + if self.opciok: + for j, _, _ in self.opciok: + j.blockSignals(True) + j.setChecked(jelolve) + j.blockSignals(False) + self._gombok_opcio() + self.oldal.kijeles_valtozott() + + def torol_kijeles(self): + self.jelolo.setChecked(False) + + def telepitendo(self): + if self.app["type"] == "choice": + opciok = self._kijelolt(False) + return (self.app, opciok) if opciok else None + if self.jelolo.isChecked() and not self.telepitve and self.app["type"] != "message": + return (self.app, None) + return None + + def eltavolitando(self): + if self.app["type"] == "choice": + opciok = self._kijelolt(True) + return (self.app, opciok) if opciok else None + if self.jelolo.isChecked() and self.telepitve and katalogus.eltavolithato(self.app): + return (self.app, None) + return None + + def _kijelolt(self, telepitett): + return [ + o["id"] + for j, _, o in self.opciok + if j.isChecked() and katalogus.opcio_telepitve(o, self.oldal.index) == telepitett + ] + + def _gombok_opcio(self): + uj = self._kijelolt(False) + regi = self._kijelolt(True) + self.jelolo.blockSignals(True) + self.jelolo.setChecked(any(j.isChecked() for j, _, _ in self.opciok)) + self.jelolo.blockSignals(False) + self.oldal.kijeles_valtozott() + self.gomb.setText(f"Telepítés ({len(uj)})" if uj else "Telepítés") + self.gomb.setEnabled(bool(uj)) + self.gomb.setProperty("fo", True) + frissit_stilus(self.gomb) + self.eltavolit_gomb.setText(f"Eltávolítás ({len(regi)})" if regi else "Eltávolítás") + self.eltavolit_gomb.setEnabled(bool(regi)) + + def _opcio_muvelet(self, telepites): + kijelolt = self._kijelolt(not telepites) + if kijelolt: + self.oldal.muvelet(self.app, telepites, kijelolt) + + def frissit(self, index): + if self.app["type"] == "choice": + db = 0 + for _, allapot, o in self.opciok: + fent = katalogus.opcio_telepitve(o, index) + allapot.setVisible(fent) + db += fent + self.telepitve = db > 0 + self.allapot.setText(f"{db} / {len(self.opciok)} TELEPÍTVE") + self.allapot.setVisible(db > 0) + self._gombok_opcio() + return + if self.app["type"] == "message": + self.gomb.setText("Tudnivalók") + self.gomb.setProperty("fo", False) + else: + self.telepitve = katalogus.telepitve(self.app, index) + self.allapot.setVisible(self.telepitve) + if self.telepitve: + self.gomb.setText("Eltávolítás") + self.gomb.setEnabled(katalogus.eltavolithato(self.app)) + self.gomb.setProperty("fo", False) + else: + self.gomb.setText("Telepítés") + self.gomb.setEnabled(True) + self.gomb.setProperty("fo", True) + frissit_stilus(self.gomb) + + def _kattint(self): + if self.app["type"] == "message": + QMessageBox.information(self, self.app["name"], katalogus.loc(self.app.get("message"))) + return + if self.app["type"] == "choice": + self._opcio_muvelet(True) + return + self.oldal.muvelet(self.app, not self.telepitve) + + +class Csoport(QWidget): + def __init__(self, nev): + super().__init__() + self.nev = nev + doboz = QVBoxLayout(self) + doboz.setContentsMargins(0, 0, 0, 0) + doboz.setSpacing(10) + self.fejlec = cimke("", "h2") + doboz.addWidget(self.fejlec) + self.lista = Kartya(terkoz=0, margo=0) + doboz.addWidget(self.lista) + self.sorok = [] + + def hozzaad(self, sor): + self.sorok.append(sor) + self.lista.elrendezes.addWidget(sor) + + def szur(self, lathatok): + db = 0 + utolso = None + for sor in self.sorok: + lathato = sor in lathatok + sor.setVisible(lathato) + sor.setProperty("utolso", False) + if lathato: + db += 1 + utolso = sor + if utolso: + utolso.setProperty("utolso", True) + for sor in self.sorok: + frissit_stilus(sor) + self.fejlec.setText(f"{self.nev.upper()} · {db}") + self.setVisible(db > 0) + return db + + +class Alkalmazasok(Oldal): + def __init__(self, kozpont): + super().__init__(kozpont, "PACMAN · AUR · FLATPAK", "Alkalmazások") + self.katalogus = [] + self.index = {"pacman": set(), "flatpak": set()} + self.sorok = [] + self.csoportok = {} + self.kategoria = "all" + + self.kereso = QLineEdit() + self.kereso.setPlaceholderText("Keresés, pl. Steam, OBS, Discord") + self.kereso.setClearButtonEnabled(True) + self.kereso.setMinimumWidth(220) + self.kereso.setMaximumWidth(340) + self.kereso.textChanged.connect(self._szur) + self.fejlec_gomb(self.kereso) + + pillek = QHBoxLayout() + pillek.setSpacing(8) + self.pillek = {} + for azon, nev in katalogus.KATEGORIAK + [(CSAK_TELEPITETT, "Csak telepítettek")]: + p = QPushButton(nev) + p.setObjectName("pill") + p.setCursor(Qt.CursorShape.PointingHandCursor) + p.clicked.connect(lambda _=False, a=azon: self._kategoria(a)) + self.pillek[azon] = p + if azon == CSAK_TELEPITETT: + pillek.addStretch(1) + pillek.addWidget(p) + self.torzs.addLayout(pillek) + + self.kiemelt = Kartya(terkoz=8, margo=24) + self.kiemelt.setObjectName("kiemelt") + ks = QHBoxLayout() + ks.setSpacing(24) + kszoveg = QVBoxLayout() + kszoveg.setSpacing(6) + kszoveg.addWidget(cimke("CSOMAG · GAMING ALAPOK", "eyebrow")) + kszoveg.addWidget(cimke("EGY KATTINTÁS, MINDEN AMI JÁTÉKHOZ KELL", "h2", True)) + kszoveg.addWidget( + cimke("Steam (Proton-GE-vel), Lutris, Heroic, GameMode és MangoHud egyben, előre beállítva.", "masodlagos", True) + ) + ks.addLayout(kszoveg, 1) + self.kiemelt_gomb = gomb("Csomag telepítése", fo=True) + self.kiemelt_gomb.clicked.connect(self._gaming_alapok) + ks.addWidget(self.kiemelt_gomb, 0, Qt.AlignmentFlag.AlignVCenter) + self.kiemelt.elrendezes.addLayout(ks) + self.torzs.addWidget(self.kiemelt) + + self.hiba = cimke("", "figyelem", True) + self.hiba.hide() + self.torzs.addWidget(self.hiba) + self._kijeles_sav() + self.lista = QVBoxLayout() + self.lista.setSpacing(28) + self.torzs.addLayout(self.lista) + self.ures = cimke("Nincs találat.", "halvany") + self.ures.hide() + self.torzs.addWidget(self.ures) + self.torzs.addStretch(1) + self._betolt() + self._kategoria("all") + + def _kijeles_sav(self): + self.sav = QFrame(self) + self.sav.setObjectName("kijelessav") + s = QHBoxLayout(self.sav) + s.setContentsMargins(48, 12, 48, 12) + s.setSpacing(8) + self.sav_szoveg = cimke("", "mono") + s.addWidget(self.sav_szoveg) + s.addStretch(1) + torles = gomb("Kijelölés törlése", kicsi=True) + torles.clicked.connect(self._kijeles_torles) + s.addWidget(torles) + self.sav_eltavolit = gomb("Kijelöltek eltávolítása") + self.sav_eltavolit.clicked.connect(lambda: self._tomeges(False)) + s.addWidget(self.sav_eltavolit) + self.sav_telepit = gomb("Kijelöltek telepítése", fo=True) + self.sav_telepit.clicked.connect(lambda: self._tomeges(True)) + s.addWidget(self.sav_telepit) + self.sav.hide() + + def resizeEvent(self, esemeny): + super().resizeEvent(esemeny) + magassag = self.sav.sizeHint().height() + self.sav.setGeometry(0, self.height() - magassag, self.width(), magassag) + + def kijeles_valtozott(self): + if not hasattr(self, "sav"): + return + uj = [x for x in (s.telepitendo() for s in self.sorok) if x] + regi = [x for x in (s.eltavolitando() for s in self.sorok) if x] + kijelolt = sum(1 for s in self.sorok if s.jelolo.isChecked()) + latszik = kijelolt > 0 + self.sav.setVisible(latszik) + self.setViewportMargins(0, 0, 0, self.sav.sizeHint().height() if latszik else 0) + self.sav_szoveg.setText(f"{kijelolt} KIJELÖLVE") + self.sav_telepit.setText(f"Kijelöltek telepítése ({len(uj)})") + self.sav_telepit.setEnabled(bool(uj)) + self.sav_eltavolit.setText(f"Kijelöltek eltávolítása ({len(regi)})") + self.sav_eltavolit.setEnabled(bool(regi)) + if latszik: + self.sav.raise_() + magassag = self.sav.sizeHint().height() + self.sav.setGeometry(0, self.height() - magassag, self.width(), magassag) + + def _kijeles_torles(self): + for s in self.sorok: + s.torol_kijeles() + + def _nev(self, app, opciok): + if opciok: + return ", ".join(f"{app['name']}: {o['name']}" for o in app.get("options", []) if o["id"] in opciok) + return app["name"] + + def _tomeges(self, telepites): + tetelek = [x for x in ((s.telepitendo() if telepites else s.eltavolitando()) for s in self.sorok) if x] + if not tetelek: + return + nevek = [self._nev(app, opciok) for app, opciok in tetelek] + if not telepites: + valasz = QMessageBox.question( + self, + "Eltávolítás", + "Biztosan eltávolítod ezeket?\n\n" + "\n".join(nevek), + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, + QMessageBox.StandardButton.No, + ) + if valasz != QMessageBox.StandardButton.Yes: + return + lepesek = [] + for app, opciok in tetelek: + for lepes in katalogus.lepesek(app, telepites, opciok): + lepes.kotelezo = False + lepesek.append(lepes) + if not lepesek: + return + cim = f"{'Telepítés' if telepites else 'Eltávolítás'}: {len(tetelek)} alkalmazás" + FolyamatAblak(self, cim, lepesek, "Minden lépés sikeresen lefutott.", "Nem minden lépés sikerült.").exec() + self._kijeles_torles() + self.megjelenik() + + def _betolt(self): + try: + self.katalogus = katalogus.betolt() + except (OSError, ValueError, RuntimeError) as e: + self.hiba.setText(f"Az alkalmazáskatalógus nem tölthető be: {e}") + self.hiba.show() + return + for azon, nev in katalogus.KATEGORIAK[1:]: + csoport = Csoport(nev) + self.csoportok[azon] = csoport + self.lista.addWidget(csoport) + for app in self.katalogus: + csoport = self.csoportok.get(app["category"]) or self.csoportok["System"] + sor = AppSor(app, self) + self.sorok.append(sor) + csoport.hozzaad(sor) + + def megjelenik(self, *_): + gyorsitott("telepitett", katalogus.telepitett_index, kesz=self._index_kesz, kor=30) + + def _index_kesz(self, index): + if index == self.index: + return + self.index = index + for s in self.sorok: + s.frissit(index) + alap = [a for a in self.katalogus if a["id"] in katalogus.GAMING_ALAPOK] + hianyzik = [a for a in alap if not katalogus.telepitve(a, index)] + self.kiemelt_gomb.setEnabled(bool(hianyzik)) + self.kiemelt_gomb.setText("Csomag telepítése" if hianyzik else "Minden telepítve") + self._szur() + + def _kategoria(self, azon): + self.kategoria = azon + for a, p in self.pillek.items(): + p.setProperty("aktiv", a == azon) + frissit_stilus(p) + self._szur() + + def _szur(self): + szoveg = self.kereso.text().strip().lower() + lathatok = set() + for s in self.sorok: + app = s.app + if self.kategoria == CSAK_TELEPITETT: + jo = s.telepitve + else: + jo = self.kategoria == "all" or app["category"] == self.kategoria + if jo and (not szoveg or szoveg in app["name"].lower() or szoveg in katalogus.loc(app.get("desc")).lower()): + lathatok.add(s) + osszes = sum(c.szur(lathatok) for c in self.csoportok.values()) + self.ures.setText( + "Még nincs telepítve egyetlen alkalmazás sem a listából." + if self.kategoria == CSAK_TELEPITETT and not szoveg + else "Nincs találat." + ) + self.ures.setVisible(osszes == 0) + self.kiemelt.setVisible(self.kategoria in ("all", "Games") and not szoveg) + + def muvelet(self, app, telepites, opciok=None): + if not telepites: + nevek = ", ".join(o["name"] for o in app.get("options", []) if o["id"] in (opciok or [])) or app["name"] + valasz = QMessageBox.question( + self, + "Eltávolítás", + f"Biztosan eltávolítod: {nevek}?", + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, + QMessageBox.StandardButton.No, + ) + if valasz != QMessageBox.StandardButton.Yes: + return + lepesek = katalogus.lepesek(app, telepites, opciok) + if not lepesek: + return + cim = f"{'Telepítés' if telepites else 'Eltávolítás'}: {app['name']}" + FolyamatAblak(self, cim, lepesek, f"{app['name']} {'telepítve' if telepites else 'eltávolítva'}.").exec() + self.megjelenik() + + def _gaming_alapok(self): + lepesek = [] + for app in self.katalogus: + if app["id"] in katalogus.GAMING_ALAPOK and not katalogus.telepitve(app, self.index): + lepesek += katalogus.lepesek(app, True) + if not lepesek: + return + FolyamatAblak(self, "Gaming alapok telepítése", lepesek, "A Gaming alapok telepítve.").exec() + self.megjelenik() + + +OLDAL = Alkalmazasok |