Compare commits

...

63 Commits
v2.2.1 ... v2.3

Author SHA1 Message Date
kramo
c5b56e3100 v2.3 2023-08-29 14:02:30 +02:00
Weblate (bot)
c9c5f41ee9 Translations update from Hosted Weblate (#181)
* Translated using Weblate (Arabic)

Currently translated at 100.0% (133 of 133 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Arabic)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Ali Aljishi <ahj696@hotmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/ar/
Translation: Cartridges/Cartridges

* Translated using Weblate (Spanish)

Currently translated at 100.0% (133 of 133 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Spanish)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/es/
Translation: Cartridges/Cartridges

* Translated using Weblate (Russian)

Currently translated at 100.0% (133 of 133 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Russian)

Currently translated at 99.2% (135 of 136 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (134 of 136 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (134 of 136 strings)

Translated using Weblate (Russian)

Currently translated at 97.7% (133 of 136 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Russian)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Russian)

Currently translated at 100.0% (130 of 130 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (130 of 130 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Сергей <asvmail.as@gmail.com>
Co-authored-by: Сергей Ворон <voron.s.a@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/ru/
Translation: Cartridges/Cartridges

* Translated using Weblate (Tamil)

Currently translated at 100.0% (133 of 133 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: K.B.Dharun Krishna <kbdharunkrishna@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/ta/
Translation: Cartridges/Cartridges

---------

Co-authored-by: Ali Aljishi <ahj696@hotmail.com>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Co-authored-by: Сергей <asvmail.as@gmail.com>
Co-authored-by: Сергей Ворон <voron.s.a@gmail.com>
Co-authored-by: K.B.Dharun Krishna <kbdharunkrishna@gmail.com>
2023-08-29 13:54:32 +02:00
kramo
ee912ba4ca Merge pull request #180 from kra-mo/revert-172-weblate-cartridges-cartridges
Revert "Translations update from Hosted Weblate"
2023-08-29 13:53:06 +02:00
kramo
46196fd0de Revert "Translations update from Hosted Weblate" 2023-08-29 13:52:55 +02:00
kramo
94f7dbfd59 Merge pull request #172 from weblate/weblate-cartridges-cartridges
Translations update from Hosted Weblate
2023-08-29 13:50:21 +02:00
kramo
8516e19d9d Make import time global, fix sorting bug 2023-08-29 12:45:24 +02:00
Hosted Weblate
79a7c5ab3e Update translation files
Updated by "Squash Git commits" hook in Weblate.

Translation: Cartridges/Cartridges
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
2023-08-27 16:19:50 +02:00
Hosted Weblate
f273f9b23f Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Hungarian)

Currently translated at 100.0% (136 of 136 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Hungarian)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: kramo <contact@kramo.hu>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/hu/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
35b23e8f27 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
200dbb067f Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Swedish)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Luna Jernberg <droidbittin@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/sv/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
66a71b105e Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
c41bfef102 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
f26f9e35ef Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
6f5836a979 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
1e4c499478 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
befbfb6d51 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Rafael Fontenelle <rafaelff@gnome.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/pt_BR/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
d11cc3ad0c Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
d0e36323f5 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Italian)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Italian)

Currently translated at 100.0% (130 of 130 strings)

Co-authored-by: Alessandro Iepure <alessandro.iepure@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: albanobattistella <albano_battistella@hotmail.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/it/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
a6022484a8 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Ukrainian)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Dan <jonweblin2205@protonmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/uk/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
25aeea7f52 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (German)

Currently translated at 96.2% (127 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Simon Hahne <simonhahne@web.de>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/de/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
642f2192f8 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Turkish)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Sabri Ünal <libreajans@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/tr/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
68def0a60d Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:50 +02:00
Hosted Weblate
5dd4f2bb57 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
Hosted Weblate
0d65a43845 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Russian)

Currently translated at 99.2% (135 of 136 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (134 of 136 strings)

Translated using Weblate (Russian)

Currently translated at 98.5% (134 of 136 strings)

Translated using Weblate (Russian)

Currently translated at 97.7% (133 of 136 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Russian)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Russian)

Currently translated at 100.0% (130 of 130 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (130 of 130 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Сергей <asvmail.as@gmail.com>
Co-authored-by: Сергей Ворон <voron.s.a@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/ru/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
Hosted Weblate
a70b528eb0 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
Hosted Weblate
4e945945c3 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
Hosted Weblate
32e7af6559 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Spanish)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: gallegonovato <fran-carro@hotmail.es>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/es/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
Hosted Weblate
c0f1c93bb6 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Arabic)

Currently translated at 100.0% (132 of 132 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Ali Aljishi <ahj696@hotmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/ar/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
Hosted Weblate
74ec8cbb75 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Dutch)

Currently translated at 100.0% (136 of 136 strings)

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Update translation files

Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Philip Goto <philip.goto@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/nl/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
Hosted Weblate
837c46b1ba Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Translated using Weblate (Chinese (Simplified))

Currently translated at 29.4% (40 of 136 strings)

Added translation using Weblate (Chinese (Simplified))

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: IF_IceFire <zzj520llj@163.com>
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/
Translate-URL: https://hosted.weblate.org/projects/cartridges/cartridges/zh_Hans/
Translation: Cartridges/Cartridges
2023-08-27 16:19:49 +02:00
kramo
5680b08e1c Desktop entry source improvements 2023-08-27 16:19:43 +02:00
Geoffrey Coulaud
c0b6998833 Merge pull request #179 from kra-mo/geoffreys-dev-branch
Improvements to game executable + better handling of corrupted log files
2023-08-27 14:16:59 +02:00
GeoffreyCoulaud
93054b2f57 Handle log rotation errors with corrupted files 2023-08-27 14:10:31 +02:00
kramo
ae86450a01 Update translations 2023-08-27 14:03:39 +02:00
kramo
ed36feecaf Add comment to clarify gio weirdness 2023-08-27 14:01:34 +02:00
GeoffreyCoulaud
6486f5b336 Simplifying game executable 2023-08-27 13:53:23 +02:00
kramo
a1afb98b20 Better implementation for desktop entry source 2023-08-27 13:38:15 +02:00
kramo
c607a65d1f Make library-rows a guint 2023-08-26 17:54:30 +02:00
kramo
5364e6a320 Allow a custom number of library rows - fixes #173 2023-08-26 17:33:30 +02:00
kramo
89862ae266 Fix transparent animated images not working 2023-08-26 15:45:21 +02:00
kramo
82a7d4b20e Make manually added animated covers work 2023-08-26 15:14:57 +02:00
kramo
c2d671273a Composite manually added covers - fixes #177 2023-08-26 14:39:38 +02:00
kramo
38d47dae33 Merge pull request #174 from kra-mo/desktop-file-importer
Desktop file importer
2023-08-25 21:53:26 +02:00
kramo
e287ec1986 Desktop source cleanups 2023-08-25 21:50:23 +02:00
kramo
a79c6b980b Proper a11y for all popovers 2023-08-23 19:59:14 +02:00
kramo
0c55c3ba2a Make buttons in rows flat 2023-08-23 19:41:46 +02:00
kramo
8c5f4f1780 Lists are ordered and I'm silly 2023-08-22 13:32:56 +02:00
kramo
01f1f31f10 Add pixmaps to icon search paths 2023-08-22 12:01:21 +02:00
kramo
a9196c1e55 Auto-detect terminal on first run 2023-08-21 16:49:31 +02:00
kramo
489cb543de Fix copyright header 2023-08-21 16:22:06 +02:00
kramo
ab128ab461 Update translations 2023-08-21 16:18:44 +02:00
kramo
9883cc6b6b Blueprint cleanups 2023-08-21 16:13:31 +02:00
kramo
70b8493e72 Preferences cleanups 2023-08-21 16:08:47 +02:00
kramo
20f1ce6e83 Deskop importer cleanups 2023-08-21 16:04:46 +02:00
kramo
1e2d85b50d Proper game_id for desktop entries 2023-08-21 15:23:29 +02:00
kramo
2d791e46b0 Basic support for Desktop Entry source 2023-08-21 14:09:41 +02:00
kramo
bc3bc2dac6 λ my beloved 2023-08-20 14:32:23 +02:00
kramo
059709d18d Host read-write access to prevent weird file paths 2023-08-19 13:25:57 +02:00
kramo
81d3323a21 Use document-open-symbolic for picking file 2023-08-19 13:07:36 +02:00
kramo
1afd8916e3 Update translation 2023-08-19 12:45:50 +02:00
kramo
5cf41402e7 Add option to choose executable via file picker 2023-08-19 12:45:15 +02:00
kramo
4bd82c9457 Add RetroArch to excluded flatpak emulators 2023-08-18 12:51:12 +02:00
kramo
d44632de8f Cleaner syntax for shared attributes 2023-08-17 21:15:21 +02:00
36 changed files with 1268 additions and 976 deletions

View File

@@ -2,142 +2,159 @@ using Gtk 4.0;
using Adw 1; using Adw 1;
template $DetailsWindow : Adw.Window { template $DetailsWindow : Adw.Window {
default-width: 480; // Same as Nautilus' properties window default-width: 480; // Same as Nautilus' properties window
default-height: -1; default-height: -1;
modal: true; modal: true;
ShortcutController { ShortcutController {
Shortcut { Shortcut {
trigger: "Escape"; trigger: "Escape";
action: "action(window.close)"; action: "action(window.close)";
} }
}
Box {
orientation: vertical;
Adw.HeaderBar HeaderBar {
show-start-title-buttons: false;
show-end-title-buttons: false;
[start]
Button cancel_button {
label: _("Cancel");
action-name: "window.close";
}
[end]
Button apply_button {
styles [
"suggested-action",
]
}
} }
Box { Adw.PreferencesPage {
orientation: vertical; vexpand: true;
Adw.HeaderBar HeaderBar { Adw.PreferencesGroup cover_group {
show-start-title-buttons: false; Adw.Clamp cover_clamp {
show-end-title-buttons: false; maximum-size: 200;
[start] Overlay {
Button cancel_button { [overlay]
label: _("Cancel"); Spinner spinner {
action-name: "window.close"; margin-start: 72;
margin-end: 72;
} }
[end] Overlay cover_overlay {
Button apply_button { halign: center;
valign: center;
[overlay]
Button cover_button_edit {
icon-name: "document-edit-symbolic";
tooltip-text: _("New Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [ styles [
"suggested-action" "circular",
"osd",
] ]
}
[overlay]
Revealer cover_button_delete_revealer {
transition-type: crossfade;
margin-end: 40;
Button cover_button_delete {
icon-name: "user-trash-symbolic";
tooltip-text: _("Delete Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [
"circular",
"osd",
]
}
}
Picture cover {
width-request: 200;
height-request: 300;
styles [
"card",
]
}
} }
}
}
}
Adw.PreferencesGroup {
Adw.EntryRow name {
title: _("Title");
} }
Adw.PreferencesPage { Adw.EntryRow developer {
vexpand: true; title: _("Developer (optional)");
Adw.PreferencesGroup cover_group {
Adw.Clamp cover_clamp {
maximum-size: 200;
Overlay {
[overlay]
Spinner spinner {
margin-start: 72;
margin-end: 72;
}
Overlay cover_overlay {
halign: center;
valign: center;
[overlay]
Button cover_button_edit {
icon-name: "document-edit-symbolic";
tooltip-text: _("New Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [
"circular", "osd"
]
}
[overlay]
Revealer cover_button_delete_revealer {
transition-type: crossfade;
margin-end: 40;
Button cover_button_delete {
icon-name: "user-trash-symbolic";
tooltip-text: _("Delete Cover");
halign: end;
valign: end;
margin-bottom: 6;
margin-end: 6;
styles [
"circular", "osd"
]
}
}
Picture cover {
width-request: 200;
height-request: 300;
styles [
"card"
]
}
}
}
}
}
Adw.PreferencesGroup {
Adw.EntryRow name {
title: _("Title");
}
Adw.EntryRow developer {
title: _("Developer (optional)");
}
}
Adw.PreferencesGroup {
Adw.EntryRow executable {
title: _("Executable");
[suffix]
Gtk.MenuButton exec_info_button {
valign: center;
icon-name: "help-about-symbolic";
tooltip-text: _("More Info");
popover: Popover exec_info_popover {
focusable: true;
Label exec_info_label {
use-markup: true;
wrap: true;
max-width-chars: 50;
halign: center;
valign: center;
margin-top: 6;
margin-bottom: 6;
margin-start: 6;
margin-end: 6;
}
};
styles [
"flat"
]
}
}
}
} }
}
Adw.PreferencesGroup {
Adw.EntryRow executable {
title: _("Executable");
[suffix]
Button file_chooser_button {
valign: center;
icon-name: "document-open-symbolic";
tooltip-text: _("Select File");
styles [
"flat",
]
}
[suffix]
MenuButton exec_info_button {
valign: center;
icon-name: "help-about-symbolic";
tooltip-text: _("More Info");
popover:
Popover exec_info_popover {
focusable: true;
Label exec_info_label {
use-markup: true;
wrap: true;
max-width-chars: 50;
halign: center;
valign: center;
margin-top: 6;
margin-bottom: 6;
margin-start: 6;
margin-end: 6;
}
}
;
styles [
"flat",
]
}
}
}
} }
}
} }

View File

@@ -76,7 +76,6 @@ template $PreferencesWindow : Adw.PreferencesWindow {
] ]
} }
} }
} }
} }
@@ -111,6 +110,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button steam_data_file_chooser_button { Button steam_data_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
} }
@@ -125,6 +127,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button lutris_data_file_chooser_button { Button lutris_data_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
@@ -134,6 +139,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button lutris_cache_file_chooser_button { Button lutris_cache_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
@@ -166,6 +174,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button heroic_config_file_chooser_button { Button heroic_config_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
@@ -216,6 +227,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button bottles_data_file_chooser_button { Button bottles_data_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
} }
@@ -230,6 +244,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button itch_config_file_chooser_button { Button itch_config_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
} }
@@ -244,6 +261,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button legendary_config_file_chooser_button { Button legendary_config_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
} }
@@ -258,6 +278,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button retroarch_config_file_chooser_button { Button retroarch_config_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
} }
@@ -272,6 +295,9 @@ template $PreferencesWindow : Adw.PreferencesWindow {
Button flatpak_data_file_chooser_button { Button flatpak_data_file_chooser_button {
icon-name: "folder-symbolic"; icon-name: "folder-symbolic";
valign: center; valign: center;
styles [
"flat"
]
} }
} }
@@ -284,6 +310,15 @@ template $PreferencesWindow : Adw.PreferencesWindow {
} }
} }
} }
Adw.ActionRow {
title: _("Desktop Entries");
activatable-widget: desktop_switch;
Switch desktop_switch {
valign: center;
}
}
} }
} }

View File

@@ -194,13 +194,19 @@ template $CartridgesWindow : Adw.ApplicationWindow {
action-name: "app.edit_game"; action-name: "app.edit_game";
tooltip-text: _("Edit"); tooltip-text: _("Edit");
styles ["raised", "circular"] styles [
"raised",
"circular",
]
} }
Button details_view_hide_button { Button details_view_hide_button {
action-name: "app.hide_game"; action-name: "app.hide_game";
styles ["raised", "circular"] styles [
"raised",
"circular",
]
} }
Button { Button {
@@ -208,7 +214,10 @@ template $CartridgesWindow : Adw.ApplicationWindow {
action-name: "app.remove_game"; action-name: "app.remove_game";
tooltip-text: _("Remove"); tooltip-text: _("Remove");
styles ["raised", "circular"] styles [
"raised",
"circular",
]
} }
MenuButton { MenuButton {
@@ -216,7 +225,10 @@ template $CartridgesWindow : Adw.ApplicationWindow {
menu-model: search; menu-model: search;
tooltip-text: _("Search"); tooltip-text: _("Search");
styles ["raised", "circular"] styles [
"raised",
"circular",
]
} }
styles [ styles [

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="cartridges"> <schemalist gettext-domain="cartridges">
<schema id="@APP_ID@" path="@PREFIX@/"> <schema id="@APP_ID@" path="@PREFIX@/">
<key name="exit-after-launch" type="b"> <key name="exit-after-launch" type="b">
<default>false</default> <default>false</default>
@@ -76,6 +77,9 @@
<key name="retroarch-location" type="s"> <key name="retroarch-location" type="s">
<default>"~/.var/app/org.libretro.RetroArch/config/retroarch/"</default> <default>"~/.var/app/org.libretro.RetroArch/config/retroarch/"</default>
</key> </key>
<key name="desktop" type="b">
<default>true</default>
</key>
<key name="flatpak" type="b"> <key name="flatpak" type="b">
<default>true</default> <default>true</default>
</key> </key>
@@ -97,7 +101,11 @@
<key name="sgdb-animated" type="b"> <key name="sgdb-animated" type="b">
<default>false</default> <default>false</default>
</key> </key>
<key name="library-rows" type="u">
<default>0</default>
</key>
</schema> </schema>
<schema id="@APP_ID@.State" path="@PREFIX@/State/"> <schema id="@APP_ID@.State" path="@PREFIX@/State/">
<key name="width" type="i"> <key name="width" type="i">
<default>1110</default> <default>1110</default>

View File

@@ -44,10 +44,13 @@
</screenshots> </screenshots>
<content_rating type="oars-1.1" /> <content_rating type="oars-1.1" />
<releases> <releases>
<release version="2.2.1" date="2023-08-17"> <release version="2.3" date="2023-08-29">
<description translatable="no"> <description translatable="no">
<ul> <ul>
<li>Fixes a small issue with import toasts</li> <li>New import source: desktop entries</li>
<li>Added the ability to pick executables via the file picker</li>
<li>Manually added covers are now padded if they are too short</li>
<li>Translations since 2.2</li>
</ul> </ul>
</description> </description>
</release> </release>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

@@ -11,7 +11,7 @@
"--device=dri", "--device=dri",
"--socket=wayland", "--socket=wayland",
"--talk-name=org.freedesktop.Flatpak", "--talk-name=org.freedesktop.Flatpak",
"--filesystem=host:ro", "--filesystem=host",
"--filesystem=~/.var/app/com.valvesoftware.Steam/data/Steam/:ro", "--filesystem=~/.var/app/com.valvesoftware.Steam/data/Steam/:ro",
"--filesystem=~/.var/app/net.lutris.Lutris/:ro", "--filesystem=~/.var/app/net.lutris.Lutris/:ro",
"--filesystem=~/.var/app/com.heroicgameslauncher.hgl/config/heroic/:ro", "--filesystem=~/.var/app/com.heroicgameslauncher.hgl/config/heroic/:ro",

View File

@@ -1,5 +1,5 @@
project('cartridges', project('cartridges',
version: '2.2.1', version: '2.3',
meson_version: '>= 0.59.0', meson_version: '>= 0.59.0',
default_options: [ 'warning_level=2', 'werror=false', ], default_options: [ 'warning_level=2', 'werror=false', ],
) )

234
po/ar.po
View File

@@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: cartridges\n" "Project-Id-Version: cartridges\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-16 11:06+0200\n" "POT-Creation-Date: 2023-08-27 14:03+0200\n"
"PO-Revision-Date: 2023-08-15 17:07+0000\n" "PO-Revision-Date: 2023-08-29 10:45+0000\n"
"Last-Translator: Ali Aljishi <ahj696@hotmail.com>\n" "Last-Translator: Ali Aljishi <ahj696@hotmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/cartridges/" "Language-Team: Arabic <https://hosted.weblate.org/projects/cartridges/"
"cartridges/ar/>\n" "cartridges/ar/>\n"
@@ -18,11 +18,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 5.0-dev\n" "X-Generator: Weblate 5.0.1-dev\n"
#: data/hu.kramo.Cartridges.desktop.in:3 #: data/hu.kramo.Cartridges.desktop.in:3
#: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47 #: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47
#: src/main.py:169 #: src/main.py:176
msgid "Cartridges" msgid "Cartridges"
msgstr "خراطيش" msgstr "خراطيش"
@@ -61,13 +61,13 @@ msgid "Edit Game Details"
msgstr "حرِّر تفاصيل اللعبة" msgstr "حرِّر تفاصيل اللعبة"
#: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71 #: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71
#: src/details_window.py:67 #: src/details_window.py:71
msgid "Game Details" msgid "Game Details"
msgstr "تفاصيل اللعبة" msgstr "تفاصيل اللعبة"
#: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:418 #: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:430
#: src/details_window.py:241 src/importer/importer.py:292 #: src/details_window.py:265 src/importer/importer.py:301
#: src/importer/importer.py:342 #: src/importer/importer.py:352
msgid "Preferences" msgid "Preferences"
msgstr "التفضيلات" msgstr "التفضيلات"
@@ -75,27 +75,31 @@ msgstr "التفضيلات"
msgid "Cancel" msgid "Cancel"
msgstr "ألغِ" msgstr "ألغِ"
#: data/gtk/details-window.blp:57 #: data/gtk/details-window.blp:58
msgid "New Cover" msgid "New Cover"
msgstr "غلاف جديد" msgstr "غلاف جديد"
#: data/gtk/details-window.blp:75 #: data/gtk/details-window.blp:77
msgid "Delete Cover" msgid "Delete Cover"
msgstr "احذف الغلاف" msgstr "احذف الغلاف"
#: data/gtk/details-window.blp:102 data/gtk/game.blp:80 #: data/gtk/details-window.blp:105 data/gtk/game.blp:80
msgid "Title" msgid "Title"
msgstr "العنوان" msgstr "العنوان"
#: data/gtk/details-window.blp:105 #: data/gtk/details-window.blp:109
msgid "Developer (optional)" msgid "Developer (optional)"
msgstr "المطوِّر (اختياري)" msgstr "المطوِّر (اختياري)"
#: data/gtk/details-window.blp:110 #: data/gtk/details-window.blp:115
msgid "Executable" msgid "Executable"
msgstr "ملفُّ التنفيذ" msgstr "ملفُّ التنفيذ"
#: data/gtk/details-window.blp:116 #: data/gtk/details-window.blp:121
msgid "Select File"
msgstr "اختر ملفًّا"
#: data/gtk/details-window.blp:132
msgid "More Info" msgid "More Info"
msgstr "معلومات أكثر" msgstr "معلومات أكثر"
@@ -103,16 +107,16 @@ msgstr "معلومات أكثر"
msgid "Edit" msgid "Edit"
msgstr "حرِّر" msgstr "حرِّر"
#: data/gtk/game.blp:107 src/window.py:171 #: data/gtk/game.blp:107 src/window.py:190
msgid "Hide" msgid "Hide"
msgstr "أخفِ" msgstr "أخفِ"
#: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56 #: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56
#: data/gtk/window.blp:209 #: data/gtk/window.blp:215
msgid "Remove" msgid "Remove"
msgstr "أزل" msgstr "أزل"
#: data/gtk/game.blp:126 src/window.py:173 #: data/gtk/game.blp:126 src/window.py:192
msgid "Unhide" msgid "Unhide"
msgstr "اكشف" msgstr "اكشف"
@@ -124,8 +128,8 @@ msgstr "عام"
msgid "Quit" msgid "Quit"
msgstr "أنهِ" msgstr "أنهِ"
#: data/gtk/help-overlay.blp:19 data/gtk/window.blp:217 data/gtk/window.blp:257 #: data/gtk/help-overlay.blp:19 data/gtk/window.blp:226 data/gtk/window.blp:269
#: data/gtk/window.blp:324 #: data/gtk/window.blp:336
msgid "Search" msgid "Search"
msgstr "ابحث" msgstr "ابحث"
@@ -137,8 +141,8 @@ msgstr "أظهر التفضيلات"
msgid "Shortcuts" msgid "Shortcuts"
msgstr "الاختصارات" msgstr "الاختصارات"
#: data/gtk/help-overlay.blp:34 src/game.py:103 src/preferences.py:120 #: data/gtk/help-overlay.blp:34 src/game.py:105 src/preferences.py:124
#: src/importer/importer.py:366 #: src/importer/importer.py:376
msgid "Undo" msgid "Undo"
msgstr "تراجع" msgstr "تراجع"
@@ -166,8 +170,8 @@ msgstr "أظهر الألعاب المخفية"
msgid "Remove game" msgid "Remove game"
msgstr "أزل اللعبة" msgstr "أزل اللعبة"
#: data/gtk/preferences.blp:13 data/gtk/preferences.blp:89 #: data/gtk/preferences.blp:13 data/gtk/preferences.blp:88
#: data/gtk/preferences.blp:304 #: data/gtk/preferences.blp:339
msgid "Behavior" msgid "Behavior"
msgstr "السلوك" msgstr "السلوك"
@@ -183,7 +187,7 @@ msgstr "تبدأ صورة الغلاف اللعبة"
msgid "Swaps the behavior of the cover image and the play button" msgid "Swaps the behavior of the cover image and the play button"
msgstr "يبدِّل سلوك صورة الغلاف وزرِّ «العب»" msgstr "يبدِّل سلوك صورة الغلاف وزرِّ «العب»"
#: data/gtk/preferences.blp:36 src/details_window.py:81 #: data/gtk/preferences.blp:36 src/details_window.py:85
msgid "Images" msgid "Images"
msgstr "الصور" msgstr "الصور"
@@ -203,116 +207,118 @@ msgstr "منطقة خطر"
msgid "Remove All Games" msgid "Remove All Games"
msgstr "أزل كلَّ الألعاب" msgstr "أزل كلَّ الألعاب"
#: data/gtk/preferences.blp:85 data/gtk/window.blp:27 data/gtk/window.blp:444 #: data/gtk/preferences.blp:84 data/gtk/window.blp:27 data/gtk/window.blp:456
msgid "Import" msgid "Import"
msgstr "استورد" msgstr "استورد"
#: data/gtk/preferences.blp:92 #: data/gtk/preferences.blp:91
#, fuzzy
#| msgid "Remove All Games"
msgid "Remove Uninstalled Games" msgid "Remove Uninstalled Games"
msgstr "أزل كلَّ الألعاب" msgstr "أزل الألعاب المحذوفة"
#: data/gtk/preferences.blp:102 #: data/gtk/preferences.blp:101
msgid "Sources" msgid "Sources"
msgstr "المصادر" msgstr "المصادر"
#: data/gtk/preferences.blp:105 #: data/gtk/preferences.blp:104
msgid "Steam" msgid "Steam"
msgstr "ستيم" msgstr "ستيم"
#: data/gtk/preferences.blp:109 data/gtk/preferences.blp:123 #: data/gtk/preferences.blp:108 data/gtk/preferences.blp:125
#: data/gtk/preferences.blp:164 data/gtk/preferences.blp:214 #: data/gtk/preferences.blp:172 data/gtk/preferences.blp:225
#: data/gtk/preferences.blp:228 data/gtk/preferences.blp:242 #: data/gtk/preferences.blp:242 data/gtk/preferences.blp:259
#: data/gtk/preferences.blp:256 data/gtk/preferences.blp:270 #: data/gtk/preferences.blp:276 data/gtk/preferences.blp:293
msgid "Install Location" msgid "Install Location"
msgstr "موضع التثبيت" msgstr "موضع التثبيت"
#: data/gtk/preferences.blp:119 #: data/gtk/preferences.blp:121
msgid "Lutris" msgid "Lutris"
msgstr "لوترس" msgstr "لوترس"
#: data/gtk/preferences.blp:132 #: data/gtk/preferences.blp:137
msgid "Cache Location" msgid "Cache Location"
msgstr "موضع الذاكرة المؤقتة" msgstr "موضع الذاكرة المؤقتة"
#: data/gtk/preferences.blp:141 #: data/gtk/preferences.blp:149
msgid "Import Steam Games" msgid "Import Steam Games"
msgstr "استورد ألعابًا من ستيم" msgstr "استورد ألعابًا من ستيم"
#: data/gtk/preferences.blp:150 #: data/gtk/preferences.blp:158
msgid "Import Flatpak Games" msgid "Import Flatpak Games"
msgstr "استورد ألعاب فلاتباك" msgstr "استورد ألعاب فلاتباك"
#: data/gtk/preferences.blp:160 #: data/gtk/preferences.blp:168
msgid "Heroic" msgid "Heroic"
msgstr "هِرُوِك" msgstr "هِرُوِك"
#: data/gtk/preferences.blp:173 #: data/gtk/preferences.blp:184
msgid "Import Epic Games" msgid "Import Epic Games"
msgstr "استورد ألعاب أَبِك" msgstr "استورد ألعاب أَبِك"
#: data/gtk/preferences.blp:182 #: data/gtk/preferences.blp:193
msgid "Import GOG Games" msgid "Import GOG Games"
msgstr "استورد ألعاب جي‌أو‌جي" msgstr "استورد ألعاب جي‌أو‌جي"
#: data/gtk/preferences.blp:191 #: data/gtk/preferences.blp:202
msgid "Import Amazon Games" msgid "Import Amazon Games"
msgstr "استورد ألعابًا من أمازون" msgstr "استورد ألعابًا من أمازون"
#: data/gtk/preferences.blp:200 #: data/gtk/preferences.blp:211
msgid "Import Sideloaded Games" msgid "Import Sideloaded Games"
msgstr "استورد ألعابًا مثبَّتةً بغير متجر" msgstr "استورد ألعابًا مثبَّتةً بغير متجر"
#: data/gtk/preferences.blp:210 #: data/gtk/preferences.blp:221
msgid "Bottles" msgid "Bottles"
msgstr "قوارير" msgstr "قوارير"
#: data/gtk/preferences.blp:224 #: data/gtk/preferences.blp:238
msgid "itch" msgid "itch"
msgstr "إتش" msgstr "إتش"
#: data/gtk/preferences.blp:238 #: data/gtk/preferences.blp:255
msgid "Legendary" msgid "Legendary"
msgstr "لجندري" msgstr "لجندري"
#: data/gtk/preferences.blp:252 #: data/gtk/preferences.blp:272
msgid "RetroArch" msgid "RetroArch"
msgstr "رتروآرتش" msgstr "رتروآرتش"
#: data/gtk/preferences.blp:266 #: data/gtk/preferences.blp:289
msgid "Flatpak" msgid "Flatpak"
msgstr "فلاتباك" msgstr "فلاتباك"
#: data/gtk/preferences.blp:279 #: data/gtk/preferences.blp:305
msgid "Import Game Launchers" msgid "Import Game Launchers"
msgstr "استورد مشغِّلات ألعاب" msgstr "استورد مشغِّلات ألعاب"
#: data/gtk/preferences.blp:292 #: data/gtk/preferences.blp:315
msgid "Desktop Entries"
msgstr "مدخلات سطح المكتب"
#: data/gtk/preferences.blp:327
msgid "SteamGridDB" msgid "SteamGridDB"
msgstr "SteamGridDB" msgstr "SteamGridDB"
#: data/gtk/preferences.blp:296 #: data/gtk/preferences.blp:331
msgid "Authentication" msgid "Authentication"
msgstr "الاستيثاق" msgstr "الاستيثاق"
#: data/gtk/preferences.blp:299 #: data/gtk/preferences.blp:334
msgid "API Key" msgid "API Key"
msgstr "مفتاح واجهة البرمجة" msgstr "مفتاح واجهة البرمجة"
#: data/gtk/preferences.blp:307 #: data/gtk/preferences.blp:342
msgid "Use SteamGridDB" msgid "Use SteamGridDB"
msgstr "استخدم SteamGridDB" msgstr "استخدم SteamGridDB"
#: data/gtk/preferences.blp:308 #: data/gtk/preferences.blp:343
msgid "Download images when adding or importing games" msgid "Download images when adding or importing games"
msgstr "نزِّل الصور حينما تنزِّل أو تستورد الألعاب" msgstr "نزِّل الصور حينما تنزِّل أو تستورد الألعاب"
#: data/gtk/preferences.blp:317 #: data/gtk/preferences.blp:352
msgid "Prefer Over Official Images" msgid "Prefer Over Official Images"
msgstr "فضِّلها على الصور الرسمية" msgstr "فضِّلها على الصور الرسمية"
#: data/gtk/preferences.blp:326 #: data/gtk/preferences.blp:361
msgid "Prefer Animated Images" msgid "Prefer Animated Images"
msgstr "فضِّل الصور المتحرِّكة" msgstr "فضِّل الصور المتحرِّكة"
@@ -340,7 +346,7 @@ msgstr "لا توجد ألعاب مخفية"
msgid "Games you hide will appear here." msgid "Games you hide will appear here."
msgstr "هنا يظهر ما أخفيت من ألعاب." msgstr "هنا يظهر ما أخفيت من ألعاب."
#: data/gtk/window.blp:64 data/gtk/window.blp:305 #: data/gtk/window.blp:64 data/gtk/window.blp:317
msgid "Back" msgid "Back"
msgstr "عد" msgstr "عد"
@@ -352,114 +358,118 @@ msgstr "عنوان اللعبة"
msgid "Play" msgid "Play"
msgstr "العب" msgstr "العب"
#: data/gtk/window.blp:243 data/gtk/window.blp:437 #: data/gtk/window.blp:255 data/gtk/window.blp:449
msgid "Add Game" msgid "Add Game"
msgstr "أضف لعبةً" msgstr "أضف لعبةً"
#: data/gtk/window.blp:250 data/gtk/window.blp:317 #: data/gtk/window.blp:262 data/gtk/window.blp:329
msgid "Main Menu" msgid "Main Menu"
msgstr "القائمة الرئيسة" msgstr "القائمة الرئيسة"
#: data/gtk/window.blp:272 #: data/gtk/window.blp:284
msgid "Search games" msgid "Search games"
msgstr "ابحث عن ألعاب" msgstr "ابحث عن ألعاب"
#: data/gtk/window.blp:312 #: data/gtk/window.blp:324
msgid "Hidden Games" msgid "Hidden Games"
msgstr "الألعاب المخفية" msgstr "الألعاب المخفية"
#: data/gtk/window.blp:339 #: data/gtk/window.blp:351
msgid "Search hidden games" msgid "Search hidden games"
msgstr "ابحث في الألعاب المخفية" msgstr "ابحث في الألعاب المخفية"
#: data/gtk/window.blp:376 #: data/gtk/window.blp:388
msgid "Sort" msgid "Sort"
msgstr "رتِّب" msgstr "رتِّب"
#: data/gtk/window.blp:379 #: data/gtk/window.blp:391
msgid "A-Z" msgid "A-Z"
msgstr "أ-ي" msgstr "أ-ي"
#: data/gtk/window.blp:385 #: data/gtk/window.blp:397
msgid "Z-A" msgid "Z-A"
msgstr "ي-أ" msgstr "ي-أ"
#: data/gtk/window.blp:391 #: data/gtk/window.blp:403
msgid "Newest" msgid "Newest"
msgstr "الأجدد" msgstr "الأجدد"
#: data/gtk/window.blp:397 #: data/gtk/window.blp:409
msgid "Oldest" msgid "Oldest"
msgstr "الأقدم" msgstr "الأقدم"
#: data/gtk/window.blp:403 #: data/gtk/window.blp:415
msgid "Last Played" msgid "Last Played"
msgstr "لُعبت آخر مرَّة" msgstr "لُعبت آخر مرَّة"
#: data/gtk/window.blp:410 #: data/gtk/window.blp:422
msgid "Show Hidden" msgid "Show Hidden"
msgstr "أظهر ما أخفي" msgstr "أظهر ما أخفي"
#: data/gtk/window.blp:423 #: data/gtk/window.blp:435
msgid "Keyboard Shortcuts" msgid "Keyboard Shortcuts"
msgstr "اختصارات لوحة المفاتيح" msgstr "اختصارات لوحة المفاتيح"
#: data/gtk/window.blp:428 #: data/gtk/window.blp:440
msgid "About Cartridges" msgid "About Cartridges"
msgstr "عن «خراطيش»" msgstr "عن «خراطيش»"
#. Translators: Replace this with your name for it to show up in the about window #. Translators: Replace this with your name for it to show up in the about window
#: src/main.py:188 #: src/main.py:195
msgid "translator_credits" msgid "translator_credits"
msgstr "Ali Aljishi <ahj696@hotmail.com>" msgstr "Ali Aljishi <ahj696@hotmail.com>"
#. The variable is the date when the game was added #. The variable is the date when the game was added
#: src/window.py:194 #: src/window.py:213
msgid "Added: {}" msgid "Added: {}"
msgstr "أضيفت في: {}" msgstr "أضيفت في: {}"
#: src/window.py:197 #: src/window.py:216
msgid "Never" msgid "Never"
msgstr "أبدًا" msgstr "أبدًا"
#. The variable is the date when the game was last played #. The variable is the date when the game was last played
#: src/window.py:201 #: src/window.py:220
msgid "Last played: {}" msgid "Last played: {}"
msgstr "لُعبت آخر مرَّة في: {}" msgstr "لُعبت آخر مرَّة في: {}"
#: src/details_window.py:72 #: src/details_window.py:76
msgid "Apply" msgid "Apply"
msgstr "طبِّق" msgstr "طبِّق"
#: src/details_window.py:78 #: src/details_window.py:82
msgid "Add New Game" msgid "Add New Game"
msgstr "أضف لعبةً جديدةً" msgstr "أضف لعبةً جديدةً"
#: src/details_window.py:79 #: src/details_window.py:83
msgid "Add" msgid "Add"
msgstr "أضف" msgstr "أضف"
#: src/details_window.py:93
msgid "Executables"
msgstr "ملفات التنفيذ"
#. Translate this string as you would translate "file" #. Translate this string as you would translate "file"
#: src/details_window.py:92 #: src/details_window.py:108
msgid "file.txt" msgid "file.txt"
msgstr "ملف.txt" msgstr "ملف.txt"
#. As in software #. As in software
#: src/details_window.py:94 #: src/details_window.py:110
msgid "program" msgid "program"
msgstr "البرنامج" msgstr "البرنامج"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:99 src/details_window.py:101 #: src/details_window.py:115 src/details_window.py:117
msgid "C:\\path\\to\\{}" msgid "C:\\path\\to\\{}"
msgstr "C:\\المسار\\إلى\\{}" msgstr "C:\\المسار\\إلى\\{}"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:105 src/details_window.py:107 #: src/details_window.py:121 src/details_window.py:123
msgid "/path/to/{}" msgid "/path/to/{}"
msgstr "/المسار/إلى/{}" msgstr "/المسار/إلى/{}"
#: src/details_window.py:112 #: src/details_window.py:128
msgid "" msgid ""
"To launch the executable \"{}\", use the command:\n" "To launch the executable \"{}\", use the command:\n"
"\n" "\n"
@@ -481,103 +491,101 @@ msgstr ""
"\n" "\n"
"ولا تنسَ إحاطة المسار بعلامتي تنصيص مزدوجتين حالما تضمَّن مسافات!" "ولا تنسَ إحاطة المسار بعلامتي تنصيص مزدوجتين حالما تضمَّن مسافات!"
#: src/details_window.py:147 src/details_window.py:153 #: src/details_window.py:171 src/details_window.py:177
msgid "Couldn't Add Game" msgid "Couldn't Add Game"
msgstr "تعذَّرت إضافة اللعبة" msgstr "تعذَّرت إضافة اللعبة"
#: src/details_window.py:147 src/details_window.py:183 #: src/details_window.py:171 src/details_window.py:207
msgid "Game title cannot be empty." msgid "Game title cannot be empty."
msgstr "لا يجوز كون عنوان اللعبة فارغًا." msgstr "لا يجوز كون عنوان اللعبة فارغًا."
#: src/details_window.py:153 src/details_window.py:191 #: src/details_window.py:177 src/details_window.py:215
msgid "Executable cannot be empty." msgid "Executable cannot be empty."
msgstr "لا يجوز كون ملفِّ التنفيذ فارغًا." msgstr "لا يجوز كون ملفِّ التنفيذ فارغًا."
#: src/details_window.py:182 src/details_window.py:190 #: src/details_window.py:206 src/details_window.py:214
msgid "Couldn't Apply Preferences" msgid "Couldn't Apply Preferences"
msgstr "تعذَّر تطبيق التفضيلات" msgstr "تعذَّر تطبيق التفضيلات"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:139 #: src/game.py:141
msgid "{} launched" msgid "{} launched"
msgstr "بُدئت {}" msgstr "بُدئت {}"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:153 #: src/game.py:155
msgid "{} hidden" msgid "{} hidden"
msgstr "أٌخفيت {}" msgstr "أٌخفيت {}"
#: src/game.py:153 #: src/game.py:155
msgid "{} unhidden" msgid "{} unhidden"
msgstr "أٌظهرت {}" msgstr "أٌظهرت {}"
#. The variable is the title of the game #. The variable is the title of the game
#. The variable is the number of games removed #. The variable is the number of games removed
#: src/game.py:170 src/importer/importer.py:363 #: src/game.py:172 src/importer/importer.py:373
msgid "{} removed" msgid "{} removed"
msgstr "أزيلت {}" msgstr "أزيلت {}"
#: src/preferences.py:119 #: src/preferences.py:123
msgid "All games removed" msgid "All games removed"
msgstr "أُزيلت كلُّ الألعاب" msgstr "أُزيلت كلُّ الألعاب"
#: src/preferences.py:168 #: src/preferences.py:172
msgid "" msgid ""
"An API key is required to use SteamGridDB. You can generate one {}here{}." "An API key is required to use SteamGridDB. You can generate one {}here{}."
msgstr "" msgstr ""
"تحتاج مفتاح واجهة برمجة حال ما أردت استخدام SteamGridDB، {}هنا تولِّده{}." "تحتاج مفتاح واجهة برمجة حال ما أردت استخدام SteamGridDB، {}هنا تولِّده{}."
#: src/preferences.py:294 #: src/preferences.py:293
msgid "Installation Not Found" msgid "Installation Not Found"
msgstr "لم يُعثر على التثبيت" msgstr "لم يُعثر على التثبيت"
#: src/preferences.py:296 #: src/preferences.py:294
msgid "Select a valid directory." msgid "Select a valid directory."
msgstr "حدِّد مجلَّدًا صالحًا." msgstr "حدِّد مجلَّدًا صالحًا."
#: src/preferences.py:351 #: src/preferences.py:330 src/importer/importer.py:299
msgid "Warning"
msgstr "تحذير"
#: src/preferences.py:364
msgid "Invalid Directory" msgid "Invalid Directory"
msgstr "مجلَّد غير صالح" msgstr "مجلَّد غير صالح"
#: src/preferences.py:357 #: src/preferences.py:370
msgid "Set Location" msgid "Set Location"
msgstr "عيِّن الموضع" msgstr "عيِّن الموضع"
#: src/utils/create_dialog.py:25 src/importer/importer.py:291 #: src/utils/create_dialog.py:33 src/importer/importer.py:300
msgid "Dismiss" msgid "Dismiss"
msgstr "تجاهل" msgstr "تجاهل"
#: src/importer/importer.py:128 #: src/importer/importer.py:137
msgid "Importing Games…" msgid "Importing Games…"
msgstr "تُستورد الألعاب…" msgstr "تُستورد الألعاب…"
#: src/importer/importer.py:290 #: src/importer/importer.py:320
msgid "Warning"
msgstr ""
#: src/importer/importer.py:311
msgid "The following errors occured during import:" msgid "The following errors occured during import:"
msgstr "" msgstr "طرأ هذا الخطأ أثناء الاستيراد:"
#: src/importer/importer.py:339 #: src/importer/importer.py:349
msgid "No new games found" msgid "No new games found"
msgstr "لم يُعثر على ألعاب جديدة" msgstr "لم يُعثر على ألعاب جديدة"
#: src/importer/importer.py:351 #: src/importer/importer.py:361
msgid "1 game imported" msgid "1 game imported"
msgstr "اُستوردت لعبة واحدة" msgstr "اُستوردت لعبة واحدة"
#. The variable is the number of games #. The variable is the number of games
#: src/importer/importer.py:355 #: src/importer/importer.py:365
msgid "{} games imported" msgid "{} games imported"
msgstr "اُستوردت {} لعبة" msgstr "اُستوردت {} لعبة"
#. A single game removed #. A single game removed
#: src/importer/importer.py:359 #: src/importer/importer.py:369
#, fuzzy
#| msgid "{} removed"
msgid "1 removed" msgid "1 removed"
msgstr "أزيلت {}" msgstr "أزيل ١"
#. The variable is the name of the source #. The variable is the name of the source
#: src/importer/sources/location.py:33 #: src/importer/sources/location.py:33

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Cartridges\n" "Project-Id-Version: Cartridges\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-16 11:06+0200\n" "POT-Creation-Date: 2023-08-27 14:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,7 +19,7 @@ msgstr ""
#: data/hu.kramo.Cartridges.desktop.in:3 #: data/hu.kramo.Cartridges.desktop.in:3
#: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47 #: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47
#: src/main.py:169 #: src/main.py:176
msgid "Cartridges" msgid "Cartridges"
msgstr "" msgstr ""
@@ -54,13 +54,13 @@ msgid "Edit Game Details"
msgstr "" msgstr ""
#: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71 #: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71
#: src/details_window.py:67 #: src/details_window.py:71
msgid "Game Details" msgid "Game Details"
msgstr "" msgstr ""
#: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:418 #: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:430
#: src/details_window.py:241 src/importer/importer.py:292 #: src/details_window.py:265 src/importer/importer.py:301
#: src/importer/importer.py:342 #: src/importer/importer.py:352
msgid "Preferences" msgid "Preferences"
msgstr "" msgstr ""
@@ -68,27 +68,31 @@ msgstr ""
msgid "Cancel" msgid "Cancel"
msgstr "" msgstr ""
#: data/gtk/details-window.blp:57 #: data/gtk/details-window.blp:58
msgid "New Cover" msgid "New Cover"
msgstr "" msgstr ""
#: data/gtk/details-window.blp:75 #: data/gtk/details-window.blp:77
msgid "Delete Cover" msgid "Delete Cover"
msgstr "" msgstr ""
#: data/gtk/details-window.blp:102 data/gtk/game.blp:80 #: data/gtk/details-window.blp:105 data/gtk/game.blp:80
msgid "Title" msgid "Title"
msgstr "" msgstr ""
#: data/gtk/details-window.blp:105 #: data/gtk/details-window.blp:109
msgid "Developer (optional)" msgid "Developer (optional)"
msgstr "" msgstr ""
#: data/gtk/details-window.blp:110 #: data/gtk/details-window.blp:115
msgid "Executable" msgid "Executable"
msgstr "" msgstr ""
#: data/gtk/details-window.blp:116 #: data/gtk/details-window.blp:121
msgid "Select File"
msgstr ""
#: data/gtk/details-window.blp:132
msgid "More Info" msgid "More Info"
msgstr "" msgstr ""
@@ -96,16 +100,16 @@ msgstr ""
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
#: data/gtk/game.blp:107 src/window.py:171 #: data/gtk/game.blp:107 src/window.py:190
msgid "Hide" msgid "Hide"
msgstr "" msgstr ""
#: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56 #: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56
#: data/gtk/window.blp:209 #: data/gtk/window.blp:215
msgid "Remove" msgid "Remove"
msgstr "" msgstr ""
#: data/gtk/game.blp:126 src/window.py:173 #: data/gtk/game.blp:126 src/window.py:192
msgid "Unhide" msgid "Unhide"
msgstr "" msgstr ""
@@ -117,8 +121,8 @@ msgstr ""
msgid "Quit" msgid "Quit"
msgstr "" msgstr ""
#: data/gtk/help-overlay.blp:19 data/gtk/window.blp:217 data/gtk/window.blp:257 #: data/gtk/help-overlay.blp:19 data/gtk/window.blp:226 data/gtk/window.blp:269
#: data/gtk/window.blp:324 #: data/gtk/window.blp:336
msgid "Search" msgid "Search"
msgstr "" msgstr ""
@@ -130,8 +134,8 @@ msgstr ""
msgid "Shortcuts" msgid "Shortcuts"
msgstr "" msgstr ""
#: data/gtk/help-overlay.blp:34 src/game.py:103 src/preferences.py:120 #: data/gtk/help-overlay.blp:34 src/game.py:105 src/preferences.py:124
#: src/importer/importer.py:366 #: src/importer/importer.py:376
msgid "Undo" msgid "Undo"
msgstr "" msgstr ""
@@ -159,8 +163,8 @@ msgstr ""
msgid "Remove game" msgid "Remove game"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:13 data/gtk/preferences.blp:89 #: data/gtk/preferences.blp:13 data/gtk/preferences.blp:88
#: data/gtk/preferences.blp:304 #: data/gtk/preferences.blp:339
msgid "Behavior" msgid "Behavior"
msgstr "" msgstr ""
@@ -176,7 +180,7 @@ msgstr ""
msgid "Swaps the behavior of the cover image and the play button" msgid "Swaps the behavior of the cover image and the play button"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:36 src/details_window.py:81 #: data/gtk/preferences.blp:36 src/details_window.py:85
msgid "Images" msgid "Images"
msgstr "" msgstr ""
@@ -196,114 +200,118 @@ msgstr ""
msgid "Remove All Games" msgid "Remove All Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:85 data/gtk/window.blp:27 data/gtk/window.blp:444 #: data/gtk/preferences.blp:84 data/gtk/window.blp:27 data/gtk/window.blp:456
msgid "Import" msgid "Import"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:92 #: data/gtk/preferences.blp:91
msgid "Remove Uninstalled Games" msgid "Remove Uninstalled Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:102 #: data/gtk/preferences.blp:101
msgid "Sources" msgid "Sources"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:105 #: data/gtk/preferences.blp:104
msgid "Steam" msgid "Steam"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:109 data/gtk/preferences.blp:123 #: data/gtk/preferences.blp:108 data/gtk/preferences.blp:125
#: data/gtk/preferences.blp:164 data/gtk/preferences.blp:214 #: data/gtk/preferences.blp:172 data/gtk/preferences.blp:225
#: data/gtk/preferences.blp:228 data/gtk/preferences.blp:242 #: data/gtk/preferences.blp:242 data/gtk/preferences.blp:259
#: data/gtk/preferences.blp:256 data/gtk/preferences.blp:270 #: data/gtk/preferences.blp:276 data/gtk/preferences.blp:293
msgid "Install Location" msgid "Install Location"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:119 #: data/gtk/preferences.blp:121
msgid "Lutris" msgid "Lutris"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:132 #: data/gtk/preferences.blp:137
msgid "Cache Location" msgid "Cache Location"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:141 #: data/gtk/preferences.blp:149
msgid "Import Steam Games" msgid "Import Steam Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:150 #: data/gtk/preferences.blp:158
msgid "Import Flatpak Games" msgid "Import Flatpak Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:160 #: data/gtk/preferences.blp:168
msgid "Heroic" msgid "Heroic"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:173 #: data/gtk/preferences.blp:184
msgid "Import Epic Games" msgid "Import Epic Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:182 #: data/gtk/preferences.blp:193
msgid "Import GOG Games" msgid "Import GOG Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:191 #: data/gtk/preferences.blp:202
msgid "Import Amazon Games" msgid "Import Amazon Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:200 #: data/gtk/preferences.blp:211
msgid "Import Sideloaded Games" msgid "Import Sideloaded Games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:210 #: data/gtk/preferences.blp:221
msgid "Bottles" msgid "Bottles"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:224 #: data/gtk/preferences.blp:238
msgid "itch" msgid "itch"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:238 #: data/gtk/preferences.blp:255
msgid "Legendary" msgid "Legendary"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:252 #: data/gtk/preferences.blp:272
msgid "RetroArch" msgid "RetroArch"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:266 #: data/gtk/preferences.blp:289
msgid "Flatpak" msgid "Flatpak"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:279 #: data/gtk/preferences.blp:305
msgid "Import Game Launchers" msgid "Import Game Launchers"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:292 #: data/gtk/preferences.blp:315
msgid "Desktop Entries"
msgstr ""
#: data/gtk/preferences.blp:327
msgid "SteamGridDB" msgid "SteamGridDB"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:296 #: data/gtk/preferences.blp:331
msgid "Authentication" msgid "Authentication"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:299 #: data/gtk/preferences.blp:334
msgid "API Key" msgid "API Key"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:307 #: data/gtk/preferences.blp:342
msgid "Use SteamGridDB" msgid "Use SteamGridDB"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:308 #: data/gtk/preferences.blp:343
msgid "Download images when adding or importing games" msgid "Download images when adding or importing games"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:317 #: data/gtk/preferences.blp:352
msgid "Prefer Over Official Images" msgid "Prefer Over Official Images"
msgstr "" msgstr ""
#: data/gtk/preferences.blp:326 #: data/gtk/preferences.blp:361
msgid "Prefer Animated Images" msgid "Prefer Animated Images"
msgstr "" msgstr ""
@@ -331,7 +339,7 @@ msgstr ""
msgid "Games you hide will appear here." msgid "Games you hide will appear here."
msgstr "" msgstr ""
#: data/gtk/window.blp:64 data/gtk/window.blp:305 #: data/gtk/window.blp:64 data/gtk/window.blp:317
msgid "Back" msgid "Back"
msgstr "" msgstr ""
@@ -343,114 +351,118 @@ msgstr ""
msgid "Play" msgid "Play"
msgstr "" msgstr ""
#: data/gtk/window.blp:243 data/gtk/window.blp:437 #: data/gtk/window.blp:255 data/gtk/window.blp:449
msgid "Add Game" msgid "Add Game"
msgstr "" msgstr ""
#: data/gtk/window.blp:250 data/gtk/window.blp:317 #: data/gtk/window.blp:262 data/gtk/window.blp:329
msgid "Main Menu" msgid "Main Menu"
msgstr "" msgstr ""
#: data/gtk/window.blp:272 #: data/gtk/window.blp:284
msgid "Search games" msgid "Search games"
msgstr "" msgstr ""
#: data/gtk/window.blp:312 #: data/gtk/window.blp:324
msgid "Hidden Games" msgid "Hidden Games"
msgstr "" msgstr ""
#: data/gtk/window.blp:339 #: data/gtk/window.blp:351
msgid "Search hidden games" msgid "Search hidden games"
msgstr "" msgstr ""
#: data/gtk/window.blp:376 #: data/gtk/window.blp:388
msgid "Sort" msgid "Sort"
msgstr "" msgstr ""
#: data/gtk/window.blp:379 #: data/gtk/window.blp:391
msgid "A-Z" msgid "A-Z"
msgstr "" msgstr ""
#: data/gtk/window.blp:385 #: data/gtk/window.blp:397
msgid "Z-A" msgid "Z-A"
msgstr "" msgstr ""
#: data/gtk/window.blp:391 #: data/gtk/window.blp:403
msgid "Newest" msgid "Newest"
msgstr "" msgstr ""
#: data/gtk/window.blp:397 #: data/gtk/window.blp:409
msgid "Oldest" msgid "Oldest"
msgstr "" msgstr ""
#: data/gtk/window.blp:403 #: data/gtk/window.blp:415
msgid "Last Played" msgid "Last Played"
msgstr "" msgstr ""
#: data/gtk/window.blp:410 #: data/gtk/window.blp:422
msgid "Show Hidden" msgid "Show Hidden"
msgstr "" msgstr ""
#: data/gtk/window.blp:423 #: data/gtk/window.blp:435
msgid "Keyboard Shortcuts" msgid "Keyboard Shortcuts"
msgstr "" msgstr ""
#: data/gtk/window.blp:428 #: data/gtk/window.blp:440
msgid "About Cartridges" msgid "About Cartridges"
msgstr "" msgstr ""
#. Translators: Replace this with your name for it to show up in the about window #. Translators: Replace this with your name for it to show up in the about window
#: src/main.py:188 #: src/main.py:195
msgid "translator_credits" msgid "translator_credits"
msgstr "" msgstr ""
#. The variable is the date when the game was added #. The variable is the date when the game was added
#: src/window.py:194 #: src/window.py:213
msgid "Added: {}" msgid "Added: {}"
msgstr "" msgstr ""
#: src/window.py:197 #: src/window.py:216
msgid "Never" msgid "Never"
msgstr "" msgstr ""
#. The variable is the date when the game was last played #. The variable is the date when the game was last played
#: src/window.py:201 #: src/window.py:220
msgid "Last played: {}" msgid "Last played: {}"
msgstr "" msgstr ""
#: src/details_window.py:72 #: src/details_window.py:76
msgid "Apply" msgid "Apply"
msgstr "" msgstr ""
#: src/details_window.py:78 #: src/details_window.py:82
msgid "Add New Game" msgid "Add New Game"
msgstr "" msgstr ""
#: src/details_window.py:79 #: src/details_window.py:83
msgid "Add" msgid "Add"
msgstr "" msgstr ""
#: src/details_window.py:93
msgid "Executables"
msgstr ""
#. Translate this string as you would translate "file" #. Translate this string as you would translate "file"
#: src/details_window.py:92 #: src/details_window.py:108
msgid "file.txt" msgid "file.txt"
msgstr "" msgstr ""
#. As in software #. As in software
#: src/details_window.py:94 #: src/details_window.py:110
msgid "program" msgid "program"
msgstr "" msgstr ""
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:99 src/details_window.py:101 #: src/details_window.py:115 src/details_window.py:117
msgid "C:\\path\\to\\{}" msgid "C:\\path\\to\\{}"
msgstr "" msgstr ""
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:105 src/details_window.py:107 #: src/details_window.py:121 src/details_window.py:123
msgid "/path/to/{}" msgid "/path/to/{}"
msgstr "" msgstr ""
#: src/details_window.py:112 #: src/details_window.py:128
msgid "" msgid ""
"To launch the executable \"{}\", use the command:\n" "To launch the executable \"{}\", use the command:\n"
"\n" "\n"
@@ -463,98 +475,98 @@ msgid ""
"If the path contains spaces, make sure to wrap it in double quotes!" "If the path contains spaces, make sure to wrap it in double quotes!"
msgstr "" msgstr ""
#: src/details_window.py:147 src/details_window.py:153 #: src/details_window.py:171 src/details_window.py:177
msgid "Couldn't Add Game" msgid "Couldn't Add Game"
msgstr "" msgstr ""
#: src/details_window.py:147 src/details_window.py:183 #: src/details_window.py:171 src/details_window.py:207
msgid "Game title cannot be empty." msgid "Game title cannot be empty."
msgstr "" msgstr ""
#: src/details_window.py:153 src/details_window.py:191 #: src/details_window.py:177 src/details_window.py:215
msgid "Executable cannot be empty." msgid "Executable cannot be empty."
msgstr "" msgstr ""
#: src/details_window.py:182 src/details_window.py:190 #: src/details_window.py:206 src/details_window.py:214
msgid "Couldn't Apply Preferences" msgid "Couldn't Apply Preferences"
msgstr "" msgstr ""
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:139 #: src/game.py:141
msgid "{} launched" msgid "{} launched"
msgstr "" msgstr ""
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:153 #: src/game.py:155
msgid "{} hidden" msgid "{} hidden"
msgstr "" msgstr ""
#: src/game.py:153 #: src/game.py:155
msgid "{} unhidden" msgid "{} unhidden"
msgstr "" msgstr ""
#. The variable is the title of the game #. The variable is the title of the game
#. The variable is the number of games removed #. The variable is the number of games removed
#: src/game.py:170 src/importer/importer.py:363 #: src/game.py:172 src/importer/importer.py:373
msgid "{} removed" msgid "{} removed"
msgstr "" msgstr ""
#: src/preferences.py:119 #: src/preferences.py:123
msgid "All games removed" msgid "All games removed"
msgstr "" msgstr ""
#: src/preferences.py:168 #: src/preferences.py:172
msgid "" msgid ""
"An API key is required to use SteamGridDB. You can generate one {}here{}." "An API key is required to use SteamGridDB. You can generate one {}here{}."
msgstr "" msgstr ""
#: src/preferences.py:294 #: src/preferences.py:293
msgid "Installation Not Found" msgid "Installation Not Found"
msgstr "" msgstr ""
#: src/preferences.py:296 #: src/preferences.py:294
msgid "Select a valid directory." msgid "Select a valid directory."
msgstr "" msgstr ""
#: src/preferences.py:351 #: src/preferences.py:330 src/importer/importer.py:299
msgid "Invalid Directory"
msgstr ""
#: src/preferences.py:357
msgid "Set Location"
msgstr ""
#: src/utils/create_dialog.py:25 src/importer/importer.py:291
msgid "Dismiss"
msgstr ""
#: src/importer/importer.py:128
msgid "Importing Games…"
msgstr ""
#: src/importer/importer.py:290
msgid "Warning" msgid "Warning"
msgstr "" msgstr ""
#: src/importer/importer.py:311 #: src/preferences.py:364
msgid "Invalid Directory"
msgstr ""
#: src/preferences.py:370
msgid "Set Location"
msgstr ""
#: src/utils/create_dialog.py:33 src/importer/importer.py:300
msgid "Dismiss"
msgstr ""
#: src/importer/importer.py:137
msgid "Importing Games…"
msgstr ""
#: src/importer/importer.py:320
msgid "The following errors occured during import:" msgid "The following errors occured during import:"
msgstr "" msgstr ""
#: src/importer/importer.py:339 #: src/importer/importer.py:349
msgid "No new games found" msgid "No new games found"
msgstr "" msgstr ""
#: src/importer/importer.py:351 #: src/importer/importer.py:361
msgid "1 game imported" msgid "1 game imported"
msgstr "" msgstr ""
#. The variable is the number of games #. The variable is the number of games
#: src/importer/importer.py:355 #: src/importer/importer.py:365
msgid "{} games imported" msgid "{} games imported"
msgstr "" msgstr ""
#. A single game removed #. A single game removed
#: src/importer/importer.py:359 #: src/importer/importer.py:369
msgid "1 removed" msgid "1 removed"
msgstr "" msgstr ""

246
po/es.po
View File

@@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: cartridges\n" "Project-Id-Version: cartridges\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-16 11:06+0200\n" "POT-Creation-Date: 2023-08-27 14:03+0200\n"
"PO-Revision-Date: 2023-08-16 15:22+0000\n" "PO-Revision-Date: 2023-08-29 10:45+0000\n"
"Last-Translator: gallegonovato <fran-carro@hotmail.es>\n" "Last-Translator: gallegonovato <fran-carro@hotmail.es>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/cartridges/" "Language-Team: Spanish <https://hosted.weblate.org/projects/cartridges/"
"cartridges/es/>\n" "cartridges/es/>\n"
@@ -18,11 +18,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.0-dev\n" "X-Generator: Weblate 5.0.1-dev\n"
#: data/hu.kramo.Cartridges.desktop.in:3 #: data/hu.kramo.Cartridges.desktop.in:3
#: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47 #: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47
#: src/main.py:169 #: src/main.py:176
msgid "Cartridges" msgid "Cartridges"
msgstr "Cartuchos" msgstr "Cartuchos"
@@ -63,13 +63,13 @@ msgid "Edit Game Details"
msgstr "Editar detalles del juego" msgstr "Editar detalles del juego"
#: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71 #: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71
#: src/details_window.py:67 #: src/details_window.py:71
msgid "Game Details" msgid "Game Details"
msgstr "Detalles del juego" msgstr "Detalles del juego"
#: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:418 #: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:430
#: src/details_window.py:241 src/importer/importer.py:292 #: src/details_window.py:265 src/importer/importer.py:301
#: src/importer/importer.py:342 #: src/importer/importer.py:352
msgid "Preferences" msgid "Preferences"
msgstr "Preferencias" msgstr "Preferencias"
@@ -77,27 +77,31 @@ msgstr "Preferencias"
msgid "Cancel" msgid "Cancel"
msgstr "Cancelar" msgstr "Cancelar"
#: data/gtk/details-window.blp:57 #: data/gtk/details-window.blp:58
msgid "New Cover" msgid "New Cover"
msgstr "Portada nueva" msgstr "Portada nueva"
#: data/gtk/details-window.blp:75 #: data/gtk/details-window.blp:77
msgid "Delete Cover" msgid "Delete Cover"
msgstr "Borrar portada" msgstr "Borrar portada"
#: data/gtk/details-window.blp:102 data/gtk/game.blp:80 #: data/gtk/details-window.blp:105 data/gtk/game.blp:80
msgid "Title" msgid "Title"
msgstr "Título" msgstr "Título"
#: data/gtk/details-window.blp:105 #: data/gtk/details-window.blp:109
msgid "Developer (optional)" msgid "Developer (optional)"
msgstr "Desarrollador (opcional)" msgstr "Desarrollador (opcional)"
#: data/gtk/details-window.blp:110 #: data/gtk/details-window.blp:115
msgid "Executable" msgid "Executable"
msgstr "Ejecutable" msgstr "Ejecutable"
#: data/gtk/details-window.blp:116 #: data/gtk/details-window.blp:121
msgid "Select File"
msgstr "Seleccionar el archivo"
#: data/gtk/details-window.blp:132
msgid "More Info" msgid "More Info"
msgstr "Más información" msgstr "Más información"
@@ -105,16 +109,16 @@ msgstr "Más información"
msgid "Edit" msgid "Edit"
msgstr "Editar" msgstr "Editar"
#: data/gtk/game.blp:107 src/window.py:171 #: data/gtk/game.blp:107 src/window.py:190
msgid "Hide" msgid "Hide"
msgstr "Ocultar" msgstr "Ocultar"
#: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56 #: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56
#: data/gtk/window.blp:209 #: data/gtk/window.blp:215
msgid "Remove" msgid "Remove"
msgstr "Eliminar" msgstr "Eliminar"
#: data/gtk/game.blp:126 src/window.py:173 #: data/gtk/game.blp:126 src/window.py:192
msgid "Unhide" msgid "Unhide"
msgstr "Desocultar" msgstr "Desocultar"
@@ -126,8 +130,8 @@ msgstr "General"
msgid "Quit" msgid "Quit"
msgstr "Salir" msgstr "Salir"
#: data/gtk/help-overlay.blp:19 data/gtk/window.blp:217 data/gtk/window.blp:257 #: data/gtk/help-overlay.blp:19 data/gtk/window.blp:226 data/gtk/window.blp:269
#: data/gtk/window.blp:324 #: data/gtk/window.blp:336
msgid "Search" msgid "Search"
msgstr "Buscar" msgstr "Buscar"
@@ -139,8 +143,8 @@ msgstr "Mostrar preferencias"
msgid "Shortcuts" msgid "Shortcuts"
msgstr "Atajos" msgstr "Atajos"
#: data/gtk/help-overlay.blp:34 src/game.py:103 src/preferences.py:120 #: data/gtk/help-overlay.blp:34 src/game.py:105 src/preferences.py:124
#: src/importer/importer.py:366 #: src/importer/importer.py:376
msgid "Undo" msgid "Undo"
msgstr "Deshacer" msgstr "Deshacer"
@@ -154,7 +158,7 @@ msgstr "Juegos"
#: data/gtk/help-overlay.blp:48 #: data/gtk/help-overlay.blp:48
msgid "Add new game" msgid "Add new game"
msgstr "Añadir juego nuevo" msgstr "Añadir un nuevo juego"
#: data/gtk/help-overlay.blp:53 #: data/gtk/help-overlay.blp:53
msgid "Import games" msgid "Import games"
@@ -168,8 +172,8 @@ msgstr "Mostrar juegos ocultos"
msgid "Remove game" msgid "Remove game"
msgstr "Eliminar juego" msgstr "Eliminar juego"
#: data/gtk/preferences.blp:13 data/gtk/preferences.blp:89 #: data/gtk/preferences.blp:13 data/gtk/preferences.blp:88
#: data/gtk/preferences.blp:304 #: data/gtk/preferences.blp:339
msgid "Behavior" msgid "Behavior"
msgstr "Comportamiento" msgstr "Comportamiento"
@@ -186,7 +190,7 @@ msgid "Swaps the behavior of the cover image and the play button"
msgstr "" msgstr ""
"Cambia el comportamiento de la imagen de portada y del botón de reproducción" "Cambia el comportamiento de la imagen de portada y del botón de reproducción"
#: data/gtk/preferences.blp:36 src/details_window.py:81 #: data/gtk/preferences.blp:36 src/details_window.py:85
msgid "Images" msgid "Images"
msgstr "Imágenes" msgstr "Imágenes"
@@ -206,114 +210,118 @@ msgstr "Zona de peligro"
msgid "Remove All Games" msgid "Remove All Games"
msgstr "Eliminar todos los juegos" msgstr "Eliminar todos los juegos"
#: data/gtk/preferences.blp:85 data/gtk/window.blp:27 data/gtk/window.blp:444 #: data/gtk/preferences.blp:84 data/gtk/window.blp:27 data/gtk/window.blp:456
msgid "Import" msgid "Import"
msgstr "Importar" msgstr "Importar"
#: data/gtk/preferences.blp:92 #: data/gtk/preferences.blp:91
msgid "Remove Uninstalled Games" msgid "Remove Uninstalled Games"
msgstr "Eliminar los juegos desinstalados" msgstr "Eliminar los juegos desinstalados"
#: data/gtk/preferences.blp:102 #: data/gtk/preferences.blp:101
msgid "Sources" msgid "Sources"
msgstr "Fuentes" msgstr "Fuentes"
#: data/gtk/preferences.blp:105 #: data/gtk/preferences.blp:104
msgid "Steam" msgid "Steam"
msgstr "Steam" msgstr "Steam"
#: data/gtk/preferences.blp:109 data/gtk/preferences.blp:123 #: data/gtk/preferences.blp:108 data/gtk/preferences.blp:125
#: data/gtk/preferences.blp:164 data/gtk/preferences.blp:214 #: data/gtk/preferences.blp:172 data/gtk/preferences.blp:225
#: data/gtk/preferences.blp:228 data/gtk/preferences.blp:242 #: data/gtk/preferences.blp:242 data/gtk/preferences.blp:259
#: data/gtk/preferences.blp:256 data/gtk/preferences.blp:270 #: data/gtk/preferences.blp:276 data/gtk/preferences.blp:293
msgid "Install Location" msgid "Install Location"
msgstr "Ruta de instalación" msgstr "Ruta de instalación"
#: data/gtk/preferences.blp:119 #: data/gtk/preferences.blp:121
msgid "Lutris" msgid "Lutris"
msgstr "Lutris" msgstr "Lutris"
#: data/gtk/preferences.blp:132 #: data/gtk/preferences.blp:137
msgid "Cache Location" msgid "Cache Location"
msgstr "Ruta de la caché" msgstr "Ruta de la caché"
#: data/gtk/preferences.blp:141 #: data/gtk/preferences.blp:149
msgid "Import Steam Games" msgid "Import Steam Games"
msgstr "Importar juegos de Steam" msgstr "Importar juegos de Steam"
#: data/gtk/preferences.blp:150 #: data/gtk/preferences.blp:158
msgid "Import Flatpak Games" msgid "Import Flatpak Games"
msgstr "Importar juegos Flatpak" msgstr "Importar juegos Flatpak"
#: data/gtk/preferences.blp:160 #: data/gtk/preferences.blp:168
msgid "Heroic" msgid "Heroic"
msgstr "Heroic" msgstr "Heroic"
#: data/gtk/preferences.blp:173 #: data/gtk/preferences.blp:184
msgid "Import Epic Games" msgid "Import Epic Games"
msgstr "Importar juegos de Epic" msgstr "Importar juegos de Epic"
#: data/gtk/preferences.blp:182 #: data/gtk/preferences.blp:193
msgid "Import GOG Games" msgid "Import GOG Games"
msgstr "Importar juegos de GOG" msgstr "Importar juegos de GOG"
#: data/gtk/preferences.blp:191 #: data/gtk/preferences.blp:202
msgid "Import Amazon Games" msgid "Import Amazon Games"
msgstr "Importar de Amazon Games" msgstr "Importar de Amazon Games"
#: data/gtk/preferences.blp:200 #: data/gtk/preferences.blp:211
msgid "Import Sideloaded Games" msgid "Import Sideloaded Games"
msgstr "Importar juegos descargados" msgstr "Importar juegos descargados"
#: data/gtk/preferences.blp:210 #: data/gtk/preferences.blp:221
msgid "Bottles" msgid "Bottles"
msgstr "Bottles" msgstr "Bottles"
#: data/gtk/preferences.blp:224 #: data/gtk/preferences.blp:238
msgid "itch" msgid "itch"
msgstr "itch" msgstr "itch"
#: data/gtk/preferences.blp:238 #: data/gtk/preferences.blp:255
msgid "Legendary" msgid "Legendary"
msgstr "Legendario" msgstr "Legendario"
#: data/gtk/preferences.blp:252 #: data/gtk/preferences.blp:272
msgid "RetroArch" msgid "RetroArch"
msgstr "RetroArch" msgstr "RetroArch"
#: data/gtk/preferences.blp:266 #: data/gtk/preferences.blp:289
msgid "Flatpak" msgid "Flatpak"
msgstr "Flatpak" msgstr "Flatpak"
#: data/gtk/preferences.blp:279 #: data/gtk/preferences.blp:305
msgid "Import Game Launchers" msgid "Import Game Launchers"
msgstr "Importar lanzadores de juegos" msgstr "Importar lanzadores de juegos"
#: data/gtk/preferences.blp:292 #: data/gtk/preferences.blp:315
msgid "Desktop Entries"
msgstr "Entradas en el escritorio"
#: data/gtk/preferences.blp:327
msgid "SteamGridDB" msgid "SteamGridDB"
msgstr "SteamGridDB" msgstr "SteamGridDB"
#: data/gtk/preferences.blp:296 #: data/gtk/preferences.blp:331
msgid "Authentication" msgid "Authentication"
msgstr "Autenticación" msgstr "Autenticación"
#: data/gtk/preferences.blp:299 #: data/gtk/preferences.blp:334
msgid "API Key" msgid "API Key"
msgstr "Clave API" msgstr "Clave API"
#: data/gtk/preferences.blp:307 #: data/gtk/preferences.blp:342
msgid "Use SteamGridDB" msgid "Use SteamGridDB"
msgstr "Usar SteamGridDB" msgstr "Usar SteamGridDB"
#: data/gtk/preferences.blp:308 #: data/gtk/preferences.blp:343
msgid "Download images when adding or importing games" msgid "Download images when adding or importing games"
msgstr "Descargar las imágenes al añadir o importar juegos" msgstr "Descargar las imágenes al añadir o importar juegos"
#: data/gtk/preferences.blp:317 #: data/gtk/preferences.blp:352
msgid "Prefer Over Official Images" msgid "Prefer Over Official Images"
msgstr "Preferir las imágenes oficiales" msgstr "Preferir las imágenes oficiales"
#: data/gtk/preferences.blp:326 #: data/gtk/preferences.blp:361
msgid "Prefer Animated Images" msgid "Prefer Animated Images"
msgstr "Prefiero las imágenes animadas" msgstr "Prefiero las imágenes animadas"
@@ -341,7 +349,7 @@ msgstr "No hay juegos ocultos"
msgid "Games you hide will appear here." msgid "Games you hide will appear here."
msgstr "Los juegos que oculte aparecerán aquí." msgstr "Los juegos que oculte aparecerán aquí."
#: data/gtk/window.blp:64 data/gtk/window.blp:305 #: data/gtk/window.blp:64 data/gtk/window.blp:317
msgid "Back" msgid "Back"
msgstr "Volver" msgstr "Volver"
@@ -353,114 +361,118 @@ msgstr "Título del juego"
msgid "Play" msgid "Play"
msgstr "Jugar" msgstr "Jugar"
#: data/gtk/window.blp:243 data/gtk/window.blp:437 #: data/gtk/window.blp:255 data/gtk/window.blp:449
msgid "Add Game" msgid "Add Game"
msgstr "Añadir juego" msgstr "Añadir juego"
#: data/gtk/window.blp:250 data/gtk/window.blp:317 #: data/gtk/window.blp:262 data/gtk/window.blp:329
msgid "Main Menu" msgid "Main Menu"
msgstr "Menú principal" msgstr "Menú principal"
#: data/gtk/window.blp:272 #: data/gtk/window.blp:284
msgid "Search games" msgid "Search games"
msgstr "Buscar los juegos" msgstr "Buscar los juegos"
#: data/gtk/window.blp:312 #: data/gtk/window.blp:324
msgid "Hidden Games" msgid "Hidden Games"
msgstr "Juegos ocultos" msgstr "Juegos ocultos"
#: data/gtk/window.blp:339 #: data/gtk/window.blp:351
msgid "Search hidden games" msgid "Search hidden games"
msgstr "Buscar los juegos ocultos" msgstr "Buscar los juegos ocultos"
#: data/gtk/window.blp:376 #: data/gtk/window.blp:388
msgid "Sort" msgid "Sort"
msgstr "Ordenar" msgstr "Ordenar"
#: data/gtk/window.blp:379 #: data/gtk/window.blp:391
msgid "A-Z" msgid "A-Z"
msgstr "A-Z" msgstr "A-Z"
#: data/gtk/window.blp:385 #: data/gtk/window.blp:397
msgid "Z-A" msgid "Z-A"
msgstr "Z-A" msgstr "Z-A"
#: data/gtk/window.blp:391 #: data/gtk/window.blp:403
msgid "Newest" msgid "Newest"
msgstr "Más recientes" msgstr "Más recientes"
#: data/gtk/window.blp:397 #: data/gtk/window.blp:409
msgid "Oldest" msgid "Oldest"
msgstr "Más antiguos" msgstr "Más antiguos"
#: data/gtk/window.blp:403 #: data/gtk/window.blp:415
msgid "Last Played" msgid "Last Played"
msgstr "Último jugado" msgstr "Último jugado"
#: data/gtk/window.blp:410 #: data/gtk/window.blp:422
msgid "Show Hidden" msgid "Show Hidden"
msgstr "Mostrar ocultos" msgstr "Mostrar ocultos"
#: data/gtk/window.blp:423 #: data/gtk/window.blp:435
msgid "Keyboard Shortcuts" msgid "Keyboard Shortcuts"
msgstr "Atajos del teclado" msgstr "Atajos del teclado"
#: data/gtk/window.blp:428 #: data/gtk/window.blp:440
msgid "About Cartridges" msgid "About Cartridges"
msgstr "Acerca de Cartuchos" msgstr "Acerca de Cartuchos"
#. Translators: Replace this with your name for it to show up in the about window #. Translators: Replace this with your name for it to show up in the about window
#: src/main.py:188 #: src/main.py:195
msgid "translator_credits" msgid "translator_credits"
msgstr "Óscar Fernández Díaz <oscfdezdz@tuta.io>" msgstr "Óscar Fernández Díaz <oscfdezdz@tuta.io>"
#. The variable is the date when the game was added #. The variable is the date when the game was added
#: src/window.py:194 #: src/window.py:213
msgid "Added: {}" msgid "Added: {}"
msgstr "Añadido: {}" msgstr "Añadido: {}"
#: src/window.py:197 #: src/window.py:216
msgid "Never" msgid "Never"
msgstr "Nunca" msgstr "Nunca"
#. The variable is the date when the game was last played #. The variable is the date when the game was last played
#: src/window.py:201 #: src/window.py:220
msgid "Last played: {}" msgid "Last played: {}"
msgstr "Último jugado: {}" msgstr "Último jugado: {}"
#: src/details_window.py:72 #: src/details_window.py:76
msgid "Apply" msgid "Apply"
msgstr "Aplicar" msgstr "Aplicar"
#: src/details_window.py:78 #: src/details_window.py:82
msgid "Add New Game" msgid "Add New Game"
msgstr "Añadir juego nuevo" msgstr "Añadir un nuevo Juego"
#: src/details_window.py:79 #: src/details_window.py:83
msgid "Add" msgid "Add"
msgstr "Añadir" msgstr "Añadir"
#: src/details_window.py:93
msgid "Executables"
msgstr "Ejecutables"
#. Translate this string as you would translate "file" #. Translate this string as you would translate "file"
#: src/details_window.py:92 #: src/details_window.py:108
msgid "file.txt" msgid "file.txt"
msgstr "archivo.txt" msgstr "archivo.txt"
#. As in software #. As in software
#: src/details_window.py:94 #: src/details_window.py:110
msgid "program" msgid "program"
msgstr "programa" msgstr "programa"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:99 src/details_window.py:101 #: src/details_window.py:115 src/details_window.py:117
msgid "C:\\path\\to\\{}" msgid "C:\\path\\to\\{}"
msgstr "C:\\ruta\\hasta\\{}" msgstr "C:\\ruta\\hasta\\{}"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:105 src/details_window.py:107 #: src/details_window.py:121 src/details_window.py:123
msgid "/path/to/{}" msgid "/path/to/{}"
msgstr "/ruta/hasta/{}" msgstr "/ruta/hasta/{}"
#: src/details_window.py:112 #: src/details_window.py:128
msgid "" msgid ""
"To launch the executable \"{}\", use the command:\n" "To launch the executable \"{}\", use the command:\n"
"\n" "\n"
@@ -482,100 +494,100 @@ msgstr ""
"\n" "\n"
"Si la ruta contiene espacios, ¡asegúrese de entrecomillarla!" "Si la ruta contiene espacios, ¡asegúrese de entrecomillarla!"
#: src/details_window.py:147 src/details_window.py:153 #: src/details_window.py:171 src/details_window.py:177
msgid "Couldn't Add Game" msgid "Couldn't Add Game"
msgstr "No se puede añadir el juego" msgstr "No se puede añadir el juego"
#: src/details_window.py:147 src/details_window.py:183 #: src/details_window.py:171 src/details_window.py:207
msgid "Game title cannot be empty." msgid "Game title cannot be empty."
msgstr "El título del juego no puede estar vacío." msgstr "El título del juego no puede estar vacío."
#: src/details_window.py:153 src/details_window.py:191 #: src/details_window.py:177 src/details_window.py:215
msgid "Executable cannot be empty." msgid "Executable cannot be empty."
msgstr "El ejecutable no puede estar vacío." msgstr "El ejecutable no puede estar vacío."
#: src/details_window.py:182 src/details_window.py:190 #: src/details_window.py:206 src/details_window.py:214
msgid "Couldn't Apply Preferences" msgid "Couldn't Apply Preferences"
msgstr "No se pudieron aplicar las preferencias" msgstr "No se pudieron aplicar las preferencias"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:139 #: src/game.py:141
msgid "{} launched" msgid "{} launched"
msgstr "{} comenzó" msgstr "{} comenzó"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:153 #: src/game.py:155
msgid "{} hidden" msgid "{} hidden"
msgstr "{} oculto" msgstr "{} oculto"
#: src/game.py:153 #: src/game.py:155
msgid "{} unhidden" msgid "{} unhidden"
msgstr "{} visible" msgstr "{} visible"
#. The variable is the title of the game #. The variable is the title of the game
#. The variable is the number of games removed #. The variable is the number of games removed
#: src/game.py:170 src/importer/importer.py:363 #: src/game.py:172 src/importer/importer.py:373
msgid "{} removed" msgid "{} removed"
msgstr "{} eliminado" msgstr "{} eliminado"
#: src/preferences.py:119 #: src/preferences.py:123
msgid "All games removed" msgid "All games removed"
msgstr "Todos los juegos eliminados" msgstr "Todos los juegos eliminados"
#: src/preferences.py:168 #: src/preferences.py:172
msgid "" msgid ""
"An API key is required to use SteamGridDB. You can generate one {}here{}." "An API key is required to use SteamGridDB. You can generate one {}here{}."
msgstr "" msgstr ""
"Se necesita una clave API para utilizar SteamGridDB. Puedes generar una {}" "Se necesita una clave API para utilizar SteamGridDB. Puedes generar una {}"
"aquí{}." "aquí{}."
#: src/preferences.py:294 #: src/preferences.py:293
msgid "Installation Not Found" msgid "Installation Not Found"
msgstr "Instalación no encontrada" msgstr "Instalación no encontrada"
#: src/preferences.py:296 #: src/preferences.py:294
msgid "Select a valid directory." msgid "Select a valid directory."
msgstr "Selecciona un directorio válido." msgstr "Selecciona un directorio válido."
#: src/preferences.py:351 #: src/preferences.py:330 src/importer/importer.py:299
msgid "Invalid Directory"
msgstr "Directorio incorrecto"
#: src/preferences.py:357
msgid "Set Location"
msgstr "Escoger la ubicación"
#: src/utils/create_dialog.py:25 src/importer/importer.py:291
msgid "Dismiss"
msgstr "Descartar"
#: src/importer/importer.py:128
msgid "Importing Games…"
msgstr "Importando juegos…"
#: src/importer/importer.py:290
msgid "Warning" msgid "Warning"
msgstr "Advertencia" msgstr "Advertencia"
#: src/importer/importer.py:311 #: src/preferences.py:364
msgid "Invalid Directory"
msgstr "Directorio incorrecto"
#: src/preferences.py:370
msgid "Set Location"
msgstr "Escoger la ubicación"
#: src/utils/create_dialog.py:33 src/importer/importer.py:300
msgid "Dismiss"
msgstr "Descartar"
#: src/importer/importer.py:137
msgid "Importing Games…"
msgstr "Importando juegos…"
#: src/importer/importer.py:320
msgid "The following errors occured during import:" msgid "The following errors occured during import:"
msgstr "Han sucedido los siguientes fallos durante la importación:" msgstr "Han sucedido los siguientes fallos durante la importación:"
#: src/importer/importer.py:339 #: src/importer/importer.py:349
msgid "No new games found" msgid "No new games found"
msgstr "No se encontraron juegos nuevos" msgstr "No se encontraron juegos nuevos"
#: src/importer/importer.py:351 #: src/importer/importer.py:361
msgid "1 game imported" msgid "1 game imported"
msgstr "1 juego importado" msgstr "1 juego importado"
#. The variable is the number of games #. The variable is the number of games
#: src/importer/importer.py:355 #: src/importer/importer.py:365
msgid "{} games imported" msgid "{} games imported"
msgstr "0 juegos importados" msgstr "0 juegos importados"
#. A single game removed #. A single game removed
#: src/importer/importer.py:359 #: src/importer/importer.py:369
msgid "1 removed" msgid "1 removed"
msgstr "1 eliminado" msgstr "1 eliminado"

277
po/ru.po
View File

@@ -3,12 +3,13 @@
# This file is distributed under the same license as the cartridges package. # This file is distributed under the same license as the cartridges package.
# Сергей <asvmail.as@gmail.com>, 2023. # Сергей <asvmail.as@gmail.com>, 2023.
# kramo <contact@kramo.hu>, 2023. # kramo <contact@kramo.hu>, 2023.
# Сергей Ворон <voron.s.a@gmail.com>, 2023.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: cartridges\n" "Project-Id-Version: cartridges\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-16 11:06+0200\n" "POT-Creation-Date: 2023-08-27 14:03+0200\n"
"PO-Revision-Date: 2023-07-31 00:05+0000\n" "PO-Revision-Date: 2023-08-29 10:45+0000\n"
"Last-Translator: Сергей <asvmail.as@gmail.com>\n" "Last-Translator: Сергей <asvmail.as@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/cartridges/" "Language-Team: Russian <https://hosted.weblate.org/projects/cartridges/"
"cartridges/ru/>\n" "cartridges/ru/>\n"
@@ -16,13 +17,13 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.0-dev\n" "X-Generator: Weblate 5.0.1-dev\n"
#: data/hu.kramo.Cartridges.desktop.in:3 #: data/hu.kramo.Cartridges.desktop.in:3
#: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47 #: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47
#: src/main.py:169 #: src/main.py:176
msgid "Cartridges" msgid "Cartridges"
msgstr "Картриджи" msgstr "Картриджи"
@@ -36,12 +37,11 @@ msgid "Launch all your games"
msgstr "Запустите все свои игры" msgstr "Запустите все свои игры"
#: data/hu.kramo.Cartridges.desktop.in:11 #: data/hu.kramo.Cartridges.desktop.in:11
#, fuzzy
#| msgid "gaming;launcher;steam;lutris;heroic;bottles;itch;flatpak;legendary;"
msgid "" msgid ""
"gaming;launcher;steam;lutris;heroic;bottles;itch;flatpak;legendary;retroarch;" "gaming;launcher;steam;lutris;heroic;bottles;itch;flatpak;legendary;retroarch;"
msgstr "" msgstr ""
"gaming;launcher;steam;lutris;heroic;bottles;itch;flatpak;legendary;игры;стим;" "gaming;launcher;steam;lutris;heroic;bottles;itch;flatpak;legendary;retroarch;"
"игры;стим;"
#: data/hu.kramo.Cartridges.metainfo.xml.in:9 #: data/hu.kramo.Cartridges.metainfo.xml.in:9
msgid "" msgid ""
@@ -64,13 +64,13 @@ msgid "Edit Game Details"
msgstr "Редактировать подробности об игре" msgstr "Редактировать подробности об игре"
#: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71 #: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71
#: src/details_window.py:67 #: src/details_window.py:71
msgid "Game Details" msgid "Game Details"
msgstr "Подробности об игре" msgstr "Подробности об игре"
#: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:418 #: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:430
#: src/details_window.py:241 src/importer/importer.py:292 #: src/details_window.py:265 src/importer/importer.py:301
#: src/importer/importer.py:342 #: src/importer/importer.py:352
msgid "Preferences" msgid "Preferences"
msgstr "Параметры" msgstr "Параметры"
@@ -78,29 +78,31 @@ msgstr "Параметры"
msgid "Cancel" msgid "Cancel"
msgstr "Отменить" msgstr "Отменить"
#: data/gtk/details-window.blp:57 #: data/gtk/details-window.blp:58
msgid "New Cover" msgid "New Cover"
msgstr "Новая обложка" msgstr "Новая обложка"
#: data/gtk/details-window.blp:75 #: data/gtk/details-window.blp:77
msgid "Delete Cover" msgid "Delete Cover"
msgstr "Удалить обложку" msgstr "Удалить обложку"
#: data/gtk/details-window.blp:102 data/gtk/game.blp:80 #: data/gtk/details-window.blp:105 data/gtk/game.blp:80
msgid "Title" msgid "Title"
msgstr "Название" msgstr "Название"
#: data/gtk/details-window.blp:105 #: data/gtk/details-window.blp:109
#, fuzzy
#| msgid "The developer or publisher (optional)"
msgid "Developer (optional)" msgid "Developer (optional)"
msgstr "Разработчик или издатель (необязательно)" msgstr "Разработчик (необязательно)"
#: data/gtk/details-window.blp:110 #: data/gtk/details-window.blp:115
msgid "Executable" msgid "Executable"
msgstr "Исполняемый" msgstr "Исполняемый"
#: data/gtk/details-window.blp:116 #: data/gtk/details-window.blp:121
msgid "Select File"
msgstr "Выбрать файл"
#: data/gtk/details-window.blp:132
msgid "More Info" msgid "More Info"
msgstr "Дополнительная информация" msgstr "Дополнительная информация"
@@ -108,29 +110,29 @@ msgstr "Дополнительная информация"
msgid "Edit" msgid "Edit"
msgstr "Редактировать" msgstr "Редактировать"
#: data/gtk/game.blp:107 src/window.py:171 #: data/gtk/game.blp:107 src/window.py:190
msgid "Hide" msgid "Hide"
msgstr "Скрыть" msgstr "Скрыть"
#: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56 #: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56
#: data/gtk/window.blp:209 #: data/gtk/window.blp:215
msgid "Remove" msgid "Remove"
msgstr "Удалить" msgstr "Удалить"
#: data/gtk/game.blp:126 src/window.py:173 #: data/gtk/game.blp:126 src/window.py:192
msgid "Unhide" msgid "Unhide"
msgstr "Показать" msgstr "Показать"
#: data/gtk/help-overlay.blp:11 data/gtk/preferences.blp:9 #: data/gtk/help-overlay.blp:11 data/gtk/preferences.blp:9
msgid "General" msgid "General"
msgstr "Основное" msgstr "Общее"
#: data/gtk/help-overlay.blp:14 #: data/gtk/help-overlay.blp:14
msgid "Quit" msgid "Quit"
msgstr "Выйти" msgstr "Выйти"
#: data/gtk/help-overlay.blp:19 data/gtk/window.blp:217 data/gtk/window.blp:257 #: data/gtk/help-overlay.blp:19 data/gtk/window.blp:226 data/gtk/window.blp:269
#: data/gtk/window.blp:324 #: data/gtk/window.blp:336
msgid "Search" msgid "Search"
msgstr "Поиск" msgstr "Поиск"
@@ -142,8 +144,8 @@ msgstr "Показать параметры"
msgid "Shortcuts" msgid "Shortcuts"
msgstr "Комбинации клавиш" msgstr "Комбинации клавиш"
#: data/gtk/help-overlay.blp:34 src/game.py:103 src/preferences.py:120 #: data/gtk/help-overlay.blp:34 src/game.py:105 src/preferences.py:124
#: src/importer/importer.py:366 #: src/importer/importer.py:376
msgid "Undo" msgid "Undo"
msgstr "Вернуть" msgstr "Вернуть"
@@ -171,24 +173,24 @@ msgstr "Показать скрытые игры"
msgid "Remove game" msgid "Remove game"
msgstr "Удалить игру" msgstr "Удалить игру"
#: data/gtk/preferences.blp:13 data/gtk/preferences.blp:89 #: data/gtk/preferences.blp:13 data/gtk/preferences.blp:88
#: data/gtk/preferences.blp:304 #: data/gtk/preferences.blp:339
msgid "Behavior" msgid "Behavior"
msgstr "Поведение" msgstr "Поведение"
#: data/gtk/preferences.blp:16 #: data/gtk/preferences.blp:16
msgid "Exit After Launching Games" msgid "Exit After Launching Games"
msgstr "Выход после запуска игр" msgstr "Выход из приложения после запуска игры"
#: data/gtk/preferences.blp:25 #: data/gtk/preferences.blp:25
msgid "Cover Image Launches Game" msgid "Cover Image Launches Game"
msgstr "Запуск игры используя изображение обложки" msgstr "Запускать игры используя изображение обложки"
#: data/gtk/preferences.blp:26 #: data/gtk/preferences.blp:26
msgid "Swaps the behavior of the cover image and the play button" msgid "Swaps the behavior of the cover image and the play button"
msgstr "Меняет местами поведение изображения обложки и кнопки запуска" msgstr "Меняет местами поведение изображения обложки и кнопки запуска"
#: data/gtk/preferences.blp:36 src/details_window.py:81 #: data/gtk/preferences.blp:36 src/details_window.py:85
msgid "Images" msgid "Images"
msgstr "Изображения" msgstr "Изображения"
@@ -208,116 +210,118 @@ msgstr "Небезопасная область"
msgid "Remove All Games" msgid "Remove All Games"
msgstr "Удалить все игры" msgstr "Удалить все игры"
#: data/gtk/preferences.blp:85 data/gtk/window.blp:27 data/gtk/window.blp:444 #: data/gtk/preferences.blp:84 data/gtk/window.blp:27 data/gtk/window.blp:456
msgid "Import" msgid "Import"
msgstr "Импортировать" msgstr "Импорт"
#: data/gtk/preferences.blp:92 #: data/gtk/preferences.blp:91
#, fuzzy
#| msgid "Remove All Games"
msgid "Remove Uninstalled Games" msgid "Remove Uninstalled Games"
msgstr "Удалить все игры" msgstr "Удалять деинсталлированные игры"
#: data/gtk/preferences.blp:102 #: data/gtk/preferences.blp:101
msgid "Sources" msgid "Sources"
msgstr "Источники" msgstr "Источники"
#: data/gtk/preferences.blp:105 #: data/gtk/preferences.blp:104
msgid "Steam" msgid "Steam"
msgstr "Steam" msgstr "Steam"
#: data/gtk/preferences.blp:109 data/gtk/preferences.blp:123 #: data/gtk/preferences.blp:108 data/gtk/preferences.blp:125
#: data/gtk/preferences.blp:164 data/gtk/preferences.blp:214 #: data/gtk/preferences.blp:172 data/gtk/preferences.blp:225
#: data/gtk/preferences.blp:228 data/gtk/preferences.blp:242 #: data/gtk/preferences.blp:242 data/gtk/preferences.blp:259
#: data/gtk/preferences.blp:256 data/gtk/preferences.blp:270 #: data/gtk/preferences.blp:276 data/gtk/preferences.blp:293
msgid "Install Location" msgid "Install Location"
msgstr "Место установки" msgstr "Место установки"
#: data/gtk/preferences.blp:119 #: data/gtk/preferences.blp:121
msgid "Lutris" msgid "Lutris"
msgstr "Lutris" msgstr "Lutris"
#: data/gtk/preferences.blp:132 #: data/gtk/preferences.blp:137
msgid "Cache Location" msgid "Cache Location"
msgstr "Расположение кэша" msgstr "Расположение кэша"
#: data/gtk/preferences.blp:141 #: data/gtk/preferences.blp:149
msgid "Import Steam Games" msgid "Import Steam Games"
msgstr "Импорт игр Steam" msgstr "Импорт игр Steam"
#: data/gtk/preferences.blp:150 #: data/gtk/preferences.blp:158
msgid "Import Flatpak Games" msgid "Import Flatpak Games"
msgstr "Импорт игр Flatpak" msgstr "Импорт игр Flatpak"
#: data/gtk/preferences.blp:160 #: data/gtk/preferences.blp:168
msgid "Heroic" msgid "Heroic"
msgstr "Heroic" msgstr "Heroic"
#: data/gtk/preferences.blp:173 #: data/gtk/preferences.blp:184
msgid "Import Epic Games" msgid "Import Epic Games"
msgstr "Импорт игр Epic" msgstr "Импорт игр Epic"
#: data/gtk/preferences.blp:182 #: data/gtk/preferences.blp:193
msgid "Import GOG Games" msgid "Import GOG Games"
msgstr "Импорт игр GOG" msgstr "Импорт игр GOG"
#: data/gtk/preferences.blp:191 #: data/gtk/preferences.blp:202
msgid "Import Amazon Games" msgid "Import Amazon Games"
msgstr "Импорт игр Amazon" msgstr "Импорт игр Amazon"
#: data/gtk/preferences.blp:200 #: data/gtk/preferences.blp:211
msgid "Import Sideloaded Games" msgid "Import Sideloaded Games"
msgstr "Импорт сторонних игр" msgstr "Импорт сторонних игр"
#: data/gtk/preferences.blp:210 #: data/gtk/preferences.blp:221
msgid "Bottles" msgid "Bottles"
msgstr "Bottles" msgstr "Bottles"
#: data/gtk/preferences.blp:224 #: data/gtk/preferences.blp:238
msgid "itch" msgid "itch"
msgstr "itch" msgstr "itch"
#: data/gtk/preferences.blp:238 #: data/gtk/preferences.blp:255
msgid "Legendary" msgid "Legendary"
msgstr "Legendary" msgstr "Legendary"
#: data/gtk/preferences.blp:252 #: data/gtk/preferences.blp:272
msgid "RetroArch" msgid "RetroArch"
msgstr "" msgstr "RetroArch"
#: data/gtk/preferences.blp:266 #: data/gtk/preferences.blp:289
msgid "Flatpak" msgid "Flatpak"
msgstr "Flatpak" msgstr "Flatpak"
#: data/gtk/preferences.blp:279 #: data/gtk/preferences.blp:305
msgid "Import Game Launchers" msgid "Import Game Launchers"
msgstr "Импорт средств запуска игр" msgstr "Импорт средств запуска игр"
#: data/gtk/preferences.blp:292 #: data/gtk/preferences.blp:315
msgid "Desktop Entries"
msgstr "Интеграция в среду рабочего стола"
#: data/gtk/preferences.blp:327
msgid "SteamGridDB" msgid "SteamGridDB"
msgstr "SteamGridDB" msgstr "SteamGridDB"
#: data/gtk/preferences.blp:296 #: data/gtk/preferences.blp:331
msgid "Authentication" msgid "Authentication"
msgstr "Аутентификация" msgstr "Аутентификация"
#: data/gtk/preferences.blp:299 #: data/gtk/preferences.blp:334
msgid "API Key" msgid "API Key"
msgstr "API-ключ" msgstr "API-ключ"
#: data/gtk/preferences.blp:307 #: data/gtk/preferences.blp:342
msgid "Use SteamGridDB" msgid "Use SteamGridDB"
msgstr "Использовать SteamGridDB" msgstr "Использовать SteamGridDB"
#: data/gtk/preferences.blp:308 #: data/gtk/preferences.blp:343
msgid "Download images when adding or importing games" msgid "Download images when adding or importing games"
msgstr "Загрузка изображений при добавлении или импорте игр" msgstr "Загрузка изображений при добавлении или импорте игр"
#: data/gtk/preferences.blp:317 #: data/gtk/preferences.blp:352
msgid "Prefer Over Official Images" msgid "Prefer Over Official Images"
msgstr "Отдавать предпочтение официальным изображениям" msgstr "Отдавать предпочтение официальным изображениям"
#: data/gtk/preferences.blp:326 #: data/gtk/preferences.blp:361
msgid "Prefer Animated Images" msgid "Prefer Animated Images"
msgstr "Отдавать предпочтение анимированным изображениям" msgstr "Отдавать предпочтение анимированным изображениям"
@@ -345,7 +349,7 @@ msgstr "Нет скрытых игр"
msgid "Games you hide will appear here." msgid "Games you hide will appear here."
msgstr "Здесь появятся скрытые игры." msgstr "Здесь появятся скрытые игры."
#: data/gtk/window.blp:64 data/gtk/window.blp:305 #: data/gtk/window.blp:64 data/gtk/window.blp:317
msgid "Back" msgid "Back"
msgstr "Назад" msgstr "Назад"
@@ -357,118 +361,118 @@ msgstr "Название игры"
msgid "Play" msgid "Play"
msgstr "Играть" msgstr "Играть"
#: data/gtk/window.blp:243 data/gtk/window.blp:437 #: data/gtk/window.blp:255 data/gtk/window.blp:449
msgid "Add Game" msgid "Add Game"
msgstr "Добавить игру" msgstr "Добавить игру"
#: data/gtk/window.blp:250 data/gtk/window.blp:317 #: data/gtk/window.blp:262 data/gtk/window.blp:329
msgid "Main Menu" msgid "Main Menu"
msgstr "Главное меню" msgstr "Главное меню"
#: data/gtk/window.blp:272 #: data/gtk/window.blp:284
#, fuzzy
#| msgid "Search"
msgid "Search games" msgid "Search games"
msgstr "Поиск" msgstr "Поиск игр"
#: data/gtk/window.blp:312 #: data/gtk/window.blp:324
msgid "Hidden Games" msgid "Hidden Games"
msgstr "Скрытые игры" msgstr "Скрытые игры"
#: data/gtk/window.blp:339 #: data/gtk/window.blp:351
#, fuzzy
#| msgid "Show hidden games"
msgid "Search hidden games" msgid "Search hidden games"
msgstr "Показать скрытые игры" msgstr "Поиск скрытых игр"
#: data/gtk/window.blp:376 #: data/gtk/window.blp:388
msgid "Sort" msgid "Sort"
msgstr "Сортировать" msgstr "Сортировать"
#: data/gtk/window.blp:379 #: data/gtk/window.blp:391
msgid "A-Z" msgid "A-Z"
msgstr "А-Я" msgstr "А-Я"
#: data/gtk/window.blp:385 #: data/gtk/window.blp:397
msgid "Z-A" msgid "Z-A"
msgstr "Я-А" msgstr "Я-А"
#: data/gtk/window.blp:391 #: data/gtk/window.blp:403
msgid "Newest" msgid "Newest"
msgstr "Сначала новые" msgstr "Сначала новые"
#: data/gtk/window.blp:397 #: data/gtk/window.blp:409
msgid "Oldest" msgid "Oldest"
msgstr "Сначала старые" msgstr "Сначала старые"
#: data/gtk/window.blp:403 #: data/gtk/window.blp:415
msgid "Last Played" msgid "Last Played"
msgstr "Последняя игра" msgstr "Последняя игра"
#: data/gtk/window.blp:410 #: data/gtk/window.blp:422
msgid "Show Hidden" msgid "Show Hidden"
msgstr "Показать скрытые" msgstr "Показать скрытые"
#: data/gtk/window.blp:423 #: data/gtk/window.blp:435
msgid "Keyboard Shortcuts" msgid "Keyboard Shortcuts"
msgstr "Комбинации клавиш" msgstr "Комбинации клавиш"
#: data/gtk/window.blp:428 #: data/gtk/window.blp:440
msgid "About Cartridges" msgid "About Cartridges"
msgstr "О приложении" msgstr "О приложении"
#. Translators: Replace this with your name for it to show up in the about window #. Translators: Replace this with your name for it to show up in the about window
#: src/main.py:188 #: src/main.py:195
msgid "translator_credits" msgid "translator_credits"
msgstr "Ser82-png" msgstr "Ser82-png"
#. The variable is the date when the game was added #. The variable is the date when the game was added
#: src/window.py:194 #: src/window.py:213
msgid "Added: {}" msgid "Added: {}"
msgstr "Добавлено: {}" msgstr "Добавлено: {}"
#: src/window.py:197 #: src/window.py:216
msgid "Never" msgid "Never"
msgstr "Никогда" msgstr "Никогда"
#. The variable is the date when the game was last played #. The variable is the date when the game was last played
#: src/window.py:201 #: src/window.py:220
msgid "Last played: {}" msgid "Last played: {}"
msgstr "Последний раз запускалась: {}" msgstr "Последний раз запускалась: {}"
#: src/details_window.py:72 #: src/details_window.py:76
msgid "Apply" msgid "Apply"
msgstr "Применить" msgstr "Применить"
#: src/details_window.py:78 #: src/details_window.py:82
msgid "Add New Game" msgid "Add New Game"
msgstr "Добавить новую игру" msgstr "Добавить новую игру"
#: src/details_window.py:79 #: src/details_window.py:83
msgid "Add" msgid "Add"
msgstr "" msgstr "Добавить"
#: src/details_window.py:93
msgid "Executables"
msgstr "Исполняемые"
#. Translate this string as you would translate "file" #. Translate this string as you would translate "file"
#: src/details_window.py:92 #: src/details_window.py:108
msgid "file.txt" msgid "file.txt"
msgstr "file.txt" msgstr "file.txt"
#. As in software #. As in software
#: src/details_window.py:94 #: src/details_window.py:110
msgid "program" msgid "program"
msgstr "программа" msgstr "программа"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:99 src/details_window.py:101 #: src/details_window.py:115 src/details_window.py:117
msgid "C:\\path\\to\\{}" msgid "C:\\path\\to\\{}"
msgstr "C:\\путь\\к\\{}" msgstr "C:\\путь\\к\\{}"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:105 src/details_window.py:107 #: src/details_window.py:121 src/details_window.py:123
msgid "/path/to/{}" msgid "/path/to/{}"
msgstr "/путь/к/{}" msgstr "/путь/к/{}"
#: src/details_window.py:112 #: src/details_window.py:128
msgid "" msgid ""
"To launch the executable \"{}\", use the command:\n" "To launch the executable \"{}\", use the command:\n"
"\n" "\n"
@@ -490,104 +494,102 @@ msgstr ""
"\n" "\n"
"Если путь содержит пробелы, обязательно заключите его в двойные кавычки!" "Если путь содержит пробелы, обязательно заключите его в двойные кавычки!"
#: src/details_window.py:147 src/details_window.py:153 #: src/details_window.py:171 src/details_window.py:177
msgid "Couldn't Add Game" msgid "Couldn't Add Game"
msgstr "Не удалось добавить игру" msgstr "Не удалось добавить игру"
#: src/details_window.py:147 src/details_window.py:183 #: src/details_window.py:171 src/details_window.py:207
msgid "Game title cannot be empty." msgid "Game title cannot be empty."
msgstr "Название игры не может быть пустым." msgstr "Название игры не может быть пустым."
#: src/details_window.py:153 src/details_window.py:191 #: src/details_window.py:177 src/details_window.py:215
msgid "Executable cannot be empty." msgid "Executable cannot be empty."
msgstr "Исполняемый файл не может быть пустым." msgstr "Исполняемый файл не может быть пустым."
#: src/details_window.py:182 src/details_window.py:190 #: src/details_window.py:206 src/details_window.py:214
msgid "Couldn't Apply Preferences" msgid "Couldn't Apply Preferences"
msgstr "Не удалось применить параметры" msgstr "Не удалось применить параметры"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:139 #: src/game.py:141
msgid "{} launched" msgid "{} launched"
msgstr "{} - запущена" msgstr "{} - запущена"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:153 #: src/game.py:155
msgid "{} hidden" msgid "{} hidden"
msgstr "{} - скрытая" msgstr "{} - скрытая"
#: src/game.py:153 #: src/game.py:155
msgid "{} unhidden" msgid "{} unhidden"
msgstr "{} - не скрыта" msgstr "{} - не скрыта"
#. The variable is the title of the game #. The variable is the title of the game
#. The variable is the number of games removed #. The variable is the number of games removed
#: src/game.py:170 src/importer/importer.py:363 #: src/game.py:172 src/importer/importer.py:373
msgid "{} removed" msgid "{} removed"
msgstr "{} удалена" msgstr "{} удалена"
#: src/preferences.py:119 #: src/preferences.py:123
msgid "All games removed" msgid "All games removed"
msgstr "Все игры удалены" msgstr "Все игры удалены"
#: src/preferences.py:168 #: src/preferences.py:172
msgid "" msgid ""
"An API key is required to use SteamGridDB. You can generate one {}here{}." "An API key is required to use SteamGridDB. You can generate one {}here{}."
msgstr "" msgstr ""
"Для использования SteamGridDB требуется ключ API. Вы можете сгенерировать " "Для использования SteamGridDB требуется ключ API. Вы можете сгенерировать "
"его {}здесь{}." "его {}здесь{}."
#: src/preferences.py:294 #: src/preferences.py:293
msgid "Installation Not Found" msgid "Installation Not Found"
msgstr "Установка не найдена" msgstr "Установка не найдена"
#: src/preferences.py:296 #: src/preferences.py:294
msgid "Select a valid directory." msgid "Select a valid directory."
msgstr "Выберите действующий каталог." msgstr "Выберите действующий каталог."
#: src/preferences.py:351 #: src/preferences.py:330 src/importer/importer.py:299
msgid "Warning"
msgstr "Предупреждение"
#: src/preferences.py:364
msgid "Invalid Directory" msgid "Invalid Directory"
msgstr "Неверный каталог" msgstr "Неверный каталог"
#: src/preferences.py:357 #: src/preferences.py:370
msgid "Set Location" msgid "Set Location"
msgstr "Установить расположение" msgstr "Установить расположение"
#: src/utils/create_dialog.py:25 src/importer/importer.py:291 #: src/utils/create_dialog.py:33 src/importer/importer.py:300
msgid "Dismiss" msgid "Dismiss"
msgstr "Отклонить" msgstr "Отклонить"
#: src/importer/importer.py:128 #: src/importer/importer.py:137
msgid "Importing Games…" msgid "Importing Games…"
msgstr "Импорт игр…" msgstr "Импорт игр…"
#: src/importer/importer.py:290 #: src/importer/importer.py:320
msgid "Warning"
msgstr ""
#: src/importer/importer.py:311
msgid "The following errors occured during import:" msgid "The following errors occured during import:"
msgstr "" msgstr "При импорте возникли следующие ошибки:"
#: src/importer/importer.py:339 #: src/importer/importer.py:349
msgid "No new games found" msgid "No new games found"
msgstr "Новых игр не найдено" msgstr "Новых игр не найдено"
#: src/importer/importer.py:351 #: src/importer/importer.py:361
msgid "1 game imported" msgid "1 game imported"
msgstr "1 игра импортирована" msgstr "1 игра импортирована"
#. The variable is the number of games #. The variable is the number of games
#: src/importer/importer.py:355 #: src/importer/importer.py:365
msgid "{} games imported" msgid "{} games imported"
msgstr "{} игр(ы) импортировано" msgstr "{} игр(ы) импортировано"
#. A single game removed #. A single game removed
#: src/importer/importer.py:359 #: src/importer/importer.py:369
#, fuzzy
#| msgid "{} removed"
msgid "1 removed" msgid "1 removed"
msgstr "{} удалена" msgstr "1 удалена"
#. The variable is the name of the source #. The variable is the name of the source
#: src/importer/sources/location.py:33 #: src/importer/sources/location.py:33
@@ -612,6 +614,15 @@ msgstr "Не удалось пройти аутентификацию SteamGridD
msgid "Verify your API key in preferences" msgid "Verify your API key in preferences"
msgstr "Проверьте ключ API-ключ в параметрах" msgstr "Проверьте ключ API-ключ в параметрах"
#~ msgid "Terminal"
#~ msgstr "Терминал"
#~ msgid "Used only by games that require one to run"
#~ msgstr "Используется только играми, требующими его запуска"
#~ msgid "Custom"
#~ msgstr "Пользовательский"
#~ msgid "The title of the game" #~ msgid "The title of the game"
#~ msgstr "Название игры" #~ msgstr "Название игры"

234
po/ta.po
View File

@@ -8,8 +8,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Cartridges\n" "Project-Id-Version: Cartridges\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-16 11:06+0200\n" "POT-Creation-Date: 2023-08-27 14:03+0200\n"
"PO-Revision-Date: 2023-08-15 04:05+0000\n" "PO-Revision-Date: 2023-08-29 10:45+0000\n"
"Last-Translator: \"K.B.Dharun Krishna\" <kbdharunkrishna@gmail.com>\n" "Last-Translator: \"K.B.Dharun Krishna\" <kbdharunkrishna@gmail.com>\n"
"Language-Team: Tamil <https://hosted.weblate.org/projects/cartridges/" "Language-Team: Tamil <https://hosted.weblate.org/projects/cartridges/"
"cartridges/ta/>\n" "cartridges/ta/>\n"
@@ -18,11 +18,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.0-dev\n" "X-Generator: Weblate 5.0.1-dev\n"
#: data/hu.kramo.Cartridges.desktop.in:3 #: data/hu.kramo.Cartridges.desktop.in:3
#: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47 #: data/hu.kramo.Cartridges.metainfo.xml.in:6 data/gtk/window.blp:47
#: src/main.py:169 #: src/main.py:176
msgid "Cartridges" msgid "Cartridges"
msgstr "கார்ட்ரிட்ஜ்கள்" msgstr "கார்ட்ரிட்ஜ்கள்"
@@ -63,13 +63,13 @@ msgid "Edit Game Details"
msgstr "விளையாட்டு விவரங்களைத் திருத்து" msgstr "விளையாட்டு விவரங்களைத் திருத்து"
#: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71 #: data/hu.kramo.Cartridges.metainfo.xml.in:38 data/gtk/window.blp:71
#: src/details_window.py:67 #: src/details_window.py:71
msgid "Game Details" msgid "Game Details"
msgstr "விளையாட்டு விவரங்கள்" msgstr "விளையாட்டு விவரங்கள்"
#: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:418 #: data/hu.kramo.Cartridges.metainfo.xml.in:42 data/gtk/window.blp:430
#: src/details_window.py:241 src/importer/importer.py:292 #: src/details_window.py:265 src/importer/importer.py:301
#: src/importer/importer.py:342 #: src/importer/importer.py:352
msgid "Preferences" msgid "Preferences"
msgstr "விருப்பங்கள்" msgstr "விருப்பங்கள்"
@@ -77,27 +77,31 @@ msgstr "விருப்பங்கள்"
msgid "Cancel" msgid "Cancel"
msgstr "ரத்துசெய்" msgstr "ரத்துசெய்"
#: data/gtk/details-window.blp:57 #: data/gtk/details-window.blp:58
msgid "New Cover" msgid "New Cover"
msgstr "புதிய அட்டை" msgstr "புதிய அட்டை"
#: data/gtk/details-window.blp:75 #: data/gtk/details-window.blp:77
msgid "Delete Cover" msgid "Delete Cover"
msgstr "அட்டையை நீக்கு" msgstr "அட்டையை நீக்கு"
#: data/gtk/details-window.blp:102 data/gtk/game.blp:80 #: data/gtk/details-window.blp:105 data/gtk/game.blp:80
msgid "Title" msgid "Title"
msgstr "தலைப்பு" msgstr "தலைப்பு"
#: data/gtk/details-window.blp:105 #: data/gtk/details-window.blp:109
msgid "Developer (optional)" msgid "Developer (optional)"
msgstr "டெவலப்பர் (விரும்பினால்)" msgstr "டெவலப்பர் (விரும்பினால்)"
#: data/gtk/details-window.blp:110 #: data/gtk/details-window.blp:115
msgid "Executable" msgid "Executable"
msgstr "செயல்படுத்தக்கூடியது" msgstr "செயல்படுத்தக்கூடியது"
#: data/gtk/details-window.blp:116 #: data/gtk/details-window.blp:121
msgid "Select File"
msgstr "கோப்பைத் தேர்ந்தெடுக்கவும்"
#: data/gtk/details-window.blp:132
msgid "More Info" msgid "More Info"
msgstr "மேலும் தகவல்" msgstr "மேலும் தகவல்"
@@ -105,16 +109,16 @@ msgstr "மேலும் தகவல்"
msgid "Edit" msgid "Edit"
msgstr "தொகு" msgstr "தொகு"
#: data/gtk/game.blp:107 src/window.py:171 #: data/gtk/game.blp:107 src/window.py:190
msgid "Hide" msgid "Hide"
msgstr "மறை" msgstr "மறை"
#: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56 #: data/gtk/game.blp:112 data/gtk/game.blp:131 data/gtk/preferences.blp:56
#: data/gtk/window.blp:209 #: data/gtk/window.blp:215
msgid "Remove" msgid "Remove"
msgstr "அகற்று" msgstr "அகற்று"
#: data/gtk/game.blp:126 src/window.py:173 #: data/gtk/game.blp:126 src/window.py:192
msgid "Unhide" msgid "Unhide"
msgstr "மறை காட்டு" msgstr "மறை காட்டு"
@@ -126,8 +130,8 @@ msgstr "பொது"
msgid "Quit" msgid "Quit"
msgstr "வெளியேறு" msgstr "வெளியேறு"
#: data/gtk/help-overlay.blp:19 data/gtk/window.blp:217 data/gtk/window.blp:257 #: data/gtk/help-overlay.blp:19 data/gtk/window.blp:226 data/gtk/window.blp:269
#: data/gtk/window.blp:324 #: data/gtk/window.blp:336
msgid "Search" msgid "Search"
msgstr "தேடு" msgstr "தேடு"
@@ -139,8 +143,8 @@ msgstr "விருப்பங்களைக் காட்டு"
msgid "Shortcuts" msgid "Shortcuts"
msgstr "குறுக்குவழிகள்" msgstr "குறுக்குவழிகள்"
#: data/gtk/help-overlay.blp:34 src/game.py:103 src/preferences.py:120 #: data/gtk/help-overlay.blp:34 src/game.py:105 src/preferences.py:124
#: src/importer/importer.py:366 #: src/importer/importer.py:376
msgid "Undo" msgid "Undo"
msgstr "செயல்தவிர்" msgstr "செயல்தவிர்"
@@ -168,8 +172,8 @@ msgstr "மறைக்கப்பட்ட விளையாட்டுக
msgid "Remove game" msgid "Remove game"
msgstr "விளையாட்டை அகற்று" msgstr "விளையாட்டை அகற்று"
#: data/gtk/preferences.blp:13 data/gtk/preferences.blp:89 #: data/gtk/preferences.blp:13 data/gtk/preferences.blp:88
#: data/gtk/preferences.blp:304 #: data/gtk/preferences.blp:339
msgid "Behavior" msgid "Behavior"
msgstr "நடத்தை" msgstr "நடத்தை"
@@ -185,7 +189,7 @@ msgstr "அட்டைப் படம் விளையாட்டை தொ
msgid "Swaps the behavior of the cover image and the play button" msgid "Swaps the behavior of the cover image and the play button"
msgstr "அட்டைப் படத்தின் நடத்தை மற்றும் பிளே பட்டனை மாற்றுகிறது" msgstr "அட்டைப் படத்தின் நடத்தை மற்றும் பிளே பட்டனை மாற்றுகிறது"
#: data/gtk/preferences.blp:36 src/details_window.py:81 #: data/gtk/preferences.blp:36 src/details_window.py:85
msgid "Images" msgid "Images"
msgstr "படங்கள்" msgstr "படங்கள்"
@@ -205,117 +209,119 @@ msgstr "ஆபத்து மண்டலம்"
msgid "Remove All Games" msgid "Remove All Games"
msgstr "அனைத்து விளையாட்டுகளையும் அகற்று" msgstr "அனைத்து விளையாட்டுகளையும் அகற்று"
#: data/gtk/preferences.blp:85 data/gtk/window.blp:27 data/gtk/window.blp:444 #: data/gtk/preferences.blp:84 data/gtk/window.blp:27 data/gtk/window.blp:456
msgid "Import" msgid "Import"
msgstr "இறக்குமதி" msgstr "இறக்குமதி"
#: data/gtk/preferences.blp:92 #: data/gtk/preferences.blp:91
#, fuzzy
#| msgid "Remove All Games"
msgid "Remove Uninstalled Games" msgid "Remove Uninstalled Games"
msgstr "அனைத்து விளையாட்டுகளையும் அகற்று" msgstr "நிறுவல் நீக்கப்பட்ட விளையாட்டுகளை அகற்று"
#: data/gtk/preferences.blp:102 #: data/gtk/preferences.blp:101
msgid "Sources" msgid "Sources"
msgstr "மூலங்கள்" msgstr "மூலங்கள்"
#: data/gtk/preferences.blp:105 #: data/gtk/preferences.blp:104
msgid "Steam" msgid "Steam"
msgstr "Steam" msgstr "Steam"
#: data/gtk/preferences.blp:109 data/gtk/preferences.blp:123 #: data/gtk/preferences.blp:108 data/gtk/preferences.blp:125
#: data/gtk/preferences.blp:164 data/gtk/preferences.blp:214 #: data/gtk/preferences.blp:172 data/gtk/preferences.blp:225
#: data/gtk/preferences.blp:228 data/gtk/preferences.blp:242 #: data/gtk/preferences.blp:242 data/gtk/preferences.blp:259
#: data/gtk/preferences.blp:256 data/gtk/preferences.blp:270 #: data/gtk/preferences.blp:276 data/gtk/preferences.blp:293
msgid "Install Location" msgid "Install Location"
msgstr "நிறுவல் இடம்" msgstr "நிறுவல் இடம்"
#: data/gtk/preferences.blp:119 #: data/gtk/preferences.blp:121
msgid "Lutris" msgid "Lutris"
msgstr "Lutris" msgstr "Lutris"
#: data/gtk/preferences.blp:132 #: data/gtk/preferences.blp:137
msgid "Cache Location" msgid "Cache Location"
msgstr "தற்காலிக சேமிப்பு இடம்" msgstr "தற்காலிக சேமிப்பு இடம்"
#: data/gtk/preferences.blp:141 #: data/gtk/preferences.blp:149
msgid "Import Steam Games" msgid "Import Steam Games"
msgstr "Steam விளையாட்டுகளை இறக்குமதி செய்யவும்" msgstr "Steam விளையாட்டுகளை இறக்குமதி செய்யவும்"
#: data/gtk/preferences.blp:150 #: data/gtk/preferences.blp:158
msgid "Import Flatpak Games" msgid "Import Flatpak Games"
msgstr "Flatpak கேம்களை இறக்குமதி செய்யவும்" msgstr "Flatpak கேம்களை இறக்குமதி செய்யவும்"
#: data/gtk/preferences.blp:160 #: data/gtk/preferences.blp:168
msgid "Heroic" msgid "Heroic"
msgstr "Heroic" msgstr "Heroic"
#: data/gtk/preferences.blp:173 #: data/gtk/preferences.blp:184
msgid "Import Epic Games" msgid "Import Epic Games"
msgstr "Epic விளையாட்டுகளை இறக்குமதி செய்" msgstr "Epic விளையாட்டுகளை இறக்குமதி செய்"
#: data/gtk/preferences.blp:182 #: data/gtk/preferences.blp:193
msgid "Import GOG Games" msgid "Import GOG Games"
msgstr "GOG விளையாட்டுகளை இறக்குமதி செய்யவும்" msgstr "GOG விளையாட்டுகளை இறக்குமதி செய்யவும்"
#: data/gtk/preferences.blp:191 #: data/gtk/preferences.blp:202
msgid "Import Amazon Games" msgid "Import Amazon Games"
msgstr "Amazon விளையாட்டுகளை இறக்குமதி செய்யவும்" msgstr "Amazon விளையாட்டுகளை இறக்குமதி செய்யவும்"
#: data/gtk/preferences.blp:200 #: data/gtk/preferences.blp:211
msgid "Import Sideloaded Games" msgid "Import Sideloaded Games"
msgstr "பக்க ஏற்றப்பட்ட விளையாட்டுகளை இறக்குமதி செய்யவும்" msgstr "பக்க ஏற்றப்பட்ட விளையாட்டுகளை இறக்குமதி செய்யவும்"
#: data/gtk/preferences.blp:210 #: data/gtk/preferences.blp:221
msgid "Bottles" msgid "Bottles"
msgstr "பாட்டில்கள்" msgstr "பாட்டில்கள்"
#: data/gtk/preferences.blp:224 #: data/gtk/preferences.blp:238
msgid "itch" msgid "itch"
msgstr "itch" msgstr "itch"
#: data/gtk/preferences.blp:238 #: data/gtk/preferences.blp:255
msgid "Legendary" msgid "Legendary"
msgstr "Legendary" msgstr "Legendary"
#: data/gtk/preferences.blp:252 #: data/gtk/preferences.blp:272
msgid "RetroArch" msgid "RetroArch"
msgstr "RetroArch" msgstr "RetroArch"
#: data/gtk/preferences.blp:266 #: data/gtk/preferences.blp:289
msgid "Flatpak" msgid "Flatpak"
msgstr "Flatpak" msgstr "Flatpak"
#: data/gtk/preferences.blp:279 #: data/gtk/preferences.blp:305
msgid "Import Game Launchers" msgid "Import Game Launchers"
msgstr "விளையாட்டு துவக்கிகளை இறக்குமதி செய்" msgstr "விளையாட்டு துவக்கிகளை இறக்குமதி செய்"
#: data/gtk/preferences.blp:292 #: data/gtk/preferences.blp:315
msgid "Desktop Entries"
msgstr "டெஸ்க்டாப் உள்ளீடுகள்"
#: data/gtk/preferences.blp:327
msgid "SteamGridDB" msgid "SteamGridDB"
msgstr "SteamGridDB" msgstr "SteamGridDB"
#: data/gtk/preferences.blp:296 #: data/gtk/preferences.blp:331
msgid "Authentication" msgid "Authentication"
msgstr "அங்கீகாரம்" msgstr "அங்கீகாரம்"
#: data/gtk/preferences.blp:299 #: data/gtk/preferences.blp:334
msgid "API Key" msgid "API Key"
msgstr "API விசை" msgstr "API விசை"
#: data/gtk/preferences.blp:307 #: data/gtk/preferences.blp:342
msgid "Use SteamGridDB" msgid "Use SteamGridDB"
msgstr "SteamGridDB ஐப் பயன்படுத்தவும்" msgstr "SteamGridDB ஐப் பயன்படுத்தவும்"
#: data/gtk/preferences.blp:308 #: data/gtk/preferences.blp:343
msgid "Download images when adding or importing games" msgid "Download images when adding or importing games"
msgstr "" msgstr ""
"விளையாட்டுகளைச் சேர்க்கும் போது அல்லது இறக்குமதி செய்யும் போது படங்களைப் பதிவிறக்கவும்" "விளையாட்டுகளைச் சேர்க்கும் போது அல்லது இறக்குமதி செய்யும் போது படங்களைப் பதிவிறக்கவும்"
#: data/gtk/preferences.blp:317 #: data/gtk/preferences.blp:352
msgid "Prefer Over Official Images" msgid "Prefer Over Official Images"
msgstr "அதிகாரப்பூர்வ படங்களை விட முன்னுரிமை" msgstr "அதிகாரப்பூர்வ படங்களை விட முன்னுரிமை"
#: data/gtk/preferences.blp:326 #: data/gtk/preferences.blp:361
msgid "Prefer Animated Images" msgid "Prefer Animated Images"
msgstr "இயங்குபடம் செய்யப்பட்ட படங்களுக்கு முன்னுரிமை கொடுங்கள்" msgstr "இயங்குபடம் செய்யப்பட்ட படங்களுக்கு முன்னுரிமை கொடுங்கள்"
@@ -343,7 +349,7 @@ msgstr "மறைக்கப்பட்ட விளையாட்டுக
msgid "Games you hide will appear here." msgid "Games you hide will appear here."
msgstr "நீங்கள் மறைக்கும் விளையாட்டுகள் இங்கே தோன்றும்." msgstr "நீங்கள் மறைக்கும் விளையாட்டுகள் இங்கே தோன்றும்."
#: data/gtk/window.blp:64 data/gtk/window.blp:305 #: data/gtk/window.blp:64 data/gtk/window.blp:317
msgid "Back" msgid "Back"
msgstr "மீண்டும்" msgstr "மீண்டும்"
@@ -355,114 +361,118 @@ msgstr "விளையாட்டு தலைப்பு"
msgid "Play" msgid "Play"
msgstr "விளையாடு" msgstr "விளையாடு"
#: data/gtk/window.blp:243 data/gtk/window.blp:437 #: data/gtk/window.blp:255 data/gtk/window.blp:449
msgid "Add Game" msgid "Add Game"
msgstr "விளையாட்டைச் சேர்க்கவும்" msgstr "விளையாட்டைச் சேர்க்கவும்"
#: data/gtk/window.blp:250 data/gtk/window.blp:317 #: data/gtk/window.blp:262 data/gtk/window.blp:329
msgid "Main Menu" msgid "Main Menu"
msgstr "முதன்மை பட்டியல்" msgstr "முதன்மை பட்டியல்"
#: data/gtk/window.blp:272 #: data/gtk/window.blp:284
msgid "Search games" msgid "Search games"
msgstr "விளையாட்டுகளைத் தேடுங்கள்" msgstr "விளையாட்டுகளைத் தேடுங்கள்"
#: data/gtk/window.blp:312 #: data/gtk/window.blp:324
msgid "Hidden Games" msgid "Hidden Games"
msgstr "மறைக்கப்பட்ட விளையாட்டுகள்" msgstr "மறைக்கப்பட்ட விளையாட்டுகள்"
#: data/gtk/window.blp:339 #: data/gtk/window.blp:351
msgid "Search hidden games" msgid "Search hidden games"
msgstr "மறைக்கப்பட்ட விளையாட்டுகளைத் தேடுங்கள்" msgstr "மறைக்கப்பட்ட விளையாட்டுகளைத் தேடுங்கள்"
#: data/gtk/window.blp:376 #: data/gtk/window.blp:388
msgid "Sort" msgid "Sort"
msgstr "வகைபடுத்து" msgstr "வகைபடுத்து"
#: data/gtk/window.blp:379 #: data/gtk/window.blp:391
msgid "A-Z" msgid "A-Z"
msgstr "A-Z" msgstr "A-Z"
#: data/gtk/window.blp:385 #: data/gtk/window.blp:397
msgid "Z-A" msgid "Z-A"
msgstr "Z-A" msgstr "Z-A"
#: data/gtk/window.blp:391 #: data/gtk/window.blp:403
msgid "Newest" msgid "Newest"
msgstr "புதியது" msgstr "புதியது"
#: data/gtk/window.blp:397 #: data/gtk/window.blp:409
msgid "Oldest" msgid "Oldest"
msgstr "பழமையானது" msgstr "பழமையானது"
#: data/gtk/window.blp:403 #: data/gtk/window.blp:415
msgid "Last Played" msgid "Last Played"
msgstr "கடைசியாக விளையாடியது" msgstr "கடைசியாக விளையாடியது"
#: data/gtk/window.blp:410 #: data/gtk/window.blp:422
msgid "Show Hidden" msgid "Show Hidden"
msgstr "மறைக்கப்பட்டதைக் காட்டு" msgstr "மறைக்கப்பட்டதைக் காட்டு"
#: data/gtk/window.blp:423 #: data/gtk/window.blp:435
msgid "Keyboard Shortcuts" msgid "Keyboard Shortcuts"
msgstr "விசைப்பலகை குறுக்குவழிகள்" msgstr "விசைப்பலகை குறுக்குவழிகள்"
#: data/gtk/window.blp:428 #: data/gtk/window.blp:440
msgid "About Cartridges" msgid "About Cartridges"
msgstr "கார்ட்ரிட்ஜ்கள் பற்றி" msgstr "கார்ட்ரிட்ஜ்கள் பற்றி"
#. Translators: Replace this with your name for it to show up in the about window #. Translators: Replace this with your name for it to show up in the about window
#: src/main.py:188 #: src/main.py:195
msgid "translator_credits" msgid "translator_credits"
msgstr "K.B.Dharun Krishna <kbdharunkrishna@gmail.com>" msgstr "K.B.Dharun Krishna <kbdharunkrishna@gmail.com>"
#. The variable is the date when the game was added #. The variable is the date when the game was added
#: src/window.py:194 #: src/window.py:213
msgid "Added: {}" msgid "Added: {}"
msgstr "சேர்க்கப்பட்டது: {}" msgstr "சேர்க்கப்பட்டது: {}"
#: src/window.py:197 #: src/window.py:216
msgid "Never" msgid "Never"
msgstr "ஒருபோதும் இல்லை" msgstr "ஒருபோதும் இல்லை"
#. The variable is the date when the game was last played #. The variable is the date when the game was last played
#: src/window.py:201 #: src/window.py:220
msgid "Last played: {}" msgid "Last played: {}"
msgstr "கடைசியாக விளையாடியது: {}" msgstr "கடைசியாக விளையாடியது: {}"
#: src/details_window.py:72 #: src/details_window.py:76
msgid "Apply" msgid "Apply"
msgstr "விண்ணப்பி" msgstr "விண்ணப்பி"
#: src/details_window.py:78 #: src/details_window.py:82
msgid "Add New Game" msgid "Add New Game"
msgstr "புதிய விளையாட்டைச் சேர்க்கவும்" msgstr "புதிய விளையாட்டைச் சேர்க்கவும்"
#: src/details_window.py:79 #: src/details_window.py:83
msgid "Add" msgid "Add"
msgstr "சேர்" msgstr "சேர்"
#: src/details_window.py:93
msgid "Executables"
msgstr "செயல்படுத்தக்கூடியவை"
#. Translate this string as you would translate "file" #. Translate this string as you would translate "file"
#: src/details_window.py:92 #: src/details_window.py:108
msgid "file.txt" msgid "file.txt"
msgstr "கோப்பு.txt" msgstr "கோப்பு.txt"
#. As in software #. As in software
#: src/details_window.py:94 #: src/details_window.py:110
msgid "program" msgid "program"
msgstr "பயன்பாடு" msgstr "பயன்பாடு"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:99 src/details_window.py:101 #: src/details_window.py:115 src/details_window.py:117
msgid "C:\\path\\to\\{}" msgid "C:\\path\\to\\{}"
msgstr "C:\\பாதை\\டு \\{}" msgstr "C:\\பாதை\\டு \\{}"
#. Translate this string as you would translate "path to {}" #. Translate this string as you would translate "path to {}"
#: src/details_window.py:105 src/details_window.py:107 #: src/details_window.py:121 src/details_window.py:123
msgid "/path/to/{}" msgid "/path/to/{}"
msgstr "/பாதை/டு/ {}" msgstr "/பாதை/டு/ {}"
#: src/details_window.py:112 #: src/details_window.py:128
msgid "" msgid ""
"To launch the executable \"{}\", use the command:\n" "To launch the executable \"{}\", use the command:\n"
"\n" "\n"
@@ -484,102 +494,100 @@ msgstr ""
"\n" "\n"
"பாதையில் இடைவெளிகள் இருந்தால், அதை இரட்டை மேற்கோள்களில் போர்த்துவதை உறுதிசெய்யவும்!" "பாதையில் இடைவெளிகள் இருந்தால், அதை இரட்டை மேற்கோள்களில் போர்த்துவதை உறுதிசெய்யவும்!"
#: src/details_window.py:147 src/details_window.py:153 #: src/details_window.py:171 src/details_window.py:177
msgid "Couldn't Add Game" msgid "Couldn't Add Game"
msgstr "விளையாட்டைச் சேர்க்க முடியவில்லை" msgstr "விளையாட்டைச் சேர்க்க முடியவில்லை"
#: src/details_window.py:147 src/details_window.py:183 #: src/details_window.py:171 src/details_window.py:207
msgid "Game title cannot be empty." msgid "Game title cannot be empty."
msgstr "விளையாட்டு தலைப்பு காலியாக இருக்கக்கூடாது." msgstr "விளையாட்டு தலைப்பு காலியாக இருக்கக்கூடாது."
#: src/details_window.py:153 src/details_window.py:191 #: src/details_window.py:177 src/details_window.py:215
msgid "Executable cannot be empty." msgid "Executable cannot be empty."
msgstr "இயங்கக்கூடியது காலியாக இருக்க முடியாது." msgstr "இயங்கக்கூடியது காலியாக இருக்க முடியாது."
#: src/details_window.py:182 src/details_window.py:190 #: src/details_window.py:206 src/details_window.py:214
msgid "Couldn't Apply Preferences" msgid "Couldn't Apply Preferences"
msgstr "விருப்பங்களைப் பயன்படுத்த முடியவில்லை" msgstr "விருப்பங்களைப் பயன்படுத்த முடியவில்லை"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:139 #: src/game.py:141
msgid "{} launched" msgid "{} launched"
msgstr "{} தொடங்கப்பட்டது" msgstr "{} தொடங்கப்பட்டது"
#. The variable is the title of the game #. The variable is the title of the game
#: src/game.py:153 #: src/game.py:155
msgid "{} hidden" msgid "{} hidden"
msgstr "{} மறைக்கப்பட்டுள்ளது" msgstr "{} மறைக்கப்பட்டுள்ளது"
#: src/game.py:153 #: src/game.py:155
msgid "{} unhidden" msgid "{} unhidden"
msgstr "{} மறைக்கப்படாதது" msgstr "{} மறைக்கப்படாதது"
#. The variable is the title of the game #. The variable is the title of the game
#. The variable is the number of games removed #. The variable is the number of games removed
#: src/game.py:170 src/importer/importer.py:363 #: src/game.py:172 src/importer/importer.py:373
msgid "{} removed" msgid "{} removed"
msgstr "{} அகற்றப்பட்டது" msgstr "{} அகற்றப்பட்டது"
#: src/preferences.py:119 #: src/preferences.py:123
msgid "All games removed" msgid "All games removed"
msgstr "அனைத்து விளையாட்டுகளும் அகற்றப்பட்டன" msgstr "அனைத்து விளையாட்டுகளும் அகற்றப்பட்டன"
#: src/preferences.py:168 #: src/preferences.py:172
msgid "" msgid ""
"An API key is required to use SteamGridDB. You can generate one {}here{}." "An API key is required to use SteamGridDB. You can generate one {}here{}."
msgstr "SteamGridDB ஐப் பயன்படுத்த API விசை தேவை. நீங்கள் ஒன்றை {}இங்கே{} உருவாக்கலாம்." msgstr "SteamGridDB ஐப் பயன்படுத்த API விசை தேவை. நீங்கள் ஒன்றை {}இங்கே{} உருவாக்கலாம்."
#: src/preferences.py:294 #: src/preferences.py:293
msgid "Installation Not Found" msgid "Installation Not Found"
msgstr "நிறுவல் கிடைக்கவில்லை" msgstr "நிறுவல் கிடைக்கவில்லை"
#: src/preferences.py:296 #: src/preferences.py:294
msgid "Select a valid directory." msgid "Select a valid directory."
msgstr "சரியான கோப்பகத்தைத் தேர்ந்தெடுக்கவும்." msgstr "சரியான கோப்பகத்தைத் தேர்ந்தெடுக்கவும்."
#: src/preferences.py:351 #: src/preferences.py:330 src/importer/importer.py:299
msgid "Warning"
msgstr "எச்சரிக்கை"
#: src/preferences.py:364
msgid "Invalid Directory" msgid "Invalid Directory"
msgstr "தவறான கோப்பகம்" msgstr "தவறான கோப்பகம்"
#: src/preferences.py:357 #: src/preferences.py:370
msgid "Set Location" msgid "Set Location"
msgstr "இருப்பிடத்தை அமைக்கவும்" msgstr "இருப்பிடத்தை அமைக்கவும்"
#: src/utils/create_dialog.py:25 src/importer/importer.py:291 #: src/utils/create_dialog.py:33 src/importer/importer.py:300
msgid "Dismiss" msgid "Dismiss"
msgstr "நிராகரி" msgstr "நிராகரி"
#: src/importer/importer.py:128 #: src/importer/importer.py:137
msgid "Importing Games…" msgid "Importing Games…"
msgstr "விளையாட்டுகளை இறக்குமதி செய்கிறது…" msgstr "விளையாட்டுகளை இறக்குமதி செய்கிறது…"
#: src/importer/importer.py:290 #: src/importer/importer.py:320
msgid "Warning"
msgstr ""
#: src/importer/importer.py:311
msgid "The following errors occured during import:" msgid "The following errors occured during import:"
msgstr "" msgstr "இறக்குமதியின் போது பின்வரும் பிழைகள் ஏற்பட்டன:"
#: src/importer/importer.py:339 #: src/importer/importer.py:349
msgid "No new games found" msgid "No new games found"
msgstr "புதிய விளையாட்டுகள் எதுவும் கண்டறியப்படவில்லை" msgstr "புதிய விளையாட்டுகள் எதுவும் கண்டறியப்படவில்லை"
#: src/importer/importer.py:351 #: src/importer/importer.py:361
msgid "1 game imported" msgid "1 game imported"
msgstr "1 விளையாட்டு இறக்குமதி செய்யப்பட்டது" msgstr "1 விளையாட்டு இறக்குமதி செய்யப்பட்டது"
#. The variable is the number of games #. The variable is the number of games
#: src/importer/importer.py:355 #: src/importer/importer.py:365
msgid "{} games imported" msgid "{} games imported"
msgstr "{} விளையாட்டுகள் இறக்குமதி செய்யப்பட்டன" msgstr "{} விளையாட்டுகள் இறக்குமதி செய்யப்பட்டன"
#. A single game removed #. A single game removed
#: src/importer/importer.py:359 #: src/importer/importer.py:369
#, fuzzy
#| msgid "{} removed"
msgid "1 removed" msgid "1 removed"
msgstr "{} அகற்றப்பட்டது" msgstr "1 அகற்றப்பட்டது"
#. The variable is the name of the source #. The variable is the name of the source
#: src/importer/sources/location.py:33 #: src/importer/sources/location.py:33

View File

@@ -18,19 +18,22 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import os import os
import shlex
from pathlib import Path
from time import time from time import time
from typing import Any, Optional from typing import Any, Optional
from gi.repository import Adw, Gio, GLib, Gtk from gi.repository import Adw, Gio, GLib, Gtk
from PIL import Image from PIL import Image, UnidentifiedImageError
from src import shared from src import shared
from src.errors.friendly_error import FriendlyError from src.errors.friendly_error import FriendlyError
from src.game import Game from src.game import Game
from src.game_cover import GameCover from src.game_cover import GameCover
from src.store.managers.cover_manager import CoverManager
from src.store.managers.sgdb_manager import SGDBManager from src.store.managers.sgdb_manager import SGDBManager
from src.utils.create_dialog import create_dialog from src.utils.create_dialog import create_dialog
from src.utils.save_cover import resize_cover, save_cover from src.utils.save_cover import convert_cover, save_cover
@Gtk.Template(resource_path=shared.PREFIX + "/gtk/details-window.ui") @Gtk.Template(resource_path=shared.PREFIX + "/gtk/details-window.ui")
@@ -50,6 +53,7 @@ class DetailsWindow(Adw.Window):
exec_info_label = Gtk.Template.Child() exec_info_label = Gtk.Template.Child()
exec_info_popover = Gtk.Template.Child() exec_info_popover = Gtk.Template.Child()
file_chooser_button = Gtk.Template.Child()
apply_button = Gtk.Template.Child() apply_button = Gtk.Template.Child()
@@ -83,10 +87,22 @@ class DetailsWindow(Adw.Window):
image_filter.add_suffix(extension[1:]) image_filter.add_suffix(extension[1:])
image_filter.add_suffix("svg") # Gdk.Texture supports .svg but PIL doesn't image_filter.add_suffix("svg") # Gdk.Texture supports .svg but PIL doesn't
file_filters = Gio.ListStore.new(Gtk.FileFilter) image_filters = Gio.ListStore.new(Gtk.FileFilter)
file_filters.append(image_filter) image_filters.append(image_filter)
self.file_dialog = Gtk.FileDialog()
self.file_dialog.set_filters(file_filters) exec_filter = Gtk.FileFilter(name=_("Executables"))
exec_filter.add_mime_type("application/x-executable")
exec_filters = Gio.ListStore.new(Gtk.FileFilter)
exec_filters.append(exec_filter)
self.image_file_dialog = Gtk.FileDialog()
self.image_file_dialog.set_filters(image_filters)
self.image_file_dialog.set_default_filter(image_filter)
self.exec_file_dialog = Gtk.FileDialog()
self.exec_file_dialog.set_filters(exec_filters)
self.exec_file_dialog.set_default_filter(exec_filter)
# Translate this string as you would translate "file" # Translate this string as you would translate "file"
file_name = _("file.txt") file_name = _("file.txt")
@@ -128,6 +144,7 @@ class DetailsWindow(Adw.Window):
self.cover_button_delete.connect("clicked", self.delete_pixbuf) self.cover_button_delete.connect("clicked", self.delete_pixbuf)
self.cover_button_edit.connect("clicked", self.choose_cover) self.cover_button_edit.connect("clicked", self.choose_cover)
self.file_chooser_button.connect("clicked", self.choose_executable)
self.apply_button.connect("clicked", self.apply_preferences) self.apply_button.connect("clicked", self.apply_preferences)
self.name.connect("entry-activated", self.focus_executable) self.name.connect("entry-activated", self.focus_executable)
@@ -262,19 +279,47 @@ class DetailsWindow(Adw.Window):
def set_cover(self, _source: Any, result: Gio.Task, *_args: Any) -> None: def set_cover(self, _source: Any, result: Gio.Task, *_args: Any) -> None:
try: try:
path = self.file_dialog.open_finish(result).get_path() path = self.image_file_dialog.open_finish(result).get_path()
except GLib.GError: except GLib.GError:
return return
def resize() -> None: def thread_func() -> None:
if cover := resize_cover(path): new_path = None
self.game_cover.new_cover(cover)
try:
with Image.open(path) as image:
if getattr(image, "is_animated", False):
new_path = convert_cover(path)
except UnidentifiedImageError:
pass
if not new_path:
new_path = convert_cover(
pixbuf=shared.store.managers[CoverManager].composite_cover(
Path(path)
)
)
if new_path:
self.game_cover.new_cover(new_path)
self.cover_button_delete_revealer.set_reveal_child(True) self.cover_button_delete_revealer.set_reveal_child(True)
self.cover_changed = True self.cover_changed = True
self.toggle_loading() self.toggle_loading()
self.toggle_loading() self.toggle_loading()
GLib.Thread.new(None, resize) GLib.Thread.new(None, thread_func)
def set_executable(self, _source: Any, result: Gio.Task, *_args: Any) -> None:
try:
path = self.exec_file_dialog.open_finish(result).get_path()
except GLib.GError:
return
self.executable.set_text(shlex.quote(path))
def choose_executable(self, *_args: Any) -> None:
self.exec_file_dialog.open(self, None, self.set_executable)
def choose_cover(self, *_args: Any) -> None: def choose_cover(self, *_args: Any) -> None:
self.file_dialog.open(self, None, self.set_cover) self.image_file_dialog.open(self, None, self.set_cover)

View File

@@ -18,7 +18,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from pathlib import Path from pathlib import Path
from typing import Any, Callable, Optional from typing import Optional
from gi.repository import Gdk, GdkPixbuf, Gio, GLib, Gtk from gi.repository import Gdk, GdkPixbuf, Gio, GLib, Gtk
from PIL import Image, ImageFilter, ImageStat from PIL import Image, ImageFilter, ImageStat
@@ -45,16 +45,6 @@ class GameCover:
self.pictures = pictures self.pictures = pictures
self.new_cover(path) self.new_cover(path)
# Wrap the function in another one as Gio.Task.run_in_thread does not allow for passing args
def create_func(self, path: Optional[Path]) -> Callable:
self.animation = GdkPixbuf.PixbufAnimation.new_from_file(str(path))
self.anim_iter = self.animation.get_iter()
def wrapper(task: Gio.Task, *_args: Any) -> None:
self.update_animation((task, self.animation))
return wrapper
def new_cover(self, path: Optional[Path] = None) -> None: def new_cover(self, path: Optional[Path] = None) -> None:
self.animation = None self.animation = None
self.texture = None self.texture = None
@@ -64,8 +54,12 @@ class GameCover:
if path: if path:
if path.suffix == ".gif": if path.suffix == ".gif":
self.animation = GdkPixbuf.PixbufAnimation.new_from_file(str(path))
self.anim_iter = self.animation.get_iter()
self.task = Gio.Task.new() self.task = Gio.Task.new()
self.task.run_in_thread(self.create_func(self.path)) self.task.run_in_thread(
lambda *_: self.update_animation((self.task, self.animation))
)
else: else:
self.texture = Gdk.Texture.new_from_filename(str(path)) self.texture = Gdk.Texture.new_from_filename(str(path))

View File

@@ -19,9 +19,10 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
import logging import logging
from time import time
from typing import Any, Optional from typing import Any, Optional
from gi.repository import Adw, GLib, Gtk from gi.repository import Adw, Gio, GLib, Gtk
from src import shared from src import shared
from src.errors.error_producer import ErrorProducer from src.errors.error_producer import ErrorProducer
@@ -31,7 +32,6 @@ from src.importer.sources.location import UnresolvableLocationError
from src.importer.sources.source import Source from src.importer.sources.source import Source
from src.store.managers.async_manager import AsyncManager from src.store.managers.async_manager import AsyncManager
from src.store.pipeline import Pipeline from src.store.pipeline import Pipeline
from src.utils.task import Task
# pylint: disable=too-many-instance-attributes # pylint: disable=too-many-instance-attributes
@@ -56,6 +56,8 @@ class Importer(ErrorProducer):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
shared.import_time = int(time())
# TODO: make this stateful # TODO: make this stateful
shared.store.new_game_ids = set() shared.store.new_game_ids = set()
shared.store.duplicate_game_ids = set() shared.store.duplicate_game_ids = set()
@@ -103,8 +105,8 @@ class Importer(ErrorProducer):
def run(self) -> None: def run(self) -> None:
"""Use several Gio.Task to import games from added sources""" """Use several Gio.Task to import games from added sources"""
if Importer.summary_toast: if self.__class__.summary_toast:
Importer.summary_toast.dismiss() self.__class__.summary_toast.dismiss()
shared.win.get_application().lookup_action("import").set_enabled(False) shared.win.get_application().lookup_action("import").set_enabled(False)
@@ -121,10 +123,13 @@ class Importer(ErrorProducer):
for source in self.sources: for source in self.sources:
logging.debug("Importing games from source %s", source.source_id) logging.debug("Importing games from source %s", source.source_id)
task = Task.new(None, None, self.source_callback, (source,)) task = Gio.Task.new(None, None, self.source_callback, (source,))
self.n_source_tasks_created += 1 self.n_source_tasks_created += 1
task.set_task_data((source,)) task.run_in_thread(
task.run_in_thread(self.source_task_thread_func) lambda _task, _obj, _data, _cancellable, src=source: self.source_task_thread_func(
(src,)
)
)
self.progress_changed_callback() self.progress_changed_callback()
@@ -145,9 +150,7 @@ class Importer(ErrorProducer):
) )
self.import_dialog.present() self.import_dialog.present()
def source_task_thread_func( def source_task_thread_func(self, data: tuple) -> None:
self, _task: Any, _obj: Any, data: tuple, _cancellable: Any
) -> None:
"""Source import task code""" """Source import task code"""
source: Source source: Source
@@ -266,7 +269,7 @@ class Importer(ErrorProducer):
shared.store.new_game_ids = set() shared.store.new_game_ids = set()
shared.store.duplicate_game_ids = set() shared.store.duplicate_game_ids = set()
self.import_dialog.close() self.import_dialog.close()
Importer.summary_toast = self.create_summary_toast() self.__class__.summary_toast = self.create_summary_toast()
self.create_error_dialog() self.create_error_dialog()
shared.win.get_application().lookup_action("import").set_enabled(True) shared.win.get_application().lookup_action("import").set_enabled(True)
@@ -335,8 +338,8 @@ class Importer(ErrorProducer):
self.imported_game_ids = set() self.imported_game_ids = set()
self.removed_game_ids = set() self.removed_game_ids = set()
if Importer.summary_toast: if self.__class__.summary_toast:
Importer.summary_toast.dismiss() self.__class__.summary_toast.dismiss()
logging.info("Import undone") logging.info("Import undone")
@@ -392,8 +395,8 @@ class Importer(ErrorProducer):
def timeout_toast(self, *_args: Any) -> None: def timeout_toast(self, *_args: Any) -> None:
"""Manually timeout the toast after the user has dismissed all warnings""" """Manually timeout the toast after the user has dismissed all warnings"""
if Importer.summary_toast: if self.__class__.summary_toast:
GLib.timeout_add_seconds(5, Importer.summary_toast.dismiss) GLib.timeout_add_seconds(5, self.__class__.summary_toast.dismiss)
def dialog_response_callback(self, _widget: Any, response: str, *args: Any) -> None: def dialog_response_callback(self, _widget: Any, response: str, *args: Any) -> None:
"""Handle after-import dialogs callback""" """Handle after-import dialogs callback"""

View File

@@ -19,7 +19,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from pathlib import Path from pathlib import Path
from time import time
from typing import NamedTuple from typing import NamedTuple
import yaml import yaml
@@ -38,17 +37,17 @@ class BottlesSourceIterable(SourceIterable):
data = self.source.locations.data["library.yml"].read_text("utf-8") data = self.source.locations.data["library.yml"].read_text("utf-8")
library: dict = yaml.safe_load(data) library: dict = yaml.safe_load(data)
added_time = int(time())
for entry in library.values(): for entry in library.values():
# Build game # Build game
values = { values = {
"source": self.source.source_id, "source": self.source.source_id,
"added": added_time, "added": shared.import_time,
"name": entry["name"], "name": entry["name"],
"game_id": self.source.game_id_format.format(game_id=entry["id"]), "game_id": self.source.game_id_format.format(game_id=entry["id"]),
"executable": self.source.executable_format.format( "executable": self.source.make_executable(
bottle_name=entry["bottle"]["name"], game_name=entry["name"] bottle_name=entry["bottle"]["name"],
game_name=entry["name"],
), ),
} }
game = Game(values) game = Game(values)
@@ -73,7 +72,6 @@ class BottlesSourceIterable(SourceIterable):
image_path = bottles_location / bottle_path / "grids" / image_name image_path = bottles_location / bottle_path / "grids" / image_name
additional_data = {"local_image_path": image_path} additional_data = {"local_image_path": image_path}
# Produce game
yield (game, additional_data) yield (game, additional_data)

View File

@@ -0,0 +1,204 @@
# desktop_source.py
#
# Copyright 2023 kramo
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
import os
import shlex
import subprocess
from pathlib import Path
from typing import NamedTuple
from gi.repository import GLib, Gtk
from src import shared
from src.game import Game
from src.importer.sources.source import Source, SourceIterable
class DesktopSourceIterable(SourceIterable):
source: "DesktopSource"
def __iter__(self):
"""Generator method producing games"""
icon_theme = Gtk.IconTheme.new()
search_paths = [
shared.home / ".local" / "share",
"/run/host/usr/local/share",
"/run/host/usr/share",
"/run/host/usr/share/pixmaps",
"/usr/share/pixmaps",
] + GLib.get_system_data_dirs()
for search_path in search_paths:
path = Path(search_path)
if not str(search_path).endswith("/pixmaps"):
path = path / "icons"
if not path.is_dir():
continue
if str(path).startswith("/app/"):
continue
icon_theme.add_search_path(str(path))
launch_command, full_path = self.check_launch_command()
for path in search_paths:
if str(path).startswith("/app/"):
continue
path = Path(path) / "applications"
if not path.is_dir():
continue
for entry in path.iterdir():
if entry.suffix != ".desktop":
continue
# Skip Lutris games
if str(entry.name).startswith("net.lutris."):
continue
keyfile = GLib.KeyFile.new()
try:
keyfile.load_from_file(str(entry), 0)
if "Game" not in keyfile.get_string_list(
"Desktop Entry", "Categories"
):
continue
name = keyfile.get_string("Desktop Entry", "Name")
executable = keyfile.get_string("Desktop Entry", "Exec").split(
" %"
)[0]
except GLib.GError:
continue
# Skip Steam games
if "steam://rungameid/" in executable:
continue
# Skip Heroic games
if "heroic://launch/" in executable:
continue
# Skip Bottles games
if "bottles-cli " in executable:
continue
try:
if keyfile.get_boolean("Desktop Entry", "NoDisplay"):
continue
except GLib.GError:
pass
# Strip /run/host from Flatpak paths
if entry.is_relative_to(prefix := "/run/host"):
entry = Path("/") / entry.relative_to(prefix)
launch_arg = shlex.quote(str(entry if full_path else entry.stem))
values = {
"source": self.source.source_id,
"added": shared.import_time,
"name": name,
"game_id": f"desktop_{entry.stem}",
"executable": f"{launch_command} {launch_arg}",
}
game = Game(values)
additional_data = {}
try:
icon_str = keyfile.get_string("Desktop Entry", "Icon")
except GLib.GError:
yield game
continue
else:
if "/" in icon_str:
additional_data = {"local_icon_path": Path(icon_str)}
yield (game, additional_data)
continue
try:
if (
icon_path := icon_theme.lookup_icon(
icon_str,
None,
512,
1,
shared.win.get_direction(),
0,
)
.get_file()
.get_path()
):
additional_data = {"local_icon_path": Path(icon_path)}
except GLib.GError:
pass
yield (game, additional_data)
def check_launch_command(self) -> (str, bool):
"""Check whether `gio launch` `gtk4-launch` or `gtk-launch` are available on the system"""
commands = (("gio launch", True), ("gtk4-launch", False), ("gtk-launch", False))
flatpak_str = "flatpak-spawn --host /bin/sh -c "
for command, full_path in commands:
# Even if `gio` is available, `gio launch` is only available on GLib >= 2.67.2
check_command = (
"gio help launch"
if command == "gio launch"
else f"type {command} &> /dev/null"
)
if os.getenv("FLATPAK_ID") == shared.APP_ID:
check_command = flatpak_str + shlex.quote(check_command)
try:
subprocess.run(check_command, shell=True, check=True)
return command, full_path
except subprocess.CalledProcessError:
pass
return commands[2]
class DesktopLocations(NamedTuple):
pass
class DesktopSource(Source):
"""Generic Flatpak source"""
source_id = "desktop"
name = _("Desktop")
iterable_class = DesktopSourceIterable
available_on = {"linux"}
locations: DesktopLocations
def __init__(self) -> None:
super().__init__()
self.locations = DesktopLocations()

View File

@@ -18,7 +18,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from pathlib import Path from pathlib import Path
from time import time
from typing import NamedTuple from typing import NamedTuple
from gi.repository import GLib, Gtk from gi.repository import GLib, Gtk
@@ -35,8 +34,6 @@ class FlatpakSourceIterable(SourceIterable):
def __iter__(self): def __iter__(self):
"""Generator method producing games""" """Generator method producing games"""
added_time = int(time())
icon_theme = Gtk.IconTheme.new() icon_theme = Gtk.IconTheme.new()
icon_theme.add_search_path(str(self.source.locations.data["icons"])) icon_theme.add_search_path(str(self.source.locations.data["icons"]))
@@ -51,6 +48,7 @@ class FlatpakSourceIterable(SourceIterable):
"com.heroicgameslauncher.hgl", "com.heroicgameslauncher.hgl",
"com.usebottles.Bottles", "com.usebottles.Bottles",
"io.itch.itch", "io.itch.itch",
"org.libretro.RetroArch",
} }
) )
@@ -78,12 +76,10 @@ class FlatpakSourceIterable(SourceIterable):
values = { values = {
"source": self.source.source_id, "source": self.source.source_id,
"added": added_time, "added": shared.import_time,
"name": name, "name": name,
"game_id": self.source.game_id_format.format(game_id=flatpak_id), "game_id": self.source.game_id_format.format(game_id=flatpak_id),
"executable": self.source.executable_format.format( "executable": self.source.make_executable(flatpak_id=flatpak_id),
flatpak_id=flatpak_id
),
} }
game = Game(values) game = Game(values)
@@ -108,7 +104,6 @@ class FlatpakSourceIterable(SourceIterable):
except GLib.GError: except GLib.GError:
pass pass
# Produce game
yield (game, additional_data) yield (game, additional_data)

View File

@@ -25,7 +25,6 @@ from functools import cached_property
from hashlib import sha256 from hashlib import sha256
from json import JSONDecodeError from json import JSONDecodeError
from pathlib import Path from pathlib import Path
from time import time
from typing import Iterable, NamedTuple, Optional, TypedDict from typing import Iterable, NamedTuple, Optional, TypedDict
from src import shared from src import shared
@@ -91,9 +90,7 @@ class SubSourceIterable(Iterable):
logging.debug("Using Heroic %s library.json path %s", self.name, path) logging.debug("Using Heroic %s library.json path %s", self.name, path)
return path return path
def process_library_entry( def process_library_entry(self, entry: HeroicLibraryEntry) -> SourceIterationResult:
self, entry: HeroicLibraryEntry, added_time: int
) -> SourceIterationResult:
"""Build a Game from a Heroic library entry""" """Build a Game from a Heroic library entry"""
app_name = entry["app_name"] app_name = entry["app_name"]
@@ -102,15 +99,13 @@ class SubSourceIterable(Iterable):
# Build game # Build game
values = { values = {
"source": f"{self.source.source_id}_{self.service}", "source": f"{self.source.source_id}_{self.service}",
"added": added_time, "added": shared.import_time,
"name": entry["title"], "name": entry["title"],
"developer": entry.get("developer", None), "developer": entry.get("developer", None),
"game_id": self.source.game_id_format.format( "game_id": self.source.game_id_format.format(
service=self.service, game_id=app_name service=self.service, game_id=app_name
), ),
"executable": self.source.executable_format.format( "executable": self.source.make_executable(runner=runner, app_name=app_name),
runner=runner, app_name=app_name
),
"hidden": self.source_iterable.is_hidden(app_name), "hidden": self.source_iterable.is_hidden(app_name),
} }
game = Game(values) game = Game(values)
@@ -129,7 +124,7 @@ class SubSourceIterable(Iterable):
Iterate through the games with a generator Iterate through the games with a generator
:raises InvalidLibraryFileError: on initial call if the library file is bad :raises InvalidLibraryFileError: on initial call if the library file is bad
""" """
added_time = int(time())
try: try:
iterator = iter( iterator = iter(
path_json_load(self.library_path)[self.library_json_entries_key] path_json_load(self.library_path)[self.library_json_entries_key]
@@ -140,7 +135,7 @@ class SubSourceIterable(Iterable):
) from error ) from error
for entry in iterator: for entry in iterator:
try: try:
yield self.process_library_entry(entry, added_time) yield self.process_library_entry(entry)
except KeyError as error: except KeyError as error:
logging.warning( logging.warning(
"Skipped invalid %s game %s", "Skipped invalid %s game %s",
@@ -178,7 +173,7 @@ class StoreSubSourceIterable(SubSourceIterable):
def is_installed(self, app_name: str) -> bool: def is_installed(self, app_name: str) -> bool:
return app_name in self.installed_app_names return app_name in self.installed_app_names
def process_library_entry(self, entry, added_time): def process_library_entry(self, entry):
# Skip games that are not installed # Skip games that are not installed
app_name = entry["app_name"] app_name = entry["app_name"]
if not self.is_installed(app_name): if not self.is_installed(app_name):
@@ -190,7 +185,7 @@ class StoreSubSourceIterable(SubSourceIterable):
) )
return None return None
# Process entry as normal # Process entry as normal
return super().process_library_entry(entry, added_time) return super().process_library_entry(entry)
def __iter__(self): def __iter__(self):
""" """

View File

@@ -20,7 +20,6 @@
from shutil import rmtree from shutil import rmtree
from sqlite3 import connect from sqlite3 import connect
from time import time
from typing import NamedTuple from typing import NamedTuple
from src import shared from src import shared
@@ -56,16 +55,14 @@ class ItchSourceIterable(SourceIterable):
connection = connect(db_path) connection = connect(db_path)
cursor = connection.execute(db_request) cursor = connection.execute(db_request)
added_time = int(time())
# Create games from the db results # Create games from the db results
for row in cursor: for row in cursor:
values = { values = {
"added": added_time, "added": shared.import_time,
"source": self.source.source_id, "source": self.source.source_id,
"name": row[1], "name": row[1],
"game_id": self.source.game_id_format.format(game_id=row[0]), "game_id": self.source.game_id_format.format(game_id=row[0]),
"executable": self.source.executable_format.format(cave_id=row[4]), "executable": self.source.make_executable(cave_id=row[4]),
} }
additional_data = {"online_cover_url": row[3] or row[2]} additional_data = {"online_cover_url": row[3] or row[2]}
game = Game(values) game = Game(values)

View File

@@ -20,7 +20,6 @@
import json import json
import logging import logging
from json import JSONDecodeError from json import JSONDecodeError
from time import time
from typing import NamedTuple from typing import NamedTuple
from src import shared from src import shared
@@ -28,17 +27,15 @@ from src.game import Game
from src.importer.sources.location import Location, LocationSubPath from src.importer.sources.location import Location, LocationSubPath
from src.importer.sources.source import ( from src.importer.sources.source import (
ExecutableFormatSource, ExecutableFormatSource,
SourceIterationResult,
SourceIterable, SourceIterable,
SourceIterationResult,
) )
class LegendarySourceIterable(SourceIterable): class LegendarySourceIterable(SourceIterable):
source: "LegendarySource" source: "LegendarySource"
def game_from_library_entry( def game_from_library_entry(self, entry: dict) -> SourceIterationResult:
self, entry: dict, added_time: int
) -> SourceIterationResult:
# Skip non-games # Skip non-games
if entry["is_dlc"]: if entry["is_dlc"]:
return None return None
@@ -46,11 +43,11 @@ class LegendarySourceIterable(SourceIterable):
# Build game # Build game
app_name = entry["app_name"] app_name = entry["app_name"]
values = { values = {
"added": added_time, "added": shared.import_time,
"source": self.source.source_id, "source": self.source.source_id,
"name": entry["title"], "name": entry["title"],
"game_id": self.source.game_id_format.format(game_id=app_name), "game_id": self.source.game_id_format.format(game_id=app_name),
"executable": self.source.executable_format.format(app_name=app_name), "executable": self.source.make_executable(app_name=app_name),
} }
data = {} data = {}
@@ -78,12 +75,10 @@ class LegendarySourceIterable(SourceIterable):
logging.warning("Couldn't open Legendary file: %s", str(file)) logging.warning("Couldn't open Legendary file: %s", str(file))
return return
added_time = int(time())
# Generate games from library # Generate games from library
for entry in library.values(): for entry in library.values():
try: try:
result = self.game_from_library_entry(entry, added_time) result = self.game_from_library_entry(entry)
except KeyError as error: except KeyError as error:
# Skip invalid games # Skip invalid games
logging.warning( logging.warning(

View File

@@ -19,7 +19,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from shutil import rmtree from shutil import rmtree
from sqlite3 import connect from sqlite3 import connect
from time import time
from typing import NamedTuple from typing import NamedTuple
from src import shared from src import shared
@@ -56,20 +55,18 @@ class LutrisSourceIterable(SourceIterable):
connection = connect(db_path) connection = connect(db_path)
cursor = connection.execute(request, params) cursor = connection.execute(request, params)
added_time = int(time())
# Create games from the DB results # Create games from the DB results
for row in cursor: for row in cursor:
# Create game # Create game
values = { values = {
"added": added_time, "added": shared.import_time,
"hidden": row[4], "hidden": row[4],
"name": row[1], "name": row[1],
"source": f"{self.source.source_id}_{row[3]}", "source": f"{self.source.source_id}_{row[3]}",
"game_id": self.source.game_id_format.format( "game_id": self.source.game_id_format.format(
runner=row[3], game_id=row[0] runner=row[3], game_id=row[0]
), ),
"executable": self.source.executable_format.format(game_id=row[0]), "executable": self.source.make_executable(game_id=row[0]),
} }
game = Game(values) game = Game(values)
@@ -77,7 +74,6 @@ class LutrisSourceIterable(SourceIterable):
image_path = self.source.locations.cache["coverart"] / f"{row[2]}.jpg" image_path = self.source.locations.cache["coverart"] / f"{row[2]}.jpg"
additional_data = {"local_image_path": image_path} additional_data = {"local_image_path": image_path}
# Produce game
yield (game, additional_data) yield (game, additional_data)
# Cleanup # Cleanup

View File

@@ -24,9 +24,7 @@ from hashlib import md5
from json import JSONDecodeError from json import JSONDecodeError
from pathlib import Path from pathlib import Path
from shlex import quote as shell_quote from shlex import quote as shell_quote
from time import time
from typing import NamedTuple from typing import NamedTuple
from urllib.parse import quote as url_quote
from src import shared from src import shared
from src.errors.friendly_error import FriendlyError from src.errors.friendly_error import FriendlyError
@@ -54,7 +52,6 @@ class RetroarchSourceIterable(SourceIterable):
raise KeyError(f"Key not found in RetroArch config: {key}") raise KeyError(f"Key not found in RetroArch config: {key}")
def __iter__(self): def __iter__(self):
added_time = int(time())
bad_playlists = set() bad_playlists = set()
config_file = self.source.locations.config["retroarch.cfg"] config_file = self.source.locations.config["retroarch.cfg"]
@@ -102,7 +99,7 @@ class RetroarchSourceIterable(SourceIterable):
values = { values = {
"source": self.source.source_id, "source": self.source.source_id,
"added": added_time, "added": shared.import_time,
"name": item["label"], "name": item["label"],
"game_id": self.source.game_id_format.format(game_id=game_id), "game_id": self.source.game_id_format.format(game_id=game_id),
"executable": self.source.make_executable( "executable": self.source.make_executable(

View File

@@ -78,7 +78,6 @@ class Source(Iterable):
def is_available(self) -> bool: def is_available(self) -> bool:
return sys.platform in self.available_on return sys.platform in self.available_on
@abstractmethod
def make_executable(self, *args, **kwargs) -> str: def make_executable(self, *args, **kwargs) -> str:
""" """
Create a game executable command. Create a game executable command.
@@ -105,7 +104,7 @@ class ExecutableFormatSource(Source):
def make_executable(self, *args, **kwargs) -> str: def make_executable(self, *args, **kwargs) -> str:
"""Use the executable format to""" """Use the executable format to"""
return self.executable_format.format(args, kwargs) return self.executable_format.format(*args, **kwargs)
# pylint: disable=abstract-method # pylint: disable=abstract-method

View File

@@ -21,7 +21,6 @@
import logging import logging
import re import re
from pathlib import Path from pathlib import Path
from time import time
from typing import Iterable, NamedTuple from typing import Iterable, NamedTuple
from src import shared from src import shared
@@ -64,8 +63,6 @@ class SteamSourceIterable(SourceIterable):
appid_cache = set() appid_cache = set()
manifests = self.get_manifests() manifests = self.get_manifests()
added_time = int(time())
for manifest in manifests: for manifest in manifests:
# Get metadata from manifest # Get metadata from manifest
steam = SteamFileHelper() steam = SteamFileHelper()
@@ -90,11 +87,11 @@ class SteamSourceIterable(SourceIterable):
# Build game from local data # Build game from local data
values = { values = {
"added": added_time, "added": shared.import_time,
"name": local_data["name"], "name": local_data["name"],
"source": self.source.source_id, "source": self.source.source_id,
"game_id": self.source.game_id_format.format(game_id=appid), "game_id": self.source.game_id_format.format(game_id=appid),
"executable": self.source.executable_format.format(game_id=appid), "executable": self.source.make_executable(game_id=appid),
} }
game = Game(values) game = Game(values)
@@ -105,7 +102,6 @@ class SteamSourceIterable(SourceIterable):
) )
additional_data = {"local_image_path": image_path, "steam_appid": appid} additional_data = {"local_image_path": image_path, "steam_appid": appid}
# Produce game
yield (game, additional_data) yield (game, additional_data)

View File

@@ -89,18 +89,24 @@ class SessionFileHandler(StreamHandler):
# If uncompressed, compress # If uncompressed, compress
if not path.name.endswith(".xz"): if not path.name.endswith(".xz"):
try:
with open(path, "r", encoding="utf-8") as original_file:
original_data = original_file.read()
except UnicodeDecodeError:
# If the file is corrupted, throw it away
path.unlink()
return
# Compress the file
compressed_path = path.with_suffix(path.suffix + ".xz") compressed_path = path.with_suffix(path.suffix + ".xz")
with ( with lzma.open(
lzma.open( compressed_path,
compressed_path, "wt",
"wt", format=FORMAT_XZ,
format=FORMAT_XZ, preset=PRESET_DEFAULT,
preset=PRESET_DEFAULT, encoding="utf-8",
encoding="utf-8", ) as lzma_file:
) as lzma_file, lzma_file.write(original_data)
open(path, "r", encoding="utf-8") as original_file,
):
lzma_file.write(original_file.read())
path.unlink() path.unlink()
path = compressed_path path = compressed_path

View File

@@ -20,6 +20,8 @@
import json import json
import lzma import lzma
import os import os
import shlex
import subprocess
import sys import sys
from typing import Any, Optional from typing import Any, Optional
@@ -36,6 +38,7 @@ from src.details_window import DetailsWindow
from src.game import Game from src.game import Game
from src.importer.importer import Importer from src.importer.importer import Importer
from src.importer.sources.bottles_source import BottlesSource from src.importer.sources.bottles_source import BottlesSource
from src.importer.sources.desktop_source import DesktopSource
from src.importer.sources.flatpak_source import FlatpakSource from src.importer.sources.flatpak_source import FlatpakSource
from src.importer.sources.heroic_source import HeroicSource from src.importer.sources.heroic_source import HeroicSource
from src.importer.sources.itch_source import ItchSource from src.importer.sources.itch_source import ItchSource
@@ -155,9 +158,9 @@ class CartridgesApplication(Adw.Application):
def on_about_action(self, *_args: Any) -> None: def on_about_action(self, *_args: Any) -> None:
# Get the debug info from the log files # Get the debug info from the log files
debug_str = "" debug_str = ""
for i, path in enumerate(shared.log_files): for index, path in enumerate(shared.log_files):
# Add a horizontal line between runs # Add a horizontal line between runs
if i > 0: if index > 0:
debug_str += "" * 37 + "\n" debug_str += "" * 37 + "\n"
# Add the run's logs # Add the run's logs
log_file = ( log_file = (
@@ -241,6 +244,9 @@ class CartridgesApplication(Adw.Application):
if shared.schema.get_boolean("flatpak"): if shared.schema.get_boolean("flatpak"):
shared.importer.add_source(FlatpakSource()) shared.importer.add_source(FlatpakSource())
if shared.schema.get_boolean("desktop"):
shared.importer.add_source(DesktopSource())
if shared.schema.get_boolean("itch"): if shared.schema.get_boolean("itch"):
shared.importer.add_source(ItchSource()) shared.importer.add_source(ItchSource())

View File

@@ -97,6 +97,8 @@ class PreferencesWindow(Adw.PreferencesWindow):
flatpak_data_file_chooser_button = Gtk.Template.Child() flatpak_data_file_chooser_button = Gtk.Template.Child()
flatpak_import_launchers_switch = Gtk.Template.Child() flatpak_import_launchers_switch = Gtk.Template.Child()
desktop_switch = Gtk.Template.Child()
sgdb_key_group = Gtk.Template.Child() sgdb_key_group = Gtk.Template.Child()
sgdb_key_entry_row = Gtk.Template.Child() sgdb_key_entry_row = Gtk.Template.Child()
sgdb_switch = Gtk.Template.Child() sgdb_switch = Gtk.Template.Child()
@@ -199,6 +201,7 @@ class PreferencesWindow(Adw.PreferencesWindow):
"sgdb", "sgdb",
"sgdb-prefer", "sgdb-prefer",
"sgdb-animated", "sgdb-animated",
"desktop",
} }
) )
@@ -276,9 +279,6 @@ class PreferencesWindow(Adw.PreferencesWindow):
def resolve_locations(self, source: Source) -> None: def resolve_locations(self, source: Source) -> None:
"""Resolve locations and add a warning if location cannot be found""" """Resolve locations and add a warning if location cannot be found"""
def clear_warning_selection(_widget: Any, label: Gtk.Label) -> None:
label.select_region(-1, -1)
for location_name, location in source.locations._asdict().items(): for location_name, location in source.locations._asdict().items():
action_row = getattr( action_row = getattr(
self, f"{source.source_id}_{location_name}_action_row", None self, f"{source.source_id}_{location_name}_action_row", None
@@ -290,15 +290,16 @@ class PreferencesWindow(Adw.PreferencesWindow):
location.resolve() location.resolve()
except UnresolvableLocationError: except UnresolvableLocationError:
title = _("Installation Not Found")
description = _("Select a valid directory.")
format_start = '<span rise="12pt"><b><big>'
format_end = "</big></b></span>\n"
popover = Gtk.Popover( popover = Gtk.Popover(
focusable=True,
child=( child=(
label := Gtk.Label( Gtk.Label(
label=( label=format_start + title + format_end + description,
'<span rise="12pt"><b><big>'
+ _("Installation Not Found")
+ "</big></b></span>\n"
+ _("Select a valid directory.")
),
use_markup=True, use_markup=True,
wrap=True, wrap=True,
max_width_chars=50, max_width_chars=50,
@@ -309,17 +310,24 @@ class PreferencesWindow(Adw.PreferencesWindow):
margin_bottom=9, margin_bottom=9,
margin_start=12, margin_start=12,
margin_end=12, margin_end=12,
selectable=True,
) )
) ),
) )
popover.connect("show", clear_warning_selection, label) popover.update_property(
(Gtk.AccessibleProperty.LABEL,), (title + description,)
)
def set_a11y_label(widget: Gtk.Popover) -> None:
self.set_focus(widget)
popover.connect("show", set_a11y_label)
menu_button = Gtk.MenuButton( menu_button = Gtk.MenuButton(
icon_name="dialog-warning-symbolic", icon_name="dialog-warning-symbolic",
valign=Gtk.Align.CENTER, valign=Gtk.Align.CENTER,
popover=popover, popover=popover,
tooltip_text=_("Warning"),
) )
menu_button.add_css_class("warning") menu_button.add_css_class("warning")

View File

@@ -52,5 +52,6 @@ image_size = (200 * scale_factor, 300 * scale_factor)
# pylint: disable=invalid-name # pylint: disable=invalid-name
win = None win = None
importer = None importer = None
import_time = None
store = None store = None
log_files = None log_files = None

View File

@@ -17,13 +17,12 @@
# #
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from typing import Callable, Any from typing import Any, Callable
from gi.repository import Gio from gi.repository import Gio
from src.game import Game from src.game import Game
from src.store.managers.manager import Manager from src.store.managers.manager import Manager
from src.utils.task import Task
class AsyncManager(Manager): class AsyncManager(Manager):
@@ -49,11 +48,10 @@ class AsyncManager(Manager):
self, game: Game, additional_data: dict, callback: Callable[["Manager"], Any] self, game: Game, additional_data: dict, callback: Callable[["Manager"], Any]
) -> None: ) -> None:
"""Create a task to process the game in a separate thread""" """Create a task to process the game in a separate thread"""
task = Task.new(None, self.cancellable, self._task_callback, (callback,)) task = Gio.Task.new(None, self.cancellable, self._task_callback, (callback,))
task.set_task_data((game, additional_data)) task.run_in_thread(lambda *_: self._task_thread_func((game, additional_data)))
task.run_in_thread(self._task_thread_func)
def _task_thread_func(self, _task, _source_object, data, _cancellable): def _task_thread_func(self, data):
"""Task thread entry point""" """Task thread entry point"""
game, additional_data, *_rest = data game, additional_data, *_rest = data
self.run(game, additional_data) self.run(game, additional_data)

View File

@@ -22,14 +22,14 @@ from pathlib import Path
from typing import NamedTuple from typing import NamedTuple
import requests import requests
from gi.repository import Gio, GdkPixbuf from gi.repository import GdkPixbuf, Gio
from requests.exceptions import HTTPError, SSLError from requests.exceptions import HTTPError, SSLError
from src import shared from src import shared
from src.game import Game from src.game import Game
from src.store.managers.manager import Manager from src.store.managers.manager import Manager
from src.store.managers.steam_api_manager import SteamAPIManager from src.store.managers.steam_api_manager import SteamAPIManager
from src.utils.save_cover import resize_cover, save_cover from src.utils.save_cover import convert_cover, save_cover
class ImageSize(NamedTuple): class ImageSize(NamedTuple):
@@ -110,18 +110,16 @@ class CoverManager(Manager):
stretch = 1 - (resized_height / cover_size.height) stretch = 1 - (resized_height / cover_size.height)
return stretch <= max_stretch return stretch <= max_stretch
def save_composited_cover( def composite_cover(
self, self,
game: Game,
image_path: Path, image_path: Path,
scale: float = 1, scale: float = 1,
blur_size: ImageSize = ImageSize(2, 2), blur_size: ImageSize = ImageSize(2, 2),
) -> None: ) -> GdkPixbuf.Pixbuf:
""" """
Save the image composited with a background blur. Return the image composited with a background blur.
If the image is stretchable, just stretch it. If the image is stretchable, just stretch it.
:param game: The game to save the cover for
:param path: Path where the source image is located :param path: Path where the source image is located
:param scale: :param scale:
Scale of the smalled image side Scale of the smalled image side
@@ -130,14 +128,15 @@ class CoverManager(Manager):
""" """
# Load source image # Load source image
source = GdkPixbuf.Pixbuf.new_from_file(str(image_path)) source = GdkPixbuf.Pixbuf.new_from_file(
str(convert_cover(image_path, resize=False))
)
source_size = ImageSize(source.get_width(), source.get_height()) source_size = ImageSize(source.get_width(), source.get_height())
cover_size = ImageSize._make(shared.image_size) cover_size = ImageSize._make(shared.image_size)
# Stretch if possible # Stretch if possible
if scale == 1 and self.is_stretchable(source_size, cover_size): if scale == 1 and self.is_stretchable(source_size, cover_size):
save_cover(game.game_id, resize_cover(pixbuf=source)) return source
return
# Create the blurred cover background # Create the blurred cover background
# fmt: off # fmt: off
@@ -164,7 +163,7 @@ class CoverManager(Manager):
GdkPixbuf.InterpType.BILINEAR, GdkPixbuf.InterpType.BILINEAR,
255, 255,
) )
save_cover(game.game_id, resize_cover(pixbuf=cover)) return cover
def main(self, game: Game, additional_data: dict) -> None: def main(self, game: Game, additional_data: dict) -> None:
if game.blacklisted: if game.blacklisted:
@@ -185,13 +184,15 @@ class CoverManager(Manager):
continue continue
# Icon cover # Icon cover
if key == "local_icon_path": composite_kwargs = {}
self.save_composited_cover(
game,
image_path,
scale=0.7,
blur_size=ImageSize(1, 2),
)
return
self.save_composited_cover(game, image_path) if key == "local_icon_path":
composite_kwargs["scale"] = 0.7
composite_kwargs["blur_size"] = ImageSize(1, 2)
save_cover(
game.game_id,
convert_cover(
pixbuf=self.composite_cover(image_path, **composite_kwargs)
),
)

View File

@@ -28,12 +28,22 @@ from PIL import Image, ImageSequence, UnidentifiedImageError
from src import shared from src import shared
def resize_cover( def convert_cover(
cover_path: Optional[Path] = None, pixbuf: Optional[GdkPixbuf.Pixbuf] = None cover_path: Optional[Path] = None,
pixbuf: Optional[GdkPixbuf.Pixbuf] = None,
resize: bool = True,
) -> Optional[Path]: ) -> Optional[Path]:
if not cover_path and not pixbuf: if not cover_path and not pixbuf:
return None return None
pixbuf_extensions = set()
for pixbuf_format in GdkPixbuf.Pixbuf.get_formats():
for pixbuf_extension in pixbuf_format.get_extensions():
pixbuf_extensions.add(pixbuf_extension)
if not resize and cover_path and cover_path.suffix.lower()[1:] in pixbuf_extensions:
return cover_path
if pixbuf: if pixbuf:
cover_path = Path(Gio.File.new_tmp("XXXXXX.tiff")[0].get_path()) cover_path = Path(Gio.File.new_tmp("XXXXXX.tiff")[0].get_path())
pixbuf.savev(str(cover_path), "tiff", ["compression"], ["1"]) pixbuf.savev(str(cover_path), "tiff", ["compression"], ["1"])
@@ -42,7 +52,8 @@ def resize_cover(
with Image.open(cover_path) as image: with Image.open(cover_path) as image:
if getattr(image, "is_animated", False): if getattr(image, "is_animated", False):
frames = tuple( frames = tuple(
frame.resize((200, 300)) for frame in ImageSequence.Iterator(image) frame.resize((200, 300)) if resize else frame
for frame in ImageSequence.Iterator(image)
) )
tmp_path = Path(Gio.File.new_tmp("XXXXXX.gif")[0].get_path()) tmp_path = Path(Gio.File.new_tmp("XXXXXX.gif")[0].get_path())
@@ -50,6 +61,7 @@ def resize_cover(
tmp_path, tmp_path,
save_all=True, save_all=True,
append_images=frames[1:], append_images=frames[1:],
disposal=2,
) )
else: else:
@@ -59,7 +71,7 @@ def resize_cover(
image = image.convert("RGBA") image = image.convert("RGBA")
tmp_path = Path(Gio.File.new_tmp("XXXXXX.tiff")[0].get_path()) tmp_path = Path(Gio.File.new_tmp("XXXXXX.tiff")[0].get_path())
image.resize(shared.image_size).save( (image.resize(shared.image_size) if resize else image).save(
tmp_path, tmp_path,
compression="tiff_adobe_deflate" compression="tiff_adobe_deflate"
if shared.schema.get_boolean("high-quality-images") if shared.schema.get_boolean("high-quality-images")
@@ -70,7 +82,7 @@ def resize_cover(
Gdk.Texture.new_from_filename(str(cover_path)).save_to_tiff( Gdk.Texture.new_from_filename(str(cover_path)).save_to_tiff(
tmp_path := Gio.File.new_tmp("XXXXXX.tiff")[0].get_path() tmp_path := Gio.File.new_tmp("XXXXXX.tiff")[0].get_path()
) )
return resize_cover(tmp_path) return convert_cover(tmp_path)
except GLib.GError: except GLib.GError:
return None return None

View File

@@ -28,7 +28,7 @@ from requests.exceptions import HTTPError
from src import shared from src import shared
from src.game import Game from src.game import Game
from src.utils.save_cover import resize_cover, save_cover from src.utils.save_cover import convert_cover, save_cover
class SGDBError(Exception): class SGDBError(Exception):
@@ -134,7 +134,7 @@ class SGDBHelper:
tmp_file = Gio.File.new_tmp()[0] tmp_file = Gio.File.new_tmp()[0]
tmp_file_path = tmp_file.get_path() tmp_file_path = tmp_file.get_path()
Path(tmp_file_path).write_bytes(response.content) Path(tmp_file_path).write_bytes(response.content)
save_cover(game.game_id, resize_cover(tmp_file_path)) save_cover(game.game_id, convert_cover(tmp_file_path))
except SGDBAuthError as error: except SGDBAuthError as error:
# Let caller handle auth errors # Let caller handle auth errors
raise error raise error

View File

@@ -1,95 +0,0 @@
# task.py
#
# Copyright 2023 Geoffrey Coulaud
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: GPL-3.0-or-later
from functools import wraps
from typing import Any, Callable
from gi.repository import Gio
def create_task_thread_func_closure(func: Callable, data: Any) -> Callable:
"""Wrap a Gio.TaskThreadFunc with the given data in a closure"""
def closure(
task: Gio.Task, source_object: object, _data: Any, cancellable: Gio.Cancellable
) -> Any:
func(task, source_object, data, cancellable)
return closure
def decorate_set_task_data(task: Gio.Task) -> Callable:
"""Decorate Gio.Task.set_task_data to replace it"""
def decorator(original_method: Callable) -> Callable:
@wraps(original_method)
def new_method(task_data: Any) -> None:
task.task_data = task_data
return new_method
return decorator
def decorate_run_in_thread(task: Gio.Task) -> Callable:
"""Decorate Gio.Task.run_in_thread to pass the task data correctly
Creates a closure around task_thread_func with the task data available."""
def decorator(original_method: Callable) -> Callable:
@wraps(original_method)
def new_method(task_thread_func: Callable) -> None:
closure = create_task_thread_func_closure(task_thread_func, task.task_data)
original_method(closure)
return new_method
return decorator
# pylint: disable=too-few-public-methods
class Task:
"""Wrapper around Gio.Task to patch task data not being passed"""
@classmethod
def new(
cls,
source_object: object,
cancellable: Gio.Cancellable,
callback: Callable,
callback_data: Any,
) -> Gio.Task:
"""Create a new, monkey-patched Gio.Task.
The `set_task_data` and `run_in_thread` methods are decorated.
As of 2023-05-19, PyGObject does not work well with Gio.Task, so to pass data
the only viable way it to create a closure with the thread function and its data.
This class is supposed to make Gio.Task comply with its expected behaviour
per the docs:
http://lazka.github.io/pgi-docs/#Gio-2.0/classes/Task.html#Gio.Task.set_task_data
This code may break if pygobject overrides change in the future.
We need to manually pass `self` to the decorators since it's otherwise bound but
not accessible from Python's side.
"""
task = Gio.Task.new(source_object, cancellable, callback, callback_data)
task.set_task_data = decorate_set_task_data(task)(task.set_task_data)
task.run_in_thread = decorate_run_in_thread(task)(task.run_in_thread)
return task

View File

@@ -114,6 +114,21 @@ class CartridgesWindow(Adw.ApplicationWindow):
style_manager.connect("notify::dark", self.set_details_view_opacity) style_manager.connect("notify::dark", self.set_details_view_opacity)
style_manager.connect("notify::high-contrast", self.set_details_view_opacity) style_manager.connect("notify::high-contrast", self.set_details_view_opacity)
# Allow for a custom number of rows for the library
if shared.schema.get_uint("library-rows"):
shared.schema.bind(
"library-rows",
self.library,
"max-children-per-line",
Gio.SettingsBindFlags.DEFAULT,
)
shared.schema.bind(
"library-rows",
self.hidden_library,
"max-children-per-line",
Gio.SettingsBindFlags.DEFAULT,
)
def search_changed(self, _widget: Any, hidden: bool) -> None: def search_changed(self, _widget: Any, hidden: bool) -> None:
# Refresh search filter on keystroke in search box # Refresh search filter on keystroke in search box
(self.hidden_library if hidden else self.library).invalidate_filter() (self.hidden_library if hidden else self.library).invalidate_filter()
@@ -243,7 +258,7 @@ class CartridgesWindow(Adw.ApplicationWindow):
).lower() ).lower()
if var != "name" and get_value(0) == get_value(1): if var != "name" and get_value(0) == get_value(1):
var, order = "name", True var, order = "name", False
return ((get_value(0) > get_value(1)) ^ order) * 2 - 1 return ((get_value(0) > get_value(1)) ^ order) * 2 - 1